@angular-wave/angular.ts 0.0.40 → 0.0.41
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/README.md +1 -0
- package/dist/angular-ts.esm.js +2 -2
- package/dist/angular-ts.umd.js +2 -2
- package/package.json +1 -1
- package/src/animations/animate-queue.js +7 -4
- package/src/core/compile/compile.js +4 -2
- package/src/core/compile/compile.spec.js +2 -43
- package/src/directive/include/include.js +5 -7
- package/src/directive/options/options.js +3 -3
- package/src/services/http/http.js +11 -7
- package/src/shared/jqlite/jqlite.js +336 -315
- package/src/shared/jqlite/jqlite.spec.js +74 -82
- package/src/types.js +13 -0
- package/types/animations/shared.d.ts +6 -1
- package/types/core/compile/compile.d.ts +2 -1
- package/types/directive/include/include.d.ts +2 -2
- package/types/services/document.d.ts +2 -1
- package/types/shared/jqlite/jqlite.d.ts +83 -21
- package/types/types.d.ts +34 -0
- package/types-back/index.d.ts +0 -56
- package/types-back/jqlite.d.ts +1 -40
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
lowercase,
|
|
13
13
|
nodeName_,
|
|
14
14
|
shallowCopy,
|
|
15
|
-
trim,
|
|
16
15
|
} from "../../shared/utils";
|
|
17
16
|
import { CACHE, EXPANDO } from "../../core/cache/cache";
|
|
18
17
|
|
|
@@ -50,7 +49,6 @@ import { CACHE, EXPANDO } from "../../core/cache/cache";
|
|
|
50
49
|
* - [`html()`](http://api.jquery.com/html/)
|
|
51
50
|
* - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
|
|
52
51
|
* - [`off()`](http://api.jquery.com/off/) - Does not support namespaces, selectors or event object as parameter
|
|
53
|
-
* - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors
|
|
54
52
|
* - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors
|
|
55
53
|
* - [`prepend()`](http://api.jquery.com/prepend/)
|
|
56
54
|
* - [`remove()`](http://api.jquery.com/remove/)
|
|
@@ -152,107 +150,40 @@ wrapMap.tbody =
|
|
|
152
150
|
wrapMap.thead;
|
|
153
151
|
wrapMap.th = wrapMap.td;
|
|
154
152
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
153
|
+
export const BOOLEAN_ATTR = {};
|
|
154
|
+
"multiple,selected,checked,disabled,readOnly,required,open"
|
|
155
|
+
.split(",")
|
|
156
|
+
.forEach((value) => {
|
|
157
|
+
BOOLEAN_ATTR[lowercase(value)] = value;
|
|
158
|
+
});
|
|
159
|
+
const BOOLEAN_ELEMENTS = {};
|
|
160
|
+
"input,select,option,textarea,button,form,details"
|
|
161
|
+
.split(",")
|
|
162
|
+
.forEach((value) => {
|
|
163
|
+
BOOLEAN_ELEMENTS[value] = true;
|
|
164
|
+
});
|
|
163
165
|
|
|
164
166
|
/**
|
|
167
|
+
* JQLite both a function and an array-like data structure for manipulation of DOM, linking elements to expando cache,
|
|
168
|
+
* and execution of chain functions.
|
|
165
169
|
*
|
|
166
|
-
* @param {Element}
|
|
167
|
-
* @returns {
|
|
170
|
+
* @param {string|Element|Document|Window|JQLite|ArrayLike<Element>|(() => void)} element
|
|
171
|
+
* @returns {JQLite}
|
|
168
172
|
*/
|
|
169
|
-
function elementAcceptsData(node) {
|
|
170
|
-
// The window object can accept data but has no nodeType
|
|
171
|
-
// Otherwise we are only interested in elements (1) and documents (9)
|
|
172
|
-
switch (node.nodeType) {
|
|
173
|
-
case Node.ELEMENT_NODE:
|
|
174
|
-
case Node.DOCUMENT_NODE:
|
|
175
|
-
case undefined:
|
|
176
|
-
return true;
|
|
177
|
-
default:
|
|
178
|
-
return false;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
export function JQLiteBuildFragment(html, context) {
|
|
183
|
-
let tmp;
|
|
184
|
-
let tag;
|
|
185
|
-
let wrap;
|
|
186
|
-
let finalHtml;
|
|
187
|
-
const fragment = context.createDocumentFragment();
|
|
188
|
-
let nodes = [];
|
|
189
|
-
let i;
|
|
190
|
-
|
|
191
|
-
if (isTextNode(html)) {
|
|
192
|
-
// Convert non-html into a text node
|
|
193
|
-
nodes.push(context.createTextNode(html));
|
|
194
|
-
} else {
|
|
195
|
-
// Convert html into DOM nodes
|
|
196
|
-
tmp = fragment.appendChild(context.createElement("div"));
|
|
197
|
-
tag = (TAG_NAME_REGEXP.exec(html) || ["", ""])[1].toLowerCase();
|
|
198
|
-
finalHtml = html;
|
|
199
|
-
|
|
200
|
-
wrap = wrapMap[tag] || [];
|
|
201
|
-
|
|
202
|
-
// Create wrappers & descend into them
|
|
203
|
-
i = wrap.length;
|
|
204
|
-
while (--i > -1) {
|
|
205
|
-
tmp.appendChild(window.document.createElement(wrap[i]));
|
|
206
|
-
tmp = tmp.firstChild;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
tmp.innerHTML = finalHtml;
|
|
210
|
-
|
|
211
|
-
nodes = concat(nodes, tmp.childNodes);
|
|
212
|
-
|
|
213
|
-
tmp = fragment.firstChild;
|
|
214
|
-
tmp.textContent = "";
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// Remove wrapper from fragment
|
|
218
|
-
fragment.textContent = "";
|
|
219
|
-
fragment.innerHTML = ""; // Clear inner HTML
|
|
220
|
-
forEach(nodes, (node) => {
|
|
221
|
-
fragment.appendChild(node);
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
return fragment;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
function JQLiteParseHTML(html, context) {
|
|
228
|
-
context = context || window.document;
|
|
229
|
-
let parsed;
|
|
230
|
-
|
|
231
|
-
if ((parsed = SINGLE_TAG_REGEXP.exec(html))) {
|
|
232
|
-
return [context.createElement(parsed[1])];
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
if ((parsed = JQLiteBuildFragment(html, context))) {
|
|
236
|
-
return parsed.childNodes;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
return [];
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/// //////////////////////////////////////////
|
|
243
173
|
export function JQLite(element) {
|
|
244
174
|
if (element instanceof JQLite) {
|
|
245
175
|
return element;
|
|
246
176
|
}
|
|
247
177
|
|
|
248
|
-
let argIsString;
|
|
178
|
+
let argIsString = false;
|
|
249
179
|
|
|
250
180
|
if (isString(element)) {
|
|
251
|
-
element =
|
|
181
|
+
element = /** @type {string} */ (element).trim();
|
|
252
182
|
argIsString = true;
|
|
253
183
|
}
|
|
184
|
+
|
|
254
185
|
if (!(this instanceof JQLite)) {
|
|
255
|
-
if (argIsString && element.charAt(0) !== "<") {
|
|
186
|
+
if (argIsString && /** @type {string} */ (element).charAt(0) !== "<") {
|
|
256
187
|
throw JQLiteMinErr(
|
|
257
188
|
"nosel",
|
|
258
189
|
"Looking up elements via selectors is not supported by JQLite! See: http://docs.angularjs.org/api/angular.element",
|
|
@@ -262,49 +193,15 @@ export function JQLite(element) {
|
|
|
262
193
|
}
|
|
263
194
|
|
|
264
195
|
if (argIsString) {
|
|
265
|
-
const parsed =
|
|
196
|
+
const parsed = parseHtml(/** @type {string} */ (element));
|
|
266
197
|
addNodes(this, parsed);
|
|
267
198
|
} else if (isFunction(element)) {
|
|
268
|
-
|
|
199
|
+
onReady(/** @type {Function} */ (element));
|
|
269
200
|
} else {
|
|
270
201
|
addNodes(this, element);
|
|
271
202
|
}
|
|
272
203
|
}
|
|
273
204
|
|
|
274
|
-
/**
|
|
275
|
-
* @param {Element} element
|
|
276
|
-
* @param {boolean} [onlyDescendants]
|
|
277
|
-
* @returns {void}
|
|
278
|
-
*/
|
|
279
|
-
export function dealoc(element, onlyDescendants) {
|
|
280
|
-
if (!element) return;
|
|
281
|
-
if (!onlyDescendants && elementAcceptsData(element))
|
|
282
|
-
JQLiteCleanData([element]);
|
|
283
|
-
|
|
284
|
-
if (element.querySelectorAll) {
|
|
285
|
-
JQLiteCleanData(element.querySelectorAll("*"));
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* If `ExpandoStore.data` and `ExpandoStore.events` are empty,
|
|
291
|
-
* then delete element's `ExpandoStore` and set its `ExpandoId`
|
|
292
|
-
* to undefined.
|
|
293
|
-
* @param {Element} element
|
|
294
|
-
*/
|
|
295
|
-
function removeIfEmptyData(element) {
|
|
296
|
-
const expandoId = element[EXPANDO];
|
|
297
|
-
const { events, data } = CACHE.get(expandoId);
|
|
298
|
-
|
|
299
|
-
if (
|
|
300
|
-
(!data || !Object.keys(data).length) &&
|
|
301
|
-
(!events || !Object.keys(events).length)
|
|
302
|
-
) {
|
|
303
|
-
CACHE.delete(expandoId);
|
|
304
|
-
element[EXPANDO] = undefined; // don't delete DOM expandos. Chrome don't like it
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
205
|
function JQLiteOff(element, type, fn, unsupported) {
|
|
309
206
|
if (isDefined(unsupported))
|
|
310
207
|
throw JQLiteMinErr(
|
|
@@ -312,7 +209,7 @@ function JQLiteOff(element, type, fn, unsupported) {
|
|
|
312
209
|
"jqLite#off() does not support the `selector` argument",
|
|
313
210
|
);
|
|
314
211
|
|
|
315
|
-
const expandoStore =
|
|
212
|
+
const expandoStore = getExpando(element);
|
|
316
213
|
const events = expandoStore && expandoStore.events;
|
|
317
214
|
const handle = expandoStore && expandoStore.handle;
|
|
318
215
|
|
|
@@ -355,7 +252,7 @@ function JQLiteOff(element, type, fn, unsupported) {
|
|
|
355
252
|
* @param {Element} element
|
|
356
253
|
* @param {string} [name] - key of field to remove
|
|
357
254
|
*/
|
|
358
|
-
function
|
|
255
|
+
export function removeElementData(element, name) {
|
|
359
256
|
const expandoId = element[EXPANDO];
|
|
360
257
|
const expandoStore = expandoId && CACHE.get(expandoId);
|
|
361
258
|
|
|
@@ -379,7 +276,7 @@ function JQLiteRemoveData(element, name) {
|
|
|
379
276
|
* @param {boolean} [createIfNecessary=false]
|
|
380
277
|
* @returns {import("../../core/cache/cache").ExpandoStore}
|
|
381
278
|
*/
|
|
382
|
-
function
|
|
279
|
+
function getExpando(element, createIfNecessary = false) {
|
|
383
280
|
let expandoId = element[EXPANDO];
|
|
384
281
|
let expandoStore = expandoId && CACHE.get(expandoId);
|
|
385
282
|
|
|
@@ -396,14 +293,141 @@ function JQLiteExpandoStore(element, createIfNecessary = false) {
|
|
|
396
293
|
return expandoStore;
|
|
397
294
|
}
|
|
398
295
|
|
|
399
|
-
|
|
296
|
+
/**
|
|
297
|
+
* Checks if the string contains HTML tags or entities.
|
|
298
|
+
* @param {string} html
|
|
299
|
+
* @returns {boolean} True if the string is plain text, false if it contains HTML tags or entities.
|
|
300
|
+
*/
|
|
301
|
+
export function isTextNode(html) {
|
|
302
|
+
return !/<|&#?\w+;/.test(html);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Check if element can accept expando data
|
|
307
|
+
* @param {Element} node
|
|
308
|
+
* @returns {boolean}
|
|
309
|
+
*/
|
|
310
|
+
function elementAcceptsData(node) {
|
|
311
|
+
// The window object can accept data but has no nodeType
|
|
312
|
+
// Otherwise we are only interested in elements (1) and documents (9)
|
|
313
|
+
switch (node.nodeType) {
|
|
314
|
+
case Node.ELEMENT_NODE:
|
|
315
|
+
case Node.DOCUMENT_NODE:
|
|
316
|
+
case undefined: // window.object
|
|
317
|
+
return true;
|
|
318
|
+
default:
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* @param {string} html
|
|
325
|
+
* @returns {DocumentFragment}
|
|
326
|
+
*/
|
|
327
|
+
export function buildFragment(html) {
|
|
328
|
+
let tmp;
|
|
329
|
+
let tag;
|
|
330
|
+
let wrap;
|
|
331
|
+
let tempFragment = document.createDocumentFragment();
|
|
332
|
+
let nodes = [];
|
|
333
|
+
let i;
|
|
334
|
+
|
|
335
|
+
if (isTextNode(html)) {
|
|
336
|
+
// Convert non-html into a text node
|
|
337
|
+
nodes.push(document.createTextNode(html));
|
|
338
|
+
} else {
|
|
339
|
+
// Convert html into DOM nodes
|
|
340
|
+
tmp = tempFragment.appendChild(document.createElement("div"));
|
|
341
|
+
tag = (TAG_NAME_REGEXP.exec(html) || ["", ""])[1].toLowerCase();
|
|
342
|
+
|
|
343
|
+
wrap = wrapMap[tag] || [];
|
|
344
|
+
|
|
345
|
+
// Create wrappers & descend into them
|
|
346
|
+
i = wrap.length;
|
|
347
|
+
while (--i > -1) {
|
|
348
|
+
tmp.appendChild(window.document.createElement(wrap[i]));
|
|
349
|
+
tmp = tmp.firstChild;
|
|
350
|
+
}
|
|
351
|
+
tmp.innerHTML = html;
|
|
352
|
+
|
|
353
|
+
nodes = concat(nodes, tmp.childNodes);
|
|
354
|
+
|
|
355
|
+
tmp = tempFragment.firstChild;
|
|
356
|
+
tmp.textContent = "";
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
let fragment = document.createDocumentFragment();
|
|
360
|
+
fragment.append(...nodes);
|
|
361
|
+
return fragment;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* @param {string} html
|
|
366
|
+
* @returns {NodeListOf<ChildNode> | HTMLElement[]}
|
|
367
|
+
*/
|
|
368
|
+
function parseHtml(html) {
|
|
369
|
+
let regEx = SINGLE_TAG_REGEXP.exec(html);
|
|
370
|
+
if (regEx) {
|
|
371
|
+
return [document.createElement(regEx[1])];
|
|
372
|
+
}
|
|
373
|
+
let fragment = buildFragment(html);
|
|
374
|
+
if (fragment) {
|
|
375
|
+
return fragment.childNodes;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return [];
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* @param {Element} element
|
|
383
|
+
* @param {boolean} [onlyDescendants]
|
|
384
|
+
* @returns {void}
|
|
385
|
+
*/
|
|
386
|
+
export function dealoc(element, onlyDescendants) {
|
|
387
|
+
if (!element) return;
|
|
388
|
+
if (!onlyDescendants && elementAcceptsData(element))
|
|
389
|
+
cleanElementData([element]);
|
|
390
|
+
|
|
391
|
+
if (element.querySelectorAll) {
|
|
392
|
+
cleanElementData(element.querySelectorAll("*"));
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* If `ExpandoStore.data` and `ExpandoStore.events` are empty,
|
|
398
|
+
* then delete element's `ExpandoStore` and set its `ExpandoId`
|
|
399
|
+
* to undefined.
|
|
400
|
+
* @param {Element} element
|
|
401
|
+
*/
|
|
402
|
+
function removeIfEmptyData(element) {
|
|
403
|
+
const expandoId = element[EXPANDO];
|
|
404
|
+
const { events, data } = CACHE.get(expandoId);
|
|
405
|
+
|
|
406
|
+
if (
|
|
407
|
+
(!data || !Object.keys(data).length) &&
|
|
408
|
+
(!events || !Object.keys(events).length)
|
|
409
|
+
) {
|
|
410
|
+
CACHE.delete(expandoId);
|
|
411
|
+
element[EXPANDO] = undefined; // don't delete DOM expandos. Chrome don't like it
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Gets or sets cache data for a given element.
|
|
417
|
+
*
|
|
418
|
+
* @param {Element} element - The DOM element to get or set data on.
|
|
419
|
+
* @param {string|Object} key - The key (as a string) to get/set or an object for mass-setting.
|
|
420
|
+
* @param {*} [value] - The value to set. If not provided, the function acts as a getter.
|
|
421
|
+
* @returns {*} - The retrieved data if acting as a getter. Otherwise, returns undefined.
|
|
422
|
+
*/
|
|
423
|
+
export function getOrSetCacheData(element, key, value) {
|
|
400
424
|
if (elementAcceptsData(element)) {
|
|
401
425
|
let prop;
|
|
402
426
|
|
|
403
427
|
const isSimpleSetter = isDefined(value);
|
|
404
428
|
const isSimpleGetter = !isSimpleSetter && key && !isObject(key);
|
|
405
429
|
const massGetter = !key;
|
|
406
|
-
const expandoStore =
|
|
430
|
+
const expandoStore = getExpando(element, !isSimpleGetter);
|
|
407
431
|
const data = expandoStore && expandoStore.data;
|
|
408
432
|
|
|
409
433
|
if (isSimpleSetter) {
|
|
@@ -421,6 +445,8 @@ function JQLiteData(element, key, value) {
|
|
|
421
445
|
data[kebabToCamel(prop)] = key[prop];
|
|
422
446
|
}
|
|
423
447
|
}
|
|
448
|
+
} else {
|
|
449
|
+
// TODO: check should occur perhaps prior at compilation level that this is a valid element
|
|
424
450
|
}
|
|
425
451
|
}
|
|
426
452
|
|
|
@@ -468,7 +494,8 @@ function JQLiteInheritedData(element, name, value) {
|
|
|
468
494
|
|
|
469
495
|
while (element) {
|
|
470
496
|
for (let i = 0, ii = names.length; i < ii; i++) {
|
|
471
|
-
if (isDefined((value =
|
|
497
|
+
if (isDefined((value = getOrSetCacheData(element, names[i]))))
|
|
498
|
+
return value;
|
|
472
499
|
}
|
|
473
500
|
|
|
474
501
|
// If dealing with a document fragment node with a host element, and no parent, use the host
|
|
@@ -480,37 +507,32 @@ function JQLiteInheritedData(element, name, value) {
|
|
|
480
507
|
}
|
|
481
508
|
}
|
|
482
509
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
export function JQLiteRemove(element, keepData) {
|
|
510
|
+
/**
|
|
511
|
+
*
|
|
512
|
+
* @param {Element} element
|
|
513
|
+
* @param {boolean} keepData
|
|
514
|
+
*/
|
|
515
|
+
export function removeElement(element, keepData = false) {
|
|
491
516
|
if (!keepData) dealoc(element);
|
|
492
517
|
const parent = element.parentNode;
|
|
493
518
|
if (parent) parent.removeChild(element);
|
|
494
519
|
}
|
|
495
520
|
|
|
496
|
-
|
|
521
|
+
/**
|
|
522
|
+
* Executea a function on `DOMContentLoaded`
|
|
523
|
+
* @param {Function} fn
|
|
524
|
+
*/
|
|
525
|
+
function onReady(fn) {
|
|
497
526
|
function trigger() {
|
|
498
527
|
window.document.removeEventListener("DOMContentLoaded", trigger);
|
|
499
|
-
window.removeEventListener("load", trigger);
|
|
500
528
|
fn();
|
|
501
529
|
}
|
|
502
|
-
|
|
503
530
|
// check if document is already loaded
|
|
504
531
|
if (window.document.readyState === "complete") {
|
|
505
532
|
window.setTimeout(fn);
|
|
506
533
|
} else {
|
|
507
|
-
// We can not use JQLite since we are not done loading
|
|
508
|
-
|
|
509
|
-
// Works for modern browsers and IE9
|
|
534
|
+
// We can not use JQLite since we are not done loading.
|
|
510
535
|
window.document.addEventListener("DOMContentLoaded", trigger);
|
|
511
|
-
|
|
512
|
-
// Fallback to window.onload for others
|
|
513
|
-
window.addEventListener("load", trigger);
|
|
514
536
|
}
|
|
515
537
|
}
|
|
516
538
|
|
|
@@ -518,7 +540,6 @@ function JQLiteReady(fn) {
|
|
|
518
540
|
// Functions which are declared directly.
|
|
519
541
|
/// ///////////////////////////////////////
|
|
520
542
|
JQLite.prototype = {
|
|
521
|
-
ready: JQLiteReady,
|
|
522
543
|
toString() {
|
|
523
544
|
const value = [];
|
|
524
545
|
forEach(this, (e) => {
|
|
@@ -532,28 +553,72 @@ JQLite.prototype = {
|
|
|
532
553
|
},
|
|
533
554
|
|
|
534
555
|
length: 0,
|
|
535
|
-
push: [].push,
|
|
536
|
-
sort: [].sort,
|
|
537
|
-
splice: [].splice,
|
|
538
556
|
};
|
|
539
557
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
558
|
+
/**
|
|
559
|
+
* Remove all child nodes of the set of matched elements from the DOM and clears CACHE data, associated with the node.
|
|
560
|
+
* @returns {JQLite} The current instance of JQLite.
|
|
561
|
+
*/
|
|
562
|
+
JQLite.prototype.empty = function () {
|
|
563
|
+
for (let i = 0; i < this.length; i++) {
|
|
564
|
+
const element = this[i];
|
|
565
|
+
dealoc(element, true);
|
|
566
|
+
// we may run into situation where we empty a transcluded node
|
|
567
|
+
if (
|
|
568
|
+
[
|
|
569
|
+
Node.ELEMENT_NODE,
|
|
570
|
+
Node.DOCUMENT_NODE,
|
|
571
|
+
Node.DOCUMENT_FRAGMENT_NODE,
|
|
572
|
+
].includes(element.nodeType)
|
|
573
|
+
) {
|
|
574
|
+
element.replaceChildren();
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
return this;
|
|
578
|
+
};
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Returns the `$scope` of the element.
|
|
582
|
+
* @returns {import("../../core/scope/scope").Scope}
|
|
583
|
+
*/
|
|
584
|
+
JQLite.prototype.scope = function () {
|
|
585
|
+
// Can't use JQLiteData here directly so we stay compatible with jQuery!
|
|
586
|
+
return (
|
|
587
|
+
getOrSetCacheData(this[0], "$scope") ||
|
|
588
|
+
JQLiteInheritedData(this[0].parentNode || this[0], [
|
|
589
|
+
"$isolateScope",
|
|
590
|
+
"$scope",
|
|
591
|
+
])
|
|
592
|
+
);
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* Returns the isolate `$scope` of the element.
|
|
597
|
+
* @returns {import("../../core/scope/scope").Scope}
|
|
598
|
+
*/
|
|
599
|
+
JQLite.prototype.isolateScope = function () {
|
|
600
|
+
return (
|
|
601
|
+
getOrSetCacheData(this[0], "$isolateScope") ||
|
|
602
|
+
getOrSetCacheData(this[0], "$isolateScopeNoTemplate")
|
|
603
|
+
);
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Return instance of controller attached to element
|
|
608
|
+
* @param {string} [name] - Controller name
|
|
609
|
+
* @returns {any}
|
|
610
|
+
*/
|
|
611
|
+
JQLite.prototype.controller = function (name) {
|
|
612
|
+
return JQLiteController(this[0], name);
|
|
613
|
+
};
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Return instance of injector attached to element
|
|
617
|
+
* @returns {import('../../types').angular.InjectorService}
|
|
618
|
+
*/
|
|
619
|
+
JQLite.prototype.injector = function () {
|
|
620
|
+
return JQLiteInheritedData(this[0], "$injector");
|
|
621
|
+
};
|
|
557
622
|
|
|
558
623
|
export function getBooleanAttrName(element, name) {
|
|
559
624
|
// check dom last since we will most likely fail on name
|
|
@@ -563,58 +628,31 @@ export function getBooleanAttrName(element, name) {
|
|
|
563
628
|
return booleanAttr && BOOLEAN_ELEMENTS[nodeName_(element)] && booleanAttr;
|
|
564
629
|
}
|
|
565
630
|
|
|
566
|
-
|
|
631
|
+
/**
|
|
632
|
+
* Takes an array of elements, calls any `$destroy` event handlers, removes any data in cache, and finally removes any
|
|
633
|
+
* listeners.
|
|
634
|
+
* @param {NodeListOf<Element>} nodes
|
|
635
|
+
*/
|
|
636
|
+
export function cleanElementData(nodes) {
|
|
567
637
|
for (let i = 0, ii = nodes.length; i < ii; i++) {
|
|
568
638
|
var events = (CACHE.get(nodes[i][EXPANDO]) || {}).events;
|
|
569
639
|
if (events && events.$destroy) {
|
|
570
640
|
JQLite(nodes[i]).triggerHandler("$destroy");
|
|
571
641
|
}
|
|
572
|
-
|
|
642
|
+
removeElementData(nodes[i]);
|
|
573
643
|
JQLiteOff(nodes[i]);
|
|
574
644
|
}
|
|
575
645
|
}
|
|
576
646
|
|
|
647
|
+
/// ///////////////////////////////////////
|
|
648
|
+
// Functions iterating getter/setters.
|
|
649
|
+
// these functions return self on setter and
|
|
650
|
+
// value on get.
|
|
651
|
+
/// ///////////////////////////////////////
|
|
577
652
|
forEach(
|
|
578
653
|
{
|
|
579
|
-
data:
|
|
580
|
-
removeData: JQLiteRemoveData,
|
|
581
|
-
cleanData: JQLiteCleanData,
|
|
582
|
-
},
|
|
583
|
-
(fn, name) => {
|
|
584
|
-
JQLite[name] = fn;
|
|
585
|
-
},
|
|
586
|
-
);
|
|
587
|
-
|
|
588
|
-
forEach(
|
|
589
|
-
{
|
|
590
|
-
data: JQLiteData,
|
|
654
|
+
data: getOrSetCacheData,
|
|
591
655
|
inheritedData: JQLiteInheritedData,
|
|
592
|
-
|
|
593
|
-
scope(element) {
|
|
594
|
-
// Can't use JQLiteData here directly so we stay compatible with jQuery!
|
|
595
|
-
return (
|
|
596
|
-
JQLiteData(element, "$scope") ||
|
|
597
|
-
JQLiteInheritedData(element.parentNode || element, [
|
|
598
|
-
"$isolateScope",
|
|
599
|
-
"$scope",
|
|
600
|
-
])
|
|
601
|
-
);
|
|
602
|
-
},
|
|
603
|
-
|
|
604
|
-
isolateScope(element) {
|
|
605
|
-
// Can't use JQLiteData here directly so we stay compatible with jQuery!
|
|
606
|
-
return (
|
|
607
|
-
JQLiteData(element, "$isolateScope") ||
|
|
608
|
-
JQLiteData(element, "$isolateScopeNoTemplate")
|
|
609
|
-
);
|
|
610
|
-
},
|
|
611
|
-
|
|
612
|
-
controller: JQLiteController,
|
|
613
|
-
|
|
614
|
-
injector(element) {
|
|
615
|
-
return JQLiteInheritedData(element, "$injector");
|
|
616
|
-
},
|
|
617
|
-
|
|
618
656
|
attr(element, name, value) {
|
|
619
657
|
let ret;
|
|
620
658
|
const { nodeType } = element;
|
|
@@ -664,7 +702,6 @@ forEach(
|
|
|
664
702
|
element.textContent = value;
|
|
665
703
|
}
|
|
666
704
|
})(),
|
|
667
|
-
|
|
668
705
|
val(element, value) {
|
|
669
706
|
if (isUndefined(value)) {
|
|
670
707
|
if (element.multiple && nodeName_(element) === "select") {
|
|
@@ -680,7 +717,6 @@ forEach(
|
|
|
680
717
|
}
|
|
681
718
|
element.value = value;
|
|
682
719
|
},
|
|
683
|
-
|
|
684
720
|
html(element, value) {
|
|
685
721
|
if (isUndefined(value)) {
|
|
686
722
|
return element.innerHTML;
|
|
@@ -688,8 +724,6 @@ forEach(
|
|
|
688
724
|
dealoc(element, true);
|
|
689
725
|
element.innerHTML = value;
|
|
690
726
|
},
|
|
691
|
-
|
|
692
|
-
empty: JQLiteEmpty,
|
|
693
727
|
},
|
|
694
728
|
(fn, name) => {
|
|
695
729
|
/**
|
|
@@ -702,13 +736,12 @@ forEach(
|
|
|
702
736
|
|
|
703
737
|
// JQLiteEmpty takes no arguments but is a setter.
|
|
704
738
|
if (
|
|
705
|
-
fn !== JQLiteEmpty &&
|
|
706
739
|
isUndefined(fn.length === 2 && fn !== JQLiteController ? arg1 : arg2)
|
|
707
740
|
) {
|
|
708
741
|
if (isObject(arg1)) {
|
|
709
742
|
// we are a write, but the object properties are the key/values
|
|
710
743
|
for (i = 0; i < nodeCount; i++) {
|
|
711
|
-
if (fn ===
|
|
744
|
+
if (fn === getOrSetCacheData) {
|
|
712
745
|
fn(this[i], arg1);
|
|
713
746
|
} else {
|
|
714
747
|
for (key in arg1) {
|
|
@@ -740,80 +773,6 @@ forEach(
|
|
|
740
773
|
},
|
|
741
774
|
);
|
|
742
775
|
|
|
743
|
-
function createEventHandler(element, events) {
|
|
744
|
-
const eventHandler = function (event, type) {
|
|
745
|
-
// jQuery specific api
|
|
746
|
-
event.isDefaultPrevented = function () {
|
|
747
|
-
return event.defaultPrevented;
|
|
748
|
-
};
|
|
749
|
-
|
|
750
|
-
let eventFns = events[type || event.type];
|
|
751
|
-
const eventFnsLength = eventFns ? eventFns.length : 0;
|
|
752
|
-
|
|
753
|
-
if (!eventFnsLength) return;
|
|
754
|
-
|
|
755
|
-
if (isUndefined(event.immediatePropagationStopped)) {
|
|
756
|
-
const originalStopImmediatePropagation = event.stopImmediatePropagation;
|
|
757
|
-
event.stopImmediatePropagation = function () {
|
|
758
|
-
event.immediatePropagationStopped = true;
|
|
759
|
-
|
|
760
|
-
if (event.stopPropagation) {
|
|
761
|
-
event.stopPropagation();
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
if (originalStopImmediatePropagation) {
|
|
765
|
-
originalStopImmediatePropagation.call(event);
|
|
766
|
-
}
|
|
767
|
-
};
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
event.isImmediatePropagationStopped = function () {
|
|
771
|
-
return event.immediatePropagationStopped === true;
|
|
772
|
-
};
|
|
773
|
-
|
|
774
|
-
// Some events have special handlers that wrap the real handler
|
|
775
|
-
const handlerWrapper =
|
|
776
|
-
eventFns.specialHandlerWrapper || defaultHandlerWrapper;
|
|
777
|
-
|
|
778
|
-
// Copy event handlers in case event handlers array is modified during execution.
|
|
779
|
-
if (eventFnsLength > 1) {
|
|
780
|
-
eventFns = shallowCopy(eventFns);
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
for (let i = 0; i < eventFnsLength; i++) {
|
|
784
|
-
if (!event.isImmediatePropagationStopped()) {
|
|
785
|
-
handlerWrapper(element, event, eventFns[i]);
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
};
|
|
789
|
-
|
|
790
|
-
// TODO: this is a hack for angularMocks/clearDataCache that makes it possible to deregister all
|
|
791
|
-
// events on `element`
|
|
792
|
-
eventHandler.elem = element;
|
|
793
|
-
return eventHandler;
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
function defaultHandlerWrapper(element, event, handler) {
|
|
797
|
-
handler.call(element, event);
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
/**
|
|
801
|
-
* @param {Node} target
|
|
802
|
-
* @param {*} event
|
|
803
|
-
* @param {*} handler
|
|
804
|
-
*/
|
|
805
|
-
function specialMouseHandlerWrapper(target, event, handler) {
|
|
806
|
-
// Refer to jQuery's implementation of mouseenter & mouseleave
|
|
807
|
-
// Read about mouseenter and mouseleave:
|
|
808
|
-
// http://www.quirksmode.org/js/events_mouse.html#link8
|
|
809
|
-
const related = event.relatedTarget;
|
|
810
|
-
// For mousenter/leave call the handler if related is outside the target.
|
|
811
|
-
// NB: No relatedTarget if the mouse left/entered the browser window
|
|
812
|
-
if (!related || (related !== target && !target.contains(related))) {
|
|
813
|
-
handler.call(target, event);
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
|
|
817
776
|
/// ///////////////////////////////////////
|
|
818
777
|
// Functions iterating traversal.
|
|
819
778
|
// These functions chain results into a single
|
|
@@ -821,25 +780,17 @@ function specialMouseHandlerWrapper(target, event, handler) {
|
|
|
821
780
|
/// ///////////////////////////////////////
|
|
822
781
|
forEach(
|
|
823
782
|
{
|
|
824
|
-
removeData:
|
|
825
|
-
on: (element, type, fn
|
|
826
|
-
if (isDefined(unsupported))
|
|
827
|
-
throw JQLiteMinErr(
|
|
828
|
-
"onargs",
|
|
829
|
-
"jqLite#on() does not support the `selector` or `eventData` parameters",
|
|
830
|
-
);
|
|
831
|
-
|
|
783
|
+
removeData: removeElementData,
|
|
784
|
+
on: (element, type, fn) => {
|
|
832
785
|
// Do not add event handlers to non-elements because they will not be cleaned up.
|
|
833
786
|
if (!elementAcceptsData(element)) {
|
|
834
787
|
return;
|
|
835
788
|
}
|
|
836
789
|
|
|
837
|
-
const expandoStore =
|
|
838
|
-
const { events } = expandoStore;
|
|
839
|
-
let { handle } = expandoStore;
|
|
790
|
+
const expandoStore = getExpando(element, true);
|
|
840
791
|
|
|
841
|
-
if (!handle) {
|
|
842
|
-
|
|
792
|
+
if (!expandoStore.handle) {
|
|
793
|
+
expandoStore.handle = createEventHandler(element, expandoStore.events);
|
|
843
794
|
}
|
|
844
795
|
|
|
845
796
|
// http://jsperf.com/string-indexof-vs-split
|
|
@@ -851,13 +802,13 @@ forEach(
|
|
|
851
802
|
specialHandlerWrapper,
|
|
852
803
|
noEventListener,
|
|
853
804
|
) {
|
|
854
|
-
let eventFns = events[type];
|
|
805
|
+
let eventFns = expandoStore.events[type];
|
|
855
806
|
|
|
856
807
|
if (!eventFns) {
|
|
857
|
-
eventFns = events[type] = [];
|
|
808
|
+
eventFns = expandoStore.events[type] = [];
|
|
858
809
|
eventFns.specialHandlerWrapper = specialHandlerWrapper;
|
|
859
810
|
if (type !== "$destroy" && !noEventListener) {
|
|
860
|
-
element.addEventListener(type, handle);
|
|
811
|
+
element.addEventListener(type, expandoStore.handle);
|
|
861
812
|
}
|
|
862
813
|
}
|
|
863
814
|
|
|
@@ -874,9 +825,7 @@ forEach(
|
|
|
874
825
|
}
|
|
875
826
|
}
|
|
876
827
|
},
|
|
877
|
-
|
|
878
828
|
off: JQLiteOff,
|
|
879
|
-
|
|
880
829
|
replaceWith(element, replaceNode) {
|
|
881
830
|
let index;
|
|
882
831
|
const parent = element.parentNode;
|
|
@@ -890,13 +839,11 @@ forEach(
|
|
|
890
839
|
index = node;
|
|
891
840
|
});
|
|
892
841
|
},
|
|
893
|
-
|
|
894
842
|
children(element) {
|
|
895
843
|
return Array.from(element.childNodes).filter(
|
|
896
844
|
(child) => child.nodeType === Node.ELEMENT_NODE,
|
|
897
845
|
);
|
|
898
846
|
},
|
|
899
|
-
|
|
900
847
|
append(element, node) {
|
|
901
848
|
const { nodeType } = element;
|
|
902
849
|
if (
|
|
@@ -922,10 +869,10 @@ forEach(
|
|
|
922
869
|
}
|
|
923
870
|
},
|
|
924
871
|
|
|
925
|
-
remove:
|
|
872
|
+
remove: removeElement,
|
|
926
873
|
|
|
927
874
|
detach(element) {
|
|
928
|
-
|
|
875
|
+
removeElement(element, true);
|
|
929
876
|
},
|
|
930
877
|
|
|
931
878
|
after(element, newElement) {
|
|
@@ -963,7 +910,7 @@ forEach(
|
|
|
963
910
|
let eventFnsCopy;
|
|
964
911
|
let handlerArgs;
|
|
965
912
|
const eventName = event.type || event;
|
|
966
|
-
const expandoStore =
|
|
913
|
+
const expandoStore = getExpando(element);
|
|
967
914
|
const events = expandoStore && expandoStore.events;
|
|
968
915
|
const eventFns = events && events[eventName];
|
|
969
916
|
|
|
@@ -1029,6 +976,80 @@ forEach(
|
|
|
1029
976
|
},
|
|
1030
977
|
);
|
|
1031
978
|
|
|
979
|
+
function createEventHandler(element, events) {
|
|
980
|
+
const eventHandler = function (event, type) {
|
|
981
|
+
// jQuery specific api
|
|
982
|
+
event.isDefaultPrevented = function () {
|
|
983
|
+
return event.defaultPrevented;
|
|
984
|
+
};
|
|
985
|
+
|
|
986
|
+
let eventFns = events[type || event.type];
|
|
987
|
+
const eventFnsLength = eventFns ? eventFns.length : 0;
|
|
988
|
+
|
|
989
|
+
if (!eventFnsLength) return;
|
|
990
|
+
|
|
991
|
+
if (isUndefined(event.immediatePropagationStopped)) {
|
|
992
|
+
const originalStopImmediatePropagation = event.stopImmediatePropagation;
|
|
993
|
+
event.stopImmediatePropagation = function () {
|
|
994
|
+
event.immediatePropagationStopped = true;
|
|
995
|
+
|
|
996
|
+
if (event.stopPropagation) {
|
|
997
|
+
event.stopPropagation();
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
if (originalStopImmediatePropagation) {
|
|
1001
|
+
originalStopImmediatePropagation.call(event);
|
|
1002
|
+
}
|
|
1003
|
+
};
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
event.isImmediatePropagationStopped = function () {
|
|
1007
|
+
return event.immediatePropagationStopped === true;
|
|
1008
|
+
};
|
|
1009
|
+
|
|
1010
|
+
// Some events have special handlers that wrap the real handler
|
|
1011
|
+
const handlerWrapper =
|
|
1012
|
+
eventFns.specialHandlerWrapper || defaultHandlerWrapper;
|
|
1013
|
+
|
|
1014
|
+
// Copy event handlers in case event handlers array is modified during execution.
|
|
1015
|
+
if (eventFnsLength > 1) {
|
|
1016
|
+
eventFns = shallowCopy(eventFns);
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
for (let i = 0; i < eventFnsLength; i++) {
|
|
1020
|
+
if (!event.isImmediatePropagationStopped()) {
|
|
1021
|
+
handlerWrapper(element, event, eventFns[i]);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
};
|
|
1025
|
+
|
|
1026
|
+
// TODO: this is a hack for angularMocks/clearDataCache that makes it possible to deregister all
|
|
1027
|
+
// events on `element`
|
|
1028
|
+
eventHandler.elem = element;
|
|
1029
|
+
return eventHandler;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
function defaultHandlerWrapper(element, event, handler) {
|
|
1033
|
+
handler.call(element, event);
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
/**
|
|
1037
|
+
* @param {Node} target
|
|
1038
|
+
* @param {*} event
|
|
1039
|
+
* @param {*} handler
|
|
1040
|
+
*/
|
|
1041
|
+
function specialMouseHandlerWrapper(target, event, handler) {
|
|
1042
|
+
// Refer to jQuery's implementation of mouseenter & mouseleave
|
|
1043
|
+
// Read about mouseenter and mouseleave:
|
|
1044
|
+
// http://www.quirksmode.org/js/events_mouse.html#link8
|
|
1045
|
+
const related = event.relatedTarget;
|
|
1046
|
+
// For mousenter/leave call the handler if related is outside the target.
|
|
1047
|
+
// NB: No relatedTarget if the mouse left/entered the browser window
|
|
1048
|
+
if (!related || (related !== target && !target.contains(related))) {
|
|
1049
|
+
handler.call(target, event);
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1032
1053
|
/**
|
|
1033
1054
|
* @param {string} elementStr
|
|
1034
1055
|
* @returns {string} Returns the string representation of the element.
|
|
@@ -1053,7 +1074,7 @@ export function startingTag(elementStr) {
|
|
|
1053
1074
|
/**
|
|
1054
1075
|
* Return the DOM siblings between the first and last node in the given array.
|
|
1055
1076
|
* @param {Array} nodes An array-like object
|
|
1056
|
-
* @returns {
|
|
1077
|
+
* @returns {JQLite} the inputted object or a JQLite collection containing the nodes
|
|
1057
1078
|
*/
|
|
1058
1079
|
export function getBlockNodes(nodes) {
|
|
1059
1080
|
// TODO(perf): update `nodes` instead of creating a new object?
|
|
@@ -1065,11 +1086,11 @@ export function getBlockNodes(nodes) {
|
|
|
1065
1086
|
if (blockNodes || nodes[i] !== node) {
|
|
1066
1087
|
if (!blockNodes) {
|
|
1067
1088
|
// use element to avoid circular dependency
|
|
1068
|
-
blockNodes =
|
|
1089
|
+
blockNodes = Array.prototype.slice.call(nodes, 0, i);
|
|
1069
1090
|
}
|
|
1070
1091
|
blockNodes.push(node);
|
|
1071
1092
|
}
|
|
1072
1093
|
}
|
|
1073
1094
|
|
|
1074
|
-
return blockNodes || nodes;
|
|
1095
|
+
return JQLite(blockNodes || nodes);
|
|
1075
1096
|
}
|