aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMisko Hevery2011-02-12 10:13:28 -0800
committerMisko Hevery2011-02-16 01:03:12 -0500
commitef4bb28be13e99f96c9ace5936cf26a174a0e5f0 (patch)
tree833057505e430cac064214ac3d55c687338da2a9
parent496e6bf9016d33a7cf2f4730d06a8655f01ca5cb (diff)
downloadangular.js-ef4bb28be13e99f96c9ace5936cf26a174a0e5f0.tar.bz2
Change API angular.compile(element)([scope], [element/true])
-rw-r--r--CHANGELOG.md1
-rw-r--r--src/Angular.js51
-rw-r--r--src/Compiler.js22
-rw-r--r--src/widgets.js8
-rw-r--r--test/AngularSpec.js725
-rw-r--r--test/BinderSpec.js110
-rw-r--r--test/CompilerSpec.js7
-rw-r--r--test/ResourceSpec.js4
-rw-r--r--test/ScenarioSpec.js12
-rw-r--r--test/ValidatorsSpec.js10
-rw-r--r--test/directivesSpec.js4
-rw-r--r--test/markupSpec.js3
-rw-r--r--test/service/invalidWidgetsSpec.js6
-rw-r--r--test/service/routeSpec.js4
-rw-r--r--test/widgetsSpec.js18
15 files changed, 524 insertions, 461 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 979d2435..04d511d0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@
recommended way to deal with initializing scope is to put it in the root constructor controller.
To migrate simply remove the call to $init() and move any code you had before $init() to the
root controller.
+- Change API angular.compile(..) to angular.compile(element)([scope], [element/true])
<a name="0.9.11"><a/>
diff --git a/src/Angular.js b/src/Angular.js
index 9b2c7ea6..9eaeb093 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -793,21 +793,50 @@ function merge(src, dst) {
* @function
*
* @description
- * Compiles a piece of HTML or DOM into a {@link angular.scope scope} object.
+ * Compiles a piece of HTML string or DOM into a view and produces a linking function, which can
+ * then be used to link {@link angular.scope scope} and the template together. The compilation
+ * process walks the DOM tree and tries to match DOM elements to {@link angular.markup markup},
+ * {@link angular.attrMarkup attrMarkup}, {@link angular.widget widgets}, and
+ * {@link angular.directive directives}. For each match it executes coresponding markup, \
+ * attrMarkup, widget or directive template function and collects the instance functions into a
+ * single linking function which is then returned. The linking function can then be used
+ * many-times-over on clones of compiled DOM structure, (For example when compiling
+ * {@link angular.widget.@ng:repeat repeater} the resulting linking function is called once for
+ * each item in the collection. The `ng:repeat` does this by cloning the template DOM once for
+ * each item in collection and then calling the linking function to link the cloned template
+ * with the a new scope for each item in the collection.)
+ *
<pre>
- var scope1 = angular.compile(window.document);
+ var mvc1 = angular.compile(window.document)();
+ mvc1.view; // compiled view elment
+ mvc1.scope; // scope bound to the element
- var scope2 = angular.compile('<div ng:click="clicked = true">click me</div>');
+ var mvc2 = angular.compile('<div ng:click="clicked = true">click me</div>')();
</pre>
*
- * @param {string|DOMElement} element Element to compile.
- * @param {Object=} parentScope Scope to become the parent scope of the newly compiled scope.
- * @returns {Object} Compiled scope object.
+ * @param {string|DOMElement} element Element or HTML to compile into a template function.
+ * @returns {function([scope][, element])} a template function which is used to bind element
+ * and scope. Where:
+ *
+ * * `scope` - {@link angular.scope scope} A scope to bind to. If none specified, then a new
+ * root scope is created.
+ * * `element` - {@link angular.element element} Element to use as the template. If none
+ * specified then reuse the element from `angular.compile(element)`. If `true`
+ * then clone the `angular.compile(element)`. The element must be either the same
+ * element as `angular.compile(element)` or an identical clone to
+ * `angular.compile(element)`. Using an element with differnt structure will cause
+ * unpredictable behavior.
+ *
+ * Calling the template function returns object: `{scope:?, view:?}`, where:
+ *
+ * * `view` - the DOM element which represents the compiled template. Either same or clone of
+ * `element` specifed in compile or template function.
+ * * `scope` - scope to which the element is bound to. Either a root scope or scope specified
+ * in the template function.
*/
-function compile(element, parentScope) {
- var compiler = new Compiler(angularTextMarkup, angularAttrMarkup, angularDirective, angularWidget),
- $element = jqLite(element);
- return compiler.compile($element)($element, parentScope);
+function compile(element) {
+ return new Compiler(angularTextMarkup, angularAttrMarkup, angularDirective, angularWidget)
+ .compile(element);
}
/////////////////////////////////////////////////
@@ -989,7 +1018,7 @@ function toKeyValue(obj) {
function angularInit(config){
if (config.autobind) {
// TODO default to the source of angular.js
- var scope = compile(window.document, _null, {'$config':config}),
+ var scope = compile(window.document)(null, createScope({'$config':config})),
$browser = scope.$service('$browser');
if (config.css)
diff --git a/src/Compiler.js b/src/Compiler.js
index 6aee40b8..890f2510 100644
--- a/src/Compiler.js
+++ b/src/Compiler.js
@@ -80,30 +80,30 @@ function Compiler(markup, attrMarkup, directives, widgets){
}
Compiler.prototype = {
- compile: function(element) {
- element = jqLite(element);
+ compile: function(templateElement) {
+ templateElement = jqLite(templateElement);
var index = 0,
template,
- parent = element.parent();
+ parent = templateElement.parent();
if (parent && parent[0]) {
parent = parent[0];
for(var i = 0; i < parent.childNodes.length; i++) {
- if (parent.childNodes[i] == element[0]) {
+ if (parent.childNodes[i] == templateElement[0]) {
index = i;
}
}
}
- template = this.templatize(element, index, 0) || new Template();
- return function(element, parentScope){
- element = jqLite(element);
- var scope = parentScope && parentScope.$eval
- ? parentScope
- : createScope(parentScope);
+ template = this.templatize(templateElement, index, 0) || new Template();
+ return function(scope, element){
+ scope = scope || createScope();
+ element = element === true
+ ? templateElement.cloneNode()
+ : (jqLite(element) || templateElement);
element.data($$scope, scope);
template.attach(element, scope);
scope.$element = element;
scope.$eval();
- return scope;
+ return {scope:scope, view:element};
};
},
diff --git a/src/widgets.js b/src/widgets.js
index 58c22081..14d6fe10 100644
--- a/src/widgets.js
+++ b/src/widgets.js
@@ -676,7 +676,7 @@ angularWidget('ng:include', function(element){
xhr('GET', src, function(code, response){
element.html(response);
childScope = useScope || createScope(scope);
- compiler.compile(element)(element, childScope);
+ compiler.compile(element)(childScope);
scope.$eval(onloadExp);
});
} else {
@@ -793,7 +793,7 @@ var ngSwitch = angularWidget('ng:switch', function (element){
var caseElement = switchCase.element.cloneNode();
element.append(caseElement);
childScope.$tryEval(switchCase.change, element);
- switchCase.template(caseElement, childScope);
+ switchCase.template(childScope, caseElement);
}
});
});
@@ -945,7 +945,7 @@ angularWidget("@ng:repeat", function(expression, element){
(index == collectionLength - 1 ? 'last' : 'middle');
lastElement.after(cloneElement = element.cloneNode());
cloneElement.attr('ng:repeat-index', index);
- linker(cloneElement, childScope);
+ linker(childScope, cloneElement);
children.push(childScope);
}
childScope.$eval();
@@ -1067,7 +1067,7 @@ angularWidget('ng:view', function(element) {
if (src) {
$xhr('GET', src, function(code, response){
element.html(response);
- compiler.compile(element)(element, childScope);
+ compiler.compile(element)(childScope);
});
} else {
element.html('');
diff --git a/test/AngularSpec.js b/test/AngularSpec.js
index 010dce7c..8ff0631d 100644
--- a/test/AngularSpec.js
+++ b/test/AngularSpec.js
@@ -1,350 +1,389 @@
-beforeEach(function(){
- compileCache = {};
-});
-
-describe('case', function(){
- it('should change case', function(){
- expect(lowercase('ABC90')).toEqual('abc90');
- expect(manualLowercase('ABC90')).toEqual('abc90');
- expect(uppercase('abc90')).toEqual('ABC90');
- expect(manualUppercase('abc90')).toEqual('ABC90');
- });
-});
-
-describe("copy", function(){
- it("should return same object", function (){
- var obj = {};
- var arr = [];
- expect(copy({}, obj)).toBe(obj);
- expect(copy([], arr)).toBe(arr);
- });
-
- it("should copy Date", function(){
- var date = new Date(123);
- expect(copy(date) instanceof Date).toBeTruthy();
- expect(copy(date).getTime()).toEqual(123);
- expect(copy(date) === date).toBeFalsy();
- });
-
- it("should copy array", function(){
- var src = [1, {name:"value"}];
- var dst = [{key:"v"}];
- expect(copy(src, dst)).toBe(dst);
- expect(dst).toEqual([1, {name:"value"}]);
- expect(dst[1]).toEqual({name:"value"});
- expect(dst[1]).not.toBe(src[1]);
- });
-
- it('should copy empty array', function() {
- var src = [];
- var dst = [{key: "v"}];
- expect(copy(src, dst)).toEqual([]);
- expect(dst).toEqual([]);
- });
-
- it("should copy object", function(){
- var src = {a:{name:"value"}};
- var dst = {b:{key:"v"}};
- expect(copy(src, dst)).toBe(dst);
- expect(dst).toEqual({a:{name:"value"}});
- expect(dst.a).toEqual(src.a);
- expect(dst.a).not.toBe(src.a);
- });
-
- it("should copy primitives", function(){
- expect(copy(null)).toEqual(null);
- expect(copy('')).toBe('');
- expect(copy('lala')).toBe('lala');
- expect(copy(123)).toEqual(123);
- expect(copy([{key:null}])).toEqual([{key:null}]);
- });
-
-});
-
-describe('equals', function(){
- it('should return true if same object', function(){
- var o = {};
- expect(equals(o, o)).toEqual(true);
- expect(equals(1, '1')).toEqual(true);
- expect(equals(1, '2')).toEqual(false);
- });
-
- it('should recurse into object', function(){
- expect(equals({}, {})).toEqual(true);
- expect(equals({name:'misko'}, {name:'misko'})).toEqual(true);
- expect(equals({name:'misko', age:1}, {name:'misko'})).toEqual(false);
- expect(equals({name:'misko'}, {name:'misko', age:1})).toEqual(false);
- expect(equals({name:'misko'}, {name:'adam'})).toEqual(false);
- expect(equals(['misko'], ['misko'])).toEqual(true);
- expect(equals(['misko'], ['adam'])).toEqual(false);
- expect(equals(['misko'], ['misko', 'adam'])).toEqual(false);
- });
-
- it('should ignore $ member variables', function(){
- expect(equals({name:'misko', $id:1}, {name:'misko', $id:2})).toEqual(true);
- expect(equals({name:'misko'}, {name:'misko', $id:2})).toEqual(true);
- expect(equals({name:'misko', $id:1}, {name:'misko'})).toEqual(true);
- });
-
- it('should ignore functions', function(){
- expect(equals({func: function() {}}, {bar: function() {}})).toEqual(true);
- });
-
- it('should work well with nulls', function() {
- expect(equals(null, '123')).toBe(false);
- expect(equals('123', null)).toBe(false);
-
- var obj = {foo:'bar'};
- expect(equals(null, obj)).toBe(false);
- expect(equals(obj, null)).toBe(false);
-
- expect(equals(null, null)).toBe(true);
- });
-
- it('should work well with undefined', function() {
- expect(equals(undefined, '123')).toBe(false);
- expect(equals('123', undefined)).toBe(false);
-
- var obj = {foo:'bar'};
- expect(equals(undefined, obj)).toBe(false);
- expect(equals(obj, undefined)).toBe(false);
-
- expect(equals(undefined, undefined)).toBe(true);
- });
-});
-
-describe('parseKeyValue', function() {
- it('should parse a string into key-value pairs', function() {
- expect(parseKeyValue('')).toEqual({});
- expect(parseKeyValue('simple=pair')).toEqual({simple: 'pair'});
- expect(parseKeyValue('first=1&second=2')).toEqual({first: '1', second: '2'});
- expect(parseKeyValue('escaped%20key=escaped%20value')).
+describe('angular', function(){
+ describe('case', function(){
+ it('should change case', function(){
+ expect(lowercase('ABC90')).toEqual('abc90');
+ expect(manualLowercase('ABC90')).toEqual('abc90');
+ expect(uppercase('abc90')).toEqual('ABC90');
+ expect(manualUppercase('abc90')).toEqual('ABC90');
+ });
+ });
+
+ describe("copy", function(){
+ it("should return same object", function (){
+ var obj = {};
+ var arr = [];
+ expect(copy({}, obj)).toBe(obj);
+ expect(copy([], arr)).toBe(arr);
+ });
+
+ it("should copy Date", function(){
+ var date = new Date(123);
+ expect(copy(date) instanceof Date).toBeTruthy();
+ expect(copy(date).getTime()).toEqual(123);
+ expect(copy(date) === date).toBeFalsy();
+ });
+
+ it("should copy array", function(){
+ var src = [1, {name:"value"}];
+ var dst = [{key:"v"}];
+ expect(copy(src, dst)).toBe(dst);
+ expect(dst).toEqual([1, {name:"value"}]);
+ expect(dst[1]).toEqual({name:"value"});
+ expect(dst[1]).not.toBe(src[1]);
+ });
+
+ it('should copy empty array', function() {
+ var src = [];
+ var dst = [{key: "v"}];
+ expect(copy(src, dst)).toEqual([]);
+ expect(dst).toEqual([]);
+ });
+
+ it("should copy object", function(){
+ var src = {a:{name:"value"}};
+ var dst = {b:{key:"v"}};
+ expect(copy(src, dst)).toBe(dst);
+ expect(dst).toEqual({a:{name:"value"}});
+ expect(dst.a).toEqual(src.a);
+ expect(dst.a).not.toBe(src.a);
+ });
+
+ it("should copy primitives", function(){
+ expect(copy(null)).toEqual(null);
+ expect(copy('')).toBe('');
+ expect(copy('lala')).toBe('lala');
+ expect(copy(123)).toEqual(123);
+ expect(copy([{key:null}])).toEqual([{key:null}]);
+ });
+
+ });
+
+ describe('equals', function(){
+ it('should return true if same object', function(){
+ var o = {};
+ expect(equals(o, o)).toEqual(true);
+ expect(equals(1, '1')).toEqual(true);
+ expect(equals(1, '2')).toEqual(false);
+ });
+
+ it('should recurse into object', function(){
+ expect(equals({}, {})).toEqual(true);
+ expect(equals({name:'misko'}, {name:'misko'})).toEqual(true);
+ expect(equals({name:'misko', age:1}, {name:'misko'})).toEqual(false);
+ expect(equals({name:'misko'}, {name:'misko', age:1})).toEqual(false);
+ expect(equals({name:'misko'}, {name:'adam'})).toEqual(false);
+ expect(equals(['misko'], ['misko'])).toEqual(true);
+ expect(equals(['misko'], ['adam'])).toEqual(false);
+ expect(equals(['misko'], ['misko', 'adam'])).toEqual(false);
+ });
+
+ it('should ignore $ member variables', function(){
+ expect(equals({name:'misko', $id:1}, {name:'misko', $id:2})).toEqual(true);
+ expect(equals({name:'misko'}, {name:'misko', $id:2})).toEqual(true);
+ expect(equals({name:'misko', $id:1}, {name:'misko'})).toEqual(true);
+ });
+
+ it('should ignore functions', function(){
+ expect(equals({func: function() {}}, {bar: function() {}})).toEqual(true);
+ });
+
+ it('should work well with nulls', function() {
+ expect(equals(null, '123')).toBe(false);
+ expect(equals('123', null)).toBe(false);
+
+ var obj = {foo:'bar'};
+ expect(equals(null, obj)).toBe(false);
+ expect(equals(obj, null)).toBe(false);
+
+ expect(equals(null, null)).toBe(true);
+ });
+
+ it('should work well with undefined', function() {
+ expect(equals(undefined, '123')).toBe(false);
+ expect(equals('123', undefined)).toBe(false);
+
+ var obj = {foo:'bar'};
+ expect(equals(undefined, obj)).toBe(false);
+ expect(equals(obj, undefined)).toBe(false);
+
+ expect(equals(undefined, undefined)).toBe(true);
+ });
+ });
+
+ describe('parseKeyValue', function() {
+ it('should parse a string into key-value pairs', function() {
+ expect(parseKeyValue('')).toEqual({});
+ expect(parseKeyValue('simple=pair')).toEqual({simple: 'pair'});
+ expect(parseKeyValue('first=1&second=2')).toEqual({first: '1', second: '2'});
+ expect(parseKeyValue('escaped%20key=escaped%20value')).
toEqual({'escaped key': 'escaped value'});
- expect(parseKeyValue('emptyKey=')).toEqual({emptyKey: ''});
- expect(parseKeyValue('flag1&key=value&flag2')).
+ expect(parseKeyValue('emptyKey=')).toEqual({emptyKey: ''});
+ expect(parseKeyValue('flag1&key=value&flag2')).
toEqual({flag1: true, key: 'value', flag2: true});
+ });
});
-});
-describe('toKeyValue', function() {
- it('should parse key-value pairs into string', function() {
- expect(toKeyValue({})).toEqual('');
- expect(toKeyValue({simple: 'pair'})).toEqual('simple=pair');
- expect(toKeyValue({first: '1', second: '2'})).toEqual('first=1&second=2');
- expect(toKeyValue({'escaped key': 'escaped value'})).
+ describe('toKeyValue', function() {
+ it('should parse key-value pairs into string', function() {
+ expect(toKeyValue({})).toEqual('');
+ expect(toKeyValue({simple: 'pair'})).toEqual('simple=pair');
+ expect(toKeyValue({first: '1', second: '2'})).toEqual('first=1&second=2');
+ expect(toKeyValue({'escaped key': 'escaped value'})).
toEqual('escaped%20key=escaped%20value');
- expect(toKeyValue({emptyKey: ''})).toEqual('emptyKey=');
- });
-
- it('should parse true values into flags', function() {
- expect(toKeyValue({flag1: true, key: 'value', flag2: true})).toEqual('flag1&key=value&flag2');
- });
-});
-
-
-describe ('rngScript', function() {
- it('should match angular.js', function() {
- expect('angular.js'.match(rngScript)).not.toBeNull();
- expect('../angular.js'.match(rngScript)).not.toBeNull();
- expect('foo/angular.js'.match(rngScript)).not.toBeNull();
-
- expect('foo.js'.match(rngScript)).toBeNull();
- expect('foo/foo.js'.match(rngScript)).toBeNull();
- expect('my-angular-app.js'.match(rngScript)).toBeNull();
- expect('foo/../my-angular-app.js'.match(rngScript)).toBeNull();
- });
-
- it('should match angular.min.js', function() {
- expect('angular.min.js'.match(rngScript)).not.toBeNull();
- expect('../angular.min.js'.match(rngScript)).not.toBeNull();
- expect('foo/angular.min.js'.match(rngScript)).not.toBeNull();
-
- expect('my-angular-app.min.js'.match(rngScript)).toBeNull();
- expect('foo/../my-angular-app.min.js'.match(rngScript)).toBeNull();
- });
-
- it('should match angular-bootstrap.js', function() {
- expect('angular-bootstrap.js'.match(rngScript)).not.toBeNull();
- expect('../angular-bootstrap.js'.match(rngScript)).not.toBeNull();
- expect('foo/angular-bootstrap.js'.match(rngScript)).not.toBeNull();
-
- expect('my-angular-app-bootstrap.js'.match(rngScript)).toBeNull();
- expect('foo/../my-angular-app-bootstrap.js'.match(rngScript)).toBeNull();
- });
-
- it('should match angular-0.9.0.js', function() {
- expect('angular-0.9.0.js'.match(rngScript)).not.toBeNull();
- expect('../angular-0.9.0.js'.match(rngScript)).not.toBeNull();
- expect('foo/angular-0.9.0.js'.match(rngScript)).not.toBeNull();
-
- expect('my-angular-app-0.9.0.js'.match(rngScript)).toBeNull();
- expect('foo/../my-angular-app-0.9.0.js'.match(rngScript)).toBeNull();
- });
-
- it('should match angular-0.9.0.min.js', function() {
- expect('angular-0.9.0.min.js'.match(rngScript)).not.toBeNull();
- expect('../angular-0.9.0.min.js'.match(rngScript)).not.toBeNull();
- expect('foo/angular-0.9.0.min.js'.match(rngScript)).not.toBeNull();
-
- expect('my-angular-app-0.9.0.min.js'.match(rngScript)).toBeNull();
- expect('foo/../my-angular-app-0.9.0.min.js'.match(rngScript)).toBeNull();
- });
-
- it('should match angular-0.9.0-de0a8612.js', function() {
- expect('angular-0.9.0-de0a8612.js'.match(rngScript)).not.toBeNull();
- expect('../angular-0.9.0-de0a8612.js'.match(rngScript)).not.toBeNull();
- expect('foo/angular-0.9.0-de0a8612.js'.match(rngScript)).not.toBeNull();
-
- expect('my-angular-app-0.9.0-de0a8612.js'.match(rngScript)).toBeNull();
- expect('foo/../my-angular-app-0.9.0-de0a8612.js'.match(rngScript)).toBeNull();
- });
-
- it('should match angular-0.9.0-de0a8612.min.js', function() {
- expect('angular-0.9.0-de0a8612.min.js'.match(rngScript)).not.toBeNull();
- expect('../angular-0.9.0-de0a8612.min.js'.match(rngScript)).not.toBeNull();
- expect('foo/angular-0.9.0-de0a8612.min.js'.match(rngScript)).not.toBeNull();
-
- expect('my-angular-app-0.9.0-de0a8612.min.js'.match(rngScript)).toBeNull();
- expect('foo/../my-angular-app-0.9.0-de0a8612.min.js'.match(rngScript)).toBeNull();
- });
-
- it('should match angular-scenario.js', function() {
- expect('angular-scenario.js'.match(rngScript)).not.toBeNull();
- expect('angular-scenario.min.js'.match(rngScript)).not.toBeNull();
- expect('../angular-scenario.js'.match(rngScript)).not.toBeNull();
- expect('foo/angular-scenario.min.js'.match(rngScript)).not.toBeNull();
- });
-
- it('should match angular-scenario-0.9.0(.min).js', function() {
- expect('angular-scenario-0.9.0.js'.match(rngScript)).not.toBeNull();
- expect('angular-scenario-0.9.0.min.js'.match(rngScript)).not.toBeNull();
- expect('../angular-scenario-0.9.0.js'.match(rngScript)).not.toBeNull();
- expect('foo/angular-scenario-0.9.0.min.js'.match(rngScript)).not.toBeNull();
- });
-
- it('should match angular-scenario-0.9.0-de0a8612(.min).js', function() {
- expect('angular-scenario-0.9.0-de0a8612.js'.match(rngScript)).not.toBeNull();
- expect('angular-scenario-0.9.0-de0a8612.min.js'.match(rngScript)).not.toBeNull();
- expect('../angular-scenario-0.9.0-de0a8612.js'.match(rngScript)).not.toBeNull();
- expect('foo/angular-scenario-0.9.0-de0a8612.min.js'.match(rngScript)).not.toBeNull();
- });
-});
-
-
-describe('angularJsConfig', function() {
- it('should find angular.js script tag and config', function() {
- var doc = { getElementsByTagName: function(tagName) {
- expect(tagName).toEqual('script');
- return [{nodeName: 'SCRIPT', src: 'random.js'},
- {nodeName: 'SCRIPT', src: 'angular.js'},
- {nodeName: 'SCRIPT', src: 'my-angular-app.js'}];
- }
- };
-
- expect(angularJsConfig(doc)).toEqual({base_url: '',
- ie_compat: 'angular-ie-compat.js',
- ie_compat_id: 'ng-ie-compat'});
- });
-
-
- it('should extract angular config from the ng: attributes', function() {
- var doc = { getElementsByTagName: function(tagName) {
- expect(lowercase(tagName)).toEqual('script');
- return [{nodeName: 'SCRIPT',
- src: 'angularjs/angular.js',
- attributes: [{name: 'ng:autobind', value:undefined},
- {name: 'ng:css', value: 'css/my_custom_angular.css'},
- {name: 'ng:ie-compat', value: 'myjs/angular-ie-compat.js'},
- {name: 'ng:ie-compat-id', value: 'ngcompat'}] }];
- }};
-
- expect(angularJsConfig(doc)).toEqual({base_url: 'angularjs/',
- autobind: true,
- css: 'css/my_custom_angular.css',
- ie_compat: 'myjs/angular-ie-compat.js',
- ie_compat_id: 'ngcompat'});
- });
-
-
- it('should extract angular autobind config from the script hashpath attributes', function() {
- var doc = { getElementsByTagName: function(tagName) {
- expect(lowercase(tagName)).toEqual('script');
- return [{nodeName: 'SCRIPT',
- src: 'angularjs/angular.js#autobind'}];
- }};
-
- expect(angularJsConfig(doc)).toEqual({base_url: 'angularjs/',
- autobind: true,
- ie_compat: 'angularjs/angular-ie-compat.js',
- ie_compat_id: 'ng-ie-compat'});
- });
-
-
- it("should default to versioned ie-compat file if angular file is versioned", function() {
- var doc = { getElementsByTagName: function(tagName) {
- expect(lowercase(tagName)).toEqual('script');
- return [{nodeName: 'SCRIPT',
- src: 'js/angular-0.9.0.js'}];
- }};
-
- expect(angularJsConfig(doc)).toEqual({base_url: 'js/',
- ie_compat: 'js/angular-ie-compat-0.9.0.js',
- ie_compat_id: 'ng-ie-compat'});
- });
-
-
- it("should default to versioned ie-compat file if angular file is versioned and minified", function() {
- var doc = { getElementsByTagName: function(tagName) {
- expect(lowercase(tagName)).toEqual('script');
- return [{nodeName: 'SCRIPT',
- src: 'js/angular-0.9.0-cba23f00.min.js'}];
- }};
-
- expect(angularJsConfig(doc)).toEqual({base_url: 'js/',
- ie_compat: 'js/angular-ie-compat-0.9.0-cba23f00.js',
- ie_compat_id: 'ng-ie-compat'});
- });
-});
-
-
-describe('angular service', function() {
- it('should override services', function() {
- var scope = createScope();
- angular.service('fake', function() { return 'old'; });
- angular.service('fake', function() { return 'new'; });
-
- expect(scope.$service('fake')).toEqual('new');
- });
-
- it('should not preserve properties on override', function() {
- angular.service('fake', {$one: true}, {$two: true}, {three: true});
- var result = angular.service('fake', {$four: true});
-
- expect(result.$one).toBeUndefined();
- expect(result.$two).toBeUndefined();
- expect(result.three).toBeUndefined();
- expect(result.$four).toBe(true);
- });
-
- it('should not preserve non-angular properties on override', function() {
- angular.service('fake', {one: true}, {two: true});
- var result = angular.service('fake', {third: true});
-
- expect(result.one).not.toBeDefined();
- expect(result.two).not.toBeDefined();
- expect(result.third).toBeTruthy();
- });
-});
-
-describe('isDate', function() {
- it('should return true for Date object', function() {
- expect(isDate(new Date())).toBe(true);
- });
-
- it('should return false for non Date objects', function() {
- expect(isDate([])).toBe(false);
- expect(isDate('')).toBe(false);
- expect(isDate(23)).toBe(false);
- expect(isDate({})).toBe(false);
+ expect(toKeyValue({emptyKey: ''})).toEqual('emptyKey=');
+ });
+
+ it('should parse true values into flags', function() {
+ expect(toKeyValue({flag1: true, key: 'value', flag2: true})).toEqual('flag1&key=value&flag2');
+ });
+ });
+
+
+ describe ('rngScript', function() {
+ it('should match angular.js', function() {
+ expect('angular.js'.match(rngScript)).not.toBeNull();
+ expect('../angular.js'.match(rngScript)).not.toBeNull();
+ expect('foo/angular.js'.match(rngScript)).not.toBeNull();
+
+ expect('foo.js'.match(rngScript)).toBeNull();
+ expect('foo/foo.js'.match(rngScript)).toBeNull();
+ expect('my-angular-app.js'.match(rngScript)).toBeNull();
+ expect('foo/../my-angular-app.js'.match(rngScript)).toBeNull();
+ });
+
+ it('should match angular.min.js', function() {
+ expect('angular.min.js'.match(rngScript)).not.toBeNull();
+ expect('../angular.min.js'.match(rngScript)).not.toBeNull();
+ expect('foo/angular.min.js'.match(rngScript)).not.toBeNull();
+
+ expect('my-angular-app.min.js'.match(rngScript)).toBeNull();
+ expect('foo/../my-angular-app.min.js'.match(rngScript)).toBeNull();
+ });
+
+ it('should match angular-bootstrap.js', function() {
+ expect('angular-bootstrap.js'.match(rngScript)).not.toBeNull();
+ expect('../angular-bootstrap.js'.match(rngScript)).not.toBeNull();
+ expect('foo/angular-bootstrap.js'.match(rngScript)).not.toBeNull();
+
+ expect('my-angular-app-bootstrap.js'.match(rngScript)).toBeNull();
+ expect('foo/../my-angular-app-bootstrap.js'.match(rngScript)).toBeNull();
+ });
+
+ it('should match angular-0.9.0.js', function() {
+ expect('angular-0.9.0.js'.match(rngScript)).not.toBeNull();
+ expect('../angular-0.9.0.js'.match(rngScript)).not.toBeNull();
+ expect('foo/angular-0.9.0.js'.match(rngScript)).not.toBeNull();
+
+ expect('my-angular-app-0.9.0.js'.match(rngScript)).toBeNull();
+ expect('foo/../my-angular-app-0.9.0.js'.match(rngScript)).toBeNull();
+ });
+
+ it('should match angular-0.9.0.min.js', function() {
+ expect('angular-0.9.0.min.js'.match(rngScript)).not.toBeNull();
+ expect('../angular-0.9.0.min.js'.match(rngScript)).not.toBeNull();
+ expect('foo/angular-0.9.0.min.js'.match(rngScript)).not.toBeNull();
+
+ expect('my-angular-app-0.9.0.min.js'.match(rngScript)).toBeNull();
+ expect('foo/../my-angular-app-0.9.0.min.js'.match(rngScript)).toBeNull();
+ });
+
+ it('should match angular-0.9.0-de0a8612.js', function() {
+ expect('angular-0.9.0-de0a8612.js'.match(rngScript)).not.toBeNull();
+ expect('../angular-0.9.0-de0a8612.js'.match(rngScript)).not.toBeNull();
+ expect('foo/angular-0.9.0-de0a8612.js'.match(rngScript)).not.toBeNull();
+
+ expect('my-angular-app-0.9.0-de0a8612.js'.match(rngScript)).toBeNull();
+ expect('foo/../my-angular-app-0.9.0-de0a8612.js'.match(rngScript)).toBeNull();
+ });
+
+ it('should match angular-0.9.0-de0a8612.min.js', function() {
+ expect('angular-0.9.0-de0a8612.min.js'.match(rngScript)).not.toBeNull();
+ expect('../angular-0.9.0-de0a8612.min.js'.match(rngScript)).not.toBeNull();
+ expect('foo/angular-0.9.0-de0a8612.min.js'.match(rngScript)).not.toBeNull();
+
+ expect('my-angular-app-0.9.0-de0a8612.min.js'.match(rngScript)).toBeNull();
+ expect('foo/../my-angular-app-0.9.0-de0a8612.min.js'.match(rngScript)).toBeNull();
+ });
+
+ it('should match angular-scenario.js', function() {
+ expect('angular-scenario.js'.match(rngScript)).not.toBeNull();
+ expect('angular-scenario.min.js'.match(rngScript)).not.toBeNull();
+ expect('../angular-scenario.js'.match(rngScript)).not.toBeNull();
+ expect('foo/angular-scenario.min.js'.match(rngScript)).not.toBeNull();
+ });
+
+ it('should match angular-scenario-0.9.0(.min).js', function() {
+ expect('angular-scenario-0.9.0.js'.match(rngScript)).not.toBeNull();
+ expect('angular-scenario-0.9.0.min.js'.match(rngScript)).not.toBeNull();
+ expect('../angular-scenario-0.9.0.js'.match(rngScript)).not.toBeNull();
+ expect('foo/angular-scenario-0.9.0.min.js'.match(rngScript)).not.toBeNull();
+ });
+
+ it('should match angular-scenario-0.9.0-de0a8612(.min).js', function() {
+ expect('angular-scenario-0.9.0-de0a8612.js'.match(rngScript)).not.toBeNull();
+ expect('angular-scenario-0.9.0-de0a8612.min.js'.match(rngScript)).not.toBeNull();
+ expect('../angular-scenario-0.9.0-de0a8612.js'.match(rngScript)).not.toBeNull();
+ expect('foo/angular-scenario-0.9.0-de0a8612.min.js'.match(rngScript)).not.toBeNull();
+ });
+ });
+
+
+ describe('angularJsConfig', function() {
+ it('should find angular.js script tag and config', function() {
+ var doc = { getElementsByTagName: function(tagName) {
+ expect(tagName).toEqual('script');
+ return [{nodeName: 'SCRIPT', src: 'random.js'},
+ {nodeName: 'SCRIPT', src: 'angular.js'},
+ {nodeName: 'SCRIPT', src: 'my-angular-app.js'}];
+ }
+ };
+
+ expect(angularJsConfig(doc)).toEqual({base_url: '',
+ ie_compat: 'angular-ie-compat.js',
+ ie_compat_id: 'ng-ie-compat'});
+ });
+
+
+ it('should extract angular config from the ng: attributes', function() {
+ var doc = { getElementsByTagName: function(tagName) {
+ expect(lowercase(tagName)).toEqual('script');
+ return [{nodeName: 'SCRIPT',
+ src: 'angularjs/angular.js',
+ attributes: [{name: 'ng:autobind', value:undefined},
+ {name: 'ng:css', value: 'css/my_custom_angular.css'},
+ {name: 'ng:ie-compat', value: 'myjs/angular-ie-compat.js'},
+ {name: 'ng:ie-compat-id', value: 'ngcompat'}] }];
+ }};
+
+ expect(angularJsConfig(doc)).toEqual({base_url: 'angularjs/',
+ autobind: true,
+ css: 'css/my_custom_angular.css',
+ ie_compat: 'myjs/angular-ie-compat.js',
+ ie_compat_id: 'ngcompat'});
+ });
+
+
+ it('should extract angular autobind config from the script hashpath attributes', function() {
+ var doc = { getElementsByTagName: function(tagName) {
+ expect(lowercase(tagName)).toEqual('script');
+ return [{nodeName: 'SCRIPT',
+ src: 'angularjs/angular.js#autobind'}];
+ }};
+
+ expect(angularJsConfig(doc)).toEqual({base_url: 'angularjs/',
+ autobind: true,
+ ie_compat: 'angularjs/angular-ie-compat.js',
+ ie_compat_id: 'ng-ie-compat'});
+ });
+
+
+ it("should default to versioned ie-compat file if angular file is versioned", function() {
+ var doc = { getElementsByTagName: function(tagName) {
+ expect(lowercase(tagName)).toEqual('script');
+ return [{nodeName: 'SCRIPT',
+ src: 'js/angular-0.9.0.js'}];
+ }};
+
+ expect(angularJsConfig(doc)).toEqual({base_url: 'js/',
+ ie_compat: 'js/angular-ie-compat-0.9.0.js',
+ ie_compat_id: 'ng-ie-compat'});
+ });
+
+
+ it("should default to versioned ie-compat file if angular file is versioned and minified", function() {
+ var doc = { getElementsByTagName: function(tagName) {
+ expect(lowercase(tagName)).toEqual('script');
+ return [{nodeName: 'SCRIPT',
+ src: 'js/angular-0.9.0-cba23f00.min.js'}];
+ }};
+
+ expect(angularJsConfig(doc)).toEqual({base_url: 'js/',
+ ie_compat: 'js/angular-ie-compat-0.9.0-cba23f00.js',
+ ie_compat_id: 'ng-ie-compat'});
+ });
+ });
+
+
+ describe('angular service', function() {
+ it('should override services', function() {
+ var scope = createScope();
+ angular.service('fake', function() { return 'old'; });
+ angular.service('fake', function() { return 'new'; });
+
+ expect(scope.$service('fake')).toEqual('new');
+ });
+
+ it('should not preserve properties on override', function() {
+ angular.service('fake', {$one: true}, {$two: true}, {three: true});
+ var result = angular.service('fake', {$four: true});
+
+ expect(result.$one).toBeUndefined();
+ expect(result.$two).toBeUndefined();
+ expect(result.three).toBeUndefined();
+ expect(result.$four).toBe(true);
+ });
+
+ it('should not preserve non-angular properties on override', function() {
+ angular.service('fake', {one: true}, {two: true});
+ var result = angular.service('fake', {third: true});
+
+ expect(result.one).not.toBeDefined();
+ expect(result.two).not.toBeDefined();
+ expect(result.third).toBeTruthy();
+ });
+ });
+
+ describe('isDate', function() {
+ it('should return true for Date object', function() {
+ expect(isDate(new Date())).toBe(true);
+ });
+
+ it('should return false for non Date objects', function() {
+ expect(isDate([])).toBe(false);
+ expect(isDate('')).toBe(false);
+ expect(isDate(23)).toBe(false);
+ expect(isDate({})).toBe(false);
+ });
+ });
+
+ describe('compile', function(){
+ var mvc;
+ afterEach(function(){
+ dealoc(mvc.view);
+ });
+
+ it('should link to existing node and create scope', function(){
+ mvc = angular.compile('<div>{{greeting = "hello world"}}</div>')();
+ expect(mvc.view.text()).toEqual('hello world');
+ expect(mvc.scope.greeting).toEqual('hello world');
+ });
+
+ it('should link to existing node and given scope', function(){
+ var scope = angular.scope();
+ mvc = angular.compile('<div>{{greeting = "hello world"}}</div>')(scope);
+ expect(mvc.view.text()).toEqual('hello world');
+ expect(mvc.scope).toEqual(scope);
+ });
+
+ it('should link to new node and given scope', function(){
+ var scope = angular.scope();
+ var template = jqLite('<div>{{greeting = "hello world"}}</div>');
+ var templateFn = angular.compile(template);
+ var templateClone = template.cloneNode();
+ mvc = templateFn(scope, templateClone);
+ expect(template.text()).toEqual('');
+ expect(mvc.view.text()).toEqual('hello world');
+ expect(mvc.view).toEqual(templateClone);
+ expect(mvc.scope.greeting).toEqual('hello world');
+ });
+
+ it('should link to cloned node and create scope', function(){
+ var scope = angular.scope();
+ var template = jqLite('<div>{{greeting = "hello world"}}</div>');
+ mvc = angular.compile(template)(scope, true);
+ expect(template.text()).toEqual('');
+ expect(mvc.view.text()).toEqual('hello world');
+ expect(mvc.scope.greeting).toEqual('hello world');
+ });
});
});
diff --git a/test/BinderSpec.js b/test/BinderSpec.js
index c3f90ad7..a1b9be14 100644
--- a/test/BinderSpec.js
+++ b/test/BinderSpec.js
@@ -4,7 +4,6 @@ describe('Binder', function(){
var self = this;
this.compile = function(html, parent) {
- var compiler = new Compiler(angularTextMarkup, angularAttrMarkup, angularDirective, angularWidget);
if (self.element) dealoc(self.element);
var element;
if (parent) {
@@ -14,11 +13,10 @@ describe('Binder', function(){
element = jqLite(html);
}
self.element = element;
- var scope = compiler.compile(element)(element);
- return {node:element, scope:scope};
+ return angular.compile(element)();
};
this.compileToHtml = function (content) {
- return sortedHtml(this.compile(content).node);
+ return sortedHtml(this.compile(content).view);
};
});
@@ -92,7 +90,7 @@ describe('Binder', function(){
var form = this.compile('<div ng:bind="model.a">x</div>');
form.scope.$set('model', {a:123});
form.scope.$eval();
- assertEquals('123', form.node.text());
+ assertEquals('123', form.view.text());
});
it('ReplaceBindingInTextWithSpan', function(){
@@ -115,7 +113,7 @@ describe('Binder', function(){
it('BindingOfAttributes', function(){
var c = this.compile("<a href='http://s/a{{b}}c' foo='x'></a>");
- var attrbinding = c.node.attr("ng:bind-attr");
+ var attrbinding = c.view.attr("ng:bind-attr");
var bindings = fromJson(attrbinding);
assertEquals("http://s/a{{b}}c", decodeURI(bindings.href));
assertTrue(!bindings.foo);
@@ -123,7 +121,7 @@ describe('Binder', function(){
it('MarkMultipleAttributes', function(){
var c = this.compile('<a href="http://s/a{{b}}c" foo="{{d}}"></a>');
- var attrbinding = c.node.attr("ng:bind-attr");
+ var attrbinding = c.view.attr("ng:bind-attr");
var bindings = fromJson(attrbinding);
assertEquals(bindings.foo, "{{d}}");
assertEquals(decodeURI(bindings.href), "http://s/a{{b}}c");
@@ -131,23 +129,23 @@ describe('Binder', function(){
it('AttributesNoneBound', function(){
var c = this.compile("<a href='abc' foo='def'></a>");
- var a = c.node;
+ var a = c.view;
assertEquals(a[0].nodeName, "A");
assertTrue(!a.attr("ng:bind-attr"));
});
it('ExistingAttrbindingIsAppended', function(){
var c = this.compile("<a href='http://s/{{abc}}' ng:bind-attr='{\"b\":\"{{def}}\"}'></a>");
- var a = c.node;
+ var a = c.view;
assertEquals('{"b":"{{def}}","href":"http://s/{{abc}}"}', a.attr('ng:bind-attr'));
});
it('AttributesAreEvaluated', function(){
var c = this.compile('<a ng:bind-attr=\'{"a":"a", "b":"a+b={{a+b}}"}\'></a>');
- var binder = c.binder, form = c.node;
+ var binder = c.binder, form = c.view;
c.scope.$eval('a=1;b=2');
c.scope.$eval();
- var a = c.node;
+ var a = c.view;
assertEquals(a.attr('a'), 'a');
assertEquals(a.attr('b'), 'a+b=3');
});
@@ -158,7 +156,7 @@ describe('Binder', function(){
c.scope.$set("person.save", function(){
savedCalled = true;
});
- browserTrigger(c.node, 'click');
+ browserTrigger(c.view, 'click');
assertTrue(savedCalled);
});
@@ -169,7 +167,7 @@ describe('Binder', function(){
log += 'click;';
});
expect(log).toEqual('');
- browserTrigger(c.node, 'click');
+ browserTrigger(c.view, 'click');
expect(log).toEqual('click;');
});
@@ -179,13 +177,13 @@ describe('Binder', function(){
c.scope.$set("person.save", function(){
savedCalled = true;
});
- browserTrigger(c.node, 'click');
+ browserTrigger(c.view, 'click');
assertTrue(savedCalled);
});
it('RepeaterUpdateBindings', function(){
var a = this.compile('<ul><LI ng:repeat="item in model.items" ng:bind="item.a"/></ul>');
- var form = a.node;
+ var form = a.view;
var items = [{a:"A"}, {a:"B"}];
a.scope.$set('model', {items:items});
@@ -225,7 +223,7 @@ describe('Binder', function(){
assertEquals('<ul>' +
'<#comment></#comment>' +
'<li ng:repeat-index="0"><span ng:bind="item.a">A</span></li>' +
- '</ul>', sortedHtml(a.node));
+ '</ul>', sortedHtml(a.view));
});
it('ExpandEntityTag', function(){
@@ -241,11 +239,11 @@ describe('Binder', function(){
it('RepeaterAdd', function(){
var c = this.compile('<div><input type="text" name="item.x" ng:repeat="item in items"></div>');
- var doc = c.node;
+ var doc = c.view;
c.scope.$set('items', [{x:'a'}, {x:'b'}]);
c.scope.$eval();
- var first = childNode(c.node, 1);
- var second = childNode(c.node, 2);
+ var first = childNode(c.view, 1);
+ var second = childNode(c.view, 2);
assertEquals('a', first.val());
assertEquals('b', second.val());
@@ -261,20 +259,20 @@ describe('Binder', function(){
c.scope.$set("items", items);
c.scope.$eval();
- expect(c.node[0].childNodes.length - 1).toEqual(0);
+ expect(c.view[0].childNodes.length - 1).toEqual(0);
items.name = "misko";
c.scope.$eval();
- expect(c.node[0].childNodes.length - 1).toEqual(1);
+ expect(c.view[0].childNodes.length - 1).toEqual(1);
delete items.name;
c.scope.$eval();
- expect(c.node[0].childNodes.length - 1).toEqual(0);
+ expect(c.view[0].childNodes.length - 1).toEqual(0);
});
it('IfTextBindingThrowsErrorDecorateTheSpan', function(){
var a = this.compile('<div>{{error.throw()}}</div>');
- var doc = a.node;
+ var doc = a.view;
var errorLogs = a.scope.$service('$log').error.logs;
a.scope.$set('error.throw', function(){throw "ErrorMsg1";});
@@ -303,7 +301,7 @@ describe('Binder', function(){
it('IfAttrBindingThrowsErrorDecorateTheAttribute', function(){
var a = this.compile('<div attr="before {{error.throw()}} after"></div>');
- var doc = a.node;
+ var doc = a.view;
var errorLogs = a.scope.$service('$log').error.logs;
a.scope.$set('error.throw', function(){throw "ErrorMsg";});
@@ -340,7 +338,7 @@ describe('Binder', function(){
'<#comment></#comment>'+
'<ul name="b1" ng:bind-attr="{"name":"{{i}}"}" ng:repeat-index="0"></ul>'+
'<ul name="b2" ng:bind-attr="{"name":"{{i}}"}" ng:repeat-index="1"></ul>'+
- '</div></div>', sortedHtml(a.node));
+ '</div></div>', sortedHtml(a.view));
});
it('HideBindingExpression', function(){
@@ -349,12 +347,12 @@ describe('Binder', function(){
a.scope.$set('hidden', 3);
a.scope.$eval();
- assertHidden(a.node);
+ assertHidden(a.view);
a.scope.$set('hidden', 2);
a.scope.$eval();
- assertVisible(a.node);
+ assertVisible(a.view);
});
it('HideBinding', function(){
@@ -363,17 +361,17 @@ describe('Binder', function(){
c.scope.$set('hidden', 'true');
c.scope.$eval();
- assertHidden(c.node);
+ assertHidden(c.view);
c.scope.$set('hidden', 'false');
c.scope.$eval();
- assertVisible(c.node);
+ assertVisible(c.view);
c.scope.$set('hidden', '');
c.scope.$eval();
- assertVisible(c.node);
+ assertVisible(c.view);
});
it('ShowBinding', function(){
@@ -382,17 +380,17 @@ describe('Binder', function(){
c.scope.$set('show', 'true');
c.scope.$eval();
- assertVisible(c.node);
+ assertVisible(c.view);
c.scope.$set('show', 'false');
c.scope.$eval();
- assertHidden(c.node);
+ assertHidden(c.view);
c.scope.$set('show', '');
c.scope.$eval();
- assertHidden(c.node);
+ assertHidden(c.view);
});
it('BindClassUndefined', function(){
@@ -401,7 +399,7 @@ describe('Binder', function(){
assertEquals(
'<div class="undefined" ng:class="undefined"></div>',
- sortedHtml(doc.node));
+ sortedHtml(doc.view));
});
it('BindClass', function(){
@@ -410,26 +408,26 @@ describe('Binder', function(){
c.scope.$set('class', 'testClass');
c.scope.$eval();
- assertEquals('<div class="testClass" ng:class="class"></div>', sortedHtml(c.node));
+ assertEquals('<div class="testClass" ng:class="class"></div>', sortedHtml(c.view));
c.scope.$set('class', ['a', 'b']);
c.scope.$eval();
- assertEquals('<div class="a b" ng:class="class"></div>', sortedHtml(c.node));
+ assertEquals('<div class="a b" ng:class="class"></div>', sortedHtml(c.view));
});
it('BindClassEvenOdd', function(){
var x = this.compile('<div><div ng:repeat="i in [0,1]" ng:class-even="\'e\'" ng:class-odd="\'o\'"/></div>');
x.scope.$eval();
- var d1 = jqLite(x.node[0].childNodes[1]);
- var d2 = jqLite(x.node[0].childNodes[2]);
+ var d1 = jqLite(x.view[0].childNodes[1]);
+ var d2 = jqLite(x.view[0].childNodes[2]);
expect(d1.hasClass('o')).toBeTruthy();
expect(d2.hasClass('e')).toBeTruthy();
assertEquals(
'<div><#comment></#comment>' +
'<div class="o" ng:class-even="\'e\'" ng:class-odd="\'o\'" ng:repeat-index="0"></div>' +
'<div class="e" ng:class-even="\'e\'" ng:class-odd="\'o\'" ng:repeat-index="1"></div></div>',
- sortedHtml(x.node));
+ sortedHtml(x.view));
});
it('BindStyle', function(){
@@ -438,7 +436,7 @@ describe('Binder', function(){
c.scope.$eval('style={color:"red"}');
c.scope.$eval();
- assertEquals("red", c.node.css('color'));
+ assertEquals("red", c.view.css('color'));
c.scope.$eval('style={}');
c.scope.$eval();
@@ -449,7 +447,7 @@ describe('Binder', function(){
c.scope.action = function(){
throw new Error('MyError');
};
- var input = c.node;
+ var input = c.view;
browserTrigger(input, 'click');
var error = input.attr('ng-exception');
assertTrue(!!error.match(/MyError/));
@@ -470,14 +468,14 @@ describe('Binder', function(){
"<div ng:non-bindable='true'>{{c}}</div></div>");
c.scope.$set('a', 123);
c.scope.$eval();
- assertEquals('123{{a}}{{b}}{{c}}', c.node.text());
+ assertEquals('123{{a}}{{b}}{{c}}', c.view.text());
});
it('OptionShouldUpdateParentToGetProperBinding', function(){
var c = this.compile('<select name="s"><option ng:repeat="i in [0,1]" value="{{i}}" ng:bind="i"></option></select>');
c.scope.$set('s', 1);
c.scope.$eval();
- assertEquals(1, c.node[0].selectedIndex);
+ assertEquals(1, c.view[0].selectedIndex);
});
it('RepeaterShouldBindInputsDefaults', function () {
@@ -494,7 +492,7 @@ describe('Binder', function(){
c.scope.$set("name", "World");
c.scope.$eval();
- assertEquals('<pre ng:bind-template="Hello {{name}}!">Hello World!</pre>', sortedHtml(c.node));
+ assertEquals('<pre ng:bind-template="Hello {{name}}!">Hello World!</pre>', sortedHtml(c.view));
});
it('FillInOptionValueWhenMissing', function(){
@@ -503,9 +501,9 @@ describe('Binder', function(){
c.scope.$set('a', 'A');
c.scope.$set('b', 'B');
c.scope.$eval();
- var optionA = childNode(c.node, 0);
- var optionB = childNode(c.node, 1);
- var optionC = childNode(c.node, 2);
+ var optionA = childNode(c.view, 0);
+ var optionB = childNode(c.view, 1);
+ var optionC = childNode(c.view, 2);
expect(optionA.attr('value')).toEqual('A');
expect(optionA.text()).toEqual('A');
@@ -565,7 +563,7 @@ describe('Binder', function(){
'<input name="c0" ng:bind-attr="{disabled:\'{{[0]}}\'}"><input name="c1" ng:bind-attr="{disabled:\'{{[]}}\'}"></div>');
c.scope.$eval();
function assertChild(index, disabled) {
- var child = childNode(c.node, index);
+ var child = childNode(c.view, index);
assertEquals(sortedHtml(child), disabled, !!child.attr('disabled'));
}
@@ -581,8 +579,8 @@ describe('Binder', function(){
var c = this.compile('<div>' +
'<input type="button" ng:click="greeting=\'ABC\'"/>' +
'<input type="button" ng:click=":garbage:"/></div>');
- var first = jqLite(c.node[0].childNodes[0]);
- var second = jqLite(c.node[0].childNodes[1]);
+ var first = jqLite(c.view[0].childNodes[0]);
+ var second = jqLite(c.view[0].childNodes[1]);
var errorLogs = c.scope.$service('$log').error.logs;
browserTrigger(first, 'click');
@@ -598,8 +596,8 @@ describe('Binder', function(){
var c = this.compile('<div>' +
'<input type="radio" name="sex" value="female"/>' +
'<input type="radio" name="sex" value="male"/></div>');
- var female = jqLite(c.node[0].childNodes[0]);
- var male = jqLite(c.node[0].childNodes[1]);
+ var female = jqLite(c.view[0].childNodes[0]);
+ var male = jqLite(c.view[0].childNodes[1]);
browserTrigger(female);
assertEquals("female", c.scope.sex);
@@ -636,7 +634,7 @@ describe('Binder', function(){
'<li ng:bind=\"k + v\" ng:repeat-index="0">a0</li>' +
'<li ng:bind=\"k + v\" ng:repeat-index="1">b1</li>' +
'</ul>',
- sortedHtml(x.node));
+ sortedHtml(x.view));
});
it('ItShouldFireChangeListenersBeforeUpdate', function(){
@@ -648,13 +646,13 @@ describe('Binder', function(){
assertEquals(123, x.scope.$get("name"));
assertEquals(
'<div ng:bind="name">123</div>',
- sortedHtml(x.node));
+ sortedHtml(x.view));
});
it('ItShouldHandleMultilineBindings', function(){
var x = this.compile('<div>{{\n 1 \n + \n 2 \n}}</div>');
x.scope.$eval();
- assertEquals("3", x.node.text());
+ assertEquals("3", x.view.text());
});
it('ItBindHiddenInputFields', function(){
@@ -667,7 +665,7 @@ describe('Binder', function(){
var x = this.compile('<input name="a" ng:format="list" value="a,b">');
x.scope.$eval();
assertEquals(['a','b'], x.scope.$get('a'));
- var input = x.node;
+ var input = x.view;
input[0].value = ' x,,yz';
browserTrigger(input, 'change');
assertEquals(['x','yz'], x.scope.$get('a'));
diff --git a/test/CompilerSpec.js b/test/CompilerSpec.js
index 647cc366..1a93ac78 100644
--- a/test/CompilerSpec.js
+++ b/test/CompilerSpec.js
@@ -27,8 +27,7 @@ describe('compiler', function(){
compiler = new Compiler(markup, attrMarkup, directives, widgets);
compile = function(html){
var e = jqLite("<div>" + html + "</div>");
- var scope = compiler.compile(e)(e);
- return scope;
+ return scope = compiler.compile(e)().scope;
};
});
@@ -48,7 +47,7 @@ describe('compiler', function(){
};
var template = compiler.compile(e);
expect(log).toEqual("found");
- scope = template(e);
+ scope = template(angular.scope(), e).scope;
expect(e.hasClass('ng-directive')).toEqual(true);
expect(log).toEqual("found:init");
});
@@ -85,7 +84,7 @@ describe('compiler', function(){
var template = this.compile(element);
return function(marker) {
this.$onEval(function() {
- marker.after(template(element.clone()).$element);
+ marker.after(template(angular.scope(), true).view);
});
};
};
diff --git a/test/ResourceSpec.js b/test/ResourceSpec.js
index d61282ea..adc93b92 100644
--- a/test/ResourceSpec.js
+++ b/test/ResourceSpec.js
@@ -169,7 +169,7 @@ describe("resource", function() {
});
it('should excersize full stack', function(){
- var scope = angular.compile('<div></div>');
+ var scope = angular.compile('<div></div>')().scope;
var $browser = scope.$service('$browser');
var $resource = scope.$service('$resource');
var Person = $resource('/Person/:id');
@@ -181,7 +181,7 @@ describe("resource", function() {
});
it('should return the same object when verifying the cache', function(){
- var scope = angular.compile('<div></div>');
+ var scope = angular.compile('<div></div>')().scope;
var $browser = scope.$service('$browser');
var $resource = scope.$service('$resource');
var Person = $resource('/Person/:id', null, {query: {method:'GET', isArray: true, verifyCache: true}});
diff --git a/test/ScenarioSpec.js b/test/ScenarioSpec.js
index cd1e3115..ce8ce69c 100644
--- a/test/ScenarioSpec.js
+++ b/test/ScenarioSpec.js
@@ -12,25 +12,25 @@ describe("ScenarioSpec: Compilation", function(){
describe('compilation', function(){
it("should compile dom node and return scope", function(){
var node = jqLite('<div ng:init="a=1">{{b=a+1}}</div>')[0];
- scope = compile(node);
+ scope = angular.compile(node)().scope;
expect(scope.a).toEqual(1);
expect(scope.b).toEqual(2);
});
it("should compile jQuery node and return scope", function(){
- scope = compile(jqLite('<div>{{a=123}}</div>'));
+ scope = compile(jqLite('<div>{{a=123}}</div>'))().scope;
expect(jqLite(scope.$element).text()).toEqual('123');
});
it("should compile text node and return scope", function(){
- scope = compile('<div>{{a=123}}</div>');
+ scope = angular.compile('<div>{{a=123}}</div>')().scope;
expect(jqLite(scope.$element).text()).toEqual('123');
});
});
describe('scope', function(){
it("should have $set, $get, $eval, $updateView methods", function(){
- scope = compile('<div>{{a}}</div>');
+ scope = angular.compile('<div>{{a}}</div>')().scope;
scope.$eval("$invalidWidgets.push({})");
expect(scope.$set("a", 2)).toEqual(2);
expect(scope.$get("a")).toEqual(2);
@@ -40,7 +40,7 @@ describe("ScenarioSpec: Compilation", function(){
});
it("should have $ objects", function(){
- scope = compile('<div></div>', {$config: {a:"b"}});
+ scope = angular.compile('<div></div>')(angular.scope({$config: {a:"b"}})).scope;
expect(scope.$service('$location')).toBeDefined();
expect(scope.$get('$eval')).toBeDefined();
expect(scope.$get('$config')).toBeDefined();
@@ -51,7 +51,7 @@ describe("ScenarioSpec: Compilation", function(){
describe("configuration", function(){
it("should take location object", function(){
var url = "http://server/#?book=moby";
- scope = compile("<div>{{$location}}</div>");
+ scope = angular.compile("<div>{{$location}}</div>")().scope;
var $location = scope.$service('$location');
var $browser = scope.$service('$browser');
expect($location.hashSearch.book).toBeUndefined();
diff --git a/test/ValidatorsSpec.js b/test/ValidatorsSpec.js
index 65b93133..2d4fca98 100644
--- a/test/ValidatorsSpec.js
+++ b/test/ValidatorsSpec.js
@@ -7,7 +7,7 @@ describe('ValidatorTest', function(){
validator.last = last;
validator._this = this;
};
- var scope = compile('<input name="name" ng:validate="myValidator:\'hevery\'"/>');
+ var scope = compile('<input name="name" ng:validate="myValidator:\'hevery\'"/>')().scope;
scope.name = 'misko';
scope.$eval();
assertEquals('misko', validator.first);
@@ -95,7 +95,7 @@ describe('ValidatorTest', function(){
beforeEach(function(){
value = null;
fn = null;
- self = compile('<input />');
+ self = angular.compile('<input />')().scope;
jqLite(document.body).append(self.$element);
self.$element.data('$validate', noop);
self.$root = self;
@@ -107,7 +107,8 @@ describe('ValidatorTest', function(){
it('should make a request and show spinner', function(){
var value, fn;
- var scope = compile('<input type="text" name="name" ng:validate="asynchronous:asyncFn"/>');
+ var scope = angular.compile(
+ '<input type="text" name="name" ng:validate="asynchronous:asyncFn"/>')().scope;
jqLite(document.body).append(scope.$element);
var input = scope.$element;
scope.asyncFn = function(v,f){
@@ -149,7 +150,8 @@ describe('ValidatorTest', function(){
});
it("should handle update function", function(){
- var scope = angular.compile('<input name="name" ng:validate="asynchronous:asyncFn:updateFn"/>');
+ var scope = angular.compile(
+ '<input name="name" ng:validate="asynchronous:asyncFn:updateFn"/>')().scope;
scope.asyncFn = jasmine.createSpy();
scope.updateFn = jasmine.createSpy();
scope.name = 'misko';
diff --git a/test/directivesSpec.js b/test/directivesSpec.js
index 8e5a10ee..2d4703a2 100644
--- a/test/directivesSpec.js
+++ b/test/directivesSpec.js
@@ -3,11 +3,9 @@ describe("directive", function(){
var compile, model, element;
beforeEach(function() {
- var compiler = new Compiler(angularTextMarkup, angularAttrMarkup, angularDirective, angularWidget);
compile = function(html) {
element = jqLite(html);
- model = compiler.compile(element)(element);
- return model;
+ return model = angular.compile(element)().scope;
};
});
diff --git a/test/markupSpec.js b/test/markupSpec.js
index 2462f19e..2c933f09 100644
--- a/test/markupSpec.js
+++ b/test/markupSpec.js
@@ -5,10 +5,9 @@ describe("markups", function(){
beforeEach(function() {
scope = null;
element = null;
- var compiler = new Compiler(angularTextMarkup, angularAttrMarkup, angularDirective, angularWidget);
compile = function(html) {
element = jqLite(html);
- scope = compiler.compile(element)(element);
+ scope = angular.compile(element)().scope;
};
});
diff --git a/test/service/invalidWidgetsSpec.js b/test/service/invalidWidgetsSpec.js
index b6b2da61..4a18dcf8 100644
--- a/test/service/invalidWidgetsSpec.js
+++ b/test/service/invalidWidgetsSpec.js
@@ -12,9 +12,9 @@ describe('$invalidWidgets', function() {
it("should count number of invalid widgets", function(){
- scope = compile('<input name="price" ng:required ng:validate="number"></input>');
- jqLite(document.body).append(scope.$element);
- scope.$init();
+ var element = jqLite('<input name="price" ng:required ng:validate="number"></input>')
+ jqLite(document.body).append(element);
+ scope = compile(element)().scope;
var $invalidWidgets = scope.$service('$invalidWidgets');
expect($invalidWidgets.length).toEqual(1);
diff --git a/test/service/routeSpec.js b/test/service/routeSpec.js
index 95258cc8..4dfa546c 100644
--- a/test/service/routeSpec.js
+++ b/test/service/routeSpec.js
@@ -18,7 +18,7 @@ describe('$route', function() {
function BookChapter() {
this.log = '<init>';
}
- scope = compile('<div></div>').$init();
+ scope = compile('<div></div>')().scope;
$location = scope.$service('$location');
$route = scope.$service('$route');
$route.when('/Book/:book/Chapter/:chapter', {controller: BookChapter, template:'Chapter.html'});
@@ -87,7 +87,7 @@ describe('$route', function() {
$route = scope.$service('$route'),
onChangeSpy = jasmine.createSpy('onChange');
- function NotFoundCtrl() {this.notFoundProp = 'not found!'}
+ function NotFoundCtrl() {this.notFoundProp = 'not found!';}
$route.when('/foo', {template: 'foo.html'});
$route.otherwise({template: '404.html', controller: NotFoundCtrl});
diff --git a/test/widgetsSpec.js b/test/widgetsSpec.js
index 606491a9..d4d0e43a 100644
--- a/test/widgetsSpec.js
+++ b/test/widgetsSpec.js
@@ -4,7 +4,6 @@ describe("widget", function(){
beforeEach(function() {
scope = null;
element = null;
- var compiler = new Compiler(angularTextMarkup, angularAttrMarkup, angularDirective, angularWidget);
compile = function(html, parent) {
if (parent) {
parent.html(html);
@@ -12,8 +11,7 @@ describe("widget", function(){
} else {
element = jqLite(html);
}
- scope = compiler.compile(element)(element);
- return scope;
+ return scope = angular.compile(element)().scope;
};
});
@@ -594,7 +592,7 @@ describe("widget", function(){
});
it('should call change on switch', function(){
- var scope = angular.compile('<ng:switch on="url" change="name=\'works\'"><div ng:switch-when="a">{{name}}</div></ng:switch>');
+ var scope = angular.compile('<ng:switch on="url" change="name=\'works\'"><div ng:switch-when="a">{{name}}</div></ng:switch>')().scope;
scope.url = 'a';
scope.$eval();
expect(scope.name).toEqual(undefined);
@@ -606,7 +604,7 @@ describe("widget", function(){
describe('ng:include', function(){
it('should include on external file', function() {
var element = jqLite('<ng:include src="url" scope="childScope"></ng:include>');
- var scope = angular.compile(element);
+ var scope = angular.compile(element)().scope;
scope.childScope = createScope();
scope.childScope.name = 'misko';
scope.url = 'myUrl';
@@ -619,7 +617,7 @@ describe("widget", function(){
it('should remove previously included text if a falsy value is bound to src', function() {
var element = jqLite('<ng:include src="url" scope="childScope"></ng:include>');
- var scope = angular.compile(element);
+ var scope = angular.compile(element)().scope;
scope.childScope = createScope();
scope.childScope.name = 'igor';
scope.url = 'myUrl';
@@ -638,7 +636,7 @@ describe("widget", function(){
it('should allow this for scope', function(){
var element = jqLite('<ng:include src="url" scope="this"></ng:include>');
- var scope = angular.compile(element);
+ var scope = angular.compile(element)().scope;
scope.url = 'myUrl';
scope.$service('$xhr.cache').data.myUrl = {value:'{{c=c+1}}'};
scope.$eval();
@@ -652,7 +650,7 @@ describe("widget", function(){
it('should evaluate onload expression when a partial is loaded', function() {
var element = jqLite('<ng:include src="url" onload="loaded = true"></ng:include>');
- var scope = angular.compile(element);
+ var scope = angular.compile(element)().scope;
expect(scope.loaded).not.toBeDefined();
@@ -791,7 +789,7 @@ describe("widget", function(){
var rootScope, rootScope, $route, $location, $browser;
beforeEach(function() {
- rootScope = angular.compile('<ng:view></ng:view>');
+ rootScope = angular.compile('<ng:view></ng:view>')().scope;
$route = rootScope.$service('$route');
$location = rootScope.$service('$location');
$browser = rootScope.$service('$browser');
@@ -870,7 +868,7 @@ describe("widget", function(){
rootScope = angular.compile(
'<div>' +
'include: <ng:include src="\'includePartial.html\'">' +
- '</ng:include></div>', myApp);
+ '</ng:include></div>')(myApp).scope;
$browser.xhr.expectGET('viewPartial.html').respond('content');
$browser.xhr.flush();