angular-gem 1.2.3 → 1.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/angular-gem/version.rb +1 -1
- data/vendor/assets/javascripts/1.2.4/angular-animate.js +1323 -0
- data/vendor/assets/javascripts/1.2.4/angular-cookies.js +202 -0
- data/vendor/assets/javascripts/1.2.4/angular-loader.js +410 -0
- data/vendor/assets/javascripts/1.2.4/angular-mocks.js +2115 -0
- data/vendor/assets/javascripts/1.2.4/angular-resource.js +546 -0
- data/vendor/assets/javascripts/1.2.4/angular-route.js +891 -0
- data/vendor/assets/javascripts/1.2.4/angular-sanitize.js +622 -0
- data/vendor/assets/javascripts/1.2.4/angular-scenario.js +32316 -0
- data/vendor/assets/javascripts/1.2.4/angular-touch.js +563 -0
- data/vendor/assets/javascripts/1.2.4/angular.js +20311 -0
- data/vendor/assets/javascripts/angular-animate.js +55 -26
- 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 +1 -1
- data/vendor/assets/javascripts/angular-resource.js +1 -1
- data/vendor/assets/javascripts/angular-route.js +1 -1
- data/vendor/assets/javascripts/angular-sanitize.js +18 -11
- data/vendor/assets/javascripts/angular-scenario.js +145 -116
- data/vendor/assets/javascripts/angular-touch.js +1 -1
- data/vendor/assets/javascripts/angular.js +145 -116
- metadata +11 -1
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.2.
|
2
|
+
* @license AngularJS v1.2.4
|
3
3
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -196,7 +196,7 @@
|
|
196
196
|
*
|
197
197
|
* <pre>
|
198
198
|
* //!annotate="YourApp" Your AngularJS Module|Replace this or ngModule with the module that you used to define your application.
|
199
|
-
* var ngModule = angular.module('YourApp', []);
|
199
|
+
* var ngModule = angular.module('YourApp', ['ngAnimate']);
|
200
200
|
* ngModule.animation('.my-crazy-animation', function() {
|
201
201
|
* return {
|
202
202
|
* enter: function(element, done) {
|
@@ -205,8 +205,8 @@
|
|
205
205
|
* //this (optional) function will be called when the animation
|
206
206
|
* //completes or when the animation is cancelled (the cancelled
|
207
207
|
* //flag will be set to true if cancelled).
|
208
|
-
* }
|
209
|
-
* }
|
208
|
+
* };
|
209
|
+
* },
|
210
210
|
* leave: function(element, done) { },
|
211
211
|
* move: function(element, done) { },
|
212
212
|
*
|
@@ -221,7 +221,7 @@
|
|
221
221
|
*
|
222
222
|
* //animation that can be triggered after the class is removed
|
223
223
|
* removeClass: function(element, className, done) { }
|
224
|
-
* }
|
224
|
+
* };
|
225
225
|
* });
|
226
226
|
* </pre>
|
227
227
|
*
|
@@ -264,6 +264,19 @@ angular.module('ngAnimate', ['ng'])
|
|
264
264
|
var NG_ANIMATE_CLASS_NAME = 'ng-animate';
|
265
265
|
var rootAnimateState = {running: true};
|
266
266
|
|
267
|
+
function extractElementNode(element) {
|
268
|
+
for(var i = 0; i < element.length; i++) {
|
269
|
+
var elm = element[i];
|
270
|
+
if(elm.nodeType == ELEMENT_NODE) {
|
271
|
+
return elm;
|
272
|
+
}
|
273
|
+
}
|
274
|
+
}
|
275
|
+
|
276
|
+
function isMatchingElement(elm1, elm2) {
|
277
|
+
return extractElementNode(elm1) == extractElementNode(elm2);
|
278
|
+
}
|
279
|
+
|
267
280
|
$provide.decorator('$animate', ['$delegate', '$injector', '$sniffer', '$rootElement', '$timeout', '$rootScope', '$document',
|
268
281
|
function($delegate, $injector, $sniffer, $rootElement, $timeout, $rootScope, $document) {
|
269
282
|
|
@@ -376,7 +389,7 @@ angular.module('ngAnimate', ['ng'])
|
|
376
389
|
* Runs the leave animation operation and, upon completion, removes the element from the DOM. Once
|
377
390
|
* the animation is started, the following CSS classes will be added for the duration of the animation:
|
378
391
|
*
|
379
|
-
* Below is a breakdown of each step that occurs during
|
392
|
+
* Below is a breakdown of each step that occurs during leave animation:
|
380
393
|
*
|
381
394
|
* | Animation Step | What the element class attribute looks like |
|
382
395
|
* |----------------------------------------------------------------------------------------------|---------------------------------------------|
|
@@ -562,7 +575,16 @@ angular.module('ngAnimate', ['ng'])
|
|
562
575
|
and the onComplete callback will be fired once the animation is fully complete.
|
563
576
|
*/
|
564
577
|
function performAnimation(animationEvent, className, element, parentElement, afterElement, domOperation, doneCallback) {
|
565
|
-
var
|
578
|
+
var node = extractElementNode(element);
|
579
|
+
//transcluded directives may sometimes fire an animation using only comment nodes
|
580
|
+
//best to catch this early on to prevent any animation operations from occurring
|
581
|
+
if(!node) {
|
582
|
+
fireDOMOperation();
|
583
|
+
closeAnimation();
|
584
|
+
return;
|
585
|
+
}
|
586
|
+
|
587
|
+
var currentClassName = node.className;
|
566
588
|
var classes = currentClassName + ' ' + className;
|
567
589
|
var animationLookup = (' ' + classes).replace(/\s+/g,'.');
|
568
590
|
if (!parentElement) {
|
@@ -766,11 +788,7 @@ angular.module('ngAnimate', ['ng'])
|
|
766
788
|
}
|
767
789
|
|
768
790
|
function cancelChildAnimations(element) {
|
769
|
-
var node = element
|
770
|
-
if(node.nodeType != ELEMENT_NODE) {
|
771
|
-
return;
|
772
|
-
}
|
773
|
-
|
791
|
+
var node = extractElementNode(element);
|
774
792
|
forEach(node.querySelectorAll('.' + NG_ANIMATE_CLASS_NAME), function(element) {
|
775
793
|
element = angular.element(element);
|
776
794
|
var data = element.data(NG_ANIMATE_STATE);
|
@@ -794,7 +812,7 @@ angular.module('ngAnimate', ['ng'])
|
|
794
812
|
}
|
795
813
|
|
796
814
|
function cleanup(element) {
|
797
|
-
if(element
|
815
|
+
if(isMatchingElement(element, $rootElement)) {
|
798
816
|
if(!rootAnimateState.disabled) {
|
799
817
|
rootAnimateState.running = false;
|
800
818
|
rootAnimateState.structural = false;
|
@@ -808,7 +826,7 @@ angular.module('ngAnimate', ['ng'])
|
|
808
826
|
function animationsDisabled(element, parentElement) {
|
809
827
|
if (rootAnimateState.disabled) return true;
|
810
828
|
|
811
|
-
if(element
|
829
|
+
if(isMatchingElement(element, $rootElement)) {
|
812
830
|
return rootAnimateState.disabled || rootAnimateState.running;
|
813
831
|
}
|
814
832
|
|
@@ -818,7 +836,7 @@ angular.module('ngAnimate', ['ng'])
|
|
818
836
|
//any animations on it
|
819
837
|
if(parentElement.length === 0) break;
|
820
838
|
|
821
|
-
var isRoot = parentElement
|
839
|
+
var isRoot = isMatchingElement(parentElement, $rootElement);
|
822
840
|
var state = isRoot ? rootAnimateState : parentElement.data(NG_ANIMATE_STATE);
|
823
841
|
var result = state && (!!state.disabled || !!state.running);
|
824
842
|
if(isRoot || result) {
|
@@ -871,6 +889,7 @@ angular.module('ngAnimate', ['ng'])
|
|
871
889
|
var NG_ANIMATE_CSS_DATA_KEY = '$$ngAnimateCSS3Data';
|
872
890
|
var NG_ANIMATE_FALLBACK_CLASS_NAME = 'ng-animate-start';
|
873
891
|
var NG_ANIMATE_FALLBACK_ACTIVE_CLASS_NAME = 'ng-animate-active';
|
892
|
+
var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3;
|
874
893
|
|
875
894
|
var lookupCache = {};
|
876
895
|
var parentCounter = 0;
|
@@ -965,7 +984,7 @@ angular.module('ngAnimate', ['ng'])
|
|
965
984
|
parentElement.data(NG_ANIMATE_PARENT_KEY, ++parentCounter);
|
966
985
|
parentID = parentCounter;
|
967
986
|
}
|
968
|
-
return parentID + '-' + element
|
987
|
+
return parentID + '-' + extractElementNode(element).className;
|
969
988
|
}
|
970
989
|
|
971
990
|
function animateSetup(element, className) {
|
@@ -1000,7 +1019,6 @@ angular.module('ngAnimate', ['ng'])
|
|
1000
1019
|
return false;
|
1001
1020
|
}
|
1002
1021
|
|
1003
|
-
var node = element[0];
|
1004
1022
|
//temporarily disable the transition so that the enter styles
|
1005
1023
|
//don't animate twice (this is here to avoid a bug in Chrome/FF).
|
1006
1024
|
var activeClassName = '';
|
@@ -1030,35 +1048,37 @@ angular.module('ngAnimate', ['ng'])
|
|
1030
1048
|
}
|
1031
1049
|
|
1032
1050
|
function blockTransitions(element) {
|
1033
|
-
element
|
1051
|
+
extractElementNode(element).style[TRANSITION_PROP + PROPERTY_KEY] = 'none';
|
1034
1052
|
}
|
1035
1053
|
|
1036
1054
|
function blockKeyframeAnimations(element) {
|
1037
|
-
element
|
1055
|
+
extractElementNode(element).style[ANIMATION_PROP] = 'none 0s';
|
1038
1056
|
}
|
1039
1057
|
|
1040
1058
|
function unblockTransitions(element) {
|
1041
|
-
var
|
1059
|
+
var prop = TRANSITION_PROP + PROPERTY_KEY;
|
1060
|
+
var node = extractElementNode(element);
|
1042
1061
|
if(node.style[prop] && node.style[prop].length > 0) {
|
1043
1062
|
node.style[prop] = '';
|
1044
1063
|
}
|
1045
1064
|
}
|
1046
1065
|
|
1047
1066
|
function unblockKeyframeAnimations(element) {
|
1048
|
-
var
|
1067
|
+
var prop = ANIMATION_PROP;
|
1068
|
+
var node = extractElementNode(element);
|
1049
1069
|
if(node.style[prop] && node.style[prop].length > 0) {
|
1050
|
-
|
1070
|
+
node.style[prop] = '';
|
1051
1071
|
}
|
1052
1072
|
}
|
1053
1073
|
|
1054
1074
|
function animateRun(element, className, activeAnimationComplete) {
|
1055
1075
|
var data = element.data(NG_ANIMATE_CSS_DATA_KEY);
|
1056
|
-
|
1076
|
+
var node = extractElementNode(element);
|
1077
|
+
if(node.className.indexOf(className) == -1 || !data) {
|
1057
1078
|
activeAnimationComplete();
|
1058
1079
|
return;
|
1059
1080
|
}
|
1060
1081
|
|
1061
|
-
var node = element[0];
|
1062
1082
|
var timings = data.timings;
|
1063
1083
|
var stagger = data.stagger;
|
1064
1084
|
var maxDuration = data.maxDuration;
|
@@ -1101,6 +1121,9 @@ angular.module('ngAnimate', ['ng'])
|
|
1101
1121
|
}
|
1102
1122
|
|
1103
1123
|
if(appliedStyles.length > 0) {
|
1124
|
+
//the element being animated may sometimes contain comment nodes in
|
1125
|
+
//the jqLite object, so we're safe to use a single variable to house
|
1126
|
+
//the styles since there is always only one element being animated
|
1104
1127
|
var oldStyle = node.getAttribute('style') || '';
|
1105
1128
|
node.setAttribute('style', oldStyle + ' ' + style);
|
1106
1129
|
}
|
@@ -1115,6 +1138,7 @@ angular.module('ngAnimate', ['ng'])
|
|
1115
1138
|
element.off(css3AnimationEvents, onAnimationProgress);
|
1116
1139
|
element.removeClass(activeClassName);
|
1117
1140
|
animateClose(element, className);
|
1141
|
+
var node = extractElementNode(element);
|
1118
1142
|
for (var i in appliedStyles) {
|
1119
1143
|
node.style.removeProperty(appliedStyles[i]);
|
1120
1144
|
}
|
@@ -1124,6 +1148,11 @@ angular.module('ngAnimate', ['ng'])
|
|
1124
1148
|
event.stopPropagation();
|
1125
1149
|
var ev = event.originalEvent || event;
|
1126
1150
|
var timeStamp = ev.$manualTimeStamp || ev.timeStamp || Date.now();
|
1151
|
+
|
1152
|
+
/* Firefox (or possibly just Gecko) likes to not round values up
|
1153
|
+
* when a ms measurement is used for the animation */
|
1154
|
+
var elapsedTime = parseFloat(ev.elapsedTime.toFixed(ELAPSED_TIME_MAX_DECIMAL_PLACES));
|
1155
|
+
|
1127
1156
|
/* $manualTimeStamp is a mocked timeStamp value which is set
|
1128
1157
|
* within browserTrigger(). This is only here so that tests can
|
1129
1158
|
* mock animations properly. Real events fallback to event.timeStamp,
|
@@ -1131,7 +1160,7 @@ angular.module('ngAnimate', ['ng'])
|
|
1131
1160
|
* We're checking to see if the timeStamp surpasses the expected delay,
|
1132
1161
|
* but we're using elapsedTime instead of the timeStamp on the 2nd
|
1133
1162
|
* pre-condition since animations sometimes close off early */
|
1134
|
-
if(Math.max(timeStamp - startTime, 0) >= maxDelayTime &&
|
1163
|
+
if(Math.max(timeStamp - startTime, 0) >= maxDelayTime && elapsedTime >= maxDuration) {
|
1135
1164
|
activeAnimationComplete();
|
1136
1165
|
}
|
1137
1166
|
}
|
@@ -1209,7 +1238,7 @@ angular.module('ngAnimate', ['ng'])
|
|
1209
1238
|
}
|
1210
1239
|
|
1211
1240
|
var parentElement = element.parent();
|
1212
|
-
var clone = angular.element(element
|
1241
|
+
var clone = angular.element(extractElementNode(element).cloneNode());
|
1213
1242
|
|
1214
1243
|
//make the element super hidden and override any CSS style values
|
1215
1244
|
clone.attr('style','position:absolute; top:-9999px; left:-9999px');
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.2.
|
2
|
+
* @license AngularJS v1.2.4
|
3
3
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -69,7 +69,7 @@ function minErr(module) {
|
|
69
69
|
return match;
|
70
70
|
});
|
71
71
|
|
72
|
-
message = message + '\nhttp://errors.angularjs.org/1.2.
|
72
|
+
message = message + '\nhttp://errors.angularjs.org/1.2.4/' +
|
73
73
|
(module ? module + '/' : '') + code;
|
74
74
|
for (i = 2; i < arguments.length; i++) {
|
75
75
|
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.2.
|
2
|
+
* @license AngularJS v1.2.4
|
3
3
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -365,25 +365,32 @@ function htmlParser( html, handler ) {
|
|
365
365
|
}
|
366
366
|
}
|
367
367
|
|
368
|
+
var hiddenPre=document.createElement("pre");
|
369
|
+
var spaceRe = /^(\s*)([\s\S]*?)(\s*)$/;
|
368
370
|
/**
|
369
371
|
* decodes all entities into regular string
|
370
372
|
* @param value
|
371
373
|
* @returns {string} A string with decoded entities.
|
372
374
|
*/
|
373
|
-
var hiddenPre=document.createElement("pre");
|
374
375
|
function decodeEntities(value) {
|
375
|
-
if (!value) {
|
376
|
-
|
377
|
-
}
|
376
|
+
if (!value) { return ''; }
|
377
|
+
|
378
378
|
// Note: IE8 does not preserve spaces at the start/end of innerHTML
|
379
|
-
|
379
|
+
// so we must capture them and reattach them afterward
|
380
380
|
var parts = spaceRe.exec(value);
|
381
|
-
parts[
|
382
|
-
|
383
|
-
|
384
|
-
|
381
|
+
var spaceBefore = parts[1];
|
382
|
+
var spaceAfter = parts[3];
|
383
|
+
var content = parts[2];
|
384
|
+
if (content) {
|
385
|
+
hiddenPre.innerHTML=content.replace(/</g,"<");
|
386
|
+
// innerText depends on styling as it doesn't display hidden elements.
|
387
|
+
// Therefore, it's better to use textContent not to cause unnecessary
|
388
|
+
// reflows. However, IE<9 don't support textContent so the innerText
|
389
|
+
// fallback is necessary.
|
390
|
+
content = 'textContent' in hiddenPre ?
|
391
|
+
hiddenPre.textContent : hiddenPre.innerText;
|
385
392
|
}
|
386
|
-
return
|
393
|
+
return spaceBefore + content + spaceAfter;
|
387
394
|
}
|
388
395
|
|
389
396
|
/**
|
@@ -9790,7 +9790,7 @@ if ( typeof module === "object" && module && typeof module.exports === "object"
|
|
9790
9790
|
})( window );
|
9791
9791
|
|
9792
9792
|
/**
|
9793
|
-
* @license AngularJS v1.2.
|
9793
|
+
* @license AngularJS v1.2.4
|
9794
9794
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
9795
9795
|
* License: MIT
|
9796
9796
|
*/
|
@@ -9860,7 +9860,7 @@ function minErr(module) {
|
|
9860
9860
|
return match;
|
9861
9861
|
});
|
9862
9862
|
|
9863
|
-
message = message + '\nhttp://errors.angularjs.org/1.2.
|
9863
|
+
message = message + '\nhttp://errors.angularjs.org/1.2.4/' +
|
9864
9864
|
(module ? module + '/' : '') + code;
|
9865
9865
|
for (i = 2; i < arguments.length; i++) {
|
9866
9866
|
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
|
@@ -10436,9 +10436,9 @@ var trim = (function() {
|
|
10436
10436
|
* @returns {boolean} True if `value` is a DOM element (or wrapped jQuery element).
|
10437
10437
|
*/
|
10438
10438
|
function isElement(node) {
|
10439
|
-
return node &&
|
10439
|
+
return !!(node &&
|
10440
10440
|
(node.nodeName // we are a direct element
|
10441
|
-
|| (node.on && node.find)); // we have an on and find method part of jQuery API
|
10441
|
+
|| (node.on && node.find))); // we have an on and find method part of jQuery API
|
10442
10442
|
}
|
10443
10443
|
|
10444
10444
|
/**
|
@@ -10639,7 +10639,7 @@ function shallowCopy(src, dst) {
|
|
10639
10639
|
|
10640
10640
|
for(var key in src) {
|
10641
10641
|
// shallowCopy is only ever called by $compile nodeLinkFn, which has control over src
|
10642
|
-
// so we don't need to worry hasOwnProperty here
|
10642
|
+
// so we don't need to worry about using our custom hasOwnProperty here
|
10643
10643
|
if (src.hasOwnProperty(key) && key.substr(0, 2) !== '$$') {
|
10644
10644
|
dst[key] = src[key];
|
10645
10645
|
}
|
@@ -11201,23 +11201,25 @@ function getter(obj, path, bindFnToScope) {
|
|
11201
11201
|
}
|
11202
11202
|
|
11203
11203
|
/**
|
11204
|
-
* Return the siblings between
|
11205
|
-
* @param {
|
11204
|
+
* Return the DOM siblings between the first and last node in the given array.
|
11205
|
+
* @param {Array} array like object
|
11206
11206
|
* @returns jQlite object containing the elements
|
11207
11207
|
*/
|
11208
|
-
function getBlockElements(
|
11209
|
-
|
11210
|
-
|
11208
|
+
function getBlockElements(nodes) {
|
11209
|
+
var startNode = nodes[0],
|
11210
|
+
endNode = nodes[nodes.length - 1];
|
11211
|
+
if (startNode === endNode) {
|
11212
|
+
return jqLite(startNode);
|
11211
11213
|
}
|
11212
11214
|
|
11213
|
-
var element =
|
11215
|
+
var element = startNode;
|
11214
11216
|
var elements = [element];
|
11215
11217
|
|
11216
11218
|
do {
|
11217
11219
|
element = element.nextSibling;
|
11218
11220
|
if (!element) break;
|
11219
11221
|
elements.push(element);
|
11220
|
-
} while (element !==
|
11222
|
+
} while (element !== endNode);
|
11221
11223
|
|
11222
11224
|
return jqLite(elements);
|
11223
11225
|
}
|
@@ -11618,11 +11620,11 @@ function setupModuleLoader(window) {
|
|
11618
11620
|
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
|
11619
11621
|
*/
|
11620
11622
|
var version = {
|
11621
|
-
full: '1.2.
|
11623
|
+
full: '1.2.4', // all of these placeholder strings will be replaced by grunt's
|
11622
11624
|
major: 1, // package task
|
11623
11625
|
minor: 2,
|
11624
|
-
dot:
|
11625
|
-
codeName: '
|
11626
|
+
dot: 4,
|
11627
|
+
codeName: 'wormhole-baster'
|
11626
11628
|
};
|
11627
11629
|
|
11628
11630
|
|
@@ -12563,7 +12565,11 @@ forEach({
|
|
12563
12565
|
},
|
12564
12566
|
|
12565
12567
|
find: function(element, selector) {
|
12566
|
-
|
12568
|
+
if (element.getElementsByTagName) {
|
12569
|
+
return element.getElementsByTagName(selector);
|
12570
|
+
} else {
|
12571
|
+
return [];
|
12572
|
+
}
|
12567
12573
|
},
|
12568
12574
|
|
12569
12575
|
clone: jqLiteClone,
|
@@ -12893,7 +12899,7 @@ function annotate(fn) {
|
|
12893
12899
|
* // ...
|
12894
12900
|
* }
|
12895
12901
|
* // Define function dependencies
|
12896
|
-
* MyController
|
12902
|
+
* MyController['$inject'] = ['$scope', '$route'];
|
12897
12903
|
*
|
12898
12904
|
* // Then
|
12899
12905
|
* expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);
|
@@ -14595,7 +14601,7 @@ function $TemplateCacheProvider() {
|
|
14595
14601
|
* * (no prefix) - Locate the required controller on the current element. Throw an error if not found.
|
14596
14602
|
* * `?` - Attempt to locate the required controller or pass `null` to the `link` fn if not found.
|
14597
14603
|
* * `^` - Locate the required controller by searching the element's parents. Throw an error if not found.
|
14598
|
-
* * `?^` - Attempt to locate the required controller by searching the element's
|
14604
|
+
* * `?^` - Attempt to locate the required controller by searching the element's parents or pass `null` to the
|
14599
14605
|
* `link` fn if not found.
|
14600
14606
|
*
|
14601
14607
|
*
|
@@ -15334,7 +15340,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
15334
15340
|
createBoundTranscludeFn(scope, childTranscludeFn || transcludeFn)
|
15335
15341
|
);
|
15336
15342
|
} else {
|
15337
|
-
nodeLinkFn(childLinkFn, childScope, node,
|
15343
|
+
nodeLinkFn(childLinkFn, childScope, node, $rootElement, boundTranscludeFn);
|
15338
15344
|
}
|
15339
15345
|
} else if (childLinkFn) {
|
15340
15346
|
childLinkFn(scope, node.childNodes, undefined, boundTranscludeFn);
|
@@ -15841,13 +15847,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
15841
15847
|
// we are out of sync and need to copy
|
15842
15848
|
if (parentValue !== lastValue) {
|
15843
15849
|
// parent changed and it has precedence
|
15844
|
-
|
15850
|
+
isolateScope[scopeName] = parentValue;
|
15845
15851
|
} else {
|
15846
15852
|
// if the parent can be assigned then do so
|
15847
|
-
parentSet(scope, parentValue =
|
15853
|
+
parentSet(scope, parentValue = isolateScope[scopeName]);
|
15848
15854
|
}
|
15849
15855
|
}
|
15850
|
-
return parentValue;
|
15856
|
+
return lastValue = parentValue;
|
15851
15857
|
});
|
15852
15858
|
break;
|
15853
15859
|
|
@@ -17840,8 +17846,8 @@ function $InterpolateProvider() {
|
|
17840
17846
|
*
|
17841
17847
|
<pre>
|
17842
17848
|
var $interpolate = ...; // injected
|
17843
|
-
var exp = $interpolate('Hello {{name}}!');
|
17844
|
-
expect(exp({name:'Angular'}).toEqual('Hello
|
17849
|
+
var exp = $interpolate('Hello {{name | uppercase}}!');
|
17850
|
+
expect(exp({name:'Angular'}).toEqual('Hello ANGULAR!');
|
17845
17851
|
</pre>
|
17846
17852
|
*
|
17847
17853
|
*
|
@@ -19039,23 +19045,24 @@ function ensureSafeMemberName(name, fullExpression) {
|
|
19039
19045
|
|
19040
19046
|
function ensureSafeObject(obj, fullExpression) {
|
19041
19047
|
// nifty check if obj is Function that is fast and works across iframes and other contexts
|
19042
|
-
if (obj
|
19043
|
-
|
19044
|
-
|
19045
|
-
|
19046
|
-
|
19047
|
-
|
19048
|
-
|
19049
|
-
|
19050
|
-
|
19051
|
-
|
19052
|
-
|
19053
|
-
|
19054
|
-
|
19055
|
-
|
19056
|
-
|
19057
|
-
|
19048
|
+
if (obj) {
|
19049
|
+
if (obj.constructor === obj) {
|
19050
|
+
throw $parseMinErr('isecfn',
|
19051
|
+
'Referencing Function in Angular expressions is disallowed! Expression: {0}',
|
19052
|
+
fullExpression);
|
19053
|
+
} else if (// isWindow(obj)
|
19054
|
+
obj.document && obj.location && obj.alert && obj.setInterval) {
|
19055
|
+
throw $parseMinErr('isecwindow',
|
19056
|
+
'Referencing the Window in Angular expressions is disallowed! Expression: {0}',
|
19057
|
+
fullExpression);
|
19058
|
+
} else if (// isElement(obj)
|
19059
|
+
obj.children && (obj.nodeName || (obj.on && obj.find))) {
|
19060
|
+
throw $parseMinErr('isecdom',
|
19061
|
+
'Referencing DOM nodes in Angular expressions is disallowed! Expression: {0}',
|
19062
|
+
fullExpression);
|
19063
|
+
}
|
19058
19064
|
}
|
19065
|
+
return obj;
|
19059
19066
|
}
|
19060
19067
|
|
19061
19068
|
var OPERATORS = {
|
@@ -20813,6 +20820,7 @@ function qFactory(nextTick, exceptionHandler) {
|
|
20813
20820
|
function $RootScopeProvider(){
|
20814
20821
|
var TTL = 10;
|
20815
20822
|
var $rootScopeMinErr = minErr('$rootScope');
|
20823
|
+
var lastDirtyWatch = null;
|
20816
20824
|
|
20817
20825
|
this.digestTtl = function(value) {
|
20818
20826
|
if (arguments.length) {
|
@@ -20914,7 +20922,7 @@ function $RootScopeProvider(){
|
|
20914
20922
|
*
|
20915
20923
|
*/
|
20916
20924
|
$new: function(isolate) {
|
20917
|
-
var
|
20925
|
+
var ChildScope,
|
20918
20926
|
child;
|
20919
20927
|
|
20920
20928
|
if (isolate) {
|
@@ -20924,11 +20932,11 @@ function $RootScopeProvider(){
|
|
20924
20932
|
child.$$asyncQueue = this.$$asyncQueue;
|
20925
20933
|
child.$$postDigestQueue = this.$$postDigestQueue;
|
20926
20934
|
} else {
|
20927
|
-
|
20935
|
+
ChildScope = function() {}; // should be anonymous; This is so that when the minifier munges
|
20928
20936
|
// the name it does not become random set of chars. This will then show up as class
|
20929
20937
|
// name in the debugger.
|
20930
|
-
|
20931
|
-
child = new
|
20938
|
+
ChildScope.prototype = this;
|
20939
|
+
child = new ChildScope();
|
20932
20940
|
child.$id = nextUid();
|
20933
20941
|
}
|
20934
20942
|
child['this'] = child;
|
@@ -21008,7 +21016,7 @@ function $RootScopeProvider(){
|
|
21008
21016
|
|
21009
21017
|
|
21010
21018
|
|
21011
|
-
// Using a listener function
|
21019
|
+
// Using a listener function
|
21012
21020
|
var food;
|
21013
21021
|
scope.foodCounter = 0;
|
21014
21022
|
expect(scope.foodCounter).toEqual(0);
|
@@ -21033,7 +21041,7 @@ function $RootScopeProvider(){
|
|
21033
21041
|
// Update food and run digest. Now the counter will increment
|
21034
21042
|
food = 'cheeseburger';
|
21035
21043
|
scope.$digest();
|
21036
|
-
expect(scope.foodCounter).toEqual(1);
|
21044
|
+
expect(scope.foodCounter).toEqual(1);
|
21037
21045
|
|
21038
21046
|
* </pre>
|
21039
21047
|
*
|
@@ -21067,6 +21075,8 @@ function $RootScopeProvider(){
|
|
21067
21075
|
eq: !!objectEquality
|
21068
21076
|
};
|
21069
21077
|
|
21078
|
+
lastDirtyWatch = null;
|
21079
|
+
|
21070
21080
|
// in the case user pass string, we need to compile it, do we really need this ?
|
21071
21081
|
if (!isFunction(listener)) {
|
21072
21082
|
var listenFn = compileToFn(listener || noop, 'listener');
|
@@ -21295,6 +21305,8 @@ function $RootScopeProvider(){
|
|
21295
21305
|
|
21296
21306
|
beginPhase('$digest');
|
21297
21307
|
|
21308
|
+
lastDirtyWatch = null;
|
21309
|
+
|
21298
21310
|
do { // "while dirty" loop
|
21299
21311
|
dirty = false;
|
21300
21312
|
current = target;
|
@@ -21304,10 +21316,13 @@ function $RootScopeProvider(){
|
|
21304
21316
|
asyncTask = asyncQueue.shift();
|
21305
21317
|
asyncTask.scope.$eval(asyncTask.expression);
|
21306
21318
|
} catch (e) {
|
21319
|
+
clearPhase();
|
21307
21320
|
$exceptionHandler(e);
|
21308
21321
|
}
|
21322
|
+
lastDirtyWatch = null;
|
21309
21323
|
}
|
21310
21324
|
|
21325
|
+
traverseScopesLoop:
|
21311
21326
|
do { // "traverse the scopes" loop
|
21312
21327
|
if ((watchers = current.$$watchers)) {
|
21313
21328
|
// process our watches
|
@@ -21317,25 +21332,34 @@ function $RootScopeProvider(){
|
|
21317
21332
|
watch = watchers[length];
|
21318
21333
|
// Most common watches are on primitives, in which case we can short
|
21319
21334
|
// circuit it with === operator, only when === fails do we use .equals
|
21320
|
-
if (watch
|
21321
|
-
|
21322
|
-
|
21323
|
-
|
21324
|
-
|
21325
|
-
|
21326
|
-
|
21327
|
-
|
21328
|
-
|
21329
|
-
|
21330
|
-
if (
|
21331
|
-
|
21332
|
-
|
21333
|
-
|
21334
|
-
|
21335
|
-
|
21335
|
+
if (watch) {
|
21336
|
+
if ((value = watch.get(current)) !== (last = watch.last) &&
|
21337
|
+
!(watch.eq
|
21338
|
+
? equals(value, last)
|
21339
|
+
: (typeof value == 'number' && typeof last == 'number'
|
21340
|
+
&& isNaN(value) && isNaN(last)))) {
|
21341
|
+
dirty = true;
|
21342
|
+
lastDirtyWatch = watch;
|
21343
|
+
watch.last = watch.eq ? copy(value) : value;
|
21344
|
+
watch.fn(value, ((last === initWatchVal) ? value : last), current);
|
21345
|
+
if (ttl < 5) {
|
21346
|
+
logIdx = 4 - ttl;
|
21347
|
+
if (!watchLog[logIdx]) watchLog[logIdx] = [];
|
21348
|
+
logMsg = (isFunction(watch.exp))
|
21349
|
+
? 'fn: ' + (watch.exp.name || watch.exp.toString())
|
21350
|
+
: watch.exp;
|
21351
|
+
logMsg += '; newVal: ' + toJson(value) + '; oldVal: ' + toJson(last);
|
21352
|
+
watchLog[logIdx].push(logMsg);
|
21353
|
+
}
|
21354
|
+
} else if (watch === lastDirtyWatch) {
|
21355
|
+
// If the most recently dirty watcher is now clean, short circuit since the remaining watchers
|
21356
|
+
// have already been tested.
|
21357
|
+
dirty = false;
|
21358
|
+
break traverseScopesLoop;
|
21336
21359
|
}
|
21337
21360
|
}
|
21338
21361
|
} catch (e) {
|
21362
|
+
clearPhase();
|
21339
21363
|
$exceptionHandler(e);
|
21340
21364
|
}
|
21341
21365
|
}
|
@@ -21344,13 +21368,16 @@ function $RootScopeProvider(){
|
|
21344
21368
|
// Insanity Warning: scope depth-first traversal
|
21345
21369
|
// yes, this code is a bit crazy, but it works and we have tests to prove it!
|
21346
21370
|
// this piece should be kept in sync with the traversal in $broadcast
|
21347
|
-
if (!(next = (current.$$childHead ||
|
21371
|
+
if (!(next = (current.$$childHead ||
|
21372
|
+
(current !== target && current.$$nextSibling)))) {
|
21348
21373
|
while(current !== target && !(next = current.$$nextSibling)) {
|
21349
21374
|
current = current.$parent;
|
21350
21375
|
}
|
21351
21376
|
}
|
21352
21377
|
} while ((current = next));
|
21353
21378
|
|
21379
|
+
// `break traverseScopesLoop;` takes us to here
|
21380
|
+
|
21354
21381
|
if(dirty && !(ttl--)) {
|
21355
21382
|
clearPhase();
|
21356
21383
|
throw $rootScopeMinErr('infdig',
|
@@ -21358,6 +21385,7 @@ function $RootScopeProvider(){
|
|
21358
21385
|
'Watchers fired in the last 5 iterations: {1}',
|
21359
21386
|
TTL, toJson(watchLog));
|
21360
21387
|
}
|
21388
|
+
|
21361
21389
|
} while (dirty || asyncQueue.length);
|
21362
21390
|
|
21363
21391
|
clearPhase();
|
@@ -21410,11 +21438,12 @@ function $RootScopeProvider(){
|
|
21410
21438
|
*/
|
21411
21439
|
$destroy: function() {
|
21412
21440
|
// we can't destroy the root scope or a scope that has been already destroyed
|
21413
|
-
if (
|
21441
|
+
if (this.$$destroyed) return;
|
21414
21442
|
var parent = this.$parent;
|
21415
21443
|
|
21416
21444
|
this.$broadcast('$destroy');
|
21417
21445
|
this.$$destroyed = true;
|
21446
|
+
if (this === $rootScope) return;
|
21418
21447
|
|
21419
21448
|
if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling;
|
21420
21449
|
if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling;
|
@@ -21452,7 +21481,7 @@ function $RootScopeProvider(){
|
|
21452
21481
|
*
|
21453
21482
|
* - `string`: execute using the rules as defined in {@link guide/expression expression}.
|
21454
21483
|
* - `function(scope)`: execute the function with the current `scope` parameter.
|
21455
|
-
*
|
21484
|
+
*
|
21456
21485
|
* @param {(object)=} locals Local variables object, useful for overriding values in scope.
|
21457
21486
|
* @returns {*} The result of evaluating the expression.
|
21458
21487
|
*/
|
@@ -23320,13 +23349,15 @@ function urlIsSameOrigin(requestUrl) {
|
|
23320
23349
|
<doc:source>
|
23321
23350
|
<script>
|
23322
23351
|
function Ctrl($scope, $window) {
|
23323
|
-
$scope.$window = $window;
|
23324
23352
|
$scope.greeting = 'Hello, World!';
|
23353
|
+
$scope.doGreeting = function(greeting) {
|
23354
|
+
$window.alert(greeting);
|
23355
|
+
};
|
23325
23356
|
}
|
23326
23357
|
</script>
|
23327
23358
|
<div ng-controller="Ctrl">
|
23328
23359
|
<input type="text" ng-model="greeting" />
|
23329
|
-
<button ng-click="
|
23360
|
+
<button ng-click="doGreeting(greeting)">ALERT</button>
|
23330
23361
|
</div>
|
23331
23362
|
</doc:source>
|
23332
23363
|
<doc:scenario>
|
@@ -24833,9 +24864,22 @@ var nullFormCtrl = {
|
|
24833
24864
|
* @property {Object} $error Is an object hash, containing references to all invalid controls or
|
24834
24865
|
* forms, where:
|
24835
24866
|
*
|
24836
|
-
* - keys are validation tokens (error names)
|
24837
|
-
* - values are arrays of controls or forms that are invalid
|
24867
|
+
* - keys are validation tokens (error names),
|
24868
|
+
* - values are arrays of controls or forms that are invalid for given error name.
|
24838
24869
|
*
|
24870
|
+
*
|
24871
|
+
* Built-in validation tokens:
|
24872
|
+
*
|
24873
|
+
* - `email`
|
24874
|
+
* - `max`
|
24875
|
+
* - `maxlength`
|
24876
|
+
* - `min`
|
24877
|
+
* - `minlength`
|
24878
|
+
* - `number`
|
24879
|
+
* - `pattern`
|
24880
|
+
* - `required`
|
24881
|
+
* - `url`
|
24882
|
+
*
|
24839
24883
|
* @description
|
24840
24884
|
* `FormController` keeps track of all its controls and nested forms as well as state of them,
|
24841
24885
|
* such as being valid/invalid or dirty/pristine.
|
@@ -26129,39 +26173,6 @@ var VALID_CLASS = 'ng-valid',
|
|
26129
26173
|
</file>
|
26130
26174
|
* </example>
|
26131
26175
|
*
|
26132
|
-
* ## Isolated Scope Pitfall
|
26133
|
-
*
|
26134
|
-
* Note that if you have a directive with an isolated scope, you cannot require `ngModel`
|
26135
|
-
* since the model value will be looked up on the isolated scope rather than the outer scope.
|
26136
|
-
* When the directive updates the model value, calling `ngModel.$setViewValue()` the property
|
26137
|
-
* on the outer scope will not be updated. However you can get around this by using $parent.
|
26138
|
-
*
|
26139
|
-
* Here is an example of this situation. You'll notice that the first div is not updating the input.
|
26140
|
-
* However the second div can update the input properly.
|
26141
|
-
*
|
26142
|
-
* <example module="badIsolatedDirective">
|
26143
|
-
<file name="script.js">
|
26144
|
-
angular.module('badIsolatedDirective', []).directive('isolate', function() {
|
26145
|
-
return {
|
26146
|
-
require: 'ngModel',
|
26147
|
-
scope: { },
|
26148
|
-
template: '<input ng-model="innerModel">',
|
26149
|
-
link: function(scope, element, attrs, ngModel) {
|
26150
|
-
scope.$watch('innerModel', function(value) {
|
26151
|
-
console.log(value);
|
26152
|
-
ngModel.$setViewValue(value);
|
26153
|
-
});
|
26154
|
-
}
|
26155
|
-
};
|
26156
|
-
});
|
26157
|
-
</file>
|
26158
|
-
<file name="index.html">
|
26159
|
-
<input ng-model="someModel"/>
|
26160
|
-
<div isolate ng-model="someModel"></div>
|
26161
|
-
<div isolate ng-model="$parent.someModel"></div>
|
26162
|
-
</file>
|
26163
|
-
* </example>
|
26164
|
-
*
|
26165
26176
|
*
|
26166
26177
|
*/
|
26167
26178
|
var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$parse',
|
@@ -26308,7 +26319,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
26308
26319
|
* It will update the $viewValue, then pass this value through each of the functions in `$parsers`,
|
26309
26320
|
* which includes any validators. The value that comes out of this `$parsers` pipeline, be applied to
|
26310
26321
|
* `$modelValue` and the **expression** specified in the `ng-model` attribute.
|
26311
|
-
*
|
26322
|
+
*
|
26312
26323
|
* Lastly, all the registered change listeners, in the `$viewChangeListeners` list, are called.
|
26313
26324
|
*
|
26314
26325
|
* Note that calling this function does not trigger a `$digest`.
|
@@ -26365,6 +26376,8 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
26365
26376
|
ctrl.$render();
|
26366
26377
|
}
|
26367
26378
|
}
|
26379
|
+
|
26380
|
+
return value;
|
26368
26381
|
});
|
26369
26382
|
}];
|
26370
26383
|
|
@@ -27858,9 +27871,12 @@ var ngIfDirective = ['$animate', function($animate) {
|
|
27858
27871
|
if (!childScope) {
|
27859
27872
|
childScope = $scope.$new();
|
27860
27873
|
$transclude(childScope, function (clone) {
|
27874
|
+
clone[clone.length++] = document.createComment(' end ngIf: ' + $attr.ngIf + ' ');
|
27875
|
+
// Note: We only need the first/last node of the cloned nodes.
|
27876
|
+
// However, we need to keep the reference to the jqlite wrapper as it might be changed later
|
27877
|
+
// by a directive with templateUrl when it's template arrives.
|
27861
27878
|
block = {
|
27862
|
-
|
27863
|
-
endNode: clone[clone.length++] = document.createComment(' end ngIf: ' + $attr.ngIf + ' ')
|
27879
|
+
clone: clone
|
27864
27880
|
};
|
27865
27881
|
$animate.enter(clone, $element.parent(), $element);
|
27866
27882
|
});
|
@@ -27873,7 +27889,7 @@ var ngIfDirective = ['$animate', function($animate) {
|
|
27873
27889
|
}
|
27874
27890
|
|
27875
27891
|
if (block) {
|
27876
|
-
$animate.leave(getBlockElements(block));
|
27892
|
+
$animate.leave(getBlockElements(block.clone));
|
27877
27893
|
block = null;
|
27878
27894
|
}
|
27879
27895
|
}
|
@@ -28116,6 +28132,8 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'
|
|
28116
28132
|
* to initialize values on a scope.
|
28117
28133
|
* </div>
|
28118
28134
|
*
|
28135
|
+
* @priority 450
|
28136
|
+
*
|
28119
28137
|
* @element ANY
|
28120
28138
|
* @param {expression} ngInit {@link guide/expression Expression} to eval.
|
28121
28139
|
*
|
@@ -28147,6 +28165,7 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'
|
|
28147
28165
|
</doc:example>
|
28148
28166
|
*/
|
28149
28167
|
var ngInitDirective = ngDirective({
|
28168
|
+
priority: 450,
|
28150
28169
|
compile: function() {
|
28151
28170
|
return {
|
28152
28171
|
pre: function(scope, element, attrs) {
|
@@ -28704,7 +28723,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
28704
28723
|
} else if (nextBlockMap.hasOwnProperty(trackById)) {
|
28705
28724
|
// restore lastBlockMap
|
28706
28725
|
forEach(nextBlockOrder, function(block) {
|
28707
|
-
if (block && block.
|
28726
|
+
if (block && block.scope) lastBlockMap[block.id] = block;
|
28708
28727
|
});
|
28709
28728
|
// This is a duplicate and we need to throw an error
|
28710
28729
|
throw ngRepeatMinErr('dupes', "Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}",
|
@@ -28721,7 +28740,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
28721
28740
|
// lastBlockMap is our own object so we don't need to use special hasOwnPropertyFn
|
28722
28741
|
if (lastBlockMap.hasOwnProperty(key)) {
|
28723
28742
|
block = lastBlockMap[key];
|
28724
|
-
elementsToRemove = getBlockElements(block);
|
28743
|
+
elementsToRemove = getBlockElements(block.clone);
|
28725
28744
|
$animate.leave(elementsToRemove);
|
28726
28745
|
forEach(elementsToRemove, function(element) { element[NG_REMOVED] = true; });
|
28727
28746
|
block.scope.$destroy();
|
@@ -28733,9 +28752,9 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
28733
28752
|
key = (collection === collectionKeys) ? index : collectionKeys[index];
|
28734
28753
|
value = collection[key];
|
28735
28754
|
block = nextBlockOrder[index];
|
28736
|
-
if (nextBlockOrder[index - 1]) previousNode = nextBlockOrder[index - 1]
|
28755
|
+
if (nextBlockOrder[index - 1]) previousNode = getBlockEnd(nextBlockOrder[index - 1]);
|
28737
28756
|
|
28738
|
-
if (block.
|
28757
|
+
if (block.scope) {
|
28739
28758
|
// if we have already seen this object, then we need to reuse the
|
28740
28759
|
// associated scope/element
|
28741
28760
|
childScope = block.scope;
|
@@ -28745,11 +28764,11 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
28745
28764
|
nextNode = nextNode.nextSibling;
|
28746
28765
|
} while(nextNode && nextNode[NG_REMOVED]);
|
28747
28766
|
|
28748
|
-
if (block
|
28767
|
+
if (getBlockStart(block) != nextNode) {
|
28749
28768
|
// existing item which got moved
|
28750
|
-
$animate.move(getBlockElements(block), null, jqLite(previousNode));
|
28769
|
+
$animate.move(getBlockElements(block.clone), null, jqLite(previousNode));
|
28751
28770
|
}
|
28752
|
-
previousNode = block
|
28771
|
+
previousNode = getBlockEnd(block);
|
28753
28772
|
} else {
|
28754
28773
|
// new item which we don't know about
|
28755
28774
|
childScope = $scope.$new();
|
@@ -28765,14 +28784,16 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
28765
28784
|
childScope.$odd = !(childScope.$even = (index&1) === 0);
|
28766
28785
|
// jshint bitwise: true
|
28767
28786
|
|
28768
|
-
if (!block.
|
28787
|
+
if (!block.scope) {
|
28769
28788
|
$transclude(childScope, function(clone) {
|
28770
28789
|
clone[clone.length++] = document.createComment(' end ngRepeat: ' + expression + ' ');
|
28771
28790
|
$animate.enter(clone, null, jqLite(previousNode));
|
28772
28791
|
previousNode = clone;
|
28773
28792
|
block.scope = childScope;
|
28774
|
-
|
28775
|
-
|
28793
|
+
// Note: We only need the first/last node of the cloned nodes.
|
28794
|
+
// However, we need to keep the reference to the jqlite wrapper as it might be changed later
|
28795
|
+
// by a directive with templateUrl when it's template arrives.
|
28796
|
+
block.clone = clone;
|
28776
28797
|
nextBlockMap[block.id] = block;
|
28777
28798
|
});
|
28778
28799
|
}
|
@@ -28781,6 +28802,14 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
28781
28802
|
});
|
28782
28803
|
}
|
28783
28804
|
};
|
28805
|
+
|
28806
|
+
function getBlockStart(block) {
|
28807
|
+
return block.clone[0];
|
28808
|
+
}
|
28809
|
+
|
28810
|
+
function getBlockEnd(block) {
|
28811
|
+
return block.clone[block.clone.length - 1];
|
28812
|
+
}
|
28784
28813
|
}];
|
28785
28814
|
|
28786
28815
|
/**
|