angular-gem 1.2.12 → 1.2.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/lib/angular-gem/version.rb +1 -1
- data/vendor/assets/javascripts/1.2.13/angular-animate.js +1589 -0
- data/vendor/assets/javascripts/1.2.13/angular-cookies.js +202 -0
- data/vendor/assets/javascripts/1.2.13/angular-loader.js +410 -0
- data/vendor/assets/javascripts/1.2.13/angular-mocks.js +2136 -0
- data/vendor/assets/javascripts/1.2.13/angular-resource.js +596 -0
- data/vendor/assets/javascripts/1.2.13/angular-route.js +921 -0
- data/vendor/assets/javascripts/1.2.13/angular-sanitize.js +625 -0
- data/vendor/assets/javascripts/1.2.13/angular-scenario.js +32880 -0
- data/vendor/assets/javascripts/1.2.13/angular-touch.js +563 -0
- data/vendor/assets/javascripts/1.2.13/angular.js +20874 -0
- data/vendor/assets/javascripts/angular-animate.js +331 -225
- data/vendor/assets/javascripts/angular-cookies.js +1 -1
- data/vendor/assets/javascripts/angular-loader.js +2 -2
- data/vendor/assets/javascripts/angular-mocks.js +29 -58
- data/vendor/assets/javascripts/angular-resource.js +5 -3
- data/vendor/assets/javascripts/angular-route.js +15 -14
- data/vendor/assets/javascripts/angular-sanitize.js +34 -31
- data/vendor/assets/javascripts/angular-scenario.js +930 -616
- data/vendor/assets/javascripts/angular-touch.js +1 -1
- data/vendor/assets/javascripts/angular.js +930 -616
- metadata +12 -2
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.2.
|
2
|
+
* @license AngularJS v1.2.13
|
3
3
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -69,7 +69,7 @@ function minErr(module) {
|
|
69
69
|
return match;
|
70
70
|
});
|
71
71
|
|
72
|
-
message = message + '\nhttp://errors.angularjs.org/1.2.
|
72
|
+
message = message + '\nhttp://errors.angularjs.org/1.2.13/' +
|
73
73
|
(module ? module + '/' : '') + code;
|
74
74
|
for (i = 2; i < arguments.length; i++) {
|
75
75
|
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.2.
|
2
|
+
* @license AngularJS v1.2.13
|
3
3
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -386,7 +386,7 @@ angular.mock.$LogProvider = function() {
|
|
386
386
|
*
|
387
387
|
* @example
|
388
388
|
* <pre>
|
389
|
-
* $log.
|
389
|
+
* $log.error('Some Error');
|
390
390
|
* var first = $log.error.logs.unshift();
|
391
391
|
* </pre>
|
392
392
|
*/
|
@@ -511,6 +511,7 @@ angular.mock.$IntervalProvider = function() {
|
|
511
511
|
};
|
512
512
|
|
513
513
|
$interval.cancel = function(promise) {
|
514
|
+
if(!promise) return false;
|
514
515
|
var fnIndex;
|
515
516
|
|
516
517
|
angular.forEach(repeatFns, function(fn, index) {
|
@@ -763,70 +764,40 @@ angular.mock.TzDate = function (offset, timestamp) {
|
|
763
764
|
angular.mock.TzDate.prototype = Date.prototype;
|
764
765
|
/* jshint +W101 */
|
765
766
|
|
766
|
-
|
767
|
-
// presence of a registered module
|
768
|
-
var animateLoaded;
|
769
|
-
try {
|
770
|
-
angular.module('ngAnimate');
|
771
|
-
animateLoaded = true;
|
772
|
-
} catch(e) {}
|
767
|
+
angular.mock.animate = angular.module('ngAnimateMock', ['ng'])
|
773
768
|
|
774
|
-
|
775
|
-
angular.module('ngAnimate').config(['$provide', function($provide) {
|
769
|
+
.config(['$provide', function($provide) {
|
776
770
|
var reflowQueue = [];
|
771
|
+
|
777
772
|
$provide.value('$$animateReflow', function(fn) {
|
778
773
|
reflowQueue.push(fn);
|
779
774
|
return angular.noop;
|
780
775
|
});
|
781
|
-
$provide.decorator('$animate', function($delegate) {
|
782
|
-
$delegate.triggerReflow = function() {
|
783
|
-
if(reflowQueue.length === 0) {
|
784
|
-
throw new Error('No animation reflows present');
|
785
|
-
}
|
786
|
-
angular.forEach(reflowQueue, function(fn) {
|
787
|
-
fn();
|
788
|
-
});
|
789
|
-
reflowQueue = [];
|
790
|
-
};
|
791
|
-
return $delegate;
|
792
|
-
});
|
793
|
-
}]);
|
794
|
-
}
|
795
|
-
|
796
|
-
angular.mock.animate = angular.module('mock.animate', ['ng'])
|
797
|
-
|
798
|
-
.config(['$provide', function($provide) {
|
799
776
|
|
800
777
|
$provide.decorator('$animate', function($delegate) {
|
801
778
|
var animate = {
|
802
779
|
queue : [],
|
803
780
|
enabled : $delegate.enabled,
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
if (!tick) throw new Error('No animation to be flushed');
|
808
|
-
if(tick.method !== name) {
|
809
|
-
throw new Error('The next animation is not "' + name +
|
810
|
-
'", but is "' + tick.method + '"');
|
781
|
+
triggerReflow : function() {
|
782
|
+
if(reflowQueue.length === 0) {
|
783
|
+
throw new Error('No animation reflows present');
|
811
784
|
}
|
812
|
-
|
813
|
-
|
785
|
+
angular.forEach(reflowQueue, function(fn) {
|
786
|
+
fn();
|
787
|
+
});
|
788
|
+
reflowQueue = [];
|
814
789
|
}
|
815
790
|
};
|
816
791
|
|
817
|
-
angular.forEach(
|
792
|
+
angular.forEach(
|
793
|
+
['enter','leave','move','addClass','removeClass','setClass'], function(method) {
|
818
794
|
animate[method] = function() {
|
819
|
-
var params = arguments;
|
820
795
|
animate.queue.push({
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
parent : angular.isElement(params[1]) && params[1],
|
825
|
-
after : angular.isElement(params[2]) && params[2],
|
826
|
-
fn : function() {
|
827
|
-
$delegate[method].apply($delegate, params);
|
828
|
-
}
|
796
|
+
event : method,
|
797
|
+
element : arguments[0],
|
798
|
+
args : arguments
|
829
799
|
});
|
800
|
+
$delegate[method].apply($delegate, arguments);
|
830
801
|
};
|
831
802
|
});
|
832
803
|
|
@@ -996,18 +967,18 @@ angular.mock.dump = function(object) {
|
|
996
967
|
*
|
997
968
|
* # Flushing HTTP requests
|
998
969
|
*
|
999
|
-
* The $httpBackend used in production
|
1000
|
-
* If we preserved this behavior in unit testing
|
1001
|
-
* hard to write,
|
970
|
+
* The $httpBackend used in production always responds to requests with responses asynchronously.
|
971
|
+
* If we preserved this behavior in unit testing we'd have to create async unit tests, which are
|
972
|
+
* hard to write, understand, and maintain. However, the testing mock can't respond
|
1002
973
|
* synchronously because that would change the execution of the code under test. For this reason the
|
1003
974
|
* mock $httpBackend has a `flush()` method, which allows the test to explicitly flush pending
|
1004
|
-
* requests and thus
|
975
|
+
* requests and thus preserve the async api of the backend while allowing the test to execute
|
1005
976
|
* synchronously.
|
1006
977
|
*
|
1007
978
|
*
|
1008
979
|
* # Unit testing with mock $httpBackend
|
1009
|
-
* The following code shows how to setup and use the mock backend
|
1010
|
-
* First we create the controller under test
|
980
|
+
* The following code shows how to setup and use the mock backend when unit testing a controller.
|
981
|
+
* First we create the controller under test:
|
1011
982
|
*
|
1012
983
|
<pre>
|
1013
984
|
// The controller code
|
@@ -1032,7 +1003,7 @@ angular.mock.dump = function(object) {
|
|
1032
1003
|
}
|
1033
1004
|
</pre>
|
1034
1005
|
*
|
1035
|
-
* Now we setup the mock backend and create the test specs
|
1006
|
+
* Now we setup the mock backend and create the test specs:
|
1036
1007
|
*
|
1037
1008
|
<pre>
|
1038
1009
|
// testing controller
|
@@ -1736,7 +1707,7 @@ angular.mock.$RootElementProvider = function() {
|
|
1736
1707
|
* In addition, ngMock also extends various core ng services such that they can be
|
1737
1708
|
* inspected and controlled in a synchronous manner within test code.
|
1738
1709
|
*
|
1739
|
-
* {@installModule
|
1710
|
+
* {@installModule mock}
|
1740
1711
|
*
|
1741
1712
|
* <div doc-module-components="ngMock"></div>
|
1742
1713
|
*
|
@@ -1954,7 +1925,7 @@ if(window.jasmine || window.mocha) {
|
|
1954
1925
|
|
1955
1926
|
var currentSpec = null,
|
1956
1927
|
isSpecRunning = function() {
|
1957
|
-
return currentSpec
|
1928
|
+
return !!currentSpec;
|
1958
1929
|
};
|
1959
1930
|
|
1960
1931
|
|
@@ -2132,7 +2103,7 @@ if(window.jasmine || window.mocha) {
|
|
2132
2103
|
window.inject = angular.mock.inject = function() {
|
2133
2104
|
var blockFns = Array.prototype.slice.call(arguments, 0);
|
2134
2105
|
var errorForStack = new Error('Declaration Location');
|
2135
|
-
return isSpecRunning() ? workFn() : workFn;
|
2106
|
+
return isSpecRunning() ? workFn.call(currentSpec) : workFn;
|
2136
2107
|
/////////////////////
|
2137
2108
|
function workFn() {
|
2138
2109
|
var modules = currentSpec.$modules || [];
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.2.
|
2
|
+
* @license AngularJS v1.2.13
|
3
3
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -40,7 +40,7 @@ function shallowClearAndCopy(src, dst) {
|
|
40
40
|
});
|
41
41
|
|
42
42
|
for (var key in src) {
|
43
|
-
if (src.hasOwnProperty(key) && key.charAt(0)
|
43
|
+
if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
|
44
44
|
dst[key] = src[key];
|
45
45
|
}
|
46
46
|
}
|
@@ -392,7 +392,9 @@ angular.module('ngResource', ['ng']).
|
|
392
392
|
val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam];
|
393
393
|
if (angular.isDefined(val) && val !== null) {
|
394
394
|
encodedVal = encodeUriSegment(val);
|
395
|
-
url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"),
|
395
|
+
url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), function(match, p1) {
|
396
|
+
return encodedVal + p1;
|
397
|
+
});
|
396
398
|
} else {
|
397
399
|
url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W|$)", "g"), function(match,
|
398
400
|
leadingSlashes, tail) {
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.2.
|
2
|
+
* @license AngularJS v1.2.13
|
3
3
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -190,7 +190,7 @@ function $RouteProvider(){
|
|
190
190
|
|
191
191
|
path = path
|
192
192
|
.replace(/([().])/g, '\\$1')
|
193
|
-
.replace(/(\/)?:(\w+)([
|
193
|
+
.replace(/(\/)?:(\w+)([\?\*])?/g, function(_, slash, key, option){
|
194
194
|
var optional = option === '?' ? option : null;
|
195
195
|
var star = option === '*' ? option : null;
|
196
196
|
keys.push({ name: key, optional: !!optional });
|
@@ -350,17 +350,17 @@ function $RouteProvider(){
|
|
350
350
|
}
|
351
351
|
</file>
|
352
352
|
|
353
|
-
<file name="
|
353
|
+
<file name="protractorTest.js">
|
354
354
|
it('should load and compile correct template', function() {
|
355
|
-
element('
|
356
|
-
var content = element('.doc-example-live [ng-view]').
|
355
|
+
element(by.linkText('Moby: Ch1')).click();
|
356
|
+
var content = element(by.css('.doc-example-live [ng-view]')).getText();
|
357
357
|
expect(content).toMatch(/controller\: ChapterCntl/);
|
358
358
|
expect(content).toMatch(/Book Id\: Moby/);
|
359
359
|
expect(content).toMatch(/Chapter Id\: 1/);
|
360
360
|
|
361
|
-
element('
|
362
|
-
|
363
|
-
content = element('.doc-example-live [ng-view]').
|
361
|
+
element(by.partialLinkText('Scarlet')).click();
|
362
|
+
|
363
|
+
content = element(by.css('.doc-example-live [ng-view]')).getText();
|
364
364
|
expect(content).toMatch(/controller\: BookCntl/);
|
365
365
|
expect(content).toMatch(/Book Id\: Scarlet/);
|
366
366
|
});
|
@@ -375,7 +375,7 @@ function $RouteProvider(){
|
|
375
375
|
* @eventType broadcast on root scope
|
376
376
|
* @description
|
377
377
|
* Broadcasted before a route change. At this point the route services starts
|
378
|
-
* resolving all of the dependencies needed for the route change to
|
378
|
+
* resolving all of the dependencies needed for the route change to occur.
|
379
379
|
* Typically this involves fetching the view template as well as any dependencies
|
380
380
|
* defined in `resolve` route property. Once all of the dependencies are resolved
|
381
381
|
* `$routeChangeSuccess` is fired.
|
@@ -794,16 +794,17 @@ ngRouteModule.directive('ngView', ngViewFillContentFactory);
|
|
794
794
|
}
|
795
795
|
</file>
|
796
796
|
|
797
|
-
<file name="
|
797
|
+
<file name="protractorTest.js">
|
798
798
|
it('should load and compile correct template', function() {
|
799
|
-
element('
|
800
|
-
var content = element('.doc-example-live [ng-view]').
|
799
|
+
element(by.linkText('Moby: Ch1')).click();
|
800
|
+
var content = element(by.css('.doc-example-live [ng-view]')).getText();
|
801
801
|
expect(content).toMatch(/controller\: ChapterCntl/);
|
802
802
|
expect(content).toMatch(/Book Id\: Moby/);
|
803
803
|
expect(content).toMatch(/Chapter Id\: 1/);
|
804
804
|
|
805
|
-
element('
|
806
|
-
|
805
|
+
element(by.partialLinkText('Scarlet')).click();
|
806
|
+
|
807
|
+
content = element(by.css('.doc-example-live [ng-view]')).getText();
|
807
808
|
expect(content).toMatch(/controller\: BookCntl/);
|
808
809
|
expect(content).toMatch(/Book Id\: Scarlet/);
|
809
810
|
});
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.2.
|
2
|
+
* @license AngularJS v1.2.13
|
3
3
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -104,35 +104,37 @@ var $sanitizeMinErr = angular.$$minErr('$sanitize');
|
|
104
104
|
</table>
|
105
105
|
</div>
|
106
106
|
</doc:source>
|
107
|
-
<doc:
|
107
|
+
<doc:protractor>
|
108
108
|
it('should sanitize the html snippet by default', function() {
|
109
|
-
expect(
|
109
|
+
expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
|
110
110
|
toBe('<p>an html\n<em>click here</em>\nsnippet</p>');
|
111
111
|
});
|
112
112
|
|
113
113
|
it('should inline raw snippet if bound to a trusted value', function() {
|
114
|
-
expect(
|
114
|
+
expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).
|
115
115
|
toBe("<p style=\"color:blue\">an html\n" +
|
116
116
|
"<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
|
117
117
|
"snippet</p>");
|
118
118
|
});
|
119
119
|
|
120
120
|
it('should escape snippet without any filter', function() {
|
121
|
-
expect(
|
121
|
+
expect(element(by.css('#bind-default div')).getInnerHtml()).
|
122
122
|
toBe("<p style=\"color:blue\">an html\n" +
|
123
123
|
"<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
|
124
124
|
"snippet</p>");
|
125
125
|
});
|
126
126
|
|
127
127
|
it('should update', function() {
|
128
|
-
|
129
|
-
|
130
|
-
expect(
|
128
|
+
element(by.model('snippet')).clear();
|
129
|
+
element(by.model('snippet')).sendKeys('new <b onclick="alert(1)">text</b>');
|
130
|
+
expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
|
131
|
+
toBe('new <b>text</b>');
|
132
|
+
expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).toBe(
|
131
133
|
'new <b onclick="alert(1)">text</b>');
|
132
|
-
expect(
|
134
|
+
expect(element(by.css('#bind-default div')).getInnerHtml()).toBe(
|
133
135
|
"new <b onclick=\"alert(1)\">text</b>");
|
134
136
|
});
|
135
|
-
</doc:
|
137
|
+
</doc:protractor>
|
136
138
|
</doc:example>
|
137
139
|
*/
|
138
140
|
function $SanitizeProvider() {
|
@@ -537,37 +539,38 @@ angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider);
|
|
537
539
|
</tr>
|
538
540
|
</table>
|
539
541
|
</doc:source>
|
540
|
-
<doc:
|
542
|
+
<doc:protractor>
|
541
543
|
it('should linkify the snippet with urls', function() {
|
542
|
-
expect(
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
'<a href="mailto:another@somewhere.org">another@somewhere.org</a>, ' +
|
547
|
-
'and one more: <a href="ftp://127.0.0.1/">ftp://127.0.0.1/</a>.');
|
544
|
+
expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
|
545
|
+
toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' +
|
546
|
+
'another@somewhere.org, and one more: ftp://127.0.0.1/.');
|
547
|
+
expect(element.all(by.css('#linky-filter a')).count()).toEqual(4);
|
548
548
|
});
|
549
549
|
|
550
|
-
it
|
551
|
-
expect(
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
"another@somewhere.org,\n" +
|
556
|
-
"and one more: ftp://127.0.0.1/.");
|
550
|
+
it('should not linkify snippet without the linky filter', function() {
|
551
|
+
expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()).
|
552
|
+
toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' +
|
553
|
+
'another@somewhere.org, and one more: ftp://127.0.0.1/.');
|
554
|
+
expect(element.all(by.css('#escaped-html a')).count()).toEqual(0);
|
557
555
|
});
|
558
556
|
|
559
557
|
it('should update', function() {
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
558
|
+
element(by.model('snippet')).clear();
|
559
|
+
element(by.model('snippet')).sendKeys('new http://link.');
|
560
|
+
expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
|
561
|
+
toBe('new http://link.');
|
562
|
+
expect(element.all(by.css('#linky-filter a')).count()).toEqual(1);
|
563
|
+
expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText())
|
564
|
+
.toBe('new http://link.');
|
564
565
|
});
|
565
566
|
|
566
567
|
it('should work with the target property', function() {
|
567
|
-
expect(
|
568
|
-
|
568
|
+
expect(element(by.id('linky-target')).
|
569
|
+
element(by.binding("snippetWithTarget | linky:'_blank'")).getText()).
|
570
|
+
toBe('http://angularjs.org/');
|
571
|
+
expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank');
|
569
572
|
});
|
570
|
-
</doc:
|
573
|
+
</doc:protractor>
|
571
574
|
</doc:example>
|
572
575
|
*/
|
573
576
|
angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
|
@@ -9790,7 +9790,7 @@ if ( typeof module === "object" && module && typeof module.exports === "object"
|
|
9790
9790
|
})( window );
|
9791
9791
|
|
9792
9792
|
/**
|
9793
|
-
* @license AngularJS v1.2.
|
9793
|
+
* @license AngularJS v1.2.13
|
9794
9794
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
9795
9795
|
* License: MIT
|
9796
9796
|
*/
|
@@ -9860,7 +9860,7 @@ function minErr(module) {
|
|
9860
9860
|
return match;
|
9861
9861
|
});
|
9862
9862
|
|
9863
|
-
message = message + '\nhttp://errors.angularjs.org/1.2.
|
9863
|
+
message = message + '\nhttp://errors.angularjs.org/1.2.13/' +
|
9864
9864
|
(module ? module + '/' : '') + code;
|
9865
9865
|
for (i = 2; i < arguments.length; i++) {
|
9866
9866
|
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
|
@@ -9952,6 +9952,7 @@ function minErr(module) {
|
|
9952
9952
|
-assertNotHasOwnProperty,
|
9953
9953
|
-getter,
|
9954
9954
|
-getBlockElements,
|
9955
|
+
-hasOwnProperty,
|
9955
9956
|
|
9956
9957
|
*/
|
9957
9958
|
|
@@ -9967,7 +9968,7 @@ function minErr(module) {
|
|
9967
9968
|
* @returns {string} Lowercased string.
|
9968
9969
|
*/
|
9969
9970
|
var lowercase = function(string){return isString(string) ? string.toLowerCase() : string;};
|
9970
|
-
|
9971
|
+
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
9971
9972
|
|
9972
9973
|
/**
|
9973
9974
|
* @ngdoc function
|
@@ -10063,7 +10064,7 @@ function isArrayLike(obj) {
|
|
10063
10064
|
* is the value of an object property or an array element and `key` is the object property key or
|
10064
10065
|
* array element index. Specifying a `context` for the function is optional.
|
10065
10066
|
*
|
10066
|
-
* It is worth
|
10067
|
+
* It is worth noting that `.forEach` does not iterate over inherited properties because it filters
|
10067
10068
|
* using the `hasOwnProperty` method.
|
10068
10069
|
*
|
10069
10070
|
<pre>
|
@@ -10072,7 +10073,7 @@ function isArrayLike(obj) {
|
|
10072
10073
|
angular.forEach(values, function(value, key){
|
10073
10074
|
this.push(key + ': ' + value);
|
10074
10075
|
}, log);
|
10075
|
-
expect(log).toEqual(['name: misko', 'gender:male']);
|
10076
|
+
expect(log).toEqual(['name: misko', 'gender: male']);
|
10076
10077
|
</pre>
|
10077
10078
|
*
|
10078
10079
|
* @param {Object|Array} obj Object to iterate over.
|
@@ -10643,7 +10644,7 @@ function shallowCopy(src, dst) {
|
|
10643
10644
|
for(var key in src) {
|
10644
10645
|
// shallowCopy is only ever called by $compile nodeLinkFn, which has control over src
|
10645
10646
|
// so we don't need to worry about using our custom hasOwnProperty here
|
10646
|
-
if (src.hasOwnProperty(key) && key.charAt(0)
|
10647
|
+
if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
|
10647
10648
|
dst[key] = src[key];
|
10648
10649
|
}
|
10649
10650
|
}
|
@@ -11002,6 +11003,7 @@ function encodeUriQuery(val, pctEncodeSpaces) {
|
|
11002
11003
|
<file name="index.html">
|
11003
11004
|
<div ng-controller="ngAppDemoController">
|
11004
11005
|
I can add: {{a}} + {{b}} = {{ a+b }}
|
11006
|
+
</div>
|
11005
11007
|
</file>
|
11006
11008
|
<file name="script.js">
|
11007
11009
|
angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) {
|
@@ -11626,11 +11628,11 @@ function setupModuleLoader(window) {
|
|
11626
11628
|
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
|
11627
11629
|
*/
|
11628
11630
|
var version = {
|
11629
|
-
full: '1.2.
|
11631
|
+
full: '1.2.13', // all of these placeholder strings will be replaced by grunt's
|
11630
11632
|
major: 1, // package task
|
11631
11633
|
minor: 2,
|
11632
|
-
dot:
|
11633
|
-
codeName: '
|
11634
|
+
dot: 13,
|
11635
|
+
codeName: 'romantic-transclusion'
|
11634
11636
|
};
|
11635
11637
|
|
11636
11638
|
|
@@ -11792,7 +11794,7 @@ function publishExternalAPI(angular){
|
|
11792
11794
|
* - [`after()`](http://api.jquery.com/after/)
|
11793
11795
|
* - [`append()`](http://api.jquery.com/append/)
|
11794
11796
|
* - [`attr()`](http://api.jquery.com/attr/)
|
11795
|
-
* - [`bind()`](http://api.jquery.com/
|
11797
|
+
* - [`bind()`](http://api.jquery.com/bind/) - Does not support namespaces, selectors or eventData
|
11796
11798
|
* - [`children()`](http://api.jquery.com/children/) - Does not support selectors
|
11797
11799
|
* - [`clone()`](http://api.jquery.com/clone/)
|
11798
11800
|
* - [`contents()`](http://api.jquery.com/contents/)
|
@@ -11819,7 +11821,7 @@ function publishExternalAPI(angular){
|
|
11819
11821
|
* - [`text()`](http://api.jquery.com/text/)
|
11820
11822
|
* - [`toggleClass()`](http://api.jquery.com/toggleClass/)
|
11821
11823
|
* - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers.
|
11822
|
-
* - [`unbind()`](http://api.jquery.com/
|
11824
|
+
* - [`unbind()`](http://api.jquery.com/unbind/) - Does not support namespaces
|
11823
11825
|
* - [`val()`](http://api.jquery.com/val/)
|
11824
11826
|
* - [`wrap()`](http://api.jquery.com/wrap/)
|
11825
11827
|
*
|
@@ -11859,6 +11861,14 @@ var jqCache = JQLite.cache = {},
|
|
11859
11861
|
? function(element, type, fn) {element.removeEventListener(type, fn, false); }
|
11860
11862
|
: function(element, type, fn) {element.detachEvent('on' + type, fn); });
|
11861
11863
|
|
11864
|
+
/*
|
11865
|
+
* !!! This is an undocumented "private" function !!!
|
11866
|
+
*/
|
11867
|
+
var jqData = JQLite._data = function(node) {
|
11868
|
+
//jQuery always returns an object on cache miss
|
11869
|
+
return this.cache[node[this.expando]] || {};
|
11870
|
+
};
|
11871
|
+
|
11862
11872
|
function jqNextId() { return ++jqId; }
|
11863
11873
|
|
11864
11874
|
|
@@ -11927,6 +11937,9 @@ function JQLite(element) {
|
|
11927
11937
|
if (element instanceof JQLite) {
|
11928
11938
|
return element;
|
11929
11939
|
}
|
11940
|
+
if (isString(element)) {
|
11941
|
+
element = trim(element);
|
11942
|
+
}
|
11930
11943
|
if (!(this instanceof JQLite)) {
|
11931
11944
|
if (isString(element) && element.charAt(0) != '<') {
|
11932
11945
|
throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');
|
@@ -13072,11 +13085,9 @@ function annotate(fn) {
|
|
13072
13085
|
* @param {(Object|function())} provider If the provider is:
|
13073
13086
|
*
|
13074
13087
|
* - `Object`: then it should have a `$get` method. The `$get` method will be invoked using
|
13075
|
-
*
|
13076
|
-
*
|
13077
|
-
*
|
13078
|
-
* {@link AUTO.$injector#instantiate $injector.instantiate()}, then treated as
|
13079
|
-
* `object`.
|
13088
|
+
* {@link AUTO.$injector#invoke $injector.invoke()} when an instance needs to be created.
|
13089
|
+
* - `Constructor`: a new instance of the provider will be created using
|
13090
|
+
* {@link AUTO.$injector#instantiate $injector.instantiate()}, then treated as `object`.
|
13080
13091
|
*
|
13081
13092
|
* @returns {Object} registered provider instance
|
13082
13093
|
|
@@ -13202,17 +13213,16 @@ function annotate(fn) {
|
|
13202
13213
|
* Here is an example of registering a service using
|
13203
13214
|
* {@link AUTO.$provide#methods_service $provide.service(class)}.
|
13204
13215
|
* <pre>
|
13205
|
-
*
|
13206
|
-
*
|
13207
|
-
*
|
13208
|
-
*
|
13209
|
-
*
|
13210
|
-
* Ping.prototype.send = function() {
|
13211
|
-
* return this.$http.get('/ping');
|
13212
|
-
* };
|
13216
|
+
* var Ping = function($http) {
|
13217
|
+
* this.$http = $http;
|
13218
|
+
* };
|
13219
|
+
*
|
13220
|
+
* Ping.$inject = ['$http'];
|
13213
13221
|
*
|
13214
|
-
*
|
13215
|
-
*
|
13222
|
+
* Ping.prototype.send = function() {
|
13223
|
+
* return this.$http.get('/ping');
|
13224
|
+
* };
|
13225
|
+
* $provide.service('ping', Ping);
|
13216
13226
|
* </pre>
|
13217
13227
|
* You would then inject and use this service like this:
|
13218
13228
|
* <pre>
|
@@ -13310,7 +13320,7 @@ function annotate(fn) {
|
|
13310
13320
|
* Here we decorate the {@link ng.$log $log} service to convert warnings to errors by intercepting
|
13311
13321
|
* calls to {@link ng.$log#error $log.warn()}.
|
13312
13322
|
* <pre>
|
13313
|
-
* $
|
13323
|
+
* $provide.decorator('$log', ['$delegate', function($delegate) {
|
13314
13324
|
* $delegate.warn = $delegate.error;
|
13315
13325
|
* return $delegate;
|
13316
13326
|
* }]);
|
@@ -13849,6 +13859,29 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
13849
13859
|
done && $timeout(done, 0, false);
|
13850
13860
|
},
|
13851
13861
|
|
13862
|
+
/**
|
13863
|
+
*
|
13864
|
+
* @ngdoc function
|
13865
|
+
* @name ng.$animate#setClass
|
13866
|
+
* @methodOf ng.$animate
|
13867
|
+
* @function
|
13868
|
+
* @description Adds and/or removes the given CSS classes to and from the element.
|
13869
|
+
* Once complete, the done() callback will be fired (if provided).
|
13870
|
+
* @param {jQuery/jqLite element} element the element which will it's CSS classes changed
|
13871
|
+
* removed from it
|
13872
|
+
* @param {string} add the CSS classes which will be added to the element
|
13873
|
+
* @param {string} remove the CSS class which will be removed from the element
|
13874
|
+
* @param {function=} done the callback function (if provided) that will be fired after the
|
13875
|
+
* CSS classes have been set on the element
|
13876
|
+
*/
|
13877
|
+
setClass : function(element, add, remove, done) {
|
13878
|
+
forEach(element, function (element) {
|
13879
|
+
jqLiteAddClass(element, add);
|
13880
|
+
jqLiteRemoveClass(element, remove);
|
13881
|
+
});
|
13882
|
+
done && $timeout(done, 0, false);
|
13883
|
+
},
|
13884
|
+
|
13852
13885
|
enabled : noop
|
13853
13886
|
};
|
13854
13887
|
}];
|
@@ -14913,13 +14946,17 @@ function $TemplateCacheProvider() {
|
|
14913
14946
|
<div compile="html"></div>
|
14914
14947
|
</div>
|
14915
14948
|
</doc:source>
|
14916
|
-
<doc:
|
14949
|
+
<doc:protractor>
|
14917
14950
|
it('should auto compile', function() {
|
14918
|
-
|
14919
|
-
|
14920
|
-
|
14951
|
+
var textarea = $('textarea');
|
14952
|
+
var output = $('div[compile]');
|
14953
|
+
// The initial state reads 'Hello Angular'.
|
14954
|
+
expect(output.getText()).toBe('Hello Angular');
|
14955
|
+
textarea.clear();
|
14956
|
+
textarea.sendKeys('{{name}}!');
|
14957
|
+
expect(output.getText()).toBe('Angular!');
|
14921
14958
|
});
|
14922
|
-
</doc:
|
14959
|
+
</doc:protractor>
|
14923
14960
|
</doc:example>
|
14924
14961
|
|
14925
14962
|
*
|
@@ -14987,7 +15024,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
14987
15024
|
var hasDirectives = {},
|
14988
15025
|
Suffix = 'Directive',
|
14989
15026
|
COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,
|
14990
|
-
CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)
|
15027
|
+
CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/,
|
15028
|
+
TABLE_CONTENT_REGEXP = /^<\s*(tr|th|td|tbody)(\s+[^>]*)?>/i;
|
14991
15029
|
|
14992
15030
|
// Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes
|
14993
15031
|
// The assumption is that future DOM event attribute names will begin with
|
@@ -15174,8 +15212,16 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
15174
15212
|
* @param {string} oldClasses The former CSS className value
|
15175
15213
|
*/
|
15176
15214
|
$updateClass : function(newClasses, oldClasses) {
|
15177
|
-
|
15178
|
-
|
15215
|
+
var toAdd = tokenDifference(newClasses, oldClasses);
|
15216
|
+
var toRemove = tokenDifference(oldClasses, newClasses);
|
15217
|
+
|
15218
|
+
if(toAdd.length === 0) {
|
15219
|
+
$animate.removeClass(this.$$element, toRemove);
|
15220
|
+
} else if(toRemove.length === 0) {
|
15221
|
+
$animate.addClass(this.$$element, toAdd);
|
15222
|
+
} else {
|
15223
|
+
$animate.setClass(this.$$element, toAdd, toRemove);
|
15224
|
+
}
|
15179
15225
|
},
|
15180
15226
|
|
15181
15227
|
/**
|
@@ -15627,7 +15673,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
15627
15673
|
templateDirective = previousCompileContext.templateDirective,
|
15628
15674
|
nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective,
|
15629
15675
|
hasTranscludeDirective = false,
|
15630
|
-
hasElementTranscludeDirective =
|
15676
|
+
hasElementTranscludeDirective = previousCompileContext.hasElementTranscludeDirective,
|
15631
15677
|
$compileNode = templateAttrs.$$element = jqLite(compileNode),
|
15632
15678
|
directive,
|
15633
15679
|
directiveName,
|
@@ -15681,7 +15727,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
15681
15727
|
hasTranscludeDirective = true;
|
15682
15728
|
|
15683
15729
|
// Special case ngIf and ngRepeat so that we don't complain about duplicate transclusion.
|
15684
|
-
// This option should only be used by directives that know how to
|
15730
|
+
// This option should only be used by directives that know how to safely handle element transclusion,
|
15685
15731
|
// where the transcluded nodes are added or replaced after linking.
|
15686
15732
|
if (!directive.$$tlb) {
|
15687
15733
|
assertNoDuplicate('transclusion', nonTlbTranscludeDirective, directive, $compileNode);
|
@@ -15728,9 +15774,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
15728
15774
|
|
15729
15775
|
if (directive.replace) {
|
15730
15776
|
replaceDirective = directive;
|
15731
|
-
$template =
|
15732
|
-
trim(directiveValue) +
|
15733
|
-
'</div>').contents();
|
15777
|
+
$template = directiveTemplateContents(directiveValue);
|
15734
15778
|
compileNode = $template[0];
|
15735
15779
|
|
15736
15780
|
if ($template.length != 1 || compileNode.nodeType !== 1) {
|
@@ -15801,6 +15845,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
15801
15845
|
|
15802
15846
|
nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true;
|
15803
15847
|
nodeLinkFn.transclude = hasTranscludeDirective && childTranscludeFn;
|
15848
|
+
previousCompileContext.hasElementTranscludeDirective = hasElementTranscludeDirective;
|
15804
15849
|
|
15805
15850
|
// might be normal or delayed nodeLinkFn depending on if templateUrl is present
|
15806
15851
|
return nodeLinkFn;
|
@@ -16128,6 +16173,28 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
16128
16173
|
}
|
16129
16174
|
|
16130
16175
|
|
16176
|
+
function directiveTemplateContents(template) {
|
16177
|
+
var type;
|
16178
|
+
template = trim(template);
|
16179
|
+
if ((type = TABLE_CONTENT_REGEXP.exec(template))) {
|
16180
|
+
type = type[1].toLowerCase();
|
16181
|
+
var table = jqLite('<table>' + template + '</table>'),
|
16182
|
+
tbody = table.children('tbody'),
|
16183
|
+
leaf = /(td|th)/.test(type) && table.find('tr');
|
16184
|
+
if (tbody.length && type !== 'tbody') {
|
16185
|
+
table = tbody;
|
16186
|
+
}
|
16187
|
+
if (leaf && leaf.length) {
|
16188
|
+
table = leaf;
|
16189
|
+
}
|
16190
|
+
return table.contents();
|
16191
|
+
}
|
16192
|
+
return jqLite('<div>' +
|
16193
|
+
template +
|
16194
|
+
'</div>').contents();
|
16195
|
+
}
|
16196
|
+
|
16197
|
+
|
16131
16198
|
function compileTemplateUrl(directives, $compileNode, tAttrs,
|
16132
16199
|
$rootElement, childTranscludeFn, preLinkFns, postLinkFns, previousCompileContext) {
|
16133
16200
|
var linkQueue = [],
|
@@ -16152,7 +16219,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
16152
16219
|
content = denormalizeTemplate(content);
|
16153
16220
|
|
16154
16221
|
if (origAsyncDirective.replace) {
|
16155
|
-
$template =
|
16222
|
+
$template = directiveTemplateContents(content);
|
16156
16223
|
compileNode = $template[0];
|
16157
16224
|
|
16158
16225
|
if ($template.length != 1 || compileNode.nodeType !== 1) {
|
@@ -16196,9 +16263,18 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
16196
16263
|
linkNode = $compileNode[0];
|
16197
16264
|
|
16198
16265
|
if (beforeTemplateLinkNode !== beforeTemplateCompileNode) {
|
16199
|
-
|
16200
|
-
|
16266
|
+
var oldClasses = beforeTemplateLinkNode.className;
|
16267
|
+
|
16268
|
+
if (!(previousCompileContext.hasElementTranscludeDirective &&
|
16269
|
+
origAsyncDirective.replace)) {
|
16270
|
+
// it was cloned therefore we have to clone as well.
|
16271
|
+
linkNode = jqLiteClone(compileNode);
|
16272
|
+
}
|
16273
|
+
|
16201
16274
|
replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode);
|
16275
|
+
|
16276
|
+
// Copy in CSS classes from original node
|
16277
|
+
safeAddClass(jqLite(linkNode), oldClasses);
|
16202
16278
|
}
|
16203
16279
|
if (afterTemplateNodeLinkFn.transclude) {
|
16204
16280
|
childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude);
|
@@ -16855,31 +16931,14 @@ function $HttpProvider() {
|
|
16855
16931
|
* XMLHttpRequest will transparently follow it, meaning that the error callback will not be
|
16856
16932
|
* called for such responses.
|
16857
16933
|
*
|
16858
|
-
* # Calling $http from outside AngularJS
|
16859
|
-
* The `$http` service will not actually send the request until the next `$digest()` is
|
16860
|
-
* executed. Normally this is not an issue, since almost all the time your call to `$http` will
|
16861
|
-
* be from within a `$apply()` block.
|
16862
|
-
* If you are calling `$http` from outside Angular, then you should wrap it in a call to
|
16863
|
-
* `$apply` to cause a $digest to occur and also to handle errors in the block correctly.
|
16864
|
-
*
|
16865
|
-
* ```
|
16866
|
-
* $scope.$apply(function() {
|
16867
|
-
* $http(...);
|
16868
|
-
* });
|
16869
|
-
* ```
|
16870
|
-
*
|
16871
16934
|
* # Writing Unit Tests that use $http
|
16872
|
-
* When unit testing
|
16873
|
-
*
|
16874
|
-
*
|
16875
|
-
* code that calls the `$http()` method inside a $apply block as explained in the previous
|
16876
|
-
* section.
|
16935
|
+
* When unit testing (using {@link api/ngMock ngMock}), it is necessary to call
|
16936
|
+
* {@link api/ngMock.$httpBackend#methods_flush $httpBackend.flush()} to flush each pending
|
16937
|
+
* request using trained responses.
|
16877
16938
|
*
|
16878
16939
|
* ```
|
16879
16940
|
* $httpBackend.expectGET(...);
|
16880
|
-
* $
|
16881
|
-
* $http.get(...);
|
16882
|
-
* });
|
16941
|
+
* $http.get(...);
|
16883
16942
|
* $httpBackend.flush();
|
16884
16943
|
* ```
|
16885
16944
|
*
|
@@ -17236,14 +17295,14 @@ function $HttpProvider() {
|
|
17236
17295
|
<option>JSONP</option>
|
17237
17296
|
</select>
|
17238
17297
|
<input type="text" ng-model="url" size="80"/>
|
17239
|
-
<button ng-click="fetch()">fetch</button><br>
|
17240
|
-
<button ng-click="updateModel('GET', 'http-hello.html')">Sample GET</button>
|
17241
|
-
<button
|
17298
|
+
<button id="fetchbtn" ng-click="fetch()">fetch</button><br>
|
17299
|
+
<button id="samplegetbtn" ng-click="updateModel('GET', 'http-hello.html')">Sample GET</button>
|
17300
|
+
<button id="samplejsonpbtn"
|
17242
17301
|
ng-click="updateModel('JSONP',
|
17243
17302
|
'http://angularjs.org/greet.php?callback=JSON_CALLBACK&name=Super%20Hero')">
|
17244
17303
|
Sample JSONP
|
17245
17304
|
</button>
|
17246
|
-
<button
|
17305
|
+
<button id="invalidjsonpbtn"
|
17247
17306
|
ng-click="updateModel('JSONP', 'http://angularjs.org/doesntexist&callback=JSON_CALLBACK')">
|
17248
17307
|
Invalid JSONP
|
17249
17308
|
</button>
|
@@ -17280,27 +17339,34 @@ function $HttpProvider() {
|
|
17280
17339
|
<file name="http-hello.html">
|
17281
17340
|
Hello, $http!
|
17282
17341
|
</file>
|
17283
|
-
<file name="
|
17342
|
+
<file name="protractorTest.js">
|
17343
|
+
var status = element(by.binding('status'));
|
17344
|
+
var data = element(by.binding('data'));
|
17345
|
+
var fetchBtn = element(by.id('fetchbtn'));
|
17346
|
+
var sampleGetBtn = element(by.id('samplegetbtn'));
|
17347
|
+
var sampleJsonpBtn = element(by.id('samplejsonpbtn'));
|
17348
|
+
var invalidJsonpBtn = element(by.id('invalidjsonpbtn'));
|
17349
|
+
|
17284
17350
|
it('should make an xhr GET request', function() {
|
17285
|
-
|
17286
|
-
|
17287
|
-
expect(
|
17288
|
-
expect(
|
17351
|
+
sampleGetBtn.click();
|
17352
|
+
fetchBtn.click();
|
17353
|
+
expect(status.getText()).toMatch('200');
|
17354
|
+
expect(data.getText()).toMatch(/Hello, \$http!/)
|
17289
17355
|
});
|
17290
17356
|
|
17291
17357
|
it('should make a JSONP request to angularjs.org', function() {
|
17292
|
-
|
17293
|
-
|
17294
|
-
expect(
|
17295
|
-
expect(
|
17358
|
+
sampleJsonpBtn.click();
|
17359
|
+
fetchBtn.click();
|
17360
|
+
expect(status.getText()).toMatch('200');
|
17361
|
+
expect(data.getText()).toMatch(/Super Hero!/);
|
17296
17362
|
});
|
17297
17363
|
|
17298
17364
|
it('should make JSONP request to invalid URL and invoke the error handler',
|
17299
17365
|
function() {
|
17300
|
-
|
17301
|
-
|
17302
|
-
expect(
|
17303
|
-
expect(
|
17366
|
+
invalidJsonpBtn.click();
|
17367
|
+
fetchBtn.click();
|
17368
|
+
expect(status.getText()).toMatch('0');
|
17369
|
+
expect(data.getText()).toMatch('Request failed');
|
17304
17370
|
});
|
17305
17371
|
</file>
|
17306
17372
|
</example>
|
@@ -17682,13 +17748,18 @@ function $HttpProvider() {
|
|
17682
17748
|
}
|
17683
17749
|
|
17684
17750
|
function createXhr(method) {
|
17685
|
-
|
17686
|
-
|
17687
|
-
|
17688
|
-
|
17689
|
-
|
17690
|
-
|
17751
|
+
//if IE and the method is not RFC2616 compliant, or if XMLHttpRequest
|
17752
|
+
//is not available, try getting an ActiveXObject. Otherwise, use XMLHttpRequest
|
17753
|
+
//if it is available
|
17754
|
+
if (msie <= 8 && (!method.match(/^(get|post|head|put|delete|options)$/i) ||
|
17755
|
+
!window.XMLHttpRequest)) {
|
17756
|
+
return new window.ActiveXObject("Microsoft.XMLHTTP");
|
17757
|
+
} else if (window.XMLHttpRequest) {
|
17758
|
+
return new window.XMLHttpRequest();
|
17759
|
+
}
|
17691
17760
|
|
17761
|
+
throw minErr('$httpBackend')('noxhr', "This browser does not support XMLHttpRequest.");
|
17762
|
+
}
|
17692
17763
|
|
17693
17764
|
/**
|
17694
17765
|
* @ngdoc object
|
@@ -17783,7 +17854,20 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc
|
|
17783
17854
|
}
|
17784
17855
|
|
17785
17856
|
if (responseType) {
|
17786
|
-
|
17857
|
+
try {
|
17858
|
+
xhr.responseType = responseType;
|
17859
|
+
} catch (e) {
|
17860
|
+
// WebKit added support for the json responseType value on 09/03/2013
|
17861
|
+
// https://bugs.webkit.org/show_bug.cgi?id=73648. Versions of Safari prior to 7 are
|
17862
|
+
// known to throw when setting the value "json" as the response type. Other older
|
17863
|
+
// browsers implementing the responseType
|
17864
|
+
//
|
17865
|
+
// The json response type can be ignored if not supported, because JSON payloads are
|
17866
|
+
// parsed on the client-side regardless.
|
17867
|
+
if (responseType !== 'json') {
|
17868
|
+
throw e;
|
17869
|
+
}
|
17870
|
+
}
|
17787
17871
|
}
|
17788
17872
|
|
17789
17873
|
xhr.send(post || null);
|
@@ -17882,11 +17966,11 @@ var $interpolateMinErr = minErr('$interpolate');
|
|
17882
17966
|
//demo.label//
|
17883
17967
|
</div>
|
17884
17968
|
</doc:source>
|
17885
|
-
<doc:
|
17886
|
-
|
17887
|
-
|
17888
|
-
|
17889
|
-
</doc:
|
17969
|
+
<doc:protractor>
|
17970
|
+
it('should interpolate binding with custom symbols', function() {
|
17971
|
+
expect(element(by.binding('demo.label')).getText()).toBe('This binding is brought you by // interpolation symbols.');
|
17972
|
+
});
|
17973
|
+
</doc:protractor>
|
17890
17974
|
</doc:example>
|
17891
17975
|
*/
|
17892
17976
|
function $InterpolateProvider() {
|
@@ -18078,7 +18162,7 @@ function $InterpolateProvider() {
|
|
18078
18162
|
* @description
|
18079
18163
|
* Symbol to denote the end of expression in the interpolated string. Defaults to `}}`.
|
18080
18164
|
*
|
18081
|
-
* Use {@link ng.$interpolateProvider#
|
18165
|
+
* Use {@link ng.$interpolateProvider#methods_endSymbol $interpolateProvider#endSymbol} to change
|
18082
18166
|
* the symbol.
|
18083
18167
|
*
|
18084
18168
|
* @returns {string} start symbol.
|
@@ -18114,7 +18198,7 @@ function $IntervalProvider() {
|
|
18114
18198
|
* In tests you can use {@link ngMock.$interval#methods_flush `$interval.flush(millis)`} to
|
18115
18199
|
* move forward by `millis` milliseconds and trigger any functions scheduled to run in that
|
18116
18200
|
* time.
|
18117
|
-
*
|
18201
|
+
*
|
18118
18202
|
* <div class="alert alert-warning">
|
18119
18203
|
* **Note**: Intervals created by this service must be explicitly destroyed when you are finished
|
18120
18204
|
* with them. In particular they are not automatically destroyed when a controller's scope or a
|
@@ -18227,8 +18311,8 @@ function $IntervalProvider() {
|
|
18227
18311
|
promise = deferred.promise,
|
18228
18312
|
iteration = 0,
|
18229
18313
|
skipApply = (isDefined(invokeApply) && !invokeApply);
|
18230
|
-
|
18231
|
-
count = isDefined(count) ? count : 0
|
18314
|
+
|
18315
|
+
count = isDefined(count) ? count : 0;
|
18232
18316
|
|
18233
18317
|
promise.then(null, null, fn);
|
18234
18318
|
|
@@ -18922,7 +19006,7 @@ function $LocationProvider(){
|
|
18922
19006
|
* @eventType broadcast on root scope
|
18923
19007
|
* @description
|
18924
19008
|
* Broadcasted before a URL will change. This change can be prevented by calling
|
18925
|
-
* `preventDefault` method of the event. See {@link ng.$rootScope.Scope
|
19009
|
+
* `preventDefault` method of the event. See {@link ng.$rootScope.Scope#methods_$on} for more
|
18926
19010
|
* details about event object. Upon successful change
|
18927
19011
|
* {@link ng.$location#events_$locationChangeSuccess $locationChangeSuccess} is fired.
|
18928
19012
|
*
|
@@ -19105,7 +19189,7 @@ function $LogProvider(){
|
|
19105
19189
|
* @name ng.$logProvider#debugEnabled
|
19106
19190
|
* @methodOf ng.$logProvider
|
19107
19191
|
* @description
|
19108
|
-
* @param {
|
19192
|
+
* @param {boolean=} flag enable or disable debug level messages
|
19109
19193
|
* @returns {*} current value if used as getter or itself (chaining) if used as setter
|
19110
19194
|
*/
|
19111
19195
|
this.debugEnabled = function(flag) {
|
@@ -19928,7 +20012,7 @@ Parser.prototype = {
|
|
19928
20012
|
var getter = getterFn(field, this.options, this.text);
|
19929
20013
|
|
19930
20014
|
return extend(function(scope, locals, self) {
|
19931
|
-
return getter(self || object(scope, locals)
|
20015
|
+
return getter(self || object(scope, locals));
|
19932
20016
|
}, {
|
19933
20017
|
assign: function(scope, value, locals) {
|
19934
20018
|
return setter(object(scope, locals), field, value, parser.text, parser.options);
|
@@ -20504,9 +20588,9 @@ function $ParseProvider() {
|
|
20504
20588
|
* asynchronous programming what `try`, `catch` and `throw` keywords are to synchronous programming.
|
20505
20589
|
*
|
20506
20590
|
* <pre>
|
20507
|
-
* // for the purpose of this example let's assume that variables `$q` and `
|
20508
|
-
* // available in the current lexical scope (they could have been injected or passed in).
|
20509
|
-
*
|
20591
|
+
* // for the purpose of this example let's assume that variables `$q`, `scope` and `okToGreet`
|
20592
|
+
* // are available in the current lexical scope (they could have been injected or passed in).
|
20593
|
+
*
|
20510
20594
|
* function asyncGreet(name) {
|
20511
20595
|
* var deferred = $q.defer();
|
20512
20596
|
*
|
@@ -20561,7 +20645,7 @@ function $ParseProvider() {
|
|
20561
20645
|
* constructed via `$q.reject`, the promise will be rejected instead.
|
20562
20646
|
* - `reject(reason)` – rejects the derived promise with the `reason`. This is equivalent to
|
20563
20647
|
* resolving it with a rejection constructed via `$q.reject`.
|
20564
|
-
* - `notify(value)` - provides updates on the status of the
|
20648
|
+
* - `notify(value)` - provides updates on the status of the promise's execution. This may be called
|
20565
20649
|
* multiple times before the promise is either resolved or rejected.
|
20566
20650
|
*
|
20567
20651
|
* **Properties**
|
@@ -20711,7 +20795,7 @@ function qFactory(nextTick, exceptionHandler) {
|
|
20711
20795
|
|
20712
20796
|
|
20713
20797
|
reject: function(reason) {
|
20714
|
-
deferred.resolve(
|
20798
|
+
deferred.resolve(createInternalRejectedPromise(reason));
|
20715
20799
|
},
|
20716
20800
|
|
20717
20801
|
|
@@ -20868,6 +20952,12 @@ function qFactory(nextTick, exceptionHandler) {
|
|
20868
20952
|
* @returns {Promise} Returns a promise that was already resolved as rejected with the `reason`.
|
20869
20953
|
*/
|
20870
20954
|
var reject = function(reason) {
|
20955
|
+
var result = defer();
|
20956
|
+
result.reject(reason);
|
20957
|
+
return result.promise;
|
20958
|
+
};
|
20959
|
+
|
20960
|
+
var createInternalRejectedPromise = function(reason) {
|
20871
20961
|
return {
|
20872
20962
|
then: function(callback, errback) {
|
20873
20963
|
var result = defer();
|
@@ -21928,7 +22018,7 @@ function $RootScopeProvider(){
|
|
21928
22018
|
* onto the {@link ng.$exceptionHandler $exceptionHandler} service.
|
21929
22019
|
*
|
21930
22020
|
* @param {string} name Event name to emit.
|
21931
|
-
* @param {...*} args Optional
|
22021
|
+
* @param {...*} args Optional one or more arguments which will be passed onto the event listeners.
|
21932
22022
|
* @return {Object} Event object (see {@link ng.$rootScope.Scope#methods_$on}).
|
21933
22023
|
*/
|
21934
22024
|
$emit: function(name, args) {
|
@@ -21996,7 +22086,7 @@ function $RootScopeProvider(){
|
|
21996
22086
|
* onto the {@link ng.$exceptionHandler $exceptionHandler} service.
|
21997
22087
|
*
|
21998
22088
|
* @param {string} name Event name to broadcast.
|
21999
|
-
* @param {...*} args Optional
|
22089
|
+
* @param {...*} args Optional one or more arguments which will be passed onto the event listeners.
|
22000
22090
|
* @return {Object} Event object, see {@link ng.$rootScope.Scope#methods_$on}
|
22001
22091
|
*/
|
22002
22092
|
$broadcast: function(name, args) {
|
@@ -22439,7 +22529,7 @@ function $SceDelegateProvider() {
|
|
22439
22529
|
*
|
22440
22530
|
* @description
|
22441
22531
|
* Returns an object that is trusted by angular for use in specified strict
|
22442
|
-
* contextual escaping contexts (such as ng-
|
22532
|
+
* contextual escaping contexts (such as ng-bind-html, ng-include, any src
|
22443
22533
|
* attribute interpolation, any dom event binding attribute interpolation
|
22444
22534
|
* such as for onclick, etc.) that uses the provided value.
|
22445
22535
|
* See {@link ng.$sce $sce} for enabling strict contextual escaping.
|
@@ -22666,8 +22756,8 @@ function $SceDelegateProvider() {
|
|
22666
22756
|
* It's important to remember that SCE only applies to interpolation expressions.
|
22667
22757
|
*
|
22668
22758
|
* If your expressions are constant literals, they're automatically trusted and you don't need to
|
22669
|
-
* call `$sce.trustAs` on them
|
22670
|
-
* `<div ng-
|
22759
|
+
* call `$sce.trustAs` on them (remember to include the `ngSanitize` module) (e.g.
|
22760
|
+
* `<div ng-bind-html="'<b>implicitly trusted</b>'"></div>`) just works.
|
22671
22761
|
*
|
22672
22762
|
* Additionally, `a[href]` and `img[src]` automatically sanitize their URLs and do not pass them
|
22673
22763
|
* through {@link ng.$sce#methods_getTrusted $sce.getTrusted}. SCE doesn't play a role here.
|
@@ -22727,7 +22817,7 @@ function $SceDelegateProvider() {
|
|
22727
22817
|
* matched against the **entire** *normalized / absolute URL* of the resource being tested
|
22728
22818
|
* (even when the RegExp did not have the `^` and `$` codes.) In addition, any flags
|
22729
22819
|
* present on the RegExp (such as multiline, global, ignoreCase) are ignored.
|
22730
|
-
* - If you are generating your
|
22820
|
+
* - If you are generating your JavaScript from some other templating engine (not
|
22731
22821
|
* recommended, e.g. in issue [#4006](https://github.com/angular/angular.js/issues/4006)),
|
22732
22822
|
* remember to escape your regular expression (and be aware that you might need more than
|
22733
22823
|
* one level of escaping depending on your templating engine and the way you interpolated
|
@@ -22744,7 +22834,7 @@ function $SceDelegateProvider() {
|
|
22744
22834
|
* ## Show me an example using SCE.
|
22745
22835
|
*
|
22746
22836
|
* @example
|
22747
|
-
<example module="mySceApp">
|
22837
|
+
<example module="mySceApp" deps="angular-sanitize.js">
|
22748
22838
|
<file name="index.html">
|
22749
22839
|
<div ng-controller="myAppController as myCtrl">
|
22750
22840
|
<i ng-bind-html="myCtrl.explicitlyTrustedHtml" id="explicitlyTrustedHtml"></i><br><br>
|
@@ -22788,13 +22878,15 @@ function $SceDelegateProvider() {
|
|
22788
22878
|
]
|
22789
22879
|
</file>
|
22790
22880
|
|
22791
|
-
<file name="
|
22881
|
+
<file name="protractorTest.js">
|
22792
22882
|
describe('SCE doc demo', function() {
|
22793
22883
|
it('should sanitize untrusted values', function() {
|
22794
|
-
expect(element('.htmlComment').
|
22884
|
+
expect(element(by.css('.htmlComment')).getInnerHtml())
|
22885
|
+
.toBe('<span>Is <i>anyone</i> reading this?</span>');
|
22795
22886
|
});
|
22887
|
+
|
22796
22888
|
it('should NOT sanitize explicitly trusted values', function() {
|
22797
|
-
expect(element('
|
22889
|
+
expect(element(by.id('explicitlyTrustedHtml')).getInnerHtml()).toBe(
|
22798
22890
|
'<span onmouseover="this.textContent="Explicitly trusted HTML bypasses ' +
|
22799
22891
|
'sanitization."">Hover over this text.</span>');
|
22800
22892
|
});
|
@@ -22969,8 +23061,8 @@ function $SceProvider() {
|
|
22969
23061
|
*
|
22970
23062
|
* @description
|
22971
23063
|
* Delegates to {@link ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs`}. As such,
|
22972
|
-
* returns an
|
22973
|
-
* escaping contexts (such as ng-
|
23064
|
+
* returns an object that is trusted by angular for use in specified strict contextual
|
23065
|
+
* escaping contexts (such as ng-bind-html, ng-include, any src attribute
|
22974
23066
|
* interpolation, any dom event binding attribute interpolation such as for onclick, etc.)
|
22975
23067
|
* that uses the provided value. See * {@link ng.$sce $sce} for enabling strict contextual
|
22976
23068
|
* escaping.
|
@@ -23553,13 +23645,13 @@ function urlIsSameOrigin(requestUrl) {
|
|
23553
23645
|
<button ng-click="doGreeting(greeting)">ALERT</button>
|
23554
23646
|
</div>
|
23555
23647
|
</doc:source>
|
23556
|
-
<doc:
|
23648
|
+
<doc:protractor>
|
23557
23649
|
it('should display the greeting in the input box', function() {
|
23558
|
-
|
23650
|
+
element(by.model('greeting')).sendKeys('Hello, E2E Tests');
|
23559
23651
|
// If we click the button it will block the test runner
|
23560
23652
|
// element(':button').click();
|
23561
23653
|
});
|
23562
|
-
</doc:
|
23654
|
+
</doc:protractor>
|
23563
23655
|
</doc:example>
|
23564
23656
|
*/
|
23565
23657
|
function $WindowProvider(){
|
@@ -23768,35 +23860,47 @@ function $FilterProvider($provide) {
|
|
23768
23860
|
Equality <input type="checkbox" ng-model="strict"><br>
|
23769
23861
|
<table id="searchObjResults">
|
23770
23862
|
<tr><th>Name</th><th>Phone</th></tr>
|
23771
|
-
<tr ng-repeat="
|
23772
|
-
<td>{{
|
23773
|
-
<td>{{
|
23863
|
+
<tr ng-repeat="friendObj in friends | filter:search:strict">
|
23864
|
+
<td>{{friendObj.name}}</td>
|
23865
|
+
<td>{{friendObj.phone}}</td>
|
23774
23866
|
</tr>
|
23775
23867
|
</table>
|
23776
23868
|
</doc:source>
|
23777
|
-
<doc:
|
23778
|
-
|
23779
|
-
|
23780
|
-
|
23781
|
-
|
23869
|
+
<doc:protractor>
|
23870
|
+
var expectFriendNames = function(expectedNames, key) {
|
23871
|
+
element.all(by.repeater(key + ' in friends').column(key + '.name')).then(function(arr) {
|
23872
|
+
arr.forEach(function(wd, i) {
|
23873
|
+
expect(wd.getText()).toMatch(expectedNames[i]);
|
23874
|
+
});
|
23875
|
+
});
|
23876
|
+
};
|
23782
23877
|
|
23783
|
-
|
23784
|
-
|
23785
|
-
|
23878
|
+
it('should search across all fields when filtering with a string', function() {
|
23879
|
+
var searchText = element(by.model('searchText'));
|
23880
|
+
searchText.clear();
|
23881
|
+
searchText.sendKeys('m');
|
23882
|
+
expectFriendNames(['Mary', 'Mike', 'Adam'], 'friend');
|
23883
|
+
|
23884
|
+
searchText.clear();
|
23885
|
+
searchText.sendKeys('76');
|
23886
|
+
expectFriendNames(['John', 'Julie'], 'friend');
|
23786
23887
|
});
|
23787
23888
|
|
23788
23889
|
it('should search in specific fields when filtering with a predicate object', function() {
|
23789
|
-
|
23790
|
-
|
23791
|
-
|
23890
|
+
var searchAny = element(by.model('search.$'));
|
23891
|
+
searchAny.clear();
|
23892
|
+
searchAny.sendKeys('i');
|
23893
|
+
expectFriendNames(['Mary', 'Mike', 'Julie', 'Juliette'], 'friendObj');
|
23792
23894
|
});
|
23793
23895
|
it('should use a equal comparison when comparator is true', function() {
|
23794
|
-
|
23795
|
-
|
23796
|
-
|
23797
|
-
|
23896
|
+
var searchName = element(by.model('search.name'));
|
23897
|
+
var strict = element(by.model('strict'));
|
23898
|
+
searchName.clear();
|
23899
|
+
searchName.sendKeys('Julie');
|
23900
|
+
strict.click();
|
23901
|
+
expectFriendNames(['Julie'], 'friendObj');
|
23798
23902
|
});
|
23799
|
-
</doc:
|
23903
|
+
</doc:protractor>
|
23800
23904
|
</doc:example>
|
23801
23905
|
*/
|
23802
23906
|
function filterFilter() {
|
@@ -23822,6 +23926,15 @@ function filterFilter() {
|
|
23822
23926
|
};
|
23823
23927
|
} else {
|
23824
23928
|
comparator = function(obj, text) {
|
23929
|
+
if (obj && text && typeof obj === 'object' && typeof text === 'object') {
|
23930
|
+
for (var objKey in obj) {
|
23931
|
+
if (objKey.charAt(0) !== '$' && hasOwnProperty.call(obj, objKey) &&
|
23932
|
+
comparator(obj[objKey], text[objKey])) {
|
23933
|
+
return true;
|
23934
|
+
}
|
23935
|
+
}
|
23936
|
+
return false;
|
23937
|
+
}
|
23825
23938
|
text = (''+text).toLowerCase();
|
23826
23939
|
return (''+obj).toLowerCase().indexOf(text) > -1;
|
23827
23940
|
};
|
@@ -23874,7 +23987,7 @@ function filterFilter() {
|
|
23874
23987
|
(function(path) {
|
23875
23988
|
if (typeof expression[path] == 'undefined') return;
|
23876
23989
|
predicates.push(function(value) {
|
23877
|
-
return search(path == '$' ? value :
|
23990
|
+
return search(path == '$' ? value : (value && value[path]), expression[path]);
|
23878
23991
|
});
|
23879
23992
|
})(key);
|
23880
23993
|
}
|
@@ -23920,21 +24033,27 @@ function filterFilter() {
|
|
23920
24033
|
</script>
|
23921
24034
|
<div ng-controller="Ctrl">
|
23922
24035
|
<input type="number" ng-model="amount"> <br>
|
23923
|
-
default currency symbol ($): {{amount | currency}}
|
23924
|
-
custom currency identifier (USD$): {{amount | currency:"USD$"}}
|
24036
|
+
default currency symbol ($): <span id="currency-default">{{amount | currency}}</span><br>
|
24037
|
+
custom currency identifier (USD$): <span>{{amount | currency:"USD$"}}</span>
|
23925
24038
|
</div>
|
23926
24039
|
</doc:source>
|
23927
|
-
<doc:
|
24040
|
+
<doc:protractor>
|
23928
24041
|
it('should init with 1234.56', function() {
|
23929
|
-
expect(
|
23930
|
-
expect(binding('amount | currency:"USD$"')).toBe('USD$1,234.56');
|
24042
|
+
expect(element(by.id('currency-default')).getText()).toBe('$1,234.56');
|
24043
|
+
expect(element(by.binding('amount | currency:"USD$"')).getText()).toBe('USD$1,234.56');
|
23931
24044
|
});
|
23932
24045
|
it('should update', function() {
|
23933
|
-
|
23934
|
-
|
23935
|
-
|
24046
|
+
if (browser.params.browser == 'safari') {
|
24047
|
+
// Safari does not understand the minus key. See
|
24048
|
+
// https://github.com/angular/protractor/issues/481
|
24049
|
+
return;
|
24050
|
+
}
|
24051
|
+
element(by.model('amount')).clear();
|
24052
|
+
element(by.model('amount')).sendKeys('-1234');
|
24053
|
+
expect(element(by.id('currency-default')).getText()).toBe('($1,234.00)');
|
24054
|
+
expect(element(by.binding('amount | currency:"USD$"')).getText()).toBe('(USD$1,234.00)');
|
23936
24055
|
});
|
23937
|
-
</doc:
|
24056
|
+
</doc:protractor>
|
23938
24057
|
</doc:example>
|
23939
24058
|
*/
|
23940
24059
|
currencyFilter.$inject = ['$locale'];
|
@@ -23973,25 +24092,26 @@ function currencyFilter($locale) {
|
|
23973
24092
|
</script>
|
23974
24093
|
<div ng-controller="Ctrl">
|
23975
24094
|
Enter number: <input ng-model='val'><br>
|
23976
|
-
Default formatting: {{val | number}}
|
23977
|
-
No fractions: {{val | number:0}}
|
23978
|
-
Negative number: {{-val | number:4}}
|
24095
|
+
Default formatting: <span id='number-default'>{{val | number}}</span><br>
|
24096
|
+
No fractions: <span>{{val | number:0}}</span><br>
|
24097
|
+
Negative number: <span>{{-val | number:4}}</span>
|
23979
24098
|
</div>
|
23980
24099
|
</doc:source>
|
23981
|
-
<doc:
|
24100
|
+
<doc:protractor>
|
23982
24101
|
it('should format numbers', function() {
|
23983
|
-
expect(
|
23984
|
-
expect(binding('val | number:0')).toBe('1,235');
|
23985
|
-
expect(binding('-val | number:4')).toBe('-1,234.5679');
|
24102
|
+
expect(element(by.id('number-default')).getText()).toBe('1,234.568');
|
24103
|
+
expect(element(by.binding('val | number:0')).getText()).toBe('1,235');
|
24104
|
+
expect(element(by.binding('-val | number:4')).getText()).toBe('-1,234.5679');
|
23986
24105
|
});
|
23987
24106
|
|
23988
24107
|
it('should update', function() {
|
23989
|
-
|
23990
|
-
|
23991
|
-
expect(
|
23992
|
-
expect(binding('
|
23993
|
-
|
23994
|
-
|
24108
|
+
element(by.model('val')).clear();
|
24109
|
+
element(by.model('val')).sendKeys('3374.333');
|
24110
|
+
expect(element(by.id('number-default')).getText()).toBe('3,374.333');
|
24111
|
+
expect(element(by.binding('val | number:0')).getText()).toBe('3,374');
|
24112
|
+
expect(element(by.binding('-val | number:4')).getText()).toBe('-3,374.3330');
|
24113
|
+
});
|
24114
|
+
</doc:protractor>
|
23995
24115
|
</doc:example>
|
23996
24116
|
*/
|
23997
24117
|
|
@@ -24221,22 +24341,22 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
|
|
24221
24341
|
<doc:example>
|
24222
24342
|
<doc:source>
|
24223
24343
|
<span ng-non-bindable>{{1288323623006 | date:'medium'}}</span>:
|
24224
|
-
{{1288323623006 | date:'medium'}}
|
24344
|
+
<span>{{1288323623006 | date:'medium'}}</span><br>
|
24225
24345
|
<span ng-non-bindable>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span>:
|
24226
|
-
{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}
|
24346
|
+
<span>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span><br>
|
24227
24347
|
<span ng-non-bindable>{{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}</span>:
|
24228
|
-
{{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}
|
24348
|
+
<span>{{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}</span><br>
|
24229
24349
|
</doc:source>
|
24230
|
-
<doc:
|
24350
|
+
<doc:protractor>
|
24231
24351
|
it('should format date', function() {
|
24232
|
-
expect(binding("1288323623006 | date:'medium'")).
|
24352
|
+
expect(element(by.binding("1288323623006 | date:'medium'")).getText()).
|
24233
24353
|
toMatch(/Oct 2\d, 2010 \d{1,2}:\d{2}:\d{2} (AM|PM)/);
|
24234
|
-
expect(binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")).
|
24354
|
+
expect(element(by.binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")).getText()).
|
24235
24355
|
toMatch(/2010\-10\-2\d \d{2}:\d{2}:\d{2} (\-|\+)?\d{4}/);
|
24236
|
-
expect(binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")).
|
24356
|
+
expect(element(by.binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")).getText()).
|
24237
24357
|
toMatch(/10\/2\d\/2010 @ \d{1,2}:\d{2}(AM|PM)/);
|
24238
24358
|
});
|
24239
|
-
</doc:
|
24359
|
+
</doc:protractor>
|
24240
24360
|
</doc:example>
|
24241
24361
|
*/
|
24242
24362
|
dateFilter.$inject = ['$locale'];
|
@@ -24335,11 +24455,11 @@ function dateFilter($locale) {
|
|
24335
24455
|
<doc:source>
|
24336
24456
|
<pre>{{ {'name':'value'} | json }}</pre>
|
24337
24457
|
</doc:source>
|
24338
|
-
<doc:
|
24458
|
+
<doc:protractor>
|
24339
24459
|
it('should jsonify filtered objects', function() {
|
24340
|
-
expect(binding("{'name':'value'}")).toMatch(/\{\n "name": ?"value"\n}/);
|
24460
|
+
expect(element(by.binding("{'name':'value'}")).getText()).toMatch(/\{\n "name": ?"value"\n}/);
|
24341
24461
|
});
|
24342
|
-
</doc:
|
24462
|
+
</doc:protractor>
|
24343
24463
|
</doc:example>
|
24344
24464
|
*
|
24345
24465
|
*/
|
@@ -24407,28 +24527,37 @@ var uppercaseFilter = valueFn(uppercase);
|
|
24407
24527
|
<p>Output letters: {{ letters | limitTo:letterLimit }}</p>
|
24408
24528
|
</div>
|
24409
24529
|
</doc:source>
|
24410
|
-
<doc:
|
24530
|
+
<doc:protractor>
|
24531
|
+
var numLimitInput = element(by.model('numLimit'));
|
24532
|
+
var letterLimitInput = element(by.model('letterLimit'));
|
24533
|
+
var limitedNumbers = element(by.binding('numbers | limitTo:numLimit'));
|
24534
|
+
var limitedLetters = element(by.binding('letters | limitTo:letterLimit'));
|
24535
|
+
|
24411
24536
|
it('should limit the number array to first three items', function() {
|
24412
|
-
expect(
|
24413
|
-
expect(
|
24414
|
-
expect(
|
24415
|
-
expect(
|
24537
|
+
expect(numLimitInput.getAttribute('value')).toBe('3');
|
24538
|
+
expect(letterLimitInput.getAttribute('value')).toBe('3');
|
24539
|
+
expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3]');
|
24540
|
+
expect(limitedLetters.getText()).toEqual('Output letters: abc');
|
24416
24541
|
});
|
24417
24542
|
|
24418
24543
|
it('should update the output when -3 is entered', function() {
|
24419
|
-
|
24420
|
-
|
24421
|
-
|
24422
|
-
|
24544
|
+
numLimitInput.clear();
|
24545
|
+
numLimitInput.sendKeys('-3');
|
24546
|
+
letterLimitInput.clear();
|
24547
|
+
letterLimitInput.sendKeys('-3');
|
24548
|
+
expect(limitedNumbers.getText()).toEqual('Output numbers: [7,8,9]');
|
24549
|
+
expect(limitedLetters.getText()).toEqual('Output letters: ghi');
|
24423
24550
|
});
|
24424
24551
|
|
24425
24552
|
it('should not exceed the maximum size of input array', function() {
|
24426
|
-
|
24427
|
-
|
24428
|
-
|
24429
|
-
|
24553
|
+
numLimitInput.clear();
|
24554
|
+
numLimitInput.sendKeys('100');
|
24555
|
+
letterLimitInput.clear();
|
24556
|
+
letterLimitInput.sendKeys('100');
|
24557
|
+
expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3,4,5,6,7,8,9]');
|
24558
|
+
expect(limitedLetters.getText()).toEqual('Output letters: abcdefghi');
|
24430
24559
|
});
|
24431
|
-
</doc:
|
24560
|
+
</doc:protractor>
|
24432
24561
|
</doc:example>
|
24433
24562
|
*/
|
24434
24563
|
function limitToFilter(){
|
@@ -24529,29 +24658,6 @@ function limitToFilter(){
|
|
24529
24658
|
</table>
|
24530
24659
|
</div>
|
24531
24660
|
</doc:source>
|
24532
|
-
<doc:scenario>
|
24533
|
-
it('should be reverse ordered by aged', function() {
|
24534
|
-
expect(binding('predicate')).toBe('-age');
|
24535
|
-
expect(repeater('table.friend', 'friend in friends').column('friend.age')).
|
24536
|
-
toEqual(['35', '29', '21', '19', '10']);
|
24537
|
-
expect(repeater('table.friend', 'friend in friends').column('friend.name')).
|
24538
|
-
toEqual(['Adam', 'Julie', 'Mike', 'Mary', 'John']);
|
24539
|
-
});
|
24540
|
-
|
24541
|
-
it('should reorder the table when user selects different predicate', function() {
|
24542
|
-
element('.doc-example-live a:contains("Name")').click();
|
24543
|
-
expect(repeater('table.friend', 'friend in friends').column('friend.name')).
|
24544
|
-
toEqual(['Adam', 'John', 'Julie', 'Mary', 'Mike']);
|
24545
|
-
expect(repeater('table.friend', 'friend in friends').column('friend.age')).
|
24546
|
-
toEqual(['35', '10', '29', '19', '21']);
|
24547
|
-
|
24548
|
-
element('.doc-example-live a:contains("Phone")').click();
|
24549
|
-
expect(repeater('table.friend', 'friend in friends').column('friend.phone')).
|
24550
|
-
toEqual(['555-9876', '555-8765', '555-5678', '555-4321', '555-1212']);
|
24551
|
-
expect(repeater('table.friend', 'friend in friends').column('friend.name')).
|
24552
|
-
toEqual(['Mary', 'Julie', 'Adam', 'Mike', 'John']);
|
24553
|
-
});
|
24554
|
-
</doc:scenario>
|
24555
24661
|
</doc:example>
|
24556
24662
|
*/
|
24557
24663
|
orderByFilter.$inject = ['$parse'];
|
@@ -24648,11 +24754,14 @@ var htmlAnchorDirective = valueFn({
|
|
24648
24754
|
element.append(document.createComment('IE fix'));
|
24649
24755
|
}
|
24650
24756
|
|
24651
|
-
if (!attr.href && !attr.name) {
|
24757
|
+
if (!attr.href && !attr.xlinkHref && !attr.name) {
|
24652
24758
|
return function(scope, element) {
|
24759
|
+
// SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.
|
24760
|
+
var href = toString.call(element.prop('href')) === '[object SVGAnimatedString]' ?
|
24761
|
+
'xlink:href' : 'href';
|
24653
24762
|
element.on('click', function(event){
|
24654
24763
|
// if we have no href url, then don't navigate anywhere.
|
24655
|
-
if (!element.attr(
|
24764
|
+
if (!element.attr(href)) {
|
24656
24765
|
event.preventDefault();
|
24657
24766
|
}
|
24658
24767
|
});
|
@@ -24702,46 +24811,55 @@ var htmlAnchorDirective = valueFn({
|
|
24702
24811
|
<a id="link-5" name="xxx" ng-click="value = 5">anchor</a> (no link)<br />
|
24703
24812
|
<a id="link-6" ng-href="{{value}}">link</a> (link, change location)
|
24704
24813
|
</doc:source>
|
24705
|
-
<doc:
|
24814
|
+
<doc:protractor>
|
24706
24815
|
it('should execute ng-click but not reload when href without value', function() {
|
24707
|
-
element('
|
24708
|
-
expect(
|
24709
|
-
expect(element('
|
24816
|
+
element(by.id('link-1')).click();
|
24817
|
+
expect(element(by.model('value')).getAttribute('value')).toEqual('1');
|
24818
|
+
expect(element(by.id('link-1')).getAttribute('href')).toBe('');
|
24710
24819
|
});
|
24711
24820
|
|
24712
24821
|
it('should execute ng-click but not reload when href empty string', function() {
|
24713
|
-
element('
|
24714
|
-
expect(
|
24715
|
-
expect(element('
|
24822
|
+
element(by.id('link-2')).click();
|
24823
|
+
expect(element(by.model('value')).getAttribute('value')).toEqual('2');
|
24824
|
+
expect(element(by.id('link-2')).getAttribute('href')).toBe('');
|
24716
24825
|
});
|
24717
24826
|
|
24718
24827
|
it('should execute ng-click and change url when ng-href specified', function() {
|
24719
|
-
expect(element('
|
24828
|
+
expect(element(by.id('link-3')).getAttribute('href')).toMatch(/\/123$/);
|
24829
|
+
|
24830
|
+
element(by.id('link-3')).click();
|
24720
24831
|
|
24721
|
-
|
24722
|
-
|
24832
|
+
// At this point, we navigate away from an Angular page, so we need
|
24833
|
+
// to use browser.driver to get the base webdriver.
|
24834
|
+
|
24835
|
+
browser.wait(function() {
|
24836
|
+
return browser.driver.getCurrentUrl().then(function(url) {
|
24837
|
+
return url.match(/\/123$/);
|
24838
|
+
});
|
24839
|
+
}, 1000, 'page should navigate to /123');
|
24723
24840
|
});
|
24724
24841
|
|
24725
24842
|
it('should execute ng-click but not reload when href empty string and name specified', function() {
|
24726
|
-
element('
|
24727
|
-
expect(
|
24728
|
-
expect(element('
|
24843
|
+
element(by.id('link-4')).click();
|
24844
|
+
expect(element(by.model('value')).getAttribute('value')).toEqual('4');
|
24845
|
+
expect(element(by.id('link-4')).getAttribute('href')).toBe('');
|
24729
24846
|
});
|
24730
24847
|
|
24731
24848
|
it('should execute ng-click but not reload when no href but name specified', function() {
|
24732
|
-
element('
|
24733
|
-
expect(
|
24734
|
-
expect(element('
|
24849
|
+
element(by.id('link-5')).click();
|
24850
|
+
expect(element(by.model('value')).getAttribute('value')).toEqual('5');
|
24851
|
+
expect(element(by.id('link-5')).getAttribute('href')).toBe(null);
|
24735
24852
|
});
|
24736
24853
|
|
24737
24854
|
it('should only change url when only ng-href', function() {
|
24738
|
-
|
24739
|
-
|
24855
|
+
element(by.model('value')).clear();
|
24856
|
+
element(by.model('value')).sendKeys('6');
|
24857
|
+
expect(element(by.id('link-6')).getAttribute('href')).toMatch(/\/6$/);
|
24740
24858
|
|
24741
|
-
element('
|
24742
|
-
expect(browser
|
24859
|
+
element(by.id('link-6')).click();
|
24860
|
+
expect(browser.getCurrentUrl()).toMatch(/\/6$/);
|
24743
24861
|
});
|
24744
|
-
</doc:
|
24862
|
+
</doc:protractor>
|
24745
24863
|
</doc:example>
|
24746
24864
|
*/
|
24747
24865
|
|
@@ -24826,13 +24944,13 @@ var htmlAnchorDirective = valueFn({
|
|
24826
24944
|
Click me to toggle: <input type="checkbox" ng-model="checked"><br/>
|
24827
24945
|
<button ng-model="button" ng-disabled="checked">Button</button>
|
24828
24946
|
</doc:source>
|
24829
|
-
<doc:
|
24947
|
+
<doc:protractor>
|
24830
24948
|
it('should toggle button', function() {
|
24831
|
-
expect(element('.doc-example-live
|
24832
|
-
|
24833
|
-
expect(element('.doc-example-live
|
24949
|
+
expect(element(by.css('.doc-example-live button')).getAttribute('disabled')).toBeFalsy();
|
24950
|
+
element(by.model('checked')).click();
|
24951
|
+
expect(element(by.css('.doc-example-live button')).getAttribute('disabled')).toBeTruthy();
|
24834
24952
|
});
|
24835
|
-
</doc:
|
24953
|
+
</doc:protractor>
|
24836
24954
|
</doc:example>
|
24837
24955
|
*
|
24838
24956
|
* @element INPUT
|
@@ -24861,13 +24979,13 @@ var htmlAnchorDirective = valueFn({
|
|
24861
24979
|
Check me to check both: <input type="checkbox" ng-model="master"><br/>
|
24862
24980
|
<input id="checkSlave" type="checkbox" ng-checked="master">
|
24863
24981
|
</doc:source>
|
24864
|
-
<doc:
|
24982
|
+
<doc:protractor>
|
24865
24983
|
it('should check both checkBoxes', function() {
|
24866
|
-
expect(element('
|
24867
|
-
|
24868
|
-
expect(element('
|
24984
|
+
expect(element(by.id('checkSlave')).getAttribute('checked')).toBeFalsy();
|
24985
|
+
element(by.model('master')).click();
|
24986
|
+
expect(element(by.id('checkSlave')).getAttribute('checked')).toBeTruthy();
|
24869
24987
|
});
|
24870
|
-
</doc:
|
24988
|
+
</doc:protractor>
|
24871
24989
|
</doc:example>
|
24872
24990
|
*
|
24873
24991
|
* @element INPUT
|
@@ -24896,13 +25014,13 @@ var htmlAnchorDirective = valueFn({
|
|
24896
25014
|
Check me to make text readonly: <input type="checkbox" ng-model="checked"><br/>
|
24897
25015
|
<input type="text" ng-readonly="checked" value="I'm Angular"/>
|
24898
25016
|
</doc:source>
|
24899
|
-
<doc:
|
25017
|
+
<doc:protractor>
|
24900
25018
|
it('should toggle readonly attr', function() {
|
24901
|
-
expect(element('.doc-example-live
|
24902
|
-
|
24903
|
-
expect(element('.doc-example-live
|
25019
|
+
expect(element(by.css('.doc-example-live [type="text"]')).getAttribute('readonly')).toBeFalsy();
|
25020
|
+
element(by.model('checked')).click();
|
25021
|
+
expect(element(by.css('.doc-example-live [type="text"]')).getAttribute('readonly')).toBeTruthy();
|
24904
25022
|
});
|
24905
|
-
</doc:
|
25023
|
+
</doc:protractor>
|
24906
25024
|
</doc:example>
|
24907
25025
|
*
|
24908
25026
|
* @element INPUT
|
@@ -24935,13 +25053,13 @@ var htmlAnchorDirective = valueFn({
|
|
24935
25053
|
<option id="greet" ng-selected="selected">Greetings!</option>
|
24936
25054
|
</select>
|
24937
25055
|
</doc:source>
|
24938
|
-
<doc:
|
25056
|
+
<doc:protractor>
|
24939
25057
|
it('should select Greetings!', function() {
|
24940
|
-
expect(element('
|
24941
|
-
|
24942
|
-
expect(element('
|
25058
|
+
expect(element(by.id('greet')).getAttribute('selected')).toBeFalsy();
|
25059
|
+
element(by.model('selected')).click();
|
25060
|
+
expect(element(by.id('greet')).getAttribute('selected')).toBeTruthy();
|
24943
25061
|
});
|
24944
|
-
</doc:
|
25062
|
+
</doc:protractor>
|
24945
25063
|
</doc:example>
|
24946
25064
|
*
|
24947
25065
|
* @element OPTION
|
@@ -24971,13 +25089,13 @@ var htmlAnchorDirective = valueFn({
|
|
24971
25089
|
<summary>Show/Hide me</summary>
|
24972
25090
|
</details>
|
24973
25091
|
</doc:source>
|
24974
|
-
<doc:
|
25092
|
+
<doc:protractor>
|
24975
25093
|
it('should toggle open', function() {
|
24976
|
-
expect(element('
|
24977
|
-
|
24978
|
-
expect(element('
|
25094
|
+
expect(element(by.id('details')).getAttribute('open')).toBeFalsy();
|
25095
|
+
element(by.model('open')).click();
|
25096
|
+
expect(element(by.id('details')).getAttribute('open')).toBeTruthy();
|
24979
25097
|
});
|
24980
|
-
</doc:
|
25098
|
+
</doc:protractor>
|
24981
25099
|
</doc:example>
|
24982
25100
|
*
|
24983
25101
|
* @element DETAILS
|
@@ -25336,18 +25454,27 @@ function FormController(element, attrs) {
|
|
25336
25454
|
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br>
|
25337
25455
|
</form>
|
25338
25456
|
</doc:source>
|
25339
|
-
<doc:
|
25457
|
+
<doc:protractor>
|
25340
25458
|
it('should initialize to model', function() {
|
25341
|
-
|
25342
|
-
|
25459
|
+
var userType = element(by.binding('userType'));
|
25460
|
+
var valid = element(by.binding('myForm.input.$valid'));
|
25461
|
+
|
25462
|
+
expect(userType.getText()).toContain('guest');
|
25463
|
+
expect(valid.getText()).toContain('true');
|
25343
25464
|
});
|
25344
25465
|
|
25345
25466
|
it('should be invalid if empty', function() {
|
25346
|
-
|
25347
|
-
|
25348
|
-
|
25467
|
+
var userType = element(by.binding('userType'));
|
25468
|
+
var valid = element(by.binding('myForm.input.$valid'));
|
25469
|
+
var userInput = element(by.model('userType'));
|
25470
|
+
|
25471
|
+
userInput.clear();
|
25472
|
+
userInput.sendKeys('');
|
25473
|
+
|
25474
|
+
expect(userType.getText()).toEqual('userType =');
|
25475
|
+
expect(valid.getText()).toContain('false');
|
25349
25476
|
});
|
25350
|
-
</doc:
|
25477
|
+
</doc:protractor>
|
25351
25478
|
</doc:example>
|
25352
25479
|
*/
|
25353
25480
|
var formDirectiveFactory = function(isNgForm) {
|
@@ -25419,7 +25546,7 @@ var ngFormDirective = formDirectiveFactory(true);
|
|
25419
25546
|
*/
|
25420
25547
|
|
25421
25548
|
var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/;
|
25422
|
-
var EMAIL_REGEXP = /^[
|
25549
|
+
var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9-]+(\.[a-z0-9-]+)*$/i;
|
25423
25550
|
var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/;
|
25424
25551
|
|
25425
25552
|
var inputType = {
|
@@ -25472,29 +25599,31 @@ var inputType = {
|
|
25472
25599
|
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
|
25473
25600
|
</form>
|
25474
25601
|
</doc:source>
|
25475
|
-
<doc:
|
25602
|
+
<doc:protractor>
|
25603
|
+
var text = element(by.binding('text'));
|
25604
|
+
var valid = element(by.binding('myForm.input.$valid'));
|
25605
|
+
var input = element(by.model('text'));
|
25606
|
+
|
25476
25607
|
it('should initialize to model', function() {
|
25477
|
-
expect(
|
25478
|
-
expect(
|
25608
|
+
expect(text.getText()).toContain('guest');
|
25609
|
+
expect(valid.getText()).toContain('true');
|
25479
25610
|
});
|
25480
25611
|
|
25481
25612
|
it('should be invalid if empty', function() {
|
25482
|
-
input
|
25483
|
-
|
25484
|
-
|
25613
|
+
input.clear();
|
25614
|
+
input.sendKeys('');
|
25615
|
+
|
25616
|
+
expect(text.getText()).toEqual('text =');
|
25617
|
+
expect(valid.getText()).toContain('false');
|
25485
25618
|
});
|
25486
25619
|
|
25487
25620
|
it('should be invalid if multi word', function() {
|
25488
|
-
input
|
25489
|
-
|
25490
|
-
});
|
25621
|
+
input.clear();
|
25622
|
+
input.sendKeys('hello world');
|
25491
25623
|
|
25492
|
-
|
25493
|
-
input('text').enter('untrimmed ');
|
25494
|
-
expect(binding('text')).toEqual('untrimmed ');
|
25495
|
-
expect(binding('myForm.input.$valid')).toEqual('true');
|
25624
|
+
expect(valid.getText()).toContain('false');
|
25496
25625
|
});
|
25497
|
-
</doc:
|
25626
|
+
</doc:protractor>
|
25498
25627
|
</doc:example>
|
25499
25628
|
*/
|
25500
25629
|
'text': textInputType,
|
@@ -25548,24 +25677,30 @@ var inputType = {
|
|
25548
25677
|
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
|
25549
25678
|
</form>
|
25550
25679
|
</doc:source>
|
25551
|
-
<doc:
|
25680
|
+
<doc:protractor>
|
25681
|
+
var value = element(by.binding('value'));
|
25682
|
+
var valid = element(by.binding('myForm.input.$valid'));
|
25683
|
+
var input = element(by.model('value'));
|
25684
|
+
|
25552
25685
|
it('should initialize to model', function() {
|
25553
|
-
|
25554
|
-
|
25686
|
+
expect(value.getText()).toContain('12');
|
25687
|
+
expect(valid.getText()).toContain('true');
|
25555
25688
|
});
|
25556
25689
|
|
25557
25690
|
it('should be invalid if empty', function() {
|
25558
|
-
|
25559
|
-
|
25560
|
-
|
25691
|
+
input.clear();
|
25692
|
+
input.sendKeys('');
|
25693
|
+
expect(value.getText()).toEqual('value =');
|
25694
|
+
expect(valid.getText()).toContain('false');
|
25561
25695
|
});
|
25562
25696
|
|
25563
25697
|
it('should be invalid if over max', function() {
|
25564
|
-
|
25565
|
-
|
25566
|
-
|
25698
|
+
input.clear();
|
25699
|
+
input.sendKeys('123');
|
25700
|
+
expect(value.getText()).toEqual('value =');
|
25701
|
+
expect(valid.getText()).toContain('false');
|
25567
25702
|
});
|
25568
|
-
</doc:
|
25703
|
+
</doc:protractor>
|
25569
25704
|
</doc:example>
|
25570
25705
|
*/
|
25571
25706
|
'number': numberInputType,
|
@@ -25617,23 +25752,31 @@ var inputType = {
|
|
25617
25752
|
<tt>myForm.$error.url = {{!!myForm.$error.url}}</tt><br/>
|
25618
25753
|
</form>
|
25619
25754
|
</doc:source>
|
25620
|
-
<doc:
|
25755
|
+
<doc:protractor>
|
25756
|
+
var text = element(by.binding('text'));
|
25757
|
+
var valid = element(by.binding('myForm.input.$valid'));
|
25758
|
+
var input = element(by.model('text'));
|
25759
|
+
|
25621
25760
|
it('should initialize to model', function() {
|
25622
|
-
expect(
|
25623
|
-
expect(
|
25761
|
+
expect(text.getText()).toContain('http://google.com');
|
25762
|
+
expect(valid.getText()).toContain('true');
|
25624
25763
|
});
|
25625
25764
|
|
25626
25765
|
it('should be invalid if empty', function() {
|
25627
|
-
input
|
25628
|
-
|
25629
|
-
|
25766
|
+
input.clear();
|
25767
|
+
input.sendKeys('');
|
25768
|
+
|
25769
|
+
expect(text.getText()).toEqual('text =');
|
25770
|
+
expect(valid.getText()).toContain('false');
|
25630
25771
|
});
|
25631
25772
|
|
25632
25773
|
it('should be invalid if not url', function() {
|
25633
|
-
input
|
25634
|
-
|
25774
|
+
input.clear();
|
25775
|
+
input.sendKeys('box');
|
25776
|
+
|
25777
|
+
expect(valid.getText()).toContain('false');
|
25635
25778
|
});
|
25636
|
-
</doc:
|
25779
|
+
</doc:protractor>
|
25637
25780
|
</doc:example>
|
25638
25781
|
*/
|
25639
25782
|
'url': urlInputType,
|
@@ -25685,23 +25828,30 @@ var inputType = {
|
|
25685
25828
|
<tt>myForm.$error.email = {{!!myForm.$error.email}}</tt><br/>
|
25686
25829
|
</form>
|
25687
25830
|
</doc:source>
|
25688
|
-
<doc:
|
25831
|
+
<doc:protractor>
|
25832
|
+
var text = element(by.binding('text'));
|
25833
|
+
var valid = element(by.binding('myForm.input.$valid'));
|
25834
|
+
var input = element(by.model('text'));
|
25835
|
+
|
25689
25836
|
it('should initialize to model', function() {
|
25690
|
-
expect(
|
25691
|
-
expect(
|
25837
|
+
expect(text.getText()).toContain('me@example.com');
|
25838
|
+
expect(valid.getText()).toContain('true');
|
25692
25839
|
});
|
25693
25840
|
|
25694
25841
|
it('should be invalid if empty', function() {
|
25695
|
-
input
|
25696
|
-
|
25697
|
-
expect(
|
25842
|
+
input.clear();
|
25843
|
+
input.sendKeys('');
|
25844
|
+
expect(text.getText()).toEqual('text =');
|
25845
|
+
expect(valid.getText()).toContain('false');
|
25698
25846
|
});
|
25699
25847
|
|
25700
25848
|
it('should be invalid if not email', function() {
|
25701
|
-
input
|
25702
|
-
|
25849
|
+
input.clear();
|
25850
|
+
input.sendKeys('xxx');
|
25851
|
+
|
25852
|
+
expect(valid.getText()).toContain('false');
|
25703
25853
|
});
|
25704
|
-
</doc:
|
25854
|
+
</doc:protractor>
|
25705
25855
|
</doc:example>
|
25706
25856
|
*/
|
25707
25857
|
'email': emailInputType,
|
@@ -25719,6 +25869,8 @@ var inputType = {
|
|
25719
25869
|
* @param {string=} name Property name of the form under which the control is published.
|
25720
25870
|
* @param {string=} ngChange Angular expression to be executed when input changes due to user
|
25721
25871
|
* interaction with the input element.
|
25872
|
+
* @param {string} ngValue Angular expression which sets the value to which the expression should
|
25873
|
+
* be set when selected.
|
25722
25874
|
*
|
25723
25875
|
* @example
|
25724
25876
|
<doc:example>
|
@@ -25726,23 +25878,31 @@ var inputType = {
|
|
25726
25878
|
<script>
|
25727
25879
|
function Ctrl($scope) {
|
25728
25880
|
$scope.color = 'blue';
|
25881
|
+
$scope.specialValue = {
|
25882
|
+
"id": "12345",
|
25883
|
+
"value": "green"
|
25884
|
+
};
|
25729
25885
|
}
|
25730
25886
|
</script>
|
25731
25887
|
<form name="myForm" ng-controller="Ctrl">
|
25732
25888
|
<input type="radio" ng-model="color" value="red"> Red <br/>
|
25733
|
-
<input type="radio" ng-model="color" value="
|
25889
|
+
<input type="radio" ng-model="color" ng-value="specialValue"> Green <br/>
|
25734
25890
|
<input type="radio" ng-model="color" value="blue"> Blue <br/>
|
25735
|
-
<tt>color = {{color}}</tt><br/>
|
25891
|
+
<tt>color = {{color | json}}</tt><br/>
|
25736
25892
|
</form>
|
25893
|
+
Note that `ng-value="specialValue"` sets radio item's value to be the value of `$scope.specialValue`.
|
25737
25894
|
</doc:source>
|
25738
|
-
<doc:
|
25895
|
+
<doc:protractor>
|
25739
25896
|
it('should change state', function() {
|
25740
|
-
|
25897
|
+
var color = element(by.binding('color'));
|
25898
|
+
|
25899
|
+
expect(color.getText()).toContain('blue');
|
25741
25900
|
|
25742
|
-
|
25743
|
-
|
25901
|
+
element.all(by.model('color')).get(0).click();
|
25902
|
+
|
25903
|
+
expect(color.getText()).toContain('red');
|
25744
25904
|
});
|
25745
|
-
</doc:
|
25905
|
+
</doc:protractor>
|
25746
25906
|
</doc:example>
|
25747
25907
|
*/
|
25748
25908
|
'radio': radioInputType,
|
@@ -25779,17 +25939,21 @@ var inputType = {
|
|
25779
25939
|
<tt>value2 = {{value2}}</tt><br/>
|
25780
25940
|
</form>
|
25781
25941
|
</doc:source>
|
25782
|
-
<doc:
|
25942
|
+
<doc:protractor>
|
25783
25943
|
it('should change state', function() {
|
25784
|
-
|
25785
|
-
|
25944
|
+
var value1 = element(by.binding('value1'));
|
25945
|
+
var value2 = element(by.binding('value2'));
|
25946
|
+
|
25947
|
+
expect(value1.getText()).toContain('true');
|
25948
|
+
expect(value2.getText()).toContain('YES');
|
25949
|
+
|
25950
|
+
element(by.model('value1')).click();
|
25951
|
+
element(by.model('value2')).click();
|
25786
25952
|
|
25787
|
-
|
25788
|
-
|
25789
|
-
expect(binding('value1')).toEqual('false');
|
25790
|
-
expect(binding('value2')).toEqual('NO');
|
25953
|
+
expect(value1.getText()).toContain('false');
|
25954
|
+
expect(value2.getText()).toContain('NO');
|
25791
25955
|
});
|
25792
|
-
</doc:
|
25956
|
+
</doc:protractor>
|
25793
25957
|
</doc:example>
|
25794
25958
|
*/
|
25795
25959
|
'checkbox': checkboxInputType,
|
@@ -25797,7 +25961,8 @@ var inputType = {
|
|
25797
25961
|
'hidden': noop,
|
25798
25962
|
'button': noop,
|
25799
25963
|
'submit': noop,
|
25800
|
-
'reset': noop
|
25964
|
+
'reset': noop,
|
25965
|
+
'file': noop
|
25801
25966
|
};
|
25802
25967
|
|
25803
25968
|
// A helper function to call $setValidity and return the value / undefined,
|
@@ -25820,6 +25985,7 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
|
25820
25985
|
|
25821
25986
|
element.on('compositionend', function() {
|
25822
25987
|
composing = false;
|
25988
|
+
listener();
|
25823
25989
|
});
|
25824
25990
|
}
|
25825
25991
|
|
@@ -26142,44 +26308,59 @@ function checkboxInputType(scope, element, attr, ctrl) {
|
|
26142
26308
|
<tt>myForm.$error.maxlength = {{!!myForm.$error.maxlength}}</tt><br>
|
26143
26309
|
</div>
|
26144
26310
|
</doc:source>
|
26145
|
-
<doc:
|
26311
|
+
<doc:protractor>
|
26312
|
+
var user = element(by.binding('{{user}}'));
|
26313
|
+
var userNameValid = element(by.binding('myForm.userName.$valid'));
|
26314
|
+
var lastNameValid = element(by.binding('myForm.lastName.$valid'));
|
26315
|
+
var lastNameError = element(by.binding('myForm.lastName.$error'));
|
26316
|
+
var formValid = element(by.binding('myForm.$valid'));
|
26317
|
+
var userNameInput = element(by.model('user.name'));
|
26318
|
+
var userLastInput = element(by.model('user.last'));
|
26319
|
+
|
26146
26320
|
it('should initialize to model', function() {
|
26147
|
-
expect(
|
26148
|
-
expect(
|
26149
|
-
expect(
|
26321
|
+
expect(user.getText()).toContain('{"name":"guest","last":"visitor"}');
|
26322
|
+
expect(userNameValid.getText()).toContain('true');
|
26323
|
+
expect(formValid.getText()).toContain('true');
|
26150
26324
|
});
|
26151
26325
|
|
26152
26326
|
it('should be invalid if empty when required', function() {
|
26153
|
-
|
26154
|
-
|
26155
|
-
|
26156
|
-
expect(
|
26327
|
+
userNameInput.clear();
|
26328
|
+
userNameInput.sendKeys('');
|
26329
|
+
|
26330
|
+
expect(user.getText()).toContain('{"last":"visitor"}');
|
26331
|
+
expect(userNameValid.getText()).toContain('false');
|
26332
|
+
expect(formValid.getText()).toContain('false');
|
26157
26333
|
});
|
26158
26334
|
|
26159
26335
|
it('should be valid if empty when min length is set', function() {
|
26160
|
-
|
26161
|
-
|
26162
|
-
|
26163
|
-
expect(
|
26336
|
+
userLastInput.clear();
|
26337
|
+
userLastInput.sendKeys('');
|
26338
|
+
|
26339
|
+
expect(user.getText()).toContain('{"name":"guest","last":""}');
|
26340
|
+
expect(lastNameValid.getText()).toContain('true');
|
26341
|
+
expect(formValid.getText()).toContain('true');
|
26164
26342
|
});
|
26165
26343
|
|
26166
26344
|
it('should be invalid if less than required min length', function() {
|
26167
|
-
|
26168
|
-
|
26169
|
-
|
26170
|
-
expect(
|
26171
|
-
expect(
|
26345
|
+
userLastInput.clear();
|
26346
|
+
userLastInput.sendKeys('xx');
|
26347
|
+
|
26348
|
+
expect(user.getText()).toContain('{"name":"guest"}');
|
26349
|
+
expect(lastNameValid.getText()).toContain('false');
|
26350
|
+
expect(lastNameError.getText()).toContain('minlength');
|
26351
|
+
expect(formValid.getText()).toContain('false');
|
26172
26352
|
});
|
26173
26353
|
|
26174
26354
|
it('should be invalid if longer than max length', function() {
|
26175
|
-
|
26176
|
-
|
26177
|
-
|
26178
|
-
expect(
|
26179
|
-
expect(
|
26180
|
-
expect(
|
26355
|
+
userLastInput.clear();
|
26356
|
+
userLastInput.sendKeys('some ridiculously long name');
|
26357
|
+
|
26358
|
+
expect(user.getText()).toContain('{"name":"guest"}');
|
26359
|
+
expect(lastNameValid.getText()).toContain('false');
|
26360
|
+
expect(lastNameError.getText()).toContain('maxlength');
|
26361
|
+
expect(formValid.getText()).toContain('false');
|
26181
26362
|
});
|
26182
|
-
</doc:
|
26363
|
+
</doc:protractor>
|
26183
26364
|
</doc:example>
|
26184
26365
|
*/
|
26185
26366
|
var inputDirective = ['$browser', '$sniffer', function($browser, $sniffer) {
|
@@ -26311,14 +26492,23 @@ var VALID_CLASS = 'ng-valid',
|
|
26311
26492
|
<textarea ng-model="userContent"></textarea>
|
26312
26493
|
</form>
|
26313
26494
|
</file>
|
26314
|
-
<file name="
|
26495
|
+
<file name="protractorTest.js">
|
26315
26496
|
it('should data-bind and become invalid', function() {
|
26316
|
-
|
26497
|
+
if (browser.params.browser = 'safari') {
|
26498
|
+
// SafariDriver can't handle contenteditable.
|
26499
|
+
return;
|
26500
|
+
};
|
26501
|
+
var contentEditable = element(by.css('.doc-example-live [contenteditable]'));
|
26317
26502
|
|
26318
|
-
expect(contentEditable.
|
26319
|
-
|
26320
|
-
|
26321
|
-
|
26503
|
+
expect(contentEditable.getText()).toEqual('Change me!');
|
26504
|
+
|
26505
|
+
// Firefox driver doesn't trigger the proper events on 'clear', so do this hack
|
26506
|
+
contentEditable.click();
|
26507
|
+
contentEditable.sendKeys(protractor.Key.chord(protractor.Key.COMMAND, "a"));
|
26508
|
+
contentEditable.sendKeys(protractor.Key.BACK_SPACE);
|
26509
|
+
|
26510
|
+
expect(contentEditable.getText()).toEqual('');
|
26511
|
+
expect(contentEditable.getAttribute('class')).toMatch(/ng-invalid-required/);
|
26322
26512
|
});
|
26323
26513
|
</file>
|
26324
26514
|
* </example>
|
@@ -26371,6 +26561,9 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
26371
26561
|
* You can override this for input directives whose concept of being empty is different to the
|
26372
26562
|
* default. The `checkboxInputType` directive does this because in its case a value of `false`
|
26373
26563
|
* implies empty.
|
26564
|
+
*
|
26565
|
+
* @param {*} value Reference to check.
|
26566
|
+
* @returns {boolean} True if `value` is empty.
|
26374
26567
|
*/
|
26375
26568
|
this.$isEmpty = function(value) {
|
26376
26569
|
return isUndefined(value) || value === '' || value === null || value !== value;
|
@@ -26598,7 +26791,10 @@ var ngModelDirective = function() {
|
|
26598
26791
|
* @name ng.directive:ngChange
|
26599
26792
|
*
|
26600
26793
|
* @description
|
26601
|
-
* Evaluate given expression when user changes the input.
|
26794
|
+
* Evaluate the given expression when the user changes the input.
|
26795
|
+
* The expression is evaluated immediately, unlike the JavaScript onchange event
|
26796
|
+
* which only triggers at the end of a change (usually, when the user leaves the
|
26797
|
+
* form element or presses the return key).
|
26602
26798
|
* The expression is not evaluated when the value change is coming from the model.
|
26603
26799
|
*
|
26604
26800
|
* Note, this directive requires `ngModel` to be present.
|
@@ -26622,24 +26818,30 @@ var ngModelDirective = function() {
|
|
26622
26818
|
* <input type="checkbox" ng-model="confirmed" ng-change="change()" id="ng-change-example1" />
|
26623
26819
|
* <input type="checkbox" ng-model="confirmed" id="ng-change-example2" />
|
26624
26820
|
* <label for="ng-change-example2">Confirmed</label><br />
|
26625
|
-
* debug = {{confirmed}}
|
26626
|
-
* counter = {{counter}}
|
26821
|
+
* <tt>debug = {{confirmed}}</tt><br/>
|
26822
|
+
* <tt>counter = {{counter}}</tt><br/>
|
26627
26823
|
* </div>
|
26628
26824
|
* </doc:source>
|
26629
|
-
* <doc:
|
26825
|
+
* <doc:protractor>
|
26826
|
+
* var counter = element(by.binding('counter'));
|
26827
|
+
* var debug = element(by.binding('confirmed'));
|
26828
|
+
*
|
26630
26829
|
* it('should evaluate the expression if changing from view', function() {
|
26631
|
-
* expect(
|
26632
|
-
*
|
26633
|
-
*
|
26634
|
-
*
|
26830
|
+
* expect(counter.getText()).toContain('0');
|
26831
|
+
*
|
26832
|
+
* element(by.id('ng-change-example1')).click();
|
26833
|
+
*
|
26834
|
+
* expect(counter.getText()).toContain('1');
|
26835
|
+
* expect(debug.getText()).toContain('true');
|
26635
26836
|
* });
|
26636
26837
|
*
|
26637
26838
|
* it('should not evaluate the expression if changing from model', function() {
|
26638
|
-
* element('
|
26639
|
-
|
26640
|
-
* expect(
|
26839
|
+
* element(by.id('ng-change-example2')).click();
|
26840
|
+
|
26841
|
+
* expect(counter.getText()).toContain('0');
|
26842
|
+
* expect(debug.getText()).toContain('true');
|
26641
26843
|
* });
|
26642
|
-
* </doc:
|
26844
|
+
* </doc:protractor>
|
26643
26845
|
* </doc:example>
|
26644
26846
|
*/
|
26645
26847
|
var ngChangeDirective = valueFn({
|
@@ -26712,20 +26914,26 @@ var requiredDirective = function() {
|
|
26712
26914
|
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
|
26713
26915
|
</form>
|
26714
26916
|
</doc:source>
|
26715
|
-
<doc:
|
26917
|
+
<doc:protractor>
|
26918
|
+
var listInput = element(by.model('names'));
|
26919
|
+
var names = element(by.binding('{{names}}'));
|
26920
|
+
var valid = element(by.binding('myForm.namesInput.$valid'));
|
26921
|
+
var error = element(by.css('span.error'));
|
26922
|
+
|
26716
26923
|
it('should initialize to model', function() {
|
26717
|
-
expect(
|
26718
|
-
expect(
|
26719
|
-
expect(
|
26924
|
+
expect(names.getText()).toContain('["igor","misko","vojta"]');
|
26925
|
+
expect(valid.getText()).toContain('true');
|
26926
|
+
expect(error.getCssValue('display')).toBe('none');
|
26720
26927
|
});
|
26721
26928
|
|
26722
26929
|
it('should be invalid if empty', function() {
|
26723
|
-
|
26724
|
-
|
26725
|
-
|
26726
|
-
expect(
|
26727
|
-
|
26728
|
-
|
26930
|
+
listInput.clear();
|
26931
|
+
listInput.sendKeys('');
|
26932
|
+
|
26933
|
+
expect(names.getText()).toContain('');
|
26934
|
+
expect(valid.getText()).toContain('false');
|
26935
|
+
expect(error.getCssValue('display')).not.toBe('none'); });
|
26936
|
+
</doc:protractor>
|
26729
26937
|
</doc:example>
|
26730
26938
|
*/
|
26731
26939
|
var ngListDirective = function() {
|
@@ -26807,15 +27015,17 @@ var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
|
|
26807
27015
|
<div>You chose {{my.favorite}}</div>
|
26808
27016
|
</form>
|
26809
27017
|
</doc:source>
|
26810
|
-
<doc:
|
27018
|
+
<doc:protractor>
|
27019
|
+
var favorite = element(by.binding('my.favorite'));
|
27020
|
+
|
26811
27021
|
it('should initialize to model', function() {
|
26812
|
-
expect(
|
27022
|
+
expect(favorite.getText()).toContain('unicorns');
|
26813
27023
|
});
|
26814
27024
|
it('should bind the values to the inputs', function() {
|
26815
|
-
|
26816
|
-
expect(
|
27025
|
+
element.all(by.model('my.favorite')).get(0).click();
|
27026
|
+
expect(favorite.getText()).toContain('pizza');
|
26817
27027
|
});
|
26818
|
-
</doc:
|
27028
|
+
</doc:protractor>
|
26819
27029
|
</doc:example>
|
26820
27030
|
*/
|
26821
27031
|
var ngValueDirective = function() {
|
@@ -26875,13 +27085,17 @@ var ngValueDirective = function() {
|
|
26875
27085
|
Hello <span ng-bind="name"></span>!
|
26876
27086
|
</div>
|
26877
27087
|
</doc:source>
|
26878
|
-
<doc:
|
27088
|
+
<doc:protractor>
|
26879
27089
|
it('should check ng-bind', function() {
|
26880
|
-
|
26881
|
-
|
26882
|
-
|
27090
|
+
var exampleContainer = $('.doc-example-live');
|
27091
|
+
var nameInput = element(by.model('name'));
|
27092
|
+
|
27093
|
+
expect(exampleContainer.findElement(by.binding('name')).getText()).toBe('Whirled');
|
27094
|
+
nameInput.clear();
|
27095
|
+
nameInput.sendKeys('world');
|
27096
|
+
expect(exampleContainer.findElement(by.binding('name')).getText()).toBe('world');
|
26883
27097
|
});
|
26884
|
-
</doc:
|
27098
|
+
</doc:protractor>
|
26885
27099
|
</doc:example>
|
26886
27100
|
*/
|
26887
27101
|
var ngBindDirective = ngDirective(function(scope, element, attr) {
|
@@ -26927,20 +27141,22 @@ var ngBindDirective = ngDirective(function(scope, element, attr) {
|
|
26927
27141
|
<pre ng-bind-template="{{salutation}} {{name}}!"></pre>
|
26928
27142
|
</div>
|
26929
27143
|
</doc:source>
|
26930
|
-
<doc:
|
27144
|
+
<doc:protractor>
|
26931
27145
|
it('should check ng-bind', function() {
|
26932
|
-
|
26933
|
-
|
26934
|
-
|
26935
|
-
|
26936
|
-
|
26937
|
-
|
26938
|
-
|
26939
|
-
|
26940
|
-
|
26941
|
-
|
27146
|
+
var salutationElem = element(by.binding('salutation'));
|
27147
|
+
var salutationInput = element(by.model('salutation'));
|
27148
|
+
var nameInput = element(by.model('name'));
|
27149
|
+
|
27150
|
+
expect(salutationElem.getText()).toBe('Hello World!');
|
27151
|
+
|
27152
|
+
salutationInput.clear();
|
27153
|
+
salutationInput.sendKeys('Greetings');
|
27154
|
+
nameInput.clear();
|
27155
|
+
nameInput.sendKeys('user');
|
27156
|
+
|
27157
|
+
expect(salutationElem.getText()).toBe('Greetings user!');
|
26942
27158
|
});
|
26943
|
-
</doc:
|
27159
|
+
</doc:protractor>
|
26944
27160
|
</doc:example>
|
26945
27161
|
*/
|
26946
27162
|
var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
|
@@ -26993,12 +27209,10 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
|
|
26993
27209
|
}]);
|
26994
27210
|
</file>
|
26995
27211
|
|
26996
|
-
<file name="
|
27212
|
+
<file name="protractorTest.js">
|
26997
27213
|
it('should check ng-bind-html', function() {
|
26998
|
-
expect(
|
26999
|
-
|
27000
|
-
'I am an <code>HTML</code>string with <a href="#">links!</a> and other <em>stuff</em>'
|
27001
|
-
);
|
27214
|
+
expect(element(by.binding('myHTML')).getText()).toBe(
|
27215
|
+
'I am an HTMLstring with links! and other stuff');
|
27002
27216
|
});
|
27003
27217
|
</file>
|
27004
27218
|
</example>
|
@@ -27130,31 +27344,34 @@ function classDirective(name, selector) {
|
|
27130
27344
|
color: red;
|
27131
27345
|
}
|
27132
27346
|
</file>
|
27133
|
-
<file name="
|
27347
|
+
<file name="protractorTest.js">
|
27348
|
+
var ps = element.all(by.css('.doc-example-live p'));
|
27349
|
+
|
27134
27350
|
it('should let you toggle the class', function() {
|
27135
27351
|
|
27136
|
-
expect(
|
27137
|
-
expect(
|
27352
|
+
expect(ps.first().getAttribute('class')).not.toMatch(/bold/);
|
27353
|
+
expect(ps.first().getAttribute('class')).not.toMatch(/red/);
|
27138
27354
|
|
27139
|
-
|
27140
|
-
expect(
|
27355
|
+
element(by.model('important')).click();
|
27356
|
+
expect(ps.first().getAttribute('class')).toMatch(/bold/);
|
27141
27357
|
|
27142
|
-
|
27143
|
-
expect(
|
27358
|
+
element(by.model('error')).click();
|
27359
|
+
expect(ps.first().getAttribute('class')).toMatch(/red/);
|
27144
27360
|
});
|
27145
27361
|
|
27146
27362
|
it('should let you toggle string example', function() {
|
27147
|
-
expect(
|
27148
|
-
|
27149
|
-
|
27363
|
+
expect(ps.get(1).getAttribute('class')).toBe('');
|
27364
|
+
element(by.model('style')).clear();
|
27365
|
+
element(by.model('style')).sendKeys('red');
|
27366
|
+
expect(ps.get(1).getAttribute('class')).toBe('red');
|
27150
27367
|
});
|
27151
27368
|
|
27152
27369
|
it('array example should have 3 classes', function() {
|
27153
|
-
expect(
|
27154
|
-
|
27155
|
-
|
27156
|
-
|
27157
|
-
expect(
|
27370
|
+
expect(ps.last().getAttribute('class')).toBe('');
|
27371
|
+
element(by.model('style1')).sendKeys('bold');
|
27372
|
+
element(by.model('style2')).sendKeys('strike');
|
27373
|
+
element(by.model('style3')).sendKeys('red');
|
27374
|
+
expect(ps.last().getAttribute('class')).toBe('bold strike red');
|
27158
27375
|
});
|
27159
27376
|
</file>
|
27160
27377
|
</example>
|
@@ -27165,8 +27382,8 @@ function classDirective(name, selector) {
|
|
27165
27382
|
|
27166
27383
|
<example animations="true">
|
27167
27384
|
<file name="index.html">
|
27168
|
-
<input type="button" value="set" ng-click="myVar='my-class'">
|
27169
|
-
<input type="button" value="clear" ng-click="myVar=''">
|
27385
|
+
<input id="setbtn" type="button" value="set" ng-click="myVar='my-class'">
|
27386
|
+
<input id="clearbtn" type="button" value="clear" ng-click="myVar=''">
|
27170
27387
|
<br>
|
27171
27388
|
<span class="base-class" ng-class="myVar">Sample Text</span>
|
27172
27389
|
</file>
|
@@ -27181,19 +27398,19 @@ function classDirective(name, selector) {
|
|
27181
27398
|
font-size:3em;
|
27182
27399
|
}
|
27183
27400
|
</file>
|
27184
|
-
<file name="
|
27401
|
+
<file name="protractorTest.js">
|
27185
27402
|
it('should check ng-class', function() {
|
27186
|
-
expect(element('.
|
27403
|
+
expect(element(by.css('.base-class')).getAttribute('class')).not.
|
27187
27404
|
toMatch(/my-class/);
|
27188
27405
|
|
27189
|
-
|
27406
|
+
element(by.id('setbtn')).click();
|
27190
27407
|
|
27191
|
-
expect(element('.
|
27408
|
+
expect(element(by.css('.base-class')).getAttribute('class')).
|
27192
27409
|
toMatch(/my-class/);
|
27193
27410
|
|
27194
|
-
|
27411
|
+
element(by.id('clearbtn')).click();
|
27195
27412
|
|
27196
|
-
expect(element('.
|
27413
|
+
expect(element(by.css('.base-class')).getAttribute('class')).not.
|
27197
27414
|
toMatch(/my-class/);
|
27198
27415
|
});
|
27199
27416
|
</file>
|
@@ -27245,11 +27462,11 @@ var ngClassDirective = classDirective('', true);
|
|
27245
27462
|
color: blue;
|
27246
27463
|
}
|
27247
27464
|
</file>
|
27248
|
-
<file name="
|
27465
|
+
<file name="protractorTest.js">
|
27249
27466
|
it('should check ng-class-odd and ng-class-even', function() {
|
27250
|
-
expect(element('
|
27467
|
+
expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).
|
27251
27468
|
toMatch(/odd/);
|
27252
|
-
expect(element('
|
27469
|
+
expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).
|
27253
27470
|
toMatch(/even/);
|
27254
27471
|
});
|
27255
27472
|
</file>
|
@@ -27293,11 +27510,11 @@ var ngClassOddDirective = classDirective('Odd', 0);
|
|
27293
27510
|
color: blue;
|
27294
27511
|
}
|
27295
27512
|
</file>
|
27296
|
-
<file name="
|
27513
|
+
<file name="protractorTest.js">
|
27297
27514
|
it('should check ng-class-odd and ng-class-even', function() {
|
27298
|
-
expect(element('
|
27515
|
+
expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).
|
27299
27516
|
toMatch(/odd/);
|
27300
|
-
expect(element('
|
27517
|
+
expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).
|
27301
27518
|
toMatch(/even/);
|
27302
27519
|
});
|
27303
27520
|
</file>
|
@@ -27350,14 +27567,14 @@ var ngClassEvenDirective = classDirective('Even', 1);
|
|
27350
27567
|
<div id="template1" ng-cloak>{{ 'hello' }}</div>
|
27351
27568
|
<div id="template2" ng-cloak class="ng-cloak">{{ 'hello IE7' }}</div>
|
27352
27569
|
</doc:source>
|
27353
|
-
<doc:
|
27570
|
+
<doc:protractor>
|
27354
27571
|
it('should remove the template directive and css class', function() {
|
27355
|
-
expect(
|
27356
|
-
|
27357
|
-
expect(
|
27358
|
-
|
27572
|
+
expect($('.doc-example-live #template1').getAttribute('ng-cloak')).
|
27573
|
+
toBeNull();
|
27574
|
+
expect($('.doc-example-live #template2').getAttribute('ng-cloak')).
|
27575
|
+
toBeNull();
|
27359
27576
|
});
|
27360
|
-
</doc:
|
27577
|
+
</doc:protractor>
|
27361
27578
|
</doc:example>
|
27362
27579
|
*
|
27363
27580
|
*/
|
@@ -27450,22 +27667,36 @@ var ngCloakDirective = ngDirective({
|
|
27450
27667
|
</ul>
|
27451
27668
|
</div>
|
27452
27669
|
</doc:source>
|
27453
|
-
<doc:
|
27670
|
+
<doc:protractor>
|
27454
27671
|
it('should check controller as', function() {
|
27455
|
-
|
27456
|
-
|
27457
|
-
|
27458
|
-
|
27459
|
-
|
27460
|
-
|
27461
|
-
|
27462
|
-
|
27463
|
-
|
27464
|
-
|
27465
|
-
expect(
|
27466
|
-
|
27672
|
+
var container = element(by.id('ctrl-as-exmpl'));
|
27673
|
+
|
27674
|
+
expect(container.findElement(by.model('settings.name'))
|
27675
|
+
.getAttribute('value')).toBe('John Smith');
|
27676
|
+
|
27677
|
+
var firstRepeat =
|
27678
|
+
container.findElement(by.repeater('contact in settings.contacts').row(0));
|
27679
|
+
var secondRepeat =
|
27680
|
+
container.findElement(by.repeater('contact in settings.contacts').row(1));
|
27681
|
+
|
27682
|
+
expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
|
27683
|
+
.toBe('408 555 1212');
|
27684
|
+
expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value'))
|
27685
|
+
.toBe('john.smith@example.org');
|
27686
|
+
|
27687
|
+
firstRepeat.findElement(by.linkText('clear')).click()
|
27688
|
+
|
27689
|
+
expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
|
27690
|
+
.toBe('');
|
27691
|
+
|
27692
|
+
container.findElement(by.linkText('add')).click();
|
27693
|
+
|
27694
|
+
expect(container.findElement(by.repeater('contact in settings.contacts').row(2))
|
27695
|
+
.findElement(by.model('contact.value'))
|
27696
|
+
.getAttribute('value'))
|
27697
|
+
.toBe('yourname@example.org');
|
27467
27698
|
});
|
27468
|
-
</doc:
|
27699
|
+
</doc:protractor>
|
27469
27700
|
</doc:example>
|
27470
27701
|
<doc:example>
|
27471
27702
|
<doc:source>
|
@@ -27513,22 +27744,36 @@ var ngCloakDirective = ngDirective({
|
|
27513
27744
|
</ul>
|
27514
27745
|
</div>
|
27515
27746
|
</doc:source>
|
27516
|
-
<doc:
|
27747
|
+
<doc:protractor>
|
27517
27748
|
it('should check controller', function() {
|
27518
|
-
|
27519
|
-
|
27520
|
-
|
27521
|
-
|
27522
|
-
|
27523
|
-
|
27524
|
-
|
27525
|
-
|
27526
|
-
|
27527
|
-
|
27528
|
-
expect(
|
27529
|
-
|
27749
|
+
var container = element(by.id('ctrl-exmpl'));
|
27750
|
+
|
27751
|
+
expect(container.findElement(by.model('name'))
|
27752
|
+
.getAttribute('value')).toBe('John Smith');
|
27753
|
+
|
27754
|
+
var firstRepeat =
|
27755
|
+
container.findElement(by.repeater('contact in contacts').row(0));
|
27756
|
+
var secondRepeat =
|
27757
|
+
container.findElement(by.repeater('contact in contacts').row(1));
|
27758
|
+
|
27759
|
+
expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
|
27760
|
+
.toBe('408 555 1212');
|
27761
|
+
expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value'))
|
27762
|
+
.toBe('john.smith@example.org');
|
27763
|
+
|
27764
|
+
firstRepeat.findElement(by.linkText('clear')).click()
|
27765
|
+
|
27766
|
+
expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
|
27767
|
+
.toBe('');
|
27768
|
+
|
27769
|
+
container.findElement(by.linkText('add')).click();
|
27770
|
+
|
27771
|
+
expect(container.findElement(by.repeater('contact in contacts').row(2))
|
27772
|
+
.findElement(by.model('contact.value'))
|
27773
|
+
.getAttribute('value'))
|
27774
|
+
.toBe('yourname@example.org');
|
27530
27775
|
});
|
27531
|
-
</doc:
|
27776
|
+
</doc:protractor>
|
27532
27777
|
</doc:example>
|
27533
27778
|
|
27534
27779
|
*/
|
@@ -27591,6 +27836,7 @@ var ngControllerDirective = [function() {
|
|
27591
27836
|
* an element is clicked.
|
27592
27837
|
*
|
27593
27838
|
* @element ANY
|
27839
|
+
* @priority 0
|
27594
27840
|
* @param {expression} ngClick {@link guide/expression Expression} to evaluate upon
|
27595
27841
|
* click. (Event object is available as `$event`)
|
27596
27842
|
*
|
@@ -27647,6 +27893,7 @@ forEach(
|
|
27647
27893
|
* The `ngDblclick` directive allows you to specify custom behavior on a dblclick event.
|
27648
27894
|
*
|
27649
27895
|
* @element ANY
|
27896
|
+
* @priority 0
|
27650
27897
|
* @param {expression} ngDblclick {@link guide/expression Expression} to evaluate upon
|
27651
27898
|
* a dblclick. (The Event object is available as `$event`)
|
27652
27899
|
*
|
@@ -27670,6 +27917,7 @@ forEach(
|
|
27670
27917
|
* The ngMousedown directive allows you to specify custom behavior on mousedown event.
|
27671
27918
|
*
|
27672
27919
|
* @element ANY
|
27920
|
+
* @priority 0
|
27673
27921
|
* @param {expression} ngMousedown {@link guide/expression Expression} to evaluate upon
|
27674
27922
|
* mousedown. (Event object is available as `$event`)
|
27675
27923
|
*
|
@@ -27693,6 +27941,7 @@ forEach(
|
|
27693
27941
|
* Specify custom behavior on mouseup event.
|
27694
27942
|
*
|
27695
27943
|
* @element ANY
|
27944
|
+
* @priority 0
|
27696
27945
|
* @param {expression} ngMouseup {@link guide/expression Expression} to evaluate upon
|
27697
27946
|
* mouseup. (Event object is available as `$event`)
|
27698
27947
|
*
|
@@ -27715,6 +27964,7 @@ forEach(
|
|
27715
27964
|
* Specify custom behavior on mouseover event.
|
27716
27965
|
*
|
27717
27966
|
* @element ANY
|
27967
|
+
* @priority 0
|
27718
27968
|
* @param {expression} ngMouseover {@link guide/expression Expression} to evaluate upon
|
27719
27969
|
* mouseover. (Event object is available as `$event`)
|
27720
27970
|
*
|
@@ -27738,6 +27988,7 @@ forEach(
|
|
27738
27988
|
* Specify custom behavior on mouseenter event.
|
27739
27989
|
*
|
27740
27990
|
* @element ANY
|
27991
|
+
* @priority 0
|
27741
27992
|
* @param {expression} ngMouseenter {@link guide/expression Expression} to evaluate upon
|
27742
27993
|
* mouseenter. (Event object is available as `$event`)
|
27743
27994
|
*
|
@@ -27761,6 +28012,7 @@ forEach(
|
|
27761
28012
|
* Specify custom behavior on mouseleave event.
|
27762
28013
|
*
|
27763
28014
|
* @element ANY
|
28015
|
+
* @priority 0
|
27764
28016
|
* @param {expression} ngMouseleave {@link guide/expression Expression} to evaluate upon
|
27765
28017
|
* mouseleave. (Event object is available as `$event`)
|
27766
28018
|
*
|
@@ -27784,6 +28036,7 @@ forEach(
|
|
27784
28036
|
* Specify custom behavior on mousemove event.
|
27785
28037
|
*
|
27786
28038
|
* @element ANY
|
28039
|
+
* @priority 0
|
27787
28040
|
* @param {expression} ngMousemove {@link guide/expression Expression} to evaluate upon
|
27788
28041
|
* mousemove. (Event object is available as `$event`)
|
27789
28042
|
*
|
@@ -27807,6 +28060,7 @@ forEach(
|
|
27807
28060
|
* Specify custom behavior on keydown event.
|
27808
28061
|
*
|
27809
28062
|
* @element ANY
|
28063
|
+
* @priority 0
|
27810
28064
|
* @param {expression} ngKeydown {@link guide/expression Expression} to evaluate upon
|
27811
28065
|
* keydown. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
|
27812
28066
|
*
|
@@ -27828,6 +28082,7 @@ forEach(
|
|
27828
28082
|
* Specify custom behavior on keyup event.
|
27829
28083
|
*
|
27830
28084
|
* @element ANY
|
28085
|
+
* @priority 0
|
27831
28086
|
* @param {expression} ngKeyup {@link guide/expression Expression} to evaluate upon
|
27832
28087
|
* keyup. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
|
27833
28088
|
*
|
@@ -27870,10 +28125,11 @@ forEach(
|
|
27870
28125
|
* Enables binding angular expressions to onsubmit events.
|
27871
28126
|
*
|
27872
28127
|
* Additionally it prevents the default action (which for form means sending the request to the
|
27873
|
-
* server and reloading the current page)
|
27874
|
-
*
|
28128
|
+
* server and reloading the current page), but only if the form does not contain `action`,
|
28129
|
+
* `data-action`, or `x-action` attributes.
|
27875
28130
|
*
|
27876
28131
|
* @element form
|
28132
|
+
* @priority 0
|
27877
28133
|
* @param {expression} ngSubmit {@link guide/expression Expression} to eval. (Event object is available as `$event`)
|
27878
28134
|
*
|
27879
28135
|
* @example
|
@@ -27898,20 +28154,20 @@ forEach(
|
|
27898
28154
|
<pre>list={{list}}</pre>
|
27899
28155
|
</form>
|
27900
28156
|
</doc:source>
|
27901
|
-
<doc:
|
28157
|
+
<doc:protractor>
|
27902
28158
|
it('should check ng-submit', function() {
|
27903
|
-
expect(binding('list')).toBe('[]');
|
27904
|
-
element('.doc-example-live #submit').click();
|
27905
|
-
expect(binding('list')).
|
27906
|
-
expect(input('text').
|
28159
|
+
expect(element(by.binding('list')).getText()).toBe('list=[]');
|
28160
|
+
element(by.css('.doc-example-live #submit')).click();
|
28161
|
+
expect(element(by.binding('list')).getText()).toContain('hello');
|
28162
|
+
expect(element(by.input('text')).getAttribute('value')).toBe('');
|
27907
28163
|
});
|
27908
28164
|
it('should ignore empty strings', function() {
|
27909
|
-
expect(binding('list')).toBe('[]');
|
27910
|
-
element('.doc-example-live #submit').click();
|
27911
|
-
element('.doc-example-live #submit').click();
|
27912
|
-
expect(binding('list')).
|
27913
|
-
|
27914
|
-
</doc:
|
28165
|
+
expect(element(by.binding('list')).getText()).toBe('list=[]');
|
28166
|
+
element(by.css('.doc-example-live #submit')).click();
|
28167
|
+
element(by.css('.doc-example-live #submit')).click();
|
28168
|
+
expect(element(by.binding('list')).getText()).toContain('hello');
|
28169
|
+
});
|
28170
|
+
</doc:protractor>
|
27915
28171
|
</doc:example>
|
27916
28172
|
*/
|
27917
28173
|
|
@@ -27923,6 +28179,7 @@ forEach(
|
|
27923
28179
|
* Specify custom behavior on focus event.
|
27924
28180
|
*
|
27925
28181
|
* @element window, input, select, textarea, a
|
28182
|
+
* @priority 0
|
27926
28183
|
* @param {expression} ngFocus {@link guide/expression Expression} to evaluate upon
|
27927
28184
|
* focus. (Event object is available as `$event`)
|
27928
28185
|
*
|
@@ -27938,6 +28195,7 @@ forEach(
|
|
27938
28195
|
* Specify custom behavior on blur event.
|
27939
28196
|
*
|
27940
28197
|
* @element window, input, select, textarea, a
|
28198
|
+
* @priority 0
|
27941
28199
|
* @param {expression} ngBlur {@link guide/expression Expression} to evaluate upon
|
27942
28200
|
* blur. (Event object is available as `$event`)
|
27943
28201
|
*
|
@@ -27953,6 +28211,7 @@ forEach(
|
|
27953
28211
|
* Specify custom behavior on copy event.
|
27954
28212
|
*
|
27955
28213
|
* @element window, input, select, textarea, a
|
28214
|
+
* @priority 0
|
27956
28215
|
* @param {expression} ngCopy {@link guide/expression Expression} to evaluate upon
|
27957
28216
|
* copy. (Event object is available as `$event`)
|
27958
28217
|
*
|
@@ -27973,6 +28232,7 @@ forEach(
|
|
27973
28232
|
* Specify custom behavior on cut event.
|
27974
28233
|
*
|
27975
28234
|
* @element window, input, select, textarea, a
|
28235
|
+
* @priority 0
|
27976
28236
|
* @param {expression} ngCut {@link guide/expression Expression} to evaluate upon
|
27977
28237
|
* cut. (Event object is available as `$event`)
|
27978
28238
|
*
|
@@ -27993,6 +28253,7 @@ forEach(
|
|
27993
28253
|
* Specify custom behavior on paste event.
|
27994
28254
|
*
|
27995
28255
|
* @element window, input, select, textarea, a
|
28256
|
+
* @priority 0
|
27996
28257
|
* @param {expression} ngPaste {@link guide/expression Expression} to evaluate upon
|
27997
28258
|
* paste. (Event object is available as `$event`)
|
27998
28259
|
*
|
@@ -28233,19 +28494,33 @@ var ngIfDirective = ['$animate', function($animate) {
|
|
28233
28494
|
top:50px;
|
28234
28495
|
}
|
28235
28496
|
</file>
|
28236
|
-
<file name="
|
28497
|
+
<file name="protractorTest.js">
|
28498
|
+
var templateSelect = element(by.model('template'));
|
28499
|
+
var includeElem = element(by.css('.doc-example-live [ng-include]'));
|
28500
|
+
|
28237
28501
|
it('should load template1.html', function() {
|
28238
|
-
|
28239
|
-
toMatch(/Content of template1.html/);
|
28502
|
+
expect(includeElem.getText()).toMatch(/Content of template1.html/);
|
28240
28503
|
});
|
28504
|
+
|
28241
28505
|
it('should load template2.html', function() {
|
28242
|
-
|
28243
|
-
|
28244
|
-
|
28506
|
+
if (browser.params.browser == 'firefox') {
|
28507
|
+
// Firefox can't handle using selects
|
28508
|
+
// See https://github.com/angular/protractor/issues/480
|
28509
|
+
return;
|
28510
|
+
}
|
28511
|
+
templateSelect.click();
|
28512
|
+
templateSelect.element.all(by.css('option')).get(2).click();
|
28513
|
+
expect(includeElem.getText()).toMatch(/Content of template2.html/);
|
28245
28514
|
});
|
28515
|
+
|
28246
28516
|
it('should change to blank', function() {
|
28247
|
-
|
28248
|
-
|
28517
|
+
if (browser.params.browser == 'firefox') {
|
28518
|
+
// Firefox can't handle using selects
|
28519
|
+
return;
|
28520
|
+
}
|
28521
|
+
templateSelect.click();
|
28522
|
+
templateSelect.element.all(by.css('option')).get(0).click();
|
28523
|
+
expect(includeElem.isPresent()).toBe(false);
|
28249
28524
|
});
|
28250
28525
|
</file>
|
28251
28526
|
</example>
|
@@ -28376,6 +28651,13 @@ var ngIncludeFillContentDirective = ['$compile',
|
|
28376
28651
|
* should use {@link guide/controller controllers} rather than `ngInit`
|
28377
28652
|
* to initialize values on a scope.
|
28378
28653
|
* </div>
|
28654
|
+
* <div class="alert alert-warning">
|
28655
|
+
* **Note**: If you have assignment in `ngInit` along with {@link api/ng.$filter `$filter`}, make
|
28656
|
+
* sure you have parenthesis for correct precedence:
|
28657
|
+
* <pre class="prettyprint">
|
28658
|
+
* <div ng-init="test1 = (data | orderBy:'name')"></div>
|
28659
|
+
* </pre>
|
28660
|
+
* </div>
|
28379
28661
|
*
|
28380
28662
|
* @priority 450
|
28381
28663
|
*
|
@@ -28398,15 +28680,15 @@ var ngIncludeFillContentDirective = ['$compile',
|
|
28398
28680
|
</div>
|
28399
28681
|
</div>
|
28400
28682
|
</doc:source>
|
28401
|
-
<doc:
|
28683
|
+
<doc:protractor>
|
28402
28684
|
it('should alias index positions', function() {
|
28403
|
-
|
28404
|
-
|
28405
|
-
|
28406
|
-
|
28407
|
-
|
28685
|
+
var elements = element.all(by.css('.example-init'));
|
28686
|
+
expect(elements.get(0).getText()).toBe('list[ 0 ][ 0 ] = a;');
|
28687
|
+
expect(elements.get(1).getText()).toBe('list[ 0 ][ 1 ] = b;');
|
28688
|
+
expect(elements.get(2).getText()).toBe('list[ 1 ][ 0 ] = c;');
|
28689
|
+
expect(elements.get(3).getText()).toBe('list[ 1 ][ 1 ] = d;');
|
28408
28690
|
});
|
28409
|
-
</doc:
|
28691
|
+
</doc:protractor>
|
28410
28692
|
</doc:example>
|
28411
28693
|
*/
|
28412
28694
|
var ngInitDirective = ngDirective({
|
@@ -28444,13 +28726,12 @@ var ngInitDirective = ngDirective({
|
|
28444
28726
|
<div>Normal: {{1 + 2}}</div>
|
28445
28727
|
<div ng-non-bindable>Ignored: {{1 + 2}}</div>
|
28446
28728
|
</doc:source>
|
28447
|
-
<doc:
|
28729
|
+
<doc:protractor>
|
28448
28730
|
it('should check ng-non-bindable', function() {
|
28449
|
-
expect(
|
28450
|
-
expect(
|
28451
|
-
toMatch(/1 \+ 2/);
|
28731
|
+
expect(element(by.binding('1 + 2')).getText()).toContain('3');
|
28732
|
+
expect(element.all(by.css('.doc-example-live div')).last().getText()).toMatch(/1 \+ 2/);
|
28452
28733
|
});
|
28453
|
-
</doc:
|
28734
|
+
</doc:protractor>
|
28454
28735
|
</doc:example>
|
28455
28736
|
*/
|
28456
28737
|
var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
|
@@ -28578,49 +28859,53 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
|
|
28578
28859
|
</ng-pluralize>
|
28579
28860
|
</div>
|
28580
28861
|
</doc:source>
|
28581
|
-
<doc:
|
28862
|
+
<doc:protractor>
|
28582
28863
|
it('should show correct pluralized string', function() {
|
28583
|
-
|
28584
|
-
|
28585
|
-
|
28586
|
-
|
28587
|
-
|
28588
|
-
|
28589
|
-
|
28590
|
-
|
28591
|
-
|
28592
|
-
|
28593
|
-
|
28594
|
-
|
28595
|
-
expect(element('.doc-example-live ng-pluralize:first').text()).
|
28596
|
-
toBe('2 people are viewing.');
|
28597
|
-
expect(element('.doc-example-live ng-pluralize:last').text()).
|
28598
|
-
toBe('Igor and Misko are viewing.');
|
28599
|
-
|
28600
|
-
using('.doc-example-live').input('personCount').enter('3');
|
28601
|
-
expect(element('.doc-example-live ng-pluralize:first').text()).
|
28602
|
-
toBe('3 people are viewing.');
|
28603
|
-
expect(element('.doc-example-live ng-pluralize:last').text()).
|
28604
|
-
toBe('Igor, Misko and one other person are viewing.');
|
28605
|
-
|
28606
|
-
using('.doc-example-live').input('personCount').enter('4');
|
28607
|
-
expect(element('.doc-example-live ng-pluralize:first').text()).
|
28608
|
-
toBe('4 people are viewing.');
|
28609
|
-
expect(element('.doc-example-live ng-pluralize:last').text()).
|
28610
|
-
toBe('Igor, Misko and 2 other people are viewing.');
|
28611
|
-
});
|
28864
|
+
var withoutOffset = element.all(by.css('ng-pluralize')).get(0);
|
28865
|
+
var withOffset = element.all(by.css('ng-pluralize')).get(1);
|
28866
|
+
var countInput = element(by.model('personCount'));
|
28867
|
+
|
28868
|
+
expect(withoutOffset.getText()).toEqual('1 person is viewing.');
|
28869
|
+
expect(withOffset.getText()).toEqual('Igor is viewing.');
|
28870
|
+
|
28871
|
+
countInput.clear();
|
28872
|
+
countInput.sendKeys('0');
|
28873
|
+
|
28874
|
+
expect(withoutOffset.getText()).toEqual('Nobody is viewing.');
|
28875
|
+
expect(withOffset.getText()).toEqual('Nobody is viewing.');
|
28612
28876
|
|
28613
|
-
|
28614
|
-
|
28615
|
-
expect(element('.doc-example-live ng-pluralize:last').text()).
|
28616
|
-
toBe('Igor, Misko and 2 other people are viewing.');
|
28877
|
+
countInput.clear();
|
28878
|
+
countInput.sendKeys('2');
|
28617
28879
|
|
28618
|
-
|
28619
|
-
|
28620
|
-
|
28621
|
-
|
28880
|
+
expect(withoutOffset.getText()).toEqual('2 people are viewing.');
|
28881
|
+
expect(withOffset.getText()).toEqual('Igor and Misko are viewing.');
|
28882
|
+
|
28883
|
+
countInput.clear();
|
28884
|
+
countInput.sendKeys('3');
|
28885
|
+
|
28886
|
+
expect(withoutOffset.getText()).toEqual('3 people are viewing.');
|
28887
|
+
expect(withOffset.getText()).toEqual('Igor, Misko and one other person are viewing.');
|
28888
|
+
|
28889
|
+
countInput.clear();
|
28890
|
+
countInput.sendKeys('4');
|
28891
|
+
|
28892
|
+
expect(withoutOffset.getText()).toEqual('4 people are viewing.');
|
28893
|
+
expect(withOffset.getText()).toEqual('Igor, Misko and 2 other people are viewing.');
|
28894
|
+
});
|
28895
|
+
it('should show data-bound names', function() {
|
28896
|
+
var withOffset = element.all(by.css('ng-pluralize')).get(1);
|
28897
|
+
var personCount = element(by.model('personCount'));
|
28898
|
+
var person1 = element(by.model('person1'));
|
28899
|
+
var person2 = element(by.model('person2'));
|
28900
|
+
personCount.clear();
|
28901
|
+
personCount.sendKeys('4');
|
28902
|
+
person1.clear();
|
28903
|
+
person1.sendKeys('Di');
|
28904
|
+
person2.clear();
|
28905
|
+
person2.sendKeys('Vojta');
|
28906
|
+
expect(withOffset.getText()).toEqual('Di, Vojta and 2 other people are viewing.');
|
28622
28907
|
});
|
28623
|
-
</doc:
|
28908
|
+
</doc:protractor>
|
28624
28909
|
</doc:example>
|
28625
28910
|
*/
|
28626
28911
|
var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interpolate) {
|
@@ -28839,25 +29124,27 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
|
|
28839
29124
|
max-height:40px;
|
28840
29125
|
}
|
28841
29126
|
</file>
|
28842
|
-
<file name="
|
28843
|
-
|
28844
|
-
|
28845
|
-
|
28846
|
-
|
28847
|
-
|
28848
|
-
|
28849
|
-
|
28850
|
-
|
29127
|
+
<file name="protractorTest.js">
|
29128
|
+
var friends = element(by.css('.doc-example-live'))
|
29129
|
+
.element.all(by.repeater('friend in friends'));
|
29130
|
+
|
29131
|
+
it('should render initial data set', function() {
|
29132
|
+
expect(friends.count()).toBe(10);
|
29133
|
+
expect(friends.get(0).getText()).toEqual('[1] John who is 25 years old.');
|
29134
|
+
expect(friends.get(1).getText()).toEqual('[2] Jessie who is 30 years old.');
|
29135
|
+
expect(friends.last().getText()).toEqual('[10] Samantha who is 60 years old.');
|
29136
|
+
expect(element(by.binding('friends.length')).getText())
|
29137
|
+
.toMatch("I have 10 friends. They are:");
|
29138
|
+
});
|
28851
29139
|
|
28852
29140
|
it('should update repeater when filter predicate changes', function() {
|
28853
|
-
|
28854
|
-
expect(r.count()).toBe(10);
|
29141
|
+
expect(friends.count()).toBe(10);
|
28855
29142
|
|
28856
|
-
|
29143
|
+
element(by.css('.doc-example-live')).element(by.model('q')).sendKeys('ma');
|
28857
29144
|
|
28858
|
-
expect(
|
28859
|
-
expect(
|
28860
|
-
expect(
|
29145
|
+
expect(friends.count()).toBe(2);
|
29146
|
+
expect(friends.get(0).getText()).toEqual('[1] Mary who is 28 years old.');
|
29147
|
+
expect(friends.last().getText()).toEqual('[2] Samantha who is 60 years old.');
|
28861
29148
|
});
|
28862
29149
|
</file>
|
28863
29150
|
</example>
|
@@ -29111,6 +29398,11 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
29111
29398
|
*
|
29112
29399
|
* Just remember to include the important flag so the CSS override will function.
|
29113
29400
|
*
|
29401
|
+
* <div class="alert alert-warning">
|
29402
|
+
* **Note:** Here is a list of values that ngShow will consider as a falsy value (case insensitive):<br />
|
29403
|
+
* "f" / "0" / "false" / "no" / "n" / "[]"
|
29404
|
+
* </div>
|
29405
|
+
*
|
29114
29406
|
* ## A note about animations with ngShow
|
29115
29407
|
*
|
29116
29408
|
* Animations in ngShow/ngHide work with the show and hide events that are triggered when the directive expression
|
@@ -29186,16 +29478,19 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
29186
29478
|
background:white;
|
29187
29479
|
}
|
29188
29480
|
</file>
|
29189
|
-
<file name="
|
29190
|
-
|
29191
|
-
|
29192
|
-
expect(element('.doc-example-live span:last:visible').count()).toEqual(1);
|
29481
|
+
<file name="protractorTest.js">
|
29482
|
+
var thumbsUp = element(by.css('.doc-example-live span.icon-thumbs-up'));
|
29483
|
+
var thumbsDown = element(by.css('.doc-example-live span.icon-thumbs-down'));
|
29193
29484
|
|
29194
|
-
|
29485
|
+
it('should check ng-show / ng-hide', function() {
|
29486
|
+
expect(thumbsUp.isDisplayed()).toBeFalsy();
|
29487
|
+
expect(thumbsDown.isDisplayed()).toBeTruthy();
|
29195
29488
|
|
29196
|
-
|
29197
|
-
|
29198
|
-
|
29489
|
+
element(by.model('checked')).click();
|
29490
|
+
|
29491
|
+
expect(thumbsUp.isDisplayed()).toBeTruthy();
|
29492
|
+
expect(thumbsDown.isDisplayed()).toBeFalsy();
|
29493
|
+
});
|
29199
29494
|
</file>
|
29200
29495
|
</example>
|
29201
29496
|
*/
|
@@ -29259,6 +29554,11 @@ var ngShowDirective = ['$animate', function($animate) {
|
|
29259
29554
|
* </pre>
|
29260
29555
|
*
|
29261
29556
|
* Just remember to include the important flag so the CSS override will function.
|
29557
|
+
*
|
29558
|
+
* <div class="alert alert-warning">
|
29559
|
+
* **Note:** Here is a list of values that ngHide will consider as a falsy value (case insensitive):<br />
|
29560
|
+
* "f" / "0" / "false" / "no" / "n" / "[]"
|
29561
|
+
* </div>
|
29262
29562
|
*
|
29263
29563
|
* ## A note about animations with ngHide
|
29264
29564
|
*
|
@@ -29335,16 +29635,19 @@ var ngShowDirective = ['$animate', function($animate) {
|
|
29335
29635
|
background:white;
|
29336
29636
|
}
|
29337
29637
|
</file>
|
29338
|
-
<file name="
|
29339
|
-
|
29340
|
-
|
29341
|
-
expect(element('.doc-example-live .check-element:last:visible').count()).toEqual(1);
|
29638
|
+
<file name="protractorTest.js">
|
29639
|
+
var thumbsUp = element(by.css('.doc-example-live span.icon-thumbs-up'));
|
29640
|
+
var thumbsDown = element(by.css('.doc-example-live span.icon-thumbs-down'));
|
29342
29641
|
|
29343
|
-
|
29642
|
+
it('should check ng-show / ng-hide', function() {
|
29643
|
+
expect(thumbsUp.isDisplayed()).toBeFalsy();
|
29644
|
+
expect(thumbsDown.isDisplayed()).toBeTruthy();
|
29344
29645
|
|
29345
|
-
|
29346
|
-
|
29347
|
-
|
29646
|
+
element(by.model('checked')).click();
|
29647
|
+
|
29648
|
+
expect(thumbsUp.isDisplayed()).toBeTruthy();
|
29649
|
+
expect(thumbsDown.isDisplayed()).toBeFalsy();
|
29650
|
+
});
|
29348
29651
|
</file>
|
29349
29652
|
</example>
|
29350
29653
|
*/
|
@@ -29383,13 +29686,15 @@ var ngHideDirective = ['$animate', function($animate) {
|
|
29383
29686
|
color: black;
|
29384
29687
|
}
|
29385
29688
|
</file>
|
29386
|
-
<file name="
|
29689
|
+
<file name="protractorTest.js">
|
29690
|
+
var colorSpan = element(by.css('.doc-example-live span'));
|
29691
|
+
|
29387
29692
|
it('should check ng-style', function() {
|
29388
|
-
expect(
|
29389
|
-
element('.doc-example-live
|
29390
|
-
expect(
|
29391
|
-
element('.doc-example-live
|
29392
|
-
expect(
|
29693
|
+
expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
|
29694
|
+
element(by.css('.doc-example-live input[value=set]')).click();
|
29695
|
+
expect(colorSpan.getCssValue('color')).toBe('rgba(255, 0, 0, 1)');
|
29696
|
+
element(by.css('.doc-example-live input[value=clear]')).click();
|
29697
|
+
expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
|
29393
29698
|
});
|
29394
29699
|
</file>
|
29395
29700
|
</example>
|
@@ -29414,7 +29719,7 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
|
|
29414
29719
|
* as specified in the template.
|
29415
29720
|
*
|
29416
29721
|
* The directive itself works similar to ngInclude, however, instead of downloading template code (or loading it
|
29417
|
-
* from the template cache), `ngSwitch` simply
|
29722
|
+
* from the template cache), `ngSwitch` simply chooses one of the nested elements and makes it visible based on which element
|
29418
29723
|
* matches the value obtained from the evaluated expression. In other words, you define a container element
|
29419
29724
|
* (where you place the directive), place an expression on the **`on="..."` attribute**
|
29420
29725
|
* (or the **`ng-switch="..."` attribute**), define any inner elements inside of the directive and place
|
@@ -29510,17 +29815,20 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
|
|
29510
29815
|
top:0;
|
29511
29816
|
}
|
29512
29817
|
</file>
|
29513
|
-
<file name="
|
29818
|
+
<file name="protractorTest.js">
|
29819
|
+
var switchElem = element(by.css('.doc-example-live [ng-switch]'));
|
29820
|
+
var select = element(by.model('selection'));
|
29821
|
+
|
29514
29822
|
it('should start in settings', function() {
|
29515
|
-
expect(
|
29823
|
+
expect(switchElem.getText()).toMatch(/Settings Div/);
|
29516
29824
|
});
|
29517
29825
|
it('should change to home', function() {
|
29518
|
-
select('
|
29519
|
-
expect(
|
29826
|
+
select.element.all(by.css('option')).get(1).click();
|
29827
|
+
expect(switchElem.getText()).toMatch(/Home Span/);
|
29520
29828
|
});
|
29521
29829
|
it('should select default', function() {
|
29522
|
-
select('
|
29523
|
-
expect(
|
29830
|
+
select.element.all(by.css('option')).get(2).click();
|
29831
|
+
expect(switchElem.getText()).toMatch(/default/);
|
29524
29832
|
});
|
29525
29833
|
</file>
|
29526
29834
|
</example>
|
@@ -29627,35 +29935,32 @@ var ngSwitchDefaultDirective = ngDirective({
|
|
29627
29935
|
<pane title="{{title}}">{{text}}</pane>
|
29628
29936
|
</div>
|
29629
29937
|
</doc:source>
|
29630
|
-
<doc:
|
29938
|
+
<doc:protractor>
|
29631
29939
|
it('should have transcluded', function() {
|
29632
|
-
|
29633
|
-
|
29634
|
-
|
29635
|
-
|
29940
|
+
var titleElement = element(by.model('title'));
|
29941
|
+
titleElement.clear();
|
29942
|
+
titleElement.sendKeys('TITLE');
|
29943
|
+
var textElement = element(by.model('text'));
|
29944
|
+
textElement.clear();
|
29945
|
+
textElement.sendKeys('TEXT');
|
29946
|
+
expect(element(by.binding('title')).getText()).toEqual('TITLE');
|
29947
|
+
expect(element(by.binding('text')).getText()).toEqual('TEXT');
|
29636
29948
|
});
|
29637
|
-
</doc:
|
29949
|
+
</doc:protractor>
|
29638
29950
|
</doc:example>
|
29639
29951
|
*
|
29640
29952
|
*/
|
29641
29953
|
var ngTranscludeDirective = ngDirective({
|
29642
|
-
|
29954
|
+
link: function($scope, $element, $attrs, controller, $transclude) {
|
29643
29955
|
if (!$transclude) {
|
29644
29956
|
throw minErr('ngTransclude')('orphan',
|
29645
|
-
|
29646
|
-
|
29647
|
-
|
29648
|
-
|
29957
|
+
'Illegal use of ngTransclude directive in the template! ' +
|
29958
|
+
'No parent directive that requires a transclusion found. ' +
|
29959
|
+
'Element: {0}',
|
29960
|
+
startingTag($element));
|
29649
29961
|
}
|
29650
|
-
|
29651
|
-
|
29652
|
-
// the parent element even when the transclusion replaces the current element. (we can't use priority here because
|
29653
|
-
// that applies only to compile fns and not controllers
|
29654
|
-
this.$transclude = $transclude;
|
29655
|
-
}],
|
29656
|
-
|
29657
|
-
link: function($scope, $element, $attrs, controller) {
|
29658
|
-
controller.$transclude(function(clone) {
|
29962
|
+
|
29963
|
+
$transclude(function(clone) {
|
29659
29964
|
$element.empty();
|
29660
29965
|
$element.append(clone);
|
29661
29966
|
});
|
@@ -29687,12 +29992,12 @@ var ngTranscludeDirective = ngDirective({
|
|
29687
29992
|
<a ng-click="currentTpl='/tpl.html'" id="tpl-link">Load inlined template</a>
|
29688
29993
|
<div id="tpl-content" ng-include src="currentTpl"></div>
|
29689
29994
|
</doc:source>
|
29690
|
-
<doc:
|
29995
|
+
<doc:protractor>
|
29691
29996
|
it('should load template defined inside script tag', function() {
|
29692
|
-
element('#tpl-link').click();
|
29693
|
-
expect(element('#tpl-content').
|
29997
|
+
element(by.css('#tpl-link')).click();
|
29998
|
+
expect(element(by.css('#tpl-content')).getText()).toMatch(/Content of the template/);
|
29694
29999
|
});
|
29695
|
-
</doc:
|
30000
|
+
</doc:protractor>
|
29696
30001
|
</doc:example>
|
29697
30002
|
*/
|
29698
30003
|
var scriptDirective = ['$templateCache', function($templateCache) {
|
@@ -29730,14 +30035,21 @@ var ngOptionsMinErr = minErr('ngOptions');
|
|
29730
30035
|
* represented by the selected option will be bound to the model identified by the `ngModel`
|
29731
30036
|
* directive.
|
29732
30037
|
*
|
30038
|
+
* <div class="alert alert-warning">
|
30039
|
+
* **Note:** `ngModel` compares by reference, not value. This is important when binding to an
|
30040
|
+
* array of objects. See an example {@link http://jsfiddle.net/qWzTb/ in this jsfiddle}.
|
30041
|
+
* </div>
|
30042
|
+
*
|
29733
30043
|
* Optionally, a single hard-coded `<option>` element, with the value set to an empty string, can
|
29734
30044
|
* be nested into the `<select>` element. This element will then represent the `null` or "not selected"
|
29735
30045
|
* option. See example below for demonstration.
|
29736
30046
|
*
|
29737
|
-
*
|
30047
|
+
* <div class="alert alert-warning">
|
30048
|
+
* **Note:** `ngOptions` provides an iterator facility for the `<option>` element which should be used instead
|
29738
30049
|
* of {@link ng.directive:ngRepeat ngRepeat} when you want the
|
29739
30050
|
* `select` model to be bound to a non-string value. This is because an option element can only
|
29740
30051
|
* be bound to string values at present.
|
30052
|
+
* </div>
|
29741
30053
|
*
|
29742
30054
|
* @param {string} ngModel Assignable angular expression to data-bind to.
|
29743
30055
|
* @param {string=} name Property name of the form under which the control is published.
|
@@ -29824,15 +30136,17 @@ var ngOptionsMinErr = minErr('ngOptions');
|
|
29824
30136
|
</div>
|
29825
30137
|
</div>
|
29826
30138
|
</doc:source>
|
29827
|
-
<doc:
|
30139
|
+
<doc:protractor>
|
29828
30140
|
it('should check ng-options', function() {
|
29829
|
-
expect(binding('{selected_color:color}')).toMatch('red');
|
29830
|
-
select('color').
|
29831
|
-
|
29832
|
-
|
29833
|
-
|
30141
|
+
expect(element(by.binding('{selected_color:color}')).getText()).toMatch('red');
|
30142
|
+
element.all(by.select('color')).first().click();
|
30143
|
+
element.all(by.css('select[ng-model="color"] option')).first().click();
|
30144
|
+
expect(element(by.binding('{selected_color:color}')).getText()).toMatch('black');
|
30145
|
+
element(by.css('.nullable select[ng-model="color"]')).click();
|
30146
|
+
element.all(by.css('.nullable select[ng-model="color"] option')).first().click();
|
30147
|
+
expect(element(by.binding('{selected_color:color}')).getText()).toMatch('null');
|
29834
30148
|
});
|
29835
|
-
</doc:
|
30149
|
+
</doc:protractor>
|
29836
30150
|
</doc:example>
|
29837
30151
|
*/
|
29838
30152
|
|
@@ -30141,7 +30455,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
30141
30455
|
|
30142
30456
|
// We now build up the list of options we need (we merge later)
|
30143
30457
|
for (index = 0; length = keys.length, index < length; index++) {
|
30144
|
-
|
30458
|
+
|
30145
30459
|
key = index;
|
30146
30460
|
if (keyName) {
|
30147
30461
|
key = keys[index];
|
@@ -32562,5 +32876,5 @@ if (config.autotest) {
|
|
32562
32876
|
})(window, document);
|
32563
32877
|
|
32564
32878
|
|
32565
|
-
!angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";\n\n[ng\\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],\n.ng-cloak, .x-ng-cloak,\n.ng-hide {\n display: none !important;\n}\n\nng\\:form {\n display: block;\n}\n</style>');
|
32879
|
+
!angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";\n\n[ng\\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],\n.ng-cloak, .x-ng-cloak,\n.ng-hide {\n display: none !important;\n}\n\nng\\:form {\n display: block;\n}\n\n.ng-animate-block-transitions {\n transition:0s all!important;\n -webkit-transition:0s all!important;\n}\n</style>');
|
32566
32880
|
!angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";\n/* CSS Document */\n\n/** Structure */\nbody {\n font-family: Arial, sans-serif;\n margin: 0;\n font-size: 14px;\n}\n\n#system-error {\n font-size: 1.5em;\n text-align: center;\n}\n\n#json, #xml {\n display: none;\n}\n\n#header {\n position: fixed;\n width: 100%;\n}\n\n#specs {\n padding-top: 50px;\n}\n\n#header .angular {\n font-family: Courier New, monospace;\n font-weight: bold;\n}\n\n#header h1 {\n font-weight: normal;\n float: left;\n font-size: 30px;\n line-height: 30px;\n margin: 0;\n padding: 10px 10px;\n height: 30px;\n}\n\n#application h2,\n#specs h2 {\n margin: 0;\n padding: 0.5em;\n font-size: 1.1em;\n}\n\n#status-legend {\n margin-top: 10px;\n margin-right: 10px;\n}\n\n#header,\n#application,\n.test-info,\n.test-actions li {\n overflow: hidden;\n}\n\n#application {\n margin: 10px;\n}\n\n#application iframe {\n width: 100%;\n height: 758px;\n}\n\n#application .popout {\n float: right;\n}\n\n#application iframe {\n border: none;\n}\n\n.tests li,\n.test-actions li,\n.test-it li,\n.test-it ol,\n.status-display {\n list-style-type: none;\n}\n\n.tests,\n.test-it ol,\n.status-display {\n margin: 0;\n padding: 0;\n}\n\n.test-info {\n margin-left: 1em;\n margin-top: 0.5em;\n border-radius: 8px 0 0 8px;\n -webkit-border-radius: 8px 0 0 8px;\n -moz-border-radius: 8px 0 0 8px;\n cursor: pointer;\n}\n\n.test-info:hover .test-name {\n text-decoration: underline;\n}\n\n.test-info .closed:before {\n content: \'\\25b8\\00A0\';\n}\n\n.test-info .open:before {\n content: \'\\25be\\00A0\';\n font-weight: bold;\n}\n\n.test-it ol {\n margin-left: 2.5em;\n}\n\n.status-display,\n.status-display li {\n float: right;\n}\n\n.status-display li {\n padding: 5px 10px;\n}\n\n.timer-result,\n.test-title {\n display: inline-block;\n margin: 0;\n padding: 4px;\n}\n\n.test-actions .test-title,\n.test-actions .test-result {\n display: table-cell;\n padding-left: 0.5em;\n padding-right: 0.5em;\n}\n\n.test-actions {\n display: table;\n}\n\n.test-actions li {\n display: table-row;\n}\n\n.timer-result {\n width: 4em;\n padding: 0 10px;\n text-align: right;\n font-family: monospace;\n}\n\n.test-it pre,\n.test-actions pre {\n clear: left;\n color: black;\n margin-left: 6em;\n}\n\n.test-describe {\n padding-bottom: 0.5em;\n}\n\n.test-describe .test-describe {\n margin: 5px 5px 10px 2em;\n}\n\n.test-actions .status-pending .test-title:before {\n content: \'\\00bb\\00A0\';\n}\n\n.scrollpane {\n max-height: 20em;\n overflow: auto;\n}\n\n/** Colors */\n\n#header {\n background-color: #F2C200;\n}\n\n#specs h2 {\n border-top: 2px solid #BABAD1;\n}\n\n#specs h2,\n#application h2 {\n background-color: #efefef;\n}\n\n#application {\n border: 1px solid #BABAD1;\n}\n\n.test-describe .test-describe {\n border-left: 1px solid #BABAD1;\n border-right: 1px solid #BABAD1;\n border-bottom: 1px solid #BABAD1;\n}\n\n.status-display {\n border: 1px solid #777;\n}\n\n.status-display .status-pending,\n.status-pending .test-info {\n background-color: #F9EEBC;\n}\n\n.status-display .status-success,\n.status-success .test-info {\n background-color: #B1D7A1;\n}\n\n.status-display .status-failure,\n.status-failure .test-info {\n background-color: #FF8286;\n}\n\n.status-display .status-error,\n.status-error .test-info {\n background-color: black;\n color: white;\n}\n\n.test-actions .status-success .test-title {\n color: #30B30A;\n}\n\n.test-actions .status-failure .test-title {\n color: #DF0000;\n}\n\n.test-actions .status-error .test-title {\n color: black;\n}\n\n.test-actions .timer-result {\n color: #888;\n}\n</style>');
|