@spcsn/taro-runtime 0.1.0
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/LICENSE +174 -0
- package/README.md +49 -0
- package/dist/bom/URL.d.ts +51 -0
- package/dist/bom/URL.js +188 -0
- package/dist/bom/URL.js.map +1 -0
- package/dist/bom/URLSearchParams.d.ts +1 -0
- package/dist/bom/URLSearchParams.js +103 -0
- package/dist/bom/URLSearchParams.js.map +1 -0
- package/dist/bom/document.d.ts +3 -0
- package/dist/bom/document.js +93 -0
- package/dist/bom/document.js.map +1 -0
- package/dist/bom/getComputedStyle.d.ts +4 -0
- package/dist/bom/getComputedStyle.js +9 -0
- package/dist/bom/getComputedStyle.js.map +1 -0
- package/dist/bom/history.d.ts +30 -0
- package/dist/bom/history.js +108 -0
- package/dist/bom/history.js.map +1 -0
- package/dist/bom/location.d.ts +37 -0
- package/dist/bom/location.js +200 -0
- package/dist/bom/location.js.map +1 -0
- package/dist/bom/navigator.d.ts +1 -0
- package/dist/bom/navigator.js +22 -0
- package/dist/bom/navigator.js.map +1 -0
- package/dist/bom/raf.d.ts +4 -0
- package/dist/bom/raf.js +28 -0
- package/dist/bom/raf.js.map +1 -0
- package/dist/bom/window.d.ts +23 -0
- package/dist/bom/window.js +74 -0
- package/dist/bom/window.js.map +1 -0
- package/dist/constants/index.d.ts +57 -0
- package/dist/constants/index.js +63 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/current.d.ts +19 -0
- package/dist/current.js +11 -0
- package/dist/current.js.map +1 -0
- package/dist/dom/anchor-element.d.ts +13 -0
- package/dist/dom/anchor-element.js +42 -0
- package/dist/dom/anchor-element.js.map +1 -0
- package/dist/dom/class-list.d.ts +16 -0
- package/dist/dom/class-list.js +79 -0
- package/dist/dom/class-list.js.map +1 -0
- package/dist/dom/document.d.ts +21 -0
- package/dist/dom/document.js +74 -0
- package/dist/dom/document.js.map +1 -0
- package/dist/dom/element.d.ts +39 -0
- package/dist/dom/element.js +261 -0
- package/dist/dom/element.js.map +1 -0
- package/dist/dom/event-source.d.ts +7 -0
- package/dist/dom/event-source.js +18 -0
- package/dist/dom/event-source.js.map +1 -0
- package/dist/dom/event-target.d.ts +8 -0
- package/dist/dom/event-target.js +72 -0
- package/dist/dom/event-target.js.map +1 -0
- package/dist/dom/event.d.ts +24 -0
- package/dist/dom/event.js +124 -0
- package/dist/dom/event.js.map +1 -0
- package/dist/dom/form.d.ts +9 -0
- package/dist/dom/form.js +30 -0
- package/dist/dom/form.js.map +1 -0
- package/dist/dom/node.d.ts +76 -0
- package/dist/dom/node.js +213 -0
- package/dist/dom/node.js.map +1 -0
- package/dist/dom/node_types.d.ts +10 -0
- package/dist/dom/root.d.ts +16 -0
- package/dist/dom/root.js +127 -0
- package/dist/dom/root.js.map +1 -0
- package/dist/dom/style.d.ts +14 -0
- package/dist/dom/style.js +138 -0
- package/dist/dom/style.js.map +1 -0
- package/dist/dom/style_properties.d.ts +3 -0
- package/dist/dom/style_properties.js +374 -0
- package/dist/dom/style_properties.js.map +1 -0
- package/dist/dom/svg.d.ts +3 -0
- package/dist/dom/svg.js +7 -0
- package/dist/dom/svg.js.map +1 -0
- package/dist/dom/text.d.ts +14 -0
- package/dist/dom/text.js +43 -0
- package/dist/dom/text.js.map +1 -0
- package/dist/dom/transfer.d.ts +7 -0
- package/dist/dom/transfer.js +16 -0
- package/dist/dom/transfer.js.map +1 -0
- package/dist/dom/tree.d.ts +4 -0
- package/dist/dom/tree.js +31 -0
- package/dist/dom/tree.js.map +1 -0
- package/dist/dom-external/element.d.ts +3 -0
- package/dist/dom-external/index.d.ts +1 -0
- package/dist/dom-external/mutation-observer/implements.d.ts +52 -0
- package/dist/dom-external/mutation-observer/implements.js +101 -0
- package/dist/dom-external/mutation-observer/implements.js.map +1 -0
- package/dist/dom-external/mutation-observer/index.d.ts +13 -0
- package/dist/dom-external/mutation-observer/index.js +32 -0
- package/dist/dom-external/mutation-observer/index.js.map +1 -0
- package/dist/dom-external/mutation-observer/record.d.ts +24 -0
- package/dist/dom-external/node.d.ts +5 -0
- package/dist/dsl/common.d.ts +14 -0
- package/dist/dsl/common.js +278 -0
- package/dist/dsl/common.js.map +1 -0
- package/dist/dsl/instance.d.ts +92 -0
- package/dist/emitter/emitter.d.ts +4 -0
- package/dist/emitter/emitter.js +7 -0
- package/dist/emitter/emitter.js.map +1 -0
- package/dist/env.d.ts +7 -0
- package/dist/env.js +10 -0
- package/dist/env.js.map +1 -0
- package/dist/hydrate.d.ts +10 -0
- package/dist/hydrate.js +62 -0
- package/dist/hydrate.js.map +1 -0
- package/dist/index.cjs.d.ts +35 -0
- package/dist/index.cjs.js +3776 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +34 -0
- package/dist/interface/animate.d.ts +81 -0
- package/dist/interface/element.d.ts +4 -0
- package/dist/interface/event-target.d.ts +11 -0
- package/dist/interface/event.d.ts +15 -0
- package/dist/interface/hydrate.d.ts +30 -0
- package/dist/interface/index.d.ts +8 -0
- package/dist/interface/node.d.ts +7 -0
- package/dist/interface/options.d.ts +5 -0
- package/dist/interface/utils.d.ts +2 -0
- package/dist/next-tick.d.ts +2 -0
- package/dist/next-tick.js +35 -0
- package/dist/next-tick.js.map +1 -0
- package/dist/options.d.ts +2 -0
- package/dist/options.js +9 -0
- package/dist/options.js.map +1 -0
- package/dist/perf.d.ts +9 -0
- package/dist/perf.js +36 -0
- package/dist/perf.js.map +1 -0
- package/dist/polyfill/array.d.ts +2 -0
- package/dist/polyfill/array.js +36 -0
- package/dist/polyfill/array.js.map +1 -0
- package/dist/polyfill/index.d.ts +2 -0
- package/dist/polyfill/index.js +20 -0
- package/dist/polyfill/index.js.map +1 -0
- package/dist/polyfill/intersection-observer.d.ts +1 -0
- package/dist/polyfill/intersection-observer.js +494 -0
- package/dist/polyfill/intersection-observer.js.map +1 -0
- package/dist/polyfill/object.d.ts +3 -0
- package/dist/polyfill/object.js +63 -0
- package/dist/polyfill/object.js.map +1 -0
- package/dist/runtime.esm.d.ts +35 -0
- package/dist/runtime.esm.js +3644 -0
- package/dist/runtime.esm.js.map +1 -0
- package/dist/utils/cache.d.ts +12 -0
- package/dist/utils/cache.js +26 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/index.d.ts +25 -0
- package/dist/utils/index.js +82 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/lodash.d.ts +2 -0
- package/dist/utils/lodash.js +33 -0
- package/dist/utils/lodash.js.map +1 -0
- package/dist/utils/router.d.ts +7 -0
- package/dist/utils/router.js +19 -0
- package/dist/utils/router.js.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1,3644 @@
|
|
|
1
|
+
import { DEFAULT_COMPONENTS, EMPTY_OBJ, EventChannel, Events, Shortcuts, TT_SPECIFIC_COMPONENTS, controlledComponent, ensure, getComponentsAlias as getComponentsAlias$1, hooks, hooks as hooks$1, internalComponents, isArray, isEnableTTDom, isFunction, isNull, isNumber, isObject, isString, isUndefined, noop, toCamelCase, toDashed, warn } from "@spcsn/taro-shared";
|
|
2
|
+
//#region src/constants/index.ts
|
|
3
|
+
const PROPERTY_THRESHOLD = 2046;
|
|
4
|
+
const TARO_RUNTIME = "Taro runtime";
|
|
5
|
+
const HOOKS_APP_ID = "taro-app";
|
|
6
|
+
const SET_DATA = "小程序 setData";
|
|
7
|
+
const PAGE_INIT = "页面初始化";
|
|
8
|
+
const ROOT_STR = "root";
|
|
9
|
+
const HTML = "html";
|
|
10
|
+
const HEAD = "head";
|
|
11
|
+
const BODY = "body";
|
|
12
|
+
const APP = "app";
|
|
13
|
+
const CONTAINER = "container";
|
|
14
|
+
const DOCUMENT_ELEMENT_NAME = "#document";
|
|
15
|
+
const DOCUMENT_FRAGMENT = "document-fragment";
|
|
16
|
+
const ID = "id";
|
|
17
|
+
const UID = "uid";
|
|
18
|
+
const CLASS = "class";
|
|
19
|
+
const STYLE = "style";
|
|
20
|
+
const FOCUS = "focus";
|
|
21
|
+
const VIEW = "view";
|
|
22
|
+
const STATIC_VIEW = "static-view";
|
|
23
|
+
const PURE_VIEW = "pure-view";
|
|
24
|
+
const CLICK_VIEW = "click-view";
|
|
25
|
+
const PROPS = "props";
|
|
26
|
+
const DATASET = "dataset";
|
|
27
|
+
const OBJECT = "object";
|
|
28
|
+
const VALUE = "value";
|
|
29
|
+
const INPUT = "input";
|
|
30
|
+
const CHANGE = "change";
|
|
31
|
+
const CUSTOM_WRAPPER = "custom-wrapper";
|
|
32
|
+
const TARGET = "target";
|
|
33
|
+
const CURRENT_TARGET = "currentTarget";
|
|
34
|
+
const TYPE = "type";
|
|
35
|
+
const CONFIRM = "confirm";
|
|
36
|
+
const TIME_STAMP = "timeStamp";
|
|
37
|
+
const KEY_CODE = "keyCode";
|
|
38
|
+
const TOUCHMOVE = "touchmove";
|
|
39
|
+
const DATE = "Date";
|
|
40
|
+
const SET_TIMEOUT = "setTimeout";
|
|
41
|
+
const COMPILE_MODE = "compileMode";
|
|
42
|
+
const CATCHMOVE = "catchMove";
|
|
43
|
+
const CATCH_VIEW = "catch-view";
|
|
44
|
+
const COMMENT = "comment";
|
|
45
|
+
const ON_LOAD = "onLoad";
|
|
46
|
+
const ON_READY = "onReady";
|
|
47
|
+
const ON_SHOW = "onShow";
|
|
48
|
+
const ON_HIDE = "onHide";
|
|
49
|
+
const OPTIONS = "options";
|
|
50
|
+
const EXTERNAL_CLASSES = "externalClasses";
|
|
51
|
+
const EVENT_CALLBACK_RESULT = "e_result";
|
|
52
|
+
const BEHAVIORS = "behaviors";
|
|
53
|
+
const A = "a";
|
|
54
|
+
let CONTEXT_ACTIONS = /* @__PURE__ */ function(CONTEXT_ACTIONS) {
|
|
55
|
+
CONTEXT_ACTIONS["INIT"] = "0";
|
|
56
|
+
CONTEXT_ACTIONS["RESTORE"] = "1";
|
|
57
|
+
CONTEXT_ACTIONS["RECOVER"] = "2";
|
|
58
|
+
CONTEXT_ACTIONS["DESTROY"] = "3";
|
|
59
|
+
return CONTEXT_ACTIONS;
|
|
60
|
+
}({});
|
|
61
|
+
//#endregion
|
|
62
|
+
//#region src/dom-external/mutation-observer/implements.ts
|
|
63
|
+
const observers = [];
|
|
64
|
+
/**
|
|
65
|
+
* The MutationObserver provides the ability
|
|
66
|
+
* to watch for changes being made to the DOM tree.
|
|
67
|
+
* It will invoke a specified callback function
|
|
68
|
+
* when DOM changes occur.
|
|
69
|
+
* @see https://dom.spec.whatwg.org/#mutationobserver
|
|
70
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
|
|
71
|
+
*/
|
|
72
|
+
var MutationObserverImpl = class {
|
|
73
|
+
constructor(callback) {
|
|
74
|
+
this.records = [];
|
|
75
|
+
this.callback = callback;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Configures the MutationObserver
|
|
79
|
+
* to begin receiving notifications
|
|
80
|
+
* through its callback function
|
|
81
|
+
* when DOM changes matching the given options occur.
|
|
82
|
+
*
|
|
83
|
+
* Options matching is to be implemented.
|
|
84
|
+
*/
|
|
85
|
+
observe(target, options) {
|
|
86
|
+
this.disconnect();
|
|
87
|
+
this.target = target;
|
|
88
|
+
this.options = options || {};
|
|
89
|
+
observers.push(this);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Stop the MutationObserver instance
|
|
93
|
+
* from receiving further notifications
|
|
94
|
+
* until and unless observe() is called again.
|
|
95
|
+
*/
|
|
96
|
+
disconnect() {
|
|
97
|
+
this.target = null;
|
|
98
|
+
const index = observers.indexOf(this);
|
|
99
|
+
if (index >= 0) observers.splice(index, 1);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Removes all pending notifications
|
|
103
|
+
* from the MutationObserver's notification queue
|
|
104
|
+
* and returns them in a new Array of MutationRecord objects.
|
|
105
|
+
*/
|
|
106
|
+
takeRecords() {
|
|
107
|
+
return this.records.splice(0, this.records.length);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
/** Match two TaroNodes by sid. */
|
|
111
|
+
const sidMatches = (observerTarget, target) => {
|
|
112
|
+
return !!observerTarget && observerTarget.sid === target?.sid;
|
|
113
|
+
};
|
|
114
|
+
const isConcerned = (record, options) => {
|
|
115
|
+
const { characterData, characterDataOldValue, attributes, attributeOldValue, childList } = options;
|
|
116
|
+
switch (record.type) {
|
|
117
|
+
case "characterData":
|
|
118
|
+
if (characterData) {
|
|
119
|
+
if (!characterDataOldValue) record.oldValue = null;
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
return false;
|
|
123
|
+
case "attributes":
|
|
124
|
+
if (attributes) {
|
|
125
|
+
if (!attributeOldValue) record.oldValue = null;
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
return false;
|
|
129
|
+
case "childList":
|
|
130
|
+
if (childList) return true;
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
let pendingMuatations = false;
|
|
135
|
+
function logMutation(observer, record) {
|
|
136
|
+
observer.records.push(record);
|
|
137
|
+
if (!pendingMuatations) {
|
|
138
|
+
pendingMuatations = true;
|
|
139
|
+
Promise.resolve().then(() => {
|
|
140
|
+
pendingMuatations = false;
|
|
141
|
+
observers.forEach((observer) => {
|
|
142
|
+
return observer.callback(observer.takeRecords());
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function recordMutation(record) {
|
|
148
|
+
observers.forEach((observer) => {
|
|
149
|
+
const { options } = observer;
|
|
150
|
+
for (let t = record.target; t; t = t.parentNode) {
|
|
151
|
+
if (sidMatches(observer.target, t) && isConcerned(record, options)) {
|
|
152
|
+
logMutation(observer, record);
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
if (!options.subtree) break;
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
//#endregion
|
|
160
|
+
//#region src/dom-external/mutation-observer/index.ts
|
|
161
|
+
var MutationObserver$1 = class {
|
|
162
|
+
constructor(callback) {
|
|
163
|
+
if (ENABLE_MUTATION_OBSERVER) this.core = new MutationObserverImpl(callback);
|
|
164
|
+
else {
|
|
165
|
+
console.warn("[Taro Warning] 若要使用 MutationObserver,请在 Taro 编译配置中设置 'mini.runtime.enableMutationObserver: true'");
|
|
166
|
+
this.core = {
|
|
167
|
+
observe: noop,
|
|
168
|
+
disconnect: noop,
|
|
169
|
+
takeRecords: noop
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
observe(...args) {
|
|
174
|
+
this.core.observe(...args);
|
|
175
|
+
}
|
|
176
|
+
disconnect() {
|
|
177
|
+
this.core.disconnect();
|
|
178
|
+
}
|
|
179
|
+
takeRecords() {
|
|
180
|
+
return this.core.takeRecords();
|
|
181
|
+
}
|
|
182
|
+
static record(record) {
|
|
183
|
+
recordMutation(record);
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
//#endregion
|
|
187
|
+
//#region src/utils/lodash.ts
|
|
188
|
+
function throttle(fn, threshold = 250, scope) {
|
|
189
|
+
let lastTime = 0;
|
|
190
|
+
let deferTimer;
|
|
191
|
+
return function(...args) {
|
|
192
|
+
const context = scope || this;
|
|
193
|
+
const now = Date.now();
|
|
194
|
+
if (now - lastTime > threshold) {
|
|
195
|
+
fn.apply(this, args);
|
|
196
|
+
lastTime = now;
|
|
197
|
+
} else {
|
|
198
|
+
clearTimeout(deferTimer);
|
|
199
|
+
deferTimer = setTimeout(() => {
|
|
200
|
+
lastTime = now;
|
|
201
|
+
fn.apply(context, args);
|
|
202
|
+
}, threshold);
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
function debounce(fn, ms = 250, scope) {
|
|
207
|
+
let timer;
|
|
208
|
+
return function(...args) {
|
|
209
|
+
const context = scope || this;
|
|
210
|
+
clearTimeout(timer);
|
|
211
|
+
timer = setTimeout(function() {
|
|
212
|
+
fn.apply(context, args);
|
|
213
|
+
}, ms);
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
//#endregion
|
|
217
|
+
//#region src/emitter/emitter.ts
|
|
218
|
+
const eventCenter = hooks$1.call("getEventCenter", Events);
|
|
219
|
+
//#endregion
|
|
220
|
+
//#region src/env.ts
|
|
221
|
+
const env = {
|
|
222
|
+
window: process.env.TARO_PLATFORM === "web" ? window : EMPTY_OBJ,
|
|
223
|
+
document: process.env.TARO_PLATFORM === "web" ? document : EMPTY_OBJ
|
|
224
|
+
};
|
|
225
|
+
//#endregion
|
|
226
|
+
//#region src/bom/getComputedStyle.ts
|
|
227
|
+
const taroGetComputedStyleProvider = process.env.TARO_PLATFORM === "web" ? env.window.getComputedStyle : function(element) {
|
|
228
|
+
return element.style;
|
|
229
|
+
};
|
|
230
|
+
//#endregion
|
|
231
|
+
//#region src/utils/cache.ts
|
|
232
|
+
/**
|
|
233
|
+
* 一个小型缓存池,用于在切换页面时,存储一些上下文信息
|
|
234
|
+
*/
|
|
235
|
+
var RuntimeCache = class {
|
|
236
|
+
constructor(name) {
|
|
237
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
238
|
+
this.name = name;
|
|
239
|
+
}
|
|
240
|
+
has(identifier) {
|
|
241
|
+
return this.cache.has(identifier);
|
|
242
|
+
}
|
|
243
|
+
set(identifier, ctx) {
|
|
244
|
+
if (identifier && ctx) this.cache.set(identifier, ctx);
|
|
245
|
+
}
|
|
246
|
+
get(identifier) {
|
|
247
|
+
if (this.has(identifier)) return this.cache.get(identifier);
|
|
248
|
+
}
|
|
249
|
+
delete(identifier) {
|
|
250
|
+
this.cache.delete(identifier);
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
//#endregion
|
|
254
|
+
//#region src/bom/history.ts
|
|
255
|
+
const cache$1 = new RuntimeCache("history");
|
|
256
|
+
var TaroHistory = class extends Events {
|
|
257
|
+
#location;
|
|
258
|
+
#stack = [];
|
|
259
|
+
#cur = 0;
|
|
260
|
+
#window;
|
|
261
|
+
constructor(location, options) {
|
|
262
|
+
super();
|
|
263
|
+
this.#window = options.window;
|
|
264
|
+
this.#location = location;
|
|
265
|
+
this.#location.on("__record_history__", (href) => {
|
|
266
|
+
this.#cur++;
|
|
267
|
+
this.#stack = this.#stack.slice(0, this.#cur);
|
|
268
|
+
this.#stack.push({
|
|
269
|
+
state: null,
|
|
270
|
+
title: "",
|
|
271
|
+
url: href
|
|
272
|
+
});
|
|
273
|
+
}, null);
|
|
274
|
+
this.#location.on("__reset_history__", (href) => {
|
|
275
|
+
this.#reset(href);
|
|
276
|
+
}, null);
|
|
277
|
+
this.on("0", () => {
|
|
278
|
+
this.#reset();
|
|
279
|
+
}, null);
|
|
280
|
+
this.on("1", (pageId) => {
|
|
281
|
+
cache$1.set(pageId, {
|
|
282
|
+
location: this.#location,
|
|
283
|
+
stack: this.#stack.slice(),
|
|
284
|
+
cur: this.#cur
|
|
285
|
+
});
|
|
286
|
+
}, null);
|
|
287
|
+
this.on("2", (pageId) => {
|
|
288
|
+
if (cache$1.has(pageId)) {
|
|
289
|
+
const ctx = cache$1.get(pageId);
|
|
290
|
+
this.#location = ctx.location;
|
|
291
|
+
this.#stack = ctx.stack;
|
|
292
|
+
this.#cur = ctx.cur;
|
|
293
|
+
}
|
|
294
|
+
}, null);
|
|
295
|
+
this.on("3", (pageId) => {
|
|
296
|
+
cache$1.delete(pageId);
|
|
297
|
+
}, null);
|
|
298
|
+
this.#reset();
|
|
299
|
+
}
|
|
300
|
+
#reset(href = "") {
|
|
301
|
+
this.#stack = [{
|
|
302
|
+
state: null,
|
|
303
|
+
title: "",
|
|
304
|
+
url: href || this.#location.href
|
|
305
|
+
}];
|
|
306
|
+
this.#cur = 0;
|
|
307
|
+
}
|
|
308
|
+
get length() {
|
|
309
|
+
return this.#stack.length;
|
|
310
|
+
}
|
|
311
|
+
get state() {
|
|
312
|
+
return this.#stack[this.#cur].state;
|
|
313
|
+
}
|
|
314
|
+
go(delta) {
|
|
315
|
+
if (!isNumber(delta) || isNaN(delta)) return;
|
|
316
|
+
let targetIdx = this.#cur + delta;
|
|
317
|
+
targetIdx = Math.min(Math.max(targetIdx, 0), this.length - 1);
|
|
318
|
+
this.#cur = targetIdx;
|
|
319
|
+
this.#location.trigger("__set_href_without_history__", this.#stack[this.#cur].url);
|
|
320
|
+
this.#window.trigger("popstate", this.#stack[this.#cur]);
|
|
321
|
+
}
|
|
322
|
+
back() {
|
|
323
|
+
this.go(-1);
|
|
324
|
+
}
|
|
325
|
+
forward() {
|
|
326
|
+
this.go(1);
|
|
327
|
+
}
|
|
328
|
+
pushState(state, title, url) {
|
|
329
|
+
if (!url || !isString(url)) return;
|
|
330
|
+
this.#stack = this.#stack.slice(0, this.#cur + 1);
|
|
331
|
+
this.#stack.push({
|
|
332
|
+
state,
|
|
333
|
+
title,
|
|
334
|
+
url
|
|
335
|
+
});
|
|
336
|
+
this.#cur = this.length - 1;
|
|
337
|
+
this.#location.trigger("__set_href_without_history__", url);
|
|
338
|
+
}
|
|
339
|
+
replaceState(state, title, url) {
|
|
340
|
+
if (!url || !isString(url)) return;
|
|
341
|
+
this.#stack[this.#cur] = {
|
|
342
|
+
state,
|
|
343
|
+
title,
|
|
344
|
+
url
|
|
345
|
+
};
|
|
346
|
+
this.#location.trigger("__set_href_without_history__", url);
|
|
347
|
+
}
|
|
348
|
+
get cache() {
|
|
349
|
+
return cache$1;
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
const History = process.env.TARO_PLATFORM === "web" ? env.window.History : TaroHistory;
|
|
353
|
+
//#endregion
|
|
354
|
+
//#region src/current.ts
|
|
355
|
+
const Current = {
|
|
356
|
+
app: null,
|
|
357
|
+
router: null,
|
|
358
|
+
page: null
|
|
359
|
+
};
|
|
360
|
+
const getCurrentInstance = () => Current;
|
|
361
|
+
//#endregion
|
|
362
|
+
//#region src/bom/URLSearchParams.ts
|
|
363
|
+
const findReg = /[!'()~]|%20|%00/g;
|
|
364
|
+
const plusReg = /\+/g;
|
|
365
|
+
const replaceCharMap = {
|
|
366
|
+
"!": "%21",
|
|
367
|
+
"'": "%27",
|
|
368
|
+
"(": "%28",
|
|
369
|
+
")": "%29",
|
|
370
|
+
"~": "%7E",
|
|
371
|
+
"%20": "+",
|
|
372
|
+
"%00": "\0"
|
|
373
|
+
};
|
|
374
|
+
function replacer(match) {
|
|
375
|
+
return replaceCharMap[match];
|
|
376
|
+
}
|
|
377
|
+
function appendTo(dict, name, value) {
|
|
378
|
+
const res = isArray(value) ? value.join(",") : value;
|
|
379
|
+
if (name in dict) dict[name].push(res);
|
|
380
|
+
else dict[name] = [res];
|
|
381
|
+
}
|
|
382
|
+
function addEach(value, key) {
|
|
383
|
+
appendTo(this, key, value);
|
|
384
|
+
}
|
|
385
|
+
function decode(str) {
|
|
386
|
+
return decodeURIComponent(str.replace(plusReg, " "));
|
|
387
|
+
}
|
|
388
|
+
function encode(str) {
|
|
389
|
+
return encodeURIComponent(str).replace(findReg, replacer);
|
|
390
|
+
}
|
|
391
|
+
const URLSearchParams = process.env.TARO_PLATFORM === "web" ? env.window.URLSearchParams : class {
|
|
392
|
+
#dict = Object.create(null);
|
|
393
|
+
constructor(query) {
|
|
394
|
+
query ??= "";
|
|
395
|
+
const dict = this.#dict;
|
|
396
|
+
if (typeof query === "string") {
|
|
397
|
+
if (query.charAt(0) === "?") query = query.slice(1);
|
|
398
|
+
for (let pairs = query.split("&"), i = 0, length = pairs.length; i < length; i++) {
|
|
399
|
+
const value = pairs[i];
|
|
400
|
+
const index = value.indexOf("=");
|
|
401
|
+
try {
|
|
402
|
+
if (index > -1) appendTo(dict, decode(value.slice(0, index)), decode(value.slice(index + 1)));
|
|
403
|
+
else if (value.length) appendTo(dict, decode(value), "");
|
|
404
|
+
} catch (err) {
|
|
405
|
+
console.warn(`[Taro warn] URL 参数 ${value} decode 异常`);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
} else if (isArray(query)) for (let i = 0, length = query.length; i < length; i++) {
|
|
409
|
+
const value = query[i];
|
|
410
|
+
appendTo(dict, value[0], value[1]);
|
|
411
|
+
}
|
|
412
|
+
else if (query.forEach) query.forEach(addEach, dict);
|
|
413
|
+
else for (const key in query) appendTo(dict, key, query[key]);
|
|
414
|
+
}
|
|
415
|
+
append(name, value) {
|
|
416
|
+
appendTo(this.#dict, name, value);
|
|
417
|
+
}
|
|
418
|
+
delete(name) {
|
|
419
|
+
delete this.#dict[name];
|
|
420
|
+
}
|
|
421
|
+
get(name) {
|
|
422
|
+
const dict = this.#dict;
|
|
423
|
+
return name in dict ? dict[name][0] : null;
|
|
424
|
+
}
|
|
425
|
+
getAll(name) {
|
|
426
|
+
const dict = this.#dict;
|
|
427
|
+
return name in dict ? dict[name].slice(0) : [];
|
|
428
|
+
}
|
|
429
|
+
has(name) {
|
|
430
|
+
return name in this.#dict;
|
|
431
|
+
}
|
|
432
|
+
keys() {
|
|
433
|
+
return Object.keys(this.#dict);
|
|
434
|
+
}
|
|
435
|
+
set(name, value) {
|
|
436
|
+
this.#dict[name] = ["" + value];
|
|
437
|
+
}
|
|
438
|
+
forEach(callback, thisArg) {
|
|
439
|
+
const dict = this.#dict;
|
|
440
|
+
Object.getOwnPropertyNames(dict).forEach(function(name) {
|
|
441
|
+
dict[name].forEach(function(value) {
|
|
442
|
+
callback.call(thisArg, value, name, this);
|
|
443
|
+
}, this);
|
|
444
|
+
}, this);
|
|
445
|
+
}
|
|
446
|
+
toJSON() {
|
|
447
|
+
return {};
|
|
448
|
+
}
|
|
449
|
+
toString() {
|
|
450
|
+
const dict = this.#dict;
|
|
451
|
+
const query = [];
|
|
452
|
+
for (const key in dict) {
|
|
453
|
+
const name = encode(key);
|
|
454
|
+
for (let i = 0, value = dict[key]; i < value.length; i++) query.push(name + "=" + encode(value[i]));
|
|
455
|
+
}
|
|
456
|
+
return query.join("&");
|
|
457
|
+
}
|
|
458
|
+
};
|
|
459
|
+
//#endregion
|
|
460
|
+
//#region src/bom/URL.ts
|
|
461
|
+
var TaroURL = class {
|
|
462
|
+
static createObjectURL() {
|
|
463
|
+
throw new Error("Oops, not support URL.createObjectURL() in miniprogram.");
|
|
464
|
+
}
|
|
465
|
+
static revokeObjectURL() {
|
|
466
|
+
throw new Error("Oops, not support URL.revokeObjectURL() in miniprogram.");
|
|
467
|
+
}
|
|
468
|
+
#hash = "";
|
|
469
|
+
#hostname = "";
|
|
470
|
+
#pathname = "";
|
|
471
|
+
#port = "";
|
|
472
|
+
#protocol = "";
|
|
473
|
+
#search;
|
|
474
|
+
constructor(url, base) {
|
|
475
|
+
if (!isString(url)) url = String(url);
|
|
476
|
+
const { hash, hostname, pathname, port, protocol, search } = parseUrlBase(url, base);
|
|
477
|
+
this.#hash = hash;
|
|
478
|
+
this.#hostname = hostname;
|
|
479
|
+
this.#pathname = pathname || "/";
|
|
480
|
+
this.#port = port;
|
|
481
|
+
this.#protocol = protocol;
|
|
482
|
+
this.#search = new URLSearchParams(search);
|
|
483
|
+
}
|
|
484
|
+
get protocol() {
|
|
485
|
+
return this.#protocol;
|
|
486
|
+
}
|
|
487
|
+
set protocol(val) {
|
|
488
|
+
isString(val) && (this.#protocol = val.trim());
|
|
489
|
+
}
|
|
490
|
+
get host() {
|
|
491
|
+
return this.hostname + (this.port ? ":" + this.port : "");
|
|
492
|
+
}
|
|
493
|
+
set host(val) {
|
|
494
|
+
if (val && isString(val)) {
|
|
495
|
+
val = val.trim();
|
|
496
|
+
const { hostname, port } = parseUrl(`//${val}`);
|
|
497
|
+
this.hostname = hostname;
|
|
498
|
+
this.port = port;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
get hostname() {
|
|
502
|
+
return this.#hostname;
|
|
503
|
+
}
|
|
504
|
+
set hostname(val) {
|
|
505
|
+
val && isString(val) && (this.#hostname = val.trim());
|
|
506
|
+
}
|
|
507
|
+
get port() {
|
|
508
|
+
return this.#port;
|
|
509
|
+
}
|
|
510
|
+
set port(val) {
|
|
511
|
+
isString(val) && (this.#port = val.trim());
|
|
512
|
+
}
|
|
513
|
+
get pathname() {
|
|
514
|
+
return this.#pathname;
|
|
515
|
+
}
|
|
516
|
+
set pathname(val) {
|
|
517
|
+
if (isString(val)) {
|
|
518
|
+
val = val.trim();
|
|
519
|
+
const HEAD_REG = /^(\/|\.\/|\.\.\/)/;
|
|
520
|
+
let temp = val;
|
|
521
|
+
while (HEAD_REG.test(temp)) temp = temp.replace(HEAD_REG, "");
|
|
522
|
+
if (temp) this.#pathname = "/" + temp;
|
|
523
|
+
else this.#pathname = "/";
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
get search() {
|
|
527
|
+
const val = this.#search.toString();
|
|
528
|
+
return val.length === 0 || val.startsWith("?") ? val : `?${val}`;
|
|
529
|
+
}
|
|
530
|
+
set search(val) {
|
|
531
|
+
if (isString(val)) {
|
|
532
|
+
val = val.trim();
|
|
533
|
+
this.#search = new URLSearchParams(val);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
get hash() {
|
|
537
|
+
return this.#hash;
|
|
538
|
+
}
|
|
539
|
+
set hash(val) {
|
|
540
|
+
if (isString(val)) {
|
|
541
|
+
val = val.trim();
|
|
542
|
+
if (val) this.#hash = val.startsWith("#") ? val : `#${val}`;
|
|
543
|
+
else this.#hash = "";
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
get href() {
|
|
547
|
+
return `${this.protocol}//${this.host}${this.pathname}${this.search}${this.hash}`;
|
|
548
|
+
}
|
|
549
|
+
set href(val) {
|
|
550
|
+
if (val && isString(val)) {
|
|
551
|
+
val = val.trim();
|
|
552
|
+
const { protocol, hostname, port, hash, search, pathname } = parseUrl(val);
|
|
553
|
+
this.protocol = protocol;
|
|
554
|
+
this.hostname = hostname;
|
|
555
|
+
this.pathname = pathname;
|
|
556
|
+
this.port = port;
|
|
557
|
+
this.hash = hash;
|
|
558
|
+
this.search = search;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
get origin() {
|
|
562
|
+
return `${this.protocol}//${this.host}`;
|
|
563
|
+
}
|
|
564
|
+
set origin(val) {
|
|
565
|
+
if (val && isString(val)) {
|
|
566
|
+
val = val.trim();
|
|
567
|
+
const { protocol, hostname, port } = parseUrl(val);
|
|
568
|
+
this.protocol = protocol;
|
|
569
|
+
this.hostname = hostname;
|
|
570
|
+
this.port = port;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
get searchParams() {
|
|
574
|
+
return this.#search;
|
|
575
|
+
}
|
|
576
|
+
toString() {
|
|
577
|
+
return this.href;
|
|
578
|
+
}
|
|
579
|
+
toJSON() {
|
|
580
|
+
return this.toString();
|
|
581
|
+
}
|
|
582
|
+
_toRaw() {
|
|
583
|
+
return {
|
|
584
|
+
protocol: this.protocol,
|
|
585
|
+
port: this.port,
|
|
586
|
+
host: this.host,
|
|
587
|
+
hostname: this.hostname,
|
|
588
|
+
pathname: this.pathname,
|
|
589
|
+
hash: this.hash,
|
|
590
|
+
search: this.search,
|
|
591
|
+
origin: this.origin,
|
|
592
|
+
href: this.href
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
const TaroURLProvider = process.env.TARO_PLATFORM === "web" ? env.window.URL : TaroURL;
|
|
597
|
+
function parseUrl(url = "") {
|
|
598
|
+
const result = {
|
|
599
|
+
href: "",
|
|
600
|
+
origin: "",
|
|
601
|
+
protocol: "",
|
|
602
|
+
hostname: "",
|
|
603
|
+
host: "",
|
|
604
|
+
port: "",
|
|
605
|
+
pathname: "",
|
|
606
|
+
search: "",
|
|
607
|
+
hash: ""
|
|
608
|
+
};
|
|
609
|
+
if (!url || !isString(url)) return result;
|
|
610
|
+
url = url.trim();
|
|
611
|
+
const matches = url.match(/^(([^:/?#]+):)?\/\/(([^/?#]+):(.+)@)?([^/?#:]*)(:(\d+))?([^?#]*)(\?([^#]*))?(#(.*))?/);
|
|
612
|
+
if (!matches) return result;
|
|
613
|
+
result.protocol = matches[1] || "https:";
|
|
614
|
+
result.hostname = matches[6] || "taro.com";
|
|
615
|
+
result.port = matches[8] || "";
|
|
616
|
+
result.pathname = matches[9] || "/";
|
|
617
|
+
result.search = matches[10] || "";
|
|
618
|
+
result.hash = matches[12] || "";
|
|
619
|
+
result.href = url;
|
|
620
|
+
result.origin = result.protocol + "//" + result.hostname + (result.port ? `:${result.port}` : "");
|
|
621
|
+
result.host = result.hostname + (result.port ? `:${result.port}` : "");
|
|
622
|
+
return result;
|
|
623
|
+
}
|
|
624
|
+
function parseUrlBase(url, base) {
|
|
625
|
+
const VALID_URL = /^(https?:)\/\//i;
|
|
626
|
+
let fullUrl = "";
|
|
627
|
+
let parsedBase = null;
|
|
628
|
+
if (!isUndefined(base)) {
|
|
629
|
+
base = String(base).trim();
|
|
630
|
+
if (!VALID_URL.test(base)) throw new TypeError(`Failed to construct 'URL': Invalid base URL`);
|
|
631
|
+
parsedBase = parseUrl(base);
|
|
632
|
+
}
|
|
633
|
+
url = String(url).trim();
|
|
634
|
+
if (VALID_URL.test(url)) fullUrl = url;
|
|
635
|
+
else if (parsedBase) if (url) if (url.startsWith("//")) fullUrl = parsedBase.protocol + url;
|
|
636
|
+
else fullUrl = parsedBase.origin + (url.startsWith("/") ? url : `/${url}`);
|
|
637
|
+
else fullUrl = parsedBase.href;
|
|
638
|
+
else throw new TypeError(`Failed to construct 'URL': Invalid URL`);
|
|
639
|
+
return parseUrl(fullUrl);
|
|
640
|
+
}
|
|
641
|
+
//#endregion
|
|
642
|
+
//#region src/bom/location.ts
|
|
643
|
+
const INIT_URL = "https://taro.com";
|
|
644
|
+
const cache = new RuntimeCache("location");
|
|
645
|
+
var TaroLocation = class extends Events {
|
|
646
|
+
#url = new TaroURLProvider(INIT_URL);
|
|
647
|
+
#noCheckUrl = false;
|
|
648
|
+
#window;
|
|
649
|
+
constructor(options) {
|
|
650
|
+
super();
|
|
651
|
+
this.#window = options.window;
|
|
652
|
+
this.#reset();
|
|
653
|
+
this.on("__set_href_without_history__", (href) => {
|
|
654
|
+
this.#noCheckUrl = true;
|
|
655
|
+
const lastHash = this.#url.hash;
|
|
656
|
+
this.#url.href = generateFullUrl(href);
|
|
657
|
+
if (lastHash !== this.#url.hash) this.#window.trigger("hashchange");
|
|
658
|
+
this.#noCheckUrl = false;
|
|
659
|
+
}, null);
|
|
660
|
+
this.on("0", () => {
|
|
661
|
+
this.#reset();
|
|
662
|
+
}, null);
|
|
663
|
+
this.on("1", (pageId) => {
|
|
664
|
+
cache.set(pageId, { lastHref: this.href });
|
|
665
|
+
}, null);
|
|
666
|
+
this.on("2", (pageId) => {
|
|
667
|
+
if (cache.has(pageId)) {
|
|
668
|
+
const ctx = cache.get(pageId);
|
|
669
|
+
this.#noCheckUrl = true;
|
|
670
|
+
this.#url.href = ctx.lastHref;
|
|
671
|
+
this.#noCheckUrl = false;
|
|
672
|
+
}
|
|
673
|
+
}, null);
|
|
674
|
+
this.on("3", (pageId) => {
|
|
675
|
+
cache.delete(pageId);
|
|
676
|
+
}, null);
|
|
677
|
+
}
|
|
678
|
+
#reset() {
|
|
679
|
+
const router = getCurrentInstance().router;
|
|
680
|
+
if (router) {
|
|
681
|
+
const { path, params } = router;
|
|
682
|
+
const searchArr = Object.keys(params).map((key) => {
|
|
683
|
+
return `${key}=${params[key]}`;
|
|
684
|
+
});
|
|
685
|
+
const searchStr = searchArr.length > 0 ? "?" + searchArr.join("&") : "";
|
|
686
|
+
const url = `${INIT_URL}${path.startsWith("/") ? path : "/" + path}${searchStr}`;
|
|
687
|
+
this.#url = new TaroURLProvider(url);
|
|
688
|
+
this.trigger("__reset_history__", this.href);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
#getPreValue() {
|
|
692
|
+
return this.#url._toRaw();
|
|
693
|
+
}
|
|
694
|
+
#rollBack(href) {
|
|
695
|
+
this.#url.href = href;
|
|
696
|
+
}
|
|
697
|
+
#recordHistory() {
|
|
698
|
+
this.trigger("__record_history__", this.href);
|
|
699
|
+
}
|
|
700
|
+
/**
|
|
701
|
+
* 校验url的变化,是否需要更新history
|
|
702
|
+
*/
|
|
703
|
+
#checkUrlChange(preValue) {
|
|
704
|
+
if (this.#noCheckUrl) return false;
|
|
705
|
+
const { protocol, hostname, port, pathname, search, hash } = this.#url._toRaw();
|
|
706
|
+
if (protocol !== preValue.protocol || hostname !== preValue.hostname || port !== preValue.port) {
|
|
707
|
+
this.#rollBack(preValue.href);
|
|
708
|
+
return false;
|
|
709
|
+
}
|
|
710
|
+
if (pathname !== preValue.pathname) return true;
|
|
711
|
+
if (search !== preValue.search) return true;
|
|
712
|
+
if (hash !== preValue.hash) {
|
|
713
|
+
this.#window.trigger("hashchange");
|
|
714
|
+
return true;
|
|
715
|
+
}
|
|
716
|
+
this.#rollBack(preValue.href);
|
|
717
|
+
return false;
|
|
718
|
+
}
|
|
719
|
+
get protocol() {
|
|
720
|
+
return this.#url.protocol;
|
|
721
|
+
}
|
|
722
|
+
set protocol(val) {
|
|
723
|
+
if (!val || !isString(val) || !/^(http|https):$/i.test(val.trim())) return;
|
|
724
|
+
val = val.trim();
|
|
725
|
+
const preValue = this.#getPreValue();
|
|
726
|
+
this.#url.protocol = val;
|
|
727
|
+
if (this.#checkUrlChange(preValue)) this.#recordHistory();
|
|
728
|
+
}
|
|
729
|
+
get host() {
|
|
730
|
+
return this.#url.host;
|
|
731
|
+
}
|
|
732
|
+
set host(val) {
|
|
733
|
+
if (!val || !isString(val)) return;
|
|
734
|
+
val = val.trim();
|
|
735
|
+
const preValue = this.#getPreValue();
|
|
736
|
+
this.#url.host = val;
|
|
737
|
+
if (this.#checkUrlChange(preValue)) this.#recordHistory();
|
|
738
|
+
}
|
|
739
|
+
get hostname() {
|
|
740
|
+
return this.#url.hostname;
|
|
741
|
+
}
|
|
742
|
+
set hostname(val) {
|
|
743
|
+
if (!val || !isString(val)) return;
|
|
744
|
+
val = val.trim();
|
|
745
|
+
const preValue = this.#getPreValue();
|
|
746
|
+
this.#url.hostname = val;
|
|
747
|
+
if (this.#checkUrlChange(preValue)) this.#recordHistory();
|
|
748
|
+
}
|
|
749
|
+
get port() {
|
|
750
|
+
return this.#url.port;
|
|
751
|
+
}
|
|
752
|
+
set port(val) {
|
|
753
|
+
const xVal = Number(val = val.trim());
|
|
754
|
+
if (!isNumber(xVal) || xVal <= 0) return;
|
|
755
|
+
const preValue = this.#getPreValue();
|
|
756
|
+
this.#url.port = val;
|
|
757
|
+
if (this.#checkUrlChange(preValue)) this.#recordHistory();
|
|
758
|
+
}
|
|
759
|
+
get pathname() {
|
|
760
|
+
return this.#url.pathname;
|
|
761
|
+
}
|
|
762
|
+
set pathname(val) {
|
|
763
|
+
if (!val || !isString(val)) return;
|
|
764
|
+
val = val.trim();
|
|
765
|
+
const preValue = this.#getPreValue();
|
|
766
|
+
this.#url.pathname = val;
|
|
767
|
+
if (this.#checkUrlChange(preValue)) this.#recordHistory();
|
|
768
|
+
}
|
|
769
|
+
get search() {
|
|
770
|
+
return this.#url.search;
|
|
771
|
+
}
|
|
772
|
+
set search(val) {
|
|
773
|
+
if (!val || !isString(val)) return;
|
|
774
|
+
val = val.trim();
|
|
775
|
+
val = val.startsWith("?") ? val : `?${val}`;
|
|
776
|
+
const preValue = this.#getPreValue();
|
|
777
|
+
this.#url.search = val;
|
|
778
|
+
if (this.#checkUrlChange(preValue)) this.#recordHistory();
|
|
779
|
+
}
|
|
780
|
+
get hash() {
|
|
781
|
+
return this.#url.hash;
|
|
782
|
+
}
|
|
783
|
+
set hash(val) {
|
|
784
|
+
if (!val || !isString(val)) return;
|
|
785
|
+
val = val.trim();
|
|
786
|
+
val = val.startsWith("#") ? val : `#${val}`;
|
|
787
|
+
const preValue = this.#getPreValue();
|
|
788
|
+
this.#url.hash = val;
|
|
789
|
+
if (this.#checkUrlChange(preValue)) this.#recordHistory();
|
|
790
|
+
}
|
|
791
|
+
get href() {
|
|
792
|
+
return this.#url.href;
|
|
793
|
+
}
|
|
794
|
+
set href(val) {
|
|
795
|
+
if (!val || !isString(val) || !/^(http:|https:)?\/\/.+/.test(val = val.trim())) return;
|
|
796
|
+
const preValue = this.#getPreValue();
|
|
797
|
+
this.#url.href = val;
|
|
798
|
+
if (this.#checkUrlChange(preValue)) this.#recordHistory();
|
|
799
|
+
}
|
|
800
|
+
get origin() {
|
|
801
|
+
return this.#url.origin;
|
|
802
|
+
}
|
|
803
|
+
set origin(val) {
|
|
804
|
+
if (!val || !isString(val) || !/^(http:|https:)?\/\/.+/.test(val = val.trim())) return;
|
|
805
|
+
const preValue = this.#getPreValue();
|
|
806
|
+
this.#url.origin = val;
|
|
807
|
+
if (this.#checkUrlChange(preValue)) this.#recordHistory();
|
|
808
|
+
}
|
|
809
|
+
assign() {
|
|
810
|
+
warn(true, "小程序环境中调用location.assign()无效.");
|
|
811
|
+
}
|
|
812
|
+
reload() {
|
|
813
|
+
warn(true, "小程序环境中调用location.reload()无效.");
|
|
814
|
+
}
|
|
815
|
+
replace(url) {
|
|
816
|
+
this.trigger("__set_href_without_history__", url);
|
|
817
|
+
}
|
|
818
|
+
toString() {
|
|
819
|
+
return this.href;
|
|
820
|
+
}
|
|
821
|
+
get cache() {
|
|
822
|
+
return cache;
|
|
823
|
+
}
|
|
824
|
+
};
|
|
825
|
+
const Location = process.env.TARO_PLATFORM === "web" ? env.window.Location : TaroLocation;
|
|
826
|
+
function generateFullUrl(val = "") {
|
|
827
|
+
const origin = INIT_URL;
|
|
828
|
+
if (/^[/?#]/.test(val)) return origin + val;
|
|
829
|
+
return val;
|
|
830
|
+
}
|
|
831
|
+
//#endregion
|
|
832
|
+
//#region src/bom/navigator.ts
|
|
833
|
+
const msg = "(Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/534.36 (KHTML, like Gecko) NodeJS/v4.1.0 Chrome/76.0.3809.132 Safari/534.36";
|
|
834
|
+
const nav = process.env.TARO_PLATFORM === "web" ? env.window.navigator : {
|
|
835
|
+
appCodeName: "Mozilla",
|
|
836
|
+
appName: "Netscape",
|
|
837
|
+
appVersion: "5.0 " + msg,
|
|
838
|
+
cookieEnabled: true,
|
|
839
|
+
mimeTypes: [],
|
|
840
|
+
onLine: true,
|
|
841
|
+
platform: "MacIntel",
|
|
842
|
+
plugins: [],
|
|
843
|
+
product: "Taro",
|
|
844
|
+
productSub: "20030107",
|
|
845
|
+
userAgent: "Mozilla/5.0 " + msg,
|
|
846
|
+
vendor: "Joyent",
|
|
847
|
+
vendorSub: ""
|
|
848
|
+
};
|
|
849
|
+
//#endregion
|
|
850
|
+
//#region src/bom/raf.ts
|
|
851
|
+
let now;
|
|
852
|
+
(function() {
|
|
853
|
+
let loadTime;
|
|
854
|
+
if (typeof performance !== "undefined" && performance !== null && performance.now) now = () => performance.now();
|
|
855
|
+
else if (Date.now) {
|
|
856
|
+
loadTime = Date.now();
|
|
857
|
+
now = () => Date.now() - loadTime;
|
|
858
|
+
} else {
|
|
859
|
+
loadTime = (/* @__PURE__ */ new Date()).getTime();
|
|
860
|
+
now = () => (/* @__PURE__ */ new Date()).getTime() - loadTime;
|
|
861
|
+
}
|
|
862
|
+
})();
|
|
863
|
+
let lastTime = 0;
|
|
864
|
+
const _raf = process.env.TARO_PLATFORM === "web" ? requestAnimationFrame : function(callback) {
|
|
865
|
+
const _now = now();
|
|
866
|
+
const nextTime = Math.max(lastTime + 16, _now);
|
|
867
|
+
return setTimeout(function() {
|
|
868
|
+
callback(lastTime = nextTime);
|
|
869
|
+
}, nextTime - _now);
|
|
870
|
+
};
|
|
871
|
+
const _caf = process.env.TARO_PLATFORM === "web" ? cancelAnimationFrame : function(seed) {
|
|
872
|
+
clearTimeout(seed);
|
|
873
|
+
};
|
|
874
|
+
//#endregion
|
|
875
|
+
//#region src/bom/window.ts
|
|
876
|
+
var TaroWindow = class extends Events {
|
|
877
|
+
constructor() {
|
|
878
|
+
super();
|
|
879
|
+
this.navigator = nav;
|
|
880
|
+
this.requestAnimationFrame = _raf;
|
|
881
|
+
this.cancelAnimationFrame = _caf;
|
|
882
|
+
this.getComputedStyle = taroGetComputedStyleProvider;
|
|
883
|
+
[...Object.getOwnPropertyNames(global || {}), ...Object.getOwnPropertySymbols(global || {})].forEach((property) => {
|
|
884
|
+
if (property === "atob" || property === "document") return;
|
|
885
|
+
if (!Object.prototype.hasOwnProperty.call(this, property)) try {
|
|
886
|
+
this[property] = global[property];
|
|
887
|
+
} catch (e) {
|
|
888
|
+
console.warn(`[Taro warn] window.${String(property)} 在赋值到 window 时报错`);
|
|
889
|
+
}
|
|
890
|
+
});
|
|
891
|
+
this.Date ||= Date;
|
|
892
|
+
this.location = new Location({ window: this });
|
|
893
|
+
this.history = new History(this.location, { window: this });
|
|
894
|
+
this.initEvent();
|
|
895
|
+
}
|
|
896
|
+
initEvent() {
|
|
897
|
+
const _location = this.location;
|
|
898
|
+
const _history = this.history;
|
|
899
|
+
this.on("0", (pageId) => {
|
|
900
|
+
_location.trigger("0", pageId);
|
|
901
|
+
}, null);
|
|
902
|
+
this.on("2", (pageId) => {
|
|
903
|
+
_location.trigger("2", pageId);
|
|
904
|
+
_history.trigger("2", pageId);
|
|
905
|
+
}, null);
|
|
906
|
+
this.on("1", (pageId) => {
|
|
907
|
+
_location.trigger("1", pageId);
|
|
908
|
+
_history.trigger("1", pageId);
|
|
909
|
+
}, null);
|
|
910
|
+
this.on("3", (pageId) => {
|
|
911
|
+
_location.trigger("3", pageId);
|
|
912
|
+
_history.trigger("3", pageId);
|
|
913
|
+
}, null);
|
|
914
|
+
}
|
|
915
|
+
get document() {
|
|
916
|
+
return env.document;
|
|
917
|
+
}
|
|
918
|
+
addEventListener(event, callback) {
|
|
919
|
+
if (!isString(event)) return;
|
|
920
|
+
this.on(event, callback, null);
|
|
921
|
+
}
|
|
922
|
+
removeEventListener(event, callback) {
|
|
923
|
+
if (!isString(event)) return;
|
|
924
|
+
this.off(event, callback, null);
|
|
925
|
+
}
|
|
926
|
+
setTimeout(...args) {
|
|
927
|
+
return setTimeout(...args);
|
|
928
|
+
}
|
|
929
|
+
clearTimeout(...args) {
|
|
930
|
+
return clearTimeout(...args);
|
|
931
|
+
}
|
|
932
|
+
};
|
|
933
|
+
const taroWindowProvider = process.env.TARO_PLATFORM === "web" ? env.window : env.window = new TaroWindow();
|
|
934
|
+
const taroLocationProvider = taroWindowProvider.location;
|
|
935
|
+
const taroHistoryProvider = taroWindowProvider.history;
|
|
936
|
+
//#endregion
|
|
937
|
+
//#region src/utils/router.ts
|
|
938
|
+
const addLeadingSlash = (url = "") => url.charAt(0) === "/" ? url : "/" + url;
|
|
939
|
+
const hasBasename = (path = "", prefix = "") => new RegExp("^" + prefix + "(\\/|\\?|#|$)", "i").test(path) || path === prefix;
|
|
940
|
+
const stripBasename = (path = "", prefix = "") => hasBasename(path, prefix) ? path.substring(prefix.length) : path;
|
|
941
|
+
const stripTrailing = (str = "") => str.replace(/[?#][\s\S]*$/, "");
|
|
942
|
+
const stripSuffix = (path = "", suffix = "") => path.includes(suffix) ? path.substring(0, path.length - suffix.length) : path;
|
|
943
|
+
const getHomePage = (path = "", basename = "", customRoutes = {}, entryPagePath = "") => {
|
|
944
|
+
const routePath = addLeadingSlash(stripBasename(path, basename));
|
|
945
|
+
const alias = Object.entries(customRoutes).find(([key]) => key === routePath)?.[1] || routePath;
|
|
946
|
+
return entryPagePath || (typeof alias === "string" ? alias : alias[0]) || basename;
|
|
947
|
+
};
|
|
948
|
+
const getCurrentPage = (routerMode = "hash", basename = "/") => {
|
|
949
|
+
return addLeadingSlash(stripBasename(routerMode === "hash" ? taroLocationProvider.hash.slice(1).split("?")[0] : taroLocationProvider.pathname, basename));
|
|
950
|
+
};
|
|
951
|
+
//#endregion
|
|
952
|
+
//#region src/utils/index.ts
|
|
953
|
+
const incrementId = () => {
|
|
954
|
+
const chatCodes = [];
|
|
955
|
+
for (let i = 65; i <= 90; i++) chatCodes.push(i);
|
|
956
|
+
for (let i = 97; i <= 122; i++) chatCodes.push(i);
|
|
957
|
+
const chatCodesLen = chatCodes.length - 1;
|
|
958
|
+
const list = [0, 0];
|
|
959
|
+
return () => {
|
|
960
|
+
const target = list.map((item) => chatCodes[item]);
|
|
961
|
+
const res = String.fromCharCode(...target);
|
|
962
|
+
let tailIdx = list.length - 1;
|
|
963
|
+
list[tailIdx]++;
|
|
964
|
+
while (list[tailIdx] > chatCodesLen) {
|
|
965
|
+
list[tailIdx] = 0;
|
|
966
|
+
tailIdx = tailIdx - 1;
|
|
967
|
+
if (tailIdx < 0) {
|
|
968
|
+
list.push(0);
|
|
969
|
+
break;
|
|
970
|
+
}
|
|
971
|
+
list[tailIdx]++;
|
|
972
|
+
}
|
|
973
|
+
return res;
|
|
974
|
+
};
|
|
975
|
+
};
|
|
976
|
+
function isElement(node) {
|
|
977
|
+
return node.nodeType === 1;
|
|
978
|
+
}
|
|
979
|
+
function isText(node) {
|
|
980
|
+
return node.nodeType === 3;
|
|
981
|
+
}
|
|
982
|
+
function isComment(node) {
|
|
983
|
+
return node.nodeName === COMMENT;
|
|
984
|
+
}
|
|
985
|
+
function isHasExtractProp(el) {
|
|
986
|
+
const res = Object.keys(el.props).find((prop) => {
|
|
987
|
+
return !(/^(class|style|id)$/.test(prop) || prop.startsWith("data-"));
|
|
988
|
+
});
|
|
989
|
+
return Boolean(res);
|
|
990
|
+
}
|
|
991
|
+
/**
|
|
992
|
+
* 往上寻找组件树直到 root,寻找是否有祖先组件绑定了同类型的事件
|
|
993
|
+
* @param node 当前组件
|
|
994
|
+
* @param type 事件类型
|
|
995
|
+
*/
|
|
996
|
+
function isParentBound(node, type) {
|
|
997
|
+
while (node = node?.parentElement || null) if (!node || node.nodeName === "root" || node.nodeName === "root-portal") return false;
|
|
998
|
+
else if (node.__handlers[type]?.length) return true;
|
|
999
|
+
return false;
|
|
1000
|
+
}
|
|
1001
|
+
function shortcutAttr(key) {
|
|
1002
|
+
switch (key) {
|
|
1003
|
+
case STYLE: return Shortcuts.Style;
|
|
1004
|
+
case "id": return "uid";
|
|
1005
|
+
case CLASS: return Shortcuts.Class;
|
|
1006
|
+
default: return key;
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
const customWrapperCache = /* @__PURE__ */ new Map();
|
|
1010
|
+
function extend(ctor, methodName, options) {
|
|
1011
|
+
if (isFunction(options)) options = { value: options };
|
|
1012
|
+
Object.defineProperty(ctor.prototype, methodName, {
|
|
1013
|
+
configurable: true,
|
|
1014
|
+
enumerable: true,
|
|
1015
|
+
...options
|
|
1016
|
+
});
|
|
1017
|
+
}
|
|
1018
|
+
let componentsAlias$1;
|
|
1019
|
+
function getComponentsAlias() {
|
|
1020
|
+
if (!componentsAlias$1) componentsAlias$1 = getComponentsAlias$1(internalComponents);
|
|
1021
|
+
return componentsAlias$1;
|
|
1022
|
+
}
|
|
1023
|
+
function convertNumber2PX(value) {
|
|
1024
|
+
return value + "px";
|
|
1025
|
+
}
|
|
1026
|
+
//#endregion
|
|
1027
|
+
//#region src/dom/class-list.ts
|
|
1028
|
+
var ClassList = class {
|
|
1029
|
+
constructor(className, el) {
|
|
1030
|
+
this.tokenList = [];
|
|
1031
|
+
this.el = el;
|
|
1032
|
+
className.trim().split(/\s+/).forEach((token) => this.tokenList.push(token));
|
|
1033
|
+
}
|
|
1034
|
+
get value() {
|
|
1035
|
+
return this.toString();
|
|
1036
|
+
}
|
|
1037
|
+
get length() {
|
|
1038
|
+
return this.tokenList.length;
|
|
1039
|
+
}
|
|
1040
|
+
add() {
|
|
1041
|
+
let index = 0;
|
|
1042
|
+
let updated = false;
|
|
1043
|
+
const tokens = arguments;
|
|
1044
|
+
const length = tokens.length;
|
|
1045
|
+
const tokenList = this.tokenList;
|
|
1046
|
+
do {
|
|
1047
|
+
const token = tokens[index];
|
|
1048
|
+
if (this.checkTokenIsValid(token) && !~tokenList.indexOf(token)) {
|
|
1049
|
+
tokenList.push(token);
|
|
1050
|
+
updated = true;
|
|
1051
|
+
}
|
|
1052
|
+
} while (++index < length);
|
|
1053
|
+
if (updated) this._update();
|
|
1054
|
+
}
|
|
1055
|
+
remove() {
|
|
1056
|
+
let i = 0;
|
|
1057
|
+
let updated = false;
|
|
1058
|
+
const tokens = arguments;
|
|
1059
|
+
const length = tokens.length;
|
|
1060
|
+
const tokenList = this.tokenList;
|
|
1061
|
+
do {
|
|
1062
|
+
const token = tokens[i] + "";
|
|
1063
|
+
if (!this.checkTokenIsValid(token)) continue;
|
|
1064
|
+
const index = tokenList.indexOf(token);
|
|
1065
|
+
if (~tokenList.indexOf(token)) {
|
|
1066
|
+
tokenList.splice(index, 1);
|
|
1067
|
+
updated = true;
|
|
1068
|
+
}
|
|
1069
|
+
} while (++i < length);
|
|
1070
|
+
if (updated) this._update();
|
|
1071
|
+
}
|
|
1072
|
+
contains(token) {
|
|
1073
|
+
if (!this.checkTokenIsValid(token)) return false;
|
|
1074
|
+
return !!~this.tokenList.indexOf(token);
|
|
1075
|
+
}
|
|
1076
|
+
toggle(token, force) {
|
|
1077
|
+
const result = this.contains(token);
|
|
1078
|
+
const method = result ? force !== true && "remove" : force !== false && "add";
|
|
1079
|
+
if (method) this[method](token);
|
|
1080
|
+
if (force === true || force === false) return force;
|
|
1081
|
+
else return !result;
|
|
1082
|
+
}
|
|
1083
|
+
replace(token, replacement_token) {
|
|
1084
|
+
if (!this.checkTokenIsValid(token) || !this.checkTokenIsValid(replacement_token)) return;
|
|
1085
|
+
const index = this.tokenList.indexOf(token);
|
|
1086
|
+
if (~index) {
|
|
1087
|
+
this.tokenList.splice(index, 1, replacement_token);
|
|
1088
|
+
this._update();
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
toString() {
|
|
1092
|
+
return this.tokenList.filter((v) => v !== "").join(" ");
|
|
1093
|
+
}
|
|
1094
|
+
checkTokenIsValid(token) {
|
|
1095
|
+
if (token === "" || /\s/.test(token)) return false;
|
|
1096
|
+
return true;
|
|
1097
|
+
}
|
|
1098
|
+
_update() {
|
|
1099
|
+
this.el.className = this.value;
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1102
|
+
//#endregion
|
|
1103
|
+
//#region src/dom/event-source.ts
|
|
1104
|
+
var EventSource = class extends Map {
|
|
1105
|
+
removeNode(child) {
|
|
1106
|
+
const { sid, uid } = child;
|
|
1107
|
+
this.delete(sid);
|
|
1108
|
+
if (uid !== sid && uid) this.delete(uid);
|
|
1109
|
+
}
|
|
1110
|
+
removeNodeTree(child) {
|
|
1111
|
+
this.removeNode(child);
|
|
1112
|
+
const { childNodes } = child;
|
|
1113
|
+
childNodes.forEach((node) => this.removeNodeTree(node));
|
|
1114
|
+
}
|
|
1115
|
+
};
|
|
1116
|
+
const eventSource = new EventSource();
|
|
1117
|
+
//#endregion
|
|
1118
|
+
//#region src/hydrate.ts
|
|
1119
|
+
let SPECIAL_NODES;
|
|
1120
|
+
let componentsAlias;
|
|
1121
|
+
/**
|
|
1122
|
+
* React also has a fancy function's name for this: `hydrate()`.
|
|
1123
|
+
* You may have been heard `hydrate` as a SSR-related function,
|
|
1124
|
+
* actually, `hydrate` basicly do the `render()` thing, but ignore some properties,
|
|
1125
|
+
* it's a vnode traverser and modifier: that's exactly what Taro's doing in here.
|
|
1126
|
+
*/
|
|
1127
|
+
function hydrate(node) {
|
|
1128
|
+
componentsAlias ||= getComponentsAlias();
|
|
1129
|
+
SPECIAL_NODES ||= hooks$1.call("getSpecialNodes");
|
|
1130
|
+
const nodeName = node.nodeName;
|
|
1131
|
+
let compileModeName = null;
|
|
1132
|
+
if (isText(node)) return {
|
|
1133
|
+
sid: node.sid,
|
|
1134
|
+
[Shortcuts.Text]: node.nodeValue,
|
|
1135
|
+
[Shortcuts.NodeName]: componentsAlias[nodeName]?._num || "8"
|
|
1136
|
+
};
|
|
1137
|
+
const data = {
|
|
1138
|
+
[Shortcuts.NodeName]: nodeName,
|
|
1139
|
+
sid: node.sid
|
|
1140
|
+
};
|
|
1141
|
+
if (node.uid !== node.sid) data.uid = node.uid;
|
|
1142
|
+
if (SPECIAL_NODES.indexOf(nodeName) > -1) {
|
|
1143
|
+
if (!node.isAnyEventBinded()) {
|
|
1144
|
+
data[Shortcuts.NodeName] = `static-${nodeName}`;
|
|
1145
|
+
if (nodeName === "view" && !isHasExtractProp(node)) data[Shortcuts.NodeName] = PURE_VIEW;
|
|
1146
|
+
}
|
|
1147
|
+
if (nodeName === "view" && node.isOnlyClickBinded() && !isHasExtractProp(node)) data[Shortcuts.NodeName] = CLICK_VIEW;
|
|
1148
|
+
}
|
|
1149
|
+
const { props } = node;
|
|
1150
|
+
for (const prop in props) {
|
|
1151
|
+
const propInCamelCase = toCamelCase(prop);
|
|
1152
|
+
if (!prop.startsWith("data-") && prop !== "class" && prop !== "style" && prop !== "id" && propInCamelCase !== "catchMove" && propInCamelCase !== "compileMode") data[propInCamelCase] = props[prop];
|
|
1153
|
+
if (process.env.TARO_ENV !== "swan" && nodeName === "view" && propInCamelCase === "catchMove" && props[prop] !== false) data[Shortcuts.NodeName] = CATCH_VIEW;
|
|
1154
|
+
if (propInCamelCase === "compileMode") compileModeName = props[prop];
|
|
1155
|
+
}
|
|
1156
|
+
data[Shortcuts.Childnodes] = node.childNodes.filter((node) => !isComment(node)).map(hydrate);
|
|
1157
|
+
if (node.className !== "") data[Shortcuts.Class] = node.className;
|
|
1158
|
+
const cssText = node.cssText;
|
|
1159
|
+
if (cssText !== "" && nodeName !== "swiper-item") data[Shortcuts.Style] = cssText;
|
|
1160
|
+
hooks$1.call("modifyHydrateData", data, node);
|
|
1161
|
+
const nn = data[Shortcuts.NodeName];
|
|
1162
|
+
const componentAlias = componentsAlias[nn];
|
|
1163
|
+
if (componentAlias) {
|
|
1164
|
+
data[Shortcuts.NodeName] = componentAlias._num;
|
|
1165
|
+
for (const prop in data) if (prop in componentAlias) {
|
|
1166
|
+
data[componentAlias[prop]] = data[prop];
|
|
1167
|
+
delete data[prop];
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
if (compileModeName !== null) data[Shortcuts.NodeName] = compileModeName;
|
|
1171
|
+
return hooks$1.call("transferHydrateData", data, node, componentAlias) || data;
|
|
1172
|
+
}
|
|
1173
|
+
//#endregion
|
|
1174
|
+
//#region src/dom/event-target.ts
|
|
1175
|
+
var TaroEventTarget = class {
|
|
1176
|
+
constructor() {
|
|
1177
|
+
this.__handlers = {};
|
|
1178
|
+
}
|
|
1179
|
+
addEventListener(type, handler, options) {
|
|
1180
|
+
type = type.toLowerCase();
|
|
1181
|
+
hooks$1.call("onAddEvent", type, handler, options, this);
|
|
1182
|
+
if (type === "regionchange") {
|
|
1183
|
+
this.addEventListener("begin", handler, options);
|
|
1184
|
+
this.addEventListener("end", handler, options);
|
|
1185
|
+
return;
|
|
1186
|
+
}
|
|
1187
|
+
let isCapture = Boolean(options);
|
|
1188
|
+
let isOnce = false;
|
|
1189
|
+
if (isObject(options)) {
|
|
1190
|
+
isCapture = Boolean(options.capture);
|
|
1191
|
+
isOnce = Boolean(options.once);
|
|
1192
|
+
}
|
|
1193
|
+
if (isOnce) {
|
|
1194
|
+
const wrapper = function() {
|
|
1195
|
+
handler.apply(this, arguments);
|
|
1196
|
+
this.removeEventListener(type, wrapper);
|
|
1197
|
+
};
|
|
1198
|
+
this.addEventListener(type, wrapper, {
|
|
1199
|
+
...options,
|
|
1200
|
+
once: false
|
|
1201
|
+
});
|
|
1202
|
+
return;
|
|
1203
|
+
}
|
|
1204
|
+
warn(isCapture, "Taro 暂未实现 event 的 capture 特性。");
|
|
1205
|
+
const oldHandler = handler;
|
|
1206
|
+
handler = function() {
|
|
1207
|
+
return oldHandler.apply(this, arguments);
|
|
1208
|
+
};
|
|
1209
|
+
handler.oldHandler = oldHandler;
|
|
1210
|
+
const handlers = this.__handlers[type];
|
|
1211
|
+
if (isArray(handlers)) handlers.push(handler);
|
|
1212
|
+
else this.__handlers[type] = [handler];
|
|
1213
|
+
}
|
|
1214
|
+
removeEventListener(type, handler) {
|
|
1215
|
+
type = type.toLowerCase();
|
|
1216
|
+
if (type === "regionchange") {
|
|
1217
|
+
this.removeEventListener("begin", handler);
|
|
1218
|
+
this.removeEventListener("end", handler);
|
|
1219
|
+
return;
|
|
1220
|
+
}
|
|
1221
|
+
if (!handler) return;
|
|
1222
|
+
const handlers = this.__handlers[type];
|
|
1223
|
+
if (!isArray(handlers)) return;
|
|
1224
|
+
const index = handlers.findIndex((item) => {
|
|
1225
|
+
if (item === handler || item.oldHandler === handler) return true;
|
|
1226
|
+
});
|
|
1227
|
+
warn(index === -1, `事件: '${type}' 没有注册在 DOM 中,因此不会被移除。`);
|
|
1228
|
+
handlers.splice(index, 1);
|
|
1229
|
+
}
|
|
1230
|
+
isAnyEventBinded() {
|
|
1231
|
+
const handlers = this.__handlers;
|
|
1232
|
+
const isAnyEventBinded = Object.keys(handlers).find((key) => handlers[key].length);
|
|
1233
|
+
return Boolean(isAnyEventBinded);
|
|
1234
|
+
}
|
|
1235
|
+
isOnlyClickBinded() {
|
|
1236
|
+
const handlers = this.__handlers;
|
|
1237
|
+
const isOnlyClickBinded = handlers.tap && Object.keys(handlers).length === 1;
|
|
1238
|
+
return Boolean(isOnlyClickBinded);
|
|
1239
|
+
}
|
|
1240
|
+
};
|
|
1241
|
+
//#endregion
|
|
1242
|
+
//#region src/dom/node.ts
|
|
1243
|
+
const CHILDNODES = Shortcuts.Childnodes;
|
|
1244
|
+
const nodeId = incrementId();
|
|
1245
|
+
var TaroNode = class TaroNode extends TaroEventTarget {
|
|
1246
|
+
constructor() {
|
|
1247
|
+
super();
|
|
1248
|
+
this.parentNode = null;
|
|
1249
|
+
this.childNodes = [];
|
|
1250
|
+
this.hydrate = (node) => () => hydrate(node);
|
|
1251
|
+
this.uid = "_" + nodeId();
|
|
1252
|
+
this.sid = this.uid;
|
|
1253
|
+
eventSource.set(this.sid, this);
|
|
1254
|
+
}
|
|
1255
|
+
updateChildNodes(isClean) {
|
|
1256
|
+
const cleanChildNodes = () => [];
|
|
1257
|
+
const rerenderChildNodes = () => {
|
|
1258
|
+
return this.childNodes.filter((node) => !isComment(node)).map(hydrate);
|
|
1259
|
+
};
|
|
1260
|
+
this.enqueueUpdate({
|
|
1261
|
+
path: `${this._path}.${CHILDNODES}`,
|
|
1262
|
+
value: isClean ? cleanChildNodes : rerenderChildNodes
|
|
1263
|
+
});
|
|
1264
|
+
}
|
|
1265
|
+
updateSingleChild(index) {
|
|
1266
|
+
this.childNodes.forEach((child, childIndex) => {
|
|
1267
|
+
if (isComment(child)) return;
|
|
1268
|
+
if (index && childIndex < index) return;
|
|
1269
|
+
this.enqueueUpdate({
|
|
1270
|
+
path: child._path,
|
|
1271
|
+
value: this.hydrate(child)
|
|
1272
|
+
});
|
|
1273
|
+
});
|
|
1274
|
+
}
|
|
1275
|
+
get _root() {
|
|
1276
|
+
return this.parentNode?._root || null;
|
|
1277
|
+
}
|
|
1278
|
+
findIndex(refChild) {
|
|
1279
|
+
const index = this.childNodes.indexOf(refChild);
|
|
1280
|
+
ensure(index !== -1, "The node to be replaced is not a child of this node.");
|
|
1281
|
+
return index;
|
|
1282
|
+
}
|
|
1283
|
+
get _path() {
|
|
1284
|
+
const parentNode = this.parentNode;
|
|
1285
|
+
if (parentNode) {
|
|
1286
|
+
const indexOfNode = parentNode.childNodes.filter((node) => !isComment(node)).indexOf(this);
|
|
1287
|
+
const index = hooks$1.call("getPathIndex", indexOfNode);
|
|
1288
|
+
return `${parentNode._path}.${CHILDNODES}.${index}`;
|
|
1289
|
+
}
|
|
1290
|
+
return "";
|
|
1291
|
+
}
|
|
1292
|
+
get nextSibling() {
|
|
1293
|
+
const parentNode = this.parentNode;
|
|
1294
|
+
return parentNode?.childNodes[parentNode.findIndex(this) + 1] || null;
|
|
1295
|
+
}
|
|
1296
|
+
get previousSibling() {
|
|
1297
|
+
const parentNode = this.parentNode;
|
|
1298
|
+
return parentNode?.childNodes[parentNode.findIndex(this) - 1] || null;
|
|
1299
|
+
}
|
|
1300
|
+
get parentElement() {
|
|
1301
|
+
const parentNode = this.parentNode;
|
|
1302
|
+
if (parentNode?.nodeType === 1) return parentNode;
|
|
1303
|
+
return null;
|
|
1304
|
+
}
|
|
1305
|
+
get firstChild() {
|
|
1306
|
+
return this.childNodes[0] || null;
|
|
1307
|
+
}
|
|
1308
|
+
get lastChild() {
|
|
1309
|
+
const childNodes = this.childNodes;
|
|
1310
|
+
return childNodes[childNodes.length - 1] || null;
|
|
1311
|
+
}
|
|
1312
|
+
/**
|
|
1313
|
+
* @textContent 目前只能置空子元素
|
|
1314
|
+
* @TODO 等待完整 innerHTML 实现
|
|
1315
|
+
*/
|
|
1316
|
+
set textContent(text) {
|
|
1317
|
+
const removedNodes = this.childNodes.slice();
|
|
1318
|
+
const addedNodes = [];
|
|
1319
|
+
while (this.firstChild) this.removeChild(this.firstChild, { doUpdate: false });
|
|
1320
|
+
if (text === "") this.updateChildNodes(true);
|
|
1321
|
+
else {
|
|
1322
|
+
const newText = env.document.createTextNode(text);
|
|
1323
|
+
addedNodes.push(newText);
|
|
1324
|
+
this.appendChild(newText);
|
|
1325
|
+
this.updateChildNodes();
|
|
1326
|
+
}
|
|
1327
|
+
MutationObserver$1.record({
|
|
1328
|
+
type: "childList",
|
|
1329
|
+
target: this,
|
|
1330
|
+
removedNodes,
|
|
1331
|
+
addedNodes
|
|
1332
|
+
});
|
|
1333
|
+
}
|
|
1334
|
+
/**
|
|
1335
|
+
* @doc https://developer.mozilla.org/zh-CN/docs/Web/API/Node/insertBefore
|
|
1336
|
+
* @scenario
|
|
1337
|
+
* [A,B,C]
|
|
1338
|
+
* 1. insert D before C, D has no parent
|
|
1339
|
+
* 2. insert D before C, D has the same parent of C
|
|
1340
|
+
* 3. insert D before C, D has the different parent of C
|
|
1341
|
+
*/
|
|
1342
|
+
insertBefore(newChild, refChild, isReplace) {
|
|
1343
|
+
if (newChild.nodeName === "document-fragment") {
|
|
1344
|
+
newChild.childNodes.reduceRight((previousValue, currentValue) => {
|
|
1345
|
+
this.insertBefore(currentValue, previousValue);
|
|
1346
|
+
return currentValue;
|
|
1347
|
+
}, refChild);
|
|
1348
|
+
return newChild;
|
|
1349
|
+
}
|
|
1350
|
+
newChild.remove({ cleanRef: false });
|
|
1351
|
+
let index = 0;
|
|
1352
|
+
newChild.parentNode = this;
|
|
1353
|
+
if (refChild) {
|
|
1354
|
+
index = this.findIndex(refChild);
|
|
1355
|
+
this.childNodes.splice(index, 0, newChild);
|
|
1356
|
+
} else this.childNodes.push(newChild);
|
|
1357
|
+
const childNodesLength = this.childNodes.length;
|
|
1358
|
+
if (this._root) if (!refChild) if (childNodesLength === 1) this.updateChildNodes();
|
|
1359
|
+
else this.enqueueUpdate({
|
|
1360
|
+
path: newChild._path,
|
|
1361
|
+
value: this.hydrate(newChild)
|
|
1362
|
+
});
|
|
1363
|
+
else if (isReplace) this.enqueueUpdate({
|
|
1364
|
+
path: newChild._path,
|
|
1365
|
+
value: this.hydrate(newChild)
|
|
1366
|
+
});
|
|
1367
|
+
else if (childNodesLength * 2 / 3 > index) this.updateChildNodes();
|
|
1368
|
+
else this.updateSingleChild(index);
|
|
1369
|
+
MutationObserver$1.record({
|
|
1370
|
+
type: "childList",
|
|
1371
|
+
target: this,
|
|
1372
|
+
addedNodes: [newChild],
|
|
1373
|
+
removedNodes: isReplace ? [refChild] : [],
|
|
1374
|
+
nextSibling: isReplace ? refChild.nextSibling : refChild || null,
|
|
1375
|
+
previousSibling: newChild.previousSibling
|
|
1376
|
+
});
|
|
1377
|
+
return newChild;
|
|
1378
|
+
}
|
|
1379
|
+
/**
|
|
1380
|
+
* @doc https://developer.mozilla.org/zh-CN/docs/Web/API/Node/appendChild
|
|
1381
|
+
* @scenario
|
|
1382
|
+
* [A,B,C]
|
|
1383
|
+
* 1. append C, C has no parent
|
|
1384
|
+
* 2. append C, C has the same parent of B
|
|
1385
|
+
* 3. append C, C has the different parent of B
|
|
1386
|
+
*/
|
|
1387
|
+
appendChild(newChild) {
|
|
1388
|
+
return this.insertBefore(newChild);
|
|
1389
|
+
}
|
|
1390
|
+
/**
|
|
1391
|
+
* @doc https://developer.mozilla.org/zh-CN/docs/Web/API/Node/replaceChild
|
|
1392
|
+
* @scenario
|
|
1393
|
+
* [A,B,C]
|
|
1394
|
+
* 1. replace B with C, C has no parent
|
|
1395
|
+
* 2. replace B with C, C has no parent, C has the same parent of B
|
|
1396
|
+
* 3. replace B with C, C has no parent, C has the different parent of B
|
|
1397
|
+
*/
|
|
1398
|
+
replaceChild(newChild, oldChild) {
|
|
1399
|
+
if (oldChild.parentNode !== this) return;
|
|
1400
|
+
this.insertBefore(newChild, oldChild, true);
|
|
1401
|
+
oldChild.remove({ doUpdate: false });
|
|
1402
|
+
return oldChild;
|
|
1403
|
+
}
|
|
1404
|
+
/**
|
|
1405
|
+
* @doc https://developer.mozilla.org/zh-CN/docs/Web/API/Node/removeChild
|
|
1406
|
+
* @scenario
|
|
1407
|
+
* [A,B,C]
|
|
1408
|
+
* 1. remove A or B
|
|
1409
|
+
* 2. remove C
|
|
1410
|
+
*/
|
|
1411
|
+
removeChild(child, options = {}) {
|
|
1412
|
+
const { cleanRef, doUpdate } = options;
|
|
1413
|
+
if (cleanRef !== false && doUpdate !== false) MutationObserver$1.record({
|
|
1414
|
+
type: "childList",
|
|
1415
|
+
target: this,
|
|
1416
|
+
removedNodes: [child],
|
|
1417
|
+
nextSibling: child.nextSibling,
|
|
1418
|
+
previousSibling: child.previousSibling
|
|
1419
|
+
});
|
|
1420
|
+
const index = this.findIndex(child);
|
|
1421
|
+
this.childNodes.splice(index, 1);
|
|
1422
|
+
child.parentNode = null;
|
|
1423
|
+
if (cleanRef !== false) eventSource.removeNodeTree(child);
|
|
1424
|
+
if (this._root && doUpdate !== false) this.updateChildNodes();
|
|
1425
|
+
return child;
|
|
1426
|
+
}
|
|
1427
|
+
remove(options) {
|
|
1428
|
+
this.parentNode?.removeChild(this, options);
|
|
1429
|
+
}
|
|
1430
|
+
hasChildNodes() {
|
|
1431
|
+
return this.childNodes.length > 0;
|
|
1432
|
+
}
|
|
1433
|
+
enqueueUpdate(payload) {
|
|
1434
|
+
this._root?.enqueueUpdate(payload);
|
|
1435
|
+
}
|
|
1436
|
+
get ownerDocument() {
|
|
1437
|
+
return env.document;
|
|
1438
|
+
}
|
|
1439
|
+
static extend(methodName, options) {
|
|
1440
|
+
extend(TaroNode, methodName, options);
|
|
1441
|
+
}
|
|
1442
|
+
};
|
|
1443
|
+
//#endregion
|
|
1444
|
+
//#region src/dom/style_properties.ts
|
|
1445
|
+
const WEBKIT = "webkit";
|
|
1446
|
+
const styleProperties = [
|
|
1447
|
+
"all",
|
|
1448
|
+
"appearance",
|
|
1449
|
+
"backdropFilter",
|
|
1450
|
+
"blockOverflow",
|
|
1451
|
+
"blockSize",
|
|
1452
|
+
"bottom",
|
|
1453
|
+
"clear",
|
|
1454
|
+
"contain",
|
|
1455
|
+
"content",
|
|
1456
|
+
"continue",
|
|
1457
|
+
"cursor",
|
|
1458
|
+
"direction",
|
|
1459
|
+
"display",
|
|
1460
|
+
"filter",
|
|
1461
|
+
"float",
|
|
1462
|
+
"gap",
|
|
1463
|
+
"height",
|
|
1464
|
+
"inset",
|
|
1465
|
+
"isolation",
|
|
1466
|
+
"left",
|
|
1467
|
+
"letterSpacing",
|
|
1468
|
+
"lightingColor",
|
|
1469
|
+
"markerSide",
|
|
1470
|
+
"mixBlendMode",
|
|
1471
|
+
"opacity",
|
|
1472
|
+
"order",
|
|
1473
|
+
"position",
|
|
1474
|
+
"quotes",
|
|
1475
|
+
"resize",
|
|
1476
|
+
"right",
|
|
1477
|
+
"rowGap",
|
|
1478
|
+
"tabSize",
|
|
1479
|
+
"tableLayout",
|
|
1480
|
+
"top",
|
|
1481
|
+
"userSelect",
|
|
1482
|
+
"verticalAlign",
|
|
1483
|
+
"visibility",
|
|
1484
|
+
"voiceFamily",
|
|
1485
|
+
"volume",
|
|
1486
|
+
"whiteSpace",
|
|
1487
|
+
"widows",
|
|
1488
|
+
"width",
|
|
1489
|
+
"zIndex",
|
|
1490
|
+
"pointerEvents",
|
|
1491
|
+
"aspectRatio"
|
|
1492
|
+
];
|
|
1493
|
+
function combine(prefix, list, excludeSelf) {
|
|
1494
|
+
!excludeSelf && styleProperties.push(prefix);
|
|
1495
|
+
list.forEach((item) => {
|
|
1496
|
+
styleProperties.push(prefix + item);
|
|
1497
|
+
if (prefix === WEBKIT) styleProperties.push("Webkit" + item);
|
|
1498
|
+
});
|
|
1499
|
+
}
|
|
1500
|
+
const color = "Color";
|
|
1501
|
+
const style = "Style";
|
|
1502
|
+
const width = "Width";
|
|
1503
|
+
const image = "Image";
|
|
1504
|
+
const size = "Size";
|
|
1505
|
+
const color_style_width = [
|
|
1506
|
+
color,
|
|
1507
|
+
style,
|
|
1508
|
+
width
|
|
1509
|
+
];
|
|
1510
|
+
const fitlength_fitwidth_image = [
|
|
1511
|
+
"FitLength",
|
|
1512
|
+
"FitWidth",
|
|
1513
|
+
image
|
|
1514
|
+
];
|
|
1515
|
+
const fitlength_fitwidth_image_radius = [...fitlength_fitwidth_image, "Radius"];
|
|
1516
|
+
const color_style_width_fitlength_fitwidth_image = [...color_style_width, ...fitlength_fitwidth_image];
|
|
1517
|
+
const endRadius_startRadius = ["EndRadius", "StartRadius"];
|
|
1518
|
+
const bottom_left_right_top = [
|
|
1519
|
+
"Bottom",
|
|
1520
|
+
"Left",
|
|
1521
|
+
"Right",
|
|
1522
|
+
"Top"
|
|
1523
|
+
];
|
|
1524
|
+
const end_start = ["End", "Start"];
|
|
1525
|
+
const content_items_self = [
|
|
1526
|
+
"Content",
|
|
1527
|
+
"Items",
|
|
1528
|
+
"Self"
|
|
1529
|
+
];
|
|
1530
|
+
const blockSize_height_inlineSize_width = [
|
|
1531
|
+
"BlockSize",
|
|
1532
|
+
"Height",
|
|
1533
|
+
"InlineSize",
|
|
1534
|
+
width
|
|
1535
|
+
];
|
|
1536
|
+
const after_before = ["After", "Before"];
|
|
1537
|
+
combine("borderBlock", color_style_width);
|
|
1538
|
+
combine("borderBlockEnd", color_style_width);
|
|
1539
|
+
combine("borderBlockStart", color_style_width);
|
|
1540
|
+
combine("outline", [...color_style_width, "Offset"]);
|
|
1541
|
+
combine("border", [
|
|
1542
|
+
...color_style_width,
|
|
1543
|
+
"Boundary",
|
|
1544
|
+
"Break",
|
|
1545
|
+
"Collapse",
|
|
1546
|
+
"Radius",
|
|
1547
|
+
"Spacing"
|
|
1548
|
+
]);
|
|
1549
|
+
combine("borderFit", ["Length", width]);
|
|
1550
|
+
combine("borderInline", color_style_width);
|
|
1551
|
+
combine("borderInlineEnd", color_style_width);
|
|
1552
|
+
combine("borderInlineStart", color_style_width);
|
|
1553
|
+
combine("borderLeft", color_style_width_fitlength_fitwidth_image);
|
|
1554
|
+
combine("borderRight", color_style_width_fitlength_fitwidth_image);
|
|
1555
|
+
combine("borderTop", color_style_width_fitlength_fitwidth_image);
|
|
1556
|
+
combine("borderBottom", color_style_width_fitlength_fitwidth_image);
|
|
1557
|
+
combine("textDecoration", [
|
|
1558
|
+
color,
|
|
1559
|
+
style,
|
|
1560
|
+
"Line"
|
|
1561
|
+
]);
|
|
1562
|
+
combine("textEmphasis", [
|
|
1563
|
+
color,
|
|
1564
|
+
style,
|
|
1565
|
+
"Position"
|
|
1566
|
+
]);
|
|
1567
|
+
combine("scrollMargin", bottom_left_right_top);
|
|
1568
|
+
combine("scrollPadding", bottom_left_right_top);
|
|
1569
|
+
combine("padding", bottom_left_right_top);
|
|
1570
|
+
combine("margin", [...bottom_left_right_top, "Trim"]);
|
|
1571
|
+
combine("scrollMarginBlock", end_start);
|
|
1572
|
+
combine("scrollMarginInline", end_start);
|
|
1573
|
+
combine("scrollPaddingBlock", end_start);
|
|
1574
|
+
combine("scrollPaddingInline", end_start);
|
|
1575
|
+
combine("gridColumn", end_start);
|
|
1576
|
+
combine("gridRow", end_start);
|
|
1577
|
+
combine("insetBlock", end_start);
|
|
1578
|
+
combine("insetInline", end_start);
|
|
1579
|
+
combine("marginBlock", end_start);
|
|
1580
|
+
combine("marginInline", end_start);
|
|
1581
|
+
combine("paddingBlock", end_start);
|
|
1582
|
+
combine("paddingInline", end_start);
|
|
1583
|
+
combine("pause", after_before);
|
|
1584
|
+
combine("cue", after_before);
|
|
1585
|
+
combine("mask", [
|
|
1586
|
+
"Clip",
|
|
1587
|
+
"Composite",
|
|
1588
|
+
image,
|
|
1589
|
+
"Mode",
|
|
1590
|
+
"Origin",
|
|
1591
|
+
"Position",
|
|
1592
|
+
"Repeat",
|
|
1593
|
+
size,
|
|
1594
|
+
"Type"
|
|
1595
|
+
]);
|
|
1596
|
+
combine("borderImage", [
|
|
1597
|
+
"Outset",
|
|
1598
|
+
"Repeat",
|
|
1599
|
+
"Slice",
|
|
1600
|
+
"Source",
|
|
1601
|
+
"Transform",
|
|
1602
|
+
width
|
|
1603
|
+
]);
|
|
1604
|
+
combine("maskBorder", [
|
|
1605
|
+
"Mode",
|
|
1606
|
+
"Outset",
|
|
1607
|
+
"Repeat",
|
|
1608
|
+
"Slice",
|
|
1609
|
+
"Source",
|
|
1610
|
+
width
|
|
1611
|
+
]);
|
|
1612
|
+
combine("font", [
|
|
1613
|
+
"Family",
|
|
1614
|
+
"FeatureSettings",
|
|
1615
|
+
"Kerning",
|
|
1616
|
+
"LanguageOverride",
|
|
1617
|
+
"MaxSize",
|
|
1618
|
+
"MinSize",
|
|
1619
|
+
"OpticalSizing",
|
|
1620
|
+
"Palette",
|
|
1621
|
+
size,
|
|
1622
|
+
"SizeAdjust",
|
|
1623
|
+
"Stretch",
|
|
1624
|
+
style,
|
|
1625
|
+
"Weight",
|
|
1626
|
+
"VariationSettings"
|
|
1627
|
+
]);
|
|
1628
|
+
combine("transform", [
|
|
1629
|
+
"Box",
|
|
1630
|
+
"Origin",
|
|
1631
|
+
style
|
|
1632
|
+
]);
|
|
1633
|
+
combine("background", [
|
|
1634
|
+
color,
|
|
1635
|
+
image,
|
|
1636
|
+
"Attachment",
|
|
1637
|
+
"BlendMode",
|
|
1638
|
+
"Clip",
|
|
1639
|
+
"Origin",
|
|
1640
|
+
"Position",
|
|
1641
|
+
"Repeat",
|
|
1642
|
+
size
|
|
1643
|
+
]);
|
|
1644
|
+
combine("listStyle", [
|
|
1645
|
+
image,
|
|
1646
|
+
"Position",
|
|
1647
|
+
"Type"
|
|
1648
|
+
]);
|
|
1649
|
+
combine("scrollSnap", [
|
|
1650
|
+
"Align",
|
|
1651
|
+
"Stop",
|
|
1652
|
+
"Type"
|
|
1653
|
+
]);
|
|
1654
|
+
combine("grid", [
|
|
1655
|
+
"Area",
|
|
1656
|
+
"AutoColumns",
|
|
1657
|
+
"AutoFlow",
|
|
1658
|
+
"AutoRows"
|
|
1659
|
+
]);
|
|
1660
|
+
combine("gridTemplate", [
|
|
1661
|
+
"Areas",
|
|
1662
|
+
"Columns",
|
|
1663
|
+
"Rows"
|
|
1664
|
+
]);
|
|
1665
|
+
combine("overflow", [
|
|
1666
|
+
"Block",
|
|
1667
|
+
"Inline",
|
|
1668
|
+
"Wrap",
|
|
1669
|
+
"X",
|
|
1670
|
+
"Y"
|
|
1671
|
+
]);
|
|
1672
|
+
combine("transition", [
|
|
1673
|
+
"Delay",
|
|
1674
|
+
"Duration",
|
|
1675
|
+
"Property",
|
|
1676
|
+
"TimingFunction"
|
|
1677
|
+
]);
|
|
1678
|
+
combine("color", [
|
|
1679
|
+
"Adjust",
|
|
1680
|
+
"InterpolationFilters",
|
|
1681
|
+
"Scheme"
|
|
1682
|
+
]);
|
|
1683
|
+
combine("textAlign", ["All", "Last"]);
|
|
1684
|
+
combine("page", [
|
|
1685
|
+
"BreakAfter",
|
|
1686
|
+
"BreakBefore",
|
|
1687
|
+
"BreakInside"
|
|
1688
|
+
]);
|
|
1689
|
+
combine("animation", [
|
|
1690
|
+
"Delay",
|
|
1691
|
+
"Direction",
|
|
1692
|
+
"Duration",
|
|
1693
|
+
"FillMode",
|
|
1694
|
+
"IterationCount",
|
|
1695
|
+
"Name",
|
|
1696
|
+
"PlayState",
|
|
1697
|
+
"TimingFunction"
|
|
1698
|
+
]);
|
|
1699
|
+
combine("flex", [
|
|
1700
|
+
"Basis",
|
|
1701
|
+
"Direction",
|
|
1702
|
+
"Flow",
|
|
1703
|
+
"Grow",
|
|
1704
|
+
"Shrink",
|
|
1705
|
+
"Wrap"
|
|
1706
|
+
]);
|
|
1707
|
+
combine("offset", [
|
|
1708
|
+
...after_before,
|
|
1709
|
+
...end_start,
|
|
1710
|
+
"Anchor",
|
|
1711
|
+
"Distance",
|
|
1712
|
+
"Path",
|
|
1713
|
+
"Position",
|
|
1714
|
+
"Rotate"
|
|
1715
|
+
]);
|
|
1716
|
+
combine("perspective", ["Origin"]);
|
|
1717
|
+
combine("clip", ["Path", "Rule"]);
|
|
1718
|
+
combine("flow", ["From", "Into"]);
|
|
1719
|
+
combine("align", [
|
|
1720
|
+
"Content",
|
|
1721
|
+
"Items",
|
|
1722
|
+
"Self"
|
|
1723
|
+
], true);
|
|
1724
|
+
combine("alignment", ["Adjust", "Baseline"], true);
|
|
1725
|
+
combine("borderStart", endRadius_startRadius, true);
|
|
1726
|
+
combine("borderEnd", endRadius_startRadius, true);
|
|
1727
|
+
combine("borderCorner", [
|
|
1728
|
+
"Fit",
|
|
1729
|
+
image,
|
|
1730
|
+
"ImageTransform"
|
|
1731
|
+
], true);
|
|
1732
|
+
combine("borderTopLeft", fitlength_fitwidth_image_radius, true);
|
|
1733
|
+
combine("borderTopRight", fitlength_fitwidth_image_radius, true);
|
|
1734
|
+
combine("borderBottomLeft", fitlength_fitwidth_image_radius, true);
|
|
1735
|
+
combine("borderBottomRight", fitlength_fitwidth_image_radius, true);
|
|
1736
|
+
combine("column", [
|
|
1737
|
+
"s",
|
|
1738
|
+
"Count",
|
|
1739
|
+
"Fill",
|
|
1740
|
+
"Gap",
|
|
1741
|
+
"Rule",
|
|
1742
|
+
"RuleColor",
|
|
1743
|
+
"RuleStyle",
|
|
1744
|
+
"RuleWidth",
|
|
1745
|
+
"Span",
|
|
1746
|
+
width
|
|
1747
|
+
], true);
|
|
1748
|
+
combine("break", [...after_before, "Inside"], true);
|
|
1749
|
+
combine("wrap", [
|
|
1750
|
+
...after_before,
|
|
1751
|
+
"Flow",
|
|
1752
|
+
"Inside",
|
|
1753
|
+
"Through"
|
|
1754
|
+
], true);
|
|
1755
|
+
combine("justify", content_items_self, true);
|
|
1756
|
+
combine("place", content_items_self, true);
|
|
1757
|
+
combine("max", [...blockSize_height_inlineSize_width, "Lines"], true);
|
|
1758
|
+
combine("min", blockSize_height_inlineSize_width, true);
|
|
1759
|
+
combine("line", [
|
|
1760
|
+
"Break",
|
|
1761
|
+
"Clamp",
|
|
1762
|
+
"Grid",
|
|
1763
|
+
"Height",
|
|
1764
|
+
"Padding",
|
|
1765
|
+
"Snap"
|
|
1766
|
+
], true);
|
|
1767
|
+
combine("inline", [
|
|
1768
|
+
"BoxAlign",
|
|
1769
|
+
size,
|
|
1770
|
+
"Sizing"
|
|
1771
|
+
], true);
|
|
1772
|
+
combine("text", [
|
|
1773
|
+
"CombineUpright",
|
|
1774
|
+
"GroupAlign",
|
|
1775
|
+
"Height",
|
|
1776
|
+
"Indent",
|
|
1777
|
+
"Justify",
|
|
1778
|
+
"Orientation",
|
|
1779
|
+
"Overflow",
|
|
1780
|
+
"Shadow",
|
|
1781
|
+
"SpaceCollapse",
|
|
1782
|
+
"SpaceTrim",
|
|
1783
|
+
"Spacing",
|
|
1784
|
+
"Transform",
|
|
1785
|
+
"UnderlinePosition",
|
|
1786
|
+
"Wrap"
|
|
1787
|
+
], true);
|
|
1788
|
+
combine("shape", [
|
|
1789
|
+
"ImageThreshold",
|
|
1790
|
+
"Inside",
|
|
1791
|
+
"Margin",
|
|
1792
|
+
"Outside"
|
|
1793
|
+
], true);
|
|
1794
|
+
combine("word", [
|
|
1795
|
+
"Break",
|
|
1796
|
+
"Spacing",
|
|
1797
|
+
"Wrap"
|
|
1798
|
+
], true);
|
|
1799
|
+
combine("object", ["Fit", "Position"], true);
|
|
1800
|
+
combine("box", [
|
|
1801
|
+
"DecorationBreak",
|
|
1802
|
+
"Shadow",
|
|
1803
|
+
"Sizing",
|
|
1804
|
+
"Snap"
|
|
1805
|
+
], true);
|
|
1806
|
+
combine(WEBKIT, [
|
|
1807
|
+
"LineClamp",
|
|
1808
|
+
"BoxOrient",
|
|
1809
|
+
"TextFillColor",
|
|
1810
|
+
"TextStroke",
|
|
1811
|
+
"TextStrokeColor",
|
|
1812
|
+
"TextStrokeWidth"
|
|
1813
|
+
], true);
|
|
1814
|
+
//#endregion
|
|
1815
|
+
//#region src/dom/style.ts
|
|
1816
|
+
function recordCss(obj) {
|
|
1817
|
+
MutationObserver$1.record({
|
|
1818
|
+
type: "attributes",
|
|
1819
|
+
target: obj._element,
|
|
1820
|
+
attributeName: "style",
|
|
1821
|
+
oldValue: obj.cssText
|
|
1822
|
+
});
|
|
1823
|
+
}
|
|
1824
|
+
function enqueueUpdate(obj) {
|
|
1825
|
+
const element = obj._element;
|
|
1826
|
+
if (element._root) element.enqueueUpdate({
|
|
1827
|
+
path: `${element._path}.${Shortcuts.Style}`,
|
|
1828
|
+
value: obj.cssText
|
|
1829
|
+
});
|
|
1830
|
+
}
|
|
1831
|
+
function setStyle(newVal, styleKey) {
|
|
1832
|
+
warn(isString(newVal) && newVal.length > 2046, `Style 属性 ${styleKey} 的值数据量过大,可能会影响渲染性能,考虑使用 CSS 类或其它方案替代。`);
|
|
1833
|
+
if (this[styleKey] === newVal) return;
|
|
1834
|
+
!this._pending && recordCss(this);
|
|
1835
|
+
if (isNull(newVal) || isUndefined(newVal) || newVal === "") {
|
|
1836
|
+
this._usedStyleProp.delete(styleKey);
|
|
1837
|
+
delete this._value[styleKey];
|
|
1838
|
+
} else {
|
|
1839
|
+
this._usedStyleProp.add(styleKey);
|
|
1840
|
+
this._value[styleKey] = newVal;
|
|
1841
|
+
}
|
|
1842
|
+
!this._pending && enqueueUpdate(this);
|
|
1843
|
+
}
|
|
1844
|
+
function initStyle(ctor, styleProperties) {
|
|
1845
|
+
const properties = {};
|
|
1846
|
+
for (let i = 0; i < styleProperties.length; i++) {
|
|
1847
|
+
const styleKey = styleProperties[i];
|
|
1848
|
+
if (ctor[styleKey]) return;
|
|
1849
|
+
properties[styleKey] = {
|
|
1850
|
+
get() {
|
|
1851
|
+
const val = this._value[styleKey];
|
|
1852
|
+
return isNull(val) || isUndefined(val) ? "" : val;
|
|
1853
|
+
},
|
|
1854
|
+
set(newVal) {
|
|
1855
|
+
setStyle.call(this, newVal, styleKey);
|
|
1856
|
+
}
|
|
1857
|
+
};
|
|
1858
|
+
}
|
|
1859
|
+
Object.defineProperties(ctor.prototype, properties);
|
|
1860
|
+
}
|
|
1861
|
+
function isCssVariable(propertyName) {
|
|
1862
|
+
return /^--/.test(propertyName);
|
|
1863
|
+
}
|
|
1864
|
+
var Style = class {
|
|
1865
|
+
constructor(element) {
|
|
1866
|
+
this._element = element;
|
|
1867
|
+
this._usedStyleProp = /* @__PURE__ */ new Set();
|
|
1868
|
+
this._value = {};
|
|
1869
|
+
}
|
|
1870
|
+
setCssVariables(styleKey) {
|
|
1871
|
+
this.hasOwnProperty(styleKey) || Object.defineProperty(this, styleKey, {
|
|
1872
|
+
enumerable: true,
|
|
1873
|
+
configurable: true,
|
|
1874
|
+
get: () => {
|
|
1875
|
+
return this._value[styleKey] || "";
|
|
1876
|
+
},
|
|
1877
|
+
set: (newVal) => {
|
|
1878
|
+
setStyle.call(this, newVal, styleKey);
|
|
1879
|
+
}
|
|
1880
|
+
});
|
|
1881
|
+
}
|
|
1882
|
+
get cssText() {
|
|
1883
|
+
if (!this._usedStyleProp.size) return "";
|
|
1884
|
+
const texts = [];
|
|
1885
|
+
this._usedStyleProp.forEach((key) => {
|
|
1886
|
+
const val = this[key];
|
|
1887
|
+
if (isNull(val) || isUndefined(val)) return;
|
|
1888
|
+
let styleName = isCssVariable(key) ? key : toDashed(key);
|
|
1889
|
+
if (styleName.indexOf("webkit") === 0 || styleName.indexOf("Webkit") === 0) styleName = `-${styleName}`;
|
|
1890
|
+
texts.push(`${styleName}: ${val};`);
|
|
1891
|
+
});
|
|
1892
|
+
return texts.join(" ");
|
|
1893
|
+
}
|
|
1894
|
+
set cssText(str) {
|
|
1895
|
+
this._pending = true;
|
|
1896
|
+
recordCss(this);
|
|
1897
|
+
this._usedStyleProp.forEach((prop) => {
|
|
1898
|
+
this.removeProperty(prop);
|
|
1899
|
+
});
|
|
1900
|
+
if (str === "" || isUndefined(str) || isNull(str)) {
|
|
1901
|
+
this._pending = false;
|
|
1902
|
+
enqueueUpdate(this);
|
|
1903
|
+
return;
|
|
1904
|
+
}
|
|
1905
|
+
const rules = str.split(";");
|
|
1906
|
+
for (let i = 0; i < rules.length; i++) {
|
|
1907
|
+
const rule = rules[i].trim();
|
|
1908
|
+
if (rule === "") continue;
|
|
1909
|
+
const [propName, ...valList] = rule.split(":");
|
|
1910
|
+
const val = valList.join(":");
|
|
1911
|
+
if (isUndefined(val)) continue;
|
|
1912
|
+
this.setProperty(propName.trim(), val.trim());
|
|
1913
|
+
}
|
|
1914
|
+
this._pending = false;
|
|
1915
|
+
enqueueUpdate(this);
|
|
1916
|
+
}
|
|
1917
|
+
setProperty(propertyName, value) {
|
|
1918
|
+
if (propertyName[0] === "-") this.setCssVariables(propertyName);
|
|
1919
|
+
else propertyName = toCamelCase(propertyName);
|
|
1920
|
+
if (isNull(value) || isUndefined(value)) this.removeProperty(propertyName);
|
|
1921
|
+
else this[propertyName] = value;
|
|
1922
|
+
}
|
|
1923
|
+
removeProperty(propertyName) {
|
|
1924
|
+
propertyName = toCamelCase(propertyName);
|
|
1925
|
+
if (!this._usedStyleProp.has(propertyName)) return "";
|
|
1926
|
+
const value = this[propertyName];
|
|
1927
|
+
this[propertyName] = void 0;
|
|
1928
|
+
return value;
|
|
1929
|
+
}
|
|
1930
|
+
getPropertyValue(propertyName) {
|
|
1931
|
+
propertyName = toCamelCase(propertyName);
|
|
1932
|
+
const value = this[propertyName];
|
|
1933
|
+
if (!value) return "";
|
|
1934
|
+
return value;
|
|
1935
|
+
}
|
|
1936
|
+
};
|
|
1937
|
+
initStyle(Style, styleProperties);
|
|
1938
|
+
hooks$1.tap("injectNewStyleProperties", (newStyleProperties) => {
|
|
1939
|
+
if (isArray(newStyleProperties)) initStyle(Style, newStyleProperties);
|
|
1940
|
+
else {
|
|
1941
|
+
if (typeof newStyleProperties !== "string") return;
|
|
1942
|
+
initStyle(Style, [newStyleProperties]);
|
|
1943
|
+
}
|
|
1944
|
+
});
|
|
1945
|
+
//#endregion
|
|
1946
|
+
//#region src/dom/tree.ts
|
|
1947
|
+
function returnTrue() {
|
|
1948
|
+
return true;
|
|
1949
|
+
}
|
|
1950
|
+
function treeToArray(root, predict) {
|
|
1951
|
+
const array = [];
|
|
1952
|
+
const filter = predict ?? returnTrue;
|
|
1953
|
+
let object = root;
|
|
1954
|
+
while (object) {
|
|
1955
|
+
if (object.nodeType === 1 && filter(object)) array.push(object);
|
|
1956
|
+
object = following(object, root);
|
|
1957
|
+
}
|
|
1958
|
+
return array;
|
|
1959
|
+
}
|
|
1960
|
+
function following(el, root) {
|
|
1961
|
+
const firstChild = el.firstChild;
|
|
1962
|
+
const isElmentTypeValid = el.nodeType === 1 || el.nodeType === 9;
|
|
1963
|
+
if (firstChild && isElmentTypeValid) return firstChild;
|
|
1964
|
+
let current = el;
|
|
1965
|
+
do {
|
|
1966
|
+
if (current === root) return null;
|
|
1967
|
+
const nextSibling = current.nextSibling;
|
|
1968
|
+
if (nextSibling) return nextSibling;
|
|
1969
|
+
current = current.parentElement;
|
|
1970
|
+
} while (current);
|
|
1971
|
+
return null;
|
|
1972
|
+
}
|
|
1973
|
+
//#endregion
|
|
1974
|
+
//#region src/dom/element.ts
|
|
1975
|
+
var TaroElement = class TaroElement extends TaroNode {
|
|
1976
|
+
constructor() {
|
|
1977
|
+
super();
|
|
1978
|
+
this.props = {};
|
|
1979
|
+
this.dataset = EMPTY_OBJ;
|
|
1980
|
+
this.nodeType = 1;
|
|
1981
|
+
this.style = new Style(this);
|
|
1982
|
+
hooks$1.call("patchElement", this);
|
|
1983
|
+
}
|
|
1984
|
+
_stopPropagation(event) {
|
|
1985
|
+
let target = this;
|
|
1986
|
+
while (target = target.parentNode) {
|
|
1987
|
+
const listeners = target.__handlers[event.type];
|
|
1988
|
+
if (!isArray(listeners)) continue;
|
|
1989
|
+
for (let i = listeners.length; i--;) {
|
|
1990
|
+
const l = listeners[i];
|
|
1991
|
+
l._stop = true;
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
get id() {
|
|
1996
|
+
return this.getAttribute("id");
|
|
1997
|
+
}
|
|
1998
|
+
set id(val) {
|
|
1999
|
+
this.setAttribute("id", val);
|
|
2000
|
+
}
|
|
2001
|
+
get className() {
|
|
2002
|
+
return this.getAttribute("class") || "";
|
|
2003
|
+
}
|
|
2004
|
+
set className(val) {
|
|
2005
|
+
this.setAttribute(CLASS, val);
|
|
2006
|
+
}
|
|
2007
|
+
get cssText() {
|
|
2008
|
+
return this.getAttribute("style") || "";
|
|
2009
|
+
}
|
|
2010
|
+
get classList() {
|
|
2011
|
+
return new ClassList(this.className, this);
|
|
2012
|
+
}
|
|
2013
|
+
get children() {
|
|
2014
|
+
return this.childNodes.filter(isElement);
|
|
2015
|
+
}
|
|
2016
|
+
get attributes() {
|
|
2017
|
+
const props = this.props;
|
|
2018
|
+
const propKeys = Object.keys(props);
|
|
2019
|
+
const style = this.style.cssText;
|
|
2020
|
+
return propKeys.map((key) => ({
|
|
2021
|
+
name: key,
|
|
2022
|
+
value: props[key]
|
|
2023
|
+
})).concat(style ? {
|
|
2024
|
+
name: STYLE,
|
|
2025
|
+
value: style
|
|
2026
|
+
} : []);
|
|
2027
|
+
}
|
|
2028
|
+
get textContent() {
|
|
2029
|
+
let text = "";
|
|
2030
|
+
const childNodes = this.childNodes;
|
|
2031
|
+
for (let i = 0; i < childNodes.length; i++) text += childNodes[i].textContent;
|
|
2032
|
+
return text;
|
|
2033
|
+
}
|
|
2034
|
+
set textContent(text) {
|
|
2035
|
+
super.textContent = text;
|
|
2036
|
+
}
|
|
2037
|
+
hasAttribute(qualifiedName) {
|
|
2038
|
+
return !isUndefined(this.props[qualifiedName]);
|
|
2039
|
+
}
|
|
2040
|
+
hasAttributes() {
|
|
2041
|
+
return this.attributes.length > 0;
|
|
2042
|
+
}
|
|
2043
|
+
get focus() {
|
|
2044
|
+
return function() {
|
|
2045
|
+
this.setAttribute(FOCUS, true);
|
|
2046
|
+
};
|
|
2047
|
+
}
|
|
2048
|
+
set focus(value) {
|
|
2049
|
+
this.setAttribute(FOCUS, value);
|
|
2050
|
+
}
|
|
2051
|
+
blur() {
|
|
2052
|
+
this.setAttribute(FOCUS, false);
|
|
2053
|
+
}
|
|
2054
|
+
setAttribute(qualifiedName, value) {
|
|
2055
|
+
warn(isString(value) && value.length > 2046, `元素 ${this.nodeName} 的 ${qualifiedName} 属性值数据量过大,可能会影响渲染性能。考虑降低图片转为 base64 的阈值或在 CSS 中使用 base64。`);
|
|
2056
|
+
const isPureView = this.nodeName === "view" && !isHasExtractProp(this) && !this.isAnyEventBinded();
|
|
2057
|
+
if (qualifiedName !== "style") MutationObserver$1.record({
|
|
2058
|
+
target: this,
|
|
2059
|
+
type: "attributes",
|
|
2060
|
+
attributeName: qualifiedName,
|
|
2061
|
+
oldValue: this.getAttribute(qualifiedName)
|
|
2062
|
+
});
|
|
2063
|
+
switch (qualifiedName) {
|
|
2064
|
+
case STYLE:
|
|
2065
|
+
this.style.cssText = value;
|
|
2066
|
+
break;
|
|
2067
|
+
case "id":
|
|
2068
|
+
if (this.uid !== this.sid) eventSource.delete(this.uid);
|
|
2069
|
+
value = String(value);
|
|
2070
|
+
this.props[qualifiedName] = this.uid = value;
|
|
2071
|
+
eventSource.set(value, this);
|
|
2072
|
+
break;
|
|
2073
|
+
default:
|
|
2074
|
+
this.props[qualifiedName] = value;
|
|
2075
|
+
if (qualifiedName.startsWith("data-")) {
|
|
2076
|
+
if (this.dataset === EMPTY_OBJ) this.dataset = Object.create(null);
|
|
2077
|
+
this.dataset[toCamelCase(qualifiedName.replace(/^data-/, ""))] = value;
|
|
2078
|
+
}
|
|
2079
|
+
break;
|
|
2080
|
+
}
|
|
2081
|
+
if (!this._root) return;
|
|
2082
|
+
const componentsAlias = getComponentsAlias();
|
|
2083
|
+
const _alias = componentsAlias[this.nodeName];
|
|
2084
|
+
const viewAlias = componentsAlias[VIEW]._num;
|
|
2085
|
+
const clickViewAlias = componentsAlias[CLICK_VIEW]._num;
|
|
2086
|
+
const staticViewAlias = componentsAlias[STATIC_VIEW]._num;
|
|
2087
|
+
const catchViewAlias = componentsAlias[CATCH_VIEW]._num;
|
|
2088
|
+
const _path = this._path;
|
|
2089
|
+
qualifiedName = shortcutAttr(qualifiedName);
|
|
2090
|
+
const qualifiedNameInCamelCase = toCamelCase(qualifiedName);
|
|
2091
|
+
const payload = {
|
|
2092
|
+
path: `${_path}.${qualifiedNameInCamelCase}`,
|
|
2093
|
+
value: isFunction(value) ? () => value : value
|
|
2094
|
+
};
|
|
2095
|
+
hooks$1.call("modifySetAttrPayload", this, qualifiedName, payload, componentsAlias);
|
|
2096
|
+
if (_alias) payload.path = `${_path}.${toCamelCase(_alias[qualifiedNameInCamelCase] || qualifiedName)}`;
|
|
2097
|
+
this.enqueueUpdate(payload);
|
|
2098
|
+
if (this.nodeName === "view") {
|
|
2099
|
+
if (qualifiedNameInCamelCase === "catchMove") this.enqueueUpdate({
|
|
2100
|
+
path: `${_path}.${Shortcuts.NodeName}`,
|
|
2101
|
+
value: value ? catchViewAlias : this.isOnlyClickBinded() && !isHasExtractProp(this) ? clickViewAlias : this.isAnyEventBinded() ? viewAlias : staticViewAlias
|
|
2102
|
+
});
|
|
2103
|
+
else if (isPureView && isHasExtractProp(this)) this.enqueueUpdate({
|
|
2104
|
+
path: `${_path}.${Shortcuts.NodeName}`,
|
|
2105
|
+
value: staticViewAlias
|
|
2106
|
+
});
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
removeAttribute(qualifiedName) {
|
|
2110
|
+
const isStaticView = this.nodeName === "view" && isHasExtractProp(this) && !this.isAnyEventBinded();
|
|
2111
|
+
MutationObserver$1.record({
|
|
2112
|
+
target: this,
|
|
2113
|
+
type: "attributes",
|
|
2114
|
+
attributeName: qualifiedName,
|
|
2115
|
+
oldValue: this.getAttribute(qualifiedName)
|
|
2116
|
+
});
|
|
2117
|
+
if (qualifiedName === "style") this.style.cssText = "";
|
|
2118
|
+
else {
|
|
2119
|
+
if (hooks$1.call("onRemoveAttribute", this, qualifiedName)) return;
|
|
2120
|
+
if (!this.props.hasOwnProperty(qualifiedName)) return;
|
|
2121
|
+
delete this.props[qualifiedName];
|
|
2122
|
+
}
|
|
2123
|
+
if (!this._root) return;
|
|
2124
|
+
const componentsAlias = getComponentsAlias();
|
|
2125
|
+
const _alias = componentsAlias[this.nodeName];
|
|
2126
|
+
const viewAlias = componentsAlias[VIEW]._num;
|
|
2127
|
+
const staticViewAlias = componentsAlias[STATIC_VIEW]._num;
|
|
2128
|
+
const pureViewAlias = componentsAlias[PURE_VIEW]._num;
|
|
2129
|
+
const clickViewAlias = componentsAlias[CLICK_VIEW]._num;
|
|
2130
|
+
const _path = this._path;
|
|
2131
|
+
qualifiedName = shortcutAttr(qualifiedName);
|
|
2132
|
+
const qualifiedNameInCamelCase = toCamelCase(qualifiedName);
|
|
2133
|
+
const payload = {
|
|
2134
|
+
path: `${_path}.${qualifiedNameInCamelCase}`,
|
|
2135
|
+
value: ""
|
|
2136
|
+
};
|
|
2137
|
+
hooks$1.call("modifyRmAttrPayload", this, qualifiedName, payload, componentsAlias);
|
|
2138
|
+
if (_alias) payload.path = `${_path}.${toCamelCase(_alias[qualifiedNameInCamelCase] || qualifiedName)}`;
|
|
2139
|
+
this.enqueueUpdate(payload);
|
|
2140
|
+
if (this.nodeName === "view") {
|
|
2141
|
+
if (qualifiedNameInCamelCase === "catchMove") this.enqueueUpdate({
|
|
2142
|
+
path: `${_path}.${Shortcuts.NodeName}`,
|
|
2143
|
+
value: this.isOnlyClickBinded() && !isHasExtractProp(this) ? clickViewAlias : this.isAnyEventBinded() ? viewAlias : isHasExtractProp(this) ? staticViewAlias : pureViewAlias
|
|
2144
|
+
});
|
|
2145
|
+
else if (isStaticView && !isHasExtractProp(this)) this.enqueueUpdate({
|
|
2146
|
+
path: `${_path}.${Shortcuts.NodeName}`,
|
|
2147
|
+
value: pureViewAlias
|
|
2148
|
+
});
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
getAttribute(qualifiedName) {
|
|
2152
|
+
return (qualifiedName === "style" ? this.style.cssText : this.props[qualifiedName]) ?? "";
|
|
2153
|
+
}
|
|
2154
|
+
getElementsByTagName(tagName) {
|
|
2155
|
+
return treeToArray(this, (el) => {
|
|
2156
|
+
return el.nodeName === tagName || tagName === "*" && this !== el;
|
|
2157
|
+
});
|
|
2158
|
+
}
|
|
2159
|
+
getElementsByClassName(className) {
|
|
2160
|
+
const classNames = className.trim().split(/\s+/);
|
|
2161
|
+
return treeToArray(this, (el) => {
|
|
2162
|
+
const classList = el.classList;
|
|
2163
|
+
return classNames.every((c) => classList.contains(c));
|
|
2164
|
+
});
|
|
2165
|
+
}
|
|
2166
|
+
dispatchEvent(event) {
|
|
2167
|
+
const cancelable = event.cancelable;
|
|
2168
|
+
const listeners = this.__handlers[event.type];
|
|
2169
|
+
if (!isArray(listeners)) return false;
|
|
2170
|
+
for (let i = listeners.length; i--;) {
|
|
2171
|
+
const listener = listeners[i];
|
|
2172
|
+
let result;
|
|
2173
|
+
if (listener._stop) listener._stop = false;
|
|
2174
|
+
else {
|
|
2175
|
+
hooks$1.call("modifyDispatchEvent", event, this);
|
|
2176
|
+
result = listener.call(this, event);
|
|
2177
|
+
}
|
|
2178
|
+
if ((result === false || event._end) && cancelable) event.defaultPrevented = true;
|
|
2179
|
+
if (!isUndefined(result) && event.mpEvent) {
|
|
2180
|
+
if (hooks$1.call("modifyTaroEventReturn", this, event, result)) event.mpEvent[EVENT_CALLBACK_RESULT] = result;
|
|
2181
|
+
}
|
|
2182
|
+
if (event._end && event._stop) break;
|
|
2183
|
+
}
|
|
2184
|
+
if (event._stop) this._stopPropagation(event);
|
|
2185
|
+
return listeners != null;
|
|
2186
|
+
}
|
|
2187
|
+
addEventListener(type, handler, options) {
|
|
2188
|
+
const name = this.nodeName;
|
|
2189
|
+
const SPECIAL_NODES = hooks$1.call("getSpecialNodes");
|
|
2190
|
+
let sideEffect = true;
|
|
2191
|
+
if (isObject(options) && options.sideEffect === false) {
|
|
2192
|
+
sideEffect = false;
|
|
2193
|
+
delete options.sideEffect;
|
|
2194
|
+
}
|
|
2195
|
+
hooks$1.call("modifyAddEventListener", this, sideEffect, getComponentsAlias);
|
|
2196
|
+
if (sideEffect !== false && !this.isAnyEventBinded() && SPECIAL_NODES.indexOf(name) > -1) {
|
|
2197
|
+
const alias = getComponentsAlias()[name]._num;
|
|
2198
|
+
this.enqueueUpdate({
|
|
2199
|
+
path: `${this._path}.${Shortcuts.NodeName}`,
|
|
2200
|
+
value: alias
|
|
2201
|
+
});
|
|
2202
|
+
}
|
|
2203
|
+
super.addEventListener(type, handler, options);
|
|
2204
|
+
}
|
|
2205
|
+
removeEventListener(type, handler, sideEffect = true) {
|
|
2206
|
+
super.removeEventListener(type, handler);
|
|
2207
|
+
const name = this.nodeName;
|
|
2208
|
+
const SPECIAL_NODES = hooks$1.call("getSpecialNodes");
|
|
2209
|
+
hooks$1.call("modifyRemoveEventListener", this, sideEffect, getComponentsAlias);
|
|
2210
|
+
if (sideEffect !== false && !this.isAnyEventBinded() && SPECIAL_NODES.indexOf(name) > -1) {
|
|
2211
|
+
const valueAlias = getComponentsAlias()[isHasExtractProp(this) ? `static-${name}` : `pure-${name}`]._num;
|
|
2212
|
+
this.enqueueUpdate({
|
|
2213
|
+
path: `${this._path}.${Shortcuts.NodeName}`,
|
|
2214
|
+
value: valueAlias
|
|
2215
|
+
});
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2218
|
+
static extend(methodName, options) {
|
|
2219
|
+
extend(TaroElement, methodName, options);
|
|
2220
|
+
}
|
|
2221
|
+
};
|
|
2222
|
+
//#endregion
|
|
2223
|
+
//#region src/options.ts
|
|
2224
|
+
const options = {
|
|
2225
|
+
prerender: true,
|
|
2226
|
+
debug: false
|
|
2227
|
+
};
|
|
2228
|
+
//#endregion
|
|
2229
|
+
//#region src/dom/event.ts
|
|
2230
|
+
var TaroEvent = class {
|
|
2231
|
+
constructor(type, opts, event) {
|
|
2232
|
+
this._stop = false;
|
|
2233
|
+
this._end = false;
|
|
2234
|
+
this.defaultPrevented = false;
|
|
2235
|
+
this.button = 0;
|
|
2236
|
+
this.timeStamp = Date.now();
|
|
2237
|
+
this.type = type.toLowerCase();
|
|
2238
|
+
this.mpEvent = event;
|
|
2239
|
+
this.bubbles = Boolean(opts && opts.bubbles);
|
|
2240
|
+
this.cancelable = Boolean(opts && opts.cancelable);
|
|
2241
|
+
}
|
|
2242
|
+
stopPropagation() {
|
|
2243
|
+
this._stop = true;
|
|
2244
|
+
}
|
|
2245
|
+
stopImmediatePropagation() {
|
|
2246
|
+
this._end = this._stop = true;
|
|
2247
|
+
}
|
|
2248
|
+
preventDefault() {
|
|
2249
|
+
this.defaultPrevented = true;
|
|
2250
|
+
}
|
|
2251
|
+
get target() {
|
|
2252
|
+
const cacheTarget = this.cacheTarget;
|
|
2253
|
+
if (!cacheTarget) {
|
|
2254
|
+
const target = Object.create(this.mpEvent?.target || null);
|
|
2255
|
+
const currentEle = env.document.getElementById(target.dataset?.sid || target.id || null);
|
|
2256
|
+
const element = env.document.getElementById(target.targetDataset?.sid || target.dataset?.sid || target.id || null);
|
|
2257
|
+
target.dataset = {
|
|
2258
|
+
...currentEle !== null ? currentEle.dataset : EMPTY_OBJ,
|
|
2259
|
+
...element !== null ? element.dataset : EMPTY_OBJ
|
|
2260
|
+
};
|
|
2261
|
+
for (const key in this.mpEvent?.detail) target[key] = this.mpEvent.detail[key];
|
|
2262
|
+
this.cacheTarget = target;
|
|
2263
|
+
return target;
|
|
2264
|
+
} else return cacheTarget;
|
|
2265
|
+
}
|
|
2266
|
+
get currentTarget() {
|
|
2267
|
+
const cacheCurrentTarget = this.cacheCurrentTarget;
|
|
2268
|
+
if (!cacheCurrentTarget) {
|
|
2269
|
+
const doc = env.document;
|
|
2270
|
+
const currentTarget = Object.create(this.mpEvent?.currentTarget || null);
|
|
2271
|
+
const element = doc.getElementById(currentTarget.dataset?.sid || currentTarget.id || null);
|
|
2272
|
+
const targetElement = doc.getElementById(this.mpEvent?.target?.dataset?.sid || this.mpEvent?.target?.id || null);
|
|
2273
|
+
if (element === null || element && element === targetElement) {
|
|
2274
|
+
this.cacheCurrentTarget = this.target;
|
|
2275
|
+
return this.target;
|
|
2276
|
+
}
|
|
2277
|
+
currentTarget.dataset = element.dataset;
|
|
2278
|
+
for (const key in this.mpEvent?.detail) currentTarget[key] = this.mpEvent.detail[key];
|
|
2279
|
+
this.cacheCurrentTarget = currentTarget;
|
|
2280
|
+
return currentTarget;
|
|
2281
|
+
} else return cacheCurrentTarget;
|
|
2282
|
+
}
|
|
2283
|
+
};
|
|
2284
|
+
function createEvent(event, node) {
|
|
2285
|
+
if (typeof event === "string") return new TaroEvent(event, {
|
|
2286
|
+
bubbles: true,
|
|
2287
|
+
cancelable: true
|
|
2288
|
+
});
|
|
2289
|
+
const domEv = new TaroEvent(event.type, {
|
|
2290
|
+
bubbles: true,
|
|
2291
|
+
cancelable: true
|
|
2292
|
+
}, event);
|
|
2293
|
+
for (const key in event) if (key === "currentTarget" || key === "target" || key === "type" || key === "timeStamp") continue;
|
|
2294
|
+
else domEv[key] = event[key];
|
|
2295
|
+
if (domEv.type === "confirm" && node?.nodeName === "input") domEv[KEY_CODE] = 13;
|
|
2296
|
+
return domEv;
|
|
2297
|
+
}
|
|
2298
|
+
const eventsBatch = {};
|
|
2299
|
+
function getEventCBResult(event) {
|
|
2300
|
+
const result = event[EVENT_CALLBACK_RESULT];
|
|
2301
|
+
if (!isUndefined(result)) delete event[EVENT_CALLBACK_RESULT];
|
|
2302
|
+
return result;
|
|
2303
|
+
}
|
|
2304
|
+
function eventHandler(event) {
|
|
2305
|
+
event.type === void 0 && Object.defineProperty(event, "type", { value: event._type });
|
|
2306
|
+
event.detail === void 0 && Object.defineProperty(event, "detail", { value: event._detail || { ...event } });
|
|
2307
|
+
event.currentTarget = event.currentTarget || event.target || { ...event };
|
|
2308
|
+
hooks$1.call("modifyMpEventImpl", event);
|
|
2309
|
+
const currentTarget = event.currentTarget;
|
|
2310
|
+
const id = currentTarget.dataset?.sid || currentTarget.id || event.detail?.id || "";
|
|
2311
|
+
const node = env.document.getElementById(id);
|
|
2312
|
+
if (node) {
|
|
2313
|
+
const dispatch = () => {
|
|
2314
|
+
const e = createEvent(event, node);
|
|
2315
|
+
hooks$1.call("modifyTaroEvent", e, node);
|
|
2316
|
+
hooks$1.call("dispatchTaroEvent", e, node);
|
|
2317
|
+
hooks$1.call("dispatchTaroEventFinish", e, node);
|
|
2318
|
+
};
|
|
2319
|
+
if (hooks$1.isExist("batchedEventUpdates")) {
|
|
2320
|
+
const type = event.type;
|
|
2321
|
+
if (!hooks$1.call("isBubbleEvents", type) || !isParentBound(node, type) || type === "touchmove" && !!node.props.catchMove) {
|
|
2322
|
+
hooks$1.call("batchedEventUpdates", () => {
|
|
2323
|
+
if (eventsBatch[type]) {
|
|
2324
|
+
eventsBatch[type].forEach((fn) => fn());
|
|
2325
|
+
delete eventsBatch[type];
|
|
2326
|
+
}
|
|
2327
|
+
dispatch();
|
|
2328
|
+
});
|
|
2329
|
+
return getEventCBResult(event);
|
|
2330
|
+
} else (eventsBatch[type] ||= []).push(dispatch);
|
|
2331
|
+
} else {
|
|
2332
|
+
dispatch();
|
|
2333
|
+
return getEventCBResult(event);
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
function eventHandlerTTDom(ele, listener, event) {
|
|
2338
|
+
Object.assign(event, {
|
|
2339
|
+
mpEvent: event,
|
|
2340
|
+
bubbles: true,
|
|
2341
|
+
cancelable: true
|
|
2342
|
+
});
|
|
2343
|
+
listener(event, ele);
|
|
2344
|
+
}
|
|
2345
|
+
//#endregion
|
|
2346
|
+
//#region src/dom/form.ts
|
|
2347
|
+
var FormElement = class extends TaroElement {
|
|
2348
|
+
get type() {
|
|
2349
|
+
return this.props["type"] ?? "";
|
|
2350
|
+
}
|
|
2351
|
+
set type(val) {
|
|
2352
|
+
this.setAttribute(TYPE, val);
|
|
2353
|
+
}
|
|
2354
|
+
get value() {
|
|
2355
|
+
const val = this.props[VALUE];
|
|
2356
|
+
return val == null ? "" : val;
|
|
2357
|
+
}
|
|
2358
|
+
set value(val) {
|
|
2359
|
+
this.setAttribute(VALUE, val);
|
|
2360
|
+
}
|
|
2361
|
+
dispatchEvent(event) {
|
|
2362
|
+
if (event.mpEvent) {
|
|
2363
|
+
const val = event.mpEvent.detail.value;
|
|
2364
|
+
if (event.type === "change") this.props.value = val;
|
|
2365
|
+
else if (event.type === "input") this.value = val;
|
|
2366
|
+
}
|
|
2367
|
+
return super.dispatchEvent(event);
|
|
2368
|
+
}
|
|
2369
|
+
};
|
|
2370
|
+
//#endregion
|
|
2371
|
+
//#region src/perf.ts
|
|
2372
|
+
var Performance = class {
|
|
2373
|
+
constructor() {
|
|
2374
|
+
this.recorder = /* @__PURE__ */ new Map();
|
|
2375
|
+
}
|
|
2376
|
+
start(id) {
|
|
2377
|
+
if (!options.debug) return;
|
|
2378
|
+
this.recorder.set(id, Date.now());
|
|
2379
|
+
}
|
|
2380
|
+
stop(id, now = Date.now()) {
|
|
2381
|
+
if (!options.debug) return;
|
|
2382
|
+
const prev = this.recorder.get(id);
|
|
2383
|
+
if (!(prev >= 0)) return;
|
|
2384
|
+
this.recorder.delete(id);
|
|
2385
|
+
const time = now - prev;
|
|
2386
|
+
console.log(`${id} 时长: ${time}ms 开始时间:${this.#parseTime(prev)} 结束时间:${this.#parseTime(now)}`);
|
|
2387
|
+
}
|
|
2388
|
+
delayStop(id, delay = 500) {
|
|
2389
|
+
if (!options.debug) return;
|
|
2390
|
+
return debounce((now = Date.now(), cb) => {
|
|
2391
|
+
this.stop(id, now);
|
|
2392
|
+
cb?.();
|
|
2393
|
+
}, delay);
|
|
2394
|
+
}
|
|
2395
|
+
#parseTime(time) {
|
|
2396
|
+
const d = new Date(time);
|
|
2397
|
+
return `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}.${`${d.getMilliseconds()}`.padStart(3, "0")}`;
|
|
2398
|
+
}
|
|
2399
|
+
};
|
|
2400
|
+
const perf = new Performance();
|
|
2401
|
+
//#endregion
|
|
2402
|
+
//#region src/dom/root.ts
|
|
2403
|
+
function findCustomWrapper(root, dataPathArr) {
|
|
2404
|
+
const list = dataPathArr.slice(1);
|
|
2405
|
+
let currentData = root;
|
|
2406
|
+
let customWrapper;
|
|
2407
|
+
let splitedPath = "";
|
|
2408
|
+
list.some((item, i) => {
|
|
2409
|
+
const key = item.replace(/^\[(.+)\]$/, "$1").replace(/\bcn\b/g, "childNodes");
|
|
2410
|
+
currentData = currentData[key];
|
|
2411
|
+
if (isArray(currentData)) currentData = currentData.filter((el) => !isComment(el));
|
|
2412
|
+
if (isUndefined(currentData)) return true;
|
|
2413
|
+
if (currentData.nodeName === "custom-wrapper") {
|
|
2414
|
+
const res = customWrapperCache.get(currentData.sid);
|
|
2415
|
+
if (res) {
|
|
2416
|
+
customWrapper = res;
|
|
2417
|
+
splitedPath = dataPathArr.slice(i + 2).join(".");
|
|
2418
|
+
}
|
|
2419
|
+
}
|
|
2420
|
+
});
|
|
2421
|
+
if (customWrapper) return {
|
|
2422
|
+
customWrapper,
|
|
2423
|
+
splitedPath
|
|
2424
|
+
};
|
|
2425
|
+
}
|
|
2426
|
+
var TaroRootElement = class extends TaroElement {
|
|
2427
|
+
constructor() {
|
|
2428
|
+
super();
|
|
2429
|
+
this.updatePayloads = [];
|
|
2430
|
+
this.updateCallbacks = [];
|
|
2431
|
+
this.pendingUpdate = false;
|
|
2432
|
+
this.ctx = null;
|
|
2433
|
+
this.nodeName = ROOT_STR;
|
|
2434
|
+
this.tagName = ROOT_STR.toUpperCase();
|
|
2435
|
+
}
|
|
2436
|
+
get _path() {
|
|
2437
|
+
return ROOT_STR;
|
|
2438
|
+
}
|
|
2439
|
+
get _root() {
|
|
2440
|
+
return this;
|
|
2441
|
+
}
|
|
2442
|
+
scheduleTask(fn) {
|
|
2443
|
+
setTimeout(fn);
|
|
2444
|
+
}
|
|
2445
|
+
enqueueUpdate(payload) {
|
|
2446
|
+
this.updatePayloads.push(payload);
|
|
2447
|
+
if (!this.pendingUpdate && this.ctx) this.performUpdate();
|
|
2448
|
+
}
|
|
2449
|
+
performUpdate(initRender = false, prerender) {
|
|
2450
|
+
this.pendingUpdate = true;
|
|
2451
|
+
const ctx = hooks$1.call("proxyToRaw", this.ctx);
|
|
2452
|
+
this.scheduleTask(() => {
|
|
2453
|
+
const setDataMark = `${SET_DATA} 开始时间戳 ${Date.now()}`;
|
|
2454
|
+
perf.start(setDataMark);
|
|
2455
|
+
const data = Object.create(null);
|
|
2456
|
+
const resetPaths = new Set(initRender ? ["root.cn.[0]", "root.cn[0]"] : []);
|
|
2457
|
+
while (this.updatePayloads.length > 0) {
|
|
2458
|
+
const { path, value } = this.updatePayloads.shift();
|
|
2459
|
+
if (path.endsWith(Shortcuts.Childnodes)) resetPaths.add(path);
|
|
2460
|
+
data[path] = value;
|
|
2461
|
+
}
|
|
2462
|
+
for (const path in data) {
|
|
2463
|
+
resetPaths.forEach((p) => {
|
|
2464
|
+
if (path.includes(p) && path !== p) delete data[path];
|
|
2465
|
+
});
|
|
2466
|
+
const value = data[path];
|
|
2467
|
+
if (isFunction(value)) data[path] = value();
|
|
2468
|
+
}
|
|
2469
|
+
if (isFunction(prerender)) return prerender(data);
|
|
2470
|
+
this.pendingUpdate = false;
|
|
2471
|
+
let normalUpdate = {};
|
|
2472
|
+
const customWrapperMap = /* @__PURE__ */ new Map();
|
|
2473
|
+
if (initRender) normalUpdate = data;
|
|
2474
|
+
else for (const p in data) {
|
|
2475
|
+
const dataPathArr = p.split(".");
|
|
2476
|
+
const found = findCustomWrapper(this, dataPathArr);
|
|
2477
|
+
if (found) {
|
|
2478
|
+
const { customWrapper, splitedPath } = found;
|
|
2479
|
+
customWrapperMap.set(customWrapper, {
|
|
2480
|
+
...customWrapperMap.get(customWrapper) || {},
|
|
2481
|
+
[`i.${splitedPath}`]: data[p]
|
|
2482
|
+
});
|
|
2483
|
+
} else normalUpdate[p] = data[p];
|
|
2484
|
+
}
|
|
2485
|
+
const customWrapperCount = customWrapperMap.size;
|
|
2486
|
+
const isNeedNormalUpdate = Object.keys(normalUpdate).length > 0;
|
|
2487
|
+
const updateArrLen = customWrapperCount + (isNeedNormalUpdate ? 1 : 0);
|
|
2488
|
+
let executeTime = 0;
|
|
2489
|
+
const cb = () => {
|
|
2490
|
+
if (++executeTime === updateArrLen) {
|
|
2491
|
+
perf.stop(setDataMark);
|
|
2492
|
+
this.flushUpdateCallback();
|
|
2493
|
+
initRender && perf.stop("页面初始化");
|
|
2494
|
+
}
|
|
2495
|
+
};
|
|
2496
|
+
if (customWrapperCount) customWrapperMap.forEach((data, ctx) => {
|
|
2497
|
+
if (options.debug) console.log("custom wrapper setData: ", data);
|
|
2498
|
+
ctx.setData(data, cb);
|
|
2499
|
+
});
|
|
2500
|
+
if (isNeedNormalUpdate) {
|
|
2501
|
+
if (options.debug) console.log("page setData:", normalUpdate);
|
|
2502
|
+
ctx.setData(normalUpdate, cb);
|
|
2503
|
+
}
|
|
2504
|
+
});
|
|
2505
|
+
}
|
|
2506
|
+
enqueueUpdateCallback(cb, ctx) {
|
|
2507
|
+
this.updateCallbacks.push(() => {
|
|
2508
|
+
ctx ? cb.call(ctx) : cb();
|
|
2509
|
+
});
|
|
2510
|
+
}
|
|
2511
|
+
flushUpdateCallback() {
|
|
2512
|
+
const updateCallbacks = this.updateCallbacks;
|
|
2513
|
+
if (!updateCallbacks.length) return;
|
|
2514
|
+
const copies = updateCallbacks.slice(0);
|
|
2515
|
+
this.updateCallbacks.length = 0;
|
|
2516
|
+
for (let i = 0; i < copies.length; i++) copies[i]();
|
|
2517
|
+
}
|
|
2518
|
+
};
|
|
2519
|
+
//#endregion
|
|
2520
|
+
//#region src/dom/text.ts
|
|
2521
|
+
var TaroText = class extends TaroNode {
|
|
2522
|
+
constructor(value) {
|
|
2523
|
+
super();
|
|
2524
|
+
this.nodeType = 3;
|
|
2525
|
+
this.nodeName = "#text";
|
|
2526
|
+
this._value = value;
|
|
2527
|
+
}
|
|
2528
|
+
set textContent(text) {
|
|
2529
|
+
MutationObserver$1.record({
|
|
2530
|
+
target: this,
|
|
2531
|
+
type: "characterData",
|
|
2532
|
+
oldValue: this._value
|
|
2533
|
+
});
|
|
2534
|
+
this._value = text;
|
|
2535
|
+
this.enqueueUpdate({
|
|
2536
|
+
path: `${this._path}.${Shortcuts.Text}`,
|
|
2537
|
+
value: text
|
|
2538
|
+
});
|
|
2539
|
+
}
|
|
2540
|
+
get textContent() {
|
|
2541
|
+
return this._value;
|
|
2542
|
+
}
|
|
2543
|
+
set nodeValue(text) {
|
|
2544
|
+
this.textContent = text;
|
|
2545
|
+
}
|
|
2546
|
+
get nodeValue() {
|
|
2547
|
+
return this._value;
|
|
2548
|
+
}
|
|
2549
|
+
set data(text) {
|
|
2550
|
+
this.textContent = text;
|
|
2551
|
+
}
|
|
2552
|
+
get data() {
|
|
2553
|
+
return this._value;
|
|
2554
|
+
}
|
|
2555
|
+
};
|
|
2556
|
+
//#endregion
|
|
2557
|
+
//#region src/dom/anchor-element.ts
|
|
2558
|
+
var AnchorElement = class extends TaroElement {
|
|
2559
|
+
get href() {
|
|
2560
|
+
return this.props["href"] ?? "";
|
|
2561
|
+
}
|
|
2562
|
+
set href(val) {
|
|
2563
|
+
this.setAttribute("href", val);
|
|
2564
|
+
}
|
|
2565
|
+
get protocol() {
|
|
2566
|
+
return this.props["protocol"] ?? "";
|
|
2567
|
+
}
|
|
2568
|
+
get host() {
|
|
2569
|
+
return this.props["host"] ?? "";
|
|
2570
|
+
}
|
|
2571
|
+
get search() {
|
|
2572
|
+
return this.props["search"] ?? "";
|
|
2573
|
+
}
|
|
2574
|
+
get hash() {
|
|
2575
|
+
return this.props["hash"] ?? "";
|
|
2576
|
+
}
|
|
2577
|
+
get hostname() {
|
|
2578
|
+
return this.props["hostname"] ?? "";
|
|
2579
|
+
}
|
|
2580
|
+
get port() {
|
|
2581
|
+
return this.props["port"] ?? "";
|
|
2582
|
+
}
|
|
2583
|
+
get pathname() {
|
|
2584
|
+
return this.props["pathname"] ?? "";
|
|
2585
|
+
}
|
|
2586
|
+
setAttribute(qualifiedName, value) {
|
|
2587
|
+
if (qualifiedName === "href") {
|
|
2588
|
+
const willSetAttr = parseUrl(value);
|
|
2589
|
+
for (const k in willSetAttr) super.setAttribute(k, willSetAttr[k]);
|
|
2590
|
+
} else super.setAttribute(qualifiedName, value);
|
|
2591
|
+
}
|
|
2592
|
+
};
|
|
2593
|
+
//#endregion
|
|
2594
|
+
//#region src/dom/transfer.ts
|
|
2595
|
+
var TransferElement = class extends TaroElement {
|
|
2596
|
+
constructor(dataName) {
|
|
2597
|
+
super();
|
|
2598
|
+
this.dataName = dataName;
|
|
2599
|
+
this.isTransferElement = true;
|
|
2600
|
+
}
|
|
2601
|
+
get _path() {
|
|
2602
|
+
return this.dataName;
|
|
2603
|
+
}
|
|
2604
|
+
};
|
|
2605
|
+
//#endregion
|
|
2606
|
+
//#region src/dom/document.ts
|
|
2607
|
+
var TaroDocument = class extends TaroElement {
|
|
2608
|
+
constructor() {
|
|
2609
|
+
super();
|
|
2610
|
+
this.createEvent = createEvent;
|
|
2611
|
+
this.nodeType = 9;
|
|
2612
|
+
this.nodeName = DOCUMENT_ELEMENT_NAME;
|
|
2613
|
+
}
|
|
2614
|
+
createElement(type) {
|
|
2615
|
+
const nodeName = type.toLowerCase();
|
|
2616
|
+
let element;
|
|
2617
|
+
switch (true) {
|
|
2618
|
+
case nodeName === ROOT_STR:
|
|
2619
|
+
element = new TaroRootElement();
|
|
2620
|
+
return element;
|
|
2621
|
+
case controlledComponent.has(nodeName):
|
|
2622
|
+
element = new FormElement();
|
|
2623
|
+
break;
|
|
2624
|
+
case nodeName === "a":
|
|
2625
|
+
element = new AnchorElement();
|
|
2626
|
+
break;
|
|
2627
|
+
case nodeName === "page-meta":
|
|
2628
|
+
case nodeName === "navigation-bar":
|
|
2629
|
+
element = new TransferElement(toCamelCase(nodeName));
|
|
2630
|
+
break;
|
|
2631
|
+
default:
|
|
2632
|
+
element = new TaroElement();
|
|
2633
|
+
break;
|
|
2634
|
+
}
|
|
2635
|
+
element.nodeName = nodeName;
|
|
2636
|
+
element.tagName = type.toUpperCase();
|
|
2637
|
+
return element;
|
|
2638
|
+
}
|
|
2639
|
+
createElementNS(_svgNS, type) {
|
|
2640
|
+
return this.createElement(type);
|
|
2641
|
+
}
|
|
2642
|
+
createTextNode(text) {
|
|
2643
|
+
return new TaroText(text);
|
|
2644
|
+
}
|
|
2645
|
+
getElementById(id) {
|
|
2646
|
+
const el = eventSource.get(id);
|
|
2647
|
+
return isUndefined(el) ? null : el;
|
|
2648
|
+
}
|
|
2649
|
+
querySelector(query) {
|
|
2650
|
+
if (/^#/.test(query)) return this.getElementById(query.slice(1));
|
|
2651
|
+
return null;
|
|
2652
|
+
}
|
|
2653
|
+
querySelectorAll() {
|
|
2654
|
+
return [];
|
|
2655
|
+
}
|
|
2656
|
+
createComment() {
|
|
2657
|
+
const textnode = new TaroText("");
|
|
2658
|
+
textnode.nodeName = COMMENT;
|
|
2659
|
+
return textnode;
|
|
2660
|
+
}
|
|
2661
|
+
get defaultView() {
|
|
2662
|
+
return env.window;
|
|
2663
|
+
}
|
|
2664
|
+
};
|
|
2665
|
+
//#endregion
|
|
2666
|
+
//#region src/bom/document.ts
|
|
2667
|
+
function createDocument() {
|
|
2668
|
+
/**
|
|
2669
|
+
* <document>
|
|
2670
|
+
* <html>
|
|
2671
|
+
* <head></head>
|
|
2672
|
+
* <body>
|
|
2673
|
+
* <container>
|
|
2674
|
+
* <app id="app" />
|
|
2675
|
+
* </container>
|
|
2676
|
+
* </body>
|
|
2677
|
+
* </html>
|
|
2678
|
+
* </document>
|
|
2679
|
+
*/
|
|
2680
|
+
const doc = new TaroDocument();
|
|
2681
|
+
const documentCreateElement = doc.createElement.bind(doc);
|
|
2682
|
+
const html = documentCreateElement(HTML);
|
|
2683
|
+
const head = documentCreateElement(HEAD);
|
|
2684
|
+
const body = documentCreateElement(BODY);
|
|
2685
|
+
const app = documentCreateElement("app");
|
|
2686
|
+
app.id = "app";
|
|
2687
|
+
const container = documentCreateElement(CONTAINER);
|
|
2688
|
+
doc.appendChild(html);
|
|
2689
|
+
html.appendChild(head);
|
|
2690
|
+
html.appendChild(body);
|
|
2691
|
+
body.appendChild(container);
|
|
2692
|
+
container.appendChild(app);
|
|
2693
|
+
doc.documentElement = html;
|
|
2694
|
+
doc.head = head;
|
|
2695
|
+
doc.body = body;
|
|
2696
|
+
return doc;
|
|
2697
|
+
}
|
|
2698
|
+
function createTTDomDocument() {
|
|
2699
|
+
const document = tt?.appDocument;
|
|
2700
|
+
if (!document) throw new Error("tt.appDocument is not found");
|
|
2701
|
+
const html = document.createElement(HTML);
|
|
2702
|
+
const head = document.createElement(HEAD);
|
|
2703
|
+
const body = document.createElement(BODY);
|
|
2704
|
+
const app = document.createElement("app");
|
|
2705
|
+
app.id = "app";
|
|
2706
|
+
const container = document.createElement(CONTAINER);
|
|
2707
|
+
const emptyFunction = () => {};
|
|
2708
|
+
document.childNodes.push(html);
|
|
2709
|
+
html.childNodes.push(head, body);
|
|
2710
|
+
body.childNodes.push(container);
|
|
2711
|
+
container.childNodes.push(app);
|
|
2712
|
+
document.documentElement = html;
|
|
2713
|
+
document.head = head;
|
|
2714
|
+
document.body = body;
|
|
2715
|
+
document.appElement = app;
|
|
2716
|
+
let builtInComponents = tt?.getBuiltInComponents?.();
|
|
2717
|
+
if (Array.isArray(builtInComponents)) builtInComponents = new Set(builtInComponents);
|
|
2718
|
+
else if (!(builtInComponents instanceof Set)) builtInComponents = new Set([...DEFAULT_COMPONENTS, ...TT_SPECIFIC_COMPONENTS]);
|
|
2719
|
+
document.getElementById = function getElementById(id) {
|
|
2720
|
+
if (id === "app") return app;
|
|
2721
|
+
else return Object.getPrototypeOf(this).getElementById.call(this, id);
|
|
2722
|
+
};
|
|
2723
|
+
document.getLastPage = function getLastPage() {
|
|
2724
|
+
let last;
|
|
2725
|
+
for (const v of this._pageDocumentMap.values()) last = v;
|
|
2726
|
+
return last;
|
|
2727
|
+
};
|
|
2728
|
+
document.createElement = function(type, ...args) {
|
|
2729
|
+
if (type === "root") return this.getLastPage();
|
|
2730
|
+
else {
|
|
2731
|
+
const el = builtInComponents.has(type) ? Object.getPrototypeOf(this).createElement.call(this, type, ...args) : Object.getPrototypeOf(this).createNativeComponent.call(this, type, { __tt__inner__options__: { name: type } });
|
|
2732
|
+
el.setAttribute("class", "");
|
|
2733
|
+
const originalSetAttribute = el.setAttribute.bind(el);
|
|
2734
|
+
const originalRemoveAttribute = el.removeAttribute.bind(el);
|
|
2735
|
+
el.setAttribute = function(name, value) {
|
|
2736
|
+
const result = originalSetAttribute(name, value);
|
|
2737
|
+
if (name === "catchMove" && value) el.addEventListener("catchtouchmove", emptyFunction);
|
|
2738
|
+
return result;
|
|
2739
|
+
};
|
|
2740
|
+
el.removeAttribute = function(name) {
|
|
2741
|
+
const oldValue = el.getAttribute(name);
|
|
2742
|
+
if (name === "catchMove" && oldValue) el.removeEventListener("catchtouchmove", emptyFunction);
|
|
2743
|
+
return originalRemoveAttribute(name);
|
|
2744
|
+
};
|
|
2745
|
+
return el;
|
|
2746
|
+
}
|
|
2747
|
+
};
|
|
2748
|
+
return document;
|
|
2749
|
+
}
|
|
2750
|
+
const taroDocumentProvider = process.env.TARO_PLATFORM === "web" ? env.document : env.document = isEnableTTDom() ? createTTDomDocument() : createDocument();
|
|
2751
|
+
//#endregion
|
|
2752
|
+
//#region src/dom/svg.ts
|
|
2753
|
+
var SVGElement = class extends TaroElement {};
|
|
2754
|
+
//#endregion
|
|
2755
|
+
//#region src/dsl/common.ts
|
|
2756
|
+
const instances = /* @__PURE__ */ new Map();
|
|
2757
|
+
const pageId = incrementId();
|
|
2758
|
+
function injectPageInstance(inst, id) {
|
|
2759
|
+
hooks$1.call("mergePageInstance", instances.get(id), inst);
|
|
2760
|
+
instances.set(id, inst);
|
|
2761
|
+
}
|
|
2762
|
+
function getPageInstance(id) {
|
|
2763
|
+
return instances.get(id);
|
|
2764
|
+
}
|
|
2765
|
+
function removePageInstance(id) {
|
|
2766
|
+
instances.delete(id);
|
|
2767
|
+
}
|
|
2768
|
+
function safeExecute(path, lifecycle, ...args) {
|
|
2769
|
+
const instance = instances.get(path);
|
|
2770
|
+
if (instance == null) return;
|
|
2771
|
+
const func = hooks$1.call("getLifecycle", instance, lifecycle);
|
|
2772
|
+
if (isArray(func)) return func.map((fn) => fn.apply(instance, args))[0];
|
|
2773
|
+
if (!isFunction(func)) return;
|
|
2774
|
+
return func.apply(instance, args);
|
|
2775
|
+
}
|
|
2776
|
+
function stringify(obj) {
|
|
2777
|
+
if (obj == null) return "";
|
|
2778
|
+
const path = Object.keys(obj).map((key) => {
|
|
2779
|
+
return key + "=" + obj[key];
|
|
2780
|
+
}).join("&");
|
|
2781
|
+
return path === "" ? path : "?" + path;
|
|
2782
|
+
}
|
|
2783
|
+
function getPath(id, options) {
|
|
2784
|
+
const idx = id.indexOf("?");
|
|
2785
|
+
if (process.env.TARO_PLATFORM === "web") return `${idx > -1 ? id.substring(0, idx) : id}${stringify(options?.stamp ? { stamp: options.stamp } : {})}`;
|
|
2786
|
+
else return `${idx > -1 ? id.substring(0, idx) : id}${stringify(options)}`;
|
|
2787
|
+
}
|
|
2788
|
+
function getOnReadyEventKey(path) {
|
|
2789
|
+
return path + ".onReady";
|
|
2790
|
+
}
|
|
2791
|
+
function getOnShowEventKey(path) {
|
|
2792
|
+
return path + ".onShow";
|
|
2793
|
+
}
|
|
2794
|
+
function getOnHideEventKey(path) {
|
|
2795
|
+
return path + ".onHide";
|
|
2796
|
+
}
|
|
2797
|
+
function createPageConfig(component, pageName, data, pageConfig) {
|
|
2798
|
+
const id = pageName ?? `taro_page_${pageId()}`;
|
|
2799
|
+
const [ONLOAD, ONUNLOAD, ONREADY, ONSHOW, ONHIDE, LIFECYCLES, SIDE_EFFECT_LIFECYCLES] = hooks$1.call("getMiniLifecycleImpl").page;
|
|
2800
|
+
let pageElement = null;
|
|
2801
|
+
let unmounting = false;
|
|
2802
|
+
let prepareMountList = [];
|
|
2803
|
+
function setCurrentRouter(page) {
|
|
2804
|
+
const router = process.env.TARO_PLATFORM === "web" ? page.$taroPath : page.route || page.__route__ || page.$taroPath;
|
|
2805
|
+
Current.router = {
|
|
2806
|
+
params: page.$taroParams,
|
|
2807
|
+
path: addLeadingSlash(router),
|
|
2808
|
+
$taroPath: page.$taroPath,
|
|
2809
|
+
onReady: getOnReadyEventKey(id),
|
|
2810
|
+
onShow: getOnShowEventKey(id),
|
|
2811
|
+
onHide: getOnHideEventKey(id)
|
|
2812
|
+
};
|
|
2813
|
+
if (!isUndefined(page.exitState)) Current.router.exitState = page.exitState;
|
|
2814
|
+
}
|
|
2815
|
+
let loadResolver;
|
|
2816
|
+
let hasLoaded;
|
|
2817
|
+
const config = {
|
|
2818
|
+
[ONLOAD](options = {}, cb) {
|
|
2819
|
+
hasLoaded = new Promise((resolve) => {
|
|
2820
|
+
loadResolver = resolve;
|
|
2821
|
+
});
|
|
2822
|
+
perf.start(PAGE_INIT);
|
|
2823
|
+
Current.page = this;
|
|
2824
|
+
this.config = pageConfig || {};
|
|
2825
|
+
const uniqueOptions = Object.assign({}, options, { $taroTimestamp: Date.now() });
|
|
2826
|
+
const $taroPath = this.$taroPath = getPath(id, uniqueOptions);
|
|
2827
|
+
if (process.env.TARO_PLATFORM === "web") config.path = $taroPath;
|
|
2828
|
+
if (this.$taroParams == null) this.$taroParams = uniqueOptions;
|
|
2829
|
+
setCurrentRouter(this);
|
|
2830
|
+
if (process.env.TARO_PLATFORM !== "web") taroWindowProvider.trigger("0", $taroPath);
|
|
2831
|
+
const mount = () => {
|
|
2832
|
+
Current.app.mount(component, $taroPath, () => {
|
|
2833
|
+
if (process.env.TARO_ENV === "tt" && isEnableTTDom()) pageElement = env.document.getPageDocumentById(this.__webviewId__);
|
|
2834
|
+
else pageElement = env.document.getElementById($taroPath);
|
|
2835
|
+
ensure(pageElement !== null, "没有找到页面实例。");
|
|
2836
|
+
safeExecute($taroPath, ON_LOAD, this.$taroParams);
|
|
2837
|
+
loadResolver();
|
|
2838
|
+
if (process.env.TARO_PLATFORM !== "web") {
|
|
2839
|
+
pageElement.ctx = this;
|
|
2840
|
+
if (process.env.TARO_ENV === "tt" && isEnableTTDom()) pageElement.sync();
|
|
2841
|
+
else pageElement.performUpdate(true, cb);
|
|
2842
|
+
} else isFunction(cb) && cb();
|
|
2843
|
+
});
|
|
2844
|
+
};
|
|
2845
|
+
if (unmounting) prepareMountList.push(mount);
|
|
2846
|
+
else mount();
|
|
2847
|
+
},
|
|
2848
|
+
[ONUNLOAD]() {
|
|
2849
|
+
const $taroPath = this.$taroPath;
|
|
2850
|
+
if (process.env.TARO_PLATFORM !== "web") taroWindowProvider.trigger("3", $taroPath);
|
|
2851
|
+
safeExecute($taroPath, ONUNLOAD);
|
|
2852
|
+
unmounting = true;
|
|
2853
|
+
Current.app.unmount($taroPath, () => {
|
|
2854
|
+
unmounting = false;
|
|
2855
|
+
instances.delete($taroPath);
|
|
2856
|
+
if (pageElement) {
|
|
2857
|
+
pageElement.ctx = null;
|
|
2858
|
+
pageElement = null;
|
|
2859
|
+
}
|
|
2860
|
+
if (prepareMountList.length) {
|
|
2861
|
+
prepareMountList.forEach((fn) => fn());
|
|
2862
|
+
prepareMountList = [];
|
|
2863
|
+
}
|
|
2864
|
+
});
|
|
2865
|
+
},
|
|
2866
|
+
[ONREADY]() {
|
|
2867
|
+
hasLoaded.then(() => {
|
|
2868
|
+
safeExecute(this.$taroPath, ON_READY);
|
|
2869
|
+
_raf(() => eventCenter.trigger(getOnReadyEventKey(id)));
|
|
2870
|
+
this.onReady.called = true;
|
|
2871
|
+
});
|
|
2872
|
+
},
|
|
2873
|
+
[ONSHOW](options = {}) {
|
|
2874
|
+
hasLoaded.then(() => {
|
|
2875
|
+
Current.page = this;
|
|
2876
|
+
setCurrentRouter(this);
|
|
2877
|
+
if (process.env.TARO_PLATFORM !== "web") taroWindowProvider.trigger("2", this.$taroPath);
|
|
2878
|
+
safeExecute(this.$taroPath, ON_SHOW, options);
|
|
2879
|
+
_raf(() => eventCenter.trigger(getOnShowEventKey(id)));
|
|
2880
|
+
});
|
|
2881
|
+
},
|
|
2882
|
+
[ONHIDE]() {
|
|
2883
|
+
if (process.env.TARO_PLATFORM !== "web") taroWindowProvider.trigger("1", this.$taroPath);
|
|
2884
|
+
if (Current.page === this) {
|
|
2885
|
+
Current.page = null;
|
|
2886
|
+
Current.router = null;
|
|
2887
|
+
}
|
|
2888
|
+
safeExecute(this.$taroPath, ON_HIDE);
|
|
2889
|
+
eventCenter.trigger(getOnHideEventKey(id));
|
|
2890
|
+
}
|
|
2891
|
+
};
|
|
2892
|
+
if (process.env.TARO_PLATFORM === "web") config.getOpenerEventChannel = () => {
|
|
2893
|
+
return EventChannel.pageChannel;
|
|
2894
|
+
};
|
|
2895
|
+
const isSWAN = process.env.TARO_ENV === "swan";
|
|
2896
|
+
LIFECYCLES.forEach((lifecycle) => {
|
|
2897
|
+
let isDefer = false;
|
|
2898
|
+
let isEvent = false;
|
|
2899
|
+
lifecycle = lifecycle.replace(/^defer:/, () => {
|
|
2900
|
+
isDefer = true;
|
|
2901
|
+
return "";
|
|
2902
|
+
});
|
|
2903
|
+
lifecycle = lifecycle.replace(/^events:/, () => {
|
|
2904
|
+
isEvent = true;
|
|
2905
|
+
return "";
|
|
2906
|
+
});
|
|
2907
|
+
if (isEvent && process.env.TARO_ENV === "alipay") {
|
|
2908
|
+
if (!config.events) config.events = {};
|
|
2909
|
+
config.events[lifecycle] = function() {
|
|
2910
|
+
return safeExecute(this.$taroPath, lifecycle, ...arguments);
|
|
2911
|
+
};
|
|
2912
|
+
} else config[lifecycle] = function() {
|
|
2913
|
+
const exec = () => safeExecute(this.$taroPath, lifecycle, ...arguments);
|
|
2914
|
+
if (isSWAN) return exec();
|
|
2915
|
+
if (isDefer) hasLoaded.then(exec);
|
|
2916
|
+
else return exec();
|
|
2917
|
+
};
|
|
2918
|
+
});
|
|
2919
|
+
SIDE_EFFECT_LIFECYCLES.forEach((lifecycle) => {
|
|
2920
|
+
if (component[lifecycle] || component.prototype?.[lifecycle] || component[lifecycle.replace(/^on/, "enable")] || pageConfig?.[lifecycle.replace(/^on/, "enable")]) config[lifecycle] = function(...args) {
|
|
2921
|
+
const target = args[0]?.target;
|
|
2922
|
+
if (target?.id) {
|
|
2923
|
+
const id = target.id;
|
|
2924
|
+
const element = env.document.getElementById(id);
|
|
2925
|
+
if (element) target.dataset = element.dataset;
|
|
2926
|
+
}
|
|
2927
|
+
return safeExecute(this.$taroPath, lifecycle, ...args);
|
|
2928
|
+
};
|
|
2929
|
+
});
|
|
2930
|
+
config.eh = eventHandler;
|
|
2931
|
+
if (!isUndefined(data)) config.data = data;
|
|
2932
|
+
hooks$1.call("modifyPageObject", config);
|
|
2933
|
+
return config;
|
|
2934
|
+
}
|
|
2935
|
+
function createComponentConfig(component, componentName, data) {
|
|
2936
|
+
const id = componentName ?? `taro_component_${pageId()}`;
|
|
2937
|
+
let componentElement = null;
|
|
2938
|
+
const [ATTACHED, DETACHED] = hooks$1.call("getMiniLifecycleImpl").component;
|
|
2939
|
+
const config = {
|
|
2940
|
+
[ATTACHED]() {
|
|
2941
|
+
perf.start(PAGE_INIT);
|
|
2942
|
+
this.pageIdCache = this.getPageId?.() || pageId();
|
|
2943
|
+
const path = getPath(id, { id: this.pageIdCache });
|
|
2944
|
+
Current.app.mount(component, path, () => {
|
|
2945
|
+
componentElement = env.document.getElementById(path);
|
|
2946
|
+
ensure(componentElement !== null, "没有找到组件实例。");
|
|
2947
|
+
this.$taroInstances = instances.get(path);
|
|
2948
|
+
safeExecute(path, ON_LOAD);
|
|
2949
|
+
if (process.env.TARO_PLATFORM !== "web") {
|
|
2950
|
+
componentElement.ctx = this;
|
|
2951
|
+
if (process.env.TARO_ENV !== "tt" || !isEnableTTDom()) componentElement.performUpdate(true);
|
|
2952
|
+
}
|
|
2953
|
+
});
|
|
2954
|
+
},
|
|
2955
|
+
[DETACHED]() {
|
|
2956
|
+
const path = getPath(id, { id: this.pageIdCache });
|
|
2957
|
+
Current.app.unmount(path, () => {
|
|
2958
|
+
instances.delete(path);
|
|
2959
|
+
if (componentElement) componentElement.ctx = null;
|
|
2960
|
+
});
|
|
2961
|
+
},
|
|
2962
|
+
methods: { eh: eventHandler }
|
|
2963
|
+
};
|
|
2964
|
+
if (!isUndefined(data)) config.data = data;
|
|
2965
|
+
[
|
|
2966
|
+
OPTIONS,
|
|
2967
|
+
EXTERNAL_CLASSES,
|
|
2968
|
+
BEHAVIORS
|
|
2969
|
+
].forEach((key) => {
|
|
2970
|
+
config[key] = component[key] ?? EMPTY_OBJ;
|
|
2971
|
+
});
|
|
2972
|
+
return config;
|
|
2973
|
+
}
|
|
2974
|
+
function createRecursiveComponentConfig(componentName) {
|
|
2975
|
+
const isCustomWrapper = componentName === CUSTOM_WRAPPER;
|
|
2976
|
+
const [ATTACHED, DETACHED] = hooks$1.call("getMiniLifecycleImpl").component;
|
|
2977
|
+
const lifeCycles = isCustomWrapper ? {
|
|
2978
|
+
[ATTACHED]() {
|
|
2979
|
+
if (process.env.TARO_ENV === "tt" && isEnableTTDom()) return;
|
|
2980
|
+
const componentId = this.data.i?.sid || this.props.i?.sid;
|
|
2981
|
+
if (isString(componentId)) {
|
|
2982
|
+
customWrapperCache.set(componentId, this);
|
|
2983
|
+
const el = env.document.getElementById(componentId);
|
|
2984
|
+
if (el) el.ctx = this;
|
|
2985
|
+
}
|
|
2986
|
+
},
|
|
2987
|
+
[DETACHED]() {
|
|
2988
|
+
if (process.env.TARO_ENV === "tt" && isEnableTTDom()) return;
|
|
2989
|
+
const componentId = this.data.i?.sid || this.props.i?.sid;
|
|
2990
|
+
if (isString(componentId)) {
|
|
2991
|
+
customWrapperCache.delete(componentId);
|
|
2992
|
+
const el = env.document.getElementById(componentId);
|
|
2993
|
+
if (el) el.ctx = null;
|
|
2994
|
+
}
|
|
2995
|
+
}
|
|
2996
|
+
} : EMPTY_OBJ;
|
|
2997
|
+
const extraOptions = {};
|
|
2998
|
+
if (process.env.TARO_ENV === "jd") extraOptions.addGlobalClass = true;
|
|
2999
|
+
return hooks$1.call("modifyRecursiveComponentConfig", {
|
|
3000
|
+
properties: {
|
|
3001
|
+
i: {
|
|
3002
|
+
type: Object,
|
|
3003
|
+
value: { [Shortcuts.NodeName]: getComponentsAlias$1(internalComponents)[VIEW]._num }
|
|
3004
|
+
},
|
|
3005
|
+
l: {
|
|
3006
|
+
type: String,
|
|
3007
|
+
value: ""
|
|
3008
|
+
}
|
|
3009
|
+
},
|
|
3010
|
+
options: {
|
|
3011
|
+
...extraOptions,
|
|
3012
|
+
virtualHost: !isCustomWrapper
|
|
3013
|
+
},
|
|
3014
|
+
methods: { eh: eventHandler },
|
|
3015
|
+
...lifeCycles
|
|
3016
|
+
}, { isCustomWrapper });
|
|
3017
|
+
}
|
|
3018
|
+
//#endregion
|
|
3019
|
+
//#region src/next-tick.ts
|
|
3020
|
+
const TIMEOUT = 100;
|
|
3021
|
+
const nextTick = (cb, ctx) => {
|
|
3022
|
+
const beginTime = Date.now();
|
|
3023
|
+
const router = Current.router;
|
|
3024
|
+
const timerFunc = () => {
|
|
3025
|
+
setTimeout(function() {
|
|
3026
|
+
ctx ? cb.call(ctx) : cb();
|
|
3027
|
+
}, 1);
|
|
3028
|
+
};
|
|
3029
|
+
if (router === null) return timerFunc();
|
|
3030
|
+
const path = router.$taroPath;
|
|
3031
|
+
/**
|
|
3032
|
+
* 三种情况
|
|
3033
|
+
* 1. 调用 nextTick 时,pendingUpdate 已经从 true 变为 false(即已更新完成),那么需要光等 100ms
|
|
3034
|
+
* 2. 调用 nextTick 时,pendingUpdate 为 true,那么刚好可以搭上便车
|
|
3035
|
+
* 3. 调用 nextTick 时,pendingUpdate 还是 false,框架仍未启动更新逻辑,这时最多轮询 100ms,等待 pendingUpdate 变为 true。
|
|
3036
|
+
*/
|
|
3037
|
+
function next() {
|
|
3038
|
+
const pageElement = env.document.getElementById(path);
|
|
3039
|
+
if (pageElement?.pendingUpdate) if (process.env.TARO_PLATFORM === "web") pageElement.firstChild?.["componentOnReady"]?.().then(() => {
|
|
3040
|
+
timerFunc();
|
|
3041
|
+
}) ?? timerFunc();
|
|
3042
|
+
else pageElement.enqueueUpdateCallback(cb, ctx);
|
|
3043
|
+
else if (Date.now() - beginTime > TIMEOUT) timerFunc();
|
|
3044
|
+
else setTimeout(() => next(), 20);
|
|
3045
|
+
}
|
|
3046
|
+
next();
|
|
3047
|
+
};
|
|
3048
|
+
//#endregion
|
|
3049
|
+
//#region src/polyfill/array.ts
|
|
3050
|
+
function handleArrayFindPolyfill() {
|
|
3051
|
+
if (!isFunction(Array.prototype.find)) Object.defineProperty(Array.prototype, "find", { value(predicate) {
|
|
3052
|
+
if (this == null) throw new TypeError("\"this\" is null or not defined");
|
|
3053
|
+
const o = Object(this);
|
|
3054
|
+
const len = o.length >>> 0;
|
|
3055
|
+
if (!isFunction(predicate)) throw new TypeError("predicate must be a function");
|
|
3056
|
+
const thisArg = arguments[1];
|
|
3057
|
+
let k = 0;
|
|
3058
|
+
while (k < len) {
|
|
3059
|
+
const kValue = o[k];
|
|
3060
|
+
if (predicate.call(thisArg, kValue, k, o)) return kValue;
|
|
3061
|
+
k++;
|
|
3062
|
+
}
|
|
3063
|
+
} });
|
|
3064
|
+
}
|
|
3065
|
+
function handleArrayIncludesPolyfill() {
|
|
3066
|
+
if (!isFunction(Array.prototype.includes)) Object.defineProperty(Array.prototype, "includes", { value(searchElement, fromIndex) {
|
|
3067
|
+
if (this == null) throw new TypeError("\"this\" is null or not defined");
|
|
3068
|
+
const o = Object(this);
|
|
3069
|
+
const len = o.length >>> 0;
|
|
3070
|
+
if (len === 0) return false;
|
|
3071
|
+
const n = fromIndex | 0;
|
|
3072
|
+
let k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
|
|
3073
|
+
while (k < len) {
|
|
3074
|
+
if (o[k] === searchElement) return true;
|
|
3075
|
+
k++;
|
|
3076
|
+
}
|
|
3077
|
+
return false;
|
|
3078
|
+
} });
|
|
3079
|
+
}
|
|
3080
|
+
//#endregion
|
|
3081
|
+
//#region src/polyfill/intersection-observer.ts
|
|
3082
|
+
function handleIntersectionObserverPolyfill() {
|
|
3083
|
+
if ("IntersectionObserver" in window && "IntersectionObserverEntry" in window && "intersectionRatio" in window.IntersectionObserverEntry.prototype) {
|
|
3084
|
+
if (!("isIntersecting" in window.IntersectionObserverEntry.prototype)) Object.defineProperty(window.IntersectionObserverEntry.prototype, "isIntersecting", { get: function() {
|
|
3085
|
+
return this.intersectionRatio > 0;
|
|
3086
|
+
} });
|
|
3087
|
+
} else handleIntersectionObserverObjectPolyfill();
|
|
3088
|
+
}
|
|
3089
|
+
function handleIntersectionObserverObjectPolyfill() {
|
|
3090
|
+
const document = window.document;
|
|
3091
|
+
/**
|
|
3092
|
+
* An IntersectionObserver registry. This registry exists to hold a strong
|
|
3093
|
+
* reference to IntersectionObserver instances currently observing a target
|
|
3094
|
+
* element. Without this registry, instances without another reference may be
|
|
3095
|
+
* garbage collected.
|
|
3096
|
+
*/
|
|
3097
|
+
const registry = [];
|
|
3098
|
+
/**
|
|
3099
|
+
* Creates the global IntersectionObserverEntry constructor.
|
|
3100
|
+
* https://w3c.github.io/IntersectionObserver/#intersection-observer-entry
|
|
3101
|
+
* @param {Object} entry A dictionary of instance properties.
|
|
3102
|
+
* @constructor
|
|
3103
|
+
*/
|
|
3104
|
+
function IntersectionObserverEntry(entry) {
|
|
3105
|
+
this.time = entry.time;
|
|
3106
|
+
this.target = entry.target;
|
|
3107
|
+
this.rootBounds = entry.rootBounds;
|
|
3108
|
+
this.boundingClientRect = entry.boundingClientRect;
|
|
3109
|
+
this.intersectionRect = entry.intersectionRect || getEmptyRect();
|
|
3110
|
+
this.isIntersecting = !!entry.intersectionRect;
|
|
3111
|
+
const targetRect = this.boundingClientRect;
|
|
3112
|
+
const targetArea = targetRect.width * targetRect.height;
|
|
3113
|
+
const intersectionRect = this.intersectionRect;
|
|
3114
|
+
const intersectionArea = intersectionRect.width * intersectionRect.height;
|
|
3115
|
+
if (targetArea) this.intersectionRatio = Number((intersectionArea / targetArea).toFixed(4));
|
|
3116
|
+
else this.intersectionRatio = this.isIntersecting ? 1 : 0;
|
|
3117
|
+
}
|
|
3118
|
+
/**
|
|
3119
|
+
* Creates the global IntersectionObserver constructor.
|
|
3120
|
+
* https://w3c.github.io/IntersectionObserver/#intersection-observer-interface
|
|
3121
|
+
* @param {Function} callback The function to be invoked after intersection
|
|
3122
|
+
* changes have queued. The function is not invoked if the queue has
|
|
3123
|
+
* been emptied by calling the `takeRecords` method.
|
|
3124
|
+
* @param {Object=} opt_options Optional configuration options.
|
|
3125
|
+
* @constructor
|
|
3126
|
+
*/
|
|
3127
|
+
function IntersectionObserver(callback, options = {}) {
|
|
3128
|
+
if (!isFunction(callback)) throw new Error("callback must be a function");
|
|
3129
|
+
if (options.root && options.root.nodeType != 1) throw new Error("root must be an Element");
|
|
3130
|
+
this._checkForIntersections = throttle(this._checkForIntersections.bind(this), this.THROTTLE_TIMEOUT);
|
|
3131
|
+
this._callback = callback;
|
|
3132
|
+
this._observationTargets = [];
|
|
3133
|
+
this._queuedEntries = [];
|
|
3134
|
+
this._rootMarginValues = this._parseRootMargin(options.rootMargin);
|
|
3135
|
+
this.thresholds = this._initThresholds(options.threshold);
|
|
3136
|
+
this.root = options.root || null;
|
|
3137
|
+
this.rootMargin = this._rootMarginValues.map(function(margin) {
|
|
3138
|
+
return margin.value + margin.unit;
|
|
3139
|
+
}).join(" ");
|
|
3140
|
+
}
|
|
3141
|
+
/**
|
|
3142
|
+
* The minimum interval within which the document will be checked for
|
|
3143
|
+
* intersection changes.
|
|
3144
|
+
*/
|
|
3145
|
+
IntersectionObserver.prototype.THROTTLE_TIMEOUT = 100;
|
|
3146
|
+
/**
|
|
3147
|
+
* The frequency in which the polyfill polls for intersection changes.
|
|
3148
|
+
* this can be updated on a per instance basis and must be set prior to
|
|
3149
|
+
* calling `observe` on the first target.
|
|
3150
|
+
*/
|
|
3151
|
+
IntersectionObserver.prototype.POLL_INTERVAL = null;
|
|
3152
|
+
/**
|
|
3153
|
+
* Use a mutation observer on the root element
|
|
3154
|
+
* to detect intersection changes.
|
|
3155
|
+
*/
|
|
3156
|
+
IntersectionObserver.prototype.USE_MUTATION_OBSERVER = true;
|
|
3157
|
+
/**
|
|
3158
|
+
* Starts observing a target element for intersection changes based on
|
|
3159
|
+
* the thresholds values.
|
|
3160
|
+
* @param {Element} target The DOM element to observe.
|
|
3161
|
+
*/
|
|
3162
|
+
IntersectionObserver.prototype.observe = function(target) {
|
|
3163
|
+
if (this._observationTargets.some(function(item) {
|
|
3164
|
+
return item.element == target;
|
|
3165
|
+
})) return;
|
|
3166
|
+
if (!(target && target.nodeType == 1)) throw new Error("target must be an Element");
|
|
3167
|
+
this._registerInstance();
|
|
3168
|
+
this._observationTargets.push({
|
|
3169
|
+
element: target,
|
|
3170
|
+
entry: null
|
|
3171
|
+
});
|
|
3172
|
+
this._monitorIntersections();
|
|
3173
|
+
this._checkForIntersections();
|
|
3174
|
+
};
|
|
3175
|
+
/**
|
|
3176
|
+
* Stops observing a target element for intersection changes.
|
|
3177
|
+
* @param {Element} target The DOM element to observe.
|
|
3178
|
+
*/
|
|
3179
|
+
IntersectionObserver.prototype.unobserve = function(target) {
|
|
3180
|
+
this._observationTargets = this._observationTargets.filter(function(item) {
|
|
3181
|
+
return item.element != target;
|
|
3182
|
+
});
|
|
3183
|
+
if (!this._observationTargets.length) {
|
|
3184
|
+
this._unmonitorIntersections();
|
|
3185
|
+
this._unregisterInstance();
|
|
3186
|
+
}
|
|
3187
|
+
};
|
|
3188
|
+
/**
|
|
3189
|
+
* Stops observing all target elements for intersection changes.
|
|
3190
|
+
*/
|
|
3191
|
+
IntersectionObserver.prototype.disconnect = function() {
|
|
3192
|
+
this._observationTargets = [];
|
|
3193
|
+
this._unmonitorIntersections();
|
|
3194
|
+
this._unregisterInstance();
|
|
3195
|
+
};
|
|
3196
|
+
/**
|
|
3197
|
+
* Returns any queue entries that have not yet been reported to the
|
|
3198
|
+
* callback and clears the queue. This can be used in conjunction with the
|
|
3199
|
+
* callback to obtain the absolute most up-to-date intersection information.
|
|
3200
|
+
* @return {Array} The currently queued entries.
|
|
3201
|
+
*/
|
|
3202
|
+
IntersectionObserver.prototype.takeRecords = function() {
|
|
3203
|
+
const records = this._queuedEntries.slice();
|
|
3204
|
+
this._queuedEntries = [];
|
|
3205
|
+
return records;
|
|
3206
|
+
};
|
|
3207
|
+
/**
|
|
3208
|
+
* Accepts the threshold value from the user configuration object and
|
|
3209
|
+
* returns a sorted array of unique threshold values. If a value is not
|
|
3210
|
+
* between 0 and 1 and error is thrown.
|
|
3211
|
+
* @private
|
|
3212
|
+
* @param {Array|number=} opt_threshold An optional threshold value or
|
|
3213
|
+
* a list of threshold values, defaulting to [0].
|
|
3214
|
+
* @return {Array} A sorted list of unique and valid threshold values.
|
|
3215
|
+
*/
|
|
3216
|
+
IntersectionObserver.prototype._initThresholds = function(opt_threshold) {
|
|
3217
|
+
let threshold = opt_threshold || [0];
|
|
3218
|
+
if (!Array.isArray(threshold)) threshold = [threshold];
|
|
3219
|
+
return threshold.sort().filter(function(t, i, a) {
|
|
3220
|
+
if (!isNumber(t) || isNaN(t) || t < 0 || t > 1) throw new Error("threshold must be a number between 0 and 1 inclusively");
|
|
3221
|
+
return t !== a[i - 1];
|
|
3222
|
+
});
|
|
3223
|
+
};
|
|
3224
|
+
/**
|
|
3225
|
+
* Accepts the rootMargin value from the user configuration object
|
|
3226
|
+
* and returns an array of the four margin values as an object containing
|
|
3227
|
+
* the value and unit properties. If any of the values are not properly
|
|
3228
|
+
* formatted or use a unit other than px or %, and error is thrown.
|
|
3229
|
+
* @private
|
|
3230
|
+
* @param {string=} opt_rootMargin An optional rootMargin value,
|
|
3231
|
+
* defaulting to '0px'.
|
|
3232
|
+
* @return {Array<Object>} An array of margin objects with the keys
|
|
3233
|
+
* value and unit.
|
|
3234
|
+
*/
|
|
3235
|
+
IntersectionObserver.prototype._parseRootMargin = function(opt_rootMargin) {
|
|
3236
|
+
const margins = (opt_rootMargin || "0px").split(/\s+/).map(function(margin) {
|
|
3237
|
+
const parts = /^(-?\d*\.?\d+)(px|%)$/.exec(margin);
|
|
3238
|
+
if (!parts) throw new Error("rootMargin must be specified in pixels or percent");
|
|
3239
|
+
return {
|
|
3240
|
+
value: parseFloat(parts[1]),
|
|
3241
|
+
unit: parts[2]
|
|
3242
|
+
};
|
|
3243
|
+
});
|
|
3244
|
+
margins[1] = margins[1] || margins[0];
|
|
3245
|
+
margins[2] = margins[2] || margins[0];
|
|
3246
|
+
margins[3] = margins[3] || margins[1];
|
|
3247
|
+
return margins;
|
|
3248
|
+
};
|
|
3249
|
+
/**
|
|
3250
|
+
* Starts polling for intersection changes if the polling is not already
|
|
3251
|
+
* happening, and if the page's visibility state is visible.
|
|
3252
|
+
* @private
|
|
3253
|
+
*/
|
|
3254
|
+
IntersectionObserver.prototype._monitorIntersections = function() {
|
|
3255
|
+
if (!this._monitoringIntersections) {
|
|
3256
|
+
this._monitoringIntersections = true;
|
|
3257
|
+
if (this.POLL_INTERVAL) this._monitoringInterval = setInterval(this._checkForIntersections, this.POLL_INTERVAL);
|
|
3258
|
+
else {
|
|
3259
|
+
addEvent(window, "resize", this._checkForIntersections, true);
|
|
3260
|
+
addEvent(document, "scroll", this._checkForIntersections, true);
|
|
3261
|
+
if (this.USE_MUTATION_OBSERVER && "MutationObserver" in window) {
|
|
3262
|
+
this._domObserver = new MutationObserver(this._checkForIntersections);
|
|
3263
|
+
this._domObserver.observe(document, {
|
|
3264
|
+
attributes: true,
|
|
3265
|
+
childList: true,
|
|
3266
|
+
characterData: true,
|
|
3267
|
+
subtree: true
|
|
3268
|
+
});
|
|
3269
|
+
}
|
|
3270
|
+
}
|
|
3271
|
+
}
|
|
3272
|
+
};
|
|
3273
|
+
/**
|
|
3274
|
+
* Stops polling for intersection changes.
|
|
3275
|
+
* @private
|
|
3276
|
+
*/
|
|
3277
|
+
IntersectionObserver.prototype._unmonitorIntersections = function() {
|
|
3278
|
+
if (this._monitoringIntersections) {
|
|
3279
|
+
this._monitoringIntersections = false;
|
|
3280
|
+
clearInterval(this._monitoringInterval);
|
|
3281
|
+
this._monitoringInterval = null;
|
|
3282
|
+
removeEvent(window, "resize", this._checkForIntersections, true);
|
|
3283
|
+
removeEvent(document, "scroll", this._checkForIntersections, true);
|
|
3284
|
+
if (this._domObserver) {
|
|
3285
|
+
this._domObserver.disconnect();
|
|
3286
|
+
this._domObserver = null;
|
|
3287
|
+
}
|
|
3288
|
+
}
|
|
3289
|
+
};
|
|
3290
|
+
/**
|
|
3291
|
+
* Scans each observation target for intersection changes and adds them
|
|
3292
|
+
* to the internal entries queue. If new entries are found, it
|
|
3293
|
+
* schedules the callback to be invoked.
|
|
3294
|
+
* @private
|
|
3295
|
+
*/
|
|
3296
|
+
IntersectionObserver.prototype._checkForIntersections = function() {
|
|
3297
|
+
const rootIsInDom = this._rootIsInDom();
|
|
3298
|
+
const rootRect = rootIsInDom ? this._getRootRect() : getEmptyRect();
|
|
3299
|
+
this._observationTargets.forEach(function(item) {
|
|
3300
|
+
const target = item.element;
|
|
3301
|
+
const targetRect = getBoundingClientRect(target);
|
|
3302
|
+
const rootContainsTarget = this._rootContainsTarget(target);
|
|
3303
|
+
const oldEntry = item.entry;
|
|
3304
|
+
const intersectionRect = rootIsInDom && rootContainsTarget && this._computeTargetAndRootIntersection(target, rootRect);
|
|
3305
|
+
const newEntry = item.entry = new IntersectionObserverEntry({
|
|
3306
|
+
time: now(),
|
|
3307
|
+
target,
|
|
3308
|
+
boundingClientRect: targetRect,
|
|
3309
|
+
rootBounds: rootRect,
|
|
3310
|
+
intersectionRect,
|
|
3311
|
+
intersectionRatio: -1,
|
|
3312
|
+
isIntersecting: false
|
|
3313
|
+
});
|
|
3314
|
+
if (!oldEntry) this._queuedEntries.push(newEntry);
|
|
3315
|
+
else if (rootIsInDom && rootContainsTarget) {
|
|
3316
|
+
if (this._hasCrossedThreshold(oldEntry, newEntry)) this._queuedEntries.push(newEntry);
|
|
3317
|
+
} else if (oldEntry && oldEntry.isIntersecting) this._queuedEntries.push(newEntry);
|
|
3318
|
+
}, this);
|
|
3319
|
+
if (this._queuedEntries.length) this._callback(this.takeRecords(), this);
|
|
3320
|
+
};
|
|
3321
|
+
/**
|
|
3322
|
+
* Accepts a target and root rect computes the intersection between then
|
|
3323
|
+
* following the algorithm in the spec.
|
|
3324
|
+
* TODO(philipwalton): at this time clip-path is not considered.
|
|
3325
|
+
* https://w3c.github.io/IntersectionObserver/#calculate-intersection-rect-algo
|
|
3326
|
+
* @param {Element} target The target DOM element
|
|
3327
|
+
* @param {Object} rootRect The bounding rect of the root after being
|
|
3328
|
+
* expanded by the rootMargin value.
|
|
3329
|
+
* @return {?Object} The final intersection rect object or undefined if no
|
|
3330
|
+
* intersection is found.
|
|
3331
|
+
* @private
|
|
3332
|
+
*/
|
|
3333
|
+
IntersectionObserver.prototype._computeTargetAndRootIntersection = function(target, rootRect) {
|
|
3334
|
+
if (window.getComputedStyle(target).display === "none") return;
|
|
3335
|
+
let intersectionRect = getBoundingClientRect(target);
|
|
3336
|
+
let parent = getParentNode(target);
|
|
3337
|
+
let atRoot = false;
|
|
3338
|
+
while (!atRoot) {
|
|
3339
|
+
let parentRect = null;
|
|
3340
|
+
const parentComputedStyle = parent.nodeType == 1 ? window.getComputedStyle(parent) : {};
|
|
3341
|
+
if (parentComputedStyle.display === "none") return;
|
|
3342
|
+
if (parent == this.root || parent == document) {
|
|
3343
|
+
atRoot = true;
|
|
3344
|
+
parentRect = rootRect;
|
|
3345
|
+
} else if (parent != document.body && parent != document.documentElement && parentComputedStyle.overflow != "visible") parentRect = getBoundingClientRect(parent);
|
|
3346
|
+
if (parentRect) {
|
|
3347
|
+
intersectionRect = computeRectIntersection(parentRect, intersectionRect);
|
|
3348
|
+
if (!intersectionRect) break;
|
|
3349
|
+
}
|
|
3350
|
+
parent = getParentNode(parent);
|
|
3351
|
+
}
|
|
3352
|
+
return intersectionRect;
|
|
3353
|
+
};
|
|
3354
|
+
/**
|
|
3355
|
+
* Returns the root rect after being expanded by the rootMargin value.
|
|
3356
|
+
* @return {Object} The expanded root rect.
|
|
3357
|
+
* @private
|
|
3358
|
+
*/
|
|
3359
|
+
IntersectionObserver.prototype._getRootRect = function() {
|
|
3360
|
+
let rootRect;
|
|
3361
|
+
if (this.root) rootRect = getBoundingClientRect(this.root);
|
|
3362
|
+
else {
|
|
3363
|
+
const html = document.documentElement;
|
|
3364
|
+
const body = document.body;
|
|
3365
|
+
rootRect = {
|
|
3366
|
+
top: 0,
|
|
3367
|
+
left: 0,
|
|
3368
|
+
right: html.clientWidth || body.clientWidth,
|
|
3369
|
+
width: html.clientWidth || body.clientWidth,
|
|
3370
|
+
bottom: html.clientHeight || body.clientHeight,
|
|
3371
|
+
height: html.clientHeight || body.clientHeight
|
|
3372
|
+
};
|
|
3373
|
+
}
|
|
3374
|
+
return this._expandRectByRootMargin(rootRect);
|
|
3375
|
+
};
|
|
3376
|
+
/**
|
|
3377
|
+
* Accepts a rect and expands it by the rootMargin value.
|
|
3378
|
+
* @param {Object} rect The rect object to expand.
|
|
3379
|
+
* @return {Object} The expanded rect.
|
|
3380
|
+
* @private
|
|
3381
|
+
*/
|
|
3382
|
+
IntersectionObserver.prototype._expandRectByRootMargin = function(rect) {
|
|
3383
|
+
const margins = this._rootMarginValues.map(function(margin, i) {
|
|
3384
|
+
return margin.unit === "px" ? margin.value : margin.value * (i % 2 ? rect.width : rect.height) / 100;
|
|
3385
|
+
});
|
|
3386
|
+
const newRect = {
|
|
3387
|
+
top: rect.top - margins[0],
|
|
3388
|
+
right: rect.right + margins[1],
|
|
3389
|
+
bottom: rect.bottom + margins[2],
|
|
3390
|
+
left: rect.left - margins[3]
|
|
3391
|
+
};
|
|
3392
|
+
newRect.width = newRect.right - newRect.left;
|
|
3393
|
+
newRect.height = newRect.bottom - newRect.top;
|
|
3394
|
+
return newRect;
|
|
3395
|
+
};
|
|
3396
|
+
/**
|
|
3397
|
+
* Accepts an old and new entry and returns true if at least one of the
|
|
3398
|
+
* threshold values has been crossed.
|
|
3399
|
+
* @param {?IntersectionObserverEntry} oldEntry The previous entry for a
|
|
3400
|
+
* particular target element or null if no previous entry exists.
|
|
3401
|
+
* @param {IntersectionObserverEntry} newEntry The current entry for a
|
|
3402
|
+
* particular target element.
|
|
3403
|
+
* @return {boolean} Returns true if a any threshold has been crossed.
|
|
3404
|
+
* @private
|
|
3405
|
+
*/
|
|
3406
|
+
IntersectionObserver.prototype._hasCrossedThreshold = function(oldEntry, newEntry) {
|
|
3407
|
+
const oldRatio = oldEntry && oldEntry.isIntersecting ? oldEntry.intersectionRatio || 0 : -1;
|
|
3408
|
+
const newRatio = newEntry.isIntersecting ? newEntry.intersectionRatio || 0 : -1;
|
|
3409
|
+
if (oldRatio === newRatio) return;
|
|
3410
|
+
for (let i = 0; i < this.thresholds.length; i++) {
|
|
3411
|
+
const threshold = this.thresholds[i];
|
|
3412
|
+
if (threshold == oldRatio || threshold == newRatio || threshold < oldRatio !== threshold < newRatio) return true;
|
|
3413
|
+
}
|
|
3414
|
+
};
|
|
3415
|
+
/**
|
|
3416
|
+
* Returns whether or not the root element is an element and is in the DOM.
|
|
3417
|
+
* @return {boolean} True if the root element is an element and is in the DOM.
|
|
3418
|
+
* @private
|
|
3419
|
+
*/
|
|
3420
|
+
IntersectionObserver.prototype._rootIsInDom = function() {
|
|
3421
|
+
return !this.root || containsDeep(document, this.root);
|
|
3422
|
+
};
|
|
3423
|
+
/**
|
|
3424
|
+
* Returns whether or not the target element is a child of root.
|
|
3425
|
+
* @param {Element} target The target element to check.
|
|
3426
|
+
* @return {boolean} True if the target element is a child of root.
|
|
3427
|
+
* @private
|
|
3428
|
+
*/
|
|
3429
|
+
IntersectionObserver.prototype._rootContainsTarget = function(target) {
|
|
3430
|
+
return containsDeep(this.root || document, target);
|
|
3431
|
+
};
|
|
3432
|
+
/**
|
|
3433
|
+
* Adds the instance to the global IntersectionObserver registry if it isn't
|
|
3434
|
+
* already present.
|
|
3435
|
+
* @private
|
|
3436
|
+
*/
|
|
3437
|
+
IntersectionObserver.prototype._registerInstance = function() {
|
|
3438
|
+
if (registry.indexOf(this) < 0) registry.push(this);
|
|
3439
|
+
};
|
|
3440
|
+
/**
|
|
3441
|
+
* Removes the instance from the global IntersectionObserver registry.
|
|
3442
|
+
* @private
|
|
3443
|
+
*/
|
|
3444
|
+
IntersectionObserver.prototype._unregisterInstance = function() {
|
|
3445
|
+
const index = registry.indexOf(this);
|
|
3446
|
+
if (index != -1) registry.splice(index, 1);
|
|
3447
|
+
};
|
|
3448
|
+
/**
|
|
3449
|
+
* Returns the result of the performance.now() method or null in browsers
|
|
3450
|
+
* that don't support the API.
|
|
3451
|
+
* @return {number} The elapsed time since the page was requested.
|
|
3452
|
+
*/
|
|
3453
|
+
function now() {
|
|
3454
|
+
return window.performance && performance.now && performance.now();
|
|
3455
|
+
}
|
|
3456
|
+
/**
|
|
3457
|
+
* Adds an event handler to a DOM node ensuring cross-browser compatibility.
|
|
3458
|
+
* @param {Node} node The DOM node to add the event handler to.
|
|
3459
|
+
* @param {string} event The event name.
|
|
3460
|
+
* @param {Function} fn The event handler to add.
|
|
3461
|
+
* @param {boolean} opt_useCapture Optionally adds the even to the capture
|
|
3462
|
+
* phase. Note: this only works in modern browsers.
|
|
3463
|
+
*/
|
|
3464
|
+
function addEvent(node, event, fn, opt_useCapture) {
|
|
3465
|
+
if (isFunction(node.addEventListener)) node.addEventListener(event, fn, opt_useCapture || false);
|
|
3466
|
+
else if (isFunction(node.attachEvent)) node.attachEvent("on" + event, fn);
|
|
3467
|
+
}
|
|
3468
|
+
/**
|
|
3469
|
+
* Removes a previously added event handler from a DOM node.
|
|
3470
|
+
* @param {Node} node The DOM node to remove the event handler from.
|
|
3471
|
+
* @param {string} event The event name.
|
|
3472
|
+
* @param {Function} fn The event handler to remove.
|
|
3473
|
+
* @param {boolean} opt_useCapture If the event handler was added with this
|
|
3474
|
+
* flag set to true, it should be set to true here in order to remove it.
|
|
3475
|
+
*/
|
|
3476
|
+
function removeEvent(node, event, fn, opt_useCapture) {
|
|
3477
|
+
if (isFunction(node.removeEventListener)) node.removeEventListener(event, fn, opt_useCapture || false);
|
|
3478
|
+
else if (isFunction(node.detatchEvent)) node.detatchEvent("on" + event, fn);
|
|
3479
|
+
}
|
|
3480
|
+
/**
|
|
3481
|
+
* Returns the intersection between two rect objects.
|
|
3482
|
+
* @param {Object} rect1 The first rect.
|
|
3483
|
+
* @param {Object} rect2 The second rect.
|
|
3484
|
+
* @return {?Object} The intersection rect or undefined if no intersection
|
|
3485
|
+
* is found.
|
|
3486
|
+
*/
|
|
3487
|
+
function computeRectIntersection(rect1, rect2) {
|
|
3488
|
+
const top = Math.max(rect1.top, rect2.top);
|
|
3489
|
+
const bottom = Math.min(rect1.bottom, rect2.bottom);
|
|
3490
|
+
const left = Math.max(rect1.left, rect2.left);
|
|
3491
|
+
const right = Math.min(rect1.right, rect2.right);
|
|
3492
|
+
const width = right - left;
|
|
3493
|
+
const height = bottom - top;
|
|
3494
|
+
return width >= 0 && height >= 0 && {
|
|
3495
|
+
top,
|
|
3496
|
+
bottom,
|
|
3497
|
+
left,
|
|
3498
|
+
right,
|
|
3499
|
+
width,
|
|
3500
|
+
height
|
|
3501
|
+
};
|
|
3502
|
+
}
|
|
3503
|
+
/**
|
|
3504
|
+
* Shims the native getBoundingClientRect for compatibility with older IE.
|
|
3505
|
+
* @param {Element} el The element whose bounding rect to get.
|
|
3506
|
+
* @return {Object} The (possibly shimmed) rect of the element.
|
|
3507
|
+
*/
|
|
3508
|
+
function getBoundingClientRect(el) {
|
|
3509
|
+
let rect;
|
|
3510
|
+
try {
|
|
3511
|
+
rect = el.getBoundingClientRect();
|
|
3512
|
+
} catch (err) {}
|
|
3513
|
+
if (!rect) return getEmptyRect();
|
|
3514
|
+
if (!(rect.width && rect.height)) rect = {
|
|
3515
|
+
top: rect.top,
|
|
3516
|
+
right: rect.right,
|
|
3517
|
+
bottom: rect.bottom,
|
|
3518
|
+
left: rect.left,
|
|
3519
|
+
width: rect.right - rect.left,
|
|
3520
|
+
height: rect.bottom - rect.top
|
|
3521
|
+
};
|
|
3522
|
+
return rect;
|
|
3523
|
+
}
|
|
3524
|
+
/**
|
|
3525
|
+
* Returns an empty rect object. An empty rect is returned when an element
|
|
3526
|
+
* is not in the DOM.
|
|
3527
|
+
* @return {Object} The empty rect.
|
|
3528
|
+
*/
|
|
3529
|
+
function getEmptyRect() {
|
|
3530
|
+
return {
|
|
3531
|
+
top: 0,
|
|
3532
|
+
bottom: 0,
|
|
3533
|
+
left: 0,
|
|
3534
|
+
right: 0,
|
|
3535
|
+
width: 0,
|
|
3536
|
+
height: 0
|
|
3537
|
+
};
|
|
3538
|
+
}
|
|
3539
|
+
/**
|
|
3540
|
+
* Checks to see if a parent element contains a child element (including inside
|
|
3541
|
+
* shadow DOM).
|
|
3542
|
+
* @param {Node} parent The parent element.
|
|
3543
|
+
* @param {Node} child The child element.
|
|
3544
|
+
* @return {boolean} True if the parent node contains the child node.
|
|
3545
|
+
*/
|
|
3546
|
+
function containsDeep(parent, child) {
|
|
3547
|
+
let node = child;
|
|
3548
|
+
while (node) {
|
|
3549
|
+
if (node == parent) return true;
|
|
3550
|
+
node = getParentNode(node);
|
|
3551
|
+
}
|
|
3552
|
+
return false;
|
|
3553
|
+
}
|
|
3554
|
+
/**
|
|
3555
|
+
* Gets the parent node of an element or its host element if the parent node
|
|
3556
|
+
* is a shadow root.
|
|
3557
|
+
* @param {Node} node The node whose parent to get.
|
|
3558
|
+
* @return {Node|null} The parent node or null if no parent exists.
|
|
3559
|
+
*/
|
|
3560
|
+
function getParentNode(node) {
|
|
3561
|
+
const parent = node.parentNode;
|
|
3562
|
+
if (parent && parent.nodeType == 11 && parent.host) return parent.host;
|
|
3563
|
+
if (parent && parent.assignedSlot) return parent.assignedSlot.parentNode;
|
|
3564
|
+
return parent;
|
|
3565
|
+
}
|
|
3566
|
+
window.IntersectionObserver = IntersectionObserver;
|
|
3567
|
+
window.IntersectionObserverEntry = IntersectionObserverEntry;
|
|
3568
|
+
}
|
|
3569
|
+
//#endregion
|
|
3570
|
+
//#region src/polyfill/object.ts
|
|
3571
|
+
function handleObjectAssignPolyfill() {
|
|
3572
|
+
if (!isFunction(Object.assign)) Object.assign = function(target) {
|
|
3573
|
+
if (target == null) throw new TypeError("Cannot convert undefined or null to object");
|
|
3574
|
+
const to = Object(target);
|
|
3575
|
+
for (let index = 1; index < arguments.length; index++) {
|
|
3576
|
+
const nextSource = arguments[index];
|
|
3577
|
+
if (nextSource != null) {
|
|
3578
|
+
for (const nextKey in nextSource) if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) to[nextKey] = nextSource[nextKey];
|
|
3579
|
+
}
|
|
3580
|
+
}
|
|
3581
|
+
return to;
|
|
3582
|
+
};
|
|
3583
|
+
}
|
|
3584
|
+
function handleObjectEntriesPolyfill() {
|
|
3585
|
+
if (!isFunction(Object.entries)) Object.entries = function(obj) {
|
|
3586
|
+
if (obj == null) throw new TypeError("Cannot convert undefined or null to object");
|
|
3587
|
+
const to = [];
|
|
3588
|
+
if (obj != null) {
|
|
3589
|
+
for (const key in obj) if (Object.prototype.hasOwnProperty.call(obj, key)) to.push([key, obj[key]]);
|
|
3590
|
+
}
|
|
3591
|
+
return to;
|
|
3592
|
+
};
|
|
3593
|
+
}
|
|
3594
|
+
function handleObjectDefinePropertyPolyfill() {
|
|
3595
|
+
if (!isFunction(Object.defineProperties)) Object.defineProperties = function(obj, properties) {
|
|
3596
|
+
function convertToDescriptor(desc) {
|
|
3597
|
+
function hasProperty(obj, prop) {
|
|
3598
|
+
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|
3599
|
+
}
|
|
3600
|
+
if (!isObject(desc)) throw new TypeError("bad desc");
|
|
3601
|
+
const d = {};
|
|
3602
|
+
if (hasProperty(desc, "enumerable")) d.enumerable = !!desc.enumerable;
|
|
3603
|
+
if (hasProperty(desc, "configurable")) d.configurable = !!desc.configurable;
|
|
3604
|
+
if (hasProperty(desc, "value")) d.value = desc.value;
|
|
3605
|
+
if (hasProperty(desc, "writable")) d.writable = !!desc.writable;
|
|
3606
|
+
if (hasProperty(desc, "get")) {
|
|
3607
|
+
const g = desc.get;
|
|
3608
|
+
if (!isFunction(g) && !isUndefined(g)) throw new TypeError("bad get");
|
|
3609
|
+
d.get = g;
|
|
3610
|
+
}
|
|
3611
|
+
if (hasProperty(desc, "set")) {
|
|
3612
|
+
const s = desc.set;
|
|
3613
|
+
if (!isFunction(s) && !isUndefined(s)) throw new TypeError("bad set");
|
|
3614
|
+
d.set = s;
|
|
3615
|
+
}
|
|
3616
|
+
if (("get" in d || "set" in d) && ("value" in d || "writable" in d)) throw new TypeError("identity-confused descriptor");
|
|
3617
|
+
return d;
|
|
3618
|
+
}
|
|
3619
|
+
if (!isObject(obj)) throw new TypeError("bad obj");
|
|
3620
|
+
properties = Object(properties);
|
|
3621
|
+
const keys = Object.keys(properties);
|
|
3622
|
+
const descs = [];
|
|
3623
|
+
for (let i = 0; i < keys.length; i++) descs.push([keys[i], convertToDescriptor(properties[keys[i]])]);
|
|
3624
|
+
for (let i = 0; i < descs.length; i++) Object.defineProperty(obj, descs[i][0], descs[i][1]);
|
|
3625
|
+
return obj;
|
|
3626
|
+
};
|
|
3627
|
+
}
|
|
3628
|
+
//#endregion
|
|
3629
|
+
//#region src/polyfill/index.ts
|
|
3630
|
+
function handlePolyfill() {
|
|
3631
|
+
if (process.env.SUPPORT_TARO_POLYFILL === "enabled" || process.env.SUPPORT_TARO_POLYFILL === "Object" || process.env.SUPPORT_TARO_POLYFILL === "Object.assign") handleObjectAssignPolyfill();
|
|
3632
|
+
if (process.env.SUPPORT_TARO_POLYFILL === "enabled" || process.env.SUPPORT_TARO_POLYFILL === "Object" || process.env.SUPPORT_TARO_POLYFILL === "Object.entries") handleObjectEntriesPolyfill();
|
|
3633
|
+
if (process.env.SUPPORT_TARO_POLYFILL === "enabled" || process.env.SUPPORT_TARO_POLYFILL === "Object" || process.env.SUPPORT_TARO_POLYFILL === "Object.defineProperty") handleObjectDefinePropertyPolyfill();
|
|
3634
|
+
if (process.env.SUPPORT_TARO_POLYFILL === "enabled" || process.env.SUPPORT_TARO_POLYFILL === "Array" || process.env.SUPPORT_TARO_POLYFILL === "Array.find") handleArrayFindPolyfill();
|
|
3635
|
+
if (process.env.SUPPORT_TARO_POLYFILL === "enabled" || process.env.SUPPORT_TARO_POLYFILL === "Array" || process.env.SUPPORT_TARO_POLYFILL === "Array.includes") handleArrayIncludesPolyfill();
|
|
3636
|
+
if (process.env.TARO_PLATFORM === "web" && isObject(window)) {
|
|
3637
|
+
if (process.env.SUPPORT_TARO_POLYFILL === "enabled" || process.env.SUPPORT_TARO_POLYFILL === "IntersectionObserver") handleIntersectionObserverPolyfill();
|
|
3638
|
+
}
|
|
3639
|
+
}
|
|
3640
|
+
if (process.env.SUPPORT_TARO_POLYFILL !== "disabled" && process.env.TARO_PLATFORM !== "web") handlePolyfill();
|
|
3641
|
+
//#endregion
|
|
3642
|
+
export { A, APP, BEHAVIORS, BODY, CATCHMOVE, CATCH_VIEW, CHANGE, CLASS, CLICK_VIEW, COMMENT, COMPILE_MODE, CONFIRM, CONTAINER, CONTEXT_ACTIONS, CURRENT_TARGET, CUSTOM_WRAPPER, Current, DATASET, DATE, DOCUMENT_ELEMENT_NAME, DOCUMENT_FRAGMENT, EVENT_CALLBACK_RESULT, EXTERNAL_CLASSES, Events, FOCUS, FormElement, HEAD, HOOKS_APP_ID, HTML, History, ID, INPUT, KEY_CODE, Location, MutationObserver$1 as MutationObserver, OBJECT, ON_HIDE, ON_LOAD, ON_READY, ON_SHOW, OPTIONS, PAGE_INIT, PROPERTY_THRESHOLD, PROPS, PURE_VIEW, ROOT_STR, SET_DATA, SET_TIMEOUT, STATIC_VIEW, STYLE, SVGElement, Style, TARGET, TARO_RUNTIME, TIME_STAMP, TOUCHMOVE, TYPE, TaroElement, TaroEvent, TaroNode, TaroRootElement, TaroText, UID, TaroURLProvider as URL, URLSearchParams, VALUE, VIEW, addLeadingSlash, _caf as cancelAnimationFrame, convertNumber2PX, createComponentConfig, createEvent, createPageConfig, createRecursiveComponentConfig, customWrapperCache, debounce, taroDocumentProvider as document, env, eventCenter, eventHandler, eventHandlerTTDom, eventSource, extend, getComponentsAlias, taroGetComputedStyleProvider as getComputedStyle, getCurrentInstance, getCurrentPage, getHomePage, getOnHideEventKey, getOnReadyEventKey, getOnShowEventKey, getPageInstance, getPath, handlePolyfill, hasBasename, taroHistoryProvider as history, hooks, hydrate, incrementId, injectPageInstance, isComment, isElement, isHasExtractProp, isParentBound, isText, taroLocationProvider as location, nav as navigator, nextTick, now, options, parseUrl, perf, removePageInstance, _raf as requestAnimationFrame, safeExecute, shortcutAttr, stringify, stripBasename, stripSuffix, stripTrailing, throttle, taroWindowProvider as window };
|
|
3643
|
+
|
|
3644
|
+
//# sourceMappingURL=runtime.esm.js.map
|