@angular-wave/angular.ts 0.0.1
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/.eslintignore +1 -0
- package/.eslintrc.cjs +29 -0
- package/.github/workflows/playwright.yml +27 -0
- package/CHANGELOG.md +17974 -0
- package/CODE_OF_CONDUCT.md +3 -0
- package/CONTRIBUTING.md +246 -0
- package/DEVELOPERS.md +488 -0
- package/LICENSE +22 -0
- package/Makefile +31 -0
- package/README.md +115 -0
- package/RELEASE.md +98 -0
- package/SECURITY.md +16 -0
- package/TRIAGING.md +135 -0
- package/css/angular.css +22 -0
- package/dist/angular-ts.cjs.js +36843 -0
- package/dist/angular-ts.esm.js +36841 -0
- package/dist/angular-ts.umd.js +36848 -0
- package/dist/build/angular-animate.js +4272 -0
- package/dist/build/angular-aria.js +426 -0
- package/dist/build/angular-message-format.js +1072 -0
- package/dist/build/angular-messages.js +829 -0
- package/dist/build/angular-mocks.js +3757 -0
- package/dist/build/angular-parse-ext.js +1275 -0
- package/dist/build/angular-resource.js +911 -0
- package/dist/build/angular-route.js +1266 -0
- package/dist/build/angular-sanitize.js +891 -0
- package/dist/build/angular-touch.js +368 -0
- package/dist/build/angular.js +36600 -0
- package/e2e/unit.spec.ts +15 -0
- package/images/android-chrome-192x192.png +0 -0
- package/images/android-chrome-512x512.png +0 -0
- package/images/apple-touch-icon.png +0 -0
- package/images/favicon-16x16.png +0 -0
- package/images/favicon-32x32.png +0 -0
- package/images/favicon.ico +0 -0
- package/images/site.webmanifest +1 -0
- package/index.html +104 -0
- package/package.json +47 -0
- package/playwright.config.ts +78 -0
- package/public/circle.html +1 -0
- package/public/my_child_directive.html +1 -0
- package/public/my_directive.html +1 -0
- package/public/my_other_directive.html +1 -0
- package/public/test.html +1 -0
- package/rollup.config.js +31 -0
- package/src/animations/animateCache.js +55 -0
- package/src/animations/animateChildrenDirective.js +105 -0
- package/src/animations/animateCss.js +1139 -0
- package/src/animations/animateCssDriver.js +291 -0
- package/src/animations/animateJs.js +367 -0
- package/src/animations/animateJsDriver.js +67 -0
- package/src/animations/animateQueue.js +851 -0
- package/src/animations/animation.js +506 -0
- package/src/animations/module.js +779 -0
- package/src/animations/ngAnimateSwap.js +119 -0
- package/src/animations/rafScheduler.js +50 -0
- package/src/animations/shared.js +378 -0
- package/src/constants.js +20 -0
- package/src/core/animate.js +845 -0
- package/src/core/animateCss.js +73 -0
- package/src/core/animateRunner.js +195 -0
- package/src/core/attributes.js +199 -0
- package/src/core/cache.js +45 -0
- package/src/core/compile.js +4727 -0
- package/src/core/controller.js +225 -0
- package/src/core/exceptionHandler.js +63 -0
- package/src/core/filter.js +146 -0
- package/src/core/interpolate.js +442 -0
- package/src/core/interval.js +188 -0
- package/src/core/intervalFactory.js +57 -0
- package/src/core/location.js +1086 -0
- package/src/core/parser/parse.js +2562 -0
- package/src/core/parser/parse.md +13 -0
- package/src/core/q.js +746 -0
- package/src/core/rootScope.js +1596 -0
- package/src/core/sanitizeUri.js +85 -0
- package/src/core/sce.js +1161 -0
- package/src/core/taskTrackerFactory.js +125 -0
- package/src/core/timeout.js +121 -0
- package/src/core/urlUtils.js +187 -0
- package/src/core/utils.js +1349 -0
- package/src/directive/a.js +37 -0
- package/src/directive/attrs.js +283 -0
- package/src/directive/bind.js +51 -0
- package/src/directive/bind.md +142 -0
- package/src/directive/change.js +12 -0
- package/src/directive/change.md +25 -0
- package/src/directive/cloak.js +12 -0
- package/src/directive/cloak.md +24 -0
- package/src/directive/events.js +75 -0
- package/src/directive/events.md +166 -0
- package/src/directive/form.js +725 -0
- package/src/directive/init.js +15 -0
- package/src/directive/init.md +41 -0
- package/src/directive/input.js +1783 -0
- package/src/directive/list.js +46 -0
- package/src/directive/list.md +22 -0
- package/src/directive/ngClass.js +249 -0
- package/src/directive/ngController.js +64 -0
- package/src/directive/ngCsp.js +82 -0
- package/src/directive/ngIf.js +134 -0
- package/src/directive/ngInclude.js +217 -0
- package/src/directive/ngModel.js +1356 -0
- package/src/directive/ngModelOptions.js +509 -0
- package/src/directive/ngOptions.js +670 -0
- package/src/directive/ngRef.js +90 -0
- package/src/directive/ngRepeat.js +650 -0
- package/src/directive/ngShowHide.js +255 -0
- package/src/directive/ngSwitch.js +178 -0
- package/src/directive/ngTransclude.js +98 -0
- package/src/directive/non-bindable.js +11 -0
- package/src/directive/non-bindable.md +17 -0
- package/src/directive/script.js +30 -0
- package/src/directive/select.js +624 -0
- package/src/directive/style.js +25 -0
- package/src/directive/style.md +23 -0
- package/src/directive/validators.js +329 -0
- package/src/exts/aria.js +544 -0
- package/src/exts/messages.js +852 -0
- package/src/filters/filter.js +207 -0
- package/src/filters/filter.md +69 -0
- package/src/filters/filters.js +239 -0
- package/src/filters/json.md +16 -0
- package/src/filters/limit-to.js +43 -0
- package/src/filters/limit-to.md +19 -0
- package/src/filters/order-by.js +183 -0
- package/src/filters/order-by.md +83 -0
- package/src/index.js +13 -0
- package/src/injector.js +1034 -0
- package/src/jqLite.js +1117 -0
- package/src/loader.js +1320 -0
- package/src/public.js +215 -0
- package/src/routeToRegExp.js +41 -0
- package/src/services/anchorScroll.js +135 -0
- package/src/services/browser.js +321 -0
- package/src/services/cacheFactory.js +398 -0
- package/src/services/cookieReader.js +72 -0
- package/src/services/document.js +64 -0
- package/src/services/http.js +1537 -0
- package/src/services/httpBackend.js +206 -0
- package/src/services/log.js +160 -0
- package/src/services/templateRequest.js +139 -0
- package/test/angular.spec.js +2153 -0
- package/test/aria/aria.spec.js +1245 -0
- package/test/binding.spec.js +504 -0
- package/test/build-test.html +14 -0
- package/test/injector.spec.js +2327 -0
- package/test/jasmine/jasmine-5.1.2/boot0.js +65 -0
- package/test/jasmine/jasmine-5.1.2/boot1.js +133 -0
- package/test/jasmine/jasmine-5.1.2/jasmine-html.js +963 -0
- package/test/jasmine/jasmine-5.1.2/jasmine.css +320 -0
- package/test/jasmine/jasmine-5.1.2/jasmine.js +10824 -0
- package/test/jasmine/jasmine-5.1.2/jasmine_favicon.png +0 -0
- package/test/jasmine/jasmine-browser.json +17 -0
- package/test/jasmine/jasmine.json +9 -0
- package/test/jqlite.spec.js +2133 -0
- package/test/loader.spec.js +219 -0
- package/test/messages/messages.spec.js +1146 -0
- package/test/min-err.spec.js +174 -0
- package/test/mock-test.html +13 -0
- package/test/module-test.html +15 -0
- package/test/ng/anomate.spec.js +606 -0
- package/test/ng/cache-factor.spec.js +334 -0
- package/test/ng/compile.spec.js +17956 -0
- package/test/ng/controller-provider.spec.js +227 -0
- package/test/ng/cookie-reader.spec.js +98 -0
- package/test/ng/directive/a.spec.js +192 -0
- package/test/ng/directive/bind.spec.js +334 -0
- package/test/ng/directive/boolean.spec.js +136 -0
- package/test/ng/directive/change.spec.js +71 -0
- package/test/ng/directive/class.spec.js +858 -0
- package/test/ng/directive/click.spec.js +38 -0
- package/test/ng/directive/cloak.spec.js +44 -0
- package/test/ng/directive/constoller.spec.js +194 -0
- package/test/ng/directive/element-style.spec.js +92 -0
- package/test/ng/directive/event.spec.js +282 -0
- package/test/ng/directive/form.spec.js +1518 -0
- package/test/ng/directive/href.spec.js +143 -0
- package/test/ng/directive/if.spec.js +402 -0
- package/test/ng/directive/include.spec.js +828 -0
- package/test/ng/directive/init.spec.js +68 -0
- package/test/ng/directive/input.spec.js +3810 -0
- package/test/ng/directive/list.spec.js +170 -0
- package/test/ng/directive/model-options.spec.js +1008 -0
- package/test/ng/directive/model.spec.js +1905 -0
- package/test/ng/directive/non-bindable.spec.js +55 -0
- package/test/ng/directive/options.spec.js +3583 -0
- package/test/ng/directive/ref.spec.js +575 -0
- package/test/ng/directive/repeat.spec.js +1675 -0
- package/test/ng/directive/script.spec.js +52 -0
- package/test/ng/directive/scrset.spec.js +67 -0
- package/test/ng/directive/select.spec.js +2541 -0
- package/test/ng/directive/show-hide.spec.js +253 -0
- package/test/ng/directive/src.spec.js +157 -0
- package/test/ng/directive/style.spec.js +178 -0
- package/test/ng/directive/switch.spec.js +647 -0
- package/test/ng/directive/validators.spec.js +717 -0
- package/test/ng/document.spec.js +52 -0
- package/test/ng/filter/filter.spec.js +714 -0
- package/test/ng/filter/filters.spec.js +35 -0
- package/test/ng/filter/limit-to.spec.js +251 -0
- package/test/ng/filter/order-by.spec.js +891 -0
- package/test/ng/filter.spec.js +149 -0
- package/test/ng/http-backend.spec.js +398 -0
- package/test/ng/http.spec.js +4071 -0
- package/test/ng/interpolate.spec.js +642 -0
- package/test/ng/interval.spec.js +343 -0
- package/test/ng/location.spec.js +3488 -0
- package/test/ng/on.spec.js +229 -0
- package/test/ng/parse.spec.js +4655 -0
- package/test/ng/prop.spec.js +805 -0
- package/test/ng/q.spec.js +2904 -0
- package/test/ng/root-element.spec.js +16 -0
- package/test/ng/sanitize-uri.spec.js +249 -0
- package/test/ng/sce.spec.js +660 -0
- package/test/ng/scope.spec.js +3442 -0
- package/test/ng/template-request.spec.js +236 -0
- package/test/ng/timeout.spec.js +351 -0
- package/test/ng/url-utils.spec.js +156 -0
- package/test/ng/utils.spec.js +144 -0
- package/test/original-test.html +21 -0
- package/test/public.spec.js +34 -0
- package/test/sanitize/bing-html.spec.js +36 -0
- package/test/server/express.js +158 -0
- package/test/test-utils.js +11 -0
- package/tsconfig.json +17 -0
- package/types/angular.d.ts +138 -0
- package/types/global.d.ts +9 -0
- package/types/index.d.ts +2357 -0
- package/types/jqlite.d.ts +558 -0
- package/vite.config.js +14 -0
package/src/jqLite.js
ADDED
|
@@ -0,0 +1,1117 @@
|
|
|
1
|
+
import {
|
|
2
|
+
minErr,
|
|
3
|
+
arrayRemove,
|
|
4
|
+
concat,
|
|
5
|
+
extend,
|
|
6
|
+
forEach,
|
|
7
|
+
isArray,
|
|
8
|
+
isDefined,
|
|
9
|
+
isFunction,
|
|
10
|
+
isObject,
|
|
11
|
+
isString,
|
|
12
|
+
isUndefined,
|
|
13
|
+
lowercase,
|
|
14
|
+
nodeName_,
|
|
15
|
+
shallowCopy,
|
|
16
|
+
trim,
|
|
17
|
+
} from "./core/utils";
|
|
18
|
+
import { CACHE } from "./core/cache";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @ngdoc function
|
|
22
|
+
* @name angular.element
|
|
23
|
+
* @module ng
|
|
24
|
+
* @kind function
|
|
25
|
+
*
|
|
26
|
+
* @description
|
|
27
|
+
* Wraps a raw DOM element or HTML string as a [jQuery](http://jquery.com) element. Regardless of the presence of jQuery, `angular.element`
|
|
28
|
+
* delegates to AngularJS's built-in subset of jQuery, called "jQuery lite" or **jqLite**.
|
|
29
|
+
*
|
|
30
|
+
* jqLite is a tiny, API-compatible subset of jQuery that allows
|
|
31
|
+
* AngularJS to manipulate the DOM in a cross-browser compatible way. jqLite implements only the most
|
|
32
|
+
* commonly needed functionality with the goal of having a very small footprint.
|
|
33
|
+
*
|
|
34
|
+
*
|
|
35
|
+
* <div class="alert alert-info">**Note:** All element references in AngularJS are always wrapped with
|
|
36
|
+
* jqLite (such as the element argument in a directive's compile / link function). They are never raw DOM references.</div>
|
|
37
|
+
*
|
|
38
|
+
* <div class="alert alert-warning">**Note:** Keep in mind that this function will not find elements
|
|
39
|
+
* by tag name / CSS selector. For lookups by tag name, try instead `angular.element(document).find(...)`
|
|
40
|
+
* or `$document.find()`, or use the standard DOM APIs, e.g. `document.querySelectorAll()`.</div>
|
|
41
|
+
*
|
|
42
|
+
* ## AngularJS's jqLite
|
|
43
|
+
* jqLite provides only the following jQuery methods:
|
|
44
|
+
*
|
|
45
|
+
* - [`addClass()`](http://api.jquery.com/addClass/) - Does not support a function as first argument
|
|
46
|
+
* - [`after()`](http://api.jquery.com/after/)
|
|
47
|
+
* - [`append()`](http://api.jquery.com/append/) - Contrary to jQuery, this doesn't clone elements
|
|
48
|
+
* so will not work correctly when invoked on a jqLite object containing more than one DOM node
|
|
49
|
+
* - [`attr()`](http://api.jquery.com/attr/) - Does not support functions as parameters
|
|
50
|
+
* - [`bind()`](http://api.jquery.com/bind/) (_deprecated_, use [`on()`](http://api.jquery.com/on/)) - Does not support namespaces, selectors or eventData
|
|
51
|
+
* - [`children()`](http://api.jquery.com/children/) - Does not support selectors
|
|
52
|
+
* - [`data()`](http://api.jquery.com/data/)
|
|
53
|
+
* - [`empty()`](http://api.jquery.com/empty/)
|
|
54
|
+
* - [`eq()`](http://api.jquery.com/eq/)
|
|
55
|
+
* - [`html()`](http://api.jquery.com/html/)
|
|
56
|
+
* - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
|
|
57
|
+
* - [`off()`](http://api.jquery.com/off/) - Does not support namespaces, selectors or event object as parameter
|
|
58
|
+
* - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors
|
|
59
|
+
* - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors
|
|
60
|
+
* - [`prepend()`](http://api.jquery.com/prepend/)
|
|
61
|
+
* - [`prop()`](http://api.jquery.com/prop/)
|
|
62
|
+
* - [`remove()`](http://api.jquery.com/remove/)
|
|
63
|
+
* - [`removeData()`](http://api.jquery.com/removeData/)
|
|
64
|
+
* - [`replaceWith()`](http://api.jquery.com/replaceWith/)
|
|
65
|
+
* - [`text()`](http://api.jquery.com/text/)
|
|
66
|
+
* - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers
|
|
67
|
+
* - [`val()`](http://api.jquery.com/val/)
|
|
68
|
+
*
|
|
69
|
+
* ## jQuery/jqLite Extras
|
|
70
|
+
* AngularJS also provides the following additional methods and events to both jQuery and jqLite:
|
|
71
|
+
*
|
|
72
|
+
* ### Events
|
|
73
|
+
* - `$destroy` - AngularJS intercepts all jqLite/jQuery's DOM destruction apis and fires this event
|
|
74
|
+
* on all DOM nodes being removed. This can be used to clean up any 3rd party bindings to the DOM
|
|
75
|
+
* element before it is removed.
|
|
76
|
+
*
|
|
77
|
+
* ### Methods
|
|
78
|
+
* - `controller(name)` - retrieves the controller of the current element or its parent. By default
|
|
79
|
+
* retrieves controller associated with the `ngController` directive. If `name` is provided as
|
|
80
|
+
* camelCase directive name, then the controller for this directive will be retrieved (e.g.
|
|
81
|
+
* `'ngModel'`).
|
|
82
|
+
* - `injector()` - retrieves the injector of the current element or its parent.
|
|
83
|
+
* - `scope()` - retrieves the {@link ng.$rootScope.Scope scope} of the current
|
|
84
|
+
* element or its parent. Requires {@link guide/production#disabling-debug-data Debug Data} to
|
|
85
|
+
* be enabled.
|
|
86
|
+
* - `isolateScope()` - retrieves an isolate {@link ng.$rootScope.Scope scope} if one is attached directly to the
|
|
87
|
+
* current element. This getter should be used only on elements that contain a directive which starts a new isolate
|
|
88
|
+
* scope. Calling `scope()` on this element always returns the original non-isolate scope.
|
|
89
|
+
* Requires {@link guide/production#disabling-debug-data Debug Data} to be enabled.
|
|
90
|
+
* - `inheritedData()` - same as `data()`, but walks up the DOM until a value is found or the top
|
|
91
|
+
* parent element is reached.
|
|
92
|
+
*
|
|
93
|
+
* @knownIssue You cannot spy on `angular.element` if you are using Jasmine version 1.x. See
|
|
94
|
+
* https://github.com/angular/angular.js/issues/14251 for more information.
|
|
95
|
+
*
|
|
96
|
+
* @param {string|Element} element HTML string or Element to be wrapped into jQuery.
|
|
97
|
+
* @returns {Object} jQuery object.
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
JQLite.cache = CACHE;
|
|
101
|
+
|
|
102
|
+
const EXPANDO = "ngId";
|
|
103
|
+
let jqId = 1;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* !!! This is an undocumented "private" function !!!
|
|
107
|
+
* @param {JQLite|Element} node
|
|
108
|
+
* @returns
|
|
109
|
+
*/
|
|
110
|
+
JQLite._data = (node) => JQLite.cache.get(node[EXPANDO]) || {};
|
|
111
|
+
|
|
112
|
+
function jqNextId() {
|
|
113
|
+
return ++jqId;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const DASH_LOWERCASE_REGEXP = /-([a-z])/g;
|
|
117
|
+
const UNDERSCORE_LOWERCASE_REGEXP = /_([a-z])/g;
|
|
118
|
+
const MOUSE_EVENT_MAP = { mouseleave: "mouseout", mouseenter: "mouseover" };
|
|
119
|
+
const jqLiteMinErr = minErr("jqLite");
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @param {string} _all
|
|
123
|
+
* @param {string} letter
|
|
124
|
+
* @returns {string}
|
|
125
|
+
*/
|
|
126
|
+
function fnCamelCaseReplace(_all, letter) {
|
|
127
|
+
return letter.toUpperCase();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Converts kebab-case to camelCase.
|
|
132
|
+
* @param {string} name Name to normalize
|
|
133
|
+
* @returns {string}
|
|
134
|
+
*/
|
|
135
|
+
export function kebabToCamel(name) {
|
|
136
|
+
return name.replace(DASH_LOWERCASE_REGEXP, fnCamelCaseReplace);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Converts sname to camelCase.
|
|
141
|
+
* @param {string} name
|
|
142
|
+
* @returns {string}
|
|
143
|
+
*/
|
|
144
|
+
export function snakeToCamel(name) {
|
|
145
|
+
return name.replace(UNDERSCORE_LOWERCASE_REGEXP, fnCamelCaseReplace);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const SINGLE_TAG_REGEXP = /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/;
|
|
149
|
+
const TAG_NAME_REGEXP = /<([\w:-]+)/;
|
|
150
|
+
|
|
151
|
+
// Table parts need to be wrapped with `<table>` or they're
|
|
152
|
+
// stripped to their contents when put in a div.
|
|
153
|
+
// XHTML parsers do not magically insert elements in the
|
|
154
|
+
// same way that tag soup parsers do, so we cannot shorten
|
|
155
|
+
// this by omitting <tbody> or other required elements.
|
|
156
|
+
const wrapMap = {
|
|
157
|
+
thead: ["table"],
|
|
158
|
+
col: ["colgroup", "table"],
|
|
159
|
+
tr: ["tbody", "table"],
|
|
160
|
+
td: ["tr", "tbody", "table"],
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
wrapMap.tbody =
|
|
164
|
+
wrapMap.tfoot =
|
|
165
|
+
wrapMap.colgroup =
|
|
166
|
+
wrapMap.caption =
|
|
167
|
+
wrapMap.thead;
|
|
168
|
+
wrapMap.th = wrapMap.td;
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Checks if the string contains HTML tags or entities.
|
|
172
|
+
* @param {string} html
|
|
173
|
+
* @returns {boolean}
|
|
174
|
+
*/
|
|
175
|
+
export function isTextNode(html) {
|
|
176
|
+
return !/<|&#?\w+;/.test(html);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
*
|
|
181
|
+
* @param {Element} node
|
|
182
|
+
* @returns {boolean}
|
|
183
|
+
*/
|
|
184
|
+
function elementAcceptsData(node) {
|
|
185
|
+
// The window object can accept data but has no nodeType
|
|
186
|
+
// Otherwise we are only interested in elements (1) and documents (9)
|
|
187
|
+
switch (node.nodeType) {
|
|
188
|
+
case Node.ELEMENT_NODE:
|
|
189
|
+
case Node.DOCUMENT_NODE:
|
|
190
|
+
case undefined:
|
|
191
|
+
return true;
|
|
192
|
+
default:
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function jqLiteHasData(node) {
|
|
198
|
+
for (const key in JQLite.cache.get(node[EXPANDO])) {
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export function jqLiteBuildFragment(html, context) {
|
|
205
|
+
let tmp;
|
|
206
|
+
let tag;
|
|
207
|
+
let wrap;
|
|
208
|
+
let finalHtml;
|
|
209
|
+
const fragment = context.createDocumentFragment();
|
|
210
|
+
let nodes = [];
|
|
211
|
+
let i;
|
|
212
|
+
|
|
213
|
+
if (isTextNode(html)) {
|
|
214
|
+
// Convert non-html into a text node
|
|
215
|
+
nodes.push(context.createTextNode(html));
|
|
216
|
+
} else {
|
|
217
|
+
// Convert html into DOM nodes
|
|
218
|
+
tmp = fragment.appendChild(context.createElement("div"));
|
|
219
|
+
tag = (TAG_NAME_REGEXP.exec(html) || ["", ""])[1].toLowerCase();
|
|
220
|
+
finalHtml = html;
|
|
221
|
+
|
|
222
|
+
wrap = wrapMap[tag] || [];
|
|
223
|
+
|
|
224
|
+
// Create wrappers & descend into them
|
|
225
|
+
i = wrap.length;
|
|
226
|
+
while (--i > -1) {
|
|
227
|
+
tmp.appendChild(window.document.createElement(wrap[i]));
|
|
228
|
+
tmp = tmp.firstChild;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
tmp.innerHTML = finalHtml;
|
|
232
|
+
|
|
233
|
+
nodes = concat(nodes, tmp.childNodes);
|
|
234
|
+
|
|
235
|
+
tmp = fragment.firstChild;
|
|
236
|
+
tmp.textContent = "";
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Remove wrapper from fragment
|
|
240
|
+
fragment.textContent = "";
|
|
241
|
+
fragment.innerHTML = ""; // Clear inner HTML
|
|
242
|
+
forEach(nodes, (node) => {
|
|
243
|
+
fragment.appendChild(node);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
return fragment;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function jqLiteParseHTML(html, context) {
|
|
250
|
+
context = context || window.document;
|
|
251
|
+
let parsed;
|
|
252
|
+
|
|
253
|
+
if ((parsed = SINGLE_TAG_REGEXP.exec(html))) {
|
|
254
|
+
return [context.createElement(parsed[1])];
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if ((parsed = jqLiteBuildFragment(html, context))) {
|
|
258
|
+
return parsed.childNodes;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return [];
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// IE9-11 has no method "contains" in SVG element and in Node.prototype. Bug #10259.
|
|
265
|
+
const jqLiteContains =
|
|
266
|
+
window.Node.prototype.contains ||
|
|
267
|
+
function (arg) {
|
|
268
|
+
return !!(this.compareDocumentPosition(arg) & 16);
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
/// //////////////////////////////////////////
|
|
272
|
+
export function JQLite(element) {
|
|
273
|
+
if (element instanceof JQLite) {
|
|
274
|
+
return element;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
let argIsString;
|
|
278
|
+
|
|
279
|
+
if (isString(element)) {
|
|
280
|
+
element = trim(element);
|
|
281
|
+
argIsString = true;
|
|
282
|
+
}
|
|
283
|
+
if (!(this instanceof JQLite)) {
|
|
284
|
+
if (argIsString && element.charAt(0) !== "<") {
|
|
285
|
+
throw jqLiteMinErr(
|
|
286
|
+
"nosel",
|
|
287
|
+
"Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element",
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
return new JQLite(element);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (argIsString) {
|
|
294
|
+
jqLiteAddNodes(this, jqLiteParseHTML(element));
|
|
295
|
+
} else if (isFunction(element)) {
|
|
296
|
+
jqLiteReady(element);
|
|
297
|
+
} else {
|
|
298
|
+
jqLiteAddNodes(this, element);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
export var jqLite = JQLite;
|
|
302
|
+
|
|
303
|
+
export function dealoc(element, onlyDescendants) {
|
|
304
|
+
if (!element) return;
|
|
305
|
+
if (!onlyDescendants && elementAcceptsData(element))
|
|
306
|
+
jqLiteCleanData([element]);
|
|
307
|
+
|
|
308
|
+
if (element.querySelectorAll) {
|
|
309
|
+
jqLiteCleanData(element.querySelectorAll("*"));
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* If `ExpandoStore.data` and `ExpandoStore.events` are empty,
|
|
315
|
+
* then delete element's `ExpandoStore` and set its `ExpandoId`
|
|
316
|
+
* to undefined.
|
|
317
|
+
* @param {Element} element
|
|
318
|
+
*/
|
|
319
|
+
function removeIfEmptyData(element) {
|
|
320
|
+
const expandoId = element[EXPANDO];
|
|
321
|
+
const { events, data } = JQLite.cache.get(expandoId);
|
|
322
|
+
|
|
323
|
+
if (
|
|
324
|
+
(!data || !Object.keys(data).length) &&
|
|
325
|
+
(!events || !Object.keys(events).length)
|
|
326
|
+
) {
|
|
327
|
+
JQLite.cache.delete(expandoId);
|
|
328
|
+
element[EXPANDO] = undefined; // don't delete DOM expandos. IE and Chrome don't like it
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function jqLiteOff(element, type, fn, unsupported) {
|
|
333
|
+
if (isDefined(unsupported))
|
|
334
|
+
throw jqLiteMinErr(
|
|
335
|
+
"offargs",
|
|
336
|
+
"jqLite#off() does not support the `selector` argument",
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
const expandoStore = jqLiteExpandoStore(element);
|
|
340
|
+
const events = expandoStore && expandoStore.events;
|
|
341
|
+
const handle = expandoStore && expandoStore.handle;
|
|
342
|
+
|
|
343
|
+
if (!handle) return; // no listeners registered
|
|
344
|
+
|
|
345
|
+
if (!type) {
|
|
346
|
+
for (type in events) {
|
|
347
|
+
if (type !== "$destroy") {
|
|
348
|
+
element.removeEventListener(type, handle);
|
|
349
|
+
}
|
|
350
|
+
delete events[type];
|
|
351
|
+
}
|
|
352
|
+
} else {
|
|
353
|
+
const removeHandler = function (type) {
|
|
354
|
+
const listenerFns = events[type];
|
|
355
|
+
if (isDefined(fn)) {
|
|
356
|
+
arrayRemove(listenerFns || [], fn);
|
|
357
|
+
}
|
|
358
|
+
if (!(isDefined(fn) && listenerFns && listenerFns.length > 0)) {
|
|
359
|
+
element.removeEventListener(type, handle);
|
|
360
|
+
delete events[type];
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
forEach(type.split(" "), (type) => {
|
|
365
|
+
removeHandler(type);
|
|
366
|
+
if (MOUSE_EVENT_MAP[type]) {
|
|
367
|
+
removeHandler(MOUSE_EVENT_MAP[type]);
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
removeIfEmptyData(element);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Removes expando data from this element. If key is provided, only
|
|
377
|
+
* its field is removed. If data is empty, also removes `ExpandoStore`
|
|
378
|
+
* from cache.
|
|
379
|
+
* @param {Element} element
|
|
380
|
+
* @param {string} [name] - key of field to remove
|
|
381
|
+
*/
|
|
382
|
+
function jqLiteRemoveData(element, name) {
|
|
383
|
+
const expandoId = element[EXPANDO];
|
|
384
|
+
const expandoStore = expandoId && JQLite.cache.get(expandoId);
|
|
385
|
+
|
|
386
|
+
if (expandoStore) {
|
|
387
|
+
if (name) {
|
|
388
|
+
delete expandoStore.data[name];
|
|
389
|
+
} else {
|
|
390
|
+
expandoStore.data = {};
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
removeIfEmptyData(element);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
*
|
|
399
|
+
* @param {Element} element
|
|
400
|
+
* @param {boolean} createIfNecessary
|
|
401
|
+
* @returns {import("./core/cache").ExpandoStore}
|
|
402
|
+
*/
|
|
403
|
+
function jqLiteExpandoStore(element, createIfNecessary = false) {
|
|
404
|
+
let expandoId = element[EXPANDO];
|
|
405
|
+
let expandoStore = expandoId && JQLite.cache.get(expandoId);
|
|
406
|
+
|
|
407
|
+
if (createIfNecessary && !expandoStore) {
|
|
408
|
+
element[EXPANDO] = expandoId = jqNextId();
|
|
409
|
+
expandoStore = {
|
|
410
|
+
events: {},
|
|
411
|
+
data: {},
|
|
412
|
+
handle: null,
|
|
413
|
+
};
|
|
414
|
+
JQLite.cache.set(expandoId, expandoStore);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
return expandoStore;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
function jqLiteData(element, key, value) {
|
|
421
|
+
if (elementAcceptsData(element)) {
|
|
422
|
+
let prop;
|
|
423
|
+
|
|
424
|
+
const isSimpleSetter = isDefined(value);
|
|
425
|
+
const isSimpleGetter = !isSimpleSetter && key && !isObject(key);
|
|
426
|
+
const massGetter = !key;
|
|
427
|
+
const expandoStore = jqLiteExpandoStore(element, !isSimpleGetter);
|
|
428
|
+
const data = expandoStore && expandoStore.data;
|
|
429
|
+
|
|
430
|
+
if (isSimpleSetter) {
|
|
431
|
+
// data('key', value)
|
|
432
|
+
data[kebabToCamel(key)] = value;
|
|
433
|
+
} else {
|
|
434
|
+
if (massGetter) {
|
|
435
|
+
// data()
|
|
436
|
+
return data;
|
|
437
|
+
}
|
|
438
|
+
if (isSimpleGetter) {
|
|
439
|
+
// data('key')
|
|
440
|
+
// don't force creation of expandoStore if it doesn't exist yet
|
|
441
|
+
return data && data[kebabToCamel(key)];
|
|
442
|
+
}
|
|
443
|
+
// mass-setter: data({key1: val1, key2: val2})
|
|
444
|
+
for (prop in key) {
|
|
445
|
+
data[kebabToCamel(prop)] = key[prop];
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
function jqLiteAddNodes(root, elements) {
|
|
452
|
+
// THIS CODE IS VERY HOT. Don't make changes without benchmarking.
|
|
453
|
+
|
|
454
|
+
if (elements) {
|
|
455
|
+
// if a Node (the most common case)
|
|
456
|
+
if (elements.nodeType) {
|
|
457
|
+
root[root.length++] = elements;
|
|
458
|
+
} else {
|
|
459
|
+
const { length } = elements;
|
|
460
|
+
|
|
461
|
+
// if an Array or NodeList and not a Window
|
|
462
|
+
if (typeof length === "number" && elements.window !== elements) {
|
|
463
|
+
if (length) {
|
|
464
|
+
for (let i = 0; i < length; i++) {
|
|
465
|
+
root[root.length++] = elements[i];
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
} else {
|
|
469
|
+
root[root.length++] = elements;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
function jqLiteController(element, name) {
|
|
476
|
+
return jqLiteInheritedData(element, `$${name || "ngController"}Controller`);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
function jqLiteInheritedData(element, name, value) {
|
|
480
|
+
// if element is the document object work with the html element instead
|
|
481
|
+
// this makes $(document).scope() possible
|
|
482
|
+
if (element.nodeType === Node.DOCUMENT_NODE) {
|
|
483
|
+
element = element.documentElement;
|
|
484
|
+
}
|
|
485
|
+
const names = isArray(name) ? name : [name];
|
|
486
|
+
|
|
487
|
+
while (element) {
|
|
488
|
+
for (let i = 0, ii = names.length; i < ii; i++) {
|
|
489
|
+
if (isDefined((value = jqLiteData(element, names[i])))) return value;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// If dealing with a document fragment node with a host element, and no parent, use the host
|
|
493
|
+
// element as the parent. This enables directives within a Shadow DOM or polyfilled Shadow DOM
|
|
494
|
+
// to lookup parent controllers.
|
|
495
|
+
element =
|
|
496
|
+
element.parentNode ||
|
|
497
|
+
(element.nodeType === Node.DOCUMENT_FRAGMENT_NODE && element.host);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
function jqLiteEmpty(element) {
|
|
502
|
+
dealoc(element, true);
|
|
503
|
+
while (element.firstChild) {
|
|
504
|
+
element.removeChild(element.firstChild);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
export function jqLiteRemove(element, keepData) {
|
|
509
|
+
if (!keepData) dealoc(element);
|
|
510
|
+
const parent = element.parentNode;
|
|
511
|
+
if (parent) parent.removeChild(element);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
function jqLiteReady(fn) {
|
|
515
|
+
function trigger() {
|
|
516
|
+
window.document.removeEventListener("DOMContentLoaded", trigger);
|
|
517
|
+
window.removeEventListener("load", trigger);
|
|
518
|
+
fn();
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// check if document is already loaded
|
|
522
|
+
if (window.document.readyState === "complete") {
|
|
523
|
+
window.setTimeout(fn);
|
|
524
|
+
} else {
|
|
525
|
+
// We can not use jqLite since we are not done loading and jQuery could be loaded later.
|
|
526
|
+
|
|
527
|
+
// Works for modern browsers and IE9
|
|
528
|
+
window.document.addEventListener("DOMContentLoaded", trigger);
|
|
529
|
+
|
|
530
|
+
// Fallback to window.onload for others
|
|
531
|
+
window.addEventListener("load", trigger);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
/// ///////////////////////////////////////
|
|
536
|
+
// Functions which are declared directly.
|
|
537
|
+
/// ///////////////////////////////////////
|
|
538
|
+
JQLite.prototype = {
|
|
539
|
+
ready: jqLiteReady,
|
|
540
|
+
toString() {
|
|
541
|
+
const value = [];
|
|
542
|
+
forEach(this, (e) => {
|
|
543
|
+
value.push(`${e}`);
|
|
544
|
+
});
|
|
545
|
+
return `[${value.join(", ")}]`;
|
|
546
|
+
},
|
|
547
|
+
|
|
548
|
+
eq(index) {
|
|
549
|
+
return index >= 0 ? jqLite(this[index]) : jqLite(this[this.length + index]);
|
|
550
|
+
},
|
|
551
|
+
|
|
552
|
+
length: 0,
|
|
553
|
+
push: [].push,
|
|
554
|
+
sort: [].sort,
|
|
555
|
+
splice: [].splice,
|
|
556
|
+
};
|
|
557
|
+
|
|
558
|
+
/// ///////////////////////////////////////
|
|
559
|
+
// Functions iterating getter/setters.
|
|
560
|
+
// these functions return self on setter and
|
|
561
|
+
// value on get.
|
|
562
|
+
/// ///////////////////////////////////////
|
|
563
|
+
export const BOOLEAN_ATTR = {};
|
|
564
|
+
"multiple,selected,checked,disabled,readOnly,required,open"
|
|
565
|
+
.split(",")
|
|
566
|
+
.forEach((value) => {
|
|
567
|
+
BOOLEAN_ATTR[lowercase(value)] = value;
|
|
568
|
+
});
|
|
569
|
+
const BOOLEAN_ELEMENTS = {};
|
|
570
|
+
"input,select,option,textarea,button,form,details"
|
|
571
|
+
.split(",")
|
|
572
|
+
.forEach((value) => {
|
|
573
|
+
BOOLEAN_ELEMENTS[value] = true;
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
export function getBooleanAttrName(element, name) {
|
|
577
|
+
// check dom last since we will most likely fail on name
|
|
578
|
+
const booleanAttr = BOOLEAN_ATTR[name.toLowerCase()];
|
|
579
|
+
|
|
580
|
+
// booleanAttr is here twice to minimize DOM access
|
|
581
|
+
return booleanAttr && BOOLEAN_ELEMENTS[nodeName_(element)] && booleanAttr;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
export function jqLiteCleanData(nodes) {
|
|
585
|
+
for (let i = 0, ii = nodes.length; i < ii; i++) {
|
|
586
|
+
var events = (jqLite._data(nodes[i]) || {}).events;
|
|
587
|
+
if (events && events.$destroy) {
|
|
588
|
+
jqLite(nodes[i]).triggerHandler("$destroy");
|
|
589
|
+
}
|
|
590
|
+
jqLiteRemoveData(nodes[i]);
|
|
591
|
+
jqLiteOff(nodes[i]);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
forEach(
|
|
596
|
+
{
|
|
597
|
+
data: jqLiteData,
|
|
598
|
+
removeData: jqLiteRemoveData,
|
|
599
|
+
hasData: jqLiteHasData,
|
|
600
|
+
cleanData: jqLiteCleanData,
|
|
601
|
+
},
|
|
602
|
+
(fn, name) => {
|
|
603
|
+
JQLite[name] = fn;
|
|
604
|
+
},
|
|
605
|
+
);
|
|
606
|
+
|
|
607
|
+
forEach(
|
|
608
|
+
{
|
|
609
|
+
data: jqLiteData,
|
|
610
|
+
inheritedData: jqLiteInheritedData,
|
|
611
|
+
|
|
612
|
+
scope(element) {
|
|
613
|
+
// Can't use jqLiteData here directly so we stay compatible with jQuery!
|
|
614
|
+
return (
|
|
615
|
+
jqLiteData(element, "$scope") ||
|
|
616
|
+
jqLiteInheritedData(element.parentNode || element, [
|
|
617
|
+
"$isolateScope",
|
|
618
|
+
"$scope",
|
|
619
|
+
])
|
|
620
|
+
);
|
|
621
|
+
},
|
|
622
|
+
|
|
623
|
+
isolateScope(element) {
|
|
624
|
+
// Can't use jqLiteData here directly so we stay compatible with jQuery!
|
|
625
|
+
return (
|
|
626
|
+
jqLiteData(element, "$isolateScope") ||
|
|
627
|
+
jqLiteData(element, "$isolateScopeNoTemplate")
|
|
628
|
+
);
|
|
629
|
+
},
|
|
630
|
+
|
|
631
|
+
controller: jqLiteController,
|
|
632
|
+
|
|
633
|
+
injector(element) {
|
|
634
|
+
return jqLiteInheritedData(element, "$injector");
|
|
635
|
+
},
|
|
636
|
+
|
|
637
|
+
attr(element, name, value) {
|
|
638
|
+
let ret;
|
|
639
|
+
const { nodeType } = element;
|
|
640
|
+
if (
|
|
641
|
+
nodeType === Node.TEXT_NODE ||
|
|
642
|
+
nodeType === Node.ATTRIBUTE_NODE ||
|
|
643
|
+
nodeType === Node.COMMENT_NODE ||
|
|
644
|
+
!element.getAttribute
|
|
645
|
+
) {
|
|
646
|
+
return;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
const lowercasedName = lowercase(name);
|
|
650
|
+
const isBooleanAttr = BOOLEAN_ATTR[lowercasedName];
|
|
651
|
+
|
|
652
|
+
if (isDefined(value)) {
|
|
653
|
+
// setter
|
|
654
|
+
|
|
655
|
+
if (value === null || (value === false && isBooleanAttr)) {
|
|
656
|
+
element.removeAttribute(name);
|
|
657
|
+
} else {
|
|
658
|
+
element.setAttribute(name, isBooleanAttr ? lowercasedName : value);
|
|
659
|
+
}
|
|
660
|
+
} else {
|
|
661
|
+
// getter
|
|
662
|
+
|
|
663
|
+
ret = element.getAttribute(name);
|
|
664
|
+
|
|
665
|
+
if (isBooleanAttr && ret !== null) {
|
|
666
|
+
ret = lowercasedName;
|
|
667
|
+
}
|
|
668
|
+
// Normalize non-existing attributes to undefined (as jQuery).
|
|
669
|
+
return ret === null ? undefined : ret;
|
|
670
|
+
}
|
|
671
|
+
},
|
|
672
|
+
|
|
673
|
+
prop(element, name, value) {
|
|
674
|
+
if (isDefined(value)) {
|
|
675
|
+
element[name] = value;
|
|
676
|
+
} else {
|
|
677
|
+
return element[name];
|
|
678
|
+
}
|
|
679
|
+
},
|
|
680
|
+
|
|
681
|
+
text: (function () {
|
|
682
|
+
getText.$dv = "";
|
|
683
|
+
return getText;
|
|
684
|
+
|
|
685
|
+
function getText(element, value) {
|
|
686
|
+
if (isUndefined(value)) {
|
|
687
|
+
const { nodeType } = element;
|
|
688
|
+
return nodeType === Node.ELEMENT_NODE || nodeType === Node.TEXT_NODE
|
|
689
|
+
? element.textContent
|
|
690
|
+
: "";
|
|
691
|
+
}
|
|
692
|
+
element.textContent = value;
|
|
693
|
+
}
|
|
694
|
+
})(),
|
|
695
|
+
|
|
696
|
+
val(element, value) {
|
|
697
|
+
if (isUndefined(value)) {
|
|
698
|
+
if (element.multiple && nodeName_(element) === "select") {
|
|
699
|
+
const result = [];
|
|
700
|
+
forEach(element.options, (option) => {
|
|
701
|
+
if (option.selected) {
|
|
702
|
+
result.push(option.value || option.text);
|
|
703
|
+
}
|
|
704
|
+
});
|
|
705
|
+
return result;
|
|
706
|
+
}
|
|
707
|
+
return element.value;
|
|
708
|
+
}
|
|
709
|
+
element.value = value;
|
|
710
|
+
},
|
|
711
|
+
|
|
712
|
+
html(element, value) {
|
|
713
|
+
if (isUndefined(value)) {
|
|
714
|
+
return element.innerHTML;
|
|
715
|
+
}
|
|
716
|
+
dealoc(element, true);
|
|
717
|
+
element.innerHTML = value;
|
|
718
|
+
},
|
|
719
|
+
|
|
720
|
+
empty: jqLiteEmpty,
|
|
721
|
+
},
|
|
722
|
+
(fn, name) => {
|
|
723
|
+
/**
|
|
724
|
+
* Properties: writes return selection, reads return first value
|
|
725
|
+
*/
|
|
726
|
+
JQLite.prototype[name] = function (arg1, arg2) {
|
|
727
|
+
let i;
|
|
728
|
+
let key;
|
|
729
|
+
const nodeCount = this.length;
|
|
730
|
+
|
|
731
|
+
// jqLiteHasClass has only two arguments, but is a getter-only fn, so we need to special-case it
|
|
732
|
+
// in a way that survives minification.
|
|
733
|
+
// jqLiteEmpty takes no arguments but is a setter.
|
|
734
|
+
if (
|
|
735
|
+
fn !== jqLiteEmpty &&
|
|
736
|
+
isUndefined(fn.length === 2 && fn !== jqLiteController ? arg1 : arg2)
|
|
737
|
+
) {
|
|
738
|
+
if (isObject(arg1)) {
|
|
739
|
+
// we are a write, but the object properties are the key/values
|
|
740
|
+
for (i = 0; i < nodeCount; i++) {
|
|
741
|
+
if (fn === jqLiteData) {
|
|
742
|
+
// data() takes the whole object in jQuery
|
|
743
|
+
fn(this[i], arg1);
|
|
744
|
+
} else {
|
|
745
|
+
for (key in arg1) {
|
|
746
|
+
fn(this[i], key, arg1[key]);
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
// return self for chaining
|
|
751
|
+
return this;
|
|
752
|
+
}
|
|
753
|
+
// we are a read, so read the first child.
|
|
754
|
+
// TODO: do we still need this?
|
|
755
|
+
let value = fn.$dv;
|
|
756
|
+
// Only if we have $dv do we iterate over all, otherwise it is just the first element.
|
|
757
|
+
const jj = isUndefined(value) ? Math.min(nodeCount, 1) : nodeCount;
|
|
758
|
+
for (let j = 0; j < jj; j++) {
|
|
759
|
+
const nodeValue = fn(this[j], arg1, arg2);
|
|
760
|
+
value = value ? value + nodeValue : nodeValue;
|
|
761
|
+
}
|
|
762
|
+
return value;
|
|
763
|
+
}
|
|
764
|
+
// we are a write, so apply to all children
|
|
765
|
+
for (i = 0; i < nodeCount; i++) {
|
|
766
|
+
fn(this[i], arg1, arg2);
|
|
767
|
+
}
|
|
768
|
+
// return self for chaining
|
|
769
|
+
return this;
|
|
770
|
+
};
|
|
771
|
+
},
|
|
772
|
+
);
|
|
773
|
+
|
|
774
|
+
function createEventHandler(element, events) {
|
|
775
|
+
const eventHandler = function (event, type) {
|
|
776
|
+
// jQuery specific api
|
|
777
|
+
event.isDefaultPrevented = function () {
|
|
778
|
+
return event.defaultPrevented;
|
|
779
|
+
};
|
|
780
|
+
|
|
781
|
+
let eventFns = events[type || event.type];
|
|
782
|
+
const eventFnsLength = eventFns ? eventFns.length : 0;
|
|
783
|
+
|
|
784
|
+
if (!eventFnsLength) return;
|
|
785
|
+
|
|
786
|
+
if (isUndefined(event.immediatePropagationStopped)) {
|
|
787
|
+
const originalStopImmediatePropagation = event.stopImmediatePropagation;
|
|
788
|
+
event.stopImmediatePropagation = function () {
|
|
789
|
+
event.immediatePropagationStopped = true;
|
|
790
|
+
|
|
791
|
+
if (event.stopPropagation) {
|
|
792
|
+
event.stopPropagation();
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
if (originalStopImmediatePropagation) {
|
|
796
|
+
originalStopImmediatePropagation.call(event);
|
|
797
|
+
}
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
event.isImmediatePropagationStopped = function () {
|
|
802
|
+
return event.immediatePropagationStopped === true;
|
|
803
|
+
};
|
|
804
|
+
|
|
805
|
+
// Some events have special handlers that wrap the real handler
|
|
806
|
+
const handlerWrapper =
|
|
807
|
+
eventFns.specialHandlerWrapper || defaultHandlerWrapper;
|
|
808
|
+
|
|
809
|
+
// Copy event handlers in case event handlers array is modified during execution.
|
|
810
|
+
if (eventFnsLength > 1) {
|
|
811
|
+
eventFns = shallowCopy(eventFns);
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
for (let i = 0; i < eventFnsLength; i++) {
|
|
815
|
+
if (!event.isImmediatePropagationStopped()) {
|
|
816
|
+
handlerWrapper(element, event, eventFns[i]);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
};
|
|
820
|
+
|
|
821
|
+
// TODO: this is a hack for angularMocks/clearDataCache that makes it possible to deregister all
|
|
822
|
+
// events on `element`
|
|
823
|
+
eventHandler.elem = element;
|
|
824
|
+
return eventHandler;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
function defaultHandlerWrapper(element, event, handler) {
|
|
828
|
+
handler.call(element, event);
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
function specialMouseHandlerWrapper(target, event, handler) {
|
|
832
|
+
// Refer to jQuery's implementation of mouseenter & mouseleave
|
|
833
|
+
// Read about mouseenter and mouseleave:
|
|
834
|
+
// http://www.quirksmode.org/js/events_mouse.html#link8
|
|
835
|
+
const related = event.relatedTarget;
|
|
836
|
+
// For mousenter/leave call the handler if related is outside the target.
|
|
837
|
+
// NB: No relatedTarget if the mouse left/entered the browser window
|
|
838
|
+
if (
|
|
839
|
+
!related ||
|
|
840
|
+
(related !== target && !jqLiteContains.call(target, related))
|
|
841
|
+
) {
|
|
842
|
+
handler.call(target, event);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
/// ///////////////////////////////////////
|
|
847
|
+
// Functions iterating traversal.
|
|
848
|
+
// These functions chain results into a single
|
|
849
|
+
// selector.
|
|
850
|
+
/// ///////////////////////////////////////
|
|
851
|
+
forEach(
|
|
852
|
+
{
|
|
853
|
+
removeData: jqLiteRemoveData,
|
|
854
|
+
on: function jqLiteOn(element, type, fn, unsupported) {
|
|
855
|
+
if (isDefined(unsupported))
|
|
856
|
+
throw jqLiteMinErr(
|
|
857
|
+
"onargs",
|
|
858
|
+
"jqLite#on() does not support the `selector` or `eventData` parameters",
|
|
859
|
+
);
|
|
860
|
+
|
|
861
|
+
// Do not add event handlers to non-elements because they will not be cleaned up.
|
|
862
|
+
if (!elementAcceptsData(element)) {
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
const expandoStore = jqLiteExpandoStore(element, true);
|
|
867
|
+
const { events } = expandoStore;
|
|
868
|
+
let { handle } = expandoStore;
|
|
869
|
+
|
|
870
|
+
if (!handle) {
|
|
871
|
+
handle = expandoStore.handle = createEventHandler(element, events);
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
// http://jsperf.com/string-indexof-vs-split
|
|
875
|
+
const types = type.indexOf(" ") >= 0 ? type.split(" ") : [type];
|
|
876
|
+
let i = types.length;
|
|
877
|
+
|
|
878
|
+
const addHandler = function (
|
|
879
|
+
type,
|
|
880
|
+
specialHandlerWrapper,
|
|
881
|
+
noEventListener,
|
|
882
|
+
) {
|
|
883
|
+
let eventFns = events[type];
|
|
884
|
+
|
|
885
|
+
if (!eventFns) {
|
|
886
|
+
eventFns = events[type] = [];
|
|
887
|
+
eventFns.specialHandlerWrapper = specialHandlerWrapper;
|
|
888
|
+
if (type !== "$destroy" && !noEventListener) {
|
|
889
|
+
element.addEventListener(type, handle);
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
eventFns.push(fn);
|
|
894
|
+
};
|
|
895
|
+
|
|
896
|
+
while (i--) {
|
|
897
|
+
type = types[i];
|
|
898
|
+
if (MOUSE_EVENT_MAP[type]) {
|
|
899
|
+
addHandler(MOUSE_EVENT_MAP[type], specialMouseHandlerWrapper);
|
|
900
|
+
addHandler(type, undefined, true);
|
|
901
|
+
} else {
|
|
902
|
+
addHandler(type);
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
},
|
|
906
|
+
|
|
907
|
+
off: jqLiteOff,
|
|
908
|
+
|
|
909
|
+
one(element, type, fn) {
|
|
910
|
+
element = jqLite(element);
|
|
911
|
+
|
|
912
|
+
// add the listener twice so that when it is called
|
|
913
|
+
// you can remove the original function and still be
|
|
914
|
+
// able to call element.off(ev, fn) normally
|
|
915
|
+
element.on(type, function onFn() {
|
|
916
|
+
element.off(type, fn);
|
|
917
|
+
element.off(type, onFn);
|
|
918
|
+
});
|
|
919
|
+
element.on(type, fn);
|
|
920
|
+
},
|
|
921
|
+
|
|
922
|
+
replaceWith(element, replaceNode) {
|
|
923
|
+
let index;
|
|
924
|
+
const parent = element.parentNode;
|
|
925
|
+
dealoc(element);
|
|
926
|
+
forEach(new JQLite(replaceNode), (node) => {
|
|
927
|
+
if (index) {
|
|
928
|
+
parent.insertBefore(node, index.nextSibling);
|
|
929
|
+
} else {
|
|
930
|
+
parent.replaceChild(node, element);
|
|
931
|
+
}
|
|
932
|
+
index = node;
|
|
933
|
+
});
|
|
934
|
+
},
|
|
935
|
+
|
|
936
|
+
children(element) {
|
|
937
|
+
return Array.from(element.childNodes).filter(
|
|
938
|
+
(child) => child.nodeType === Node.ELEMENT_NODE,
|
|
939
|
+
);
|
|
940
|
+
},
|
|
941
|
+
|
|
942
|
+
append(element, node) {
|
|
943
|
+
const { nodeType } = element;
|
|
944
|
+
if (
|
|
945
|
+
nodeType !== Node.ELEMENT_NODE &&
|
|
946
|
+
nodeType !== Node.DOCUMENT_FRAGMENT_NODE
|
|
947
|
+
)
|
|
948
|
+
return;
|
|
949
|
+
|
|
950
|
+
node = new JQLite(node);
|
|
951
|
+
|
|
952
|
+
for (let i = 0, ii = node.length; i < ii; i++) {
|
|
953
|
+
const child = node[i];
|
|
954
|
+
element.appendChild(child);
|
|
955
|
+
}
|
|
956
|
+
},
|
|
957
|
+
|
|
958
|
+
prepend(element, node) {
|
|
959
|
+
if (element.nodeType === Node.ELEMENT_NODE) {
|
|
960
|
+
const index = element.firstChild;
|
|
961
|
+
forEach(new JQLite(node), (child) => {
|
|
962
|
+
element.insertBefore(child, index);
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
},
|
|
966
|
+
|
|
967
|
+
remove: jqLiteRemove,
|
|
968
|
+
|
|
969
|
+
detach(element) {
|
|
970
|
+
jqLiteRemove(element, true);
|
|
971
|
+
},
|
|
972
|
+
|
|
973
|
+
after(element, newElement) {
|
|
974
|
+
let index = element;
|
|
975
|
+
const parent = element.parentNode;
|
|
976
|
+
|
|
977
|
+
if (parent) {
|
|
978
|
+
newElement = new JQLite(newElement);
|
|
979
|
+
|
|
980
|
+
for (let i = 0, ii = newElement.length; i < ii; i++) {
|
|
981
|
+
const node = newElement[i];
|
|
982
|
+
parent.insertBefore(node, index.nextSibling);
|
|
983
|
+
index = node;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
},
|
|
987
|
+
|
|
988
|
+
parent(element) {
|
|
989
|
+
const parent = element.parentNode;
|
|
990
|
+
return parent && parent.nodeType !== Node.DOCUMENT_FRAGMENT_NODE
|
|
991
|
+
? parent
|
|
992
|
+
: null;
|
|
993
|
+
},
|
|
994
|
+
|
|
995
|
+
// TODO: remove after migrating tests away from jqLite
|
|
996
|
+
find(element, selector) {
|
|
997
|
+
if (element.getElementsByTagName) {
|
|
998
|
+
return element.getElementsByTagName(selector);
|
|
999
|
+
}
|
|
1000
|
+
return [];
|
|
1001
|
+
},
|
|
1002
|
+
|
|
1003
|
+
triggerHandler(element, event, extraParameters) {
|
|
1004
|
+
let dummyEvent;
|
|
1005
|
+
let eventFnsCopy;
|
|
1006
|
+
let handlerArgs;
|
|
1007
|
+
const eventName = event.type || event;
|
|
1008
|
+
const expandoStore = jqLiteExpandoStore(element);
|
|
1009
|
+
const events = expandoStore && expandoStore.events;
|
|
1010
|
+
const eventFns = events && events[eventName];
|
|
1011
|
+
|
|
1012
|
+
if (eventFns) {
|
|
1013
|
+
// Create a dummy event to pass to the handlers
|
|
1014
|
+
dummyEvent = {
|
|
1015
|
+
preventDefault() {
|
|
1016
|
+
this.defaultPrevented = true;
|
|
1017
|
+
},
|
|
1018
|
+
isDefaultPrevented() {
|
|
1019
|
+
return this.defaultPrevented === true;
|
|
1020
|
+
},
|
|
1021
|
+
stopImmediatePropagation() {
|
|
1022
|
+
this.immediatePropagationStopped = true;
|
|
1023
|
+
},
|
|
1024
|
+
isImmediatePropagationStopped() {
|
|
1025
|
+
return this.immediatePropagationStopped === true;
|
|
1026
|
+
},
|
|
1027
|
+
stopPropagation: () => {},
|
|
1028
|
+
type: eventName,
|
|
1029
|
+
target: element,
|
|
1030
|
+
};
|
|
1031
|
+
|
|
1032
|
+
// If a custom event was provided then extend our dummy event with it
|
|
1033
|
+
if (event.type) {
|
|
1034
|
+
dummyEvent = extend(dummyEvent, event);
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
// Copy event handlers in case event handlers array is modified during execution.
|
|
1038
|
+
eventFnsCopy = shallowCopy(eventFns);
|
|
1039
|
+
handlerArgs = extraParameters
|
|
1040
|
+
? [dummyEvent].concat(extraParameters)
|
|
1041
|
+
: [dummyEvent];
|
|
1042
|
+
|
|
1043
|
+
forEach(eventFnsCopy, (fn) => {
|
|
1044
|
+
if (!dummyEvent.isImmediatePropagationStopped()) {
|
|
1045
|
+
fn.apply(element, handlerArgs);
|
|
1046
|
+
}
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
},
|
|
1050
|
+
},
|
|
1051
|
+
(fn, name) => {
|
|
1052
|
+
/**
|
|
1053
|
+
* chaining functions
|
|
1054
|
+
*/
|
|
1055
|
+
JQLite.prototype[name] = function (arg1, arg2, arg3) {
|
|
1056
|
+
let value;
|
|
1057
|
+
|
|
1058
|
+
for (let i = 0, ii = this.length; i < ii; i++) {
|
|
1059
|
+
if (isUndefined(value)) {
|
|
1060
|
+
value = fn(this[i], arg1, arg2, arg3);
|
|
1061
|
+
if (isDefined(value)) {
|
|
1062
|
+
// any function which returns a value needs to be wrapped
|
|
1063
|
+
value = jqLite(value);
|
|
1064
|
+
}
|
|
1065
|
+
} else {
|
|
1066
|
+
jqLiteAddNodes(value, fn(this[i], arg1, arg2, arg3));
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
return isDefined(value) ? value : this;
|
|
1070
|
+
};
|
|
1071
|
+
},
|
|
1072
|
+
);
|
|
1073
|
+
|
|
1074
|
+
/**
|
|
1075
|
+
* @param {string} elementStr
|
|
1076
|
+
* @returns {string} Returns the string representation of the element.
|
|
1077
|
+
*/
|
|
1078
|
+
export function startingTag(elementStr) {
|
|
1079
|
+
const clone = jqLite(elementStr)[0].cloneNode(true);
|
|
1080
|
+
const element = jqLite(clone).empty();
|
|
1081
|
+
var elemHtml = jqLite("<div></div>").append(element).html();
|
|
1082
|
+
try {
|
|
1083
|
+
return element[0].nodeType === Node.TEXT_NODE
|
|
1084
|
+
? lowercase(elemHtml)
|
|
1085
|
+
: elemHtml
|
|
1086
|
+
.match(/^(<[^>]+>)/)[1]
|
|
1087
|
+
.replace(/^<([\w-]+)/, function (match, nodeName) {
|
|
1088
|
+
return "<" + lowercase(nodeName);
|
|
1089
|
+
});
|
|
1090
|
+
} catch (e) {
|
|
1091
|
+
return lowercase(elemHtml);
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
/**
|
|
1096
|
+
* Return the DOM siblings between the first and last node in the given array.
|
|
1097
|
+
* @param {Array} nodes An array-like object
|
|
1098
|
+
* @returns {Array} the inputted object or a jqLite collection containing the nodes
|
|
1099
|
+
*/
|
|
1100
|
+
export function getBlockNodes(nodes) {
|
|
1101
|
+
// TODO(perf): update `nodes` instead of creating a new object?
|
|
1102
|
+
let node = nodes[0];
|
|
1103
|
+
const endNode = nodes[nodes.length - 1];
|
|
1104
|
+
let blockNodes;
|
|
1105
|
+
|
|
1106
|
+
for (let i = 1; node !== endNode && (node = node.nextSibling); i++) {
|
|
1107
|
+
if (blockNodes || nodes[i] !== node) {
|
|
1108
|
+
if (!blockNodes) {
|
|
1109
|
+
// use element to avoid circular dependency
|
|
1110
|
+
blockNodes = jqLite(Array.prototype.slice.call(nodes, 0, i));
|
|
1111
|
+
}
|
|
1112
|
+
blockNodes.push(node);
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
return blockNodes || nodes;
|
|
1117
|
+
}
|