<commit_before>// watches changes in the file upload control (input[file]) and
// puts the files selected in an attribute
var app = angular.module("webui.directives.fileselect", ["webui.services.deps"]);
app.directive("indeterminate", [
    "$parse", function syncInput (parse) {
        return {
            require  : "ngModel",
            // Restrict the directive so it can only be used as an attribute
            restrict : "A",

            link : function link (scope, elem, attr, ngModelCtrl) {
                // Whenever the bound value of the attribute changes we update
                // use upward emit notification for change to prevent the performance penalty bring by $scope.$watch
                var getter = parse(attr["ngModel"]);
                var setter = getter.assign;
                var children = []; // cache children input
                var get = function () {
                    return getter(scope);
                };
                // the internal 'indeterminate' flag on the attached dom element
                var setIndeterminateState = function (newValue) {
                    elem.prop("indeterminate", newValue);
                };
                var setModelValueWithoutSideEffect = function (newVal) {
                    setter(scope, newVal);
                    ngModelCtrl.$modelValue = newVal;
                    ngModelCtrl.$viewValue = newVal;
                    ngModelCtrl.$render();
                };
                var setWithSideEffect = function (newVal) {
                    ngModelCtrl.$setViewValue(newVal);
                    ngModelCtrl.$render();
                };
                var passIfLeafChild = function (callback) {
                    return function () {
                        if (children.length > 0) {
                            callback.apply(this, arguments);
                        }
                    };
                };
                var passIfNotIsLeafChild = function (callback) {
                    return function () {
                        if (children.length === 0) {
                            callback.apply(this, arguments);
                        }
                    };
                };
                var passThroughThisScope = function (callback) {
                    return function (event) {
                        if (event.targetScope !== event.currentScope) {
                            return callback.apply(this, arguments);
                        }
                    };
                };
                if (attr["indeterminate"] && parse(attr["indeterminate"]).constant && !scope.$eval(attr["indeterminate"])) {
                    // is leaf input, Only receive parent change and emit child change event
                    setIndeterminateState(scope.$eval(attr["indeterminate"]));
                    ngModelCtrl.$viewChangeListeners.push(passIfNotIsLeafChild(function () {
                        scope.$emit("childSelectedChange");
                    }));
                    scope.$on("ParentSelectedChange", passThroughThisScope(
                        function (event, newVal) {
                            setWithSideEffect(newVal);
                        }));
                    scope.$emit("i'm child input", get);
                    setWithSideEffect(get());
                    scope.$emit("childSelectedChange");
                } else {
                    // init first time and only once
                    // establish parent-child's relation
                    scope.$on("i'm child input", passThroughThisScope(
                        function (event, child) {
                            children.push(child);
                        })
                    );
                    var updateBaseOnChildrenState = function () {
                        var allSelected = children.every(function (child) {
                            return child();
                        });
                        var anySeleted = children.some(function (child) {
                            return child();
                        });
                        setIndeterminateState(allSelected !== anySeleted);
                        setWithSideEffect(allSelected);
                    };
                    // is not leaf input, Only receive child change and parent change event
                    ngModelCtrl.$viewChangeListeners.push(passIfLeafChild(function () {
                        if (!elem.prop("indeterminate")) { // emit when prop indeterminate is set to false
                            scope.$broadcast("ParentSelectedChange", get());
                        }
                    }));
                    // reset input state base on children inputs
                    scope.$on("childSelectedChange", passThroughThisScope(passIfLeafChild(updateBaseOnChildrenState)));
                }
            }
        };
    }
]);
<commit_msg>add more comment<commit_after>// watches changes in the file upload control (input[file]) and
// puts the files selected in an attribute
var app = angular.module("webui.directives.fileselect", ["webui.services.deps"]);
app.directive("indeterminate", [
    "$parse", function syncInput (parse) {
        return {
            require  : "ngModel",
            // Restrict the directive so it can only be used as an attribute
            restrict : "A",

            link : function link (scope, elem, attr, ngModelCtrl) {
                // Whenever the bound value of the attribute changes we update
                // use upward emit notification for change to prevent the performance penalty bring by $scope.$watch
                var getter = parse(attr["ngModel"]);
                var setter = getter.assign;
                var children = []; // cache children input
                var get = function () {
                    return getter(scope);
                };
                // the internal 'indeterminate' flag on the attached dom element
                var setIndeterminateState = function (newValue) {
                    elem.prop("indeterminate", newValue);
                };
                var setWithSideEffect = function (newVal) {
                    ngModelCtrl.$setViewValue(newVal);
                    ngModelCtrl.$render();
                };
                var passIfLeafChild = function (callback) { // ensure to execute callback when this input have one or more subinputs
                    return function () {
                        if (children.length > 0) {
                            callback.apply(this, arguments);
                        }
                    };
                };
                var passIfNotIsLeafChild = function (callback) { // ensure to execute callback when this input havent subinput
                    return function () {
                        if (children.length === 0) {
                            callback.apply(this, arguments);
                        }
                    };
                };
                var passThroughThisScope = function (callback) { // pass through the event from the scope where they sent
                    return function (event) {
                        if (event.targetScope !== event.currentScope) {
                            return callback.apply(this, arguments);
                        }
                    };
                };
                if (attr["indeterminate"] && parse(attr["indeterminate"]).constant && !scope.$eval(attr["indeterminate"])) {
                    // is leaf input, Only receive parent change and emit child change event
                    setIndeterminateState(scope.$eval(attr["indeterminate"]));
                    ngModelCtrl.$viewChangeListeners.push(passIfNotIsLeafChild(function () {
                        scope.$emit("childSelectedChange");
                    }));
                    scope.$on("ParentSelectedChange", passThroughThisScope(
                        function (event, newVal) {
                            setWithSideEffect(newVal); // set value to parent's value; this will cause listener to emit childChange event; this won't be a infinite loop
                        }));
                    // init first time and only once
                    scope.$emit("i'm child input", get);
                    scope.$emit("childSelectedChange"); // force emitted, and force the parent change their state base on children at first time
                } else {
                    // establish parent-child's relation
                    // listen for the child emitted token
                    scope.$on("i'm child input", passThroughThisScope(
                        function (event, child) {
                            children.push(child);
                        })
                    );
                    var updateBaseOnChildrenState = function () {
                        var allSelected = children.every(function (child) {
                            return child();
                        });
                        var anySeleted = children.some(function (child) {
                            return child();
                        });
                        setIndeterminateState(allSelected !== anySeleted); // if at least one is selected, but not all then set input property indeterminate to true
                        setWithSideEffect(allSelected);
                    };
                    // is not leaf input, Only receive child change and parent change event
                    ngModelCtrl.$viewChangeListeners.push(passIfLeafChild(function () {
                        // emit when property indeterminate is set to false, prevent recursively emitting event from parent to children, children to parent
                        if (!elem.prop("indeterminate")) {
                            scope.$broadcast("ParentSelectedChange", get());
                        }
                    }));
                    // reset input state base on children inputs
                    scope.$on("childSelectedChange", passThroughThisScope(passIfLeafChild(updateBaseOnChildrenState)));
                }
            }
        };
    }
]);
<|endoftext|>


<commit_before>import { addTrackFunction } from 'meteor/vulcan:events';
import { getRenderContext, getFragment, createClientTemplate } from 'meteor/vulcan:lib';
import gql from 'graphql-tag';

function trackInternal(eventName, eventProperties) {
  const { apolloClient } = getRenderContext();

  const fragmentName = 'AnalyticsEventFragment';
  const fragment = getFragment(fragmentName);

  const mutation = gql`${createClientTemplate({ typeName: 'AnalyticsEvent', fragmentName })}${fragment}`;

  const variables = {
    data: {
      name: eventName,
      properties: eventProperties,
    },
  };
  apolloClient.mutate({ mutation, variables });
}

addTrackFunction(trackInternal);
<commit_msg>fix trackInternal<commit_after>import { addTrackFunction } from 'meteor/vulcan:events';
import { getApolloClient, getFragment, createClientTemplate } from 'meteor/vulcan:lib';
import gql from 'graphql-tag';

function trackInternal(eventName, eventProperties) {
  const apolloClient = getApolloClient();

  const fragmentName = 'AnalyticsEventFragment';
  const fragment = getFragment(fragmentName);

  const mutation = gql`${createClientTemplate({ typeName: 'AnalyticsEvent', fragmentName })}${fragment}`;

  const variables = {
    data: {
      name: eventName,
      properties: eventProperties,
    },
  };
  apolloClient.mutate({ mutation, variables });
}

addTrackFunction(trackInternal);
<|endoftext|>


<commit_before>"use strict";

/*global module, require*/

var floatDialogue = require("floating-dialogue");

/*
 Lets us import shape layers from a variety of file formats.
 */
module.exports = function(toolbar, container, handlers) {
    var dialogue = floatDialogue(
	container.append("div")
    	    .attr("id", "import-dialogue")
    )
	    .drag(),

	filePicker = dialogue.content().append("input")
	    .attr("type", "file")
	    .attr("multiple", true)
	    .attr("accept", ".csv,.tsv,.json,.shp,.dbf,.prj")
	    .attr("id", "import-file-picker")
	    .on("change", function(d, i) {
		handlers(
		    Array.prototype.slice.call(this.files)
		);
	    });

    toolbar.add("I", dialogue);

    return {
	content: function() {
	    return dialogue.content();
	},

	show: function() {
	    return dialogue.show();
	}
    };
};
<commit_msg>Can now submit the same files to the import dialogue twice.<commit_after>"use strict";

/*global module, require*/

var floatDialogue = require("floating-dialogue");

/*
 Lets us import shape layers from a variety of file formats.
 */
module.exports = function(toolbar, container, handlers) {
    var dialogue = floatDialogue(
	container.append("div")
    	    .attr("id", "import-dialogue")
    )
	    .drag(),

	filePicker = dialogue.content().append("form")
	    .append("input")
	    .attr("type", "file")
	    .attr("multiple", true)
	    .attr("accept", ".csv,.tsv,.json,.shp,.dbf,.prj")
	    .attr("id", "import-file-picker")
	    .on("change", function(d, i) {
		handlers(
		    Array.prototype.slice.call(this.files)
		);
		/*
		 Clear the files so that this will work if the user selects the same files twice in a row.
		 */
		this.parentElement.reset();
	    });

    toolbar.add("I", dialogue);

    return {
	content: function() {
	    return dialogue.content();
	},

	show: function() {
	    return dialogue.show();
	}
    };
};
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

