aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Angular.js80
-rw-r--r--src/Compiler.js12
-rw-r--r--src/Formatters.js4
-rw-r--r--src/Parser.js12
-rw-r--r--src/Resource.js8
-rw-r--r--src/Scope.js1
-rw-r--r--src/Validators.js4
-rw-r--r--src/Widgets.js28
-rw-r--r--src/apis.js62
-rw-r--r--src/jqLite.js15
10 files changed, 138 insertions, 88 deletions
diff --git a/src/Angular.js b/src/Angular.js
index c3562e84..12293ddb 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -1,25 +1,13 @@
if (typeof document.getAttribute == 'undefined')
document.getAttribute = function() {};
-function noop() {}
-function identity($) {return $;}
if (!window['console']) window['console']={'log':noop, 'error':noop};
-function extensionMap(angular, name) {
- var extPoint;
- return angular[name] || (extPoint = angular[name] = function (name, fn, prop){
- if (isDefined(fn)) {
- extPoint[name] = extend(fn, prop || {});
- }
- return extPoint[name];
- });
-}
-
var consoleNode,
NOOP = 'noop',
jQuery = window['jQuery'] || window['$'], // weirdness to make IE happy
_ = window['_'],
- jqLite = jQuery,
+ jqLite = jQuery || jqLiteWrap,
slice = Array.prototype.slice,
angular = window['angular'] || (window['angular'] = {}),
angularTextMarkup = extensionMap(angular, 'textMarkup'),
@@ -44,7 +32,7 @@ function foreach(obj, iterator, context) {
if (obj) {
if (obj.forEach) {
obj.forEach(iterator, context);
- } else if (obj instanceof Array) {
+ } else if (isObject(obj) && isNumber(obj.length)) {
for (key = 0; key < obj.length; key++)
iterator.call(context, obj[key], key);
} else {
@@ -55,22 +43,66 @@ function foreach(obj, iterator, context) {
return obj;
}
-function extend(dst, obj) {
- foreach(obj, function(value, key){
- dst[key] = value;
+function extend(dst) {
+ foreach(arguments, function(obj){
+ if (obj !== dst) {
+ foreach(obj, function(value, key){
+ dst[key] = value;
+ });
+ }
});
return dst;
}
+function noop() {}
+function identity($) {return $;}
+function extensionMap(angular, name) {
+ var extPoint;
+ return angular[name] || (extPoint = angular[name] = function (name, fn, prop){
+ if (isDefined(fn)) {
+ extPoint[name] = extend(fn, prop || {});
+ }
+ return extPoint[name];
+ });
+}
+
+function jqLiteWrap(element) {
+ if (typeof element == 'string') {
+ var div = document.createElement('div');
+ div.innerHTML = element;
+ element = div.childNodes[0];
+ }
+ return element instanceof JQLite ? element : new JQLite(element);
+}
function isUndefined(value){ return typeof value == 'undefined'; }
function isDefined(value){ return typeof value != 'undefined'; }
function isObject(value){ return typeof value == 'object';}
function isString(value){ return typeof value == 'string';}
+function isNumber(value){ return typeof value == 'number';}
function isArray(value) { return value instanceof Array; }
function isFunction(value){ return typeof value == 'function';}
function lowercase(value){ return isString(value) ? value.toLowerCase() : value; }
function uppercase(value){ return isString(value) ? value.toUpperCase() : value; }
function trim(value) { return isString(value) ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value; };
+function map(obj, iterator, context) {
+ var results = [];
+ foreach(obj, function(value, index, list) {
+ results.push(iterator.call(context, value, index, list));
+ });
+ return results;
+};
+function size(obj) {
+ var size = 0;
+ if (obj) {
+ if (isNumber(obj.length)) {
+ return obj.length;
+ } else if (isObject(obj)){
+ for (key in obj)
+ size++;
+ }
+ }
+ return size;
+}
function includes(array, obj) {
for ( var i = 0; i < array.length; i++) {
if (obj === array[i]) return true;
@@ -78,6 +110,13 @@ function includes(array, obj) {
return false;
}
+function indexOf(array, obj) {
+ for ( var i = 0; i < array.length; i++) {
+ if (obj === array[i]) return i;
+ }
+ return -1;
+}
+
function log(a, b, c){
var console = window['console'];
switch(arguments.length) {
@@ -157,11 +196,14 @@ function copy(source, destination){
destination.pop();
}
} else {
- foreach(function(value, key){
+ foreach(destination, function(value, key){
delete destination[key];
});
}
- return $.extend(true, destination, source);
+ foreach(source, function(value, key){
+ destination[key] = isArray(value) ? copy(value, []) : (isObject(value) ? copy(value, {}) : value);
+ });
+ return destination;
}
};
diff --git a/src/Compiler.js b/src/Compiler.js
index 4f30521b..923f7b2f 100644
--- a/src/Compiler.js
+++ b/src/Compiler.js
@@ -73,11 +73,12 @@ function eachNode(element, fn){
}
function eachAttribute(element, fn){
- var i, attrs = element[0].attributes || [], size = attrs.length, chld, attr;
+ var i, attrs = element[0].attributes || [], size = attrs.length, chld, attr, attrValue = {};
for (i = 0; i < size; i++) {
var attr = attrs[i];
- fn(attr.name, attr.value);
+ attrValue[attr.name] = attr.value;
}
+ foreach(attrValue, fn);
}
function Compiler(textMarkup, attrMarkup, directives, widgets){
@@ -92,12 +93,15 @@ Compiler.prototype = {
rawElement = jqLite(rawElement);
var template = this.templatize(rawElement) || new Template();
return function(element, parentScope){
+ parentScope = parentScope || {};
var scope = createScope(parentScope);
+ parentScope.$root = parentScope.$root || scope;
return extend(scope, {
$element:element,
$init: function() {
template.init(element, scope);
scope.$eval();
+ return scope;
}
});
};
@@ -132,12 +136,12 @@ Compiler.prototype = {
});
// Process attributes/directives
- eachAttribute(element, function(name, value){
+ eachAttribute(element, function(value, name){
foreach(self.attrMarkup, function(markup){
markup.call(selfApi, value, name, element);
});
});
- eachAttribute(element, function(name, value){
+ eachAttribute(element, function(value, name){
var directive = directives[name];
if (!exclusive && directive) {
if (directive.exclusive) {
diff --git a/src/Formatters.js b/src/Formatters.js
index f2d5d33e..402e8a2b 100644
--- a/src/Formatters.js
+++ b/src/Formatters.js
@@ -9,7 +9,7 @@ extend(angularFormatter, {
function(obj) { return obj ? obj.join(", ") : obj; },
function(value) {
var list = [];
- foreach(value.split(','), function(item){
+ foreach((value || '').split(','), function(item){
item = trim(item);
if (item) list.push(item);
});
@@ -18,6 +18,6 @@ extend(angularFormatter, {
),
'trim':formater(
- function(obj) { return obj ? $.trim("" + obj) : ""; }
+ function(obj) { return obj ? trim("" + obj) : ""; }
)
});
diff --git a/src/Parser.js b/src/Parser.js
index 81a2afdc..ef1465a0 100644
--- a/src/Parser.js
+++ b/src/Parser.js
@@ -558,14 +558,14 @@ Parser.prototype = {
}
var statements = this.statements();
this.consume("}");
- return function(self){
+ return function(self) {
return function($){
- var scope = new Scope(self.scope.state);
- scope.set('$', $);
+ var scope = createScope(self.state);
+ scope['$'] = $;
for ( var i = 0; i < args.length; i++) {
- scope.set(args[i], arguments[i]);
+ scope.$set(args[i], arguments[i]);
}
- return statements({scope:scope});
+ return statements({scope:{get:scope.$get, set:scope.$set}});
};
};
},
@@ -573,7 +573,7 @@ Parser.prototype = {
fieldAccess: function(object) {
var field = this.expect().text;
var fn = function (self){
- return Scope.getter(object(self), field);
+ return getter(object(self), field);
};
fn.isAssignable = field;
return fn;
diff --git a/src/Resource.js b/src/Resource.js
index 971ad6e5..27ce8aa9 100644
--- a/src/Resource.js
+++ b/src/Resource.js
@@ -46,11 +46,11 @@ ResourceFactory.prototype = {
route: function(url, paramDefaults, actions){
var self = this;
var route = new Route(url);
- actions = $.extend({}, ResourceFactory.DEFAULT_ACTIONS, actions);
+ actions = extend({}, ResourceFactory.DEFAULT_ACTIONS, actions);
function extractParams(data){
var ids = {};
foreach(paramDefaults || {}, function(value, key){
- ids[key] = value.charAt && value.charAt(0) == '@' ? Scope.getter(data, value.substr(1)) : value;
+ ids[key] = value.charAt && value.charAt(0) == '@' ? getter(data, value.substr(1)) : value;
});
return ids;
}
@@ -83,7 +83,7 @@ ResourceFactory.prototype = {
}
var value = action.isArray ? [] : new Resource(data);
- self.xhr(action.method, route.url($.extend({}, action.params || {}, extractParams(data), params)), data, function(response) {
+ self.xhr(action.method, route.url(extend({}, action.params || {}, extractParams(data), params)), data, function(response) {
if (action.isArray) {
foreach(response, function(item){
value.push(new Resource(item));
@@ -97,7 +97,7 @@ ResourceFactory.prototype = {
};
Resource.bind = function(additionalParamDefaults){
- return self.route(url, $.extend({}, paramDefaults, additionalParamDefaults), actions);
+ return self.route(url, extend({}, paramDefaults, additionalParamDefaults), actions);
};
if (!isGet) {
diff --git a/src/Scope.js b/src/Scope.js
index 6ba6aa8e..3e225653 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -61,6 +61,7 @@ function expressionCompile(exp){
function parserNewScopeAdapter(fn) {
return function(){
return fn({
+ state: this,
scope: {
set: this.$set,
get: this.$get
diff --git a/src/Validators.js b/src/Validators.js
index cdff5e1a..662145c0 100644
--- a/src/Validators.js
+++ b/src/Validators.js
@@ -91,12 +91,12 @@ foreach({
obj[lastKey] = text;
if (state === undefined) {
// we have never seen this before, Request it
- jQuery(obj).addClass('ng-input-indicator-wait');
+ jqLite(obj).addClass('ng-input-indicator-wait');
state = stateCache[text] = null;
asynchronousFn(text, function(error){
state = stateCache[text] = error ? error : false;
if (stateCache[obj[lastKey]] !== null) {
- jQuery(obj).removeClass('ng-input-indicator-wait');
+ jqLite(obj).removeClass('ng-input-indicator-wait');
}
updateView();
});
diff --git a/src/Widgets.js b/src/Widgets.js
index 42b9e916..b5222ac7 100644
--- a/src/Widgets.js
+++ b/src/Widgets.js
@@ -18,7 +18,7 @@ function compileValidator(expr) {
return new Parser(expr).validator()();
}
-function valueAccessor(element) {
+function valueAccessor(scope, element) {
var validatorName = element.attr('ng-validate') || NOOP,
validator = compileValidator(validatorName),
required = element.attr('ng-required'),
@@ -26,7 +26,7 @@ function valueAccessor(element) {
required = required || required == '';
if (!validator) throw "Validator named '" + validatorName + "' not found.";
function validate(value) {
- var error = required && !trim(value) ? "Required" : validator.call(this, value);
+ var error = required && !trim(value) ? "Required" : validator({self:scope, scope:{get:scope.$get, set:scope.$set}}, value);
if (error !== lastError) {
if (error) {
element.addClass(NG_VALIDATION_ERROR);
@@ -45,23 +45,31 @@ function valueAccessor(element) {
};
}
-function checkedAccessor(element) {
+function checkedAccessor(scope, element) {
var domElement = element[0];
return {
- get: function(){ return !!domElement.checked; },
- set: function(value){ domElement.checked = !!value; }
+ get: function(){
+ return !!domElement.checked;
+ },
+ set: function(value){
+ domElement.checked = !!value;
+ }
};
}
-function radioAccessor(element) {
+function radioAccessor(scope, element) {
var domElement = element[0];
return {
- get: function(){ return domElement.checked ? domElement.value : null; },
- set: function(value){ domElement.checked = value == domElement.value; }
+ get: function(){
+ return domElement.checked ? domElement.value : null;
+ },
+ set: function(value){
+ domElement.checked = value == domElement.value;
+ }
};
}
-function optionsAccessor(element) {
+function optionsAccessor(scope, element) {
var options = element[0].options;
return {
get: function(){
@@ -107,7 +115,7 @@ function inputWidget(events, modelAccessor, viewAccessor, initValue) {
return function(element) {
var scope = this,
model = modelAccessor(scope, element),
- view = viewAccessor(element),
+ view = viewAccessor(scope, element),
action = element.attr('ng-action') || '',
value = view.get() || copy(initValue);
if (isDefined(value)) model.set(value);
diff --git a/src/apis.js b/src/apis.js
index e375e8fc..3d0c5db3 100644
--- a/src/apis.js
+++ b/src/apis.js
@@ -11,11 +11,15 @@ var angularGlobal = {
}
};
-var angularCollection = {};
+var angularCollection = {
+ 'size': size
+};
var angularObject = {};
var angularArray = {
+ 'indexOf': indexOf,
+ 'include': includes,
'includeIf':function(array, value, condition) {
- var index = _.indexOf(array, value);
+ var index = indexOf(array, value);
if (condition) {
if (index == -1)
array.push(value);
@@ -36,7 +40,7 @@ var angularArray = {
return sum;
},
'remove':function(array, value) {
- var index = _.indexOf(array, value);
+ var index = indexOf(array, value);
if (index >=0)
array.splice(index, 1);
return value;
@@ -44,7 +48,7 @@ var angularArray = {
'find':function(array, condition, defaultValue) {
if (!condition) return undefined;
var fn = angular['Function']['compile'](condition);
- _.detect(array, function($){
+ foreach(array, function($){
if (fn($)){
defaultValue = $;
return true;
@@ -65,7 +69,6 @@ var angularArray = {
}
return true;
};
- var getter = Scope.getter;
var search = function(obj, text){
if (text.charAt(0) === '!') {
return !search(obj, text.substr(1));
@@ -136,13 +139,18 @@ var angularArray = {
return filtered;
},
'add':function(array, value) {
- array.push(_.isUndefined(value)? {} : value);
+ array.push(isUndefined(value)? {} : value);
return array;
},
'count':function(array, condition) {
if (!condition) return array.length;
- var fn = angular['Function']['compile'](condition);
- return _.reduce(array, 0, function(count, $){return count + (fn($)?1:0);});
+ var fn = angular['Function']['compile'](condition), count = 0;
+ foreach(array, function(value){
+ if (fn(value)) {
+ count ++;
+ }
+ });
+ return count;
},
'orderBy':function(array, expression, descend) {
function reverse(comp, descending) {
@@ -161,14 +169,14 @@ var angularArray = {
return t1 < t2 ? -1 : 1;
}
}
- expression = _.isArray(expression) ? expression: [expression];
- expression = _.map(expression, function($){
+ expression = isArray(expression) ? expression: [expression];
+ expression = map(expression, function($){
var descending = false;
if (typeof $ == "string" && ($.charAt(0) == '+' || $.charAt(0) == '-')) {
descending = $.charAt(0) == '-';
$ = $.substring(1);
}
- var get = $ ? angular['Function']['compile']($) : _.identity;
+ var get = $ ? angular['Function']['compile']($) : identity;
return reverse(function(a,b){
return compare(get(a),get(b));
}, descending);
@@ -180,22 +188,24 @@ var angularArray = {
}
return 0;
};
- return _.clone(array).sort(reverse(comparator, descend));
+ return copy(array).sort(reverse(comparator, descend));
},
'orderByToggle':function(predicate, attribute) {
var STRIP = /^([+|-])?(.*)/;
var ascending = false;
var index = -1;
- _.detect(predicate, function($, i){
- if ($ == attribute) {
- ascending = true;
- index = i;
- return true;
- }
- if (($.charAt(0)=='+'||$.charAt(0)=='-') && $.substring(1) == attribute) {
- ascending = $.charAt(0) == '+';
- index = i;
- return true;
+ foreach(predicate, function($, i){
+ if (index == -1) {
+ if ($ == attribute) {
+ ascending = true;
+ index = i;
+ return true;
+ }
+ if (($.charAt(0)=='+'||$.charAt(0)=='-') && $.substring(1) == attribute) {
+ ascending = $.charAt(0) == '+';
+ index = i;
+ return true;
+ }
}
});
if (index >= 0) {
@@ -281,16 +291,14 @@ var angularDate = {
var angularFunction = {
'compile':function(expression) {
- if (_.isFunction(expression)){
+ if (isFunction(expression)){
return expression;
} else if (expression){
- var scope = new Scope();
return function($) {
- scope.state = $;
- return scope.eval(expression);
+ return createScope($).$eval(expression);
};
} else {
- return function($){return $;};
+ return identity;
}
}
};
diff --git a/src/jqLite.js b/src/jqLite.js
index a5014354..449854d5 100644
--- a/src/jqLite.js
+++ b/src/jqLite.js
@@ -1,5 +1,4 @@
-
-///////////////////////////////////
+//////////////////////////////////
//JQLite
//////////////////////////////////
@@ -38,18 +37,6 @@ function JQLite(element) {
this[0] = element;
}
-
-function jqLiteWrap(element) {
- if (typeof element == 'string') {
- var div = document.createElement('div');
- div.innerHTML = element;
- element = div.childNodes[0];
- }
- return element instanceof JQLite ? element : new JQLite(element);
-}
-
-jqLite = jqLite || jqLiteWrap;
-
JQLite.prototype = {
data: function(key, value) {
var element = this[0],