angular-gem 1.2.12 → 1.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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>');
|