CLASS({
  name: 'RestDAO',
  package: 'foam.core.dao',
  extendsModel: 'AbstractDAO',

  imports: [
    'ajsonp'
  ],

  properties: [
    {
      name: 'model',
      label: 'Type of data stored in this DAO.'
    },
    {
      name: 'url',
      label: 'REST API URL.'
    },
    {
      model_: 'ArrayProperty',
      subType: 'Property',
      name: 'paramProperties',
      help: 'Properties that are handled as separate parameters rather than in the query.'
    },
    {
      model_: 'IntProperty',
      name: 'batchSize',
      defaultValue: 200
    },
    {
      model_: 'IntProperty',
      name: 'skipThreshold',
      defaultValue: 1000
    }
  ],

  methods: {
    jsonToObj: function(json) {
      return this.model.create(json);
    },
    objToJson: function(obj) {
      return JSONUtil.compact.stringify(obj);
    },
    buildURL: function(query) {
      return this.url;
    },
    buildFindURL: function(key) {
      return this.url + '/' + key;
    },
    buildPutURL: function(obj) {
      return this.url;
    },
    buildPutParams: function(obj) {
      return [];
    },
    buildSelectParams: function(sink, query) {
      return [];
    },
    put: function(value, sink) {
      var self = this;
      var extra = {};
      this.ajsonp(this.buildPutURL(value),
             this.buildPutParams(value),
             "POST",
             this.objToJson(value, extra)
            )(
        function(resp, status) {
          var obj;

          if ( ( status !== undefined && status !== 200 ) ||
               ( obj = self.jsonToObj(resp, extra) ) ) {
            sink && sink.error && sink.error([resp, status]);
            return;
          }
          sink && sink.put && sink.put(obj);
          self.notify_('put', [obj]);
        });
    },
    remove: function(query, sink) {
    },
    select: function(sink, options) {
      sink = sink || [].sink;
      var fut = afuture();
      var self = this;
      var limit;
      var skipped = 0;
      var index = 0;
      var fc = this.createFlowControl_();
      // TODO: This is a very ugly way of passing additional data
      // from buildURL to jsonToObj, used by the IssueCommentNetworkDAO
      // Clean this up.
      var extra = {};
      var params = [];

      if ( options ) {
        index += options.skip || 0;

        var query = options.query;
        var url;

        if ( query ) {
          var origQuery = query;
          query = query.normalize();

          var outquery = [query, origQuery.deepClone()];

          params = this.buildSelectParams(sink, outquery);

          url = this.buildURL(outquery, extra);

          query = outquery[0];
          origQuery = outquery[1];

          var mql = query.toMQL();
          if ( mql ) params.push('q=' + encodeURIComponent(query.toMQL()));
        } else {
          url = this.buildURL();
        }

        if ( options.order ) {
          var sort = options.order.toMQL();
          params.push("sort=" + sort);
        }

        if ( options.limit ) {
          limit = options.limit;
        }
      }

      var finished = false;
      awhile(
        function() { return !finished; },
        function(ret) {
          var batch = self.batchSize;

          if ( Number.isFinite(limit) )
            var batch = Math.min(batch, limit);

          // No need to fetch items for count.
          if ( CountExpr.isInstance(sink) ) {
            batch = 0;
          }

          var myparams = params.slice();
          myparams.push('maxResults=' + batch);
          myparams.push('startIndex=' + index);

          self.ajsonp(url, myparams)(Movement.whenIdle(function(data) {
            // Short-circuit count.
            // TODO: This count is wrong for queries that use
            if ( CountExpr.isInstance(sink) ) {
              sink.count = data.totalResults;
              finished = true;
              ret(); return;
            }

            var items = data && data.items ? data.items : [];

            // Fetching no items indicates EOF.
            if ( items.length == 0 ) finished = true;
            index += items.length;

            for ( var i = 0 ; i < items.length; i++ ) {
              var item = self.jsonToObj(items[i], extra)

              // Filter items that don't match due to
              // low resolution of Date parameters in MQL
              if ( origQuery && !origQuery.f(item) ) {
                skipped++;
                continue;
              }

              if ( Number.isFinite(limit) ) {
                if ( limit <= 0 ) { finished = true; break; }
                limit--;
              }

              if ( fc.stopped ) { finished = true; break; }
              if ( fc.errorEvt ) {
                sink.error && sink.error(fc.errorEvt);
                finished = true;
                break;
              }

              sink && sink.put && sink.put(item, null, fc);
            }
            if ( limit <= 0 ) finished = true;
            if ( ! data || index >= data.totalResults ) finished = true;
            if ( skipped >= self.skipThreshold ) finished = true;
            ret();
          }));
        })(function() { sink && sink.eof && sink.eof(); fut.set(sink); });

      return fut.get;
    },
    buildFindParams: function(key) {
      return [];
    },
    find: function(key, sink) {
      var self = this;
      this.ajsonp(this.buildFindURL(key), this.buildFindParams())(function(data, status) {
        var deserialized;
        if ( status !== 200 || ! (deserialized = self.jsonToObj(data)) ) {
          sink && sink.error && sink.error('Network error');
          return;
        }

        sink && sink.put && sink.put(deserialized);
      });
    }
  }
});
<commit_msg>Partial eval query before sending to network in RestDAO.<commit_after>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

