@angular-wave/angular.ts 0.0.39 → 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.
Files changed (144) hide show
  1. package/Makefile +2 -0
  2. package/README.md +2 -1
  3. package/dist/angular-ts.esm.js +2 -2
  4. package/dist/angular-ts.umd.js +2 -1
  5. package/package.json +1 -1
  6. package/rollup.config.js +10 -5
  7. package/src/angular.spec.js +25 -26
  8. package/src/animations/animate-css-driver.js +3 -3
  9. package/src/animations/animate-queue.js +10 -7
  10. package/src/animations/animation.js +2 -2
  11. package/src/animations/shared.js +6 -6
  12. package/src/binding.spec.js +7 -7
  13. package/src/core/animate/animate.js +5 -5
  14. package/src/core/animate/animate.spec.js +31 -31
  15. package/src/core/cache/cache-factory.html +18 -0
  16. package/src/core/cache/{cache-factor.test.js → cache-factory.test.js} +1 -1
  17. package/src/core/compile/compile.js +33 -25
  18. package/src/core/compile/compile.md +2 -2
  19. package/src/core/compile/compile.spec.js +2 -43
  20. package/src/core/cookie-reader.spec.js +2 -2
  21. package/src/core/core.html +22 -0
  22. package/src/core/core.test.js +12 -0
  23. package/src/core/document.spec.js +4 -4
  24. package/src/core/exception-handler.js +30 -23
  25. package/src/core/interpolate/interpolate.js +7 -0
  26. package/src/core/{cache/cache-factor.html → location/location.html} +1 -1
  27. package/src/core/location/location.js +2 -2
  28. package/src/core/location/location.spec.js +17 -17
  29. package/src/core/location/location.test.js +12 -0
  30. package/src/core/on.spec.js +3 -3
  31. package/src/core/parser/parse.html +18 -0
  32. package/src/core/parser/parse.spec.js +1 -1
  33. package/src/core/parser/parse.test.js +12 -0
  34. package/src/core/prop.spec.js +3 -4
  35. package/src/core/pubsub/pubsub.html +18 -0
  36. package/src/core/pubsub/pubsub.spec.js +1 -1
  37. package/src/core/pubsub/pubsub.test.js +12 -0
  38. package/src/core/q/q.html +18 -0
  39. package/src/core/q/q.js +33 -0
  40. package/src/core/q/q.test.js +0 -0
  41. package/src/core/root-element.spec.js +4 -4
  42. package/src/core/sanitize/sanitize-uri.spec.js +1 -1
  43. package/src/core/sanitize/sanitize-uri.test.js +12 -0
  44. package/src/core/sanitize/sanitize.html +21 -0
  45. package/src/core/sce/sce.html +18 -0
  46. package/src/core/sce/sce.spec.js +2 -1
  47. package/src/core/sce/sce.test.js +12 -0
  48. package/src/core/scope/scope.html +18 -0
  49. package/src/core/scope/scope.js +1 -1
  50. package/src/core/scope/scope.spec.js +1 -1
  51. package/src/core/scope/scope.test.js +12 -0
  52. package/src/core/task-tracker-factory.js +9 -11
  53. package/src/core/timeout/timeout.html +18 -0
  54. package/src/core/timeout/timeout.js +9 -0
  55. package/src/core/timeout/timeout.spec.js +2 -2
  56. package/src/core/timeout/timout.test.js +12 -0
  57. package/src/core/url-utils/url-utils.html +18 -0
  58. package/src/core/url-utils/url-utils.spec.js +4 -2
  59. package/src/core/url-utils/url-utils.test.js +12 -0
  60. package/src/directive/attrs/attrs.spec.js +1 -2
  61. package/src/directive/attrs/boolean.spec.js +1 -2
  62. package/src/directive/attrs/element-style.spec.js +6 -7
  63. package/src/directive/attrs/src.spec.js +1 -2
  64. package/src/directive/bind/bind.spec.js +1 -2
  65. package/src/directive/class/class.spec.js +15 -16
  66. package/src/directive/cloak/cloak.spec.js +3 -4
  67. package/src/directive/controller/controller.spec.js +4 -5
  68. package/src/directive/events/click.spec.js +1 -2
  69. package/src/directive/events/event.spec.js +1 -1
  70. package/src/directive/events/events.js +7 -0
  71. package/src/directive/form/form.spec.js +17 -17
  72. package/src/directive/if/if.spec.js +2 -2
  73. package/src/directive/include/include.js +5 -7
  74. package/src/directive/include/include.spec.js +32 -32
  75. package/src/directive/init/init.spec.js +2 -3
  76. package/src/directive/input/input.spec.js +3 -3
  77. package/src/directive/list/list.spec.js +1 -2
  78. package/src/directive/model/model.js +13 -0
  79. package/src/directive/model/model.spec.js +4 -5
  80. package/src/directive/model-options/model-options.spec.js +3 -3
  81. package/src/directive/non-bindable/non-bindable.spec.js +1 -2
  82. package/src/directive/options/options.js +5 -5
  83. package/src/directive/options/options.spec.js +13 -13
  84. package/src/directive/ref/href.spec.js +1 -2
  85. package/src/directive/repeat/repeat.spec.js +12 -12
  86. package/src/directive/script/script.spec.js +2 -3
  87. package/src/directive/select/select.js +6 -6
  88. package/src/directive/select/select.spec.js +5 -5
  89. package/src/directive/show-hide/show-hide.spec.js +12 -13
  90. package/src/directive/style/style.spec.js +3 -4
  91. package/src/directive/switch/switch.spec.js +2 -3
  92. package/src/directive/validators/validators.spec.js +1 -1
  93. package/src/exts/aria/aria.spec.js +1 -2
  94. package/src/exts/messages/messages.spec.js +5 -5
  95. package/src/filters/filter.spec.js +5 -5
  96. package/src/filters/filters.html +21 -0
  97. package/src/filters/filters.spec.js +3 -3
  98. package/src/filters/filters.test.js +12 -0
  99. package/src/filters/limit-to.md +1 -1
  100. package/src/filters/limit-to.spec.js +4 -4
  101. package/src/filters/order-by.spec.js +2 -2
  102. package/src/index.js +186 -31
  103. package/src/loader.js +49 -11
  104. package/src/public.js +2 -3
  105. package/src/router/directives/state-directives.spec.js +90 -90
  106. package/src/router/directives/view-directive.js +2 -2
  107. package/src/router/directives/view-directive.spec.js +9 -9
  108. package/src/router/state/state.spec.js +2 -4
  109. package/src/router/template-factory.spec.js +2 -2
  110. package/src/router/transition/hook-registry.js +2 -2
  111. package/src/router/view/view.spec.js +1 -1
  112. package/src/services/browser.js +56 -39
  113. package/src/services/document.js +16 -13
  114. package/src/services/http/http.js +11 -7
  115. package/src/services/log.js +39 -43
  116. package/src/services/template-request.js +9 -0
  117. package/src/shared/common.js +0 -3
  118. package/src/shared/jqlite/jqlite.js +370 -355
  119. package/src/shared/jqlite/jqlite.spec.js +260 -272
  120. package/src/shared/strings.js +2 -2
  121. package/src/shared/test-utils.js +2 -2
  122. package/src/shared/utils.js +8 -11
  123. package/src/types.js +13 -0
  124. package/types/animations/shared.d.ts +7 -2
  125. package/types/core/compile/compile.d.ts +2 -1
  126. package/types/core/exception-handler.d.ts +9 -42
  127. package/types/core/interpolate/interpolate.d.ts +1 -1
  128. package/types/core/q/q.d.ts +35 -1
  129. package/types/core/task-tracker-factory.d.ts +18 -11
  130. package/types/core/timeout/timeout.d.ts +10 -1
  131. package/types/directive/include/include.d.ts +2 -2
  132. package/types/directive/model/model.d.ts +28 -4
  133. package/types/index.d.ts +664 -79
  134. package/types/services/browser.d.ts +50 -20
  135. package/types/services/document.d.ts +14 -9
  136. package/types/services/log.d.ts +37 -34
  137. package/types/services/template-request.d.ts +1 -1
  138. package/types/shared/common.d.ts +0 -1
  139. package/types/shared/jqlite/jqlite.d.ts +83 -22
  140. package/types/shared/utils.d.ts +22 -22
  141. package/types/types.d.ts +34 -0
  142. package/types-back/index.d.ts +0 -130
  143. package/types-back/jqlite.d.ts +1 -40
  144. /package/src/core/cache/{cache-factor.spec.js → cache-factory.spec.js} +0 -0
