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
|
*/
|
@@ -68,7 +68,7 @@ function minErr(module) {
|
|
68
68
|
return match;
|
69
69
|
});
|
70
70
|
|
71
|
-
message = message + '\nhttp://errors.angularjs.org/1.2.
|
71
|
+
message = message + '\nhttp://errors.angularjs.org/1.2.13/' +
|
72
72
|
(module ? module + '/' : '') + code;
|
73
73
|
for (i = 2; i < arguments.length; i++) {
|
74
74
|
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
|
@@ -160,6 +160,7 @@ function minErr(module) {
|
|
160
160
|
-assertNotHasOwnProperty,
|
161
161
|
-getter,
|
162
162
|
-getBlockElements,
|
163
|
+
-hasOwnProperty,
|
163
164
|
|
164
165
|
*/
|
165
166
|
|
@@ -175,7 +176,7 @@ function minErr(module) {
|
|
175
176
|
* @returns {string} Lowercased string.
|
176
177
|
*/
|
177
178
|
var lowercase = function(string){return isString(string) ? string.toLowerCase() : string;};
|
178
|
-
|
179
|
+
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
179
180
|
|
180
181
|
/**
|
181
182
|
* @ngdoc function
|
@@ -271,7 +272,7 @@ function isArrayLike(obj) {
|
|
271
272
|
* is the value of an object property or an array element and `key` is the object property key or
|
272
273
|
* array element index. Specifying a `context` for the function is optional.
|
273
274
|
*
|
274
|
-
* It is worth
|
275
|
+
* It is worth noting that `.forEach` does not iterate over inherited properties because it filters
|
275
276
|
* using the `hasOwnProperty` method.
|
276
277
|
*
|
277
278
|
<pre>
|
@@ -280,7 +281,7 @@ function isArrayLike(obj) {
|
|
280
281
|
angular.forEach(values, function(value, key){
|
281
282
|
this.push(key + ': ' + value);
|
282
283
|
}, log);
|
283
|
-
expect(log).toEqual(['name: misko', 'gender:male']);
|
284
|
+
expect(log).toEqual(['name: misko', 'gender: male']);
|
284
285
|
</pre>
|
285
286
|
*
|
286
287
|
* @param {Object|Array} obj Object to iterate over.
|
@@ -851,7 +852,7 @@ function shallowCopy(src, dst) {
|
|
851
852
|
for(var key in src) {
|
852
853
|
// shallowCopy is only ever called by $compile nodeLinkFn, which has control over src
|
853
854
|
// so we don't need to worry about using our custom hasOwnProperty here
|
854
|
-
if (src.hasOwnProperty(key) && key.charAt(0)
|
855
|
+
if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
|
855
856
|
dst[key] = src[key];
|
856
857
|
}
|
857
858
|
}
|
@@ -1210,6 +1211,7 @@ function encodeUriQuery(val, pctEncodeSpaces) {
|
|
1210
1211
|
<file name="index.html">
|
1211
1212
|
<div ng-controller="ngAppDemoController">
|
1212
1213
|
I can add: {{a}} + {{b}} = {{ a+b }}
|
1214
|
+
</div>
|
1213
1215
|
</file>
|
1214
1216
|
<file name="script.js">
|
1215
1217
|
angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) {
|
@@ -1834,11 +1836,11 @@ function setupModuleLoader(window) {
|
|
1834
1836
|
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
|
1835
1837
|
*/
|
1836
1838
|
var version = {
|
1837
|
-
full: '1.2.
|
1839
|
+
full: '1.2.13', // all of these placeholder strings will be replaced by grunt's
|
1838
1840
|
major: 1, // package task
|
1839
1841
|
minor: 2,
|
1840
|
-
dot:
|
1841
|
-
codeName: '
|
1842
|
+
dot: 13,
|
1843
|
+
codeName: 'romantic-transclusion'
|
1842
1844
|
};
|
1843
1845
|
|
1844
1846
|
|
@@ -2000,7 +2002,7 @@ function publishExternalAPI(angular){
|
|
2000
2002
|
* - [`after()`](http://api.jquery.com/after/)
|
2001
2003
|
* - [`append()`](http://api.jquery.com/append/)
|
2002
2004
|
* - [`attr()`](http://api.jquery.com/attr/)
|
2003
|
-
* - [`bind()`](http://api.jquery.com/
|
2005
|
+
* - [`bind()`](http://api.jquery.com/bind/) - Does not support namespaces, selectors or eventData
|
2004
2006
|
* - [`children()`](http://api.jquery.com/children/) - Does not support selectors
|
2005
2007
|
* - [`clone()`](http://api.jquery.com/clone/)
|
2006
2008
|
* - [`contents()`](http://api.jquery.com/contents/)
|
@@ -2027,7 +2029,7 @@ function publishExternalAPI(angular){
|
|
2027
2029
|
* - [`text()`](http://api.jquery.com/text/)
|
2028
2030
|
* - [`toggleClass()`](http://api.jquery.com/toggleClass/)
|
2029
2031
|
* - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers.
|
2030
|
-
* - [`unbind()`](http://api.jquery.com/
|
2032
|
+
* - [`unbind()`](http://api.jquery.com/unbind/) - Does not support namespaces
|
2031
2033
|
* - [`val()`](http://api.jquery.com/val/)
|
2032
2034
|
* - [`wrap()`](http://api.jquery.com/wrap/)
|
2033
2035
|
*
|
@@ -2067,6 +2069,14 @@ var jqCache = JQLite.cache = {},
|
|
2067
2069
|
? function(element, type, fn) {element.removeEventListener(type, fn, false); }
|
2068
2070
|
: function(element, type, fn) {element.detachEvent('on' + type, fn); });
|
2069
2071
|
|
2072
|
+
/*
|
2073
|
+
* !!! This is an undocumented "private" function !!!
|
2074
|
+
*/
|
2075
|
+
var jqData = JQLite._data = function(node) {
|
2076
|
+
//jQuery always returns an object on cache miss
|
2077
|
+
return this.cache[node[this.expando]] || {};
|
2078
|
+
};
|
2079
|
+
|
2070
2080
|
function jqNextId() { return ++jqId; }
|
2071
2081
|
|
2072
2082
|
|
@@ -2135,6 +2145,9 @@ function JQLite(element) {
|
|
2135
2145
|
if (element instanceof JQLite) {
|
2136
2146
|
return element;
|
2137
2147
|
}
|
2148
|
+
if (isString(element)) {
|
2149
|
+
element = trim(element);
|
2150
|
+
}
|
2138
2151
|
if (!(this instanceof JQLite)) {
|
2139
2152
|
if (isString(element) && element.charAt(0) != '<') {
|
2140
2153
|
throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');
|
@@ -3280,11 +3293,9 @@ function annotate(fn) {
|
|
3280
3293
|
* @param {(Object|function())} provider If the provider is:
|
3281
3294
|
*
|
3282
3295
|
* - `Object`: then it should have a `$get` method. The `$get` method will be invoked using
|
3283
|
-
*
|
3284
|
-
*
|
3285
|
-
*
|
3286
|
-
* {@link AUTO.$injector#instantiate $injector.instantiate()}, then treated as
|
3287
|
-
* `object`.
|
3296
|
+
* {@link AUTO.$injector#invoke $injector.invoke()} when an instance needs to be created.
|
3297
|
+
* - `Constructor`: a new instance of the provider will be created using
|
3298
|
+
* {@link AUTO.$injector#instantiate $injector.instantiate()}, then treated as `object`.
|
3288
3299
|
*
|
3289
3300
|
* @returns {Object} registered provider instance
|
3290
3301
|
|
@@ -3410,17 +3421,16 @@ function annotate(fn) {
|
|
3410
3421
|
* Here is an example of registering a service using
|
3411
3422
|
* {@link AUTO.$provide#methods_service $provide.service(class)}.
|
3412
3423
|
* <pre>
|
3413
|
-
*
|
3414
|
-
*
|
3415
|
-
*
|
3416
|
-
*
|
3417
|
-
*
|
3418
|
-
* Ping.prototype.send = function() {
|
3419
|
-
* return this.$http.get('/ping');
|
3420
|
-
* };
|
3424
|
+
* var Ping = function($http) {
|
3425
|
+
* this.$http = $http;
|
3426
|
+
* };
|
3427
|
+
*
|
3428
|
+
* Ping.$inject = ['$http'];
|
3421
3429
|
*
|
3422
|
-
*
|
3423
|
-
*
|
3430
|
+
* Ping.prototype.send = function() {
|
3431
|
+
* return this.$http.get('/ping');
|
3432
|
+
* };
|
3433
|
+
* $provide.service('ping', Ping);
|
3424
3434
|
* </pre>
|
3425
3435
|
* You would then inject and use this service like this:
|
3426
3436
|
* <pre>
|
@@ -3518,7 +3528,7 @@ function annotate(fn) {
|
|
3518
3528
|
* Here we decorate the {@link ng.$log $log} service to convert warnings to errors by intercepting
|
3519
3529
|
* calls to {@link ng.$log#error $log.warn()}.
|
3520
3530
|
* <pre>
|
3521
|
-
* $
|
3531
|
+
* $provide.decorator('$log', ['$delegate', function($delegate) {
|
3522
3532
|
* $delegate.warn = $delegate.error;
|
3523
3533
|
* return $delegate;
|
3524
3534
|
* }]);
|
@@ -4057,6 +4067,29 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4057
4067
|
done && $timeout(done, 0, false);
|
4058
4068
|
},
|
4059
4069
|
|
4070
|
+
/**
|
4071
|
+
*
|
4072
|
+
* @ngdoc function
|
4073
|
+
* @name ng.$animate#setClass
|
4074
|
+
* @methodOf ng.$animate
|
4075
|
+
* @function
|
4076
|
+
* @description Adds and/or removes the given CSS classes to and from the element.
|
4077
|
+
* Once complete, the done() callback will be fired (if provided).
|
4078
|
+
* @param {jQuery/jqLite element} element the element which will it's CSS classes changed
|
4079
|
+
* removed from it
|
4080
|
+
* @param {string} add the CSS classes which will be added to the element
|
4081
|
+
* @param {string} remove the CSS class which will be removed from the element
|
4082
|
+
* @param {function=} done the callback function (if provided) that will be fired after the
|
4083
|
+
* CSS classes have been set on the element
|
4084
|
+
*/
|
4085
|
+
setClass : function(element, add, remove, done) {
|
4086
|
+
forEach(element, function (element) {
|
4087
|
+
jqLiteAddClass(element, add);
|
4088
|
+
jqLiteRemoveClass(element, remove);
|
4089
|
+
});
|
4090
|
+
done && $timeout(done, 0, false);
|
4091
|
+
},
|
4092
|
+
|
4060
4093
|
enabled : noop
|
4061
4094
|
};
|
4062
4095
|
}];
|
@@ -5121,13 +5154,17 @@ function $TemplateCacheProvider() {
|
|
5121
5154
|
<div compile="html"></div>
|
5122
5155
|
</div>
|
5123
5156
|
</doc:source>
|
5124
|
-
<doc:
|
5157
|
+
<doc:protractor>
|
5125
5158
|
it('should auto compile', function() {
|
5126
|
-
|
5127
|
-
|
5128
|
-
|
5159
|
+
var textarea = $('textarea');
|
5160
|
+
var output = $('div[compile]');
|
5161
|
+
// The initial state reads 'Hello Angular'.
|
5162
|
+
expect(output.getText()).toBe('Hello Angular');
|
5163
|
+
textarea.clear();
|
5164
|
+
textarea.sendKeys('{{name}}!');
|
5165
|
+
expect(output.getText()).toBe('Angular!');
|
5129
5166
|
});
|
5130
|
-
</doc:
|
5167
|
+
</doc:protractor>
|
5131
5168
|
</doc:example>
|
5132
5169
|
|
5133
5170
|
*
|
@@ -5195,7 +5232,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
5195
5232
|
var hasDirectives = {},
|
5196
5233
|
Suffix = 'Directive',
|
5197
5234
|
COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,
|
5198
|
-
CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)
|
5235
|
+
CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/,
|
5236
|
+
TABLE_CONTENT_REGEXP = /^<\s*(tr|th|td|tbody)(\s+[^>]*)?>/i;
|
5199
5237
|
|
5200
5238
|
// Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes
|
5201
5239
|
// The assumption is that future DOM event attribute names will begin with
|
@@ -5382,8 +5420,16 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
5382
5420
|
* @param {string} oldClasses The former CSS className value
|
5383
5421
|
*/
|
5384
5422
|
$updateClass : function(newClasses, oldClasses) {
|
5385
|
-
|
5386
|
-
|
5423
|
+
var toAdd = tokenDifference(newClasses, oldClasses);
|
5424
|
+
var toRemove = tokenDifference(oldClasses, newClasses);
|
5425
|
+
|
5426
|
+
if(toAdd.length === 0) {
|
5427
|
+
$animate.removeClass(this.$$element, toRemove);
|
5428
|
+
} else if(toRemove.length === 0) {
|
5429
|
+
$animate.addClass(this.$$element, toAdd);
|
5430
|
+
} else {
|
5431
|
+
$animate.setClass(this.$$element, toAdd, toRemove);
|
5432
|
+
}
|
5387
5433
|
},
|
5388
5434
|
|
5389
5435
|
/**
|
@@ -5835,7 +5881,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
5835
5881
|
templateDirective = previousCompileContext.templateDirective,
|
5836
5882
|
nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective,
|
5837
5883
|
hasTranscludeDirective = false,
|
5838
|
-
hasElementTranscludeDirective =
|
5884
|
+
hasElementTranscludeDirective = previousCompileContext.hasElementTranscludeDirective,
|
5839
5885
|
$compileNode = templateAttrs.$$element = jqLite(compileNode),
|
5840
5886
|
directive,
|
5841
5887
|
directiveName,
|
@@ -5889,7 +5935,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
5889
5935
|
hasTranscludeDirective = true;
|
5890
5936
|
|
5891
5937
|
// Special case ngIf and ngRepeat so that we don't complain about duplicate transclusion.
|
5892
|
-
// This option should only be used by directives that know how to
|
5938
|
+
// This option should only be used by directives that know how to safely handle element transclusion,
|
5893
5939
|
// where the transcluded nodes are added or replaced after linking.
|
5894
5940
|
if (!directive.$$tlb) {
|
5895
5941
|
assertNoDuplicate('transclusion', nonTlbTranscludeDirective, directive, $compileNode);
|
@@ -5936,9 +5982,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
5936
5982
|
|
5937
5983
|
if (directive.replace) {
|
5938
5984
|
replaceDirective = directive;
|
5939
|
-
$template =
|
5940
|
-
trim(directiveValue) +
|
5941
|
-
'</div>').contents();
|
5985
|
+
$template = directiveTemplateContents(directiveValue);
|
5942
5986
|
compileNode = $template[0];
|
5943
5987
|
|
5944
5988
|
if ($template.length != 1 || compileNode.nodeType !== 1) {
|
@@ -6009,6 +6053,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6009
6053
|
|
6010
6054
|
nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true;
|
6011
6055
|
nodeLinkFn.transclude = hasTranscludeDirective && childTranscludeFn;
|
6056
|
+
previousCompileContext.hasElementTranscludeDirective = hasElementTranscludeDirective;
|
6012
6057
|
|
6013
6058
|
// might be normal or delayed nodeLinkFn depending on if templateUrl is present
|
6014
6059
|
return nodeLinkFn;
|
@@ -6336,6 +6381,28 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6336
6381
|
}
|
6337
6382
|
|
6338
6383
|
|
6384
|
+
function directiveTemplateContents(template) {
|
6385
|
+
var type;
|
6386
|
+
template = trim(template);
|
6387
|
+
if ((type = TABLE_CONTENT_REGEXP.exec(template))) {
|
6388
|
+
type = type[1].toLowerCase();
|
6389
|
+
var table = jqLite('<table>' + template + '</table>'),
|
6390
|
+
tbody = table.children('tbody'),
|
6391
|
+
leaf = /(td|th)/.test(type) && table.find('tr');
|
6392
|
+
if (tbody.length && type !== 'tbody') {
|
6393
|
+
table = tbody;
|
6394
|
+
}
|
6395
|
+
if (leaf && leaf.length) {
|
6396
|
+
table = leaf;
|
6397
|
+
}
|
6398
|
+
return table.contents();
|
6399
|
+
}
|
6400
|
+
return jqLite('<div>' +
|
6401
|
+
template +
|
6402
|
+
'</div>').contents();
|
6403
|
+
}
|
6404
|
+
|
6405
|
+
|
6339
6406
|
function compileTemplateUrl(directives, $compileNode, tAttrs,
|
6340
6407
|
$rootElement, childTranscludeFn, preLinkFns, postLinkFns, previousCompileContext) {
|
6341
6408
|
var linkQueue = [],
|
@@ -6360,7 +6427,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6360
6427
|
content = denormalizeTemplate(content);
|
6361
6428
|
|
6362
6429
|
if (origAsyncDirective.replace) {
|
6363
|
-
$template =
|
6430
|
+
$template = directiveTemplateContents(content);
|
6364
6431
|
compileNode = $template[0];
|
6365
6432
|
|
6366
6433
|
if ($template.length != 1 || compileNode.nodeType !== 1) {
|
@@ -6404,9 +6471,18 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6404
6471
|
linkNode = $compileNode[0];
|
6405
6472
|
|
6406
6473
|
if (beforeTemplateLinkNode !== beforeTemplateCompileNode) {
|
6407
|
-
|
6408
|
-
|
6474
|
+
var oldClasses = beforeTemplateLinkNode.className;
|
6475
|
+
|
6476
|
+
if (!(previousCompileContext.hasElementTranscludeDirective &&
|
6477
|
+
origAsyncDirective.replace)) {
|
6478
|
+
// it was cloned therefore we have to clone as well.
|
6479
|
+
linkNode = jqLiteClone(compileNode);
|
6480
|
+
}
|
6481
|
+
|
6409
6482
|
replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode);
|
6483
|
+
|
6484
|
+
// Copy in CSS classes from original node
|
6485
|
+
safeAddClass(jqLite(linkNode), oldClasses);
|
6410
6486
|
}
|
6411
6487
|
if (afterTemplateNodeLinkFn.transclude) {
|
6412
6488
|
childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude);
|
@@ -7063,31 +7139,14 @@ function $HttpProvider() {
|
|
7063
7139
|
* XMLHttpRequest will transparently follow it, meaning that the error callback will not be
|
7064
7140
|
* called for such responses.
|
7065
7141
|
*
|
7066
|
-
* # Calling $http from outside AngularJS
|
7067
|
-
* The `$http` service will not actually send the request until the next `$digest()` is
|
7068
|
-
* executed. Normally this is not an issue, since almost all the time your call to `$http` will
|
7069
|
-
* be from within a `$apply()` block.
|
7070
|
-
* If you are calling `$http` from outside Angular, then you should wrap it in a call to
|
7071
|
-
* `$apply` to cause a $digest to occur and also to handle errors in the block correctly.
|
7072
|
-
*
|
7073
|
-
* ```
|
7074
|
-
* $scope.$apply(function() {
|
7075
|
-
* $http(...);
|
7076
|
-
* });
|
7077
|
-
* ```
|
7078
|
-
*
|
7079
7142
|
* # Writing Unit Tests that use $http
|
7080
|
-
* When unit testing
|
7081
|
-
*
|
7082
|
-
*
|
7083
|
-
* code that calls the `$http()` method inside a $apply block as explained in the previous
|
7084
|
-
* section.
|
7143
|
+
* When unit testing (using {@link api/ngMock ngMock}), it is necessary to call
|
7144
|
+
* {@link api/ngMock.$httpBackend#methods_flush $httpBackend.flush()} to flush each pending
|
7145
|
+
* request using trained responses.
|
7085
7146
|
*
|
7086
7147
|
* ```
|
7087
7148
|
* $httpBackend.expectGET(...);
|
7088
|
-
* $
|
7089
|
-
* $http.get(...);
|
7090
|
-
* });
|
7149
|
+
* $http.get(...);
|
7091
7150
|
* $httpBackend.flush();
|
7092
7151
|
* ```
|
7093
7152
|
*
|
@@ -7444,14 +7503,14 @@ function $HttpProvider() {
|
|
7444
7503
|
<option>JSONP</option>
|
7445
7504
|
</select>
|
7446
7505
|
<input type="text" ng-model="url" size="80"/>
|
7447
|
-
<button ng-click="fetch()">fetch</button><br>
|
7448
|
-
<button ng-click="updateModel('GET', 'http-hello.html')">Sample GET</button>
|
7449
|
-
<button
|
7506
|
+
<button id="fetchbtn" ng-click="fetch()">fetch</button><br>
|
7507
|
+
<button id="samplegetbtn" ng-click="updateModel('GET', 'http-hello.html')">Sample GET</button>
|
7508
|
+
<button id="samplejsonpbtn"
|
7450
7509
|
ng-click="updateModel('JSONP',
|
7451
7510
|
'http://angularjs.org/greet.php?callback=JSON_CALLBACK&name=Super%20Hero')">
|
7452
7511
|
Sample JSONP
|
7453
7512
|
</button>
|
7454
|
-
<button
|
7513
|
+
<button id="invalidjsonpbtn"
|
7455
7514
|
ng-click="updateModel('JSONP', 'http://angularjs.org/doesntexist&callback=JSON_CALLBACK')">
|
7456
7515
|
Invalid JSONP
|
7457
7516
|
</button>
|
@@ -7488,27 +7547,34 @@ function $HttpProvider() {
|
|
7488
7547
|
<file name="http-hello.html">
|
7489
7548
|
Hello, $http!
|
7490
7549
|
</file>
|
7491
|
-
<file name="
|
7550
|
+
<file name="protractorTest.js">
|
7551
|
+
var status = element(by.binding('status'));
|
7552
|
+
var data = element(by.binding('data'));
|
7553
|
+
var fetchBtn = element(by.id('fetchbtn'));
|
7554
|
+
var sampleGetBtn = element(by.id('samplegetbtn'));
|
7555
|
+
var sampleJsonpBtn = element(by.id('samplejsonpbtn'));
|
7556
|
+
var invalidJsonpBtn = element(by.id('invalidjsonpbtn'));
|
7557
|
+
|
7492
7558
|
it('should make an xhr GET request', function() {
|
7493
|
-
|
7494
|
-
|
7495
|
-
expect(
|
7496
|
-
expect(
|
7559
|
+
sampleGetBtn.click();
|
7560
|
+
fetchBtn.click();
|
7561
|
+
expect(status.getText()).toMatch('200');
|
7562
|
+
expect(data.getText()).toMatch(/Hello, \$http!/)
|
7497
7563
|
});
|
7498
7564
|
|
7499
7565
|
it('should make a JSONP request to angularjs.org', function() {
|
7500
|
-
|
7501
|
-
|
7502
|
-
expect(
|
7503
|
-
expect(
|
7566
|
+
sampleJsonpBtn.click();
|
7567
|
+
fetchBtn.click();
|
7568
|
+
expect(status.getText()).toMatch('200');
|
7569
|
+
expect(data.getText()).toMatch(/Super Hero!/);
|
7504
7570
|
});
|
7505
7571
|
|
7506
7572
|
it('should make JSONP request to invalid URL and invoke the error handler',
|
7507
7573
|
function() {
|
7508
|
-
|
7509
|
-
|
7510
|
-
expect(
|
7511
|
-
expect(
|
7574
|
+
invalidJsonpBtn.click();
|
7575
|
+
fetchBtn.click();
|
7576
|
+
expect(status.getText()).toMatch('0');
|
7577
|
+
expect(data.getText()).toMatch('Request failed');
|
7512
7578
|
});
|
7513
7579
|
</file>
|
7514
7580
|
</example>
|
@@ -7890,13 +7956,18 @@ function $HttpProvider() {
|
|
7890
7956
|
}
|
7891
7957
|
|
7892
7958
|
function createXhr(method) {
|
7893
|
-
|
7894
|
-
|
7895
|
-
|
7896
|
-
|
7897
|
-
|
7898
|
-
|
7959
|
+
//if IE and the method is not RFC2616 compliant, or if XMLHttpRequest
|
7960
|
+
//is not available, try getting an ActiveXObject. Otherwise, use XMLHttpRequest
|
7961
|
+
//if it is available
|
7962
|
+
if (msie <= 8 && (!method.match(/^(get|post|head|put|delete|options)$/i) ||
|
7963
|
+
!window.XMLHttpRequest)) {
|
7964
|
+
return new window.ActiveXObject("Microsoft.XMLHTTP");
|
7965
|
+
} else if (window.XMLHttpRequest) {
|
7966
|
+
return new window.XMLHttpRequest();
|
7967
|
+
}
|
7899
7968
|
|
7969
|
+
throw minErr('$httpBackend')('noxhr', "This browser does not support XMLHttpRequest.");
|
7970
|
+
}
|
7900
7971
|
|
7901
7972
|
/**
|
7902
7973
|
* @ngdoc object
|
@@ -7991,7 +8062,20 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc
|
|
7991
8062
|
}
|
7992
8063
|
|
7993
8064
|
if (responseType) {
|
7994
|
-
|
8065
|
+
try {
|
8066
|
+
xhr.responseType = responseType;
|
8067
|
+
} catch (e) {
|
8068
|
+
// WebKit added support for the json responseType value on 09/03/2013
|
8069
|
+
// https://bugs.webkit.org/show_bug.cgi?id=73648. Versions of Safari prior to 7 are
|
8070
|
+
// known to throw when setting the value "json" as the response type. Other older
|
8071
|
+
// browsers implementing the responseType
|
8072
|
+
//
|
8073
|
+
// The json response type can be ignored if not supported, because JSON payloads are
|
8074
|
+
// parsed on the client-side regardless.
|
8075
|
+
if (responseType !== 'json') {
|
8076
|
+
throw e;
|
8077
|
+
}
|
8078
|
+
}
|
7995
8079
|
}
|
7996
8080
|
|
7997
8081
|
xhr.send(post || null);
|
@@ -8090,11 +8174,11 @@ var $interpolateMinErr = minErr('$interpolate');
|
|
8090
8174
|
//demo.label//
|
8091
8175
|
</div>
|
8092
8176
|
</doc:source>
|
8093
|
-
<doc:
|
8094
|
-
|
8095
|
-
|
8096
|
-
|
8097
|
-
</doc:
|
8177
|
+
<doc:protractor>
|
8178
|
+
it('should interpolate binding with custom symbols', function() {
|
8179
|
+
expect(element(by.binding('demo.label')).getText()).toBe('This binding is brought you by // interpolation symbols.');
|
8180
|
+
});
|
8181
|
+
</doc:protractor>
|
8098
8182
|
</doc:example>
|
8099
8183
|
*/
|
8100
8184
|
function $InterpolateProvider() {
|
@@ -8286,7 +8370,7 @@ function $InterpolateProvider() {
|
|
8286
8370
|
* @description
|
8287
8371
|
* Symbol to denote the end of expression in the interpolated string. Defaults to `}}`.
|
8288
8372
|
*
|
8289
|
-
* Use {@link ng.$interpolateProvider#
|
8373
|
+
* Use {@link ng.$interpolateProvider#methods_endSymbol $interpolateProvider#endSymbol} to change
|
8290
8374
|
* the symbol.
|
8291
8375
|
*
|
8292
8376
|
* @returns {string} start symbol.
|
@@ -8322,7 +8406,7 @@ function $IntervalProvider() {
|
|
8322
8406
|
* In tests you can use {@link ngMock.$interval#methods_flush `$interval.flush(millis)`} to
|
8323
8407
|
* move forward by `millis` milliseconds and trigger any functions scheduled to run in that
|
8324
8408
|
* time.
|
8325
|
-
*
|
8409
|
+
*
|
8326
8410
|
* <div class="alert alert-warning">
|
8327
8411
|
* **Note**: Intervals created by this service must be explicitly destroyed when you are finished
|
8328
8412
|
* with them. In particular they are not automatically destroyed when a controller's scope or a
|
@@ -8435,8 +8519,8 @@ function $IntervalProvider() {
|
|
8435
8519
|
promise = deferred.promise,
|
8436
8520
|
iteration = 0,
|
8437
8521
|
skipApply = (isDefined(invokeApply) && !invokeApply);
|
8438
|
-
|
8439
|
-
count = isDefined(count) ? count : 0
|
8522
|
+
|
8523
|
+
count = isDefined(count) ? count : 0;
|
8440
8524
|
|
8441
8525
|
promise.then(null, null, fn);
|
8442
8526
|
|
@@ -9130,7 +9214,7 @@ function $LocationProvider(){
|
|
9130
9214
|
* @eventType broadcast on root scope
|
9131
9215
|
* @description
|
9132
9216
|
* Broadcasted before a URL will change. This change can be prevented by calling
|
9133
|
-
* `preventDefault` method of the event. See {@link ng.$rootScope.Scope
|
9217
|
+
* `preventDefault` method of the event. See {@link ng.$rootScope.Scope#methods_$on} for more
|
9134
9218
|
* details about event object. Upon successful change
|
9135
9219
|
* {@link ng.$location#events_$locationChangeSuccess $locationChangeSuccess} is fired.
|
9136
9220
|
*
|
@@ -9313,7 +9397,7 @@ function $LogProvider(){
|
|
9313
9397
|
* @name ng.$logProvider#debugEnabled
|
9314
9398
|
* @methodOf ng.$logProvider
|
9315
9399
|
* @description
|
9316
|
-
* @param {
|
9400
|
+
* @param {boolean=} flag enable or disable debug level messages
|
9317
9401
|
* @returns {*} current value if used as getter or itself (chaining) if used as setter
|
9318
9402
|
*/
|
9319
9403
|
this.debugEnabled = function(flag) {
|
@@ -10136,7 +10220,7 @@ Parser.prototype = {
|
|
10136
10220
|
var getter = getterFn(field, this.options, this.text);
|
10137
10221
|
|
10138
10222
|
return extend(function(scope, locals, self) {
|
10139
|
-
return getter(self || object(scope, locals)
|
10223
|
+
return getter(self || object(scope, locals));
|
10140
10224
|
}, {
|
10141
10225
|
assign: function(scope, value, locals) {
|
10142
10226
|
return setter(object(scope, locals), field, value, parser.text, parser.options);
|
@@ -10712,9 +10796,9 @@ function $ParseProvider() {
|
|
10712
10796
|
* asynchronous programming what `try`, `catch` and `throw` keywords are to synchronous programming.
|
10713
10797
|
*
|
10714
10798
|
* <pre>
|
10715
|
-
* // for the purpose of this example let's assume that variables `$q` and `
|
10716
|
-
* // available in the current lexical scope (they could have been injected or passed in).
|
10717
|
-
*
|
10799
|
+
* // for the purpose of this example let's assume that variables `$q`, `scope` and `okToGreet`
|
10800
|
+
* // are available in the current lexical scope (they could have been injected or passed in).
|
10801
|
+
*
|
10718
10802
|
* function asyncGreet(name) {
|
10719
10803
|
* var deferred = $q.defer();
|
10720
10804
|
*
|
@@ -10769,7 +10853,7 @@ function $ParseProvider() {
|
|
10769
10853
|
* constructed via `$q.reject`, the promise will be rejected instead.
|
10770
10854
|
* - `reject(reason)` – rejects the derived promise with the `reason`. This is equivalent to
|
10771
10855
|
* resolving it with a rejection constructed via `$q.reject`.
|
10772
|
-
* - `notify(value)` - provides updates on the status of the
|
10856
|
+
* - `notify(value)` - provides updates on the status of the promise's execution. This may be called
|
10773
10857
|
* multiple times before the promise is either resolved or rejected.
|
10774
10858
|
*
|
10775
10859
|
* **Properties**
|
@@ -10919,7 +11003,7 @@ function qFactory(nextTick, exceptionHandler) {
|
|
10919
11003
|
|
10920
11004
|
|
10921
11005
|
reject: function(reason) {
|
10922
|
-
deferred.resolve(
|
11006
|
+
deferred.resolve(createInternalRejectedPromise(reason));
|
10923
11007
|
},
|
10924
11008
|
|
10925
11009
|
|
@@ -11076,6 +11160,12 @@ function qFactory(nextTick, exceptionHandler) {
|
|
11076
11160
|
* @returns {Promise} Returns a promise that was already resolved as rejected with the `reason`.
|
11077
11161
|
*/
|
11078
11162
|
var reject = function(reason) {
|
11163
|
+
var result = defer();
|
11164
|
+
result.reject(reason);
|
11165
|
+
return result.promise;
|
11166
|
+
};
|
11167
|
+
|
11168
|
+
var createInternalRejectedPromise = function(reason) {
|
11079
11169
|
return {
|
11080
11170
|
then: function(callback, errback) {
|
11081
11171
|
var result = defer();
|
@@ -12136,7 +12226,7 @@ function $RootScopeProvider(){
|
|
12136
12226
|
* onto the {@link ng.$exceptionHandler $exceptionHandler} service.
|
12137
12227
|
*
|
12138
12228
|
* @param {string} name Event name to emit.
|
12139
|
-
* @param {...*} args Optional
|
12229
|
+
* @param {...*} args Optional one or more arguments which will be passed onto the event listeners.
|
12140
12230
|
* @return {Object} Event object (see {@link ng.$rootScope.Scope#methods_$on}).
|
12141
12231
|
*/
|
12142
12232
|
$emit: function(name, args) {
|
@@ -12204,7 +12294,7 @@ function $RootScopeProvider(){
|
|
12204
12294
|
* onto the {@link ng.$exceptionHandler $exceptionHandler} service.
|
12205
12295
|
*
|
12206
12296
|
* @param {string} name Event name to broadcast.
|
12207
|
-
* @param {...*} args Optional
|
12297
|
+
* @param {...*} args Optional one or more arguments which will be passed onto the event listeners.
|
12208
12298
|
* @return {Object} Event object, see {@link ng.$rootScope.Scope#methods_$on}
|
12209
12299
|
*/
|
12210
12300
|
$broadcast: function(name, args) {
|
@@ -12647,7 +12737,7 @@ function $SceDelegateProvider() {
|
|
12647
12737
|
*
|
12648
12738
|
* @description
|
12649
12739
|
* Returns an object that is trusted by angular for use in specified strict
|
12650
|
-
* contextual escaping contexts (such as ng-
|
12740
|
+
* contextual escaping contexts (such as ng-bind-html, ng-include, any src
|
12651
12741
|
* attribute interpolation, any dom event binding attribute interpolation
|
12652
12742
|
* such as for onclick, etc.) that uses the provided value.
|
12653
12743
|
* See {@link ng.$sce $sce} for enabling strict contextual escaping.
|
@@ -12874,8 +12964,8 @@ function $SceDelegateProvider() {
|
|
12874
12964
|
* It's important to remember that SCE only applies to interpolation expressions.
|
12875
12965
|
*
|
12876
12966
|
* If your expressions are constant literals, they're automatically trusted and you don't need to
|
12877
|
-
* call `$sce.trustAs` on them
|
12878
|
-
* `<div ng-
|
12967
|
+
* call `$sce.trustAs` on them (remember to include the `ngSanitize` module) (e.g.
|
12968
|
+
* `<div ng-bind-html="'<b>implicitly trusted</b>'"></div>`) just works.
|
12879
12969
|
*
|
12880
12970
|
* Additionally, `a[href]` and `img[src]` automatically sanitize their URLs and do not pass them
|
12881
12971
|
* through {@link ng.$sce#methods_getTrusted $sce.getTrusted}. SCE doesn't play a role here.
|
@@ -12935,7 +13025,7 @@ function $SceDelegateProvider() {
|
|
12935
13025
|
* matched against the **entire** *normalized / absolute URL* of the resource being tested
|
12936
13026
|
* (even when the RegExp did not have the `^` and `$` codes.) In addition, any flags
|
12937
13027
|
* present on the RegExp (such as multiline, global, ignoreCase) are ignored.
|
12938
|
-
* - If you are generating your
|
13028
|
+
* - If you are generating your JavaScript from some other templating engine (not
|
12939
13029
|
* recommended, e.g. in issue [#4006](https://github.com/angular/angular.js/issues/4006)),
|
12940
13030
|
* remember to escape your regular expression (and be aware that you might need more than
|
12941
13031
|
* one level of escaping depending on your templating engine and the way you interpolated
|
@@ -12952,7 +13042,7 @@ function $SceDelegateProvider() {
|
|
12952
13042
|
* ## Show me an example using SCE.
|
12953
13043
|
*
|
12954
13044
|
* @example
|
12955
|
-
<example module="mySceApp">
|
13045
|
+
<example module="mySceApp" deps="angular-sanitize.js">
|
12956
13046
|
<file name="index.html">
|
12957
13047
|
<div ng-controller="myAppController as myCtrl">
|
12958
13048
|
<i ng-bind-html="myCtrl.explicitlyTrustedHtml" id="explicitlyTrustedHtml"></i><br><br>
|
@@ -12996,13 +13086,15 @@ function $SceDelegateProvider() {
|
|
12996
13086
|
]
|
12997
13087
|
</file>
|
12998
13088
|
|
12999
|
-
<file name="
|
13089
|
+
<file name="protractorTest.js">
|
13000
13090
|
describe('SCE doc demo', function() {
|
13001
13091
|
it('should sanitize untrusted values', function() {
|
13002
|
-
expect(element('.htmlComment').
|
13092
|
+
expect(element(by.css('.htmlComment')).getInnerHtml())
|
13093
|
+
.toBe('<span>Is <i>anyone</i> reading this?</span>');
|
13003
13094
|
});
|
13095
|
+
|
13004
13096
|
it('should NOT sanitize explicitly trusted values', function() {
|
13005
|
-
expect(element('
|
13097
|
+
expect(element(by.id('explicitlyTrustedHtml')).getInnerHtml()).toBe(
|
13006
13098
|
'<span onmouseover="this.textContent="Explicitly trusted HTML bypasses ' +
|
13007
13099
|
'sanitization."">Hover over this text.</span>');
|
13008
13100
|
});
|
@@ -13177,8 +13269,8 @@ function $SceProvider() {
|
|
13177
13269
|
*
|
13178
13270
|
* @description
|
13179
13271
|
* Delegates to {@link ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs`}. As such,
|
13180
|
-
* returns an
|
13181
|
-
* escaping contexts (such as ng-
|
13272
|
+
* returns an object that is trusted by angular for use in specified strict contextual
|
13273
|
+
* escaping contexts (such as ng-bind-html, ng-include, any src attribute
|
13182
13274
|
* interpolation, any dom event binding attribute interpolation such as for onclick, etc.)
|
13183
13275
|
* that uses the provided value. See * {@link ng.$sce $sce} for enabling strict contextual
|
13184
13276
|
* escaping.
|
@@ -13761,13 +13853,13 @@ function urlIsSameOrigin(requestUrl) {
|
|
13761
13853
|
<button ng-click="doGreeting(greeting)">ALERT</button>
|
13762
13854
|
</div>
|
13763
13855
|
</doc:source>
|
13764
|
-
<doc:
|
13856
|
+
<doc:protractor>
|
13765
13857
|
it('should display the greeting in the input box', function() {
|
13766
|
-
|
13858
|
+
element(by.model('greeting')).sendKeys('Hello, E2E Tests');
|
13767
13859
|
// If we click the button it will block the test runner
|
13768
13860
|
// element(':button').click();
|
13769
13861
|
});
|
13770
|
-
</doc:
|
13862
|
+
</doc:protractor>
|
13771
13863
|
</doc:example>
|
13772
13864
|
*/
|
13773
13865
|
function $WindowProvider(){
|
@@ -13976,35 +14068,47 @@ function $FilterProvider($provide) {
|
|
13976
14068
|
Equality <input type="checkbox" ng-model="strict"><br>
|
13977
14069
|
<table id="searchObjResults">
|
13978
14070
|
<tr><th>Name</th><th>Phone</th></tr>
|
13979
|
-
<tr ng-repeat="
|
13980
|
-
<td>{{
|
13981
|
-
<td>{{
|
14071
|
+
<tr ng-repeat="friendObj in friends | filter:search:strict">
|
14072
|
+
<td>{{friendObj.name}}</td>
|
14073
|
+
<td>{{friendObj.phone}}</td>
|
13982
14074
|
</tr>
|
13983
14075
|
</table>
|
13984
14076
|
</doc:source>
|
13985
|
-
<doc:
|
13986
|
-
|
13987
|
-
|
13988
|
-
|
13989
|
-
|
14077
|
+
<doc:protractor>
|
14078
|
+
var expectFriendNames = function(expectedNames, key) {
|
14079
|
+
element.all(by.repeater(key + ' in friends').column(key + '.name')).then(function(arr) {
|
14080
|
+
arr.forEach(function(wd, i) {
|
14081
|
+
expect(wd.getText()).toMatch(expectedNames[i]);
|
14082
|
+
});
|
14083
|
+
});
|
14084
|
+
};
|
13990
14085
|
|
13991
|
-
|
13992
|
-
|
13993
|
-
|
14086
|
+
it('should search across all fields when filtering with a string', function() {
|
14087
|
+
var searchText = element(by.model('searchText'));
|
14088
|
+
searchText.clear();
|
14089
|
+
searchText.sendKeys('m');
|
14090
|
+
expectFriendNames(['Mary', 'Mike', 'Adam'], 'friend');
|
14091
|
+
|
14092
|
+
searchText.clear();
|
14093
|
+
searchText.sendKeys('76');
|
14094
|
+
expectFriendNames(['John', 'Julie'], 'friend');
|
13994
14095
|
});
|
13995
14096
|
|
13996
14097
|
it('should search in specific fields when filtering with a predicate object', function() {
|
13997
|
-
|
13998
|
-
|
13999
|
-
|
14098
|
+
var searchAny = element(by.model('search.$'));
|
14099
|
+
searchAny.clear();
|
14100
|
+
searchAny.sendKeys('i');
|
14101
|
+
expectFriendNames(['Mary', 'Mike', 'Julie', 'Juliette'], 'friendObj');
|
14000
14102
|
});
|
14001
14103
|
it('should use a equal comparison when comparator is true', function() {
|
14002
|
-
|
14003
|
-
|
14004
|
-
|
14005
|
-
|
14104
|
+
var searchName = element(by.model('search.name'));
|
14105
|
+
var strict = element(by.model('strict'));
|
14106
|
+
searchName.clear();
|
14107
|
+
searchName.sendKeys('Julie');
|
14108
|
+
strict.click();
|
14109
|
+
expectFriendNames(['Julie'], 'friendObj');
|
14006
14110
|
});
|
14007
|
-
</doc:
|
14111
|
+
</doc:protractor>
|
14008
14112
|
</doc:example>
|
14009
14113
|
*/
|
14010
14114
|
function filterFilter() {
|
@@ -14030,6 +14134,15 @@ function filterFilter() {
|
|
14030
14134
|
};
|
14031
14135
|
} else {
|
14032
14136
|
comparator = function(obj, text) {
|
14137
|
+
if (obj && text && typeof obj === 'object' && typeof text === 'object') {
|
14138
|
+
for (var objKey in obj) {
|
14139
|
+
if (objKey.charAt(0) !== '$' && hasOwnProperty.call(obj, objKey) &&
|
14140
|
+
comparator(obj[objKey], text[objKey])) {
|
14141
|
+
return true;
|
14142
|
+
}
|
14143
|
+
}
|
14144
|
+
return false;
|
14145
|
+
}
|
14033
14146
|
text = (''+text).toLowerCase();
|
14034
14147
|
return (''+obj).toLowerCase().indexOf(text) > -1;
|
14035
14148
|
};
|
@@ -14082,7 +14195,7 @@ function filterFilter() {
|
|
14082
14195
|
(function(path) {
|
14083
14196
|
if (typeof expression[path] == 'undefined') return;
|
14084
14197
|
predicates.push(function(value) {
|
14085
|
-
return search(path == '$' ? value :
|
14198
|
+
return search(path == '$' ? value : (value && value[path]), expression[path]);
|
14086
14199
|
});
|
14087
14200
|
})(key);
|
14088
14201
|
}
|
@@ -14128,21 +14241,27 @@ function filterFilter() {
|
|
14128
14241
|
</script>
|
14129
14242
|
<div ng-controller="Ctrl">
|
14130
14243
|
<input type="number" ng-model="amount"> <br>
|
14131
|
-
default currency symbol ($): {{amount | currency}}
|
14132
|
-
custom currency identifier (USD$): {{amount | currency:"USD$"}}
|
14244
|
+
default currency symbol ($): <span id="currency-default">{{amount | currency}}</span><br>
|
14245
|
+
custom currency identifier (USD$): <span>{{amount | currency:"USD$"}}</span>
|
14133
14246
|
</div>
|
14134
14247
|
</doc:source>
|
14135
|
-
<doc:
|
14248
|
+
<doc:protractor>
|
14136
14249
|
it('should init with 1234.56', function() {
|
14137
|
-
expect(
|
14138
|
-
expect(binding('amount | currency:"USD$"')).toBe('USD$1,234.56');
|
14250
|
+
expect(element(by.id('currency-default')).getText()).toBe('$1,234.56');
|
14251
|
+
expect(element(by.binding('amount | currency:"USD$"')).getText()).toBe('USD$1,234.56');
|
14139
14252
|
});
|
14140
14253
|
it('should update', function() {
|
14141
|
-
|
14142
|
-
|
14143
|
-
|
14254
|
+
if (browser.params.browser == 'safari') {
|
14255
|
+
// Safari does not understand the minus key. See
|
14256
|
+
// https://github.com/angular/protractor/issues/481
|
14257
|
+
return;
|
14258
|
+
}
|
14259
|
+
element(by.model('amount')).clear();
|
14260
|
+
element(by.model('amount')).sendKeys('-1234');
|
14261
|
+
expect(element(by.id('currency-default')).getText()).toBe('($1,234.00)');
|
14262
|
+
expect(element(by.binding('amount | currency:"USD$"')).getText()).toBe('(USD$1,234.00)');
|
14144
14263
|
});
|
14145
|
-
</doc:
|
14264
|
+
</doc:protractor>
|
14146
14265
|
</doc:example>
|
14147
14266
|
*/
|
14148
14267
|
currencyFilter.$inject = ['$locale'];
|
@@ -14181,25 +14300,26 @@ function currencyFilter($locale) {
|
|
14181
14300
|
</script>
|
14182
14301
|
<div ng-controller="Ctrl">
|
14183
14302
|
Enter number: <input ng-model='val'><br>
|
14184
|
-
Default formatting: {{val | number}}
|
14185
|
-
No fractions: {{val | number:0}}
|
14186
|
-
Negative number: {{-val | number:4}}
|
14303
|
+
Default formatting: <span id='number-default'>{{val | number}}</span><br>
|
14304
|
+
No fractions: <span>{{val | number:0}}</span><br>
|
14305
|
+
Negative number: <span>{{-val | number:4}}</span>
|
14187
14306
|
</div>
|
14188
14307
|
</doc:source>
|
14189
|
-
<doc:
|
14308
|
+
<doc:protractor>
|
14190
14309
|
it('should format numbers', function() {
|
14191
|
-
expect(
|
14192
|
-
expect(binding('val | number:0')).toBe('1,235');
|
14193
|
-
expect(binding('-val | number:4')).toBe('-1,234.5679');
|
14310
|
+
expect(element(by.id('number-default')).getText()).toBe('1,234.568');
|
14311
|
+
expect(element(by.binding('val | number:0')).getText()).toBe('1,235');
|
14312
|
+
expect(element(by.binding('-val | number:4')).getText()).toBe('-1,234.5679');
|
14194
14313
|
});
|
14195
14314
|
|
14196
14315
|
it('should update', function() {
|
14197
|
-
|
14198
|
-
|
14199
|
-
expect(
|
14200
|
-
expect(binding('
|
14201
|
-
|
14202
|
-
|
14316
|
+
element(by.model('val')).clear();
|
14317
|
+
element(by.model('val')).sendKeys('3374.333');
|
14318
|
+
expect(element(by.id('number-default')).getText()).toBe('3,374.333');
|
14319
|
+
expect(element(by.binding('val | number:0')).getText()).toBe('3,374');
|
14320
|
+
expect(element(by.binding('-val | number:4')).getText()).toBe('-3,374.3330');
|
14321
|
+
});
|
14322
|
+
</doc:protractor>
|
14203
14323
|
</doc:example>
|
14204
14324
|
*/
|
14205
14325
|
|
@@ -14429,22 +14549,22 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
|
|
14429
14549
|
<doc:example>
|
14430
14550
|
<doc:source>
|
14431
14551
|
<span ng-non-bindable>{{1288323623006 | date:'medium'}}</span>:
|
14432
|
-
{{1288323623006 | date:'medium'}}
|
14552
|
+
<span>{{1288323623006 | date:'medium'}}</span><br>
|
14433
14553
|
<span ng-non-bindable>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span>:
|
14434
|
-
{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}
|
14554
|
+
<span>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span><br>
|
14435
14555
|
<span ng-non-bindable>{{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}</span>:
|
14436
|
-
{{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}
|
14556
|
+
<span>{{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}</span><br>
|
14437
14557
|
</doc:source>
|
14438
|
-
<doc:
|
14558
|
+
<doc:protractor>
|
14439
14559
|
it('should format date', function() {
|
14440
|
-
expect(binding("1288323623006 | date:'medium'")).
|
14560
|
+
expect(element(by.binding("1288323623006 | date:'medium'")).getText()).
|
14441
14561
|
toMatch(/Oct 2\d, 2010 \d{1,2}:\d{2}:\d{2} (AM|PM)/);
|
14442
|
-
expect(binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")).
|
14562
|
+
expect(element(by.binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")).getText()).
|
14443
14563
|
toMatch(/2010\-10\-2\d \d{2}:\d{2}:\d{2} (\-|\+)?\d{4}/);
|
14444
|
-
expect(binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")).
|
14564
|
+
expect(element(by.binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")).getText()).
|
14445
14565
|
toMatch(/10\/2\d\/2010 @ \d{1,2}:\d{2}(AM|PM)/);
|
14446
14566
|
});
|
14447
|
-
</doc:
|
14567
|
+
</doc:protractor>
|
14448
14568
|
</doc:example>
|
14449
14569
|
*/
|
14450
14570
|
dateFilter.$inject = ['$locale'];
|
@@ -14543,11 +14663,11 @@ function dateFilter($locale) {
|
|
14543
14663
|
<doc:source>
|
14544
14664
|
<pre>{{ {'name':'value'} | json }}</pre>
|
14545
14665
|
</doc:source>
|
14546
|
-
<doc:
|
14666
|
+
<doc:protractor>
|
14547
14667
|
it('should jsonify filtered objects', function() {
|
14548
|
-
expect(binding("{'name':'value'}")).toMatch(/\{\n "name": ?"value"\n}/);
|
14668
|
+
expect(element(by.binding("{'name':'value'}")).getText()).toMatch(/\{\n "name": ?"value"\n}/);
|
14549
14669
|
});
|
14550
|
-
</doc:
|
14670
|
+
</doc:protractor>
|
14551
14671
|
</doc:example>
|
14552
14672
|
*
|
14553
14673
|
*/
|
@@ -14615,28 +14735,37 @@ var uppercaseFilter = valueFn(uppercase);
|
|
14615
14735
|
<p>Output letters: {{ letters | limitTo:letterLimit }}</p>
|
14616
14736
|
</div>
|
14617
14737
|
</doc:source>
|
14618
|
-
<doc:
|
14738
|
+
<doc:protractor>
|
14739
|
+
var numLimitInput = element(by.model('numLimit'));
|
14740
|
+
var letterLimitInput = element(by.model('letterLimit'));
|
14741
|
+
var limitedNumbers = element(by.binding('numbers | limitTo:numLimit'));
|
14742
|
+
var limitedLetters = element(by.binding('letters | limitTo:letterLimit'));
|
14743
|
+
|
14619
14744
|
it('should limit the number array to first three items', function() {
|
14620
|
-
expect(
|
14621
|
-
expect(
|
14622
|
-
expect(
|
14623
|
-
expect(
|
14745
|
+
expect(numLimitInput.getAttribute('value')).toBe('3');
|
14746
|
+
expect(letterLimitInput.getAttribute('value')).toBe('3');
|
14747
|
+
expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3]');
|
14748
|
+
expect(limitedLetters.getText()).toEqual('Output letters: abc');
|
14624
14749
|
});
|
14625
14750
|
|
14626
14751
|
it('should update the output when -3 is entered', function() {
|
14627
|
-
|
14628
|
-
|
14629
|
-
|
14630
|
-
|
14752
|
+
numLimitInput.clear();
|
14753
|
+
numLimitInput.sendKeys('-3');
|
14754
|
+
letterLimitInput.clear();
|
14755
|
+
letterLimitInput.sendKeys('-3');
|
14756
|
+
expect(limitedNumbers.getText()).toEqual('Output numbers: [7,8,9]');
|
14757
|
+
expect(limitedLetters.getText()).toEqual('Output letters: ghi');
|
14631
14758
|
});
|
14632
14759
|
|
14633
14760
|
it('should not exceed the maximum size of input array', function() {
|
14634
|
-
|
14635
|
-
|
14636
|
-
|
14637
|
-
|
14761
|
+
numLimitInput.clear();
|
14762
|
+
numLimitInput.sendKeys('100');
|
14763
|
+
letterLimitInput.clear();
|
14764
|
+
letterLimitInput.sendKeys('100');
|
14765
|
+
expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3,4,5,6,7,8,9]');
|
14766
|
+
expect(limitedLetters.getText()).toEqual('Output letters: abcdefghi');
|
14638
14767
|
});
|
14639
|
-
</doc:
|
14768
|
+
</doc:protractor>
|
14640
14769
|
</doc:example>
|
14641
14770
|
*/
|
14642
14771
|
function limitToFilter(){
|
@@ -14737,29 +14866,6 @@ function limitToFilter(){
|
|
14737
14866
|
</table>
|
14738
14867
|
</div>
|
14739
14868
|
</doc:source>
|
14740
|
-
<doc:scenario>
|
14741
|
-
it('should be reverse ordered by aged', function() {
|
14742
|
-
expect(binding('predicate')).toBe('-age');
|
14743
|
-
expect(repeater('table.friend', 'friend in friends').column('friend.age')).
|
14744
|
-
toEqual(['35', '29', '21', '19', '10']);
|
14745
|
-
expect(repeater('table.friend', 'friend in friends').column('friend.name')).
|
14746
|
-
toEqual(['Adam', 'Julie', 'Mike', 'Mary', 'John']);
|
14747
|
-
});
|
14748
|
-
|
14749
|
-
it('should reorder the table when user selects different predicate', function() {
|
14750
|
-
element('.doc-example-live a:contains("Name")').click();
|
14751
|
-
expect(repeater('table.friend', 'friend in friends').column('friend.name')).
|
14752
|
-
toEqual(['Adam', 'John', 'Julie', 'Mary', 'Mike']);
|
14753
|
-
expect(repeater('table.friend', 'friend in friends').column('friend.age')).
|
14754
|
-
toEqual(['35', '10', '29', '19', '21']);
|
14755
|
-
|
14756
|
-
element('.doc-example-live a:contains("Phone")').click();
|
14757
|
-
expect(repeater('table.friend', 'friend in friends').column('friend.phone')).
|
14758
|
-
toEqual(['555-9876', '555-8765', '555-5678', '555-4321', '555-1212']);
|
14759
|
-
expect(repeater('table.friend', 'friend in friends').column('friend.name')).
|
14760
|
-
toEqual(['Mary', 'Julie', 'Adam', 'Mike', 'John']);
|
14761
|
-
});
|
14762
|
-
</doc:scenario>
|
14763
14869
|
</doc:example>
|
14764
14870
|
*/
|
14765
14871
|
orderByFilter.$inject = ['$parse'];
|
@@ -14856,11 +14962,14 @@ var htmlAnchorDirective = valueFn({
|
|
14856
14962
|
element.append(document.createComment('IE fix'));
|
14857
14963
|
}
|
14858
14964
|
|
14859
|
-
if (!attr.href && !attr.name) {
|
14965
|
+
if (!attr.href && !attr.xlinkHref && !attr.name) {
|
14860
14966
|
return function(scope, element) {
|
14967
|
+
// SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.
|
14968
|
+
var href = toString.call(element.prop('href')) === '[object SVGAnimatedString]' ?
|
14969
|
+
'xlink:href' : 'href';
|
14861
14970
|
element.on('click', function(event){
|
14862
14971
|
// if we have no href url, then don't navigate anywhere.
|
14863
|
-
if (!element.attr(
|
14972
|
+
if (!element.attr(href)) {
|
14864
14973
|
event.preventDefault();
|
14865
14974
|
}
|
14866
14975
|
});
|
@@ -14910,46 +15019,55 @@ var htmlAnchorDirective = valueFn({
|
|
14910
15019
|
<a id="link-5" name="xxx" ng-click="value = 5">anchor</a> (no link)<br />
|
14911
15020
|
<a id="link-6" ng-href="{{value}}">link</a> (link, change location)
|
14912
15021
|
</doc:source>
|
14913
|
-
<doc:
|
15022
|
+
<doc:protractor>
|
14914
15023
|
it('should execute ng-click but not reload when href without value', function() {
|
14915
|
-
element('
|
14916
|
-
expect(
|
14917
|
-
expect(element('
|
15024
|
+
element(by.id('link-1')).click();
|
15025
|
+
expect(element(by.model('value')).getAttribute('value')).toEqual('1');
|
15026
|
+
expect(element(by.id('link-1')).getAttribute('href')).toBe('');
|
14918
15027
|
});
|
14919
15028
|
|
14920
15029
|
it('should execute ng-click but not reload when href empty string', function() {
|
14921
|
-
element('
|
14922
|
-
expect(
|
14923
|
-
expect(element('
|
15030
|
+
element(by.id('link-2')).click();
|
15031
|
+
expect(element(by.model('value')).getAttribute('value')).toEqual('2');
|
15032
|
+
expect(element(by.id('link-2')).getAttribute('href')).toBe('');
|
14924
15033
|
});
|
14925
15034
|
|
14926
15035
|
it('should execute ng-click and change url when ng-href specified', function() {
|
14927
|
-
expect(element('
|
15036
|
+
expect(element(by.id('link-3')).getAttribute('href')).toMatch(/\/123$/);
|
15037
|
+
|
15038
|
+
element(by.id('link-3')).click();
|
14928
15039
|
|
14929
|
-
|
14930
|
-
|
15040
|
+
// At this point, we navigate away from an Angular page, so we need
|
15041
|
+
// to use browser.driver to get the base webdriver.
|
15042
|
+
|
15043
|
+
browser.wait(function() {
|
15044
|
+
return browser.driver.getCurrentUrl().then(function(url) {
|
15045
|
+
return url.match(/\/123$/);
|
15046
|
+
});
|
15047
|
+
}, 1000, 'page should navigate to /123');
|
14931
15048
|
});
|
14932
15049
|
|
14933
15050
|
it('should execute ng-click but not reload when href empty string and name specified', function() {
|
14934
|
-
element('
|
14935
|
-
expect(
|
14936
|
-
expect(element('
|
15051
|
+
element(by.id('link-4')).click();
|
15052
|
+
expect(element(by.model('value')).getAttribute('value')).toEqual('4');
|
15053
|
+
expect(element(by.id('link-4')).getAttribute('href')).toBe('');
|
14937
15054
|
});
|
14938
15055
|
|
14939
15056
|
it('should execute ng-click but not reload when no href but name specified', function() {
|
14940
|
-
element('
|
14941
|
-
expect(
|
14942
|
-
expect(element('
|
15057
|
+
element(by.id('link-5')).click();
|
15058
|
+
expect(element(by.model('value')).getAttribute('value')).toEqual('5');
|
15059
|
+
expect(element(by.id('link-5')).getAttribute('href')).toBe(null);
|
14943
15060
|
});
|
14944
15061
|
|
14945
15062
|
it('should only change url when only ng-href', function() {
|
14946
|
-
|
14947
|
-
|
15063
|
+
element(by.model('value')).clear();
|
15064
|
+
element(by.model('value')).sendKeys('6');
|
15065
|
+
expect(element(by.id('link-6')).getAttribute('href')).toMatch(/\/6$/);
|
14948
15066
|
|
14949
|
-
element('
|
14950
|
-
expect(browser
|
15067
|
+
element(by.id('link-6')).click();
|
15068
|
+
expect(browser.getCurrentUrl()).toMatch(/\/6$/);
|
14951
15069
|
});
|
14952
|
-
</doc:
|
15070
|
+
</doc:protractor>
|
14953
15071
|
</doc:example>
|
14954
15072
|
*/
|
14955
15073
|
|
@@ -15034,13 +15152,13 @@ var htmlAnchorDirective = valueFn({
|
|
15034
15152
|
Click me to toggle: <input type="checkbox" ng-model="checked"><br/>
|
15035
15153
|
<button ng-model="button" ng-disabled="checked">Button</button>
|
15036
15154
|
</doc:source>
|
15037
|
-
<doc:
|
15155
|
+
<doc:protractor>
|
15038
15156
|
it('should toggle button', function() {
|
15039
|
-
expect(element('.doc-example-live
|
15040
|
-
|
15041
|
-
expect(element('.doc-example-live
|
15157
|
+
expect(element(by.css('.doc-example-live button')).getAttribute('disabled')).toBeFalsy();
|
15158
|
+
element(by.model('checked')).click();
|
15159
|
+
expect(element(by.css('.doc-example-live button')).getAttribute('disabled')).toBeTruthy();
|
15042
15160
|
});
|
15043
|
-
</doc:
|
15161
|
+
</doc:protractor>
|
15044
15162
|
</doc:example>
|
15045
15163
|
*
|
15046
15164
|
* @element INPUT
|
@@ -15069,13 +15187,13 @@ var htmlAnchorDirective = valueFn({
|
|
15069
15187
|
Check me to check both: <input type="checkbox" ng-model="master"><br/>
|
15070
15188
|
<input id="checkSlave" type="checkbox" ng-checked="master">
|
15071
15189
|
</doc:source>
|
15072
|
-
<doc:
|
15190
|
+
<doc:protractor>
|
15073
15191
|
it('should check both checkBoxes', function() {
|
15074
|
-
expect(element('
|
15075
|
-
|
15076
|
-
expect(element('
|
15192
|
+
expect(element(by.id('checkSlave')).getAttribute('checked')).toBeFalsy();
|
15193
|
+
element(by.model('master')).click();
|
15194
|
+
expect(element(by.id('checkSlave')).getAttribute('checked')).toBeTruthy();
|
15077
15195
|
});
|
15078
|
-
</doc:
|
15196
|
+
</doc:protractor>
|
15079
15197
|
</doc:example>
|
15080
15198
|
*
|
15081
15199
|
* @element INPUT
|
@@ -15104,13 +15222,13 @@ var htmlAnchorDirective = valueFn({
|
|
15104
15222
|
Check me to make text readonly: <input type="checkbox" ng-model="checked"><br/>
|
15105
15223
|
<input type="text" ng-readonly="checked" value="I'm Angular"/>
|
15106
15224
|
</doc:source>
|
15107
|
-
<doc:
|
15225
|
+
<doc:protractor>
|
15108
15226
|
it('should toggle readonly attr', function() {
|
15109
|
-
expect(element('.doc-example-live
|
15110
|
-
|
15111
|
-
expect(element('.doc-example-live
|
15227
|
+
expect(element(by.css('.doc-example-live [type="text"]')).getAttribute('readonly')).toBeFalsy();
|
15228
|
+
element(by.model('checked')).click();
|
15229
|
+
expect(element(by.css('.doc-example-live [type="text"]')).getAttribute('readonly')).toBeTruthy();
|
15112
15230
|
});
|
15113
|
-
</doc:
|
15231
|
+
</doc:protractor>
|
15114
15232
|
</doc:example>
|
15115
15233
|
*
|
15116
15234
|
* @element INPUT
|
@@ -15143,13 +15261,13 @@ var htmlAnchorDirective = valueFn({
|
|
15143
15261
|
<option id="greet" ng-selected="selected">Greetings!</option>
|
15144
15262
|
</select>
|
15145
15263
|
</doc:source>
|
15146
|
-
<doc:
|
15264
|
+
<doc:protractor>
|
15147
15265
|
it('should select Greetings!', function() {
|
15148
|
-
expect(element('
|
15149
|
-
|
15150
|
-
expect(element('
|
15266
|
+
expect(element(by.id('greet')).getAttribute('selected')).toBeFalsy();
|
15267
|
+
element(by.model('selected')).click();
|
15268
|
+
expect(element(by.id('greet')).getAttribute('selected')).toBeTruthy();
|
15151
15269
|
});
|
15152
|
-
</doc:
|
15270
|
+
</doc:protractor>
|
15153
15271
|
</doc:example>
|
15154
15272
|
*
|
15155
15273
|
* @element OPTION
|
@@ -15179,13 +15297,13 @@ var htmlAnchorDirective = valueFn({
|
|
15179
15297
|
<summary>Show/Hide me</summary>
|
15180
15298
|
</details>
|
15181
15299
|
</doc:source>
|
15182
|
-
<doc:
|
15300
|
+
<doc:protractor>
|
15183
15301
|
it('should toggle open', function() {
|
15184
|
-
expect(element('
|
15185
|
-
|
15186
|
-
expect(element('
|
15302
|
+
expect(element(by.id('details')).getAttribute('open')).toBeFalsy();
|
15303
|
+
element(by.model('open')).click();
|
15304
|
+
expect(element(by.id('details')).getAttribute('open')).toBeTruthy();
|
15187
15305
|
});
|
15188
|
-
</doc:
|
15306
|
+
</doc:protractor>
|
15189
15307
|
</doc:example>
|
15190
15308
|
*
|
15191
15309
|
* @element DETAILS
|
@@ -15544,18 +15662,27 @@ function FormController(element, attrs) {
|
|
15544
15662
|
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br>
|
15545
15663
|
</form>
|
15546
15664
|
</doc:source>
|
15547
|
-
<doc:
|
15665
|
+
<doc:protractor>
|
15548
15666
|
it('should initialize to model', function() {
|
15549
|
-
|
15550
|
-
|
15667
|
+
var userType = element(by.binding('userType'));
|
15668
|
+
var valid = element(by.binding('myForm.input.$valid'));
|
15669
|
+
|
15670
|
+
expect(userType.getText()).toContain('guest');
|
15671
|
+
expect(valid.getText()).toContain('true');
|
15551
15672
|
});
|
15552
15673
|
|
15553
15674
|
it('should be invalid if empty', function() {
|
15554
|
-
|
15555
|
-
|
15556
|
-
|
15675
|
+
var userType = element(by.binding('userType'));
|
15676
|
+
var valid = element(by.binding('myForm.input.$valid'));
|
15677
|
+
var userInput = element(by.model('userType'));
|
15678
|
+
|
15679
|
+
userInput.clear();
|
15680
|
+
userInput.sendKeys('');
|
15681
|
+
|
15682
|
+
expect(userType.getText()).toEqual('userType =');
|
15683
|
+
expect(valid.getText()).toContain('false');
|
15557
15684
|
});
|
15558
|
-
</doc:
|
15685
|
+
</doc:protractor>
|
15559
15686
|
</doc:example>
|
15560
15687
|
*/
|
15561
15688
|
var formDirectiveFactory = function(isNgForm) {
|
@@ -15627,7 +15754,7 @@ var ngFormDirective = formDirectiveFactory(true);
|
|
15627
15754
|
*/
|
15628
15755
|
|
15629
15756
|
var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/;
|
15630
|
-
var EMAIL_REGEXP = /^[
|
15757
|
+
var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9-]+(\.[a-z0-9-]+)*$/i;
|
15631
15758
|
var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/;
|
15632
15759
|
|
15633
15760
|
var inputType = {
|
@@ -15680,29 +15807,31 @@ var inputType = {
|
|
15680
15807
|
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
|
15681
15808
|
</form>
|
15682
15809
|
</doc:source>
|
15683
|
-
<doc:
|
15810
|
+
<doc:protractor>
|
15811
|
+
var text = element(by.binding('text'));
|
15812
|
+
var valid = element(by.binding('myForm.input.$valid'));
|
15813
|
+
var input = element(by.model('text'));
|
15814
|
+
|
15684
15815
|
it('should initialize to model', function() {
|
15685
|
-
expect(
|
15686
|
-
expect(
|
15816
|
+
expect(text.getText()).toContain('guest');
|
15817
|
+
expect(valid.getText()).toContain('true');
|
15687
15818
|
});
|
15688
15819
|
|
15689
15820
|
it('should be invalid if empty', function() {
|
15690
|
-
input
|
15691
|
-
|
15692
|
-
|
15821
|
+
input.clear();
|
15822
|
+
input.sendKeys('');
|
15823
|
+
|
15824
|
+
expect(text.getText()).toEqual('text =');
|
15825
|
+
expect(valid.getText()).toContain('false');
|
15693
15826
|
});
|
15694
15827
|
|
15695
15828
|
it('should be invalid if multi word', function() {
|
15696
|
-
input
|
15697
|
-
|
15698
|
-
});
|
15829
|
+
input.clear();
|
15830
|
+
input.sendKeys('hello world');
|
15699
15831
|
|
15700
|
-
|
15701
|
-
input('text').enter('untrimmed ');
|
15702
|
-
expect(binding('text')).toEqual('untrimmed ');
|
15703
|
-
expect(binding('myForm.input.$valid')).toEqual('true');
|
15832
|
+
expect(valid.getText()).toContain('false');
|
15704
15833
|
});
|
15705
|
-
</doc:
|
15834
|
+
</doc:protractor>
|
15706
15835
|
</doc:example>
|
15707
15836
|
*/
|
15708
15837
|
'text': textInputType,
|
@@ -15756,24 +15885,30 @@ var inputType = {
|
|
15756
15885
|
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
|
15757
15886
|
</form>
|
15758
15887
|
</doc:source>
|
15759
|
-
<doc:
|
15888
|
+
<doc:protractor>
|
15889
|
+
var value = element(by.binding('value'));
|
15890
|
+
var valid = element(by.binding('myForm.input.$valid'));
|
15891
|
+
var input = element(by.model('value'));
|
15892
|
+
|
15760
15893
|
it('should initialize to model', function() {
|
15761
|
-
|
15762
|
-
|
15894
|
+
expect(value.getText()).toContain('12');
|
15895
|
+
expect(valid.getText()).toContain('true');
|
15763
15896
|
});
|
15764
15897
|
|
15765
15898
|
it('should be invalid if empty', function() {
|
15766
|
-
|
15767
|
-
|
15768
|
-
|
15899
|
+
input.clear();
|
15900
|
+
input.sendKeys('');
|
15901
|
+
expect(value.getText()).toEqual('value =');
|
15902
|
+
expect(valid.getText()).toContain('false');
|
15769
15903
|
});
|
15770
15904
|
|
15771
15905
|
it('should be invalid if over max', function() {
|
15772
|
-
|
15773
|
-
|
15774
|
-
|
15906
|
+
input.clear();
|
15907
|
+
input.sendKeys('123');
|
15908
|
+
expect(value.getText()).toEqual('value =');
|
15909
|
+
expect(valid.getText()).toContain('false');
|
15775
15910
|
});
|
15776
|
-
</doc:
|
15911
|
+
</doc:protractor>
|
15777
15912
|
</doc:example>
|
15778
15913
|
*/
|
15779
15914
|
'number': numberInputType,
|
@@ -15825,23 +15960,31 @@ var inputType = {
|
|
15825
15960
|
<tt>myForm.$error.url = {{!!myForm.$error.url}}</tt><br/>
|
15826
15961
|
</form>
|
15827
15962
|
</doc:source>
|
15828
|
-
<doc:
|
15963
|
+
<doc:protractor>
|
15964
|
+
var text = element(by.binding('text'));
|
15965
|
+
var valid = element(by.binding('myForm.input.$valid'));
|
15966
|
+
var input = element(by.model('text'));
|
15967
|
+
|
15829
15968
|
it('should initialize to model', function() {
|
15830
|
-
expect(
|
15831
|
-
expect(
|
15969
|
+
expect(text.getText()).toContain('http://google.com');
|
15970
|
+
expect(valid.getText()).toContain('true');
|
15832
15971
|
});
|
15833
15972
|
|
15834
15973
|
it('should be invalid if empty', function() {
|
15835
|
-
input
|
15836
|
-
|
15837
|
-
|
15974
|
+
input.clear();
|
15975
|
+
input.sendKeys('');
|
15976
|
+
|
15977
|
+
expect(text.getText()).toEqual('text =');
|
15978
|
+
expect(valid.getText()).toContain('false');
|
15838
15979
|
});
|
15839
15980
|
|
15840
15981
|
it('should be invalid if not url', function() {
|
15841
|
-
input
|
15842
|
-
|
15982
|
+
input.clear();
|
15983
|
+
input.sendKeys('box');
|
15984
|
+
|
15985
|
+
expect(valid.getText()).toContain('false');
|
15843
15986
|
});
|
15844
|
-
</doc:
|
15987
|
+
</doc:protractor>
|
15845
15988
|
</doc:example>
|
15846
15989
|
*/
|
15847
15990
|
'url': urlInputType,
|
@@ -15893,23 +16036,30 @@ var inputType = {
|
|
15893
16036
|
<tt>myForm.$error.email = {{!!myForm.$error.email}}</tt><br/>
|
15894
16037
|
</form>
|
15895
16038
|
</doc:source>
|
15896
|
-
<doc:
|
16039
|
+
<doc:protractor>
|
16040
|
+
var text = element(by.binding('text'));
|
16041
|
+
var valid = element(by.binding('myForm.input.$valid'));
|
16042
|
+
var input = element(by.model('text'));
|
16043
|
+
|
15897
16044
|
it('should initialize to model', function() {
|
15898
|
-
expect(
|
15899
|
-
expect(
|
16045
|
+
expect(text.getText()).toContain('me@example.com');
|
16046
|
+
expect(valid.getText()).toContain('true');
|
15900
16047
|
});
|
15901
16048
|
|
15902
16049
|
it('should be invalid if empty', function() {
|
15903
|
-
input
|
15904
|
-
|
15905
|
-
expect(
|
16050
|
+
input.clear();
|
16051
|
+
input.sendKeys('');
|
16052
|
+
expect(text.getText()).toEqual('text =');
|
16053
|
+
expect(valid.getText()).toContain('false');
|
15906
16054
|
});
|
15907
16055
|
|
15908
16056
|
it('should be invalid if not email', function() {
|
15909
|
-
input
|
15910
|
-
|
16057
|
+
input.clear();
|
16058
|
+
input.sendKeys('xxx');
|
16059
|
+
|
16060
|
+
expect(valid.getText()).toContain('false');
|
15911
16061
|
});
|
15912
|
-
</doc:
|
16062
|
+
</doc:protractor>
|
15913
16063
|
</doc:example>
|
15914
16064
|
*/
|
15915
16065
|
'email': emailInputType,
|
@@ -15927,6 +16077,8 @@ var inputType = {
|
|
15927
16077
|
* @param {string=} name Property name of the form under which the control is published.
|
15928
16078
|
* @param {string=} ngChange Angular expression to be executed when input changes due to user
|
15929
16079
|
* interaction with the input element.
|
16080
|
+
* @param {string} ngValue Angular expression which sets the value to which the expression should
|
16081
|
+
* be set when selected.
|
15930
16082
|
*
|
15931
16083
|
* @example
|
15932
16084
|
<doc:example>
|
@@ -15934,23 +16086,31 @@ var inputType = {
|
|
15934
16086
|
<script>
|
15935
16087
|
function Ctrl($scope) {
|
15936
16088
|
$scope.color = 'blue';
|
16089
|
+
$scope.specialValue = {
|
16090
|
+
"id": "12345",
|
16091
|
+
"value": "green"
|
16092
|
+
};
|
15937
16093
|
}
|
15938
16094
|
</script>
|
15939
16095
|
<form name="myForm" ng-controller="Ctrl">
|
15940
16096
|
<input type="radio" ng-model="color" value="red"> Red <br/>
|
15941
|
-
<input type="radio" ng-model="color" value="
|
16097
|
+
<input type="radio" ng-model="color" ng-value="specialValue"> Green <br/>
|
15942
16098
|
<input type="radio" ng-model="color" value="blue"> Blue <br/>
|
15943
|
-
<tt>color = {{color}}</tt><br/>
|
16099
|
+
<tt>color = {{color | json}}</tt><br/>
|
15944
16100
|
</form>
|
16101
|
+
Note that `ng-value="specialValue"` sets radio item's value to be the value of `$scope.specialValue`.
|
15945
16102
|
</doc:source>
|
15946
|
-
<doc:
|
16103
|
+
<doc:protractor>
|
15947
16104
|
it('should change state', function() {
|
15948
|
-
|
16105
|
+
var color = element(by.binding('color'));
|
16106
|
+
|
16107
|
+
expect(color.getText()).toContain('blue');
|
15949
16108
|
|
15950
|
-
|
15951
|
-
|
16109
|
+
element.all(by.model('color')).get(0).click();
|
16110
|
+
|
16111
|
+
expect(color.getText()).toContain('red');
|
15952
16112
|
});
|
15953
|
-
</doc:
|
16113
|
+
</doc:protractor>
|
15954
16114
|
</doc:example>
|
15955
16115
|
*/
|
15956
16116
|
'radio': radioInputType,
|
@@ -15987,17 +16147,21 @@ var inputType = {
|
|
15987
16147
|
<tt>value2 = {{value2}}</tt><br/>
|
15988
16148
|
</form>
|
15989
16149
|
</doc:source>
|
15990
|
-
<doc:
|
16150
|
+
<doc:protractor>
|
15991
16151
|
it('should change state', function() {
|
15992
|
-
|
15993
|
-
|
16152
|
+
var value1 = element(by.binding('value1'));
|
16153
|
+
var value2 = element(by.binding('value2'));
|
16154
|
+
|
16155
|
+
expect(value1.getText()).toContain('true');
|
16156
|
+
expect(value2.getText()).toContain('YES');
|
16157
|
+
|
16158
|
+
element(by.model('value1')).click();
|
16159
|
+
element(by.model('value2')).click();
|
15994
16160
|
|
15995
|
-
|
15996
|
-
|
15997
|
-
expect(binding('value1')).toEqual('false');
|
15998
|
-
expect(binding('value2')).toEqual('NO');
|
16161
|
+
expect(value1.getText()).toContain('false');
|
16162
|
+
expect(value2.getText()).toContain('NO');
|
15999
16163
|
});
|
16000
|
-
</doc:
|
16164
|
+
</doc:protractor>
|
16001
16165
|
</doc:example>
|
16002
16166
|
*/
|
16003
16167
|
'checkbox': checkboxInputType,
|
@@ -16005,7 +16169,8 @@ var inputType = {
|
|
16005
16169
|
'hidden': noop,
|
16006
16170
|
'button': noop,
|
16007
16171
|
'submit': noop,
|
16008
|
-
'reset': noop
|
16172
|
+
'reset': noop,
|
16173
|
+
'file': noop
|
16009
16174
|
};
|
16010
16175
|
|
16011
16176
|
// A helper function to call $setValidity and return the value / undefined,
|
@@ -16028,6 +16193,7 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
|
16028
16193
|
|
16029
16194
|
element.on('compositionend', function() {
|
16030
16195
|
composing = false;
|
16196
|
+
listener();
|
16031
16197
|
});
|
16032
16198
|
}
|
16033
16199
|
|
@@ -16350,44 +16516,59 @@ function checkboxInputType(scope, element, attr, ctrl) {
|
|
16350
16516
|
<tt>myForm.$error.maxlength = {{!!myForm.$error.maxlength}}</tt><br>
|
16351
16517
|
</div>
|
16352
16518
|
</doc:source>
|
16353
|
-
<doc:
|
16519
|
+
<doc:protractor>
|
16520
|
+
var user = element(by.binding('{{user}}'));
|
16521
|
+
var userNameValid = element(by.binding('myForm.userName.$valid'));
|
16522
|
+
var lastNameValid = element(by.binding('myForm.lastName.$valid'));
|
16523
|
+
var lastNameError = element(by.binding('myForm.lastName.$error'));
|
16524
|
+
var formValid = element(by.binding('myForm.$valid'));
|
16525
|
+
var userNameInput = element(by.model('user.name'));
|
16526
|
+
var userLastInput = element(by.model('user.last'));
|
16527
|
+
|
16354
16528
|
it('should initialize to model', function() {
|
16355
|
-
expect(
|
16356
|
-
expect(
|
16357
|
-
expect(
|
16529
|
+
expect(user.getText()).toContain('{"name":"guest","last":"visitor"}');
|
16530
|
+
expect(userNameValid.getText()).toContain('true');
|
16531
|
+
expect(formValid.getText()).toContain('true');
|
16358
16532
|
});
|
16359
16533
|
|
16360
16534
|
it('should be invalid if empty when required', function() {
|
16361
|
-
|
16362
|
-
|
16363
|
-
|
16364
|
-
expect(
|
16535
|
+
userNameInput.clear();
|
16536
|
+
userNameInput.sendKeys('');
|
16537
|
+
|
16538
|
+
expect(user.getText()).toContain('{"last":"visitor"}');
|
16539
|
+
expect(userNameValid.getText()).toContain('false');
|
16540
|
+
expect(formValid.getText()).toContain('false');
|
16365
16541
|
});
|
16366
16542
|
|
16367
16543
|
it('should be valid if empty when min length is set', function() {
|
16368
|
-
|
16369
|
-
|
16370
|
-
|
16371
|
-
expect(
|
16544
|
+
userLastInput.clear();
|
16545
|
+
userLastInput.sendKeys('');
|
16546
|
+
|
16547
|
+
expect(user.getText()).toContain('{"name":"guest","last":""}');
|
16548
|
+
expect(lastNameValid.getText()).toContain('true');
|
16549
|
+
expect(formValid.getText()).toContain('true');
|
16372
16550
|
});
|
16373
16551
|
|
16374
16552
|
it('should be invalid if less than required min length', function() {
|
16375
|
-
|
16376
|
-
|
16377
|
-
|
16378
|
-
expect(
|
16379
|
-
expect(
|
16553
|
+
userLastInput.clear();
|
16554
|
+
userLastInput.sendKeys('xx');
|
16555
|
+
|
16556
|
+
expect(user.getText()).toContain('{"name":"guest"}');
|
16557
|
+
expect(lastNameValid.getText()).toContain('false');
|
16558
|
+
expect(lastNameError.getText()).toContain('minlength');
|
16559
|
+
expect(formValid.getText()).toContain('false');
|
16380
16560
|
});
|
16381
16561
|
|
16382
16562
|
it('should be invalid if longer than max length', function() {
|
16383
|
-
|
16384
|
-
|
16385
|
-
|
16386
|
-
expect(
|
16387
|
-
expect(
|
16388
|
-
expect(
|
16563
|
+
userLastInput.clear();
|
16564
|
+
userLastInput.sendKeys('some ridiculously long name');
|
16565
|
+
|
16566
|
+
expect(user.getText()).toContain('{"name":"guest"}');
|
16567
|
+
expect(lastNameValid.getText()).toContain('false');
|
16568
|
+
expect(lastNameError.getText()).toContain('maxlength');
|
16569
|
+
expect(formValid.getText()).toContain('false');
|
16389
16570
|
});
|
16390
|
-
</doc:
|
16571
|
+
</doc:protractor>
|
16391
16572
|
</doc:example>
|
16392
16573
|
*/
|
16393
16574
|
var inputDirective = ['$browser', '$sniffer', function($browser, $sniffer) {
|
@@ -16519,14 +16700,23 @@ var VALID_CLASS = 'ng-valid',
|
|
16519
16700
|
<textarea ng-model="userContent"></textarea>
|
16520
16701
|
</form>
|
16521
16702
|
</file>
|
16522
|
-
<file name="
|
16703
|
+
<file name="protractorTest.js">
|
16523
16704
|
it('should data-bind and become invalid', function() {
|
16524
|
-
|
16705
|
+
if (browser.params.browser = 'safari') {
|
16706
|
+
// SafariDriver can't handle contenteditable.
|
16707
|
+
return;
|
16708
|
+
};
|
16709
|
+
var contentEditable = element(by.css('.doc-example-live [contenteditable]'));
|
16525
16710
|
|
16526
|
-
expect(contentEditable.
|
16527
|
-
|
16528
|
-
|
16529
|
-
|
16711
|
+
expect(contentEditable.getText()).toEqual('Change me!');
|
16712
|
+
|
16713
|
+
// Firefox driver doesn't trigger the proper events on 'clear', so do this hack
|
16714
|
+
contentEditable.click();
|
16715
|
+
contentEditable.sendKeys(protractor.Key.chord(protractor.Key.COMMAND, "a"));
|
16716
|
+
contentEditable.sendKeys(protractor.Key.BACK_SPACE);
|
16717
|
+
|
16718
|
+
expect(contentEditable.getText()).toEqual('');
|
16719
|
+
expect(contentEditable.getAttribute('class')).toMatch(/ng-invalid-required/);
|
16530
16720
|
});
|
16531
16721
|
</file>
|
16532
16722
|
* </example>
|
@@ -16579,6 +16769,9 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
16579
16769
|
* You can override this for input directives whose concept of being empty is different to the
|
16580
16770
|
* default. The `checkboxInputType` directive does this because in its case a value of `false`
|
16581
16771
|
* implies empty.
|
16772
|
+
*
|
16773
|
+
* @param {*} value Reference to check.
|
16774
|
+
* @returns {boolean} True if `value` is empty.
|
16582
16775
|
*/
|
16583
16776
|
this.$isEmpty = function(value) {
|
16584
16777
|
return isUndefined(value) || value === '' || value === null || value !== value;
|
@@ -16806,7 +16999,10 @@ var ngModelDirective = function() {
|
|
16806
16999
|
* @name ng.directive:ngChange
|
16807
17000
|
*
|
16808
17001
|
* @description
|
16809
|
-
* Evaluate given expression when user changes the input.
|
17002
|
+
* Evaluate the given expression when the user changes the input.
|
17003
|
+
* The expression is evaluated immediately, unlike the JavaScript onchange event
|
17004
|
+
* which only triggers at the end of a change (usually, when the user leaves the
|
17005
|
+
* form element or presses the return key).
|
16810
17006
|
* The expression is not evaluated when the value change is coming from the model.
|
16811
17007
|
*
|
16812
17008
|
* Note, this directive requires `ngModel` to be present.
|
@@ -16830,24 +17026,30 @@ var ngModelDirective = function() {
|
|
16830
17026
|
* <input type="checkbox" ng-model="confirmed" ng-change="change()" id="ng-change-example1" />
|
16831
17027
|
* <input type="checkbox" ng-model="confirmed" id="ng-change-example2" />
|
16832
17028
|
* <label for="ng-change-example2">Confirmed</label><br />
|
16833
|
-
* debug = {{confirmed}}
|
16834
|
-
* counter = {{counter}}
|
17029
|
+
* <tt>debug = {{confirmed}}</tt><br/>
|
17030
|
+
* <tt>counter = {{counter}}</tt><br/>
|
16835
17031
|
* </div>
|
16836
17032
|
* </doc:source>
|
16837
|
-
* <doc:
|
17033
|
+
* <doc:protractor>
|
17034
|
+
* var counter = element(by.binding('counter'));
|
17035
|
+
* var debug = element(by.binding('confirmed'));
|
17036
|
+
*
|
16838
17037
|
* it('should evaluate the expression if changing from view', function() {
|
16839
|
-
* expect(
|
16840
|
-
*
|
16841
|
-
*
|
16842
|
-
*
|
17038
|
+
* expect(counter.getText()).toContain('0');
|
17039
|
+
*
|
17040
|
+
* element(by.id('ng-change-example1')).click();
|
17041
|
+
*
|
17042
|
+
* expect(counter.getText()).toContain('1');
|
17043
|
+
* expect(debug.getText()).toContain('true');
|
16843
17044
|
* });
|
16844
17045
|
*
|
16845
17046
|
* it('should not evaluate the expression if changing from model', function() {
|
16846
|
-
* element('
|
16847
|
-
|
16848
|
-
* expect(
|
17047
|
+
* element(by.id('ng-change-example2')).click();
|
17048
|
+
|
17049
|
+
* expect(counter.getText()).toContain('0');
|
17050
|
+
* expect(debug.getText()).toContain('true');
|
16849
17051
|
* });
|
16850
|
-
* </doc:
|
17052
|
+
* </doc:protractor>
|
16851
17053
|
* </doc:example>
|
16852
17054
|
*/
|
16853
17055
|
var ngChangeDirective = valueFn({
|
@@ -16920,20 +17122,26 @@ var requiredDirective = function() {
|
|
16920
17122
|
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
|
16921
17123
|
</form>
|
16922
17124
|
</doc:source>
|
16923
|
-
<doc:
|
17125
|
+
<doc:protractor>
|
17126
|
+
var listInput = element(by.model('names'));
|
17127
|
+
var names = element(by.binding('{{names}}'));
|
17128
|
+
var valid = element(by.binding('myForm.namesInput.$valid'));
|
17129
|
+
var error = element(by.css('span.error'));
|
17130
|
+
|
16924
17131
|
it('should initialize to model', function() {
|
16925
|
-
expect(
|
16926
|
-
expect(
|
16927
|
-
expect(
|
17132
|
+
expect(names.getText()).toContain('["igor","misko","vojta"]');
|
17133
|
+
expect(valid.getText()).toContain('true');
|
17134
|
+
expect(error.getCssValue('display')).toBe('none');
|
16928
17135
|
});
|
16929
17136
|
|
16930
17137
|
it('should be invalid if empty', function() {
|
16931
|
-
|
16932
|
-
|
16933
|
-
|
16934
|
-
expect(
|
16935
|
-
|
16936
|
-
|
17138
|
+
listInput.clear();
|
17139
|
+
listInput.sendKeys('');
|
17140
|
+
|
17141
|
+
expect(names.getText()).toContain('');
|
17142
|
+
expect(valid.getText()).toContain('false');
|
17143
|
+
expect(error.getCssValue('display')).not.toBe('none'); });
|
17144
|
+
</doc:protractor>
|
16937
17145
|
</doc:example>
|
16938
17146
|
*/
|
16939
17147
|
var ngListDirective = function() {
|
@@ -17015,15 +17223,17 @@ var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
|
|
17015
17223
|
<div>You chose {{my.favorite}}</div>
|
17016
17224
|
</form>
|
17017
17225
|
</doc:source>
|
17018
|
-
<doc:
|
17226
|
+
<doc:protractor>
|
17227
|
+
var favorite = element(by.binding('my.favorite'));
|
17228
|
+
|
17019
17229
|
it('should initialize to model', function() {
|
17020
|
-
expect(
|
17230
|
+
expect(favorite.getText()).toContain('unicorns');
|
17021
17231
|
});
|
17022
17232
|
it('should bind the values to the inputs', function() {
|
17023
|
-
|
17024
|
-
expect(
|
17233
|
+
element.all(by.model('my.favorite')).get(0).click();
|
17234
|
+
expect(favorite.getText()).toContain('pizza');
|
17025
17235
|
});
|
17026
|
-
</doc:
|
17236
|
+
</doc:protractor>
|
17027
17237
|
</doc:example>
|
17028
17238
|
*/
|
17029
17239
|
var ngValueDirective = function() {
|
@@ -17083,13 +17293,17 @@ var ngValueDirective = function() {
|
|
17083
17293
|
Hello <span ng-bind="name"></span>!
|
17084
17294
|
</div>
|
17085
17295
|
</doc:source>
|
17086
|
-
<doc:
|
17296
|
+
<doc:protractor>
|
17087
17297
|
it('should check ng-bind', function() {
|
17088
|
-
|
17089
|
-
|
17090
|
-
|
17298
|
+
var exampleContainer = $('.doc-example-live');
|
17299
|
+
var nameInput = element(by.model('name'));
|
17300
|
+
|
17301
|
+
expect(exampleContainer.findElement(by.binding('name')).getText()).toBe('Whirled');
|
17302
|
+
nameInput.clear();
|
17303
|
+
nameInput.sendKeys('world');
|
17304
|
+
expect(exampleContainer.findElement(by.binding('name')).getText()).toBe('world');
|
17091
17305
|
});
|
17092
|
-
</doc:
|
17306
|
+
</doc:protractor>
|
17093
17307
|
</doc:example>
|
17094
17308
|
*/
|
17095
17309
|
var ngBindDirective = ngDirective(function(scope, element, attr) {
|
@@ -17135,20 +17349,22 @@ var ngBindDirective = ngDirective(function(scope, element, attr) {
|
|
17135
17349
|
<pre ng-bind-template="{{salutation}} {{name}}!"></pre>
|
17136
17350
|
</div>
|
17137
17351
|
</doc:source>
|
17138
|
-
<doc:
|
17352
|
+
<doc:protractor>
|
17139
17353
|
it('should check ng-bind', function() {
|
17140
|
-
|
17141
|
-
|
17142
|
-
|
17143
|
-
|
17144
|
-
|
17145
|
-
|
17146
|
-
|
17147
|
-
|
17148
|
-
|
17149
|
-
|
17354
|
+
var salutationElem = element(by.binding('salutation'));
|
17355
|
+
var salutationInput = element(by.model('salutation'));
|
17356
|
+
var nameInput = element(by.model('name'));
|
17357
|
+
|
17358
|
+
expect(salutationElem.getText()).toBe('Hello World!');
|
17359
|
+
|
17360
|
+
salutationInput.clear();
|
17361
|
+
salutationInput.sendKeys('Greetings');
|
17362
|
+
nameInput.clear();
|
17363
|
+
nameInput.sendKeys('user');
|
17364
|
+
|
17365
|
+
expect(salutationElem.getText()).toBe('Greetings user!');
|
17150
17366
|
});
|
17151
|
-
</doc:
|
17367
|
+
</doc:protractor>
|
17152
17368
|
</doc:example>
|
17153
17369
|
*/
|
17154
17370
|
var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
|
@@ -17201,12 +17417,10 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
|
|
17201
17417
|
}]);
|
17202
17418
|
</file>
|
17203
17419
|
|
17204
|
-
<file name="
|
17420
|
+
<file name="protractorTest.js">
|
17205
17421
|
it('should check ng-bind-html', function() {
|
17206
|
-
expect(
|
17207
|
-
|
17208
|
-
'I am an <code>HTML</code>string with <a href="#">links!</a> and other <em>stuff</em>'
|
17209
|
-
);
|
17422
|
+
expect(element(by.binding('myHTML')).getText()).toBe(
|
17423
|
+
'I am an HTMLstring with links! and other stuff');
|
17210
17424
|
});
|
17211
17425
|
</file>
|
17212
17426
|
</example>
|
@@ -17338,31 +17552,34 @@ function classDirective(name, selector) {
|
|
17338
17552
|
color: red;
|
17339
17553
|
}
|
17340
17554
|
</file>
|
17341
|
-
<file name="
|
17555
|
+
<file name="protractorTest.js">
|
17556
|
+
var ps = element.all(by.css('.doc-example-live p'));
|
17557
|
+
|
17342
17558
|
it('should let you toggle the class', function() {
|
17343
17559
|
|
17344
|
-
expect(
|
17345
|
-
expect(
|
17560
|
+
expect(ps.first().getAttribute('class')).not.toMatch(/bold/);
|
17561
|
+
expect(ps.first().getAttribute('class')).not.toMatch(/red/);
|
17346
17562
|
|
17347
|
-
|
17348
|
-
expect(
|
17563
|
+
element(by.model('important')).click();
|
17564
|
+
expect(ps.first().getAttribute('class')).toMatch(/bold/);
|
17349
17565
|
|
17350
|
-
|
17351
|
-
expect(
|
17566
|
+
element(by.model('error')).click();
|
17567
|
+
expect(ps.first().getAttribute('class')).toMatch(/red/);
|
17352
17568
|
});
|
17353
17569
|
|
17354
17570
|
it('should let you toggle string example', function() {
|
17355
|
-
expect(
|
17356
|
-
|
17357
|
-
|
17571
|
+
expect(ps.get(1).getAttribute('class')).toBe('');
|
17572
|
+
element(by.model('style')).clear();
|
17573
|
+
element(by.model('style')).sendKeys('red');
|
17574
|
+
expect(ps.get(1).getAttribute('class')).toBe('red');
|
17358
17575
|
});
|
17359
17576
|
|
17360
17577
|
it('array example should have 3 classes', function() {
|
17361
|
-
expect(
|
17362
|
-
|
17363
|
-
|
17364
|
-
|
17365
|
-
expect(
|
17578
|
+
expect(ps.last().getAttribute('class')).toBe('');
|
17579
|
+
element(by.model('style1')).sendKeys('bold');
|
17580
|
+
element(by.model('style2')).sendKeys('strike');
|
17581
|
+
element(by.model('style3')).sendKeys('red');
|
17582
|
+
expect(ps.last().getAttribute('class')).toBe('bold strike red');
|
17366
17583
|
});
|
17367
17584
|
</file>
|
17368
17585
|
</example>
|
@@ -17373,8 +17590,8 @@ function classDirective(name, selector) {
|
|
17373
17590
|
|
17374
17591
|
<example animations="true">
|
17375
17592
|
<file name="index.html">
|
17376
|
-
<input type="button" value="set" ng-click="myVar='my-class'">
|
17377
|
-
<input type="button" value="clear" ng-click="myVar=''">
|
17593
|
+
<input id="setbtn" type="button" value="set" ng-click="myVar='my-class'">
|
17594
|
+
<input id="clearbtn" type="button" value="clear" ng-click="myVar=''">
|
17378
17595
|
<br>
|
17379
17596
|
<span class="base-class" ng-class="myVar">Sample Text</span>
|
17380
17597
|
</file>
|
@@ -17389,19 +17606,19 @@ function classDirective(name, selector) {
|
|
17389
17606
|
font-size:3em;
|
17390
17607
|
}
|
17391
17608
|
</file>
|
17392
|
-
<file name="
|
17609
|
+
<file name="protractorTest.js">
|
17393
17610
|
it('should check ng-class', function() {
|
17394
|
-
expect(element('.
|
17611
|
+
expect(element(by.css('.base-class')).getAttribute('class')).not.
|
17395
17612
|
toMatch(/my-class/);
|
17396
17613
|
|
17397
|
-
|
17614
|
+
element(by.id('setbtn')).click();
|
17398
17615
|
|
17399
|
-
expect(element('.
|
17616
|
+
expect(element(by.css('.base-class')).getAttribute('class')).
|
17400
17617
|
toMatch(/my-class/);
|
17401
17618
|
|
17402
|
-
|
17619
|
+
element(by.id('clearbtn')).click();
|
17403
17620
|
|
17404
|
-
expect(element('.
|
17621
|
+
expect(element(by.css('.base-class')).getAttribute('class')).not.
|
17405
17622
|
toMatch(/my-class/);
|
17406
17623
|
});
|
17407
17624
|
</file>
|
@@ -17453,11 +17670,11 @@ var ngClassDirective = classDirective('', true);
|
|
17453
17670
|
color: blue;
|
17454
17671
|
}
|
17455
17672
|
</file>
|
17456
|
-
<file name="
|
17673
|
+
<file name="protractorTest.js">
|
17457
17674
|
it('should check ng-class-odd and ng-class-even', function() {
|
17458
|
-
expect(element('
|
17675
|
+
expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).
|
17459
17676
|
toMatch(/odd/);
|
17460
|
-
expect(element('
|
17677
|
+
expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).
|
17461
17678
|
toMatch(/even/);
|
17462
17679
|
});
|
17463
17680
|
</file>
|
@@ -17501,11 +17718,11 @@ var ngClassOddDirective = classDirective('Odd', 0);
|
|
17501
17718
|
color: blue;
|
17502
17719
|
}
|
17503
17720
|
</file>
|
17504
|
-
<file name="
|
17721
|
+
<file name="protractorTest.js">
|
17505
17722
|
it('should check ng-class-odd and ng-class-even', function() {
|
17506
|
-
expect(element('
|
17723
|
+
expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).
|
17507
17724
|
toMatch(/odd/);
|
17508
|
-
expect(element('
|
17725
|
+
expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).
|
17509
17726
|
toMatch(/even/);
|
17510
17727
|
});
|
17511
17728
|
</file>
|
@@ -17558,14 +17775,14 @@ var ngClassEvenDirective = classDirective('Even', 1);
|
|
17558
17775
|
<div id="template1" ng-cloak>{{ 'hello' }}</div>
|
17559
17776
|
<div id="template2" ng-cloak class="ng-cloak">{{ 'hello IE7' }}</div>
|
17560
17777
|
</doc:source>
|
17561
|
-
<doc:
|
17778
|
+
<doc:protractor>
|
17562
17779
|
it('should remove the template directive and css class', function() {
|
17563
|
-
expect(
|
17564
|
-
|
17565
|
-
expect(
|
17566
|
-
|
17780
|
+
expect($('.doc-example-live #template1').getAttribute('ng-cloak')).
|
17781
|
+
toBeNull();
|
17782
|
+
expect($('.doc-example-live #template2').getAttribute('ng-cloak')).
|
17783
|
+
toBeNull();
|
17567
17784
|
});
|
17568
|
-
</doc:
|
17785
|
+
</doc:protractor>
|
17569
17786
|
</doc:example>
|
17570
17787
|
*
|
17571
17788
|
*/
|
@@ -17658,22 +17875,36 @@ var ngCloakDirective = ngDirective({
|
|
17658
17875
|
</ul>
|
17659
17876
|
</div>
|
17660
17877
|
</doc:source>
|
17661
|
-
<doc:
|
17878
|
+
<doc:protractor>
|
17662
17879
|
it('should check controller as', function() {
|
17663
|
-
|
17664
|
-
|
17665
|
-
|
17666
|
-
|
17667
|
-
|
17668
|
-
|
17669
|
-
|
17670
|
-
|
17671
|
-
|
17672
|
-
|
17673
|
-
expect(
|
17674
|
-
|
17880
|
+
var container = element(by.id('ctrl-as-exmpl'));
|
17881
|
+
|
17882
|
+
expect(container.findElement(by.model('settings.name'))
|
17883
|
+
.getAttribute('value')).toBe('John Smith');
|
17884
|
+
|
17885
|
+
var firstRepeat =
|
17886
|
+
container.findElement(by.repeater('contact in settings.contacts').row(0));
|
17887
|
+
var secondRepeat =
|
17888
|
+
container.findElement(by.repeater('contact in settings.contacts').row(1));
|
17889
|
+
|
17890
|
+
expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
|
17891
|
+
.toBe('408 555 1212');
|
17892
|
+
expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value'))
|
17893
|
+
.toBe('john.smith@example.org');
|
17894
|
+
|
17895
|
+
firstRepeat.findElement(by.linkText('clear')).click()
|
17896
|
+
|
17897
|
+
expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
|
17898
|
+
.toBe('');
|
17899
|
+
|
17900
|
+
container.findElement(by.linkText('add')).click();
|
17901
|
+
|
17902
|
+
expect(container.findElement(by.repeater('contact in settings.contacts').row(2))
|
17903
|
+
.findElement(by.model('contact.value'))
|
17904
|
+
.getAttribute('value'))
|
17905
|
+
.toBe('yourname@example.org');
|
17675
17906
|
});
|
17676
|
-
</doc:
|
17907
|
+
</doc:protractor>
|
17677
17908
|
</doc:example>
|
17678
17909
|
<doc:example>
|
17679
17910
|
<doc:source>
|
@@ -17721,22 +17952,36 @@ var ngCloakDirective = ngDirective({
|
|
17721
17952
|
</ul>
|
17722
17953
|
</div>
|
17723
17954
|
</doc:source>
|
17724
|
-
<doc:
|
17955
|
+
<doc:protractor>
|
17725
17956
|
it('should check controller', function() {
|
17726
|
-
|
17727
|
-
|
17728
|
-
|
17729
|
-
|
17730
|
-
|
17731
|
-
|
17732
|
-
|
17733
|
-
|
17734
|
-
|
17735
|
-
|
17736
|
-
expect(
|
17737
|
-
|
17957
|
+
var container = element(by.id('ctrl-exmpl'));
|
17958
|
+
|
17959
|
+
expect(container.findElement(by.model('name'))
|
17960
|
+
.getAttribute('value')).toBe('John Smith');
|
17961
|
+
|
17962
|
+
var firstRepeat =
|
17963
|
+
container.findElement(by.repeater('contact in contacts').row(0));
|
17964
|
+
var secondRepeat =
|
17965
|
+
container.findElement(by.repeater('contact in contacts').row(1));
|
17966
|
+
|
17967
|
+
expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
|
17968
|
+
.toBe('408 555 1212');
|
17969
|
+
expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value'))
|
17970
|
+
.toBe('john.smith@example.org');
|
17971
|
+
|
17972
|
+
firstRepeat.findElement(by.linkText('clear')).click()
|
17973
|
+
|
17974
|
+
expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
|
17975
|
+
.toBe('');
|
17976
|
+
|
17977
|
+
container.findElement(by.linkText('add')).click();
|
17978
|
+
|
17979
|
+
expect(container.findElement(by.repeater('contact in contacts').row(2))
|
17980
|
+
.findElement(by.model('contact.value'))
|
17981
|
+
.getAttribute('value'))
|
17982
|
+
.toBe('yourname@example.org');
|
17738
17983
|
});
|
17739
|
-
</doc:
|
17984
|
+
</doc:protractor>
|
17740
17985
|
</doc:example>
|
17741
17986
|
|
17742
17987
|
*/
|
@@ -17799,6 +18044,7 @@ var ngControllerDirective = [function() {
|
|
17799
18044
|
* an element is clicked.
|
17800
18045
|
*
|
17801
18046
|
* @element ANY
|
18047
|
+
* @priority 0
|
17802
18048
|
* @param {expression} ngClick {@link guide/expression Expression} to evaluate upon
|
17803
18049
|
* click. (Event object is available as `$event`)
|
17804
18050
|
*
|
@@ -17855,6 +18101,7 @@ forEach(
|
|
17855
18101
|
* The `ngDblclick` directive allows you to specify custom behavior on a dblclick event.
|
17856
18102
|
*
|
17857
18103
|
* @element ANY
|
18104
|
+
* @priority 0
|
17858
18105
|
* @param {expression} ngDblclick {@link guide/expression Expression} to evaluate upon
|
17859
18106
|
* a dblclick. (The Event object is available as `$event`)
|
17860
18107
|
*
|
@@ -17878,6 +18125,7 @@ forEach(
|
|
17878
18125
|
* The ngMousedown directive allows you to specify custom behavior on mousedown event.
|
17879
18126
|
*
|
17880
18127
|
* @element ANY
|
18128
|
+
* @priority 0
|
17881
18129
|
* @param {expression} ngMousedown {@link guide/expression Expression} to evaluate upon
|
17882
18130
|
* mousedown. (Event object is available as `$event`)
|
17883
18131
|
*
|
@@ -17901,6 +18149,7 @@ forEach(
|
|
17901
18149
|
* Specify custom behavior on mouseup event.
|
17902
18150
|
*
|
17903
18151
|
* @element ANY
|
18152
|
+
* @priority 0
|
17904
18153
|
* @param {expression} ngMouseup {@link guide/expression Expression} to evaluate upon
|
17905
18154
|
* mouseup. (Event object is available as `$event`)
|
17906
18155
|
*
|
@@ -17923,6 +18172,7 @@ forEach(
|
|
17923
18172
|
* Specify custom behavior on mouseover event.
|
17924
18173
|
*
|
17925
18174
|
* @element ANY
|
18175
|
+
* @priority 0
|
17926
18176
|
* @param {expression} ngMouseover {@link guide/expression Expression} to evaluate upon
|
17927
18177
|
* mouseover. (Event object is available as `$event`)
|
17928
18178
|
*
|
@@ -17946,6 +18196,7 @@ forEach(
|
|
17946
18196
|
* Specify custom behavior on mouseenter event.
|
17947
18197
|
*
|
17948
18198
|
* @element ANY
|
18199
|
+
* @priority 0
|
17949
18200
|
* @param {expression} ngMouseenter {@link guide/expression Expression} to evaluate upon
|
17950
18201
|
* mouseenter. (Event object is available as `$event`)
|
17951
18202
|
*
|
@@ -17969,6 +18220,7 @@ forEach(
|
|
17969
18220
|
* Specify custom behavior on mouseleave event.
|
17970
18221
|
*
|
17971
18222
|
* @element ANY
|
18223
|
+
* @priority 0
|
17972
18224
|
* @param {expression} ngMouseleave {@link guide/expression Expression} to evaluate upon
|
17973
18225
|
* mouseleave. (Event object is available as `$event`)
|
17974
18226
|
*
|
@@ -17992,6 +18244,7 @@ forEach(
|
|
17992
18244
|
* Specify custom behavior on mousemove event.
|
17993
18245
|
*
|
17994
18246
|
* @element ANY
|
18247
|
+
* @priority 0
|
17995
18248
|
* @param {expression} ngMousemove {@link guide/expression Expression} to evaluate upon
|
17996
18249
|
* mousemove. (Event object is available as `$event`)
|
17997
18250
|
*
|
@@ -18015,6 +18268,7 @@ forEach(
|
|
18015
18268
|
* Specify custom behavior on keydown event.
|
18016
18269
|
*
|
18017
18270
|
* @element ANY
|
18271
|
+
* @priority 0
|
18018
18272
|
* @param {expression} ngKeydown {@link guide/expression Expression} to evaluate upon
|
18019
18273
|
* keydown. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
|
18020
18274
|
*
|
@@ -18036,6 +18290,7 @@ forEach(
|
|
18036
18290
|
* Specify custom behavior on keyup event.
|
18037
18291
|
*
|
18038
18292
|
* @element ANY
|
18293
|
+
* @priority 0
|
18039
18294
|
* @param {expression} ngKeyup {@link guide/expression Expression} to evaluate upon
|
18040
18295
|
* keyup. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
|
18041
18296
|
*
|
@@ -18078,10 +18333,11 @@ forEach(
|
|
18078
18333
|
* Enables binding angular expressions to onsubmit events.
|
18079
18334
|
*
|
18080
18335
|
* Additionally it prevents the default action (which for form means sending the request to the
|
18081
|
-
* server and reloading the current page)
|
18082
|
-
*
|
18336
|
+
* server and reloading the current page), but only if the form does not contain `action`,
|
18337
|
+
* `data-action`, or `x-action` attributes.
|
18083
18338
|
*
|
18084
18339
|
* @element form
|
18340
|
+
* @priority 0
|
18085
18341
|
* @param {expression} ngSubmit {@link guide/expression Expression} to eval. (Event object is available as `$event`)
|
18086
18342
|
*
|
18087
18343
|
* @example
|
@@ -18106,20 +18362,20 @@ forEach(
|
|
18106
18362
|
<pre>list={{list}}</pre>
|
18107
18363
|
</form>
|
18108
18364
|
</doc:source>
|
18109
|
-
<doc:
|
18365
|
+
<doc:protractor>
|
18110
18366
|
it('should check ng-submit', function() {
|
18111
|
-
expect(binding('list')).toBe('[]');
|
18112
|
-
element('.doc-example-live #submit').click();
|
18113
|
-
expect(binding('list')).
|
18114
|
-
expect(input('text').
|
18367
|
+
expect(element(by.binding('list')).getText()).toBe('list=[]');
|
18368
|
+
element(by.css('.doc-example-live #submit')).click();
|
18369
|
+
expect(element(by.binding('list')).getText()).toContain('hello');
|
18370
|
+
expect(element(by.input('text')).getAttribute('value')).toBe('');
|
18115
18371
|
});
|
18116
18372
|
it('should ignore empty strings', function() {
|
18117
|
-
expect(binding('list')).toBe('[]');
|
18118
|
-
element('.doc-example-live #submit').click();
|
18119
|
-
element('.doc-example-live #submit').click();
|
18120
|
-
expect(binding('list')).
|
18121
|
-
|
18122
|
-
</doc:
|
18373
|
+
expect(element(by.binding('list')).getText()).toBe('list=[]');
|
18374
|
+
element(by.css('.doc-example-live #submit')).click();
|
18375
|
+
element(by.css('.doc-example-live #submit')).click();
|
18376
|
+
expect(element(by.binding('list')).getText()).toContain('hello');
|
18377
|
+
});
|
18378
|
+
</doc:protractor>
|
18123
18379
|
</doc:example>
|
18124
18380
|
*/
|
18125
18381
|
|
@@ -18131,6 +18387,7 @@ forEach(
|
|
18131
18387
|
* Specify custom behavior on focus event.
|
18132
18388
|
*
|
18133
18389
|
* @element window, input, select, textarea, a
|
18390
|
+
* @priority 0
|
18134
18391
|
* @param {expression} ngFocus {@link guide/expression Expression} to evaluate upon
|
18135
18392
|
* focus. (Event object is available as `$event`)
|
18136
18393
|
*
|
@@ -18146,6 +18403,7 @@ forEach(
|
|
18146
18403
|
* Specify custom behavior on blur event.
|
18147
18404
|
*
|
18148
18405
|
* @element window, input, select, textarea, a
|
18406
|
+
* @priority 0
|
18149
18407
|
* @param {expression} ngBlur {@link guide/expression Expression} to evaluate upon
|
18150
18408
|
* blur. (Event object is available as `$event`)
|
18151
18409
|
*
|
@@ -18161,6 +18419,7 @@ forEach(
|
|
18161
18419
|
* Specify custom behavior on copy event.
|
18162
18420
|
*
|
18163
18421
|
* @element window, input, select, textarea, a
|
18422
|
+
* @priority 0
|
18164
18423
|
* @param {expression} ngCopy {@link guide/expression Expression} to evaluate upon
|
18165
18424
|
* copy. (Event object is available as `$event`)
|
18166
18425
|
*
|
@@ -18181,6 +18440,7 @@ forEach(
|
|
18181
18440
|
* Specify custom behavior on cut event.
|
18182
18441
|
*
|
18183
18442
|
* @element window, input, select, textarea, a
|
18443
|
+
* @priority 0
|
18184
18444
|
* @param {expression} ngCut {@link guide/expression Expression} to evaluate upon
|
18185
18445
|
* cut. (Event object is available as `$event`)
|
18186
18446
|
*
|
@@ -18201,6 +18461,7 @@ forEach(
|
|
18201
18461
|
* Specify custom behavior on paste event.
|
18202
18462
|
*
|
18203
18463
|
* @element window, input, select, textarea, a
|
18464
|
+
* @priority 0
|
18204
18465
|
* @param {expression} ngPaste {@link guide/expression Expression} to evaluate upon
|
18205
18466
|
* paste. (Event object is available as `$event`)
|
18206
18467
|
*
|
@@ -18441,19 +18702,33 @@ var ngIfDirective = ['$animate', function($animate) {
|
|
18441
18702
|
top:50px;
|
18442
18703
|
}
|
18443
18704
|
</file>
|
18444
|
-
<file name="
|
18705
|
+
<file name="protractorTest.js">
|
18706
|
+
var templateSelect = element(by.model('template'));
|
18707
|
+
var includeElem = element(by.css('.doc-example-live [ng-include]'));
|
18708
|
+
|
18445
18709
|
it('should load template1.html', function() {
|
18446
|
-
|
18447
|
-
toMatch(/Content of template1.html/);
|
18710
|
+
expect(includeElem.getText()).toMatch(/Content of template1.html/);
|
18448
18711
|
});
|
18712
|
+
|
18449
18713
|
it('should load template2.html', function() {
|
18450
|
-
|
18451
|
-
|
18452
|
-
|
18714
|
+
if (browser.params.browser == 'firefox') {
|
18715
|
+
// Firefox can't handle using selects
|
18716
|
+
// See https://github.com/angular/protractor/issues/480
|
18717
|
+
return;
|
18718
|
+
}
|
18719
|
+
templateSelect.click();
|
18720
|
+
templateSelect.element.all(by.css('option')).get(2).click();
|
18721
|
+
expect(includeElem.getText()).toMatch(/Content of template2.html/);
|
18453
18722
|
});
|
18723
|
+
|
18454
18724
|
it('should change to blank', function() {
|
18455
|
-
|
18456
|
-
|
18725
|
+
if (browser.params.browser == 'firefox') {
|
18726
|
+
// Firefox can't handle using selects
|
18727
|
+
return;
|
18728
|
+
}
|
18729
|
+
templateSelect.click();
|
18730
|
+
templateSelect.element.all(by.css('option')).get(0).click();
|
18731
|
+
expect(includeElem.isPresent()).toBe(false);
|
18457
18732
|
});
|
18458
18733
|
</file>
|
18459
18734
|
</example>
|
@@ -18584,6 +18859,13 @@ var ngIncludeFillContentDirective = ['$compile',
|
|
18584
18859
|
* should use {@link guide/controller controllers} rather than `ngInit`
|
18585
18860
|
* to initialize values on a scope.
|
18586
18861
|
* </div>
|
18862
|
+
* <div class="alert alert-warning">
|
18863
|
+
* **Note**: If you have assignment in `ngInit` along with {@link api/ng.$filter `$filter`}, make
|
18864
|
+
* sure you have parenthesis for correct precedence:
|
18865
|
+
* <pre class="prettyprint">
|
18866
|
+
* <div ng-init="test1 = (data | orderBy:'name')"></div>
|
18867
|
+
* </pre>
|
18868
|
+
* </div>
|
18587
18869
|
*
|
18588
18870
|
* @priority 450
|
18589
18871
|
*
|
@@ -18606,15 +18888,15 @@ var ngIncludeFillContentDirective = ['$compile',
|
|
18606
18888
|
</div>
|
18607
18889
|
</div>
|
18608
18890
|
</doc:source>
|
18609
|
-
<doc:
|
18891
|
+
<doc:protractor>
|
18610
18892
|
it('should alias index positions', function() {
|
18611
|
-
|
18612
|
-
|
18613
|
-
|
18614
|
-
|
18615
|
-
|
18893
|
+
var elements = element.all(by.css('.example-init'));
|
18894
|
+
expect(elements.get(0).getText()).toBe('list[ 0 ][ 0 ] = a;');
|
18895
|
+
expect(elements.get(1).getText()).toBe('list[ 0 ][ 1 ] = b;');
|
18896
|
+
expect(elements.get(2).getText()).toBe('list[ 1 ][ 0 ] = c;');
|
18897
|
+
expect(elements.get(3).getText()).toBe('list[ 1 ][ 1 ] = d;');
|
18616
18898
|
});
|
18617
|
-
</doc:
|
18899
|
+
</doc:protractor>
|
18618
18900
|
</doc:example>
|
18619
18901
|
*/
|
18620
18902
|
var ngInitDirective = ngDirective({
|
@@ -18652,13 +18934,12 @@ var ngInitDirective = ngDirective({
|
|
18652
18934
|
<div>Normal: {{1 + 2}}</div>
|
18653
18935
|
<div ng-non-bindable>Ignored: {{1 + 2}}</div>
|
18654
18936
|
</doc:source>
|
18655
|
-
<doc:
|
18937
|
+
<doc:protractor>
|
18656
18938
|
it('should check ng-non-bindable', function() {
|
18657
|
-
expect(
|
18658
|
-
expect(
|
18659
|
-
toMatch(/1 \+ 2/);
|
18939
|
+
expect(element(by.binding('1 + 2')).getText()).toContain('3');
|
18940
|
+
expect(element.all(by.css('.doc-example-live div')).last().getText()).toMatch(/1 \+ 2/);
|
18660
18941
|
});
|
18661
|
-
</doc:
|
18942
|
+
</doc:protractor>
|
18662
18943
|
</doc:example>
|
18663
18944
|
*/
|
18664
18945
|
var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
|
@@ -18786,49 +19067,53 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
|
|
18786
19067
|
</ng-pluralize>
|
18787
19068
|
</div>
|
18788
19069
|
</doc:source>
|
18789
|
-
<doc:
|
19070
|
+
<doc:protractor>
|
18790
19071
|
it('should show correct pluralized string', function() {
|
18791
|
-
|
18792
|
-
|
18793
|
-
|
18794
|
-
|
18795
|
-
|
18796
|
-
|
18797
|
-
|
18798
|
-
|
18799
|
-
|
18800
|
-
|
18801
|
-
|
18802
|
-
|
18803
|
-
expect(element('.doc-example-live ng-pluralize:first').text()).
|
18804
|
-
toBe('2 people are viewing.');
|
18805
|
-
expect(element('.doc-example-live ng-pluralize:last').text()).
|
18806
|
-
toBe('Igor and Misko are viewing.');
|
18807
|
-
|
18808
|
-
using('.doc-example-live').input('personCount').enter('3');
|
18809
|
-
expect(element('.doc-example-live ng-pluralize:first').text()).
|
18810
|
-
toBe('3 people are viewing.');
|
18811
|
-
expect(element('.doc-example-live ng-pluralize:last').text()).
|
18812
|
-
toBe('Igor, Misko and one other person are viewing.');
|
18813
|
-
|
18814
|
-
using('.doc-example-live').input('personCount').enter('4');
|
18815
|
-
expect(element('.doc-example-live ng-pluralize:first').text()).
|
18816
|
-
toBe('4 people are viewing.');
|
18817
|
-
expect(element('.doc-example-live ng-pluralize:last').text()).
|
18818
|
-
toBe('Igor, Misko and 2 other people are viewing.');
|
18819
|
-
});
|
19072
|
+
var withoutOffset = element.all(by.css('ng-pluralize')).get(0);
|
19073
|
+
var withOffset = element.all(by.css('ng-pluralize')).get(1);
|
19074
|
+
var countInput = element(by.model('personCount'));
|
19075
|
+
|
19076
|
+
expect(withoutOffset.getText()).toEqual('1 person is viewing.');
|
19077
|
+
expect(withOffset.getText()).toEqual('Igor is viewing.');
|
19078
|
+
|
19079
|
+
countInput.clear();
|
19080
|
+
countInput.sendKeys('0');
|
19081
|
+
|
19082
|
+
expect(withoutOffset.getText()).toEqual('Nobody is viewing.');
|
19083
|
+
expect(withOffset.getText()).toEqual('Nobody is viewing.');
|
18820
19084
|
|
18821
|
-
|
18822
|
-
|
18823
|
-
expect(element('.doc-example-live ng-pluralize:last').text()).
|
18824
|
-
toBe('Igor, Misko and 2 other people are viewing.');
|
19085
|
+
countInput.clear();
|
19086
|
+
countInput.sendKeys('2');
|
18825
19087
|
|
18826
|
-
|
18827
|
-
|
18828
|
-
|
18829
|
-
|
19088
|
+
expect(withoutOffset.getText()).toEqual('2 people are viewing.');
|
19089
|
+
expect(withOffset.getText()).toEqual('Igor and Misko are viewing.');
|
19090
|
+
|
19091
|
+
countInput.clear();
|
19092
|
+
countInput.sendKeys('3');
|
19093
|
+
|
19094
|
+
expect(withoutOffset.getText()).toEqual('3 people are viewing.');
|
19095
|
+
expect(withOffset.getText()).toEqual('Igor, Misko and one other person are viewing.');
|
19096
|
+
|
19097
|
+
countInput.clear();
|
19098
|
+
countInput.sendKeys('4');
|
19099
|
+
|
19100
|
+
expect(withoutOffset.getText()).toEqual('4 people are viewing.');
|
19101
|
+
expect(withOffset.getText()).toEqual('Igor, Misko and 2 other people are viewing.');
|
19102
|
+
});
|
19103
|
+
it('should show data-bound names', function() {
|
19104
|
+
var withOffset = element.all(by.css('ng-pluralize')).get(1);
|
19105
|
+
var personCount = element(by.model('personCount'));
|
19106
|
+
var person1 = element(by.model('person1'));
|
19107
|
+
var person2 = element(by.model('person2'));
|
19108
|
+
personCount.clear();
|
19109
|
+
personCount.sendKeys('4');
|
19110
|
+
person1.clear();
|
19111
|
+
person1.sendKeys('Di');
|
19112
|
+
person2.clear();
|
19113
|
+
person2.sendKeys('Vojta');
|
19114
|
+
expect(withOffset.getText()).toEqual('Di, Vojta and 2 other people are viewing.');
|
18830
19115
|
});
|
18831
|
-
</doc:
|
19116
|
+
</doc:protractor>
|
18832
19117
|
</doc:example>
|
18833
19118
|
*/
|
18834
19119
|
var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interpolate) {
|
@@ -19047,25 +19332,27 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
|
|
19047
19332
|
max-height:40px;
|
19048
19333
|
}
|
19049
19334
|
</file>
|
19050
|
-
<file name="
|
19051
|
-
|
19052
|
-
|
19053
|
-
|
19054
|
-
|
19055
|
-
|
19056
|
-
|
19057
|
-
|
19058
|
-
|
19335
|
+
<file name="protractorTest.js">
|
19336
|
+
var friends = element(by.css('.doc-example-live'))
|
19337
|
+
.element.all(by.repeater('friend in friends'));
|
19338
|
+
|
19339
|
+
it('should render initial data set', function() {
|
19340
|
+
expect(friends.count()).toBe(10);
|
19341
|
+
expect(friends.get(0).getText()).toEqual('[1] John who is 25 years old.');
|
19342
|
+
expect(friends.get(1).getText()).toEqual('[2] Jessie who is 30 years old.');
|
19343
|
+
expect(friends.last().getText()).toEqual('[10] Samantha who is 60 years old.');
|
19344
|
+
expect(element(by.binding('friends.length')).getText())
|
19345
|
+
.toMatch("I have 10 friends. They are:");
|
19346
|
+
});
|
19059
19347
|
|
19060
19348
|
it('should update repeater when filter predicate changes', function() {
|
19061
|
-
|
19062
|
-
expect(r.count()).toBe(10);
|
19349
|
+
expect(friends.count()).toBe(10);
|
19063
19350
|
|
19064
|
-
|
19351
|
+
element(by.css('.doc-example-live')).element(by.model('q')).sendKeys('ma');
|
19065
19352
|
|
19066
|
-
expect(
|
19067
|
-
expect(
|
19068
|
-
expect(
|
19353
|
+
expect(friends.count()).toBe(2);
|
19354
|
+
expect(friends.get(0).getText()).toEqual('[1] Mary who is 28 years old.');
|
19355
|
+
expect(friends.last().getText()).toEqual('[2] Samantha who is 60 years old.');
|
19069
19356
|
});
|
19070
19357
|
</file>
|
19071
19358
|
</example>
|
@@ -19319,6 +19606,11 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
19319
19606
|
*
|
19320
19607
|
* Just remember to include the important flag so the CSS override will function.
|
19321
19608
|
*
|
19609
|
+
* <div class="alert alert-warning">
|
19610
|
+
* **Note:** Here is a list of values that ngShow will consider as a falsy value (case insensitive):<br />
|
19611
|
+
* "f" / "0" / "false" / "no" / "n" / "[]"
|
19612
|
+
* </div>
|
19613
|
+
*
|
19322
19614
|
* ## A note about animations with ngShow
|
19323
19615
|
*
|
19324
19616
|
* Animations in ngShow/ngHide work with the show and hide events that are triggered when the directive expression
|
@@ -19394,16 +19686,19 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
19394
19686
|
background:white;
|
19395
19687
|
}
|
19396
19688
|
</file>
|
19397
|
-
<file name="
|
19398
|
-
|
19399
|
-
|
19400
|
-
expect(element('.doc-example-live span:last:visible').count()).toEqual(1);
|
19689
|
+
<file name="protractorTest.js">
|
19690
|
+
var thumbsUp = element(by.css('.doc-example-live span.icon-thumbs-up'));
|
19691
|
+
var thumbsDown = element(by.css('.doc-example-live span.icon-thumbs-down'));
|
19401
19692
|
|
19402
|
-
|
19693
|
+
it('should check ng-show / ng-hide', function() {
|
19694
|
+
expect(thumbsUp.isDisplayed()).toBeFalsy();
|
19695
|
+
expect(thumbsDown.isDisplayed()).toBeTruthy();
|
19403
19696
|
|
19404
|
-
|
19405
|
-
|
19406
|
-
|
19697
|
+
element(by.model('checked')).click();
|
19698
|
+
|
19699
|
+
expect(thumbsUp.isDisplayed()).toBeTruthy();
|
19700
|
+
expect(thumbsDown.isDisplayed()).toBeFalsy();
|
19701
|
+
});
|
19407
19702
|
</file>
|
19408
19703
|
</example>
|
19409
19704
|
*/
|
@@ -19467,6 +19762,11 @@ var ngShowDirective = ['$animate', function($animate) {
|
|
19467
19762
|
* </pre>
|
19468
19763
|
*
|
19469
19764
|
* Just remember to include the important flag so the CSS override will function.
|
19765
|
+
*
|
19766
|
+
* <div class="alert alert-warning">
|
19767
|
+
* **Note:** Here is a list of values that ngHide will consider as a falsy value (case insensitive):<br />
|
19768
|
+
* "f" / "0" / "false" / "no" / "n" / "[]"
|
19769
|
+
* </div>
|
19470
19770
|
*
|
19471
19771
|
* ## A note about animations with ngHide
|
19472
19772
|
*
|
@@ -19543,16 +19843,19 @@ var ngShowDirective = ['$animate', function($animate) {
|
|
19543
19843
|
background:white;
|
19544
19844
|
}
|
19545
19845
|
</file>
|
19546
|
-
<file name="
|
19547
|
-
|
19548
|
-
|
19549
|
-
expect(element('.doc-example-live .check-element:last:visible').count()).toEqual(1);
|
19846
|
+
<file name="protractorTest.js">
|
19847
|
+
var thumbsUp = element(by.css('.doc-example-live span.icon-thumbs-up'));
|
19848
|
+
var thumbsDown = element(by.css('.doc-example-live span.icon-thumbs-down'));
|
19550
19849
|
|
19551
|
-
|
19850
|
+
it('should check ng-show / ng-hide', function() {
|
19851
|
+
expect(thumbsUp.isDisplayed()).toBeFalsy();
|
19852
|
+
expect(thumbsDown.isDisplayed()).toBeTruthy();
|
19552
19853
|
|
19553
|
-
|
19554
|
-
|
19555
|
-
|
19854
|
+
element(by.model('checked')).click();
|
19855
|
+
|
19856
|
+
expect(thumbsUp.isDisplayed()).toBeTruthy();
|
19857
|
+
expect(thumbsDown.isDisplayed()).toBeFalsy();
|
19858
|
+
});
|
19556
19859
|
</file>
|
19557
19860
|
</example>
|
19558
19861
|
*/
|
@@ -19591,13 +19894,15 @@ var ngHideDirective = ['$animate', function($animate) {
|
|
19591
19894
|
color: black;
|
19592
19895
|
}
|
19593
19896
|
</file>
|
19594
|
-
<file name="
|
19897
|
+
<file name="protractorTest.js">
|
19898
|
+
var colorSpan = element(by.css('.doc-example-live span'));
|
19899
|
+
|
19595
19900
|
it('should check ng-style', function() {
|
19596
|
-
expect(
|
19597
|
-
element('.doc-example-live
|
19598
|
-
expect(
|
19599
|
-
element('.doc-example-live
|
19600
|
-
expect(
|
19901
|
+
expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
|
19902
|
+
element(by.css('.doc-example-live input[value=set]')).click();
|
19903
|
+
expect(colorSpan.getCssValue('color')).toBe('rgba(255, 0, 0, 1)');
|
19904
|
+
element(by.css('.doc-example-live input[value=clear]')).click();
|
19905
|
+
expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
|
19601
19906
|
});
|
19602
19907
|
</file>
|
19603
19908
|
</example>
|
@@ -19622,7 +19927,7 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
|
|
19622
19927
|
* as specified in the template.
|
19623
19928
|
*
|
19624
19929
|
* The directive itself works similar to ngInclude, however, instead of downloading template code (or loading it
|
19625
|
-
* from the template cache), `ngSwitch` simply
|
19930
|
+
* from the template cache), `ngSwitch` simply chooses one of the nested elements and makes it visible based on which element
|
19626
19931
|
* matches the value obtained from the evaluated expression. In other words, you define a container element
|
19627
19932
|
* (where you place the directive), place an expression on the **`on="..."` attribute**
|
19628
19933
|
* (or the **`ng-switch="..."` attribute**), define any inner elements inside of the directive and place
|
@@ -19718,17 +20023,20 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
|
|
19718
20023
|
top:0;
|
19719
20024
|
}
|
19720
20025
|
</file>
|
19721
|
-
<file name="
|
20026
|
+
<file name="protractorTest.js">
|
20027
|
+
var switchElem = element(by.css('.doc-example-live [ng-switch]'));
|
20028
|
+
var select = element(by.model('selection'));
|
20029
|
+
|
19722
20030
|
it('should start in settings', function() {
|
19723
|
-
expect(
|
20031
|
+
expect(switchElem.getText()).toMatch(/Settings Div/);
|
19724
20032
|
});
|
19725
20033
|
it('should change to home', function() {
|
19726
|
-
select('
|
19727
|
-
expect(
|
20034
|
+
select.element.all(by.css('option')).get(1).click();
|
20035
|
+
expect(switchElem.getText()).toMatch(/Home Span/);
|
19728
20036
|
});
|
19729
20037
|
it('should select default', function() {
|
19730
|
-
select('
|
19731
|
-
expect(
|
20038
|
+
select.element.all(by.css('option')).get(2).click();
|
20039
|
+
expect(switchElem.getText()).toMatch(/default/);
|
19732
20040
|
});
|
19733
20041
|
</file>
|
19734
20042
|
</example>
|
@@ -19835,35 +20143,32 @@ var ngSwitchDefaultDirective = ngDirective({
|
|
19835
20143
|
<pane title="{{title}}">{{text}}</pane>
|
19836
20144
|
</div>
|
19837
20145
|
</doc:source>
|
19838
|
-
<doc:
|
20146
|
+
<doc:protractor>
|
19839
20147
|
it('should have transcluded', function() {
|
19840
|
-
|
19841
|
-
|
19842
|
-
|
19843
|
-
|
20148
|
+
var titleElement = element(by.model('title'));
|
20149
|
+
titleElement.clear();
|
20150
|
+
titleElement.sendKeys('TITLE');
|
20151
|
+
var textElement = element(by.model('text'));
|
20152
|
+
textElement.clear();
|
20153
|
+
textElement.sendKeys('TEXT');
|
20154
|
+
expect(element(by.binding('title')).getText()).toEqual('TITLE');
|
20155
|
+
expect(element(by.binding('text')).getText()).toEqual('TEXT');
|
19844
20156
|
});
|
19845
|
-
</doc:
|
20157
|
+
</doc:protractor>
|
19846
20158
|
</doc:example>
|
19847
20159
|
*
|
19848
20160
|
*/
|
19849
20161
|
var ngTranscludeDirective = ngDirective({
|
19850
|
-
|
20162
|
+
link: function($scope, $element, $attrs, controller, $transclude) {
|
19851
20163
|
if (!$transclude) {
|
19852
20164
|
throw minErr('ngTransclude')('orphan',
|
19853
|
-
|
19854
|
-
|
19855
|
-
|
19856
|
-
|
20165
|
+
'Illegal use of ngTransclude directive in the template! ' +
|
20166
|
+
'No parent directive that requires a transclusion found. ' +
|
20167
|
+
'Element: {0}',
|
20168
|
+
startingTag($element));
|
19857
20169
|
}
|
19858
|
-
|
19859
|
-
|
19860
|
-
// the parent element even when the transclusion replaces the current element. (we can't use priority here because
|
19861
|
-
// that applies only to compile fns and not controllers
|
19862
|
-
this.$transclude = $transclude;
|
19863
|
-
}],
|
19864
|
-
|
19865
|
-
link: function($scope, $element, $attrs, controller) {
|
19866
|
-
controller.$transclude(function(clone) {
|
20170
|
+
|
20171
|
+
$transclude(function(clone) {
|
19867
20172
|
$element.empty();
|
19868
20173
|
$element.append(clone);
|
19869
20174
|
});
|
@@ -19895,12 +20200,12 @@ var ngTranscludeDirective = ngDirective({
|
|
19895
20200
|
<a ng-click="currentTpl='/tpl.html'" id="tpl-link">Load inlined template</a>
|
19896
20201
|
<div id="tpl-content" ng-include src="currentTpl"></div>
|
19897
20202
|
</doc:source>
|
19898
|
-
<doc:
|
20203
|
+
<doc:protractor>
|
19899
20204
|
it('should load template defined inside script tag', function() {
|
19900
|
-
element('#tpl-link').click();
|
19901
|
-
expect(element('#tpl-content').
|
20205
|
+
element(by.css('#tpl-link')).click();
|
20206
|
+
expect(element(by.css('#tpl-content')).getText()).toMatch(/Content of the template/);
|
19902
20207
|
});
|
19903
|
-
</doc:
|
20208
|
+
</doc:protractor>
|
19904
20209
|
</doc:example>
|
19905
20210
|
*/
|
19906
20211
|
var scriptDirective = ['$templateCache', function($templateCache) {
|
@@ -19938,14 +20243,21 @@ var ngOptionsMinErr = minErr('ngOptions');
|
|
19938
20243
|
* represented by the selected option will be bound to the model identified by the `ngModel`
|
19939
20244
|
* directive.
|
19940
20245
|
*
|
20246
|
+
* <div class="alert alert-warning">
|
20247
|
+
* **Note:** `ngModel` compares by reference, not value. This is important when binding to an
|
20248
|
+
* array of objects. See an example {@link http://jsfiddle.net/qWzTb/ in this jsfiddle}.
|
20249
|
+
* </div>
|
20250
|
+
*
|
19941
20251
|
* Optionally, a single hard-coded `<option>` element, with the value set to an empty string, can
|
19942
20252
|
* be nested into the `<select>` element. This element will then represent the `null` or "not selected"
|
19943
20253
|
* option. See example below for demonstration.
|
19944
20254
|
*
|
19945
|
-
*
|
20255
|
+
* <div class="alert alert-warning">
|
20256
|
+
* **Note:** `ngOptions` provides an iterator facility for the `<option>` element which should be used instead
|
19946
20257
|
* of {@link ng.directive:ngRepeat ngRepeat} when you want the
|
19947
20258
|
* `select` model to be bound to a non-string value. This is because an option element can only
|
19948
20259
|
* be bound to string values at present.
|
20260
|
+
* </div>
|
19949
20261
|
*
|
19950
20262
|
* @param {string} ngModel Assignable angular expression to data-bind to.
|
19951
20263
|
* @param {string=} name Property name of the form under which the control is published.
|
@@ -20032,15 +20344,17 @@ var ngOptionsMinErr = minErr('ngOptions');
|
|
20032
20344
|
</div>
|
20033
20345
|
</div>
|
20034
20346
|
</doc:source>
|
20035
|
-
<doc:
|
20347
|
+
<doc:protractor>
|
20036
20348
|
it('should check ng-options', function() {
|
20037
|
-
expect(binding('{selected_color:color}')).toMatch('red');
|
20038
|
-
select('color').
|
20039
|
-
|
20040
|
-
|
20041
|
-
|
20349
|
+
expect(element(by.binding('{selected_color:color}')).getText()).toMatch('red');
|
20350
|
+
element.all(by.select('color')).first().click();
|
20351
|
+
element.all(by.css('select[ng-model="color"] option')).first().click();
|
20352
|
+
expect(element(by.binding('{selected_color:color}')).getText()).toMatch('black');
|
20353
|
+
element(by.css('.nullable select[ng-model="color"]')).click();
|
20354
|
+
element.all(by.css('.nullable select[ng-model="color"] option')).first().click();
|
20355
|
+
expect(element(by.binding('{selected_color:color}')).getText()).toMatch('null');
|
20042
20356
|
});
|
20043
|
-
</doc:
|
20357
|
+
</doc:protractor>
|
20044
20358
|
</doc:example>
|
20045
20359
|
*/
|
20046
20360
|
|
@@ -20349,7 +20663,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
20349
20663
|
|
20350
20664
|
// We now build up the list of options we need (we merge later)
|
20351
20665
|
for (index = 0; length = keys.length, index < length; index++) {
|
20352
|
-
|
20666
|
+
|
20353
20667
|
key = index;
|
20354
20668
|
if (keyName) {
|
20355
20669
|
key = keys[index];
|
@@ -20557,4 +20871,4 @@ var styleDirective = valueFn({
|
|
20557
20871
|
|
20558
20872
|
})(window, document);
|
20559
20873
|
|
20560
|
-
!angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}</style>');
|
20874
|
+
!angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}.ng-animate-block-transitions{transition:0s all!important;-webkit-transition:0s all!important;}</style>');
|