@angular-wave/angular.ts 0.7.5 → 0.7.7
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.
- package/@types/core/scope/scope.d.ts +0 -2
- package/@types/directive/setter/setter.d.ts +2 -2
- package/@types/shared/utils.d.ts +8 -0
- package/dist/angular-ts.esm.js +208 -176
- package/dist/angular-ts.umd.js +208 -176
- package/dist/angular-ts.umd.min.js +1 -1
- package/docs/assets/scss/index.scss +12 -0
- package/docs/content/_index.md +15 -4
- package/docs/content/docs/directive/bind.md +70 -0
- package/docs/content/docs/directive/click.md +3 -0
- package/docs/content/docs/directive/dblclick.md +3 -0
- package/docs/content/docs/directive/keydown.md +38 -0
- package/docs/content/docs/directive/keyup.md +38 -0
- package/docs/content/docs/directive/load.md +43 -0
- package/docs/static/examples/ng-bind/ng-bind.html +9 -0
- package/docs/static/examples/ng-keydown/ng-keydown.html +9 -0
- package/docs/static/examples/ng-keyup/ng-keyup.html +9 -0
- package/docs/static/examples/ng-load/ng-load.html +8 -0
- package/legacy.d.ts +0 -4
- package/package.json +1 -1
- package/src/core/location/location.js +1 -1
- package/src/core/scope/scope.js +0 -5
- package/src/directive/bind/bind.js +16 -4
- package/src/directive/bind/bind.spec.js +13 -0
- package/src/directive/events/events.js +1 -1
- package/src/directive/events/events.md +0 -41
- package/src/directive/messages/messages.js +1 -1
- package/src/directive/repeat/repeat.js +175 -153
- package/src/directive/setter/setter.js +1 -1
- package/src/directive/switch/switch.spec.js +1 -1
- package/src/router/directives/state-directives.js +4 -6
- package/src/services/anchor-scroll.js +1 -1
- package/src/shared/utils.js +19 -1
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
minErr,
|
|
3
|
+
hashKey,
|
|
4
|
+
isArrayLike,
|
|
5
|
+
hasOwn,
|
|
6
|
+
isDefined,
|
|
7
|
+
callBackOnce,
|
|
8
|
+
} from "../../shared/utils.js";
|
|
9
|
+
import { getBlockNodes, removeElement } from "../../shared/dom.js";
|
|
3
10
|
import { $injectTokens } from "../../injection-tokens.js";
|
|
4
11
|
|
|
5
12
|
const NG_REMOVED = "$$NG_REMOVED";
|
|
@@ -78,7 +85,7 @@ export function ngRepeatDirective($animate) {
|
|
|
78
85
|
transclude: "element",
|
|
79
86
|
priority: 1000,
|
|
80
87
|
terminal: true,
|
|
81
|
-
compile: (
|
|
88
|
+
compile: ($element, $attr) => {
|
|
82
89
|
const expression = $attr["ngRepeat"];
|
|
83
90
|
const hasAnimate = !!$attr["animate"];
|
|
84
91
|
|
|
@@ -126,6 +133,14 @@ export function ngRepeatDirective($animate) {
|
|
|
126
133
|
|
|
127
134
|
let trackByIdExpFn;
|
|
128
135
|
|
|
136
|
+
const swap = callBackOnce(() => {
|
|
137
|
+
if (isDefined($attr["lazy"]) && isDefined($attr["swap"])) {
|
|
138
|
+
document
|
|
139
|
+
.querySelectorAll($attr["swap"])
|
|
140
|
+
.forEach((x) => removeElement(x));
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
|
|
129
144
|
return function ngRepeatLink($scope, $element, $attr, ctrl, $transclude) {
|
|
130
145
|
// Store a list of elements from previous run. This is a hash where key is the item from the
|
|
131
146
|
// iterator, and the value is objects with following properties.
|
|
@@ -137,174 +152,181 @@ export function ngRepeatDirective($animate) {
|
|
|
137
152
|
// hasOwnProperty.
|
|
138
153
|
let lastBlockMap = Object.create(null);
|
|
139
154
|
// watch props
|
|
140
|
-
$scope.$watch(
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
155
|
+
$scope.$watch(
|
|
156
|
+
rhs,
|
|
157
|
+
(collection) => {
|
|
158
|
+
swap();
|
|
159
|
+
let index,
|
|
160
|
+
length,
|
|
161
|
+
previousNode = $element, // node that cloned nodes should be inserted after
|
|
162
|
+
// initialized to the comment node anchor
|
|
163
|
+
nextNode;
|
|
164
|
+
const // Same as lastBlockMap but it has the current state. It will become the
|
|
165
|
+
// lastBlockMap on the next iteration.
|
|
166
|
+
nextBlockMap = Object.create(null);
|
|
167
|
+
let collectionLength,
|
|
168
|
+
key,
|
|
169
|
+
value, // key/value of iteration
|
|
170
|
+
trackById,
|
|
171
|
+
trackByIdFn,
|
|
172
|
+
collectionKeys,
|
|
173
|
+
block, // last object information {scope, element, id}
|
|
174
|
+
nextBlockOrder,
|
|
175
|
+
elementsToRemove;
|
|
158
176
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
177
|
+
if (aliasAs) {
|
|
178
|
+
$scope[aliasAs] = collection;
|
|
179
|
+
}
|
|
162
180
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
181
|
+
if (isArrayLike(collection)) {
|
|
182
|
+
collectionKeys = collection;
|
|
183
|
+
trackByIdFn = trackByIdExpFn || trackByIdArrayFn;
|
|
184
|
+
} else {
|
|
185
|
+
trackByIdFn = trackByIdExpFn || trackByIdObjFn;
|
|
186
|
+
// if object, extract keys, in enumeration order, unsorted
|
|
187
|
+
collectionKeys = [];
|
|
188
|
+
for (const itemKey in collection) {
|
|
189
|
+
if (hasOwn(collection, itemKey) && itemKey.charAt(0) !== "$") {
|
|
190
|
+
collectionKeys.push(itemKey);
|
|
191
|
+
}
|
|
173
192
|
}
|
|
174
193
|
}
|
|
175
|
-
}
|
|
176
194
|
|
|
177
|
-
|
|
178
|
-
|
|
195
|
+
collectionLength = collectionKeys.length;
|
|
196
|
+
nextBlockOrder = new Array(collectionLength);
|
|
179
197
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
198
|
+
// locate existing items
|
|
199
|
+
for (index = 0; index < collectionLength; index++) {
|
|
200
|
+
key =
|
|
201
|
+
collection === collectionKeys ? index : collectionKeys[index];
|
|
202
|
+
value = collection[key];
|
|
203
|
+
trackById = trackByIdFn($scope, key, value);
|
|
204
|
+
if (lastBlockMap[trackById]) {
|
|
205
|
+
// found previously seen block
|
|
206
|
+
block = lastBlockMap[trackById];
|
|
207
|
+
delete lastBlockMap[trackById];
|
|
208
|
+
nextBlockMap[trackById] = block;
|
|
209
|
+
nextBlockOrder[index] = block;
|
|
210
|
+
} else if (nextBlockMap[trackById]) {
|
|
211
|
+
// if collision detected. restore lastBlockMap and throw an error
|
|
212
|
+
Object.values(nextBlockOrder).forEach((block) => {
|
|
213
|
+
if (block && block.scope) lastBlockMap[block.id] = block;
|
|
214
|
+
});
|
|
215
|
+
throw ngRepeatMinErr(
|
|
216
|
+
"dupes",
|
|
217
|
+
"Duplicates keys in a repeater are not allowed. Repeater: {0}, Duplicate key: {1} for value: {2}",
|
|
218
|
+
expression,
|
|
219
|
+
trackById,
|
|
220
|
+
value,
|
|
221
|
+
);
|
|
222
|
+
} else {
|
|
223
|
+
// new never before seen block
|
|
224
|
+
nextBlockOrder[index] = {
|
|
225
|
+
id: trackById,
|
|
226
|
+
scope: undefined,
|
|
227
|
+
clone: undefined,
|
|
228
|
+
};
|
|
229
|
+
nextBlockMap[trackById] = true;
|
|
230
|
+
}
|
|
211
231
|
}
|
|
212
|
-
}
|
|
213
232
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}
|
|
223
|
-
if (elementsToRemove.parentNode) {
|
|
224
|
-
// if the element was not removed yet because of pending animation, mark it as deleted
|
|
225
|
-
// so that we can ignore it later
|
|
226
|
-
for (
|
|
227
|
-
index = 0, length = elementsToRemove.length;
|
|
228
|
-
index < length;
|
|
229
|
-
index++
|
|
230
|
-
) {
|
|
231
|
-
elementsToRemove[index][NG_REMOVED] = true;
|
|
233
|
+
// remove leftover items
|
|
234
|
+
for (let blockKey in lastBlockMap) {
|
|
235
|
+
block = lastBlockMap[blockKey];
|
|
236
|
+
elementsToRemove = block.clone;
|
|
237
|
+
if (hasAnimate) {
|
|
238
|
+
$animate.leave(elementsToRemove);
|
|
239
|
+
} else {
|
|
240
|
+
elementsToRemove.remove();
|
|
232
241
|
}
|
|
242
|
+
if (elementsToRemove.parentNode) {
|
|
243
|
+
// if the element was not removed yet because of pending animation, mark it as deleted
|
|
244
|
+
// so that we can ignore it later
|
|
245
|
+
for (
|
|
246
|
+
index = 0, length = elementsToRemove.length;
|
|
247
|
+
index < length;
|
|
248
|
+
index++
|
|
249
|
+
) {
|
|
250
|
+
elementsToRemove[index][NG_REMOVED] = true;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
block.scope.$destroy();
|
|
233
254
|
}
|
|
234
|
-
block.scope.$destroy();
|
|
235
|
-
}
|
|
236
255
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
256
|
+
for (index = 0; index < collectionLength; index++) {
|
|
257
|
+
key =
|
|
258
|
+
collection === collectionKeys ? index : collectionKeys[index];
|
|
259
|
+
value = collection[key];
|
|
260
|
+
block = nextBlockOrder[index];
|
|
241
261
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
262
|
+
if (block.scope) {
|
|
263
|
+
// if we have already seen this object, then we need to reuse the
|
|
264
|
+
// associated scope/element
|
|
245
265
|
|
|
246
|
-
|
|
266
|
+
nextNode = previousNode;
|
|
247
267
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
268
|
+
// skip nodes that are already pending removal via leave animation
|
|
269
|
+
do {
|
|
270
|
+
nextNode = nextNode.nextSibling;
|
|
271
|
+
} while (nextNode && nextNode[NG_REMOVED]);
|
|
252
272
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
273
|
+
if (getBlockStart(block) !== nextNode) {
|
|
274
|
+
// existing item which got moved
|
|
275
|
+
$animate.move(getBlockNodes(block.clone), null, previousNode);
|
|
276
|
+
}
|
|
277
|
+
previousNode = getBlockEnd(block);
|
|
278
|
+
updateScope(
|
|
279
|
+
block.scope,
|
|
280
|
+
index,
|
|
281
|
+
valueIdentifier,
|
|
282
|
+
value,
|
|
283
|
+
keyIdentifier,
|
|
284
|
+
key,
|
|
285
|
+
collectionLength,
|
|
286
|
+
);
|
|
287
|
+
} else {
|
|
288
|
+
// new item which we don't know about
|
|
289
|
+
$transclude(
|
|
290
|
+
/**
|
|
291
|
+
* Clone attach function
|
|
292
|
+
* @param {Array<NodeList>} clone
|
|
293
|
+
* @param {import("../../core/scope/scope.js").Scope} scope
|
|
294
|
+
*/
|
|
275
295
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
296
|
+
(clone, scope) => {
|
|
297
|
+
block.scope = scope;
|
|
298
|
+
const endNode = clone;
|
|
299
|
+
if (hasAnimate) {
|
|
300
|
+
$animate.enter(clone, null, previousNode);
|
|
301
|
+
} else {
|
|
302
|
+
// @ts-ignore
|
|
303
|
+
previousNode.after(clone);
|
|
304
|
+
}
|
|
285
305
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
306
|
+
// @ts-ignore
|
|
307
|
+
previousNode = endNode;
|
|
308
|
+
// Note: We only need the first/last node of the cloned nodes.
|
|
309
|
+
// However, we need to keep the reference to the dom wrapper as it might be changed later
|
|
310
|
+
// by a directive with templateUrl when its template arrives.
|
|
311
|
+
block.clone = clone;
|
|
312
|
+
nextBlockMap[block.id] = block;
|
|
313
|
+
updateScope(
|
|
314
|
+
block.scope,
|
|
315
|
+
index,
|
|
316
|
+
valueIdentifier,
|
|
317
|
+
value,
|
|
318
|
+
keyIdentifier,
|
|
319
|
+
key,
|
|
320
|
+
collectionLength,
|
|
321
|
+
);
|
|
322
|
+
},
|
|
323
|
+
);
|
|
324
|
+
}
|
|
304
325
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
326
|
+
lastBlockMap = nextBlockMap;
|
|
327
|
+
},
|
|
328
|
+
isDefined($attr["lazy"]),
|
|
329
|
+
);
|
|
308
330
|
};
|
|
309
331
|
},
|
|
310
332
|
};
|
|
@@ -2,7 +2,7 @@ ngSetterDirective.$inject = ["$parse", "$log"];
|
|
|
2
2
|
/**
|
|
3
3
|
* @param {import('../../core/parse/interface.ts').ParseService} $parse
|
|
4
4
|
* @param {import('../../services/log/interface.ts').LogService} $log
|
|
5
|
-
* @returns {import('
|
|
5
|
+
* @returns {import('interface.ts').Directive}
|
|
6
6
|
*/
|
|
7
7
|
export function ngSetterDirective($parse, $log) {
|
|
8
8
|
return {
|
|
@@ -382,12 +382,10 @@ export function $StateRefActiveDirective(
|
|
|
382
382
|
const removeClasses = allClasses.filter(
|
|
383
383
|
(cls) => !addClasses.includes(cls),
|
|
384
384
|
);
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
);
|
|
390
|
-
});
|
|
385
|
+
addClasses.forEach((className) => $element.classList.add(className));
|
|
386
|
+
removeClasses.forEach((className) =>
|
|
387
|
+
$element.classList.remove(className),
|
|
388
|
+
);
|
|
391
389
|
}
|
|
392
390
|
update();
|
|
393
391
|
},
|
|
@@ -128,7 +128,7 @@ export class AnchorScrollProvider {
|
|
|
128
128
|
// skip the initial scroll if $location.hash is empty
|
|
129
129
|
if (newVal === oldVal && newVal === "") return;
|
|
130
130
|
|
|
131
|
-
const action = () =>
|
|
131
|
+
const action = () => Promise.resolve().then(scroll);
|
|
132
132
|
if (document.readyState === "complete") {
|
|
133
133
|
// Force the action to be run async for consistent behavior
|
|
134
134
|
// from the action's point of view
|
package/src/shared/utils.js
CHANGED
|
@@ -232,7 +232,7 @@ export function isWindow(obj) {
|
|
|
232
232
|
* @returns {boolean}
|
|
233
233
|
*/
|
|
234
234
|
export function isScope(obj) {
|
|
235
|
-
return obj && obj.$
|
|
235
|
+
return obj && obj.$watch;
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
/**
|
|
@@ -1193,3 +1193,21 @@ export function isObjectEmpty(obj) {
|
|
|
1193
1193
|
export function hasOwn(obj, key) {
|
|
1194
1194
|
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
1195
1195
|
}
|
|
1196
|
+
|
|
1197
|
+
/**
|
|
1198
|
+
* Wraps a function so it can only be called once.
|
|
1199
|
+
* Subsequent calls do nothing and return undefined.
|
|
1200
|
+
*
|
|
1201
|
+
* @param {Function} fn - The function to wrap.
|
|
1202
|
+
* @returns {Function} A new function that will call `fn` only once.
|
|
1203
|
+
*/
|
|
1204
|
+
export function callBackOnce(fn) {
|
|
1205
|
+
let called = false;
|
|
1206
|
+
|
|
1207
|
+
return function (...args) {
|
|
1208
|
+
if (!called) {
|
|
1209
|
+
called = true;
|
|
1210
|
+
return fn.apply(this, args);
|
|
1211
|
+
}
|
|
1212
|
+
};
|
|
1213
|
+
}
|