@@ -12,12 +12,10 @@ 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
 
19
18
  /**
20
- * @ngdoc function
21
19
  * @name angular.element
22
20
  * @module ng
23
21
  * @kind function
@@ -26,24 +24,23 @@ import { CACHE, EXPANDO } from "../../core/cache/cache";
26
24
  * Wraps a raw DOM element or HTML string as a [jQuery](http://jquery.com) element. Regardless of the presence of jQuery, `angular.element`
27
25
  * delegates to AngularJS's built-in subset of jQuery, called "jQuery lite" or **jqLite**.
28
26
  *
29
- * jqLite is a tiny, API-compatible subset of jQuery that allows
30
- * AngularJS to manipulate the DOM in a cross-browser compatible way. jqLite implements only the most
27
+ * JQLite is a tiny, API-compatible subset of jQuery that allows
28
+ * AngularJS to manipulate the DOM in a cross-browser compatible way. JQLite implements only the most
31
29
  * commonly needed functionality with the goal of having a very small footprint.
32
30
  *
33
- *
34
31
  * <div class="alert alert-info">**Note:** All element references in AngularJS are always wrapped with
35
- * jqLite (such as the element argument in a directive's compile / link function). They are never raw DOM references.</div>
32
+ * JQLite (such as the element argument in a directive's compile / link function). They are never raw DOM references.</div>
36
33
  *
37
34
  * <div class="alert alert-warning">**Note:** Keep in mind that this function will not find elements
38
35
  * by tag name / CSS selector. For lookups by tag name, try instead `angular.element(document).find(...)`
39
36
  * or `$document.find()`, or use the standard DOM APIs, e.g. `document.querySelectorAll()`.</div>
40
37
  *
41
- * ## AngularJS's jqLite
42
- * jqLite provides only the following jQuery methods:
38
+ * ## AngularJS's JQLite
39
+ * JQLite provides only the following jQuery methods:
43
40
  *
44
41
  * - [`after()`](http://api.jquery.com/after/)
45
42
  * - [`append()`](http://api.jquery.com/append/) - Contrary to jQuery, this doesn't clone elements
46
- * so will not work correctly when invoked on a jqLite object containing more than one DOM node
43
+ * so will not work correctly when invoked on a JQLite object containing more than one DOM node
47
44
  * - [`attr()`](http://api.jquery.com/attr/) - Does not support functions as parameters
48
45
  * - [`children()`](http://api.jquery.com/children/) - Does not support selectors
49
46
  * - [`data()`](http://api.jquery.com/data/)
@@ -52,7 +49,6 @@ import { CACHE, EXPANDO } from "../../core/cache/cache";
52
49
  * - [`html()`](http://api.jquery.com/html/)
53
50
  * - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
54
51
  * - [`off()`](http://api.jquery.com/off/) - Does not support namespaces, selectors or event object as parameter
55
- * - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors
56
52
  * - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors
57
53
  * - [`prepend()`](http://api.jquery.com/prepend/)
58
54
  * - [`remove()`](http://api.jquery.com/remove/)
@@ -63,10 +59,10 @@ import { CACHE, EXPANDO } from "../../core/cache/cache";
63
59
  * - [`val()`](http://api.jquery.com/val/)
64
60
  *
65
61
  * ## jQuery/jqLite Extras
66
- * AngularJS also provides the following additional methods and events to both jQuery and jqLite:
62
+ * AngularJS also provides the following additional methods and events to both jQuery and JQLite:
67
63
  *
68
64
  * ### Events
69
- * - `$destroy` - AngularJS intercepts all jqLite/jQuery's DOM destruction apis and fires this event
65
+ * - `$destroy` - AngularJS intercepts all JQLite/jQuery's DOM destruction apis and fires this event
70
66
  * on all DOM nodes being removed. This can be used to clean up any 3rd party bindings to the DOM
71
67
  * element before it is removed.
72
68
  *
@@ -93,6 +89,7 @@ import { CACHE, EXPANDO } from "../../core/cache/cache";
93
89
  * @returns {Object} jQuery object.
94
90
  */
