@angular-wave/angular.ts 0.0.40 → 0.0.42
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 +28 -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 +5 -3
- package/src/core/compile/compile.md +2 -5
- package/src/core/compile/compile.spec.js +2 -43
- package/src/core/exception-handler.js +6 -6
- package/src/core/interpolate/interpolate.js +1 -1
- package/src/core/location/location.spec.js +0 -4
- package/src/core/q/q.js +1 -1
- package/src/core/scope/scope.js +1 -1
- package/src/core/task-tracker-factory.js +2 -2
- package/src/core/timeout/timeout.js +1 -1
- package/src/core/url-utils/url-utils.js +0 -2
- package/src/directive/bind/bind.js +2 -2
- package/src/directive/change/change.js +1 -1
- package/src/directive/cloak/cloak.js +1 -1
- package/src/directive/events/events.js +1 -1
- package/src/directive/form/form.js +2 -2
- package/src/directive/include/include.js +5 -7
- package/src/directive/init/init.js +1 -1
- package/src/directive/list/list.js +1 -1
- package/src/directive/model/model.js +1 -1
- package/src/directive/model-options/model-options.js +56 -421
- package/src/directive/model-options/model-options.md +407 -0
- package/src/directive/model-options/model-options.spec.js +1 -1
- package/src/directive/non-bindable/non-bindable.js +1 -2
- package/src/directive/options/options.js +3 -3
- package/src/directive/style/style.js +1 -1
- package/src/directive/switch/switch.js +2 -2
- package/src/directive/transclude/transclude.js +2 -2
- package/src/index.js +0 -461
- package/src/loader.js +1 -1
- package/src/public.js +1 -1
- package/src/router/template-factory.js +2 -2
- package/src/router/view-scroll.js +1 -1
- package/src/services/browser.js +1 -1
- package/src/services/document.js +2 -2
- package/src/services/http/http.js +11 -7
- package/src/services/log.js +1 -1
- package/src/services/template-request.js +1 -1
- package/src/shared/jqlite/jqlite.js +380 -351
- package/src/shared/jqlite/jqlite.spec.js +73 -82
- package/src/shared/utils.js +1 -1
- package/src/types.js +451 -0
- package/tsconfig.json +1 -1
- package/types/animations/shared.d.ts +7 -2
- package/types/core/compile/compile.d.ts +2 -1
- package/types/core/exception-handler.d.ts +5 -7
- package/types/core/interpolate/interpolate.d.ts +1 -1
- package/types/core/q/q.d.ts +1 -1
- package/types/core/task-tracker-factory.d.ts +5 -5
- package/types/core/timeout/timeout.d.ts +2 -2
- package/types/directive/bind/bind.d.ts +4 -4
- package/types/directive/change/change.d.ts +2 -2
- package/types/directive/cloak/cloak.d.ts +2 -2
- package/types/directive/include/include.d.ts +2 -2
- package/types/directive/init/init.d.ts +2 -2
- package/types/directive/list/list.d.ts +2 -2
- package/types/directive/model/model.d.ts +13 -7
- package/types/directive/model-options/model-options.d.ts +49 -0
- package/types/directive/non-bindable/non-bindable.d.ts +2 -3
- package/types/directive/style/style.d.ts +2 -2
- package/types/directive/switch/switch.d.ts +4 -4
- package/types/index.d.ts +1 -702
- package/types/public.d.ts +2 -2
- package/types/router/template-factory.d.ts +4 -4
- package/types/services/browser.d.ts +3 -3
- package/types/services/document.d.ts +6 -7
- package/types/services/log.d.ts +2 -2
- package/types/services/template-request.d.ts +1 -1
- package/types/shared/jqlite/jqlite.d.ts +91 -21
- package/types/shared/utils.d.ts +2 -2
- package/types/types.d.ts +438 -0
- package/types-back/index.d.ts +1 -83
- package/types-back/jqlite.d.ts +1 -121
- package/types-back/global.d.ts +0 -11
|
@@ -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,123 @@ 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').InjectorService}
|
|
618
|
+
*/
|
|
619
|
+
JQLite.prototype.injector = function () {
|
|
620
|
+
return JQLiteInheritedData(this[0], "$injector");
|
|
621
|
+
};
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* Adds an event listener to each element in the JQLite collection.
|
|
625
|
+
*
|
|
626
|
+
* @param {string} type - The event type(s) to listen for. Multiple event types can be specified, separated by a space.
|
|
627
|
+
* @param {Function} fn - The function to execute when the event is triggered.
|
|
628
|
+
* @returns {JQLite} The JQLite collection for chaining.
|
|
629
|
+
*/
|
|
630
|
+
JQLite.prototype.on = function (type, fn) {
|
|
631
|
+
// Do not add event handlers to non-elements because they will not be cleaned up.
|
|
632
|
+
for (let i = 0, ii = this.length; i < ii; i++) {
|
|
633
|
+
const element = this[i];
|
|
634
|
+
if (!elementAcceptsData(element)) {
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
const expandoStore = getExpando(element, true);
|
|
639
|
+
|
|
640
|
+
if (!expandoStore.handle) {
|
|
641
|
+
expandoStore.handle = createEventHandler(element, expandoStore.events);
|
|
642
|
+
}
|
|
643
|
+
// http://jsperf.com/string-indexof-vs-split
|
|
644
|
+
const types = type.indexOf(" ") >= 0 ? type.split(" ") : [type];
|
|
645
|
+
let j = types.length;
|
|
646
|
+
|
|
647
|
+
const addHandler = function (type, specialHandlerWrapper, noEventListener) {
|
|
648
|
+
let eventFns = expandoStore.events[type];
|
|
649
|
+
|
|
650
|
+
if (!eventFns) {
|
|
651
|
+
eventFns = expandoStore.events[type] = [];
|
|
652
|
+
eventFns.specialHandlerWrapper = specialHandlerWrapper;
|
|
653
|
+
if (type !== "$destroy" && !noEventListener) {
|
|
654
|
+
element.addEventListener(type, expandoStore.handle);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
eventFns.push(fn);
|
|
659
|
+
};
|
|
660
|
+
|
|
661
|
+
while (j--) {
|
|
662
|
+
type = types[j];
|
|
663
|
+
if (MOUSE_EVENT_MAP[type]) {
|
|
664
|
+
addHandler(MOUSE_EVENT_MAP[type], specialMouseHandlerWrapper);
|
|
665
|
+
addHandler(type, undefined, true);
|
|
666
|
+
} else {
|
|
667
|
+
addHandler(type);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
return this;
|
|
672
|
+
};
|
|
557
673
|
|
|
558
674
|
export function getBooleanAttrName(element, name) {
|
|
559
675
|
// check dom last since we will most likely fail on name
|
|
@@ -563,58 +679,31 @@ export function getBooleanAttrName(element, name) {
|
|
|
563
679
|
return booleanAttr && BOOLEAN_ELEMENTS[nodeName_(element)] && booleanAttr;
|
|
564
680
|
}
|
|
565
681
|
|
|
566
|
-
|
|
682
|
+
/**
|
|
683
|
+
* Takes an array of elements, calls any `$destroy` event handlers, removes any data in cache, and finally removes any
|
|
684
|
+
* listeners.
|
|
685
|
+
* @param {NodeListOf<Element>} nodes
|
|
686
|
+
*/
|
|
687
|
+
export function cleanElementData(nodes) {
|
|
567
688
|
for (let i = 0, ii = nodes.length; i < ii; i++) {
|
|
568
689
|
var events = (CACHE.get(nodes[i][EXPANDO]) || {}).events;
|
|
569
690
|
if (events && events.$destroy) {
|
|
570
691
|
JQLite(nodes[i]).triggerHandler("$destroy");
|
|
571
692
|
}
|
|
572
|
-
|
|
693
|
+
removeElementData(nodes[i]);
|
|
573
694
|
JQLiteOff(nodes[i]);
|
|
574
695
|
}
|
|
575
696
|
}
|
|
576
697
|
|
|
698
|
+
/// ///////////////////////////////////////
|
|
699
|
+
// Functions iterating getter/setters.
|
|
700
|
+
// these functions return self on setter and
|
|
701
|
+
// value on get.
|
|
702
|
+
/// ///////////////////////////////////////
|
|
577
703
|
forEach(
|
|
578
704
|
{
|
|
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,
|
|
705
|
+
data: getOrSetCacheData,
|
|
591
706
|
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
707
|
attr(element, name, value) {
|
|
619
708
|
let ret;
|
|
620
709
|
const { nodeType } = element;
|
|
@@ -664,7 +753,6 @@ forEach(
|
|
|
664
753
|
element.textContent = value;
|
|
665
754
|
}
|
|
666
755
|
})(),
|
|
667
|
-
|
|
668
756
|
val(element, value) {
|
|
669
757
|
if (isUndefined(value)) {
|
|
670
758
|
if (element.multiple && nodeName_(element) === "select") {
|
|
@@ -680,7 +768,6 @@ forEach(
|
|
|
680
768
|
}
|
|
681
769
|
element.value = value;
|
|
682
770
|
},
|
|
683
|
-
|
|
684
771
|
html(element, value) {
|
|
685
772
|
if (isUndefined(value)) {
|
|
686
773
|
return element.innerHTML;
|
|
@@ -688,8 +775,6 @@ forEach(
|
|
|
688
775
|
dealoc(element, true);
|
|
689
776
|
element.innerHTML = value;
|
|
690
777
|
},
|
|
691
|
-
|
|
692
|
-
empty: JQLiteEmpty,
|
|
693
778
|
},
|
|
694
779
|
(fn, name) => {
|
|
695
780
|
/**
|
|
@@ -702,13 +787,12 @@ forEach(
|
|
|
702
787
|
|
|
703
788
|
// JQLiteEmpty takes no arguments but is a setter.
|
|
704
789
|
if (
|
|
705
|
-
fn !== JQLiteEmpty &&
|
|
706
790
|
isUndefined(fn.length === 2 && fn !== JQLiteController ? arg1 : arg2)
|
|
707
791
|
) {
|
|
708
792
|
if (isObject(arg1)) {
|
|
709
793
|
// we are a write, but the object properties are the key/values
|
|
710
794
|
for (i = 0; i < nodeCount; i++) {
|
|
711
|
-
if (fn ===
|
|
795
|
+
if (fn === getOrSetCacheData) {
|
|
712
796
|
fn(this[i], arg1);
|
|
713
797
|
} else {
|
|
714
798
|
for (key in arg1) {
|
|
@@ -740,80 +824,6 @@ forEach(
|
|
|
740
824
|
},
|
|
741
825
|
);
|
|
742
826
|
|
|
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
827
|
/// ///////////////////////////////////////
|
|
818
828
|
// Functions iterating traversal.
|
|
819
829
|
// These functions chain results into a single
|
|
@@ -821,62 +831,9 @@ function specialMouseHandlerWrapper(target, event, handler) {
|
|
|
821
831
|
/// ///////////////////////////////////////
|
|
822
832
|
forEach(
|
|
823
833
|
{
|
|
824
|
-
removeData:
|
|
825
|
-
on: (element, type, fn, unsupported) => {
|
|
826
|
-
if (isDefined(unsupported))
|
|
827
|
-
throw JQLiteMinErr(
|
|
828
|
-
"onargs",
|
|
829
|
-
"jqLite#on() does not support the `selector` or `eventData` parameters",
|
|
830
|
-
);
|
|
831
|
-
|
|
832
|
-
// Do not add event handlers to non-elements because they will not be cleaned up.
|
|
833
|
-
if (!elementAcceptsData(element)) {
|
|
834
|
-
return;
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
const expandoStore = JQLiteExpandoStore(element, true);
|
|
838
|
-
const { events } = expandoStore;
|
|
839
|
-
let { handle } = expandoStore;
|
|
840
|
-
|
|
841
|
-
if (!handle) {
|
|
842
|
-
handle = expandoStore.handle = createEventHandler(element, events);
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
// http://jsperf.com/string-indexof-vs-split
|
|
846
|
-
const types = type.indexOf(" ") >= 0 ? type.split(" ") : [type];
|
|
847
|
-
let i = types.length;
|
|
848
|
-
|
|
849
|
-
const addHandler = function (
|
|
850
|
-
type,
|
|
851
|
-
specialHandlerWrapper,
|
|
852
|
-
noEventListener,
|
|
853
|
-
) {
|
|
854
|
-
let eventFns = events[type];
|
|
855
|
-
|
|
856
|
-
if (!eventFns) {
|
|
857
|
-
eventFns = events[type] = [];
|
|
858
|
-
eventFns.specialHandlerWrapper = specialHandlerWrapper;
|
|
859
|
-
if (type !== "$destroy" && !noEventListener) {
|
|
860
|
-
element.addEventListener(type, handle);
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
|
|
864
|
-
eventFns.push(fn);
|
|
865
|
-
};
|
|
866
|
-
|
|
867
|
-
while (i--) {
|
|
868
|
-
type = types[i];
|
|
869
|
-
if (MOUSE_EVENT_MAP[type]) {
|
|
870
|
-
addHandler(MOUSE_EVENT_MAP[type], specialMouseHandlerWrapper);
|
|
871
|
-
addHandler(type, undefined, true);
|
|
872
|
-
} else {
|
|
873
|
-
addHandler(type);
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
},
|
|
834
|
+
removeData: removeElementData,
|
|
877
835
|
|
|
878
836
|
off: JQLiteOff,
|
|
879
|
-
|
|
880
837
|
replaceWith(element, replaceNode) {
|
|
881
838
|
let index;
|
|
882
839
|
const parent = element.parentNode;
|
|
@@ -890,13 +847,11 @@ forEach(
|
|
|
890
847
|
index = node;
|
|
891
848
|
});
|
|
892
849
|
},
|
|
893
|
-
|
|
894
850
|
children(element) {
|
|
895
851
|
return Array.from(element.childNodes).filter(
|
|
896
852
|
(child) => child.nodeType === Node.ELEMENT_NODE,
|
|
897
853
|
);
|
|
898
854
|
},
|
|
899
|
-
|
|
900
855
|
append(element, node) {
|
|
901
856
|
const { nodeType } = element;
|
|
902
857
|
if (
|
|
@@ -922,10 +877,10 @@ forEach(
|
|
|
922
877
|
}
|
|
923
878
|
},
|
|
924
879
|
|
|
925
|
-
remove:
|
|
880
|
+
remove: removeElement,
|
|
926
881
|
|
|
927
882
|
detach(element) {
|
|
928
|
-
|
|
883
|
+
removeElement(element, true);
|
|
929
884
|
},
|
|
930
885
|
|
|
931
886
|
after(element, newElement) {
|
|
@@ -963,7 +918,7 @@ forEach(
|
|
|
963
918
|
let eventFnsCopy;
|
|
964
919
|
let handlerArgs;
|
|
965
920
|
const eventName = event.type || event;
|
|
966
|
-
const expandoStore =
|
|
921
|
+
const expandoStore = getExpando(element);
|
|
967
922
|
const events = expandoStore && expandoStore.events;
|
|
968
923
|
const eventFns = events && events[eventName];
|
|
969
924
|
|
|
@@ -1029,6 +984,80 @@ forEach(
|
|
|
1029
984
|
},
|
|
1030
985
|
);
|
|
1031
986
|
|
|
987
|
+
function createEventHandler(element, events) {
|
|
988
|
+
const eventHandler = function (event, type) {
|
|
989
|
+
// jQuery specific api
|
|
990
|
+
event.isDefaultPrevented = function () {
|
|
991
|
+
return event.defaultPrevented;
|
|
992
|
+
};
|
|
993
|
+
|
|
994
|
+
let eventFns = events[type || event.type];
|
|
995
|
+
const eventFnsLength = eventFns ? eventFns.length : 0;
|
|
996
|
+
|
|
997
|
+
if (!eventFnsLength) return;
|
|
998
|
+
|
|
999
|
+
if (isUndefined(event.immediatePropagationStopped)) {
|
|
1000
|
+
const originalStopImmediatePropagation = event.stopImmediatePropagation;
|
|
1001
|
+
event.stopImmediatePropagation = function () {
|
|
1002
|
+
event.immediatePropagationStopped = true;
|
|
1003
|
+
|
|
1004
|
+
if (event.stopPropagation) {
|
|
1005
|
+
event.stopPropagation();
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
if (originalStopImmediatePropagation) {
|
|
1009
|
+
originalStopImmediatePropagation.call(event);
|
|
1010
|
+
}
|
|
1011
|
+
};
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
event.isImmediatePropagationStopped = function () {
|
|
1015
|
+
return event.immediatePropagationStopped === true;
|
|
1016
|
+
};
|
|
1017
|
+
|
|
1018
|
+
// Some events have special handlers that wrap the real handler
|
|
1019
|
+
const handlerWrapper =
|
|
1020
|
+
eventFns.specialHandlerWrapper || defaultHandlerWrapper;
|
|
1021
|
+
|
|
1022
|
+
// Copy event handlers in case event handlers array is modified during execution.
|
|
1023
|
+
if (eventFnsLength > 1) {
|
|
1024
|
+
eventFns = shallowCopy(eventFns);
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
for (let i = 0; i < eventFnsLength; i++) {
|
|
1028
|
+
if (!event.isImmediatePropagationStopped()) {
|
|
1029
|
+
handlerWrapper(element, event, eventFns[i]);
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
};
|
|
1033
|
+
|
|
1034
|
+
// TODO: this is a hack for angularMocks/clearDataCache that makes it possible to deregister all
|
|
1035
|
+
// events on `element`
|
|
1036
|
+
eventHandler.elem = element;
|
|
1037
|
+
return eventHandler;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
function defaultHandlerWrapper(element, event, handler) {
|
|
1041
|
+
handler.call(element, event);
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
/**
|
|
1045
|
+
* @param {Node} target
|
|
1046
|
+
* @param {*} event
|
|
1047
|
+
* @param {*} handler
|
|
1048
|
+
*/
|
|
1049
|
+
function specialMouseHandlerWrapper(target, event, handler) {
|
|
1050
|
+
// Refer to jQuery's implementation of mouseenter & mouseleave
|
|
1051
|
+
// Read about mouseenter and mouseleave:
|
|
1052
|
+
// http://www.quirksmode.org/js/events_mouse.html#link8
|
|
1053
|
+
const related = event.relatedTarget;
|
|
1054
|
+
// For mousenter/leave call the handler if related is outside the target.
|
|
1055
|
+
// NB: No relatedTarget if the mouse left/entered the browser window
|
|
1056
|
+
if (!related || (related !== target && !target.contains(related))) {
|
|
1057
|
+
handler.call(target, event);
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1032
1061
|
/**
|
|
1033
1062
|
* @param {string} elementStr
|
|
1034
1063
|
* @returns {string} Returns the string representation of the element.
|
|
@@ -1053,7 +1082,7 @@ export function startingTag(elementStr) {
|
|
|
1053
1082
|
/**
|
|
1054
1083
|
* Return the DOM siblings between the first and last node in the given array.
|
|
1055
1084
|
* @param {Array} nodes An array-like object
|
|
1056
|
-
* @returns {
|
|
1085
|
+
* @returns {JQLite} the inputted object or a JQLite collection containing the nodes
|
|
1057
1086
|
*/
|
|
1058
1087
|
export function getBlockNodes(nodes) {
|
|
1059
1088
|
// TODO(perf): update `nodes` instead of creating a new object?
|
|
@@ -1065,11 +1094,11 @@ export function getBlockNodes(nodes) {
|
|
|
1065
1094
|
if (blockNodes || nodes[i] !== node) {
|
|
1066
1095
|
if (!blockNodes) {
|
|
1067
1096
|
// use element to avoid circular dependency
|
|
1068
|
-
blockNodes =
|
|
1097
|
+
blockNodes = Array.prototype.slice.call(nodes, 0, i);
|
|
1069
1098
|
}
|
|
1070
1099
|
blockNodes.push(node);
|
|
1071
1100
|
}
|
|
1072
1101
|
}
|
|
1073
1102
|
|
|
1074
|
-
return blockNodes || nodes;
|
|
1103
|
+
return JQLite(blockNodes || nodes);
|
|
1075
1104
|
}
|