CLASS({
  name: 'RestDAO',
  package: 'foam.core.dao',
  extendsModel: 'AbstractDAO',

  imports: [
    'ajsonp'
  ],

  properties: [
    {
      name: 'model',
      label: 'Type of data stored in this DAO.'
    },
    {
      name: 'url',
      label: 'REST API URL.'
    },
    {
      model_: 'ArrayProperty',
      subType: 'Property',
      name: 'paramProperties',
      help: 'Properties that are handled as separate parameters rather than in the query.'
    },
    {
      model_: 'IntProperty',
      name: 'batchSize',
      defaultValue: 200
    },
    {
      model_: 'IntProperty',
      name: 'skipThreshold',
      defaultValue: 1000
    }
  ],

  methods: {
    jsonToObj: function(json) {
      return this.model.create(json);
    },
    objToJson: function(obj) {
      return JSONUtil.compact.stringify(obj);
    },
    buildURL: function(query) {
      return this.url;
    },
    buildFindURL: function(key) {
      return this.url + '/' + key;
    },
    buildPutURL: function(obj) {
      return this.url;
    },
    buildPutParams: function(obj) {
      return [];
    },
    buildSelectParams: function(sink, query) {
      return [];
    },
    put: function(value, sink) {
      var self = this;
      var extra = {};
      this.ajsonp(this.buildPutURL(value),
             this.buildPutParams(value),
             "POST",
             this.objToJson(value, extra)
            )(
        function(resp, status) {
          var obj;

          if ( ( status !== undefined && status !== 200 ) ||
               ( obj = self.jsonToObj(resp, extra) ) ) {
            sink && sink.error && sink.error([resp, status]);
            return;
          }
          sink && sink.put && sink.put(obj);
          self.notify_('put', [obj]);
        });
    },
    remove: function(query, sink) {
    },
    select: function(sink, options) {
      sink = sink || [].sink;
      var fut = afuture();
      var self = this;
      var limit;
      var skipped = 0;
      var index = 0;
      var fc = this.createFlowControl_();
      // TODO: This is a very ugly way of passing additional data
      // from buildURL to jsonToObj, used by the IssueCommentNetworkDAO
      // Clean this up.
      var extra = {};
      var params = [];

      if ( options ) {
        index += options.skip || 0;

        var query = options.query.partialEval();
        var url;

        if ( query ) {
          var origQuery = query;
          query = query.normalize();

          var outquery = [query, origQuery.deepClone()];

          params = this.buildSelectParams(sink, outquery);

          url = this.buildURL(outquery, extra);

          query = outquery[0];
          origQuery = outquery[1];

          var mql = query.toMQL();
          if ( mql ) params.push('q=' + encodeURIComponent(query.toMQL()));
        } else {
          url = this.buildURL();
        }

        if ( options.order ) {
          var sort = options.order.toMQL();
          params.push("sort=" + sort);
        }

        if ( options.limit ) {
          limit = options.limit;
        }
      }

      var finished = false;
      awhile(
        function() { return !finished; },
        function(ret) {
          var batch = self.batchSize;

          if ( Number.isFinite(limit) )
            var batch = Math.min(batch, limit);

          // No need to fetch items for count.
          if ( CountExpr.isInstance(sink) ) {
            batch = 0;
          }

          var myparams = params.slice();
          myparams.push('maxResults=' + batch);
          myparams.push('startIndex=' + index);

          self.ajsonp(url, myparams)(Movement.whenIdle(function(data) {
            // Short-circuit count.
            // TODO: This count is wrong for queries that use
            if ( CountExpr.isInstance(sink) ) {
              sink.count = data.totalResults;
              finished = true;
              ret(); return;
            }

            var items = data && data.items ? data.items : [];

            // Fetching no items indicates EOF.
            if ( items.length == 0 ) finished = true;
            index += items.length;

            for ( var i = 0 ; i < items.length; i++ ) {
              var item = self.jsonToObj(items[i], extra)

              // Filter items that don't match due to
              // low resolution of Date parameters in MQL
              if ( origQuery && !origQuery.f(item) ) {
                skipped++;
                continue;
              }

              if ( Number.isFinite(limit) ) {
                if ( limit <= 0 ) { finished = true; break; }
                limit--;
              }

              if ( fc.stopped ) { finished = true; break; }
              if ( fc.errorEvt ) {
                sink.error && sink.error(fc.errorEvt);
                finished = true;
                break;
              }

              sink && sink.put && sink.put(item, null, fc);
            }
            if ( limit <= 0 ) finished = true;
            if ( ! data || index >= data.totalResults ) finished = true;
            if ( skipped >= self.skipThreshold ) finished = true;
            ret();
          }));
        })(function() { sink && sink.eof && sink.eof(); fut.set(sink); });

      return fut.get;
    },
    buildFindParams: function(key) {
      return [];
    },
    find: function(key, sink) {
      var self = this;
      this.ajsonp(this.buildFindURL(key), this.buildFindParams())(function(data, status) {
        var deserialized;
        if ( status !== 200 || ! (deserialized = self.jsonToObj(data)) ) {
          sink && sink.error && sink.error('Network error');
          return;
        }

        sink && sink.put && sink.put(deserialized);
      });
    }
  }
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

CLASS({
  package: 'foam.util',
  name: 'JavaSource2',
  requires: [
    'foam.i18n.TranslationFormatStringParser',
    'foam.util.InlineTrait',
  ],

  properties: [
    {
      name: 'defaultPackage',
      defaultValue: 'foam.core',
    },
  ],

  methods: [
    function prepModel(model) {
      // Java doesn't support traits, so we'll copy traits into the model directly.
      model = this.InlineTrait.create().inlineTraits(model);

      var filter = function(m) {
        if ( m.labels && m.labels.indexOf('java') == -1 ) {
          return false;
        }
        return true;
      };

      model.properties = model.properties.filter(filter);
      model.methods = model.methods.filter(filter);
      model.listeners = model.listeners.filter(filter);
      model.messages = model.messages.filter(filter);

      return model;
    },
    function generate(model) {
      if ( model.javaSource ) {
        return model.javaSource();
      }
      return this.javaSource.call(this.prepModel(model), undefined, this);
    },
  ],

  templates: [
    function javaSource(_, util) {/*<%
var escapeDoubleQuotes = function(s) {
  return s.replace(/"/g, '\\"');
};

var primitives = [
  'byte',
  'char',
  'short',
  'int',
  'long',
  'float',
  'double',
  'boolean',
];

var propertyMap = {}
var toPropertyMap = function(f) {
  propertyMap[f.name] = f;
}
this.properties.forEach(toPropertyMap);

var idName;
var modelProperties = [];
var overriddenProperties = [];
var runtimeProperties = this.getRuntimeProperties();
var parent = this.X.lookup(this.extends);
for ( var i = 0 ; i < runtimeProperties.length ; i++ ) {
  var prop = runtimeProperties[i];
  if (prop.name == 'id') { idName = prop.name; }
  if (prop.labels && (
    prop.labels.indexOf('compiletime') != -1 ||
    prop.labels.indexOf('java') == -1 ) ) { continue; }
  if (parent && parent.getProperty(prop.name)) {
    if (propertyMap[prop.name]) {
      overriddenProperties.push(prop);
    }
    continue;
  }
  modelProperties.push(prop)
}
var allProperties = modelProperties.concat(overriddenProperties);
if (!idName) {
  if (this.ids && this.ids.length) {
    idName = this.ids[0];
  } else if(allProperties.length) {
    idName = allProperties[0].name;
  }
} else {
  // Since there's already an ID property, we don't need to do any special
  // handling of ID so unset it.
  idName = undefined;
}

var allRequires = this.getAllRequires();
if (parent) allRequires.push(parent.id);
allRequires = allRequires.map(function(req) {
  if (req && req.indexOf('.') == -1) {
    req = util.defaultPackage + '.' + req;
  }
  return req;
});

%>
// Generated by foam.util.JavaSource2.  DO NOT MODIFY BY HAND
package <%= this.package || util.defaultPackage %>;

import foam.core2.*;

<% this.javaClassImports.forEach(function(i) { %>
import <%= i %>;
<% }); %>

<% allRequires.forEach(function(req) { %>
import <%= req %>;
<% }); %>

public class <%= this.javaClassName %> extends <%= parent && parent.javaClassName || 'FObject' %> {

<% for ( var i = 0, message; message = this.messages[i]; i++) { %>
  public static String <%= message.name %> = "<%= escapeDoubleQuotes(message.value) %>";
<% } %>

<% for (var i = 0, constant; constant = this.constants[i]; i++) { %>
  <% if (constant.javaValue && constant.javaType) { %>
  public static <%= constant.javaType %> <%= constant.name %> = <%= constant.javaValue %>;
  <% } %>
<% } %>

<%
for ( var i = 0 ; i < allProperties.length ; i++ ) {
  var prop = allProperties[i];
  var override = overriddenProperties.indexOf(prop) != -1 ? 'override' : '';
  var name = prop.name;
  var constant = constantize(name);
  var type = prop.javaType;
  var propertyModel = (prop.model_.id || prop.model_.name).split('.').pop();
  var propFactory = prop.javaFactory || prop.javaLazyFactory;
%>
  <% if (!override) { %>
  protected <%= type %> <%= name %>_;
  protected boolean <%= name %>Inited_ = false;
  <% } %>

  private static <%= propertyModel %> <%= this.javaClassName %>_<%= constant %>_;
  public static <%= propertyModel %> <%= this.javaClassName %>_<%= constant %>() {
    if (<%= this.javaClassName %>_<%= constant %>_ != null)
      return <%= this.javaClassName %>_<%= constant %>_;
    <%= propertyModel %> p = new <%= propertyModel %>();
    p.setName("<%= name %>");
    p.setLabel("<%= prop.label %>");
  <% if (prop.javaValidate) { %>
    p.setValidate(new FoamFunction<String>() {
      @Override public String call(Object... args) {
        <%= this.javaClassName %> fobj = (<%= this.javaClassName %>) args[0];
        return fobj.validate_<%= name %>();
      }
    });
  <% } %>
    <%= this.javaClassName %>_<%= constant %>_ = p;
    return p;
  }

  <% if (prop.javaValidate) { %>
  public String validate_<%= name %>() {
    <%= type %> value = get<%= name.capitalize() %>();
    <%= propertyModel %> property = <%= this.javaClassName %>_<%= constant %>();
    <%= multiline(prop.javaValidate) %>
  }
  <% } %>

  public <%= type %> get<%= name.capitalize() %>() {
  <% if (prop.javaGetter) { %>
    <%= TemplateUtil.lazyCompile(TemplateUtil.expandTemplate(prop, prop.javaGetter)).bind(prop)() %>
  <% } else { %>
    if (<%= name %>Inited_) {
      return <%= name %>_;
    }
    <% if (prop.javaDefaultValueFn) { %>
    <%= prop.javaDefaultValueFn %>
    <% } else if (prop.javaDefaultValue) { %>
    return <%= prop.javaDefaultValue %>;
    <% } else if (propFactory) { %>
    set<%= name.capitalize() %>(_<%= name %>_factory());
    return <%= prop.name %>_;
    <% } else { %>
    return <%= prop.name %>_;
    <% } %>
  <% } %>
  }

  <% if (propFactory) { %>
  private <%= type %> _<%= name %>_factory() { <%= propFactory %> }
  <% } %>

  private <%= type %> <%= name %>_adapt_(Object oldValue, Object newValue) {
    <%= TemplateUtil.lazyCompile(TemplateUtil.expandTemplate(prop, prop.javaAdapt)).bind(prop)() %>
  }
  protected <%= type %> <%= name %>_adapt(Object oldValue, Object newValue) {
  <% if (override) { %>
    return super.<%= name %>_adapt(oldValue, <%= name %>_adapt_(oldValue, newValue));
  <% } else { %>
    return <%= name %>_adapt_(oldValue, newValue);
  <% } %>
  }

  private <%= type %> <%= name %>_preSet_(Object oldValue, <%= type %> newValue) {
    <%= TemplateUtil.lazyCompile(TemplateUtil.expandTemplate(prop, prop.javaPreSet)).bind(prop)() %>
  }
  protected <%= type %> <%= name %>_preSet(Object oldValue, <%= type %> newValue) {
  <% if (override) { %>
    return super.<%= name %>_preSet(oldValue, <%= name %>_preSet_(oldValue, newValue));
  <% } else { %>
    return <%= name %>_preSet_(oldValue, newValue);
  <% } %>
  }

  private void <%= name %>_postSet_(Object oldValue, <%= type %> newValue) {
    <%= TemplateUtil.lazyCompile(TemplateUtil.expandTemplate(prop, prop.javaPostSet)).bind(prop)() %>
  }
  protected void <%= name %>_postSet(Object oldValue, <%= type %> newValue) {
  <% if (override) { %>
    super.<%= name %>_postSet(oldValue, newValue);
  <% } %>
    <%= name %>_postSet_(oldValue, newValue);
  }

  public void set<%= name.capitalize() %>(<%= type %> value) {
    set("<%= name %>", value);
  }
<% } %>

  public Object get(String key) {
    switch (key) {
<% for (var i = 0, prop; prop = allProperties[i]; i++) { %>
  <% var name = prop.name, type = prop.javaType %>
      case "<%= name %>":
        return get<%= name.capitalize() %>();
<% } %>
      default:
        break;
    }
    return super.get(key);
  }

  public boolean hasOwnProperty(String key) {
    switch (key) {
<% for (var i = 0, prop; prop = allProperties[i]; i++) { %>
  <% var name = prop.name, type = prop.javaType %>
      case "<%= name %>":
        return <%= name %>Inited_;
<% } %>
      default:
        break;
    }
    return super.hasOwnProperty(key);
  }

  public foam.core.Property getProperty(String key) {
    switch (key) {
<% for (var i = 0, prop; prop = allProperties[i]; i++) { %>
  <% var name = prop.name, type = prop.javaType %>
      case "<%= name %>":
        return <%= this.javaClassName %>_<%= constantize(name) %>();
<% } %>
      default:
        break;
    }
    return super.getProperty(key);
  }

  public void set(String key, Object value) {
    switch (key) {
<% for (var i = 0, prop; prop = allProperties[i]; i++) { %>
  <% var name = prop.name, type = prop.javaType %>
      case "<%= name %>":
        <%= type %> <%=name%>Old = <%= name %>_;
        <%= name %>_ = <%= name %>_preSet(<%=name%>Old, <%= name %>_adapt(<%=name%>Old, value));
        <%= name %>Inited_ = true;
        <%= name %>_postSet(<%=name%>Old, <%= name %>_);
        break;
<% } %>
      default:
        super.set(key, value);
        break;
    }
  }

  public void clearProperty(String key) {
    switch (key) {
<% for (var i = 0, prop; prop = allProperties[i]; i++) { %>
  <% var name = prop.name %>
      case "<%= name %>":
  <% if (primitives.indexOf(prop.javaType) == -1) { %>
        <%= name %>_ = null;
  <% } %>
        <%= name %>Inited_ = false;
        break;
<% } %>
      default:
        super.clearProperty(key);
        break;
    }
  }

<%
var staticModelName = this.javaClassName + 'Model_';
var staticModelProperties = modelProperties.map(function(prop) {
  return this.javaClassName + '_' + constantize(prop.name) + '()';
}.bind(this));
%>
private static foam.core.Model <%=staticModelName%>;
public static foam.core.Model <%=this.javaClassName%>Model() {
  if (<%=this.javaClassName%>Model_ == null) {
    java.util.List<foam.core.Property> properties = new java.util.ArrayList<>();
    <% staticModelProperties.forEach(function(p) { %>
    properties.add(<%=p%>);
    <% }) %>
<% if (parent) { %>
    properties.addAll(
        <%=parent.id%>.<%=parent.javaClassName%>Model().getProperties());
<% } %>
    <%=this.javaClassName%>Model_ = new foam.core.Model();
    <%=this.javaClassName%>Model_.setName("<%= this.javaClassName %>");
    <%=this.javaClassName%>Model_.setPackage("<%= this.package %>");
    <%=this.javaClassName%>Model_.setProperties(properties);
    <%=this.javaClassName%>Model_.factory = new FoamFunction<FObject>() {
      @Override public FObject call(Object... args) {
        return new <%= this.javaClassName %>();
      }
    };
  }
  return <%=this.javaClassName%>Model_;
}
public foam.core.Model getModel_() {
  return <%= this.javaClassName %>Model();
}

<%
  function javaSource(f) {
    f.javaSource$f && f.javaSource$f.call(f, out, self);
  }

  this.methods.forEach(javaSource);
  this.listeners.forEach(javaSource);
  this.actions.forEach(javaSource);
%>

  <%= multiline(this.javaCode) %>

<% if (this.name == 'Model') { %>
  public FoamFunction<FObject> factory;
  public FObject createInstance() {
    return factory.call();
  }
<% } %>
}
    */},
  ],
});
<commit_msg>Some java generation changes. For generating imports for requires, user their javaClassName instead of the foam model id. Include parent's javaClassImports. Use javaImplements instead of implements. Introduce an 'id' on all generated models.<commit_after>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

CLASS({
  package: 'foam.util',
  name: 'JavaSource2',
  requires: [
    'foam.i18n.TranslationFormatStringParser',
    'foam.util.InlineTrait',
  ],

  properties: [
    {
      name: 'defaultPackage',
      defaultValue: 'foam.core',
    },
  ],

  methods: [
    function prepModel(model) {
      // Java doesn't support traits, so we'll copy traits into the model directly.
      model = this.InlineTrait.create().inlineTraits(model);

      var filter = function(m) {
        if ( m.labels && m.labels.indexOf('java') == -1 ) {
          return false;
        }
        return true;
      };

      model.properties = model.properties.filter(filter);
      model.methods = model.methods.filter(filter);
      model.listeners = model.listeners.filter(filter);
      model.messages = model.messages.filter(filter);

      return model;
    },
    function generate(model) {
      if ( model.javaSource ) {
        return model.javaSource();
      }
      return this.javaSource.call(this.prepModel(model), undefined, this);
    },
  ],

  templates: [
    function javaSource(_, util) {/*<%
var escapeDoubleQuotes = function(s) {
  return s.replace(/"/g, '\\"');
};

var primitives = [
  'byte',
  'char',
  'short',
  'int',
  'long',
  'float',
  'double',
  'boolean',
];

var propertyMap = {}
var toPropertyMap = function(f) {
  propertyMap[f.name] = f;
}
this.properties.forEach(toPropertyMap);

var idName;
var modelProperties = [];
var overriddenProperties = [];
var runtimeProperties = this.getRuntimeProperties();
var parent = this.X.lookup(this.extends);
for ( var i = 0 ; i < runtimeProperties.length ; i++ ) {
  var prop = runtimeProperties[i];
  if (prop.name == 'id') { idName = prop.name; }
  if (prop.labels && (
    prop.labels.indexOf('compiletime') != -1 ||
    prop.labels.indexOf('java') == -1 ) ) { continue; }
  if (parent && parent.getProperty(prop.name)) {
    if (propertyMap[prop.name]) {
      overriddenProperties.push(prop);
    }
    continue;
  }
  modelProperties.push(prop)
}
var allProperties = modelProperties.concat(overriddenProperties);
if (!idName) {
  if (this.ids && this.ids.length) {
    idName = this.ids[0];
  } else if(allProperties.length) {
    idName = allProperties[0].name;
  }
} else {
  // Since there's already an ID property, we don't need to do any special
  // handling of ID so unset it.
  idName = undefined;
}

var allRequires = this.getAllRequires();
if (parent) allRequires.push(parent.id);
allRequires = allRequires.map(function(req) {
  var model = self.X.lookup(req);
  var package = model.package || util.defaultPackage;
  return package + '.' + model.javaClassName;
});

var imports = {};
var curModel = this;
while (curModel) {
  curModel.javaClassImports.forEach(function(i) { imports[i] = 1; });
  curModel = curModel.extends && this.X.lookup(curModel.extends);
}
imports = Object.keys(imports);

%>
// Generated by foam.util.JavaSource2.  DO NOT MODIFY BY HAND
package <%= this.package || util.defaultPackage %>;

import foam.core2.*;

<% imports.forEach(function(i) { %>
import <%= i %>;
<% }); %>

<% allRequires.forEach(function(req) { %>
import <%= req %>;
<% }); %>

public class <%= this.javaClassName %>
    extends <%= parent && parent.javaClassName || 'FObject' %>
    <% if (this.javaImplements.length) { %>implements <%= this.javaImplements.join(', ') %><% } %> {

<% for ( var i = 0, message; message = this.messages[i]; i++) { %>
  public static String <%= message.name %> = "<%= escapeDoubleQuotes(message.value) %>";
<% } %>

<% for (var i = 0, constant; constant = this.constants[i]; i++) { %>
  <% if (constant.javaValue && constant.javaType) { %>
  public static <%= constant.javaType %> <%= constant.name %> = <%= constant.javaValue %>;
  <% } %>
<% } %>

<%
for ( var i = 0 ; i < allProperties.length ; i++ ) {
  var prop = allProperties[i];
  var override = overriddenProperties.indexOf(prop) != -1 ? 'override' : '';
  var name = prop.name;
  var constant = constantize(name);
  var type = prop.javaType;
  var propertyModel = (prop.model_.id || prop.model_.name).split('.').pop();
  var propFactory = prop.javaFactory || prop.javaLazyFactory;
%>
  <% if (!override) { %>
  protected <%= type %> <%= name %>_;
  protected boolean <%= name %>Inited_ = false;
  <% } %>

  private static <%= propertyModel %> <%= this.javaClassName %>_<%= constant %>_;
  public static <%= propertyModel %> <%= this.javaClassName %>_<%= constant %>() {
    if (<%= this.javaClassName %>_<%= constant %>_ != null)
      return <%= this.javaClassName %>_<%= constant %>_;
    <%= propertyModel %> p = new <%= propertyModel %>();
    p.setName("<%= name %>");
    p.setLabel("<%= prop.label %>");
  <% if (prop.javaValidate) { %>
    p.setValidate(new FoamFunction<String>() {
      @Override public String call(Object... args) {
        <%= this.javaClassName %> fobj = (<%= this.javaClassName %>) args[0];
        return fobj.validate_<%= name %>();
      }
    });
  <% } %>
    <%= this.javaClassName %>_<%= constant %>_ = p;
    return p;
  }

  <% if (prop.javaValidate) { %>
  public String validate_<%= name %>() {
    <%= type %> value = get<%= name.capitalize() %>();
    <%= propertyModel %> property = <%= this.javaClassName %>_<%= constant %>();
    <%= multiline(prop.javaValidate) %>
  }
  <% } %>

  public <%= type %> get<%= name.capitalize() %>() {
  <% if (prop.javaGetter) { %>
    <%= TemplateUtil.lazyCompile(TemplateUtil.expandTemplate(prop, prop.javaGetter)).bind(prop)() %>
  <% } else { %>
    if (<%= name %>Inited_) {
      return <%= name %>_;
    }
    <% if (prop.javaDefaultValueFn) { %>
    <%= prop.javaDefaultValueFn %>
    <% } else if (prop.javaDefaultValue) { %>
    return <%= prop.javaDefaultValue %>;
    <% } else if (propFactory) { %>
    set<%= name.capitalize() %>(_<%= name %>_factory());
    return <%= prop.name %>_;
    <% } else { %>
    return <%= prop.name %>_;
    <% } %>
  <% } %>
  }

  <% if (propFactory) { %>
  private <%= type %> _<%= name %>_factory() { <%= propFactory %> }
  <% } %>

  private <%= type %> <%= name %>_adapt_(Object oldValue, Object newValue) {
    <%= TemplateUtil.lazyCompile(TemplateUtil.expandTemplate(prop, prop.javaAdapt)).bind(prop)() %>
  }
  protected <%= type %> <%= name %>_adapt(Object oldValue, Object newValue) {
  <% if (override) { %>
    return super.<%= name %>_adapt(oldValue, <%= name %>_adapt_(oldValue, newValue));
  <% } else { %>
    return <%= name %>_adapt_(oldValue, newValue);
  <% } %>
  }

  private <%= type %> <%= name %>_preSet_(Object oldValue, <%= type %> newValue) {
    <%= TemplateUtil.lazyCompile(TemplateUtil.expandTemplate(prop, prop.javaPreSet)).bind(prop)() %>
  }
  protected <%= type %> <%= name %>_preSet(Object oldValue, <%= type %> newValue) {
  <% if (override) { %>
    return super.<%= name %>_preSet(oldValue, <%= name %>_preSet_(oldValue, newValue));
  <% } else { %>
    return <%= name %>_preSet_(oldValue, newValue);
  <% } %>
  }

  private void <%= name %>_postSet_(Object oldValue, <%= type %> newValue) {
    <%= TemplateUtil.lazyCompile(TemplateUtil.expandTemplate(prop, prop.javaPostSet)).bind(prop)() %>
  }
  protected void <%= name %>_postSet(Object oldValue, <%= type %> newValue) {
  <% if (override) { %>
    super.<%= name %>_postSet(oldValue, newValue);
  <% } %>
    <%= name %>_postSet_(oldValue, newValue);
  }

  public void set<%= name.capitalize() %>(<%= type %> value) {
    set("<%= name %>", value);
  }
<% } %>

  public Object get(String key) {
    switch (key) {
<% for (var i = 0, prop; prop = allProperties[i]; i++) { %>
  <% var name = prop.name, type = prop.javaType %>
      case "<%= name %>":
        return get<%= name.capitalize() %>();
<% } %>
<% if (idName) { %>
      case "id":
        return get("<%= idName %>");
<% } %>
      default:
        break;
    }
    return super.get(key);
  }

  public boolean hasOwnProperty(String key) {
    switch (key) {
<% for (var i = 0, prop; prop = allProperties[i]; i++) { %>
  <% var name = prop.name, type = prop.javaType %>
      case "<%= name %>":
        return <%= name %>Inited_;
<% } %>
<% if (idName) { %>
      case "id":
        return hasOwnProperty("<%= idName %>");
<% } %>
      default:
        break;
    }
    return super.hasOwnProperty(key);
  }

  public foam.core.Property getProperty(String key) {
    switch (key) {
<% for (var i = 0, prop; prop = allProperties[i]; i++) { %>
  <% var name = prop.name, type = prop.javaType %>
      case "<%= name %>":
        return <%= this.javaClassName %>_<%= constantize(name) %>();
<% } %>
<% if (idName) { %>
      case "id":
        return getProperty("<%= idName %>");
<% } %>
      default:
        break;
    }
    return super.getProperty(key);
  }

  public void set(String key, Object value) {
    switch (key) {
<% for (var i = 0, prop; prop = allProperties[i]; i++) { %>
  <% var name = prop.name, type = prop.javaType %>
      case "<%= name %>":
        <%= type %> <%=name%>Old = <%= name %>_;
        <%= name %>_ = <%= name %>_preSet(<%=name%>Old, <%= name %>_adapt(<%=name%>Old, value));
        <%= name %>Inited_ = true;
        <%= name %>_postSet(<%=name%>Old, <%= name %>_);
        break;
<% } %>
<% if (idName) { %>
      case "id":
        set("<%= idName %>", value);
<% } %>
      default:
        super.set(key, value);
        break;
    }
  }

  public void clearProperty(String key) {
    switch (key) {
<% for (var i = 0, prop; prop = allProperties[i]; i++) { %>
  <% var name = prop.name %>
      case "<%= name %>":
  <% if (primitives.indexOf(prop.javaType) == -1) { %>
        <%= name %>_ = null;
  <% } %>
        <%= name %>Inited_ = false;
        break;
<% } %>
<% if (idName) { %>
      case "id":
        clearProperty("<%= idName %>");
<% } %>
      default:
        super.clearProperty(key);
        break;
    }
  }

<%
var staticModelName = this.javaClassName + 'Model_';
var staticModelProperties = modelProperties.map(function(prop) {
  return this.javaClassName + '_' + constantize(prop.name) + '()';
}.bind(this));
%>
private static foam.core.Model <%=staticModelName%>;
public static foam.core.Model <%=this.javaClassName%>Model() {
  if (<%=this.javaClassName%>Model_ == null) {
    java.util.List<foam.core.Property> properties = new java.util.ArrayList<>();
    <% staticModelProperties.forEach(function(p) { %>
    properties.add(<%=p%>);
    <% }) %>
<% if (parent) { %>
    properties.addAll(
        <%=parent.javaClassName%>.<%=parent.javaClassName%>Model().getProperties());
<% } %>
    <%=this.javaClassName%>Model_ = new foam.core.Model();
    <%=this.javaClassName%>Model_.setName("<%= this.javaClassName %>");
    <%=this.javaClassName%>Model_.setPackage("<%= this.package %>");
    <%=this.javaClassName%>Model_.setProperties(properties);
    <%=this.javaClassName%>Model_.factory = new FoamFunction<FObject>() {
      @Override public FObject call(Object... args) {
        return new <%= this.javaClassName %>();
      }
    };
  }
  return <%=this.javaClassName%>Model_;
}
public foam.core.Model getModel_() {
  return <%= this.javaClassName %>Model();
}

<%
  function javaSource(f) {
    f.javaSource$f && f.javaSource$f.call(f, out, self);
  }

  this.methods.forEach(javaSource);
  this.listeners.forEach(javaSource);
  this.actions.forEach(javaSource);
%>

  <%= multiline(this.javaCode) %>

<% if (this.name == 'Model') { %>
  public FoamFunction<FObject> factory;
  public FObject createInstance() {
    return factory.call();
  }
<% } %>
}
    */},
  ],
});
<|endoftext|>


<commit_before>(function() {
var t = new Test.TAP.Class();
t.plan(35)

var thistop = Test.prototype.top

t.testModuleClass = function() {
    var self = this;
    self.ok(Joose.Module, "The module class is here")

    Module("com.test.module", function () {
        Class("Test1", {
            methods: { world: function () { return "hello" } }
        });
        Class("Test2", {
            methods: { world: function () { return "hello" } }
        })
    })

    self.ok(com.test.module, "There is something in the module spot")
    self.ok(com.test.module.meta, "And is has a meta object")
    self.ok(com.test.module.meta.meta, "And a meta meta object")
    self.ok(com.test.module.meta.meta.isa(Joose.Module), "And it is a Module")
    self.ok(com.test.module.meta.meta.isa(Joose.Module), "And it is a Module")
    self.ok(com.test.module.meta.getName() == "com.test.module", "The name is correct")

    self.ok(com.test.module.Test1, "There is also something in the class spot")
    self.ok(com.test.module.Test1.meta, "and it has a meta object")
    self.ok(com.test.module.Test1.meta.meta.isa(Joose.Class), "it is a class")

    self.ok(com.test.module.Test2, "There is also something in the class spot")
    self.ok(com.test.module.Test2.meta, "and it has a meta object")
    self.ok(com.test.module.Test2.meta.meta.isa(Joose.Class), "it is a class")

    self.ok(com.test.module.Test1.meta.className()  == "com.test.module.Test1", "The class name is correct")
    self.ok(com.test.module.Test2.meta.className() == "com.test.module.Test2", "The class name is correct")

    self.ok(com.test.module.meta.alias, "There is an alias method");
    com.test.module.meta.alias(thistop)
    self.ok(thistop.Test1, "There is something in the expected spot")
    self.ok(thistop.Test1 === com.test.module.Test1, "Class is now global")

    self.ok(new thistop.Test1(), "We can instantiate class")
    var o = new thistop.Test1();
    self.ok(o.world() == "hello", "and call methods on them")

    self.ok(new com.test.module.Test1(), "We can also instantiate the fully qualified name");
    self.ok(new com.test.module.Test1().world() == "hello", "and call methods on them");

    self.lives_ok(function () {com.test.module.meta.alias(thistop)}, "We can import again")
    self.ok(new thistop.Test1().world() == "hello", "and call methods")

    self.throws_ok(function () {com.test.module.meta.alias(thistop)}, "here is already something else", "Importing fails if there is already something else")

    Module("com.test", function () {
        Class("Test1", {
            methods: { one: function () { return 1 } }
        })
    })

    self.ok(new com.test.Test1(), "we can make modules on a lower hierarchy")

    Module("com.test", function () {
        Class("Test2", {
            methods: { one: function () { return 1 } }
        })
    })

    self.ok(new com.test.Test1(), "We can do declare modules multiple times. The formerly declared class is still there")
    self.ok(new com.test.Test2(), "we can make modules on a lower hierarchy. The new class is here.")

    self.throws_ok(function () {
        Module("Joose.SimpleRequest", function () {
            Class("FooBar", {})
        })
    }, "Trying to setup module", "We cannot put a module in a used spot")

    Module("com.test.module", function (m) {
        self.ok(new m.Test1().world() == "hello", "Module passes the current module to the module creation function")
    })

    self.throws_ok(function () {
        Module("com.test.meta.bla", function () {

        })
    }, "Module names may not include a part called 'meta'.", "meta is not allowed in a module name")

    self.ok(__global__.nomodule, "There is a global module")

    self.ok(__global__.nomodule.meta.meta.isa(Joose.Module), "it is actually a module :)")

    self.ok(Joose.A.exists(__global__.nomodule.meta.getNames(), "Joose.Class"), "Joose.Class is in it")

    self.ok(Joose.Module.getAllModules(), "We can get all modules")
}

return t;
})()
<commit_msg>fixed failing test case for aliasing over the top of something else<commit_after>(function() {
var t = new Test.TAP.Class();
t.plan(35)

var thistop = Test.prototype.top()

t.testModuleClass = function() {
    var self = this;
    self.ok(Joose.Module, "The module class is here")

    Module("com.test.module", function () {
        Class("Test1", {
            methods: { world: function () { return "hello" } }
        });
        Class("Test2", {
            methods: { world: function () { return "hello" } }
        })
    })

    self.ok(com.test.module, "There is something in the module spot")
    self.ok(com.test.module.meta, "And is has a meta object")
    self.ok(com.test.module.meta.meta, "And a meta meta object")
    self.ok(com.test.module.meta.meta.isa(Joose.Module), "And it is a Module")
    self.ok(com.test.module.meta.meta.isa(Joose.Module), "And it is a Module")
    self.ok(com.test.module.meta.getName() == "com.test.module", "The name is correct")

    self.ok(com.test.module.Test1, "There is also something in the class spot")
    self.ok(com.test.module.Test1.meta, "and it has a meta object")
    self.ok(com.test.module.Test1.meta.meta.isa(Joose.Class), "it is a class")

    self.ok(com.test.module.Test2, "There is also something in the class spot")
    self.ok(com.test.module.Test2.meta, "and it has a meta object")
    self.ok(com.test.module.Test2.meta.meta.isa(Joose.Class), "it is a class")

    self.ok(com.test.module.Test1.meta.className()  == "com.test.module.Test1", "The class name is correct")
    self.ok(com.test.module.Test2.meta.className() == "com.test.module.Test2", "The class name is correct")

    self.ok(com.test.module.meta.alias, "There is an alias method");
    com.test.module.meta.alias(thistop)
    self.ok(thistop.Test1, "There is something in the expected spot")
    self.ok(thistop.Test1 === com.test.module.Test1, "Class is now global")

    self.ok(new thistop.Test1(), "We can instantiate class")
    var o = new thistop.Test1();
    self.ok(o.world() == "hello", "and call methods on them")

    self.ok(new com.test.module.Test1(), "We can also instantiate the fully qualified name");
    self.ok(new com.test.module.Test1().world() == "hello", "and call methods on them");

    self.lives_ok(function () {com.test.module.meta.alias(thistop)},
        "We can import again")
    self.ok(new thistop.Test1().world() == "hello", "and call methods")

    thistop.Test1 = function() {};
    self.throws_ok(function () {com.test.module.meta.alias(thistop)},
        "here is already something else",
        "Importing fails if there is already something else")

    Module("com.test", function () {
        Class("Test1", {
            methods: { one: function () { return 1 } }
        })
    })

    self.ok(new com.test.Test1(), "we can make modules on a lower hierarchy")

    Module("com.test", function () {
        Class("Test2", {
            methods: { one: function () { return 1 } }
        })
    })

    self.ok(new com.test.Test1(), "We can do declare modules multiple times. The formerly declared class is still there")
    self.ok(new com.test.Test2(), "we can make modules on a lower hierarchy. The new class is here.")

    self.throws_ok(function () {
        Module("Joose.SimpleRequest", function () {
            Class("FooBar", {})
        })
    }, "Trying to setup module", "We cannot put a module in a used spot")

    Module("com.test.module", function (m) {
        self.ok(new m.Test1().world() == "hello", "Module passes the current module to the module creation function")
    })

    self.throws_ok(function () {
        Module("com.test.meta.bla", function () {

        })
    }, "Module names may not include a part called 'meta'.", "meta is not allowed in a module name")

    self.ok(__global__.nomodule, "There is a global module")

    self.ok(__global__.nomodule.meta.meta.isa(Joose.Module), "it is actually a module :)")

    self.ok(Joose.A.exists(__global__.nomodule.meta.getNames(), "Joose.Class"), "Joose.Class is in it")

    self.ok(Joose.Module.getAllModules(), "We can get all modules")
}

return t;
})()
<|endoftext|>


<commit_before>/* jqBootstrapValidation
 * A plugin for automating validation on Twitter Bootstrap formatted forms.
 *
 * v1.3.6
 *
 * License: MIT <http://opensource.org/licenses/mit-license.php> - see LICENSE file
 *
 * http://ReactiveRaven.github.com/jqBootstrapValidation/
 */

(function( $ ){

	var createdElements = [];

	var defaults = {
		options: {
			prependExistingHelpBlock: false,
			sniffHtml: true, // sniff for 'required', 'maxlength', etc
			preventSubmit: true, // stop the form submit event from firing if validation fails
			submitError: false, // function called if there is an error when trying to submit
			submitSuccess: false, // function called just before a successful submit event is sent to the server
            semanticallyStrict: false, // set to true to tidy up generated HTML output
			autoAdd: {
				helpBlocks: true
			},
            filter: function () {
                // return $(this).is(":visible"); // only validate elements you can see
                return true; // validate everything
            }
		},
    methods: {
      init : function( options ) {

        var settings = $.extend(true, {}, defaults);

        settings.options = $.extend(true, settings.options, options);

        var $siblingElements = this;

        var uniqueForms = $.unique(
          $siblingElements.map( function () {
            return $(this).parents("form")[0];
          }).toArray()
        );

        $(uniqueForms).bind("submit", function (e) {
          var $form = $(this);
          var warningsFound = 0;
          var $inputs = $form.find("input,textarea,select").not("[type=submit],[type=image]").filter(settings.options.filter);
          $inputs.trigger("submit.validation").trigger("validationLostFocus.validation");

          $inputs.each(function (i, el) {
            var $this = $(el),
              $controlGroup = $this.parents(".form-group").first();
            if (
              $controlGroup.hasClass("warning")
            ) {
              $controlGroup.removeClass("warning").addClass("error");
              warningsFound++;
            }
          });

          $inputs.trigger("validationLostFocus.validation");

          if (warningsFound) {
            if (settings.options.preventSubmit) {
              e.preventDefault();
            }
            $form.addClass("error");
            if ($.isFunction(settings.options.submitError)) {
              settings.options.submitError($form, e, $inputs.jqBootstrapValidation("collectErrors", true));
            }
          } else {
            $form.removeClass("error");
            if ($.isFunction(settings.options.submitSuccess)) {
              settings.options.submitSuccess($form, e);
            }
          }
        });

        return this.each(function(){

          // Get references to everything we're interested in
          var $this = $(this),
            $controlGroup = $this.parents(".form-group").first(),
            $helpBlock = $controlGroup.find(".help-block").first(),
            $form = $this.parents("form").first(),
            validatorNames = [];

          // create message container if not exists
          if (!$helpBlock.length && settings.options.autoAdd && settings.options.autoAdd.helpBlocks) {
              $helpBlock = $('<div class="help-block" />');
              $controlGroup.find('.controls').append($helpBlock);
							createdElements.push($helpBlock[0]);
          }

          // =============================================================
          //                                     SNIFF HTML FOR VALIDATORS
          // =============================================================

          // *snort sniff snuffle*

          if (settings.options.sniffHtml) {
            var message = "";
            // ---------------------------------------------------------
            //                                                   PATTERN
            // ---------------------------------------------------------
            if ($this.attr("pattern") !== undefined) {
              message = "Not in the expected format<!-- data-validation-pattern-message to override -->";
              if ($this.data("validationPatternMessage")) {
                message = $this.data("validationPatternMessage");
              }
              $this.data("validationPatternMessage", message);
              $this.data("validationPatternRegex", $this.attr("pattern"));
            }
            // ---------------------------------------------------------
            //                                                       MAX
            // ---------------------------------------------------------
            if ($this.attr("max") !== undefined || $this.attr("aria-valuemax") !== undefined) {
              var max = ($this.attr("max") !== undefined ? $this.attr("max") : $this.attr("aria-valuemax"));
              message = "Too high: Maximum of '" + max + "'<!-- data-validation-max-message to override -->";
              if ($this.data("validationMaxMessage")) {
                message = $this.data("validationMaxMessage");
              }
              $this.data("validationMaxMessage", message);
              $this.data("validationMaxMax", max);
            }
            // ---------------------------------------------------------
            //                                                       MIN
            // ---------------------------------------------------------
            if ($this.attr("min") !== undefined || $this.attr("aria-valuemin") !== undefined) {
              var min = ($this.attr("min") !== undefined ? $this.attr("min") : $this.attr("aria-valuemin"));
              message = "Too low: Minimum of '" + min + "'<!-- data-validation-min-message to override -->";
              if ($this.data("validationMinMessage")) {
                message = $this.data("validationMinMessage");
              }
              $this.data("validationMinMessage", message);
              $this.data("validationMinMin", min);
            }
            // ---------------------------------------------------------
            //                                                 MAXLENGTH
            // ---------------------------------------------------------
            if ($this.attr("maxlength") !== undefined) {
              message = "Too long: Maximum of '" + $this.attr("maxlength") + "' characters<!-- data-validation-maxlength-message to override -->";
              if ($this.data("validationMaxlengthMessage")) {
                message = $this.data("validationMaxlengthMessage");
              }
              $this.data("validationMaxlengthMessage", message);
              $this.data("validationMaxlengthMaxlength", $this.attr("maxlength"));
            }
            // ---------------------------------------------------------
            //                                                 MINLENGTH
            // ---------------------------------------------------------
            if ($this.attr("minlength") !== undefined) {
              message = "Too short: Minimum of '" + $this.attr("minlength") + "' characters<!-- data-validation-minlength-message to override -->";
              if ($this.data("validationMinlengthMessage")) {
                message = $this.data("validationMinlengthMessage");
              }
              $this.data("validationMinlengthMessage", message);
              $this.data("validationMinlengthMinlength", $this.attr("minlength"));
            }
            // ---------------------------------------------------------
            //                                                  REQUIRED
            // ---------------------------------------------------------
            if ($this.attr("required") !== undefined || $this.attr("aria-required") !== undefined) {
              message = settings.builtInValidators.required.message;
              if ($this.data("validationRequiredMessage")) {
                message = $this.data("validationRequiredMessage");
              }
              $this.data("validationRequiredMessage", message);
            }
            // ---------------------------------------------------------
            //                                                    NUMBER
            // ---------------------------------------------------------
            if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "number") {
              message = settings.builtInValidators.number.message;
              if ($this.data("validationNumberMessage")) {
                message = $this.data("validationNumberMessage");
              }
              $this.data("validationNumberMessage", message);
            }
            // ---------------------------------------------------------
            //                                                     EMAIL
            // ---------------------------------------------------------
            if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "email") {
              message = "Not a valid email address<!-- data-validator-validemail-message to override -->";
              if ($this.data("validationValidemailMessage")) {
                message = $this.data("validationValidemailMessage");
              } else if ($this.data("validationEmailMessage")) {
                message = $this.data("validationEmailMessage");
              }
              $this.data("validationValidemailMessage", message);
            }
            // ---------------------------------------------------------
            //                                                MINCHECKED
            // ---------------------------------------------------------
            if ($this.attr("minchecked") !== undefined) {
              message = "Not enough options checked; Minimum of '" + $this.attr("minchecked") + "' required<!-- data-validation-minchecked-message to override -->";
              if ($this.data("validationMincheckedMessage")) {
                message = $this.data("validationMincheckedMessage");
              }
              $this.data("validationMincheckedMessage", message);
              $this.data("validationMincheckedMinchecked", $this.attr("minchecked"));
            }
            // ---------------------------------------------------------
            //                                                MAXCHECKED
            // ---------------------------------------------------------
            if ($this.attr("maxchecked") !== undefined) {
              message = "Too many options checked; Maximum of '" + $this.attr("maxchecked") + "' required<!-- data-validation-maxchecked-message to override -->";
              if ($this.data("validationMaxcheckedMessage")) {
                message = $this.data("validationMaxcheckedMessage");
              }
              $this.data("validationMaxcheckedMessage", message);
              $this.data("validationMaxcheckedMaxchecked", $this.attr("maxchecked"));
            }
          }

          // =============================================================
          //                                       COLLECT VALIDATOR NAMES
          // =============================================================

          // Get named validators
          if ($this.data("validation") !== undefined) {
            validatorNames = $this.data("validation").split(",");
          }

          // Get extra ones defined on the element's data attributes
          $.each($this.data(), function (i, el) {
            var parts = i.replace(/([A-Z])/g, ",$1").split(",");
            if (parts[0] === "validation" && parts[1]) {
              validatorNames.push(parts[1]);
            }
          });

          // =============================================================
          //                                     NORMALISE VALIDATOR NAMES
          // =============================================================

          var validatorNamesToInspect = validatorNames;
          var newValidatorNamesToInspect = [];

          do // repeatedly expand 'shortcut' validators into their real validators
          {
            // Uppercase only the first letter of each name
            $.each(validatorNames, function (i, el) {
              validatorNames[i] = formatValidatorName(el);
            });

            // Remove duplicate validator names
            validatorNames = $.unique(validatorNames);

            // Pull out the new validator names from each shortcut
            newValidatorNamesToInspect = [];
            $.each(validatorNamesToInspect, function(i, el) {
              if ($this.data("validation" + el + "Shortcut") !== undefined) {
                // Are these custom validators?
                // Pull them out!
                $.each($this.data("validation" + el + "Shortcut").split(","), function(i2, el2) {
                  newValidatorNamesToInspect.push(el2);
                });
              } else if (settings.builtInValidators[el.toLowerCase()]) {
                // Is this a recognised built-in?
                // Pull it out!
                var validator = settings.builtInValidators[el.toLowerCase()];
                if (validator.type.toLowerCase() === "shortcut") {
                  $.each(validator.shortcut.split(","), function (i, el) {
                    el = formatValidatorName(el);
                    newValidatorNamesToInspect.push(el);
                    validatorNames.push(el);
                  });
                }
              }
            });

            validatorNamesToInspect = newValidatorNamesToInspect;

          } while (validatorNamesToInspect.length > 0)

          // =============================================================
          //                                       SET UP VALIDATOR ARRAYS
          // =============================================================

          var validators = {};

          $.each(validatorNames, function (i, el) {
            // Set up the 'override' message
            var message = $this.data("validation" + el + "Message");
            var hasOverrideMessage = (message !== undefined);
            var foundValidator = false;
            message =
              (
                message
                  ? message
                  : "'" + el + "' validation failed <!-- Add attribute 'data-validation-" + el.toLowerCase() + "-message' to input to change this message -->"
              )
            ;

            $.each(
              settings.validatorTypes,
              function (validatorType, validatorTemplate) {
                if (validators[validatorType] === undefined) {
                  validators[validatorType] = [];
                }
                if (!foundValidator && $this.data("validation" + el + formatValidatorName(validatorTemplate.name)) !== undefined) {
                  validators[validatorType].push(
                    $.extend(
                      true,
                      {
                        name: formatValidatorName(validatorTemplate.name),
                        message: message
                      },
                      validatorTemplate.init($this, el)
                    )
                  );
                  foundValidator = true;
                }
              }
            );

            if (!foundValidator && settings.builtInValidators[el.toLowerCase()]) {

              var validator = $.extend(true, {}, settings.builtInValidators[el.toLowerCase()]);
              if (hasOverrideMessage) {
                validator.message = message;
              }
              var validatorType = validator.type.toLowerCase();

              if (validatorType === "shortcut") {
                foundValidator = true;
              } else {
                $.each(
                  settings.validatorTypes,
                  function (validatorTemplateType, validatorTemplate) {
                    if (validators[validatorTemplateType] === undefined) {
                      validators[validatorTemplateType] = [];
                    }
                    if (!foundValidator && validatorType === validatorTemplateType.toLowerCase()) {
                      $this.data("validation" + el + formatValidatorName(validatorTemplate.name), validator[validatorTemplate.name.toLowerCase()]);
                      validators[validatorType].push(
                        $.extend(
                          validator,
                          validatorTemplate.init($this, el)
                        )
                      );
                      foundValidator = true;
                    }
                  }
                );
              }
            }

            if (! foundValidator) {
              $.error("Cannot find validation info for '" + el + "'");
            }
          });

          // =============================================================
          //                                         STORE FALLBACK VALUES
          // =============================================================

          $helpBlock.data(
            "original-contents",
            (
              $helpBlock.data("original-contents")
                ? $helpBlock.data("original-contents")
                : $helpBlock.html()
            )
          );

          $helpBlock.data(
            "original-role",
            (
              $helpBlock.data("original-role")
                ? $helpBlock.data("original-role")
                : $helpBlock.attr("role")
            )
          );

          $controlGroup.data(
            "original-classes",
            (
              $controlGroup.data("original-clases")
                ? $controlGroup.data("original-classes")
                : $controlGroup.attr("class")
            )
          );

          $this.data(
            "original-aria-invalid",
            (
              $this.data("original-aria-invalid")
                ? $this.data("original-aria-invalid")
                : $this.attr("aria-invalid")
            )
          );

          // =============================================================
          //                                                    VALIDATION
          // =============================================================

          $this.bind(
            "validation.validation",
            function (event, params) {

              var value = getValue($this);

              // Get a list of the errors to apply
              var errorsFound = [];

              $.each(validators, function (validatorType, validatorTypeArray) {
                if (value || value.length || (params && params.includeEmpty) || (!!settings.validatorTypes[validatorType].blockSubmit && params && !!params.submitting)) {
                  $.each(validatorTypeArray, function (i, validator) {
                    if (settings.validatorTypes[validatorType].validate($this, value, validator)) {
                      errorsFound.push(validator.message);
                    }
                  });
                }
              });

              return errorsFound;
            }
          );

          $this.bind(
            "getValidators.validation",
            function () {
              return validators;
            }
          );

          // =============================================================
          //                                             WATCH FOR CHANGES
          // =============================================================
          $this.bind(
            "submit.validation",
            function () {
              return $this.triggerHandler("change.validation", {submitting: true});
            }
          );
          $this.bind(
            [
              "keyup",
              "focus",
              "blur",
              "click",
              "keydown",
              "keypress",
              "change"
            ].join(".validation ") + ".validation",
            function (e, params) {

              var value = getValue($this);

              var errorsFound = [];

              $controlGroup.find("input,textarea,select").each(function (i, el) {
                var oldCount = errorsFound.length;
                $.each($(el).triggerHandler("validation.validation", params), function (j, message) {
                  errorsFound.push(message);
                });
                if (errorsFound.length > oldCount) {
                  $(el).attr("aria-invalid", "true");
                } else {
                  var original = $this.data("original-aria-invalid");
                  $(el).attr("aria-invalid", (original !== undefined ? original : false));
                }
              });

              $form.find("input,select,textarea").not($this).not("[name=\"" + $this.attr("name") + "\"]").trigger("validationLostFocus.validation");

              errorsFound = $.unique(errorsFound.sort());

              // Were there any errors?
              if (errorsFound.length) {
                // Better flag it up as a warning.
                $controlGroup.removeClass("success error").addClass("warning");

                // How many errors did we find?
                if (settings.options.semanticallyStrict && errorsFound.length === 1) {
                  // Only one? Being strict? Just output it.
                  $helpBlock.html(errorsFound[0] +
                    ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" ));
                } else {
                  // Multiple? Being sloppy? Glue them together into an UL.
                  $helpBlock.html("<ul role=\"alert\"><li>" + errorsFound.join("</li><li>") + "</li></ul>" +
                    ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" ));
                }
              } else {
                $controlGroup.removeClass("warning error success");
                if (value.length > 0) {
                  $controlGroup.addClass("success");
                }
                $helpBlock.html($helpBlock.data("original-contents"));
              }

              if (e.type === "blur") {
                $controlGroup.removeClass("success");
              }
            }
          );
          $this.bind("validationLostFocus.validation", function () {
            $controlGroup.removeClass("success");
          });
        });
      },
      destroy : function( ) {

        return this.each(
          function() {

            var
              $this = $(this),
              $controlGroup = $this.parents(".form-group").first(),
              $helpBlock = $controlGroup.find(".help-block").first();

            // remove our events
            $this.unbind('.validation'); // events are namespaced.
            // reset help text
            $helpBlock.html($helpBlock.data("original-contents"));
            // reset classes
            $controlGroup.attr("class", $controlGroup.data("original-classes"));
            // reset aria
            $this.attr("aria-invalid", $this.data("original-aria-invalid"));
            // reset role
            $helpBlock.attr("role", $this.data("original-role"));
						// remove all elements we created
						if (createdElements.indexOf($helpBlock[0]) > -1) {
							$helpBlock.remove();
						}

          }
        );

      },
      collectErrors : function(includeEmpty) {

        var errorMessages = {};
        this.each(function (i, el) {
          var $el = $(el);
          var name = $el.attr("name");
          var errors = $el.triggerHandler("validation.validation", {includeEmpty: true});
          errorMessages[name] = $.extend(true, errors, errorMessages[name]);
        });

        $.each(errorMessages, function (i, el) {
          if (el.length === 0) {
            delete errorMessages[i];
          }
        });

        return errorMessages;

      },
      hasErrors: function() {

        var errorMessages = [];

        this.each(function (i, el) {
          errorMessages = errorMessages.concat(
            $(el).triggerHandler("getValidators.validation") ? $(el).triggerHandler("validation.validation", {submitting: true}) : []
          );
        });

        return (errorMessages.length > 0);
      },
      override : function (newDefaults) {
        defaults = $.extend(true, defaults, newDefaults);
      }
    },
		validatorTypes: {
      callback: {
        name: "callback",
        init: function ($this, name) {
          return {
            validatorName: name,
            callback: $this.data("validation" + name + "Callback"),
            lastValue: $this.val(),
            lastValid: true,
            lastFinished: true
          };
        },
        validate: function ($this, value, validator) {
          if (validator.lastValue === value && validator.lastFinished) {
            return !validator.lastValid;
          }

          if (validator.lastFinished === true)
          {
            validator.lastValue = value;
            validator.lastValid = true;
            validator.lastFinished = false;

            var rrjqbvValidator = validator;
            var rrjqbvThis = $this;
            executeFunctionByName(
              validator.callback,
              window,
              $this,
              value,
              function (data) {
                if (rrjqbvValidator.lastValue === data.value) {
                  rrjqbvValidator.lastValid = data.valid;
                  if (data.message) {
                    rrjqbvValidator.message = data.message;
                  }
                  rrjqbvValidator.lastFinished = true;
                  rrjqbvThis.data("validation" + rrjqbvValidator.validatorName + "Message", rrjqbvValidator.message);
                  // Timeout is set to avoid problems with the events being considered 'already fired'
                  setTimeout(function () {
                    rrjqbvThis.trigger("change.validation");
                  }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
                }
              }
            );
          }

          return false;

        }
      },
      ajax: {
        name: "ajax",
        init: function ($this, name) {
          return {
            validatorName: name,
            url: $this.data("validation" + name + "Ajax"),
            lastValue: $this.val(),
            lastValid: true,
            lastFinished: true
          };
        },
        validate: function ($this, value, validator) {
          if (""+validator.lastValue === ""+value && validator.lastFinished === true) {
            return validator.lastValid === false;
          }

          if (validator.lastFinished === true)
          {
            validator.lastValue = value;
            validator.lastValid = true;
            validator.lastFinished = false;
            $.ajax({
              url: validator.url,
              data: "value=" + value + "&field=" + $this.attr("name"),
              dataType: "json",
              success: function (data) {
                if (""+validator.lastValue === ""+data.value) {
                  validator.lastValid = !!(data.valid);
                  if (data.message) {
                    validator.message = data.message;
                  }
                  validator.lastFinished = true;
                  $this.data("validation" + validator.validatorName + "Message", validator.message);
                  // Timeout is set to avoid problems with the events being considered 'already fired'
                  setTimeout(function () {
                    $this.trigger("change.validation");
                  }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
                }
              },
              failure: function () {
                validator.lastValid = true;
                validator.message = "ajax call failed";
                validator.lastFinished = true;
                $this.data("validation" + validator.validatorName + "Message", validator.message);
                // Timeout is set to avoid problems with the events being considered 'already fired'
                setTimeout(function () {
                  $this.trigger("change.validation");
                }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
              }
            });
          }

          return false;

        }
      },
			regex: {
				name: "regex",
				init: function ($this, name) {
					return {regex: regexFromString($this.data("validation" + name + "Regex"))};
				},
				validate: function ($this, value, validator) {
					return (!validator.regex.test(value) && ! validator.negative)
						|| (validator.regex.test(value) && validator.negative);
				}
			},
			required: {
				name: "required",
				init: function ($this, name) {
					return {};
				},
				validate: function ($this, value, validator) {
					return !!(value.length === 0  && ! validator.negative)
						|| !!(value.length > 0 && validator.negative);
				},
        blockSubmit: true
			},
			match: {
				name: "match",
				init: function ($this, name) {
					var element = $this.parents("form").first().find("[name=\"" + $this.data("validation" + name + "Match") + "\"]").first();
					element.bind("validation.validation", function () {
						$this.trigger("change.validation", {submitting: true});
					});
					return {"element": element};
				},
				validate: function ($this, value, validator) {
					return (value !== validator.element.val() && ! validator.negative)
						|| (value === validator.element.val() && validator.negative);
				},
        blockSubmit: true
			},
			max: {
				name: "max",
				init: function ($this, name) {
					return {max: $this.data("validation" + name + "Max")};
				},
				validate: function ($this, value, validator) {
					return (parseFloat(value, 10) > parseFloat(validator.max, 10) && ! validator.negative)
						|| (parseFloat(value, 10) <= parseFloat(validator.max, 10) && validator.negative);
				}
			},
			min: {
				name: "min",
				init: function ($this, name) {
					return {min: $this.data("validation" + name + "Min")};
				},
				validate: function ($this, value, validator) {
					return (parseFloat(value) < parseFloat(validator.min) && ! validator.negative)
						|| (parseFloat(value) >= parseFloat(validator.min) && validator.negative);
				}
			},
			maxlength: {
				name: "maxlength",
				init: function ($this, name) {
					return {maxlength: $this.data("validation" + name + "Maxlength")};
				},
				validate: function ($this, value, validator) {
					return ((value.length > validator.maxlength) && ! validator.negative)
						|| ((value.length <= validator.maxlength) && validator.negative);
				}
			},
			minlength: {
				name: "minlength",
				init: function ($this, name) {
					return {minlength: $this.data("validation" + name + "Minlength")};
				},
				validate: function ($this, value, validator) {
					return ((value.length < validator.minlength) && ! validator.negative)
						|| ((value.length >= validator.minlength) && validator.negative);
				}
			},
			maxchecked: {
				name: "maxchecked",
				init: function ($this, name) {
					var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]");
					elements.bind("click.validation", function () {
						$this.trigger("change.validation", {includeEmpty: true});
					});
					return {maxchecked: $this.data("validation" + name + "Maxchecked"), elements: elements};
				},
				validate: function ($this, value, validator) {
					return (validator.elements.filter(":checked").length > validator.maxchecked && ! validator.negative)
						|| (validator.elements.filter(":checked").length <= validator.maxchecked && validator.negative);
				},
        blockSubmit: true
			},
			minchecked: {
				name: "minchecked",
				init: function ($this, name) {
					var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]");
					elements.bind("click.validation", function () {
						$this.trigger("change.validation", {includeEmpty: true});
					});
					return {minchecked: $this.data("validation" + name + "Minchecked"), elements: elements};
				},
				validate: function ($this, value, validator) {
					return (validator.elements.filter(":checked").length < validator.minchecked && ! validator.negative)
						|| (validator.elements.filter(":checked").length >= validator.minchecked && validator.negative);
				},
        blockSubmit: true
			}
		},
		builtInValidators: {
			email: {
				name: "Email",
				type: "shortcut",
				shortcut: "validemail"
			},
			validemail: {
				name: "Validemail",
				type: "regex",
				regex: "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\.[A-Za-z]{2,4}",
				message: "Not a valid email address<!-- data-validator-validemail-message to override -->"
			},
			passwordagain: {
				name: "Passwordagain",
				type: "match",
				match: "password",
				message: "Does not match the given password<!-- data-validator-paswordagain-message to override -->"
			},
			positive: {
				name: "Positive",
				type: "shortcut",
				shortcut: "number,positivenumber"
			},
			negative: {
				name: "Negative",
				type: "shortcut",
				shortcut: "number,negativenumber"
			},
			number: {
				name: "Number",
				type: "regex",
				regex: "([+-]?\\\d+(\\\.\\\d*)?([eE][+-]?[0-9]+)?)?",
				message: "Must be a number<!-- data-validator-number-message to override -->"
			},
			integer: {
				name: "Integer",
				type: "regex",
				regex: "[+-]?\\\d+",
				message: "No decimal places allowed<!-- data-validator-integer-message to override -->"
			},
			positivenumber: {
				name: "Positivenumber",
				type: "min",
				min: 0,
				message: "Must be a positive number<!-- data-validator-positivenumber-message to override -->"
			},
			negativenumber: {
				name: "Negativenumber",
				type: "max",
				max: 0,
				message: "Must be a negative number<!-- data-validator-negativenumber-message to override -->"
			},
			required: {
				name: "Required",
				type: "required",
				message: "This is required<!-- data-validator-required-message to override -->"
			},
			checkone: {
				name: "Checkone",
				type: "minchecked",
				minchecked: 1,
				message: "Check at least one option<!-- data-validation-checkone-message to override -->"
			}
		}
	};

	var formatValidatorName = function (name) {
		return name
			.toLowerCase()
			.replace(
				/(^|\s)([a-z])/g ,
				function(m,p1,p2) {
					return p1+p2.toUpperCase();
				}
			)
		;
	};

	var getValue = function ($this) {
		// Extract the value we're talking about
		var value = $this.val();
		var type = $this.attr("type");
		if (type === "checkbox") {
			value = ($this.is(":checked") ? value : "");
		}
		if (type === "radio") {
			value = ($('input[name="' + $this.attr("name") + '"]:checked').length > 0 ? value : "");
		}
		return value;
	};

  function regexFromString(inputstring) {
		return new RegExp("^" + inputstring + "$");
	}

  /**
   * Thanks to Jason Bunting via StackOverflow.com
   *
   * http://stackoverflow.com/questions/359788/how-to-execute-a-javascript-function-when-i-have-its-name-as-a-string#answer-359910
   * Short link: http://tinyurl.com/executeFunctionByName
  **/
  function executeFunctionByName(functionName, context /*, args*/) {
    var args = Array.prototype.slice.call(arguments).splice(2);
    var namespaces = functionName.split(".");
    var func = namespaces.pop();
    for(var i = 0; i < namespaces.length; i++) {
      context = context[namespaces[i]];
    }
    return context[func].apply(this, args);
  }

	$.fn.jqBootstrapValidation = function( method ) {

		if ( defaults.methods[method] ) {
			return defaults.methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
		} else if ( typeof method === 'object' || ! method ) {
			return defaults.methods.init.apply( this, arguments );
		} else {
		$.error( 'Method ' +  method + ' does not exist on jQuery.jqBootstrapValidation' );
			return null;
		}

	};

  $.jqBootstrapValidation = function (options) {
    $(":input").not("[type=image],[type=submit]").jqBootstrapValidation.apply(this,arguments);
  };

})( jQuery );
<commit_msg>change<commit_after><|endoftext|>