95
91
 
92
+ /** @type {number} */
96
93
  let jqId = 1;
97
94
 
98
95
  function jqNextId() {
@@ -102,7 +99,7 @@ function jqNextId() {
102
99
  const DASH_LOWERCASE_REGEXP = /-([a-z])/g;
103
100
  const UNDERSCORE_LOWERCASE_REGEXP = /_([a-z])/g;
104
101
  const MOUSE_EVENT_MAP = { mouseleave: "mouseout", mouseenter: "mouseover" };
105
- const jqLiteMinErr = minErr("jqLite");
102
+ const JQLiteMinErr = minErr("jqLite");
106
103
 
107
104
  /**
108
105
  * @param {string} _all
@@ -153,177 +150,66 @@ wrapMap.tbody =
153
150
  wrapMap.thead;
154
151
  wrapMap.th = wrapMap.td;
155
152
 
156
- /**
157
- * Checks if the string contains HTML tags or entities.
158
- * @param {string} html
159
- * @returns {boolean}
160
- */
161
- export function isTextNode(html) {
162
- return !/<|&#?\w+;/.test(html);
163
- }
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
+ });
164
165
 
165
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.
166
169
  *
167
- * @param {Element} node
168
- * @returns {boolean}
170
+ * @param {string|Element|Document|Window|JQLite|ArrayLike<Element>|(() => void)} element
171
+ * @returns {JQLite}
169
172
  */
