' +
+ '
.' +
+ '
.' +
+ '
.' +
+ '').find(".run");
+ current.log = current.scenario.append('
').find(".log");
+ current.run.find(".name").text(name);
+ this.tests.push(current);
+ this.console.append(current.scenario);
+ },
+ end:function(name){
+ var current = this.current;
+ var run = current.run;
+ this.current = null;
+ current.end = new Date().getTime();
+ current.time = current.end - current.start;
+ run.find(".time").text(current.time);
+ run.find(".state").text(current.error ? "FAIL" : "PASS");
+ run.addClass(current.error ? "fail" : "pass");
+ if (current.error)
+ run.find(".run").append('
').text(current.error);
+ current.scenario.find(".log").hide();
+ },
+ log:function(level) {
+ var buf = [];
+ for ( var i = 1; i < arguments.length; i++) {
+ var arg = arguments[i];
+ buf.push(typeof arg == "string" ?arg:nglr.toJson(arg));
+ }
+ var log = jQuery('
');
+ log.text(buf.join(" "));
+ this.current.log.append(log);
+ this.console.scrollTop(this.console[0].scrollHeight);
+ if (level == "error")
+ this.current.error = buf.join(" ");
+ }
+};
+
+nglr.test.Scenario = function(name, scenario){
+ this.name = name;
+ this.scenario = scenario;
+};
+nglr.test.Scenario.prototype = {
+ run:function(runner, callback) {
+ var self = this;
+ _.stepper(this.scenario, function(next, steps, name){
+ if (name.charAt(0) == '$') {
+ next();
+ } else {
+ runner.start(self.name + "::" + name);
+ var allSteps = (self.scenario.$before||[]).concat(steps);
+ _.stepper(allSteps, function(next, step){
+ self.executeStep(runner, step, next);
+ }, function(){
+ runner.end();
+ next();
+ });
+ }
+ }, callback);
+ },
+ verb:function(step){
+ var fn = null;
+ if (!step) fn = function (){ throw "Step is null!"; }
+ else if (step.Given) fn = angular.test.GIVEN[step.Given];
+ else if (step.When) fn = angular.test.WHEN[step.When];
+ else if (step.Then) fn = angular.test.THEN[step.Then];
+ return fn || function (){
+ throw "ERROR: Need Given/When/Then got: " + nglr.toJson(step);
+ };
+ },
+ context: function(runner) {
+ var frame = runner.frame;
+ var window = frame[0].contentWindow;
+ var document;
+ if (window.jQuery)
+ document = window.jQuery(window.document);
+ var context = {
+ frame:frame,
+ window:window,
+ log:_.bind(runner.log, runner, "info"),
+ document:document,
+ assert:function(element, path){
+ if (element.size() != 1) {
+ throw "Expected to find '1' found '"+
+ element.size()+"' for '"+path+"'.";
+ }
+ return element;
+ },
+ element:function(path){
+ var exp = path.replace("{{","[ng-bind=").replace("}}", "]");
+ var element = document.find(exp);
+ return context.assert(element, path);
+ }
+ };
+ return context;
+ },
+ executeStep:function(runner, step, callback) {
+ if (!step) {
+ callback();
+ return;
+ }
+ runner.log("info", nglr.toJson(step));
+ var fn = this.verb(step);
+ var context = this.context(runner);
+ _.extend(context, step);
+ try {
+ (fn.call(context)||function(c){c();})(callback);
+ } catch (e) {
+ runner.log("error", "ERROR: " + nglr.toJson(e));
+ }
+ }
+};
diff --git a/src/test/Steps.js b/src/test/Steps.js
new file mode 100644
index 00000000..af4b84d6
--- /dev/null
+++ b/src/test/Steps.js
@@ -0,0 +1,57 @@
+angular.test.GIVEN = {
+ browser:function(){
+ var self = this;
+ if (jQuery.browser.safari && this.frame.attr('src') == this.at) {
+ this.window.location.reload();
+ } else {
+ this.frame.attr('src', this.at);
+ }
+ return function(done){
+ self.frame.load(function(){
+ self.frame.unbind();
+ done();
+ });
+ };
+ },
+ dataset:function(){
+ this.frame.name="$DATASET:" + nglr.toJson({dataset:this.dataset});
+ }
+};
+angular.test.WHEN = {
+ enter:function(){
+ var element = this.element(this.at);
+ element.attr('value', this.text);
+ element.change();
+ },
+ click:function(){
+ var element = this.element(this.at);
+ var input = element[0];
+ // emulate the browser behavior which causes it
+ // to be overridden at the end.
+ var checked = input.checked = !input.checked;
+ element.click();
+ input.checked = checked;
+ },
+ select:function(){
+ var element = this.element(this.at);
+ var path = "option[value=" + this.option + "]";
+ var option = this.assert(element.find(path));
+ option[0].selected = !option[0].selected;
+ element.change();
+ }
+};
+angular.test.THEN = {
+ text:function(){
+ var element = this.element(this.at);
+ if (typeof this.should_be != undefined ) {
+ var should_be = this.should_be;
+ if (_.isArray(this.should_be))
+ should_be = JSON.stringify(should_be);
+ if (element.text() != should_be)
+ throw "Expected " + should_be +
+ " but was " + element.text() + ".";
+ }
+ },
+ drainRequestQueue:function(){
+ }
+};
diff --git a/src/test/_namespace.js b/src/test/_namespace.js
new file mode 100644
index 00000000..78f430f1
--- /dev/null
+++ b/src/test/_namespace.js
@@ -0,0 +1,5 @@
+if (!angular) angular = {};
+if (!angular.test) angular.test = {};
+if (!angular.test.GIVEN) angular.test.GIVEN = {};
+if (!angular.test.WHEN) angular.test.WHEN = {};
+if (!angular.test.THEN) angular.test.THEN = {};
--
cgit v1.2.3
From 214c142d9de60a7f53d8c7ada2812ffff4837e0f Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Fri, 8 Jan 2010 16:04:35 -0800
Subject: created a way to init the code without autobootstrap
---
src/Binder.js | 17 +++++++++++++----
src/Loader.js | 19 +++++++++++++++++--
src/angular-bootstrap.js | 49 ++++++++++++++++++++++--------------------------
src/test/Runner.js | 18 ++++++++++--------
4 files changed, 62 insertions(+), 41 deletions(-)
(limited to 'src')
diff --git a/src/Binder.js b/src/Binder.js
index 86e99fb8..8b4d27fb 100644
--- a/src/Binder.js
+++ b/src/Binder.js
@@ -103,8 +103,17 @@ nglr.Binder.prototype.updateView = function() {
_.each(this.updateListeners, function(fn) {fn();});
};
+nglr.Binder.prototype.docFindWithSelf = function(exp){
+ var doc = jQuery(this.doc);
+ var selection = doc.find(exp);
+ if (doc.is(exp)){
+ selection = selection.andSelf();
+ }
+ return selection;
+};
+
nglr.Binder.prototype.executeInit = function() {
- jQuery("[ng-init]", this.doc).each(function() {
+ this.docFindWithSelf("[ng-init]").each(function() {
var jThis = jQuery(this);
var scope = jThis.scope();
try {
@@ -116,7 +125,7 @@ nglr.Binder.prototype.executeInit = function() {
};
nglr.Binder.prototype.entity = function (scope) {
- jQuery("[ng-entity]", this.doc).attr("ng-watch", function() {
+ this.docFindWithSelf("[ng-entity]").attr("ng-watch", function() {
try {
var jNode = jQuery(this);
var decl = scope.entity(jNode.attr("ng-entity"));
@@ -131,12 +140,12 @@ nglr.Binder.prototype.compile = function() {
var jNode = jQuery(this.doc);
var self = this;
if (this.config.autoSubmit) {
- var submits = jQuery(":submit", this.doc).not("[ng-action]");
+ var submits = this.docFindWithSelf(":submit").not("[ng-action]");
submits.attr("ng-action", "$save()");
submits.not(":disabled").not("ng-bind-attr").attr("ng-bind-attr", '{disabled:"{{$invalidWidgets}}"}');
}
this.precompile(this.doc)(this.doc, jNode.scope(), "");
- jQuery("a[ng-action]", this.doc).live('click', function (event) {
+ this.docFindWithSelf("a[ng-action]").live('click', function (event) {
var jNode = jQuery(this);
try {
jNode.scope().eval(jNode.attr('ng-action'));
diff --git a/src/Loader.js b/src/Loader.js
index fdcfa3cc..f7482d24 100644
--- a/src/Loader.js
+++ b/src/Loader.js
@@ -166,7 +166,6 @@ nglr.Loader.prototype.load = function() {
this.loadCss('/stylesheets/jquery-ui/smoothness/jquery-ui-1.7.1.css');
this.loadCss('/stylesheets/nglr.css');
console.log("Server: " + this.config.server);
- jQuery.noConflict();
nglr.msie = jQuery.browser.msie;
this.configureJQueryPlugins();
this.computeConfiguration();
@@ -201,7 +200,7 @@ nglr.Loader.prototype.uid = function() {
nglr.Loader.prototype.computeConfiguration = function() {
var config = this.config;
if (!config.database) {
- var match = config.server.match(/https?:\/\/([\w]*)/)
+ var match = config.server.match(/https?:\/\/([\w]*)/);
config.database = match ? match[1] : "$MEMORY";
}
};
@@ -387,3 +386,19 @@ nglr.UrlWatcher.prototype.setUrl = function(url) {
nglr.UrlWatcher.prototype.getUrl = function() {
return window.location.href;
};
+
+window['angularFactory'] = function(config) {
+ var defaults = {
+ server: ""
+ };
+ //todo: don't load stylesheet by default
+ //todo: don't start watcher
+ function compile(root){
+ var loader = new nglr.Loader(root, jQuery("head"), _(defaults).extend(config));
+ loader.load();
+ return jQuery(root).scope();
+ };
+ return {
+ compile:compile
+ };
+};
diff --git a/src/angular-bootstrap.js b/src/angular-bootstrap.js
index b7ae6a38..8ac4f9f3 100644
--- a/src/angular-bootstrap.js
+++ b/src/angular-bootstrap.js
@@ -39,25 +39,25 @@
};
if (scriptConfig.autoLoadDependencies) {
- addScript("/javascripts/webtoolkit.base64.js");
- addScript("/javascripts/swfobject.js");
- addScript("/javascripts/jQuery/jquery-1.3.2.js");
- addScript("/javascripts/jQuery/jquery-ui-1.7.1.custom.min.js");
- addScript("/javascripts/underscore/underscore.js");
- addScript("/javascripts/nglr/Loader.js");
- addScript("/javascripts/nglr/API.js");
- addScript("/javascripts/nglr/Binder.js");
- addScript("/javascripts/nglr/ControlBar.js");
- addScript("/javascripts/nglr/DataStore.js");
- addScript("/javascripts/nglr/Filters.js");
- addScript("/javascripts/nglr/JSON.js");
- addScript("/javascripts/nglr/Model.js");
- addScript("/javascripts/nglr/Parser.js");
- addScript("/javascripts/nglr/Scope.js");
- addScript("/javascripts/nglr/Server.js");
- addScript("/javascripts/nglr/Users.js");
- addScript("/javascripts/nglr/Validators.js");
- addScript("/javascripts/nglr/Widgets.js");
+ addScript("/../lib/webtoolkit/webtoolkit.base64.js");
+ addScript("/../lib/swfobject/swfobject.js");
+ addScript("/../lib/jquery/jquery-1.3.2.js");
+ addScript("/../lib/jquery/jquery-ui-1.7.1.custom.min.js");
+ addScript("/../lib/underscore/underscore.js");
+ addScript("/Loader.js");
+ addScript("/API.js");
+ addScript("/Binder.js");
+ addScript("/ControlBar.js");
+ addScript("/DataStore.js");
+ addScript("/Filters.js");
+ addScript("/JSON.js");
+ addScript("/Model.js");
+ addScript("/Parser.js");
+ addScript("/Scope.js");
+ addScript("/Server.js");
+ addScript("/Users.js");
+ addScript("/Validators.js");
+ addScript("/Widgets.js");
} else {
addScript("/ajax/libs/swfobject/2.2/swfobject.js", "http://ajax.googleapis.com");
addScript("/ajax/libs/jquery/1.3.2/jquery.min.js", "http://ajax.googleapis.com");
@@ -65,12 +65,6 @@
}
window.onload = function() {
- window.angular.init = function(root, config){
- var cnfgMerged = _.clone(scriptConfig||{});
- _.extend(cnfgMerged, config);
- new nglr.Loader(root, jQuery("head"), cnfgMerged).load();
- };
-
var doc = window.document;
if (scriptConfig.bindRootId) {
doc = null;
@@ -86,12 +80,13 @@
doc = window.document.getElementById(id);
}
}
+ var angular = window.angularFactory(scriptConfig);
if (scriptConfig.autoBind && doc) {
- window.angular.init(doc);
+ window.angularScope = angular.compile(doc);
}
if (typeof previousOnLoad === 'function') {
try {
- previousOnLoad.apply(this, arguments);
+ previousOnLoad.apply(this, arguments);
} catch (e) {}
}
};
diff --git a/src/test/Runner.js b/src/test/Runner.js
index 478ef73e..c7dd431a 100644
--- a/src/test/Runner.js
+++ b/src/test/Runner.js
@@ -1,3 +1,5 @@
+if (!nglr.test) nglr.test = {};
+
nglr.test.ScenarioRunner = function(scenarios, body) {
this.scenarios = scenarios;
this.body = body;
@@ -46,10 +48,10 @@ nglr.test.Runner.prototype = {
scenario:jQuery('
')
};
current.run = current.scenario.append(
- '
' +
- '
.' +
- '
.' +
- '
.' +
+ '
' +
+ '
.' +
+ '
.' +
+ '
.' +
'').find(".run");
current.log = current.scenario.append('
').find(".log");
current.run.find(".name").text(name);
@@ -79,7 +81,7 @@ nglr.test.Runner.prototype = {
log.text(buf.join(" "));
this.current.log.append(log);
this.console.scrollTop(this.console[0].scrollHeight);
- if (level == "error")
+ if (level == "error")
this.current.error = buf.join(" ");
}
};
@@ -114,16 +116,16 @@ nglr.test.Scenario.prototype = {
else if (step.Then) fn = angular.test.THEN[step.Then];
return fn || function (){
throw "ERROR: Need Given/When/Then got: " + nglr.toJson(step);
- };
+ };
},
context: function(runner) {
var frame = runner.frame;
var window = frame[0].contentWindow;
var document;
- if (window.jQuery)
+ if (window.jQuery)
document = window.jQuery(window.document);
var context = {
- frame:frame,
+ frame:frame,
window:window,
log:_.bind(runner.log, runner, "info"),
document:document,
--
cgit v1.2.3
From eb9e66f4804cf417ce142e5515b039db73d31144 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Sat, 9 Jan 2010 13:21:24 -0800
Subject: cleanup
---
src/Loader.js | 1 +
1 file changed, 1 insertion(+)
(limited to 'src')
diff --git a/src/Loader.js b/src/Loader.js
index f7482d24..5240944c 100644
--- a/src/Loader.js
+++ b/src/Loader.js
@@ -402,3 +402,4 @@ window['angularFactory'] = function(config) {
compile:compile
};
};
+
--
cgit v1.2.3
From 88eca572fdc7f68a7f384b612052c49de00df433 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Sat, 9 Jan 2010 13:43:16 -0800
Subject: change bootstrap to angular.compile
---
src/Loader.js | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
(limited to 'src')
diff --git a/src/Loader.js b/src/Loader.js
index 5240944c..eae6e4f5 100644
--- a/src/Loader.js
+++ b/src/Loader.js
@@ -387,19 +387,15 @@ nglr.UrlWatcher.prototype.getUrl = function() {
return window.location.href;
};
-window['angularFactory'] = function(config) {
+angular['compile'] = function(root, config) {
+ config = config || {};
var defaults = {
server: ""
};
//todo: don't load stylesheet by default
//todo: don't start watcher
- function compile(root){
- var loader = new nglr.Loader(root, jQuery("head"), _(defaults).extend(config));
- loader.load();
- return jQuery(root).scope();
- };
- return {
- compile:compile
- };
+ var loader = new nglr.Loader(root, jQuery("head"), _(defaults).extend(config));
+ loader.load();
+ return jQuery(root).scope();
};
--
cgit v1.2.3
From 9b9a0dadcce82ae42ac09ad396d647739af20a06 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Sat, 9 Jan 2010 15:02:43 -0800
Subject: removed nglr namespace
---
src/API.js | 8 +-
src/Binder.js | 106 +++----
src/ControlBar.js | 22 +-
src/DataStore.js | 72 ++---
src/Filters.js | 8 +-
src/JSON.js | 20 +-
src/Loader.js | 145 ++++-----
src/Model.js | 26 +-
src/Parser.js | 116 +++----
src/Scope.js | 62 ++--
src/Server.js | 32 +-
src/Users.js | 8 +-
src/Validators.js | 2 +-
src/Widgets.js | 244 +++++++--------
src/Widgets.js.orig | 764 -----------------------------------------------
src/XSitePost.js | 100 -------
src/angular-bootstrap.js | 3 +-
src/angular.prefix | 2 +
src/angular.suffix | 1 +
src/test/Runner.js | 26 +-
src/test/Steps.js | 2 +-
21 files changed, 455 insertions(+), 1314 deletions(-)
delete mode 100644 src/Widgets.js.orig
delete mode 100644 src/XSitePost.js
create mode 100644 src/angular.prefix
create mode 100644 src/angular.suffix
(limited to 'src')
diff --git a/src/API.js b/src/API.js
index c51fe01d..6fb6e8fc 100644
--- a/src/API.js
+++ b/src/API.js
@@ -66,7 +66,7 @@ angular.Array = {
}
return true;
};
- var getter = nglr.Scope.getter;
+ var getter = Scope.getter;
var search = function(obj, text){
if (text.charAt(0) === '!') {
return !search(obj, text.substr(1));
@@ -147,7 +147,7 @@ angular.Array = {
},
orderBy:function(array, expression, descend) {
function reverse(comp, descending) {
- return nglr.toBoolean(descending) ?
+ return toBoolean(descending) ?
function(a,b){return comp(b,a);} : comp;
}
function compare(v1, v2){
@@ -224,7 +224,7 @@ angular.Array = {
value = {};
array[index] = value;
}
- nglr.merge(mergeValue, value);
+ merge(mergeValue, value);
return array;
}
};
@@ -281,7 +281,7 @@ angular.Function = {
if (_.isFunction(expression)){
return expression;
} else if (expression){
- var scope = new nglr.Scope();
+ var scope = new Scope();
return function($) {
scope.state = $;
return scope.eval(expression);
diff --git a/src/Binder.js b/src/Binder.js
index 8b4d27fb..3589cb88 100644
--- a/src/Binder.js
+++ b/src/Binder.js
@@ -1,5 +1,5 @@
// Copyright (C) 2009 BRAT Tech LLC
-nglr.Binder = function(doc, widgetFactory, urlWatcher, config) {
+Binder = function(doc, widgetFactory, urlWatcher, config) {
this.doc = doc;
this.urlWatcher = urlWatcher;
this.anchor = {};
@@ -8,7 +8,7 @@ nglr.Binder = function(doc, widgetFactory, urlWatcher, config) {
this.updateListeners = [];
};
-nglr.Binder.parseBindings = function(string) {
+Binder.parseBindings = function(string) {
var results = [];
var lastIndex = 0;
var index;
@@ -28,18 +28,18 @@ nglr.Binder.parseBindings = function(string) {
return results.length === 0 ? [ string ] : results;
};
-nglr.Binder.hasBinding = function(string) {
- var bindings = nglr.Binder.parseBindings(string);
- return bindings.length > 1 || nglr.Binder.binding(bindings[0]) !== null;
+Binder.hasBinding = function(string) {
+ var bindings = Binder.parseBindings(string);
+ return bindings.length > 1 || Binder.binding(bindings[0]) !== null;
};
-nglr.Binder.binding = function(string) {
+Binder.binding = function(string) {
var binding = string.replace(/\n/gm, ' ').match(/^\{\{(.*)\}\}$/);
return binding ? binding[1] : null;
};
-nglr.Binder.prototype.parseQueryString = function(query) {
+Binder.prototype.parseQueryString = function(query) {
var params = {};
query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,
function (match, left, right) {
@@ -48,7 +48,7 @@ nglr.Binder.prototype.parseQueryString = function(query) {
return params;
};
-nglr.Binder.prototype.parseAnchor = function(url) {
+Binder.prototype.parseAnchor = function(url) {
var self = this;
url = url || this.urlWatcher.getUrl();
@@ -65,13 +65,13 @@ nglr.Binder.prototype.parseAnchor = function(url) {
});
};
-nglr.Binder.prototype.onUrlChange = function (url) {
+Binder.prototype.onUrlChange = function (url) {
console.log("URL change detected", url);
this.parseAnchor(url);
this.updateView();
};
-nglr.Binder.prototype.updateAnchor = function() {
+Binder.prototype.updateAnchor = function() {
var url = this.urlWatcher.getUrl();
var anchorIndex = url.indexOf('#');
if (anchorIndex > -1)
@@ -93,7 +93,7 @@ nglr.Binder.prototype.updateAnchor = function() {
return url;
};
-nglr.Binder.prototype.updateView = function() {
+Binder.prototype.updateView = function() {
var start = new Date().getTime();
var scope = jQuery(this.doc).scope();
scope.set("$invalidWidgets", []);
@@ -103,7 +103,7 @@ nglr.Binder.prototype.updateView = function() {
_.each(this.updateListeners, function(fn) {fn();});
};
-nglr.Binder.prototype.docFindWithSelf = function(exp){
+Binder.prototype.docFindWithSelf = function(exp){
var doc = jQuery(this.doc);
var selection = doc.find(exp);
if (doc.is(exp)){
@@ -112,31 +112,31 @@ nglr.Binder.prototype.docFindWithSelf = function(exp){
return selection;
};
-nglr.Binder.prototype.executeInit = function() {
+Binder.prototype.executeInit = function() {
this.docFindWithSelf("[ng-init]").each(function() {
var jThis = jQuery(this);
var scope = jThis.scope();
try {
scope.eval(jThis.attr('ng-init'));
} catch (e) {
- nglr.alert("EVAL ERROR:\n" + jThis.attr('ng-init') + '\n' + nglr.toJson(e, true));
+ alert("EVAL ERROR:\n" + jThis.attr('ng-init') + '\n' + toJson(e, true));
}
});
};
-nglr.Binder.prototype.entity = function (scope) {
+Binder.prototype.entity = function (scope) {
this.docFindWithSelf("[ng-entity]").attr("ng-watch", function() {
try {
var jNode = jQuery(this);
var decl = scope.entity(jNode.attr("ng-entity"));
return decl + (jNode.attr('ng-watch') || "");
} catch (e) {
- nglr.alert(e);
+ alert(e);
}
});
};
-nglr.Binder.prototype.compile = function() {
+Binder.prototype.compile = function() {
var jNode = jQuery(this.doc);
var self = this;
if (this.config.autoSubmit) {
@@ -153,37 +153,37 @@ nglr.Binder.prototype.compile = function() {
jNode.removeClass("ng-exception");
} catch (e) {
jNode.addClass("ng-exception");
- jNode.attr('ng-error', nglr.toJson(e, true));
+ jNode.attr('ng-error', toJson(e, true));
}
self.updateView();
return false;
});
};
-nglr.Binder.prototype.translateBinding = function(node, parentPath, factories) {
+Binder.prototype.translateBinding = function(node, parentPath, factories) {
var path = parentPath.concat();
var offset = path.pop();
- var parts = nglr.Binder.parseBindings(node.nodeValue);
- if (parts.length > 1 || nglr.Binder.binding(parts[0])) {
+ var parts = Binder.parseBindings(node.nodeValue);
+ if (parts.length > 1 || Binder.binding(parts[0])) {
var parent = node.parentNode;
- if (nglr.isLeafNode(parent)) {
+ if (isLeafNode(parent)) {
parent.setAttribute('ng-bind-template', node.nodeValue);
factories.push({path:path, fn:function(node, scope, prefix) {
- return new nglr.BindUpdater(node, node.getAttribute('ng-bind-template'));
+ return new BindUpdater(node, node.getAttribute('ng-bind-template'));
}});
} else {
for (var i = 0; i < parts.length; i++) {
var part = parts[i];
- var binding = nglr.Binder.binding(part);
+ var binding = Binder.binding(part);
var newNode;
if (binding) {
newNode = document.createElement("span");
var jNewNode = jQuery(newNode);
jNewNode.attr("ng-bind", binding);
if (i === 0) {
- factories.push({path:path.concat(offset + i), fn:nglr.Binder.prototype.ng_bind});
+ factories.push({path:path.concat(offset + i), fn:Binder.prototype.ng_bind});
}
- } else if (nglr.msie && part.charAt(0) == ' ') {
+ } else if (msie && part.charAt(0) == ' ') {
newNode = document.createElement("span");
newNode.innerHTML = ' ' + part.substring(1);
} else {
@@ -196,7 +196,7 @@ nglr.Binder.prototype.translateBinding = function(node, parentPath, factories) {
}
};
-nglr.Binder.prototype.precompile = function(root) {
+Binder.prototype.precompile = function(root) {
var factories = [];
this.precompileNode(root, [], factories);
return function (template, scope, prefix) {
@@ -211,13 +211,13 @@ nglr.Binder.prototype.precompile = function(root) {
try {
scope.addWidget(factory.fn(node, scope, prefix));
} catch (e) {
- nglr.alert(e);
+ alert(e);
}
}
};
};
-nglr.Binder.prototype.precompileNode = function(node, path, factories) {
+Binder.prototype.precompileNode = function(node, path, factories) {
var nodeType = node.nodeType;
if (nodeType == Node.TEXT_NODE) {
this.translateBinding(node, path, factories);
@@ -234,19 +234,19 @@ nglr.Binder.prototype.precompileNode = function(node, path, factories) {
if (attributes) {
var bindings = node.getAttribute('ng-bind-attr');
node.removeAttribute('ng-bind-attr');
- bindings = bindings ? nglr.fromJson(bindings) : {};
+ bindings = bindings ? fromJson(bindings) : {};
var attrLen = attributes.length;
for (var i = 0; i < attrLen; i++) {
var attr = attributes[i];
var attrName = attr.name;
// http://www.glennjones.net/Post/809/getAttributehrefbug.htm
- var attrValue = nglr.msie && attrName == 'href' ?
+ var attrValue = msie && attrName == 'href' ?
decodeURI(node.getAttribute(attrName, 2)) : attr.value;
- if (nglr.Binder.hasBinding(attrValue)) {
+ if (Binder.hasBinding(attrValue)) {
bindings[attrName] = attrValue;
}
}
- var json = nglr.toJson(bindings);
+ var json = toJson(bindings);
if (json.length > 2) {
node.setAttribute("ng-bind-attr", json);
}
@@ -270,7 +270,7 @@ nglr.Binder.prototype.precompileNode = function(node, path, factories) {
return clone;
};
factories.push({path:path, fn:function(node, scope, prefix) {
- return new nglr.RepeaterUpdater(jQuery(node), repeaterExpression, template, prefix);
+ return new RepeaterUpdater(jQuery(node), repeaterExpression, template, prefix);
}});
return;
}
@@ -309,42 +309,42 @@ nglr.Binder.prototype.precompileNode = function(node, path, factories) {
}
};
-nglr.Binder.prototype.ng_eval = function(node) {
- return new nglr.EvalUpdater(node, node.getAttribute('ng-eval'));
+Binder.prototype.ng_eval = function(node) {
+ return new EvalUpdater(node, node.getAttribute('ng-eval'));
};
-nglr.Binder.prototype.ng_bind = function(node) {
- return new nglr.BindUpdater(node, "{{" + node.getAttribute('ng-bind') + "}}");
+Binder.prototype.ng_bind = function(node) {
+ return new BindUpdater(node, "{{" + node.getAttribute('ng-bind') + "}}");
};
-nglr.Binder.prototype.ng_bind_attr = function(node) {
- return new nglr.BindAttrUpdater(node, nglr.fromJson(node.getAttribute('ng-bind-attr')));
+Binder.prototype.ng_bind_attr = function(node) {
+ return new BindAttrUpdater(node, fromJson(node.getAttribute('ng-bind-attr')));
};
-nglr.Binder.prototype.ng_hide = function(node) {
- return new nglr.HideUpdater(node, node.getAttribute('ng-hide'));
+Binder.prototype.ng_hide = function(node) {
+ return new HideUpdater(node, node.getAttribute('ng-hide'));
};
-nglr.Binder.prototype.ng_show = function(node) {
- return new nglr.ShowUpdater(node, node.getAttribute('ng-show'));
+Binder.prototype.ng_show = function(node) {
+ return new ShowUpdater(node, node.getAttribute('ng-show'));
};
-nglr.Binder.prototype.ng_class = function(node) {
- return new nglr.ClassUpdater(node, node.getAttribute('ng-class'));
+Binder.prototype.ng_class = function(node) {
+ return new ClassUpdater(node, node.getAttribute('ng-class'));
};
-nglr.Binder.prototype.ng_class_even = function(node) {
- return new nglr.ClassEvenUpdater(node, node.getAttribute('ng-class-even'));
+Binder.prototype.ng_class_even = function(node) {
+ return new ClassEvenUpdater(node, node.getAttribute('ng-class-even'));
};
-nglr.Binder.prototype.ng_class_odd = function(node) {
- return new nglr.ClassOddUpdater(node, node.getAttribute('ng-class-odd'));
+Binder.prototype.ng_class_odd = function(node) {
+ return new ClassOddUpdater(node, node.getAttribute('ng-class-odd'));
};
-nglr.Binder.prototype.ng_style = function(node) {
- return new nglr.StyleUpdater(node, node.getAttribute('ng-style'));
+Binder.prototype.ng_style = function(node) {
+ return new StyleUpdater(node, node.getAttribute('ng-style'));
};
-nglr.Binder.prototype.ng_watch = function(node, scope) {
+Binder.prototype.ng_watch = function(node, scope) {
scope.watch(node.getAttribute('ng-watch'));
};
diff --git a/src/ControlBar.js b/src/ControlBar.js
index 3e1f0b57..b66a1464 100644
--- a/src/ControlBar.js
+++ b/src/ControlBar.js
@@ -1,16 +1,16 @@
// Copyright (C) 2008,2009 BRAT Tech LLC
-nglr.ControlBar = function (document, serverUrl) {
+ControlBar = function (document, serverUrl) {
this.document = document;
this.serverUrl = serverUrl;
this.window = window;
this.callbacks = [];
};
-nglr.ControlBar.prototype.bind = function () {
+ControlBar.prototype.bind = function () {
};
-nglr.ControlBar.HTML =
+ControlBar.HTML =
'
' +
'
' +
'
' +
@@ -18,25 +18,25 @@ nglr.ControlBar.HTML =
'
' +
'
';
-nglr.ControlBar.prototype.login = function (loginSubmitFn) {
+ControlBar.prototype.login = function (loginSubmitFn) {
this.callbacks.push(loginSubmitFn);
if (this.callbacks.length == 1) {
this.doTemplate("/user_session/new.mini?return_url=" + encodeURIComponent(this.urlWithoutAnchor()));
}
};
-nglr.ControlBar.prototype.logout = function (loginSubmitFn) {
+ControlBar.prototype.logout = function (loginSubmitFn) {
this.callbacks.push(loginSubmitFn);
if (this.callbacks.length == 1) {
this.doTemplate("/user_session/do_destroy.mini");
}
};
-nglr.ControlBar.prototype.urlWithoutAnchor = function (path) {
+ControlBar.prototype.urlWithoutAnchor = function (path) {
return this.window.location.href.split("#")[0];
};
-nglr.ControlBar.prototype.doTemplate = function (path) {
+ControlBar.prototype.doTemplate = function (path) {
var self = this;
var id = new Date().getTime();
var url = this.urlWithoutAnchor();
@@ -49,7 +49,7 @@ nglr.ControlBar.prototype.doTemplate = function (path) {
resizable: false, modal:true,
title: 'Authentication:
<angular/>'
});
- nglr["_iframe_notify_" + id] = function() {
+ callbacks["_iframe_notify_" + id] = function() {
loginView.dialog("destroy");
loginView.remove();
jQuery.each(self.callbacks, function(i, callback){
@@ -59,13 +59,13 @@ nglr.ControlBar.prototype.doTemplate = function (path) {
};
};
-nglr.ControlBar.FORBIDEN =
+ControlBar.FORBIDEN =
'
' +
'Sorry, you do not have permission for this!'+
'
';
-nglr.ControlBar.prototype.notAuthorized = function () {
+ControlBar.prototype.notAuthorized = function () {
if (this.forbidenView) return;
- this.forbidenView = jQuery(nglr.ControlBar.FORBIDEN);
+ this.forbidenView = jQuery(ControlBar.FORBIDEN);
this.forbidenView.dialog({bgiframe:true, height:70, modal:true});
};
diff --git a/src/DataStore.js b/src/DataStore.js
index 97ab92ff..bdf882a0 100644
--- a/src/DataStore.js
+++ b/src/DataStore.js
@@ -1,6 +1,6 @@
// Copyright (C) 2009 BRAT Tech LLC
-nglr.DataStore = function(post, users, anchor) {
+DataStore = function(post, users, anchor) {
this.post = post;
this.users = users;
this._cache = {$collections:[]};
@@ -8,14 +8,14 @@ nglr.DataStore = function(post, users, anchor) {
this.bulkRequest = [];
};
-nglr.DataStore.prototype.cache = function(document) {
- if (document.constructor != nglr.Model) {
- throw "Parameter must be an instance of Entity! " + nglr.toJson(document);
+DataStore.prototype.cache = function(document) {
+ if (document.constructor != Model) {
+ throw "Parameter must be an instance of Entity! " + toJson(document);
}
var key = document.$entity + '/' + document.$id;
var cachedDocument = this._cache[key];
if (cachedDocument) {
- nglr.Model.copyDirectFields(document, cachedDocument);
+ Model.copyDirectFields(document, cachedDocument);
} else {
this._cache[key] = document;
cachedDocument = document;
@@ -23,7 +23,7 @@ nglr.DataStore.prototype.cache = function(document) {
return cachedDocument;
};
-nglr.DataStore.prototype.load = function(instance, id, callback, failure) {
+DataStore.prototype.load = function(instance, id, callback, failure) {
if (id && id !== '*') {
var self = this;
this._jsonRequest(["GET", instance.$entity + "/" + id], function(response) {
@@ -31,13 +31,13 @@ nglr.DataStore.prototype.load = function(instance, id, callback, failure) {
instance.$migrate();
var clone = instance.$$entity(instance);
self.cache(clone);
- (callback||nglr.noop)(instance);
+ (callback||noop)(instance);
}, failure);
}
return instance;
};
-nglr.DataStore.prototype.loadMany = function(entity, ids, callback) {
+DataStore.prototype.loadMany = function(entity, ids, callback) {
var self=this;
var list = [];
var callbackCount = 0;
@@ -45,26 +45,26 @@ nglr.DataStore.prototype.loadMany = function(entity, ids, callback) {
list.push(self.load(entity(), id, function(){
callbackCount++;
if (callbackCount == ids.length) {
- (callback||nglr.noop)(list);
+ (callback||noop)(list);
}
}));
});
return list;
}
-nglr.DataStore.prototype.loadOrCreate = function(instance, id, callback) {
+DataStore.prototype.loadOrCreate = function(instance, id, callback) {
var self=this;
return this.load(instance, id, callback, function(response){
if (response.$status_code == 404) {
instance.$id = id;
- (callback||nglr.noop)(instance);
+ (callback||noop)(instance);
} else {
throw response;
}
});
};
-nglr.DataStore.prototype.loadAll = function(entity, callback) {
+DataStore.prototype.loadAll = function(entity, callback) {
var self = this;
var list = [];
list.$$accept = function(doc){
@@ -78,12 +78,12 @@ nglr.DataStore.prototype.loadAll = function(entity, callback) {
document.$loadFrom(rows[i]);
list.push(self.cache(document));
}
- (callback||nglr.noop)(list);
+ (callback||noop)(list);
});
return list;
};
-nglr.DataStore.prototype.save = function(document, callback) {
+DataStore.prototype.save = function(document, callback) {
var self = this;
var data = {};
document.$saveTo(data);
@@ -103,7 +103,7 @@ nglr.DataStore.prototype.save = function(document, callback) {
});
};
-nglr.DataStore.prototype.remove = function(document, callback) {
+DataStore.prototype.remove = function(document, callback) {
var self = this;
var data = {};
document.$saveTo(data);
@@ -117,11 +117,11 @@ nglr.DataStore.prototype.remove = function(document, callback) {
}
}
});
- (callback||nglr.noop)(response);
+ (callback||noop)(response);
});
};
-nglr.DataStore.prototype._jsonRequest = function(request, callback, failure) {
+DataStore.prototype._jsonRequest = function(request, callback, failure) {
request.$$callback = callback;
request.$$failure = failure||function(response){
throw response;
@@ -129,7 +129,7 @@ nglr.DataStore.prototype._jsonRequest = function(request, callback, failure) {
this.bulkRequest.push(request);
};
-nglr.DataStore.prototype.flush = function() {
+DataStore.prototype.flush = function() {
if (this.bulkRequest.length === 0) return;
var self = this;
var bulkRequest = this.bulkRequest;
@@ -142,7 +142,7 @@ nglr.DataStore.prototype.flush = function() {
self.post(bulkRequest, callback);
});
} else if(bulkResponse.$status_code) {
- nglr.alert(nglr.toJson(bulkResponse));
+ alert(toJson(bulkResponse));
} else {
for ( var i = 0; i < bulkResponse.length; i++) {
var response = bulkResponse[i];
@@ -163,7 +163,7 @@ nglr.DataStore.prototype.flush = function() {
this.post(bulkRequest, callback);
};
-nglr.DataStore.prototype.saveScope = function(scope, callback) {
+DataStore.prototype.saveScope = function(scope, callback) {
var saveCounter = 1;
function onSaveDone() {
saveCounter--;
@@ -172,7 +172,7 @@ nglr.DataStore.prototype.saveScope = function(scope, callback) {
}
for(var key in scope) {
var item = scope[key];
- if (item && item.$save == nglr.Model.prototype.$save) {
+ if (item && item.$save == Model.prototype.$save) {
saveCounter++;
item.$save(onSaveDone);
}
@@ -180,7 +180,7 @@ nglr.DataStore.prototype.saveScope = function(scope, callback) {
onSaveDone();
};
-nglr.DataStore.prototype.query = function(type, query, arg, callback){
+DataStore.prototype.query = function(type, query, arg, callback){
var self = this;
var queryList = [];
queryList.$$accept = function(doc){
@@ -200,7 +200,7 @@ nglr.DataStore.prototype.query = function(type, query, arg, callback){
return queryList;
};
-nglr.DataStore.prototype.entities = function(callback) {
+DataStore.prototype.entities = function(callback) {
var entities = [];
var self = this;
this._jsonRequest(["GET", "$entities"], function(response) {
@@ -213,7 +213,7 @@ nglr.DataStore.prototype.entities = function(callback) {
return entities;
};
-nglr.DataStore.prototype.documentCountsByUser = function(){
+DataStore.prototype.documentCountsByUser = function(){
var counts = {};
var self = this;
self.post([["GET", "$users"]], function(code, response){
@@ -224,7 +224,7 @@ nglr.DataStore.prototype.documentCountsByUser = function(){
return counts;
};
-nglr.DataStore.prototype.userDocumentIdsByEntity = function(user){
+DataStore.prototype.userDocumentIdsByEntity = function(user){
var ids = {};
var self = this;
self.post([["GET", "$users/" + user]], function(code, response){
@@ -235,19 +235,19 @@ nglr.DataStore.prototype.userDocumentIdsByEntity = function(user){
return ids;
};
-nglr.DataStore.NullEntity = function(){};
-nglr.DataStore.NullEntity.all = function(){return [];};
-nglr.DataStore.NullEntity.query = function(){return [];};
-nglr.DataStore.NullEntity.load = function(){return {};};
-nglr.DataStore.NullEntity.title = undefined;
+DataStore.NullEntity = function(){};
+DataStore.NullEntity.all = function(){return [];};
+DataStore.NullEntity.query = function(){return [];};
+DataStore.NullEntity.load = function(){return {};};
+DataStore.NullEntity.title = undefined;
-nglr.DataStore.prototype.entity = function(name, defaults){
+DataStore.prototype.entity = function(name, defaults){
if (!name) {
- return nglr.DataStore.NullEntity;
+ return DataStore.NullEntity;
}
var self = this;
var entity = function(initialState){
- return new nglr.Model(entity, initialState);
+ return new Model(entity, initialState);
};
// entity.name does not work as name seems to be reserved for functions
entity.title = name;
@@ -275,7 +275,7 @@ nglr.DataStore.prototype.entity = function(name, defaults){
return entity;
};
-nglr.DataStore.prototype.join = function(join){
+DataStore.prototype.join = function(join){
var fn = function(){
throw "Joined entities can not be instantiated into a document.";
};
@@ -312,7 +312,7 @@ nglr.DataStore.prototype.join = function(join){
var row = {};
joinedResult.push(row);
row[baseName] = doc;
- var id = nglr.Scope.getter(row, nextJoinOn);
+ var id = Scope.getter(row, nextJoinOn);
joinIds[id] = id;
});
nextJoin.join.loadMany(_.toArray(joinIds), function(result){
@@ -321,7 +321,7 @@ nglr.DataStore.prototype.join = function(join){
byId[doc.$id] = doc;
});
_(joinedResult).each(function(row){
- var id = nglr.Scope.getter(row, nextJoinOn);
+ var id = Scope.getter(row, nextJoinOn);
row[nextJoinName] = byId[id];
});
});
diff --git a/src/Filters.js b/src/Filters.js
index f75f3603..dd4217be 100644
--- a/src/Filters.js
+++ b/src/Filters.js
@@ -60,11 +60,11 @@ angular.filter.date = function(amount) {
angular.filter.json = function(object) {
jQuery(this.element).addClass("ng-monospace");
- return nglr.toJson(object, true);
+ return toJson(object, true);
};
angular.filter.trackPackage = function(trackingNo, noMatch) {
- trackingNo = nglr.trim(trackingNo);
+ trackingNo = trim(trackingNo);
var tNo = trackingNo.replace(/ /g, '');
var MATCHERS = angular.filter.trackPackage.MATCHERS;
for ( var i = 0; i < MATCHERS.length; i++) {
@@ -77,7 +77,7 @@ angular.filter.trackPackage = function(trackingNo, noMatch) {
return new angular.filter.Meta({
text:text,
url:url,
- html: '
' + text + '',
+ html: '
' + text + '',
trackingNo:trackingNo});
}
}
@@ -115,7 +115,7 @@ angular.filter.link = function(obj, title) {
if (angular.validator.email(url) === null) {
url = "mailto:" + url;
}
- var html = '
' + text + '';
+ var html = '
' + text + '';
return new angular.filter.Meta({text:text, url:url, html:html});
}
return obj;
diff --git a/src/JSON.js b/src/JSON.js
index 2b6393bf..84c9a857 100644
--- a/src/JSON.js
+++ b/src/JSON.js
@@ -1,18 +1,18 @@
-nglr.array = [].constructor;
+array = [].constructor;
-nglr.toJson = function(obj, pretty){
+toJson = function(obj, pretty){
var buf = [];
- nglr.toJsonArray(buf, obj, pretty ? "\n " : null);
+ toJsonArray(buf, obj, pretty ? "\n " : null);
return buf.join('');
};
-nglr.toPrettyJson = function(obj) {
- return nglr.toJson(obj, true);
+toPrettyJson = function(obj) {
+ return toJson(obj, true);
};
-nglr.fromJson = function(json) {
+fromJson = function(json) {
try {
- var parser = new nglr.Parser(json, true);
+ var parser = new Parser(json, true);
var expression = parser.primary();
parser.assertAllConsumed();
return expression();
@@ -23,7 +23,7 @@ nglr.fromJson = function(json) {
};
-nglr.toJsonArray = function(buf, obj, pretty){
+toJsonArray = function(buf, obj, pretty){
var type = typeof obj;
if (obj === null) {
buf.push("null");
@@ -50,7 +50,7 @@ nglr.toJsonArray = function(buf, obj, pretty){
if (typeof item == 'function' || typeof item == 'undefined') {
buf.push("null");
} else {
- nglr.toJsonArray(buf, item, pretty);
+ toJsonArray(buf, item, pretty);
}
sep = true;
}
@@ -80,7 +80,7 @@ nglr.toJsonArray = function(buf, obj, pretty){
}
buf.push(angular.String.quote(key));
buf.push(":");
- nglr.toJsonArray(buf, value, childPretty);
+ toJsonArray(buf, value, childPretty);
comma = true;
}
} catch (e) {
diff --git a/src/Loader.js b/src/Loader.js
index eae6e4f5..dfaa355a 100644
--- a/src/Loader.js
+++ b/src/Loader.js
@@ -22,34 +22,37 @@ if (typeof Node == 'undefined') {
};
}
-if (_.isUndefined(window.nglr)) nglr = {};
-if (_.isUndefined(window.angular)) angular = {};
-if (_.isUndefined(angular.validator)) angular.validator = {};
-if (_.isUndefined(angular.filter)) angular.filter = {};
-if (_.isUndefined(window.console))
+var callbacks = {};
+
+if (!window.angular){ angular = {}; window['angular'] = angular; }
+if (!angular.validator) angular.validator = {};
+if (!angular.filter) angular.filter = {};
+if (!window.console)
window.console = {
log:function() {},
error:function() {}
};
-if (_.isUndefined(nglr.alert)) {
- nglr.alert = function(){console.log(arguments); window.alert.apply(window, arguments); };
+if (_.isUndefined(alert)) {
+ alert = function(){console.log(arguments); window.alert.apply(window, arguments); };
}
-nglr.consoleLog = function(level, objs) {
+var consoleNode;
+
+consoleLog = function(level, objs) {
var log = document.createElement("div");
log.className = level;
var msg = "";
var sep = "";
for ( var i = 0; i < objs.length; i++) {
var obj = objs[i];
- msg += sep + (typeof obj == 'string' ? obj : nglr.toJson(obj));
+ msg += sep + (typeof obj == 'string' ? obj : toJson(obj));
sep = " ";
}
log.appendChild(document.createTextNode(msg));
- nglr.consoleNode.appendChild(log);
+ consoleNode.appendChild(log);
};
-nglr.isNode = function(inp) {
+isNode = function(inp) {
return inp &&
inp.tagName &&
inp.nodeName &&
@@ -57,7 +60,7 @@ nglr.isNode = function(inp) {
inp.removeAttribute;
};
-nglr.isLeafNode = function(node) {
+isLeafNode = function(node) {
switch (node.nodeName) {
case "OPTION":
case "PRE":
@@ -68,11 +71,11 @@ nglr.isLeafNode = function(node) {
}
};
-nglr.noop = function() {
+noop = function() {
};
-nglr.setHtml = function(node, html) {
- if (nglr.isLeafNode(node)) {
- if (nglr.msie) {
+setHtml = function(node, html) {
+ if (isLeafNode(node)) {
+ if (msie) {
node.innerText = html;
} else {
node.textContent = html;
@@ -82,7 +85,7 @@ nglr.setHtml = function(node, html) {
}
};
-nglr.escapeHtml = function(html) {
+escapeHtml = function(html) {
if (!html || !html.replace)
return html;
return html.
@@ -91,14 +94,14 @@ nglr.escapeHtml = function(html) {
replace(/>/g, '>');
};
-nglr.escapeAttr = function(html) {
+escapeAttr = function(html) {
if (!html || !html.replace)
return html;
return html.replace(//g, '>').replace(/\"/g,
'"');
};
-nglr.bind = function(_this, _function) {
+bind = function(_this, _function) {
if (!_this)
throw "Missing this";
if (!_.isFunction(_function))
@@ -108,7 +111,7 @@ nglr.bind = function(_this, _function) {
};
};
-nglr.shiftBind = function(_this, _function) {
+shiftBind = function(_this, _function) {
return function() {
var args = [ this ];
for ( var i = 0; i < arguments.length; i++) {
@@ -118,7 +121,7 @@ nglr.shiftBind = function(_this, _function) {
};
};
-nglr.outerHTML = function(node) {
+outerHTML = function(node) {
var temp = document.createElement('div');
temp.appendChild(node);
var outerHTML = temp.innerHTML;
@@ -126,26 +129,26 @@ nglr.outerHTML = function(node) {
return outerHTML;
};
-nglr.trim = function(str) {
+trim = function(str) {
return str.replace(/^ */, '').replace(/ *$/, '');
};
-nglr.toBoolean = function(value) {
+toBoolean = function(value) {
var v = ("" + value).toLowerCase();
if (v == 'f' || v == '0' || v == 'false' || v == 'no')
value = false;
return !!value;
};
-nglr.merge = function(src, dst) {
+merge = function(src, dst) {
for ( var key in src) {
var value = dst[key];
var type = typeof value;
if (type == 'undefined') {
- dst[key] = nglr.fromJson(nglr.toJson(src[key]));
- } else if (type == 'object' && value.constructor != nglr.array &&
+ dst[key] = fromJson(toJson(src[key]));
+ } else if (type == 'object' && value.constructor != array &&
key.substring(0, 1) != "$") {
- nglr.merge(src[key], value);
+ merge(src[key], value);
}
}
};
@@ -154,25 +157,25 @@ nglr.merge = function(src, dst) {
// Loader
// ////////////////////////////
-nglr.Loader = function(document, head, config) {
+Loader = function(document, head, config) {
this.document = jQuery(document);
this.head = jQuery(head);
this.config = config;
this.location = window.location;
};
-nglr.Loader.prototype.load = function() {
+Loader.prototype.load = function() {
this.configureLogging();
this.loadCss('/stylesheets/jquery-ui/smoothness/jquery-ui-1.7.1.css');
- this.loadCss('/stylesheets/nglr.css');
+ this.loadCss('/stylesheets/css');
console.log("Server: " + this.config.server);
- nglr.msie = jQuery.browser.msie;
+ msie = jQuery.browser.msie;
this.configureJQueryPlugins();
this.computeConfiguration();
this.bindHtml();
};
-nglr.Loader.prototype.configureJQueryPlugins = function() {
+Loader.prototype.configureJQueryPlugins = function() {
console.log('Loader.configureJQueryPlugins()');
jQuery.fn.removeNode = function() {
var node = this.get(0);
@@ -189,15 +192,15 @@ nglr.Loader.prototype.configureJQueryPlugins = function() {
return null;
};
jQuery.fn.controller = function() {
- return this.data('controller') || nglr.NullController.instance;
+ return this.data('controller') || NullController.instance;
};
};
-nglr.Loader.prototype.uid = function() {
+Loader.prototype.uid = function() {
return "" + new Date().getTime();
};
-nglr.Loader.prototype.computeConfiguration = function() {
+Loader.prototype.computeConfiguration = function() {
var config = this.config;
if (!config.database) {
var match = config.server.match(/https?:\/\/([\w]*)/);
@@ -205,27 +208,27 @@ nglr.Loader.prototype.computeConfiguration = function() {
}
};
-nglr.Loader.prototype.bindHtml = function() {
+Loader.prototype.bindHtml = function() {
console.log('Loader.bindHtml()');
- var watcher = new nglr.UrlWatcher(this.location);
+ var watcher = new UrlWatcher(this.location);
var document = this.document;
- var widgetFactory = new nglr.WidgetFactory(this.config.server, this.config.database);
- var binder = new nglr.Binder(document[0], widgetFactory, watcher, this.config);
- widgetFactory.onChangeListener = nglr.shiftBind(binder, binder.updateModel);
- var controlBar = new nglr.ControlBar(document.find('body'), this.config.server);
+ var widgetFactory = new WidgetFactory(this.config.server, this.config.database);
+ var binder = new Binder(document[0], widgetFactory, watcher, this.config);
+ widgetFactory.onChangeListener = shiftBind(binder, binder.updateModel);
+ var controlBar = new ControlBar(document.find('body'), this.config.server);
var onUpdate = function(){binder.updateView();};
var server = this.config.database=="$MEMORY" ?
- new nglr.FrameServer(this.window) :
- new nglr.Server(this.config.server, jQuery.getScript);
- server = new nglr.VisualServer(server, new nglr.Status(jQuery(document.body)), onUpdate);
- var users = new nglr.Users(server, controlBar);
+ new FrameServer(this.window) :
+ new Server(this.config.server, jQuery.getScript);
+ server = new VisualServer(server, new Status(jQuery(document.body)), onUpdate);
+ var users = new Users(server, controlBar);
var databasePath = '/data/' + this.config.database;
var post = function(request, callback){
server.request("POST", databasePath, request, callback);
};
- var datastore = new nglr.DataStore(post, users, binder.anchor);
+ var datastore = new DataStore(post, users, binder.anchor);
binder.updateListeners.push(function(){datastore.flush();});
- var scope = new nglr.Scope( {
+ var scope = new Scope( {
$anchor : binder.anchor,
$binder : binder,
$config : this.config,
@@ -241,7 +244,7 @@ nglr.Loader.prototype.bindHtml = function() {
jQuery.each(["get", "set", "eval", "addWatchListener", "updateView"],
function(i, method){
- angular[method] = nglr.bind(scope, scope[method]);
+ angular[method] = bind(scope, scope[method]);
});
document.data('scope', scope);
@@ -265,7 +268,7 @@ nglr.Loader.prototype.bindHtml = function() {
fetchCurrentUser();
console.log('PopUp.bind()');
- new nglr.PopUp(document).bind();
+ new PopUp(document).bind();
console.log('$binder.parseAnchor()');
binder.parseAnchor();
@@ -276,16 +279,16 @@ nglr.Loader.prototype.bindHtml = function() {
console.log('$binder.updateView()');
binder.updateView();
- watcher.listener = nglr.bind(binder, binder.onUrlChange, watcher);
- watcher.onUpdate = function(){nglr.alert("update");};
+ watcher.listener = bind(binder, binder.onUrlChange, watcher);
+ watcher.onUpdate = function(){alert("update");};
watcher.watch();
document.find("body").show();
console.log('ready()');
};
-nglr.Loader.prototype.visualPost = function(delegate) {
- var status = new nglr.Status(jQuery(document.body));
+Loader.prototype.visualPost = function(delegate) {
+ var status = new Status(jQuery(document.body));
return function(request, delegateCallback) {
status.beginRequest(request);
var callback = function() {
@@ -293,14 +296,14 @@ nglr.Loader.prototype.visualPost = function(delegate) {
try {
delegateCallback.apply(this, arguments);
} catch (e) {
- nglr.alert(nglr.toJson(e));
+ alert(toJson(e));
}
};
delegate(request, callback);
};
};
-nglr.Loader.prototype.configureLogging = function() {
+Loader.prototype.configureLogging = function() {
var url = window.location.href + '#';
url = url.split('#')[1];
var config = {
@@ -312,19 +315,19 @@ nglr.Loader.prototype.configureLogging = function() {
config[part[0]] = part[1];
}
if (config.debug == 'console') {
- nglr.consoleNode = document.createElement("div");
- nglr.consoleNode.id = 'ng-console';
- document.getElementsByTagName('body')[0].appendChild(nglr.consoleNode);
+ consoleNode = document.createElement("div");
+ consoleNode.id = 'ng-console';
+ document.getElementsByTagName('body')[0].appendChild(consoleNode);
console.log = function() {
- nglr.consoleLog('ng-console-info', arguments);
+ consoleLog('ng-console-info', arguments);
};
console.error = function() {
- nglr.consoleLog('ng-console-error', arguments);
+ consoleLog('ng-console-error', arguments);
};
}
};
-nglr.Loader.prototype.loadCss = function(css) {
+Loader.prototype.loadCss = function(css) {
var cssTag = document.createElement('link');
cssTag.rel = "stylesheet";
cssTag.type = "text/css";
@@ -334,7 +337,7 @@ nglr.Loader.prototype.loadCss = function(css) {
this.head[0].appendChild(cssTag);
};
-nglr.UrlWatcher = function(location) {
+UrlWatcher = function(location) {
this.location = location;
this.delay = 25;
this.setTimeout = function(fn, delay) {
@@ -346,7 +349,7 @@ nglr.UrlWatcher = function(location) {
this.expectedUrl = location.href;
};
-nglr.UrlWatcher.prototype.watch = function() {
+UrlWatcher.prototype.watch = function() {
var self = this;
var pull = function() {
if (self.expectedUrl !== self.location.href) {
@@ -357,12 +360,12 @@ nglr.UrlWatcher.prototype.watch = function() {
}
self.location.href = self.expectedUrl;
var id = '_iframe_notify_' + notify[1];
- var notifyFn = nglr[id];
- delete nglr[id];
+ var notifyFn = callbacks[id];
+ delete callbacks[id];
try {
- (notifyFn||nglr.noop)();
+ (notifyFn||noop)();
} catch (e) {
- nglr.alert(e);
+ alert(e);
}
} else {
self.listener(self.location.href);
@@ -374,16 +377,16 @@ nglr.UrlWatcher.prototype.watch = function() {
pull();
};
-nglr.UrlWatcher.prototype.setUrl = function(url) {
+UrlWatcher.prototype.setUrl = function(url) {
var existingURL = window.location.href;
if (!existingURL.match(/#/))
existingURL += '#';
if (existingURL != url)
window.location.href = url;
- self.existingURL = url;
+ this.existingURL = url;
};
-nglr.UrlWatcher.prototype.getUrl = function() {
+UrlWatcher.prototype.getUrl = function() {
return window.location.href;
};
@@ -394,7 +397,7 @@ angular['compile'] = function(root, config) {
};
//todo: don't load stylesheet by default
//todo: don't start watcher
- var loader = new nglr.Loader(root, jQuery("head"), _(defaults).extend(config));
+ var loader = new Loader(root, jQuery("head"), _(defaults).extend(config));
loader.load();
return jQuery(root).scope();
};
diff --git a/src/Model.js b/src/Model.js
index 5e48251f..35f6a1c1 100644
--- a/src/Model.js
+++ b/src/Model.js
@@ -3,14 +3,14 @@
// Single $ is special and does not get searched
// Double $$ is special an is client only (does not get sent to server)
-nglr.Model = function(entity, initial) {
+Model = function(entity, initial) {
this.$$entity = entity;
this.$loadFrom(initial||{});
this.$entity = entity.title;
this.$migrate();
};
-nglr.Model.copyDirectFields = function(src, dst) {
+Model.copyDirectFields = function(src, dst) {
if (src === dst || !src || !dst) return;
var isDataField = function(src, dst, field) {
return (field.substring(0,2) !== '$$') &&
@@ -27,39 +27,39 @@ nglr.Model.copyDirectFields = function(src, dst) {
}
};
-nglr.Model.prototype.$migrate = function() {
- nglr.merge(this.$$entity.defaults, this);
+Model.prototype.$migrate = function() {
+ merge(this.$$entity.defaults, this);
return this;
};
-nglr.Model.prototype.$merge = function(other) {
- nglr.merge(other, this);
+Model.prototype.$merge = function(other) {
+ merge(other, this);
return this;
};
-nglr.Model.prototype.$save = function(callback) {
+Model.prototype.$save = function(callback) {
this.$$entity.datastore.save(this, callback === true ? undefined : callback);
if (callback === true) this.$$entity.datastore.flush();
return this;
};
-nglr.Model.prototype.$delete = function(callback) {
+Model.prototype.$delete = function(callback) {
this.$$entity.datastore.remove(this, callback === true ? undefined : callback);
if (callback === true) this.$$entity.datastore.flush();
return this;
};
-nglr.Model.prototype.$loadById = function(id, callback) {
+Model.prototype.$loadById = function(id, callback) {
this.$$entity.datastore.load(this, id, callback);
return this;
};
-nglr.Model.prototype.$loadFrom = function(other) {
- nglr.Model.copyDirectFields(other, this);
+Model.prototype.$loadFrom = function(other) {
+ Model.copyDirectFields(other, this);
return this;
};
-nglr.Model.prototype.$saveTo = function(other) {
- nglr.Model.copyDirectFields(this, other);
+Model.prototype.$saveTo = function(other) {
+ Model.copyDirectFields(this, other);
return this;
};
diff --git a/src/Parser.js b/src/Parser.js
index 3d72bebf..b23215be 100644
--- a/src/Parser.js
+++ b/src/Parser.js
@@ -1,4 +1,4 @@
-nglr.Lexer = function(text, parsStrings){
+Lexer = function(text, parsStrings){
this.text = text;
// UTC dates have 20 characters, we send them through parser
this.dateParseLength = parsStrings ? 20 : -1;
@@ -6,7 +6,7 @@ nglr.Lexer = function(text, parsStrings){
this.index = 0;
};
-nglr.Lexer.OPERATORS = {
+Lexer.OPERATORS = {
'null':function(self){return null;},
'true':function(self){return true;},
'false':function(self){return false;},
@@ -31,7 +31,7 @@ nglr.Lexer.OPERATORS = {
'!':function(self, a){return !a;}
};
-nglr.Lexer.prototype.peek = function() {
+Lexer.prototype.peek = function() {
if (this.index + 1 < this.text.length) {
return this.text.charAt(this.index + 1);
} else {
@@ -39,9 +39,9 @@ nglr.Lexer.prototype.peek = function() {
}
};
-nglr.Lexer.prototype.parse = function() {
+Lexer.prototype.parse = function() {
var tokens = this.tokens;
- var OPERATORS = nglr.Lexer.OPERATORS;
+ var OPERATORS = Lexer.OPERATORS;
var canStartRegExp = true;
while (this.index < this.text.length) {
var ch = this.text.charAt(this.index);
@@ -102,22 +102,22 @@ nglr.Lexer.prototype.parse = function() {
return tokens;
};
-nglr.Lexer.prototype.isNumber = function(ch) {
+Lexer.prototype.isNumber = function(ch) {
return '0' <= ch && ch <= '9';
};
-nglr.Lexer.prototype.isWhitespace = function(ch) {
+Lexer.prototype.isWhitespace = function(ch) {
return ch == ' ' || ch == '\r' || ch == '\t' ||
ch == '\n' || ch == '\v';
};
-nglr.Lexer.prototype.isIdent = function(ch) {
+Lexer.prototype.isIdent = function(ch) {
return 'a' <= ch && ch <= 'z' ||
'A' <= ch && ch <= 'Z' ||
'_' == ch || ch == '$';
};
-nglr.Lexer.prototype.readNumber = function() {
+Lexer.prototype.readNumber = function() {
var number = "";
var start = this.index;
while (this.index < this.text.length) {
@@ -134,7 +134,7 @@ nglr.Lexer.prototype.readNumber = function() {
fn:function(){return number;}});
};
-nglr.Lexer.prototype.readIdent = function() {
+Lexer.prototype.readIdent = function() {
var ident = "";
var start = this.index;
while (this.index < this.text.length) {
@@ -146,7 +146,7 @@ nglr.Lexer.prototype.readIdent = function() {
}
this.index++;
}
- var fn = nglr.Lexer.OPERATORS[ident];
+ var fn = Lexer.OPERATORS[ident];
if (!fn) {
fn = function(self){
return self.scope.get(ident);
@@ -155,8 +155,8 @@ nglr.Lexer.prototype.readIdent = function() {
}
this.tokens.push({index:start, text:ident, fn:fn});
};
-nglr.Lexer.ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'};
-nglr.Lexer.prototype.readString = function(quote) {
+Lexer.ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'};
+Lexer.prototype.readString = function(quote) {
var start = this.index;
var dateParseLength = this.dateParseLength;
this.index++;
@@ -170,7 +170,7 @@ nglr.Lexer.prototype.readString = function(quote) {
this.index += 4;
string += String.fromCharCode(parseInt(hex, 16));
} else {
- var rep = nglr.Lexer.ESCAPE[ch];
+ var rep = Lexer.ESCAPE[ch];
if (rep) {
string += rep;
} else {
@@ -198,7 +198,7 @@ nglr.Lexer.prototype.readString = function(quote) {
(start+1) + "' in expression '" + this.text + "'.";
};
-nglr.Lexer.prototype.readRegexp = function(quote) {
+Lexer.prototype.readRegexp = function(quote) {
var start = this.index;
this.index++;
var regexp = "";
@@ -233,30 +233,30 @@ nglr.Lexer.prototype.readRegexp = function(quote) {
};
-nglr.Parser = function(text, parseStrings){
+Parser = function(text, parseStrings){
this.text = text;
- this.tokens = new nglr.Lexer(text, parseStrings).parse();
+ this.tokens = new Lexer(text, parseStrings).parse();
this.index = 0;
};
-nglr.Parser.ZERO = function(){
+Parser.ZERO = function(){
return 0;
};
-nglr.Parser.prototype.error = function(msg, token) {
+Parser.prototype.error = function(msg, token) {
throw "Token '" + token.text +
"' is " + msg + " at column='" +
(token.index + 1) + "' of expression '" +
this.text + "' starting at '" + this.text.substring(token.index) + "'.";
};
-nglr.Parser.prototype.peekToken = function() {
+Parser.prototype.peekToken = function() {
if (this.tokens.length === 0)
throw "Unexpected end of expression: " + this.text;
return this.tokens[0];
};
-nglr.Parser.prototype.peek = function(e1, e2, e3, e4) {
+Parser.prototype.peek = function(e1, e2, e3, e4) {
var tokens = this.tokens;
if (tokens.length > 0) {
var token = tokens[0];
@@ -269,7 +269,7 @@ nglr.Parser.prototype.peek = function(e1, e2, e3, e4) {
return false;
};
-nglr.Parser.prototype.expect = function(e1, e2, e3, e4){
+Parser.prototype.expect = function(e1, e2, e3, e4){
var token = this.peek(e1, e2, e3, e4);
if (token) {
this.tokens.shift();
@@ -279,7 +279,7 @@ nglr.Parser.prototype.expect = function(e1, e2, e3, e4){
return false;
};
-nglr.Parser.prototype.consume = function(e1){
+Parser.prototype.consume = function(e1){
if (!this.expect(e1)) {
var token = this.peek();
throw "Expecting '" + e1 + "' at column '" +
@@ -289,32 +289,32 @@ nglr.Parser.prototype.consume = function(e1){
}
};
-nglr.Parser.prototype._unary = function(fn, parse) {
+Parser.prototype._unary = function(fn, parse) {
var right = parse.apply(this);
return function(self) {
return fn(self, right(self));
};
};
-nglr.Parser.prototype._binary = function(left, fn, parse) {
+Parser.prototype._binary = function(left, fn, parse) {
var right = parse.apply(this);
return function(self) {
return fn(self, left(self), right(self));
};
};
-nglr.Parser.prototype.hasTokens = function () {
+Parser.prototype.hasTokens = function () {
return this.tokens.length > 0;
};
-nglr.Parser.prototype.assertAllConsumed = function(){
+Parser.prototype.assertAllConsumed = function(){
if (this.tokens.length !== 0) {
throw "Did not understand '" + this.text.substring(this.tokens[0].index) +
"' while evaluating '" + this.text + "'.";
}
};
-nglr.Parser.prototype.statements = function(){
+Parser.prototype.statements = function(){
var statements = [];
while(true) {
if (this.tokens.length > 0 && !this.peek('}', ')', ';', ']'))
@@ -333,7 +333,7 @@ nglr.Parser.prototype.statements = function(){
}
};
-nglr.Parser.prototype.filterChain = function(){
+Parser.prototype.filterChain = function(){
var left = this.expression();
var token;
while(true) {
@@ -345,15 +345,15 @@ nglr.Parser.prototype.filterChain = function(){
}
};
-nglr.Parser.prototype.filter = function(){
+Parser.prototype.filter = function(){
return this._pipeFunction(angular.filter);
};
-nglr.Parser.prototype.validator = function(){
+Parser.prototype.validator = function(){
return this._pipeFunction(angular.validator);
};
-nglr.Parser.prototype._pipeFunction = function(fnScope){
+Parser.prototype._pipeFunction = function(fnScope){
var fn = this.functionIdent(fnScope);
var argsFn = [];
var token;
@@ -375,11 +375,11 @@ nglr.Parser.prototype._pipeFunction = function(fnScope){
}
};
-nglr.Parser.prototype.expression = function(){
+Parser.prototype.expression = function(){
return this.throwStmt();
};
-nglr.Parser.prototype.throwStmt = function(){
+Parser.prototype.throwStmt = function(){
if (this.expect('throw')) {
var throwExp = this.assignment();
return function (self) {
@@ -390,7 +390,7 @@ nglr.Parser.prototype.throwStmt = function(){
}
};
-nglr.Parser.prototype.assignment = function(){
+Parser.prototype.assignment = function(){
var left = this.logicalOR();
var token;
if (token = this.expect('=')) {
@@ -406,7 +406,7 @@ nglr.Parser.prototype.assignment = function(){
}
};
-nglr.Parser.prototype.logicalOR = function(){
+Parser.prototype.logicalOR = function(){
var left = this.logicalAND();
var token;
while(true) {
@@ -418,7 +418,7 @@ nglr.Parser.prototype.logicalOR = function(){
}
};
-nglr.Parser.prototype.logicalAND = function(){
+Parser.prototype.logicalAND = function(){
var left = this.negated();
var token;
while(true) {
@@ -430,7 +430,7 @@ nglr.Parser.prototype.logicalAND = function(){
}
};
-nglr.Parser.prototype.negated = function(){
+Parser.prototype.negated = function(){
var token;
if (token = this.expect('!')) {
return this._unary(token.fn, this.equality);
@@ -439,7 +439,7 @@ nglr.Parser.prototype.negated = function(){
}
};
-nglr.Parser.prototype.equality = function(){
+Parser.prototype.equality = function(){
var left = this.relational();
var token;
while(true) {
@@ -451,7 +451,7 @@ nglr.Parser.prototype.equality = function(){
}
};
-nglr.Parser.prototype.relational = function(){
+Parser.prototype.relational = function(){
var left = this.additive();
var token;
while(true) {
@@ -463,7 +463,7 @@ nglr.Parser.prototype.relational = function(){
}
};
-nglr.Parser.prototype.additive = function(){
+Parser.prototype.additive = function(){
var left = this.multiplicative();
var token;
while(token = this.expect('+','-')) {
@@ -472,7 +472,7 @@ nglr.Parser.prototype.additive = function(){
return left;
};
-nglr.Parser.prototype.multiplicative = function(){
+Parser.prototype.multiplicative = function(){
var left = this.unary();
var token;
while(token = this.expect('*','/','%')) {
@@ -481,18 +481,18 @@ nglr.Parser.prototype.multiplicative = function(){
return left;
};
-nglr.Parser.prototype.unary = function(){
+Parser.prototype.unary = function(){
var token;
if (this.expect('+')) {
return this.primary();
} else if (token = this.expect('-')) {
- return this._binary(nglr.Parser.ZERO, token.fn, this.multiplicative);
+ return this._binary(Parser.ZERO, token.fn, this.multiplicative);
} else {
return this.primary();
}
};
-nglr.Parser.prototype.functionIdent = function(fnScope) {
+Parser.prototype.functionIdent = function(fnScope) {
var token = this.expect();
var element = token.text.split('.');
var instance = fnScope;
@@ -509,7 +509,7 @@ nglr.Parser.prototype.functionIdent = function(fnScope) {
return instance;
};
-nglr.Parser.prototype.primary = function() {
+Parser.prototype.primary = function() {
var primary;
if (this.expect('(')) {
var expression = this.filterChain();
@@ -545,7 +545,7 @@ nglr.Parser.prototype.primary = function() {
return primary;
};
-nglr.Parser.prototype.closure = function(hasArgs) {
+Parser.prototype.closure = function(hasArgs) {
var args = [];
if (hasArgs) {
if (!this.expect(')')) {
@@ -561,7 +561,7 @@ nglr.Parser.prototype.closure = function(hasArgs) {
this.consume("}");
return function(self){
return function($){
- var scope = new nglr.Scope(self.scope.state);
+ var scope = new Scope(self.scope.state);
scope.set('$', $);
for ( var i = 0; i < args.length; i++) {
scope.set(args[i], arguments[i]);
@@ -571,16 +571,16 @@ nglr.Parser.prototype.closure = function(hasArgs) {
};
};
-nglr.Parser.prototype.fieldAccess = function(object) {
+Parser.prototype.fieldAccess = function(object) {
var field = this.expect().text;
var fn = function (self){
- return nglr.Scope.getter(object(self), field);
+ return Scope.getter(object(self), field);
};
fn.isAssignable = field;
return fn;
};
-nglr.Parser.prototype.objectIndex = function(obj) {
+Parser.prototype.objectIndex = function(obj) {
var indexFn = this.expression();
this.consume(']');
if (this.expect('=')) {
@@ -597,7 +597,7 @@ nglr.Parser.prototype.objectIndex = function(obj) {
}
};
-nglr.Parser.prototype.functionCall = function(fn) {
+Parser.prototype.functionCall = function(fn) {
var argsFn = [];
if (this.peekToken().text != ')') {
do {
@@ -620,7 +620,7 @@ nglr.Parser.prototype.functionCall = function(fn) {
};
// This is used with json array declaration
-nglr.Parser.prototype.arrayDeclaration = function () {
+Parser.prototype.arrayDeclaration = function () {
var elementFns = [];
if (this.peekToken().text != ']') {
do {
@@ -637,7 +637,7 @@ nglr.Parser.prototype.arrayDeclaration = function () {
};
};
-nglr.Parser.prototype.object = function () {
+Parser.prototype.object = function () {
var keyValues = [];
if (this.peekToken().text != '}') {
do {
@@ -659,7 +659,7 @@ nglr.Parser.prototype.object = function () {
};
};
-nglr.Parser.prototype.entityDeclaration = function () {
+Parser.prototype.entityDeclaration = function () {
var decl = [];
while(this.hasTokens()) {
decl.push(this.entityDecl());
@@ -676,7 +676,7 @@ nglr.Parser.prototype.entityDeclaration = function () {
};
};
-nglr.Parser.prototype.entityDecl = function () {
+Parser.prototype.entityDecl = function () {
var entity = this.expect().text;
var instance;
var defaults;
@@ -705,7 +705,7 @@ nglr.Parser.prototype.entityDecl = function () {
};
};
-nglr.Parser.prototype.watch = function () {
+Parser.prototype.watch = function () {
var decl = [];
while(this.hasTokens()) {
decl.push(this.watchDecl());
@@ -722,7 +722,7 @@ nglr.Parser.prototype.watch = function () {
};
};
-nglr.Parser.prototype.watchDecl = function () {
+Parser.prototype.watchDecl = function () {
var anchorName = this.expect().text;
this.consume(":");
var expression;
diff --git a/src/Scope.js b/src/Scope.js
index 45dd15a4..e3634cee 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -1,6 +1,6 @@
// Copyright (C) 2009 BRAT Tech LLC
-nglr.Scope = function(initialState, name) {
+Scope = function(initialState, name) {
this.widgets = [];
this.watchListeners = {};
this.name = name;
@@ -14,9 +14,9 @@ nglr.Scope = function(initialState, name) {
}
};
-nglr.Scope.expressionCache = {};
+Scope.expressionCache = {};
-nglr.Scope.prototype.updateView = function() {
+Scope.prototype.updateView = function() {
var self = this;
this.fireWatchers();
_.each(this.widgets, function(widget){
@@ -26,21 +26,21 @@ nglr.Scope.prototype.updateView = function() {
});
};
-nglr.Scope.prototype.addWidget = function(controller) {
+Scope.prototype.addWidget = function(controller) {
if (controller) this.widgets.push(controller);
};
-nglr.Scope.prototype.isProperty = function(exp) {
+Scope.prototype.isProperty = function(exp) {
for ( var i = 0; i < exp.length; i++) {
var ch = exp.charAt(i);
- if (ch!='.' && !nglr.Lexer.prototype.isIdent(ch)) {
+ if (ch!='.' && !Lexer.prototype.isIdent(ch)) {
return false;
}
}
return true;
};
-nglr.Scope.getter = function(instance, path) {
+Scope.getter = function(instance, path) {
if (!path) return instance;
var element = path.split('.');
var key;
@@ -65,16 +65,16 @@ nglr.Scope.getter = function(instance, path) {
}
}
if (typeof instance === 'function' && !instance.$$factory) {
- return nglr.bind(lastInstance, instance);
+ return bind(lastInstance, instance);
}
return instance;
};
-nglr.Scope.prototype.get = function(path) {
- return nglr.Scope.getter(this.state, path);
+Scope.prototype.get = function(path) {
+ return Scope.getter(this.state, path);
};
-nglr.Scope.prototype.set = function(path, value) {
+Scope.prototype.set = function(path, value) {
var element = path.split('.');
var instance = this.state;
for ( var i = 0; element.length > 1; i++) {
@@ -90,17 +90,17 @@ nglr.Scope.prototype.set = function(path, value) {
return value;
};
-nglr.Scope.prototype.setEval = function(expressionText, value) {
- this.eval(expressionText + "=" + nglr.toJson(value));
+Scope.prototype.setEval = function(expressionText, value) {
+ this.eval(expressionText + "=" + toJson(value));
};
-nglr.Scope.prototype.eval = function(expressionText, context) {
- var expression = nglr.Scope.expressionCache[expressionText];
+Scope.prototype.eval = function(expressionText, context) {
+ var expression = Scope.expressionCache[expressionText];
if (!expression) {
- var parser = new nglr.Parser(expressionText);
+ var parser = new Parser(expressionText);
expression = parser.statements();
parser.assertAllConsumed();
- nglr.Scope.expressionCache[expressionText] = expression;
+ Scope.expressionCache[expressionText] = expression;
}
context = context || {};
context.scope = this;
@@ -110,7 +110,7 @@ nglr.Scope.prototype.eval = function(expressionText, context) {
//TODO: Refactor. This function needs to be an execution closure for widgets
// move to widgets
// remove expression, just have inner closure.
-nglr.Scope.prototype.evalWidget = function(widget, expression, context, onSuccess, onFailure) {
+Scope.prototype.evalWidget = function(widget, expression, context, onSuccess, onFailure) {
try {
var value = this.eval(expression, context);
if (widget.hasError) {
@@ -125,7 +125,7 @@ nglr.Scope.prototype.evalWidget = function(widget, expression, context, onSucces
return true;
} catch (e){
console.error('Eval Widget Error:', e);
- var jsonError = nglr.toJson(e, true);
+ var jsonError = toJson(e, true);
widget.hasError = true;
jQuery(widget.view).
addClass('ng-exception').
@@ -137,42 +137,42 @@ nglr.Scope.prototype.evalWidget = function(widget, expression, context, onSucces
}
};
-nglr.Scope.prototype.validate = function(expressionText, value) {
- var expression = nglr.Scope.expressionCache[expressionText];
+Scope.prototype.validate = function(expressionText, value) {
+ var expression = Scope.expressionCache[expressionText];
if (!expression) {
- expression = new nglr.Parser(expressionText).validator();
- nglr.Scope.expressionCache[expressionText] = expression;
+ expression = new Parser(expressionText).validator();
+ Scope.expressionCache[expressionText] = expression;
}
var self = {scope:this};
return expression(self)(self, value);
};
-nglr.Scope.prototype.entity = function(entityDeclaration) {
- var expression = new nglr.Parser(entityDeclaration).entityDeclaration();
+Scope.prototype.entity = function(entityDeclaration) {
+ var expression = new Parser(entityDeclaration).entityDeclaration();
return expression({scope:this});
};
-nglr.Scope.prototype.markInvalid = function(widget) {
+Scope.prototype.markInvalid = function(widget) {
this.state.$invalidWidgets.push(widget);
};
-nglr.Scope.prototype.watch = function(declaration) {
+Scope.prototype.watch = function(declaration) {
var self = this;
- new nglr.Parser(declaration).watch()({
+ new Parser(declaration).watch()({
scope:this,
addListener:function(watch, exp){
self.addWatchListener(watch, function(n,o){
try {
return exp({scope:self}, n, o);
} catch(e) {
- nglr.alert(e);
+ alert(e);
}
});
}
});
};
-nglr.Scope.prototype.addWatchListener = function(watchExpression, listener) {
+Scope.prototype.addWatchListener = function(watchExpression, listener) {
var watcher = this.watchListeners[watchExpression];
if (!watcher) {
watcher = {listeners:[], expression:watchExpression};
@@ -181,7 +181,7 @@ nglr.Scope.prototype.addWatchListener = function(watchExpression, listener) {
watcher.listeners.push(listener);
};
-nglr.Scope.prototype.fireWatchers = function() {
+Scope.prototype.fireWatchers = function() {
var self = this;
var fired = false;
jQuery.each(this.watchListeners, function(name, watcher) {
diff --git a/src/Server.js b/src/Server.js
index 94b0cc10..d00f893b 100644
--- a/src/Server.js
+++ b/src/Server.js
@@ -1,6 +1,6 @@
// Copyright (C) 2008,2009 BRAT Tech LLC
-nglr.Server = function(url, getScript) {
+Server = function(url, getScript) {
this.url = url;
this.nextId = 0;
this.getScript = getScript;
@@ -8,51 +8,51 @@ nglr.Server = function(url, getScript) {
this.maxSize = 1800;
};
-nglr.Server.prototype.base64url = function(txt) {
+Server.prototype.base64url = function(txt) {
return Base64.encode(txt);
};
-nglr.Server.prototype.request = function(method, url, request, callback) {
+Server.prototype.request = function(method, url, request, callback) {
var requestId = this.uuid + (this.nextId++);
- nglr[requestId] = function(response) {
- delete nglr[requestId];
+ callbacks[requestId] = function(response) {
+ delete angular[requestId];
callback(200, response);
};
var payload = {u:url, m:method, p:request};
- payload = this.base64url(nglr.toJson(payload));
+ payload = this.base64url(toJson(payload));
var totalPockets = Math.ceil(payload.length / this.maxSize);
var baseUrl = this.url + "/$/" + requestId + "/" + totalPockets + "/";
for ( var pocketNo = 0; pocketNo < totalPockets; pocketNo++) {
var pocket = payload.substr(pocketNo * this.maxSize, this.maxSize);
- this.getScript(baseUrl + (pocketNo+1) + "?h=" + pocket, nglr.noop);
+ this.getScript(baseUrl + (pocketNo+1) + "?h=" + pocket, noop);
}
};
-nglr.FrameServer = function(frame) {
+FrameServer = function(frame) {
this.frame = frame;
};
-nglr.FrameServer.PREFIX = "$DATASET:";
+FrameServer.PREFIX = "$DATASET:";
-nglr.FrameServer.prototype = {
+FrameServer.prototype = {
read:function(){
- this.data = nglr.fromJson(this.frame.name.substr(nglr.FrameServer.PREFIX.length));
+ this.data = fromJson(this.frame.name.substr(FrameServer.PREFIX.length));
},
write:function(){
- this.frame.name = nglr.FrameServer.PREFIX + nglr.toJson(this.data);
+ this.frame.name = FrameServer.PREFIX + toJson(this.data);
},
request: function(method, url, request, callback) {
- //alert(method + " " + url + " " + nglr.toJson(request) + " " + nglr.toJson(callback));
+ //alert(method + " " + url + " " + toJson(request) + " " + toJson(callback));
}
};
-nglr.VisualServer = function(delegate, status, update) {
+VisualServer = function(delegate, status, update) {
this.delegate = delegate;
this.update = update;
this.status = status;
};
-nglr.VisualServer.prototype = {
+VisualServer.prototype = {
request:function(method, url, request, callback) {
var self = this;
this.status.beginRequest(request);
@@ -61,7 +61,7 @@ nglr.VisualServer.prototype = {
try {
callback.apply(this, arguments);
} catch (e) {
- nglr.alert(nglr.toJson(e));
+ alert(toJson(e));
}
self.update();
});
diff --git a/src/Users.js b/src/Users.js
index c0c15848..d10b96df 100644
--- a/src/Users.js
+++ b/src/Users.js
@@ -1,10 +1,10 @@
// Copyright (C) 2008,2009 BRAT Tech LLC
-nglr.Users = function(server, controlBar) {
+Users = function(server, controlBar) {
this.server = server;
this.controlBar = controlBar;
};
-nglr.Users.prototype = {
+Users.prototype = {
fetchCurrentUser:function(callback) {
var self = this;
this.server.request("GET", "/account.json", {}, function(code, response){
@@ -17,7 +17,7 @@ nglr.Users.prototype = {
var self = this;
this.controlBar.logout(function(){
delete self.current;
- (callback||nglr.noop)();
+ (callback||noop)();
});
},
@@ -25,7 +25,7 @@ nglr.Users.prototype = {
var self = this;
this.controlBar.login(function(){
self.fetchCurrentUser(function(){
- (callback||nglr.noop)();
+ (callback||noop)();
});
});
},
diff --git a/src/Validators.js b/src/Validators.js
index 94cb1d52..7cfaa2b4 100644
--- a/src/Validators.js
+++ b/src/Validators.js
@@ -72,7 +72,7 @@ angular.validator.url = function(value) {
angular.validator.json = function(value) {
try {
- nglr.fromJson(value);
+ fromJson(value);
return null;
} catch (e) {
return e.toString();
diff --git a/src/Widgets.js b/src/Widgets.js
index de74533a..3a0f2845 100644
--- a/src/Widgets.js
+++ b/src/Widgets.js
@@ -1,7 +1,7 @@
// Copyright (C) 2009 BRAT Tech LLC
-nglr.WidgetFactory = function(serverUrl, database) {
+WidgetFactory = function(serverUrl, database) {
this.nextUploadId = 0;
this.serverUrl = serverUrl;
this.database = database;
@@ -9,7 +9,7 @@ nglr.WidgetFactory = function(serverUrl, database) {
this.onChangeListener = function(){};
};
-nglr.WidgetFactory.prototype.createController = function(input, scope) {
+WidgetFactory.prototype.createController = function(input, scope) {
var controller;
var type = input.attr('type').toLowerCase();
var exp = input.attr('name');
@@ -17,22 +17,22 @@ nglr.WidgetFactory.prototype.createController = function(input, scope) {
var event = "change";
var bubbleEvent = true;
if (type == 'button' || type == 'submit' || type == 'reset' || type == 'image') {
- controller = new nglr.ButtonController(input[0], exp);
+ controller = new ButtonController(input[0], exp);
event = "click";
bubbleEvent = false;
} else if (type == 'text' || type == 'textarea' || type == 'hidden' || type == 'password') {
- controller = new nglr.TextController(input[0], exp);
+ controller = new TextController(input[0], exp);
event = "keyup change";
} else if (type == 'checkbox') {
- controller = new nglr.CheckboxController(input[0], exp);
+ controller = new CheckboxController(input[0], exp);
event = "click";
} else if (type == 'radio') {
- controller = new nglr.RadioController(input[0], exp);
+ controller = new RadioController(input[0], exp);
event="click";
} else if (type == 'select-one') {
- controller = new nglr.SelectController(input[0], exp);
+ controller = new SelectController(input[0], exp);
} else if (type == 'select-multiple') {
- controller = new nglr.MultiSelectController(input[0], exp);
+ controller = new MultiSelectController(input[0], exp);
} else if (type == 'file') {
controller = this.createFileController(input, exp);
} else {
@@ -54,9 +54,9 @@ nglr.WidgetFactory.prototype.createController = function(input, scope) {
return controller;
};
-nglr.WidgetFactory.prototype.createFileController = function(fileInput) {
+WidgetFactory.prototype.createFileController = function(fileInput) {
var uploadId = '__uploadWidget_' + (this.nextUploadId++);
- var view = nglr.FileController.template(uploadId);
+ var view = FileController.template(uploadId);
fileInput.after(view);
var att = {
data:this.serverUrl + "/admin/ServerAPI.swf",
@@ -67,13 +67,13 @@ nglr.WidgetFactory.prototype.createFileController = function(fileInput) {
allowScriptAccess:"always"};
var swfNode = this.createSWF(att, par, uploadId);
fileInput.remove();
- var cntl = new nglr.FileController(view, fileInput[0].name, swfNode, this.serverUrl + "/data/" + this.database);
+ var cntl = new FileController(view, fileInput[0].name, swfNode, this.serverUrl + "/data/" + this.database);
jQuery(swfNode).data('controller', cntl);
return cntl;
};
-nglr.WidgetFactory.prototype.createTextWidget = function(textInput) {
- var controller = new nglr.TextController(textInput);
+WidgetFactory.prototype.createTextWidget = function(textInput) {
+ var controller = new TextController(textInput);
controller.onChange(this.onChangeListener);
return controller;
};
@@ -82,7 +82,7 @@ nglr.WidgetFactory.prototype.createTextWidget = function(textInput) {
// FileController
///////////////////////
-nglr.FileController = function(view, scopeName, uploader, databaseUrl) {
+FileController = function(view, scopeName, uploader, databaseUrl) {
this.view = view;
this.uploader = uploader;
this.scopeName = scopeName;
@@ -91,13 +91,13 @@ nglr.FileController = function(view, scopeName, uploader, databaseUrl) {
this.lastValue = undefined;
};
-nglr.FileController.dispatchEvent = function(id, event, args) {
+FileController.dispatchEvent = function(id, event, args) {
var object = document.getElementById(id);
var controller = jQuery(object).data("controller");
- nglr.FileController.prototype['_on_' + event].apply(controller, args);
+ FileController.prototype['_on_' + event].apply(controller, args);
};
-nglr.FileController.template = function(id) {
+FileController.template = function(id) {
return jQuery('
' +
'' +
'' +
@@ -106,33 +106,33 @@ nglr.FileController.template = function(id) {
'');
};
-nglr.FileController.prototype._on_cancel = function() {
+FileController.prototype._on_cancel = function() {
};
-nglr.FileController.prototype._on_complete = function() {
+FileController.prototype._on_complete = function() {
};
-nglr.FileController.prototype._on_httpStatus = function(status) {
- nglr.alert("httpStatus:" + this.scopeName + " status:" + status);
+FileController.prototype._on_httpStatus = function(status) {
+ alert("httpStatus:" + this.scopeName + " status:" + status);
};
-nglr.FileController.prototype._on_ioError = function() {
- nglr.alert("ioError:" + this.scopeName);
+FileController.prototype._on_ioError = function() {
+ alert("ioError:" + this.scopeName);
};
-nglr.FileController.prototype._on_open = function() {
- nglr.alert("open:" + this.scopeName);
+FileController.prototype._on_open = function() {
+ alert("open:" + this.scopeName);
};
-nglr.FileController.prototype._on_progress = function(bytesLoaded, bytesTotal) {
+FileController.prototype._on_progress = function(bytesLoaded, bytesTotal) {
};
-nglr.FileController.prototype._on_securityError = function() {
- nglr.alert("securityError:" + this.scopeName);
+FileController.prototype._on_securityError = function() {
+ alert("securityError:" + this.scopeName);
};
-nglr.FileController.prototype._on_uploadCompleteData = function(data) {
- var value = nglr.fromJson(data);
+FileController.prototype._on_uploadCompleteData = function(data) {
+ var value = fromJson(data);
value.url = this.attachmentsPath + '/' + value.id + '/' + value.text;
this.view.find("input").attr('checked', true);
var scope = this.view.scope();
@@ -142,14 +142,14 @@ nglr.FileController.prototype._on_uploadCompleteData = function(data) {
scope.get('$binder').updateView();
};
-nglr.FileController.prototype._on_select = function(name, size, type) {
+FileController.prototype._on_select = function(name, size, type) {
this.name = name;
this.view.find("a").text(name).attr('href', name);
this.view.find("span").text(angular.filter.bytes(size));
this.upload();
};
-nglr.FileController.prototype.updateModel = function(scope) {
+FileController.prototype.updateModel = function(scope) {
var isChecked = this.view.find("input").attr('checked');
var value = isChecked ? this.value : null;
if (this.lastValue === value) {
@@ -160,7 +160,7 @@ nglr.FileController.prototype.updateModel = function(scope) {
}
};
-nglr.FileController.prototype.updateView = function(scope) {
+FileController.prototype.updateView = function(scope) {
var modelValue = scope.get(this.scopeName);
if (modelValue && this.value !== modelValue) {
this.value = modelValue;
@@ -172,7 +172,7 @@ nglr.FileController.prototype.updateView = function(scope) {
this.view.find("input").attr('checked', !!modelValue);
};
-nglr.FileController.prototype.upload = function() {
+FileController.prototype.upload = function() {
if (this.name) {
this.uploader.uploadFile(this.attachmentsPath);
}
@@ -182,23 +182,23 @@ nglr.FileController.prototype.upload = function() {
///////////////////////
// NullController
///////////////////////
-nglr.NullController = function(view) {this.view = view;};
-nglr.NullController.prototype.updateModel = function() { return true; };
-nglr.NullController.prototype.updateView = function() { };
-nglr.NullController.instance = new nglr.NullController();
+NullController = function(view) {this.view = view;};
+NullController.prototype.updateModel = function() { return true; };
+NullController.prototype.updateView = function() { };
+NullController.instance = new NullController();
///////////////////////
// ButtonController
///////////////////////
-nglr.ButtonController = function(view) {this.view = view;};
-nglr.ButtonController.prototype.updateModel = function(scope) { return true; };
-nglr.ButtonController.prototype.updateView = function(scope) {};
+ButtonController = function(view) {this.view = view;};
+ButtonController.prototype.updateModel = function(scope) { return true; };
+ButtonController.prototype.updateView = function(scope) {};
///////////////////////
// TextController
///////////////////////
-nglr.TextController = function(view, exp) {
+TextController = function(view, exp) {
this.view = view;
this.exp = exp;
this.validator = view.getAttribute('ng-validate');
@@ -212,7 +212,7 @@ nglr.TextController = function(view, exp) {
}
};
-nglr.TextController.prototype.updateModel = function(scope) {
+TextController.prototype.updateModel = function(scope) {
var value = this.view.value;
if (this.lastValue === value) {
return false;
@@ -223,7 +223,7 @@ nglr.TextController.prototype.updateModel = function(scope) {
}
};
-nglr.TextController.prototype.updateView = function(scope) {
+TextController.prototype.updateView = function(scope) {
var view = this.view;
var value = scope.get(this.exp);
if (typeof value === "undefined") {
@@ -258,14 +258,14 @@ nglr.TextController.prototype.updateView = function(scope) {
///////////////////////
// CheckboxController
///////////////////////
-nglr.CheckboxController = function(view, exp) {
+CheckboxController = function(view, exp) {
this.view = view;
this.exp = exp;
this.lastValue = undefined;
this.initialValue = view.checked ? view.value : "";
};
-nglr.CheckboxController.prototype.updateModel = function(scope) {
+CheckboxController.prototype.updateModel = function(scope) {
var input = this.view;
var value = input.checked ? input.value : '';
if (this.lastValue === value) {
@@ -277,7 +277,7 @@ nglr.CheckboxController.prototype.updateModel = function(scope) {
}
};
-nglr.CheckboxController.prototype.updateView = function(scope) {
+CheckboxController.prototype.updateView = function(scope) {
var input = this.view;
var value = scope.eval(this.exp);
if (typeof value === "undefined") {
@@ -290,14 +290,14 @@ nglr.CheckboxController.prototype.updateView = function(scope) {
///////////////////////
// SelectController
///////////////////////
-nglr.SelectController = function(view, exp) {
+SelectController = function(view, exp) {
this.view = view;
this.exp = exp;
this.lastValue = undefined;
this.initialValue = view.value;
};
-nglr.SelectController.prototype.updateModel = function(scope) {
+SelectController.prototype.updateModel = function(scope) {
var input = this.view;
if (input.selectedIndex < 0) {
scope.setEval(this.exp, null);
@@ -313,7 +313,7 @@ nglr.SelectController.prototype.updateModel = function(scope) {
}
};
-nglr.SelectController.prototype.updateView = function(scope) {
+SelectController.prototype.updateView = function(scope) {
var input = this.view;
var value = scope.get(this.exp);
if (typeof value === 'undefined') {
@@ -329,14 +329,14 @@ nglr.SelectController.prototype.updateView = function(scope) {
///////////////////////
// MultiSelectController
///////////////////////
-nglr.MultiSelectController = function(view, exp) {
+MultiSelectController = function(view, exp) {
this.view = view;
this.exp = exp;
this.lastValue = undefined;
this.initialValue = this.selected();
};
-nglr.MultiSelectController.prototype.selected = function () {
+MultiSelectController.prototype.selected = function () {
var value = [];
var options = this.view.options;
for ( var i = 0; i < options.length; i++) {
@@ -348,7 +348,7 @@ nglr.MultiSelectController.prototype.selected = function () {
return value;
};
-nglr.MultiSelectController.prototype.updateModel = function(scope) {
+MultiSelectController.prototype.updateModel = function(scope) {
var value = this.selected();
// TODO: This is wrong! no caching going on here as we are always comparing arrays
if (this.lastValue === value) {
@@ -360,7 +360,7 @@ nglr.MultiSelectController.prototype.updateModel = function(scope) {
}
};
-nglr.MultiSelectController.prototype.updateView = function(scope) {
+MultiSelectController.prototype.updateView = function(scope) {
var input = this.view;
var selected = scope.get(this.exp);
if (typeof selected === "undefined") {
@@ -380,7 +380,7 @@ nglr.MultiSelectController.prototype.updateView = function(scope) {
///////////////////////
// RadioController
///////////////////////
-nglr.RadioController = function(view, exp) {
+RadioController = function(view, exp) {
this.view = view;
this.exp = exp;
this.lastChecked = undefined;
@@ -389,7 +389,7 @@ nglr.RadioController = function(view, exp) {
this.initialValue = view.checked ? view.value : null;
};
-nglr.RadioController.prototype.updateModel = function(scope) {
+RadioController.prototype.updateModel = function(scope) {
var input = this.view;
if (this.lastChecked) {
return false;
@@ -401,7 +401,7 @@ nglr.RadioController.prototype.updateModel = function(scope) {
}
};
-nglr.RadioController.prototype.updateView = function(scope) {
+RadioController.prototype.updateView = function(scope) {
var input = this.view;
var value = scope.get(this.exp);
if (this.initialValue && typeof value === "undefined") {
@@ -417,25 +417,25 @@ nglr.RadioController.prototype.updateView = function(scope) {
///////////////////////
//ElementController
///////////////////////
-nglr.BindUpdater = function(view, exp) {
+BindUpdater = function(view, exp) {
this.view = view;
- this.exp = nglr.Binder.parseBindings(exp);
+ this.exp = Binder.parseBindings(exp);
this.hasError = false;
this.scopeSelf = {element:view};
};
-nglr.BindUpdater.toText = function(obj) {
- var e = nglr.escapeHtml;
+BindUpdater.toText = function(obj) {
+ var e = escapeHtml;
switch(typeof obj) {
case "string":
case "boolean":
case "number":
return e(obj);
case "function":
- return nglr.BindUpdater.toText(obj());
+ return BindUpdater.toText(obj());
case "object":
- if (nglr.isNode(obj)) {
- return nglr.outerHTML(obj);
+ if (isNode(obj)) {
+ return outerHTML(obj);
} else if (obj instanceof angular.filter.Meta) {
switch(typeof obj.html) {
case "string":
@@ -444,8 +444,8 @@ nglr.BindUpdater.toText = function(obj) {
case "function":
return obj.html();
case "object":
- if (nglr.isNode(obj.html))
- return nglr.outerHTML(obj.html);
+ if (isNode(obj.html))
+ return outerHTML(obj.html);
default:
break;
}
@@ -461,43 +461,43 @@ nglr.BindUpdater.toText = function(obj) {
}
if (obj === null)
return "";
- return e(nglr.toJson(obj, true));
+ return e(toJson(obj, true));
default:
return "";
}
};
-nglr.BindUpdater.prototype.updateModel = function(scope) {};
-nglr.BindUpdater.prototype.updateView = function(scope) {
+BindUpdater.prototype.updateModel = function(scope) {};
+BindUpdater.prototype.updateView = function(scope) {
var html = [];
var parts = this.exp;
var length = parts.length;
for(var i=0; i
loading....
';
+Status.DOM ='
loading....
';
-nglr.Status.prototype.beginRequest = function () {
+Status.prototype.beginRequest = function () {
if (this.requestCount === 0) {
this.loader.show();
}
this.requestCount++;
};
-nglr.Status.prototype.endRequest = function () {
+Status.prototype.endRequest = function () {
this.requestCount--;
if (this.requestCount === 0) {
this.loader.hide("fold");
diff --git a/src/Widgets.js.orig b/src/Widgets.js.orig
deleted file mode 100644
index df1d3e40..00000000
--- a/src/Widgets.js.orig
+++ /dev/null
@@ -1,764 +0,0 @@
- // Copyright (C) 2009 BRAT Tech LLC
-
-
-nglr.WidgetFactory = function(serverUrl) {
- this.nextUploadId = 0;
- this.serverUrl = serverUrl;
- this.createSWF = swfobject.createSWF;
- this.onChangeListener = function(){};
-};
-
-nglr.WidgetFactory.prototype.createController = function(input, scope) {
- var controller;
- var type = input.attr('type').toLowerCase();
- var exp = input.attr('name');
- if (exp) exp = exp.split(':').pop();
- var event = "change";
- var bubbleEvent = true;
- if (type == 'button' || type == 'submit' || type == 'reset') {
- controller = new nglr.ButtonController(input[0], exp);
- event = "click";
- bubbleEvent = false;
- } else if (type == 'text' || type == 'textarea') {
- controller = new nglr.TextController(input[0], exp);
- event = "keyup change";
- } else if (type == 'checkbox') {
- controller = new nglr.CheckboxController(input[0], exp);
- event = "click";
- } else if (type == 'radio') {
- controller = new nglr.RadioController(input[0], exp);
- event="click";
- } else if (type == 'select-one') {
- controller = new nglr.SelectController(input[0], exp);
- } else if (type == 'select-multiple') {
- controller = new nglr.MultiSelectController(input[0], exp);
- } else if (type == 'file') {
- controller = this.createFileController(input, exp);
- } else {
- throw 'Unknown type: ' + type;
- }
- input.data('controller', controller);
- var binder = scope.get('$binder');
- var action = function() {
- if (controller.updateModel(scope)) {
- var action = jQuery(controller.view).attr('ng-action') || "";
- if (scope.evalWidget(controller, action)) {
- binder.updateView(scope);
- }
- }
- return bubbleEvent;
- };
- jQuery(controller.view, ":input").
- bind(event, action);
- return controller;
-};
-
-nglr.WidgetFactory.prototype.createFileController = function(fileInput) {
- var uploadId = '__uploadWidget_' + (this.nextUploadId++);
- var view = nglr.FileController.template(uploadId);
- fileInput.after(view);
- var att = {
- data:this.serverUrl + "/admin/ServerAPI.swf",
- width:"95", height:"20", align:"top",
- wmode:"transparent"};
- var par = {
- flashvars:"uploadWidgetId=" + uploadId,
- allowScriptAccess:"always"};
- var swfNode = this.createSWF(att, par, uploadId);
- fileInput.remove();
- var cntl = new nglr.FileController(view, fileInput[0].name, swfNode, this.serverUrl);
- jQuery(swfNode).data('controller', cntl);
- return cntl;
-};
-
-nglr.WidgetFactory.prototype.createTextWidget = function(textInput) {
- var controller = new nglr.TextController(textInput);
- controller.onChange(this.onChangeListener);
- return controller;
-};
-
-/////////////////////
-// FileController
-///////////////////////
-
-nglr.FileController = function(view, scopeName, uploader, serverUrl) {
- this.view = view;
- this.uploader = uploader;
- this.scopeName = scopeName;
- this.uploadUrl = serverUrl + '/upload';
- this.attachmentBase = serverUrl + '/attachments';
- this.value = null;
- this.lastValue = undefined;
-};
-
-nglr.FileController.dispatchEvent = function(id, event, args) {
- var object = document.getElementById(id);
- var controller = jQuery(object).data("controller");
- nglr.FileController.prototype['_on_' + event].apply(controller, args);
-};
-
-nglr.FileController.template = function(id) {
- return jQuery('
' +
- '' +
- '' +
- '' +
- '' +
- '');
-};
-
-nglr.FileController.prototype._on_cancel = function() {
-};
-
-nglr.FileController.prototype._on_complete = function() {
-};
-
-nglr.FileController.prototype._on_httpStatus = function(status) {
- nglr.alert("httpStatus:" + this.scopeName + " status:" + status);
-};
-
-nglr.FileController.prototype._on_ioError = function() {
- nglr.alert("ioError:" + this.scopeName);
-};
-
-nglr.FileController.prototype._on_open = function() {
- nglr.alert("open:" + this.scopeName);
-};
-
-nglr.FileController.prototype._on_progress = function(bytesLoaded, bytesTotal) {
-};
-
-nglr.FileController.prototype._on_securityError = function() {
- nglr.alert("securityError:" + this.scopeName);
-};
-
-nglr.FileController.prototype._on_uploadCompleteData = function(data) {
- this.value = nglr.fromJson(data);
- this.value.url = this.attachmentBase + '/' + this.value.id + '/' + this.value.text;
- this.view.find("input").attr('checked', true);
- var scope = this.view.scope();
- this.updateModel(scope);
- scope.get('$binder').updateView();
-};
-
-nglr.FileController.prototype._on_select = function(name, size, type) {
- this.name = name;
- this.view.find("a").text(name).attr('href', name);
- this.view.find("span").text(filters.bytes(size));
- this.upload();
-};
-
-nglr.FileController.prototype.updateModel = function(scope) {
- var isChecked = this.view.find("input").attr('checked');
- var value = isChecked ? this.value : null;
- if (this.lastValue === value) {
- return false;
- } else {
- scope.set(this.scopeName, value);
- return true;
- }
-};
-
-nglr.FileController.prototype.updateView = function(scope) {
- var modelValue = scope.get(this.scopeName);
- if (modelValue && this.value !== modelValue) {
- this.value = modelValue;
- this.view.find("a").
- attr("href", this.value.url).
- text(this.value.name);
- this.view.find("span").text(filters.bytes(this.value.size));
- }
- this.view.find("input").attr('checked', !!modelValue);
-};
-
-nglr.FileController.prototype.upload = function() {
- if (this.name) {
- this.uploader.uploadFile(this.uploadUrl);
- }
-};
-
-
-///////////////////////
-// NullController
-///////////////////////
-nglr.NullController = function(view) {this.view = view;};
-nglr.NullController.prototype.updateModel = function() { return true; };
-nglr.NullController.prototype.updateView = function() { };
-nglr.NullController.instance = new nglr.NullController();
-
-
-///////////////////////
-// ButtonController
-///////////////////////
-nglr.ButtonController = function(view) {this.view = view;};
-nglr.ButtonController.prototype.updateModel = function(scope) { return true; };
-nglr.ButtonController.prototype.updateView = function(scope) {};
-
-///////////////////////
-// TextController
-///////////////////////
-nglr.TextController = function(view, exp) {
- this.view = view;
- this.exp = exp;
- this.validator = view.getAttribute('ng-validate');
- this.required = typeof view.attributes['ng-required'] != "undefined";
- this.lastErrorText = null;
- this.lastValue = undefined;
- this.initialValue = view.value;
- var widget = view.getAttribute('ng-widget');
- if (widget === 'datepicker') {
- jQuery(view).datepicker();
- }
-};
-
-nglr.TextController.prototype.updateModel = function(scope) {
- var value = this.view.value;
- if (this.lastValue === value) {
- return false;
- } else {
- scope.set(this.exp, value);
- this.lastValue = value;
- return true;
- }
-};
-
-nglr.TextController.prototype.updateView = function(scope) {
- var view = this.view;
- var value = scope.get(this.exp);
- if (typeof value === "undefined") {
- value = this.initialValue;
- scope.set(this.exp, value);
- }
- value = value ? value : '';
- if (this.lastValue != value) {
- view.value = value;
- this.lastValue = value;
- }
- var isValidationError = false;
- view.removeAttribute('ng-error');
- if (this.required) {
- isValidationError = !(value && value.length > 0);
- }
- var errorText = isValidationError ? "Required Value" : null;
- if (!isValidationError && this.validator && value) {
- errorText = scope.validate(this.validator, value);
- isValidationError = !!errorText;
- }
- if (this.lastErrorText !== errorText) {
- this.lastErrorText = isValidationError;
- if (errorText !== null) {
- view.setAttribute('ng-error', errorText);
- scope.markInvalid(this);
- }
- jQuery(view).toggleClass('ng-validation-error', isValidationError);
- }
-};
-
-///////////////////////
-// CheckboxController
-///////////////////////
-nglr.CheckboxController = function(view, exp) {
- this.view = view;
- this.exp = exp;
- this.lastValue = undefined;
- this.initialValue = view.checked ? view.value : "";
-};
-
-nglr.CheckboxController.prototype.updateModel = function(scope) {
- var input = this.view;
- var value = input.checked ? input.value : '';
- if (this.lastValue === value) {
- return false;
- } else {
- scope.setEval(this.exp, value);
- this.lastValue = value;
- return true;
- }
-};
-
-nglr.CheckboxController.prototype.updateView = function(scope) {
- var input = this.view;
- var value = scope.eval(this.exp);
- if (typeof value === "undefined") {
- value = this.initialValue;
- scope.setEval(this.exp, value);
- }
- input.checked = input.value == (''+value);
-};
-
-///////////////////////
-// SelectController
-///////////////////////
-nglr.SelectController = function(view, exp) {
- this.view = view;
- this.exp = exp;
- this.lastValue = undefined;
- this.initialValue = view.value;
-};
-
-nglr.SelectController.prototype.updateModel = function(scope) {
- var input = this.view;
- if (input.selectedIndex < 0) {
- scope.set(this.exp, null);
- } else {
- var value = this.view.value;
- if (this.lastValue === value) {
- return false;
- } else {
- scope.set(this.exp, value);
- this.lastValue = value;
- return true;
- }
- }
-};
-
-nglr.SelectController.prototype.updateView = function(scope) {
- var input = this.view;
- var value = scope.get(this.exp);
- if (typeof value === 'undefined') {
- value = this.initialValue;
- scope.set(this.exp, value);
- }
- if (value !== this.lastValue) {
- input.value = value ? value : "";
- this.lastValue = value;
- }
-};
-
-///////////////////////
-// MultiSelectController
-///////////////////////
-nglr.MultiSelectController = function(view, exp) {
- this.view = view;
- this.exp = exp;
- this.lastValue = undefined;
- this.initialValue = this.selected();
-};
-
-nglr.MultiSelectController.prototype.selected = function () {
- var value = [];
- var options = this.view.options;
- for ( var i = 0; i < options.length; i++) {
- var option = options[i];
- if (option.selected) {
- value.push(option.value);
- }
- }
- return value;
-};
-
-nglr.MultiSelectController.prototype.updateModel = function(scope) {
- var value = this.selected();
- // TODO: This is wrong! no caching going on here as we are always comparing arrays
- if (this.lastValue === value) {
- return false;
- } else {
- scope.set(this.exp, value);
- this.lastValue = value;
- return true;
- }
-};
-
-nglr.MultiSelectController.prototype.updateView = function(scope) {
- var input = this.view;
- var selected = scope.get(this.exp);
- if (typeof selected === "undefined") {
- selected = this.initialValue;
- scope.set(this.exp, selected);
- }
- if (selected !== this.lastValue) {
- var options = input.options;
- for ( var i = 0; i < options.length; i++) {
- var option = options[i];
- option.selected = selected.contains(option.value);
- }
- this.lastValue = selected;
- }
-};
-
-///////////////////////
-// RadioController
-///////////////////////
-nglr.RadioController = function(view, exp) {
- this.view = view;
- this.exp = exp;
- this.lastChecked = undefined;
- this.lastValue = undefined;
- this.inputValue = view.value;
- this.initialValue = view.checked ? view.value : null;
-};
-
-nglr.RadioController.prototype.updateModel = function(scope) {
- var input = this.view;
- if (this.lastChecked) {
- return false;
- } else {
- input.checked = true;
- this.lastValue = scope.set(this.exp, this.inputValue);
- this.lastChecked = true;
- return true;
- }
-};
-
-nglr.RadioController.prototype.updateView = function(scope) {
- var input = this.view;
- var value = scope.get(this.exp);
- if (this.initialValue && typeof value === "undefined") {
- value = this.initialValue;
- scope.set(this.exp, value);
- }
- if (this.lastValue != value) {
- this.lastChecked = input.checked = this.inputValue == (''+value);
- this.lastValue = value;
- }
-};
-
-///////////////////////
-//ElementController
-///////////////////////
-nglr.BindUpdater = function(view, exp) {
- this.view = view;
- this.exp = exp.parseBindings();
- this.hasError = false;
- this.scopeSelf = {element:view};
-};
-
-nglr.BindUpdater.toText = function(obj) {
- var e = nglr.escapeHtml;
- switch(typeof obj) {
- case "string":
- case "boolean":
- case "number":
- return e(obj);
- case "function":
- return nglr.BindUpdater.toText(obj());
- case "object":
- if (nglr.isNode(obj)) {
- return nglr.outerHTML(obj);
- } else if (obj && obj.TAG === filters.Meta.TAG) {
- switch(typeof obj.html) {
- case "string":
- case "number":
- return obj.html;
- case "function":
- return obj.html();
- default:
- break;
- }
- switch(typeof obj.text) {
- case "string":
- case "number":
- return e(obj.text);
- case "function":
- return e(obj.text());
- default:
- break;
- }
- }
- if (obj === null)
- return "";
- return e(nglr.toJson(obj, true));
- default:
- return "";
- }
-};
-
-nglr.BindUpdater.prototype.updateModel = function(scope) {};
-nglr.BindUpdater.prototype.updateView = function(scope) {
- var html = [];
- var parts = this.exp;
- var length = parts.length;
- for(var i=0; i
iteratorLength; --r) {
- var unneeded = this.children.pop();
- unneeded.element.removeNode();
- }
- // Special case for option in select
- if (child && child.element[0].nodeName === "OPTION") {
- var select = jQuery(child.element[0].parentNode);
- var cntl = select.data('controller');
- if (cntl) {
- cntl.lastValue = undefined;
- cntl.updateView(scope);
- }
- }
- });
-};
-
-//////////////////////////////////
-// PopUp
-//////////////////////////////////
-
-nglr.PopUp = function(doc) {
- this.doc = doc;
-};
-
-nglr.PopUp.OUT_EVENT = "mouseleave mouseout click dblclick keypress keyup";
-
-nglr.PopUp.prototype.bind = function () {
- var self = this;
- this.doc.find('.ng-validation-error,.ng-exception').
- live("mouseover", nglr.PopUp.onOver);
-};
-
-nglr.PopUp.onOver = function(e) {
- nglr.PopUp.onOut();
- var jNode = jQuery(this);
- jNode.bind(nglr.PopUp.OUT_EVENT, nglr.PopUp.onOut);
- var position = jNode.position();
- var de = document.documentElement;
- var w = self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
- var hasArea = w - position.left;
- var width = 300;
- var title = jNode.hasClass("ng-exception") ? "EXCEPTION:" : "Validation error...";
- var msg = jNode.attr("ng-error");
-
- var x;
- var arrowPos = hasArea>(width+75) ? "left" : "right";
- var tip = jQuery(
- "" +
- "
" +
- "
"+title+"
" +
- "
"+msg+"
" +
- "
");
- jQuery("body").append(tip);
- if(arrowPos === 'left'){
- x = position.left + this.offsetWidth + 11;
- }else{
- x = position.left - (width + 15);
- tip.find('.ng-arrow-right').css({left:width+1});
- }
-
- tip.css({left: x+"px", top: (position.top - 3)+"px"});
- return true;
-};
-
-nglr.PopUp.onOut = function() {
- jQuery('#ng-callout').
- unbind(nglr.PopUp.OUT_EVENT, nglr.PopUp.onOut).
- remove();
- return true;
-};
-
-//////////////////////////////////
-// Status
-//////////////////////////////////
-
-nglr.Status = function (body) {
- this.body = body;
- this.requestCount = 0;
-};
-nglr.Status.ANGULAR = "<a class='ng-angular-logo' href='http://www.getangular.com'><angular/></a>™";
-
-nglr.Status.prototype.beginRequest = function () {
- if (this.requestCount === 0) {
-<<<<<<< HEAD:public/javascripts/nglr/Widgets.js
- this.dialogView = jQuery('');
-=======
- this.dialogView = jQuery('');
- this.progressWidget = this.dialogView.find("div");
- this.progressWidget.progressbar({value:0});
->>>>>>> master:public/javascripts/nglr/Widgets.js
- this.dialogView.dialog({bgiframe:true, minHeight:50, modal:true});
- this.maxRequestCount = 0;
- }
- this.requestCount++;
- this.maxRequestCount++;
-};
-
-nglr.Status.prototype.endRequest = function () {
- this.requestCount--;
- if (this.requestCount === 0) {
- this.dialogView.dialog("destroy");
- this.dialogView.remove();
- this.dialogView = null;
- }
-};
diff --git a/src/XSitePost.js b/src/XSitePost.js
deleted file mode 100644
index 7d81e207..00000000
--- a/src/XSitePost.js
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright (C) 2008,2009 BRAT Tech LLC
-
-if (typeof nglr == 'undefined') nglr = {};
-
-if (typeof console == 'undefined') console = {};
-if (typeof console.log == 'undefined')
- console.log = function() {};
-if (typeof console.error == 'undefined')
- console.error = function() {};
-
-nglr.XSitePost = function(baseUrl, window, prefix) {
- this.baseUrl = baseUrl;
- this.post = jQuery.post;
- this.window = window;
- this.inQueue = {};
- this.outQueue = [];
- this.maxMsgSize = 100000;
- this.delay = 20;
- this.prefix = prefix;
- this.setTimeout=function(fn, delay){window.setTimeout(fn, delay);};
-};
-
-nglr.XSitePost.prototype.init = function() {
- this.window.name = '';
- this.response('ready', 'null');
-};
-
-nglr.XSitePost.prototype.incomingFragment = function(fragment) {
- var parts = fragment.split(";");
- this.incomingMsg(parts.shift(), 1*parts.shift(), 1*parts.shift(), parts.shift());
-};
-
-nglr.XSitePost.prototype.incomingMsg = function(id, partNo, totalParts, msgPart) {
- var msg = this.inQueue[id];
- if (!msg) {
- msg = {id:id, parts:[], count:0};
- this.inQueue[id] = msg;
- }
- msg.parts[partNo] = msgPart;
- msg.count++;
- if (totalParts === msg.count) {
- delete this.inQueue[id];
- var request = this.decodePost(msg.parts.join(''));
- var self = this;
- this.post(this.baseUrl + request.url, request.params, function(response, status){
- self.response(id, response, status);
- });
- }
-};
-
-nglr.XSitePost.prototype.response = function(id, response, status) {
- var start = 0;
- var end;
- var msg = Base64.encode(response);
- var msgLen = msg.length;
- var total = Math.ceil(msgLen / this.maxMsgSize);
- var part = 0;
- while (start < msgLen) {
- end = Math.min(msgLen, start + this.maxMsgSize);
- this.outQueue.push(id + ':'+part+':'+total+':' + msg.substring(start, end));
- start = end;
- part++;
- }
-};
-
-nglr.XSitePost.prototype.decodePost = function(post) {
- var parts = post.split(':');
- var url = Base64.decode(parts.shift());
- var params = {};
- while(parts.length !== 0) {
- var key = parts.shift();
- var value = Base64.decode(parts.shift());
- params[key] = value;
- }
- return {url:url, params:params};
-};
-
-nglr.XSitePost.prototype.listen = function() {
- console.log("listen()");
- var self = this;
- var window = this.window;
- var outQueue = this.outQueue;
- var setTimeout = this.setTimeout;
- var prefix = this.prefix;
- var prefixLen = prefix.length;
- var prefixRec = prefix + '>';
- var prefixRecLen = prefixRec.length;
- window.name = prefix;
- var pull = function(){
- var value = window.name;
- if (value == prefix && outQueue.length > 0) {
- window.name = prefix + '<' + outQueue.shift();
- } else if (value.substr(0, prefixRecLen) == prefixRec) {
- self.incomingFragment(value.substr(prefixRecLen));
- window.name = prefix;
- }
- setTimeout(pull, self.delay);
- };
- pull();
-};
diff --git a/src/angular-bootstrap.js b/src/angular-bootstrap.js
index 8ac4f9f3..b13bbf34 100644
--- a/src/angular-bootstrap.js
+++ b/src/angular-bootstrap.js
@@ -80,9 +80,8 @@
doc = window.document.getElementById(id);
}
}
- var angular = window.angularFactory(scriptConfig);
if (scriptConfig.autoBind && doc) {
- window.angularScope = angular.compile(doc);
+ window.angularScope = angular.compile(doc, scriptConfig);
}
if (typeof previousOnLoad === 'function') {
try {
diff --git a/src/angular.prefix b/src/angular.prefix
new file mode 100644
index 00000000..522c17bf
--- /dev/null
+++ b/src/angular.prefix
@@ -0,0 +1,2 @@
+
+(function(window, document){
\ No newline at end of file
diff --git a/src/angular.suffix b/src/angular.suffix
new file mode 100644
index 00000000..4b3cc37b
--- /dev/null
+++ b/src/angular.suffix
@@ -0,0 +1 @@
+})(window, document);
\ No newline at end of file
diff --git a/src/test/Runner.js b/src/test/Runner.js
index c7dd431a..5840282e 100644
--- a/src/test/Runner.js
+++ b/src/test/Runner.js
@@ -1,11 +1,11 @@
-if (!nglr.test) nglr.test = {};
+if (typeof test == 'undefined') test = {};
-nglr.test.ScenarioRunner = function(scenarios, body) {
+test.ScenarioRunner = function(scenarios, body) {
this.scenarios = scenarios;
this.body = body;
};
-nglr.test.ScenarioRunner.prototype = {
+test.ScenarioRunner.prototype = {
run:function(){
this.setUpUI();
this.runScenarios();
@@ -25,22 +25,22 @@ nglr.test.ScenarioRunner.prototype = {
});
},
runScenarios:function(){
- var runner = new nglr.test.Runner(this.console, this.testFrame);
+ var runner = new test.Runner(this.console, this.testFrame);
_.stepper(this.scenarios, function(next, scenario, name){
- new nglr.test.Scenario(name, scenario).run(runner, next);
+ new test.Scenario(name, scenario).run(runner, next);
}, function(){
}
);
}
};
-nglr.test.Runner = function(console, frame){
+test.Runner = function(console, frame){
this.console = console;
this.current = null;
this.tests = [];
this.frame = frame;
};
-nglr.test.Runner.prototype = {
+test.Runner.prototype = {
start:function(name){
var current = this.current = {
name:name,
@@ -75,7 +75,7 @@ nglr.test.Runner.prototype = {
var buf = [];
for ( var i = 1; i < arguments.length; i++) {
var arg = arguments[i];
- buf.push(typeof arg == "string" ?arg:nglr.toJson(arg));
+ buf.push(typeof arg == "string" ?arg:toJson(arg));
}
var log = jQuery('');
log.text(buf.join(" "));
@@ -86,11 +86,11 @@ nglr.test.Runner.prototype = {
}
};
-nglr.test.Scenario = function(name, scenario){
+test.Scenario = function(name, scenario){
this.name = name;
this.scenario = scenario;
};
-nglr.test.Scenario.prototype = {
+test.Scenario.prototype = {
run:function(runner, callback) {
var self = this;
_.stepper(this.scenario, function(next, steps, name){
@@ -115,7 +115,7 @@ nglr.test.Scenario.prototype = {
else if (step.When) fn = angular.test.WHEN[step.When];
else if (step.Then) fn = angular.test.THEN[step.Then];
return fn || function (){
- throw "ERROR: Need Given/When/Then got: " + nglr.toJson(step);
+ throw "ERROR: Need Given/When/Then got: " + toJson(step);
};
},
context: function(runner) {
@@ -149,14 +149,14 @@ nglr.test.Scenario.prototype = {
callback();
return;
}
- runner.log("info", nglr.toJson(step));
+ runner.log("info", toJson(step));
var fn = this.verb(step);
var context = this.context(runner);
_.extend(context, step);
try {
(fn.call(context)||function(c){c();})(callback);
} catch (e) {
- runner.log("error", "ERROR: " + nglr.toJson(e));
+ runner.log("error", "ERROR: " + toJson(e));
}
}
};
diff --git a/src/test/Steps.js b/src/test/Steps.js
index af4b84d6..cc9ff549 100644
--- a/src/test/Steps.js
+++ b/src/test/Steps.js
@@ -14,7 +14,7 @@ angular.test.GIVEN = {
};
},
dataset:function(){
- this.frame.name="$DATASET:" + nglr.toJson({dataset:this.dataset});
+ this.frame.name="$DATASET:" + toJson({dataset:this.dataset});
}
};
angular.test.WHEN = {
--
cgit v1.2.3
From 1aba6b53b88c70b61a0cc991b1371739305d117b Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Sun, 10 Jan 2010 08:58:57 -0800
Subject: basic calculator works with minified.js, lots of references still
broken
---
src/API.js | 72 +++++++++++++++++++++++++-------------------------
src/DataStore.js | 2 +-
src/Filters.js | 2 +-
src/JSON.js | 6 ++---
src/Loader.js | 47 +++++++++++++++-----------------
src/Parser.js | 8 +++---
src/Scope.js | 2 +-
src/Widgets.js | 16 +++++++----
src/test/Runner.js | 2 +-
src/test/_namespace.js | 10 +++----
10 files changed, 85 insertions(+), 82 deletions(-)
(limited to 'src')
diff --git a/src/API.js b/src/API.js
index 6fb6e8fc..49089da0 100644
--- a/src/API.js
+++ b/src/API.js
@@ -1,5 +1,5 @@
-angular.Global = {
- typeOf:function(obj){
+angular['Global'] = {
+ 'typeOf':function(obj){
var type = typeof obj;
switch(type) {
case "object":
@@ -12,10 +12,10 @@ angular.Global = {
}
};
-angular.Collection = {};
-angular.Object = {};
-angular.Array = {
- includeIf:function(array, value, condition) {
+angular['Collection'] = {};
+angular['Object'] = {};
+angular['Array'] = {
+ 'includeIf':function(array, value, condition) {
var index = _.indexOf(array, value);
if (condition) {
if (index == -1)
@@ -25,8 +25,8 @@ angular.Array = {
}
return array;
},
- sum:function(array, expression) {
- var fn = angular.Function.compile(expression);
+ 'sum':function(array, expression) {
+ var fn = angular['Function']['compile'](expression);
var sum = 0;
for (var i = 0; i < array.length; i++) {
var value = 1 * fn(array[i]);
@@ -36,15 +36,15 @@ angular.Array = {
}
return sum;
},
- remove:function(array, value) {
+ 'remove':function(array, value) {
var index = _.indexOf(array, value);
if (index >=0)
array.splice(index, 1);
return value;
},
- find:function(array, condition, defaultValue) {
+ 'find':function(array, condition, defaultValue) {
if (!condition) return undefined;
- var fn = angular.Function.compile(condition);
+ var fn = angular['Function']['compile'](condition);
_.detect(array, function($){
if (fn($)){
defaultValue = $;
@@ -53,10 +53,10 @@ angular.Array = {
});
return defaultValue;
},
- findById:function(array, id) {
+ 'findById':function(array, id) {
return angular.Array.find(array, function($){return $.$id == id;}, null);
},
- filter:function(array, expression) {
+ 'filter':function(array, expression) {
var predicates = [];
predicates.check = function(value) {
for (var j = 0; j < predicates.length; j++) {
@@ -136,16 +136,16 @@ angular.Array = {
}
return filtered;
},
- add:function(array, value) {
+ 'add':function(array, value) {
array.push(_.isUndefined(value)? {} : value);
return array;
},
- count:function(array, condition) {
+ 'count':function(array, condition) {
if (!condition) return array.length;
- var fn = angular.Function.compile(condition);
+ var fn = angular['Function']['compile'](condition);
return _.reduce(array, 0, function(count, $){return count + (fn($)?1:0);});
},
- orderBy:function(array, expression, descend) {
+ 'orderBy':function(array, expression, descend) {
function reverse(comp, descending) {
return toBoolean(descending) ?
function(a,b){return comp(b,a);} : comp;
@@ -169,7 +169,7 @@ angular.Array = {
descending = $.charAt(0) == '-';
$ = $.substring(1);
}
- var get = $ ? angular.Function.compile($) : _.identity;
+ var get = $ ? angular['Function']['compile']($) : _.identity;
return reverse(function(a,b){
return compare(get(a),get(b));
}, descending);
@@ -183,7 +183,7 @@ angular.Array = {
};
return _.clone(array).sort(reverse(comparator, descend));
},
- orderByToggle:function(predicate, attribute) {
+ 'orderByToggle':function(predicate, attribute) {
var STRIP = /^([+|-])?(.*)/;
var ascending = false;
var index = -1;
@@ -205,7 +205,7 @@ angular.Array = {
predicate.unshift((ascending ? "-" : "+") + attribute);
return predicate;
},
- orderByDirection:function(predicate, attribute, ascend, descend) {
+ 'orderByDirection':function(predicate, attribute, ascend, descend) {
ascend = ascend || 'ng-ascend';
descend = descend || 'ng-descend';
var att = predicate[0] || '';
@@ -218,7 +218,7 @@ angular.Array = {
}
return att == attribute ? (direction ? ascend : descend) : "";
},
- merge:function(array, index, mergeValue) {
+ 'merge':function(array, index, mergeValue) {
var value = array[index];
if (!value) {
value = {};
@@ -228,8 +228,8 @@ angular.Array = {
return array;
}
};
-angular.String = {
- quote:function(string) {
+angular['String'] = {
+ 'quote':function(string) {
return '"' + string.replace(/\\/g, '\\\\').
replace(/"/g, '\\"').
replace(/\n/g, '\\n').
@@ -239,8 +239,8 @@ angular.String = {
replace(/\v/g, '\\v') +
'"';
},
- quoteUnicode:function(string) {
- var str = angular.String.quote(string);
+ 'quoteUnicode':function(string) {
+ var str = angular['String']['quote'](string);
var chars = [];
for ( var i = 0; i < str.length; i++) {
var ch = str.charCodeAt(i);
@@ -253,7 +253,7 @@ angular.String = {
}
return chars.join('');
},
- toDate:function(string){
+ 'toDate':function(string){
var match;
if (typeof string == 'string' &&
(match = string.match(/^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z$/))){
@@ -265,8 +265,8 @@ angular.String = {
return string;
}
};
-angular.Date = {
- toString:function(date){
+angular['Date'] = {
+ 'toString':function(date){
function pad(n) { return n < 10 ? "0" + n : n; }
return (date.getUTCFullYear()) + '-' +
pad(date.getUTCMonth() + 1) + '-' +
@@ -276,8 +276,8 @@ angular.Date = {
pad(date.getUTCSeconds()) + 'Z';
}
};
-angular.Function = {
- compile:function(expression) {
+angular['Function'] = {
+ 'compile':function(expression) {
if (_.isFunction(expression)){
return expression;
} else if (expression){
@@ -299,20 +299,20 @@ angular.Function = {
dst[name] = _[name];
});
};
- extend(angular.Global, {},
+ extend(angular['Global'], {},
['extend', 'clone','isEqual',
'isElement', 'isArray', 'isFunction', 'isUndefined']);
- extend(angular.Collection, angular.Global,
+ extend(angular['Collection'], angular['Global'],
['each', 'map', 'reduce', 'reduceRight', 'detect',
'select', 'reject', 'all', 'any', 'include',
'invoke', 'pluck', 'max', 'min', 'sortBy',
'sortedIndex', 'toArray', 'size']);
- extend(angular.Array, angular.Collection,
+ extend(angular['Array'], angular['Collection'],
['first', 'last', 'compact', 'flatten', 'without',
'uniq', 'intersect', 'zip', 'indexOf', 'lastIndexOf']);
- extend(angular.Object, angular.Collection,
+ extend(angular['Object'], angular['Collection'],
['keys', 'values']);
- extend(angular.String, angular.Global);
- extend(angular.Function, angular.Global,
+ extend(angular['String'], angular['Global']);
+ extend(angular['Function'], angular['Global'],
['bind', 'bindAll', 'delay', 'defer', 'wrap', 'compose']);
})();
\ No newline at end of file
diff --git a/src/DataStore.js b/src/DataStore.js
index bdf882a0..6eeabb21 100644
--- a/src/DataStore.js
+++ b/src/DataStore.js
@@ -92,7 +92,7 @@ DataStore.prototype.save = function(document, callback) {
var cachedDoc = self.cache(document);
_.each(self._cache.$collections, function(collection){
if (collection.$$accept(document)) {
- angular.Array.includeIf(collection, cachedDoc, true);
+ angular['Array']['includeIf'](collection, cachedDoc, true);
}
});
if (document.$$anchor) {
diff --git a/src/Filters.js b/src/Filters.js
index dd4217be..b3f56e75 100644
--- a/src/Filters.js
+++ b/src/Filters.js
@@ -22,7 +22,7 @@ angular.filter.Meta.get = function(obj, attr){
}
};
-angular.filter.currency = function(amount){
+angular.filter['currency'] = function(amount){
jQuery(this.element).toggleClass('ng-format-negative', amount < 0);
return '$' + angular.filter.number.apply(this, [amount, 2]);
};
diff --git a/src/JSON.js b/src/JSON.js
index 84c9a857..238ed489 100644
--- a/src/JSON.js
+++ b/src/JSON.js
@@ -38,7 +38,7 @@ toJsonArray = function(buf, obj, pretty){
buf.push('' + obj);
}
} else if (type === 'string') {
- return buf.push(angular.String.quoteUnicode(obj));
+ return buf.push(angular['String']['quoteUnicode'](obj));
} else if (type === 'object') {
if (obj instanceof Array) {
buf.push("[");
@@ -56,7 +56,7 @@ toJsonArray = function(buf, obj, pretty){
}
buf.push("]");
} else if (obj instanceof Date) {
- buf.push(angular.String.quoteUnicode(angular.Date.toString(obj)));
+ buf.push(angular['String']['quoteUnicode'](angular['Date']['toString'](obj)));
} else {
buf.push("{");
if (pretty) buf.push(pretty);
@@ -78,7 +78,7 @@ toJsonArray = function(buf, obj, pretty){
buf.push(",");
if (pretty) buf.push(pretty);
}
- buf.push(angular.String.quote(key));
+ buf.push(angular['String']['quote'](key));
buf.push(":");
toJsonArray(buf, value, childPretty);
comma = true;
diff --git a/src/Loader.js b/src/Loader.js
index dfaa355a..19840567 100644
--- a/src/Loader.js
+++ b/src/Loader.js
@@ -23,6 +23,8 @@ if (typeof Node == 'undefined') {
}
var callbacks = {};
+var jQuery = window['jQuery'];
+var msie = jQuery['browser']['msie'];
if (!window.angular){ angular = {}; window['angular'] = angular; }
if (!angular.validator) angular.validator = {};
@@ -32,8 +34,8 @@ if (!window.console)
log:function() {},
error:function() {}
};
-if (_.isUndefined(alert)) {
- alert = function(){console.log(arguments); window.alert.apply(window, arguments); };
+if (!angular.alert) {
+ angular.alert = function(){console.log(arguments); window.alert.apply(window, arguments); };
}
var consoleNode;
@@ -169,7 +171,6 @@ Loader.prototype.load = function() {
this.loadCss('/stylesheets/jquery-ui/smoothness/jquery-ui-1.7.1.css');
this.loadCss('/stylesheets/css');
console.log("Server: " + this.config.server);
- msie = jQuery.browser.msie;
this.configureJQueryPlugins();
this.computeConfiguration();
this.bindHtml();
@@ -177,11 +178,7 @@ Loader.prototype.load = function() {
Loader.prototype.configureJQueryPlugins = function() {
console.log('Loader.configureJQueryPlugins()');
- jQuery.fn.removeNode = function() {
- var node = this.get(0);
- node.parentNode.removeChild(node);
- };
- jQuery.fn.scope = function() {
+ jQuery['fn']['scope'] = function() {
var element = this;
while (element && element.get(0)) {
var scope = element.data("scope");
@@ -191,7 +188,7 @@ Loader.prototype.configureJQueryPlugins = function() {
}
return null;
};
- jQuery.fn.controller = function() {
+ jQuery['fn']['controller'] = function() {
return this.data('controller') || NullController.instance;
};
};
@@ -229,24 +226,19 @@ Loader.prototype.bindHtml = function() {
var datastore = new DataStore(post, users, binder.anchor);
binder.updateListeners.push(function(){datastore.flush();});
var scope = new Scope( {
- $anchor : binder.anchor,
- $binder : binder,
- $config : this.config,
- $console : window.console,
- $datastore : datastore,
- $save : function(callback) {
+ '$anchor' : binder.anchor,
+ '$binder' : binder,
+ '$config' : this.config,
+ '$console' : window.console,
+ '$datastore' : datastore,
+ '$save' : function(callback) {
datastore.saveScope(scope.state, callback, binder.anchor);
},
- $window : window,
- $uid : this.uid,
- $users : users
+ '$window' : window,
+ '$uid' : this.uid,
+ '$users' : users
}, "ROOT");
- jQuery.each(["get", "set", "eval", "addWatchListener", "updateView"],
- function(i, method){
- angular[method] = bind(scope, scope[method]);
- });
-
document.data('scope', scope);
console.log('$binder.entity()');
binder.entity(scope);
@@ -284,7 +276,6 @@ Loader.prototype.bindHtml = function() {
watcher.watch();
document.find("body").show();
console.log('ready()');
-
};
Loader.prototype.visualPost = function(delegate) {
@@ -399,6 +390,12 @@ angular['compile'] = function(root, config) {
//todo: don't start watcher
var loader = new Loader(root, jQuery("head"), _(defaults).extend(config));
loader.load();
- return jQuery(root).scope();
+ var scope = jQuery(root).scope();
+ //TODO: cleanup
+ return {
+ 'updateView':function(){return scope.updateView.apply(scope, arguments);},
+ 'set':function(){return scope.set.apply(scope, arguments);},
+ 'get':function(){return scope.get.apply(scope, arguments);}
+ };
};
diff --git a/src/Parser.js b/src/Parser.js
index b23215be..cdece11e 100644
--- a/src/Parser.js
+++ b/src/Parser.js
@@ -185,7 +185,7 @@ Lexer.prototype.readString = function(quote) {
this.tokens.push({index:start, text:string,
fn:function(){
return (string.length == dateParseLength) ?
- angular.String.toDate(string) : string;
+ angular['String']['toDate'](string) : string;
}});
return;
} else {
@@ -346,11 +346,11 @@ Parser.prototype.filterChain = function(){
};
Parser.prototype.filter = function(){
- return this._pipeFunction(angular.filter);
+ return this._pipeFunction(angular['filter']);
};
Parser.prototype.validator = function(){
- return this._pipeFunction(angular.validator);
+ return this._pipeFunction(angular['validator']);
};
Parser.prototype._pipeFunction = function(fnScope){
@@ -697,7 +697,7 @@ Parser.prototype.entityDecl = function () {
self.scope.set(instance, document);
return "$anchor." + instance + ":{" +
instance + "=" + entity + ".load($anchor." + instance + ");" +
- instance + ".$$anchor=" + angular.String.quote(instance) + ";" +
+ instance + ".$$anchor=" + angular['String']['quote'](instance) + ";" +
"};";
} else {
return "";
diff --git a/src/Scope.js b/src/Scope.js
index e3634cee..dff3bfbd 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -55,7 +55,7 @@ Scope.getter = function(instance, path) {
instance = instance[key];
}
if (_.isUndefined(instance) && key.charAt(0) == '$') {
- var type = angular.Global.typeOf(lastInstance);
+ var type = angular['Global']['typeOf'](lastInstance);
type = angular[type.charAt(0).toUpperCase()+type.substring(1)];
var fn = type ? type[[key.substring(1)]] : undefined;
if (fn) {
diff --git a/src/Widgets.js b/src/Widgets.js
index 3a0f2845..4e4facf8 100644
--- a/src/Widgets.js
+++ b/src/Widgets.js
@@ -5,7 +5,13 @@ WidgetFactory = function(serverUrl, database) {
this.nextUploadId = 0;
this.serverUrl = serverUrl;
this.database = database;
- this.createSWF = swfobject.createSWF;
+ if (window.swfobject) {
+ this.createSWF = swfobject.createSWF;
+ } else {
+ this.createSWF = function(){
+ alert("ERROR: swfobject not loaded!");
+ };
+ }
this.onChangeListener = function(){};
};
@@ -145,7 +151,7 @@ FileController.prototype._on_uploadCompleteData = function(data) {
FileController.prototype._on_select = function(name, size, type) {
this.name = name;
this.view.find("a").text(name).attr('href', name);
- this.view.find("span").text(angular.filter.bytes(size));
+ this.view.find("span").text(angular['filter']['bytes'](size));
this.upload();
};
@@ -167,7 +173,7 @@ FileController.prototype.updateView = function(scope) {
this.view.find("a").
attr("href", this.value.url).
text(this.value.text);
- this.view.find("span").text(angular.filter.bytes(this.value.size));
+ this.view.find("span").text(angular['filter']['bytes'](this.value.size));
}
this.view.find("input").attr('checked', !!modelValue);
};
@@ -677,8 +683,8 @@ RepeaterUpdater.prototype.updateView = function(scope) {
});
// shrink children
for ( var r = childrenLength; r > iteratorLength; --r) {
- var unneeded = this.children.pop();
- unneeded.element.removeNode();
+ var unneeded = this.children.pop().element[0];
+ unneeded.parentNode.removeChild(unneeded);
}
// Special case for option in select
if (child && child.element[0].nodeName === "OPTION") {
diff --git a/src/test/Runner.js b/src/test/Runner.js
index 5840282e..c6684951 100644
--- a/src/test/Runner.js
+++ b/src/test/Runner.js
@@ -110,7 +110,7 @@ test.Scenario.prototype = {
},
verb:function(step){
var fn = null;
- if (!step) fn = function (){ throw "Step is null!"; }
+ if (!step) fn = function (){ throw "Step is null!"; };
else if (step.Given) fn = angular.test.GIVEN[step.Given];
else if (step.When) fn = angular.test.WHEN[step.When];
else if (step.Then) fn = angular.test.THEN[step.Then];
diff --git a/src/test/_namespace.js b/src/test/_namespace.js
index 78f430f1..e29ae72a 100644
--- a/src/test/_namespace.js
+++ b/src/test/_namespace.js
@@ -1,5 +1,5 @@
-if (!angular) angular = {};
-if (!angular.test) angular.test = {};
-if (!angular.test.GIVEN) angular.test.GIVEN = {};
-if (!angular.test.WHEN) angular.test.WHEN = {};
-if (!angular.test.THEN) angular.test.THEN = {};
+if (!angular) var angular = window['angular'] = {};
+if (!angular['test']) var angularTest = angular['test'] = {};
+if (!angular['test']['GIVEN']) angularTest['GIVEN'] = {};
+if (!angular['test']['WHEN']) angularTest['WHEN'] = {};
+if (!angular['test']['THEN']) angularTest['THEN'] = {};
--
cgit v1.2.3
From 1a42a3fab99ca02af0476f5a87175c53104aa2e3 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Mon, 11 Jan 2010 16:15:12 -0800
Subject: green
---
src/API.js | 77 ++++----
src/Binder.js | 8 +-
src/ControlBar.js | 2 +-
src/DataStore.js | 18 +-
src/Filters.js | 511 +++++++++++++++++++++++++++--------------------------
src/JSON.js | 2 +-
src/Loader.js | 491 +++++++++++++++++++++++++-------------------------
src/Scope.js | 6 +-
src/Server.js | 2 +-
src/Validators.js | 152 ++++++++--------
src/Widgets.js | 4 +-
src/angular.prefix | 3 +-
12 files changed, 647 insertions(+), 629 deletions(-)
(limited to 'src')
diff --git a/src/API.js b/src/API.js
index 49089da0..d795f4c3 100644
--- a/src/API.js
+++ b/src/API.js
@@ -1,9 +1,8 @@
-angular['Global'] = {
+var angularGlobal = {
'typeOf':function(obj){
+ if (obj === null) return "null";
var type = typeof obj;
- switch(type) {
- case "object":
- if (obj === null) return "null";
+ if (type == "object") {
if (obj instanceof Array) return "array";
if (obj instanceof Date) return "date";
if (obj.nodeType == 1) return "element";
@@ -12,9 +11,9 @@ angular['Global'] = {
}
};
-angular['Collection'] = {};
-angular['Object'] = {};
-angular['Array'] = {
+var angularCollection = {};
+var angularObject = {};
+var angularArray = {
'includeIf':function(array, value, condition) {
var index = _.indexOf(array, value);
if (condition) {
@@ -177,7 +176,7 @@ angular['Array'] = {
var comparator = function(o1, o2){
for ( var i = 0; i < expression.length; i++) {
var comp = expression[i](o1, o2);
- if (comp != 0) return comp;
+ if (comp !== 0) return comp;
}
return 0;
};
@@ -197,7 +196,7 @@ angular['Array'] = {
ascending = $.charAt(0) == '+';
index = i;
return true;
- };
+ }
});
if (index >= 0) {
predicate.splice(index, 1);
@@ -228,7 +227,8 @@ angular['Array'] = {
return array;
}
};
-angular['String'] = {
+
+var angularString = {
'quote':function(string) {
return '"' + string.replace(/\\/g, '\\\\').
replace(/"/g, '\\"').
@@ -265,7 +265,8 @@ angular['String'] = {
return string;
}
};
-angular['Date'] = {
+
+var angularDate = {
'toString':function(date){
function pad(n) { return n < 10 ? "0" + n : n; }
return (date.getUTCFullYear()) + '-' +
@@ -276,7 +277,8 @@ angular['Date'] = {
pad(date.getUTCSeconds()) + 'Z';
}
};
-angular['Function'] = {
+
+var angularFunction = {
'compile':function(expression) {
if (_.isFunction(expression)){
return expression;
@@ -292,27 +294,30 @@ angular['Function'] = {
}
};
-(function(){
- function extend(dst, src, names){
- _.extend(dst, src);
- _.each((names||[]), function(name){
- dst[name] = _[name];
- });
- };
- extend(angular['Global'], {},
- ['extend', 'clone','isEqual',
- 'isElement', 'isArray', 'isFunction', 'isUndefined']);
- extend(angular['Collection'], angular['Global'],
- ['each', 'map', 'reduce', 'reduceRight', 'detect',
- 'select', 'reject', 'all', 'any', 'include',
- 'invoke', 'pluck', 'max', 'min', 'sortBy',
- 'sortedIndex', 'toArray', 'size']);
- extend(angular['Array'], angular['Collection'],
- ['first', 'last', 'compact', 'flatten', 'without',
- 'uniq', 'intersect', 'zip', 'indexOf', 'lastIndexOf']);
- extend(angular['Object'], angular['Collection'],
- ['keys', 'values']);
- extend(angular['String'], angular['Global']);
- extend(angular['Function'], angular['Global'],
- ['bind', 'bindAll', 'delay', 'defer', 'wrap', 'compose']);
-})();
\ No newline at end of file
+function defineApi(dst, chain, underscoreNames){
+ var lastChain = _.last(chain);
+ foreach(underscoreNames, function(name){
+ lastChain[name] = _[name];
+ });
+ angular[dst] = angular[dst] || {};
+ foreach(chain, function(parent){
+ extend(angular[dst], parent);
+ });
+}
+defineApi('Global', [angularGlobal],
+ ['extend', 'clone','isEqual',
+ 'isElement', 'isArray', 'isFunction', 'isUndefined']);
+defineApi('Collection', [angularGlobal, angularCollection],
+ ['each', 'map', 'reduce', 'reduceRight', 'detect',
+ 'select', 'reject', 'all', 'any', 'include',
+ 'invoke', 'pluck', 'max', 'min', 'sortBy',
+ 'sortedIndex', 'toArray', 'size']);
+defineApi('Array', [angularGlobal, angularCollection, angularArray],
+ ['first', 'last', 'compact', 'flatten', 'without',
+ 'uniq', 'intersect', 'zip', 'indexOf', 'lastIndexOf']);
+defineApi('Object', [angularGlobal, angularCollection, angularObject],
+ ['keys', 'values']);
+defineApi('String', [angularGlobal, angularString], []);
+defineApi('Date', [angularGlobal, angularDate], []);
+defineApi('Function', [angularGlobal, angularCollection, angularFunction],
+ ['bind', 'bindAll', 'delay', 'defer', 'wrap', 'compose']);
diff --git a/src/Binder.js b/src/Binder.js
index 3589cb88..4c5299ed 100644
--- a/src/Binder.js
+++ b/src/Binder.js
@@ -57,16 +57,16 @@ Binder.prototype.parseAnchor = function(url) {
var anchor = url.substring(anchorIndex + 1);
var anchorQuery = this.parseQueryString(anchor);
- jQuery.each(self.anchor, function(key, newValue) {
+ foreach(self.anchor, function(newValue, key) {
delete self.anchor[key];
});
- jQuery.each(anchorQuery, function(key, newValue) {
+ foreach(anchorQuery, function(newValue, key) {
self.anchor[key] = newValue;
});
};
Binder.prototype.onUrlChange = function (url) {
- console.log("URL change detected", url);
+ log("URL change detected", url);
this.parseAnchor(url);
this.updateView();
};
@@ -252,7 +252,7 @@ Binder.prototype.precompileNode = function(node, path, factories) {
}
}
- if (!node.getAttribute) console.log(node);
+ if (!node.getAttribute) log(node);
var repeaterExpression = node.getAttribute('ng-repeat');
if (repeaterExpression) {
node.removeAttribute('ng-repeat');
diff --git a/src/ControlBar.js b/src/ControlBar.js
index b66a1464..fb8147d5 100644
--- a/src/ControlBar.js
+++ b/src/ControlBar.js
@@ -52,7 +52,7 @@ ControlBar.prototype.doTemplate = function (path) {
callbacks["_iframe_notify_" + id] = function() {
loginView.dialog("destroy");
loginView.remove();
- jQuery.each(self.callbacks, function(i, callback){
+ foreach(self.callbacks, function(callback){
callback();
});
self.callbacks = [];
diff --git a/src/DataStore.js b/src/DataStore.js
index 6eeabb21..f99e5824 100644
--- a/src/DataStore.js
+++ b/src/DataStore.js
@@ -41,7 +41,7 @@ DataStore.prototype.loadMany = function(entity, ids, callback) {
var self=this;
var list = [];
var callbackCount = 0;
- jQuery.each(ids, function(i, id){
+ foreach(ids, function(id){
list.push(self.load(entity(), id, function(){
callbackCount++;
if (callbackCount == ids.length) {
@@ -50,7 +50,7 @@ DataStore.prototype.loadMany = function(entity, ids, callback) {
}));
});
return list;
-}
+};
DataStore.prototype.loadOrCreate = function(instance, id, callback) {
var self=this;
@@ -134,9 +134,9 @@ DataStore.prototype.flush = function() {
var self = this;
var bulkRequest = this.bulkRequest;
this.bulkRequest = [];
- console.log('REQUEST:', bulkRequest);
+ log('REQUEST:', bulkRequest);
function callback(code, bulkResponse){
- console.log('RESPONSE[' + code + ']: ', bulkResponse);
+ log('RESPONSE[' + code + ']: ', bulkResponse);
if(bulkResponse.$status_code == 401) {
self.users.login(function(){
self.post(bulkRequest, callback);
@@ -147,9 +147,9 @@ DataStore.prototype.flush = function() {
for ( var i = 0; i < bulkResponse.length; i++) {
var response = bulkResponse[i];
var request = bulkRequest[i];
- var code = response.$status_code;
- if(code) {
- if(code == 403) {
+ var responseCode = response.$status_code;
+ if(responseCode) {
+ if(responseCode == 403) {
self.users.notAuthorized();
} else {
request.$$failure(response);
@@ -217,7 +217,7 @@ DataStore.prototype.documentCountsByUser = function(){
var counts = {};
var self = this;
self.post([["GET", "$users"]], function(code, response){
- jQuery.each(response[0], function(key, value){
+ foreach(response[0], function(value, key){
counts[key] = value;
});
});
@@ -228,7 +228,7 @@ DataStore.prototype.userDocumentIdsByEntity = function(user){
var ids = {};
var self = this;
self.post([["GET", "$users/" + user]], function(code, response){
- jQuery.each(response[0], function(key, value){
+ foreach(response[0], function(value, key){
ids[key] = value;
});
});
diff --git a/src/Filters.js b/src/Filters.js
index b3f56e75..67fcffa1 100644
--- a/src/Filters.js
+++ b/src/Filters.js
@@ -1,13 +1,13 @@
// Copyright (C) 2009 BRAT Tech LLC
-angular.filter.Meta = function(obj){
+angularFilter.Meta = function(obj){
if (obj) {
for ( var key in obj) {
this[key] = obj[key];
}
}
};
-angular.filter.Meta.get = function(obj, attr){
+angularFilter.Meta.get = function(obj, attr){
attr = attr || 'text';
switch(typeof obj) {
case "string":
@@ -22,269 +22,280 @@ angular.filter.Meta.get = function(obj, attr){
}
};
-angular.filter['currency'] = function(amount){
- jQuery(this.element).toggleClass('ng-format-negative', amount < 0);
- return '$' + angular.filter.number.apply(this, [amount, 2]);
-};
+var angularFilterGoogleChartApi;
-angular.filter.number = function(amount, fractionSize){
- if (isNaN(amount) || !isFinite(amount)) {
- return '';
- }
- fractionSize = typeof fractionSize == 'undefined' ? 2 : fractionSize;
- var isNegative = amount < 0;
- amount = Math.abs(amount);
- var pow = Math.pow(10, fractionSize);
- var text = "" + Math.round(amount * pow);
- var whole = text.substring(0, text.length - fractionSize);
- whole = whole || '0';
- var frc = text.substring(text.length - fractionSize);
- text = isNegative ? '-' : '';
- for (var i = 0; i < whole.length; i++) {
- if ((whole.length - i)%3 === 0 && i !== 0) {
- text += ',';
- }
- text += whole.charAt(i);
- }
- if (fractionSize > 0) {
- for (var j = frc.length; j < fractionSize; j++) {
- frc += '0';
+foreach({
+ 'currency': function(amount){
+ jQuery(this.element).toggleClass('ng-format-negative', amount < 0);
+ return '$' + angularFilter['number'].apply(this, [amount, 2]);
+ },
+
+ 'number': function(amount, fractionSize){
+ if (isNaN(amount) || !isFinite(amount)) {
+ return '';
}
- text += '.' + frc.substring(0, fractionSize);
- }
- return text;
-};
-
-angular.filter.date = function(amount) {
-};
-
-angular.filter.json = function(object) {
- jQuery(this.element).addClass("ng-monospace");
- return toJson(object, true);
-};
-
-angular.filter.trackPackage = function(trackingNo, noMatch) {
- trackingNo = trim(trackingNo);
- var tNo = trackingNo.replace(/ /g, '');
- var MATCHERS = angular.filter.trackPackage.MATCHERS;
- for ( var i = 0; i < MATCHERS.length; i++) {
- var carrier = MATCHERS[i];
- for ( var j = 0; j < carrier.regexp.length; j++) {
- var regexp = carrier.regexp[j];
- if (regexp.test(tNo)) {
- var text = carrier.name + ": " + trackingNo;
- var url = carrier.url + trackingNo;
- return new angular.filter.Meta({
- text:text,
- url:url,
- html: '' + text + '',
- trackingNo:trackingNo});
+ fractionSize = typeof fractionSize == 'undefined' ? 2 : fractionSize;
+ var isNegative = amount < 0;
+ amount = Math.abs(amount);
+ var pow = Math.pow(10, fractionSize);
+ var text = "" + Math.round(amount * pow);
+ var whole = text.substring(0, text.length - fractionSize);
+ whole = whole || '0';
+ var frc = text.substring(text.length - fractionSize);
+ text = isNegative ? '-' : '';
+ for (var i = 0; i < whole.length; i++) {
+ if ((whole.length - i)%3 === 0 && i !== 0) {
+ text += ',';
}
+ text += whole.charAt(i);
}
- }
- if (trackingNo)
- return noMatch ||
- new angular.filter.Meta({text:trackingNo + " is not recognized"});
- else
- return null;
-};
-
-angular.filter.trackPackage.MATCHERS = [
- { name: "UPS",
- url: "http://wwwapps.ups.com/WebTracking/processInputRequest?sort_by=status&tracknums_displayed=1&TypeOfInquiryNumber=T&loc=en_US&track.x=0&track.y=0&InquiryNumber1=",
- regexp: [
- /^1Z[0-9A-Z]{16}$/i]},
- { name: "FedEx",
- url: "http://www.fedex.com/Tracking?tracknumbers=",
- regexp: [
- /^96\d{10}?$/i,
- /^96\d{17}?$/i,
- /^96\d{20}?$/i,
- /^\d{15}$/i,
- /^\d{12}$/i]},
- { name: "USPS",
- url: "http://trkcnfrm1.smi.usps.com/PTSInternetWeb/InterLabelInquiry.do?origTrackNum=",
- regexp: [
- /^(91\d{20})$/i,
- /^(91\d{18})$/i]}];
-
-angular.filter.link = function(obj, title) {
- var text = title || angular.filter.Meta.get(obj);
- var url = angular.filter.Meta.get(obj, "url") || angular.filter.Meta.get(obj);
- if (url) {
- if (angular.validator.email(url) === null) {
- url = "mailto:" + url;
- }
- var html = '' + text + '';
- return new angular.filter.Meta({text:text, url:url, html:html});
- }
- return obj;
-};
-
-
-angular.filter.bytes = function(size) {
- if(size === null) return "";
-
- var suffix = 0;
- while (size > 1000) {
- size = size / 1024;
- suffix++;
- }
- var txt = "" + size;
- var dot = txt.indexOf('.');
- if (dot > -1 && dot + 2 < txt.length) {
- txt = txt.substring(0, dot + 2);
- }
- return txt + " " + angular.filter.bytes.SUFFIX[suffix];
-};
-angular.filter.bytes.SUFFIX = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];
-
-angular.filter.image = function(obj, width, height) {
- if (obj && obj.url) {
- var style = "";
- if (width) {
- style = ' style="max-width: ' + width +
- 'px; max-height: ' + (height || width) + 'px;"';
+ if (fractionSize > 0) {
+ for (var j = frc.length; j < fractionSize; j++) {
+ frc += '0';
+ }
+ text += '.' + frc.substring(0, fractionSize);
}
- return new angular.filter.Meta({url:obj.url, text:obj.url,
- html:'
'});
- }
- return null;
-};
-
-angular.filter.lowercase = function (obj) {
- var text = angular.filter.Meta.get(obj);
- return text ? ("" + text).toLowerCase() : text;
-};
-
-angular.filter.uppercase = function (obj) {
- var text = angular.filter.Meta.get(obj);
- return text ? ("" + text).toUpperCase() : text;
-};
-
-angular.filter.linecount = function (obj) {
- var text = angular.filter.Meta.get(obj);
- if (text==='' || !text) return 1;
- return text.split(/\n|\f/).length;
-};
-
-angular.filter['if'] = function (result, expression) {
- return expression ? result : undefined;
-};
-
-angular.filter.unless = function (result, expression) {
- return expression ? undefined : result;
-};
-
-angular.filter.googleChartApi = function(type, data, width, height) {
- data = data || {};
- var api = angular.filter.googleChartApi;
- var chart = {
- cht:type,
- chco:api.collect(data, 'color'),
- chtt:api.title(data),
- chdl:api.collect(data, 'label'),
- chd:api.values(data),
- chf:'bg,s,FFFFFF00'
- };
- if (_.isArray(data.xLabels)) {
- chart.chxt='x';
- chart.chxl='0:|' + data.xLabels.join('|');
- }
- return angular.filter.googleChartApi.encode(chart, width, height);
-};
-
-angular.filter.googleChartApi.values = function(data){
- var seriesValues = [];
- _.each(data.series||[], function(serie){
- var values = [];
- _.each(serie.values||[], function(value){
- values.push(value);
- });
- seriesValues.push(values.join(','));
- });
- var values = seriesValues.join('|');
- return values === "" ? null : "t:" + values;
-};
-
-angular.filter.googleChartApi.title = function(data){
- var titles = [];
- var title = data.title || [];
- _.each(_.isArray(title)?title:[title], function(text){
- titles.push(encodeURIComponent(text));
- });
- return titles.join('|');
-};
-
-angular.filter.googleChartApi.collect = function(data, key){
- var outterValues = [];
- var count = 0;
- _.each(data.series||[], function(serie){
- var innerValues = [];
- var value = serie[key] || [];
- _.each(_.isArray(value)?value:[value], function(color){
- innerValues.push(encodeURIComponent(color));
- count++;
+ return text;
+ },
+
+ 'date': function(amount) {
+ },
+
+ 'json': function(object) {
+ jQuery(this.element).addClass("ng-monospace");
+ return toJson(object, true);
+ },
+
+ 'trackPackage': (function(){
+ var MATCHERS = [
+ { name: "UPS",
+ url: "http://wwwapps.ups.com/WebTracking/processInputRequest?sort_by=status&tracknums_displayed=1&TypeOfInquiryNumber=T&loc=en_US&track.x=0&track.y=0&InquiryNumber1=",
+ regexp: [
+ /^1Z[0-9A-Z]{16}$/i]},
+ { name: "FedEx",
+ url: "http://www.fedex.com/Tracking?tracknumbers=",
+ regexp: [
+ /^96\d{10}?$/i,
+ /^96\d{17}?$/i,
+ /^96\d{20}?$/i,
+ /^\d{15}$/i,
+ /^\d{12}$/i]},
+ { name: "USPS",
+ url: "http://trkcnfrm1.smi.usps.com/PTSInternetWeb/InterLabelInquiry.do?origTrackNum=",
+ regexp: [
+ /^(91\d{20})$/i,
+ /^(91\d{18})$/i]}];
+ return function(trackingNo, noMatch) {
+ trackingNo = trim(trackingNo);
+ var tNo = trackingNo.replace(/ /g, '');
+ var returnValue;
+ foreach(MATCHERS, function(carrier){
+ foreach(carrier.regexp, function(regexp){
+ if (regexp.test(tNo)) {
+ var text = carrier.name + ": " + trackingNo;
+ var url = carrier.url + trackingNo;
+ returnValue = new angularFilter.Meta({
+ text:text,
+ url:url,
+ html: '' + text + '',
+ trackingNo:trackingNo});
+ _.breakLoop();
+ }
+ });
+ if (returnValue) _.breakLoop();
});
- outterValues.push(innerValues.join('|'));
- });
- return count?outterValues.join(','):null;
-};
-
-angular.filter.googleChartApi.encode= function(params, width, height) {
- width = width || 200;
- height = height || width;
- var url = "http://chart.apis.google.com/chart?";
- var urlParam = [];
- params.chs = width + "x" + height;
- for ( var key in params) {
- var value = params[key];
- if (value) {
- urlParam.push(key + "=" + value);
+ if (returnValue)
+ return returnValue;
+ else if (trackingNo)
+ return noMatch || new angularFilter.Meta({text:trackingNo + " is not recognized"});
+ else
+ return null;
+ };})(),
+
+ 'link': function(obj, title) {
+ var text = title || angularFilter.Meta.get(obj);
+ var url = angularFilter.Meta.get(obj, "url") || angularFilter.Meta.get(obj);
+ if (url) {
+ if (angular.validator.email(url) === null) {
+ url = "mailto:" + url;
+ }
+ var html = '' + text + '';
+ return new angularFilter.Meta({text:text, url:url, html:html});
}
- }
- urlParam.sort();
- url += urlParam.join("&");
- return new angular.filter.Meta({url:url, text:value,
- html:'
'});
-};
-
-angular.filter.qrcode = function(value, width, height) {
- return angular.filter.googleChartApi.encode({cht:'qr', chl:encodeURIComponent(value)}, width, height);
-};
-angular.filter.chart = {
- pie:function(data, width, height) {
- return angular.filter.googleChartApi('p', data, width, height);
+ return obj;
},
- pie3d:function(data, width, height) {
- return angular.filter.googleChartApi('p3', data, width, height);
+
+
+ 'bytes': (function(){
+ var SUFFIX = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];
+ return function(size) {
+ if(size === null) return "";
+
+ var suffix = 0;
+ while (size > 1000) {
+ size = size / 1024;
+ suffix++;
+ }
+ var txt = "" + size;
+ var dot = txt.indexOf('.');
+ if (dot > -1 && dot + 2 < txt.length) {
+ txt = txt.substring(0, dot + 2);
+ }
+ return txt + " " + SUFFIX[suffix];
+ };
+ })(),
+
+ 'image': function(obj, width, height) {
+ if (obj && obj.url) {
+ var style = "";
+ if (width) {
+ style = ' style="max-width: ' + width +
+ 'px; max-height: ' + (height || width) + 'px;"';
+ }
+ return new angularFilter.Meta({url:obj.url, text:obj.url,
+ html:'
'});
+ }
+ return null;
},
- pieConcentric:function(data, width, height) {
- return angular.filter.googleChartApi('pc', data, width, height);
+
+ 'lowercase': function (obj) {
+ var text = angularFilter.Meta.get(obj);
+ return text ? ("" + text).toLowerCase() : text;
},
- barHorizontalStacked:function(data, width, height) {
- return angular.filter.googleChartApi('bhs', data, width, height);
+
+ 'uppercase': function (obj) {
+ var text = angularFilter.Meta.get(obj);
+ return text ? ("" + text).toUpperCase() : text;
},
- barHorizontalGrouped:function(data, width, height) {
- return angular.filter.googleChartApi('bhg', data, width, height);
+
+ 'linecount': function (obj) {
+ var text = angularFilter.Meta.get(obj);
+ if (text==='' || !text) return 1;
+ return text.split(/\n|\f/).length;
},
- barVerticalStacked:function(data, width, height) {
- return angular.filter.googleChartApi('bvs', data, width, height);
+
+ 'if': function (result, expression) {
+ return expression ? result : undefined;
},
- barVerticalGrouped:function(data, width, height) {
- return angular.filter.googleChartApi('bvg', data, width, height);
+
+ 'unless': function (result, expression) {
+ return expression ? undefined : result;
},
- line:function(data, width, height) {
- return angular.filter.googleChartApi('lc', data, width, height);
+
+ 'googleChartApi': extend(
+ function(type, data, width, height) {
+ data = data || {};
+ var chart = {
+ cht:type,
+ chco:angularFilterGoogleChartApi.collect(data, 'color'),
+ chtt:angularFilterGoogleChartApi.title(data),
+ chdl:angularFilterGoogleChartApi.collect(data, 'label'),
+ chd:angularFilterGoogleChartApi.values(data),
+ chf:'bg,s,FFFFFF00'
+ };
+ if (_.isArray(data.xLabels)) {
+ chart.chxt='x';
+ chart.chxl='0:|' + data.xLabels.join('|');
+ }
+ return angularFilterGoogleChartApi['encode'](chart, width, height);
+ },
+ {
+ 'values': function(data){
+ var seriesValues = [];
+ foreach(data.series||[], function(serie){
+ var values = [];
+ foreach(serie.values||[], function(value){
+ values.push(value);
+ });
+ seriesValues.push(values.join(','));
+ });
+ var values = seriesValues.join('|');
+ return values === "" ? null : "t:" + values;
+ },
+
+ 'title': function(data){
+ var titles = [];
+ var title = data.title || [];
+ foreach(_.isArray(title)?title:[title], function(text){
+ titles.push(encodeURIComponent(text));
+ });
+ return titles.join('|');
+ },
+
+ 'collect': function(data, key){
+ var outterValues = [];
+ var count = 0;
+ foreach(data.series||[], function(serie){
+ var innerValues = [];
+ var value = serie[key] || [];
+ foreach(_.isArray(value)?value:[value], function(color){
+ innerValues.push(encodeURIComponent(color));
+ count++;
+ });
+ outterValues.push(innerValues.join('|'));
+ });
+ return count?outterValues.join(','):null;
+ },
+
+ 'encode': function(params, width, height) {
+ width = width || 200;
+ height = height || width;
+ var url = "http://chart.apis.google.com/chart?";
+ var urlParam = [];
+ params.chs = width + "x" + height;
+ foreach(params, function(value, key){
+ if (value) {
+ urlParam.push(key + "=" + value);
+ }
+ });
+ urlParam.sort();
+ url += urlParam.join("&");
+ return new angularFilter.Meta({url:url,
+ html:'
'});
+ }
+ }
+ ),
+
+
+ 'qrcode': function(value, width, height) {
+ return angularFilterGoogleChartApi['encode']({cht:'qr', chl:encodeURIComponent(value)}, width, height);
},
- sparkline:function(data, width, height) {
- return angular.filter.googleChartApi('ls', data, width, height);
+ 'chart': {
+ pie:function(data, width, height) {
+ return angularFilterGoogleChartApi('p', data, width, height);
+ },
+ pie3d:function(data, width, height) {
+ return angularFilterGoogleChartApi('p3', data, width, height);
+ },
+ pieConcentric:function(data, width, height) {
+ return angularFilterGoogleChartApi('pc', data, width, height);
+ },
+ barHorizontalStacked:function(data, width, height) {
+ return angularFilterGoogleChartApi('bhs', data, width, height);
+ },
+ barHorizontalGrouped:function(data, width, height) {
+ return angularFilterGoogleChartApi('bhg', data, width, height);
+ },
+ barVerticalStacked:function(data, width, height) {
+ return angularFilterGoogleChartApi('bvs', data, width, height);
+ },
+ barVerticalGrouped:function(data, width, height) {
+ return angularFilterGoogleChartApi('bvg', data, width, height);
+ },
+ line:function(data, width, height) {
+ return angularFilterGoogleChartApi('lc', data, width, height);
+ },
+ sparkline:function(data, width, height) {
+ return angularFilterGoogleChartApi('ls', data, width, height);
+ },
+ scatter:function(data, width, height) {
+ return angularFilterGoogleChartApi('s', data, width, height);
+ }
},
- scatter:function(data, width, height) {
- return angular.filter.googleChartApi('s', data, width, height);
+
+ 'html': function(html){
+ return new angularFilter.Meta({html:html});
}
-};
+}, function(v,k){angularFilter[k] = v;});
-angular.filter.html = function(html){
- return new angular.filter.Meta({html:html});
-};
+angularFilterGoogleChartApi = angularFilter['googleChartApi'];
diff --git a/src/JSON.js b/src/JSON.js
index 238ed489..14fce1fb 100644
--- a/src/JSON.js
+++ b/src/JSON.js
@@ -17,7 +17,7 @@ fromJson = function(json) {
parser.assertAllConsumed();
return expression();
} catch (e) {
- console.error("fromJson error: ", json, e);
+ error("fromJson error: ", json, e);
throw e;
}
};
diff --git a/src/Loader.js b/src/Loader.js
index 19840567..104dfec8 100644
--- a/src/Loader.js
+++ b/src/Loader.js
@@ -3,8 +3,7 @@
// IE compatibility
if (typeof document.getAttribute == 'undefined')
- document.getAttribute = function() {
- };
+ document.getAttribute = function() {};
if (typeof Node == 'undefined') {
Node = {
ELEMENT_NODE : 1,
@@ -22,25 +21,26 @@ if (typeof Node == 'undefined') {
};
}
-var callbacks = {};
-var jQuery = window['jQuery'];
-var msie = jQuery['browser']['msie'];
-
-if (!window.angular){ angular = {}; window['angular'] = angular; }
-if (!angular.validator) angular.validator = {};
-if (!angular.filter) angular.filter = {};
-if (!window.console)
- window.console = {
- log:function() {},
- error:function() {}
- };
-if (!angular.alert) {
- angular.alert = function(){console.log(arguments); window.alert.apply(window, arguments); };
-}
-
-var consoleNode;
-
-consoleLog = function(level, objs) {
+function noop() {}
+if (!window['console']) window['console']={'log':noop, 'error':noop};
+
+var consoleNode,
+ foreach = _.each,
+ extend = _.extend,
+ jQuery = window['jQuery'],
+ msie = jQuery['browser']['msie'],
+ log = function(){window['console']['log'].apply(this, arguments);},
+ error = function(){window['console']['error'].apply(this, arguments);},
+ angular = window['angular'] || (window['angular'] = {}),
+ angularValidator = angular['validator'] || (angular['validator'] = {}),
+ angularFilter = angular['filter'] || (angular['filter'] = {}),
+ angularCallbacks = angular['callbacks'] || (angular['callbacks'] = {}),
+ angularAlert = angular['alert'] || (angular['alert'] = function(){
+ log(arguments); window.alert.apply(window, arguments);
+ });
+
+
+function consoleLog(level, objs) {
var log = document.createElement("div");
log.className = level;
var msg = "";
@@ -52,17 +52,17 @@ consoleLog = function(level, objs) {
}
log.appendChild(document.createTextNode(msg));
consoleNode.appendChild(log);
-};
+}
-isNode = function(inp) {
+function isNode(inp) {
return inp &&
inp.tagName &&
inp.nodeName &&
inp.ownerDocument &&
inp.removeAttribute;
-};
+}
-isLeafNode = function(node) {
+function isLeafNode (node) {
switch (node.nodeName) {
case "OPTION":
case "PRE":
@@ -71,11 +71,9 @@ isLeafNode = function(node) {
default:
return false;
}
-};
+}
-noop = function() {
-};
-setHtml = function(node, html) {
+function setHtml(node, html) {
if (isLeafNode(node)) {
if (msie) {
node.innerText = html;
@@ -85,25 +83,25 @@ setHtml = function(node, html) {
} else {
node.innerHTML = html;
}
-};
+}
-escapeHtml = function(html) {
+function escapeHtml(html) {
if (!html || !html.replace)
return html;
return html.
replace(/&/g, '&').
replace(//g, '>');
-};
+}
-escapeAttr = function(html) {
+function escapeAttr(html) {
if (!html || !html.replace)
return html;
return html.replace(//g, '>').replace(/\"/g,
'"');
-};
+}
-bind = function(_this, _function) {
+function bind(_this, _function) {
if (!_this)
throw "Missing this";
if (!_.isFunction(_function))
@@ -111,9 +109,9 @@ bind = function(_this, _function) {
return function() {
return _function.apply(_this, arguments);
};
-};
+}
-shiftBind = function(_this, _function) {
+function shiftBind(_this, _function) {
return function() {
var args = [ this ];
for ( var i = 0; i < arguments.length; i++) {
@@ -121,28 +119,28 @@ shiftBind = function(_this, _function) {
}
return _function.apply(_this, args);
};
-};
+}
-outerHTML = function(node) {
+function outerHTML(node) {
var temp = document.createElement('div');
temp.appendChild(node);
var outerHTML = temp.innerHTML;
temp.removeChild(node);
return outerHTML;
-};
+}
-trim = function(str) {
+function trim(str) {
return str.replace(/^ */, '').replace(/ *$/, '');
-};
+}
-toBoolean = function(value) {
+function toBoolean(value) {
var v = ("" + value).toLowerCase();
if (v == 'f' || v == '0' || v == 'false' || v == 'no')
value = false;
return !!value;
-};
+}
-merge = function(src, dst) {
+function merge(src, dst) {
for ( var key in src) {
var value = dst[key];
var type = typeof value;
@@ -153,182 +151,184 @@ merge = function(src, dst) {
merge(src[key], value);
}
}
-};
+}
// ////////////////////////////
// Loader
// ////////////////////////////
-Loader = function(document, head, config) {
+function Loader(document, head, config) {
this.document = jQuery(document);
this.head = jQuery(head);
this.config = config;
this.location = window.location;
-};
-
-Loader.prototype.load = function() {
- this.configureLogging();
- this.loadCss('/stylesheets/jquery-ui/smoothness/jquery-ui-1.7.1.css');
- this.loadCss('/stylesheets/css');
- console.log("Server: " + this.config.server);
- this.configureJQueryPlugins();
- this.computeConfiguration();
- this.bindHtml();
-};
-
-Loader.prototype.configureJQueryPlugins = function() {
- console.log('Loader.configureJQueryPlugins()');
- jQuery['fn']['scope'] = function() {
- var element = this;
- while (element && element.get(0)) {
- var scope = element.data("scope");
- if (scope)
- return scope;
- element = element.parent();
- }
- return null;
- };
- jQuery['fn']['controller'] = function() {
- return this.data('controller') || NullController.instance;
- };
-};
-
-Loader.prototype.uid = function() {
- return "" + new Date().getTime();
-};
-
-Loader.prototype.computeConfiguration = function() {
- var config = this.config;
- if (!config.database) {
- var match = config.server.match(/https?:\/\/([\w]*)/);
- config.database = match ? match[1] : "$MEMORY";
- }
-};
-
-Loader.prototype.bindHtml = function() {
- console.log('Loader.bindHtml()');
- var watcher = new UrlWatcher(this.location);
- var document = this.document;
- var widgetFactory = new WidgetFactory(this.config.server, this.config.database);
- var binder = new Binder(document[0], widgetFactory, watcher, this.config);
- widgetFactory.onChangeListener = shiftBind(binder, binder.updateModel);
- var controlBar = new ControlBar(document.find('body'), this.config.server);
- var onUpdate = function(){binder.updateView();};
- var server = this.config.database=="$MEMORY" ?
- new FrameServer(this.window) :
- new Server(this.config.server, jQuery.getScript);
- server = new VisualServer(server, new Status(jQuery(document.body)), onUpdate);
- var users = new Users(server, controlBar);
- var databasePath = '/data/' + this.config.database;
- var post = function(request, callback){
- server.request("POST", databasePath, request, callback);
- };
- var datastore = new DataStore(post, users, binder.anchor);
- binder.updateListeners.push(function(){datastore.flush();});
- var scope = new Scope( {
- '$anchor' : binder.anchor,
- '$binder' : binder,
- '$config' : this.config,
- '$console' : window.console,
- '$datastore' : datastore,
- '$save' : function(callback) {
- datastore.saveScope(scope.state, callback, binder.anchor);
- },
- '$window' : window,
- '$uid' : this.uid,
- '$users' : users
- }, "ROOT");
-
- document.data('scope', scope);
- console.log('$binder.entity()');
- binder.entity(scope);
-
- console.log('$binder.compile()');
- binder.compile();
-
- console.log('ControlBar.bind()');
- controlBar.bind();
-
- console.log('$users.fetchCurrentUser()');
- function fetchCurrentUser() {
- users.fetchCurrentUser(function(u) {
- if (!u && document.find("[ng-auth=eager]").length) {
- users.login();
- }
- });
- }
- fetchCurrentUser();
-
- console.log('PopUp.bind()');
- new PopUp(document).bind();
-
- console.log('$binder.parseAnchor()');
- binder.parseAnchor();
-
- console.log('$binder.executeInit()');
- binder.executeInit();
-
- console.log('$binder.updateView()');
- binder.updateView();
-
- watcher.listener = bind(binder, binder.onUrlChange, watcher);
- watcher.onUpdate = function(){alert("update");};
- watcher.watch();
- document.find("body").show();
- console.log('ready()');
-};
+}
-Loader.prototype.visualPost = function(delegate) {
- var status = new Status(jQuery(document.body));
- return function(request, delegateCallback) {
- status.beginRequest(request);
- var callback = function() {
- status.endRequest();
- try {
- delegateCallback.apply(this, arguments);
- } catch (e) {
- alert(toJson(e));
+Loader.prototype = {
+ load: function() {
+ this.configureLogging();
+ this.loadCss('/stylesheets/jquery-ui/smoothness/jquery-ui-1.7.1.css');
+ this.loadCss('/stylesheets/css');
+ log("Server: " + this.config.server);
+ this.configureJQueryPlugins();
+ this.computeConfiguration();
+ this.bindHtml();
+ },
+
+ configureJQueryPlugins: function() {
+ log('Loader.configureJQueryPlugins()');
+ jQuery['fn']['scope'] = function() {
+ var element = this;
+ while (element && element.get(0)) {
+ var scope = element.data("scope");
+ if (scope)
+ return scope;
+ element = element.parent();
}
+ return null;
};
- delegate(request, callback);
- };
-};
-
-Loader.prototype.configureLogging = function() {
- var url = window.location.href + '#';
- url = url.split('#')[1];
- var config = {
- debug : null
- };
- var configs = url.split('&');
- for ( var i = 0; i < configs.length; i++) {
- var part = (configs[i] + '=').split('=');
- config[part[0]] = part[1];
- }
- if (config.debug == 'console') {
- consoleNode = document.createElement("div");
- consoleNode.id = 'ng-console';
- document.getElementsByTagName('body')[0].appendChild(consoleNode);
- console.log = function() {
- consoleLog('ng-console-info', arguments);
+ jQuery['fn']['controller'] = function() {
+ return this.data('controller') || NullController.instance;
+ };
+ },
+
+ uid: function() {
+ return "" + new Date().getTime();
+ },
+
+ computeConfiguration: function() {
+ var config = this.config;
+ if (!config.database) {
+ var match = config.server.match(/https?:\/\/([\w]*)/);
+ config.database = match ? match[1] : "$MEMORY";
+ }
+ },
+
+ bindHtml: function() {
+ log('Loader.bindHtml()');
+ var watcher = new UrlWatcher(this.location);
+ var document = this.document;
+ var widgetFactory = new WidgetFactory(this.config.server, this.config.database);
+ var binder = new Binder(document[0], widgetFactory, watcher, this.config);
+ widgetFactory.onChangeListener = shiftBind(binder, binder.updateModel);
+ var controlBar = new ControlBar(document.find('body'), this.config.server);
+ var onUpdate = function(){binder.updateView();};
+ var server = this.config.database=="$MEMORY" ?
+ new FrameServer(this.window) :
+ new Server(this.config.server, jQuery.getScript);
+ server = new VisualServer(server, new Status(jQuery(document.body)), onUpdate);
+ var users = new Users(server, controlBar);
+ var databasePath = '/data/' + this.config.database;
+ var post = function(request, callback){
+ server.request("POST", databasePath, request, callback);
+ };
+ var datastore = new DataStore(post, users, binder.anchor);
+ binder.updateListeners.push(function(){datastore.flush();});
+ var scope = new Scope( {
+ '$anchor' : binder.anchor,
+ '$binder' : binder,
+ '$config' : this.config,
+ '$console' : window.console,
+ '$datastore' : datastore,
+ '$save' : function(callback) {
+ datastore.saveScope(scope.state, callback, binder.anchor);
+ },
+ '$window' : window,
+ '$uid' : this.uid,
+ '$users' : users
+ }, "ROOT");
+
+ document.data('scope', scope);
+ log('$binder.entity()');
+ binder.entity(scope);
+
+ log('$binder.compile()');
+ binder.compile();
+
+ log('ControlBar.bind()');
+ controlBar.bind();
+
+ log('$users.fetchCurrentUser()');
+ function fetchCurrentUser() {
+ users.fetchCurrentUser(function(u) {
+ if (!u && document.find("[ng-auth=eager]").length) {
+ users.login();
+ }
+ });
+ }
+ fetchCurrentUser();
+
+ log('PopUp.bind()');
+ new PopUp(document).bind();
+
+ log('$binder.parseAnchor()');
+ binder.parseAnchor();
+
+ log('$binder.executeInit()');
+ binder.executeInit();
+
+ log('$binder.updateView()');
+ binder.updateView();
+
+ watcher.listener = bind(binder, binder.onUrlChange, watcher);
+ watcher.onUpdate = function(){alert("update");};
+ watcher.watch();
+ document.find("body").show();
+ log('ready()');
+ },
+
+ visualPost: function(delegate) {
+ var status = new Status(jQuery(document.body));
+ return function(request, delegateCallback) {
+ status.beginRequest(request);
+ var callback = function() {
+ status.endRequest();
+ try {
+ delegateCallback.apply(this, arguments);
+ } catch (e) {
+ alert(toJson(e));
+ }
+ };
+ delegate(request, callback);
};
- console.error = function() {
- consoleLog('ng-console-error', arguments);
+ },
+
+ configureLogging: function() {
+ var url = window.location.href + '#';
+ url = url.split('#')[1];
+ var config = {
+ debug : null
};
+ var configs = url.split('&');
+ for ( var i = 0; i < configs.length; i++) {
+ var part = (configs[i] + '=').split('=');
+ config[part[0]] = part[1];
+ }
+ if (config.debug == 'console') {
+ consoleNode = document.createElement("div");
+ consoleNode.id = 'ng-console';
+ document.getElementsByTagName('body')[0].appendChild(consoleNode);
+ log = function() {
+ consoleLog('ng-console-info', arguments);
+ };
+ console.error = function() {
+ consoleLog('ng-console-error', arguments);
+ };
+ }
+ },
+
+ loadCss: function(css) {
+ var cssTag = document.createElement('link');
+ cssTag.rel = "stylesheet";
+ cssTag.type = "text/css";
+ if (!css.match(/^http:/))
+ css = this.config.server + css;
+ cssTag.href = css;
+ this.head[0].appendChild(cssTag);
}
};
-Loader.prototype.loadCss = function(css) {
- var cssTag = document.createElement('link');
- cssTag.rel = "stylesheet";
- cssTag.type = "text/css";
- if (!css.match(/^http:/))
- css = this.config.server + css;
- cssTag.href = css;
- this.head[0].appendChild(cssTag);
-};
-
-UrlWatcher = function(location) {
+function UrlWatcher(location) {
this.location = location;
this.delay = 25;
this.setTimeout = function(fn, delay) {
@@ -338,49 +338,51 @@ UrlWatcher = function(location) {
return url;
};
this.expectedUrl = location.href;
-};
+}
-UrlWatcher.prototype.watch = function() {
- var self = this;
- var pull = function() {
- if (self.expectedUrl !== self.location.href) {
- var notify = self.location.hash.match(/^#\$iframe_notify=(.*)$/);
- if (notify) {
- if (!self.expectedUrl.match(/#/)) {
- self.expectedUrl += "#";
- }
- self.location.href = self.expectedUrl;
- var id = '_iframe_notify_' + notify[1];
- var notifyFn = callbacks[id];
- delete callbacks[id];
- try {
- (notifyFn||noop)();
- } catch (e) {
- alert(e);
+UrlWatcher.prototype = {
+ watch: function() {
+ var self = this;
+ var pull = function() {
+ if (self.expectedUrl !== self.location.href) {
+ var notify = self.location.hash.match(/^#\$iframe_notify=(.*)$/);
+ if (notify) {
+ if (!self.expectedUrl.match(/#/)) {
+ self.expectedUrl += "#";
+ }
+ self.location.href = self.expectedUrl;
+ var id = '_iframe_notify_' + notify[1];
+ var notifyFn = angularCallbacks[id];
+ delete angularCallbacks[id];
+ try {
+ (notifyFn||noop)();
+ } catch (e) {
+ alert(e);
+ }
+ } else {
+ self.listener(self.location.href);
+ self.expectedUrl = self.location.href;
}
- } else {
- self.listener(self.location.href);
- self.expectedUrl = self.location.href;
}
- }
- self.setTimeout(pull, self.delay);
- };
- pull();
-};
-
-UrlWatcher.prototype.setUrl = function(url) {
- var existingURL = window.location.href;
- if (!existingURL.match(/#/))
- existingURL += '#';
- if (existingURL != url)
- window.location.href = url;
- this.existingURL = url;
-};
-
-UrlWatcher.prototype.getUrl = function() {
- return window.location.href;
+ self.setTimeout(pull, self.delay);
+ };
+ pull();
+ },
+
+ setUrl: function(url) {
+ var existingURL = window.location.href;
+ if (!existingURL.match(/#/))
+ existingURL += '#';
+ if (existingURL != url)
+ window.location.href = url;
+ this.existingURL = url;
+ },
+
+ getUrl: function() {
+ return window.location.href;
+ }
};
-
+
angular['compile'] = function(root, config) {
config = config || {};
var defaults = {
@@ -397,5 +399,4 @@ angular['compile'] = function(root, config) {
'set':function(){return scope.set.apply(scope, arguments);},
'get':function(){return scope.get.apply(scope, arguments);}
};
-};
-
+};
\ No newline at end of file
diff --git a/src/Scope.js b/src/Scope.js
index dff3bfbd..f4b34c3c 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -124,7 +124,7 @@ Scope.prototype.evalWidget = function(widget, expression, context, onSuccess, on
}
return true;
} catch (e){
- console.error('Eval Widget Error:', e);
+ error('Eval Widget Error:', e);
var jsonError = toJson(e, true);
widget.hasError = true;
jQuery(widget.view).
@@ -184,10 +184,10 @@ Scope.prototype.addWatchListener = function(watchExpression, listener) {
Scope.prototype.fireWatchers = function() {
var self = this;
var fired = false;
- jQuery.each(this.watchListeners, function(name, watcher) {
+ foreach(this.watchListeners, function(watcher) {
var value = self.eval(watcher.expression);
if (value !== watcher.lastValue) {
- jQuery.each(watcher.listeners, function(i, listener){
+ foreach(watcher.listeners, function(listener){
listener(value, watcher.lastValue);
fired = true;
});
diff --git a/src/Server.js b/src/Server.js
index d00f893b..8f682038 100644
--- a/src/Server.js
+++ b/src/Server.js
@@ -14,7 +14,7 @@ Server.prototype.base64url = function(txt) {
Server.prototype.request = function(method, url, request, callback) {
var requestId = this.uuid + (this.nextId++);
- callbacks[requestId] = function(response) {
+ angularCallbacks[requestId] = function(response) {
delete angular[requestId];
callback(200, response);
};
diff --git a/src/Validators.js b/src/Validators.js
index 7cfaa2b4..eb8cff59 100644
--- a/src/Validators.js
+++ b/src/Validators.js
@@ -1,80 +1,82 @@
// Copyright (C) 2009 BRAT Tech LLC
-angular.validator.regexp = function(value, regexp, msg) {
- if (!value.match(regexp)) {
- return msg ||
- "Value does not match expected format " + regexp + ".";
- } else {
- return null;
- }
-};
-
-angular.validator.number = function(value, min, max) {
- var num = 1 * value;
- if (num == value) {
- if (typeof min != 'undefined' && num < min) {
- return "Value can not be less than " + min + ".";
+foreach({
+ 'regexp': function(value, regexp, msg) {
+ if (!value.match(regexp)) {
+ return msg ||
+ "Value does not match expected format " + regexp + ".";
+ } else {
+ return null;
}
- if (typeof min != 'undefined' && num > max) {
- return "Value can not be greater than " + max + ".";
+ },
+
+ 'number': function(value, min, max) {
+ var num = 1 * value;
+ if (num == value) {
+ if (typeof min != 'undefined' && num < min) {
+ return "Value can not be less than " + min + ".";
+ }
+ if (typeof min != 'undefined' && num > max) {
+ return "Value can not be greater than " + max + ".";
+ }
+ return null;
+ } else {
+ return "Value is not a number.";
+ }
+ },
+
+ 'integer': function(value, min, max) {
+ var number = angularValidator['number'](value, min, max);
+ if (number === null && value != Math.round(value)) {
+ return "Value is not a whole number.";
+ }
+ return number;
+ },
+
+ 'date': function(value, min, max) {
+ if (value.match(/^\d\d?\/\d\d?\/\d\d\d\d$/)) {
+ return null;
+ }
+ return "Value is not a date. (Expecting format: 12/31/2009).";
+ },
+
+ 'ssn': function(value) {
+ if (value.match(/^\d\d\d-\d\d-\d\d\d\d$/)) {
+ return null;
+ }
+ return "SSN needs to be in 999-99-9999 format.";
+ },
+
+ 'email': function(value) {
+ if (value.match(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/)) {
+ return null;
+ }
+ return "Email needs to be in username@host.com format.";
+ },
+
+ 'phone': function(value) {
+ if (value.match(/^1\(\d\d\d\)\d\d\d-\d\d\d\d$/)) {
+ return null;
+ }
+ if (value.match(/^\+\d{2,3} (\(\d{1,5}\))?[\d ]+\d$/)) {
+ return null;
+ }
+ return "Phone number needs to be in 1(987)654-3210 format in North America or +999 (123) 45678 906 internationaly.";
+ },
+
+ 'url': function(value) {
+ if (value.match(/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/)) {
+ return null;
+ }
+ return "URL needs to be in http://server[:port]/path format.";
+ },
+
+ 'json': function(value) {
+ try {
+ fromJson(value);
+ return null;
+ } catch (e) {
+ return e.toString();
}
- return null;
- } else {
- return "Value is not a number.";
- }
-};
-
-angular.validator.integer = function(value, min, max) {
- var number = angular.validator.number(value, min, max);
- if (number === null && value != Math.round(value)) {
- return "Value is not a whole number.";
- }
- return number;
-};
-
-angular.validator.date = function(value, min, max) {
- if (value.match(/^\d\d?\/\d\d?\/\d\d\d\d$/)) {
- return null;
- }
- return "Value is not a date. (Expecting format: 12/31/2009).";
-};
-
-angular.validator.ssn = function(value) {
- if (value.match(/^\d\d\d-\d\d-\d\d\d\d$/)) {
- return null;
- }
- return "SSN needs to be in 999-99-9999 format.";
-};
-
-angular.validator.email = function(value) {
- if (value.match(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/)) {
- return null;
- }
- return "Email needs to be in username@host.com format.";
-};
-
-angular.validator.phone = function(value) {
- if (value.match(/^1\(\d\d\d\)\d\d\d-\d\d\d\d$/)) {
- return null;
- }
- if (value.match(/^\+\d{2,3} (\(\d{1,5}\))?[\d ]+\d$/)) {
- return null;
- }
- return "Phone number needs to be in 1(987)654-3210 format in North America or +999 (123) 45678 906 internationaly.";
-};
-
-angular.validator.url = function(value) {
- if (value.match(/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/)) {
- return null;
- }
- return "URL needs to be in http://server[:port]/path format.";
-};
-
-angular.validator.json = function(value) {
- try {
- fromJson(value);
- return null;
- } catch (e) {
- return e.toString();
}
-};
+}, function(v,k) {angularValidator[k] = v;});
diff --git a/src/Widgets.js b/src/Widgets.js
index 4e4facf8..5dcb84c4 100644
--- a/src/Widgets.js
+++ b/src/Widgets.js
@@ -525,7 +525,7 @@ BindAttrUpdater.prototype.updateView = function(scope) {
attrValues.push(value);
} catch (e) {
this.hasError = true;
- console.error('BindAttrUpdater', e);
+ error('BindAttrUpdater', e);
var jsonError = toJson(e, true);
attrValues.push('[' + jsonError + ']');
jNode.
@@ -657,7 +657,7 @@ RepeaterUpdater.prototype.updateView = function(scope) {
var keyExp = this.keyExp;
var valueExp = this.valueExp;
var i = 0;
- jQuery.each(iterator, function(key, value){
+ foreach(iterator, function(value, key){
if (i < childrenLength) {
// reuse children
child = self.children[i];
diff --git a/src/angular.prefix b/src/angular.prefix
index 522c17bf..dbd4959a 100644
--- a/src/angular.prefix
+++ b/src/angular.prefix
@@ -1,2 +1 @@
-
-(function(window, document){
\ No newline at end of file
+(function(window, document){
--
cgit v1.2.3
From 6d5471c9bea9671dec7900a7bc548aea8ddd5a3e Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Mon, 11 Jan 2010 17:32:33 -0800
Subject: all files converted to prototype= {}
---
src/Binder.js | 595 ++++++++++-----------
src/ControlBar.js | 106 ++--
src/DataStore.js | 604 +++++++++++-----------
src/Filters.js | 2 -
src/JSON.js | 10 +-
src/Loader.js | 4 -
src/Model.js | 82 +--
src/Parser.js | 1292 +++++++++++++++++++++++-----------------------
src/Scope.js | 295 ++++++-----
src/Server.js | 44 +-
src/Users.js | 11 +-
src/Validators.js | 2 -
src/Widgets.js | 972 +++++++++++++++++-----------------
src/angular-bootstrap.js | 25 +-
src/angular.prefix | 23 +
15 files changed, 2068 insertions(+), 1999 deletions(-)
(limited to 'src')
diff --git a/src/Binder.js b/src/Binder.js
index 4c5299ed..36cb6ec3 100644
--- a/src/Binder.js
+++ b/src/Binder.js
@@ -1,12 +1,11 @@
-// Copyright (C) 2009 BRAT Tech LLC
-Binder = function(doc, widgetFactory, urlWatcher, config) {
+function Binder(doc, widgetFactory, urlWatcher, config) {
this.doc = doc;
this.urlWatcher = urlWatcher;
this.anchor = {};
this.widgetFactory = widgetFactory;
this.config = config || {};
this.updateListeners = [];
-};
+}
Binder.parseBindings = function(string) {
var results = [];
@@ -39,312 +38,314 @@ Binder.binding = function(string) {
};
-Binder.prototype.parseQueryString = function(query) {
- var params = {};
- query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,
- function (match, left, right) {
- if (left) params[decodeURIComponent(left)] = decodeURIComponent(right);
- });
- return params;
-};
-
-Binder.prototype.parseAnchor = function(url) {
- var self = this;
- url = url || this.urlWatcher.getUrl();
-
- var anchorIndex = url.indexOf('#');
- if (anchorIndex < 0) return;
- var anchor = url.substring(anchorIndex + 1);
-
- var anchorQuery = this.parseQueryString(anchor);
- foreach(self.anchor, function(newValue, key) {
- delete self.anchor[key];
- });
- foreach(anchorQuery, function(newValue, key) {
- self.anchor[key] = newValue;
- });
-};
-
-Binder.prototype.onUrlChange = function (url) {
- log("URL change detected", url);
- this.parseAnchor(url);
- this.updateView();
-};
-
-Binder.prototype.updateAnchor = function() {
- var url = this.urlWatcher.getUrl();
- var anchorIndex = url.indexOf('#');
- if (anchorIndex > -1)
- url = url.substring(0, anchorIndex);
- url += "#";
- var sep = '';
- for (var key in this.anchor) {
- var value = this.anchor[key];
- if (typeof value === 'undefined' || value === null) {
- delete this.anchor[key];
- } else {
- url += sep + encodeURIComponent(key);
- if (value !== true)
- url += "=" + encodeURIComponent(value);
- sep = '&';
- }
- }
- this.urlWatcher.setUrl(url);
- return url;
-};
-
-Binder.prototype.updateView = function() {
- var start = new Date().getTime();
- var scope = jQuery(this.doc).scope();
- scope.set("$invalidWidgets", []);
- scope.updateView();
- var end = new Date().getTime();
- this.updateAnchor();
- _.each(this.updateListeners, function(fn) {fn();});
-};
-
-Binder.prototype.docFindWithSelf = function(exp){
- var doc = jQuery(this.doc);
- var selection = doc.find(exp);
- if (doc.is(exp)){
- selection = selection.andSelf();
- }
- return selection;
-};
-
-Binder.prototype.executeInit = function() {
- this.docFindWithSelf("[ng-init]").each(function() {
- var jThis = jQuery(this);
- var scope = jThis.scope();
- try {
- scope.eval(jThis.attr('ng-init'));
- } catch (e) {
- alert("EVAL ERROR:\n" + jThis.attr('ng-init') + '\n' + toJson(e, true));
+Binder.prototype = {
+ parseQueryString: function(query) {
+ var params = {};
+ query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,
+ function (match, left, right) {
+ if (left) params[decodeURIComponent(left)] = decodeURIComponent(right);
+ });
+ return params;
+ },
+
+ parseAnchor: function(url) {
+ var self = this;
+ url = url || this.urlWatcher.getUrl();
+
+ var anchorIndex = url.indexOf('#');
+ if (anchorIndex < 0) return;
+ var anchor = url.substring(anchorIndex + 1);
+
+ var anchorQuery = this.parseQueryString(anchor);
+ foreach(self.anchor, function(newValue, key) {
+ delete self.anchor[key];
+ });
+ foreach(anchorQuery, function(newValue, key) {
+ self.anchor[key] = newValue;
+ });
+ },
+
+ onUrlChange: function (url) {
+ log("URL change detected", url);
+ this.parseAnchor(url);
+ this.updateView();
+ },
+
+ updateAnchor: function() {
+ var url = this.urlWatcher.getUrl();
+ var anchorIndex = url.indexOf('#');
+ if (anchorIndex > -1)
+ url = url.substring(0, anchorIndex);
+ url += "#";
+ var sep = '';
+ for (var key in this.anchor) {
+ var value = this.anchor[key];
+ if (typeof value === 'undefined' || value === null) {
+ delete this.anchor[key];
+ } else {
+ url += sep + encodeURIComponent(key);
+ if (value !== true)
+ url += "=" + encodeURIComponent(value);
+ sep = '&';
+ }
}
- });
-};
-
-Binder.prototype.entity = function (scope) {
- this.docFindWithSelf("[ng-entity]").attr("ng-watch", function() {
- try {
- var jNode = jQuery(this);
- var decl = scope.entity(jNode.attr("ng-entity"));
- return decl + (jNode.attr('ng-watch') || "");
- } catch (e) {
- alert(e);
+ this.urlWatcher.setUrl(url);
+ return url;
+ },
+
+ updateView: function() {
+ var start = new Date().getTime();
+ var scope = jQuery(this.doc).scope();
+ scope.set("$invalidWidgets", []);
+ scope.updateView();
+ var end = new Date().getTime();
+ this.updateAnchor();
+ _.each(this.updateListeners, function(fn) {fn();});
+ },
+
+ docFindWithSelf: function(exp){
+ var doc = jQuery(this.doc);
+ var selection = doc.find(exp);
+ if (doc.is(exp)){
+ selection = selection.andSelf();
}
- });
-};
-
-Binder.prototype.compile = function() {
- var jNode = jQuery(this.doc);
- var self = this;
- if (this.config.autoSubmit) {
- var submits = this.docFindWithSelf(":submit").not("[ng-action]");
- submits.attr("ng-action", "$save()");
- submits.not(":disabled").not("ng-bind-attr").attr("ng-bind-attr", '{disabled:"{{$invalidWidgets}}"}');
- }
- this.precompile(this.doc)(this.doc, jNode.scope(), "");
- this.docFindWithSelf("a[ng-action]").live('click', function (event) {
- var jNode = jQuery(this);
- try {
- jNode.scope().eval(jNode.attr('ng-action'));
- jNode.removeAttr('ng-error');
- jNode.removeClass("ng-exception");
- } catch (e) {
- jNode.addClass("ng-exception");
- jNode.attr('ng-error', toJson(e, true));
+ return selection;
+ },
+
+ executeInit: function() {
+ this.docFindWithSelf("[ng-init]").each(function() {
+ var jThis = jQuery(this);
+ var scope = jThis.scope();
+ try {
+ scope.eval(jThis.attr('ng-init'));
+ } catch (e) {
+ alert("EVAL ERROR:\n" + jThis.attr('ng-init') + '\n' + toJson(e, true));
+ }
+ });
+ },
+
+ entity: function (scope) {
+ this.docFindWithSelf("[ng-entity]").attr("ng-watch", function() {
+ try {
+ var jNode = jQuery(this);
+ var decl = scope.entity(jNode.attr("ng-entity"));
+ return decl + (jNode.attr('ng-watch') || "");
+ } catch (e) {
+ alert(e);
+ }
+ });
+ },
+
+ compile: function() {
+ var jNode = jQuery(this.doc);
+ var self = this;
+ if (this.config.autoSubmit) {
+ var submits = this.docFindWithSelf(":submit").not("[ng-action]");
+ submits.attr("ng-action", "$save()");
+ submits.not(":disabled").not("ng-bind-attr").attr("ng-bind-attr", '{disabled:"{{$invalidWidgets}}"}');
}
- self.updateView();
- return false;
- });
-};
-
-Binder.prototype.translateBinding = function(node, parentPath, factories) {
- var path = parentPath.concat();
- var offset = path.pop();
- var parts = Binder.parseBindings(node.nodeValue);
- if (parts.length > 1 || Binder.binding(parts[0])) {
- var parent = node.parentNode;
- if (isLeafNode(parent)) {
- parent.setAttribute('ng-bind-template', node.nodeValue);
- factories.push({path:path, fn:function(node, scope, prefix) {
- return new BindUpdater(node, node.getAttribute('ng-bind-template'));
- }});
- } else {
- for (var i = 0; i < parts.length; i++) {
- var part = parts[i];
- var binding = Binder.binding(part);
- var newNode;
- if (binding) {
- newNode = document.createElement("span");
- var jNewNode = jQuery(newNode);
- jNewNode.attr("ng-bind", binding);
- if (i === 0) {
- factories.push({path:path.concat(offset + i), fn:Binder.prototype.ng_bind});
+ this.precompile(this.doc)(this.doc, jNode.scope(), "");
+ this.docFindWithSelf("a[ng-action]").live('click', function (event) {
+ var jNode = jQuery(this);
+ try {
+ jNode.scope().eval(jNode.attr('ng-action'));
+ jNode.removeAttr('ng-error');
+ jNode.removeClass("ng-exception");
+ } catch (e) {
+ jNode.addClass("ng-exception");
+ jNode.attr('ng-error', toJson(e, true));
+ }
+ self.updateView();
+ return false;
+ });
+ },
+
+ translateBinding: function(node, parentPath, factories) {
+ var path = parentPath.concat();
+ var offset = path.pop();
+ var parts = Binder.parseBindings(node.nodeValue);
+ if (parts.length > 1 || Binder.binding(parts[0])) {
+ var parent = node.parentNode;
+ if (isLeafNode(parent)) {
+ parent.setAttribute('ng-bind-template', node.nodeValue);
+ factories.push({path:path, fn:function(node, scope, prefix) {
+ return new BindUpdater(node, node.getAttribute('ng-bind-template'));
+ }});
+ } else {
+ for (var i = 0; i < parts.length; i++) {
+ var part = parts[i];
+ var binding = Binder.binding(part);
+ var newNode;
+ if (binding) {
+ newNode = document.createElement("span");
+ var jNewNode = jQuery(newNode);
+ jNewNode.attr("ng-bind", binding);
+ if (i === 0) {
+ factories.push({path:path.concat(offset + i), fn:this.ng_bind});
+ }
+ } else if (msie && part.charAt(0) == ' ') {
+ newNode = document.createElement("span");
+ newNode.innerHTML = ' ' + part.substring(1);
+ } else {
+ newNode = document.createTextNode(part);
}
- } else if (msie && part.charAt(0) == ' ') {
- newNode = document.createElement("span");
- newNode.innerHTML = ' ' + part.substring(1);
- } else {
- newNode = document.createTextNode(part);
+ parent.insertBefore(newNode, node);
}
- parent.insertBefore(newNode, node);
}
+ parent.removeChild(node);
}
- parent.removeChild(node);
- }
-};
-
-Binder.prototype.precompile = function(root) {
- var factories = [];
- this.precompileNode(root, [], factories);
- return function (template, scope, prefix) {
- var len = factories.length;
- for (var i = 0; i < len; i++) {
- var factory = factories[i];
- var node = template;
- var path = factory.path;
- for (var j = 0; j < path.length; j++) {
- node = node.childNodes[path[j]];
+ },
+
+ precompile: function(root) {
+ var factories = [];
+ this.precompileNode(root, [], factories);
+ return function (template, scope, prefix) {
+ var len = factories.length;
+ for (var i = 0; i < len; i++) {
+ var factory = factories[i];
+ var node = template;
+ var path = factory.path;
+ for (var j = 0; j < path.length; j++) {
+ node = node.childNodes[path[j]];
+ }
+ try {
+ scope.addWidget(factory.fn(node, scope, prefix));
+ } catch (e) {
+ alert(e);
+ }
}
- try {
- scope.addWidget(factory.fn(node, scope, prefix));
- } catch (e) {
- alert(e);
+ };
+ },
+
+ precompileNode: function(node, path, factories) {
+ var nodeType = node.nodeType;
+ if (nodeType == Node.TEXT_NODE) {
+ this.translateBinding(node, path, factories);
+ return;
+ } else if (nodeType != Node.ELEMENT_NODE && nodeType != Node.DOCUMENT_NODE) {
+ return;
+ }
+
+ if (!node.getAttribute) return;
+ var nonBindable = node.getAttribute('ng-non-bindable');
+ if (nonBindable || nonBindable === "") return;
+
+ var attributes = node.attributes;
+ if (attributes) {
+ var bindings = node.getAttribute('ng-bind-attr');
+ node.removeAttribute('ng-bind-attr');
+ bindings = bindings ? fromJson(bindings) : {};
+ var attrLen = attributes.length;
+ for (var i = 0; i < attrLen; i++) {
+ var attr = attributes[i];
+ var attrName = attr.name;
+ // http://www.glennjones.net/Post/809/getAttributehrefbug.htm
+ var attrValue = msie && attrName == 'href' ?
+ decodeURI(node.getAttribute(attrName, 2)) : attr.value;
+ if (Binder.hasBinding(attrValue)) {
+ bindings[attrName] = attrValue;
+ }
+ }
+ var json = toJson(bindings);
+ if (json.length > 2) {
+ node.setAttribute("ng-bind-attr", json);
}
}
- };
-};
-
-Binder.prototype.precompileNode = function(node, path, factories) {
- var nodeType = node.nodeType;
- if (nodeType == Node.TEXT_NODE) {
- this.translateBinding(node, path, factories);
- return;
- } else if (nodeType != Node.ELEMENT_NODE && nodeType != Node.DOCUMENT_NODE) {
- return;
- }
-
- if (!node.getAttribute) return;
- var nonBindable = node.getAttribute('ng-non-bindable');
- if (nonBindable || nonBindable === "") return;
-
- var attributes = node.attributes;
- if (attributes) {
- var bindings = node.getAttribute('ng-bind-attr');
- node.removeAttribute('ng-bind-attr');
- bindings = bindings ? fromJson(bindings) : {};
- var attrLen = attributes.length;
- for (var i = 0; i < attrLen; i++) {
- var attr = attributes[i];
- var attrName = attr.name;
- // http://www.glennjones.net/Post/809/getAttributehrefbug.htm
- var attrValue = msie && attrName == 'href' ?
- decodeURI(node.getAttribute(attrName, 2)) : attr.value;
- if (Binder.hasBinding(attrValue)) {
- bindings[attrName] = attrValue;
+
+ if (!node.getAttribute) log(node);
+ var repeaterExpression = node.getAttribute('ng-repeat');
+ if (repeaterExpression) {
+ node.removeAttribute('ng-repeat');
+ var precompiled = this.precompile(node);
+ var view = document.createComment("ng-repeat: " + repeaterExpression);
+ var parentNode = node.parentNode;
+ parentNode.insertBefore(view, node);
+ parentNode.removeChild(node);
+ function template(childScope, prefix, i) {
+ var clone = jQuery(node).clone();
+ clone.css('display', '');
+ clone.attr('ng-repeat-index', "" + i);
+ clone.data('scope', childScope);
+ precompiled(clone[0], childScope, prefix + i + ":");
+ return clone;
}
+ factories.push({path:path, fn:function(node, scope, prefix) {
+ return new RepeaterUpdater(jQuery(node), repeaterExpression, template, prefix);
+ }});
+ return;
}
- var json = toJson(bindings);
- if (json.length > 2) {
- node.setAttribute("ng-bind-attr", json);
+
+ if (node.getAttribute('ng-eval')) factories.push({path:path, fn:this.ng_eval});
+ if (node.getAttribute('ng-bind')) factories.push({path:path, fn:this.ng_bind});
+ if (node.getAttribute('ng-bind-attr')) factories.push({path:path, fn:this.ng_bind_attr});
+ if (node.getAttribute('ng-hide')) factories.push({path:path, fn:this.ng_hide});
+ if (node.getAttribute('ng-show')) factories.push({path:path, fn:this.ng_show});
+ if (node.getAttribute('ng-class')) factories.push({path:path, fn:this.ng_class});
+ if (node.getAttribute('ng-class-odd')) factories.push({path:path, fn:this.ng_class_odd});
+ if (node.getAttribute('ng-class-even')) factories.push({path:path, fn:this.ng_class_even});
+ if (node.getAttribute('ng-style')) factories.push({path:path, fn:this.ng_style});
+ if (node.getAttribute('ng-watch')) factories.push({path:path, fn:this.ng_watch});
+ var nodeName = node.nodeName;
+ if ((nodeName == 'INPUT' ) ||
+ nodeName == 'TEXTAREA' ||
+ nodeName == 'SELECT' ||
+ nodeName == 'BUTTON') {
+ var self = this;
+ factories.push({path:path, fn:function(node, scope, prefix) {
+ node.name = prefix + node.name.split(":").pop();
+ return self.widgetFactory.createController(jQuery(node), scope);
+ }});
}
- }
-
- if (!node.getAttribute) log(node);
- var repeaterExpression = node.getAttribute('ng-repeat');
- if (repeaterExpression) {
- node.removeAttribute('ng-repeat');
- var precompiled = this.precompile(node);
- var view = document.createComment("ng-repeat: " + repeaterExpression);
- var parentNode = node.parentNode;
- parentNode.insertBefore(view, node);
- parentNode.removeChild(node);
- var template = function(childScope, prefix, i) {
- var clone = jQuery(node).clone();
- clone.css('display', '');
- clone.attr('ng-repeat-index', "" + i);
- clone.data('scope', childScope);
- precompiled(clone[0], childScope, prefix + i + ":");
- return clone;
- };
- factories.push({path:path, fn:function(node, scope, prefix) {
- return new RepeaterUpdater(jQuery(node), repeaterExpression, template, prefix);
- }});
- return;
- }
-
- if (node.getAttribute('ng-eval')) factories.push({path:path, fn:this.ng_eval});
- if (node.getAttribute('ng-bind')) factories.push({path:path, fn:this.ng_bind});
- if (node.getAttribute('ng-bind-attr')) factories.push({path:path, fn:this.ng_bind_attr});
- if (node.getAttribute('ng-hide')) factories.push({path:path, fn:this.ng_hide});
- if (node.getAttribute('ng-show')) factories.push({path:path, fn:this.ng_show});
- if (node.getAttribute('ng-class')) factories.push({path:path, fn:this.ng_class});
- if (node.getAttribute('ng-class-odd')) factories.push({path:path, fn:this.ng_class_odd});
- if (node.getAttribute('ng-class-even')) factories.push({path:path, fn:this.ng_class_even});
- if (node.getAttribute('ng-style')) factories.push({path:path, fn:this.ng_style});
- if (node.getAttribute('ng-watch')) factories.push({path:path, fn:this.ng_watch});
- var nodeName = node.nodeName;
- if ((nodeName == 'INPUT' ) ||
- nodeName == 'TEXTAREA' ||
- nodeName == 'SELECT' ||
- nodeName == 'BUTTON') {
- var self = this;
- factories.push({path:path, fn:function(node, scope, prefix) {
- node.name = prefix + node.name.split(":").pop();
- return self.widgetFactory.createController(jQuery(node), scope);
- }});
- }
- if (nodeName == 'OPTION') {
- var html = jQuery('').append(jQuery(node).clone()).html();
- if (!html.match(/';
-ControlBar.prototype.login = function (loginSubmitFn) {
- this.callbacks.push(loginSubmitFn);
- if (this.callbacks.length == 1) {
- this.doTemplate("/user_session/new.mini?return_url=" + encodeURIComponent(this.urlWithoutAnchor()));
- }
-};
-
-ControlBar.prototype.logout = function (loginSubmitFn) {
- this.callbacks.push(loginSubmitFn);
- if (this.callbacks.length == 1) {
- this.doTemplate("/user_session/do_destroy.mini");
- }
-};
-
-ControlBar.prototype.urlWithoutAnchor = function (path) {
- return this.window.location.href.split("#")[0];
-};
-
-ControlBar.prototype.doTemplate = function (path) {
- var self = this;
- var id = new Date().getTime();
- var url = this.urlWithoutAnchor();
- url += "#$iframe_notify=" + id;
- var iframeHeight = 330;
- var loginView = jQuery('
');
- this.document.append(loginView);
- loginView.dialog({
- height:iframeHeight + 33, width:500,
- resizable: false, modal:true,
- title: 'Authentication:
<angular/>'
- });
- callbacks["_iframe_notify_" + id] = function() {
- loginView.dialog("destroy");
- loginView.remove();
- foreach(self.callbacks, function(callback){
- callback();
- });
- self.callbacks = [];
- };
-};
-
ControlBar.FORBIDEN =
'
' +
'Sorry, you do not have permission for this!'+
'
';
-ControlBar.prototype.notAuthorized = function () {
- if (this.forbidenView) return;
- this.forbidenView = jQuery(ControlBar.FORBIDEN);
- this.forbidenView.dialog({bgiframe:true, height:70, modal:true});
-};
+
+
+ControlBar.prototype = {
+ bind: function () {
+ },
+
+ login: function (loginSubmitFn) {
+ this.callbacks.push(loginSubmitFn);
+ if (this.callbacks.length == 1) {
+ this.doTemplate("/user_session/new.mini?return_url=" + encodeURIComponent(this.urlWithoutAnchor()));
+ }
+ },
+
+ logout: function (loginSubmitFn) {
+ this.callbacks.push(loginSubmitFn);
+ if (this.callbacks.length == 1) {
+ this.doTemplate("/user_session/do_destroy.mini");
+ }
+ },
+
+ urlWithoutAnchor: function (path) {
+ return this.window.location.href.split("#")[0];
+ },
+
+ doTemplate: function (path) {
+ var self = this;
+ var id = new Date().getTime();
+ var url = this.urlWithoutAnchor();
+ url += "#$iframe_notify=" + id;
+ var iframeHeight = 330;
+ var loginView = jQuery('
');
+ this.document.append(loginView);
+ loginView.dialog({
+ height:iframeHeight + 33, width:500,
+ resizable: false, modal:true,
+ title: 'Authentication:
<angular/>'
+ });
+ callbacks["_iframe_notify_" + id] = function() {
+ loginView.dialog("destroy");
+ loginView.remove();
+ foreach(self.callbacks, function(callback){
+ callback();
+ });
+ self.callbacks = [];
+ };
+ },
+
+ notAuthorized: function () {
+ if (this.forbidenView) return;
+ this.forbidenView = jQuery(ControlBar.FORBIDEN);
+ this.forbidenView.dialog({bgiframe:true, height:70, modal:true});
+ }
+};
\ No newline at end of file
diff --git a/src/DataStore.js b/src/DataStore.js
index f99e5824..7952096f 100644
--- a/src/DataStore.js
+++ b/src/DataStore.js
@@ -1,6 +1,4 @@
-// Copyright (C) 2009 BRAT Tech LLC
-
-DataStore = function(post, users, anchor) {
+function DataStore(post, users, anchor) {
this.post = post;
this.users = users;
this._cache = {$collections:[]};
@@ -8,325 +6,329 @@ DataStore = function(post, users, anchor) {
this.bulkRequest = [];
};
-DataStore.prototype.cache = function(document) {
- if (document.constructor != Model) {
- throw "Parameter must be an instance of Entity! " + toJson(document);
- }
- var key = document.$entity + '/' + document.$id;
- var cachedDocument = this._cache[key];
- if (cachedDocument) {
- Model.copyDirectFields(document, cachedDocument);
- } else {
- this._cache[key] = document;
- cachedDocument = document;
- }
- return cachedDocument;
-};
-
-DataStore.prototype.load = function(instance, id, callback, failure) {
- if (id && id !== '*') {
- var self = this;
- this._jsonRequest(["GET", instance.$entity + "/" + id], function(response) {
- instance.$loadFrom(response);
- instance.$migrate();
- var clone = instance.$$entity(instance);
- self.cache(clone);
- (callback||noop)(instance);
- }, failure);
- }
- return instance;
-};
-
-DataStore.prototype.loadMany = function(entity, ids, callback) {
- var self=this;
- var list = [];
- var callbackCount = 0;
- foreach(ids, function(id){
- list.push(self.load(entity(), id, function(){
- callbackCount++;
- if (callbackCount == ids.length) {
- (callback||noop)(list);
- }
- }));
- });
- return list;
-};
+DataStore.NullEntity = extend(function(){}, {
+ 'all': function(){return [];},
+ 'query': function(){return [];},
+ 'load': function(){return {};},
+ 'title': undefined
+});
-DataStore.prototype.loadOrCreate = function(instance, id, callback) {
- var self=this;
- return this.load(instance, id, callback, function(response){
- if (response.$status_code == 404) {
- instance.$id = id;
- (callback||noop)(instance);
+DataStore.prototype = {
+ cache: function(document) {
+ if (! document instanceof Model) {
+ throw "Parameter must be an instance of Entity! " + toJson(document);
+ }
+ var key = document.$entity + '/' + document.$id;
+ var cachedDocument = this._cache[key];
+ if (cachedDocument) {
+ Model.copyDirectFields(document, cachedDocument);
} else {
- throw response;
+ this._cache[key] = document;
+ cachedDocument = document;
}
- });
-};
-
-DataStore.prototype.loadAll = function(entity, callback) {
- var self = this;
- var list = [];
- list.$$accept = function(doc){
- return doc.$entity == entity.title;
- };
- this._cache.$collections.push(list);
- this._jsonRequest(["GET", entity.title], function(response) {
- var rows = response;
- for ( var i = 0; i < rows.length; i++) {
- var document = entity();
- document.$loadFrom(rows[i]);
- list.push(self.cache(document));
+ return cachedDocument;
+ },
+
+ load: function(instance, id, callback, failure) {
+ if (id && id !== '*') {
+ var self = this;
+ this._jsonRequest(["GET", instance.$entity + "/" + id], function(response) {
+ instance.$loadFrom(response);
+ instance.$migrate();
+ var clone = instance.$$entity(instance);
+ self.cache(clone);
+ (callback||noop)(instance);
+ }, failure);
}
- (callback||noop)(list);
- });
- return list;
-};
-
-DataStore.prototype.save = function(document, callback) {
- var self = this;
- var data = {};
- document.$saveTo(data);
- this._jsonRequest(["POST", "", data], function(response) {
- document.$loadFrom(response);
- var cachedDoc = self.cache(document);
- _.each(self._cache.$collections, function(collection){
- if (collection.$$accept(document)) {
- angular['Array']['includeIf'](collection, cachedDoc, true);
+ return instance;
+ },
+
+ loadMany: function(entity, ids, callback) {
+ var self=this;
+ var list = [];
+ var callbackCount = 0;
+ foreach(ids, function(id){
+ list.push(self.load(entity(), id, function(){
+ callbackCount++;
+ if (callbackCount == ids.length) {
+ (callback||noop)(list);
+ }
+ }));
+ });
+ return list;
+ },
+
+ loadOrCreate: function(instance, id, callback) {
+ var self=this;
+ return this.load(instance, id, callback, function(response){
+ if (response.$status_code == 404) {
+ instance.$id = id;
+ (callback||noop)(instance);
+ } else {
+ throw response;
}
});
- if (document.$$anchor) {
- self.anchor[document.$$anchor] = document.$id;
- }
- if (callback)
- callback(document);
- });
-};
-
-DataStore.prototype.remove = function(document, callback) {
- var self = this;
- var data = {};
- document.$saveTo(data);
- this._jsonRequest(["DELETE", "", data], function(response) {
- delete self._cache[document.$entity + '/' + document.$id];
- _.each(self._cache.$collections, function(collection){
- for ( var i = 0; i < collection.length; i++) {
- var item = collection[i];
- if (item.$id == document.$id) {
- collection.splice(i, 1);
+ },
+
+ loadAll: function(entity, callback) {
+ var self = this;
+ var list = [];
+ list.$$accept = function(doc){
+ return doc.$entity == entity.title;
+ };
+ this._cache.$collections.push(list);
+ this._jsonRequest(["GET", entity.title], function(response) {
+ var rows = response;
+ for ( var i = 0; i < rows.length; i++) {
+ var document = entity();
+ document.$loadFrom(rows[i]);
+ list.push(self.cache(document));
+ }
+ (callback||noop)(list);
+ });
+ return list;
+ },
+
+ save: function(document, callback) {
+ var self = this;
+ var data = {};
+ document.$saveTo(data);
+ this._jsonRequest(["POST", "", data], function(response) {
+ document.$loadFrom(response);
+ var cachedDoc = self.cache(document);
+ _.each(self._cache.$collections, function(collection){
+ if (collection.$$accept(document)) {
+ angular['Array']['includeIf'](collection, cachedDoc, true);
}
+ });
+ if (document.$$anchor) {
+ self.anchor[document.$$anchor] = document.$id;
}
+ if (callback)
+ callback(document);
});
- (callback||noop)(response);
- });
-};
-
-DataStore.prototype._jsonRequest = function(request, callback, failure) {
- request.$$callback = callback;
- request.$$failure = failure||function(response){
- throw response;
- };
- this.bulkRequest.push(request);
-};
-
-DataStore.prototype.flush = function() {
- if (this.bulkRequest.length === 0) return;
- var self = this;
- var bulkRequest = this.bulkRequest;
- this.bulkRequest = [];
- log('REQUEST:', bulkRequest);
- function callback(code, bulkResponse){
- log('RESPONSE[' + code + ']: ', bulkResponse);
- if(bulkResponse.$status_code == 401) {
- self.users.login(function(){
- self.post(bulkRequest, callback);
+ },
+
+ remove: function(document, callback) {
+ var self = this;
+ var data = {};
+ document.$saveTo(data);
+ this._jsonRequest(["DELETE", "", data], function(response) {
+ delete self._cache[document.$entity + '/' + document.$id];
+ _.each(self._cache.$collections, function(collection){
+ for ( var i = 0; i < collection.length; i++) {
+ var item = collection[i];
+ if (item.$id == document.$id) {
+ collection.splice(i, 1);
+ }
+ }
});
- } else if(bulkResponse.$status_code) {
- alert(toJson(bulkResponse));
- } else {
- for ( var i = 0; i < bulkResponse.length; i++) {
- var response = bulkResponse[i];
- var request = bulkRequest[i];
- var responseCode = response.$status_code;
- if(responseCode) {
- if(responseCode == 403) {
- self.users.notAuthorized();
+ (callback||noop)(response);
+ });
+ },
+
+ _jsonRequest: function(request, callback, failure) {
+ request.$$callback = callback;
+ request.$$failure = failure||function(response){
+ throw response;
+ };
+ this.bulkRequest.push(request);
+ },
+
+ flush: function() {
+ if (this.bulkRequest.length === 0) return;
+ var self = this;
+ var bulkRequest = this.bulkRequest;
+ this.bulkRequest = [];
+ log('REQUEST:', bulkRequest);
+ function callback(code, bulkResponse){
+ log('RESPONSE[' + code + ']: ', bulkResponse);
+ if(bulkResponse.$status_code == 401) {
+ self.users.login(function(){
+ self.post(bulkRequest, callback);
+ });
+ } else if(bulkResponse.$status_code) {
+ alert(toJson(bulkResponse));
+ } else {
+ for ( var i = 0; i < bulkResponse.length; i++) {
+ var response = bulkResponse[i];
+ var request = bulkRequest[i];
+ var responseCode = response.$status_code;
+ if(responseCode) {
+ if(responseCode == 403) {
+ self.users.notAuthorized();
+ } else {
+ request.$$failure(response);
+ }
} else {
- request.$$failure(response);
+ request.$$callback(response);
}
- } else {
- request.$$callback(response);
}
}
}
- }
- this.post(bulkRequest, callback);
-};
-
-DataStore.prototype.saveScope = function(scope, callback) {
- var saveCounter = 1;
- function onSaveDone() {
- saveCounter--;
- if (saveCounter === 0 && callback)
- callback();
- }
- for(var key in scope) {
- var item = scope[key];
- if (item && item.$save == Model.prototype.$save) {
- saveCounter++;
- item.$save(onSaveDone);
- }
- }
- onSaveDone();
-};
-
-DataStore.prototype.query = function(type, query, arg, callback){
- var self = this;
- var queryList = [];
- queryList.$$accept = function(doc){
- return false;
- };
- this._cache.$collections.push(queryList);
- var request = type.title + '/' + query + '=' + arg;
- this._jsonRequest(["GET", request], function(response){
- var list = response;
- for(var i = 0; i < list.length; i++) {
- var document = new type().$loadFrom(list[i]);
- queryList.push(self.cache(document));
+ this.post(bulkRequest, callback);
+ },
+
+ saveScope: function(scope, callback) {
+ var saveCounter = 1;
+ function onSaveDone() {
+ saveCounter--;
+ if (saveCounter === 0 && callback)
+ callback();
}
- if (callback)
- callback(queryList);
- });
- return queryList;
-};
-
-DataStore.prototype.entities = function(callback) {
- var entities = [];
- var self = this;
- this._jsonRequest(["GET", "$entities"], function(response) {
- for (var entityName in response) {
- entities.push(self.entity(entityName));
+ for(var key in scope) {
+ var item = scope[key];
+ if (item && item.$save == Model.prototype.$save) {
+ saveCounter++;
+ item.$save(onSaveDone);
+ }
}
- entities.sort(function(a,b){return a.title > b.title ? 1 : -1;});
- if (callback) callback(entities);
- });
- return entities;
-};
-
-DataStore.prototype.documentCountsByUser = function(){
- var counts = {};
- var self = this;
- self.post([["GET", "$users"]], function(code, response){
- foreach(response[0], function(value, key){
- counts[key] = value;
+ onSaveDone();
+ },
+
+ query: function(type, query, arg, callback){
+ var self = this;
+ var queryList = [];
+ queryList.$$accept = function(doc){
+ return false;
+ };
+ this._cache.$collections.push(queryList);
+ var request = type.title + '/' + query + '=' + arg;
+ this._jsonRequest(["GET", request], function(response){
+ var list = response;
+ for(var i = 0; i < list.length; i++) {
+ var document = new type().$loadFrom(list[i]);
+ queryList.push(self.cache(document));
+ }
+ if (callback)
+ callback(queryList);
});
- });
- return counts;
-};
-
-DataStore.prototype.userDocumentIdsByEntity = function(user){
- var ids = {};
- var self = this;
- self.post([["GET", "$users/" + user]], function(code, response){
- foreach(response[0], function(value, key){
- ids[key] = value;
+ return queryList;
+ },
+
+ entities: function(callback) {
+ var entities = [];
+ var self = this;
+ this._jsonRequest(["GET", "$entities"], function(response) {
+ for (var entityName in response) {
+ entities.push(self.entity(entityName));
+ }
+ entities.sort(function(a,b){return a.title > b.title ? 1 : -1;});
+ if (callback) callback(entities);
});
- });
- return ids;
-};
-
-DataStore.NullEntity = function(){};
-DataStore.NullEntity.all = function(){return [];};
-DataStore.NullEntity.query = function(){return [];};
-DataStore.NullEntity.load = function(){return {};};
-DataStore.NullEntity.title = undefined;
-
-DataStore.prototype.entity = function(name, defaults){
- if (!name) {
- return DataStore.NullEntity;
- }
- var self = this;
- var entity = function(initialState){
- return new Model(entity, initialState);
- };
- // entity.name does not work as name seems to be reserved for functions
- entity.title = name;
- entity.$$factory = true;
- entity.datastore = this;
- entity.defaults = defaults || {};
- entity.load = function(id, callback){
- return self.load(entity(), id, callback);
- };
- entity.loadMany = function(ids, callback){
- return self.loadMany(entity, ids, callback);
- };
- entity.loadOrCreate = function(id, callback){
- return self.loadOrCreate(entity(), id, callback);
- };
- entity.all = function(callback){
- return self.loadAll(entity, callback);
- };
- entity.query = function(query, queryArgs, callback){
- return self.query(entity, query, queryArgs, callback);
- };
- entity.properties = function(callback) {
- self._jsonRequest(["GET", name + "/$properties"], callback);
- };
- return entity;
-};
-
-DataStore.prototype.join = function(join){
- var fn = function(){
- throw "Joined entities can not be instantiated into a document.";
- };
- function base(name){return name ? name.substring(0, name.indexOf('.')) : undefined;}
- function next(name){return name.substring(name.indexOf('.') + 1);}
- var joinOrder = _(join).chain().
- map(function($, name){
- return name;}).
- sortBy(function(name){
- var path = [];
- do {
- if (_(path).include(name)) throw "Infinite loop in join: " + path.join(" -> ");
- path.push(name);
- if (!join[name]) throw _("Named entity '<%=name%>' is undefined.").template({name:name});
- name = base(join[name].on);
- } while(name);
- return path.length;
- }).
- value();
- if (_(joinOrder).select(function($){return join[$].on;}).length != joinOrder.length - 1)
- throw "Exactly one entity needs to be primary.";
- fn.query = function(exp, value) {
- var joinedResult = [];
- var baseName = base(exp);
- if (baseName != joinOrder[0]) throw _("Named entity '<%=name%>' is not a primary entity.").template({name:baseName});
- var Entity = join[baseName].join;
- var joinIndex = 1;
- Entity.query(next(exp), value, function(result){
- var nextJoinName = joinOrder[joinIndex++];
- var nextJoin = join[nextJoinName];
- var nextJoinOn = nextJoin.on;
- var joinIds = {};
- _(result).each(function(doc){
- var row = {};
- joinedResult.push(row);
- row[baseName] = doc;
- var id = Scope.getter(row, nextJoinOn);
- joinIds[id] = id;
+ return entities;
+ },
+
+ documentCountsByUser: function(){
+ var counts = {};
+ var self = this;
+ self.post([["GET", "$users"]], function(code, response){
+ foreach(response[0], function(value, key){
+ counts[key] = value;
});
- nextJoin.join.loadMany(_.toArray(joinIds), function(result){
- var byId = {};
+ });
+ return counts;
+ },
+
+ userDocumentIdsByEntity: function(user){
+ var ids = {};
+ var self = this;
+ self.post([["GET", "$users/" + user]], function(code, response){
+ foreach(response[0], function(value, key){
+ ids[key] = value;
+ });
+ });
+ return ids;
+ },
+
+ entity: function(name, defaults){
+ if (!name) {
+ return DataStore.NullEntity;
+ }
+ var self = this;
+ var entity = extend(function(initialState){
+ return new Model(entity, initialState);
+ }, {
+ // entity.name does not work as name seems to be reserved for functions
+ 'title': name,
+ '$$factory': true,
+ 'datastore': this,
+ 'defaults': defaults || {},
+ 'load': function(id, callback){
+ return self.load(entity(), id, callback);
+ },
+ 'loadMany': function(ids, callback){
+ return self.loadMany(entity, ids, callback);
+ },
+ 'loadOrCreate': function(id, callback){
+ return self.loadOrCreate(entity(), id, callback);
+ },
+ 'all': function(callback){
+ return self.loadAll(entity, callback);
+ },
+ 'query': function(query, queryArgs, callback){
+ return self.query(entity, query, queryArgs, callback);
+ },
+ 'properties': function(callback) {
+ self._jsonRequest(["GET", name + "/$properties"], callback);
+ }
+ });
+ return entity;
+ },
+
+ join: function(join){
+ function fn(){
+ throw "Joined entities can not be instantiated into a document.";
+ };
+ function base(name){return name ? name.substring(0, name.indexOf('.')) : undefined;}
+ function next(name){return name.substring(name.indexOf('.') + 1);}
+ var joinOrder = _(join).chain().
+ map(function($, name){
+ return name;}).
+ sortBy(function(name){
+ var path = [];
+ do {
+ if (_(path).include(name)) throw "Infinite loop in join: " + path.join(" -> ");
+ path.push(name);
+ if (!join[name]) throw _("Named entity '<%=name%>' is undefined.").template({name:name});
+ name = base(join[name].on);
+ } while(name);
+ return path.length;
+ }).
+ value();
+ if (_(joinOrder).select(function($){return join[$].on;}).length != joinOrder.length - 1)
+ throw "Exactly one entity needs to be primary.";
+ fn['query'] = function(exp, value) {
+ var joinedResult = [];
+ var baseName = base(exp);
+ if (baseName != joinOrder[0]) throw _("Named entity '<%=name%>' is not a primary entity.").template({name:baseName});
+ var Entity = join[baseName].join;
+ var joinIndex = 1;
+ Entity['query'](next(exp), value, function(result){
+ var nextJoinName = joinOrder[joinIndex++];
+ var nextJoin = join[nextJoinName];
+ var nextJoinOn = nextJoin.on;
+ var joinIds = {};
_(result).each(function(doc){
- byId[doc.$id] = doc;
- });
- _(joinedResult).each(function(row){
+ var row = {};
+ joinedResult.push(row);
+ row[baseName] = doc;
var id = Scope.getter(row, nextJoinOn);
- row[nextJoinName] = byId[id];
+ joinIds[id] = id;
+ });
+ nextJoin.join.loadMany(_.toArray(joinIds), function(result){
+ var byId = {};
+ _(result).each(function(doc){
+ byId[doc.$id] = doc;
+ });
+ _(joinedResult).each(function(row){
+ var id = Scope.getter(row, nextJoinOn);
+ row[nextJoinName] = byId[id];
+ });
});
});
- });
- return joinedResult;
- };
- return fn;
-};
+ return joinedResult;
+ };
+ return fn;
+ }
+};
\ No newline at end of file
diff --git a/src/Filters.js b/src/Filters.js
index 67fcffa1..666c9f30 100644
--- a/src/Filters.js
+++ b/src/Filters.js
@@ -1,5 +1,3 @@
-// Copyright (C) 2009 BRAT Tech LLC
-
angularFilter.Meta = function(obj){
if (obj) {
for ( var key in obj) {
diff --git a/src/JSON.js b/src/JSON.js
index 14fce1fb..0c842865 100644
--- a/src/JSON.js
+++ b/src/JSON.js
@@ -1,16 +1,16 @@
array = [].constructor;
-toJson = function(obj, pretty){
+function toJson(obj, pretty){
var buf = [];
toJsonArray(buf, obj, pretty ? "\n " : null);
return buf.join('');
};
-toPrettyJson = function(obj) {
+function toPrettyJson(obj) {
return toJson(obj, true);
};
-fromJson = function(json) {
+function fromJson(json) {
try {
var parser = new Parser(json, true);
var expression = parser.primary();
@@ -22,8 +22,10 @@ fromJson = function(json) {
}
};
+angular['toJson'] = toJson;
+angular['fromJson'] = fromJson;
-toJsonArray = function(buf, obj, pretty){
+function toJsonArray(buf, obj, pretty){
var type = typeof obj;
if (obj === null) {
buf.push("null");
diff --git a/src/Loader.js b/src/Loader.js
index 104dfec8..5207defb 100644
--- a/src/Loader.js
+++ b/src/Loader.js
@@ -1,7 +1,3 @@
-// Copyright (C) 2008,2009 BRAT Tech LLC
-
-// IE compatibility
-
if (typeof document.getAttribute == 'undefined')
document.getAttribute = function() {};
if (typeof Node == 'undefined') {
diff --git a/src/Model.js b/src/Model.js
index 35f6a1c1..4a3a1806 100644
--- a/src/Model.js
+++ b/src/Model.js
@@ -1,12 +1,10 @@
-// Copyright (C) 2009 BRAT Tech LLC
-
// Single $ is special and does not get searched
// Double $$ is special an is client only (does not get sent to server)
-Model = function(entity, initial) {
- this.$$entity = entity;
+function Model(entity, initial) {
+ this['$$entity'] = entity;
this.$loadFrom(initial||{});
- this.$entity = entity.title;
+ this.$entity = entity['title'];
this.$migrate();
};
@@ -27,39 +25,41 @@ Model.copyDirectFields = function(src, dst) {
}
};
-Model.prototype.$migrate = function() {
- merge(this.$$entity.defaults, this);
- return this;
-};
-
-Model.prototype.$merge = function(other) {
- merge(other, this);
- return this;
-};
-
-Model.prototype.$save = function(callback) {
- this.$$entity.datastore.save(this, callback === true ? undefined : callback);
- if (callback === true) this.$$entity.datastore.flush();
- return this;
-};
-
-Model.prototype.$delete = function(callback) {
- this.$$entity.datastore.remove(this, callback === true ? undefined : callback);
- if (callback === true) this.$$entity.datastore.flush();
- return this;
-};
-
-Model.prototype.$loadById = function(id, callback) {
- this.$$entity.datastore.load(this, id, callback);
- return this;
-};
-
-Model.prototype.$loadFrom = function(other) {
- Model.copyDirectFields(other, this);
- return this;
-};
-
-Model.prototype.$saveTo = function(other) {
- Model.copyDirectFields(this, other);
- return this;
-};
+Model.prototype = {
+ '$migrate': function() {
+ merge(this['$$entity'].defaults, this);
+ return this;
+ },
+
+ '$merge': function(other) {
+ merge(other, this);
+ return this;
+ },
+
+ '$save': function(callback) {
+ this['$$entity'].datastore.save(this, callback === true ? undefined : callback);
+ if (callback === true) this['$$entity'].datastore.flush();
+ return this;
+ },
+
+ '$delete': function(callback) {
+ this['$$entity'].datastore.remove(this, callback === true ? undefined : callback);
+ if (callback === true) this['$$entity'].datastore.flush();
+ return this;
+ },
+
+ '$loadById': function(id, callback) {
+ this['$$entity'].datastore.load(this, id, callback);
+ return this;
+ },
+
+ '$loadFrom': function(other) {
+ Model.copyDirectFields(other, this);
+ return this;
+ },
+
+ '$saveTo': function(other) {
+ Model.copyDirectFields(this, other);
+ return this;
+ }
+};
\ No newline at end of file
diff --git a/src/Parser.js b/src/Parser.js
index cdece11e..333b8413 100644
--- a/src/Parser.js
+++ b/src/Parser.js
@@ -1,4 +1,4 @@
-Lexer = function(text, parsStrings){
+function Lexer(text, parsStrings){
this.text = text;
// UTC dates have 20 characters, we send them through parser
this.dateParseLength = parsStrings ? 20 : -1;
@@ -30,210 +30,214 @@ Lexer.OPERATORS = {
'|':function(self, a,b){return b(self, a);},
'!':function(self, a){return !a;}
};
+Lexer.ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'};
-Lexer.prototype.peek = function() {
- if (this.index + 1 < this.text.length) {
- return this.text.charAt(this.index + 1);
- } else {
- return false;
- }
-};
-
-Lexer.prototype.parse = function() {
- var tokens = this.tokens;
- var OPERATORS = Lexer.OPERATORS;
- var canStartRegExp = true;
- while (this.index < this.text.length) {
- var ch = this.text.charAt(this.index);
- if (ch == '"' || ch == "'") {
- this.readString(ch);
- canStartRegExp = true;
- } else if (ch == '(' || ch == '[') {
- tokens.push({index:this.index, text:ch});
- this.index++;
- } else if (ch == '{' ) {
- var peekCh = this.peek();
- if (peekCh == ':' || peekCh == '(') {
- tokens.push({index:this.index, text:ch + peekCh});
+Lexer.prototype = {
+ peek: function() {
+ if (this.index + 1 < this.text.length) {
+ return this.text.charAt(this.index + 1);
+ } else {
+ return false;
+ }
+ },
+
+ parse: function() {
+ var tokens = this.tokens;
+ var OPERATORS = Lexer.OPERATORS;
+ var canStartRegExp = true;
+ while (this.index < this.text.length) {
+ var ch = this.text.charAt(this.index);
+ if (ch == '"' || ch == "'") {
+ this.readString(ch);
+ canStartRegExp = true;
+ } else if (ch == '(' || ch == '[') {
+ tokens.push({index:this.index, text:ch});
this.index++;
- } else {
+ } else if (ch == '{' ) {
+ var peekCh = this.peek();
+ if (peekCh == ':' || peekCh == '(') {
+ tokens.push({index:this.index, text:ch + peekCh});
+ this.index++;
+ } else {
+ tokens.push({index:this.index, text:ch});
+ }
+ this.index++;
+ canStartRegExp = true;
+ } else if (ch == ')' || ch == ']' || ch == '}' ) {
tokens.push({index:this.index, text:ch});
+ this.index++;
+ canStartRegExp = false;
+ } else if ( ch == ':' || ch == '.' || ch == ',' || ch == ';') {
+ tokens.push({index:this.index, text:ch});
+ this.index++;
+ canStartRegExp = true;
+ } else if ( canStartRegExp && ch == '/' ) {
+ this.readRegexp();
+ canStartRegExp = false;
+ } else if ( this.isNumber(ch) ) {
+ this.readNumber();
+ canStartRegExp = false;
+ } else if (this.isIdent(ch)) {
+ this.readIdent();
+ canStartRegExp = false;
+ } else if (this.isWhitespace(ch)) {
+ this.index++;
+ } else {
+ var ch2 = ch + this.peek();
+ var fn = OPERATORS[ch];
+ var fn2 = OPERATORS[ch2];
+ if (fn2) {
+ tokens.push({index:this.index, text:ch2, fn:fn2});
+ this.index += 2;
+ } else if (fn) {
+ tokens.push({index:this.index, text:ch, fn:fn});
+ this.index += 1;
+ } else {
+ throw "Lexer Error: Unexpected next character [" +
+ this.text.substring(this.index) +
+ "] in expression '" + this.text +
+ "' at column '" + (this.index+1) + "'.";
+ }
+ canStartRegExp = true;
}
- this.index++;
- canStartRegExp = true;
- } else if (ch == ')' || ch == ']' || ch == '}' ) {
- tokens.push({index:this.index, text:ch});
- this.index++;
- canStartRegExp = false;
- } else if ( ch == ':' || ch == '.' || ch == ',' || ch == ';') {
- tokens.push({index:this.index, text:ch});
- this.index++;
- canStartRegExp = true;
- } else if ( canStartRegExp && ch == '/' ) {
- this.readRegexp();
- canStartRegExp = false;
- } else if ( this.isNumber(ch) ) {
- this.readNumber();
- canStartRegExp = false;
- } else if (this.isIdent(ch)) {
- this.readIdent();
- canStartRegExp = false;
- } else if (this.isWhitespace(ch)) {
- this.index++;
- } else {
- var ch2 = ch + this.peek();
- var fn = OPERATORS[ch];
- var fn2 = OPERATORS[ch2];
- if (fn2) {
- tokens.push({index:this.index, text:ch2, fn:fn2});
- this.index += 2;
- } else if (fn) {
- tokens.push({index:this.index, text:ch, fn:fn});
- this.index += 1;
+ }
+ return tokens;
+ },
+
+ isNumber: function(ch) {
+ return '0' <= ch && ch <= '9';
+ },
+
+ isWhitespace: function(ch) {
+ return ch == ' ' || ch == '\r' || ch == '\t' ||
+ ch == '\n' || ch == '\v';
+ },
+
+ isIdent: function(ch) {
+ return 'a' <= ch && ch <= 'z' ||
+ 'A' <= ch && ch <= 'Z' ||
+ '_' == ch || ch == '$';
+ },
+
+ readNumber: function() {
+ var number = "";
+ var start = this.index;
+ while (this.index < this.text.length) {
+ var ch = this.text.charAt(this.index);
+ if (ch == '.' || this.isNumber(ch)) {
+ number += ch;
} else {
- throw "Lexer Error: Unexpected next character [" +
- this.text.substring(this.index) +
- "] in expression '" + this.text +
- "' at column '" + (this.index+1) + "'.";
+ break;
}
- canStartRegExp = true;
+ this.index++;
}
- }
- return tokens;
-};
-
-Lexer.prototype.isNumber = function(ch) {
- return '0' <= ch && ch <= '9';
-};
-
-Lexer.prototype.isWhitespace = function(ch) {
- return ch == ' ' || ch == '\r' || ch == '\t' ||
- ch == '\n' || ch == '\v';
-};
-
-Lexer.prototype.isIdent = function(ch) {
- return 'a' <= ch && ch <= 'z' ||
- 'A' <= ch && ch <= 'Z' ||
- '_' == ch || ch == '$';
-};
-
-Lexer.prototype.readNumber = function() {
- var number = "";
- var start = this.index;
- while (this.index < this.text.length) {
- var ch = this.text.charAt(this.index);
- if (ch == '.' || this.isNumber(ch)) {
- number += ch;
- } else {
- break;
+ number = 1 * number;
+ this.tokens.push({index:start, text:number,
+ fn:function(){return number;}});
+ },
+
+ readIdent: function() {
+ var ident = "";
+ var start = this.index;
+ while (this.index < this.text.length) {
+ var ch = this.text.charAt(this.index);
+ if (ch == '.' || this.isIdent(ch) || this.isNumber(ch)) {
+ ident += ch;
+ } else {
+ break;
+ }
+ this.index++;
}
- this.index++;
- }
- number = 1 * number;
- this.tokens.push({index:start, text:number,
- fn:function(){return number;}});
-};
-
-Lexer.prototype.readIdent = function() {
- var ident = "";
- var start = this.index;
- while (this.index < this.text.length) {
- var ch = this.text.charAt(this.index);
- if (ch == '.' || this.isIdent(ch) || this.isNumber(ch)) {
- ident += ch;
- } else {
- break;
+ var fn = Lexer.OPERATORS[ident];
+ if (!fn) {
+ fn = function(self){
+ return self.scope.get(ident);
+ };
+ fn.isAssignable = ident;
}
+ this.tokens.push({index:start, text:ident, fn:fn});
+ },
+
+ readString: function(quote) {
+ var start = this.index;
+ var dateParseLength = this.dateParseLength;
this.index++;
- }
- var fn = Lexer.OPERATORS[ident];
- if (!fn) {
- fn = function(self){
- return self.scope.get(ident);
- };
- fn.isAssignable = ident;
- }
- this.tokens.push({index:start, text:ident, fn:fn});
-};
-Lexer.ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'};
-Lexer.prototype.readString = function(quote) {
- var start = this.index;
- var dateParseLength = this.dateParseLength;
- this.index++;
- var string = "";
- var escape = false;
- while (this.index < this.text.length) {
- var ch = this.text.charAt(this.index);
- if (escape) {
- if (ch == 'u') {
- var hex = this.text.substring(this.index + 1, this.index + 5);
- this.index += 4;
- string += String.fromCharCode(parseInt(hex, 16));
- } else {
- var rep = Lexer.ESCAPE[ch];
- if (rep) {
- string += rep;
+ var string = "";
+ var escape = false;
+ while (this.index < this.text.length) {
+ var ch = this.text.charAt(this.index);
+ if (escape) {
+ if (ch == 'u') {
+ var hex = this.text.substring(this.index + 1, this.index + 5);
+ this.index += 4;
+ string += String.fromCharCode(parseInt(hex, 16));
} else {
- string += ch;
+ var rep = Lexer.ESCAPE[ch];
+ if (rep) {
+ string += rep;
+ } else {
+ string += ch;
+ }
}
+ escape = false;
+ } else if (ch == '\\') {
+ escape = true;
+ } else if (ch == quote) {
+ this.index++;
+ this.tokens.push({index:start, text:string,
+ fn:function(){
+ return (string.length == dateParseLength) ?
+ angular['String']['toDate'](string) : string;
+ }});
+ return;
+ } else {
+ string += ch;
}
- escape = false;
- } else if (ch == '\\') {
- escape = true;
- } else if (ch == quote) {
this.index++;
- this.tokens.push({index:start, text:string,
- fn:function(){
- return (string.length == dateParseLength) ?
- angular['String']['toDate'](string) : string;
- }});
- return;
- } else {
- string += ch;
}
+ throw "Lexer Error: Unterminated quote [" +
+ this.text.substring(start) + "] starting at column '" +
+ (start+1) + "' in expression '" + this.text + "'.";
+ },
+
+ readRegexp: function(quote) {
+ var start = this.index;
this.index++;
- }
- throw "Lexer Error: Unterminated quote [" +
- this.text.substring(start) + "] starting at column '" +
- (start+1) + "' in expression '" + this.text + "'.";
-};
-
-Lexer.prototype.readRegexp = function(quote) {
- var start = this.index;
- this.index++;
- var regexp = "";
- var escape = false;
- while (this.index < this.text.length) {
- var ch = this.text.charAt(this.index);
- if (escape) {
- regexp += ch;
- escape = false;
- } else if (ch === '\\') {
- regexp += ch;
- escape = true;
- } else if (ch === '/') {
- this.index++;
- var flags = "";
- if (this.isIdent(this.text.charAt(this.index))) {
- this.readIdent();
- flags = this.tokens.pop().text;
+ var regexp = "";
+ var escape = false;
+ while (this.index < this.text.length) {
+ var ch = this.text.charAt(this.index);
+ if (escape) {
+ regexp += ch;
+ escape = false;
+ } else if (ch === '\\') {
+ regexp += ch;
+ escape = true;
+ } else if (ch === '/') {
+ this.index++;
+ var flags = "";
+ if (this.isIdent(this.text.charAt(this.index))) {
+ this.readIdent();
+ flags = this.tokens.pop().text;
+ }
+ var compiledRegexp = new RegExp(regexp, flags);
+ this.tokens.push({index:start, text:regexp, flags:flags,
+ fn:function(){return compiledRegexp;}});
+ return;
+ } else {
+ regexp += ch;
}
- var compiledRegexp = new RegExp(regexp, flags);
- this.tokens.push({index:start, text:regexp, flags:flags,
- fn:function(){return compiledRegexp;}});
- return;
- } else {
- regexp += ch;
+ this.index++;
}
- this.index++;
+ throw "Lexer Error: Unterminated RegExp [" +
+ this.text.substring(start) + "] starting at column '" +
+ (start+1) + "' in expression '" + this.text + "'.";
}
- throw "Lexer Error: Unterminated RegExp [" +
- this.text.substring(start) + "] starting at column '" +
- (start+1) + "' in expression '" + this.text + "'.";
};
+/////////////////////////////////////////
-Parser = function(text, parseStrings){
+function Parser(text, parseStrings){
this.text = text;
this.tokens = new Lexer(text, parseStrings).parse();
this.index = 0;
@@ -243,499 +247,501 @@ Parser.ZERO = function(){
return 0;
};
-Parser.prototype.error = function(msg, token) {
- throw "Token '" + token.text +
- "' is " + msg + " at column='" +
- (token.index + 1) + "' of expression '" +
- this.text + "' starting at '" + this.text.substring(token.index) + "'.";
-};
-
-Parser.prototype.peekToken = function() {
- if (this.tokens.length === 0)
- throw "Unexpected end of expression: " + this.text;
- return this.tokens[0];
-};
-
-Parser.prototype.peek = function(e1, e2, e3, e4) {
- var tokens = this.tokens;
- if (tokens.length > 0) {
- var token = tokens[0];
- var t = token.text;
- if (t==e1 || t==e2 || t==e3 || t==e4 ||
- (!e1 && !e2 && !e3 && !e4)) {
+Parser.prototype = {
+ error: function(msg, token) {
+ throw "Token '" + token.text +
+ "' is " + msg + " at column='" +
+ (token.index + 1) + "' of expression '" +
+ this.text + "' starting at '" + this.text.substring(token.index) + "'.";
+ },
+
+ peekToken: function() {
+ if (this.tokens.length === 0)
+ throw "Unexpected end of expression: " + this.text;
+ return this.tokens[0];
+ },
+
+ peek: function(e1, e2, e3, e4) {
+ var tokens = this.tokens;
+ if (tokens.length > 0) {
+ var token = tokens[0];
+ var t = token.text;
+ if (t==e1 || t==e2 || t==e3 || t==e4 ||
+ (!e1 && !e2 && !e3 && !e4)) {
+ return token;
+ }
+ }
+ return false;
+ },
+
+ expect: function(e1, e2, e3, e4){
+ var token = this.peek(e1, e2, e3, e4);
+ if (token) {
+ this.tokens.shift();
+ this.currentToken = token;
return token;
}
- }
- return false;
-};
-
-Parser.prototype.expect = function(e1, e2, e3, e4){
- var token = this.peek(e1, e2, e3, e4);
- if (token) {
- this.tokens.shift();
- this.currentToken = token;
- return token;
- }
- return false;
-};
-
-Parser.prototype.consume = function(e1){
- if (!this.expect(e1)) {
- var token = this.peek();
- throw "Expecting '" + e1 + "' at column '" +
- (token.index+1) + "' in '" +
- this.text + "' got '" +
- this.text.substring(token.index) + "'.";
- }
-};
-
-Parser.prototype._unary = function(fn, parse) {
- var right = parse.apply(this);
- return function(self) {
- return fn(self, right(self));
- };
-};
-
-Parser.prototype._binary = function(left, fn, parse) {
- var right = parse.apply(this);
- return function(self) {
- return fn(self, left(self), right(self));
- };
-};
-
-Parser.prototype.hasTokens = function () {
- return this.tokens.length > 0;
-};
-
-Parser.prototype.assertAllConsumed = function(){
- if (this.tokens.length !== 0) {
- throw "Did not understand '" + this.text.substring(this.tokens[0].index) +
- "' while evaluating '" + this.text + "'.";
- }
-};
-
-Parser.prototype.statements = function(){
- var statements = [];
- while(true) {
- if (this.tokens.length > 0 && !this.peek('}', ')', ';', ']'))
- statements.push(this.filterChain());
- if (!this.expect(';')) {
- return function (self){
- var value;
- for ( var i = 0; i < statements.length; i++) {
- var statement = statements[i];
- if (statement)
- value = statement(self);
- }
- return value;
- };
+ return false;
+ },
+
+ consume: function(e1){
+ if (!this.expect(e1)) {
+ var token = this.peek();
+ throw "Expecting '" + e1 + "' at column '" +
+ (token.index+1) + "' in '" +
+ this.text + "' got '" +
+ this.text.substring(token.index) + "'.";
}
- }
-};
-
-Parser.prototype.filterChain = function(){
- var left = this.expression();
- var token;
- while(true) {
- if ((token = this.expect('|'))) {
- left = this._binary(left, token.fn, this.filter);
- } else {
- return left;
+ },
+
+ _unary: function(fn, parse) {
+ var right = parse.apply(this);
+ return function(self) {
+ return fn(self, right(self));
+ };
+ },
+
+ _binary: function(left, fn, parse) {
+ var right = parse.apply(this);
+ return function(self) {
+ return fn(self, left(self), right(self));
+ };
+ },
+
+ hasTokens: function () {
+ return this.tokens.length > 0;
+ },
+
+ assertAllConsumed: function(){
+ if (this.tokens.length !== 0) {
+ throw "Did not understand '" + this.text.substring(this.tokens[0].index) +
+ "' while evaluating '" + this.text + "'.";
}
- }
-};
-
-Parser.prototype.filter = function(){
- return this._pipeFunction(angular['filter']);
-};
-
-Parser.prototype.validator = function(){
- return this._pipeFunction(angular['validator']);
-};
-
-Parser.prototype._pipeFunction = function(fnScope){
- var fn = this.functionIdent(fnScope);
- var argsFn = [];
- var token;
- while(true) {
- if ((token = this.expect(':'))) {
- argsFn.push(this.expression());
- } else {
- var fnInvoke = function(self, input){
- var args = [input];
- for ( var i = 0; i < argsFn.length; i++) {
- args.push(argsFn[i](self));
- }
- return fn.apply(self, args);
- };
- return function(){
- return fnInvoke;
- };
+ },
+
+ statements: function(){
+ var statements = [];
+ while(true) {
+ if (this.tokens.length > 0 && !this.peek('}', ')', ';', ']'))
+ statements.push(this.filterChain());
+ if (!this.expect(';')) {
+ return function (self){
+ var value;
+ for ( var i = 0; i < statements.length; i++) {
+ var statement = statements[i];
+ if (statement)
+ value = statement(self);
+ }
+ return value;
+ };
+ }
}
- }
-};
-
-Parser.prototype.expression = function(){
- return this.throwStmt();
-};
-
-Parser.prototype.throwStmt = function(){
- if (this.expect('throw')) {
- var throwExp = this.assignment();
- return function (self) {
- throw throwExp(self);
- };
- } else {
- return this.assignment();
- }
-};
-
-Parser.prototype.assignment = function(){
- var left = this.logicalOR();
- var token;
- if (token = this.expect('=')) {
- if (!left.isAssignable) {
- throw "Left hand side '" +
- this.text.substring(0, token.index) + "' of assignment '" +
- this.text.substring(token.index) + "' is not assignable.";
- }
- var ident = function(){return left.isAssignable;};
- return this._binary(ident, token.fn, this.logicalOR);
- } else {
- return left;
- }
-};
-
-Parser.prototype.logicalOR = function(){
- var left = this.logicalAND();
- var token;
- while(true) {
- if ((token = this.expect('||'))) {
- left = this._binary(left, token.fn, this.logicalAND);
+ },
+
+ filterChain: function(){
+ var left = this.expression();
+ var token;
+ while(true) {
+ if ((token = this.expect('|'))) {
+ left = this._binary(left, token.fn, this.filter);
+ } else {
+ return left;
+ }
+ }
+ },
+
+ filter: function(){
+ return this._pipeFunction(angular['filter']);
+ },
+
+ validator: function(){
+ return this._pipeFunction(angular['validator']);
+ },
+
+ _pipeFunction: function(fnScope){
+ var fn = this.functionIdent(fnScope);
+ var argsFn = [];
+ var token;
+ while(true) {
+ if ((token = this.expect(':'))) {
+ argsFn.push(this.expression());
+ } else {
+ var fnInvoke = function(self, input){
+ var args = [input];
+ for ( var i = 0; i < argsFn.length; i++) {
+ args.push(argsFn[i](self));
+ }
+ return fn.apply(self, args);
+ };
+ return function(){
+ return fnInvoke;
+ };
+ }
+ }
+ },
+
+ expression: function(){
+ return this.throwStmt();
+ },
+
+ throwStmt: function(){
+ if (this.expect('throw')) {
+ var throwExp = this.assignment();
+ return function (self) {
+ throw throwExp(self);
+ };
} else {
- return left;
+ return this.assignment();
}
- }
-};
-
-Parser.prototype.logicalAND = function(){
- var left = this.negated();
- var token;
- while(true) {
- if ((token = this.expect('&&'))) {
- left = this._binary(left, token.fn, this.negated);
+ },
+
+ assignment: function(){
+ var left = this.logicalOR();
+ var token;
+ if (token = this.expect('=')) {
+ if (!left.isAssignable) {
+ throw "Left hand side '" +
+ this.text.substring(0, token.index) + "' of assignment '" +
+ this.text.substring(token.index) + "' is not assignable.";
+ }
+ var ident = function(){return left.isAssignable;};
+ return this._binary(ident, token.fn, this.logicalOR);
} else {
- return left;
+ return left;
}
- }
-};
-
-Parser.prototype.negated = function(){
- var token;
- if (token = this.expect('!')) {
- return this._unary(token.fn, this.equality);
- } else {
- return this.equality();
- }
-};
-
-Parser.prototype.equality = function(){
- var left = this.relational();
- var token;
- while(true) {
- if ((token = this.expect('==','!='))) {
- left = this._binary(left, token.fn, this.relational);
+ },
+
+ logicalOR: function(){
+ var left = this.logicalAND();
+ var token;
+ while(true) {
+ if ((token = this.expect('||'))) {
+ left = this._binary(left, token.fn, this.logicalAND);
+ } else {
+ return left;
+ }
+ }
+ },
+
+ logicalAND: function(){
+ var left = this.negated();
+ var token;
+ while(true) {
+ if ((token = this.expect('&&'))) {
+ left = this._binary(left, token.fn, this.negated);
+ } else {
+ return left;
+ }
+ }
+ },
+
+ negated: function(){
+ var token;
+ if (token = this.expect('!')) {
+ return this._unary(token.fn, this.equality);
} else {
- return left;
+ return this.equality();
}
- }
-};
-
-Parser.prototype.relational = function(){
- var left = this.additive();
- var token;
- while(true) {
- if ((token = this.expect('<', '>', '<=', '>='))) {
- left = this._binary(left, token.fn, this.additive);
+ },
+
+ equality: function(){
+ var left = this.relational();
+ var token;
+ while(true) {
+ if ((token = this.expect('==','!='))) {
+ left = this._binary(left, token.fn, this.relational);
+ } else {
+ return left;
+ }
+ }
+ },
+
+ relational: function(){
+ var left = this.additive();
+ var token;
+ while(true) {
+ if ((token = this.expect('<', '>', '<=', '>='))) {
+ left = this._binary(left, token.fn, this.additive);
+ } else {
+ return left;
+ }
+ }
+ },
+
+ additive: function(){
+ var left = this.multiplicative();
+ var token;
+ while(token = this.expect('+','-')) {
+ left = this._binary(left, token.fn, this.multiplicative);
+ }
+ return left;
+ },
+
+ multiplicative: function(){
+ var left = this.unary();
+ var token;
+ while(token = this.expect('*','/','%')) {
+ left = this._binary(left, token.fn, this.unary);
+ }
+ return left;
+ },
+
+ unary: function(){
+ var token;
+ if (this.expect('+')) {
+ return this.primary();
+ } else if (token = this.expect('-')) {
+ return this._binary(Parser.ZERO, token.fn, this.multiplicative);
} else {
- return left;
+ return this.primary();
}
- }
-};
-
-Parser.prototype.additive = function(){
- var left = this.multiplicative();
- var token;
- while(token = this.expect('+','-')) {
- left = this._binary(left, token.fn, this.multiplicative);
- }
- return left;
-};
-
-Parser.prototype.multiplicative = function(){
- var left = this.unary();
- var token;
- while(token = this.expect('*','/','%')) {
- left = this._binary(left, token.fn, this.unary);
- }
- return left;
-};
-
-Parser.prototype.unary = function(){
- var token;
- if (this.expect('+')) {
- return this.primary();
- } else if (token = this.expect('-')) {
- return this._binary(Parser.ZERO, token.fn, this.multiplicative);
- } else {
- return this.primary();
- }
-};
-
-Parser.prototype.functionIdent = function(fnScope) {
- var token = this.expect();
- var element = token.text.split('.');
- var instance = fnScope;
- var key;
- for ( var i = 0; i < element.length; i++) {
- key = element[i];
- if (instance)
- instance = instance[key];
- }
- if (typeof instance != 'function') {
- throw "Function '" + token.text + "' at column '" +
- (token.index+1) + "' in '" + this.text + "' is not defined.";
- }
- return instance;
-};
-
-Parser.prototype.primary = function() {
- var primary;
- if (this.expect('(')) {
- var expression = this.filterChain();
- this.consume(')');
- primary = expression;
- } else if (this.expect('[')) {
- primary = this.arrayDeclaration();
- } else if (this.expect('{')) {
- primary = this.object();
- } else if (this.expect('{:')) {
- primary = this.closure(false);
- } else if (this.expect('{(')) {
- primary = this.closure(true);
- } else {
+ },
+
+ functionIdent: function(fnScope) {
var token = this.expect();
- primary = token.fn;
- if (!primary) {
- this.error("not a primary expression", token);
+ var element = token.text.split('.');
+ var instance = fnScope;
+ var key;
+ for ( var i = 0; i < element.length; i++) {
+ key = element[i];
+ if (instance)
+ instance = instance[key];
}
- }
- var next;
- while (next = this.expect('(', '[', '.')) {
- if (next.text === '(') {
- primary = this.functionCall(primary);
- } else if (next.text === '[') {
- primary = this.objectIndex(primary);
- } else if (next.text === '.') {
- primary = this.fieldAccess(primary);
+ if (typeof instance != 'function') {
+ throw "Function '" + token.text + "' at column '" +
+ (token.index+1) + "' in '" + this.text + "' is not defined.";
+ }
+ return instance;
+ },
+
+ primary: function() {
+ var primary;
+ if (this.expect('(')) {
+ var expression = this.filterChain();
+ this.consume(')');
+ primary = expression;
+ } else if (this.expect('[')) {
+ primary = this.arrayDeclaration();
+ } else if (this.expect('{')) {
+ primary = this.object();
+ } else if (this.expect('{:')) {
+ primary = this.closure(false);
+ } else if (this.expect('{(')) {
+ primary = this.closure(true);
} else {
- throw "IMPOSSIBLE";
+ var token = this.expect();
+ primary = token.fn;
+ if (!primary) {
+ this.error("not a primary expression", token);
+ }
}
- }
- return primary;
-};
-
-Parser.prototype.closure = function(hasArgs) {
- var args = [];
- if (hasArgs) {
- if (!this.expect(')')) {
- args.push(this.expect().text);
- while(this.expect(',')) {
+ var next;
+ while (next = this.expect('(', '[', '.')) {
+ if (next.text === '(') {
+ primary = this.functionCall(primary);
+ } else if (next.text === '[') {
+ primary = this.objectIndex(primary);
+ } else if (next.text === '.') {
+ primary = this.fieldAccess(primary);
+ } else {
+ throw "IMPOSSIBLE";
+ }
+ }
+ return primary;
+ },
+
+ closure: function(hasArgs) {
+ var args = [];
+ if (hasArgs) {
+ if (!this.expect(')')) {
args.push(this.expect().text);
+ while(this.expect(',')) {
+ args.push(this.expect().text);
+ }
+ this.consume(')');
}
- this.consume(')');
+ this.consume(":");
}
- this.consume(":");
- }
- var statements = this.statements();
- this.consume("}");
- return function(self){
- return function($){
- var scope = new Scope(self.scope.state);
- scope.set('$', $);
- for ( var i = 0; i < args.length; i++) {
- scope.set(args[i], arguments[i]);
+ var statements = this.statements();
+ this.consume("}");
+ return function(self){
+ return function($){
+ var scope = new Scope(self.scope.state);
+ scope.set('$', $);
+ for ( var i = 0; i < args.length; i++) {
+ scope.set(args[i], arguments[i]);
+ }
+ return statements({scope:scope});
+ };
+ };
+ },
+
+ fieldAccess: function(object) {
+ var field = this.expect().text;
+ var fn = function (self){
+ return Scope.getter(object(self), field);
+ };
+ fn.isAssignable = field;
+ return fn;
+ },
+
+ objectIndex: function(obj) {
+ var indexFn = this.expression();
+ this.consume(']');
+ if (this.expect('=')) {
+ var rhs = this.expression();
+ return function (self){
+ return obj(self)[indexFn(self)] = rhs(self);
+ };
+ } else {
+ return function (self){
+ var o = obj(self);
+ var i = indexFn(self);
+ return (o) ? o[i] : undefined;
+ };
+ }
+ },
+
+ functionCall: function(fn) {
+ var argsFn = [];
+ if (this.peekToken().text != ')') {
+ do {
+ argsFn.push(this.expression());
+ } while (this.expect(','));
+ }
+ this.consume(')');
+ return function (self){
+ var args = [];
+ for ( var i = 0; i < argsFn.length; i++) {
+ args.push(argsFn[i](self));
+ }
+ var fnPtr = fn(self);
+ if (typeof fnPtr === 'function') {
+ return fnPtr.apply(self, args);
+ } else {
+ throw "Expression '" + fn.isAssignable + "' is not a function.";
}
- return statements({scope:scope});
};
- };
-};
-
-Parser.prototype.fieldAccess = function(object) {
- var field = this.expect().text;
- var fn = function (self){
- return Scope.getter(object(self), field);
- };
- fn.isAssignable = field;
- return fn;
-};
-
-Parser.prototype.objectIndex = function(obj) {
- var indexFn = this.expression();
- this.consume(']');
- if (this.expect('=')) {
- var rhs = this.expression();
+ },
+
+ // This is used with json array declaration
+ arrayDeclaration: function () {
+ var elementFns = [];
+ if (this.peekToken().text != ']') {
+ do {
+ elementFns.push(this.expression());
+ } while (this.expect(','));
+ }
+ this.consume(']');
return function (self){
- return obj(self)[indexFn(self)] = rhs(self);
+ var array = [];
+ for ( var i = 0; i < elementFns.length; i++) {
+ array.push(elementFns[i](self));
+ }
+ return array;
};
- } else {
+ },
+
+ object: function () {
+ var keyValues = [];
+ if (this.peekToken().text != '}') {
+ do {
+ var key = this.expect().text;
+ this.consume(":");
+ var value = this.expression();
+ keyValues.push({key:key, value:value});
+ } while (this.expect(','));
+ }
+ this.consume('}');
return function (self){
- var o = obj(self);
- var i = indexFn(self);
- return (o) ? o[i] : undefined;
+ var object = {};
+ for ( var i = 0; i < keyValues.length; i++) {
+ var keyValue = keyValues[i];
+ var value = keyValue.value(self);
+ object[keyValue.key] = value;
+ }
+ return object;
};
- }
-};
-
-Parser.prototype.functionCall = function(fn) {
- var argsFn = [];
- if (this.peekToken().text != ')') {
- do {
- argsFn.push(this.expression());
- } while (this.expect(','));
- }
- this.consume(')');
- return function (self){
- var args = [];
- for ( var i = 0; i < argsFn.length; i++) {
- args.push(argsFn[i](self));
+ },
+
+ entityDeclaration: function () {
+ var decl = [];
+ while(this.hasTokens()) {
+ decl.push(this.entityDecl());
+ if (!this.expect(';')) {
+ this.assertAllConsumed();
+ }
}
- var fnPtr = fn(self);
- if (typeof fnPtr === 'function') {
- return fnPtr.apply(self, args);
- } else {
- throw "Expression '" + fn.isAssignable + "' is not a function.";
+ return function (self){
+ var code = "";
+ for ( var i = 0; i < decl.length; i++) {
+ code += decl[i](self);
+ }
+ return code;
+ };
+ },
+
+ entityDecl: function () {
+ var entity = this.expect().text;
+ var instance;
+ var defaults;
+ if (this.expect('=')) {
+ instance = entity;
+ entity = this.expect().text;
}
- };
-};
-
-// This is used with json array declaration
-Parser.prototype.arrayDeclaration = function () {
- var elementFns = [];
- if (this.peekToken().text != ']') {
- do {
- elementFns.push(this.expression());
- } while (this.expect(','));
- }
- this.consume(']');
- return function (self){
- var array = [];
- for ( var i = 0; i < elementFns.length; i++) {
- array.push(elementFns[i](self));
- }
- return array;
- };
-};
-
-Parser.prototype.object = function () {
- var keyValues = [];
- if (this.peekToken().text != '}') {
- do {
- var key = this.expect().text;
- this.consume(":");
- var value = this.expression();
- keyValues.push({key:key, value:value});
- } while (this.expect(','));
- }
- this.consume('}');
- return function (self){
- var object = {};
- for ( var i = 0; i < keyValues.length; i++) {
- var keyValue = keyValues[i];
- var value = keyValue.value(self);
- object[keyValue.key] = value;
- }
- return object;
- };
-};
-
-Parser.prototype.entityDeclaration = function () {
- var decl = [];
- while(this.hasTokens()) {
- decl.push(this.entityDecl());
- if (!this.expect(';')) {
- this.assertAllConsumed();
+ if (this.expect(':')) {
+ defaults = this.primary()(null);
}
- }
- return function (self){
- var code = "";
- for ( var i = 0; i < decl.length; i++) {
- code += decl[i](self);
+ return function(self) {
+ var datastore = self.scope.get('$datastore');
+ var Entity = datastore.entity(entity, defaults);
+ self.scope.set(entity, Entity);
+ if (instance) {
+ var document = Entity();
+ document.$$anchor = instance;
+ self.scope.set(instance, document);
+ return "$anchor." + instance + ":{" +
+ instance + "=" + entity + ".load($anchor." + instance + ");" +
+ instance + ".$$anchor=" + angular['String']['quote'](instance) + ";" +
+ "};";
+ } else {
+ return "";
+ }
+ };
+ },
+
+ watch: function () {
+ var decl = [];
+ while(this.hasTokens()) {
+ decl.push(this.watchDecl());
+ if (!this.expect(';')) {
+ this.assertAllConsumed();
+ }
}
- return code;
- };
-};
-
-Parser.prototype.entityDecl = function () {
- var entity = this.expect().text;
- var instance;
- var defaults;
- if (this.expect('=')) {
- instance = entity;
- entity = this.expect().text;
- }
- if (this.expect(':')) {
- defaults = this.primary()(null);
- }
- return function(self) {
- var datastore = self.scope.get('$datastore');
- var Entity = datastore.entity(entity, defaults);
- self.scope.set(entity, Entity);
- if (instance) {
- var document = Entity();
- document.$$anchor = instance;
- self.scope.set(instance, document);
- return "$anchor." + instance + ":{" +
- instance + "=" + entity + ".load($anchor." + instance + ");" +
- instance + ".$$anchor=" + angular['String']['quote'](instance) + ";" +
- "};";
+ this.assertAllConsumed();
+ return function (self){
+ for ( var i = 0; i < decl.length; i++) {
+ var d = decl[i](self);
+ self.addListener(d.name, d.fn);
+ }
+ };
+ },
+
+ watchDecl: function () {
+ var anchorName = this.expect().text;
+ this.consume(":");
+ var expression;
+ if (this.peekToken().text == '{') {
+ this.consume("{");
+ expression = this.statements();
+ this.consume("}");
} else {
- return "";
- }
- };
-};
-
-Parser.prototype.watch = function () {
- var decl = [];
- while(this.hasTokens()) {
- decl.push(this.watchDecl());
- if (!this.expect(';')) {
- this.assertAllConsumed();
- }
- }
- this.assertAllConsumed();
- return function (self){
- for ( var i = 0; i < decl.length; i++) {
- var d = decl[i](self);
- self.addListener(d.name, d.fn);
+ expression = this.expression();
}
- };
-};
-
-Parser.prototype.watchDecl = function () {
- var anchorName = this.expect().text;
- this.consume(":");
- var expression;
- if (this.peekToken().text == '{') {
- this.consume("{");
- expression = this.statements();
- this.consume("}");
- } else {
- expression = this.expression();
+ return function(self) {
+ return {name:anchorName, fn:expression};
+ };
}
- return function(self) {
- return {name:anchorName, fn:expression};
- };
};
diff --git a/src/Scope.js b/src/Scope.js
index f4b34c3c..dcc50007 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -1,6 +1,4 @@
-// Copyright (C) 2009 BRAT Tech LLC
-
-Scope = function(initialState, name) {
+function Scope(initialState, name) {
this.widgets = [];
this.watchListeners = {};
this.name = name;
@@ -15,31 +13,6 @@ Scope = function(initialState, name) {
};
Scope.expressionCache = {};
-
-Scope.prototype.updateView = function() {
- var self = this;
- this.fireWatchers();
- _.each(this.widgets, function(widget){
- self.evalWidget(widget, "", {}, function(){
- this.updateView(self);
- });
- });
-};
-
-Scope.prototype.addWidget = function(controller) {
- if (controller) this.widgets.push(controller);
-};
-
-Scope.prototype.isProperty = function(exp) {
- for ( var i = 0; i < exp.length; i++) {
- var ch = exp.charAt(i);
- if (ch!='.' && !Lexer.prototype.isIdent(ch)) {
- return false;
- }
- }
- return true;
-};
-
Scope.getter = function(instance, path) {
if (!path) return instance;
var element = path.split('.');
@@ -70,129 +43,155 @@ Scope.getter = function(instance, path) {
return instance;
};
-Scope.prototype.get = function(path) {
- return Scope.getter(this.state, path);
-};
-
-Scope.prototype.set = function(path, value) {
- var element = path.split('.');
- var instance = this.state;
- for ( var i = 0; element.length > 1; i++) {
- var key = element.shift();
- var newInstance = instance[key];
- if (!newInstance) {
- newInstance = {};
- instance[key] = newInstance;
+Scope.prototype = {
+ updateView: function() {
+ var self = this;
+ this.fireWatchers();
+ _.each(this.widgets, function(widget){
+ self.evalWidget(widget, "", {}, function(){
+ this.updateView(self);
+ });
+ });
+ },
+
+ addWidget: function(controller) {
+ if (controller) this.widgets.push(controller);
+ },
+
+ isProperty: function(exp) {
+ for ( var i = 0; i < exp.length; i++) {
+ var ch = exp.charAt(i);
+ if (ch!='.' && !Lexer.prototype.isIdent(ch)) {
+ return false;
+ }
}
- instance = newInstance;
- }
- instance[element.shift()] = value;
- return value;
-};
-
-Scope.prototype.setEval = function(expressionText, value) {
- this.eval(expressionText + "=" + toJson(value));
-};
-
-Scope.prototype.eval = function(expressionText, context) {
- var expression = Scope.expressionCache[expressionText];
- if (!expression) {
- var parser = new Parser(expressionText);
- expression = parser.statements();
- parser.assertAllConsumed();
- Scope.expressionCache[expressionText] = expression;
- }
- context = context || {};
- context.scope = this;
- return expression(context);
-};
-
-//TODO: Refactor. This function needs to be an execution closure for widgets
-// move to widgets
-// remove expression, just have inner closure.
-Scope.prototype.evalWidget = function(widget, expression, context, onSuccess, onFailure) {
- try {
- var value = this.eval(expression, context);
- if (widget.hasError) {
- widget.hasError = false;
- jQuery(widget.view).
- removeClass('ng-exception').
- removeAttr('ng-error');
+ return true;
+ },
+
+ get: function(path) {
+ return Scope.getter(this.state, path);
+ },
+
+ set: function(path, value) {
+ var element = path.split('.');
+ var instance = this.state;
+ for ( var i = 0; element.length > 1; i++) {
+ var key = element.shift();
+ var newInstance = instance[key];
+ if (!newInstance) {
+ newInstance = {};
+ instance[key] = newInstance;
+ }
+ instance = newInstance;
}
- if (onSuccess) {
- value = onSuccess.apply(widget, [value]);
+ instance[element.shift()] = value;
+ return value;
+ },
+
+ setEval: function(expressionText, value) {
+ this.eval(expressionText + "=" + toJson(value));
+ },
+
+ eval: function(expressionText, context) {
+ var expression = Scope.expressionCache[expressionText];
+ if (!expression) {
+ var parser = new Parser(expressionText);
+ expression = parser.statements();
+ parser.assertAllConsumed();
+ Scope.expressionCache[expressionText] = expression;
}
- return true;
- } catch (e){
- error('Eval Widget Error:', e);
- var jsonError = toJson(e, true);
- widget.hasError = true;
- jQuery(widget.view).
- addClass('ng-exception').
- attr('ng-error', jsonError);
- if (onFailure) {
- onFailure.apply(widget, [e, jsonError]);
+ context = context || {};
+ context.scope = this;
+ return expression(context);
+ },
+
+ //TODO: Refactor. This function needs to be an execution closure for widgets
+ // move to widgets
+ // remove expression, just have inner closure.
+ evalWidget: function(widget, expression, context, onSuccess, onFailure) {
+ try {
+ var value = this.eval(expression, context);
+ if (widget.hasError) {
+ widget.hasError = false;
+ jQuery(widget.view).
+ removeClass('ng-exception').
+ removeAttr('ng-error');
+ }
+ if (onSuccess) {
+ value = onSuccess.apply(widget, [value]);
+ }
+ return true;
+ } catch (e){
+ error('Eval Widget Error:', e);
+ var jsonError = toJson(e, true);
+ widget.hasError = true;
+ jQuery(widget.view).
+ addClass('ng-exception').
+ attr('ng-error', jsonError);
+ if (onFailure) {
+ onFailure.apply(widget, [e, jsonError]);
+ }
+ return false;
}
- return false;
- }
-};
-
-Scope.prototype.validate = function(expressionText, value) {
- var expression = Scope.expressionCache[expressionText];
- if (!expression) {
- expression = new Parser(expressionText).validator();
- Scope.expressionCache[expressionText] = expression;
- }
- var self = {scope:this};
- return expression(self)(self, value);
-};
-
-Scope.prototype.entity = function(entityDeclaration) {
- var expression = new Parser(entityDeclaration).entityDeclaration();
- return expression({scope:this});
-};
-
-Scope.prototype.markInvalid = function(widget) {
- this.state.$invalidWidgets.push(widget);
-};
-
-Scope.prototype.watch = function(declaration) {
- var self = this;
- new Parser(declaration).watch()({
- scope:this,
- addListener:function(watch, exp){
- self.addWatchListener(watch, function(n,o){
- try {
- return exp({scope:self}, n, o);
- } catch(e) {
- alert(e);
- }
- });
+ },
+
+ validate: function(expressionText, value) {
+ var expression = Scope.expressionCache[expressionText];
+ if (!expression) {
+ expression = new Parser(expressionText).validator();
+ Scope.expressionCache[expressionText] = expression;
}
- });
-};
-
-Scope.prototype.addWatchListener = function(watchExpression, listener) {
- var watcher = this.watchListeners[watchExpression];
- if (!watcher) {
- watcher = {listeners:[], expression:watchExpression};
- this.watchListeners[watchExpression] = watcher;
- }
- watcher.listeners.push(listener);
-};
-
-Scope.prototype.fireWatchers = function() {
- var self = this;
- var fired = false;
- foreach(this.watchListeners, function(watcher) {
- var value = self.eval(watcher.expression);
- if (value !== watcher.lastValue) {
- foreach(watcher.listeners, function(listener){
- listener(value, watcher.lastValue);
- fired = true;
- });
- watcher.lastValue = value;
+ var self = {scope:this};
+ return expression(self)(self, value);
+ },
+
+ entity: function(entityDeclaration) {
+ var expression = new Parser(entityDeclaration).entityDeclaration();
+ return expression({scope:this});
+ },
+
+ markInvalid: function(widget) {
+ this.state.$invalidWidgets.push(widget);
+ },
+
+ watch: function(declaration) {
+ var self = this;
+ new Parser(declaration).watch()({
+ scope:this,
+ addListener:function(watch, exp){
+ self.addWatchListener(watch, function(n,o){
+ try {
+ return exp({scope:self}, n, o);
+ } catch(e) {
+ alert(e);
+ }
+ });
+ }
+ });
+ },
+
+ addWatchListener: function(watchExpression, listener) {
+ var watcher = this.watchListeners[watchExpression];
+ if (!watcher) {
+ watcher = {listeners:[], expression:watchExpression};
+ this.watchListeners[watchExpression] = watcher;
}
- });
- return fired;
-};
+ watcher.listeners.push(listener);
+ },
+
+ fireWatchers: function() {
+ var self = this;
+ var fired = false;
+ foreach(this.watchListeners, function(watcher) {
+ var value = self.eval(watcher.expression);
+ if (value !== watcher.lastValue) {
+ foreach(watcher.listeners, function(listener){
+ listener(value, watcher.lastValue);
+ fired = true;
+ });
+ watcher.lastValue = value;
+ }
+ });
+ return fired;
+ }
+};
\ No newline at end of file
diff --git a/src/Server.js b/src/Server.js
index 8f682038..f351e84c 100644
--- a/src/Server.js
+++ b/src/Server.js
@@ -1,6 +1,4 @@
-// Copyright (C) 2008,2009 BRAT Tech LLC
-
-Server = function(url, getScript) {
+function Server(url, getScript) {
this.url = url;
this.nextId = 0;
this.getScript = getScript;
@@ -8,27 +6,29 @@ Server = function(url, getScript) {
this.maxSize = 1800;
};
-Server.prototype.base64url = function(txt) {
- return Base64.encode(txt);
-};
-
-Server.prototype.request = function(method, url, request, callback) {
- var requestId = this.uuid + (this.nextId++);
- angularCallbacks[requestId] = function(response) {
- delete angular[requestId];
- callback(200, response);
- };
- var payload = {u:url, m:method, p:request};
- payload = this.base64url(toJson(payload));
- var totalPockets = Math.ceil(payload.length / this.maxSize);
- var baseUrl = this.url + "/$/" + requestId + "/" + totalPockets + "/";
- for ( var pocketNo = 0; pocketNo < totalPockets; pocketNo++) {
- var pocket = payload.substr(pocketNo * this.maxSize, this.maxSize);
- this.getScript(baseUrl + (pocketNo+1) + "?h=" + pocket, noop);
+Server.prototype = {
+ base64url: function(txt) {
+ return Base64.encode(txt);
+ },
+
+ request: function(method, url, request, callback) {
+ var requestId = this.uuid + (this.nextId++);
+ angularCallbacks[requestId] = function(response) {
+ delete angular[requestId];
+ callback(200, response);
+ };
+ var payload = {u:url, m:method, p:request};
+ payload = this.base64url(toJson(payload));
+ var totalPockets = Math.ceil(payload.length / this.maxSize);
+ var baseUrl = this.url + "/$/" + requestId + "/" + totalPockets + "/";
+ for ( var pocketNo = 0; pocketNo < totalPockets; pocketNo++) {
+ var pocket = payload.substr(pocketNo * this.maxSize, this.maxSize);
+ this.getScript(baseUrl + (pocketNo+1) + "?h=" + pocket, noop);
+ }
}
};
-FrameServer = function(frame) {
+function FrameServer(frame) {
this.frame = frame;
};
FrameServer.PREFIX = "$DATASET:";
@@ -46,7 +46,7 @@ FrameServer.prototype = {
};
-VisualServer = function(delegate, status, update) {
+function VisualServer(delegate, status, update) {
this.delegate = delegate;
this.update = update;
this.status = status;
diff --git a/src/Users.js b/src/Users.js
index d10b96df..47da4f73 100644
--- a/src/Users.js
+++ b/src/Users.js
@@ -1,11 +1,10 @@
-// Copyright (C) 2008,2009 BRAT Tech LLC
-Users = function(server, controlBar) {
+function Users(server, controlBar) {
this.server = server;
this.controlBar = controlBar;
};
Users.prototype = {
- fetchCurrentUser:function(callback) {
+ 'fetchCurrentUser':function(callback) {
var self = this;
this.server.request("GET", "/account.json", {}, function(code, response){
self.current = response.user;
@@ -13,7 +12,7 @@ Users.prototype = {
});
},
- logout: function(callback) {
+ 'logout': function(callback) {
var self = this;
this.controlBar.logout(function(){
delete self.current;
@@ -21,7 +20,7 @@ Users.prototype = {
});
},
- login: function(callback) {
+ 'login': function(callback) {
var self = this;
this.controlBar.login(function(){
self.fetchCurrentUser(function(){
@@ -30,7 +29,7 @@ Users.prototype = {
});
},
- notAuthorized: function(){
+ 'notAuthorized': function(){
this.controlBar.notAuthorized();
}
};
diff --git a/src/Validators.js b/src/Validators.js
index eb8cff59..5549ee39 100644
--- a/src/Validators.js
+++ b/src/Validators.js
@@ -1,5 +1,3 @@
-// Copyright (C) 2009 BRAT Tech LLC
-
foreach({
'regexp': function(value, regexp, msg) {
if (!value.match(regexp)) {
diff --git a/src/Widgets.js b/src/Widgets.js
index 5dcb84c4..f93f2476 100644
--- a/src/Widgets.js
+++ b/src/Widgets.js
@@ -1,7 +1,4 @@
-// Copyright (C) 2009 BRAT Tech LLC
-
-
-WidgetFactory = function(serverUrl, database) {
+function WidgetFactory(serverUrl, database) {
this.nextUploadId = 0;
this.serverUrl = serverUrl;
this.database = database;
@@ -15,80 +12,81 @@ WidgetFactory = function(serverUrl, database) {
this.onChangeListener = function(){};
};
-WidgetFactory.prototype.createController = function(input, scope) {
- var controller;
- var type = input.attr('type').toLowerCase();
- var exp = input.attr('name');
- if (exp) exp = exp.split(':').pop();
- var event = "change";
- var bubbleEvent = true;
- if (type == 'button' || type == 'submit' || type == 'reset' || type == 'image') {
- controller = new ButtonController(input[0], exp);
- event = "click";
- bubbleEvent = false;
- } else if (type == 'text' || type == 'textarea' || type == 'hidden' || type == 'password') {
- controller = new TextController(input[0], exp);
- event = "keyup change";
- } else if (type == 'checkbox') {
- controller = new CheckboxController(input[0], exp);
- event = "click";
- } else if (type == 'radio') {
- controller = new RadioController(input[0], exp);
- event="click";
- } else if (type == 'select-one') {
- controller = new SelectController(input[0], exp);
- } else if (type == 'select-multiple') {
- controller = new MultiSelectController(input[0], exp);
- } else if (type == 'file') {
- controller = this.createFileController(input, exp);
- } else {
- throw 'Unknown type: ' + type;
- }
- input.data('controller', controller);
- var binder = scope.get('$binder');
- var action = function() {
- if (controller.updateModel(scope)) {
- var action = jQuery(controller.view).attr('ng-action') || "";
- if (scope.evalWidget(controller, action)) {
- binder.updateView(scope);
- }
+WidgetFactory.prototype = {
+ createController: function(input, scope) {
+ var controller;
+ var type = input.attr('type').toLowerCase();
+ var exp = input.attr('name');
+ if (exp) exp = exp.split(':').pop();
+ var event = "change";
+ var bubbleEvent = true;
+ if (type == 'button' || type == 'submit' || type == 'reset' || type == 'image') {
+ controller = new ButtonController(input[0], exp);
+ event = "click";
+ bubbleEvent = false;
+ } else if (type == 'text' || type == 'textarea' || type == 'hidden' || type == 'password') {
+ controller = new TextController(input[0], exp);
+ event = "keyup change";
+ } else if (type == 'checkbox') {
+ controller = new CheckboxController(input[0], exp);
+ event = "click";
+ } else if (type == 'radio') {
+ controller = new RadioController(input[0], exp);
+ event="click";
+ } else if (type == 'select-one') {
+ controller = new SelectController(input[0], exp);
+ } else if (type == 'select-multiple') {
+ controller = new MultiSelectController(input[0], exp);
+ } else if (type == 'file') {
+ controller = this.createFileController(input, exp);
+ } else {
+ throw 'Unknown type: ' + type;
}
- return bubbleEvent;
- };
- jQuery(controller.view, ":input").
- bind(event, action);
- return controller;
-};
-
-WidgetFactory.prototype.createFileController = function(fileInput) {
- var uploadId = '__uploadWidget_' + (this.nextUploadId++);
- var view = FileController.template(uploadId);
- fileInput.after(view);
- var att = {
- data:this.serverUrl + "/admin/ServerAPI.swf",
- width:"95", height:"20", align:"top",
- wmode:"transparent"};
- var par = {
- flashvars:"uploadWidgetId=" + uploadId,
- allowScriptAccess:"always"};
- var swfNode = this.createSWF(att, par, uploadId);
- fileInput.remove();
- var cntl = new FileController(view, fileInput[0].name, swfNode, this.serverUrl + "/data/" + this.database);
- jQuery(swfNode).data('controller', cntl);
- return cntl;
-};
-
-WidgetFactory.prototype.createTextWidget = function(textInput) {
- var controller = new TextController(textInput);
- controller.onChange(this.onChangeListener);
- return controller;
+ input.data('controller', controller);
+ var binder = scope.get('$binder');
+ var action = function() {
+ if (controller.updateModel(scope)) {
+ var action = jQuery(controller.view).attr('ng-action') || "";
+ if (scope.evalWidget(controller, action)) {
+ binder.updateView(scope);
+ }
+ }
+ return bubbleEvent;
+ };
+ jQuery(controller.view, ":input").
+ bind(event, action);
+ return controller;
+ },
+
+ createFileController: function(fileInput) {
+ var uploadId = '__uploadWidget_' + (this.nextUploadId++);
+ var view = FileController.template(uploadId);
+ fileInput.after(view);
+ var att = {
+ data:this.serverUrl + "/admin/ServerAPI.swf",
+ width:"95", height:"20", align:"top",
+ wmode:"transparent"};
+ var par = {
+ flashvars:"uploadWidgetId=" + uploadId,
+ allowScriptAccess:"always"};
+ var swfNode = this.createSWF(att, par, uploadId);
+ fileInput.remove();
+ var cntl = new FileController(view, fileInput[0].name, swfNode, this.serverUrl + "/data/" + this.database);
+ jQuery(swfNode).data('controller', cntl);
+ return cntl;
+ },
+
+ createTextWidget: function(textInput) {
+ var controller = new TextController(textInput);
+ controller.onChange(this.onChangeListener);
+ return controller;
+ }
};
-
/////////////////////
// FileController
///////////////////////
-FileController = function(view, scopeName, uploader, databaseUrl) {
+function FileController(view, scopeName, uploader, databaseUrl) {
this.view = view;
this.uploader = uploader;
this.scopeName = scopeName;
@@ -112,99 +110,89 @@ FileController.template = function(id) {
'');
};
-FileController.prototype._on_cancel = function() {
-};
-
-FileController.prototype._on_complete = function() {
-};
-
-FileController.prototype._on_httpStatus = function(status) {
- alert("httpStatus:" + this.scopeName + " status:" + status);
-};
-
-FileController.prototype._on_ioError = function() {
- alert("ioError:" + this.scopeName);
-};
-
-FileController.prototype._on_open = function() {
- alert("open:" + this.scopeName);
-};
-
-FileController.prototype._on_progress = function(bytesLoaded, bytesTotal) {
-};
-
-FileController.prototype._on_securityError = function() {
- alert("securityError:" + this.scopeName);
-};
-
-FileController.prototype._on_uploadCompleteData = function(data) {
- var value = fromJson(data);
- value.url = this.attachmentsPath + '/' + value.id + '/' + value.text;
- this.view.find("input").attr('checked', true);
- var scope = this.view.scope();
- this.value = value;
- this.updateModel(scope);
- this.value = null;
- scope.get('$binder').updateView();
-};
-
-FileController.prototype._on_select = function(name, size, type) {
- this.name = name;
- this.view.find("a").text(name).attr('href', name);
- this.view.find("span").text(angular['filter']['bytes'](size));
- this.upload();
-};
-
-FileController.prototype.updateModel = function(scope) {
- var isChecked = this.view.find("input").attr('checked');
- var value = isChecked ? this.value : null;
- if (this.lastValue === value) {
- return false;
- } else {
- scope.set(this.scopeName, value);
- return true;
- }
-};
-
-FileController.prototype.updateView = function(scope) {
- var modelValue = scope.get(this.scopeName);
- if (modelValue && this.value !== modelValue) {
- this.value = modelValue;
- this.view.find("a").
- attr("href", this.value.url).
- text(this.value.text);
- this.view.find("span").text(angular['filter']['bytes'](this.value.size));
- }
- this.view.find("input").attr('checked', !!modelValue);
-};
-
-FileController.prototype.upload = function() {
- if (this.name) {
- this.uploader.uploadFile(this.attachmentsPath);
+FileController.prototype = {
+ '_on_cancel': noop,
+ '_on_complete': noop,
+ '_on_httpStatus': function(status) {
+ alert("httpStatus:" + this.scopeName + " status:" + status);
+ },
+ '_on_ioError': function() {
+ alert("ioError:" + this.scopeName);
+ },
+ '_on_open': function() {
+ alert("open:" + this.scopeName);
+ },
+ '_on_progress':noop,
+ '_on_securityError': function() {
+ alert("securityError:" + this.scopeName);
+ },
+ '_on_uploadCompleteData': function(data) {
+ var value = fromJson(data);
+ value.url = this.attachmentsPath + '/' + value.id + '/' + value.text;
+ this.view.find("input").attr('checked', true);
+ var scope = this.view.scope();
+ this.value = value;
+ this.updateModel(scope);
+ this.value = null;
+ scope.get('$binder').updateView();
+ },
+ '_on_select': function(name, size, type) {
+ this.name = name;
+ this.view.find("a").text(name).attr('href', name);
+ this.view.find("span").text(angular['filter']['bytes'](size));
+ this.upload();
+ },
+
+ updateModel: function(scope) {
+ var isChecked = this.view.find("input").attr('checked');
+ var value = isChecked ? this.value : null;
+ if (this.lastValue === value) {
+ return false;
+ } else {
+ scope.set(this.scopeName, value);
+ return true;
+ }
+ },
+
+ updateView: function(scope) {
+ var modelValue = scope.get(this.scopeName);
+ if (modelValue && this.value !== modelValue) {
+ this.value = modelValue;
+ this.view.find("a").
+ attr("href", this.value.url).
+ text(this.value.text);
+ this.view.find("span").text(angular['filter']['bytes'](this.value.size));
+ }
+ this.view.find("input").attr('checked', !!modelValue);
+ },
+
+ upload: function() {
+ if (this.name) {
+ this.uploader.uploadFile(this.attachmentsPath);
+ }
}
};
-
///////////////////////
// NullController
///////////////////////
-NullController = function(view) {this.view = view;};
-NullController.prototype.updateModel = function() { return true; };
-NullController.prototype.updateView = function() { };
+function NullController(view) {this.view = view;};
+NullController.prototype = {
+ updateModel: function() { return true; },
+ updateView: noop
+};
NullController.instance = new NullController();
///////////////////////
// ButtonController
///////////////////////
-ButtonController = function(view) {this.view = view;};
-ButtonController.prototype.updateModel = function(scope) { return true; };
-ButtonController.prototype.updateView = function(scope) {};
+var ButtonController = NullController;
///////////////////////
// TextController
///////////////////////
-TextController = function(view, exp) {
+function TextController(view, exp) {
this.view = view;
this.exp = exp;
this.validator = view.getAttribute('ng-validate');
@@ -218,175 +206,183 @@ TextController = function(view, exp) {
}
};
-TextController.prototype.updateModel = function(scope) {
- var value = this.view.value;
- if (this.lastValue === value) {
- return false;
- } else {
- scope.setEval(this.exp, value);
- this.lastValue = value;
- return true;
- }
-};
-
-TextController.prototype.updateView = function(scope) {
- var view = this.view;
- var value = scope.get(this.exp);
- if (typeof value === "undefined") {
- value = this.initialValue;
- scope.setEval(this.exp, value);
- }
- value = value ? value : '';
- if (this.lastValue != value) {
- view.value = value;
- this.lastValue = value;
- }
- var isValidationError = false;
- view.removeAttribute('ng-error');
- if (this.required) {
- isValidationError = !(value && value.length > 0);
- }
- var errorText = isValidationError ? "Required Value" : null;
- if (!isValidationError && this.validator && value) {
- errorText = scope.validate(this.validator, value);
- isValidationError = !!errorText;
- }
- if (this.lastErrorText !== errorText) {
- this.lastErrorText = isValidationError;
- if (errorText !== null) {
- view.setAttribute('ng-error', errorText);
- scope.markInvalid(this);
+TextController.prototype = {
+ updateModel: function(scope) {
+ var value = this.view.value;
+ if (this.lastValue === value) {
+ return false;
+ } else {
+ scope.setEval(this.exp, value);
+ this.lastValue = value;
+ return true;
+ }
+ },
+
+ updateView: function(scope) {
+ var view = this.view;
+ var value = scope.get(this.exp);
+ if (typeof value === "undefined") {
+ value = this.initialValue;
+ scope.setEval(this.exp, value);
+ }
+ value = value ? value : '';
+ if (this.lastValue != value) {
+ view.value = value;
+ this.lastValue = value;
+ }
+ var isValidationError = false;
+ view.removeAttribute('ng-error');
+ if (this.required) {
+ isValidationError = !(value && value.length > 0);
+ }
+ var errorText = isValidationError ? "Required Value" : null;
+ if (!isValidationError && this.validator && value) {
+ errorText = scope.validate(this.validator, value);
+ isValidationError = !!errorText;
+ }
+ if (this.lastErrorText !== errorText) {
+ this.lastErrorText = isValidationError;
+ if (errorText !== null) {
+ view.setAttribute('ng-error', errorText);
+ scope.markInvalid(this);
+ }
+ jQuery(view).toggleClass('ng-validation-error', isValidationError);
}
- jQuery(view).toggleClass('ng-validation-error', isValidationError);
}
};
///////////////////////
// CheckboxController
///////////////////////
-CheckboxController = function(view, exp) {
+function CheckboxController(view, exp) {
this.view = view;
this.exp = exp;
this.lastValue = undefined;
this.initialValue = view.checked ? view.value : "";
};
-CheckboxController.prototype.updateModel = function(scope) {
- var input = this.view;
- var value = input.checked ? input.value : '';
- if (this.lastValue === value) {
- return false;
- } else {
- scope.setEval(this.exp, value);
- this.lastValue = value;
- return true;
- }
-};
-
-CheckboxController.prototype.updateView = function(scope) {
- var input = this.view;
- var value = scope.eval(this.exp);
- if (typeof value === "undefined") {
- value = this.initialValue;
- scope.setEval(this.exp, value);
+CheckboxController.prototype = {
+ updateModel: function(scope) {
+ var input = this.view;
+ var value = input.checked ? input.value : '';
+ if (this.lastValue === value) {
+ return false;
+ } else {
+ scope.setEval(this.exp, value);
+ this.lastValue = value;
+ return true;
+ }
+ },
+
+ updateView: function(scope) {
+ var input = this.view;
+ var value = scope.eval(this.exp);
+ if (typeof value === "undefined") {
+ value = this.initialValue;
+ scope.setEval(this.exp, value);
+ }
+ input.checked = input.value == (''+value);
}
- input.checked = input.value == (''+value);
};
///////////////////////
// SelectController
///////////////////////
-SelectController = function(view, exp) {
+function SelectController(view, exp) {
this.view = view;
this.exp = exp;
this.lastValue = undefined;
this.initialValue = view.value;
};
-SelectController.prototype.updateModel = function(scope) {
- var input = this.view;
- if (input.selectedIndex < 0) {
- scope.setEval(this.exp, null);
- } else {
- var value = this.view.value;
- if (this.lastValue === value) {
- return false;
+SelectController.prototype = {
+ updateModel: function(scope) {
+ var input = this.view;
+ if (input.selectedIndex < 0) {
+ scope.setEval(this.exp, null);
} else {
+ var value = this.view.value;
+ if (this.lastValue === value) {
+ return false;
+ } else {
+ scope.setEval(this.exp, value);
+ this.lastValue = value;
+ return true;
+ }
+ }
+ },
+
+ updateView: function(scope) {
+ var input = this.view;
+ var value = scope.get(this.exp);
+ if (typeof value === 'undefined') {
+ value = this.initialValue;
scope.setEval(this.exp, value);
+ }
+ if (value !== this.lastValue) {
+ input.value = value ? value : "";
this.lastValue = value;
- return true;
}
}
};
-SelectController.prototype.updateView = function(scope) {
- var input = this.view;
- var value = scope.get(this.exp);
- if (typeof value === 'undefined') {
- value = this.initialValue;
- scope.setEval(this.exp, value);
- }
- if (value !== this.lastValue) {
- input.value = value ? value : "";
- this.lastValue = value;
- }
-};
-
///////////////////////
// MultiSelectController
///////////////////////
-MultiSelectController = function(view, exp) {
+function MultiSelectController(view, exp) {
this.view = view;
this.exp = exp;
this.lastValue = undefined;
this.initialValue = this.selected();
};
-MultiSelectController.prototype.selected = function () {
- var value = [];
- var options = this.view.options;
- for ( var i = 0; i < options.length; i++) {
- var option = options[i];
- if (option.selected) {
- value.push(option.value);
- }
- }
- return value;
-};
-
-MultiSelectController.prototype.updateModel = function(scope) {
- var value = this.selected();
- // TODO: This is wrong! no caching going on here as we are always comparing arrays
- if (this.lastValue === value) {
- return false;
- } else {
- scope.setEval(this.exp, value);
- this.lastValue = value;
- return true;
- }
-};
-
-MultiSelectController.prototype.updateView = function(scope) {
- var input = this.view;
- var selected = scope.get(this.exp);
- if (typeof selected === "undefined") {
- selected = this.initialValue;
- scope.setEval(this.exp, selected);
- }
- if (selected !== this.lastValue) {
- var options = input.options;
+MultiSelectController.prototype = {
+ selected: function () {
+ var value = [];
+ var options = this.view.options;
for ( var i = 0; i < options.length; i++) {
var option = options[i];
- option.selected = _.include(selected, option.value);
+ if (option.selected) {
+ value.push(option.value);
+ }
+ }
+ return value;
+ },
+
+ updateModel: function(scope) {
+ var value = this.selected();
+ // TODO: This is wrong! no caching going on here as we are always comparing arrays
+ if (this.lastValue === value) {
+ return false;
+ } else {
+ scope.setEval(this.exp, value);
+ this.lastValue = value;
+ return true;
+ }
+ },
+
+ updateView: function(scope) {
+ var input = this.view;
+ var selected = scope.get(this.exp);
+ if (typeof selected === "undefined") {
+ selected = this.initialValue;
+ scope.setEval(this.exp, selected);
+ }
+ if (selected !== this.lastValue) {
+ var options = input.options;
+ for ( var i = 0; i < options.length; i++) {
+ var option = options[i];
+ option.selected = _.include(selected, option.value);
+ }
+ this.lastValue = selected;
}
- this.lastValue = selected;
}
};
///////////////////////
// RadioController
///////////////////////
-RadioController = function(view, exp) {
+function RadioController(view, exp) {
this.view = view;
this.exp = exp;
this.lastChecked = undefined;
@@ -395,35 +391,37 @@ RadioController = function(view, exp) {
this.initialValue = view.checked ? view.value : null;
};
-RadioController.prototype.updateModel = function(scope) {
- var input = this.view;
- if (this.lastChecked) {
- return false;
- } else {
- input.checked = true;
- this.lastValue = scope.setEval(this.exp, this.inputValue);
- this.lastChecked = true;
- return true;
- }
-};
-
-RadioController.prototype.updateView = function(scope) {
- var input = this.view;
- var value = scope.get(this.exp);
- if (this.initialValue && typeof value === "undefined") {
- value = this.initialValue;
- scope.setEval(this.exp, value);
- }
- if (this.lastValue != value) {
- this.lastChecked = input.checked = this.inputValue == (''+value);
- this.lastValue = value;
+RadioController.prototype = {
+ updateModel: function(scope) {
+ var input = this.view;
+ if (this.lastChecked) {
+ return false;
+ } else {
+ input.checked = true;
+ this.lastValue = scope.setEval(this.exp, this.inputValue);
+ this.lastChecked = true;
+ return true;
+ }
+ },
+
+ updateView: function(scope) {
+ var input = this.view;
+ var value = scope.get(this.exp);
+ if (this.initialValue && typeof value === "undefined") {
+ value = this.initialValue;
+ scope.setEval(this.exp, value);
+ }
+ if (this.lastValue != value) {
+ this.lastChecked = input.checked = this.inputValue == (''+value);
+ this.lastValue = value;
+ }
}
};
///////////////////////
//ElementController
///////////////////////
-BindUpdater = function(view, exp) {
+function BindUpdater(view, exp) {
this.view = view;
this.exp = Binder.parseBindings(exp);
this.hasError = false;
@@ -473,152 +471,170 @@ BindUpdater.toText = function(obj) {
}
};
-BindUpdater.prototype.updateModel = function(scope) {};
-BindUpdater.prototype.updateView = function(scope) {
- var html = [];
- var parts = this.exp;
- var length = parts.length;
- for(var i=0; i
iteratorLength; --r) {
+ var unneeded = this.children.pop().element[0];
+ unneeded.parentNode.removeChild(unneeded);
}
- cursor = child.element;
- var s = new Date().getTime();
- child.scope.updateView();
- time += new Date().getTime() - s;
- i++;
- });
- // shrink children
- for ( var r = childrenLength; r > iteratorLength; --r) {
- var unneeded = this.children.pop().element[0];
- unneeded.parentNode.removeChild(unneeded);
- }
- // Special case for option in select
- if (child && child.element[0].nodeName === "OPTION") {
- var select = jQuery(child.element[0].parentNode);
- var cntl = select.data('controller');
- if (cntl) {
- cntl.lastValue = undefined;
- cntl.updateView(scope);
+ // Special case for option in select
+ if (child && child.element[0].nodeName === "OPTION") {
+ var select = jQuery(child.element[0].parentNode);
+ var cntl = select.data('controller');
+ if (cntl) {
+ cntl.lastValue = undefined;
+ cntl.updateView(scope);
+ }
}
- }
- });
+ });
+ }
};
//////////////////////////////////
// PopUp
//////////////////////////////////
-PopUp = function(doc) {
+function PopUp(doc) {
this.doc = doc;
};
PopUp.OUT_EVENT = "mouseleave mouseout click dblclick keypress keyup";
-PopUp.prototype.bind = function () {
- var self = this;
- this.doc.find('.ng-validation-error,.ng-exception').
- live("mouseover", PopUp.onOver);
-};
-
PopUp.onOver = function(e) {
PopUp.onOut();
var jNode = jQuery(this);
@@ -753,28 +765,38 @@ PopUp.onOut = function() {
return true;
};
+PopUp.prototype = {
+ bind: function () {
+ var self = this;
+ this.doc.find('.ng-validation-error,.ng-exception').
+ live("mouseover", PopUp.onOver);
+ }
+};
+
//////////////////////////////////
// Status
//////////////////////////////////
-Status = function(body) {
+function Status(body) {
this.loader = body.append(Status.DOM).find("#ng-loading");
this.requestCount = 0;
};
Status.DOM ='loading....
';
-Status.prototype.beginRequest = function () {
- if (this.requestCount === 0) {
- this.loader.show();
- }
- this.requestCount++;
-};
-
-Status.prototype.endRequest = function () {
- this.requestCount--;
- if (this.requestCount === 0) {
- this.loader.hide("fold");
+Status.prototype = {
+ beginRequest: function () {
+ if (this.requestCount === 0) {
+ this.loader.show();
+ }
+ this.requestCount++;
+ },
+
+ endRequest: function () {
+ this.requestCount--;
+ if (this.requestCount === 0) {
+ this.loader.hide("fold");
+ }
}
};
diff --git a/src/angular-bootstrap.js b/src/angular-bootstrap.js
index b13bbf34..50c78f81 100644
--- a/src/angular-bootstrap.js
+++ b/src/angular-bootstrap.js
@@ -1,5 +1,26 @@
-// Copyright (C) 2008,2009 BRAT Tech LLC
-
+/**
+ * The MIT License
+ *
+ * Copyright (c) 2010 Adam Abrons and Misko Hevery http://getangular.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
(function(previousOnLoad){
var filename = /(.*)\/angular-(.*).js(#(.*))?/;
var scripts = document.getElementsByTagName("script");
diff --git a/src/angular.prefix b/src/angular.prefix
index dbd4959a..26a8429f 100644
--- a/src/angular.prefix
+++ b/src/angular.prefix
@@ -1 +1,24 @@
+/**
+ * The MIT License
+ *
+ * Copyright (c) 2010 Adam Abrons and Misko Hevery http://getangular.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
(function(window, document){
--
cgit v1.2.3
From 13dee60685216a1da9e3bce4d5130693f6f5c624 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Tue, 12 Jan 2010 08:40:10 -0800
Subject: dissable URL watching
---
src/Loader.js | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
(limited to 'src')
diff --git a/src/Loader.js b/src/Loader.js
index 5207defb..07731062 100644
--- a/src/Loader.js
+++ b/src/Loader.js
@@ -163,8 +163,6 @@ function Loader(document, head, config) {
Loader.prototype = {
load: function() {
this.configureLogging();
- this.loadCss('/stylesheets/jquery-ui/smoothness/jquery-ui-1.7.1.css');
- this.loadCss('/stylesheets/css');
log("Server: " + this.config.server);
this.configureJQueryPlugins();
this.computeConfiguration();
@@ -266,9 +264,9 @@ Loader.prototype = {
log('$binder.updateView()');
binder.updateView();
- watcher.listener = bind(binder, binder.onUrlChange, watcher);
- watcher.onUpdate = function(){alert("update");};
- watcher.watch();
+ //watcher.listener = bind(binder, binder.onUrlChange, watcher);
+ //watcher.onUpdate = function(){alert("update");};
+ //watcher.watch();
document.find("body").show();
log('ready()');
},
@@ -382,11 +380,14 @@ UrlWatcher.prototype = {
angular['compile'] = function(root, config) {
config = config || {};
var defaults = {
- server: ""
+ 'server': "",
+ 'addUrlChangeListener': noop
};
- //todo: don't load stylesheet by default
//todo: don't start watcher
var loader = new Loader(root, jQuery("head"), _(defaults).extend(config));
+ //todo: don't load stylesheet by default
+ // loader.loadCss('/stylesheets/jquery-ui/smoothness/jquery-ui-1.7.1.css');
+ // loader.loadCss('/stylesheets/css');
loader.load();
var scope = jQuery(root).scope();
//TODO: cleanup
--
cgit v1.2.3
From 19bbee030ba012b8fc4835c1d17e039804b2b94b Mon Sep 17 00:00:00 2001
From: Adam Abrons
Date: Tue, 12 Jan 2010 09:34:27 -0800
Subject: send database to mini login
---
src/ControlBar.js | 5 +++--
src/Loader.js | 2 +-
2 files changed, 4 insertions(+), 3 deletions(-)
(limited to 'src')
diff --git a/src/ControlBar.js b/src/ControlBar.js
index 3e1f0b57..bed7742f 100644
--- a/src/ControlBar.js
+++ b/src/ControlBar.js
@@ -1,8 +1,9 @@
// Copyright (C) 2008,2009 BRAT Tech LLC
-nglr.ControlBar = function (document, serverUrl) {
+nglr.ControlBar = function (document, serverUrl, database) {
this.document = document;
this.serverUrl = serverUrl;
+ this.database = database;
this.window = window;
this.callbacks = [];
};
@@ -21,7 +22,7 @@ nglr.ControlBar.HTML =
nglr.ControlBar.prototype.login = function (loginSubmitFn) {
this.callbacks.push(loginSubmitFn);
if (this.callbacks.length == 1) {
- this.doTemplate("/user_session/new.mini?return_url=" + encodeURIComponent(this.urlWithoutAnchor()));
+ this.doTemplate("/user_session/new.mini?database="+encodeURIComponent(this.database)+"&return_url=" + encodeURIComponent(this.urlWithoutAnchor()));
}
};
diff --git a/src/Loader.js b/src/Loader.js
index fdcfa3cc..e4dec316 100644
--- a/src/Loader.js
+++ b/src/Loader.js
@@ -213,7 +213,7 @@ nglr.Loader.prototype.bindHtml = function() {
var widgetFactory = new nglr.WidgetFactory(this.config.server, this.config.database);
var binder = new nglr.Binder(document[0], widgetFactory, watcher, this.config);
widgetFactory.onChangeListener = nglr.shiftBind(binder, binder.updateModel);
- var controlBar = new nglr.ControlBar(document.find('body'), this.config.server);
+ var controlBar = new nglr.ControlBar(document.find('body'), this.config.server, this.config.database);
var onUpdate = function(){binder.updateView();};
var server = this.config.database=="$MEMORY" ?
new nglr.FrameServer(this.window) :
--
cgit v1.2.3
From cae222ec7af7e1ab09bc2c0181efddc2d3d1aca2 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Tue, 12 Jan 2010 10:25:55 -0800
Subject: fix the special case for console functions
---
src/Loader.js | 33 ++++++++++++++++++++++++++++++---
1 file changed, 30 insertions(+), 3 deletions(-)
(limited to 'src')
diff --git a/src/Loader.js b/src/Loader.js
index 07731062..5cef348a 100644
--- a/src/Loader.js
+++ b/src/Loader.js
@@ -25,8 +25,6 @@ var consoleNode,
extend = _.extend,
jQuery = window['jQuery'],
msie = jQuery['browser']['msie'],
- log = function(){window['console']['log'].apply(this, arguments);},
- error = function(){window['console']['error'].apply(this, arguments);},
angular = window['angular'] || (window['angular'] = {}),
angularValidator = angular['validator'] || (angular['validator'] = {}),
angularFilter = angular['filter'] || (angular['filter'] = {}),
@@ -34,7 +32,36 @@ var consoleNode,
angularAlert = angular['alert'] || (angular['alert'] = function(){
log(arguments); window.alert.apply(window, arguments);
});
-
+
+function log(a, b, c){
+ var console = window['console'];
+ switch(arguments.length) {
+ case 1:
+ console['log'](a);
+ break;
+ case 2:
+ console['log'](a, b);
+ break;
+ default:
+ console['log'](a, b, c);
+ break;
+ }
+}
+
+function error(a, b, c){
+ var console = window['console'];
+ switch(arguments.length) {
+ case 1:
+ console['error'](a);
+ break;
+ case 2:
+ console['error'](a, b);
+ break;
+ default:
+ console['error'](a, b, c);
+ break;
+ }
+}
function consoleLog(level, objs) {
var log = document.createElement("div");
--
cgit v1.2.3
From e2a48aa2322801bd67cecd9ec516c07977500a52 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Tue, 12 Jan 2010 10:38:00 -0800
Subject: dissable set url
---
src/Loader.js | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
(limited to 'src')
diff --git a/src/Loader.js b/src/Loader.js
index 5cef348a..2ce44f48 100644
--- a/src/Loader.js
+++ b/src/Loader.js
@@ -391,12 +391,12 @@ UrlWatcher.prototype = {
},
setUrl: function(url) {
- var existingURL = window.location.href;
- if (!existingURL.match(/#/))
- existingURL += '#';
- if (existingURL != url)
- window.location.href = url;
- this.existingURL = url;
+// var existingURL = window.location.href;
+// if (!existingURL.match(/#/))
+// existingURL += '#';
+// if (existingURL != url)
+// window.location.href = url;
+// this.existingURL = url;
},
getUrl: function() {
--
cgit v1.2.3
From 27709c3f69384a7630aa336a1e73e730ea5f9790 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Tue, 12 Jan 2010 14:19:19 -0800
Subject: break out init phase into scope
---
src/Loader.js | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
(limited to 'src')
diff --git a/src/Loader.js b/src/Loader.js
index 2ce44f48..f3c765cd 100644
--- a/src/Loader.js
+++ b/src/Loader.js
@@ -284,10 +284,7 @@ Loader.prototype = {
log('$binder.parseAnchor()');
binder.parseAnchor();
-
- log('$binder.executeInit()');
- binder.executeInit();
-
+
log('$binder.updateView()');
binder.updateView();
@@ -419,8 +416,9 @@ angular['compile'] = function(root, config) {
var scope = jQuery(root).scope();
//TODO: cleanup
return {
- 'updateView':function(){return scope.updateView.apply(scope, arguments);},
+ 'updateView':function(){return scope.updateView();},
'set':function(){return scope.set.apply(scope, arguments);},
- 'get':function(){return scope.get.apply(scope, arguments);}
+ 'get':function(){return scope.get.apply(scope, arguments);},
+ 'init':function(){scope.get('$binder.executeInit')(); scope.updateView();}
};
};
\ No newline at end of file
--
cgit v1.2.3
From 595b4ea097bcb512173b6d4a12924ea1a3d70ecd Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Mon, 18 Jan 2010 10:47:03 -0800
Subject: checkpoint for integration with angular
---
src/Angular.js | 414 +++++++++++++++++++++++++++++++++++++++++++++
src/Loader.js | 424 -----------------------------------------------
src/angular-bootstrap.js | 115 -------------
3 files changed, 414 insertions(+), 539 deletions(-)
create mode 100644 src/Angular.js
delete mode 100644 src/Loader.js
delete mode 100644 src/angular-bootstrap.js
(limited to 'src')
diff --git a/src/Angular.js b/src/Angular.js
new file mode 100644
index 00000000..69cab0a2
--- /dev/null
+++ b/src/Angular.js
@@ -0,0 +1,414 @@
+if (typeof document.getAttribute == 'undefined')
+ document.getAttribute = function() {};
+if (typeof Node == 'undefined') {
+ Node = {
+ ELEMENT_NODE : 1,
+ ATTRIBUTE_NODE : 2,
+ TEXT_NODE : 3,
+ CDATA_SECTION_NODE : 4,
+ ENTITY_REFERENCE_NODE : 5,
+ ENTITY_NODE : 6,
+ PROCESSING_INSTRUCTION_NODE : 7,
+ COMMENT_NODE : 8,
+ DOCUMENT_NODE : 9,
+ DOCUMENT_TYPE_NODE : 10,
+ DOCUMENT_FRAGMENT_NODE : 11,
+ NOTATION_NODE : 12
+ };
+}
+
+function noop() {}
+if (!window['console']) window['console']={'log':noop, 'error':noop};
+
+var consoleNode,
+ foreach = _.each,
+ extend = _.extend,
+ jQuery = window['jQuery'],
+ msie = jQuery['browser']['msie'],
+ angular = window['angular'] || (window['angular'] = {}),
+ angularValidator = angular['validator'] || (angular['validator'] = {}),
+ angularFilter = angular['filter'] || (angular['filter'] = {}),
+ angularCallbacks = angular['callbacks'] || (angular['callbacks'] = {}),
+ angularAlert = angular['alert'] || (angular['alert'] = function(){
+ log(arguments); window.alert.apply(window, arguments);
+ });
+
+function log(a, b, c){
+ var console = window['console'];
+ switch(arguments.length) {
+ case 1:
+ console['log'](a);
+ break;
+ case 2:
+ console['log'](a, b);
+ break;
+ default:
+ console['log'](a, b, c);
+ break;
+ }
+}
+
+function error(a, b, c){
+ var console = window['console'];
+ switch(arguments.length) {
+ case 1:
+ console['error'](a);
+ break;
+ case 2:
+ console['error'](a, b);
+ break;
+ default:
+ console['error'](a, b, c);
+ break;
+ }
+}
+
+function consoleLog(level, objs) {
+ var log = document.createElement("div");
+ log.className = level;
+ var msg = "";
+ var sep = "";
+ for ( var i = 0; i < objs.length; i++) {
+ var obj = objs[i];
+ msg += sep + (typeof obj == 'string' ? obj : toJson(obj));
+ sep = " ";
+ }
+ log.appendChild(document.createTextNode(msg));
+ consoleNode.appendChild(log);
+}
+
+function isNode(inp) {
+ return inp &&
+ inp.tagName &&
+ inp.nodeName &&
+ inp.ownerDocument &&
+ inp.removeAttribute;
+}
+
+function isLeafNode (node) {
+ switch (node.nodeName) {
+ case "OPTION":
+ case "PRE":
+ case "TITLE":
+ return true;
+ default:
+ return false;
+ }
+}
+
+function setHtml(node, html) {
+ if (isLeafNode(node)) {
+ if (msie) {
+ node.innerText = html;
+ } else {
+ node.textContent = html;
+ }
+ } else {
+ node.innerHTML = html;
+ }
+}
+
+function escapeHtml(html) {
+ if (!html || !html.replace)
+ return html;
+ return html.
+ replace(/&/g, '&').
+ replace(//g, '>');
+}
+
+function escapeAttr(html) {
+ if (!html || !html.replace)
+ return html;
+ return html.replace(//g, '>').replace(/\"/g,
+ '"');
+}
+
+function bind(_this, _function) {
+ if (!_this)
+ throw "Missing this";
+ if (!_.isFunction(_function))
+ throw "Missing function";
+ return function() {
+ return _function.apply(_this, arguments);
+ };
+}
+
+function shiftBind(_this, _function) {
+ return function() {
+ var args = [ this ];
+ for ( var i = 0; i < arguments.length; i++) {
+ args.push(arguments[i]);
+ }
+ return _function.apply(_this, args);
+ };
+}
+
+function outerHTML(node) {
+ var temp = document.createElement('div');
+ temp.appendChild(node);
+ var outerHTML = temp.innerHTML;
+ temp.removeChild(node);
+ return outerHTML;
+}
+
+function trim(str) {
+ return str.replace(/^ */, '').replace(/ *$/, '');
+}
+
+function toBoolean(value) {
+ var v = ("" + value).toLowerCase();
+ if (v == 'f' || v == '0' || v == 'false' || v == 'no')
+ value = false;
+ return !!value;
+}
+
+function merge(src, dst) {
+ for ( var key in src) {
+ var value = dst[key];
+ var type = typeof value;
+ if (type == 'undefined') {
+ dst[key] = fromJson(toJson(src[key]));
+ } else if (type == 'object' && value.constructor != array &&
+ key.substring(0, 1) != "$") {
+ merge(src[key], value);
+ }
+ }
+}
+
+// ////////////////////////////
+// Angular
+// ////////////////////////////
+
+function Angular(document, head, config) {
+ this.document = jQuery(document);
+ this.head = jQuery(head);
+ this.config = config;
+ this.location = window.location;
+}
+
+Angular.prototype = {
+ load: function() {
+ this.configureLogging();
+ log("Server: " + this.config.server);
+ this.configureJQueryPlugins();
+ this.computeConfiguration();
+ this.bindHtml();
+ },
+
+ configureJQueryPlugins: function() {
+ log('Angular.configureJQueryPlugins()');
+ jQuery['fn']['scope'] = function() {
+ var element = this;
+ while (element && element.get(0)) {
+ var scope = element.data("scope");
+ if (scope)
+ return scope;
+ element = element.parent();
+ }
+ return null;
+ };
+ jQuery['fn']['controller'] = function() {
+ return this.data('controller') || NullController.instance;
+ };
+ },
+
+ uid: function() {
+ return "" + new Date().getTime();
+ },
+
+ computeConfiguration: function() {
+ var config = this.config;
+ if (!config.database) {
+ var match = config.server.match(/https?:\/\/([\w]*)/);
+ config.database = match ? match[1] : "$MEMORY";
+ }
+ },
+
+ bindHtml: function() {
+ log('Angular.bindHtml()');
+ var watcher = new UrlWatcher(this.location);
+ var document = this.document;
+ var widgetFactory = new WidgetFactory(this.config.server, this.config.database);
+ var binder = new Binder(document[0], widgetFactory, watcher, this.config);
+ widgetFactory.onChangeListener = shiftBind(binder, binder.updateModel);
+ var controlBar = new ControlBar(document.find('body'), this.config.server);
+ var onUpdate = function(){binder.updateView();};
+ var server = this.config.database=="$MEMORY" ?
+ new FrameServer(this.window) :
+ new Server(this.config.server, jQuery.getScript);
+ server = new VisualServer(server, new Status(jQuery(document.body)), onUpdate);
+ var users = new Users(server, controlBar);
+ var databasePath = '/data/' + this.config.database;
+ var post = function(request, callback){
+ server.request("POST", databasePath, request, callback);
+ };
+ var datastore = new DataStore(post, users, binder.anchor);
+ binder.updateListeners.push(function(){datastore.flush();});
+ var scope = new Scope( {
+ '$anchor' : binder.anchor,
+ '$binder' : binder,
+ '$config' : this.config,
+ '$console' : window.console,
+ '$datastore' : datastore,
+ '$save' : function(callback) {
+ datastore.saveScope(scope.state, callback, binder.anchor);
+ },
+ '$window' : window,
+ '$uid' : this.uid,
+ '$users' : users
+ }, "ROOT");
+
+ document.data('scope', scope);
+ log('$binder.entity()');
+ binder.entity(scope);
+
+ log('$binder.compile()');
+ binder.compile();
+
+ log('ControlBar.bind()');
+ controlBar.bind();
+
+ log('$users.fetchCurrentUser()');
+ function fetchCurrentUser() {
+ users.fetchCurrentUser(function(u) {
+ if (!u && document.find("[ng-auth=eager]").length) {
+ users.login();
+ }
+ });
+ }
+ fetchCurrentUser();
+
+ log('PopUp.bind()');
+ new PopUp(document).bind();
+
+ log('$binder.parseAnchor()');
+ binder.parseAnchor();
+
+ log('$binder.updateView()');
+ binder.updateView();
+
+ //watcher.listener = bind(binder, binder.onUrlChange, watcher);
+ //watcher.onUpdate = function(){alert("update");};
+ //watcher.watch();
+ document.find("body").show();
+ log('ready()');
+ },
+
+ visualPost: function(delegate) {
+ var status = new Status(jQuery(document.body));
+ return function(request, delegateCallback) {
+ status.beginRequest(request);
+ var callback = function() {
+ status.endRequest();
+ try {
+ delegateCallback.apply(this, arguments);
+ } catch (e) {
+ alert(toJson(e));
+ }
+ };
+ delegate(request, callback);
+ };
+ },
+
+ configureLogging: function() {
+ var url = window.location.href + '#';
+ url = url.split('#')[1];
+ var config = {
+ debug : null
+ };
+ var configs = url.split('&');
+ for ( var i = 0; i < configs.length; i++) {
+ var part = (configs[i] + '=').split('=');
+ config[part[0]] = part[1];
+ }
+ if (config.debug == 'console') {
+ consoleNode = document.createElement("div");
+ consoleNode.id = 'ng-console';
+ document.getElementsByTagName('body')[0].appendChild(consoleNode);
+ log = function() {
+ consoleLog('ng-console-info', arguments);
+ };
+ console.error = function() {
+ consoleLog('ng-console-error', arguments);
+ };
+ }
+ }
+};
+
+function UrlWatcher(location) {
+ this.location = location;
+ this.delay = 25;
+ this.setTimeout = function(fn, delay) {
+ window.setTimeout(fn, delay);
+ };
+ this.listener = function(url) {
+ return url;
+ };
+ this.expectedUrl = location.href;
+}
+
+UrlWatcher.prototype = {
+ watch: function() {
+ var self = this;
+ var pull = function() {
+ if (self.expectedUrl !== self.location.href) {
+ var notify = self.location.hash.match(/^#\$iframe_notify=(.*)$/);
+ if (notify) {
+ if (!self.expectedUrl.match(/#/)) {
+ self.expectedUrl += "#";
+ }
+ self.location.href = self.expectedUrl;
+ var id = '_iframe_notify_' + notify[1];
+ var notifyFn = angularCallbacks[id];
+ delete angularCallbacks[id];
+ try {
+ (notifyFn||noop)();
+ } catch (e) {
+ alert(e);
+ }
+ } else {
+ self.listener(self.location.href);
+ self.expectedUrl = self.location.href;
+ }
+ }
+ self.setTimeout(pull, self.delay);
+ };
+ pull();
+ },
+
+ setUrl: function(url) {
+// var existingURL = window.location.href;
+// if (!existingURL.match(/#/))
+// existingURL += '#';
+// if (existingURL != url)
+// window.location.href = url;
+// this.existingURL = url;
+ },
+
+ getUrl: function() {
+ return window.location.href;
+ }
+};
+
+angular['compile'] = function(root, config) {
+ config = config || {};
+ var defaults = {
+ 'server': "",
+ 'addUrlChangeListener': noop
+ };
+ //todo: don't start watcher
+ var angular = new Angular(root, jQuery("head"), _(defaults).extend(config));
+ //todo: don't load stylesheet by default
+ // loader.loadCss('/stylesheets/jquery-ui/smoothness/jquery-ui-1.7.1.css');
+ // loader.loadCss('/stylesheets/css');
+ angular.load();
+ var scope = jQuery(root).scope();
+ //TODO: cleanup
+ return {
+ 'updateView':function(){return scope.updateView();},
+ 'set':function(){return scope.set.apply(scope, arguments);},
+ 'get':function(){return scope.get.apply(scope, arguments);},
+ 'init':function(){scope.get('$binder.executeInit')(); scope.updateView();}
+ };
+};
\ No newline at end of file
diff --git a/src/Loader.js b/src/Loader.js
deleted file mode 100644
index f3c765cd..00000000
--- a/src/Loader.js
+++ /dev/null
@@ -1,424 +0,0 @@
-if (typeof document.getAttribute == 'undefined')
- document.getAttribute = function() {};
-if (typeof Node == 'undefined') {
- Node = {
- ELEMENT_NODE : 1,
- ATTRIBUTE_NODE : 2,
- TEXT_NODE : 3,
- CDATA_SECTION_NODE : 4,
- ENTITY_REFERENCE_NODE : 5,
- ENTITY_NODE : 6,
- PROCESSING_INSTRUCTION_NODE : 7,
- COMMENT_NODE : 8,
- DOCUMENT_NODE : 9,
- DOCUMENT_TYPE_NODE : 10,
- DOCUMENT_FRAGMENT_NODE : 11,
- NOTATION_NODE : 12
- };
-}
-
-function noop() {}
-if (!window['console']) window['console']={'log':noop, 'error':noop};
-
-var consoleNode,
- foreach = _.each,
- extend = _.extend,
- jQuery = window['jQuery'],
- msie = jQuery['browser']['msie'],
- angular = window['angular'] || (window['angular'] = {}),
- angularValidator = angular['validator'] || (angular['validator'] = {}),
- angularFilter = angular['filter'] || (angular['filter'] = {}),
- angularCallbacks = angular['callbacks'] || (angular['callbacks'] = {}),
- angularAlert = angular['alert'] || (angular['alert'] = function(){
- log(arguments); window.alert.apply(window, arguments);
- });
-
-function log(a, b, c){
- var console = window['console'];
- switch(arguments.length) {
- case 1:
- console['log'](a);
- break;
- case 2:
- console['log'](a, b);
- break;
- default:
- console['log'](a, b, c);
- break;
- }
-}
-
-function error(a, b, c){
- var console = window['console'];
- switch(arguments.length) {
- case 1:
- console['error'](a);
- break;
- case 2:
- console['error'](a, b);
- break;
- default:
- console['error'](a, b, c);
- break;
- }
-}
-
-function consoleLog(level, objs) {
- var log = document.createElement("div");
- log.className = level;
- var msg = "";
- var sep = "";
- for ( var i = 0; i < objs.length; i++) {
- var obj = objs[i];
- msg += sep + (typeof obj == 'string' ? obj : toJson(obj));
- sep = " ";
- }
- log.appendChild(document.createTextNode(msg));
- consoleNode.appendChild(log);
-}
-
-function isNode(inp) {
- return inp &&
- inp.tagName &&
- inp.nodeName &&
- inp.ownerDocument &&
- inp.removeAttribute;
-}
-
-function isLeafNode (node) {
- switch (node.nodeName) {
- case "OPTION":
- case "PRE":
- case "TITLE":
- return true;
- default:
- return false;
- }
-}
-
-function setHtml(node, html) {
- if (isLeafNode(node)) {
- if (msie) {
- node.innerText = html;
- } else {
- node.textContent = html;
- }
- } else {
- node.innerHTML = html;
- }
-}
-
-function escapeHtml(html) {
- if (!html || !html.replace)
- return html;
- return html.
- replace(/&/g, '&').
- replace(//g, '>');
-}
-
-function escapeAttr(html) {
- if (!html || !html.replace)
- return html;
- return html.replace(//g, '>').replace(/\"/g,
- '"');
-}
-
-function bind(_this, _function) {
- if (!_this)
- throw "Missing this";
- if (!_.isFunction(_function))
- throw "Missing function";
- return function() {
- return _function.apply(_this, arguments);
- };
-}
-
-function shiftBind(_this, _function) {
- return function() {
- var args = [ this ];
- for ( var i = 0; i < arguments.length; i++) {
- args.push(arguments[i]);
- }
- return _function.apply(_this, args);
- };
-}
-
-function outerHTML(node) {
- var temp = document.createElement('div');
- temp.appendChild(node);
- var outerHTML = temp.innerHTML;
- temp.removeChild(node);
- return outerHTML;
-}
-
-function trim(str) {
- return str.replace(/^ */, '').replace(/ *$/, '');
-}
-
-function toBoolean(value) {
- var v = ("" + value).toLowerCase();
- if (v == 'f' || v == '0' || v == 'false' || v == 'no')
- value = false;
- return !!value;
-}
-
-function merge(src, dst) {
- for ( var key in src) {
- var value = dst[key];
- var type = typeof value;
- if (type == 'undefined') {
- dst[key] = fromJson(toJson(src[key]));
- } else if (type == 'object' && value.constructor != array &&
- key.substring(0, 1) != "$") {
- merge(src[key], value);
- }
- }
-}
-
-// ////////////////////////////
-// Loader
-// ////////////////////////////
-
-function Loader(document, head, config) {
- this.document = jQuery(document);
- this.head = jQuery(head);
- this.config = config;
- this.location = window.location;
-}
-
-Loader.prototype = {
- load: function() {
- this.configureLogging();
- log("Server: " + this.config.server);
- this.configureJQueryPlugins();
- this.computeConfiguration();
- this.bindHtml();
- },
-
- configureJQueryPlugins: function() {
- log('Loader.configureJQueryPlugins()');
- jQuery['fn']['scope'] = function() {
- var element = this;
- while (element && element.get(0)) {
- var scope = element.data("scope");
- if (scope)
- return scope;
- element = element.parent();
- }
- return null;
- };
- jQuery['fn']['controller'] = function() {
- return this.data('controller') || NullController.instance;
- };
- },
-
- uid: function() {
- return "" + new Date().getTime();
- },
-
- computeConfiguration: function() {
- var config = this.config;
- if (!config.database) {
- var match = config.server.match(/https?:\/\/([\w]*)/);
- config.database = match ? match[1] : "$MEMORY";
- }
- },
-
- bindHtml: function() {
- log('Loader.bindHtml()');
- var watcher = new UrlWatcher(this.location);
- var document = this.document;
- var widgetFactory = new WidgetFactory(this.config.server, this.config.database);
- var binder = new Binder(document[0], widgetFactory, watcher, this.config);
- widgetFactory.onChangeListener = shiftBind(binder, binder.updateModel);
- var controlBar = new ControlBar(document.find('body'), this.config.server);
- var onUpdate = function(){binder.updateView();};
- var server = this.config.database=="$MEMORY" ?
- new FrameServer(this.window) :
- new Server(this.config.server, jQuery.getScript);
- server = new VisualServer(server, new Status(jQuery(document.body)), onUpdate);
- var users = new Users(server, controlBar);
- var databasePath = '/data/' + this.config.database;
- var post = function(request, callback){
- server.request("POST", databasePath, request, callback);
- };
- var datastore = new DataStore(post, users, binder.anchor);
- binder.updateListeners.push(function(){datastore.flush();});
- var scope = new Scope( {
- '$anchor' : binder.anchor,
- '$binder' : binder,
- '$config' : this.config,
- '$console' : window.console,
- '$datastore' : datastore,
- '$save' : function(callback) {
- datastore.saveScope(scope.state, callback, binder.anchor);
- },
- '$window' : window,
- '$uid' : this.uid,
- '$users' : users
- }, "ROOT");
-
- document.data('scope', scope);
- log('$binder.entity()');
- binder.entity(scope);
-
- log('$binder.compile()');
- binder.compile();
-
- log('ControlBar.bind()');
- controlBar.bind();
-
- log('$users.fetchCurrentUser()');
- function fetchCurrentUser() {
- users.fetchCurrentUser(function(u) {
- if (!u && document.find("[ng-auth=eager]").length) {
- users.login();
- }
- });
- }
- fetchCurrentUser();
-
- log('PopUp.bind()');
- new PopUp(document).bind();
-
- log('$binder.parseAnchor()');
- binder.parseAnchor();
-
- log('$binder.updateView()');
- binder.updateView();
-
- //watcher.listener = bind(binder, binder.onUrlChange, watcher);
- //watcher.onUpdate = function(){alert("update");};
- //watcher.watch();
- document.find("body").show();
- log('ready()');
- },
-
- visualPost: function(delegate) {
- var status = new Status(jQuery(document.body));
- return function(request, delegateCallback) {
- status.beginRequest(request);
- var callback = function() {
- status.endRequest();
- try {
- delegateCallback.apply(this, arguments);
- } catch (e) {
- alert(toJson(e));
- }
- };
- delegate(request, callback);
- };
- },
-
- configureLogging: function() {
- var url = window.location.href + '#';
- url = url.split('#')[1];
- var config = {
- debug : null
- };
- var configs = url.split('&');
- for ( var i = 0; i < configs.length; i++) {
- var part = (configs[i] + '=').split('=');
- config[part[0]] = part[1];
- }
- if (config.debug == 'console') {
- consoleNode = document.createElement("div");
- consoleNode.id = 'ng-console';
- document.getElementsByTagName('body')[0].appendChild(consoleNode);
- log = function() {
- consoleLog('ng-console-info', arguments);
- };
- console.error = function() {
- consoleLog('ng-console-error', arguments);
- };
- }
- },
-
- loadCss: function(css) {
- var cssTag = document.createElement('link');
- cssTag.rel = "stylesheet";
- cssTag.type = "text/css";
- if (!css.match(/^http:/))
- css = this.config.server + css;
- cssTag.href = css;
- this.head[0].appendChild(cssTag);
- }
-};
-
-function UrlWatcher(location) {
- this.location = location;
- this.delay = 25;
- this.setTimeout = function(fn, delay) {
- window.setTimeout(fn, delay);
- };
- this.listener = function(url) {
- return url;
- };
- this.expectedUrl = location.href;
-}
-
-UrlWatcher.prototype = {
- watch: function() {
- var self = this;
- var pull = function() {
- if (self.expectedUrl !== self.location.href) {
- var notify = self.location.hash.match(/^#\$iframe_notify=(.*)$/);
- if (notify) {
- if (!self.expectedUrl.match(/#/)) {
- self.expectedUrl += "#";
- }
- self.location.href = self.expectedUrl;
- var id = '_iframe_notify_' + notify[1];
- var notifyFn = angularCallbacks[id];
- delete angularCallbacks[id];
- try {
- (notifyFn||noop)();
- } catch (e) {
- alert(e);
- }
- } else {
- self.listener(self.location.href);
- self.expectedUrl = self.location.href;
- }
- }
- self.setTimeout(pull, self.delay);
- };
- pull();
- },
-
- setUrl: function(url) {
-// var existingURL = window.location.href;
-// if (!existingURL.match(/#/))
-// existingURL += '#';
-// if (existingURL != url)
-// window.location.href = url;
-// this.existingURL = url;
- },
-
- getUrl: function() {
- return window.location.href;
- }
-};
-
-angular['compile'] = function(root, config) {
- config = config || {};
- var defaults = {
- 'server': "",
- 'addUrlChangeListener': noop
- };
- //todo: don't start watcher
- var loader = new Loader(root, jQuery("head"), _(defaults).extend(config));
- //todo: don't load stylesheet by default
- // loader.loadCss('/stylesheets/jquery-ui/smoothness/jquery-ui-1.7.1.css');
- // loader.loadCss('/stylesheets/css');
- loader.load();
- var scope = jQuery(root).scope();
- //TODO: cleanup
- return {
- 'updateView':function(){return scope.updateView();},
- 'set':function(){return scope.set.apply(scope, arguments);},
- 'get':function(){return scope.get.apply(scope, arguments);},
- 'init':function(){scope.get('$binder.executeInit')(); scope.updateView();}
- };
-};
\ No newline at end of file
diff --git a/src/angular-bootstrap.js b/src/angular-bootstrap.js
deleted file mode 100644
index 50c78f81..00000000
--- a/src/angular-bootstrap.js
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
- * The MIT License
- *
- * Copyright (c) 2010 Adam Abrons and Misko Hevery http://getangular.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-(function(previousOnLoad){
- var filename = /(.*)\/angular-(.*).js(#(.*))?/;
- var scripts = document.getElementsByTagName("script");
- var scriptConfig = {
- autoSubmit:true,
- autoBind:true,
- autoLoadDependencies:false
- };
- for(var j = 0; j < scripts.length; j++) {
- var src = scripts[j].src;
- if (src && src.match(filename)) {
- var parts = src.match(filename);
- if (parts[2] == 'bootstrap') {
- scriptConfig.autoLoadDependencies = true;
- }
- scriptConfig.server = parts[1] || '';
- if (!scriptConfig.server) {
- scriptConfig.server = window.location.toString().split(window.location.pathname)[0];
- }
- if (parts[4]) {
- var directive = parts[4].split('&');
- for ( var i = 0; i < directive.length; i++) {
- var keyValue = directive[i].split('=');
- var key = keyValue[0];
- var value = keyValue.length == 1 ? true : keyValue[1];
- if (value == 'false') value = false;
- if (value == 'true') value = true;
- scriptConfig[key] = value;
- }
- }
- }
- }
-
- var addScript = function(path, server){
- server = server || scriptConfig.server;
- document.write('');
- };
-
- if (scriptConfig.autoLoadDependencies) {
- addScript("/../lib/webtoolkit/webtoolkit.base64.js");
- addScript("/../lib/swfobject/swfobject.js");
- addScript("/../lib/jquery/jquery-1.3.2.js");
- addScript("/../lib/jquery/jquery-ui-1.7.1.custom.min.js");
- addScript("/../lib/underscore/underscore.js");
- addScript("/Loader.js");
- addScript("/API.js");
- addScript("/Binder.js");
- addScript("/ControlBar.js");
- addScript("/DataStore.js");
- addScript("/Filters.js");
- addScript("/JSON.js");
- addScript("/Model.js");
- addScript("/Parser.js");
- addScript("/Scope.js");
- addScript("/Server.js");
- addScript("/Users.js");
- addScript("/Validators.js");
- addScript("/Widgets.js");
- } else {
- addScript("/ajax/libs/swfobject/2.2/swfobject.js", "http://ajax.googleapis.com");
- addScript("/ajax/libs/jquery/1.3.2/jquery.min.js", "http://ajax.googleapis.com");
- addScript("/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js", "http://ajax.googleapis.com");
- }
-
- window.onload = function() {
- var doc = window.document;
- if (scriptConfig.bindRootId) {
- doc = null;
- var ids = scriptConfig.bindRootId.split('|');
- for ( var i = 0; i < ids.length && !doc; i++) {
- var idCond = ids[i].split('?');
- var id = idCond[0];
- if (idCond.length > 1) {
- if (!window.document.getElementById(idCond[1])) {
- continue;
- }
- }
- doc = window.document.getElementById(id);
- }
- }
- if (scriptConfig.autoBind && doc) {
- window.angularScope = angular.compile(doc, scriptConfig);
- }
- if (typeof previousOnLoad === 'function') {
- try {
- previousOnLoad.apply(this, arguments);
- } catch (e) {}
- }
- };
-})(window.onload);
-
-
--
cgit v1.2.3
From 0e566fe6cb41de388df6793b350fb81aaa4a8476 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Mon, 18 Jan 2010 17:56:08 -0800
Subject: tweeter demo client
---
src/Angular.js | 30 ++++++++++++++++--------------
src/Binder.js | 1 -
src/Filters.js | 17 +++++++++++++++++
3 files changed, 33 insertions(+), 15 deletions(-)
(limited to 'src')
diff --git a/src/Angular.js b/src/Angular.js
index 69cab0a2..3dc72ff7 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -227,7 +227,7 @@ Angular.prototype = {
bindHtml: function() {
log('Angular.bindHtml()');
- var watcher = new UrlWatcher(this.location);
+ var watcher = this.watcher = new UrlWatcher(this.location);
var document = this.document;
var widgetFactory = new WidgetFactory(this.config.server, this.config.database);
var binder = new Binder(document[0], widgetFactory, watcher, this.config);
@@ -285,12 +285,6 @@ Angular.prototype = {
log('$binder.parseAnchor()');
binder.parseAnchor();
- log('$binder.updateView()');
- binder.updateView();
-
- //watcher.listener = bind(binder, binder.onUrlChange, watcher);
- //watcher.onUpdate = function(){alert("update");};
- //watcher.watch();
document.find("body").show();
log('ready()');
},
@@ -378,12 +372,13 @@ UrlWatcher.prototype = {
},
setUrl: function(url) {
-// var existingURL = window.location.href;
-// if (!existingURL.match(/#/))
-// existingURL += '#';
-// if (existingURL != url)
-// window.location.href = url;
-// this.existingURL = url;
+ //TODO: conditionaly?
+ var existingURL = window.location.href;
+ if (!existingURL.match(/#/))
+ existingURL += '#';
+ if (existingURL != url)
+ window.location.href = url;
+ this.existingURL = url;
},
getUrl: function() {
@@ -409,6 +404,13 @@ angular['compile'] = function(root, config) {
'updateView':function(){return scope.updateView();},
'set':function(){return scope.set.apply(scope, arguments);},
'get':function(){return scope.get.apply(scope, arguments);},
- 'init':function(){scope.get('$binder.executeInit')(); scope.updateView();}
+ 'init':function(){scope.get('$binder.executeInit')(); scope.updateView();},
+ 'watchUrl':function(){
+ var binder = scope.get('$binder');
+ var watcher = angular.watcher;
+ watcher.listener = bind(binder, binder.onUrlChange, watcher);
+ watcher.onUpdate = function(){alert("update");};
+ watcher.watch();
+ }
};
};
\ No newline at end of file
diff --git a/src/Binder.js b/src/Binder.js
index 36cb6ec3..b29a07c6 100644
--- a/src/Binder.js
+++ b/src/Binder.js
@@ -66,7 +66,6 @@ Binder.prototype = {
},
onUrlChange: function (url) {
- log("URL change detected", url);
this.parseAnchor(url);
this.updateView();
},
diff --git a/src/Filters.js b/src/Filters.js
index 666c9f30..833d5630 100644
--- a/src/Filters.js
+++ b/src/Filters.js
@@ -293,6 +293,23 @@ foreach({
'html': function(html){
return new angularFilter.Meta({html:html});
+ },
+
+ 'linky': function(text){
+ function regExpEscape(text) {
+ return text.replace(/([\/\.\*\+\?\|\(\)\[\]\{\}\\])/g, '\\$1');
+ }
+ var URL = /(ftp|http|https):\/\/([^\(\)|\s]+)/gm;
+ var html = text;
+ var dups = {};
+ foreach(text.match(URL)||[], function(url){
+ url = url.replace(/\.$/, '');
+ if (!dups[url]) {
+ html = html.replace(new RegExp(regExpEscape(url), 'gm'), ''+url+'');
+ dups[url] = true;
+ }
+ });
+ return new angularFilter.Meta({text:text, html:html});
}
}, function(v,k){angularFilter[k] = v;});
--
cgit v1.2.3
From db2031c5a1df205e6db40ca6aba80930375069c0 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Tue, 19 Jan 2010 17:53:20 -0800
Subject: added debug info; fix parser bug with double negation
---
src/Parser.js | 28 +++++++++++++---------------
1 file changed, 13 insertions(+), 15 deletions(-)
(limited to 'src')
diff --git a/src/Parser.js b/src/Parser.js
index 333b8413..840f5541 100644
--- a/src/Parser.js
+++ b/src/Parser.js
@@ -294,15 +294,13 @@ Parser.prototype = {
}
},
- _unary: function(fn, parse) {
- var right = parse.apply(this);
+ _unary: function(fn, right) {
return function(self) {
return fn(self, right(self));
};
},
- _binary: function(left, fn, parse) {
- var right = parse.apply(this);
+ _binary: function(left, fn, right) {
return function(self) {
return fn(self, left(self), right(self));
};
@@ -343,7 +341,7 @@ Parser.prototype = {
var token;
while(true) {
if ((token = this.expect('|'))) {
- left = this._binary(left, token.fn, this.filter);
+ left = this._binary(left, token.fn, this.filter());
} else {
return left;
}
@@ -405,7 +403,7 @@ Parser.prototype = {
this.text.substring(token.index) + "' is not assignable.";
}
var ident = function(){return left.isAssignable;};
- return this._binary(ident, token.fn, this.logicalOR);
+ return this._binary(ident, token.fn, this.logicalOR());
} else {
return left;
}
@@ -416,7 +414,7 @@ Parser.prototype = {
var token;
while(true) {
if ((token = this.expect('||'))) {
- left = this._binary(left, token.fn, this.logicalAND);
+ left = this._binary(left, token.fn, this.logicalAND());
} else {
return left;
}
@@ -428,7 +426,7 @@ Parser.prototype = {
var token;
while(true) {
if ((token = this.expect('&&'))) {
- left = this._binary(left, token.fn, this.negated);
+ left = this._binary(left, token.fn, this.negated());
} else {
return left;
}
@@ -438,9 +436,9 @@ Parser.prototype = {
negated: function(){
var token;
if (token = this.expect('!')) {
- return this._unary(token.fn, this.equality);
+ return this._unary(token.fn, this.assignment());
} else {
- return this.equality();
+ return this.equality();
}
},
@@ -449,7 +447,7 @@ Parser.prototype = {
var token;
while(true) {
if ((token = this.expect('==','!='))) {
- left = this._binary(left, token.fn, this.relational);
+ left = this._binary(left, token.fn, this.relational());
} else {
return left;
}
@@ -461,7 +459,7 @@ Parser.prototype = {
var token;
while(true) {
if ((token = this.expect('<', '>', '<=', '>='))) {
- left = this._binary(left, token.fn, this.additive);
+ left = this._binary(left, token.fn, this.additive());
} else {
return left;
}
@@ -472,7 +470,7 @@ Parser.prototype = {
var left = this.multiplicative();
var token;
while(token = this.expect('+','-')) {
- left = this._binary(left, token.fn, this.multiplicative);
+ left = this._binary(left, token.fn, this.multiplicative());
}
return left;
},
@@ -481,7 +479,7 @@ Parser.prototype = {
var left = this.unary();
var token;
while(token = this.expect('*','/','%')) {
- left = this._binary(left, token.fn, this.unary);
+ left = this._binary(left, token.fn, this.unary());
}
return left;
},
@@ -491,7 +489,7 @@ Parser.prototype = {
if (this.expect('+')) {
return this.primary();
} else if (token = this.expect('-')) {
- return this._binary(Parser.ZERO, token.fn, this.multiplicative);
+ return this._binary(Parser.ZERO, token.fn, this.multiplicative());
} else {
return this.primary();
}
--
cgit v1.2.3
From dc0db57b36bb6cd47dfea835a315f61b34ed8e1b Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Wed, 20 Jan 2010 06:52:50 -0800
Subject: tweek tweeter
---
src/Filters.js | 27 ++++++++++++++++-----------
1 file changed, 16 insertions(+), 11 deletions(-)
(limited to 'src')
diff --git a/src/Filters.js b/src/Filters.js
index 833d5630..a0bedaaf 100644
--- a/src/Filters.js
+++ b/src/Filters.js
@@ -296,20 +296,25 @@ foreach({
},
'linky': function(text){
+ if (!text) return text;
function regExpEscape(text) {
return text.replace(/([\/\.\*\+\?\|\(\)\[\]\{\}\\])/g, '\\$1');
}
- var URL = /(ftp|http|https):\/\/([^\(\)|\s]+)/gm;
- var html = text;
- var dups = {};
- foreach(text.match(URL)||[], function(url){
- url = url.replace(/\.$/, '');
- if (!dups[url]) {
- html = html.replace(new RegExp(regExpEscape(url), 'gm'), ''+url+'');
- dups[url] = true;
- }
- });
- return new angularFilter.Meta({text:text, html:html});
+ var URL = /(ftp|http|https|mailto):\/\/([^\(\)|\s]+)/;
+ var match;
+ var raw = text;
+ var html = [];
+ while (match=raw.match(URL)) {
+ var url = match[0].replace(/[\.\;\,\(\)\{\}\<\>]$/,'');
+ var i = raw.indexOf(url);
+ html.push(escapeHtml(raw.substr(0, i)));
+ html.push('');
+ html.push(url);
+ html.push('');
+ raw = raw.substring(i + url.length);
+ }
+ html.push(escapeHtml(raw));
+ return new angularFilter.Meta({text:text, html:html.join('')});
}
}, function(v,k){angularFilter[k] = v;});
--
cgit v1.2.3
From e41ee88ef85986dcd0fea23fefcc57d89cee5c0b Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Fri, 22 Jan 2010 11:21:22 -0800
Subject: fix bug when multiple binders on same page
---
src/Binder.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
(limited to 'src')
diff --git a/src/Binder.js b/src/Binder.js
index b29a07c6..b687fb77 100644
--- a/src/Binder.js
+++ b/src/Binder.js
@@ -137,7 +137,6 @@ Binder.prototype = {
compile: function() {
var jNode = jQuery(this.doc);
- var self = this;
if (this.config.autoSubmit) {
var submits = this.docFindWithSelf(":submit").not("[ng-action]");
submits.attr("ng-action", "$save()");
@@ -146,15 +145,16 @@ Binder.prototype = {
this.precompile(this.doc)(this.doc, jNode.scope(), "");
this.docFindWithSelf("a[ng-action]").live('click', function (event) {
var jNode = jQuery(this);
+ var scope = jNode.scope();
try {
- jNode.scope().eval(jNode.attr('ng-action'));
+ scope.eval(jNode.attr('ng-action'));
jNode.removeAttr('ng-error');
jNode.removeClass("ng-exception");
} catch (e) {
jNode.addClass("ng-exception");
jNode.attr('ng-error', toJson(e, true));
}
- self.updateView();
+ scope.eval('$binder.updateView()');
return false;
});
},
--
cgit v1.2.3
From 4460328bc1173f5d97fb4ff54edc041968486fce Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Sat, 23 Jan 2010 15:54:58 -0800
Subject: lots of cleanup to get it ready for OS
---
src/Angular.js | 328 ++++++++++++++++++++++++---------------------------------
src/Binder.js | 19 ++--
src/JSON.js | 18 +++-
src/Users.js | 4 +-
src/Widgets.js | 11 +-
5 files changed, 163 insertions(+), 217 deletions(-)
(limited to 'src')
diff --git a/src/Angular.js b/src/Angular.js
index 3dc72ff7..51fca458 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -134,16 +134,6 @@ function bind(_this, _function) {
};
}
-function shiftBind(_this, _function) {
- return function() {
- var args = [ this ];
- for ( var i = 0; i < arguments.length; i++) {
- args.push(arguments[i]);
- }
- return _function.apply(_this, args);
- };
-}
-
function outerHTML(node) {
var temp = document.createElement('div');
temp.appendChild(node);
@@ -177,159 +167,9 @@ function merge(src, dst) {
}
// ////////////////////////////
-// Angular
+// UrlWatcher
// ////////////////////////////
-function Angular(document, head, config) {
- this.document = jQuery(document);
- this.head = jQuery(head);
- this.config = config;
- this.location = window.location;
-}
-
-Angular.prototype = {
- load: function() {
- this.configureLogging();
- log("Server: " + this.config.server);
- this.configureJQueryPlugins();
- this.computeConfiguration();
- this.bindHtml();
- },
-
- configureJQueryPlugins: function() {
- log('Angular.configureJQueryPlugins()');
- jQuery['fn']['scope'] = function() {
- var element = this;
- while (element && element.get(0)) {
- var scope = element.data("scope");
- if (scope)
- return scope;
- element = element.parent();
- }
- return null;
- };
- jQuery['fn']['controller'] = function() {
- return this.data('controller') || NullController.instance;
- };
- },
-
- uid: function() {
- return "" + new Date().getTime();
- },
-
- computeConfiguration: function() {
- var config = this.config;
- if (!config.database) {
- var match = config.server.match(/https?:\/\/([\w]*)/);
- config.database = match ? match[1] : "$MEMORY";
- }
- },
-
- bindHtml: function() {
- log('Angular.bindHtml()');
- var watcher = this.watcher = new UrlWatcher(this.location);
- var document = this.document;
- var widgetFactory = new WidgetFactory(this.config.server, this.config.database);
- var binder = new Binder(document[0], widgetFactory, watcher, this.config);
- widgetFactory.onChangeListener = shiftBind(binder, binder.updateModel);
- var controlBar = new ControlBar(document.find('body'), this.config.server);
- var onUpdate = function(){binder.updateView();};
- var server = this.config.database=="$MEMORY" ?
- new FrameServer(this.window) :
- new Server(this.config.server, jQuery.getScript);
- server = new VisualServer(server, new Status(jQuery(document.body)), onUpdate);
- var users = new Users(server, controlBar);
- var databasePath = '/data/' + this.config.database;
- var post = function(request, callback){
- server.request("POST", databasePath, request, callback);
- };
- var datastore = new DataStore(post, users, binder.anchor);
- binder.updateListeners.push(function(){datastore.flush();});
- var scope = new Scope( {
- '$anchor' : binder.anchor,
- '$binder' : binder,
- '$config' : this.config,
- '$console' : window.console,
- '$datastore' : datastore,
- '$save' : function(callback) {
- datastore.saveScope(scope.state, callback, binder.anchor);
- },
- '$window' : window,
- '$uid' : this.uid,
- '$users' : users
- }, "ROOT");
-
- document.data('scope', scope);
- log('$binder.entity()');
- binder.entity(scope);
-
- log('$binder.compile()');
- binder.compile();
-
- log('ControlBar.bind()');
- controlBar.bind();
-
- log('$users.fetchCurrentUser()');
- function fetchCurrentUser() {
- users.fetchCurrentUser(function(u) {
- if (!u && document.find("[ng-auth=eager]").length) {
- users.login();
- }
- });
- }
- fetchCurrentUser();
-
- log('PopUp.bind()');
- new PopUp(document).bind();
-
- log('$binder.parseAnchor()');
- binder.parseAnchor();
-
- document.find("body").show();
- log('ready()');
- },
-
- visualPost: function(delegate) {
- var status = new Status(jQuery(document.body));
- return function(request, delegateCallback) {
- status.beginRequest(request);
- var callback = function() {
- status.endRequest();
- try {
- delegateCallback.apply(this, arguments);
- } catch (e) {
- alert(toJson(e));
- }
- };
- delegate(request, callback);
- };
- },
-
- configureLogging: function() {
- var url = window.location.href + '#';
- url = url.split('#')[1];
- var config = {
- debug : null
- };
- var configs = url.split('&');
- for ( var i = 0; i < configs.length; i++) {
- var part = (configs[i] + '=').split('=');
- config[part[0]] = part[1];
- }
- if (config.debug == 'console') {
- consoleNode = document.createElement("div");
- consoleNode.id = 'ng-console';
- document.getElementsByTagName('body')[0].appendChild(consoleNode);
- log = function() {
- consoleLog('ng-console-info', arguments);
- };
- console.error = function() {
- consoleLog('ng-console-error', arguments);
- };
- }
- }
-};
-
function UrlWatcher(location) {
this.location = location;
this.delay = 25;
@@ -343,6 +183,9 @@ function UrlWatcher(location) {
}
UrlWatcher.prototype = {
+ listen: function(fn){
+ this.listener = fn;
+ },
watch: function() {
var self = this;
var pull = function() {
@@ -369,48 +212,149 @@ UrlWatcher.prototype = {
self.setTimeout(pull, self.delay);
};
pull();
+ return this;
},
- setUrl: function(url) {
- //TODO: conditionaly?
- var existingURL = window.location.href;
+ set: function(url) {
+ var existingURL = this.location.href;
if (!existingURL.match(/#/))
existingURL += '#';
if (existingURL != url)
- window.location.href = url;
+ this.location.href = url;
this.existingURL = url;
},
- getUrl: function() {
+ get: function() {
return window.location.href;
}
};
-
-angular['compile'] = function(root, config) {
- config = config || {};
- var defaults = {
- 'server': "",
- 'addUrlChangeListener': noop
- };
- //todo: don't start watcher
- var angular = new Angular(root, jQuery("head"), _(defaults).extend(config));
- //todo: don't load stylesheet by default
- // loader.loadCss('/stylesheets/jquery-ui/smoothness/jquery-ui-1.7.1.css');
- // loader.loadCss('/stylesheets/css');
- angular.load();
- var scope = jQuery(root).scope();
- //TODO: cleanup
- return {
- 'updateView':function(){return scope.updateView();},
- 'set':function(){return scope.set.apply(scope, arguments);},
- 'get':function(){return scope.get.apply(scope, arguments);},
- 'init':function(){scope.get('$binder.executeInit')(); scope.updateView();},
- 'watchUrl':function(){
- var binder = scope.get('$binder');
- var watcher = angular.watcher;
- watcher.listener = bind(binder, binder.onUrlChange, watcher);
- watcher.onUpdate = function(){alert("update");};
- watcher.watch();
+
+/////////////////////////////////////////////////
+function configureJQueryPlugins() {
+ log('Angular.configureJQueryPlugins()');
+ var fn = jQuery['fn'];
+ fn['scope'] = function() {
+ var element = this;
+ while (element && element.get(0)) {
+ var scope = element.data("scope");
+ if (scope)
+ return scope;
+ element = element.parent();
}
+ return null;
+ };
+ fn['controller'] = function() {
+ return this.data('controller') || NullController.instance;
};
+}
+
+function configureLogging(config) {
+ if (config.debug == 'console' && !consoleNode) {
+ consoleNode = document.createElement("div");
+ consoleNode.id = 'ng-console';
+ document.getElementsByTagName('body')[0].appendChild(consoleNode);
+ log = function() {
+ consoleLog('ng-console-info', arguments);
+ };
+ console.error = function() {
+ consoleLog('ng-console-error', arguments);
+ };
+ }
+}
+
+function exposeMethods(obj, methods){
+ var bound = {};
+ foreach(methods, function(fn, name){
+ bound[name] = _(fn).bind(obj);
+ });
+ return bound;
+}
+
+function wireAngular(element, config) {
+ var widgetFactory = new WidgetFactory(config['server'], config['database']);
+ var binder = new Binder(element[0], widgetFactory, config['location'], config);
+ var controlBar = new ControlBar(element.find('body'), config.server);
+ var onUpdate = function(){binder.updateView();};
+ var server = config.database=="$MEMORY" ?
+ new FrameServer(this.window) :
+ new Server(config.server, jQuery.getScript);
+ server = new VisualServer(server, new Status(jQuery(element.body)), onUpdate);
+ var users = new Users(server, controlBar);
+ var databasePath = '/data/' + config.database;
+ var post = function(request, callback){
+ server.request("POST", databasePath, request, callback);
+ };
+ var datastore = new DataStore(post, users, binder.anchor);
+ binder.updateListeners.push(function(){datastore.flush();});
+ var scope = new Scope({
+ '$anchor' : binder.anchor,
+ '$updateView': _(binder.updateView).bind(binder),
+ '$config' : config,
+ '$console' : window.console,
+ '$datastore' : exposeMethods(datastore, {
+ 'load': datastore.load,
+ 'loadMany': datastore.loadMany,
+ 'loadOrCreate': datastore.loadOrCreate,
+ 'loadAll': datastore.loadAll,
+ 'save': datastore.save,
+ 'remove': datastore.remove,
+ 'flush': datastore.flush,
+ 'query': datastore.query,
+ 'entity': datastore.entity,
+ 'entities': datastore.entities,
+ 'documentCountsByUser': datastore.documentCountsByUser,
+ 'userDocumentIdsByEntity': datastore.userDocumentIdsByEntity,
+ 'join': datastore.join
+ }),
+ '$save' : function(callback) {
+ datastore.saveScope(scope.state, callback, binder.anchor);
+ },
+ '$window' : window,
+ '$uid' : function() {
+ return "" + new Date().getTime();
+ },
+ '$users' : users
+ }, "ROOT");
+
+ element.data('scope', scope);
+ binder.entity(scope);
+ binder.compile();
+ controlBar.bind();
+
+ //TODO: remove this code
+ new PopUp(element).bind();
+
+ var self = _(exposeMethods(scope, {
+ 'updateView': scope.updateView,
+ 'set': scope.set,
+ 'get': scope.get,
+ 'eval': scope.eval
+ })).extend({
+ 'init':function(){
+ config['location']['listen'](_(binder.onUrlChange).bind(binder));
+ binder.parseAnchor();
+ binder.executeInit();
+ scope.updateView();
+ return self;
+ },
+ 'element':element[0],
+ 'config':config
+ });
+ return self;
+}
+
+angular['startUrlWatcher'] = function(){
+ return new UrlWatcher(window['location']).watch();
+};
+
+angular['compile'] = function(element, config) {
+ config = _({
+ 'server': "",
+ 'location': {'get':noop, 'set':noop, 'listen':noop}
+ }).extend(config||{});
+
+ configureLogging(config);
+ configureJQueryPlugins();
+
+ return wireAngular(jQuery(element), config);
};
\ No newline at end of file
diff --git a/src/Binder.js b/src/Binder.js
index b687fb77..3fc45a20 100644
--- a/src/Binder.js
+++ b/src/Binder.js
@@ -1,6 +1,6 @@
-function Binder(doc, widgetFactory, urlWatcher, config) {
+function Binder(doc, widgetFactory, location, config) {
this.doc = doc;
- this.urlWatcher = urlWatcher;
+ this.location = location;
this.anchor = {};
this.widgetFactory = widgetFactory;
this.config = config || {};
@@ -48,9 +48,8 @@ Binder.prototype = {
return params;
},
- parseAnchor: function(url) {
- var self = this;
- url = url || this.urlWatcher.getUrl();
+ parseAnchor: function() {
+ var self = this, url = this.location.get() || "";
var anchorIndex = url.indexOf('#');
if (anchorIndex < 0) return;
@@ -65,13 +64,13 @@ Binder.prototype = {
});
},
- onUrlChange: function (url) {
- this.parseAnchor(url);
+ onUrlChange: function() {
+ this.parseAnchor();
this.updateView();
},
updateAnchor: function() {
- var url = this.urlWatcher.getUrl();
+ var url = this.location.get();
var anchorIndex = url.indexOf('#');
if (anchorIndex > -1)
url = url.substring(0, anchorIndex);
@@ -88,7 +87,7 @@ Binder.prototype = {
sep = '&';
}
}
- this.urlWatcher.setUrl(url);
+ this.location.set(url);
return url;
},
@@ -154,7 +153,7 @@ Binder.prototype = {
jNode.addClass("ng-exception");
jNode.attr('ng-error', toJson(e, true));
}
- scope.eval('$binder.updateView()');
+ scope.get('$updateView')();
return false;
});
},
diff --git a/src/JSON.js b/src/JSON.js
index 0c842865..98dfddd2 100644
--- a/src/JSON.js
+++ b/src/JSON.js
@@ -2,7 +2,7 @@ array = [].constructor;
function toJson(obj, pretty){
var buf = [];
- toJsonArray(buf, obj, pretty ? "\n " : null);
+ toJsonArray(buf, obj, pretty ? "\n " : null, _([]));
return buf.join('');
};
@@ -25,7 +25,14 @@ function fromJson(json) {
angular['toJson'] = toJson;
angular['fromJson'] = fromJson;
-function toJsonArray(buf, obj, pretty){
+function toJsonArray(buf, obj, pretty, stack){
+ if (typeof obj == "object") {
+ if (stack.include(obj)) {
+ buf.push("RECURSION");
+ return;
+ }
+ stack.push(obj);
+ }
var type = typeof obj;
if (obj === null) {
buf.push("null");
@@ -52,7 +59,7 @@ function toJsonArray(buf, obj, pretty){
if (typeof item == 'function' || typeof item == 'undefined') {
buf.push("null");
} else {
- toJsonArray(buf, item, pretty);
+ toJsonArray(buf, item, pretty, stack);
}
sep = true;
}
@@ -82,7 +89,7 @@ function toJsonArray(buf, obj, pretty){
}
buf.push(angular['String']['quote'](key));
buf.push(":");
- toJsonArray(buf, value, childPretty);
+ toJsonArray(buf, value, childPretty, stack);
comma = true;
}
} catch (e) {
@@ -91,4 +98,7 @@ function toJsonArray(buf, obj, pretty){
buf.push("}");
}
}
+ if (typeof obj == "object") {
+ stack.pop();
+ }
};
diff --git a/src/Users.js b/src/Users.js
index 47da4f73..79ed3129 100644
--- a/src/Users.js
+++ b/src/Users.js
@@ -7,7 +7,7 @@ Users.prototype = {
'fetchCurrentUser':function(callback) {
var self = this;
this.server.request("GET", "/account.json", {}, function(code, response){
- self.current = response.user;
+ self['current'] = response['user'];
callback(response.user);
});
},
@@ -15,7 +15,7 @@ Users.prototype = {
'logout': function(callback) {
var self = this;
this.controlBar.logout(function(){
- delete self.current;
+ delete self['current'];
(callback||noop)();
});
},
diff --git a/src/Widgets.js b/src/Widgets.js
index f93f2476..a012adf3 100644
--- a/src/Widgets.js
+++ b/src/Widgets.js
@@ -9,7 +9,6 @@ function WidgetFactory(serverUrl, database) {
alert("ERROR: swfobject not loaded!");
};
}
- this.onChangeListener = function(){};
};
WidgetFactory.prototype = {
@@ -43,12 +42,12 @@ WidgetFactory.prototype = {
throw 'Unknown type: ' + type;
}
input.data('controller', controller);
- var binder = scope.get('$binder');
+ var updateView = scope.get('$updateView');
var action = function() {
if (controller.updateModel(scope)) {
var action = jQuery(controller.view).attr('ng-action') || "";
if (scope.evalWidget(controller, action)) {
- binder.updateView(scope);
+ updateView(scope);
}
}
return bubbleEvent;
@@ -74,12 +73,6 @@ WidgetFactory.prototype = {
var cntl = new FileController(view, fileInput[0].name, swfNode, this.serverUrl + "/data/" + this.database);
jQuery(swfNode).data('controller', cntl);
return cntl;
- },
-
- createTextWidget: function(textInput) {
- var controller = new TextController(textInput);
- controller.onChange(this.onChangeListener);
- return controller;
}
};
/////////////////////
--
cgit v1.2.3
From c7719c24121b500f0bc2ac7c652d8ec0de418a37 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Sun, 24 Jan 2010 12:10:26 -0800
Subject: fix initialization
---
src/Angular.js | 3 +--
src/Binder.js | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)
(limited to 'src')
diff --git a/src/Angular.js b/src/Angular.js
index 51fca458..d3eef9d9 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -231,7 +231,6 @@ UrlWatcher.prototype = {
/////////////////////////////////////////////////
function configureJQueryPlugins() {
- log('Angular.configureJQueryPlugins()');
var fn = jQuery['fn'];
fn['scope'] = function() {
var element = this;
@@ -334,7 +333,7 @@ function wireAngular(element, config) {
config['location']['listen'](_(binder.onUrlChange).bind(binder));
binder.parseAnchor();
binder.executeInit();
- scope.updateView();
+ binder.updateView();
return self;
},
'element':element[0],
diff --git a/src/Binder.js b/src/Binder.js
index 3fc45a20..48a4f611 100644
--- a/src/Binder.js
+++ b/src/Binder.js
@@ -70,7 +70,7 @@ Binder.prototype = {
},
updateAnchor: function() {
- var url = this.location.get();
+ var url = this.location.get() || "";
var anchorIndex = url.indexOf('#');
if (anchorIndex > -1)
url = url.substring(0, anchorIndex);
--
cgit v1.2.3
From efad9ec5be8da442af5fb3dffc08510f7a71e10f Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Sun, 24 Jan 2010 17:10:58 -0800
Subject: changes to make it closure compiler compatible
---
src/Angular.js | 20 ++++++-----
src/Binder.js | 15 ++++----
src/ControlBar.js | 2 +-
src/DataStore.js | 104 ++++++++++++++++++++++++++----------------------------
src/Model.js | 12 +++----
src/Parser.js | 3 +-
src/Scope.js | 12 ++++---
src/Server.js | 4 +--
8 files changed, 87 insertions(+), 85 deletions(-)
(limited to 'src')
diff --git a/src/Angular.js b/src/Angular.js
index d3eef9d9..cadef4d0 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -20,11 +20,9 @@ if (typeof Node == 'undefined') {
function noop() {}
if (!window['console']) window['console']={'log':noop, 'error':noop};
-var consoleNode,
+var consoleNode, jQuery, msie,
foreach = _.each,
extend = _.extend,
- jQuery = window['jQuery'],
- msie = jQuery['browser']['msie'],
angular = window['angular'] || (window['angular'] = {}),
angularValidator = angular['validator'] || (angular['validator'] = {}),
angularFilter = angular['filter'] || (angular['filter'] = {}),
@@ -212,7 +210,6 @@ UrlWatcher.prototype = {
self.setTimeout(pull, self.delay);
};
pull();
- return this;
},
set: function(url) {
@@ -271,19 +268,20 @@ function exposeMethods(obj, methods){
function wireAngular(element, config) {
var widgetFactory = new WidgetFactory(config['server'], config['database']);
- var binder = new Binder(element[0], widgetFactory, config['location'], config);
+ var binder = new Binder(element[0], widgetFactory, datastore, config['location'], config);
var controlBar = new ControlBar(element.find('body'), config.server);
var onUpdate = function(){binder.updateView();};
- var server = config.database=="$MEMORY" ?
+ var server = config['database'] =="$MEMORY" ?
new FrameServer(this.window) :
- new Server(config.server, jQuery.getScript);
+ new Server(config['server'], jQuery['getScript']);
server = new VisualServer(server, new Status(jQuery(element.body)), onUpdate);
var users = new Users(server, controlBar);
- var databasePath = '/data/' + config.database;
+ var databasePath = '/data/' + config['database'];
var post = function(request, callback){
server.request("POST", databasePath, request, callback);
};
var datastore = new DataStore(post, users, binder.anchor);
+ binder.datastore = datastore;
binder.updateListeners.push(function(){datastore.flush();});
var scope = new Scope({
'$anchor' : binder.anchor,
@@ -343,10 +341,14 @@ function wireAngular(element, config) {
}
angular['startUrlWatcher'] = function(){
- return new UrlWatcher(window['location']).watch();
+ var watcher = new UrlWatcher(window['location']);
+ watcher.watch();
+ return exposeMethods(watcher, {'listen':watcher.listen, 'set':watcher.set, 'get':watcher.get});
};
angular['compile'] = function(element, config) {
+ jQuery = window['jQuery'];
+ msie = jQuery['browser']['msie'];
config = _({
'server': "",
'location': {'get':noop, 'set':noop, 'listen':noop}
diff --git a/src/Binder.js b/src/Binder.js
index 48a4f611..e516ec32 100644
--- a/src/Binder.js
+++ b/src/Binder.js
@@ -1,6 +1,7 @@
-function Binder(doc, widgetFactory, location, config) {
+function Binder(doc, widgetFactory, datastore, location, config) {
this.doc = doc;
this.location = location;
+ this.datastore = datastore;
this.anchor = {};
this.widgetFactory = widgetFactory;
this.config = config || {};
@@ -49,7 +50,7 @@ Binder.prototype = {
},
parseAnchor: function() {
- var self = this, url = this.location.get() || "";
+ var self = this, url = this.location['get']() || "";
var anchorIndex = url.indexOf('#');
if (anchorIndex < 0) return;
@@ -70,7 +71,7 @@ Binder.prototype = {
},
updateAnchor: function() {
- var url = this.location.get() || "";
+ var url = this.location['get']() || "";
var anchorIndex = url.indexOf('#');
if (anchorIndex > -1)
url = url.substring(0, anchorIndex);
@@ -87,7 +88,7 @@ Binder.prototype = {
sep = '&';
}
}
- this.location.set(url);
+ this.location['set'](url);
return url;
},
@@ -123,12 +124,14 @@ Binder.prototype = {
},
entity: function (scope) {
+ var self = this;
this.docFindWithSelf("[ng-entity]").attr("ng-watch", function() {
try {
var jNode = jQuery(this);
- var decl = scope.entity(jNode.attr("ng-entity"));
+ var decl = scope.entity(jNode.attr("ng-entity"), self.datastore);
return decl + (jNode.attr('ng-watch') || "");
} catch (e) {
+ log(e);
alert(e);
}
});
@@ -136,7 +139,7 @@ Binder.prototype = {
compile: function() {
var jNode = jQuery(this.doc);
- if (this.config.autoSubmit) {
+ if (this.config['autoSubmit']) {
var submits = this.docFindWithSelf(":submit").not("[ng-action]");
submits.attr("ng-action", "$save()");
submits.not(":disabled").not("ng-bind-attr").attr("ng-bind-attr", '{disabled:"{{$invalidWidgets}}"}');
diff --git a/src/ControlBar.js b/src/ControlBar.js
index 53c87199..a50b8854 100644
--- a/src/ControlBar.js
+++ b/src/ControlBar.js
@@ -55,7 +55,7 @@ ControlBar.prototype = {
resizable: false, modal:true,
title: 'Authentication: <angular/>'
});
- callbacks["_iframe_notify_" + id] = function() {
+ angularCallbacks["_iframe_notify_" + id] = function() {
loginView.dialog("destroy");
loginView.remove();
foreach(self.callbacks, function(callback){
diff --git a/src/DataStore.js b/src/DataStore.js
index 7952096f..789b8f71 100644
--- a/src/DataStore.js
+++ b/src/DataStore.js
@@ -1,7 +1,8 @@
function DataStore(post, users, anchor) {
this.post = post;
this.users = users;
- this._cache = {$collections:[]};
+ this._cache_collections = [];
+ this._cache = {'$collections':this._cache_collections};
this.anchor = anchor;
this.bulkRequest = [];
};
@@ -15,10 +16,10 @@ DataStore.NullEntity = extend(function(){}, {
DataStore.prototype = {
cache: function(document) {
- if (! document instanceof Model) {
+ if (! document.datastore === this) {
throw "Parameter must be an instance of Entity! " + toJson(document);
}
- var key = document.$entity + '/' + document.$id;
+ var key = document['$entity'] + '/' + document['$id'];
var cachedDocument = this._cache[key];
if (cachedDocument) {
Model.copyDirectFields(document, cachedDocument);
@@ -32,10 +33,10 @@ DataStore.prototype = {
load: function(instance, id, callback, failure) {
if (id && id !== '*') {
var self = this;
- this._jsonRequest(["GET", instance.$entity + "/" + id], function(response) {
- instance.$loadFrom(response);
- instance.$migrate();
- var clone = instance.$$entity(instance);
+ this._jsonRequest(["GET", instance['$entity'] + "/" + id], function(response) {
+ instance['$loadFrom'](response);
+ instance['$migrate']();
+ var clone = instance['$$entity'](instance);
self.cache(clone);
(callback||noop)(instance);
}, failure);
@@ -61,8 +62,8 @@ DataStore.prototype = {
loadOrCreate: function(instance, id, callback) {
var self=this;
return this.load(instance, id, callback, function(response){
- if (response.$status_code == 404) {
- instance.$id = id;
+ if (response['$status_code'] == 404) {
+ instance['$id'] = id;
(callback||noop)(instance);
} else {
throw response;
@@ -73,15 +74,15 @@ DataStore.prototype = {
loadAll: function(entity, callback) {
var self = this;
var list = [];
- list.$$accept = function(doc){
- return doc.$entity == entity.title;
+ list['$$accept'] = function(doc){
+ return doc['$entity'] == entity['title'];
};
- this._cache.$collections.push(list);
- this._jsonRequest(["GET", entity.title], function(response) {
+ this._cache_collections.push(list);
+ this._jsonRequest(["GET", entity['title']], function(response) {
var rows = response;
for ( var i = 0; i < rows.length; i++) {
var document = entity();
- document.$loadFrom(rows[i]);
+ document['$loadFrom'](rows[i]);
list.push(self.cache(document));
}
(callback||noop)(list);
@@ -92,17 +93,17 @@ DataStore.prototype = {
save: function(document, callback) {
var self = this;
var data = {};
- document.$saveTo(data);
+ document['$saveTo'](data);
this._jsonRequest(["POST", "", data], function(response) {
- document.$loadFrom(response);
+ document['$loadFrom'](response);
var cachedDoc = self.cache(document);
- _.each(self._cache.$collections, function(collection){
- if (collection.$$accept(document)) {
- angular['Array']['includeIf'](collection, cachedDoc, true);
+ _.each(self._cache_collections, function(collection){
+ if (collection['$$accept'](document)) {
+ angularArray['includeIf'](collection, cachedDoc, true);
}
});
- if (document.$$anchor) {
- self.anchor[document.$$anchor] = document.$id;
+ if (document['$$anchor']) {
+ self.anchor[document['$$anchor']] = document['$id'];
}
if (callback)
callback(document);
@@ -112,13 +113,13 @@ DataStore.prototype = {
remove: function(document, callback) {
var self = this;
var data = {};
- document.$saveTo(data);
+ document['$saveTo'](data);
this._jsonRequest(["DELETE", "", data], function(response) {
- delete self._cache[document.$entity + '/' + document.$id];
- _.each(self._cache.$collections, function(collection){
+ delete self._cache[document['$entity'] + '/' + document['$id']];
+ _.each(self._cache_collections, function(collection){
for ( var i = 0; i < collection.length; i++) {
var item = collection[i];
- if (item.$id == document.$id) {
+ if (item['$id'] == document['$id']) {
collection.splice(i, 1);
}
}
@@ -128,8 +129,8 @@ DataStore.prototype = {
},
_jsonRequest: function(request, callback, failure) {
- request.$$callback = callback;
- request.$$failure = failure||function(response){
+ request['$$callback'] = callback;
+ request['$$failure'] = failure||function(response){
throw response;
};
this.bulkRequest.push(request);
@@ -143,25 +144,25 @@ DataStore.prototype = {
log('REQUEST:', bulkRequest);
function callback(code, bulkResponse){
log('RESPONSE[' + code + ']: ', bulkResponse);
- if(bulkResponse.$status_code == 401) {
- self.users.login(function(){
+ if(bulkResponse['$status_code'] == 401) {
+ self.users['login'](function(){
self.post(bulkRequest, callback);
});
- } else if(bulkResponse.$status_code) {
+ } else if(bulkResponse['$status_code']) {
alert(toJson(bulkResponse));
} else {
for ( var i = 0; i < bulkResponse.length; i++) {
var response = bulkResponse[i];
var request = bulkRequest[i];
- var responseCode = response.$status_code;
+ var responseCode = response['$status_code'];
if(responseCode) {
if(responseCode == 403) {
- self.users.notAuthorized();
+ self.users['notAuthorized']();
} else {
- request.$$failure(response);
+ request['$$failure'](response);
}
} else {
- request.$$callback(response);
+ request['$$callback'](response);
}
}
}
@@ -178,9 +179,9 @@ DataStore.prototype = {
}
for(var key in scope) {
var item = scope[key];
- if (item && item.$save == Model.prototype.$save) {
+ if (item && item['$save'] == Model.prototype['$save']) {
saveCounter++;
- item.$save(onSaveDone);
+ item['$save'](onSaveDone);
}
}
onSaveDone();
@@ -189,19 +190,18 @@ DataStore.prototype = {
query: function(type, query, arg, callback){
var self = this;
var queryList = [];
- queryList.$$accept = function(doc){
+ queryList['$$accept'] = function(doc){
return false;
};
- this._cache.$collections.push(queryList);
- var request = type.title + '/' + query + '=' + arg;
+ this._cache_collections.push(queryList);
+ var request = type['title'] + '/' + query + '=' + arg;
this._jsonRequest(["GET", request], function(response){
var list = response;
- for(var i = 0; i < list.length; i++) {
- var document = new type().$loadFrom(list[i]);
+ foreach(list, function(item){
+ var document = type()['$loadFrom'](item);
queryList.push(self.cache(document));
- }
- if (callback)
- callback(queryList);
+ });
+ (callback||noop)(queryList);
});
return queryList;
},
@@ -210,11 +210,11 @@ DataStore.prototype = {
var entities = [];
var self = this;
this._jsonRequest(["GET", "$entities"], function(response) {
- for (var entityName in response) {
+ foreach(response, function(value, entityName){
entities.push(self.entity(entityName));
- }
+ });
entities.sort(function(a,b){return a.title > b.title ? 1 : -1;});
- if (callback) callback(entities);
+ (callback||noop)(entities);
});
return entities;
},
@@ -223,9 +223,7 @@ DataStore.prototype = {
var counts = {};
var self = this;
self.post([["GET", "$users"]], function(code, response){
- foreach(response[0], function(value, key){
- counts[key] = value;
- });
+ extend(counts, response[0]);
});
return counts;
},
@@ -234,9 +232,7 @@ DataStore.prototype = {
var ids = {};
var self = this;
self.post([["GET", "$users/" + user]], function(code, response){
- foreach(response[0], function(value, key){
- ids[key] = value;
- });
+ extend(ids, response[0]);
});
return ids;
},
@@ -252,7 +248,7 @@ DataStore.prototype = {
// entity.name does not work as name seems to be reserved for functions
'title': name,
'$$factory': true,
- 'datastore': this,
+ datastore: this, //private, obfuscate
'defaults': defaults || {},
'load': function(id, callback){
return self.load(entity(), id, callback);
diff --git a/src/Model.js b/src/Model.js
index 4a3a1806..b09efd0e 100644
--- a/src/Model.js
+++ b/src/Model.js
@@ -3,9 +3,9 @@
function Model(entity, initial) {
this['$$entity'] = entity;
- this.$loadFrom(initial||{});
- this.$entity = entity['title'];
- this.$migrate();
+ this['$loadFrom'](initial||{});
+ this['$entity'] = entity['title'];
+ this['$migrate']();
};
Model.copyDirectFields = function(src, dst) {
@@ -25,9 +25,9 @@ Model.copyDirectFields = function(src, dst) {
}
};
-Model.prototype = {
+extend(Model.prototype, {
'$migrate': function() {
- merge(this['$$entity'].defaults, this);
+ merge(this['$$entity']['defaults'], this);
return this;
},
@@ -62,4 +62,4 @@ Model.prototype = {
Model.copyDirectFields(this, other);
return this;
}
-};
\ No newline at end of file
+});
\ No newline at end of file
diff --git a/src/Parser.js b/src/Parser.js
index 840f5541..d33ae3db 100644
--- a/src/Parser.js
+++ b/src/Parser.js
@@ -691,8 +691,7 @@ Parser.prototype = {
defaults = this.primary()(null);
}
return function(self) {
- var datastore = self.scope.get('$datastore');
- var Entity = datastore.entity(entity, defaults);
+ var Entity = self.datastore.entity(entity, defaults);
self.scope.set(entity, Entity);
if (instance) {
var document = Entity();
diff --git a/src/Scope.js b/src/Scope.js
index dcc50007..3b1f3930 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -6,9 +6,9 @@ function Scope(initialState, name) {
var State = function(){};
State.prototype = initialState;
this.state = new State();
- this.state.$parent = initialState;
+ this.state['$parent'] = initialState;
if (name == "ROOT") {
- this.state.$root = this.state;
+ this.state['$root'] = this.state;
}
};
@@ -37,7 +37,7 @@ Scope.getter = function(instance, path) {
}
}
}
- if (typeof instance === 'function' && !instance.$$factory) {
+ if (typeof instance === 'function' && !instance['$$factory']) {
return bind(lastInstance, instance);
}
return instance;
@@ -69,10 +69,12 @@ Scope.prototype = {
},
get: function(path) {
+// log('SCOPE.get', path, Scope.getter(this.state, path));
return Scope.getter(this.state, path);
},
set: function(path, value) {
+// log('SCOPE.set', path, value);
var element = path.split('.');
var instance = this.state;
for ( var i = 0; element.length > 1; i++) {
@@ -145,9 +147,9 @@ Scope.prototype = {
return expression(self)(self, value);
},
- entity: function(entityDeclaration) {
+ entity: function(entityDeclaration, datastore) {
var expression = new Parser(entityDeclaration).entityDeclaration();
- return expression({scope:this});
+ return expression({scope:this, datastore:datastore});
},
markInvalid: function(widget) {
diff --git a/src/Server.js b/src/Server.js
index f351e84c..2932c09b 100644
--- a/src/Server.js
+++ b/src/Server.js
@@ -14,10 +14,10 @@ Server.prototype = {
request: function(method, url, request, callback) {
var requestId = this.uuid + (this.nextId++);
angularCallbacks[requestId] = function(response) {
- delete angular[requestId];
+ delete angularCallbacks[requestId];
callback(200, response);
};
- var payload = {u:url, m:method, p:request};
+ var payload = {'u':url, 'm':method, 'p':request};
payload = this.base64url(toJson(payload));
var totalPockets = Math.ceil(payload.length / this.maxSize);
var baseUrl = this.url + "/$/" + requestId + "/" + totalPockets + "/";
--
cgit v1.2.3
From a5c446441fee005975a82885771e8d931e7a4e7a Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Sun, 24 Jan 2010 19:12:01 -0800
Subject: fix closure compiler incompatibilities
---
src/Angular.js | 4 ++--
src/ControlBar.js | 23 +++++++++++------------
src/Users.js | 6 +++---
src/Widgets.js | 48 +++++++++++++++++++++++++-----------------------
4 files changed, 41 insertions(+), 40 deletions(-)
(limited to 'src')
diff --git a/src/Angular.js b/src/Angular.js
index cadef4d0..bfbe8ee9 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -269,10 +269,10 @@ function exposeMethods(obj, methods){
function wireAngular(element, config) {
var widgetFactory = new WidgetFactory(config['server'], config['database']);
var binder = new Binder(element[0], widgetFactory, datastore, config['location'], config);
- var controlBar = new ControlBar(element.find('body'), config.server);
+ var controlBar = new ControlBar(element.find('body'), config['server']);
var onUpdate = function(){binder.updateView();};
var server = config['database'] =="$MEMORY" ?
- new FrameServer(this.window) :
+ new FrameServer(window) :
new Server(config['server'], jQuery['getScript']);
server = new VisualServer(server, new Status(jQuery(element.body)), onUpdate);
var users = new Users(server, controlBar);
diff --git a/src/ControlBar.js b/src/ControlBar.js
index a50b8854..6fe5b42d 100644
--- a/src/ControlBar.js
+++ b/src/ControlBar.js
@@ -1,7 +1,7 @@
function ControlBar(document, serverUrl) {
- this.document = document;
+ this._document = document;
this.serverUrl = serverUrl;
- this.window = window;
+ this._window = window;
this.callbacks = [];
};
@@ -39,25 +39,24 @@ ControlBar.prototype = {
},
urlWithoutAnchor: function (path) {
- return this.window.location.href.split("#")[0];
+ return this._window['location']['href'].split("#")[0];
},
doTemplate: function (path) {
var self = this;
var id = new Date().getTime();
- var url = this.urlWithoutAnchor();
- url += "#$iframe_notify=" + id;
+ var url = this.urlWithoutAnchor() + "#$iframe_notify=" + id;
var iframeHeight = 330;
var loginView = jQuery('');
- this.document.append(loginView);
- loginView.dialog({
- height:iframeHeight + 33, width:500,
- resizable: false, modal:true,
- title: 'Authentication: <angular/>'
+ this._document.append(loginView);
+ loginView['dialog']({
+ 'height':iframeHeight + 33, 'width':500,
+ 'resizable': false, 'modal':true,
+ 'title': 'Authentication: <angular/>'
});
angularCallbacks["_iframe_notify_" + id] = function() {
- loginView.dialog("destroy");
- loginView.remove();
+ loginView['dialog']("destroy");
+ loginView['remove']();
foreach(self.callbacks, function(callback){
callback();
});
diff --git a/src/Users.js b/src/Users.js
index 79ed3129..f81507f4 100644
--- a/src/Users.js
+++ b/src/Users.js
@@ -3,7 +3,7 @@ function Users(server, controlBar) {
this.controlBar = controlBar;
};
-Users.prototype = {
+extend(Users.prototype, {
'fetchCurrentUser':function(callback) {
var self = this;
this.server.request("GET", "/account.json", {}, function(code, response){
@@ -23,7 +23,7 @@ Users.prototype = {
'login': function(callback) {
var self = this;
this.controlBar.login(function(){
- self.fetchCurrentUser(function(){
+ self['fetchCurrentUser'](function(){
(callback||noop)();
});
});
@@ -32,4 +32,4 @@ Users.prototype = {
'notAuthorized': function(){
this.controlBar.notAuthorized();
}
-};
+});
diff --git a/src/Widgets.js b/src/Widgets.js
index a012adf3..cf8c5d99 100644
--- a/src/Widgets.js
+++ b/src/Widgets.js
@@ -2,8 +2,8 @@ function WidgetFactory(serverUrl, database) {
this.nextUploadId = 0;
this.serverUrl = serverUrl;
this.database = database;
- if (window.swfobject) {
- this.createSWF = swfobject.createSWF;
+ if (window['swfobject']) {
+ this.createSWF = window['swfobject']['createSWF'];
} else {
this.createSWF = function(){
alert("ERROR: swfobject not loaded!");
@@ -62,12 +62,12 @@ WidgetFactory.prototype = {
var view = FileController.template(uploadId);
fileInput.after(view);
var att = {
- data:this.serverUrl + "/admin/ServerAPI.swf",
- width:"95", height:"20", align:"top",
- wmode:"transparent"};
+ 'data':this.serverUrl + "/admin/ServerAPI.swf",
+ 'width':"95", 'height':"20", 'align':"top",
+ 'wmode':"transparent"};
var par = {
- flashvars:"uploadWidgetId=" + uploadId,
- allowScriptAccess:"always"};
+ 'flashvars':"uploadWidgetId=" + uploadId,
+ 'allowScriptAccess':"always"};
var swfNode = this.createSWF(att, par, uploadId);
fileInput.remove();
var cntl = new FileController(view, fileInput[0].name, swfNode, this.serverUrl + "/data/" + this.database);
@@ -88,10 +88,12 @@ function FileController(view, scopeName, uploader, databaseUrl) {
this.lastValue = undefined;
};
-FileController.dispatchEvent = function(id, event, args) {
+angularCallbacks['flashEvent'] = function(id, event, args) {
var object = document.getElementById(id);
- var controller = jQuery(object).data("controller");
- FileController.prototype['_on_' + event].apply(controller, args);
+ var jobject = jQuery(object);
+ var controller = jobject.data("controller");
+ FileController.prototype[event].apply(controller, args);
+ jobject.scope().get('$updateView')();
};
FileController.template = function(id) {
@@ -103,23 +105,23 @@ FileController.template = function(id) {
'');
};
-FileController.prototype = {
- '_on_cancel': noop,
- '_on_complete': noop,
- '_on_httpStatus': function(status) {
+extend(FileController.prototype, {
+ 'cancel': noop,
+ 'complete': noop,
+ 'httpStatus': function(status) {
alert("httpStatus:" + this.scopeName + " status:" + status);
},
- '_on_ioError': function() {
+ 'ioError': function() {
alert("ioError:" + this.scopeName);
},
- '_on_open': function() {
+ 'open': function() {
alert("open:" + this.scopeName);
},
- '_on_progress':noop,
- '_on_securityError': function() {
+ 'progress':noop,
+ 'securityError': function() {
alert("securityError:" + this.scopeName);
},
- '_on_uploadCompleteData': function(data) {
+ 'uploadCompleteData': function(data) {
var value = fromJson(data);
value.url = this.attachmentsPath + '/' + value.id + '/' + value.text;
this.view.find("input").attr('checked', true);
@@ -129,7 +131,7 @@ FileController.prototype = {
this.value = null;
scope.get('$binder').updateView();
},
- '_on_select': function(name, size, type) {
+ 'select': function(name, size, type) {
this.name = name;
this.view.find("a").text(name).attr('href', name);
this.view.find("span").text(angular['filter']['bytes'](size));
@@ -161,10 +163,10 @@ FileController.prototype = {
upload: function() {
if (this.name) {
- this.uploader.uploadFile(this.attachmentsPath);
+ this.uploader['uploadFile'](this.attachmentsPath);
}
}
-};
+});
///////////////////////
// NullController
@@ -532,7 +534,7 @@ BindAttrUpdater.prototype = {
}
var attrValue = attrValues.length ? attrValues.join('') : null;
if(isImage && attrName == 'src' && !attrValue)
- attrValue = scope.get('config.server') + '/images/blank.gif';
+ attrValue = scope.get('$config.blankImage');
jNode.attr(attrName, attrValue);
}
}
--
cgit v1.2.3
From 0f42fa2930f5827ac9f1eac2ce09ea3bf9533563 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Sun, 24 Jan 2010 19:33:04 -0800
Subject: fix closure compiler issues
---
src/Scope.js | 2 +-
src/Server.js | 7 +++----
src/Widgets.js | 5 ++---
3 files changed, 6 insertions(+), 8 deletions(-)
(limited to 'src')
diff --git a/src/Scope.js b/src/Scope.js
index 3b1f3930..9be6bc3f 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -153,7 +153,7 @@ Scope.prototype = {
},
markInvalid: function(widget) {
- this.state.$invalidWidgets.push(widget);
+ this.state['$invalidWidgets'].push(widget);
},
watch: function(declaration) {
diff --git a/src/Server.js b/src/Server.js
index 2932c09b..5c4ec3c6 100644
--- a/src/Server.js
+++ b/src/Server.js
@@ -13,14 +13,13 @@ Server.prototype = {
request: function(method, url, request, callback) {
var requestId = this.uuid + (this.nextId++);
+ var payload = this.base64url(toJson({'u':url, 'm':method, 'p':request}));
+ var totalPockets = Math.ceil(payload.length / this.maxSize);
+ var baseUrl = this.url + "/$/" + requestId + "/" + totalPockets + "/";
angularCallbacks[requestId] = function(response) {
delete angularCallbacks[requestId];
callback(200, response);
};
- var payload = {'u':url, 'm':method, 'p':request};
- payload = this.base64url(toJson(payload));
- var totalPockets = Math.ceil(payload.length / this.maxSize);
- var baseUrl = this.url + "/$/" + requestId + "/" + totalPockets + "/";
for ( var pocketNo = 0; pocketNo < totalPockets; pocketNo++) {
var pocket = payload.substr(pocketNo * this.maxSize, this.maxSize);
this.getScript(baseUrl + (pocketNo+1) + "?h=" + pocket, noop);
diff --git a/src/Widgets.js b/src/Widgets.js
index cf8c5d99..d85c0ddc 100644
--- a/src/Widgets.js
+++ b/src/Widgets.js
@@ -93,7 +93,7 @@ angularCallbacks['flashEvent'] = function(id, event, args) {
var jobject = jQuery(object);
var controller = jobject.data("controller");
FileController.prototype[event].apply(controller, args);
- jobject.scope().get('$updateView')();
+ _.defer(jobject.scope().get('$updateView'));
};
FileController.template = function(id) {
@@ -102,7 +102,7 @@ FileController.template = function(id) {
'' +
'' +
'' +
- '');
+ '');
};
extend(FileController.prototype, {
@@ -129,7 +129,6 @@ extend(FileController.prototype, {
this.value = value;
this.updateModel(scope);
this.value = null;
- scope.get('$binder').updateView();
},
'select': function(name, size, type) {
this.name = name;
--
cgit v1.2.3
From 473e57e22532f9b85fc9dcc1bcc53e12a10154c2 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Sun, 24 Jan 2010 20:44:17 -0800
Subject: bindRootId configuration option
---
src/Filters.js | 51 ++++++++++++++++++++++++++-------------------------
src/Parser.js | 2 +-
src/Scope.js | 1 +
3 files changed, 28 insertions(+), 26 deletions(-)
(limited to 'src')
diff --git a/src/Filters.js b/src/Filters.js
index a0bedaaf..77fa5ec7 100644
--- a/src/Filters.js
+++ b/src/Filters.js
@@ -184,25 +184,25 @@ foreach({
function(type, data, width, height) {
data = data || {};
var chart = {
- cht:type,
- chco:angularFilterGoogleChartApi.collect(data, 'color'),
- chtt:angularFilterGoogleChartApi.title(data),
- chdl:angularFilterGoogleChartApi.collect(data, 'label'),
- chd:angularFilterGoogleChartApi.values(data),
- chf:'bg,s,FFFFFF00'
+ 'cht':type,
+ 'chco':angularFilterGoogleChartApi['collect'](data, 'color'),
+ 'chtt':angularFilterGoogleChartApi['title'](data),
+ 'chdl':angularFilterGoogleChartApi['collect'](data, 'label'),
+ 'chd':angularFilterGoogleChartApi['values'](data),
+ 'chf':'bg,s,FFFFFF00'
};
- if (_.isArray(data.xLabels)) {
- chart.chxt='x';
- chart.chxl='0:|' + data.xLabels.join('|');
+ if (_.isArray(data['xLabels'])) {
+ chart['chxt']='x';
+ chart['chxl']='0:|' + data.xLabels.join('|');
}
return angularFilterGoogleChartApi['encode'](chart, width, height);
},
{
'values': function(data){
var seriesValues = [];
- foreach(data.series||[], function(serie){
+ foreach(data['series']||[], function(serie){
var values = [];
- foreach(serie.values||[], function(value){
+ foreach(serie['values']||[], function(value){
values.push(value);
});
seriesValues.push(values.join(','));
@@ -213,7 +213,7 @@ foreach({
'title': function(data){
var titles = [];
- var title = data.title || [];
+ var title = data['title'] || [];
foreach(_.isArray(title)?title:[title], function(text){
titles.push(encodeURIComponent(text));
});
@@ -223,7 +223,7 @@ foreach({
'collect': function(data, key){
var outterValues = [];
var count = 0;
- foreach(data.series||[], function(serie){
+ foreach(data['series']||[], function(serie){
var innerValues = [];
var value = serie[key] || [];
foreach(_.isArray(value)?value:[value], function(color){
@@ -240,7 +240,7 @@ foreach({
height = height || width;
var url = "http://chart.apis.google.com/chart?";
var urlParam = [];
- params.chs = width + "x" + height;
+ params['chs'] = width + "x" + height;
foreach(params, function(value, key){
if (value) {
urlParam.push(key + "=" + value);
@@ -256,37 +256,38 @@ foreach({
'qrcode': function(value, width, height) {
- return angularFilterGoogleChartApi['encode']({cht:'qr', chl:encodeURIComponent(value)}, width, height);
+ return angularFilterGoogleChartApi['encode']({
+ 'cht':'qr', 'chl':encodeURIComponent(value)}, width, height);
},
'chart': {
- pie:function(data, width, height) {
+ 'pie':function(data, width, height) {
return angularFilterGoogleChartApi('p', data, width, height);
},
- pie3d:function(data, width, height) {
+ 'pie3d':function(data, width, height) {
return angularFilterGoogleChartApi('p3', data, width, height);
},
- pieConcentric:function(data, width, height) {
+ 'pieConcentric':function(data, width, height) {
return angularFilterGoogleChartApi('pc', data, width, height);
},
- barHorizontalStacked:function(data, width, height) {
+ 'barHorizontalStacked':function(data, width, height) {
return angularFilterGoogleChartApi('bhs', data, width, height);
},
- barHorizontalGrouped:function(data, width, height) {
+ 'barHorizontalGrouped':function(data, width, height) {
return angularFilterGoogleChartApi('bhg', data, width, height);
},
- barVerticalStacked:function(data, width, height) {
+ 'barVerticalStacked':function(data, width, height) {
return angularFilterGoogleChartApi('bvs', data, width, height);
},
- barVerticalGrouped:function(data, width, height) {
+ 'barVerticalGrouped':function(data, width, height) {
return angularFilterGoogleChartApi('bvg', data, width, height);
},
- line:function(data, width, height) {
+ 'line':function(data, width, height) {
return angularFilterGoogleChartApi('lc', data, width, height);
},
- sparkline:function(data, width, height) {
+ 'sparkline':function(data, width, height) {
return angularFilterGoogleChartApi('ls', data, width, height);
},
- scatter:function(data, width, height) {
+ 'scatter':function(data, width, height) {
return angularFilterGoogleChartApi('s', data, width, height);
}
},
diff --git a/src/Parser.js b/src/Parser.js
index d33ae3db..fe9671af 100644
--- a/src/Parser.js
+++ b/src/Parser.js
@@ -695,7 +695,7 @@ Parser.prototype = {
self.scope.set(entity, Entity);
if (instance) {
var document = Entity();
- document.$$anchor = instance;
+ document['$$anchor'] = instance;
self.scope.set(instance, document);
return "$anchor." + instance + ":{" +
instance + "=" + entity + ".load($anchor." + instance + ");" +
diff --git a/src/Scope.js b/src/Scope.js
index 9be6bc3f..7e477ec5 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -95,6 +95,7 @@ Scope.prototype = {
},
eval: function(expressionText, context) {
+ log('Scope.eval', expressionText);
var expression = Scope.expressionCache[expressionText];
if (!expression) {
var parser = new Parser(expressionText);
--
cgit v1.2.3
From a2540fd581f35e8f79240d827d2252da5798c3a2 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Mon, 25 Jan 2010 23:49:52 -0800
Subject: fixes to make it pass on IE
---
src/API.js | 2 ++
src/Angular.js | 3 ++-
2 files changed, 4 insertions(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/API.js b/src/API.js
index d795f4c3..ce690ad1 100644
--- a/src/API.js
+++ b/src/API.js
@@ -319,5 +319,7 @@ defineApi('Object', [angularGlobal, angularCollection, angularObject],
['keys', 'values']);
defineApi('String', [angularGlobal, angularString], []);
defineApi('Date', [angularGlobal, angularDate], []);
+//IE bug
+angular['Date']['toString'] = angularDate['toString'];
defineApi('Function', [angularGlobal, angularCollection, angularFunction],
['bind', 'bindAll', 'delay', 'defer', 'wrap', 'compose']);
diff --git a/src/Angular.js b/src/Angular.js
index bfbe8ee9..f06562da 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -20,7 +20,8 @@ if (typeof Node == 'undefined') {
function noop() {}
if (!window['console']) window['console']={'log':noop, 'error':noop};
-var consoleNode, jQuery, msie,
+var consoleNode, msie,
+ jQuery = window['jQuery'] || window['$'], // weirdness to make IE happy
foreach = _.each,
extend = _.extend,
angular = window['angular'] || (window['angular'] = {}),
--
cgit v1.2.3
From 88384854c209f87507c273218fea85009f3801d6 Mon Sep 17 00:00:00 2001
From: Adam Abrons
Date: Tue, 26 Jan 2010 11:27:50 -0800
Subject: add default rake task (compile and test), send database name to login
---
src/Angular.js | 2 +-
src/ControlBar.js | 5 +++--
2 files changed, 4 insertions(+), 3 deletions(-)
(limited to 'src')
diff --git a/src/Angular.js b/src/Angular.js
index f06562da..a055ce1d 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -270,7 +270,7 @@ function exposeMethods(obj, methods){
function wireAngular(element, config) {
var widgetFactory = new WidgetFactory(config['server'], config['database']);
var binder = new Binder(element[0], widgetFactory, datastore, config['location'], config);
- var controlBar = new ControlBar(element.find('body'), config['server']);
+ var controlBar = new ControlBar(element.find('body'), config['server'], config['database']);
var onUpdate = function(){binder.updateView();};
var server = config['database'] =="$MEMORY" ?
new FrameServer(window) :
diff --git a/src/ControlBar.js b/src/ControlBar.js
index 73be74db..685beeb2 100644
--- a/src/ControlBar.js
+++ b/src/ControlBar.js
@@ -1,6 +1,7 @@
-function ControlBar(document, serverUrl) {
+function ControlBar(document, serverUrl, database) {
this._document = document;
this.serverUrl = serverUrl;
+ this.database = database;
this._window = window;
this.callbacks = [];
};
@@ -26,7 +27,7 @@ ControlBar.prototype = {
login: function (loginSubmitFn) {
this.callbacks.push(loginSubmitFn);
if (this.callbacks.length == 1) {
- this.doTemplate("/user_session/new.mini?return_url=" + encodeURIComponent(this.urlWithoutAnchor()));
+ this.doTemplate("/user_session/new.mini?database="+encodeURIComponent(this.database)+"&return_url=" + encodeURIComponent(this.urlWithoutAnchor()));
}
},
--
cgit v1.2.3
From f5055c6530ffdb94436b52afe8c52ab6c2f2f14a Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Tue, 26 Jan 2010 15:59:46 -0800
Subject: remove uneeded log
---
src/Scope.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/Scope.js b/src/Scope.js
index 7e477ec5..b8fadfa0 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -95,7 +95,7 @@ Scope.prototype = {
},
eval: function(expressionText, context) {
- log('Scope.eval', expressionText);
+// log('Scope.eval', expressionText);
var expression = Scope.expressionCache[expressionText];
if (!expression) {
var parser = new Parser(expressionText);
--
cgit v1.2.3
From 3d99e0f6dee6569ca9471d419bda79aec95b9ebc Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Thu, 28 Jan 2010 20:44:34 -0800
Subject: work
---
src/Angular.js | 1 +
src/Formaters.js | 6 ++++++
src/Scope.js | 2 +-
3 files changed, 8 insertions(+), 1 deletion(-)
create mode 100644 src/Formaters.js
(limited to 'src')
diff --git a/src/Angular.js b/src/Angular.js
index bfbe8ee9..b208d0ec 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -26,6 +26,7 @@ var consoleNode, jQuery, msie,
angular = window['angular'] || (window['angular'] = {}),
angularValidator = angular['validator'] || (angular['validator'] = {}),
angularFilter = angular['filter'] || (angular['filter'] = {}),
+ angularFormater = angular['formater'] || (angular['formater'] = {}),
angularCallbacks = angular['callbacks'] || (angular['callbacks'] = {}),
angularAlert = angular['alert'] || (angular['alert'] = function(){
log(arguments); window.alert.apply(window, arguments);
diff --git a/src/Formaters.js b/src/Formaters.js
new file mode 100644
index 00000000..e623d6b8
--- /dev/null
+++ b/src/Formaters.js
@@ -0,0 +1,6 @@
+
+extend(angularFormater, {
+ 'noop':function(){
+
+ }
+});
diff --git a/src/Scope.js b/src/Scope.js
index 7e477ec5..b8fadfa0 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -95,7 +95,7 @@ Scope.prototype = {
},
eval: function(expressionText, context) {
- log('Scope.eval', expressionText);
+// log('Scope.eval', expressionText);
var expression = Scope.expressionCache[expressionText];
if (!expression) {
var parser = new Parser(expressionText);
--
cgit v1.2.3
From a9c182764b5feeb2466c4bb32f7572762f7fab6d Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Thu, 28 Jan 2010 22:10:49 -0800
Subject: added formatters
---
src/Angular.js | 3 ++-
src/Formaters.js | 6 ------
src/Formatters.js | 14 ++++++++++++++
src/Widgets.js | 37 +++++++++++++++++++++----------------
4 files changed, 37 insertions(+), 23 deletions(-)
delete mode 100644 src/Formaters.js
create mode 100644 src/Formatters.js
(limited to 'src')
diff --git a/src/Angular.js b/src/Angular.js
index ce25423c..3c88c6b7 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -24,10 +24,11 @@ var consoleNode, msie,
jQuery = window['jQuery'] || window['$'], // weirdness to make IE happy
foreach = _.each,
extend = _.extend,
+ identity = _.identity,
angular = window['angular'] || (window['angular'] = {}),
angularValidator = angular['validator'] || (angular['validator'] = {}),
angularFilter = angular['filter'] || (angular['filter'] = {}),
- angularFormater = angular['formater'] || (angular['formater'] = {}),
+ angularFormatter = angular['formatter'] || (angular['formatter'] = {}),
angularCallbacks = angular['callbacks'] || (angular['callbacks'] = {}),
angularAlert = angular['alert'] || (angular['alert'] = function(){
log(arguments); window.alert.apply(window, arguments);
diff --git a/src/Formaters.js b/src/Formaters.js
deleted file mode 100644
index e623d6b8..00000000
--- a/src/Formaters.js
+++ /dev/null
@@ -1,6 +0,0 @@
-
-extend(angularFormater, {
- 'noop':function(){
-
- }
-});
diff --git a/src/Formatters.js b/src/Formatters.js
new file mode 100644
index 00000000..74126feb
--- /dev/null
+++ b/src/Formatters.js
@@ -0,0 +1,14 @@
+function formater(format, parse) {return {'format':format, 'parse':parse};}
+function toString(obj) {return ""+obj;};
+extend(angularFormatter, {
+ 'noop':formater(identity, identity),
+ 'boolean':formater(toString, toBoolean),
+ 'number':formater(toString, function(obj){return 1*obj;}),
+
+ 'list':formater(
+ function(obj) { return obj ? obj.join(", ") : obj; },
+ function(value) {
+ return value ? _(_(value.split(',')).map(jQuery.trim)).select(_.identity) : value;
+ }
+ )
+});
diff --git a/src/Widgets.js b/src/Widgets.js
index d85c0ddc..d392d285 100644
--- a/src/Widgets.js
+++ b/src/Widgets.js
@@ -19,25 +19,26 @@ WidgetFactory.prototype = {
if (exp) exp = exp.split(':').pop();
var event = "change";
var bubbleEvent = true;
+ var formatter = angularFormatter[input.attr('ng-format')] || angularFormatter['noop'];
if (type == 'button' || type == 'submit' || type == 'reset' || type == 'image') {
- controller = new ButtonController(input[0], exp);
+ controller = new ButtonController(input[0], exp, formatter);
event = "click";
bubbleEvent = false;
} else if (type == 'text' || type == 'textarea' || type == 'hidden' || type == 'password') {
- controller = new TextController(input[0], exp);
+ controller = new TextController(input[0], exp, formatter);
event = "keyup change";
} else if (type == 'checkbox') {
- controller = new CheckboxController(input[0], exp);
+ controller = new CheckboxController(input[0], exp, formatter);
event = "click";
} else if (type == 'radio') {
- controller = new RadioController(input[0], exp);
+ controller = new RadioController(input[0], exp, formatter);
event="click";
} else if (type == 'select-one') {
- controller = new SelectController(input[0], exp);
+ controller = new SelectController(input[0], exp, formatter);
} else if (type == 'select-multiple') {
- controller = new MultiSelectController(input[0], exp);
+ controller = new MultiSelectController(input[0], exp, formatter);
} else if (type == 'file') {
- controller = this.createFileController(input, exp);
+ controller = this.createFileController(input, exp, formatter);
} else {
throw 'Unknown type: ' + type;
}
@@ -186,8 +187,9 @@ var ButtonController = NullController;
///////////////////////
// TextController
///////////////////////
-function TextController(view, exp) {
+function TextController(view, exp, formatter) {
this.view = view;
+ this.formatter = formatter;
this.exp = exp;
this.validator = view.getAttribute('ng-validate');
this.required = typeof view.attributes['ng-required'] != "undefined";
@@ -206,7 +208,7 @@ TextController.prototype = {
if (this.lastValue === value) {
return false;
} else {
- scope.setEval(this.exp, value);
+ scope.setEval(this.exp, this.formatter['parse'](value));
this.lastValue = value;
return true;
}
@@ -214,10 +216,10 @@ TextController.prototype = {
updateView: function(scope) {
var view = this.view;
- var value = scope.get(this.exp);
+ var value = this.formatter['format'](scope.get(this.exp));
if (typeof value === "undefined") {
value = this.initialValue;
- scope.setEval(this.exp, value);
+ scope.setEval(this.exp, this.formatter['parse'](value));
}
value = value ? value : '';
if (this.lastValue != value) {
@@ -248,21 +250,23 @@ TextController.prototype = {
///////////////////////
// CheckboxController
///////////////////////
-function CheckboxController(view, exp) {
+function CheckboxController(view, exp, formatter) {
this.view = view;
this.exp = exp;
this.lastValue = undefined;
+ this.formatter = formatter;
this.initialValue = view.checked ? view.value : "";
};
CheckboxController.prototype = {
- updateModel: function(scope) {
+ updateModel: function(scope) {
+ jstd.console.log("model");
var input = this.view;
var value = input.checked ? input.value : '';
if (this.lastValue === value) {
return false;
} else {
- scope.setEval(this.exp, value);
+ scope.setEval(this.exp, this.formatter['parse'](value));
this.lastValue = value;
return true;
}
@@ -273,9 +277,10 @@ CheckboxController.prototype = {
var value = scope.eval(this.exp);
if (typeof value === "undefined") {
value = this.initialValue;
- scope.setEval(this.exp, value);
+ scope.setEval(this.exp, this.formatter['parse'](value));
}
- input.checked = input.value == (''+value);
+ value = this.formatter['format'](value);
+ input.checked = input.value == value;
}
};
--
cgit v1.2.3
From 2880411713bf051b0d30b0a1f3531a34272f3b25 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Fri, 29 Jan 2010 10:15:15 -0800
Subject: added bootstrap, fixed formatter
---
src/Widgets.js | 25 +++++++++++-----------
src/angular-bootstrap.js | 55 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 68 insertions(+), 12 deletions(-)
create mode 100644 src/angular-bootstrap.js
(limited to 'src')
diff --git a/src/Widgets.js b/src/Widgets.js
index d392d285..69b444c0 100644
--- a/src/Widgets.js
+++ b/src/Widgets.js
@@ -195,7 +195,7 @@ function TextController(view, exp, formatter) {
this.required = typeof view.attributes['ng-required'] != "undefined";
this.lastErrorText = null;
this.lastValue = undefined;
- this.initialValue = view.value;
+ this.initialValue = this.formatter['parse'](view.value);
var widget = view.getAttribute('ng-widget');
if (widget === 'datepicker') {
jQuery(view).datepicker();
@@ -204,11 +204,11 @@ function TextController(view, exp, formatter) {
TextController.prototype = {
updateModel: function(scope) {
- var value = this.view.value;
+ var value = this.formatter['parse'](this.view.value);
if (this.lastValue === value) {
return false;
} else {
- scope.setEval(this.exp, this.formatter['parse'](value));
+ scope.setEval(this.exp, value);
this.lastValue = value;
return true;
}
@@ -216,16 +216,17 @@ TextController.prototype = {
updateView: function(scope) {
var view = this.view;
- var value = this.formatter['format'](scope.get(this.exp));
+ var value = scope.get(this.exp);
if (typeof value === "undefined") {
value = this.initialValue;
- scope.setEval(this.exp, this.formatter['parse'](value));
+ scope.setEval(this.exp, value);
}
value = value ? value : '';
- if (this.lastValue != value) {
- view.value = value;
+ if (!_(this.lastValue).isEqual(value)) {
+ view.value = this.formatter['format'](value);
this.lastValue = value;
}
+
var isValidationError = false;
view.removeAttribute('ng-error');
if (this.required) {
@@ -255,14 +256,15 @@ function CheckboxController(view, exp, formatter) {
this.exp = exp;
this.lastValue = undefined;
this.formatter = formatter;
- this.initialValue = view.checked ? view.value : "";
+ this.initialValue = this.formatter['parse'](view.checked ? view.value : "");
};
CheckboxController.prototype = {
updateModel: function(scope) {
- jstd.console.log("model");
var input = this.view;
var value = input.checked ? input.value : '';
+ value = this.formatter['parse'](value);
+ value = this.formatter['format'](value);
if (this.lastValue === value) {
return false;
} else {
@@ -277,10 +279,9 @@ CheckboxController.prototype = {
var value = scope.eval(this.exp);
if (typeof value === "undefined") {
value = this.initialValue;
- scope.setEval(this.exp, this.formatter['parse'](value));
+ scope.setEval(this.exp, value);
}
- value = this.formatter['format'](value);
- input.checked = input.value == value;
+ input.checked = this.formatter['parse'](input.value) == value;
}
};
diff --git a/src/angular-bootstrap.js b/src/angular-bootstrap.js
new file mode 100644
index 00000000..0f7cd2ea
--- /dev/null
+++ b/src/angular-bootstrap.js
@@ -0,0 +1,55 @@
+/**
+ * The MIT License
+ *
+ * Copyright (c) 2010 Adam Abrons and Misko Hevery http://getangular.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+(function(previousOnLoad){
+ var filename = /(.*)\/angular-(.*).js/;
+ var scripts = document.getElementsByTagName("script");
+ var serverPath;
+ for(var j = 0; j < scripts.length; j++) {
+ var match = (scripts[j].src || "").match(filename);
+ if (match) {
+ serverPath = match[1];
+ }
+ }
+
+ function addScript(file){
+ document.write('');
+ };
+
+ addScript("/Angular.js");
+ addScript("/API.js");
+ addScript("/Binder.js");
+ addScript("/ControlBar.js");
+ addScript("/DataStore.js");
+ addScript("/Filters.js");
+ addScript("/Formatters.js");
+ addScript("/JSON.js");
+ addScript("/Model.js");
+ addScript("/Parser.js");
+ addScript("/Scope.js");
+ addScript("/Server.js");
+ addScript("/Users.js");
+ addScript("/Validators.js");
+ addScript("/Widgets.js");
+})(window.onload);
+
--
cgit v1.2.3
From 302472f4fa50f995085ebf36b8990bedf3806973 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Thu, 4 Feb 2010 11:12:34 -0800
Subject: list formater always should return arry
---
src/Formatters.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/Formatters.js b/src/Formatters.js
index 74126feb..661dd701 100644
--- a/src/Formatters.js
+++ b/src/Formatters.js
@@ -8,7 +8,7 @@ extend(angularFormatter, {
'list':formater(
function(obj) { return obj ? obj.join(", ") : obj; },
function(value) {
- return value ? _(_(value.split(',')).map(jQuery.trim)).select(_.identity) : value;
+ return value ? _(_(value.split(',')).map(jQuery.trim)).select(_.identity) : [];
}
)
});
--
cgit v1.2.3
From 5dd43b85e73ca1708e7fd85094b533b02266a79a Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Thu, 4 Feb 2010 11:45:38 -0800
Subject: ng-required treats whitespace as empty
---
src/Widgets.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/Widgets.js b/src/Widgets.js
index 69b444c0..c5ab7c6f 100644
--- a/src/Widgets.js
+++ b/src/Widgets.js
@@ -230,7 +230,7 @@ TextController.prototype = {
var isValidationError = false;
view.removeAttribute('ng-error');
if (this.required) {
- isValidationError = !(value && value.length > 0);
+ isValidationError = !(value && $.trim(value).length > 0);
}
var errorText = isValidationError ? "Required Value" : null;
if (!isValidationError && this.validator && value) {
--
cgit v1.2.3
From 1da18e73a4d09b2a1ace92a4094eeba014eb7dc4 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Thu, 4 Feb 2010 13:27:56 -0800
Subject: consider widget errors only when widgets are visible
---
src/Angular.js | 4 ++++
src/Formatters.js | 6 +++++-
src/Widgets.js | 4 ++--
3 files changed, 11 insertions(+), 3 deletions(-)
(limited to 'src')
diff --git a/src/Angular.js b/src/Angular.js
index 3c88c6b7..ded4485f 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -97,6 +97,10 @@ function isLeafNode (node) {
}
}
+function isVisible(element) {
+ return jQuery(element).is(":visible");
+}
+
function setHtml(node, html) {
if (isLeafNode(node)) {
if (msie) {
diff --git a/src/Formatters.js b/src/Formatters.js
index 661dd701..6aa832af 100644
--- a/src/Formatters.js
+++ b/src/Formatters.js
@@ -1,4 +1,4 @@
-function formater(format, parse) {return {'format':format, 'parse':parse};}
+function formater(format, parse) {return {'format':format, 'parse':parse || format};}
function toString(obj) {return ""+obj;};
extend(angularFormatter, {
'noop':formater(identity, identity),
@@ -10,5 +10,9 @@ extend(angularFormatter, {
function(value) {
return value ? _(_(value.split(',')).map(jQuery.trim)).select(_.identity) : [];
}
+ ),
+
+ 'trim':formater(
+ function(obj) { return obj ? $.trim("" + obj) : ""; }
)
});
diff --git a/src/Widgets.js b/src/Widgets.js
index c5ab7c6f..01877128 100644
--- a/src/Widgets.js
+++ b/src/Widgets.js
@@ -230,7 +230,7 @@ TextController.prototype = {
var isValidationError = false;
view.removeAttribute('ng-error');
if (this.required) {
- isValidationError = !(value && $.trim(value).length > 0);
+ isValidationError = !(value && $.trim("" + value).length > 0);
}
var errorText = isValidationError ? "Required Value" : null;
if (!isValidationError && this.validator && value) {
@@ -239,7 +239,7 @@ TextController.prototype = {
}
if (this.lastErrorText !== errorText) {
this.lastErrorText = isValidationError;
- if (errorText !== null) {
+ if (errorText !== null && isVisible(view)) {
view.setAttribute('ng-error', errorText);
scope.markInvalid(this);
}
--
cgit v1.2.3
From 9f919c42f0885e39870195fab8ce2a22621119b7 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Thu, 4 Feb 2010 14:02:20 -0800
Subject: better handling of $invalidWidgets
---
src/Angular.js | 1 +
src/Binder.js | 2 +-
src/Scope.js | 5 +++++
3 files changed, 7 insertions(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/Angular.js b/src/Angular.js
index ded4485f..fa6a610c 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -294,6 +294,7 @@ function wireAngular(element, config) {
'$anchor' : binder.anchor,
'$updateView': _(binder.updateView).bind(binder),
'$config' : config,
+ '$invalidWidgets': [],
'$console' : window.console,
'$datastore' : exposeMethods(datastore, {
'load': datastore.load,
diff --git a/src/Binder.js b/src/Binder.js
index e516ec32..8dac934b 100644
--- a/src/Binder.js
+++ b/src/Binder.js
@@ -95,7 +95,7 @@ Binder.prototype = {
updateView: function() {
var start = new Date().getTime();
var scope = jQuery(this.doc).scope();
- scope.set("$invalidWidgets", []);
+ scope.clearInvalid();
scope.updateView();
var end = new Date().getTime();
this.updateAnchor();
diff --git a/src/Scope.js b/src/Scope.js
index b8fadfa0..cedb0542 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -153,6 +153,11 @@ Scope.prototype = {
return expression({scope:this, datastore:datastore});
},
+ clearInvalid: function() {
+ var invalid = this.state['$invalidWidgets'];
+ while(invalid.length > 0) {invalid.pop();}
+ },
+
markInvalid: function(widget) {
this.state['$invalidWidgets'].push(widget);
},
--
cgit v1.2.3
From 251fab40291183c8e50ea0fabd23c30341cc72d3 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Thu, 4 Feb 2010 15:04:28 -0800
Subject: updateView is now called on binder instead of scope
---
src/Angular.js | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
(limited to 'src')
diff --git a/src/Angular.js b/src/Angular.js
index fa6a610c..a7d4f719 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -34,6 +34,10 @@ var consoleNode, msie,
log(arguments); window.alert.apply(window, arguments);
});
+var isVisible = isVisible || function (element) {
+ return jQuery(element).is(":visible");
+}
+
function log(a, b, c){
var console = window['console'];
switch(arguments.length) {
@@ -97,10 +101,6 @@ function isLeafNode (node) {
}
}
-function isVisible(element) {
- return jQuery(element).is(":visible");
-}
-
function setHtml(node, html) {
if (isLeafNode(node)) {
if (msie) {
@@ -281,7 +281,7 @@ function wireAngular(element, config) {
var server = config['database'] =="$MEMORY" ?
new FrameServer(window) :
new Server(config['server'], jQuery['getScript']);
- server = new VisualServer(server, new Status(jQuery(element.body)), onUpdate);
+ server = new VisualServer(server, new Status(element.find('body')), onUpdate);
var users = new Users(server, controlBar);
var databasePath = '/data/' + config['database'];
var post = function(request, callback){
@@ -330,7 +330,6 @@ function wireAngular(element, config) {
new PopUp(element).bind();
var self = _(exposeMethods(scope, {
- 'updateView': scope.updateView,
'set': scope.set,
'get': scope.get,
'eval': scope.eval
@@ -343,6 +342,7 @@ function wireAngular(element, config) {
return self;
},
'element':element[0],
+ 'updateView': _(binder.updateView).bind(binder),
'config':config
});
return self;
--
cgit v1.2.3
From 5eb440c22bb87b1d69c14193954620b9f1cec023 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Thu, 4 Feb 2010 15:12:34 -0800
Subject: lazy load the status dom
---
src/Widgets.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'src')
diff --git a/src/Widgets.js b/src/Widgets.js
index 01877128..5e844ae0 100644
--- a/src/Widgets.js
+++ b/src/Widgets.js
@@ -779,8 +779,8 @@ PopUp.prototype = {
function Status(body) {
- this.loader = body.append(Status.DOM).find("#ng-loading");
this.requestCount = 0;
+ this.body = body;
};
Status.DOM ='loading....
';
@@ -788,7 +788,7 @@ Status.DOM ='loading....
';
Status.prototype = {
beginRequest: function () {
if (this.requestCount === 0) {
- this.loader.show();
+ (this.loader = this.loader || this.body.append(Status.DOM).find("#ng-loading")).show();
}
this.requestCount++;
},
--
cgit v1.2.3
From 6d75afe6d2ea26bb412becd1e8f7cab8031eaab4 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Fri, 5 Feb 2010 14:13:19 -0800
Subject: fixed memory leak on repeaters
---
src/Widgets.js | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
(limited to 'src')
diff --git a/src/Widgets.js b/src/Widgets.js
index 5e844ae0..6eb2acc3 100644
--- a/src/Widgets.js
+++ b/src/Widgets.js
@@ -425,7 +425,6 @@ function BindUpdater(view, exp) {
this.view = view;
this.exp = Binder.parseBindings(exp);
this.hasError = false;
- this.scopeSelf = {element:view};
};
BindUpdater.toText = function(obj) {
@@ -481,7 +480,7 @@ BindUpdater.prototype = {
var part = parts[i];
var binding = Binder.binding(part);
if (binding) {
- scope.evalWidget(this, binding, this.scopeSelf, function(value){
+ scope.evalWidget(this, binding, {element:this.view}, function(value){
html.push(BindUpdater.toText(value));
}, function(e, text){
setHtml(this.view, text);
@@ -700,8 +699,7 @@ RepeaterUpdater.prototype = {
});
// shrink children
for ( var r = childrenLength; r > iteratorLength; --r) {
- var unneeded = this.children.pop().element[0];
- unneeded.parentNode.removeChild(unneeded);
+ this.children.pop().element.remove();
}
// Special case for option in select
if (child && child.element[0].nodeName === "OPTION") {
--
cgit v1.2.3
From 9d566a0cd0225685efb192c195280b6857628d32 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Fri, 5 Feb 2010 14:41:45 -0800
Subject: better integer farmater
---
src/Validators.js | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
(limited to 'src')
diff --git a/src/Validators.js b/src/Validators.js
index 5549ee39..84681f15 100644
--- a/src/Validators.js
+++ b/src/Validators.js
@@ -24,11 +24,12 @@ foreach({
},
'integer': function(value, min, max) {
- var number = angularValidator['number'](value, min, max);
- if (number === null && value != Math.round(value)) {
+ var numberError = angularValidator['number'](value, min, max);
+ if (numberError) return numberError;
+ if (!("" + value).match(/^\s*[\d+]*\s*$/) || value != Math.round(value)) {
return "Value is not a whole number.";
}
- return number;
+ return null;
},
'date': function(value, min, max) {
--
cgit v1.2.3
From 799d72931a5a01de74bba69d8a6638cd57cec315 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Tue, 9 Feb 2010 13:13:18 -0800
Subject: added onUpdateView listener for config
---
src/Angular.js | 2 ++
src/Binder.js | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/Angular.js b/src/Angular.js
index a7d4f719..93ca71b4 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -276,6 +276,7 @@ function exposeMethods(obj, methods){
function wireAngular(element, config) {
var widgetFactory = new WidgetFactory(config['server'], config['database']);
var binder = new Binder(element[0], widgetFactory, datastore, config['location'], config);
+ binder.updateListeners.push(config.onUpdateView);
var controlBar = new ControlBar(element.find('body'), config['server'], config['database']);
var onUpdate = function(){binder.updateView();};
var server = config['database'] =="$MEMORY" ?
@@ -358,6 +359,7 @@ angular['compile'] = function(element, config) {
jQuery = window['jQuery'];
msie = jQuery['browser']['msie'];
config = _({
+ 'onUpdateView': noop,
'server': "",
'location': {'get':noop, 'set':noop, 'listen':noop}
}).extend(config||{});
diff --git a/src/Binder.js b/src/Binder.js
index 8dac934b..4699a601 100644
--- a/src/Binder.js
+++ b/src/Binder.js
@@ -99,7 +99,7 @@ Binder.prototype = {
scope.updateView();
var end = new Date().getTime();
this.updateAnchor();
- _.each(this.updateListeners, function(fn) {fn();});
+ foreach(this.updateListeners, function(fn) {fn();});
},
docFindWithSelf: function(exp){
--
cgit v1.2.3
From b2a8a089b6c31c8ff176c2483f659caae4f71afb Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Thu, 11 Feb 2010 09:57:42 -0800
Subject: make validator more leniant for errors which are false instead of
null
---
src/Widgets.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/Widgets.js b/src/Widgets.js
index 6eb2acc3..4f359e91 100644
--- a/src/Widgets.js
+++ b/src/Widgets.js
@@ -239,7 +239,7 @@ TextController.prototype = {
}
if (this.lastErrorText !== errorText) {
this.lastErrorText = isValidationError;
- if (errorText !== null && isVisible(view)) {
+ if (errorText && isVisible(view)) {
view.setAttribute('ng-error', errorText);
scope.markInvalid(this);
}
--
cgit v1.2.3
From 6cc946413622f1cef97997849e73a06a00f876fd Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Fri, 12 Feb 2010 14:16:33 -0800
Subject: Fixed negation grouping bug Make 'this' of validation be scope
---
src/Filters.js | 4 ++--
src/Parser.js | 53 +++++++++++++++++++++++------------------------------
src/Scope.js | 4 ++--
src/Widgets.js | 6 +++---
4 files changed, 30 insertions(+), 37 deletions(-)
(limited to 'src')
diff --git a/src/Filters.js b/src/Filters.js
index 77fa5ec7..60d53fb9 100644
--- a/src/Filters.js
+++ b/src/Filters.js
@@ -24,7 +24,7 @@ var angularFilterGoogleChartApi;
foreach({
'currency': function(amount){
- jQuery(this.element).toggleClass('ng-format-negative', amount < 0);
+ jQuery(this.$element).toggleClass('ng-format-negative', amount < 0);
return '$' + angularFilter['number'].apply(this, [amount, 2]);
},
@@ -60,7 +60,7 @@ foreach({
},
'json': function(object) {
- jQuery(this.element).addClass("ng-monospace");
+ jQuery(this.$element).addClass("ng-monospace");
return toJson(object, true);
},
diff --git a/src/Parser.js b/src/Parser.js
index fe9671af..3aa644ac 100644
--- a/src/Parser.js
+++ b/src/Parser.js
@@ -369,7 +369,16 @@ Parser.prototype = {
for ( var i = 0; i < argsFn.length; i++) {
args.push(argsFn[i](self));
}
- return fn.apply(self, args);
+ var pipeThis = function(){
+ var _this = this;
+ foreach(self, function(v, k) {
+ if (k.charAt(0) == '$') {
+ _this[k] = v;
+ }
+ });
+ };
+ pipeThis.prototype = self.self;
+ return fn.apply(new pipeThis(), args);
};
return function(){
return fnInvoke;
@@ -422,48 +431,30 @@ Parser.prototype = {
},
logicalAND: function(){
- var left = this.negated();
+ var left = this.equality();
var token;
- while(true) {
- if ((token = this.expect('&&'))) {
- left = this._binary(left, token.fn, this.negated());
- } else {
- return left;
- }
- }
- },
-
- negated: function(){
- var token;
- if (token = this.expect('!')) {
- return this._unary(token.fn, this.assignment());
- } else {
- return this.equality();
+ if ((token = this.expect('&&'))) {
+ left = this._binary(left, token.fn, this.logicalAND());
}
+ return left;
},
equality: function(){
var left = this.relational();
var token;
- while(true) {
- if ((token = this.expect('==','!='))) {
- left = this._binary(left, token.fn, this.relational());
- } else {
- return left;
- }
+ if ((token = this.expect('==','!='))) {
+ left = this._binary(left, token.fn, this.equality());
}
+ return left;
},
relational: function(){
var left = this.additive();
var token;
- while(true) {
- if ((token = this.expect('<', '>', '<=', '>='))) {
- left = this._binary(left, token.fn, this.additive());
- } else {
- return left;
- }
+ if (token = this.expect('<', '>', '<=', '>=')) {
+ left = this._binary(left, token.fn, this.relational());
}
+ return left;
},
additive: function(){
@@ -489,7 +480,9 @@ Parser.prototype = {
if (this.expect('+')) {
return this.primary();
} else if (token = this.expect('-')) {
- return this._binary(Parser.ZERO, token.fn, this.multiplicative());
+ return this._binary(Parser.ZERO, token.fn, this.unary());
+ } else if (token = this.expect('!')) {
+ return this._unary(token.fn, this.unary());
} else {
return this.primary();
}
diff --git a/src/Scope.js b/src/Scope.js
index cedb0542..c0998168 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -138,13 +138,13 @@ Scope.prototype = {
}
},
- validate: function(expressionText, value) {
+ validate: function(expressionText, value, element) {
var expression = Scope.expressionCache[expressionText];
if (!expression) {
expression = new Parser(expressionText).validator();
Scope.expressionCache[expressionText] = expression;
}
- var self = {scope:this};
+ var self = {scope:this, self:this.state, '$element':element};
return expression(self)(self, value);
},
diff --git a/src/Widgets.js b/src/Widgets.js
index 4f359e91..71fcd110 100644
--- a/src/Widgets.js
+++ b/src/Widgets.js
@@ -234,7 +234,7 @@ TextController.prototype = {
}
var errorText = isValidationError ? "Required Value" : null;
if (!isValidationError && this.validator && value) {
- errorText = scope.validate(this.validator, value);
+ errorText = scope.validate(this.validator, value, view);
isValidationError = !!errorText;
}
if (this.lastErrorText !== errorText) {
@@ -480,7 +480,7 @@ BindUpdater.prototype = {
var part = parts[i];
var binding = Binder.binding(part);
if (binding) {
- scope.evalWidget(this, binding, {element:this.view}, function(value){
+ scope.evalWidget(this, binding, {$element:this.view}, function(value){
html.push(BindUpdater.toText(value));
}, function(e, text){
setHtml(this.view, text);
@@ -520,7 +520,7 @@ BindAttrUpdater.prototype = {
var binding = Binder.binding(attributeTemplate[i]);
if (binding) {
try {
- var value = scope.eval(binding, {element:jNode[0], attrName:attrName});
+ var value = scope.eval(binding, {$element:jNode[0], attrName:attrName});
if (value && (value.constructor !== array || value.length !== 0))
attrValues.push(value);
} catch (e) {
--
cgit v1.2.3
From 3f9a2ab9bdfcd12cb7df74b0d38cecf2ee4ac94a Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Fri, 12 Feb 2010 19:39:01 -0800
Subject: added asynchronous validator
---
src/Parser.js | 4 ++--
src/Validators.js | 29 +++++++++++++++++++++++++++++
2 files changed, 31 insertions(+), 2 deletions(-)
(limited to 'src')
diff --git a/src/Parser.js b/src/Parser.js
index 3aa644ac..b59b21a7 100644
--- a/src/Parser.js
+++ b/src/Parser.js
@@ -349,11 +349,11 @@ Parser.prototype = {
},
filter: function(){
- return this._pipeFunction(angular['filter']);
+ return this._pipeFunction(angularFilter);
},
validator: function(){
- return this._pipeFunction(angular['validator']);
+ return this._pipeFunction(angularValidator);
},
_pipeFunction: function(fnScope){
diff --git a/src/Validators.js b/src/Validators.js
index 84681f15..b7efcb4a 100644
--- a/src/Validators.js
+++ b/src/Validators.js
@@ -77,5 +77,34 @@ foreach({
} catch (e) {
return e.toString();
}
+ },
+
+ 'asynchronous': function(text, asynchronousFn) {
+ var stateKey = '$validateState';
+ var lastKey = '$lastKey';
+ var obj = this['$element'];
+ var stateCache = obj[stateKey] = obj[stateKey] || {};
+ var state = stateCache[text];
+ var updateView = this['$updateView'];
+ obj[lastKey] = text;
+ if (state === undefined) {
+ // we have never seen this before, Request it
+ jQuery(obj).addClass('ng-input-indicator-wait');
+ state = stateCache[text] = null;
+ asynchronousFn(text, function(error){
+ state = stateCache[text] = error ? error : false;
+ if (stateCache[obj[lastKey]] !== null) {
+ jQuery(obj).removeClass('ng-input-indicator-wait');
+ }
+ updateView();
+ });
+ }
+
+ if (state === null){
+ // request in flight, mark widget invalid, but don't show it to user
+ this['$invalidWidgets'].push(this.$element);
+ }
+ return state;
}
+
}, function(v,k) {angularValidator[k] = v;});
--
cgit v1.2.3
From b561f6a0cc3e2e03c05925fbed3e06723f91b4b5 Mon Sep 17 00:00:00 2001
From: Adam Abrons
Date: Tue, 16 Feb 2010 21:30:15 -0800
Subject: stop showing loading... text
---
src/Angular.js | 4 ++--
src/Widgets.js | 7 +++++++
2 files changed, 9 insertions(+), 2 deletions(-)
(limited to 'src')
diff --git a/src/Angular.js b/src/Angular.js
index 93ca71b4..6cb3f602 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -282,7 +282,7 @@ function wireAngular(element, config) {
var server = config['database'] =="$MEMORY" ?
new FrameServer(window) :
new Server(config['server'], jQuery['getScript']);
- server = new VisualServer(server, new Status(element.find('body')), onUpdate);
+ server = new VisualServer(server, new NullStatus(element.find('body')), onUpdate);
var users = new Users(server, controlBar);
var databasePath = '/data/' + config['database'];
var post = function(request, callback){
@@ -368,4 +368,4 @@ angular['compile'] = function(element, config) {
configureJQueryPlugins();
return wireAngular(jQuery(element), config);
-};
\ No newline at end of file
+};
diff --git a/src/Widgets.js b/src/Widgets.js
index 71fcd110..13506a78 100644
--- a/src/Widgets.js
+++ b/src/Widgets.js
@@ -775,6 +775,13 @@ PopUp.prototype = {
// Status
//////////////////////////////////
+function NullStatus(body) {
+};
+
+NullStatus.prototype = {
+ beginRequest:function(){},
+ endRequest:function(){}
+};
function Status(body) {
this.requestCount = 0;
--
cgit v1.2.3
From 7e14dff90516a41ff1903cc44fe3389710f15556 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Wed, 17 Feb 2010 16:05:26 -0800
Subject: fix this on filter to point to scope
---
src/Scope.js | 1 +
1 file changed, 1 insertion(+)
(limited to 'src')
diff --git a/src/Scope.js b/src/Scope.js
index c0998168..4de57dd2 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -105,6 +105,7 @@ Scope.prototype = {
}
context = context || {};
context.scope = this;
+ context.self = this.state;
return expression(context);
},
--
cgit v1.2.3
From 2f99af1cce0e7bd440f937d2557dbd583d8a6129 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Wed, 17 Feb 2010 20:50:13 -0800
Subject: fixed upload widget
---
src/Widgets.js | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
(limited to 'src')
diff --git a/src/Widgets.js b/src/Widgets.js
index 13506a78..6d7530f0 100644
--- a/src/Widgets.js
+++ b/src/Widgets.js
@@ -57,7 +57,7 @@ WidgetFactory.prototype = {
bind(event, action);
return controller;
},
-
+
createFileController: function(fileInput) {
var uploadId = '__uploadWidget_' + (this.nextUploadId++);
var view = FileController.template(uploadId);
@@ -72,7 +72,7 @@ WidgetFactory.prototype = {
var swfNode = this.createSWF(att, par, uploadId);
fileInput.remove();
var cntl = new FileController(view, fileInput[0].name, swfNode, this.serverUrl + "/data/" + this.database);
- jQuery(swfNode).data('controller', cntl);
+ jQuery(swfNode).parent().data('controller', cntl);
return cntl;
}
};
@@ -92,7 +92,7 @@ function FileController(view, scopeName, uploader, databaseUrl) {
angularCallbacks['flashEvent'] = function(id, event, args) {
var object = document.getElementById(id);
var jobject = jQuery(object);
- var controller = jobject.data("controller");
+ var controller = jobject.parent().data("controller");
FileController.prototype[event].apply(controller, args);
_.defer(jobject.scope().get('$updateView'));
};
@@ -103,7 +103,7 @@ FileController.template = function(id) {
'' +
'' +
'' +
- '');
+ '');
};
extend(FileController.prototype, {
@@ -130,14 +130,14 @@ extend(FileController.prototype, {
this.value = value;
this.updateModel(scope);
this.value = null;
- },
+ },
'select': function(name, size, type) {
this.name = name;
this.view.find("a").text(name).attr('href', name);
this.view.find("span").text(angular['filter']['bytes'](size));
this.upload();
},
-
+
updateModel: function(scope) {
var isChecked = this.view.find("input").attr('checked');
var value = isChecked ? this.value : null;
@@ -148,7 +148,7 @@ extend(FileController.prototype, {
return true;
}
},
-
+
updateView: function(scope) {
var modelValue = scope.get(this.scopeName);
if (modelValue && this.value !== modelValue) {
@@ -160,7 +160,7 @@ extend(FileController.prototype, {
}
this.view.find("input").attr('checked', !!modelValue);
},
-
+
upload: function() {
if (this.name) {
this.uploader['uploadFile'](this.attachmentsPath);
@@ -213,7 +213,7 @@ TextController.prototype = {
return true;
}
},
-
+
updateView: function(scope) {
var view = this.view;
var value = scope.get(this.exp);
@@ -226,7 +226,7 @@ TextController.prototype = {
view.value = this.formatter['format'](value);
this.lastValue = value;
}
-
+
var isValidationError = false;
view.removeAttribute('ng-error');
if (this.required) {
@@ -273,7 +273,7 @@ CheckboxController.prototype = {
return true;
}
},
-
+
updateView: function(scope) {
var input = this.view;
var value = scope.eval(this.exp);
@@ -311,7 +311,7 @@ SelectController.prototype = {
}
}
},
-
+
updateView: function(scope) {
var input = this.view;
var value = scope.get(this.exp);
@@ -348,7 +348,7 @@ MultiSelectController.prototype = {
}
return value;
},
-
+
updateModel: function(scope) {
var value = this.selected();
// TODO: This is wrong! no caching going on here as we are always comparing arrays
@@ -360,7 +360,7 @@ MultiSelectController.prototype = {
return true;
}
},
-
+
updateView: function(scope) {
var input = this.view;
var selected = scope.get(this.exp);
@@ -403,7 +403,7 @@ RadioController.prototype = {
return true;
}
},
-
+
updateView: function(scope) {
var input = this.view;
var value = scope.get(this.exp);
@@ -540,7 +540,7 @@ BindAttrUpdater.prototype = {
if(isImage && attrName == 'src' && !attrValue)
attrValue = scope.get('$config.blankImage');
jNode.attr(attrName, attrValue);
- }
+ }
}
};
@@ -797,7 +797,7 @@ Status.prototype = {
}
this.requestCount++;
},
-
+
endRequest: function () {
this.requestCount--;
if (this.requestCount === 0) {
--
cgit v1.2.3
From 97c02c9def42655e28ec86fed288ca363b152f9e Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Sat, 20 Feb 2010 14:56:06 -0800
Subject: upgraded underscore.js for ie compatibility
---
src/Users.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
(limited to 'src')
diff --git a/src/Users.js b/src/Users.js
index f81507f4..fb5845d3 100644
--- a/src/Users.js
+++ b/src/Users.js
@@ -8,10 +8,10 @@ extend(Users.prototype, {
var self = this;
this.server.request("GET", "/account.json", {}, function(code, response){
self['current'] = response['user'];
- callback(response.user);
+ callback(response['user']);
});
},
-
+
'logout': function(callback) {
var self = this;
this.controlBar.logout(function(){
@@ -19,7 +19,7 @@ extend(Users.prototype, {
(callback||noop)();
});
},
-
+
'login': function(callback) {
var self = this;
this.controlBar.login(function(){
--
cgit v1.2.3
From b628de9758c313b106d22468f4b49bd223698fd5 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Sat, 20 Feb 2010 17:27:21 -0800
Subject: fix option value bug
---
src/Binder.js | 64 +++++++++++++++++++++++++++++++----------------------------
1 file changed, 34 insertions(+), 30 deletions(-)
(limited to 'src')
diff --git a/src/Binder.js b/src/Binder.js
index 4699a601..9fc32513 100644
--- a/src/Binder.js
+++ b/src/Binder.js
@@ -48,14 +48,14 @@ Binder.prototype = {
});
return params;
},
-
+
parseAnchor: function() {
var self = this, url = this.location['get']() || "";
-
+
var anchorIndex = url.indexOf('#');
if (anchorIndex < 0) return;
var anchor = url.substring(anchorIndex + 1);
-
+
var anchorQuery = this.parseQueryString(anchor);
foreach(self.anchor, function(newValue, key) {
delete self.anchor[key];
@@ -64,12 +64,12 @@ Binder.prototype = {
self.anchor[key] = newValue;
});
},
-
+
onUrlChange: function() {
this.parseAnchor();
this.updateView();
},
-
+
updateAnchor: function() {
var url = this.location['get']() || "";
var anchorIndex = url.indexOf('#');
@@ -91,7 +91,7 @@ Binder.prototype = {
this.location['set'](url);
return url;
},
-
+
updateView: function() {
var start = new Date().getTime();
var scope = jQuery(this.doc).scope();
@@ -101,7 +101,7 @@ Binder.prototype = {
this.updateAnchor();
foreach(this.updateListeners, function(fn) {fn();});
},
-
+
docFindWithSelf: function(exp){
var doc = jQuery(this.doc);
var selection = doc.find(exp);
@@ -110,7 +110,7 @@ Binder.prototype = {
}
return selection;
},
-
+
executeInit: function() {
this.docFindWithSelf("[ng-init]").each(function() {
var jThis = jQuery(this);
@@ -122,7 +122,7 @@ Binder.prototype = {
}
});
},
-
+
entity: function (scope) {
var self = this;
this.docFindWithSelf("[ng-entity]").attr("ng-watch", function() {
@@ -136,7 +136,7 @@ Binder.prototype = {
}
});
},
-
+
compile: function() {
var jNode = jQuery(this.doc);
if (this.config['autoSubmit']) {
@@ -160,7 +160,7 @@ Binder.prototype = {
return false;
});
},
-
+
translateBinding: function(node, parentPath, factories) {
var path = parentPath.concat();
var offset = path.pop();
@@ -196,7 +196,7 @@ Binder.prototype = {
parent.removeChild(node);
}
},
-
+
precompile: function(root) {
var factories = [];
this.precompileNode(root, [], factories);
@@ -217,7 +217,7 @@ Binder.prototype = {
}
};
},
-
+
precompileNode: function(node, path, factories) {
var nodeType = node.nodeType;
if (nodeType == Node.TEXT_NODE) {
@@ -226,11 +226,11 @@ Binder.prototype = {
} else if (nodeType != Node.ELEMENT_NODE && nodeType != Node.DOCUMENT_NODE) {
return;
}
-
+
if (!node.getAttribute) return;
var nonBindable = node.getAttribute('ng-non-bindable');
if (nonBindable || nonBindable === "") return;
-
+
var attributes = node.attributes;
if (attributes) {
var bindings = node.getAttribute('ng-bind-attr');
@@ -252,7 +252,7 @@ Binder.prototype = {
node.setAttribute("ng-bind-attr", json);
}
}
-
+
if (!node.getAttribute) log(node);
var repeaterExpression = node.getAttribute('ng-repeat');
if (repeaterExpression) {
@@ -275,7 +275,7 @@ Binder.prototype = {
}});
return;
}
-
+
if (node.getAttribute('ng-eval')) factories.push({path:path, fn:this.ng_eval});
if (node.getAttribute('ng-bind')) factories.push({path:path, fn:this.ng_bind});
if (node.getAttribute('ng-bind-attr')) factories.push({path:path, fn:this.ng_bind_attr});
@@ -300,53 +300,57 @@ Binder.prototype = {
if (nodeName == 'OPTION') {
var html = jQuery('').append(jQuery(node).clone()).html();
if (!html.match(/