aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndres Ornelas2010-07-27 10:44:46 -0700
committerAndres Ornelas2010-07-27 10:44:46 -0700
commitb42072733c3afd03a49457d88ffed28ebe55655e (patch)
tree2fa2b8703cdc75fe19a204d2c9677e27d33c8176 /src
parent2f7c538628929888ce7c99b9577e34f8c87211f7 (diff)
parent8ddee9bb25ade2bbe7d57db6353b29867606c184 (diff)
downloadangular.js-b42072733c3afd03a49457d88ffed28ebe55655e.tar.bz2
Merge branch 'master' of github.com:angular/angular.js into future
Diffstat (limited to 'src')
-rw-r--r--src/Angular.js106
-rw-r--r--src/AngularPublic.js8
-rw-r--r--src/Browser.js48
-rw-r--r--src/Compiler.js17
-rw-r--r--src/Parser.js2
-rw-r--r--src/Resource.js10
-rw-r--r--src/Scope.js43
-rw-r--r--src/apis.js4
-rw-r--r--src/delete/Binder.js356
-rw-r--r--src/delete/Model.js65
-rw-r--r--src/delete/Scope.js407
-rw-r--r--src/delete/Widgets.js806
-rw-r--r--src/directives.js111
-rw-r--r--src/filters.js8
-rw-r--r--src/jqLite.js17
-rw-r--r--src/markups.js28
-rw-r--r--src/moveToAngularCom/ControlBar.js72
-rw-r--r--src/moveToAngularCom/DataStore.js330
-rw-r--r--src/moveToAngularCom/Server.js68
-rw-r--r--src/moveToAngularCom/Users.js35
-rw-r--r--src/moveToAngularCom/directivesAngularCom.js29
-rw-r--r--src/scenario/DSL.js5
-rw-r--r--src/services.js32
-rw-r--r--src/widgets.js33
24 files changed, 272 insertions, 2368 deletions
diff --git a/src/Angular.js b/src/Angular.js
index 2b26c88d..850fe34c 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -3,8 +3,6 @@
if (typeof document.getAttribute == 'undefined')
document.getAttribute = function() {};
-if (!window['console']) window['console']={'log':noop, 'error':noop};
-
var consoleNode,
PRIORITY_FIRST = -99999,
PRIORITY_WATCH = -1000,
@@ -18,11 +16,12 @@ var consoleNode,
msie = !!/(msie) ([\w.]+)/.exec(lowercase(navigator.userAgent)),
jqLite = jQuery || jqLiteWrap,
slice = Array.prototype.slice,
+ error = window['console'] ? bind(window['console'], window['console']['error'] || noop) : noop,
angular = window['angular'] || (window['angular'] = {}),
angularTextMarkup = extensionMap(angular, 'textMarkup'),
angularAttrMarkup = extensionMap(angular, 'attrMarkup'),
angularDirective = extensionMap(angular, 'directive'),
- angularWidget = extensionMap(angular, 'widget'),
+ angularWidget = extensionMap(angular, 'widget', lowercase),
angularValidator = extensionMap(angular, 'validator'),
angularFilter = extensionMap(angular, 'filter'),
angularFormatter = extensionMap(angular, 'formatter'),
@@ -30,10 +29,6 @@ var consoleNode,
angularCallbacks = extensionMap(angular, 'callbacks'),
nodeName;
-function angularAlert(){
- log(arguments); window.alert.apply(window, arguments);
-}
-
function foreach(obj, iterator, context) {
var key;
if (obj) {
@@ -78,11 +73,16 @@ function extend(dst) {
return dst;
}
+function inherit(parent, extra) {
+ return extend(new (extend(function(){}, {prototype:parent}))(), extra);
+};
+
function noop() {}
function identity($) {return $;}
-function extensionMap(angular, name) {
+function extensionMap(angular, name, transform) {
var extPoint;
return angular[name] || (extPoint = angular[name] = function (name, fn, prop){
+ name = (transform || identity)(name);
if (isDefined(fn)) {
extPoint[name] = extend(fn, prop || {});
}
@@ -173,50 +173,6 @@ function indexOf(array, obj) {
return -1;
}
-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 isLeafNode (node) {
if (node) {
switch (node.nodeName) {
@@ -259,6 +215,32 @@ function copy(source, destination){
}
}
+function equals(o1, o2) {
+ if (o1 == o2) return true;
+ var t1 = typeof o1, t2 = typeof o2, length, key, keySet;
+ if (t1 == t2 && t1 == 'object') {
+ if (o1 instanceof Array) {
+ if ((length = o1.length) == o2.length) {
+ for(key=0; key<length; key++) {
+ if (!equals(o1[key], o2[key])) return false;
+ }
+ return true;
+ }
+ } else {
+ keySet = {};
+ for(key in o1) {
+ if (key.charAt(0) !== '$' && !equals(o1[key], o2[key])) return false;
+ keySet[key] = true;
+ }
+ for(key in o2) {
+ if (key.charAt(0) !== '$' && keySet[key] !== true) return false;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
function setHtml(node, html) {
if (isLeafNode(node)) {
if (msie) {
@@ -310,12 +292,14 @@ function escapeAttr(html) {
}
function bind(_this, _function) {
- if (!isFunction(_function))
- throw "Not a function!";
var curryArgs = slice.call(arguments, 2, arguments.length);
- return function() {
- return _function.apply(_this, curryArgs.concat(slice.call(arguments, 0, arguments.length)));
- };
+ return curryArgs.length == 0 ?
+ function() {
+ return _function.apply(_this, arguments);
+ } :
+ function() {
+ return _function.apply(_this, curryArgs.concat(slice.call(arguments, 0, arguments.length)));
+ };
}
function outerHTML(node) {
@@ -329,7 +313,7 @@ function outerHTML(node) {
function toBoolean(value) {
if (value && value.length !== 0) {
var v = lowercase("" + value);
- value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == '[]');
+ value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]');
} else {
value = false;
}
@@ -349,12 +333,12 @@ function merge(src, dst) {
}
}
-function compile(element, parentScope, overrides) {
+function compile(element, parentScope) {
var compiler = new Compiler(angularTextMarkup, angularAttrMarkup, angularDirective, angularWidget),
$element = jqLite(element),
parent = extend({}, parentScope);
parent.$element = $element;
- return compiler.compile($element)($element, parent, overrides);
+ return compiler.compile($element)($element, parent);
}
/////////////////////////////////////////////////
@@ -389,7 +373,7 @@ function angularInit(config){
function angularJsConfig(document) {
var filename = /(.*)\/angular(-(.*))?.js(#(.*))?/,
- scripts = document.getElementsByTagName("SCRIPT"),
+ scripts = document.getElementsByTagName("script"),
match;
for(var j = 0; j < scripts.length; j++) {
match = (scripts[j].src || "").match(filename);
diff --git a/src/AngularPublic.js b/src/AngularPublic.js
index 7230c3e5..7b093f88 100644
--- a/src/AngularPublic.js
+++ b/src/AngularPublic.js
@@ -1,7 +1,10 @@
var browserSingleton;
angularService('$browser', function browserFactory(){
if (!browserSingleton) {
- browserSingleton = new Browser(window.location, window.document);
+ browserSingleton = new Browser(
+ window.location,
+ jqLite(window.document),
+ jqLite(window.document.getElementsByTagName('head')[0]));
browserSingleton.startUrlWatcher();
browserSingleton.bind();
}
@@ -14,9 +17,12 @@ extend(angular, {
'scope': createScope,
'copy': copy,
'extend': extend,
+ 'equals': equals,
'foreach': foreach,
'noop':noop,
'bind':bind,
+ 'toJson': toJson,
+ 'fromJson': fromJson,
'identity':identity,
'isUndefined': isUndefined,
'isDefined': isDefined,
diff --git a/src/Browser.js b/src/Browser.js
index 0552b3ae..3287cf0e 100644
--- a/src/Browser.js
+++ b/src/Browser.js
@@ -2,7 +2,7 @@
// Browser
//////////////////////////////
-function Browser(location, document) {
+function Browser(location, document, head) {
this.delay = 50;
this.expectedUrl = location.href;
this.urlListeners = [];
@@ -21,8 +21,9 @@ function Browser(location, document) {
};
this.location = location;
- this.document = jqLite(document);
- this.body = jqLite(document.body);
+ this.document = document;
+ this.head = head;
+ this.idCounter = 0;
}
Browser.prototype = {
@@ -58,21 +59,34 @@ Browser.prototype = {
callback = post;
post = null;
}
- var xhr = new this.XHR(),
- self = this;
- xhr.open(method, url, true);
- this.outstandingRequests.count ++;
- xhr.onreadystatechange = function() {
- if (xhr.readyState == 4) {
- try {
- callback(xhr.status || 200, xhr.responseText);
- } finally {
- self.outstandingRequests.count--;
- self.processRequestCallbacks();
+ if (lowercase(method) == 'json') {
+ var callbackId = "angular_" + Math.random() + '_' + (this.idCounter++);
+ callbackId = callbackId.replace(/\d\./, '');
+ var script = this.document[0].createElement('script');
+ script.type = 'text/javascript';
+ script.src = url.replace('JSON_CALLBACK', callbackId);
+ this.head.append(script);
+ window[callbackId] = function(data){
+ window[callbackId] = undefined;
+ callback(200, data);
+ };
+ } else {
+ var xhr = new this.XHR(),
+ self = this;
+ xhr.open(method, url, true);
+ this.outstandingRequests.count ++;
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ try {
+ callback(xhr.status || 200, xhr.responseText);
+ } finally {
+ self.outstandingRequests.count--;
+ self.processRequestCallbacks();
+ }
}
- }
- };
- xhr.send(post || '');
+ };
+ xhr.send(post || '');
+ }
},
processRequestCallbacks: function(){
diff --git a/src/Compiler.js b/src/Compiler.js
index c8910c27..bcf1f61a 100644
--- a/src/Compiler.js
+++ b/src/Compiler.js
@@ -30,7 +30,9 @@ Template.prototype = {
element = jqLite(element);
foreach(this.inits, function(fn) {
queue.push(function(scope) {
- scope.$tryEval(fn, element, element);
+ scope.$tryEval(function(){
+ return fn.call(scope, element);
+ }, element);
});
});
@@ -121,20 +123,25 @@ Compiler.prototype = {
descend: function(value){ if(isDefined(value)) descend = value; return descend;},
directives: function(value){ if(isDefined(value)) directives = value; return directives;}
};
- priority = element.attr('ng-eval-order') || priority || 0;
+ try {
+ priority = element.attr('ng:eval-order') || priority || 0;
+ } catch (e) {
+ // for some reason IE throws error under some weird circumstances. so just assume nothing
+ priority = priority || 0;
+ }
if (isString(priority)) {
priority = PRIORITY[uppercase(priority)] || 0;
}
template = new Template(priority);
eachAttribute(element, function(value, name){
if (!widget) {
- if (widget = self.widgets['@' + name]) {
+ if (widget = self.widgets('@' + name)) {
widget = bind(selfApi, widget, value, element);
}
}
});
if (!widget) {
- if (widget = self.widgets[nodeName(element)]) {
+ if (widget = self.widgets(nodeName(element))) {
widget = bind(selfApi, widget, element);
}
}
@@ -200,7 +207,7 @@ function eachAttribute(element, fn){
var i, attrs = element[0].attributes || [], chld, attr, name, value, attrValue = {};
for (i = 0; i < attrs.length; i++) {
attr = attrs[i];
- name = attr.name.replace(':', '-');
+ name = attr.name;
value = attr.value;
if (msie && name == 'href') {
value = decodeURIComponent(element[0].getAttribute(name, 2));
diff --git a/src/Parser.js b/src/Parser.js
index df270792..5c2307e4 100644
--- a/src/Parser.js
+++ b/src/Parser.js
@@ -602,6 +602,8 @@ Parser.prototype = {
var fnPtr = fn(self);
if (typeof fnPtr === 'function') {
return fnPtr.apply(self, args);
+ } else if (fnPtr === undefined) {
+ return fnPtr;
} else {
throw "Expression '" + fn.isAssignable + "' is not a function.";
}
diff --git a/src/Resource.js b/src/Resource.js
index 6ee0b1cf..f4f26ebd 100644
--- a/src/Resource.js
+++ b/src/Resource.js
@@ -1,3 +1,5 @@
+
+
function Route(template, defaults) {
this.template = template = template + '#';
this.defaults = defaults || {};
@@ -26,6 +28,7 @@ Route.prototype = {
query.push(encodeURI(key) + '=' + encodeURI(value));
}
});
+ url = url.replace(/\/*$/, '');
return url + (query.length ? '?' + query.join('&') : '');
}
};
@@ -91,11 +94,10 @@ ResourceFactory.prototype = {
action.method,
route.url(extend({}, action.params || {}, extractParams(data), params)),
data,
- function(status, response) {
+ function(status, response, clear) {
if (status == 200) {
if (action.isArray) {
- if (action.cacheThenRetrieve)
- value = [];
+ value.length = 0;
foreach(response, function(item){
value.push(new Resource(item));
});
@@ -107,7 +109,7 @@ ResourceFactory.prototype = {
throw {status: status, response:response, message: status + ": " + response};
}
},
- action.cacheThenRetrieve
+ action.verifyCache
);
return value;
};
diff --git a/src/Scope.js b/src/Scope.js
index e9b61ec4..4d2aa5c3 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -46,7 +46,15 @@ function setter(instance, path, value){
///////////////////////////////////
var getterFnCache = {};
-var JS_KEYWORDS = ["this", "throw", "for", "foreach", "var", "const"];
+var JS_KEYWORDS = {};
+foreach(
+ ["abstract", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default",
+ "delete", "do", "double", "else", "enum", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto",
+ "if", "implements", "import", "ininstanceof", "intinterface", "long", "native", "new", "null", "package", "private",
+ "protected", "public", "return", "short", "static", "super", "switch", "synchronized", "this", "throw", "throws",
+ "transient", "true", "try", "typeof", "var", "volatile", "void", "while", "with"],
+ function(key){ JS_KEYWORDS[key] = true;}
+);
function getterFn(path){
var fn = getterFnCache[path];
if (fn) return fn;
@@ -54,7 +62,7 @@ function getterFn(path){
var code = 'function (self){\n';
code += ' var last, fn, type;\n';
foreach(path.split('.'), function(key) {
- key = (includes(JS_KEYWORDS, key)) ? '["' + key + '"]' : '.' + key;
+ key = (JS_KEYWORDS[key]) ? '["' + key + '"]' : '.' + key;
code += ' if(!self) return self;\n';
code += ' last = self;\n';
code += ' self = self' + key + ';\n';
@@ -72,8 +80,8 @@ function getterFn(path){
}
});
code += ' return self;\n}';
- fn = eval('(' + code + ')');
- fn.toString = function(){ return code; };
+ fn = eval('fn = ' + code);
+ fn["toString"] = function(){ return code; };
return getterFnCache[path] = fn;
}
@@ -82,7 +90,7 @@ function getterFn(path){
var compileCache = {};
function expressionCompile(exp){
- if (isFunction(exp)) return exp;
+ if (typeof exp === 'function') return exp;
var fn = compileCache[exp];
if (!fn) {
var parser = new Parser(exp);
@@ -122,24 +130,30 @@ function createScope(parent, services, existing) {
$set: bind(instance, setter, instance),
$eval: function $eval(exp) {
- if (exp !== undefined) {
- return expressionCompile(exp).apply(instance, slice.call(arguments, 1, arguments.length));
- } else {
+ if (exp === undefined) {
for ( var i = 0, iSize = evalLists.sorted.length; i < iSize; i++) {
for ( var queue = evalLists.sorted[i],
- jSize = queue.length,
- j= 0; j < jSize; j++) {
+ jSize = queue.length,
+ j= 0; j < jSize; j++) {
instance.$tryEval(queue[j].fn, queue[j].handler);
}
}
+ } else if (typeof exp === 'function'){
+ return exp.call(instance);
+ } else {
+ return expressionCompile(exp).call(instance);
}
},
$tryEval: function (expression, exceptionHandler) {
try {
- return expressionCompile(expression).apply(instance, slice.call(arguments, 2, arguments.length));
+ if (typeof expression == 'function') {
+ return expression.call(instance);
+ } else {
+ return expressionCompile(expression).call(instance);
+ }
} catch (e) {
- error(e);
+ (instance.$log || {error:error}).error(e);
if (isFunction(exceptionHandler)) {
exceptionHandler(e);
} else if (exceptionHandler) {
@@ -153,12 +167,15 @@ function createScope(parent, services, existing) {
$watch: function(watchExp, listener, exceptionHandler) {
var watch = expressionCompile(watchExp),
last;
+ listener = expressionCompile(listener);
function watcher(){
var value = watch.call(instance),
lastValue = last;
if (last !== value) {
last = value;
- instance.$tryEval(listener, exceptionHandler, value, lastValue);
+ instance.$tryEval(function(){
+ return listener.call(instance, value, lastValue);
+ }, exceptionHandler);
}
}
instance.$onEval(PRIORITY_WATCH, watcher);
diff --git a/src/apis.js b/src/apis.js
index 306d0ce8..136473b6 100644
--- a/src/apis.js
+++ b/src/apis.js
@@ -12,7 +12,9 @@ var angularGlobal = {
};
var angularCollection = {
- 'size': size
+ 'copy': copy,
+ 'size': size,
+ 'equals': equals
};
var angularObject = {
'extend': extend
diff --git a/src/delete/Binder.js b/src/delete/Binder.js
deleted file mode 100644
index 9fc32513..00000000
--- a/src/delete/Binder.js
+++ /dev/null
@@ -1,356 +0,0 @@
-function Binder(doc, widgetFactory, datastore, location, config) {
- this.doc = doc;
- this.location = location;
- this.datastore = datastore;
- this.anchor = {};
- this.widgetFactory = widgetFactory;
- this.config = config || {};
- this.updateListeners = [];
-}
-
-Binder.parseBindings = function(string) {
- var results = [];
- var lastIndex = 0;
- var index;
- while((index = string.indexOf('{{', lastIndex)) > -1) {
- if (lastIndex < index)
- results.push(string.substr(lastIndex, index - lastIndex));
- lastIndex = index;
-
- index = string.indexOf('}}', index);
- index = index < 0 ? string.length : index + 2;
-
- results.push(string.substr(lastIndex, index - lastIndex));
- lastIndex = index;
- }
- if (lastIndex != string.length)
- results.push(string.substr(lastIndex, string.length - lastIndex));
- return results.length === 0 ? [ string ] : results;
-};
-
-Binder.hasBinding = function(string) {
- var bindings = Binder.parseBindings(string);
- return bindings.length > 1 || Binder.binding(bindings[0]) !== null;
-};
-
-Binder.binding = function(string) {
- var binding = string.replace(/\n/gm, ' ').match(/^\{\{(.*)\}\}$/);
- return binding ? binding[1] : null;
-};
-
-
-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() {
- 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];
- });
- foreach(anchorQuery, function(newValue, key) {
- self.anchor[key] = newValue;
- });
- },
-
- onUrlChange: function() {
- this.parseAnchor();
- this.updateView();
- },
-
- updateAnchor: function() {
- var url = this.location['get']() || "";
- 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.location['set'](url);
- return url;
- },
-
- updateView: function() {
- var start = new Date().getTime();
- var scope = jQuery(this.doc).scope();
- scope.clearInvalid();
- scope.updateView();
- var end = new Date().getTime();
- this.updateAnchor();
- foreach(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();
- }
- 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) {
- var self = this;
- this.docFindWithSelf("[ng-entity]").attr("ng-watch", function() {
- try {
- var jNode = jQuery(this);
- var decl = scope.entity(jNode.attr("ng-entity"), self.datastore);
- return decl + (jNode.attr('ng-watch') || "");
- } catch (e) {
- log(e);
- alert(e);
- }
- });
- },
-
- compile: function() {
- var jNode = jQuery(this.doc);
- 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);
- var scope = jNode.scope();
- try {
- 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));
- }
- scope.get('$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 = '&nbsp;' + part.substring(1);
- } else {
- newNode = document.createTextNode(part);
- }
- parent.insertBefore(newNode, node);
- }
- }
- parent.removeChild(node);
- }
- },
-
- 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);
- }
- }
- };
- },
-
- 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);
- }
- }
-
- 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;
- }
-
- 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('<select/>').append(jQuery(node).clone()).html();
- if (!html.match(/<option(\s.*\s|\s)value\s*=\s*.*>.*<\/\s*option\s*>/gi)) {
- if (Binder.hasBinding(node.text)) {
- jQuery(node).attr('ng-bind-attr', angular.toJson({'value':node.text}));
- } else {
- node.value = node.text;
- }
- }
- }
-
- var children = node.childNodes;
- for (var k = 0; k < children.length; k++) {
- this.precompileNode(children[k], path.concat(k), factories);
- }
- },
-
- ng_eval: function(node) {
- return new EvalUpdater(node, node.getAttribute('ng-eval'));
- },
-
- ng_bind: function(node) {
- return new BindUpdater(node, "{{" + node.getAttribute('ng-bind') + "}}");
- },
-
- ng_bind_attr: function(node) {
- return new BindAttrUpdater(node, fromJson(node.getAttribute('ng-bind-attr')));
- },
-
- ng_hide: function(node) {
- return new HideUpdater(node, node.getAttribute('ng-hide'));
- },
-
- ng_show: function(node) {
- return new ShowUpdater(node, node.getAttribute('ng-show'));
- },
-
- ng_class: function(node) {
- return new ClassUpdater(node, node.getAttribute('ng-class'));
- },
-
- ng_class_even: function(node) {
- return new ClassEvenUpdater(node, node.getAttribute('ng-class-even'));
- },
-
- ng_class_odd: function(node) {
- return new ClassOddUpdater(node, node.getAttribute('ng-class-odd'));
- },
-
- ng_style: function(node) {
- return new StyleUpdater(node, node.getAttribute('ng-style'));
- },
-
- ng_watch: function(node, scope) {
- scope.watch(node.getAttribute('ng-watch'));
- }
-};
diff --git a/src/delete/Model.js b/src/delete/Model.js
deleted file mode 100644
index b09efd0e..00000000
--- a/src/delete/Model.js
+++ /dev/null
@@ -1,65 +0,0 @@
-// Single $ is special and does not get searched
-// Double $$ is special an is client only (does not get sent to server)
-
-function Model(entity, initial) {
- this['$$entity'] = entity;
- this['$loadFrom'](initial||{});
- this['$entity'] = entity['title'];
- this['$migrate']();
-};
-
-Model.copyDirectFields = function(src, dst) {
- if (src === dst || !src || !dst) return;
- var isDataField = function(src, dst, field) {
- return (field.substring(0,2) !== '$$') &&
- (typeof src[field] !== 'function') &&
- (typeof dst[field] !== 'function');
- };
- for (var field in dst) {
- if (isDataField(src, dst, field))
- delete dst[field];
- }
- for (field in src) {
- if (isDataField(src, dst, field))
- dst[field] = src[field];
- }
-};
-
-extend(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/delete/Scope.js b/src/delete/Scope.js
deleted file mode 100644
index ae3f9f11..00000000
--- a/src/delete/Scope.js
+++ /dev/null
@@ -1,407 +0,0 @@
-function Scope(initialState, name) {
- var self = this;
- self.widgets = [];
- self.evals = [];
- self.watchListeners = {};
- self.name = name;
- initialState = initialState || {};
- var State = function(){};
- State.prototype = initialState;
- self.state = new State();
- extend(self.state, {
- '$parent': initialState,
- '$watch': bind(self, self.addWatchListener),
- '$eval': bind(self, self.eval),
- '$bind': bind(self, bind, self),
- // change name to autoEval?
- '$addEval': bind(self, self.addEval),
- '$updateView': bind(self, self.updateView)
- });
- if (name == "ROOT") {
- self.state['$root'] = self.state;
- }
-};
-
-Scope.expressionCache = {};
-Scope.getter = function(instance, path) {
- if (!path) return instance;
- var element = path.split('.');
- var key;
- var lastInstance = instance;
- var len = element.length;
- for ( var i = 0; i < len; i++) {
- key = element[i];
- if (!key.match(/^[\$\w][\$\w\d]*$/))
- throw "Expression '" + path + "' is not a valid expression for accesing variables.";
- if (instance) {
- lastInstance = instance;
- instance = instance[key];
- }
- if (_.isUndefined(instance) && key.charAt(0) == '$') {
- 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) {
- instance = _.bind(fn, lastInstance, lastInstance);
- return instance;
- }
- }
- }
- if (typeof instance === 'function' && !instance['$$factory']) {
- return bind(lastInstance, instance);
- }
- return instance;
-};
-
-Scope.setter = function(instance, path, value){
- var element = path.split('.');
- for ( var i = 0; element.length > 1; i++) {
- var key = element.shift();
- var newInstance = instance[key];
- if (!newInstance) {
- newInstance = {};
- instance[key] = newInstance;
- }
- instance = newInstance;
- }
- instance[element.shift()] = value;
- return value;
-};
-
-Scope.prototype = {
- // TODO: rename to update? or eval?
- updateView: function() {
- var self = this;
- this.fireWatchers();
- foreach(this.widgets, function(widget){
- self.evalWidget(widget, "", {}, function(){
- this.updateView(self);
- });
- });
- foreach(this.evals, bind(this, this.apply));
- },
-
- addWidget: function(controller) {
- if (controller) this.widgets.push(controller);
- },
-
- addEval: function(fn, listener) {
- // todo: this should take a function/string and a listener
- // todo: this is a hack, which will need to be cleaned up.
- var self = this,
- listenFn = listener || noop,
- expr = self.compile(fn);
- this.evals.push(function(){
- self.apply(listenFn, expr());
- });
- },
-
- 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;
- },
-
- 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 instance = this.state;
- return Scope.setter(instance, path, value);
- },
-
- setEval: function(expressionText, value) {
- this.eval(expressionText + "=" + toJson(value));
- },
-
- compile: function(exp) {
- if (isFunction(exp)) return bind(this.state, exp);
- var expFn = Scope.expressionCache[exp], self = this;
- if (!expFn) {
- var parser = new Parser(exp);
- expFn = parser.statements();
- parser.assertAllConsumed();
- Scope.expressionCache[exp] = expFn;
- }
- return function(context){
- context = context || {};
- context.self = self.state;
- context.scope = self;
- return expFn.call(self, context);
- };
- },
-
- eval: function(exp, context) {
-// log('Scope.eval', expressionText);
- return this.compile(exp)(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){
- var jsonError = toJson(e, true);
- error('Eval Widget Error:', jsonError);
- widget.hasError = true;
- jQuery(widget.view).
- addClass('ng-exception').
- attr('ng-error', jsonError);
- if (onFailure) {
- onFailure.apply(widget, [e, jsonError]);
- }
- return false;
- }
- },
-
- 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, self:this.state, '$element':element};
- return expression(self)(self, value);
- },
-
- entity: function(entityDeclaration, datastore) {
- var expression = new Parser(entityDeclaration).entityDeclaration();
- 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);
- },
-
- 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) {
- // TODO: clean me up!
- if (!isFunction(listener)) {
- listener = this.compile(listener);
- }
- var watcher = this.watchListeners[watchExpression];
- if (!watcher) {
- watcher = {listeners:[], expression:watchExpression};
- this.watchListeners[watchExpression] = watcher;
- }
- watcher.listeners.push(listener);
- },
-
- fireWatchers: function() {
- var self = this, 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;
- },
-
- apply: function(fn) {
- fn.apply(this.state, slice.call(arguments, 1, arguments.length));
- }
-};
-
-//////////////////////////////
-
-function getter(instance, path) {
- if (!path) return instance;
- var element = path.split('.');
- var key;
- var lastInstance = instance;
- var len = element.length;
- for ( var i = 0; i < len; i++) {
- key = element[i];
- if (!key.match(/^[\$\w][\$\w\d]*$/))
- throw "Expression '" + path + "' is not a valid expression for accesing variables.";
- if (instance) {
- lastInstance = instance;
- instance = instance[key];
- }
- if (_.isUndefined(instance) && key.charAt(0) == '$') {
- 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) {
- instance = _.bind(fn, lastInstance, lastInstance);
- return instance;
- }
- }
- }
- if (typeof instance === 'function' && !instance['$$factory']) {
- return bind(lastInstance, instance);
- }
- return instance;
-};
-
-function setter(instance, path, value){
- var element = path.split('.');
- for ( var i = 0; element.length > 1; i++) {
- var key = element.shift();
- var newInstance = instance[key];
- if (!newInstance) {
- newInstance = {};
- instance[key] = newInstance;
- }
- instance = newInstance;
- }
- instance[element.shift()] = value;
- return value;
-};
-
-var compileCache = {};
-function expressionCompile(exp){
- if (isFunction(exp)) return exp;
- var expFn = compileCache[exp];
- if (!expFn) {
- var parser = new Parser(exp);
- expFn = parser.statements();
- parser.assertAllConsumed();
- compileCache[exp] = expFn;
- }
- // return expFn
- // TODO(remove this hack)
- return function(){
- return expFn({
- scope: {
- set: this.$set,
- get: this.$get
- }
- });
- };
-};
-
-var NON_RENDERABLE_ELEMENTS = {
- '#text': 1, '#comment':1, 'TR':1, 'TH':1
-};
-
-function isRenderableElement(element){
- return element && element[0] && !NON_RENDERABLE_ELEMENTS[element[0].nodeName];
-}
-
-function rethrow(e) { throw e; }
-function errorHandlerFor(element) {
- while (!isRenderableElement(element)) {
- element = element.parent() || jqLite(document.body);
- }
- return function(error) {
- element.attr('ng-error', angular.toJson(error));
- element.addClass('ng-exception');
- };
-}
-
-function createScope(parent, Class) {
- function Parent(){}
- function API(){}
- function Behavior(){}
-
- var instance, behavior, api, watchList = [], evalList = [];
-
- Class = Class || noop;
- parent = Parent.prototype = parent || {};
- api = API.prototype = new Parent();
- behavior = Behavior.prototype = extend(new API(), Class.prototype);
- instance = new Behavior();
-
- extend(api, {
- $parent: parent,
- $bind: bind(instance, bind, instance),
- $get: bind(instance, getter, instance),
- $set: bind(instance, setter, instance),
-
- $eval: function(exp) {
- if (isDefined(exp)) {
- return expressionCompile(exp).apply(instance, slice.call(arguments, 1, arguments.length));
- } else {
- foreach(evalList, function(eval) {
- instance.$tryEval(eval.fn, eval.handler);
- });
- foreach(watchList, function(watch) {
- var value = instance.$tryEval(watch.watch, watch.handler);
- if (watch.last !== value) {
- instance.$tryEval(watch.listener, watch.handler, value, watch.last);
- watch.last = value;
- }
- });
- }
- },
-
- $tryEval: function (expression, exceptionHandler) {
- try {
- return expressionCompile(expression).apply(instance, slice.call(arguments, 2, arguments.length));
- } catch (e) {
- error(e);
- if (isFunction(exceptionHandler)) {
- exceptionHandler(e);
- } else if (exceptionHandler) {
- errorHandlerFor(exceptionHandler)(e);
- }
- }
- },
-
- $watch: function(watchExp, listener, exceptionHandler) {
- var watch = expressionCompile(watchExp);
- watchList.push({
- watch: watch,
- last: watch.call(instance),
- handler: exceptionHandler,
- listener:expressionCompile(listener)
- });
- },
-
- $onEval: function(expr, exceptionHandler){
- evalList.push({
- fn: expressionCompile(expr),
- handler: exceptionHandler
- });
- }
- });
-
- Class.apply(instance, slice.call(arguments, 2, arguments.length));
-
- return instance;
-}
diff --git a/src/delete/Widgets.js b/src/delete/Widgets.js
deleted file mode 100644
index 96b63793..00000000
--- a/src/delete/Widgets.js
+++ /dev/null
@@ -1,806 +0,0 @@
-function WidgetFactory(serverUrl, database) {
- this.nextUploadId = 0;
- this.serverUrl = serverUrl;
- this.database = database;
- if (window['swfobject']) {
- this.createSWF = window['swfobject']['createSWF'];
- } else {
- this.createSWF = function(){
- alert("ERROR: swfobject not loaded!");
- };
- }
-};
-
-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;
- var formatter = angularFormatter[input.attr('ng-format')] || angularFormatter['noop'];
- if (type == 'button' || type == 'submit' || type == 'reset' || type == 'image') {
- 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, formatter);
- event = "keyup change";
- } else if (type == 'checkbox') {
- controller = new CheckboxController(input[0], exp, formatter);
- event = "click";
- } else if (type == 'radio') {
- controller = new RadioController(input[0], exp, formatter);
- event="click";
- } else if (type == 'select-one') {
- controller = new SelectController(input[0], exp, formatter);
- } else if (type == 'select-multiple') {
- controller = new MultiSelectController(input[0], exp, formatter);
- } else if (type == 'file') {
- controller = this.createFileController(input, exp, formatter);
- } else {
- throw 'Unknown type: ' + type;
- }
- input.data('controller', controller);
- 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)) {
- 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).parent().data('controller', cntl);
- return cntl;
- }
-};
-/////////////////////
-// FileController
-///////////////////////
-
-function FileController(view, scopeName, uploader, databaseUrl) {
- this.view = view;
- this.uploader = uploader;
- this.scopeName = scopeName;
- this.attachmentsPath = databaseUrl + '/_attachments';
- this.value = null;
- this.lastValue = undefined;
-};
-
-angularCallbacks['flashEvent'] = function(id, event, args) {
- var object = document.getElementById(id);
- var jobject = jQuery(object);
- var controller = jobject.parent().data("controller");
- FileController.prototype[event].apply(controller, args);
- _.defer(jobject.scope().get('$updateView'));
-};
-
-FileController.template = function(id) {
- return jQuery('<span class="ng-upload-widget">' +
- '<input type="checkbox" ng-non-bindable="true"/>' +
- '<object id="' + id + '" />' +
- '<a></a>' +
- '<span/>' +
- '</span>');
-};
-
-extend(FileController.prototype, {
- 'cancel': noop,
- 'complete': noop,
- 'httpStatus': function(status) {
- alert("httpStatus:" + this.scopeName + " status:" + status);
- },
- 'ioError': function() {
- alert("ioError:" + this.scopeName);
- },
- 'open': function() {
- alert("open:" + this.scopeName);
- },
- 'progress':noop,
- 'securityError': function() {
- alert("securityError:" + this.scopeName);
- },
- '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;
- },
- '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
-///////////////////////
-function NullController(view) {this.view = view;};
-NullController.prototype = {
- updateModel: function() { return true; },
- updateView: noop
-};
-NullController.instance = new NullController();
-
-
-///////////////////////
-// ButtonController
-///////////////////////
-var ButtonController = NullController;
-
-///////////////////////
-// TextController
-///////////////////////
-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";
- this.lastErrorText = null;
- this.lastValue = undefined;
- this.initialValue = this.formatter['parse'](view.value);
- var widget = view.getAttribute('ng-widget');
- if (widget === 'datepicker') {
- jQuery(view).datepicker();
- }
-};
-
-TextController.prototype = {
- updateModel: function(scope) {
- var value = this.formatter['parse'](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).isEqual(value)) {
- view.value = this.formatter['format'](value);
- this.lastValue = value;
- }
-
- var isValidationError = false;
- view.removeAttribute('ng-error');
- if (this.required) {
- isValidationError = !(value && $.trim("" + value).length > 0);
- }
- var errorText = isValidationError ? "Required Value" : null;
- if (!isValidationError && this.validator && value) {
- errorText = scope.validate(this.validator, value, view);
- isValidationError = !!errorText;
- }
- if (this.lastErrorText !== errorText) {
- this.lastErrorText = isValidationError;
- if (errorText && isVisible(view)) {
- view.setAttribute('ng-error', errorText);
- scope.markInvalid(this);
- }
- jQuery(view).toggleClass('ng-validation-error', isValidationError);
- }
- }
-};
-
-///////////////////////
-// CheckboxController
-///////////////////////
-function CheckboxController(view, exp, formatter) {
- this.view = view;
- this.exp = exp;
- this.lastValue = undefined;
- this.formatter = formatter;
- this.initialValue = this.formatter['parse'](view.checked ? view.value : "");
-};
-
-CheckboxController.prototype = {
- updateModel: function(scope) {
- 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 {
- scope.setEval(this.exp, this.formatter['parse'](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 = this.formatter['parse'](input.value) == value;
- }
-};
-
-///////////////////////
-// SelectController
-///////////////////////
-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;
- } 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;
- }
- }
-};
-
-///////////////////////
-// MultiSelectController
-///////////////////////
-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;
- },
-
- 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;
- }
- }
-};
-
-///////////////////////
-// RadioController
-///////////////////////
-function RadioController(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;
-};
-
-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
-///////////////////////
-function BindUpdater(view, exp) {
- this.view = view;
- this.exp = Binder.parseBindings(exp);
- this.hasError = false;
-};
-
-BindUpdater.toText = function(obj) {
- var e = escapeHtml;
- switch(typeof obj) {
- case "string":
- case "boolean":
- case "number":
- return e(obj);
- case "function":
- return BindUpdater.toText(obj());
- case "object":
- if (isNode(obj)) {
- return outerHTML(obj);
- } else if (obj instanceof angular.filter.Meta) {
- switch(typeof obj.html) {
- case "string":
- case "number":
- return obj.html;
- case "function":
- return obj.html();
- case "object":
- if (isNode(obj.html))
- return outerHTML(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(toJson(obj, true));
- default:
- return "";
- }
-};
-
-BindUpdater.prototype = {
- updateModel: noop,
- updateView: function(scope) {
- var html = [];
- var parts = this.exp;
- var length = parts.length;
- for(var i=0; i<length; i++) {
- var part = parts[i];
- var binding = Binder.binding(part);
- if (binding) {
- scope.evalWidget(this, binding, {$element:this.view}, function(value){
- html.push(BindUpdater.toText(value));
- }, function(e, text){
- setHtml(this.view, text);
- });
- if (this.hasError) {
- return;
- }
- } else {
- html.push(escapeHtml(part));
- }
- }
- setHtml(this.view, html.join(''));
- }
-};
-
-function BindAttrUpdater(view, attrs) {
- this.view = view;
- this.attrs = attrs;
-};
-
-BindAttrUpdater.prototype = {
- updateModel: noop,
- updateView: function(scope) {
- var jNode = jQuery(this.view);
- var attributeTemplates = this.attrs;
- if (this.hasError) {
- this.hasError = false;
- jNode.
- removeClass('ng-exception').
- removeAttr('ng-error');
- }
- var isImage = jNode.is('img');
- for (var attrName in attributeTemplates) {
- var attributeTemplate = Binder.parseBindings(attributeTemplates[attrName]);
- var attrValues = [];
- for ( var i = 0; i < attributeTemplate.length; i++) {
- var binding = Binder.binding(attributeTemplate[i]);
- if (binding) {
- try {
- var value = scope.eval(binding, {$element:jNode[0], attrName:attrName});
- if (value && (value.constructor !== array || value.length !== 0))
- attrValues.push(value);
- } catch (e) {
- this.hasError = true;
- error('BindAttrUpdater', e);
- var jsonError = toJson(e, true);
- attrValues.push('[' + jsonError + ']');
- jNode.
- addClass('ng-exception').
- attr('ng-error', jsonError);
- }
- } else {
- attrValues.push(attributeTemplate[i]);
- }
- }
- var attrValue = attrValues.length ? attrValues.join('') : null;
- if(isImage && attrName == 'src' && !attrValue)
- attrValue = scope.get('$config.blankImage');
- jNode.attr(attrName, attrValue);
- }
- }
-};
-
-function EvalUpdater(view, exp) {
- this.view = view;
- this.exp = exp;
- this.hasError = false;
-};
-EvalUpdater.prototype = {
- updateModel: noop,
- updateView: function(scope) {
- scope.evalWidget(this, this.exp);
- }
-};
-
-function HideUpdater(view, exp) { this.view = view; this.exp = exp; };
-HideUpdater.prototype = {
- updateModel: noop,
- updateView: function(scope) {
- scope.evalWidget(this, this.exp, {}, function(hideValue){
- var view = jQuery(this.view);
- if (toBoolean(hideValue)) {
- view.hide();
- } else {
- view.show();
- }
- });
- }
-};
-
-function ShowUpdater(view, exp) { this.view = view; this.exp = exp; };
-ShowUpdater.prototype = {
- updateModel: noop,
- updateView: function(scope) {
- scope.evalWidget(this, this.exp, {}, function(hideValue){
- var view = jQuery(this.view);
- if (toBoolean(hideValue)) {
- view.show();
- } else {
- view.hide();
- }
- });
- }
-};
-
-function ClassUpdater(view, exp) { this.view = view; this.exp = exp; };
-ClassUpdater.prototype = {
- updateModel: noop,
- updateView: function(scope) {
- scope.evalWidget(this, this.exp, {}, function(classValue){
- if (classValue !== null && classValue !== undefined) {
- this.view.className = classValue;
- }
- });
- }
-};
-
-function ClassEvenUpdater(view, exp) { this.view = view; this.exp = exp; };
-ClassEvenUpdater.prototype = {
- updateModel: noop,
- updateView: function(scope) {
- scope.evalWidget(this, this.exp, {}, function(classValue){
- var index = scope.get('$index');
- jQuery(this.view).toggleClass(classValue, index % 2 === 1);
- });
- }
-};
-
-function ClassOddUpdater(view, exp) { this.view = view; this.exp = exp; };
-ClassOddUpdater.prototype = {
- updateModel: noop,
- updateView: function(scope) {
- scope.evalWidget(this, this.exp, {}, function(classValue){
- var index = scope.get('$index');
- jQuery(this.view).toggleClass(classValue, index % 2 === 0);
- });
- }
-};
-
-function StyleUpdater(view, exp) { this.view = view; this.exp = exp; };
-StyleUpdater.prototype = {
- updateModel: noop,
- updateView: function(scope) {
- scope.evalWidget(this, this.exp, {}, function(styleValue){
- jQuery(this.view).attr('style', "").css(styleValue);
- });
- }
-};
-
-///////////////////////
-// RepeaterUpdater
-///////////////////////
-function RepeaterUpdater(view, repeaterExpression, template, prefix) {
- this.view = view;
- this.template = template;
- this.prefix = prefix;
- this.children = [];
- var match = repeaterExpression.match(/^\s*(.+)\s+in\s+(.*)\s*$/);
- if (! match) {
- throw "Expected ng-repeat in form of 'item in collection' but got '" +
- repeaterExpression + "'.";
- }
- var keyValue = match[1];
- this.iteratorExp = match[2];
- match = keyValue.match(/^([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\)$/);
- if (!match) {
- throw "'item' in 'item in collection' should be identifier or (key, value) but get '" +
- keyValue + "'.";
- }
- this.valueExp = match[3] || match[1];
- this.keyExp = match[2];
-};
-
-RepeaterUpdater.prototype = {
- updateModel: noop,
- updateView: function(scope) {
- scope.evalWidget(this, this.iteratorExp, {}, function(iterator){
- var self = this;
- if (!iterator) {
- iterator = [];
- if (scope.isProperty(this.iteratorExp)) {
- scope.set(this.iteratorExp, iterator);
- }
- }
- var childrenLength = this.children.length;
- var cursor = this.view;
- var time = 0;
- var child = null;
- var keyExp = this.keyExp;
- var valueExp = this.valueExp;
- var iteratorCounter = 0;
- foreach(iterator, function(value, key){
- if (iteratorCounter < childrenLength) {
- // reuse children
- child = self.children[iteratorCounter];
- child.scope.set(valueExp, value);
- } else {
- // grow children
- var name = self.prefix +
- valueExp + " in " + self.iteratorExp + "[" + iteratorCounter + "]";
- var childScope = new Scope(scope.state, name);
- childScope.set('$index', iteratorCounter);
- if (keyExp)
- childScope.set(keyExp, key);
- childScope.set(valueExp, value);
- child = { scope:childScope, element:self.template(childScope, self.prefix, iteratorCounter) };
- cursor.after(child.element);
- self.children.push(child);
- }
- cursor = child.element;
- var s = new Date().getTime();
- child.scope.updateView();
- time += new Date().getTime() - s;
- iteratorCounter++;
- });
- // shrink children
- for ( var r = childrenLength; r > iteratorCounter; --r) {
- this.children.pop().element.remove();
- }
- // 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
-//////////////////////////////////
-
-function PopUp(doc) {
- this.doc = doc;
-};
-
-PopUp.OUT_EVENT = "mouseleave mouseout click dblclick keypress keyup";
-
-PopUp.onOver = function(e) {
- PopUp.onOut();
- var jNode = jQuery(this);
- jNode.bind(PopUp.OUT_EVENT, 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(
- "<div id='ng-callout' style='width:"+width+"px'>" +
- "<div class='ng-arrow-"+arrowPos+"'/>" +
- "<div class='ng-title'>"+title+"</div>" +
- "<div class='ng-content'>"+msg+"</div>" +
- "</div>");
- 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;
-};
-
-PopUp.onOut = function() {
- jQuery('#ng-callout').
- unbind(PopUp.OUT_EVENT, PopUp.onOut).
- remove();
- return true;
-};
-
-PopUp.prototype = {
- bind: function () {
- var self = this;
- this.doc.find('.ng-validation-error,.ng-exception').
- live("mouseover", PopUp.onOver);
- }
-};
-
-//////////////////////////////////
-// Status
-//////////////////////////////////
-
-function NullStatus(body) {
-};
-
-NullStatus.prototype = {
- beginRequest:function(){},
- endRequest:function(){}
-};
-
-function Status(body) {
- this.requestCount = 0;
- this.body = body;
-};
-
-Status.DOM ='<div id="ng-spacer"></div><div id="ng-loading">loading....</div>';
-
-Status.prototype = {
- beginRequest: function () {
- if (this.requestCount === 0) {
- (this.loader = this.loader || this.body.append(Status.DOM).find("#ng-loading")).show();
- }
- this.requestCount++;
- },
-
- endRequest: function () {
- this.requestCount--;
- if (this.requestCount === 0) {
- this.loader.hide("fold");
- }
- }
-};
diff --git a/src/directives.js b/src/directives.js
index cabf0c23..ffe37890 100644
--- a/src/directives.js
+++ b/src/directives.js
@@ -1,10 +1,10 @@
-angularDirective("ng-init", function(expression){
+angularDirective("ng:init", function(expression){
return function(element){
this.$tryEval(expression, element);
};
});
-angularDirective("ng-controller", function(expression){
+angularDirective("ng:controller", function(expression){
return function(element){
var controller = getter(window, expression, true) || getter(this, expression, true);
if (!controller)
@@ -16,22 +16,23 @@ angularDirective("ng-controller", function(expression){
};
});
-angularDirective("ng-eval", function(expression){
+angularDirective("ng:eval", function(expression){
return function(element){
this.$onEval(expression, element);
};
});
-angularDirective("ng-bind", function(expression){
+angularDirective("ng:bind", function(expression){
return function(element) {
var lastValue = noop, lastError = noop;
this.$onEval(function() {
- var error,
- value = this.$tryEval(expression, function(e){
- error = toJson(e);
- }),
- isHtml,
- isDomElement;
+ var error, value, isHtml, isDomElement,
+ oldElement = this.hasOwnProperty('$element') ? this.$element : undefined;
+ this.$element = element;
+ value = this.$tryEval(expression, function(e){
+ error = toJson(e);
+ });
+ this.$element = oldElement;
if (lastValue === value && lastError == error) return;
isHtml = value instanceof HTML,
isDomElement = isElement(value);
@@ -74,7 +75,9 @@ function compileBindTemplate(template){
});
});
bindTemplateCache[template] = fn = function(element){
- var parts = [], self = this;
+ var parts = [], self = this,
+ oldElement = this.hasOwnProperty('$element') ? self.$element : undefined;
+ self.$element = element;
for ( var i = 0; i < bindings.length; i++) {
var value = bindings[i].call(self, element);
if (isElement(value))
@@ -83,13 +86,14 @@ function compileBindTemplate(template){
value = toJson(value, true);
parts.push(value);
};
+ self.$element = oldElement;
return parts.join('');
};
}
return fn;
}
-angularDirective("ng-bind-template", function(expression){
+angularDirective("ng:bind-template", function(expression){
var templateFn = compileBindTemplate(expression);
return function(element) {
var lastValue;
@@ -108,7 +112,7 @@ var REMOVE_ATTRIBUTES = {
'readonly':'readOnly',
'checked':'checked'
};
-angularDirective("ng-bind-attr", function(expression){
+angularDirective("ng:bind-attr", function(expression){
return function(element){
var lastValue = {};
this.$onEval(function(){
@@ -134,17 +138,17 @@ angularDirective("ng-bind-attr", function(expression){
};
});
-angularWidget("@ng-non-bindable", noop);
+angularWidget("@ng:non-bindable", noop);
-angularWidget("@ng-repeat", function(expression, element){
- element.removeAttr('ng-repeat');
- element.replaceWith(this.comment("ng-repeat: " + expression));
+angularWidget("@ng:repeat", function(expression, element){
+ element.removeAttr('ng:repeat');
+ element.replaceWith(this.comment("ng:repeat: " + expression));
var template = this.compile(element);
return function(reference){
var match = expression.match(/^\s*(.+)\s+in\s+(.*)\s*$/),
lhs, rhs, valueIdent, keyIdent;
if (! match) {
- throw "Expected ng-repeat in form of 'item in collection' but got '" +
+ throw "Expected ng:repeat in form of 'item in collection' but got '" +
expression + "'.";
}
lhs = match[1];
@@ -157,32 +161,32 @@ angularWidget("@ng-repeat", function(expression, element){
valueIdent = match[3] || match[1];
keyIdent = match[2];
- if (isUndefined(this.$eval(rhs))) this.$set(rhs, []);
-
var children = [], currentScope = this;
this.$onEval(function(){
var index = 0, childCount = children.length, childScope, lastElement = reference,
- collection = this.$tryEval(rhs, reference);
+ collection = this.$tryEval(rhs, reference), is_array = isArray(collection);
for ( var key in collection) {
- if (index < childCount) {
- // reuse existing child
- childScope = children[index];
- childScope[valueIdent] = collection[key];
- if (keyIdent) childScope[keyIdent] = key;
- } else {
- // grow children
- childScope = template(element.clone(), createScope(currentScope));
- childScope[valueIdent] = collection[key];
- if (keyIdent) childScope[keyIdent] = key;
- lastElement.after(childScope.$element);
- childScope.$index = index;
- childScope.$element.attr('ng-repeat-index', index);
- childScope.$init();
- children.push(childScope);
+ if (!is_array || collection.hasOwnProperty(key)) {
+ if (index < childCount) {
+ // reuse existing child
+ childScope = children[index];
+ childScope[valueIdent] = collection[key];
+ if (keyIdent) childScope[keyIdent] = key;
+ } else {
+ // grow children
+ childScope = template(element.clone(), createScope(currentScope));
+ childScope[valueIdent] = collection[key];
+ if (keyIdent) childScope[keyIdent] = key;
+ lastElement.after(childScope.$element);
+ childScope.$index = index;
+ childScope.$element.attr('ng:repeat-index', index);
+ childScope.$init();
+ children.push(childScope);
+ }
+ childScope.$eval();
+ lastElement = childScope.$element;
+ index ++;
}
- childScope.$eval();
- lastElement = childScope.$element;
- index ++;
};
// shrink children
while(children.length > index) {
@@ -192,7 +196,7 @@ angularWidget("@ng-repeat", function(expression, element){
};
});
-angularDirective("ng-click", function(expression, element){
+angularDirective("ng:click", function(expression, element){
return function(element){
var self = this;
element.bind('click', function(){
@@ -203,7 +207,7 @@ angularDirective("ng-click", function(expression, element){
};
});
-angularDirective("ng-watch", function(expression, element){
+angularDirective("ng:watch", function(expression, element){
return function(element){
var self = this;
new Parser(expression).watch()({
@@ -221,8 +225,8 @@ function ngClass(selector) {
var existing = element[0].className + ' ';
return function(element){
this.$onEval(function(){
- var value = this.$eval(expression);
if (selector(this.$index)) {
+ var value = this.$eval(expression);
if (isArray(value)) value = value.join(' ');
element[0].className = trim(existing + value);
}
@@ -231,11 +235,11 @@ function ngClass(selector) {
};
}
-angularDirective("ng-class", ngClass(function(){return true;}));
-angularDirective("ng-class-odd", ngClass(function(i){return i % 2 === 0;}));
-angularDirective("ng-class-even", ngClass(function(i){return i % 2 === 1;}));
+angularDirective("ng:class", ngClass(function(){return true;}));
+angularDirective("ng:class-odd", ngClass(function(i){return i % 2 === 0;}));
+angularDirective("ng:class-even", ngClass(function(i){return i % 2 === 1;}));
-angularDirective("ng-show", function(expression, element){
+angularDirective("ng:show", function(expression, element){
return function(element){
this.$onEval(function(){
element.css('display', toBoolean(this.$eval(expression)) ? '' : 'none');
@@ -243,7 +247,7 @@ angularDirective("ng-show", function(expression, element){
};
});
-angularDirective("ng-hide", function(expression, element){
+angularDirective("ng:hide", function(expression, element){
return function(element){
this.$onEval(function(){
element.css('display', toBoolean(this.$eval(expression)) ? 'none' : '');
@@ -251,10 +255,19 @@ angularDirective("ng-hide", function(expression, element){
};
});
-angularDirective("ng-style", function(expression, element){
+angularDirective("ng:style", function(expression, element){
return function(element){
+ var resetStyle = getStyle(element);
this.$onEval(function(){
- element.css(this.$eval(expression));
+ var style = this.$eval(expression) || {}, key, mergedStyle = {};
+ for(key in style) {
+ if (resetStyle[key] === undefined) resetStyle[key] = '';
+ mergedStyle[key] = style[key];
+ }
+ for(key in resetStyle) {
+ mergedStyle[key] = mergedStyle[key] || resetStyle[key];
+ }
+ element.css(mergedStyle);
}, element);
};
});
diff --git a/src/filters.js b/src/filters.js
index a911b935..99d17405 100644
--- a/src/filters.js
+++ b/src/filters.js
@@ -2,7 +2,7 @@ var angularFilterGoogleChartApi;
foreach({
'currency': function(amount){
- this.$element.toggleClass('ng-format-negative', amount < 0);
+ this.$element.toggleClass('ng:format-negative', amount < 0);
return '$' + angularFilter['number'].apply(this, [amount, 2]);
},
@@ -34,7 +34,11 @@ foreach({
return text;
},
- 'date': function(amount) {
+ 'date': function(date) {
+ if (date instanceof Date)
+ return date.toLocaleDateString();
+ else
+ return date;
},
'json': function(object) {
diff --git a/src/jqLite.js b/src/jqLite.js
index 68172fd8..cff9ae00 100644
--- a/src/jqLite.js
+++ b/src/jqLite.js
@@ -36,6 +36,23 @@ function jqClearData(element) {
}
}
+function getStyle(element) {
+ var current = {}, style = element[0].style, value, name, i;
+ if (typeof style.length == 'number') {
+ for(i = 0; i < style.length; i++) {
+ name = style[i];
+ current[name] = style[name];
+ }
+ } else {
+ for (name in style) {
+ value = style[name];
+ if (1*name != name && name != 'cssText' && value && typeof value == 'string' && value !='false')
+ current[name] = value;
+ }
+ }
+ return current;
+}
+
function JQLite(element) {
if (isElement(element)) {
this[0] = element;
diff --git a/src/markups.js b/src/markups.js
index 74b293b8..ac2b5636 100644
--- a/src/markups.js
+++ b/src/markups.js
@@ -32,14 +32,14 @@ angularTextMarkup('{{}}', function(text, textNode, parentElement) {
self = this;
if (hasBindings(bindings)) {
if (isLeafNode(parentElement[0])) {
- parentElement.attr('ng-bind-template', text);
+ parentElement.attr('ng:bind-template', text);
} else {
var cursor = textNode, newElement;
foreach(parseBindings(text), function(text){
var exp = binding(text);
if (exp) {
newElement = self.element('span');
- newElement.attr('ng-bind', exp);
+ newElement.attr('ng:bind', exp);
} else {
newElement = self.text(text);
}
@@ -68,18 +68,18 @@ angularTextMarkup('OPTION', function(text, textNode, parentElement){
}
});
-var NG_BIND_ATTR = 'ng-bind-attr';
+var NG_BIND_ATTR = 'ng:bind-attr';
angularAttrMarkup('{{}}', function(value, name, element){
- if (name.substr(0, 3) != 'ng-') {
- if (msie && name == 'src')
- value = decodeURI(value);
- var bindings = parseBindings(value),
- bindAttr;
- if (hasBindings(bindings)) {
- element.removeAttr(name);
- bindAttr = fromJson(element.attr(NG_BIND_ATTR) || "{}");
- bindAttr[name] = value;
- element.attr(NG_BIND_ATTR, toJson(bindAttr));
- }
+ // don't process existing attribute markup
+ if (angularDirective(name) || angularDirective("@" + name)) return;
+ if (msie && name == 'src')
+ value = decodeURI(value);
+ var bindings = parseBindings(value),
+ bindAttr;
+ if (hasBindings(bindings)) {
+ element.removeAttr(name);
+ bindAttr = fromJson(element.attr(NG_BIND_ATTR) || "{}");
+ bindAttr[name] = value;
+ element.attr(NG_BIND_ATTR, toJson(bindAttr));
}
});
diff --git a/src/moveToAngularCom/ControlBar.js b/src/moveToAngularCom/ControlBar.js
deleted file mode 100644
index 685beeb2..00000000
--- a/src/moveToAngularCom/ControlBar.js
+++ /dev/null
@@ -1,72 +0,0 @@
-function ControlBar(document, serverUrl, database) {
- this._document = document;
- this.serverUrl = serverUrl;
- this.database = database;
- this._window = window;
- this.callbacks = [];
-};
-
-ControlBar.HTML =
- '<div>' +
- '<div class="ui-widget-overlay"></div>' +
- '<div id="ng-login" ng-non-bindable="true">' +
- '<div class="ng-login-container"></div>' +
- '</div>' +
- '</div>';
-
-
-ControlBar.FORBIDEN =
- '<div ng-non-bindable="true" title="Permission Error:">' +
- 'Sorry, you do not have permission for this!'+
- '</div>';
-
-ControlBar.prototype = {
- bind: function () {
- },
-
- login: function (loginSubmitFn) {
- this.callbacks.push(loginSubmitFn);
- if (this.callbacks.length == 1) {
- this.doTemplate("/user_session/new.mini?database="+encodeURIComponent(this.database)+"&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() + "#$iframe_notify=" + id;
- var iframeHeight = 330;
- var loginView = jQuery('<div style="overflow:hidden; padding:2px 0 0 0;"><iframe name="'+ url +'" src="'+this.serverUrl + path + '" width="500" height="'+ iframeHeight +'"/></div>');
- this._document.append(loginView);
- loginView['dialog']({
- 'height':iframeHeight + 33, 'width':500,
- 'resizable': false, 'modal':true,
- 'title': 'Authentication: <a href="http://www.getangular.com"><tt>&lt;angular/&gt;</tt></a>'
- });
- angularCallbacks["_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/moveToAngularCom/DataStore.js b/src/moveToAngularCom/DataStore.js
deleted file mode 100644
index 70bcc623..00000000
--- a/src/moveToAngularCom/DataStore.js
+++ /dev/null
@@ -1,330 +0,0 @@
-function DataStore(post, users, anchor) {
- this.post = post;
- this.users = users;
- this._cache_collections = [];
- this._cache = {'$collections':this._cache_collections};
- this.anchor = anchor;
- this.bulkRequest = [];
-};
-
-DataStore.NullEntity = extend(function(){}, {
- 'all': function(){return [];},
- 'query': function(){return [];},
- 'load': function(){return {};},
- 'title': undefined
-});
-
-DataStore.prototype = {
- cache: function(document) {
- if (! document.datastore === this) {
- 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;
- },
-
- 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;
- },
-
- 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;
- }
- });
- },
-
- 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)) {
- angularArray['includeIf'](collection, cachedDoc, true);
- }
- });
- if (document['$$anchor']) {
- self.anchor[document['$$anchor']] = document['$id'];
- }
- if (callback)
- callback(document);
- });
- },
-
- 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);
- }
- }
- });
- (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['$$callback'](response);
- }
- }
- }
- }
- this.post(bulkRequest, callback);
- },
-
- 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();
- },
-
- 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;
- foreach(list, function(item){
- var document = type()['$loadFrom'](item);
- queryList.push(self.cache(document));
- });
- (callback||noop)(queryList);
- });
- return queryList;
- },
-
- entities: function(callback) {
- var entities = [];
- var self = this;
- this._jsonRequest(["GET", "$entities"], function(response) {
- foreach(response, function(value, entityName){
- entities.push(self.entity(entityName));
- });
- entities.sort(function(a,b){return a.title > b.title ? 1 : -1;});
- (callback||noop)(entities);
- });
- return entities;
- },
-
- documentCountsByUser: function(){
- var counts = {};
- var self = this;
- self.post([["GET", "$users"]], function(code, response){
- extend(counts, response[0]);
- });
- return counts;
- },
-
- userDocumentIdsByEntity: function(user){
- var ids = {};
- var self = this;
- self.post([["GET", "$users/" + user]], function(code, response){
- extend(ids, response[0]);
- });
- 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, //private, obfuscate
- '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){
- var row = {};
- joinedResult.push(row);
- row[baseName] = doc;
- var id = Scope.getter(row, nextJoinOn);
- 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;
- }
-};
diff --git a/src/moveToAngularCom/Server.js b/src/moveToAngularCom/Server.js
deleted file mode 100644
index 5c4ec3c6..00000000
--- a/src/moveToAngularCom/Server.js
+++ /dev/null
@@ -1,68 +0,0 @@
-function Server(url, getScript) {
- this.url = url;
- this.nextId = 0;
- this.getScript = getScript;
- this.uuid = "_" + ("" + Math.random()).substr(2) + "_";
- this.maxSize = 1800;
-};
-
-Server.prototype = {
- base64url: function(txt) {
- return Base64.encode(txt);
- },
-
- 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);
- };
- for ( var pocketNo = 0; pocketNo < totalPockets; pocketNo++) {
- var pocket = payload.substr(pocketNo * this.maxSize, this.maxSize);
- this.getScript(baseUrl + (pocketNo+1) + "?h=" + pocket, noop);
- }
- }
-};
-
-function FrameServer(frame) {
- this.frame = frame;
-};
-FrameServer.PREFIX = "$DATASET:";
-
-FrameServer.prototype = {
- read:function(){
- this.data = fromJson(this.frame.name.substr(FrameServer.PREFIX.length));
- },
- write:function(){
- this.frame.name = FrameServer.PREFIX + toJson(this.data);
- },
- request: function(method, url, request, callback) {
- //alert(method + " " + url + " " + toJson(request) + " " + toJson(callback));
- }
-};
-
-
-function VisualServer(delegate, status, update) {
- this.delegate = delegate;
- this.update = update;
- this.status = status;
-};
-
-VisualServer.prototype = {
- request:function(method, url, request, callback) {
- var self = this;
- this.status.beginRequest(request);
- this.delegate.request(method, url, request, function() {
- self.status.endRequest();
- try {
- callback.apply(this, arguments);
- } catch (e) {
- alert(toJson(e));
- }
- self.update();
- });
- }
-};
diff --git a/src/moveToAngularCom/Users.js b/src/moveToAngularCom/Users.js
deleted file mode 100644
index fb5845d3..00000000
--- a/src/moveToAngularCom/Users.js
+++ /dev/null
@@ -1,35 +0,0 @@
-function Users(server, controlBar) {
- this.server = server;
- this.controlBar = controlBar;
-};
-
-extend(Users.prototype, {
- 'fetchCurrentUser':function(callback) {
- var self = this;
- this.server.request("GET", "/account.json", {}, function(code, response){
- self['current'] = response['user'];
- callback(response['user']);
- });
- },
-
- 'logout': function(callback) {
- var self = this;
- this.controlBar.logout(function(){
- delete self['current'];
- (callback||noop)();
- });
- },
-
- 'login': function(callback) {
- var self = this;
- this.controlBar.login(function(){
- self['fetchCurrentUser'](function(){
- (callback||noop)();
- });
- });
- },
-
- 'notAuthorized': function(){
- this.controlBar.notAuthorized();
- }
-});
diff --git a/src/moveToAngularCom/directivesAngularCom.js b/src/moveToAngularCom/directivesAngularCom.js
deleted file mode 100644
index 84032bdd..00000000
--- a/src/moveToAngularCom/directivesAngularCom.js
+++ /dev/null
@@ -1,29 +0,0 @@
-
-angular.directive("auth", function(expression, element){
- return function(){
- if(expression == "eager") {
- this.$users.fetchCurrent();
- }
- };
-});
-
-
-//expression = "book=Book:{year=2000}"
-angular.directive("entity", function(expression, element){
- //parse expression, ignore element
- var entityName; // "Book";
- var instanceName; // "book";
- var defaults; // {year: 2000};
-
- parse(expression);
-
- return function(){
- this[entityName] = this.$datastore.entity(entityName, defaults);
- this[instanceName] = this[entityName]();
- this.$watch("$anchor."+instanceName, function(newAnchor){
- this[instanceName] = this[entityName].get(this.$anchor[instanceName]);
- });
- };
-});
-
-
diff --git a/src/scenario/DSL.js b/src/scenario/DSL.js
index bcf2b6c5..fcadd3ca 100644
--- a/src/scenario/DSL.js
+++ b/src/scenario/DSL.js
@@ -35,9 +35,8 @@ angular.scenario.dsl.input = function(selector) {
value + "'", function(done){
var input = this.testDocument.
find(':radio[name$=@' + selector + '][value=' + value + ']');
- var event = this.testWindow.document.createEvent('MouseEvent');
- event.initMouseEvent('click', true, true, this.testWindow, 0,0,0,0,0, false, false, false, false, 0, null);
- input[0].dispatchEvent(event);
+ jqLiteWrap(input[0]).trigger('click');
+ input[0].checked = true;
done();
});
}
diff --git a/src/services.js b/src/services.js
index 64f2ea4f..106f8954 100644
--- a/src/services.js
+++ b/src/services.js
@@ -65,18 +65,24 @@ angularService("$location", function(browser){
}, {inject: ['$browser']});
angularService("$log", function($window){
- var console = $window.console,
- log = console && console.log || noop;
+ var console = $window.console || {log: noop, warn: noop, info: noop, error: noop},
+ log = console.log || noop;
return {
- log: log,
- warn: console && console.warn || log,
- info: console && console.info || log,
- error: console && console.error || log
+ log: bind(console, log),
+ warn: bind(console, console.warn || log),
+ info: bind(console, console.info || log),
+ error: bind(console, console.error || log)
};
}, {inject:['$window']});
-angularService("$hover", function(browser) {
- var tooltip, self = this, error, width = 300, arrowWidth = 10;
+angularService('$exceptionHandler', function($log){
+ return function(e) {
+ $log.error(e);
+ };
+}, {inject:['$log']});
+
+angularService("$hover", function(browser, document) {
+ var tooltip, self = this, error, width = 300, arrowWidth = 10, body = jqLite(document[0].body);;
browser.hover(function(element, show){
if (show && (error = element.attr(NG_EXCEPTION) || element.attr(NG_VALIDATION_ERROR))) {
if (!tooltip) {
@@ -89,9 +95,9 @@ angularService("$hover", function(browser) {
tooltip.callout.append(tooltip.arrow);
tooltip.callout.append(tooltip.title);
tooltip.callout.append(tooltip.content);
- self.$browser.body.append(tooltip.callout);
+ body.append(tooltip.callout);
}
- var docRect = self.$browser.body[0].getBoundingClientRect(),
+ var docRect = body[0].getBoundingClientRect(),
elementRect = element[0].getBoundingClientRect(),
leftSpace = docRect.right - elementRect.right - arrowWidth;
tooltip.title.text(element.hasClass("ng-exception") ? "EXCEPTION:" : "Validation error...");
@@ -119,7 +125,7 @@ angularService("$hover", function(browser) {
tooltip = null;
}
});
-}, {inject:['$browser']});
+}, {inject:['$browser', '$document']});
angularService("$invalidWidgets", function(){
var invalidWidgets = [];
@@ -313,7 +319,7 @@ angularService('$xhr.bulk', function($xhr, $error, $log){
angularService('$xhr.cache', function($xhr){
var inflight = {}, self = this;;
- function cache(method, url, post, callback, cacheThenRetrieve){
+ function cache(method, url, post, callback, verifyCache){
if (isFunction(post)) {
callback = post;
post = null;
@@ -322,7 +328,7 @@ angularService('$xhr.cache', function($xhr){
var data;
if (data = cache.data[url]) {
callback(200, copy(data.value));
- if (!cacheThenRetrieve)
+ if (!verifyCache)
return;
}
diff --git a/src/widgets.js b/src/widgets.js
index efafa9c5..5f0fcf7c 100644
--- a/src/widgets.js
+++ b/src/widgets.js
@@ -15,7 +15,7 @@ function modelAccessor(scope, element) {
function modelFormattedAccessor(scope, element) {
var accessor = modelAccessor(scope, element),
- formatterName = element.attr('ng-format') || NOOP,
+ formatterName = element.attr('ng:format') || NOOP,
formatter = angularFormatter(formatterName);
if (!formatter) throw "Formatter named '" + formatterName + "' not found.";
return {
@@ -33,10 +33,10 @@ function compileValidator(expr) {
}
function valueAccessor(scope, element) {
- var validatorName = element.attr('ng-validate') || NOOP,
+ var validatorName = element.attr('ng:validate') || NOOP,
validator = compileValidator(validatorName),
- requiredExpr = element.attr('ng-required'),
- formatterName = element.attr('ng-format') || NOOP,
+ requiredExpr = element.attr('ng:required'),
+ formatterName = element.attr('ng:format') || NOOP,
formatter = angularFormatter(formatterName),
format, parse, lastError, required;
invalidWidgets = scope.$invalidWidgets || {markValid:noop, markInvalid:noop};
@@ -83,8 +83,7 @@ function valueAccessor(scope, element) {
elementError(element, NG_VALIDATION_ERROR, null);
invalidWidgets.markValid(element);
} else {
- var error,
- validateScope = extend(new (extend(function(){}, {prototype:scope}))(), {$element:element});
+ var error, validateScope = inherit(scope, {$element:element});
error = required && !value ?
'Required' :
(value ? validator(validateScope, value) : null);
@@ -193,10 +192,10 @@ function inputWidget(events, modelAccessor, viewAccessor, initFn) {
var scope = this,
model = modelAccessor(scope, element),
view = viewAccessor(scope, element),
- action = element.attr('ng-change') || '',
+ action = element.attr('ng:change') || '',
lastValue;
initFn.call(scope, model, view, element);
- this.$eval(element.attr('ng-init')||'');
+ this.$eval(element.attr('ng:init')||'');
// Don't register a handler if we are a button (noopAccessor) and there is no action
if (action || modelAccessor !== noopAccessor) {
element.bind(events, function(){
@@ -223,24 +222,24 @@ function inputWidgetSelector(element){
return INPUT_TYPE[lowercase(element[0].type)] || noop;
}
-angularWidget('INPUT', inputWidgetSelector);
-angularWidget('TEXTAREA', inputWidgetSelector);
-angularWidget('BUTTON', inputWidgetSelector);
-angularWidget('SELECT', function(element){
+angularWidget('input', inputWidgetSelector);
+angularWidget('textarea', inputWidgetSelector);
+angularWidget('button', inputWidgetSelector);
+angularWidget('select', function(element){
this.descend(true);
return inputWidgetSelector.call(this, element);
});
-angularWidget('NG:INCLUDE', function(element){
+angularWidget('ng:include', function(element){
var compiler = this,
srcExp = element.attr("src"),
scopeExp = element.attr("scope") || '';
- if (element[0]['ng-compiled']) {
+ if (element[0]['ng:compiled']) {
this.descend(true);
this.directives(true);
} else {
- element[0]['ng-compiled'] = true;
+ element[0]['ng:compiled'] = true;
return function(element){
var scope = this, childScope;
var changeCounter = 0;
@@ -266,7 +265,7 @@ angularWidget('NG:INCLUDE', function(element){
}
});
-var ngSwitch = angularWidget('NG:SWITCH', function (element){
+var ngSwitch = angularWidget('ng:switch', function (element){
var compiler = this,
watchExpr = element.attr("on"),
usingExpr = (element.attr("using") || 'equals'),
@@ -276,7 +275,7 @@ var ngSwitch = angularWidget('NG:SWITCH', function (element){
cases = [];
if (!usingFn) throw "Using expression '" + usingExpr + "' unknown.";
eachNode(element, function(caseElement){
- var when = caseElement.attr('ng-switch-when');
+ var when = caseElement.attr('ng:switch-when');
if (when) {
cases.push({
when: function(scope, value){