170
- function elementAcceptsData(node) {
171
- // The window object can accept data but has no nodeType
172
- // Otherwise we are only interested in elements (1) and documents (9)
173
- switch (node.nodeType) {
174
- case Node.ELEMENT_NODE:
175
- case Node.DOCUMENT_NODE:
176
- case undefined:
177
- return true;
178
- default:
179
- return false;
180
- }
181
- }
182
-
183
- export function jqLiteBuildFragment(html, context) {
184
- let tmp;
185
- let tag;
186
- let wrap;
187
- let finalHtml;
188
- const fragment = context.createDocumentFragment();
189
- let nodes = [];
190
- let i;
191
-
192
- if (isTextNode(html)) {
193
- // Convert non-html into a text node
194
- nodes.push(context.createTextNode(html));
195
- } else {
196
- // Convert html into DOM nodes
197
- tmp = fragment.appendChild(context.createElement("div"));
198
- tag = (TAG_NAME_REGEXP.exec(html) || ["", ""])[1].toLowerCase();
199
- finalHtml = html;
200
-
201
- wrap = wrapMap[tag] || [];
202
-
203
- // Create wrappers & descend into them
204
- i = wrap.length;
205
- while (--i > -1) {
206
- tmp.appendChild(window.document.createElement(wrap[i]));
207
- tmp = tmp.firstChild;
208
- }
209
-
210
- tmp.innerHTML = finalHtml;
211
-
212
- nodes = concat(nodes, tmp.childNodes);
213
-
214
- tmp = fragment.firstChild;
215
- tmp.textContent = "";
216
- }
217
-
218
- // Remove wrapper from fragment
219
- fragment.textContent = "";
220
- fragment.innerHTML = ""; // Clear inner HTML
221
- forEach(nodes, (node) => {
222
- fragment.appendChild(node);
223
- });
224
-
225
- return fragment;
226
- }
227
-
228
- function jqLiteParseHTML(html, context) {
229
- context = context || window.document;
230
- let parsed;
231
-
232
- if ((parsed = SINGLE_TAG_REGEXP.exec(html))) {
233
- return [context.createElement(parsed[1])];
234
- }
235
-
236
- if ((parsed = jqLiteBuildFragment(html, context))) {
237
- return parsed.childNodes;
238
- }
239
-
240
- return [];
241
- }
242
-
243
- // IE9-11 has no method "contains" in SVG element and in Node.prototype. Bug #10259.
244
- const jqLiteContains =
245
- window.Node.prototype.contains ||
246
- function (arg) {
247
- return !!(this.compareDocumentPosition(arg) & 16);
248
- };
249
-
250
- /// //////////////////////////////////////////
251
173
  export function JQLite(element) {
252
174
  if (element instanceof JQLite) {
253
175
  return element;
254
176
  }
255
177
 
256
- let argIsString;
178
+ let argIsString = false;
257
179
 
258
180
  if (isString(element)) {
259
- element = trim(element);
181
+ element = /** @type {string} */ (element).trim();
260
182
  argIsString = true;
261
183
  }
184
+
262
185
  if (!(this instanceof JQLite)) {
263
- if (argIsString && element.charAt(0) !== "<") {
264
- throw jqLiteMinErr(
186
+ if (argIsString && /** @type {string} */ (element).charAt(0) !== "<") {
187
+ throw JQLiteMinErr(
265
188
  "nosel",
266
- "Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element",
189
+ "Looking up elements via selectors is not supported by JQLite! See: http://docs.angularjs.org/api/angular.element",
267
190
  );
268
191
  }
269
192
  return new JQLite(element);
270
193
  }
271
194
 
272
195
  if (argIsString) {
273
- const parsed = jqLiteParseHTML(element);
196
+ const parsed = parseHtml(/** @type {string} */ (element));
274
197
  addNodes(this, parsed);
275
198
  } else if (isFunction(element)) {
276
- jqLiteReady(element);
199
+ onReady(/** @type {Function} */ (element));
277
200
  } else {
278
201
  addNodes(this, element);
279
202
  }
280
203
  }
281
- export var jqLite = JQLite;
282
-
283
- jqLite.CACHE = CACHE;
284
-
285
- /**
286
- * @param {Element} element
287
- * @param {boolean} [onlyDescendants]
288
- * @returns {void}
289
- */
290
- export function dealoc(element, onlyDescendants) {
291
- if (!element) return;
292
- if (!onlyDescendants && elementAcceptsData(element))
293
- jqLiteCleanData([element]);
294
-
295
- if (element.querySelectorAll) {
296
- jqLiteCleanData(element.querySelectorAll("*"));
297
- }
298
- }
299
-
300
- /**
301
- * If `ExpandoStore.data` and `ExpandoStore.events` are empty,
302
- * then delete element's `ExpandoStore` and set its `ExpandoId`
303
- * to undefined.
304
- * @param {Element} element
305
- */
306
- function removeIfEmptyData(element) {
307
- const expandoId = element[EXPANDO];
308
- const { events, data } = CACHE.get(expandoId);
309
-
310
- if (
311
- (!data || !Object.keys(data).length) &&
312
- (!events || !Object.keys(events).length)
313
- ) {
314
- CACHE.delete(expandoId);
315
- element[EXPANDO] = undefined; // don't delete DOM expandos. Chrome don't like it
316
- }
317
- }
318
204
 
319
- function jqLiteOff(element, type, fn, unsupported) {
205
+ function JQLiteOff(element, type, fn, unsupported) {
320
206
  if (isDefined(unsupported))
321
- throw jqLiteMinErr(
207
+ throw JQLiteMinErr(
322
208
  "offargs",
323
209
  "jqLite#off() does not support the `selector` argument",
324
210
  );
325
211
 
326
- const expandoStore = jqLiteExpandoStore(element);
212
+ const expandoStore = getExpando(element);
327
213
  const events = expandoStore && expandoStore.events;
328
214
  const handle = expandoStore && expandoStore.handle;
329
215
 
@@ -366,7 +252,7 @@ function jqLiteOff(element, type, fn, unsupported) {
366
252
  * @param {Element} element
367
253
  * @param {string} [name] - key of field to remove
368
254
  */
369
- function jqLiteRemoveData(element, name) {
255
+ export function removeElementData(element, name) {
370
256
  const expandoId = element[EXPANDO];
371
257
  const expandoStore = expandoId && CACHE.get(expandoId);
372
258
 
@@ -382,12 +268,15 @@ function jqLiteRemoveData(element, name) {
382
268
  }
383
269
 
384
270
  /**
271
+ * Stores data associated with an element inside the expando property of the DOM element.
272
+ *
273
+ * @see {@link https://developer.mozilla.org/en-US/docs/Glossary/Expando MDN Glossary: Expando}
385
274
  *
386
275
  * @param {Element} element
387
- * @param {boolean} createIfNecessary
388
- * @returns {import("./core/cache").ExpandoStore}
276
+ * @param {boolean} [createIfNecessary=false]
277
+ * @returns {import("../../core/cache/cache").ExpandoStore}
389
278
  */
390
- function jqLiteExpandoStore(element, createIfNecessary = false) {
279
+ function getExpando(element, createIfNecessary = false) {
391
280
  let expandoId = element[EXPANDO];
392
281
  let expandoStore = expandoId && CACHE.get(expandoId);
393
282
 
@@ -404,14 +293,141 @@ function jqLiteExpandoStore(element, createIfNecessary = false) {
404
293
  return expandoStore;
405
294
  }
406
295
 
407
- function jqLiteData(element, key, value) {
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) {
408
424
  if (elementAcceptsData(element)) {
409
425
  let prop;
410
426
 
411
427
  const isSimpleSetter = isDefined(value);
412
428
  const isSimpleGetter = !isSimpleSetter && key && !isObject(key);
413
429
  const massGetter = !key;
414
- const expandoStore = jqLiteExpandoStore(element, !isSimpleGetter);
430
+ const expandoStore = getExpando(element, !isSimpleGetter);
415
431
  const data = expandoStore && expandoStore.data;
416
432
 
417
433
  if (isSimpleSetter) {
@@ -429,6 +445,8 @@ function jqLiteData(element, key, value) {
429
445
  data[kebabToCamel(prop)] = key[prop];
430
446
  }
431
447
  }
448
+ } else {
449
+ // TODO: check should occur perhaps prior at compilation level that this is a valid element
432
450
  }
433
451
  }
434
452
 
@@ -462,11 +480,11 @@ function addNodes(root, elements) {
462
480
  }
463
481
  }
464
482
 
465
- function jqLiteController(element, name) {
466
- return jqLiteInheritedData(element, `$${name || "ngController"}Controller`);
483
+ function JQLiteController(element, name) {
484
+ return JQLiteInheritedData(element, `$${name || "ngController"}Controller`);
467
485
  }
468
486
 
469
- function jqLiteInheritedData(element, name, value) {
487
+ function JQLiteInheritedData(element, name, value) {
470
488
  // if element is the document object work with the html element instead
471
489
  // this makes $(document).scope() possible
472
490
  if (element.nodeType === Node.DOCUMENT_NODE) {
@@ -476,7 +494,8 @@ function jqLiteInheritedData(element, name, value) {
476
494
 
477
495
  while (element) {
478
496
  for (let i = 0, ii = names.length; i < ii; i++) {
479
- if (isDefined((value = jqLiteData(element, names[i])))) return value;
497
+ if (isDefined((value = getOrSetCacheData(element, names[i]))))
498
+ return value;
480
499
  }
481
500
 
482
501
  // If dealing with a document fragment node with a host element, and no parent, use the host
@@ -488,37 +507,32 @@ function jqLiteInheritedData(element, name, value) {
488
507
  }
489
508
  }
490
509
 
491
- function jqLiteEmpty(element) {
492
- dealoc(element, true);
493
- while (element.firstChild) {
494
- element.removeChild(element.firstChild);
495
- }
496
- }
497
-
498
- export function jqLiteRemove(element, keepData) {
510
+ /**
511
+ *
512
+ * @param {Element} element
513
+ * @param {boolean} keepData
514
+ */
515
+ export function removeElement(element, keepData = false) {
499
516
  if (!keepData) dealoc(element);
500
517
  const parent = element.parentNode;
501
518
  if (parent) parent.removeChild(element);
502
519
  }
503
520
 
504
- function jqLiteReady(fn) {
521
+ /**
522
+ * Executea a function on `DOMContentLoaded`
523
+ * @param {Function} fn
524
+ */
525
+ function onReady(fn) {
505
526
  function trigger() {
506
527
  window.document.removeEventListener("DOMContentLoaded", trigger);
507
- window.removeEventListener("load", trigger);
508
528
  fn();
509
529
  }
510
-
511
530
  // check if document is already loaded
512
531
  if (window.document.readyState === "complete") {
513
532
  window.setTimeout(fn);
514
533
  } else {
515
- // We can not use jqLite since we are not done loading and jQuery could be loaded later.
516
-
517
- // Works for modern browsers and IE9
534
+ // We can not use JQLite since we are not done loading.
518
535
  window.document.addEventListener("DOMContentLoaded", trigger);
519
-
520
- // Fallback to window.onload for others
521
- window.addEventListener("load", trigger);
522
536
  }
523
537
  }
524
538
 
@@ -526,7 +540,6 @@ function jqLiteReady(fn) {
526
540
  // Functions which are declared directly.
527
541
  /// ///////////////////////////////////////
528
542
  JQLite.prototype = {
529
- ready: jqLiteReady,
530
543
  toString() {
531
544
  const value = [];
532
545
  forEach(this, (e) => {
@@ -536,32 +549,76 @@ JQLite.prototype = {
536
549
  },
537
550
 
538
551
  eq(index) {
539
- return index >= 0 ? jqLite(this[index]) : jqLite(this[this.length + index]);
552
+ return index >= 0 ? JQLite(this[index]) : JQLite(this[this.length + index]);
540
553
  },
541
554
 
542
555
  length: 0,
543
- push: [].push,
544
- sort: [].sort,
545
- splice: [].splice,
546
556
  };
547
557
 
548
- /// ///////////////////////////////////////
549
- // Functions iterating getter/setters.
550
- // these functions return self on setter and
551
- // value on get.
552
- /// ///////////////////////////////////////
553
- export const BOOLEAN_ATTR = {};
554
- "multiple,selected,checked,disabled,readOnly,required,open"
555
- .split(",")
556
- .forEach((value) => {
557
- BOOLEAN_ATTR[lowercase(value)] = value;
558
- });
559
- const BOOLEAN_ELEMENTS = {};
560
- "input,select,option,textarea,button,form,details"
561
- .split(",")
562
- .forEach((value) => {
563
- BOOLEAN_ELEMENTS[value] = true;
564
- });
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
+ };
565
622
 
566
623
  export function getBooleanAttrName(element, name) {
567
624
  // check dom last since we will most likely fail on name
@@ -571,58 +628,31 @@ export function getBooleanAttrName(element, name) {
571
628
  return booleanAttr && BOOLEAN_ELEMENTS[nodeName_(element)] && booleanAttr;
572
629
  }
573
630
 
574
- export function jqLiteCleanData(nodes) {
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) {
575
637
  for (let i = 0, ii = nodes.length; i < ii; i++) {
576
638
  var events = (CACHE.get(nodes[i][EXPANDO]) || {}).events;
577
639
  if (events && events.$destroy) {
578
- jqLite(nodes[i]).triggerHandler("$destroy");
640
+ JQLite(nodes[i]).triggerHandler("$destroy");
579
641
  }
580
- jqLiteRemoveData(nodes[i]);
581
- jqLiteOff(nodes[i]);
642
+ removeElementData(nodes[i]);
643
+ JQLiteOff(nodes[i]);
582
644
  }
583
645
  }
584
646
 
647
+ /// ///////////////////////////////////////
648
+ // Functions iterating getter/setters.
649
+ // these functions return self on setter and
650
+ // value on get.
651
+ /// ///////////////////////////////////////
585
652
  forEach(
586
653
  {
587
- data: jqLiteData,
588
- removeData: jqLiteRemoveData,
589
- cleanData: jqLiteCleanData,
590
- },
591
- (fn, name) => {
592
- JQLite[name] = fn;
593
- },
594
- );
595
-
596
- forEach(
597
- {
598
- data: jqLiteData,
599
- inheritedData: jqLiteInheritedData,
600
-
601
- scope(element) {
602
- // Can't use jqLiteData here directly so we stay compatible with jQuery!
603
- return (
604
- jqLiteData(element, "$scope") ||
605
- jqLiteInheritedData(element.parentNode || element, [
606
- "$isolateScope",
607
- "$scope",
608
- ])
609
- );
610
- },
611
-
612
- isolateScope(element) {
613
- // Can't use jqLiteData here directly so we stay compatible with jQuery!
614
- return (
615
- jqLiteData(element, "$isolateScope") ||
616
- jqLiteData(element, "$isolateScopeNoTemplate")
617
- );
618
- },
619
-
620
- controller: jqLiteController,
621
-
622
- injector(element) {
623
- return jqLiteInheritedData(element, "$injector");
624
- },
625
-
654
+ data: getOrSetCacheData,
655
+ inheritedData: JQLiteInheritedData,
626
656
  attr(element, name, value) {
627
657
  let ret;
628
658
  const { nodeType } = element;
@@ -672,7 +702,6 @@ forEach(
672
702
  element.textContent = value;
673
703
  }
674
704
  })(),
675
-
676
705
  val(element, value) {
677
706
  if (isUndefined(value)) {
678
707
  if (element.multiple && nodeName_(element) === "select") {
@@ -688,7 +717,6 @@ forEach(
688
717
  }
689
718
  element.value = value;
690
719
  },
691
-
692
720
  html(element, value) {
693
721
  if (isUndefined(value)) {
694
722
  return element.innerHTML;
@@ -696,8 +724,6 @@ forEach(
696
724
  dealoc(element, true);
697
725
  element.innerHTML = value;
698
726
  },
699
-
700
- empty: jqLiteEmpty,
701
727
  },
702
728
  (fn, name) => {
703
729
  /**
@@ -708,15 +734,14 @@ forEach(
708
734
  let key;
709
735
  const nodeCount = this.length;
710
736
 
711
- // jqLiteEmpty takes no arguments but is a setter.
737
+ // JQLiteEmpty takes no arguments but is a setter.
712
738
  if (
713
- fn !== jqLiteEmpty &&
714
- isUndefined(fn.length === 2 && fn !== jqLiteController ? arg1 : arg2)
739
+ isUndefined(fn.length === 2 && fn !== JQLiteController ? arg1 : arg2)
715
740
  ) {
716
741
  if (isObject(arg1)) {
717
742
  // we are a write, but the object properties are the key/values
718
743
  for (i = 0; i < nodeCount; i++) {
719
- if (fn === jqLiteData) {
744
+ if (fn === getOrSetCacheData) {
720
745
  fn(this[i], arg1);
721
746
  } else {
722
747
  for (key in arg1) {
@@ -748,78 +773,6 @@ forEach(
748
773
  },
749
774
  );
750
775
 
751
- function createEventHandler(element, events) {
752
- const eventHandler = function (event, type) {
753
- // jQuery specific api
754
- event.isDefaultPrevented = function () {
755
- return event.defaultPrevented;
756
- };
757
-
758
- let eventFns = events[type || event.type];
759
- const eventFnsLength = eventFns ? eventFns.length : 0;
760
-
761
- if (!eventFnsLength) return;
762
-
763
- if (isUndefined(event.immediatePropagationStopped)) {
764
- const originalStopImmediatePropagation = event.stopImmediatePropagation;
765
- event.stopImmediatePropagation = function () {
766
- event.immediatePropagationStopped = true;
767
-
768
- if (event.stopPropagation) {
769
- event.stopPropagation();
770
- }
771
-
772
- if (originalStopImmediatePropagation) {
773
- originalStopImmediatePropagation.call(event);
774
- }
775
- };
776
- }
777
-
778
- event.isImmediatePropagationStopped = function () {
779
- return event.immediatePropagationStopped === true;
780
- };
781
-
782
- // Some events have special handlers that wrap the real handler
783
- const handlerWrapper =
784
- eventFns.specialHandlerWrapper || defaultHandlerWrapper;
785
-
786
- // Copy event handlers in case event handlers array is modified during execution.
787
- if (eventFnsLength > 1) {
788
- eventFns = shallowCopy(eventFns);
789
- }
790
-
791
- for (let i = 0; i < eventFnsLength; i++) {
792
- if (!event.isImmediatePropagationStopped()) {
793
- handlerWrapper(element, event, eventFns[i]);
794
- }
795
- }
796
- };
797
-
798
- // TODO: this is a hack for angularMocks/clearDataCache that makes it possible to deregister all
799
- // events on `element`
800
- eventHandler.elem = element;
801
- return eventHandler;
802
- }
803
-
804
- function defaultHandlerWrapper(element, event, handler) {
805
- handler.call(element, event);
806
- }
807
-
808
- function specialMouseHandlerWrapper(target, event, handler) {
809
- // Refer to jQuery's implementation of mouseenter & mouseleave
810
- // Read about mouseenter and mouseleave:
811
- // http://www.quirksmode.org/js/events_mouse.html#link8
812
- const related = event.relatedTarget;
813
- // For mousenter/leave call the handler if related is outside the target.
814
- // NB: No relatedTarget if the mouse left/entered the browser window
815
- if (
816
- !related ||
817
- (related !== target && !jqLiteContains.call(target, related))
818
- ) {
819
- handler.call(target, event);
820
- }
821
- }
822
-
823
776
  /// ///////////////////////////////////////
824
777
  // Functions iterating traversal.
825
778
  // These functions chain results into a single
@@ -827,25 +780,17 @@ function specialMouseHandlerWrapper(target, event, handler) {
827
780
  /// ///////////////////////////////////////
828
781
  forEach(
829
782
  {
830
- removeData: jqLiteRemoveData,
831
- on: (element, type, fn, unsupported) => {
832
- if (isDefined(unsupported))
833
- throw jqLiteMinErr(
834
- "onargs",
835
- "jqLite#on() does not support the `selector` or `eventData` parameters",
836
- );
837
-
783
+ removeData: removeElementData,
784
+ on: (element, type, fn) => {
838
785
  // Do not add event handlers to non-elements because they will not be cleaned up.
839
786
  if (!elementAcceptsData(element)) {
840
787
  return;
841
788
  }
842
789
 
843
- const expandoStore = jqLiteExpandoStore(element, true);
844
- const { events } = expandoStore;
845
- let { handle } = expandoStore;
790
+ const expandoStore = getExpando(element, true);
846
791
 
847
- if (!handle) {
848
- handle = expandoStore.handle = createEventHandler(element, events);
792
+ if (!expandoStore.handle) {
793
+ expandoStore.handle = createEventHandler(element, expandoStore.events);
849
794
  }
850
795
 
851
796
  // http://jsperf.com/string-indexof-vs-split
@@ -857,13 +802,13 @@ forEach(
857
802
  specialHandlerWrapper,
858
803
  noEventListener,
859
804
  ) {
860
- let eventFns = events[type];
805
+ let eventFns = expandoStore.events[type];
861
806
 
862
807
  if (!eventFns) {
863
- eventFns = events[type] = [];
808
+ eventFns = expandoStore.events[type] = [];
864
809
  eventFns.specialHandlerWrapper = specialHandlerWrapper;
865
810
  if (type !== "$destroy" && !noEventListener) {
866
- element.addEventListener(type, handle);
811
+ element.addEventListener(type, expandoStore.handle);
867
812
  }
868
813
  }
869
814
 
@@ -880,9 +825,7 @@ forEach(
880
825
  }
881
826
  }
882
827
  },
883
-
884
- off: jqLiteOff,
885
-
828
+ off: JQLiteOff,
886
829
  replaceWith(element, replaceNode) {
887
830
  let index;
888
831
  const parent = element.parentNode;
@@ -896,13 +839,11 @@ forEach(
896
839
  index = node;
897
840
  });
898
841
  },
899
-
900
842
  children(element) {
901
843
  return Array.from(element.childNodes).filter(
902
844
  (child) => child.nodeType === Node.ELEMENT_NODE,
903
845
  );
904
846
  },
905
-
906
847
  append(element, node) {
907
848
  const { nodeType } = element;
908
849
  if (
@@ -928,10 +869,10 @@ forEach(
928
869
  }
929
870
  },
930
871
 
931
- remove: jqLiteRemove,
872
+ remove: removeElement,
932
873
 
933
874
  detach(element) {
934
- jqLiteRemove(element, true);
875
+ removeElement(element, true);
935
876
  },
936
877
 
937
878
  after(element, newElement) {
@@ -956,7 +897,7 @@ forEach(
956
897
  : null;
957
898
  },
958
899
 
959
- // TODO: remove after migrating tests away from jqLite
900
+ // TODO: remove after migrating tests away from JQLite
960
901
  find(element, selector) {
961
902
  if (element.getElementsByTagName) {
962
903
  return element.getElementsByTagName(selector);
@@ -969,7 +910,7 @@ forEach(
969
910
  let eventFnsCopy;
970
911
  let handlerArgs;
971
912
  const eventName = event.type || event;
972
- const expandoStore = jqLiteExpandoStore(element);
913
+ const expandoStore = getExpando(element);
973
914
  const events = expandoStore && expandoStore.events;
974
915
  const eventFns = events && events[eventName];
975
916
 
@@ -1024,7 +965,7 @@ forEach(
1024
965
  value = fn(this[i], arg1, arg2, arg3);
1025
966
  if (isDefined(value)) {
1026
967
  // any function which returns a value needs to be wrapped
1027
- value = jqLite(value);
968
+ value = JQLite(value);
1028
969
  }
1029
970
  } else {
1030
971
  addNodes(value, fn(this[i], arg1, arg2, arg3));
@@ -1035,14 +976,88 @@ forEach(
1035
976
  },
1036
977
  );
1037
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
+
1038
1053
  /**
1039
1054
  * @param {string} elementStr
1040
1055
  * @returns {string} Returns the string representation of the element.
1041
1056
  */
1042
1057
  export function startingTag(elementStr) {
1043
- const clone = jqLite(elementStr)[0].cloneNode(true);
1044
- const element = jqLite(clone).empty();
1045
- var elemHtml = jqLite("<div></div>").append(element).html();
1058
+ const clone = JQLite(elementStr)[0].cloneNode(true);
1059
+ const element = JQLite(clone).empty();
1060
+ var elemHtml = JQLite("<div></div>").append(element).html();
1046
1061
  try {
1047
1062
  return element[0].nodeType === Node.TEXT_NODE
1048
1063
  ? lowercase(elemHtml)
@@ -1059,7 +1074,7 @@ export function startingTag(elementStr) {
1059
1074
  /**
1060
1075
  * Return the DOM siblings between the first and last node in the given array.
1061
1076
  * @param {Array} nodes An array-like object
1062
- * @returns {Array} the inputted object or a jqLite collection containing the nodes
1077
+ * @returns {JQLite} the inputted object or a JQLite collection containing the nodes
1063
1078
  */
1064
1079
  export function getBlockNodes(nodes) {
1065
1080
  // TODO(perf): update `nodes` instead of creating a new object?
@@ -1071,11 +1086,11 @@ export function getBlockNodes(nodes) {
1071
1086
  if (blockNodes || nodes[i] !== node) {
1072
1087
  if (!blockNodes) {
1073
1088
  // use element to avoid circular dependency
1074
- blockNodes = jqLite(Array.prototype.slice.call(nodes, 0, i));
1089
+ blockNodes = Array.prototype.slice.call(nodes, 0, i);
1075
1090
  }
1076
1091
  blockNodes.push(node);
1077
1092
  }
1078
1093
  }
1079
1094
 
1080
- return blockNodes || nodes;
1095
+ return JQLite(blockNodes || nodes);
1081
1096
  }