@tarojs/runtime 3.7.0-alpha.2 → 3.7.0-alpha.3
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/dist/runtime.cjs.d.ts +710 -0
- package/dist/runtime.cjs.js +4491 -0
- package/dist/runtime.esm.d.ts +20 -13
- package/dist/runtime.esm.js +133 -53
- package/dist/runtime.esm.js.map +1 -1
- package/dist/runtime.h5.d.ts +710 -0
- package/dist/runtime.h5.js +3249 -0
- package/package.json +11 -6
- package/dist/bom/URL.d.ts +0 -61
- package/dist/bom/URLSearchParams.d.ts +0 -14
- package/dist/bom/document.d.ts +0 -2
- package/dist/bom/getComputedStyle.d.ts +0 -3
- package/dist/bom/history.d.ts +0 -29
- package/dist/bom/location.d.ts +0 -36
- package/dist/bom/navigator.d.ts +0 -1
- package/dist/bom/raf.d.ts +0 -5
- package/dist/bom/window.d.ts +0 -4
- package/dist/constants/index.d.ts +0 -58
- package/dist/current.d.ts +0 -19
- package/dist/dom/anchor-element.d.ts +0 -13
- package/dist/dom/class-list.d.ts +0 -14
- package/dist/dom/custom-wrapper.d.ts +0 -4
- package/dist/dom/document.d.ts +0 -20
- package/dist/dom/element.d.ts +0 -38
- package/dist/dom/event-source.d.ts +0 -7
- package/dist/dom/event-target.d.ts +0 -7
- package/dist/dom/event.d.ts +0 -23
- package/dist/dom/form.d.ts +0 -7
- package/dist/dom/node.d.ts +0 -75
- package/dist/dom/node_types.d.ts +0 -10
- package/dist/dom/root.d.ts +0 -15
- package/dist/dom/style.d.ts +0 -14
- package/dist/dom/style_properties.d.ts +0 -3
- package/dist/dom/svg.d.ts +0 -3
- package/dist/dom/text.d.ts +0 -14
- package/dist/dom/tree.d.ts +0 -4
- package/dist/dom-external/element.d.ts +0 -3
- package/dist/dom-external/index.d.ts +0 -1
- package/dist/dom-external/inner-html/html.d.ts +0 -2
- package/dist/dom-external/inner-html/parser.d.ts +0 -25
- package/dist/dom-external/inner-html/scaner.d.ts +0 -30
- package/dist/dom-external/inner-html/style.d.ts +0 -27
- package/dist/dom-external/inner-html/tags.d.ts +0 -8
- package/dist/dom-external/inner-html/utils.d.ts +0 -1
- package/dist/dom-external/mutation-observer/implements.d.ts +0 -52
- package/dist/dom-external/mutation-observer/index.d.ts +0 -13
- package/dist/dom-external/mutation-observer/record.d.ts +0 -24
- package/dist/dom-external/node.d.ts +0 -11
- package/dist/dsl/common.d.ts +0 -16
- package/dist/dsl/instance.d.ts +0 -87
- package/dist/emitter/emitter.d.ts +0 -4
- package/dist/env.d.ts +0 -7
- package/dist/hydrate.d.ts +0 -10
- package/dist/index.d.ts +0 -30
- package/dist/interface/element.d.ts +0 -4
- package/dist/interface/event-target.d.ts +0 -10
- package/dist/interface/event.d.ts +0 -15
- package/dist/interface/hydrate.d.ts +0 -30
- package/dist/interface/index.d.ts +0 -7
- package/dist/interface/node.d.ts +0 -7
- package/dist/interface/options.d.ts +0 -16
- package/dist/interface/utils.d.ts +0 -2
- package/dist/next-tick.d.ts +0 -2
- package/dist/options.d.ts +0 -2
- package/dist/perf.d.ts +0 -7
- package/dist/utils/cache.d.ts +0 -12
- package/dist/utils/index.d.ts +0 -23
|
@@ -0,0 +1,3249 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var shared = require('@tarojs/shared');
|
|
4
|
+
|
|
5
|
+
const PROPERTY_THRESHOLD = 2046;
|
|
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 VALUE = 'value';
|
|
25
|
+
const INPUT = 'input';
|
|
26
|
+
const CHANGE = 'change';
|
|
27
|
+
const CUSTOM_WRAPPER = 'custom-wrapper';
|
|
28
|
+
const TARGET = 'target';
|
|
29
|
+
const CURRENT_TARGET = 'currentTarget';
|
|
30
|
+
const TYPE = 'type';
|
|
31
|
+
const CONFIRM = 'confirm';
|
|
32
|
+
const TIME_STAMP = 'timeStamp';
|
|
33
|
+
const KEY_CODE = 'keyCode';
|
|
34
|
+
const TOUCHMOVE = 'touchmove';
|
|
35
|
+
const CATCHMOVE = 'catchMove';
|
|
36
|
+
const CATCH_VIEW = 'catch-view';
|
|
37
|
+
const COMMENT = 'comment';
|
|
38
|
+
const ON_LOAD = 'onLoad';
|
|
39
|
+
const ON_READY = 'onReady';
|
|
40
|
+
const ON_SHOW = 'onShow';
|
|
41
|
+
const ON_HIDE = 'onHide';
|
|
42
|
+
const OPTIONS = 'options';
|
|
43
|
+
const EXTERNAL_CLASSES = 'externalClasses';
|
|
44
|
+
const EVENT_CALLBACK_RESULT = 'e_result';
|
|
45
|
+
const BEHAVIORS = 'behaviors';
|
|
46
|
+
const A = 'a';
|
|
47
|
+
/**
|
|
48
|
+
* 页面上下文切换时的行为
|
|
49
|
+
*/
|
|
50
|
+
var CONTEXT_ACTIONS;
|
|
51
|
+
(function (CONTEXT_ACTIONS) {
|
|
52
|
+
CONTEXT_ACTIONS["INIT"] = "0";
|
|
53
|
+
CONTEXT_ACTIONS["RESTORE"] = "1";
|
|
54
|
+
CONTEXT_ACTIONS["RECOVER"] = "2";
|
|
55
|
+
CONTEXT_ACTIONS["DESTORY"] = "3";
|
|
56
|
+
})(CONTEXT_ACTIONS || (CONTEXT_ACTIONS = {}));
|
|
57
|
+
|
|
58
|
+
const observers = [];
|
|
59
|
+
/** Match two TaroNodes by sid. */
|
|
60
|
+
const sidMatches = (observerTarget, target) => {
|
|
61
|
+
return !!observerTarget && observerTarget.sid === (target === null || target === void 0 ? void 0 : target.sid);
|
|
62
|
+
};
|
|
63
|
+
const isConcerned = (record, options) => {
|
|
64
|
+
const { characterData, characterDataOldValue, attributes, attributeOldValue, childList } = options;
|
|
65
|
+
switch (record.type) {
|
|
66
|
+
case "characterData" /* MutationRecordType.CHARACTER_DATA */:
|
|
67
|
+
if (characterData) {
|
|
68
|
+
if (!characterDataOldValue)
|
|
69
|
+
record.oldValue = null;
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
case "attributes" /* MutationRecordType.ATTRIBUTES */:
|
|
74
|
+
if (attributes) {
|
|
75
|
+
if (!attributeOldValue)
|
|
76
|
+
record.oldValue = null;
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
return false;
|
|
80
|
+
case "childList" /* MutationRecordType.CHILD_LIST */:
|
|
81
|
+
if (childList) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
let pendingMuatations = false;
|
|
88
|
+
function logMutation(observer, record) {
|
|
89
|
+
observer.records.push(record);
|
|
90
|
+
if (!pendingMuatations) {
|
|
91
|
+
pendingMuatations = true;
|
|
92
|
+
Promise
|
|
93
|
+
.resolve()
|
|
94
|
+
.then(() => {
|
|
95
|
+
pendingMuatations = false;
|
|
96
|
+
observers.forEach(observer => {
|
|
97
|
+
return observer.callback(observer.takeRecords());
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function recordMutation(record) {
|
|
103
|
+
observers.forEach(observer => {
|
|
104
|
+
const { options } = observer;
|
|
105
|
+
for (let t = record.target; t; t = t.parentNode) {
|
|
106
|
+
if (sidMatches(observer.target, t) && isConcerned(record, options)) {
|
|
107
|
+
logMutation(observer, record);
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
if (!options.subtree)
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
class MutationObserver {
|
|
117
|
+
constructor(callback) {
|
|
118
|
+
{
|
|
119
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
120
|
+
console.warn('[Taro Warning] 若要使用 MutationObserver,请在 Taro 编译配置中设置 \'mini.enableMutationObserver: true\'');
|
|
121
|
+
}
|
|
122
|
+
this.core = {
|
|
123
|
+
observe: shared.noop,
|
|
124
|
+
disconnect: shared.noop,
|
|
125
|
+
takeRecords: shared.noop
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
observe(...args) {
|
|
130
|
+
this.core.observe(...args);
|
|
131
|
+
}
|
|
132
|
+
disconnect() {
|
|
133
|
+
this.core.disconnect();
|
|
134
|
+
}
|
|
135
|
+
takeRecords() {
|
|
136
|
+
return this.core.takeRecords();
|
|
137
|
+
}
|
|
138
|
+
static record(record) {
|
|
139
|
+
recordMutation(record);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const incrementId = () => {
|
|
144
|
+
const chatCodes = [];
|
|
145
|
+
// A-Z
|
|
146
|
+
for (let i = 65; i <= 90; i++) {
|
|
147
|
+
chatCodes.push(i);
|
|
148
|
+
}
|
|
149
|
+
// a-z
|
|
150
|
+
for (let i = 97; i <= 122; i++) {
|
|
151
|
+
chatCodes.push(i);
|
|
152
|
+
}
|
|
153
|
+
const chatCodesLen = chatCodes.length - 1;
|
|
154
|
+
const list = [0, 0];
|
|
155
|
+
return () => {
|
|
156
|
+
const target = list.map(item => chatCodes[item]);
|
|
157
|
+
const res = String.fromCharCode(...target);
|
|
158
|
+
let tailIdx = list.length - 1;
|
|
159
|
+
list[tailIdx]++;
|
|
160
|
+
while (list[tailIdx] > chatCodesLen) {
|
|
161
|
+
list[tailIdx] = 0;
|
|
162
|
+
tailIdx = tailIdx - 1;
|
|
163
|
+
if (tailIdx < 0) {
|
|
164
|
+
list.push(0);
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
list[tailIdx]++;
|
|
168
|
+
}
|
|
169
|
+
return res;
|
|
170
|
+
};
|
|
171
|
+
};
|
|
172
|
+
function isElement(node) {
|
|
173
|
+
return node.nodeType === 1 /* NodeType.ELEMENT_NODE */;
|
|
174
|
+
}
|
|
175
|
+
function isText(node) {
|
|
176
|
+
return node.nodeType === 3 /* NodeType.TEXT_NODE */;
|
|
177
|
+
}
|
|
178
|
+
function isComment(node) {
|
|
179
|
+
return node.nodeName === COMMENT;
|
|
180
|
+
}
|
|
181
|
+
function isHasExtractProp(el) {
|
|
182
|
+
const res = Object.keys(el.props).find(prop => {
|
|
183
|
+
return !(/^(class|style|id)$/.test(prop) || prop.startsWith('data-'));
|
|
184
|
+
});
|
|
185
|
+
return Boolean(res);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* 往上寻找组件树直到 root,寻找是否有祖先组件绑定了同类型的事件
|
|
189
|
+
* @param node 当前组件
|
|
190
|
+
* @param type 事件类型
|
|
191
|
+
*/
|
|
192
|
+
function isParentBinded(node, type) {
|
|
193
|
+
var _a;
|
|
194
|
+
let res = false;
|
|
195
|
+
while ((node === null || node === void 0 ? void 0 : node.parentElement) && node.parentElement._path !== ROOT_STR) {
|
|
196
|
+
if ((_a = node.parentElement.__handlers[type]) === null || _a === void 0 ? void 0 : _a.length) {
|
|
197
|
+
res = true;
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
node = node.parentElement;
|
|
201
|
+
}
|
|
202
|
+
return res;
|
|
203
|
+
}
|
|
204
|
+
function shortcutAttr(key) {
|
|
205
|
+
switch (key) {
|
|
206
|
+
case STYLE:
|
|
207
|
+
return "st" /* Shortcuts.Style */;
|
|
208
|
+
case ID:
|
|
209
|
+
return UID;
|
|
210
|
+
case CLASS:
|
|
211
|
+
return "cl" /* Shortcuts.Class */;
|
|
212
|
+
default:
|
|
213
|
+
return key;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
const customWrapperCache = new Map();
|
|
217
|
+
function extend(ctor, methodName, options) {
|
|
218
|
+
if (shared.isFunction(options)) {
|
|
219
|
+
options = {
|
|
220
|
+
value: options
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
Object.defineProperty(ctor.prototype, methodName, Object.assign({ configurable: true, enumerable: true }, options));
|
|
224
|
+
}
|
|
225
|
+
let componentsAlias$1;
|
|
226
|
+
function getComponentsAlias() {
|
|
227
|
+
if (!componentsAlias$1) {
|
|
228
|
+
componentsAlias$1 = shared.getComponentsAlias(shared.internalComponents);
|
|
229
|
+
}
|
|
230
|
+
return componentsAlias$1;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
class ClassList {
|
|
234
|
+
constructor(className, el) {
|
|
235
|
+
this.tokenList = [];
|
|
236
|
+
this.el = el;
|
|
237
|
+
className.trim().split(/\s+/).forEach(token => this.tokenList.push(token));
|
|
238
|
+
}
|
|
239
|
+
get value() {
|
|
240
|
+
return this.toString();
|
|
241
|
+
}
|
|
242
|
+
get length() {
|
|
243
|
+
return this.tokenList.length;
|
|
244
|
+
}
|
|
245
|
+
add() {
|
|
246
|
+
let index = 0;
|
|
247
|
+
let updated = false;
|
|
248
|
+
const tokens = arguments;
|
|
249
|
+
const length = tokens.length;
|
|
250
|
+
const tokenList = this.tokenList;
|
|
251
|
+
do {
|
|
252
|
+
const token = tokens[index];
|
|
253
|
+
if (this.checkTokenIsValid(token) && !~tokenList.indexOf(token)) {
|
|
254
|
+
tokenList.push(token);
|
|
255
|
+
updated = true;
|
|
256
|
+
}
|
|
257
|
+
} while (++index < length);
|
|
258
|
+
if (updated) {
|
|
259
|
+
this._update();
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
remove() {
|
|
263
|
+
let i = 0;
|
|
264
|
+
let updated = false;
|
|
265
|
+
const tokens = arguments;
|
|
266
|
+
const length = tokens.length;
|
|
267
|
+
const tokenList = this.tokenList;
|
|
268
|
+
do {
|
|
269
|
+
const token = tokens[i] + '';
|
|
270
|
+
if (!this.checkTokenIsValid(token))
|
|
271
|
+
continue;
|
|
272
|
+
const index = tokenList.indexOf(token);
|
|
273
|
+
if (~tokenList.indexOf(token)) {
|
|
274
|
+
tokenList.splice(index, 1);
|
|
275
|
+
updated = true;
|
|
276
|
+
}
|
|
277
|
+
} while (++i < length);
|
|
278
|
+
if (updated) {
|
|
279
|
+
this._update();
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
contains(token) {
|
|
283
|
+
if (!this.checkTokenIsValid(token))
|
|
284
|
+
return false;
|
|
285
|
+
return !!~this.tokenList.indexOf(token);
|
|
286
|
+
}
|
|
287
|
+
toggle(token, force) {
|
|
288
|
+
const result = this.contains(token);
|
|
289
|
+
const method = result ? force !== true && 'remove' : force !== false && 'add';
|
|
290
|
+
if (method) {
|
|
291
|
+
// @ts-ignore
|
|
292
|
+
this[method](token);
|
|
293
|
+
}
|
|
294
|
+
if (force === true || force === false) {
|
|
295
|
+
return force;
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
return !result;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
replace(token, replacement_token) {
|
|
302
|
+
if (!this.checkTokenIsValid(token) || !this.checkTokenIsValid(replacement_token))
|
|
303
|
+
return;
|
|
304
|
+
const index = this.tokenList.indexOf(token);
|
|
305
|
+
if (~index) {
|
|
306
|
+
this.tokenList.splice(index, 1, replacement_token);
|
|
307
|
+
this._update();
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
toString() {
|
|
311
|
+
return this.tokenList.filter(v => v !== '').join(' ');
|
|
312
|
+
}
|
|
313
|
+
checkTokenIsValid(token) {
|
|
314
|
+
if (token === '' || /\s/.test(token))
|
|
315
|
+
return false;
|
|
316
|
+
return true;
|
|
317
|
+
}
|
|
318
|
+
_update() {
|
|
319
|
+
this.el.className = this.value;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
class EventSource extends Map {
|
|
324
|
+
removeNode(child) {
|
|
325
|
+
const { sid, uid } = child;
|
|
326
|
+
this.delete(sid);
|
|
327
|
+
if (uid !== sid && uid)
|
|
328
|
+
this.delete(uid);
|
|
329
|
+
}
|
|
330
|
+
removeNodeTree(child) {
|
|
331
|
+
this.removeNode(child);
|
|
332
|
+
const { childNodes } = child;
|
|
333
|
+
childNodes.forEach(node => this.removeNodeTree(node));
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
const eventSource = new EventSource();
|
|
337
|
+
|
|
338
|
+
const env = {
|
|
339
|
+
window: window ,
|
|
340
|
+
document: document
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
let SPECIAL_NODES;
|
|
344
|
+
let componentsAlias;
|
|
345
|
+
/**
|
|
346
|
+
* React also has a fancy function's name for this: `hydrate()`.
|
|
347
|
+
* You may have been heard `hydrate` as a SSR-related function,
|
|
348
|
+
* actually, `hydrate` basicly do the `render()` thing, but ignore some properties,
|
|
349
|
+
* it's a vnode traverser and modifier: that's exactly what Taro's doing in here.
|
|
350
|
+
*/
|
|
351
|
+
function hydrate(node) {
|
|
352
|
+
if (!componentsAlias) {
|
|
353
|
+
// 初始化 componentsAlias
|
|
354
|
+
componentsAlias = getComponentsAlias();
|
|
355
|
+
}
|
|
356
|
+
if (!SPECIAL_NODES) {
|
|
357
|
+
// 初始化 SPECIAL_NODES
|
|
358
|
+
SPECIAL_NODES = shared.hooks.call('getSpecialNodes');
|
|
359
|
+
}
|
|
360
|
+
const nodeName = node.nodeName;
|
|
361
|
+
if (isText(node)) {
|
|
362
|
+
return {
|
|
363
|
+
["v" /* Shortcuts.Text */]: node.nodeValue,
|
|
364
|
+
["nn" /* Shortcuts.NodeName */]: componentsAlias[nodeName]._num
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
const data = {
|
|
368
|
+
["nn" /* Shortcuts.NodeName */]: nodeName,
|
|
369
|
+
sid: node.sid
|
|
370
|
+
};
|
|
371
|
+
if (node.uid !== node.sid) {
|
|
372
|
+
data.uid = node.uid;
|
|
373
|
+
}
|
|
374
|
+
if (!node.isAnyEventBinded() && SPECIAL_NODES.indexOf(nodeName) > -1) {
|
|
375
|
+
data["nn" /* Shortcuts.NodeName */] = `static-${nodeName}`;
|
|
376
|
+
if (nodeName === VIEW && !isHasExtractProp(node)) {
|
|
377
|
+
data["nn" /* Shortcuts.NodeName */] = PURE_VIEW;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
const { props } = node;
|
|
381
|
+
for (const prop in props) {
|
|
382
|
+
const propInCamelCase = shared.toCamelCase(prop);
|
|
383
|
+
if (!prop.startsWith('data-') && // 在 node.dataset 的数据
|
|
384
|
+
prop !== CLASS &&
|
|
385
|
+
prop !== STYLE &&
|
|
386
|
+
prop !== ID &&
|
|
387
|
+
propInCamelCase !== CATCHMOVE) {
|
|
388
|
+
data[propInCamelCase] = props[prop];
|
|
389
|
+
}
|
|
390
|
+
if (nodeName === VIEW && propInCamelCase === CATCHMOVE && props[prop] !== false) {
|
|
391
|
+
data["nn" /* Shortcuts.NodeName */] = CATCH_VIEW;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
let { childNodes } = node;
|
|
395
|
+
// 过滤 comment 节点
|
|
396
|
+
childNodes = childNodes.filter(node => !isComment(node));
|
|
397
|
+
if (childNodes.length > 0) {
|
|
398
|
+
data["cn" /* Shortcuts.Childnodes */] = childNodes.map(hydrate);
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
data["cn" /* Shortcuts.Childnodes */] = [];
|
|
402
|
+
}
|
|
403
|
+
if (node.className !== '') {
|
|
404
|
+
data["cl" /* Shortcuts.Class */] = node.className;
|
|
405
|
+
}
|
|
406
|
+
const cssText = node.cssText;
|
|
407
|
+
if (cssText !== '' && nodeName !== 'swiper-item') {
|
|
408
|
+
data["st" /* Shortcuts.Style */] = cssText;
|
|
409
|
+
}
|
|
410
|
+
shared.hooks.call('modifyHydrateData', data);
|
|
411
|
+
const nn = data["nn" /* Shortcuts.NodeName */];
|
|
412
|
+
const componentAlias = componentsAlias[nn];
|
|
413
|
+
if (componentAlias) {
|
|
414
|
+
data["nn" /* Shortcuts.NodeName */] = componentAlias._num;
|
|
415
|
+
for (const prop in data) {
|
|
416
|
+
if (prop in componentAlias) {
|
|
417
|
+
data[componentAlias[prop]] = data[prop];
|
|
418
|
+
delete data[prop];
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return data;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
class TaroEventTarget {
|
|
426
|
+
constructor() {
|
|
427
|
+
this.__handlers = {};
|
|
428
|
+
}
|
|
429
|
+
addEventListener(type, handler, options) {
|
|
430
|
+
type = type.toLowerCase();
|
|
431
|
+
shared.hooks.call('onAddEvent', type, handler, options, this);
|
|
432
|
+
if (type === 'regionchange') {
|
|
433
|
+
// map 组件的 regionchange 事件非常特殊,详情:https://github.com/NervJS/taro/issues/5766
|
|
434
|
+
this.addEventListener('begin', handler, options);
|
|
435
|
+
this.addEventListener('end', handler, options);
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
let isCapture = Boolean(options);
|
|
439
|
+
let isOnce = false;
|
|
440
|
+
if (shared.isObject(options)) {
|
|
441
|
+
isCapture = Boolean(options.capture);
|
|
442
|
+
isOnce = Boolean(options.once);
|
|
443
|
+
}
|
|
444
|
+
if (isOnce) {
|
|
445
|
+
const wrapper = function () {
|
|
446
|
+
handler.apply(this, arguments); // this 指向 Element
|
|
447
|
+
this.removeEventListener(type, wrapper);
|
|
448
|
+
};
|
|
449
|
+
this.addEventListener(type, wrapper, Object.assign(Object.assign({}, options), { once: false }));
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
process.env.NODE_ENV !== 'production' && shared.warn(isCapture, 'Taro 暂未实现 event 的 capture 特性。');
|
|
453
|
+
// 某些框架,如 PReact 有委托的机制,handler 始终是同一个函数
|
|
454
|
+
// 这会导致多层停止冒泡失败:view -> view(handler.stop = false) -> view(handler.stop = true)
|
|
455
|
+
// 这样解决:view -> view(handlerA.stop = false) -> view(handlerB.stop = false)
|
|
456
|
+
// 因此每次绑定事件都新建一个函数,如果带来了性能问题,可以把这段逻辑抽取到 PReact 插件中。
|
|
457
|
+
const oldHandler = handler;
|
|
458
|
+
handler = function () {
|
|
459
|
+
return oldHandler.apply(this, arguments); // this 指向 Element
|
|
460
|
+
};
|
|
461
|
+
handler.oldHandler = oldHandler;
|
|
462
|
+
const handlers = this.__handlers[type];
|
|
463
|
+
if (shared.isArray(handlers)) {
|
|
464
|
+
handlers.push(handler);
|
|
465
|
+
}
|
|
466
|
+
else {
|
|
467
|
+
this.__handlers[type] = [handler];
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
removeEventListener(type, handler) {
|
|
471
|
+
type = type.toLowerCase();
|
|
472
|
+
if (type === 'regionchange') {
|
|
473
|
+
// map 组件的 regionchange 事件非常特殊,详情:https://github.com/NervJS/taro/issues/5766
|
|
474
|
+
this.removeEventListener('begin', handler);
|
|
475
|
+
this.removeEventListener('end', handler);
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
if (!handler) {
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
const handlers = this.__handlers[type];
|
|
482
|
+
if (!shared.isArray(handlers)) {
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
const index = handlers.findIndex(item => {
|
|
486
|
+
if (item === handler || item.oldHandler === handler)
|
|
487
|
+
return true;
|
|
488
|
+
});
|
|
489
|
+
process.env.NODE_ENV !== 'production' && shared.warn(index === -1, `事件: '${type}' 没有注册在 DOM 中,因此不会被移除。`);
|
|
490
|
+
handlers.splice(index, 1);
|
|
491
|
+
}
|
|
492
|
+
isAnyEventBinded() {
|
|
493
|
+
const handlers = this.__handlers;
|
|
494
|
+
const isAnyEventBinded = Object.keys(handlers).find(key => handlers[key].length);
|
|
495
|
+
return Boolean(isAnyEventBinded);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
const CHILDNODES = "cn" /* Shortcuts.Childnodes */;
|
|
500
|
+
const nodeId = incrementId();
|
|
501
|
+
class TaroNode extends TaroEventTarget {
|
|
502
|
+
constructor() {
|
|
503
|
+
super();
|
|
504
|
+
this.parentNode = null;
|
|
505
|
+
this.childNodes = [];
|
|
506
|
+
this.hydrate = (node) => () => hydrate(node);
|
|
507
|
+
this.uid = '_' + nodeId(); // dom 节点 id,开发者可修改
|
|
508
|
+
this.sid = this.uid; // dom 节点全局唯一 id,不可被修改
|
|
509
|
+
eventSource.set(this.sid, this);
|
|
510
|
+
}
|
|
511
|
+
updateChildNodes(isClean) {
|
|
512
|
+
const cleanChildNodes = () => [];
|
|
513
|
+
const rerenderChildNodes = () => {
|
|
514
|
+
const childNodes = this.childNodes.filter(node => !isComment(node));
|
|
515
|
+
return childNodes.map(hydrate);
|
|
516
|
+
};
|
|
517
|
+
this.enqueueUpdate({
|
|
518
|
+
path: `${this._path}.${CHILDNODES}`,
|
|
519
|
+
value: isClean ? cleanChildNodes : rerenderChildNodes
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
get _root() {
|
|
523
|
+
var _a;
|
|
524
|
+
return ((_a = this.parentNode) === null || _a === void 0 ? void 0 : _a._root) || null;
|
|
525
|
+
}
|
|
526
|
+
findIndex(refChild) {
|
|
527
|
+
const index = this.childNodes.indexOf(refChild);
|
|
528
|
+
shared.ensure(index !== -1, 'The node to be replaced is not a child of this node.');
|
|
529
|
+
return index;
|
|
530
|
+
}
|
|
531
|
+
get _path() {
|
|
532
|
+
const parentNode = this.parentNode;
|
|
533
|
+
if (parentNode) {
|
|
534
|
+
// 计算路径时,先过滤掉 comment 节点
|
|
535
|
+
const list = parentNode.childNodes.filter(node => !isComment(node));
|
|
536
|
+
const indexOfNode = list.indexOf(this);
|
|
537
|
+
const index = shared.hooks.call('getPathIndex', indexOfNode);
|
|
538
|
+
return `${parentNode._path}.${CHILDNODES}.${index}`;
|
|
539
|
+
}
|
|
540
|
+
return '';
|
|
541
|
+
}
|
|
542
|
+
get nextSibling() {
|
|
543
|
+
const parentNode = this.parentNode;
|
|
544
|
+
return (parentNode === null || parentNode === void 0 ? void 0 : parentNode.childNodes[parentNode.findIndex(this) + 1]) || null;
|
|
545
|
+
}
|
|
546
|
+
get previousSibling() {
|
|
547
|
+
const parentNode = this.parentNode;
|
|
548
|
+
return (parentNode === null || parentNode === void 0 ? void 0 : parentNode.childNodes[parentNode.findIndex(this) - 1]) || null;
|
|
549
|
+
}
|
|
550
|
+
get parentElement() {
|
|
551
|
+
const parentNode = this.parentNode;
|
|
552
|
+
if ((parentNode === null || parentNode === void 0 ? void 0 : parentNode.nodeType) === 1 /* NodeType.ELEMENT_NODE */) {
|
|
553
|
+
return parentNode;
|
|
554
|
+
}
|
|
555
|
+
return null;
|
|
556
|
+
}
|
|
557
|
+
get firstChild() {
|
|
558
|
+
return this.childNodes[0] || null;
|
|
559
|
+
}
|
|
560
|
+
get lastChild() {
|
|
561
|
+
const childNodes = this.childNodes;
|
|
562
|
+
return childNodes[childNodes.length - 1] || null;
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* @textContent 目前只能置空子元素
|
|
566
|
+
* @TODO 等待完整 innerHTML 实现
|
|
567
|
+
*/
|
|
568
|
+
// eslint-disable-next-line accessor-pairs
|
|
569
|
+
set textContent(text) {
|
|
570
|
+
const removedNodes = this.childNodes.slice();
|
|
571
|
+
const addedNodes = [];
|
|
572
|
+
// Handle old children' data structure & ref
|
|
573
|
+
while (this.firstChild) {
|
|
574
|
+
this.removeChild(this.firstChild, { doUpdate: false });
|
|
575
|
+
}
|
|
576
|
+
if (text === '') {
|
|
577
|
+
this.updateChildNodes(true);
|
|
578
|
+
}
|
|
579
|
+
else {
|
|
580
|
+
const newText = env.document.createTextNode(text);
|
|
581
|
+
addedNodes.push(newText);
|
|
582
|
+
this.appendChild(newText);
|
|
583
|
+
this.updateChildNodes();
|
|
584
|
+
}
|
|
585
|
+
// @Todo: appendChild 会多触发一次
|
|
586
|
+
MutationObserver.record({
|
|
587
|
+
type: "childList" /* MutationRecordType.CHILD_LIST */,
|
|
588
|
+
target: this,
|
|
589
|
+
removedNodes,
|
|
590
|
+
addedNodes
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* @doc https://developer.mozilla.org/zh-CN/docs/Web/API/Node/insertBefore
|
|
595
|
+
* @scenario
|
|
596
|
+
* [A,B,C]
|
|
597
|
+
* 1. insert D before C, D has no parent
|
|
598
|
+
* 2. insert D before C, D has the same parent of C
|
|
599
|
+
* 3. insert D before C, D has the different parent of C
|
|
600
|
+
*/
|
|
601
|
+
insertBefore(newChild, refChild, isReplace) {
|
|
602
|
+
if (newChild.nodeName === DOCUMENT_FRAGMENT) {
|
|
603
|
+
newChild.childNodes.reduceRight((previousValue, currentValue) => {
|
|
604
|
+
this.insertBefore(currentValue, previousValue);
|
|
605
|
+
return currentValue;
|
|
606
|
+
}, refChild);
|
|
607
|
+
return newChild;
|
|
608
|
+
}
|
|
609
|
+
// Parent release newChild
|
|
610
|
+
// - cleanRef: false (No need to clean eventSource, because newChild is about to be inserted)
|
|
611
|
+
// - update: true (Need to update parent.childNodes, because parent.childNodes is reordered)
|
|
612
|
+
newChild.remove({ cleanRef: false });
|
|
613
|
+
// Data structure
|
|
614
|
+
newChild.parentNode = this;
|
|
615
|
+
if (refChild) {
|
|
616
|
+
// insertBefore & replaceChild
|
|
617
|
+
const index = this.findIndex(refChild);
|
|
618
|
+
this.childNodes.splice(index, 0, newChild);
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
// appendChild
|
|
622
|
+
this.childNodes.push(newChild);
|
|
623
|
+
}
|
|
624
|
+
// Serialization
|
|
625
|
+
if (this._root) {
|
|
626
|
+
if (!refChild) {
|
|
627
|
+
// appendChild
|
|
628
|
+
const isOnlyChild = this.childNodes.length === 1;
|
|
629
|
+
if (isOnlyChild) {
|
|
630
|
+
this.updateChildNodes();
|
|
631
|
+
}
|
|
632
|
+
else {
|
|
633
|
+
this.enqueueUpdate({
|
|
634
|
+
path: newChild._path,
|
|
635
|
+
value: this.hydrate(newChild)
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
else if (isReplace) {
|
|
640
|
+
// replaceChild
|
|
641
|
+
this.enqueueUpdate({
|
|
642
|
+
path: newChild._path,
|
|
643
|
+
value: this.hydrate(newChild)
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
else {
|
|
647
|
+
// insertBefore
|
|
648
|
+
this.updateChildNodes();
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
MutationObserver.record({
|
|
652
|
+
type: "childList" /* MutationRecordType.CHILD_LIST */,
|
|
653
|
+
target: this,
|
|
654
|
+
addedNodes: [newChild],
|
|
655
|
+
removedNodes: isReplace
|
|
656
|
+
? [refChild] /** replaceChild */
|
|
657
|
+
: [],
|
|
658
|
+
nextSibling: isReplace
|
|
659
|
+
? refChild.nextSibling /** replaceChild */
|
|
660
|
+
: (refChild || null),
|
|
661
|
+
previousSibling: newChild.previousSibling
|
|
662
|
+
});
|
|
663
|
+
return newChild;
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* @doc https://developer.mozilla.org/zh-CN/docs/Web/API/Node/appendChild
|
|
667
|
+
* @scenario
|
|
668
|
+
* [A,B,C]
|
|
669
|
+
* 1. append C, C has no parent
|
|
670
|
+
* 2. append C, C has the same parent of B
|
|
671
|
+
* 3. append C, C has the different parent of B
|
|
672
|
+
*/
|
|
673
|
+
appendChild(newChild) {
|
|
674
|
+
return this.insertBefore(newChild);
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* @doc https://developer.mozilla.org/zh-CN/docs/Web/API/Node/replaceChild
|
|
678
|
+
* @scenario
|
|
679
|
+
* [A,B,C]
|
|
680
|
+
* 1. replace B with C, C has no parent
|
|
681
|
+
* 2. replace B with C, C has no parent, C has the same parent of B
|
|
682
|
+
* 3. replace B with C, C has no parent, C has the different parent of B
|
|
683
|
+
*/
|
|
684
|
+
replaceChild(newChild, oldChild) {
|
|
685
|
+
if (oldChild.parentNode !== this)
|
|
686
|
+
return;
|
|
687
|
+
// Insert the newChild
|
|
688
|
+
this.insertBefore(newChild, oldChild, true);
|
|
689
|
+
// Destroy the oldChild
|
|
690
|
+
// - cleanRef: true (Need to clean eventSource, because the oldChild was detached from the DOM tree)
|
|
691
|
+
// - update: false (No need to update parent.childNodes, because replace will not cause the parent.childNodes being reordered)
|
|
692
|
+
oldChild.remove({ doUpdate: false });
|
|
693
|
+
return oldChild;
|
|
694
|
+
}
|
|
695
|
+
/**
|
|
696
|
+
* @doc https://developer.mozilla.org/zh-CN/docs/Web/API/Node/removeChild
|
|
697
|
+
* @scenario
|
|
698
|
+
* [A,B,C]
|
|
699
|
+
* 1. remove A or B
|
|
700
|
+
* 2. remove C
|
|
701
|
+
*/
|
|
702
|
+
removeChild(child, options = {}) {
|
|
703
|
+
const { cleanRef, doUpdate } = options;
|
|
704
|
+
if (cleanRef !== false && doUpdate !== false) {
|
|
705
|
+
// appendChild/replaceChild/insertBefore 不应该触发
|
|
706
|
+
// @Todo: 但其实如果 newChild 的父节点是另一颗子树的节点,应该是要触发的
|
|
707
|
+
MutationObserver.record({
|
|
708
|
+
type: "childList" /* MutationRecordType.CHILD_LIST */,
|
|
709
|
+
target: this,
|
|
710
|
+
removedNodes: [child],
|
|
711
|
+
nextSibling: child.nextSibling,
|
|
712
|
+
previousSibling: child.previousSibling
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
// Data Structure
|
|
716
|
+
const index = this.findIndex(child);
|
|
717
|
+
this.childNodes.splice(index, 1);
|
|
718
|
+
child.parentNode = null;
|
|
719
|
+
// Set eventSource
|
|
720
|
+
if (cleanRef !== false) {
|
|
721
|
+
eventSource.removeNodeTree(child);
|
|
722
|
+
}
|
|
723
|
+
// Serialization
|
|
724
|
+
if (this._root && doUpdate !== false) {
|
|
725
|
+
this.updateChildNodes();
|
|
726
|
+
}
|
|
727
|
+
return child;
|
|
728
|
+
}
|
|
729
|
+
remove(options) {
|
|
730
|
+
var _a;
|
|
731
|
+
(_a = this.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(this, options);
|
|
732
|
+
}
|
|
733
|
+
hasChildNodes() {
|
|
734
|
+
return this.childNodes.length > 0;
|
|
735
|
+
}
|
|
736
|
+
enqueueUpdate(payload) {
|
|
737
|
+
var _a;
|
|
738
|
+
(_a = this._root) === null || _a === void 0 ? void 0 : _a.enqueueUpdate(payload);
|
|
739
|
+
}
|
|
740
|
+
get ownerDocument() {
|
|
741
|
+
return env.document;
|
|
742
|
+
}
|
|
743
|
+
static extend(methodName, options) {
|
|
744
|
+
extend(TaroNode, methodName, options);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
/*
|
|
749
|
+
*
|
|
750
|
+
* https://www.w3.org/Style/CSS/all-properties.en.html
|
|
751
|
+
*/
|
|
752
|
+
const WEBKIT = 'webkit';
|
|
753
|
+
const styleProperties = [
|
|
754
|
+
'all',
|
|
755
|
+
'appearance',
|
|
756
|
+
'blockOverflow',
|
|
757
|
+
'blockSize',
|
|
758
|
+
'bottom',
|
|
759
|
+
'clear',
|
|
760
|
+
'contain',
|
|
761
|
+
'content',
|
|
762
|
+
'continue',
|
|
763
|
+
'cursor',
|
|
764
|
+
'direction',
|
|
765
|
+
'display',
|
|
766
|
+
'filter',
|
|
767
|
+
'float',
|
|
768
|
+
'gap',
|
|
769
|
+
'height',
|
|
770
|
+
'inset',
|
|
771
|
+
'isolation',
|
|
772
|
+
'left',
|
|
773
|
+
'letterSpacing',
|
|
774
|
+
'lightingColor',
|
|
775
|
+
'markerSide',
|
|
776
|
+
'mixBlendMode',
|
|
777
|
+
'opacity',
|
|
778
|
+
'order',
|
|
779
|
+
'position',
|
|
780
|
+
'quotes',
|
|
781
|
+
'resize',
|
|
782
|
+
'right',
|
|
783
|
+
'rowGap',
|
|
784
|
+
'tabSize',
|
|
785
|
+
'tableLayout',
|
|
786
|
+
'top',
|
|
787
|
+
'userSelect',
|
|
788
|
+
'verticalAlign',
|
|
789
|
+
'visibility',
|
|
790
|
+
'voiceFamily',
|
|
791
|
+
'volume',
|
|
792
|
+
'whiteSpace',
|
|
793
|
+
'widows',
|
|
794
|
+
'width',
|
|
795
|
+
'zIndex',
|
|
796
|
+
'pointerEvents',
|
|
797
|
+
'aspectRatio'
|
|
798
|
+
/** 非常用 style */
|
|
799
|
+
// 'azimuth',
|
|
800
|
+
// 'backfaceVisibility',
|
|
801
|
+
// 'baselineShift',
|
|
802
|
+
// 'captionSide',
|
|
803
|
+
// 'chains',
|
|
804
|
+
// 'dominantBaseline',
|
|
805
|
+
// 'elevation',
|
|
806
|
+
// 'emptyCells',
|
|
807
|
+
// 'forcedColorAdjust',
|
|
808
|
+
// 'glyphOrientationVertical',
|
|
809
|
+
// 'hangingPunctuation',
|
|
810
|
+
// 'hyphenateCharacter',
|
|
811
|
+
// 'hyphens',
|
|
812
|
+
// 'imageOrientation',
|
|
813
|
+
// 'imageResolution',
|
|
814
|
+
// 'orphans',
|
|
815
|
+
// 'playDuring',
|
|
816
|
+
// 'pointerEvents',
|
|
817
|
+
// 'regionFragment',
|
|
818
|
+
// 'richness',
|
|
819
|
+
// 'running',
|
|
820
|
+
// 'scrollBehavior',
|
|
821
|
+
// 'speechRate',
|
|
822
|
+
// 'stress',
|
|
823
|
+
// 'stringSet',
|
|
824
|
+
// 'unicodeBidi',
|
|
825
|
+
// 'willChange',
|
|
826
|
+
// 'writingMode',
|
|
827
|
+
];
|
|
828
|
+
// 减少文件体积
|
|
829
|
+
function combine(prefix, list, excludeSelf) {
|
|
830
|
+
!excludeSelf && styleProperties.push(prefix);
|
|
831
|
+
list.forEach(item => {
|
|
832
|
+
styleProperties.push(prefix + item);
|
|
833
|
+
if (prefix === WEBKIT) {
|
|
834
|
+
styleProperties.push('Webkit' + item);
|
|
835
|
+
}
|
|
836
|
+
});
|
|
837
|
+
}
|
|
838
|
+
const color = 'Color';
|
|
839
|
+
const style = 'Style';
|
|
840
|
+
const width = 'Width';
|
|
841
|
+
const image = 'Image';
|
|
842
|
+
const size = 'Size';
|
|
843
|
+
const color_style_width = [color, style, width];
|
|
844
|
+
const fitlength_fitwidth_image = ['FitLength', 'FitWidth', image];
|
|
845
|
+
const fitlength_fitwidth_image_radius = [...fitlength_fitwidth_image, 'Radius'];
|
|
846
|
+
const color_style_width_fitlength_fitwidth_image = [...color_style_width, ...fitlength_fitwidth_image];
|
|
847
|
+
const endRadius_startRadius = ['EndRadius', 'StartRadius'];
|
|
848
|
+
const bottom_left_right_top = ['Bottom', 'Left', 'Right', 'Top'];
|
|
849
|
+
const end_start = ['End', 'Start'];
|
|
850
|
+
const content_items_self = ['Content', 'Items', 'Self'];
|
|
851
|
+
const blockSize_height_inlineSize_width = ['BlockSize', 'Height', 'InlineSize', width];
|
|
852
|
+
const after_before = ['After', 'Before'];
|
|
853
|
+
combine('borderBlock', color_style_width);
|
|
854
|
+
combine('borderBlockEnd', color_style_width);
|
|
855
|
+
combine('borderBlockStart', color_style_width);
|
|
856
|
+
combine('outline', [...color_style_width, 'Offset']);
|
|
857
|
+
combine('border', [...color_style_width, 'Boundary', 'Break', 'Collapse', 'Radius', 'Spacing']);
|
|
858
|
+
combine('borderFit', ['Length', width]);
|
|
859
|
+
combine('borderInline', color_style_width);
|
|
860
|
+
combine('borderInlineEnd', color_style_width);
|
|
861
|
+
combine('borderInlineStart', color_style_width);
|
|
862
|
+
combine('borderLeft', color_style_width_fitlength_fitwidth_image);
|
|
863
|
+
combine('borderRight', color_style_width_fitlength_fitwidth_image);
|
|
864
|
+
combine('borderTop', color_style_width_fitlength_fitwidth_image);
|
|
865
|
+
combine('borderBottom', color_style_width_fitlength_fitwidth_image);
|
|
866
|
+
combine('textDecoration', [color, style, 'Line']);
|
|
867
|
+
combine('textEmphasis', [color, style, 'Position']);
|
|
868
|
+
combine('scrollMargin', bottom_left_right_top);
|
|
869
|
+
combine('scrollPadding', bottom_left_right_top);
|
|
870
|
+
combine('padding', bottom_left_right_top);
|
|
871
|
+
combine('margin', [...bottom_left_right_top, 'Trim']);
|
|
872
|
+
combine('scrollMarginBlock', end_start);
|
|
873
|
+
combine('scrollMarginInline', end_start);
|
|
874
|
+
combine('scrollPaddingBlock', end_start);
|
|
875
|
+
combine('scrollPaddingInline', end_start);
|
|
876
|
+
combine('gridColumn', end_start);
|
|
877
|
+
combine('gridRow', end_start);
|
|
878
|
+
combine('insetBlock', end_start);
|
|
879
|
+
combine('insetInline', end_start);
|
|
880
|
+
combine('marginBlock', end_start);
|
|
881
|
+
combine('marginInline', end_start);
|
|
882
|
+
combine('paddingBlock', end_start);
|
|
883
|
+
combine('paddingInline', end_start);
|
|
884
|
+
combine('pause', after_before);
|
|
885
|
+
combine('cue', after_before);
|
|
886
|
+
combine('mask', ['Clip', 'Composite', image, 'Mode', 'Origin', 'Position', 'Repeat', size, 'Type']);
|
|
887
|
+
combine('borderImage', ['Outset', 'Repeat', 'Slice', 'Source', 'Transform', width]);
|
|
888
|
+
combine('maskBorder', ['Mode', 'Outset', 'Repeat', 'Slice', 'Source', width]);
|
|
889
|
+
combine('font', ['Family', 'FeatureSettings', 'Kerning', 'LanguageOverride', 'MaxSize', 'MinSize', 'OpticalSizing', 'Palette', size, 'SizeAdjust', 'Stretch', style, 'Weight', 'VariationSettings']);
|
|
890
|
+
combine('transform', ['Box', 'Origin', style]);
|
|
891
|
+
combine('background', [color, image, 'Attachment', 'BlendMode', 'Clip', 'Origin', 'Position', 'Repeat', size]);
|
|
892
|
+
combine('listStyle', [image, 'Position', 'Type']);
|
|
893
|
+
combine('scrollSnap', ['Align', 'Stop', 'Type']);
|
|
894
|
+
combine('grid', ['Area', 'AutoColumns', 'AutoFlow', 'AutoRows']);
|
|
895
|
+
combine('gridTemplate', ['Areas', 'Columns', 'Rows']);
|
|
896
|
+
combine('overflow', ['Block', 'Inline', 'Wrap', 'X', 'Y']);
|
|
897
|
+
combine('transition', ['Delay', 'Duration', 'Property', 'TimingFunction']);
|
|
898
|
+
combine('color', ['Adjust', 'InterpolationFilters', 'Scheme']);
|
|
899
|
+
combine('textAlign', ['All', 'Last']);
|
|
900
|
+
combine('page', ['BreakAfter', 'BreakBefore', 'BreakInside']);
|
|
901
|
+
combine('animation', ['Delay', 'Direction', 'Duration', 'FillMode', 'IterationCount', 'Name', 'PlayState', 'TimingFunction']);
|
|
902
|
+
combine('flex', ['Basis', 'Direction', 'Flow', 'Grow', 'Shrink', 'Wrap']);
|
|
903
|
+
combine('offset', [...after_before, ...end_start, 'Anchor', 'Distance', 'Path', 'Position', 'Rotate']);
|
|
904
|
+
combine('perspective', ['Origin']);
|
|
905
|
+
combine('clip', ['Path', 'Rule']);
|
|
906
|
+
combine('flow', ['From', 'Into']);
|
|
907
|
+
combine('align', ['Content', 'Items', 'Self'], true);
|
|
908
|
+
combine('alignment', ['Adjust', 'Baseline'], true);
|
|
909
|
+
combine('borderStart', endRadius_startRadius, true);
|
|
910
|
+
combine('borderEnd', endRadius_startRadius, true);
|
|
911
|
+
combine('borderCorner', ['Fit', image, 'ImageTransform'], true);
|
|
912
|
+
combine('borderTopLeft', fitlength_fitwidth_image_radius, true);
|
|
913
|
+
combine('borderTopRight', fitlength_fitwidth_image_radius, true);
|
|
914
|
+
combine('borderBottomLeft', fitlength_fitwidth_image_radius, true);
|
|
915
|
+
combine('borderBottomRight', fitlength_fitwidth_image_radius, true);
|
|
916
|
+
combine('column', ['s', 'Count', 'Fill', 'Gap', 'Rule', 'RuleColor', 'RuleStyle', 'RuleWidth', 'Span', width], true);
|
|
917
|
+
combine('break', [...after_before, 'Inside'], true);
|
|
918
|
+
combine('wrap', [...after_before, 'Flow', 'Inside', 'Through'], true);
|
|
919
|
+
combine('justify', content_items_self, true);
|
|
920
|
+
combine('place', content_items_self, true);
|
|
921
|
+
combine('max', [...blockSize_height_inlineSize_width, 'Lines'], true);
|
|
922
|
+
combine('min', blockSize_height_inlineSize_width, true);
|
|
923
|
+
combine('line', ['Break', 'Clamp', 'Grid', 'Height', 'Padding', 'Snap'], true);
|
|
924
|
+
combine('inline', ['BoxAlign', size, 'Sizing'], true);
|
|
925
|
+
combine('text', ['CombineUpright', 'GroupAlign', 'Height', 'Indent', 'Justify', 'Orientation', 'Overflow', 'Shadow', 'SpaceCollapse', 'SpaceTrim', 'Spacing', 'Transform', 'UnderlinePosition', 'Wrap'], true);
|
|
926
|
+
combine('shape', ['ImageThreshold', 'Inside', 'Margin', 'Outside'], true);
|
|
927
|
+
combine('word', ['Break', 'Spacing', 'Wrap'], true);
|
|
928
|
+
combine('object', ['Fit', 'Position'], true);
|
|
929
|
+
combine('box', ['DecorationBreak', 'Shadow', 'Sizing', 'Snap'], true);
|
|
930
|
+
combine(WEBKIT, ['LineClamp', 'BoxOrient', 'TextFillColor', 'TextStroke', 'TextStrokeColor', 'TextStrokeWidth'], true);
|
|
931
|
+
|
|
932
|
+
function recordCss(obj) {
|
|
933
|
+
MutationObserver.record({
|
|
934
|
+
type: "attributes" /* MutationRecordType.ATTRIBUTES */,
|
|
935
|
+
target: obj._element,
|
|
936
|
+
attributeName: 'style',
|
|
937
|
+
oldValue: obj.cssText
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
function enqueueUpdate(obj) {
|
|
941
|
+
const element = obj._element;
|
|
942
|
+
if (element._root) {
|
|
943
|
+
element.enqueueUpdate({
|
|
944
|
+
path: `${element._path}.${"st" /* Shortcuts.Style */}`,
|
|
945
|
+
value: obj.cssText
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
function setStyle(newVal, styleKey) {
|
|
950
|
+
process.env.NODE_ENV !== 'production' && shared.warn(shared.isString(newVal) && newVal.length > PROPERTY_THRESHOLD, `Style 属性 ${styleKey} 的值数据量过大,可能会影响渲染性能,考虑使用 CSS 类或其它方案替代。`);
|
|
951
|
+
const old = this[styleKey];
|
|
952
|
+
if (old === newVal)
|
|
953
|
+
return;
|
|
954
|
+
!this._pending && recordCss(this);
|
|
955
|
+
if (shared.isNull(newVal) || shared.isUndefined(newVal)) {
|
|
956
|
+
this._usedStyleProp.delete(styleKey);
|
|
957
|
+
delete this._value[styleKey];
|
|
958
|
+
}
|
|
959
|
+
else {
|
|
960
|
+
this._usedStyleProp.add(styleKey);
|
|
961
|
+
this._value[styleKey] = newVal;
|
|
962
|
+
}
|
|
963
|
+
!this._pending && enqueueUpdate(this);
|
|
964
|
+
}
|
|
965
|
+
function initStyle(ctor, styleProperties) {
|
|
966
|
+
const properties = {};
|
|
967
|
+
for (let i = 0; i < styleProperties.length; i++) {
|
|
968
|
+
const styleKey = styleProperties[i];
|
|
969
|
+
if (ctor[styleKey])
|
|
970
|
+
return;
|
|
971
|
+
properties[styleKey] = {
|
|
972
|
+
get() {
|
|
973
|
+
const val = this._value[styleKey];
|
|
974
|
+
return shared.isNull(val) || shared.isUndefined(val) ? '' : val;
|
|
975
|
+
},
|
|
976
|
+
set(newVal) {
|
|
977
|
+
setStyle.call(this, newVal, styleKey);
|
|
978
|
+
}
|
|
979
|
+
};
|
|
980
|
+
}
|
|
981
|
+
Object.defineProperties(ctor.prototype, properties);
|
|
982
|
+
}
|
|
983
|
+
function isCssVariable(propertyName) {
|
|
984
|
+
return /^--/.test(propertyName);
|
|
985
|
+
}
|
|
986
|
+
class Style {
|
|
987
|
+
constructor(element) {
|
|
988
|
+
this._element = element;
|
|
989
|
+
this._usedStyleProp = new Set();
|
|
990
|
+
this._value = {};
|
|
991
|
+
}
|
|
992
|
+
setCssVariables(styleKey) {
|
|
993
|
+
this.hasOwnProperty(styleKey) || Object.defineProperty(this, styleKey, {
|
|
994
|
+
enumerable: true,
|
|
995
|
+
configurable: true,
|
|
996
|
+
get: () => {
|
|
997
|
+
return this._value[styleKey] || '';
|
|
998
|
+
},
|
|
999
|
+
set: (newVal) => {
|
|
1000
|
+
setStyle.call(this, newVal, styleKey);
|
|
1001
|
+
}
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
get cssText() {
|
|
1005
|
+
if (!this._usedStyleProp.size)
|
|
1006
|
+
return '';
|
|
1007
|
+
const texts = [];
|
|
1008
|
+
this._usedStyleProp.forEach(key => {
|
|
1009
|
+
const val = this[key];
|
|
1010
|
+
if (shared.isNull(val) || shared.isUndefined(val))
|
|
1011
|
+
return;
|
|
1012
|
+
let styleName = isCssVariable(key) ? key : shared.toDashed(key);
|
|
1013
|
+
if (styleName.indexOf('webkit') === 0 || styleName.indexOf('Webkit') === 0) {
|
|
1014
|
+
styleName = `-${styleName}`;
|
|
1015
|
+
}
|
|
1016
|
+
texts.push(`${styleName}: ${val};`);
|
|
1017
|
+
});
|
|
1018
|
+
return texts.join(' ');
|
|
1019
|
+
}
|
|
1020
|
+
set cssText(str) {
|
|
1021
|
+
this._pending = true;
|
|
1022
|
+
recordCss(this);
|
|
1023
|
+
this._usedStyleProp.forEach(prop => {
|
|
1024
|
+
this.removeProperty(prop);
|
|
1025
|
+
});
|
|
1026
|
+
if (str === '' || shared.isUndefined(str) || shared.isNull(str)) {
|
|
1027
|
+
this._pending = false;
|
|
1028
|
+
enqueueUpdate(this);
|
|
1029
|
+
return;
|
|
1030
|
+
}
|
|
1031
|
+
const rules = str.split(';');
|
|
1032
|
+
for (let i = 0; i < rules.length; i++) {
|
|
1033
|
+
const rule = rules[i].trim();
|
|
1034
|
+
if (rule === '') {
|
|
1035
|
+
continue;
|
|
1036
|
+
}
|
|
1037
|
+
// 可能存在 'background: url(http:x/y/z)' 的情况
|
|
1038
|
+
const [propName, ...valList] = rule.split(':');
|
|
1039
|
+
const val = valList.join(':');
|
|
1040
|
+
if (shared.isUndefined(val)) {
|
|
1041
|
+
continue;
|
|
1042
|
+
}
|
|
1043
|
+
this.setProperty(propName.trim(), val.trim());
|
|
1044
|
+
}
|
|
1045
|
+
this._pending = false;
|
|
1046
|
+
enqueueUpdate(this);
|
|
1047
|
+
}
|
|
1048
|
+
setProperty(propertyName, value) {
|
|
1049
|
+
if (propertyName[0] === '-') {
|
|
1050
|
+
// 支持 webkit 属性或 css 变量
|
|
1051
|
+
this.setCssVariables(propertyName);
|
|
1052
|
+
}
|
|
1053
|
+
else {
|
|
1054
|
+
propertyName = shared.toCamelCase(propertyName);
|
|
1055
|
+
}
|
|
1056
|
+
if (shared.isNull(value) || shared.isUndefined(value)) {
|
|
1057
|
+
this.removeProperty(propertyName);
|
|
1058
|
+
}
|
|
1059
|
+
else {
|
|
1060
|
+
this[propertyName] = value;
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
removeProperty(propertyName) {
|
|
1064
|
+
propertyName = shared.toCamelCase(propertyName);
|
|
1065
|
+
if (!this._usedStyleProp.has(propertyName)) {
|
|
1066
|
+
return '';
|
|
1067
|
+
}
|
|
1068
|
+
const value = this[propertyName];
|
|
1069
|
+
this[propertyName] = undefined;
|
|
1070
|
+
return value;
|
|
1071
|
+
}
|
|
1072
|
+
getPropertyValue(propertyName) {
|
|
1073
|
+
propertyName = shared.toCamelCase(propertyName);
|
|
1074
|
+
const value = this[propertyName];
|
|
1075
|
+
if (!value) {
|
|
1076
|
+
return '';
|
|
1077
|
+
}
|
|
1078
|
+
return value;
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
initStyle(Style, styleProperties);
|
|
1082
|
+
shared.hooks.tap('injectNewStyleProperties', (newStyleProperties) => {
|
|
1083
|
+
if (shared.isArray(newStyleProperties)) {
|
|
1084
|
+
initStyle(Style, newStyleProperties);
|
|
1085
|
+
}
|
|
1086
|
+
else {
|
|
1087
|
+
if (typeof newStyleProperties !== 'string')
|
|
1088
|
+
return;
|
|
1089
|
+
initStyle(Style, [newStyleProperties]);
|
|
1090
|
+
}
|
|
1091
|
+
});
|
|
1092
|
+
|
|
1093
|
+
function returnTrue() {
|
|
1094
|
+
return true;
|
|
1095
|
+
}
|
|
1096
|
+
function treeToArray(root, predict) {
|
|
1097
|
+
const array = [];
|
|
1098
|
+
const filter = predict !== null && predict !== void 0 ? predict : returnTrue;
|
|
1099
|
+
let object = root;
|
|
1100
|
+
while (object) {
|
|
1101
|
+
if (object.nodeType === 1 /* NodeType.ELEMENT_NODE */ && filter(object)) {
|
|
1102
|
+
array.push(object);
|
|
1103
|
+
}
|
|
1104
|
+
object = following(object, root);
|
|
1105
|
+
}
|
|
1106
|
+
return array;
|
|
1107
|
+
}
|
|
1108
|
+
function following(el, root) {
|
|
1109
|
+
const firstChild = el.firstChild;
|
|
1110
|
+
const isElmentTypeValid = el.nodeType === 1 /* NodeType.ELEMENT_NODE */ || el.nodeType === 9 /* NodeType.DOCUMENT_NODE */;
|
|
1111
|
+
// 如果当前 el 不是 element 或 document 元素,则可以直接不递归他的子元素了
|
|
1112
|
+
if (firstChild && isElmentTypeValid) {
|
|
1113
|
+
return firstChild;
|
|
1114
|
+
}
|
|
1115
|
+
let current = el;
|
|
1116
|
+
do {
|
|
1117
|
+
if (current === root) {
|
|
1118
|
+
return null;
|
|
1119
|
+
}
|
|
1120
|
+
const nextSibling = current.nextSibling;
|
|
1121
|
+
if (nextSibling) {
|
|
1122
|
+
return nextSibling;
|
|
1123
|
+
}
|
|
1124
|
+
current = current.parentElement;
|
|
1125
|
+
} while (current);
|
|
1126
|
+
return null;
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
class TaroElement extends TaroNode {
|
|
1130
|
+
constructor() {
|
|
1131
|
+
super();
|
|
1132
|
+
this.props = {};
|
|
1133
|
+
this.dataset = shared.EMPTY_OBJ;
|
|
1134
|
+
this.nodeType = 1 /* NodeType.ELEMENT_NODE */;
|
|
1135
|
+
this.style = new Style(this);
|
|
1136
|
+
shared.hooks.call('patchElement', this);
|
|
1137
|
+
}
|
|
1138
|
+
_stopPropagation(event) {
|
|
1139
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
1140
|
+
let target = this;
|
|
1141
|
+
// eslint-disable-next-line no-cond-assign
|
|
1142
|
+
while ((target = target.parentNode)) {
|
|
1143
|
+
const listeners = target.__handlers[event.type];
|
|
1144
|
+
if (!shared.isArray(listeners)) {
|
|
1145
|
+
continue;
|
|
1146
|
+
}
|
|
1147
|
+
for (let i = listeners.length; i--;) {
|
|
1148
|
+
const l = listeners[i];
|
|
1149
|
+
l._stop = true;
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
get id() {
|
|
1154
|
+
return this.getAttribute(ID);
|
|
1155
|
+
}
|
|
1156
|
+
set id(val) {
|
|
1157
|
+
this.setAttribute(ID, val);
|
|
1158
|
+
}
|
|
1159
|
+
get className() {
|
|
1160
|
+
return this.getAttribute(CLASS) || '';
|
|
1161
|
+
}
|
|
1162
|
+
set className(val) {
|
|
1163
|
+
this.setAttribute(CLASS, val);
|
|
1164
|
+
}
|
|
1165
|
+
get cssText() {
|
|
1166
|
+
return this.getAttribute(STYLE) || '';
|
|
1167
|
+
}
|
|
1168
|
+
get classList() {
|
|
1169
|
+
return new ClassList(this.className, this);
|
|
1170
|
+
}
|
|
1171
|
+
get children() {
|
|
1172
|
+
return this.childNodes.filter(isElement);
|
|
1173
|
+
}
|
|
1174
|
+
get attributes() {
|
|
1175
|
+
const props = this.props;
|
|
1176
|
+
const propKeys = Object.keys(props);
|
|
1177
|
+
const style = this.style.cssText;
|
|
1178
|
+
const attrs = propKeys.map(key => ({ name: key, value: props[key] }));
|
|
1179
|
+
return attrs.concat(style ? { name: STYLE, value: style } : []);
|
|
1180
|
+
}
|
|
1181
|
+
get textContent() {
|
|
1182
|
+
let text = '';
|
|
1183
|
+
const childNodes = this.childNodes;
|
|
1184
|
+
for (let i = 0; i < childNodes.length; i++) {
|
|
1185
|
+
text += childNodes[i].textContent;
|
|
1186
|
+
}
|
|
1187
|
+
return text;
|
|
1188
|
+
}
|
|
1189
|
+
set textContent(text) {
|
|
1190
|
+
super.textContent = text;
|
|
1191
|
+
}
|
|
1192
|
+
hasAttribute(qualifiedName) {
|
|
1193
|
+
return !shared.isUndefined(this.props[qualifiedName]);
|
|
1194
|
+
}
|
|
1195
|
+
hasAttributes() {
|
|
1196
|
+
return this.attributes.length > 0;
|
|
1197
|
+
}
|
|
1198
|
+
get focus() {
|
|
1199
|
+
return function () {
|
|
1200
|
+
this.setAttribute(FOCUS, true);
|
|
1201
|
+
};
|
|
1202
|
+
}
|
|
1203
|
+
// 兼容 Vue3,详情请见:https://github.com/NervJS/taro/issues/10579
|
|
1204
|
+
set focus(value) {
|
|
1205
|
+
this.setAttribute(FOCUS, value);
|
|
1206
|
+
}
|
|
1207
|
+
blur() {
|
|
1208
|
+
this.setAttribute(FOCUS, false);
|
|
1209
|
+
}
|
|
1210
|
+
setAttribute(qualifiedName, value) {
|
|
1211
|
+
process.env.NODE_ENV !== 'production' && shared.warn(shared.isString(value) && value.length > PROPERTY_THRESHOLD, `元素 ${this.nodeName} 的 ${qualifiedName} 属性值数据量过大,可能会影响渲染性能。考虑降低图片转为 base64 的阈值或在 CSS 中使用 base64。`);
|
|
1212
|
+
const isPureView = this.nodeName === VIEW && !isHasExtractProp(this) && !this.isAnyEventBinded();
|
|
1213
|
+
if (qualifiedName !== STYLE) {
|
|
1214
|
+
MutationObserver.record({
|
|
1215
|
+
target: this,
|
|
1216
|
+
type: "attributes" /* MutationRecordType.ATTRIBUTES */,
|
|
1217
|
+
attributeName: qualifiedName,
|
|
1218
|
+
oldValue: this.getAttribute(qualifiedName)
|
|
1219
|
+
});
|
|
1220
|
+
}
|
|
1221
|
+
switch (qualifiedName) {
|
|
1222
|
+
case STYLE:
|
|
1223
|
+
this.style.cssText = value;
|
|
1224
|
+
break;
|
|
1225
|
+
case ID:
|
|
1226
|
+
if (this.uid !== this.sid) {
|
|
1227
|
+
// eventSource[sid] 永远保留,直到组件卸载
|
|
1228
|
+
// eventSource[uid] 可变
|
|
1229
|
+
eventSource.delete(this.uid);
|
|
1230
|
+
}
|
|
1231
|
+
value = String(value);
|
|
1232
|
+
this.props[qualifiedName] = this.uid = value;
|
|
1233
|
+
eventSource.set(value, this);
|
|
1234
|
+
break;
|
|
1235
|
+
default:
|
|
1236
|
+
this.props[qualifiedName] = value;
|
|
1237
|
+
if (qualifiedName.startsWith('data-')) {
|
|
1238
|
+
if (this.dataset === shared.EMPTY_OBJ) {
|
|
1239
|
+
this.dataset = Object.create(null);
|
|
1240
|
+
}
|
|
1241
|
+
this.dataset[shared.toCamelCase(qualifiedName.replace(/^data-/, ''))] = value;
|
|
1242
|
+
}
|
|
1243
|
+
break;
|
|
1244
|
+
}
|
|
1245
|
+
// Serialization
|
|
1246
|
+
if (!this._root)
|
|
1247
|
+
return;
|
|
1248
|
+
const componentsAlias = getComponentsAlias();
|
|
1249
|
+
const _alias = componentsAlias[this.nodeName];
|
|
1250
|
+
const viewAlias = componentsAlias[VIEW]._num;
|
|
1251
|
+
const staticViewAlias = componentsAlias[STATIC_VIEW]._num;
|
|
1252
|
+
const catchViewAlias = componentsAlias[CATCH_VIEW]._num;
|
|
1253
|
+
const _path = this._path;
|
|
1254
|
+
qualifiedName = shortcutAttr(qualifiedName);
|
|
1255
|
+
const qualifiedNameInCamelCase = shared.toCamelCase(qualifiedName);
|
|
1256
|
+
const payload = {
|
|
1257
|
+
path: `${_path}.${qualifiedNameInCamelCase}`,
|
|
1258
|
+
value: shared.isFunction(value) ? () => value : value
|
|
1259
|
+
};
|
|
1260
|
+
shared.hooks.call('modifySetAttrPayload', this, qualifiedName, payload, componentsAlias);
|
|
1261
|
+
if (_alias) {
|
|
1262
|
+
const qualifiedNameAlias = _alias[qualifiedNameInCamelCase] || qualifiedName;
|
|
1263
|
+
payload.path = `${_path}.${shared.toCamelCase(qualifiedNameAlias)}`;
|
|
1264
|
+
}
|
|
1265
|
+
this.enqueueUpdate(payload);
|
|
1266
|
+
if (this.nodeName === VIEW) {
|
|
1267
|
+
if (qualifiedNameInCamelCase === CATCHMOVE) {
|
|
1268
|
+
// catchMove = true: catch-view
|
|
1269
|
+
// catchMove = false: view or static-view
|
|
1270
|
+
this.enqueueUpdate({
|
|
1271
|
+
path: `${_path}.${"nn" /* Shortcuts.NodeName */}`,
|
|
1272
|
+
value: value ? catchViewAlias : (this.isAnyEventBinded() ? viewAlias : staticViewAlias)
|
|
1273
|
+
});
|
|
1274
|
+
}
|
|
1275
|
+
else if (isPureView && isHasExtractProp(this)) {
|
|
1276
|
+
// pure-view => static-view
|
|
1277
|
+
this.enqueueUpdate({
|
|
1278
|
+
path: `${_path}.${"nn" /* Shortcuts.NodeName */}`,
|
|
1279
|
+
value: staticViewAlias
|
|
1280
|
+
});
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
removeAttribute(qualifiedName) {
|
|
1285
|
+
const isStaticView = this.nodeName === VIEW && isHasExtractProp(this) && !this.isAnyEventBinded();
|
|
1286
|
+
MutationObserver.record({
|
|
1287
|
+
target: this,
|
|
1288
|
+
type: "attributes" /* MutationRecordType.ATTRIBUTES */,
|
|
1289
|
+
attributeName: qualifiedName,
|
|
1290
|
+
oldValue: this.getAttribute(qualifiedName)
|
|
1291
|
+
});
|
|
1292
|
+
if (qualifiedName === STYLE) {
|
|
1293
|
+
this.style.cssText = '';
|
|
1294
|
+
}
|
|
1295
|
+
else {
|
|
1296
|
+
const isInterrupt = shared.hooks.call('onRemoveAttribute', this, qualifiedName);
|
|
1297
|
+
if (isInterrupt) {
|
|
1298
|
+
return;
|
|
1299
|
+
}
|
|
1300
|
+
if (!this.props.hasOwnProperty(qualifiedName)) {
|
|
1301
|
+
return;
|
|
1302
|
+
}
|
|
1303
|
+
delete this.props[qualifiedName];
|
|
1304
|
+
}
|
|
1305
|
+
// Serialization
|
|
1306
|
+
if (!this._root)
|
|
1307
|
+
return;
|
|
1308
|
+
const componentsAlias = getComponentsAlias();
|
|
1309
|
+
const _alias = componentsAlias[this.nodeName];
|
|
1310
|
+
const viewAlias = componentsAlias[VIEW]._num;
|
|
1311
|
+
const staticViewAlias = componentsAlias[STATIC_VIEW]._num;
|
|
1312
|
+
const pureViewAlias = componentsAlias[PURE_VIEW]._num;
|
|
1313
|
+
const _path = this._path;
|
|
1314
|
+
qualifiedName = shortcutAttr(qualifiedName);
|
|
1315
|
+
const qualifiedNameInCamelCase = shared.toCamelCase(qualifiedName);
|
|
1316
|
+
const payload = {
|
|
1317
|
+
path: `${_path}.${qualifiedNameInCamelCase}`,
|
|
1318
|
+
value: ''
|
|
1319
|
+
};
|
|
1320
|
+
shared.hooks.call('modifyRmAttrPayload', this, qualifiedName, payload, componentsAlias);
|
|
1321
|
+
if (_alias) {
|
|
1322
|
+
const qualifiedNameAlias = _alias[qualifiedNameInCamelCase] || qualifiedName;
|
|
1323
|
+
payload.path = `${_path}.${shared.toCamelCase(qualifiedNameAlias)}`;
|
|
1324
|
+
}
|
|
1325
|
+
this.enqueueUpdate(payload);
|
|
1326
|
+
if (this.nodeName === VIEW) {
|
|
1327
|
+
if (qualifiedNameInCamelCase === CATCHMOVE) {
|
|
1328
|
+
// catch-view => view or static-view or pure-view
|
|
1329
|
+
this.enqueueUpdate({
|
|
1330
|
+
path: `${_path}.${"nn" /* Shortcuts.NodeName */}`,
|
|
1331
|
+
value: this.isAnyEventBinded() ? viewAlias : (isHasExtractProp(this) ? staticViewAlias : pureViewAlias)
|
|
1332
|
+
});
|
|
1333
|
+
}
|
|
1334
|
+
else if (isStaticView && !isHasExtractProp(this)) {
|
|
1335
|
+
// static-view => pure-view
|
|
1336
|
+
this.enqueueUpdate({
|
|
1337
|
+
path: `${_path}.${"nn" /* Shortcuts.NodeName */}`,
|
|
1338
|
+
value: pureViewAlias
|
|
1339
|
+
});
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
getAttribute(qualifiedName) {
|
|
1344
|
+
const attr = qualifiedName === STYLE ? this.style.cssText : this.props[qualifiedName];
|
|
1345
|
+
return attr !== null && attr !== void 0 ? attr : '';
|
|
1346
|
+
}
|
|
1347
|
+
getElementsByTagName(tagName) {
|
|
1348
|
+
return treeToArray(this, (el) => {
|
|
1349
|
+
return el.nodeName === tagName || (tagName === '*' && this !== el);
|
|
1350
|
+
});
|
|
1351
|
+
}
|
|
1352
|
+
getElementsByClassName(className) {
|
|
1353
|
+
const classNames = className.trim().split(/\s+/);
|
|
1354
|
+
return treeToArray(this, (el) => {
|
|
1355
|
+
const classList = el.classList;
|
|
1356
|
+
return classNames.every(c => classList.contains(c));
|
|
1357
|
+
});
|
|
1358
|
+
}
|
|
1359
|
+
dispatchEvent(event) {
|
|
1360
|
+
const cancelable = event.cancelable;
|
|
1361
|
+
const listeners = this.__handlers[event.type];
|
|
1362
|
+
if (!shared.isArray(listeners)) {
|
|
1363
|
+
return false;
|
|
1364
|
+
}
|
|
1365
|
+
for (let i = listeners.length; i--;) {
|
|
1366
|
+
const listener = listeners[i];
|
|
1367
|
+
let result;
|
|
1368
|
+
if (listener._stop) {
|
|
1369
|
+
listener._stop = false;
|
|
1370
|
+
}
|
|
1371
|
+
else {
|
|
1372
|
+
shared.hooks.call('modifyDispatchEvent', event, this);
|
|
1373
|
+
result = listener.call(this, event);
|
|
1374
|
+
}
|
|
1375
|
+
if ((result === false || event._end) && cancelable) {
|
|
1376
|
+
event.defaultPrevented = true;
|
|
1377
|
+
}
|
|
1378
|
+
if (!shared.isUndefined(result) && event.mpEvent) {
|
|
1379
|
+
event.mpEvent[EVENT_CALLBACK_RESULT] = result;
|
|
1380
|
+
}
|
|
1381
|
+
if (event._end && event._stop) {
|
|
1382
|
+
break;
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
if (event._stop) {
|
|
1386
|
+
this._stopPropagation(event);
|
|
1387
|
+
}
|
|
1388
|
+
else {
|
|
1389
|
+
event._stop = true;
|
|
1390
|
+
}
|
|
1391
|
+
return listeners != null;
|
|
1392
|
+
}
|
|
1393
|
+
addEventListener(type, handler, options) {
|
|
1394
|
+
const name = this.nodeName;
|
|
1395
|
+
const SPECIAL_NODES = shared.hooks.call('getSpecialNodes');
|
|
1396
|
+
let sideEffect = true;
|
|
1397
|
+
if (shared.isObject(options) && options.sideEffect === false) {
|
|
1398
|
+
sideEffect = false;
|
|
1399
|
+
delete options.sideEffect;
|
|
1400
|
+
}
|
|
1401
|
+
if (sideEffect !== false && !this.isAnyEventBinded() && SPECIAL_NODES.indexOf(name) > -1) {
|
|
1402
|
+
const componentsAlias = getComponentsAlias();
|
|
1403
|
+
const alias = componentsAlias[name]._num;
|
|
1404
|
+
this.enqueueUpdate({
|
|
1405
|
+
path: `${this._path}.${"nn" /* Shortcuts.NodeName */}`,
|
|
1406
|
+
value: alias
|
|
1407
|
+
});
|
|
1408
|
+
}
|
|
1409
|
+
super.addEventListener(type, handler, options);
|
|
1410
|
+
}
|
|
1411
|
+
removeEventListener(type, handler, sideEffect = true) {
|
|
1412
|
+
super.removeEventListener(type, handler);
|
|
1413
|
+
const name = this.nodeName;
|
|
1414
|
+
const SPECIAL_NODES = shared.hooks.call('getSpecialNodes');
|
|
1415
|
+
if (sideEffect !== false && !this.isAnyEventBinded() && SPECIAL_NODES.indexOf(name) > -1) {
|
|
1416
|
+
const componentsAlias = getComponentsAlias();
|
|
1417
|
+
const value = isHasExtractProp(this) ? `static-${name}` : `pure-${name}`;
|
|
1418
|
+
const valueAlias = componentsAlias[value]._num;
|
|
1419
|
+
this.enqueueUpdate({
|
|
1420
|
+
path: `${this._path}.${"nn" /* Shortcuts.NodeName */}`,
|
|
1421
|
+
value: valueAlias
|
|
1422
|
+
});
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
static extend(methodName, options) {
|
|
1426
|
+
extend(TaroElement, methodName, options);
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
const options = {
|
|
1431
|
+
prerender: true,
|
|
1432
|
+
debug: false
|
|
1433
|
+
};
|
|
1434
|
+
|
|
1435
|
+
function makeMap(str, expectsLowerCase) {
|
|
1436
|
+
const map = Object.create(null);
|
|
1437
|
+
const list = str.split(',');
|
|
1438
|
+
for (let i = 0; i < list.length; i++) {
|
|
1439
|
+
map[list[i]] = true;
|
|
1440
|
+
}
|
|
1441
|
+
return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val];
|
|
1442
|
+
}
|
|
1443
|
+
const internalCompsList = Object.keys(shared.internalComponents)
|
|
1444
|
+
.map(i => i.toLowerCase())
|
|
1445
|
+
.join(',');
|
|
1446
|
+
// https://developers.weixin.qq.com/miniprogram/dev/component
|
|
1447
|
+
makeMap(internalCompsList, true);
|
|
1448
|
+
// https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements
|
|
1449
|
+
makeMap('a,i,abbr,iframe,select,acronym,slot,small,span,bdi,kbd,strong,big,map,sub,sup,br,mark,mark,meter,template,canvas,textarea,cite,object,time,code,output,u,data,picture,tt,datalist,var,dfn,del,q,em,s,embed,samp,b', true);
|
|
1450
|
+
// https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements
|
|
1451
|
+
makeMap('address,fieldset,li,article,figcaption,main,aside,figure,nav,blockquote,footer,ol,details,form,p,dialog,h1,h2,h3,h4,h5,h6,pre,dd,header,section,div,hgroup,table,dl,hr,ul,dt', true);
|
|
1452
|
+
|
|
1453
|
+
options.html = {
|
|
1454
|
+
skipElements: new Set(['style', 'script']),
|
|
1455
|
+
voidElements: new Set([
|
|
1456
|
+
'!doctype', 'area', 'base', 'br', 'col', 'command',
|
|
1457
|
+
'embed', 'hr', 'img', 'input', 'keygen', 'link',
|
|
1458
|
+
'meta', 'param', 'source', 'track', 'wbr'
|
|
1459
|
+
]),
|
|
1460
|
+
closingElements: new Set([
|
|
1461
|
+
'html', 'head', 'body', 'p', 'dt', 'dd', 'li', 'option',
|
|
1462
|
+
'thead', 'th', 'tbody', 'tr', 'td', 'tfoot', 'colgroup'
|
|
1463
|
+
]),
|
|
1464
|
+
renderHTMLTag: false
|
|
1465
|
+
};
|
|
1466
|
+
|
|
1467
|
+
// Taro 事件对象。以 Web 标准的事件对象为基础,加入小程序事件对象中携带的部分信息,并模拟实现事件冒泡。
|
|
1468
|
+
class TaroEvent {
|
|
1469
|
+
constructor(type, opts, event) {
|
|
1470
|
+
this._stop = false;
|
|
1471
|
+
this._end = false;
|
|
1472
|
+
this.defaultPrevented = false;
|
|
1473
|
+
// Mouse Event botton property, it's used in 3rd lib, like react-router. default 0 in general
|
|
1474
|
+
this.button = 0;
|
|
1475
|
+
// timestamp can either be hi-res ( relative to page load) or low-res (relative to UNIX epoch)
|
|
1476
|
+
// here use hi-res timestamp
|
|
1477
|
+
this.timeStamp = Date.now();
|
|
1478
|
+
this.type = type.toLowerCase();
|
|
1479
|
+
this.mpEvent = event;
|
|
1480
|
+
this.bubbles = Boolean(opts && opts.bubbles);
|
|
1481
|
+
this.cancelable = Boolean(opts && opts.cancelable);
|
|
1482
|
+
}
|
|
1483
|
+
stopPropagation() {
|
|
1484
|
+
this._stop = true;
|
|
1485
|
+
}
|
|
1486
|
+
stopImmediatePropagation() {
|
|
1487
|
+
this._end = this._stop = true;
|
|
1488
|
+
}
|
|
1489
|
+
preventDefault() {
|
|
1490
|
+
this.defaultPrevented = true;
|
|
1491
|
+
}
|
|
1492
|
+
get target() {
|
|
1493
|
+
var _a, _b;
|
|
1494
|
+
const cacheTarget = this.cacheTarget;
|
|
1495
|
+
if (!cacheTarget) {
|
|
1496
|
+
const target = Object.create(((_a = this.mpEvent) === null || _a === void 0 ? void 0 : _a.target) || null);
|
|
1497
|
+
const element = env.document.getElementById(target.id);
|
|
1498
|
+
target.dataset = element !== null ? element.dataset : shared.EMPTY_OBJ;
|
|
1499
|
+
for (const key in (_b = this.mpEvent) === null || _b === void 0 ? void 0 : _b.detail) {
|
|
1500
|
+
target[key] = this.mpEvent.detail[key];
|
|
1501
|
+
}
|
|
1502
|
+
this.cacheTarget = target;
|
|
1503
|
+
return target;
|
|
1504
|
+
}
|
|
1505
|
+
else {
|
|
1506
|
+
return cacheTarget;
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
get currentTarget() {
|
|
1510
|
+
var _a, _b, _c, _d;
|
|
1511
|
+
const cacheCurrentTarget = this.cacheCurrentTarget;
|
|
1512
|
+
if (!cacheCurrentTarget) {
|
|
1513
|
+
const doc = env.document;
|
|
1514
|
+
const currentTarget = Object.create(((_a = this.mpEvent) === null || _a === void 0 ? void 0 : _a.currentTarget) || null);
|
|
1515
|
+
const element = doc.getElementById(currentTarget.id);
|
|
1516
|
+
const targetElement = doc.getElementById(((_c = (_b = this.mpEvent) === null || _b === void 0 ? void 0 : _b.target) === null || _c === void 0 ? void 0 : _c.id) || null);
|
|
1517
|
+
if (element === null || (element && element === targetElement)) {
|
|
1518
|
+
this.cacheCurrentTarget = this.target;
|
|
1519
|
+
return this.target;
|
|
1520
|
+
}
|
|
1521
|
+
currentTarget.dataset = element.dataset;
|
|
1522
|
+
for (const key in (_d = this.mpEvent) === null || _d === void 0 ? void 0 : _d.detail) {
|
|
1523
|
+
currentTarget[key] = this.mpEvent.detail[key];
|
|
1524
|
+
}
|
|
1525
|
+
this.cacheCurrentTarget = currentTarget;
|
|
1526
|
+
return currentTarget;
|
|
1527
|
+
}
|
|
1528
|
+
else {
|
|
1529
|
+
return cacheCurrentTarget;
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
function createEvent(event, node) {
|
|
1534
|
+
if (typeof event === 'string') {
|
|
1535
|
+
// For Vue3 using document.createEvent
|
|
1536
|
+
return new TaroEvent(event, { bubbles: true, cancelable: true });
|
|
1537
|
+
}
|
|
1538
|
+
const domEv = new TaroEvent(event.type, { bubbles: true, cancelable: true }, event);
|
|
1539
|
+
for (const key in event) {
|
|
1540
|
+
if (key === CURRENT_TARGET || key === TARGET || key === TYPE || key === TIME_STAMP) {
|
|
1541
|
+
continue;
|
|
1542
|
+
}
|
|
1543
|
+
else {
|
|
1544
|
+
domEv[key] = event[key];
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
if (domEv.type === CONFIRM && (node === null || node === void 0 ? void 0 : node.nodeName) === INPUT) {
|
|
1548
|
+
// eslint-disable-next-line dot-notation
|
|
1549
|
+
domEv[KEY_CODE] = 13;
|
|
1550
|
+
}
|
|
1551
|
+
return domEv;
|
|
1552
|
+
}
|
|
1553
|
+
const eventsBatch = {};
|
|
1554
|
+
function getEventCBResult(event) {
|
|
1555
|
+
const result = event[EVENT_CALLBACK_RESULT];
|
|
1556
|
+
if (!shared.isUndefined(result)) {
|
|
1557
|
+
delete event[EVENT_CALLBACK_RESULT];
|
|
1558
|
+
}
|
|
1559
|
+
return result;
|
|
1560
|
+
}
|
|
1561
|
+
// 小程序的事件代理回调函数
|
|
1562
|
+
function eventHandler(event) {
|
|
1563
|
+
var _a, _b;
|
|
1564
|
+
// Note: ohos 上事件没有设置 type、detail 类型 setter 方法,且部分事件(例如 load 等)缺失 target 导致事件错误
|
|
1565
|
+
event.type === undefined && Object.defineProperty(event, 'type', {
|
|
1566
|
+
value: event._type // ohos only
|
|
1567
|
+
});
|
|
1568
|
+
event.detail === undefined && Object.defineProperty(event, 'detail', {
|
|
1569
|
+
value: event._detail || Object.assign({}, event) // ohos only
|
|
1570
|
+
});
|
|
1571
|
+
event.currentTarget = event.currentTarget || event.target || Object.assign({}, event);
|
|
1572
|
+
shared.hooks.call('modifyMpEventImpl', event);
|
|
1573
|
+
const currentTarget = event.currentTarget;
|
|
1574
|
+
const id = ((_a = currentTarget.dataset) === null || _a === void 0 ? void 0 : _a.sid /** sid */) || currentTarget.id /** uid */ || ((_b = event.detail) === null || _b === void 0 ? void 0 : _b.id) || '';
|
|
1575
|
+
const node = env.document.getElementById(id);
|
|
1576
|
+
if (node) {
|
|
1577
|
+
const dispatch = () => {
|
|
1578
|
+
const e = createEvent(event, node);
|
|
1579
|
+
shared.hooks.call('modifyTaroEvent', e, node);
|
|
1580
|
+
shared.hooks.call('dispatchTaroEvent', e, node);
|
|
1581
|
+
shared.hooks.call('dispatchTaroEventFinish', e, node);
|
|
1582
|
+
};
|
|
1583
|
+
if (shared.hooks.isExist('batchedEventUpdates')) {
|
|
1584
|
+
const type = event.type;
|
|
1585
|
+
if (!shared.hooks.call('isBubbleEvents', type) ||
|
|
1586
|
+
!isParentBinded(node, type) ||
|
|
1587
|
+
(type === TOUCHMOVE && !!node.props.catchMove)) {
|
|
1588
|
+
// 最上层组件统一 batchUpdate
|
|
1589
|
+
shared.hooks.call('batchedEventUpdates', () => {
|
|
1590
|
+
if (eventsBatch[type]) {
|
|
1591
|
+
eventsBatch[type].forEach(fn => fn());
|
|
1592
|
+
delete eventsBatch[type];
|
|
1593
|
+
}
|
|
1594
|
+
dispatch();
|
|
1595
|
+
});
|
|
1596
|
+
return getEventCBResult(event);
|
|
1597
|
+
}
|
|
1598
|
+
else {
|
|
1599
|
+
// 如果上层组件也有绑定同类型的组件,委托给上层组件调用事件回调
|
|
1600
|
+
(eventsBatch[type] || (eventsBatch[type] = [])).push(dispatch);
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
else {
|
|
1604
|
+
dispatch();
|
|
1605
|
+
return getEventCBResult(event);
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
class FormElement extends TaroElement {
|
|
1611
|
+
get type() {
|
|
1612
|
+
var _a;
|
|
1613
|
+
return (_a = this.props[TYPE]) !== null && _a !== void 0 ? _a : '';
|
|
1614
|
+
}
|
|
1615
|
+
set type(val) {
|
|
1616
|
+
this.setAttribute(TYPE, val);
|
|
1617
|
+
}
|
|
1618
|
+
get value() {
|
|
1619
|
+
// eslint-disable-next-line dot-notation
|
|
1620
|
+
const val = this.props[VALUE];
|
|
1621
|
+
return val == null ? '' : val;
|
|
1622
|
+
}
|
|
1623
|
+
set value(val) {
|
|
1624
|
+
this.setAttribute(VALUE, val);
|
|
1625
|
+
}
|
|
1626
|
+
dispatchEvent(event) {
|
|
1627
|
+
if (event.mpEvent) {
|
|
1628
|
+
const val = event.mpEvent.detail.value;
|
|
1629
|
+
if (event.type === CHANGE) {
|
|
1630
|
+
this.props.value = val;
|
|
1631
|
+
}
|
|
1632
|
+
else if (event.type === INPUT) {
|
|
1633
|
+
// Web 规范中表单组件的 value 应该跟着输入改变
|
|
1634
|
+
// 只是改 this.props.value 的话不会进行 setData,因此这里修改 this.value。
|
|
1635
|
+
// 只测试了 React、Vue、Vue3 input 组件的 onInput 事件,onChange 事件不确定有没有副作用,所以暂不修改。
|
|
1636
|
+
this.value = val;
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
return super.dispatchEvent(event);
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
class Performance {
|
|
1644
|
+
constructor() {
|
|
1645
|
+
this.recorder = new Map();
|
|
1646
|
+
}
|
|
1647
|
+
start(id) {
|
|
1648
|
+
if (!options.debug) {
|
|
1649
|
+
return;
|
|
1650
|
+
}
|
|
1651
|
+
this.recorder.set(id, Date.now());
|
|
1652
|
+
}
|
|
1653
|
+
stop(id) {
|
|
1654
|
+
if (!options.debug) {
|
|
1655
|
+
return;
|
|
1656
|
+
}
|
|
1657
|
+
const now = Date.now();
|
|
1658
|
+
const prev = this.recorder.get(id);
|
|
1659
|
+
this.recorder.delete(id);
|
|
1660
|
+
const time = now - prev;
|
|
1661
|
+
// eslint-disable-next-line no-console
|
|
1662
|
+
console.log(`${id} 时长: ${time}ms`);
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
const perf = new Performance();
|
|
1666
|
+
|
|
1667
|
+
function findCustomWrapper(root, dataPathArr) {
|
|
1668
|
+
// ['root', 'cn', '[0]'] remove 'root' => ['cn', '[0]']
|
|
1669
|
+
const list = dataPathArr.slice(1);
|
|
1670
|
+
let currentData = root;
|
|
1671
|
+
let customWrapper;
|
|
1672
|
+
let splitedPath = '';
|
|
1673
|
+
list.some((item, i) => {
|
|
1674
|
+
const key = item
|
|
1675
|
+
// '[0]' => '0'
|
|
1676
|
+
.replace(/^\[(.+)\]$/, '$1')
|
|
1677
|
+
// 'cn' => 'childNodes'
|
|
1678
|
+
.replace(/\bcn\b/g, 'childNodes');
|
|
1679
|
+
currentData = currentData[key];
|
|
1680
|
+
if (shared.isArray(currentData)) {
|
|
1681
|
+
currentData = currentData.filter(el => !isComment(el));
|
|
1682
|
+
}
|
|
1683
|
+
if (shared.isUndefined(currentData))
|
|
1684
|
+
return true;
|
|
1685
|
+
if (currentData.nodeName === CUSTOM_WRAPPER) {
|
|
1686
|
+
const res = customWrapperCache.get(currentData.sid);
|
|
1687
|
+
if (res) {
|
|
1688
|
+
customWrapper = res;
|
|
1689
|
+
splitedPath = dataPathArr.slice(i + 2).join('.');
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
});
|
|
1693
|
+
if (customWrapper) {
|
|
1694
|
+
return {
|
|
1695
|
+
customWrapper,
|
|
1696
|
+
splitedPath
|
|
1697
|
+
};
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
class TaroRootElement extends TaroElement {
|
|
1701
|
+
constructor() {
|
|
1702
|
+
super();
|
|
1703
|
+
this.updatePayloads = [];
|
|
1704
|
+
this.updateCallbacks = [];
|
|
1705
|
+
this.pendingUpdate = false;
|
|
1706
|
+
this.ctx = null;
|
|
1707
|
+
this.nodeName = ROOT_STR;
|
|
1708
|
+
this.tagName = ROOT_STR.toUpperCase();
|
|
1709
|
+
}
|
|
1710
|
+
get _path() {
|
|
1711
|
+
return ROOT_STR;
|
|
1712
|
+
}
|
|
1713
|
+
get _root() {
|
|
1714
|
+
return this;
|
|
1715
|
+
}
|
|
1716
|
+
enqueueUpdate(payload) {
|
|
1717
|
+
this.updatePayloads.push(payload);
|
|
1718
|
+
if (!this.pendingUpdate && this.ctx) {
|
|
1719
|
+
this.performUpdate();
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
performUpdate(initRender = false, prerender) {
|
|
1723
|
+
this.pendingUpdate = true;
|
|
1724
|
+
const ctx = shared.hooks.call('proxyToRaw', this.ctx);
|
|
1725
|
+
setTimeout(() => {
|
|
1726
|
+
const setDataMark = `${SET_DATA} 开始时间戳 ${Date.now()}`;
|
|
1727
|
+
perf.start(setDataMark);
|
|
1728
|
+
const data = Object.create(null);
|
|
1729
|
+
const resetPaths = new Set(initRender
|
|
1730
|
+
? ['root.cn.[0]', 'root.cn[0]']
|
|
1731
|
+
: []);
|
|
1732
|
+
while (this.updatePayloads.length > 0) {
|
|
1733
|
+
const { path, value } = this.updatePayloads.shift();
|
|
1734
|
+
if (path.endsWith("cn" /* Shortcuts.Childnodes */)) {
|
|
1735
|
+
resetPaths.add(path);
|
|
1736
|
+
}
|
|
1737
|
+
data[path] = value;
|
|
1738
|
+
}
|
|
1739
|
+
for (const path in data) {
|
|
1740
|
+
resetPaths.forEach(p => {
|
|
1741
|
+
// 已经重置了数组,就不需要分别再设置了
|
|
1742
|
+
if (path.includes(p) && path !== p) {
|
|
1743
|
+
delete data[path];
|
|
1744
|
+
}
|
|
1745
|
+
});
|
|
1746
|
+
const value = data[path];
|
|
1747
|
+
if (shared.isFunction(value)) {
|
|
1748
|
+
data[path] = value();
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
// 预渲染
|
|
1752
|
+
if (shared.isFunction(prerender))
|
|
1753
|
+
return prerender(data);
|
|
1754
|
+
// 正常渲染
|
|
1755
|
+
this.pendingUpdate = false;
|
|
1756
|
+
let normalUpdate = {};
|
|
1757
|
+
const customWrapperMap = new Map();
|
|
1758
|
+
if (initRender) {
|
|
1759
|
+
// 初次渲染,使用页面级别的 setData
|
|
1760
|
+
normalUpdate = data;
|
|
1761
|
+
}
|
|
1762
|
+
else {
|
|
1763
|
+
// 更新渲染,区分 CustomWrapper 与页面级别的 setData
|
|
1764
|
+
for (const p in data) {
|
|
1765
|
+
const dataPathArr = p.split('.');
|
|
1766
|
+
const found = findCustomWrapper(this, dataPathArr);
|
|
1767
|
+
if (found) {
|
|
1768
|
+
// 此项数据使用 CustomWrapper 去更新
|
|
1769
|
+
const { customWrapper, splitedPath } = found;
|
|
1770
|
+
// 合并同一个 customWrapper 的相关更新到一次 setData 中
|
|
1771
|
+
customWrapperMap.set(customWrapper, Object.assign(Object.assign({}, (customWrapperMap.get(customWrapper) || {})), { [`i.${splitedPath}`]: data[p] }));
|
|
1772
|
+
}
|
|
1773
|
+
else {
|
|
1774
|
+
// 此项数据使用页面去更新
|
|
1775
|
+
normalUpdate[p] = data[p];
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
const customWrapperCount = customWrapperMap.size;
|
|
1780
|
+
const isNeedNormalUpdate = Object.keys(normalUpdate).length > 0;
|
|
1781
|
+
const updateArrLen = customWrapperCount + (isNeedNormalUpdate ? 1 : 0);
|
|
1782
|
+
let executeTime = 0;
|
|
1783
|
+
const cb = () => {
|
|
1784
|
+
if (++executeTime === updateArrLen) {
|
|
1785
|
+
perf.stop(setDataMark);
|
|
1786
|
+
this.flushUpdateCallback();
|
|
1787
|
+
initRender && perf.stop(PAGE_INIT);
|
|
1788
|
+
}
|
|
1789
|
+
};
|
|
1790
|
+
// custom-wrapper setData
|
|
1791
|
+
if (customWrapperCount) {
|
|
1792
|
+
customWrapperMap.forEach((data, ctx) => {
|
|
1793
|
+
if (process.env.NODE_ENV !== 'production' && options.debug) {
|
|
1794
|
+
// eslint-disable-next-line no-console
|
|
1795
|
+
console.log('custom wrapper setData: ', data);
|
|
1796
|
+
}
|
|
1797
|
+
ctx.setData(data, cb);
|
|
1798
|
+
});
|
|
1799
|
+
}
|
|
1800
|
+
// page setData
|
|
1801
|
+
if (isNeedNormalUpdate) {
|
|
1802
|
+
if (process.env.NODE_ENV !== 'production' && options.debug) {
|
|
1803
|
+
// eslint-disable-next-line no-console
|
|
1804
|
+
console.log('page setData:', normalUpdate);
|
|
1805
|
+
}
|
|
1806
|
+
ctx.setData(normalUpdate, cb);
|
|
1807
|
+
}
|
|
1808
|
+
}, 0);
|
|
1809
|
+
}
|
|
1810
|
+
enqueueUpdateCallback(cb, ctx) {
|
|
1811
|
+
this.updateCallbacks.push(() => {
|
|
1812
|
+
ctx ? cb.call(ctx) : cb();
|
|
1813
|
+
});
|
|
1814
|
+
}
|
|
1815
|
+
flushUpdateCallback() {
|
|
1816
|
+
const updateCallbacks = this.updateCallbacks;
|
|
1817
|
+
if (!updateCallbacks.length)
|
|
1818
|
+
return;
|
|
1819
|
+
const copies = updateCallbacks.slice(0);
|
|
1820
|
+
this.updateCallbacks.length = 0;
|
|
1821
|
+
for (let i = 0; i < copies.length; i++) {
|
|
1822
|
+
copies[i]();
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
class TaroText extends TaroNode {
|
|
1828
|
+
constructor(value) {
|
|
1829
|
+
super();
|
|
1830
|
+
this.nodeType = 3 /* NodeType.TEXT_NODE */;
|
|
1831
|
+
this.nodeName = '#text';
|
|
1832
|
+
this._value = value;
|
|
1833
|
+
}
|
|
1834
|
+
set textContent(text) {
|
|
1835
|
+
MutationObserver.record({
|
|
1836
|
+
target: this,
|
|
1837
|
+
type: "characterData" /* MutationRecordType.CHARACTER_DATA */,
|
|
1838
|
+
oldValue: this._value
|
|
1839
|
+
});
|
|
1840
|
+
this._value = text;
|
|
1841
|
+
this.enqueueUpdate({
|
|
1842
|
+
path: `${this._path}.${"v" /* Shortcuts.Text */}`,
|
|
1843
|
+
value: text
|
|
1844
|
+
});
|
|
1845
|
+
}
|
|
1846
|
+
get textContent() {
|
|
1847
|
+
return this._value;
|
|
1848
|
+
}
|
|
1849
|
+
set nodeValue(text) {
|
|
1850
|
+
this.textContent = text;
|
|
1851
|
+
}
|
|
1852
|
+
get nodeValue() {
|
|
1853
|
+
return this._value;
|
|
1854
|
+
}
|
|
1855
|
+
set data(text) {
|
|
1856
|
+
this.textContent = text;
|
|
1857
|
+
}
|
|
1858
|
+
get data() {
|
|
1859
|
+
return this._value;
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
/******************************************************************************
|
|
1864
|
+
Copyright (c) Microsoft Corporation.
|
|
1865
|
+
|
|
1866
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
1867
|
+
purpose with or without fee is hereby granted.
|
|
1868
|
+
|
|
1869
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
1870
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
1871
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
1872
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
1873
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
1874
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
1875
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
1876
|
+
***************************************************************************** */
|
|
1877
|
+
/* global Reflect, Promise */
|
|
1878
|
+
|
|
1879
|
+
|
|
1880
|
+
function __classPrivateFieldGet(receiver, state, kind, f) {
|
|
1881
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
1882
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
1883
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
1884
|
+
}
|
|
1885
|
+
|
|
1886
|
+
function __classPrivateFieldSet(receiver, state, value, kind, f) {
|
|
1887
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
1888
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
1889
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
1890
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
var _URLSearchParams_dict;
|
|
1894
|
+
const findReg = /[!'()~]|%20|%00/g;
|
|
1895
|
+
const plusReg = /\+/g;
|
|
1896
|
+
const replaceCharMap = {
|
|
1897
|
+
'!': '%21',
|
|
1898
|
+
"'": '%27',
|
|
1899
|
+
'(': '%28',
|
|
1900
|
+
')': '%29',
|
|
1901
|
+
'~': '%7E',
|
|
1902
|
+
'%20': '+',
|
|
1903
|
+
'%00': '\x00',
|
|
1904
|
+
};
|
|
1905
|
+
function replacer(match) {
|
|
1906
|
+
return replaceCharMap[match];
|
|
1907
|
+
}
|
|
1908
|
+
function appendTo(dict, name, value) {
|
|
1909
|
+
const res = shared.isArray(value) ? value.join(',') : value;
|
|
1910
|
+
if (name in dict)
|
|
1911
|
+
dict[name].push(res);
|
|
1912
|
+
else
|
|
1913
|
+
dict[name] = [res];
|
|
1914
|
+
}
|
|
1915
|
+
function addEach(value, key) {
|
|
1916
|
+
appendTo(this, key, value);
|
|
1917
|
+
}
|
|
1918
|
+
function decode(str) {
|
|
1919
|
+
return decodeURIComponent(str.replace(plusReg, ' '));
|
|
1920
|
+
}
|
|
1921
|
+
function encode(str) {
|
|
1922
|
+
return encodeURIComponent(str).replace(findReg, replacer);
|
|
1923
|
+
}
|
|
1924
|
+
class URLSearchParams {
|
|
1925
|
+
constructor(query) {
|
|
1926
|
+
_URLSearchParams_dict.set(this, Object.create(null));
|
|
1927
|
+
query !== null && query !== void 0 ? query : (query = '');
|
|
1928
|
+
const dict = __classPrivateFieldGet(this, _URLSearchParams_dict, "f");
|
|
1929
|
+
if (typeof query === 'string') {
|
|
1930
|
+
if (query.charAt(0) === '?') {
|
|
1931
|
+
query = query.slice(1);
|
|
1932
|
+
}
|
|
1933
|
+
for (let pairs = query.split('&'), i = 0, length = pairs.length; i < length; i++) {
|
|
1934
|
+
const value = pairs[i];
|
|
1935
|
+
const index = value.indexOf('=');
|
|
1936
|
+
if (index > -1) {
|
|
1937
|
+
appendTo(dict, decode(value.slice(0, index)), decode(value.slice(index + 1)));
|
|
1938
|
+
}
|
|
1939
|
+
else if (value.length) {
|
|
1940
|
+
appendTo(dict, decode(value), '');
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
}
|
|
1944
|
+
else {
|
|
1945
|
+
if (shared.isArray(query)) {
|
|
1946
|
+
for (let i = 0, length = query.length; i < length; i++) {
|
|
1947
|
+
const value = query[i];
|
|
1948
|
+
appendTo(dict, value[0], value[1]);
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
else if (query.forEach) {
|
|
1952
|
+
query.forEach(addEach, dict);
|
|
1953
|
+
}
|
|
1954
|
+
else {
|
|
1955
|
+
for (const key in query) {
|
|
1956
|
+
appendTo(dict, key, query[key]);
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
append(name, value) {
|
|
1962
|
+
appendTo(__classPrivateFieldGet(this, _URLSearchParams_dict, "f"), name, value);
|
|
1963
|
+
}
|
|
1964
|
+
delete(name) {
|
|
1965
|
+
delete __classPrivateFieldGet(this, _URLSearchParams_dict, "f")[name];
|
|
1966
|
+
}
|
|
1967
|
+
get(name) {
|
|
1968
|
+
const dict = __classPrivateFieldGet(this, _URLSearchParams_dict, "f");
|
|
1969
|
+
return name in dict ? dict[name][0] : null;
|
|
1970
|
+
}
|
|
1971
|
+
getAll(name) {
|
|
1972
|
+
const dict = __classPrivateFieldGet(this, _URLSearchParams_dict, "f");
|
|
1973
|
+
return name in dict ? dict[name].slice(0) : [];
|
|
1974
|
+
}
|
|
1975
|
+
has(name) {
|
|
1976
|
+
return name in __classPrivateFieldGet(this, _URLSearchParams_dict, "f");
|
|
1977
|
+
}
|
|
1978
|
+
keys() {
|
|
1979
|
+
return Object.keys(__classPrivateFieldGet(this, _URLSearchParams_dict, "f"));
|
|
1980
|
+
}
|
|
1981
|
+
set(name, value) {
|
|
1982
|
+
__classPrivateFieldGet(this, _URLSearchParams_dict, "f")[name] = ['' + value];
|
|
1983
|
+
}
|
|
1984
|
+
forEach(callback, thisArg) {
|
|
1985
|
+
const dict = __classPrivateFieldGet(this, _URLSearchParams_dict, "f");
|
|
1986
|
+
Object.getOwnPropertyNames(dict).forEach(function (name) {
|
|
1987
|
+
dict[name].forEach(function (value) {
|
|
1988
|
+
callback.call(thisArg, value, name, this);
|
|
1989
|
+
}, this);
|
|
1990
|
+
}, this);
|
|
1991
|
+
}
|
|
1992
|
+
toJSON() {
|
|
1993
|
+
return {};
|
|
1994
|
+
}
|
|
1995
|
+
toString() {
|
|
1996
|
+
const dict = __classPrivateFieldGet(this, _URLSearchParams_dict, "f");
|
|
1997
|
+
const query = [];
|
|
1998
|
+
for (const key in dict) {
|
|
1999
|
+
const name = encode(key);
|
|
2000
|
+
for (let i = 0, value = dict[key]; i < value.length; i++) {
|
|
2001
|
+
query.push(name + '=' + encode(value[i]));
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
return query.join('&');
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
_URLSearchParams_dict = new WeakMap();
|
|
2008
|
+
|
|
2009
|
+
var _URL_hash, _URL_hostname, _URL_pathname, _URL_port, _URL_protocol, _URL_search;
|
|
2010
|
+
class URL {
|
|
2011
|
+
static createObjectURL() {
|
|
2012
|
+
throw new Error('Oops, not support URL.createObjectURL() in miniprogram.');
|
|
2013
|
+
}
|
|
2014
|
+
static revokeObjectURL() {
|
|
2015
|
+
throw new Error('Oops, not support URL.revokeObjectURL() in miniprogram.');
|
|
2016
|
+
}
|
|
2017
|
+
constructor(url, base) {
|
|
2018
|
+
/* private property */
|
|
2019
|
+
_URL_hash.set(this, '');
|
|
2020
|
+
_URL_hostname.set(this, '');
|
|
2021
|
+
_URL_pathname.set(this, '');
|
|
2022
|
+
_URL_port.set(this, '');
|
|
2023
|
+
_URL_protocol.set(this, '');
|
|
2024
|
+
_URL_search.set(this, void 0);
|
|
2025
|
+
if (!shared.isString(url))
|
|
2026
|
+
url = String(url);
|
|
2027
|
+
const parseResult = parseUrlBase(url, base);
|
|
2028
|
+
const { hash, hostname, pathname, port, protocol, search } = parseResult;
|
|
2029
|
+
__classPrivateFieldSet(this, _URL_hash, hash, "f");
|
|
2030
|
+
__classPrivateFieldSet(this, _URL_hostname, hostname, "f");
|
|
2031
|
+
__classPrivateFieldSet(this, _URL_pathname, pathname || '/', "f");
|
|
2032
|
+
__classPrivateFieldSet(this, _URL_port, port, "f");
|
|
2033
|
+
__classPrivateFieldSet(this, _URL_protocol, protocol, "f");
|
|
2034
|
+
__classPrivateFieldSet(this, _URL_search, new URLSearchParams(search), "f");
|
|
2035
|
+
}
|
|
2036
|
+
/* public property */
|
|
2037
|
+
get protocol() {
|
|
2038
|
+
return __classPrivateFieldGet(this, _URL_protocol, "f");
|
|
2039
|
+
}
|
|
2040
|
+
set protocol(val) {
|
|
2041
|
+
shared.isString(val) && (__classPrivateFieldSet(this, _URL_protocol, val.trim(), "f"));
|
|
2042
|
+
}
|
|
2043
|
+
get host() {
|
|
2044
|
+
return this.hostname + (this.port ? ':' + this.port : '');
|
|
2045
|
+
}
|
|
2046
|
+
set host(val) {
|
|
2047
|
+
if (val && shared.isString(val)) {
|
|
2048
|
+
val = val.trim();
|
|
2049
|
+
const { hostname, port } = parseUrl(`//${val}`);
|
|
2050
|
+
this.hostname = hostname;
|
|
2051
|
+
this.port = port;
|
|
2052
|
+
}
|
|
2053
|
+
}
|
|
2054
|
+
get hostname() {
|
|
2055
|
+
return __classPrivateFieldGet(this, _URL_hostname, "f");
|
|
2056
|
+
}
|
|
2057
|
+
set hostname(val) {
|
|
2058
|
+
val && shared.isString(val) && (__classPrivateFieldSet(this, _URL_hostname, val.trim(), "f"));
|
|
2059
|
+
}
|
|
2060
|
+
get port() {
|
|
2061
|
+
return __classPrivateFieldGet(this, _URL_port, "f");
|
|
2062
|
+
}
|
|
2063
|
+
set port(val) {
|
|
2064
|
+
shared.isString(val) && (__classPrivateFieldSet(this, _URL_port, val.trim(), "f"));
|
|
2065
|
+
}
|
|
2066
|
+
get pathname() {
|
|
2067
|
+
return __classPrivateFieldGet(this, _URL_pathname, "f");
|
|
2068
|
+
}
|
|
2069
|
+
set pathname(val) {
|
|
2070
|
+
if (shared.isString(val)) {
|
|
2071
|
+
val = val.trim();
|
|
2072
|
+
const HEAD_REG = /^(\/|\.\/|\.\.\/)/;
|
|
2073
|
+
let temp = val;
|
|
2074
|
+
while (HEAD_REG.test(temp)) {
|
|
2075
|
+
temp = temp.replace(HEAD_REG, '');
|
|
2076
|
+
}
|
|
2077
|
+
if (temp)
|
|
2078
|
+
__classPrivateFieldSet(this, _URL_pathname, '/' + temp, "f");
|
|
2079
|
+
else
|
|
2080
|
+
__classPrivateFieldSet(this, _URL_pathname, '/', "f");
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
get search() {
|
|
2084
|
+
const val = __classPrivateFieldGet(this, _URL_search, "f").toString();
|
|
2085
|
+
return (val.length === 0 || val.startsWith('?')) ? val : `?${val}`;
|
|
2086
|
+
}
|
|
2087
|
+
set search(val) {
|
|
2088
|
+
if (shared.isString(val)) {
|
|
2089
|
+
val = val.trim();
|
|
2090
|
+
__classPrivateFieldSet(this, _URL_search, new URLSearchParams(val), "f");
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
get hash() {
|
|
2094
|
+
return __classPrivateFieldGet(this, _URL_hash, "f");
|
|
2095
|
+
}
|
|
2096
|
+
set hash(val) {
|
|
2097
|
+
if (shared.isString(val)) {
|
|
2098
|
+
val = val.trim();
|
|
2099
|
+
if (val)
|
|
2100
|
+
__classPrivateFieldSet(this, _URL_hash, val.startsWith('#') ? val : `#${val}`, "f");
|
|
2101
|
+
else
|
|
2102
|
+
__classPrivateFieldSet(this, _URL_hash, '', "f");
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
2105
|
+
get href() {
|
|
2106
|
+
return `${this.protocol}//${this.host}${this.pathname}${this.search}${this.hash}`;
|
|
2107
|
+
}
|
|
2108
|
+
set href(val) {
|
|
2109
|
+
if (val && shared.isString(val)) {
|
|
2110
|
+
val = val.trim();
|
|
2111
|
+
const { protocol, hostname, port, hash, search, pathname } = parseUrl(val);
|
|
2112
|
+
this.protocol = protocol;
|
|
2113
|
+
this.hostname = hostname;
|
|
2114
|
+
this.pathname = pathname;
|
|
2115
|
+
this.port = port;
|
|
2116
|
+
this.hash = hash;
|
|
2117
|
+
this.search = search;
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
get origin() {
|
|
2121
|
+
return `${this.protocol}//${this.host}`;
|
|
2122
|
+
}
|
|
2123
|
+
set origin(val) {
|
|
2124
|
+
if (val && shared.isString(val)) {
|
|
2125
|
+
val = val.trim();
|
|
2126
|
+
const { protocol, hostname, port } = parseUrl(val);
|
|
2127
|
+
this.protocol = protocol;
|
|
2128
|
+
this.hostname = hostname;
|
|
2129
|
+
this.port = port;
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
get searchParams() {
|
|
2133
|
+
return __classPrivateFieldGet(this, _URL_search, "f");
|
|
2134
|
+
}
|
|
2135
|
+
// public method
|
|
2136
|
+
toString() {
|
|
2137
|
+
return this.href;
|
|
2138
|
+
}
|
|
2139
|
+
toJSON() {
|
|
2140
|
+
return this.toString();
|
|
2141
|
+
}
|
|
2142
|
+
// convenient for deconstructor
|
|
2143
|
+
_toRaw() {
|
|
2144
|
+
return {
|
|
2145
|
+
protocol: this.protocol,
|
|
2146
|
+
port: this.port,
|
|
2147
|
+
host: this.host,
|
|
2148
|
+
hostname: this.hostname,
|
|
2149
|
+
pathname: this.pathname,
|
|
2150
|
+
hash: this.hash,
|
|
2151
|
+
search: this.search,
|
|
2152
|
+
origin: this.origin,
|
|
2153
|
+
href: this.href,
|
|
2154
|
+
};
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
_URL_hash = new WeakMap(), _URL_hostname = new WeakMap(), _URL_pathname = new WeakMap(), _URL_port = new WeakMap(), _URL_protocol = new WeakMap(), _URL_search = new WeakMap();
|
|
2158
|
+
function parseUrl(url = '') {
|
|
2159
|
+
const result = {
|
|
2160
|
+
href: '',
|
|
2161
|
+
origin: '',
|
|
2162
|
+
protocol: '',
|
|
2163
|
+
hostname: '',
|
|
2164
|
+
host: '',
|
|
2165
|
+
port: '',
|
|
2166
|
+
pathname: '',
|
|
2167
|
+
search: '',
|
|
2168
|
+
hash: ''
|
|
2169
|
+
};
|
|
2170
|
+
if (!url || !shared.isString(url))
|
|
2171
|
+
return result;
|
|
2172
|
+
url = url.trim();
|
|
2173
|
+
const PATTERN = /^(([^:/?#]+):)?\/\/(([^/?#]+):(.+)@)?([^/?#:]*)(:(\d+))?([^?#]*)(\?([^#]*))?(#(.*))?/;
|
|
2174
|
+
const matches = url.match(PATTERN);
|
|
2175
|
+
if (!matches)
|
|
2176
|
+
return result;
|
|
2177
|
+
// TODO: username & password ?
|
|
2178
|
+
result.protocol = matches[1] || 'https:';
|
|
2179
|
+
result.hostname = matches[6] || 'taro.com';
|
|
2180
|
+
result.port = matches[8] || '';
|
|
2181
|
+
result.pathname = matches[9] || '/';
|
|
2182
|
+
result.search = matches[10] || '';
|
|
2183
|
+
result.hash = matches[12] || '';
|
|
2184
|
+
result.href = url;
|
|
2185
|
+
result.origin = result.protocol + '//' + result.hostname;
|
|
2186
|
+
result.host = result.hostname + (result.port ? `:${result.port}` : '');
|
|
2187
|
+
return result;
|
|
2188
|
+
}
|
|
2189
|
+
function parseUrlBase(url, base) {
|
|
2190
|
+
const VALID_URL = /^(https?:)\/\//i;
|
|
2191
|
+
let fullUrl = '';
|
|
2192
|
+
let parsedBase = null;
|
|
2193
|
+
if (!shared.isUndefined(base)) {
|
|
2194
|
+
base = String(base).trim();
|
|
2195
|
+
if (!VALID_URL.test(base))
|
|
2196
|
+
throw new TypeError(`Failed to construct 'URL': Invalid base URL`);
|
|
2197
|
+
parsedBase = parseUrl(base);
|
|
2198
|
+
}
|
|
2199
|
+
url = String(url).trim();
|
|
2200
|
+
if (VALID_URL.test(url)) {
|
|
2201
|
+
fullUrl = url;
|
|
2202
|
+
}
|
|
2203
|
+
else if (parsedBase) {
|
|
2204
|
+
if (url) {
|
|
2205
|
+
if (url.startsWith('//')) {
|
|
2206
|
+
fullUrl = parsedBase.protocol + url;
|
|
2207
|
+
}
|
|
2208
|
+
else {
|
|
2209
|
+
fullUrl = parsedBase.origin + (url.startsWith('/') ? url : `/${url}`);
|
|
2210
|
+
}
|
|
2211
|
+
}
|
|
2212
|
+
else {
|
|
2213
|
+
fullUrl = parsedBase.href;
|
|
2214
|
+
}
|
|
2215
|
+
}
|
|
2216
|
+
else {
|
|
2217
|
+
throw new TypeError(`Failed to construct 'URL': Invalid URL`);
|
|
2218
|
+
}
|
|
2219
|
+
return parseUrl(fullUrl);
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2222
|
+
class AnchorElement extends TaroElement {
|
|
2223
|
+
get href() {
|
|
2224
|
+
var _a;
|
|
2225
|
+
return (_a = this.props["href" /* AnchorElementAttrs.HREF */]) !== null && _a !== void 0 ? _a : '';
|
|
2226
|
+
}
|
|
2227
|
+
set href(val) {
|
|
2228
|
+
this.setAttribute("href" /* AnchorElementAttrs.HREF */, val);
|
|
2229
|
+
}
|
|
2230
|
+
get protocol() {
|
|
2231
|
+
var _a;
|
|
2232
|
+
return (_a = this.props["protocol" /* AnchorElementAttrs.PROTOCOL */]) !== null && _a !== void 0 ? _a : '';
|
|
2233
|
+
}
|
|
2234
|
+
get host() {
|
|
2235
|
+
var _a;
|
|
2236
|
+
return (_a = this.props["host" /* AnchorElementAttrs.HOST */]) !== null && _a !== void 0 ? _a : '';
|
|
2237
|
+
}
|
|
2238
|
+
get search() {
|
|
2239
|
+
var _a;
|
|
2240
|
+
return (_a = this.props["search" /* AnchorElementAttrs.SEARCH */]) !== null && _a !== void 0 ? _a : '';
|
|
2241
|
+
}
|
|
2242
|
+
get hash() {
|
|
2243
|
+
var _a;
|
|
2244
|
+
return (_a = this.props["hash" /* AnchorElementAttrs.HASH */]) !== null && _a !== void 0 ? _a : '';
|
|
2245
|
+
}
|
|
2246
|
+
get hostname() {
|
|
2247
|
+
var _a;
|
|
2248
|
+
return (_a = this.props["hostname" /* AnchorElementAttrs.HOSTNAME */]) !== null && _a !== void 0 ? _a : '';
|
|
2249
|
+
}
|
|
2250
|
+
get port() {
|
|
2251
|
+
var _a;
|
|
2252
|
+
return (_a = this.props["port" /* AnchorElementAttrs.PORT */]) !== null && _a !== void 0 ? _a : '';
|
|
2253
|
+
}
|
|
2254
|
+
get pathname() {
|
|
2255
|
+
var _a;
|
|
2256
|
+
return (_a = this.props["pathname" /* AnchorElementAttrs.PATHNAME */]) !== null && _a !== void 0 ? _a : '';
|
|
2257
|
+
}
|
|
2258
|
+
setAttribute(qualifiedName, value) {
|
|
2259
|
+
if (qualifiedName === "href" /* AnchorElementAttrs.HREF */) {
|
|
2260
|
+
const willSetAttr = parseUrl(value);
|
|
2261
|
+
for (const k in willSetAttr) {
|
|
2262
|
+
super.setAttribute(k, willSetAttr[k]);
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
else {
|
|
2266
|
+
super.setAttribute(qualifiedName, value);
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
|
|
2271
|
+
class CustomWrapperElement extends TaroElement {
|
|
2272
|
+
}
|
|
2273
|
+
|
|
2274
|
+
class TaroDocument extends TaroElement {
|
|
2275
|
+
constructor() {
|
|
2276
|
+
super();
|
|
2277
|
+
this.createEvent = createEvent;
|
|
2278
|
+
this.nodeType = 9 /* NodeType.DOCUMENT_NODE */;
|
|
2279
|
+
this.nodeName = DOCUMENT_ELEMENT_NAME;
|
|
2280
|
+
}
|
|
2281
|
+
createElement(type) {
|
|
2282
|
+
const nodeName = type.toLowerCase();
|
|
2283
|
+
let element;
|
|
2284
|
+
switch (true) {
|
|
2285
|
+
case nodeName === ROOT_STR:
|
|
2286
|
+
element = new TaroRootElement();
|
|
2287
|
+
return element;
|
|
2288
|
+
case shared.controlledComponent.has(nodeName):
|
|
2289
|
+
element = new FormElement();
|
|
2290
|
+
break;
|
|
2291
|
+
case nodeName === A:
|
|
2292
|
+
element = new AnchorElement();
|
|
2293
|
+
break;
|
|
2294
|
+
case nodeName === CUSTOM_WRAPPER:
|
|
2295
|
+
element = new CustomWrapperElement();
|
|
2296
|
+
break;
|
|
2297
|
+
default:
|
|
2298
|
+
element = new TaroElement();
|
|
2299
|
+
break;
|
|
2300
|
+
}
|
|
2301
|
+
element.nodeName = nodeName;
|
|
2302
|
+
element.tagName = type.toUpperCase();
|
|
2303
|
+
return element;
|
|
2304
|
+
}
|
|
2305
|
+
// an ugly fake createElementNS to deal with @vue/runtime-dom's
|
|
2306
|
+
// support mounting app to svg container since vue@3.0.8
|
|
2307
|
+
createElementNS(_svgNS, type) {
|
|
2308
|
+
return this.createElement(type);
|
|
2309
|
+
}
|
|
2310
|
+
createTextNode(text) {
|
|
2311
|
+
return new TaroText(text);
|
|
2312
|
+
}
|
|
2313
|
+
getElementById(id) {
|
|
2314
|
+
const el = eventSource.get(id);
|
|
2315
|
+
return shared.isUndefined(el) ? null : el;
|
|
2316
|
+
}
|
|
2317
|
+
querySelector(query) {
|
|
2318
|
+
// 为了 Vue3 的乞丐版实现
|
|
2319
|
+
if (/^#/.test(query)) {
|
|
2320
|
+
return this.getElementById(query.slice(1));
|
|
2321
|
+
}
|
|
2322
|
+
return null;
|
|
2323
|
+
}
|
|
2324
|
+
querySelectorAll() {
|
|
2325
|
+
// fake hack
|
|
2326
|
+
return [];
|
|
2327
|
+
}
|
|
2328
|
+
// @TODO: @PERF: 在 hydrate 移除掉空的 node
|
|
2329
|
+
createComment() {
|
|
2330
|
+
const textnode = new TaroText('');
|
|
2331
|
+
textnode.nodeName = COMMENT;
|
|
2332
|
+
return textnode;
|
|
2333
|
+
}
|
|
2334
|
+
get defaultView() {
|
|
2335
|
+
return env.window;
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
|
|
2339
|
+
exports.document = void 0;
|
|
2340
|
+
if (process.env.TARO_ENV && !true) {
|
|
2341
|
+
/* eslint-disable no-inner-declarations */
|
|
2342
|
+
function createDocument() {
|
|
2343
|
+
/**
|
|
2344
|
+
* <document>
|
|
2345
|
+
* <html>
|
|
2346
|
+
* <head></head>
|
|
2347
|
+
* <body>
|
|
2348
|
+
* <container>
|
|
2349
|
+
* <app id="app" />
|
|
2350
|
+
* </container>
|
|
2351
|
+
* </body>
|
|
2352
|
+
* </html>
|
|
2353
|
+
* </document>
|
|
2354
|
+
*/
|
|
2355
|
+
const doc = new TaroDocument();
|
|
2356
|
+
const documentCreateElement = doc.createElement.bind(doc);
|
|
2357
|
+
const html = documentCreateElement(HTML);
|
|
2358
|
+
const head = documentCreateElement(HEAD);
|
|
2359
|
+
const body = documentCreateElement(BODY);
|
|
2360
|
+
const app = documentCreateElement(APP);
|
|
2361
|
+
app.id = APP;
|
|
2362
|
+
const container = documentCreateElement(CONTAINER); // 多包一层主要为了兼容 vue
|
|
2363
|
+
doc.appendChild(html);
|
|
2364
|
+
html.appendChild(head);
|
|
2365
|
+
html.appendChild(body);
|
|
2366
|
+
body.appendChild(container);
|
|
2367
|
+
container.appendChild(app);
|
|
2368
|
+
doc.documentElement = html;
|
|
2369
|
+
doc.head = head;
|
|
2370
|
+
doc.body = body;
|
|
2371
|
+
return doc;
|
|
2372
|
+
}
|
|
2373
|
+
exports.document = env.document = createDocument();
|
|
2374
|
+
}
|
|
2375
|
+
else {
|
|
2376
|
+
exports.document = env.document;
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2379
|
+
function getComputedStyle(element) {
|
|
2380
|
+
return element.style;
|
|
2381
|
+
}
|
|
2382
|
+
|
|
2383
|
+
const eventCenter = shared.hooks.call('getEventCenter', shared.Events);
|
|
2384
|
+
|
|
2385
|
+
/**
|
|
2386
|
+
* 一个小型缓存池,用于在切换页面时,存储一些上下文信息
|
|
2387
|
+
*/
|
|
2388
|
+
class RuntimeCache {
|
|
2389
|
+
constructor(name) {
|
|
2390
|
+
this.cache = new Map();
|
|
2391
|
+
this.name = name;
|
|
2392
|
+
}
|
|
2393
|
+
has(identifier) {
|
|
2394
|
+
return this.cache.has(identifier);
|
|
2395
|
+
}
|
|
2396
|
+
set(identifier, ctx) {
|
|
2397
|
+
if (identifier && ctx) {
|
|
2398
|
+
this.cache.set(identifier, ctx);
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2401
|
+
get(identifier) {
|
|
2402
|
+
if (this.has(identifier))
|
|
2403
|
+
return this.cache.get(identifier);
|
|
2404
|
+
}
|
|
2405
|
+
delete(identifier) {
|
|
2406
|
+
this.cache.delete(identifier);
|
|
2407
|
+
}
|
|
2408
|
+
}
|
|
2409
|
+
|
|
2410
|
+
var _History_instances, _History_location, _History_stack, _History_cur, _History_window, _History_reset;
|
|
2411
|
+
const cache$1 = new RuntimeCache('history');
|
|
2412
|
+
class History extends shared.Events {
|
|
2413
|
+
constructor(location, options) {
|
|
2414
|
+
super();
|
|
2415
|
+
_History_instances.add(this);
|
|
2416
|
+
/* private property */
|
|
2417
|
+
_History_location.set(this, void 0);
|
|
2418
|
+
_History_stack.set(this, []);
|
|
2419
|
+
_History_cur.set(this, 0);
|
|
2420
|
+
_History_window.set(this, void 0);
|
|
2421
|
+
__classPrivateFieldSet(this, _History_window, options.window, "f");
|
|
2422
|
+
__classPrivateFieldSet(this, _History_location, location, "f");
|
|
2423
|
+
__classPrivateFieldGet(this, _History_location, "f").on('__record_history__', (href) => {
|
|
2424
|
+
var _a;
|
|
2425
|
+
__classPrivateFieldSet(this, _History_cur, (_a = __classPrivateFieldGet(this, _History_cur, "f"), _a++, _a), "f");
|
|
2426
|
+
__classPrivateFieldSet(this, _History_stack, __classPrivateFieldGet(this, _History_stack, "f").slice(0, __classPrivateFieldGet(this, _History_cur, "f")), "f");
|
|
2427
|
+
__classPrivateFieldGet(this, _History_stack, "f").push({
|
|
2428
|
+
state: null,
|
|
2429
|
+
title: '',
|
|
2430
|
+
url: href
|
|
2431
|
+
});
|
|
2432
|
+
}, null);
|
|
2433
|
+
__classPrivateFieldGet(this, _History_location, "f").on('__reset_history__', (href) => {
|
|
2434
|
+
__classPrivateFieldGet(this, _History_instances, "m", _History_reset).call(this, href);
|
|
2435
|
+
}, null);
|
|
2436
|
+
// 切换上下文行为
|
|
2437
|
+
this.on(CONTEXT_ACTIONS.INIT, () => {
|
|
2438
|
+
__classPrivateFieldGet(this, _History_instances, "m", _History_reset).call(this);
|
|
2439
|
+
}, null);
|
|
2440
|
+
this.on(CONTEXT_ACTIONS.RESTORE, (pageId) => {
|
|
2441
|
+
cache$1.set(pageId, {
|
|
2442
|
+
location: __classPrivateFieldGet(this, _History_location, "f"),
|
|
2443
|
+
stack: __classPrivateFieldGet(this, _History_stack, "f").slice(),
|
|
2444
|
+
cur: __classPrivateFieldGet(this, _History_cur, "f")
|
|
2445
|
+
});
|
|
2446
|
+
}, null);
|
|
2447
|
+
this.on(CONTEXT_ACTIONS.RECOVER, (pageId) => {
|
|
2448
|
+
if (cache$1.has(pageId)) {
|
|
2449
|
+
const ctx = cache$1.get(pageId);
|
|
2450
|
+
__classPrivateFieldSet(this, _History_location, ctx.location, "f");
|
|
2451
|
+
__classPrivateFieldSet(this, _History_stack, ctx.stack, "f");
|
|
2452
|
+
__classPrivateFieldSet(this, _History_cur, ctx.cur, "f");
|
|
2453
|
+
}
|
|
2454
|
+
}, null);
|
|
2455
|
+
this.on(CONTEXT_ACTIONS.DESTORY, (pageId) => {
|
|
2456
|
+
cache$1.delete(pageId);
|
|
2457
|
+
}, null);
|
|
2458
|
+
__classPrivateFieldGet(this, _History_instances, "m", _History_reset).call(this);
|
|
2459
|
+
}
|
|
2460
|
+
/* public property */
|
|
2461
|
+
get length() {
|
|
2462
|
+
return __classPrivateFieldGet(this, _History_stack, "f").length;
|
|
2463
|
+
}
|
|
2464
|
+
get state() {
|
|
2465
|
+
return __classPrivateFieldGet(this, _History_stack, "f")[__classPrivateFieldGet(this, _History_cur, "f")].state;
|
|
2466
|
+
}
|
|
2467
|
+
/* public method */
|
|
2468
|
+
go(delta) {
|
|
2469
|
+
if (!shared.isNumber(delta) || isNaN(delta))
|
|
2470
|
+
return;
|
|
2471
|
+
let targetIdx = __classPrivateFieldGet(this, _History_cur, "f") + delta;
|
|
2472
|
+
targetIdx = Math.min(Math.max(targetIdx, 0), this.length - 1);
|
|
2473
|
+
__classPrivateFieldSet(this, _History_cur, targetIdx, "f");
|
|
2474
|
+
__classPrivateFieldGet(this, _History_location, "f").trigger('__set_href_without_history__', __classPrivateFieldGet(this, _History_stack, "f")[__classPrivateFieldGet(this, _History_cur, "f")].url);
|
|
2475
|
+
__classPrivateFieldGet(this, _History_window, "f").trigger('popstate', __classPrivateFieldGet(this, _History_stack, "f")[__classPrivateFieldGet(this, _History_cur, "f")]);
|
|
2476
|
+
}
|
|
2477
|
+
back() {
|
|
2478
|
+
this.go(-1);
|
|
2479
|
+
}
|
|
2480
|
+
forward() {
|
|
2481
|
+
this.go(1);
|
|
2482
|
+
}
|
|
2483
|
+
pushState(state, title, url) {
|
|
2484
|
+
if (!url || !shared.isString(url))
|
|
2485
|
+
return;
|
|
2486
|
+
__classPrivateFieldSet(this, _History_stack, __classPrivateFieldGet(this, _History_stack, "f").slice(0, __classPrivateFieldGet(this, _History_cur, "f") + 1), "f");
|
|
2487
|
+
__classPrivateFieldGet(this, _History_stack, "f").push({
|
|
2488
|
+
state,
|
|
2489
|
+
title,
|
|
2490
|
+
url
|
|
2491
|
+
});
|
|
2492
|
+
__classPrivateFieldSet(this, _History_cur, this.length - 1, "f");
|
|
2493
|
+
__classPrivateFieldGet(this, _History_location, "f").trigger('__set_href_without_history__', url);
|
|
2494
|
+
}
|
|
2495
|
+
replaceState(state, title, url) {
|
|
2496
|
+
if (!url || !shared.isString(url))
|
|
2497
|
+
return;
|
|
2498
|
+
__classPrivateFieldGet(this, _History_stack, "f")[__classPrivateFieldGet(this, _History_cur, "f")] = {
|
|
2499
|
+
state,
|
|
2500
|
+
title,
|
|
2501
|
+
url
|
|
2502
|
+
};
|
|
2503
|
+
__classPrivateFieldGet(this, _History_location, "f").trigger('__set_href_without_history__', url);
|
|
2504
|
+
}
|
|
2505
|
+
// For debug
|
|
2506
|
+
get cache() {
|
|
2507
|
+
return cache$1;
|
|
2508
|
+
}
|
|
2509
|
+
}
|
|
2510
|
+
_History_location = new WeakMap(), _History_stack = new WeakMap(), _History_cur = new WeakMap(), _History_window = new WeakMap(), _History_instances = new WeakSet(), _History_reset = function _History_reset(href = '') {
|
|
2511
|
+
__classPrivateFieldSet(this, _History_stack, [
|
|
2512
|
+
{
|
|
2513
|
+
state: null,
|
|
2514
|
+
title: '',
|
|
2515
|
+
url: href || __classPrivateFieldGet(this, _History_location, "f").href
|
|
2516
|
+
}
|
|
2517
|
+
], "f");
|
|
2518
|
+
__classPrivateFieldSet(this, _History_cur, 0, "f");
|
|
2519
|
+
};
|
|
2520
|
+
|
|
2521
|
+
const Current = {
|
|
2522
|
+
app: null,
|
|
2523
|
+
router: null,
|
|
2524
|
+
page: null
|
|
2525
|
+
};
|
|
2526
|
+
const getCurrentInstance = () => Current;
|
|
2527
|
+
|
|
2528
|
+
var _Location_instances, _Location_url, _Location_noCheckUrl, _Location_window, _Location_reset, _Location_getPreValue, _Location_rollBack, _Location_recordHistory, _Location_checkUrlChange;
|
|
2529
|
+
const INIT_URL = 'https://taro.com';
|
|
2530
|
+
const cache = new RuntimeCache('location');
|
|
2531
|
+
class Location extends shared.Events {
|
|
2532
|
+
constructor(options) {
|
|
2533
|
+
super();
|
|
2534
|
+
_Location_instances.add(this);
|
|
2535
|
+
/* private property */
|
|
2536
|
+
_Location_url.set(this, new URL(INIT_URL));
|
|
2537
|
+
_Location_noCheckUrl.set(this, false);
|
|
2538
|
+
_Location_window.set(this, void 0);
|
|
2539
|
+
__classPrivateFieldSet(this, _Location_window, options.window, "f");
|
|
2540
|
+
__classPrivateFieldGet(this, _Location_instances, "m", _Location_reset).call(this);
|
|
2541
|
+
this.on('__set_href_without_history__', (href) => {
|
|
2542
|
+
__classPrivateFieldSet(this, _Location_noCheckUrl, true, "f");
|
|
2543
|
+
const lastHash = __classPrivateFieldGet(this, _Location_url, "f").hash;
|
|
2544
|
+
__classPrivateFieldGet(this, _Location_url, "f").href = generateFullUrl(href);
|
|
2545
|
+
if (lastHash !== __classPrivateFieldGet(this, _Location_url, "f").hash) {
|
|
2546
|
+
__classPrivateFieldGet(this, _Location_window, "f").trigger('hashchange');
|
|
2547
|
+
}
|
|
2548
|
+
__classPrivateFieldSet(this, _Location_noCheckUrl, false, "f");
|
|
2549
|
+
}, null);
|
|
2550
|
+
// 切换上下文行为
|
|
2551
|
+
this.on(CONTEXT_ACTIONS.INIT, () => {
|
|
2552
|
+
__classPrivateFieldGet(this, _Location_instances, "m", _Location_reset).call(this);
|
|
2553
|
+
}, null);
|
|
2554
|
+
this.on(CONTEXT_ACTIONS.RESTORE, (pageId) => {
|
|
2555
|
+
cache.set(pageId, {
|
|
2556
|
+
lastHref: this.href,
|
|
2557
|
+
});
|
|
2558
|
+
}, null);
|
|
2559
|
+
this.on(CONTEXT_ACTIONS.RECOVER, (pageId) => {
|
|
2560
|
+
// 数据恢复时,不需要执行跳转
|
|
2561
|
+
if (cache.has(pageId)) {
|
|
2562
|
+
const ctx = cache.get(pageId);
|
|
2563
|
+
__classPrivateFieldSet(this, _Location_noCheckUrl, true, "f");
|
|
2564
|
+
__classPrivateFieldGet(this, _Location_url, "f").href = ctx.lastHref;
|
|
2565
|
+
__classPrivateFieldSet(this, _Location_noCheckUrl, false, "f");
|
|
2566
|
+
}
|
|
2567
|
+
}, null);
|
|
2568
|
+
this.on(CONTEXT_ACTIONS.DESTORY, (pageId) => {
|
|
2569
|
+
cache.delete(pageId);
|
|
2570
|
+
}, null);
|
|
2571
|
+
}
|
|
2572
|
+
/* public property */
|
|
2573
|
+
get protocol() {
|
|
2574
|
+
return __classPrivateFieldGet(this, _Location_url, "f").protocol;
|
|
2575
|
+
}
|
|
2576
|
+
set protocol(val) {
|
|
2577
|
+
const REG = /^(http|https):$/i;
|
|
2578
|
+
if (!val || !shared.isString(val) || !REG.test(val.trim()))
|
|
2579
|
+
return;
|
|
2580
|
+
val = val.trim();
|
|
2581
|
+
const preValue = __classPrivateFieldGet(this, _Location_instances, "m", _Location_getPreValue).call(this);
|
|
2582
|
+
__classPrivateFieldGet(this, _Location_url, "f").protocol = val;
|
|
2583
|
+
if (__classPrivateFieldGet(this, _Location_instances, "m", _Location_checkUrlChange).call(this, preValue))
|
|
2584
|
+
__classPrivateFieldGet(this, _Location_instances, "m", _Location_recordHistory).call(this);
|
|
2585
|
+
}
|
|
2586
|
+
get host() {
|
|
2587
|
+
return __classPrivateFieldGet(this, _Location_url, "f").host;
|
|
2588
|
+
}
|
|
2589
|
+
set host(val) {
|
|
2590
|
+
if (!val || !shared.isString(val))
|
|
2591
|
+
return;
|
|
2592
|
+
val = val.trim();
|
|
2593
|
+
const preValue = __classPrivateFieldGet(this, _Location_instances, "m", _Location_getPreValue).call(this);
|
|
2594
|
+
__classPrivateFieldGet(this, _Location_url, "f").host = val;
|
|
2595
|
+
if (__classPrivateFieldGet(this, _Location_instances, "m", _Location_checkUrlChange).call(this, preValue))
|
|
2596
|
+
__classPrivateFieldGet(this, _Location_instances, "m", _Location_recordHistory).call(this);
|
|
2597
|
+
}
|
|
2598
|
+
get hostname() {
|
|
2599
|
+
return __classPrivateFieldGet(this, _Location_url, "f").hostname;
|
|
2600
|
+
}
|
|
2601
|
+
set hostname(val) {
|
|
2602
|
+
if (!val || !shared.isString(val))
|
|
2603
|
+
return;
|
|
2604
|
+
val = val.trim();
|
|
2605
|
+
const preValue = __classPrivateFieldGet(this, _Location_instances, "m", _Location_getPreValue).call(this);
|
|
2606
|
+
__classPrivateFieldGet(this, _Location_url, "f").hostname = val;
|
|
2607
|
+
if (__classPrivateFieldGet(this, _Location_instances, "m", _Location_checkUrlChange).call(this, preValue))
|
|
2608
|
+
__classPrivateFieldGet(this, _Location_instances, "m", _Location_recordHistory).call(this);
|
|
2609
|
+
}
|
|
2610
|
+
get port() {
|
|
2611
|
+
return __classPrivateFieldGet(this, _Location_url, "f").port;
|
|
2612
|
+
}
|
|
2613
|
+
set port(val) {
|
|
2614
|
+
const xVal = Number((val = val.trim()));
|
|
2615
|
+
if (!shared.isNumber(xVal) || xVal <= 0)
|
|
2616
|
+
return;
|
|
2617
|
+
const preValue = __classPrivateFieldGet(this, _Location_instances, "m", _Location_getPreValue).call(this);
|
|
2618
|
+
__classPrivateFieldGet(this, _Location_url, "f").port = val;
|
|
2619
|
+
if (__classPrivateFieldGet(this, _Location_instances, "m", _Location_checkUrlChange).call(this, preValue))
|
|
2620
|
+
__classPrivateFieldGet(this, _Location_instances, "m", _Location_recordHistory).call(this);
|
|
2621
|
+
}
|
|
2622
|
+
get pathname() {
|
|
2623
|
+
return __classPrivateFieldGet(this, _Location_url, "f").pathname;
|
|
2624
|
+
}
|
|
2625
|
+
set pathname(val) {
|
|
2626
|
+
if (!val || !shared.isString(val))
|
|
2627
|
+
return;
|
|
2628
|
+
val = val.trim();
|
|
2629
|
+
const preValue = __classPrivateFieldGet(this, _Location_instances, "m", _Location_getPreValue).call(this);
|
|
2630
|
+
__classPrivateFieldGet(this, _Location_url, "f").pathname = val;
|
|
2631
|
+
if (__classPrivateFieldGet(this, _Location_instances, "m", _Location_checkUrlChange).call(this, preValue))
|
|
2632
|
+
__classPrivateFieldGet(this, _Location_instances, "m", _Location_recordHistory).call(this);
|
|
2633
|
+
}
|
|
2634
|
+
get search() {
|
|
2635
|
+
return __classPrivateFieldGet(this, _Location_url, "f").search;
|
|
2636
|
+
}
|
|
2637
|
+
set search(val) {
|
|
2638
|
+
if (!val || !shared.isString(val))
|
|
2639
|
+
return;
|
|
2640
|
+
val = val.trim();
|
|
2641
|
+
val = val.startsWith('?') ? val : `?${val}`;
|
|
2642
|
+
const preValue = __classPrivateFieldGet(this, _Location_instances, "m", _Location_getPreValue).call(this);
|
|
2643
|
+
__classPrivateFieldGet(this, _Location_url, "f").search = val;
|
|
2644
|
+
if (__classPrivateFieldGet(this, _Location_instances, "m", _Location_checkUrlChange).call(this, preValue))
|
|
2645
|
+
__classPrivateFieldGet(this, _Location_instances, "m", _Location_recordHistory).call(this);
|
|
2646
|
+
}
|
|
2647
|
+
get hash() {
|
|
2648
|
+
return __classPrivateFieldGet(this, _Location_url, "f").hash;
|
|
2649
|
+
}
|
|
2650
|
+
// 小程序的navigateTo存在截断hash字符串的问题
|
|
2651
|
+
set hash(val) {
|
|
2652
|
+
if (!val || !shared.isString(val))
|
|
2653
|
+
return;
|
|
2654
|
+
val = val.trim();
|
|
2655
|
+
val = val.startsWith('#') ? val : `#${val}`;
|
|
2656
|
+
const preValue = __classPrivateFieldGet(this, _Location_instances, "m", _Location_getPreValue).call(this);
|
|
2657
|
+
__classPrivateFieldGet(this, _Location_url, "f").hash = val;
|
|
2658
|
+
if (__classPrivateFieldGet(this, _Location_instances, "m", _Location_checkUrlChange).call(this, preValue))
|
|
2659
|
+
__classPrivateFieldGet(this, _Location_instances, "m", _Location_recordHistory).call(this);
|
|
2660
|
+
}
|
|
2661
|
+
get href() {
|
|
2662
|
+
return __classPrivateFieldGet(this, _Location_url, "f").href;
|
|
2663
|
+
}
|
|
2664
|
+
set href(val) {
|
|
2665
|
+
const REG = /^(http:|https:)?\/\/.+/;
|
|
2666
|
+
if (!val || !shared.isString(val) || !REG.test((val = val.trim())))
|
|
2667
|
+
return;
|
|
2668
|
+
const preValue = __classPrivateFieldGet(this, _Location_instances, "m", _Location_getPreValue).call(this);
|
|
2669
|
+
__classPrivateFieldGet(this, _Location_url, "f").href = val;
|
|
2670
|
+
if (__classPrivateFieldGet(this, _Location_instances, "m", _Location_checkUrlChange).call(this, preValue))
|
|
2671
|
+
__classPrivateFieldGet(this, _Location_instances, "m", _Location_recordHistory).call(this);
|
|
2672
|
+
}
|
|
2673
|
+
get origin() {
|
|
2674
|
+
return __classPrivateFieldGet(this, _Location_url, "f").origin;
|
|
2675
|
+
}
|
|
2676
|
+
set origin(val) {
|
|
2677
|
+
const REG = /^(http:|https:)?\/\/.+/;
|
|
2678
|
+
if (!val || !shared.isString(val) || !REG.test((val = val.trim())))
|
|
2679
|
+
return;
|
|
2680
|
+
const preValue = __classPrivateFieldGet(this, _Location_instances, "m", _Location_getPreValue).call(this);
|
|
2681
|
+
__classPrivateFieldGet(this, _Location_url, "f").origin = val;
|
|
2682
|
+
if (__classPrivateFieldGet(this, _Location_instances, "m", _Location_checkUrlChange).call(this, preValue))
|
|
2683
|
+
__classPrivateFieldGet(this, _Location_instances, "m", _Location_recordHistory).call(this);
|
|
2684
|
+
}
|
|
2685
|
+
/* public method */
|
|
2686
|
+
assign() {
|
|
2687
|
+
shared.warn(true, '小程序环境中调用location.assign()无效.');
|
|
2688
|
+
}
|
|
2689
|
+
reload() {
|
|
2690
|
+
shared.warn(true, '小程序环境中调用location.reload()无效.');
|
|
2691
|
+
}
|
|
2692
|
+
replace(url) {
|
|
2693
|
+
this.trigger('__set_href_without_history__', url);
|
|
2694
|
+
}
|
|
2695
|
+
toString() {
|
|
2696
|
+
return this.href;
|
|
2697
|
+
}
|
|
2698
|
+
// For debug
|
|
2699
|
+
get cache() {
|
|
2700
|
+
return cache;
|
|
2701
|
+
}
|
|
2702
|
+
}
|
|
2703
|
+
_Location_url = new WeakMap(), _Location_noCheckUrl = new WeakMap(), _Location_window = new WeakMap(), _Location_instances = new WeakSet(), _Location_reset = function _Location_reset() {
|
|
2704
|
+
const Current = getCurrentInstance();
|
|
2705
|
+
const router = Current.router;
|
|
2706
|
+
if (router) {
|
|
2707
|
+
const { path, params } = router;
|
|
2708
|
+
const searchArr = Object.keys(params).map((key) => {
|
|
2709
|
+
return `${key}=${params[key]}`;
|
|
2710
|
+
});
|
|
2711
|
+
const searchStr = searchArr.length > 0 ? '?' + searchArr.join('&') : '';
|
|
2712
|
+
const url = `${INIT_URL}${path.startsWith('/') ? path : '/' + path}${searchStr}`;
|
|
2713
|
+
__classPrivateFieldSet(this, _Location_url, new URL(url), "f");
|
|
2714
|
+
this.trigger('__reset_history__', this.href);
|
|
2715
|
+
}
|
|
2716
|
+
}, _Location_getPreValue = function _Location_getPreValue() {
|
|
2717
|
+
return __classPrivateFieldGet(this, _Location_url, "f")._toRaw();
|
|
2718
|
+
}, _Location_rollBack = function _Location_rollBack(href) {
|
|
2719
|
+
__classPrivateFieldGet(this, _Location_url, "f").href = href;
|
|
2720
|
+
}, _Location_recordHistory = function _Location_recordHistory() {
|
|
2721
|
+
this.trigger('__record_history__', this.href);
|
|
2722
|
+
}, _Location_checkUrlChange = function _Location_checkUrlChange(preValue) {
|
|
2723
|
+
if (__classPrivateFieldGet(this, _Location_noCheckUrl, "f")) {
|
|
2724
|
+
return false;
|
|
2725
|
+
}
|
|
2726
|
+
const { protocol, hostname, port, pathname, search, hash } = __classPrivateFieldGet(this, _Location_url, "f")._toRaw();
|
|
2727
|
+
// 跨域三要素不允许修改
|
|
2728
|
+
if (protocol !== preValue.protocol || hostname !== preValue.hostname || port !== preValue.port) {
|
|
2729
|
+
__classPrivateFieldGet(this, _Location_instances, "m", _Location_rollBack).call(this, preValue.href);
|
|
2730
|
+
return false;
|
|
2731
|
+
}
|
|
2732
|
+
// pathname
|
|
2733
|
+
if (pathname !== preValue.pathname) {
|
|
2734
|
+
return true;
|
|
2735
|
+
}
|
|
2736
|
+
// search
|
|
2737
|
+
if (search !== preValue.search) {
|
|
2738
|
+
return true;
|
|
2739
|
+
}
|
|
2740
|
+
// hashchange
|
|
2741
|
+
if (hash !== preValue.hash) {
|
|
2742
|
+
__classPrivateFieldGet(this, _Location_window, "f").trigger('hashchange');
|
|
2743
|
+
return true;
|
|
2744
|
+
}
|
|
2745
|
+
__classPrivateFieldGet(this, _Location_instances, "m", _Location_rollBack).call(this, preValue.href);
|
|
2746
|
+
return false;
|
|
2747
|
+
};
|
|
2748
|
+
function generateFullUrl(val = '') {
|
|
2749
|
+
const origin = INIT_URL;
|
|
2750
|
+
if (/^[/?#]/.test(val)) {
|
|
2751
|
+
return origin + val;
|
|
2752
|
+
}
|
|
2753
|
+
return val;
|
|
2754
|
+
}
|
|
2755
|
+
|
|
2756
|
+
const nav = env.window.navigator ;
|
|
2757
|
+
|
|
2758
|
+
// https://github.com/myrne/performance-now
|
|
2759
|
+
exports.now = void 0;
|
|
2760
|
+
(function () {
|
|
2761
|
+
let loadTime;
|
|
2762
|
+
if ((typeof performance !== 'undefined' && performance !== null) && performance.now) {
|
|
2763
|
+
exports.now = () => performance.now();
|
|
2764
|
+
}
|
|
2765
|
+
else if (Date.now) {
|
|
2766
|
+
loadTime = Date.now();
|
|
2767
|
+
exports.now = () => Date.now() - loadTime;
|
|
2768
|
+
}
|
|
2769
|
+
else {
|
|
2770
|
+
loadTime = new Date().getTime();
|
|
2771
|
+
exports.now = () => new Date().getTime() - loadTime;
|
|
2772
|
+
}
|
|
2773
|
+
})();
|
|
2774
|
+
let lastTime = 0;
|
|
2775
|
+
// https://gist.github.com/paulirish/1579671
|
|
2776
|
+
// https://gist.github.com/jalbam/5fe05443270fa6d8136238ec72accbc0
|
|
2777
|
+
const _raf = typeof requestAnimationFrame !== 'undefined' && requestAnimationFrame !== null ? requestAnimationFrame : function (callback) {
|
|
2778
|
+
const _now = exports.now();
|
|
2779
|
+
const nextTime = Math.max(lastTime + 16, _now); // First time will execute it immediately but barely noticeable and performance is gained.
|
|
2780
|
+
return setTimeout(function () { callback(lastTime = nextTime); }, nextTime - _now);
|
|
2781
|
+
};
|
|
2782
|
+
const _caf = typeof cancelAnimationFrame !== 'undefined' && cancelAnimationFrame !== null
|
|
2783
|
+
? cancelAnimationFrame
|
|
2784
|
+
: function (seed) {
|
|
2785
|
+
// fix https://github.com/NervJS/taro/issues/7749
|
|
2786
|
+
clearTimeout(seed);
|
|
2787
|
+
};
|
|
2788
|
+
|
|
2789
|
+
exports.window = void 0;
|
|
2790
|
+
if (process.env.TARO_ENV && !true) {
|
|
2791
|
+
class Window extends shared.Events {
|
|
2792
|
+
constructor() {
|
|
2793
|
+
super();
|
|
2794
|
+
this.navigator = nav;
|
|
2795
|
+
this.requestAnimationFrame = _raf;
|
|
2796
|
+
this.cancelAnimationFrame = _caf;
|
|
2797
|
+
this.getComputedStyle = getComputedStyle;
|
|
2798
|
+
const globalProperties = [
|
|
2799
|
+
...Object.getOwnPropertyNames(global || {}),
|
|
2800
|
+
...Object.getOwnPropertySymbols(global || {})
|
|
2801
|
+
];
|
|
2802
|
+
globalProperties.forEach(property => {
|
|
2803
|
+
if (property === 'atob' || property === 'document')
|
|
2804
|
+
return;
|
|
2805
|
+
if (!Object.prototype.hasOwnProperty.call(this, property)) {
|
|
2806
|
+
// 防止小程序环境下,window 上的某些 get 属性在赋值时报错
|
|
2807
|
+
try {
|
|
2808
|
+
this[property] = global[property];
|
|
2809
|
+
}
|
|
2810
|
+
catch (e) {
|
|
2811
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
2812
|
+
console.warn(`[Taro warn] window.${String(property)} 在赋值到 window 时报错`);
|
|
2813
|
+
}
|
|
2814
|
+
}
|
|
2815
|
+
}
|
|
2816
|
+
});
|
|
2817
|
+
this.Date || (this.Date = Date);
|
|
2818
|
+
// 应用启动时,提供给需要读取历史信息的库使用
|
|
2819
|
+
this.location = new Location({ window: this });
|
|
2820
|
+
this.history = new History(this.location, { window: this });
|
|
2821
|
+
this.initEvent();
|
|
2822
|
+
}
|
|
2823
|
+
initEvent() {
|
|
2824
|
+
const _location = this.location;
|
|
2825
|
+
const _history = this.history;
|
|
2826
|
+
this.on(CONTEXT_ACTIONS.INIT, (pageId) => {
|
|
2827
|
+
// 页面onload,为该页面建立新的上下文信息
|
|
2828
|
+
_location.trigger(CONTEXT_ACTIONS.INIT, pageId);
|
|
2829
|
+
}, null);
|
|
2830
|
+
this.on(CONTEXT_ACTIONS.RECOVER, (pageId) => {
|
|
2831
|
+
// 页面onshow,恢复当前页面的上下文信息
|
|
2832
|
+
_location.trigger(CONTEXT_ACTIONS.RECOVER, pageId);
|
|
2833
|
+
_history.trigger(CONTEXT_ACTIONS.RECOVER, pageId);
|
|
2834
|
+
}, null);
|
|
2835
|
+
this.on(CONTEXT_ACTIONS.RESTORE, (pageId) => {
|
|
2836
|
+
// 页面onhide,缓存当前页面的上下文信息
|
|
2837
|
+
_location.trigger(CONTEXT_ACTIONS.RESTORE, pageId);
|
|
2838
|
+
_history.trigger(CONTEXT_ACTIONS.RESTORE, pageId);
|
|
2839
|
+
}, null);
|
|
2840
|
+
this.on(CONTEXT_ACTIONS.DESTORY, (pageId) => {
|
|
2841
|
+
// 页面onunload,清除当前页面的上下文信息
|
|
2842
|
+
_location.trigger(CONTEXT_ACTIONS.DESTORY, pageId);
|
|
2843
|
+
_history.trigger(CONTEXT_ACTIONS.DESTORY, pageId);
|
|
2844
|
+
}, null);
|
|
2845
|
+
}
|
|
2846
|
+
get document() {
|
|
2847
|
+
return env.document;
|
|
2848
|
+
}
|
|
2849
|
+
addEventListener(event, callback) {
|
|
2850
|
+
if (!shared.isString(event))
|
|
2851
|
+
return;
|
|
2852
|
+
this.on(event, callback, null);
|
|
2853
|
+
}
|
|
2854
|
+
removeEventListener(event, callback) {
|
|
2855
|
+
if (!shared.isString(event))
|
|
2856
|
+
return;
|
|
2857
|
+
this.off(event, callback, null);
|
|
2858
|
+
}
|
|
2859
|
+
setTimeout(...args) {
|
|
2860
|
+
return setTimeout(...args);
|
|
2861
|
+
}
|
|
2862
|
+
clearTimeout(...args) {
|
|
2863
|
+
return clearTimeout(...args);
|
|
2864
|
+
}
|
|
2865
|
+
}
|
|
2866
|
+
exports.window = env.window = new Window();
|
|
2867
|
+
}
|
|
2868
|
+
else {
|
|
2869
|
+
exports.window = env.window;
|
|
2870
|
+
}
|
|
2871
|
+
const location = exports.window.location;
|
|
2872
|
+
const history = exports.window.history;
|
|
2873
|
+
|
|
2874
|
+
// for Vue3
|
|
2875
|
+
class SVGElement extends TaroElement {
|
|
2876
|
+
}
|
|
2877
|
+
|
|
2878
|
+
/* eslint-disable dot-notation */
|
|
2879
|
+
const instances = new Map();
|
|
2880
|
+
const pageId = incrementId();
|
|
2881
|
+
function injectPageInstance(inst, id) {
|
|
2882
|
+
shared.hooks.call('mergePageInstance', instances.get(id), inst);
|
|
2883
|
+
instances.set(id, inst);
|
|
2884
|
+
}
|
|
2885
|
+
function getPageInstance(id) {
|
|
2886
|
+
return instances.get(id);
|
|
2887
|
+
}
|
|
2888
|
+
function removePageInstance(id) {
|
|
2889
|
+
instances.delete(id);
|
|
2890
|
+
}
|
|
2891
|
+
function addLeadingSlash(path) {
|
|
2892
|
+
if (path == null) {
|
|
2893
|
+
return '';
|
|
2894
|
+
}
|
|
2895
|
+
return path.charAt(0) === '/' ? path : '/' + path;
|
|
2896
|
+
}
|
|
2897
|
+
function safeExecute(path, lifecycle, ...args) {
|
|
2898
|
+
const instance = instances.get(path);
|
|
2899
|
+
if (instance == null) {
|
|
2900
|
+
return;
|
|
2901
|
+
}
|
|
2902
|
+
const func = shared.hooks.call('getLifecycle', instance, lifecycle);
|
|
2903
|
+
if (shared.isArray(func)) {
|
|
2904
|
+
const res = func.map(fn => fn.apply(instance, args));
|
|
2905
|
+
return res[0];
|
|
2906
|
+
}
|
|
2907
|
+
if (!shared.isFunction(func)) {
|
|
2908
|
+
return;
|
|
2909
|
+
}
|
|
2910
|
+
return func.apply(instance, args);
|
|
2911
|
+
}
|
|
2912
|
+
function stringify(obj) {
|
|
2913
|
+
if (obj == null) {
|
|
2914
|
+
return '';
|
|
2915
|
+
}
|
|
2916
|
+
const path = Object.keys(obj).map((key) => {
|
|
2917
|
+
return key + '=' + obj[key];
|
|
2918
|
+
}).join('&');
|
|
2919
|
+
return path === '' ? path : '?' + path;
|
|
2920
|
+
}
|
|
2921
|
+
function getPath(id, options) {
|
|
2922
|
+
const idx = id.indexOf('?');
|
|
2923
|
+
{
|
|
2924
|
+
return `${idx > -1 ? id.substring(0, idx) : id}${stringify((options === null || options === void 0 ? void 0 : options.stamp) ? { stamp: options.stamp } : {})}`;
|
|
2925
|
+
}
|
|
2926
|
+
}
|
|
2927
|
+
function getOnReadyEventKey(path) {
|
|
2928
|
+
return path + '.' + ON_READY;
|
|
2929
|
+
}
|
|
2930
|
+
function getOnShowEventKey(path) {
|
|
2931
|
+
return path + '.' + ON_SHOW;
|
|
2932
|
+
}
|
|
2933
|
+
function getOnHideEventKey(path) {
|
|
2934
|
+
return path + '.' + ON_HIDE;
|
|
2935
|
+
}
|
|
2936
|
+
function createPageConfig(component, pageName, data, pageConfig) {
|
|
2937
|
+
// 小程序 Page 构造器是一个傲娇小公主,不能把复杂的对象挂载到参数上
|
|
2938
|
+
const id = pageName !== null && pageName !== void 0 ? pageName : `taro_page_${pageId()}`;
|
|
2939
|
+
const [ONLOAD, ONUNLOAD, ONREADY, ONSHOW, ONHIDE, LIFECYCLES, SIDE_EFFECT_LIFECYCLES,] = shared.hooks.call('getMiniLifecycleImpl').page;
|
|
2940
|
+
let pageElement = null;
|
|
2941
|
+
let unmounting = false;
|
|
2942
|
+
let prepareMountList = [];
|
|
2943
|
+
function setCurrentRouter(page) {
|
|
2944
|
+
const router = page.$taroPath ;
|
|
2945
|
+
Current.router = {
|
|
2946
|
+
params: page.$taroParams,
|
|
2947
|
+
path: addLeadingSlash(router),
|
|
2948
|
+
$taroPath: page.$taroPath,
|
|
2949
|
+
onReady: getOnReadyEventKey(id),
|
|
2950
|
+
onShow: getOnShowEventKey(id),
|
|
2951
|
+
onHide: getOnHideEventKey(id)
|
|
2952
|
+
};
|
|
2953
|
+
if (!shared.isUndefined(page.exitState)) {
|
|
2954
|
+
Current.router.exitState = page.exitState;
|
|
2955
|
+
}
|
|
2956
|
+
}
|
|
2957
|
+
let loadResolver;
|
|
2958
|
+
let hasLoaded;
|
|
2959
|
+
const config = {
|
|
2960
|
+
[ONLOAD](options = {}, cb) {
|
|
2961
|
+
hasLoaded = new Promise(resolve => { loadResolver = resolve; });
|
|
2962
|
+
perf.start(PAGE_INIT);
|
|
2963
|
+
Current.page = this;
|
|
2964
|
+
this.config = pageConfig || {};
|
|
2965
|
+
// this.$taroPath 是页面唯一标识
|
|
2966
|
+
const uniqueOptions = Object.assign({}, options, { $taroTimestamp: Date.now() });
|
|
2967
|
+
const $taroPath = this.$taroPath = getPath(id, uniqueOptions);
|
|
2968
|
+
{
|
|
2969
|
+
config.path = $taroPath;
|
|
2970
|
+
}
|
|
2971
|
+
// this.$taroParams 作为暴露给开发者的页面参数对象,可以被随意修改
|
|
2972
|
+
if (this.$taroParams == null) {
|
|
2973
|
+
this.$taroParams = uniqueOptions;
|
|
2974
|
+
}
|
|
2975
|
+
setCurrentRouter(this);
|
|
2976
|
+
const mount = () => {
|
|
2977
|
+
Current.app.mount(component, $taroPath, () => {
|
|
2978
|
+
pageElement = env.document.getElementById($taroPath);
|
|
2979
|
+
shared.ensure(pageElement !== null, '没有找到页面实例。');
|
|
2980
|
+
safeExecute($taroPath, ON_LOAD, this.$taroParams);
|
|
2981
|
+
loadResolver();
|
|
2982
|
+
{
|
|
2983
|
+
shared.isFunction(cb) && cb();
|
|
2984
|
+
}
|
|
2985
|
+
});
|
|
2986
|
+
};
|
|
2987
|
+
if (unmounting) {
|
|
2988
|
+
prepareMountList.push(mount);
|
|
2989
|
+
}
|
|
2990
|
+
else {
|
|
2991
|
+
mount();
|
|
2992
|
+
}
|
|
2993
|
+
},
|
|
2994
|
+
[ONUNLOAD]() {
|
|
2995
|
+
const $taroPath = this.$taroPath;
|
|
2996
|
+
// 触发onUnload生命周期
|
|
2997
|
+
safeExecute($taroPath, ONUNLOAD);
|
|
2998
|
+
unmounting = true;
|
|
2999
|
+
Current.app.unmount($taroPath, () => {
|
|
3000
|
+
unmounting = false;
|
|
3001
|
+
instances.delete($taroPath);
|
|
3002
|
+
if (pageElement) {
|
|
3003
|
+
pageElement.ctx = null;
|
|
3004
|
+
pageElement = null;
|
|
3005
|
+
}
|
|
3006
|
+
if (prepareMountList.length) {
|
|
3007
|
+
prepareMountList.forEach(fn => fn());
|
|
3008
|
+
prepareMountList = [];
|
|
3009
|
+
}
|
|
3010
|
+
});
|
|
3011
|
+
},
|
|
3012
|
+
[ONREADY]() {
|
|
3013
|
+
hasLoaded.then(() => {
|
|
3014
|
+
// 触发生命周期
|
|
3015
|
+
safeExecute(this.$taroPath, ON_READY);
|
|
3016
|
+
// 通过事件触发子组件的生命周期
|
|
3017
|
+
_raf(() => eventCenter.trigger(getOnReadyEventKey(id)));
|
|
3018
|
+
this.onReady.called = true;
|
|
3019
|
+
});
|
|
3020
|
+
},
|
|
3021
|
+
[ONSHOW](options = {}) {
|
|
3022
|
+
hasLoaded.then(() => {
|
|
3023
|
+
// 设置 Current 的 page 和 router
|
|
3024
|
+
Current.page = this;
|
|
3025
|
+
setCurrentRouter(this);
|
|
3026
|
+
// 触发生命周期
|
|
3027
|
+
safeExecute(this.$taroPath, ON_SHOW, options);
|
|
3028
|
+
// 通过事件触发子组件的生命周期
|
|
3029
|
+
_raf(() => eventCenter.trigger(getOnShowEventKey(id)));
|
|
3030
|
+
});
|
|
3031
|
+
},
|
|
3032
|
+
[ONHIDE]() {
|
|
3033
|
+
// 设置 Current 的 page 和 router
|
|
3034
|
+
if (Current.page === this) {
|
|
3035
|
+
Current.page = null;
|
|
3036
|
+
Current.router = null;
|
|
3037
|
+
}
|
|
3038
|
+
// 触发生命周期
|
|
3039
|
+
safeExecute(this.$taroPath, ON_HIDE);
|
|
3040
|
+
// 通过事件触发子组件的生命周期
|
|
3041
|
+
eventCenter.trigger(getOnHideEventKey(id));
|
|
3042
|
+
}
|
|
3043
|
+
};
|
|
3044
|
+
LIFECYCLES.forEach((lifecycle) => {
|
|
3045
|
+
config[lifecycle] = function () {
|
|
3046
|
+
return safeExecute(this.$taroPath, lifecycle, ...arguments);
|
|
3047
|
+
};
|
|
3048
|
+
});
|
|
3049
|
+
// onShareAppMessage 和 onShareTimeline 一样,会影响小程序右上方按钮的选项,因此不能默认注册。
|
|
3050
|
+
SIDE_EFFECT_LIFECYCLES.forEach(lifecycle => {
|
|
3051
|
+
var _a;
|
|
3052
|
+
if (component[lifecycle] ||
|
|
3053
|
+
((_a = component.prototype) === null || _a === void 0 ? void 0 : _a[lifecycle]) ||
|
|
3054
|
+
component[lifecycle.replace(/^on/, 'enable')] ||
|
|
3055
|
+
(pageConfig === null || pageConfig === void 0 ? void 0 : pageConfig[lifecycle.replace(/^on/, 'enable')])) {
|
|
3056
|
+
config[lifecycle] = function (...args) {
|
|
3057
|
+
var _a;
|
|
3058
|
+
const target = (_a = args[0]) === null || _a === void 0 ? void 0 : _a.target;
|
|
3059
|
+
if (target === null || target === void 0 ? void 0 : target.id) {
|
|
3060
|
+
const id = target.id;
|
|
3061
|
+
const element = env.document.getElementById(id);
|
|
3062
|
+
if (element) {
|
|
3063
|
+
target.dataset = element.dataset;
|
|
3064
|
+
}
|
|
3065
|
+
}
|
|
3066
|
+
return safeExecute(this.$taroPath, lifecycle, ...args);
|
|
3067
|
+
};
|
|
3068
|
+
}
|
|
3069
|
+
});
|
|
3070
|
+
config.eh = eventHandler;
|
|
3071
|
+
if (!shared.isUndefined(data)) {
|
|
3072
|
+
config.data = data;
|
|
3073
|
+
}
|
|
3074
|
+
shared.hooks.call('modifyPageObject', config);
|
|
3075
|
+
return config;
|
|
3076
|
+
}
|
|
3077
|
+
function createComponentConfig(component, componentName, data) {
|
|
3078
|
+
const id = componentName !== null && componentName !== void 0 ? componentName : `taro_component_${pageId()}`;
|
|
3079
|
+
let componentElement = null;
|
|
3080
|
+
const [ATTACHED, DETACHED] = shared.hooks.call('getMiniLifecycleImpl').component;
|
|
3081
|
+
const config = {
|
|
3082
|
+
[ATTACHED]() {
|
|
3083
|
+
var _a;
|
|
3084
|
+
perf.start(PAGE_INIT);
|
|
3085
|
+
const path = getPath(id, { id: ((_a = this.getPageId) === null || _a === void 0 ? void 0 : _a.call(this)) || pageId() });
|
|
3086
|
+
Current.app.mount(component, path, () => {
|
|
3087
|
+
componentElement = env.document.getElementById(path);
|
|
3088
|
+
shared.ensure(componentElement !== null, '没有找到组件实例。');
|
|
3089
|
+
this.$taroInstances = instances.get(path);
|
|
3090
|
+
safeExecute(path, ON_LOAD);
|
|
3091
|
+
});
|
|
3092
|
+
},
|
|
3093
|
+
[DETACHED]() {
|
|
3094
|
+
const path = getPath(id, { id: this.getPageId() });
|
|
3095
|
+
Current.app.unmount(path, () => {
|
|
3096
|
+
instances.delete(path);
|
|
3097
|
+
if (componentElement) {
|
|
3098
|
+
componentElement.ctx = null;
|
|
3099
|
+
}
|
|
3100
|
+
});
|
|
3101
|
+
},
|
|
3102
|
+
methods: {
|
|
3103
|
+
eh: eventHandler
|
|
3104
|
+
}
|
|
3105
|
+
};
|
|
3106
|
+
if (!shared.isUndefined(data)) {
|
|
3107
|
+
config.data = data;
|
|
3108
|
+
}
|
|
3109
|
+
[OPTIONS, EXTERNAL_CLASSES, BEHAVIORS].forEach(key => {
|
|
3110
|
+
var _a;
|
|
3111
|
+
config[key] = (_a = component[key]) !== null && _a !== void 0 ? _a : shared.EMPTY_OBJ;
|
|
3112
|
+
});
|
|
3113
|
+
return config;
|
|
3114
|
+
}
|
|
3115
|
+
function createRecursiveComponentConfig(componentName) {
|
|
3116
|
+
const isCustomWrapper = componentName === CUSTOM_WRAPPER;
|
|
3117
|
+
const [ATTACHED, DETACHED] = shared.hooks.call('getMiniLifecycleImpl').component;
|
|
3118
|
+
const lifeCycles = isCustomWrapper
|
|
3119
|
+
? {
|
|
3120
|
+
[ATTACHED]() {
|
|
3121
|
+
var _a, _b;
|
|
3122
|
+
const componentId = ((_a = this.data.i) === null || _a === void 0 ? void 0 : _a.sid) || ((_b = this.props.i) === null || _b === void 0 ? void 0 : _b.sid);
|
|
3123
|
+
if (shared.isString(componentId)) {
|
|
3124
|
+
customWrapperCache.set(componentId, this);
|
|
3125
|
+
const el = env.document.getElementById(componentId);
|
|
3126
|
+
if (el) {
|
|
3127
|
+
el.ctx = this;
|
|
3128
|
+
}
|
|
3129
|
+
}
|
|
3130
|
+
},
|
|
3131
|
+
[DETACHED]() {
|
|
3132
|
+
var _a, _b;
|
|
3133
|
+
const componentId = ((_a = this.data.i) === null || _a === void 0 ? void 0 : _a.sid) || ((_b = this.props.i) === null || _b === void 0 ? void 0 : _b.sid);
|
|
3134
|
+
if (shared.isString(componentId)) {
|
|
3135
|
+
customWrapperCache.delete(componentId);
|
|
3136
|
+
const el = env.document.getElementById(componentId);
|
|
3137
|
+
if (el) {
|
|
3138
|
+
el.ctx = null;
|
|
3139
|
+
}
|
|
3140
|
+
}
|
|
3141
|
+
}
|
|
3142
|
+
}
|
|
3143
|
+
: shared.EMPTY_OBJ;
|
|
3144
|
+
return Object.assign({ properties: {
|
|
3145
|
+
i: {
|
|
3146
|
+
type: Object,
|
|
3147
|
+
value: {
|
|
3148
|
+
["nn" /* Shortcuts.NodeName */]: shared.getComponentsAlias(shared.internalComponents)[VIEW]._num
|
|
3149
|
+
}
|
|
3150
|
+
},
|
|
3151
|
+
l: {
|
|
3152
|
+
type: String,
|
|
3153
|
+
value: ''
|
|
3154
|
+
}
|
|
3155
|
+
}, options: {
|
|
3156
|
+
addGlobalClass: true,
|
|
3157
|
+
virtualHost: !isCustomWrapper
|
|
3158
|
+
}, methods: {
|
|
3159
|
+
eh: eventHandler
|
|
3160
|
+
} }, lifeCycles);
|
|
3161
|
+
}
|
|
3162
|
+
|
|
3163
|
+
const TIMEOUT = 100;
|
|
3164
|
+
const nextTick = (cb, ctx) => {
|
|
3165
|
+
const beginTime = Date.now();
|
|
3166
|
+
const router = Current.router;
|
|
3167
|
+
const timerFunc = () => {
|
|
3168
|
+
setTimeout(function () {
|
|
3169
|
+
ctx ? cb.call(ctx) : cb();
|
|
3170
|
+
}, 1);
|
|
3171
|
+
};
|
|
3172
|
+
if (router === null)
|
|
3173
|
+
return timerFunc();
|
|
3174
|
+
const path = router.$taroPath;
|
|
3175
|
+
/**
|
|
3176
|
+
* 三种情况
|
|
3177
|
+
* 1. 调用 nextTick 时,pendingUpdate 已经从 true 变为 false(即已更新完成),那么需要光等 100ms
|
|
3178
|
+
* 2. 调用 nextTick 时,pendingUpdate 为 true,那么刚好可以搭上便车
|
|
3179
|
+
* 3. 调用 nextTick 时,pendingUpdate 还是 false,框架仍未启动更新逻辑,这时最多轮询 100ms,等待 pendingUpdate 变为 true。
|
|
3180
|
+
*/
|
|
3181
|
+
function next() {
|
|
3182
|
+
var _a, _b, _c;
|
|
3183
|
+
const pageElement = env.document.getElementById(path);
|
|
3184
|
+
if (pageElement === null || pageElement === void 0 ? void 0 : pageElement.pendingUpdate) {
|
|
3185
|
+
{
|
|
3186
|
+
// eslint-disable-next-line dot-notation
|
|
3187
|
+
(_c = (_b = (_a = pageElement.firstChild) === null || _a === void 0 ? void 0 : _a['componentOnReady']) === null || _b === void 0 ? void 0 : _b.call(_a).then(() => {
|
|
3188
|
+
timerFunc();
|
|
3189
|
+
})) !== null && _c !== void 0 ? _c : timerFunc();
|
|
3190
|
+
}
|
|
3191
|
+
}
|
|
3192
|
+
else if (Date.now() - beginTime > TIMEOUT) {
|
|
3193
|
+
timerFunc();
|
|
3194
|
+
}
|
|
3195
|
+
else {
|
|
3196
|
+
setTimeout(() => next(), 20);
|
|
3197
|
+
}
|
|
3198
|
+
}
|
|
3199
|
+
next();
|
|
3200
|
+
};
|
|
3201
|
+
|
|
3202
|
+
Object.defineProperty(exports, 'Events', {
|
|
3203
|
+
enumerable: true,
|
|
3204
|
+
get: function () { return shared.Events; }
|
|
3205
|
+
});
|
|
3206
|
+
Object.defineProperty(exports, 'hooks', {
|
|
3207
|
+
enumerable: true,
|
|
3208
|
+
get: function () { return shared.hooks; }
|
|
3209
|
+
});
|
|
3210
|
+
exports.Current = Current;
|
|
3211
|
+
exports.FormElement = FormElement;
|
|
3212
|
+
exports.History = History;
|
|
3213
|
+
exports.Location = Location;
|
|
3214
|
+
exports.MutationObserver = MutationObserver;
|
|
3215
|
+
exports.SVGElement = SVGElement;
|
|
3216
|
+
exports.Style = Style;
|
|
3217
|
+
exports.TaroElement = TaroElement;
|
|
3218
|
+
exports.TaroEvent = TaroEvent;
|
|
3219
|
+
exports.TaroNode = TaroNode;
|
|
3220
|
+
exports.TaroRootElement = TaroRootElement;
|
|
3221
|
+
exports.TaroText = TaroText;
|
|
3222
|
+
exports.URL = URL;
|
|
3223
|
+
exports.URLSearchParams = URLSearchParams;
|
|
3224
|
+
exports.addLeadingSlash = addLeadingSlash;
|
|
3225
|
+
exports.cancelAnimationFrame = _caf;
|
|
3226
|
+
exports.createComponentConfig = createComponentConfig;
|
|
3227
|
+
exports.createEvent = createEvent;
|
|
3228
|
+
exports.createPageConfig = createPageConfig;
|
|
3229
|
+
exports.createRecursiveComponentConfig = createRecursiveComponentConfig;
|
|
3230
|
+
exports.eventCenter = eventCenter;
|
|
3231
|
+
exports.eventHandler = eventHandler;
|
|
3232
|
+
exports.eventSource = eventSource;
|
|
3233
|
+
exports.getComputedStyle = getComputedStyle;
|
|
3234
|
+
exports.getCurrentInstance = getCurrentInstance;
|
|
3235
|
+
exports.getPageInstance = getPageInstance;
|
|
3236
|
+
exports.getPath = getPath;
|
|
3237
|
+
exports.history = history;
|
|
3238
|
+
exports.hydrate = hydrate;
|
|
3239
|
+
exports.incrementId = incrementId;
|
|
3240
|
+
exports.injectPageInstance = injectPageInstance;
|
|
3241
|
+
exports.location = location;
|
|
3242
|
+
exports.navigator = nav;
|
|
3243
|
+
exports.nextTick = nextTick;
|
|
3244
|
+
exports.options = options;
|
|
3245
|
+
exports.parseUrl = parseUrl;
|
|
3246
|
+
exports.removePageInstance = removePageInstance;
|
|
3247
|
+
exports.requestAnimationFrame = _raf;
|
|
3248
|
+
exports.safeExecute = safeExecute;
|
|
3249
|
+
exports.stringify = stringify;
|