@vue/runtime-dom 3.2.39 → 3.2.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/runtime-dom.cjs.js +1575 -1607
- package/dist/runtime-dom.cjs.prod.js +1469 -1502
- package/dist/runtime-dom.esm-browser.js +10720 -10724
- package/dist/runtime-dom.esm-browser.prod.js +1 -1
- package/dist/runtime-dom.esm-bundler.js +1630 -1662
- package/dist/runtime-dom.global.js +10702 -10706
- package/dist/runtime-dom.global.prod.js +1 -1
- package/package.json +3 -3
|
@@ -5,1538 +5,1505 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var runtimeCore = require('@vue/runtime-core');
|
|
6
6
|
var shared = require('@vue/shared');
|
|
7
7
|
|
|
8
|
-
const svgNS = 'http://www.w3.org/2000/svg';
|
|
9
|
-
const doc = (typeof document !== 'undefined' ? document : null);
|
|
10
|
-
const templateContainer = doc && /*#__PURE__*/ doc.createElement('template');
|
|
11
|
-
const nodeOps = {
|
|
12
|
-
insert: (child, parent, anchor) => {
|
|
13
|
-
parent.insertBefore(child, anchor || null);
|
|
14
|
-
},
|
|
15
|
-
remove: child => {
|
|
16
|
-
const parent = child.parentNode;
|
|
17
|
-
if (parent) {
|
|
18
|
-
parent.removeChild(child);
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
createElement: (tag, isSVG, is, props) => {
|
|
22
|
-
const el = isSVG
|
|
23
|
-
? doc.createElementNS(svgNS, tag)
|
|
24
|
-
: doc.createElement(tag, is ? { is } : undefined);
|
|
25
|
-
if (tag === 'select' && props && props.multiple != null) {
|
|
26
|
-
el.setAttribute('multiple', props.multiple);
|
|
27
|
-
}
|
|
28
|
-
return el;
|
|
29
|
-
},
|
|
30
|
-
createText: text => doc.createTextNode(text),
|
|
31
|
-
createComment: text => doc.createComment(text),
|
|
32
|
-
setText: (node, text) => {
|
|
33
|
-
node.nodeValue = text;
|
|
34
|
-
},
|
|
35
|
-
setElementText: (el, text) => {
|
|
36
|
-
el.textContent = text;
|
|
37
|
-
},
|
|
38
|
-
parentNode: node => node.parentNode,
|
|
39
|
-
nextSibling: node => node.nextSibling,
|
|
40
|
-
querySelector: selector => doc.querySelector(selector),
|
|
41
|
-
setScopeId(el, id) {
|
|
42
|
-
el.setAttribute(id, '');
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
// -
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
//
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
// remove outer svg wrapper
|
|
84
|
-
const wrapper = template.firstChild;
|
|
85
|
-
while (wrapper.firstChild) {
|
|
86
|
-
template.appendChild(wrapper.firstChild);
|
|
87
|
-
}
|
|
88
|
-
template.removeChild(wrapper);
|
|
89
|
-
}
|
|
90
|
-
parent.insertBefore(template, anchor);
|
|
91
|
-
}
|
|
92
|
-
return [
|
|
93
|
-
// first
|
|
94
|
-
before ? before.nextSibling : parent.firstChild,
|
|
95
|
-
// last
|
|
96
|
-
anchor ? anchor.previousSibling : parent.lastChild
|
|
97
|
-
];
|
|
98
|
-
}
|
|
8
|
+
const svgNS = 'http://www.w3.org/2000/svg';
|
|
9
|
+
const doc = (typeof document !== 'undefined' ? document : null);
|
|
10
|
+
const templateContainer = doc && /*#__PURE__*/ doc.createElement('template');
|
|
11
|
+
const nodeOps = {
|
|
12
|
+
insert: (child, parent, anchor) => {
|
|
13
|
+
parent.insertBefore(child, anchor || null);
|
|
14
|
+
},
|
|
15
|
+
remove: child => {
|
|
16
|
+
const parent = child.parentNode;
|
|
17
|
+
if (parent) {
|
|
18
|
+
parent.removeChild(child);
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
createElement: (tag, isSVG, is, props) => {
|
|
22
|
+
const el = isSVG
|
|
23
|
+
? doc.createElementNS(svgNS, tag)
|
|
24
|
+
: doc.createElement(tag, is ? { is } : undefined);
|
|
25
|
+
if (tag === 'select' && props && props.multiple != null) {
|
|
26
|
+
el.setAttribute('multiple', props.multiple);
|
|
27
|
+
}
|
|
28
|
+
return el;
|
|
29
|
+
},
|
|
30
|
+
createText: text => doc.createTextNode(text),
|
|
31
|
+
createComment: text => doc.createComment(text),
|
|
32
|
+
setText: (node, text) => {
|
|
33
|
+
node.nodeValue = text;
|
|
34
|
+
},
|
|
35
|
+
setElementText: (el, text) => {
|
|
36
|
+
el.textContent = text;
|
|
37
|
+
},
|
|
38
|
+
parentNode: node => node.parentNode,
|
|
39
|
+
nextSibling: node => node.nextSibling,
|
|
40
|
+
querySelector: selector => doc.querySelector(selector),
|
|
41
|
+
setScopeId(el, id) {
|
|
42
|
+
el.setAttribute(id, '');
|
|
43
|
+
},
|
|
44
|
+
// __UNSAFE__
|
|
45
|
+
// Reason: innerHTML.
|
|
46
|
+
// Static content here can only come from compiled templates.
|
|
47
|
+
// As long as the user only uses trusted templates, this is safe.
|
|
48
|
+
insertStaticContent(content, parent, anchor, isSVG, start, end) {
|
|
49
|
+
// <parent> before | first ... last | anchor </parent>
|
|
50
|
+
const before = anchor ? anchor.previousSibling : parent.lastChild;
|
|
51
|
+
// #5308 can only take cached path if:
|
|
52
|
+
// - has a single root node
|
|
53
|
+
// - nextSibling info is still available
|
|
54
|
+
if (start && (start === end || start.nextSibling)) {
|
|
55
|
+
// cached
|
|
56
|
+
while (true) {
|
|
57
|
+
parent.insertBefore(start.cloneNode(true), anchor);
|
|
58
|
+
if (start === end || !(start = start.nextSibling))
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
// fresh insert
|
|
64
|
+
templateContainer.innerHTML = isSVG ? `<svg>${content}</svg>` : content;
|
|
65
|
+
const template = templateContainer.content;
|
|
66
|
+
if (isSVG) {
|
|
67
|
+
// remove outer svg wrapper
|
|
68
|
+
const wrapper = template.firstChild;
|
|
69
|
+
while (wrapper.firstChild) {
|
|
70
|
+
template.appendChild(wrapper.firstChild);
|
|
71
|
+
}
|
|
72
|
+
template.removeChild(wrapper);
|
|
73
|
+
}
|
|
74
|
+
parent.insertBefore(template, anchor);
|
|
75
|
+
}
|
|
76
|
+
return [
|
|
77
|
+
// first
|
|
78
|
+
before ? before.nextSibling : parent.firstChild,
|
|
79
|
+
// last
|
|
80
|
+
anchor ? anchor.previousSibling : parent.lastChild
|
|
81
|
+
];
|
|
82
|
+
}
|
|
99
83
|
};
|
|
100
84
|
|
|
101
|
-
// compiler should normalize class + :class bindings on the same element
|
|
102
|
-
// into a single binding ['staticClass', dynamic]
|
|
103
|
-
function patchClass(el, value, isSVG) {
|
|
104
|
-
// directly setting className should be faster than setAttribute in theory
|
|
105
|
-
// if this is an element during a transition, take the temporary transition
|
|
106
|
-
// classes into account.
|
|
107
|
-
const transitionClasses = el._vtc;
|
|
108
|
-
if (transitionClasses) {
|
|
109
|
-
value = (value ? [value, ...transitionClasses] : [...transitionClasses]).join(' ');
|
|
110
|
-
}
|
|
111
|
-
if (value == null) {
|
|
112
|
-
el.removeAttribute('class');
|
|
113
|
-
}
|
|
114
|
-
else if (isSVG) {
|
|
115
|
-
el.setAttribute('class', value);
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
el.className = value;
|
|
119
|
-
}
|
|
85
|
+
// compiler should normalize class + :class bindings on the same element
|
|
86
|
+
// into a single binding ['staticClass', dynamic]
|
|
87
|
+
function patchClass(el, value, isSVG) {
|
|
88
|
+
// directly setting className should be faster than setAttribute in theory
|
|
89
|
+
// if this is an element during a transition, take the temporary transition
|
|
90
|
+
// classes into account.
|
|
91
|
+
const transitionClasses = el._vtc;
|
|
92
|
+
if (transitionClasses) {
|
|
93
|
+
value = (value ? [value, ...transitionClasses] : [...transitionClasses]).join(' ');
|
|
94
|
+
}
|
|
95
|
+
if (value == null) {
|
|
96
|
+
el.removeAttribute('class');
|
|
97
|
+
}
|
|
98
|
+
else if (isSVG) {
|
|
99
|
+
el.setAttribute('class', value);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
el.className = value;
|
|
103
|
+
}
|
|
120
104
|
}
|
|
121
105
|
|
|
122
|
-
function patchStyle(el, prev, next) {
|
|
123
|
-
const style = el.style;
|
|
124
|
-
const isCssString = shared.isString(next);
|
|
125
|
-
if (next && !isCssString) {
|
|
126
|
-
for (const key in next) {
|
|
127
|
-
setStyle(style, key, next[key]);
|
|
128
|
-
}
|
|
129
|
-
if (prev && !shared.isString(prev)) {
|
|
130
|
-
for (const key in prev) {
|
|
131
|
-
if (next[key] == null) {
|
|
132
|
-
setStyle(style, key, '');
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
const currentDisplay = style.display;
|
|
139
|
-
if (isCssString) {
|
|
140
|
-
if (prev !== next) {
|
|
141
|
-
style.cssText = next;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
else if (prev) {
|
|
145
|
-
el.removeAttribute('style');
|
|
146
|
-
}
|
|
147
|
-
// indicates that the `display` of the element is controlled by `v-show`,
|
|
148
|
-
// so we always keep the current `display` value regardless of the `style`
|
|
149
|
-
// value, thus handing over control to `v-show`.
|
|
150
|
-
if ('_vod' in el) {
|
|
151
|
-
style.display = currentDisplay;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
const importantRE = /\s*!important$/;
|
|
156
|
-
function setStyle(style, name, val) {
|
|
157
|
-
if (shared.isArray(val)) {
|
|
158
|
-
val.forEach(v => setStyle(style, name, v));
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
if (val == null)
|
|
162
|
-
val = '';
|
|
163
|
-
if (name.startsWith('--')) {
|
|
164
|
-
// custom property definition
|
|
165
|
-
style.setProperty(name, val);
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
const prefixed = autoPrefix(style, name);
|
|
169
|
-
if (importantRE.test(val)) {
|
|
170
|
-
// !important
|
|
171
|
-
style.setProperty(shared.hyphenate(prefixed), val.replace(importantRE, ''), 'important');
|
|
172
|
-
}
|
|
173
|
-
else {
|
|
174
|
-
style[prefixed] = val;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
const prefixes = ['Webkit', 'Moz', 'ms'];
|
|
180
|
-
const prefixCache = {};
|
|
181
|
-
function autoPrefix(style, rawName) {
|
|
182
|
-
const cached = prefixCache[rawName];
|
|
183
|
-
if (cached) {
|
|
184
|
-
return cached;
|
|
185
|
-
}
|
|
186
|
-
let name = runtimeCore.camelize(rawName);
|
|
187
|
-
if (name !== 'filter' && name in style) {
|
|
188
|
-
return (prefixCache[rawName] = name);
|
|
189
|
-
}
|
|
190
|
-
name = shared.capitalize(name);
|
|
191
|
-
for (let i = 0; i < prefixes.length; i++) {
|
|
192
|
-
const prefixed = prefixes[i] + name;
|
|
193
|
-
if (prefixed in style) {
|
|
194
|
-
return (prefixCache[rawName] = prefixed);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
return rawName;
|
|
106
|
+
function patchStyle(el, prev, next) {
|
|
107
|
+
const style = el.style;
|
|
108
|
+
const isCssString = shared.isString(next);
|
|
109
|
+
if (next && !isCssString) {
|
|
110
|
+
for (const key in next) {
|
|
111
|
+
setStyle(style, key, next[key]);
|
|
112
|
+
}
|
|
113
|
+
if (prev && !shared.isString(prev)) {
|
|
114
|
+
for (const key in prev) {
|
|
115
|
+
if (next[key] == null) {
|
|
116
|
+
setStyle(style, key, '');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
const currentDisplay = style.display;
|
|
123
|
+
if (isCssString) {
|
|
124
|
+
if (prev !== next) {
|
|
125
|
+
style.cssText = next;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else if (prev) {
|
|
129
|
+
el.removeAttribute('style');
|
|
130
|
+
}
|
|
131
|
+
// indicates that the `display` of the element is controlled by `v-show`,
|
|
132
|
+
// so we always keep the current `display` value regardless of the `style`
|
|
133
|
+
// value, thus handing over control to `v-show`.
|
|
134
|
+
if ('_vod' in el) {
|
|
135
|
+
style.display = currentDisplay;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const importantRE = /\s*!important$/;
|
|
140
|
+
function setStyle(style, name, val) {
|
|
141
|
+
if (shared.isArray(val)) {
|
|
142
|
+
val.forEach(v => setStyle(style, name, v));
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
if (val == null)
|
|
146
|
+
val = '';
|
|
147
|
+
if (name.startsWith('--')) {
|
|
148
|
+
// custom property definition
|
|
149
|
+
style.setProperty(name, val);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
const prefixed = autoPrefix(style, name);
|
|
153
|
+
if (importantRE.test(val)) {
|
|
154
|
+
// !important
|
|
155
|
+
style.setProperty(shared.hyphenate(prefixed), val.replace(importantRE, ''), 'important');
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
style[prefixed] = val;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
const prefixes = ['Webkit', 'Moz', 'ms'];
|
|
164
|
+
const prefixCache = {};
|
|
165
|
+
function autoPrefix(style, rawName) {
|
|
166
|
+
const cached = prefixCache[rawName];
|
|
167
|
+
if (cached) {
|
|
168
|
+
return cached;
|
|
169
|
+
}
|
|
170
|
+
let name = runtimeCore.camelize(rawName);
|
|
171
|
+
if (name !== 'filter' && name in style) {
|
|
172
|
+
return (prefixCache[rawName] = name);
|
|
173
|
+
}
|
|
174
|
+
name = shared.capitalize(name);
|
|
175
|
+
for (let i = 0; i < prefixes.length; i++) {
|
|
176
|
+
const prefixed = prefixes[i] + name;
|
|
177
|
+
if (prefixed in style) {
|
|
178
|
+
return (prefixCache[rawName] = prefixed);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return rawName;
|
|
198
182
|
}
|
|
199
183
|
|
|
200
|
-
const xlinkNS = 'http://www.w3.org/1999/xlink';
|
|
201
|
-
function patchAttr(el, key, value, isSVG, instance) {
|
|
202
|
-
if (isSVG && key.startsWith('xlink:')) {
|
|
203
|
-
if (value == null) {
|
|
204
|
-
el.removeAttributeNS(xlinkNS, key.slice(6, key.length));
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
el.setAttributeNS(xlinkNS, key, value);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
else {
|
|
211
|
-
// note we are only checking boolean attributes that don't have a
|
|
212
|
-
// corresponding dom prop of the same name here.
|
|
213
|
-
const isBoolean = shared.isSpecialBooleanAttr(key);
|
|
214
|
-
if (value == null || (isBoolean && !shared.includeBooleanAttr(value))) {
|
|
215
|
-
el.removeAttribute(key);
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
el.setAttribute(key, isBoolean ? '' : value);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
184
|
+
const xlinkNS = 'http://www.w3.org/1999/xlink';
|
|
185
|
+
function patchAttr(el, key, value, isSVG, instance) {
|
|
186
|
+
if (isSVG && key.startsWith('xlink:')) {
|
|
187
|
+
if (value == null) {
|
|
188
|
+
el.removeAttributeNS(xlinkNS, key.slice(6, key.length));
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
el.setAttributeNS(xlinkNS, key, value);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
// note we are only checking boolean attributes that don't have a
|
|
196
|
+
// corresponding dom prop of the same name here.
|
|
197
|
+
const isBoolean = shared.isSpecialBooleanAttr(key);
|
|
198
|
+
if (value == null || (isBoolean && !shared.includeBooleanAttr(value))) {
|
|
199
|
+
el.removeAttribute(key);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
el.setAttribute(key, isBoolean ? '' : value);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
221
205
|
}
|
|
222
206
|
|
|
223
|
-
// __UNSAFE__
|
|
224
|
-
// functions. The user is responsible for using them with only trusted content.
|
|
225
|
-
function patchDOMProp(el, key, value,
|
|
226
|
-
// the following args are passed only due to potential innerHTML/textContent
|
|
227
|
-
// overriding existing VNodes, in which case the old tree must be properly
|
|
228
|
-
// unmounted.
|
|
229
|
-
prevChildren, parentComponent, parentSuspense, unmountChildren) {
|
|
230
|
-
if (key === 'innerHTML' || key === 'textContent') {
|
|
231
|
-
if (prevChildren) {
|
|
232
|
-
unmountChildren(prevChildren, parentComponent, parentSuspense);
|
|
233
|
-
}
|
|
234
|
-
el[key] = value == null ? '' : value;
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
if (key === 'value' &&
|
|
238
|
-
el.tagName !== 'PROGRESS' &&
|
|
239
|
-
// custom elements may use _value internally
|
|
240
|
-
!el.tagName.includes('-')) {
|
|
241
|
-
// store value as _value as well since
|
|
242
|
-
// non-string values will be stringified.
|
|
243
|
-
el._value = value;
|
|
244
|
-
const newValue = value == null ? '' : value;
|
|
245
|
-
if (el.value !== newValue ||
|
|
246
|
-
// #4956: always set for OPTION elements because its value falls back to
|
|
247
|
-
// textContent if no value attribute is present. And setting .value for
|
|
248
|
-
// OPTION has no side effect
|
|
249
|
-
el.tagName === 'OPTION') {
|
|
250
|
-
el.value = newValue;
|
|
251
|
-
}
|
|
252
|
-
if (value == null) {
|
|
253
|
-
el.removeAttribute(key);
|
|
254
|
-
}
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
let needRemove = false;
|
|
258
|
-
if (value === '' || value == null) {
|
|
259
|
-
const type = typeof el[key];
|
|
260
|
-
if (type === 'boolean') {
|
|
261
|
-
// e.g. <select multiple> compiles to { multiple: '' }
|
|
262
|
-
value = shared.includeBooleanAttr(value);
|
|
263
|
-
}
|
|
264
|
-
else if (value == null && type === 'string') {
|
|
265
|
-
// e.g. <div :id="null">
|
|
266
|
-
value = '';
|
|
267
|
-
needRemove = true;
|
|
268
|
-
}
|
|
269
|
-
else if (type === 'number') {
|
|
270
|
-
// e.g. <img :width="null">
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
// some properties
|
|
277
|
-
//
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
needRemove && el.removeAttribute(key);
|
|
207
|
+
// __UNSAFE__
|
|
208
|
+
// functions. The user is responsible for using them with only trusted content.
|
|
209
|
+
function patchDOMProp(el, key, value,
|
|
210
|
+
// the following args are passed only due to potential innerHTML/textContent
|
|
211
|
+
// overriding existing VNodes, in which case the old tree must be properly
|
|
212
|
+
// unmounted.
|
|
213
|
+
prevChildren, parentComponent, parentSuspense, unmountChildren) {
|
|
214
|
+
if (key === 'innerHTML' || key === 'textContent') {
|
|
215
|
+
if (prevChildren) {
|
|
216
|
+
unmountChildren(prevChildren, parentComponent, parentSuspense);
|
|
217
|
+
}
|
|
218
|
+
el[key] = value == null ? '' : value;
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
if (key === 'value' &&
|
|
222
|
+
el.tagName !== 'PROGRESS' &&
|
|
223
|
+
// custom elements may use _value internally
|
|
224
|
+
!el.tagName.includes('-')) {
|
|
225
|
+
// store value as _value as well since
|
|
226
|
+
// non-string values will be stringified.
|
|
227
|
+
el._value = value;
|
|
228
|
+
const newValue = value == null ? '' : value;
|
|
229
|
+
if (el.value !== newValue ||
|
|
230
|
+
// #4956: always set for OPTION elements because its value falls back to
|
|
231
|
+
// textContent if no value attribute is present. And setting .value for
|
|
232
|
+
// OPTION has no side effect
|
|
233
|
+
el.tagName === 'OPTION') {
|
|
234
|
+
el.value = newValue;
|
|
235
|
+
}
|
|
236
|
+
if (value == null) {
|
|
237
|
+
el.removeAttribute(key);
|
|
238
|
+
}
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
let needRemove = false;
|
|
242
|
+
if (value === '' || value == null) {
|
|
243
|
+
const type = typeof el[key];
|
|
244
|
+
if (type === 'boolean') {
|
|
245
|
+
// e.g. <select multiple> compiles to { multiple: '' }
|
|
246
|
+
value = shared.includeBooleanAttr(value);
|
|
247
|
+
}
|
|
248
|
+
else if (value == null && type === 'string') {
|
|
249
|
+
// e.g. <div :id="null">
|
|
250
|
+
value = '';
|
|
251
|
+
needRemove = true;
|
|
252
|
+
}
|
|
253
|
+
else if (type === 'number') {
|
|
254
|
+
// e.g. <img :width="null">
|
|
255
|
+
value = 0;
|
|
256
|
+
needRemove = true;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
// some properties perform value validation and throw,
|
|
260
|
+
// some properties has getter, no setter, will error in 'use strict'
|
|
261
|
+
// eg. <select :type="null"></select> <select :willValidate="null"></select>
|
|
262
|
+
try {
|
|
263
|
+
el[key] = value;
|
|
264
|
+
}
|
|
265
|
+
catch (e) {
|
|
266
|
+
}
|
|
267
|
+
needRemove && el.removeAttribute(key);
|
|
285
268
|
}
|
|
286
269
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
//
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
const
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
}
|
|
372
|
-
invoker.value = initialValue;
|
|
373
|
-
invoker.attached = getNow();
|
|
374
|
-
return invoker;
|
|
375
|
-
}
|
|
376
|
-
function patchStopImmediatePropagation(e, value) {
|
|
377
|
-
if (shared.isArray(value)) {
|
|
378
|
-
const originalStop = e.stopImmediatePropagation;
|
|
379
|
-
e.stopImmediatePropagation = () => {
|
|
380
|
-
originalStop.call(e);
|
|
381
|
-
e._stopped = true;
|
|
382
|
-
};
|
|
383
|
-
return value.map(fn => (e) => !e._stopped && fn && fn(e));
|
|
384
|
-
}
|
|
385
|
-
else {
|
|
386
|
-
return value;
|
|
387
|
-
}
|
|
270
|
+
function addEventListener(el, event, handler, options) {
|
|
271
|
+
el.addEventListener(event, handler, options);
|
|
272
|
+
}
|
|
273
|
+
function removeEventListener(el, event, handler, options) {
|
|
274
|
+
el.removeEventListener(event, handler, options);
|
|
275
|
+
}
|
|
276
|
+
function patchEvent(el, rawName, prevValue, nextValue, instance = null) {
|
|
277
|
+
// vei = vue event invokers
|
|
278
|
+
const invokers = el._vei || (el._vei = {});
|
|
279
|
+
const existingInvoker = invokers[rawName];
|
|
280
|
+
if (nextValue && existingInvoker) {
|
|
281
|
+
// patch
|
|
282
|
+
existingInvoker.value = nextValue;
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
const [name, options] = parseName(rawName);
|
|
286
|
+
if (nextValue) {
|
|
287
|
+
// add
|
|
288
|
+
const invoker = (invokers[rawName] = createInvoker(nextValue, instance));
|
|
289
|
+
addEventListener(el, name, invoker, options);
|
|
290
|
+
}
|
|
291
|
+
else if (existingInvoker) {
|
|
292
|
+
// remove
|
|
293
|
+
removeEventListener(el, name, existingInvoker, options);
|
|
294
|
+
invokers[rawName] = undefined;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
const optionsModifierRE = /(?:Once|Passive|Capture)$/;
|
|
299
|
+
function parseName(name) {
|
|
300
|
+
let options;
|
|
301
|
+
if (optionsModifierRE.test(name)) {
|
|
302
|
+
options = {};
|
|
303
|
+
let m;
|
|
304
|
+
while ((m = name.match(optionsModifierRE))) {
|
|
305
|
+
name = name.slice(0, name.length - m[0].length);
|
|
306
|
+
options[m[0].toLowerCase()] = true;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
const event = name[2] === ':' ? name.slice(3) : shared.hyphenate(name.slice(2));
|
|
310
|
+
return [event, options];
|
|
311
|
+
}
|
|
312
|
+
// To avoid the overhead of repeatedly calling Date.now(), we cache
|
|
313
|
+
// and use the same timestamp for all event listeners attached in the same tick.
|
|
314
|
+
let cachedNow = 0;
|
|
315
|
+
const p = /*#__PURE__*/ Promise.resolve();
|
|
316
|
+
const getNow = () => cachedNow || (p.then(() => (cachedNow = 0)), (cachedNow = Date.now()));
|
|
317
|
+
function createInvoker(initialValue, instance) {
|
|
318
|
+
const invoker = (e) => {
|
|
319
|
+
// async edge case vuejs/vue#6566
|
|
320
|
+
// inner click event triggers patch, event handler
|
|
321
|
+
// attached to outer element during patch, and triggered again. This
|
|
322
|
+
// happens because browsers fire microtask ticks between event propagation.
|
|
323
|
+
// this no longer happens for templates in Vue 3, but could still be
|
|
324
|
+
// theoretically possible for hand-written render functions.
|
|
325
|
+
// the solution: we save the timestamp when a handler is attached,
|
|
326
|
+
// and also attach the timestamp to any event that was handled by vue
|
|
327
|
+
// for the first time (to avoid inconsistent event timestamp implementations
|
|
328
|
+
// or events fired from iframes, e.g. #2513)
|
|
329
|
+
// The handler would only fire if the event passed to it was fired
|
|
330
|
+
// AFTER it was attached.
|
|
331
|
+
if (!e._vts) {
|
|
332
|
+
e._vts = Date.now();
|
|
333
|
+
}
|
|
334
|
+
else if (e._vts <= invoker.attached) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
runtimeCore.callWithAsyncErrorHandling(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* ErrorCodes.NATIVE_EVENT_HANDLER */, [e]);
|
|
338
|
+
};
|
|
339
|
+
invoker.value = initialValue;
|
|
340
|
+
invoker.attached = getNow();
|
|
341
|
+
return invoker;
|
|
342
|
+
}
|
|
343
|
+
function patchStopImmediatePropagation(e, value) {
|
|
344
|
+
if (shared.isArray(value)) {
|
|
345
|
+
const originalStop = e.stopImmediatePropagation;
|
|
346
|
+
e.stopImmediatePropagation = () => {
|
|
347
|
+
originalStop.call(e);
|
|
348
|
+
e._stopped = true;
|
|
349
|
+
};
|
|
350
|
+
return value.map(fn => (e) => !e._stopped && fn && fn(e));
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
return value;
|
|
354
|
+
}
|
|
388
355
|
}
|
|
389
356
|
|
|
390
|
-
const nativeOnRE = /^on[a-z]/;
|
|
391
|
-
const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren) => {
|
|
392
|
-
if (key === 'class') {
|
|
393
|
-
patchClass(el, nextValue, isSVG);
|
|
394
|
-
}
|
|
395
|
-
else if (key === 'style') {
|
|
396
|
-
patchStyle(el, prevValue, nextValue);
|
|
397
|
-
}
|
|
398
|
-
else if (shared.isOn(key)) {
|
|
399
|
-
// ignore v-model listeners
|
|
400
|
-
if (!shared.isModelListener(key)) {
|
|
401
|
-
patchEvent(el, key, prevValue, nextValue, parentComponent);
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
else if (key[0] === '.'
|
|
405
|
-
? ((key = key.slice(1)), true)
|
|
406
|
-
: key[0] === '^'
|
|
407
|
-
? ((key = key.slice(1)), false)
|
|
408
|
-
: shouldSetAsProp(el, key, nextValue, isSVG)) {
|
|
409
|
-
patchDOMProp(el, key, nextValue, prevChildren, parentComponent, parentSuspense, unmountChildren);
|
|
410
|
-
}
|
|
411
|
-
else {
|
|
412
|
-
// special case for <input v-model type="checkbox"> with
|
|
413
|
-
// :true-value & :false-value
|
|
414
|
-
// store value as dom properties since non-string values will be
|
|
415
|
-
// stringified.
|
|
416
|
-
if (key === 'true-value') {
|
|
417
|
-
el._trueValue = nextValue;
|
|
418
|
-
}
|
|
419
|
-
else if (key === 'false-value') {
|
|
420
|
-
el._falseValue = nextValue;
|
|
421
|
-
}
|
|
422
|
-
patchAttr(el, key, nextValue, isSVG);
|
|
423
|
-
}
|
|
424
|
-
};
|
|
425
|
-
function shouldSetAsProp(el, key, value, isSVG) {
|
|
426
|
-
if (isSVG) {
|
|
427
|
-
// most keys must be set as attribute on svg elements to work
|
|
428
|
-
// ...except innerHTML & textContent
|
|
429
|
-
if (key === 'innerHTML' || key === 'textContent') {
|
|
430
|
-
return true;
|
|
431
|
-
}
|
|
432
|
-
// or native onclick with function values
|
|
433
|
-
if (key in el && nativeOnRE.test(key) && shared.isFunction(value)) {
|
|
434
|
-
return true;
|
|
435
|
-
}
|
|
436
|
-
return false;
|
|
437
|
-
}
|
|
438
|
-
// these are enumerated attrs, however their corresponding DOM properties
|
|
439
|
-
// are actually booleans - this leads to setting it with a string "false"
|
|
440
|
-
// value leading it to be coerced to `true`, so we need to always treat
|
|
441
|
-
// them as attributes.
|
|
442
|
-
// Note that `contentEditable` doesn't have this problem: its DOM
|
|
443
|
-
// property is also enumerated string values.
|
|
444
|
-
if (key === 'spellcheck' || key === 'draggable' || key === 'translate') {
|
|
445
|
-
return false;
|
|
446
|
-
}
|
|
447
|
-
// #1787, #2840 form property on form elements is readonly and must be set as
|
|
448
|
-
// attribute.
|
|
449
|
-
if (key === 'form') {
|
|
450
|
-
return false;
|
|
451
|
-
}
|
|
452
|
-
// #1526 <input list> must be set as attribute
|
|
453
|
-
if (key === 'list' && el.tagName === 'INPUT') {
|
|
454
|
-
return false;
|
|
455
|
-
}
|
|
456
|
-
// #2766 <textarea type> must be set as attribute
|
|
457
|
-
if (key === 'type' && el.tagName === 'TEXTAREA') {
|
|
458
|
-
return false;
|
|
459
|
-
}
|
|
460
|
-
// native onclick with string value, must be set as attribute
|
|
461
|
-
if (nativeOnRE.test(key) && shared.isString(value)) {
|
|
462
|
-
return false;
|
|
463
|
-
}
|
|
464
|
-
return key in el;
|
|
357
|
+
const nativeOnRE = /^on[a-z]/;
|
|
358
|
+
const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren) => {
|
|
359
|
+
if (key === 'class') {
|
|
360
|
+
patchClass(el, nextValue, isSVG);
|
|
361
|
+
}
|
|
362
|
+
else if (key === 'style') {
|
|
363
|
+
patchStyle(el, prevValue, nextValue);
|
|
364
|
+
}
|
|
365
|
+
else if (shared.isOn(key)) {
|
|
366
|
+
// ignore v-model listeners
|
|
367
|
+
if (!shared.isModelListener(key)) {
|
|
368
|
+
patchEvent(el, key, prevValue, nextValue, parentComponent);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
else if (key[0] === '.'
|
|
372
|
+
? ((key = key.slice(1)), true)
|
|
373
|
+
: key[0] === '^'
|
|
374
|
+
? ((key = key.slice(1)), false)
|
|
375
|
+
: shouldSetAsProp(el, key, nextValue, isSVG)) {
|
|
376
|
+
patchDOMProp(el, key, nextValue, prevChildren, parentComponent, parentSuspense, unmountChildren);
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
// special case for <input v-model type="checkbox"> with
|
|
380
|
+
// :true-value & :false-value
|
|
381
|
+
// store value as dom properties since non-string values will be
|
|
382
|
+
// stringified.
|
|
383
|
+
if (key === 'true-value') {
|
|
384
|
+
el._trueValue = nextValue;
|
|
385
|
+
}
|
|
386
|
+
else if (key === 'false-value') {
|
|
387
|
+
el._falseValue = nextValue;
|
|
388
|
+
}
|
|
389
|
+
patchAttr(el, key, nextValue, isSVG);
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
function shouldSetAsProp(el, key, value, isSVG) {
|
|
393
|
+
if (isSVG) {
|
|
394
|
+
// most keys must be set as attribute on svg elements to work
|
|
395
|
+
// ...except innerHTML & textContent
|
|
396
|
+
if (key === 'innerHTML' || key === 'textContent') {
|
|
397
|
+
return true;
|
|
398
|
+
}
|
|
399
|
+
// or native onclick with function values
|
|
400
|
+
if (key in el && nativeOnRE.test(key) && shared.isFunction(value)) {
|
|
401
|
+
return true;
|
|
402
|
+
}
|
|
403
|
+
return false;
|
|
404
|
+
}
|
|
405
|
+
// these are enumerated attrs, however their corresponding DOM properties
|
|
406
|
+
// are actually booleans - this leads to setting it with a string "false"
|
|
407
|
+
// value leading it to be coerced to `true`, so we need to always treat
|
|
408
|
+
// them as attributes.
|
|
409
|
+
// Note that `contentEditable` doesn't have this problem: its DOM
|
|
410
|
+
// property is also enumerated string values.
|
|
411
|
+
if (key === 'spellcheck' || key === 'draggable' || key === 'translate') {
|
|
412
|
+
return false;
|
|
413
|
+
}
|
|
414
|
+
// #1787, #2840 form property on form elements is readonly and must be set as
|
|
415
|
+
// attribute.
|
|
416
|
+
if (key === 'form') {
|
|
417
|
+
return false;
|
|
418
|
+
}
|
|
419
|
+
// #1526 <input list> must be set as attribute
|
|
420
|
+
if (key === 'list' && el.tagName === 'INPUT') {
|
|
421
|
+
return false;
|
|
422
|
+
}
|
|
423
|
+
// #2766 <textarea type> must be set as attribute
|
|
424
|
+
if (key === 'type' && el.tagName === 'TEXTAREA') {
|
|
425
|
+
return false;
|
|
426
|
+
}
|
|
427
|
+
// native onclick with string value, must be set as attribute
|
|
428
|
+
if (nativeOnRE.test(key) && shared.isString(value)) {
|
|
429
|
+
return false;
|
|
430
|
+
}
|
|
431
|
+
return key in el;
|
|
465
432
|
}
|
|
466
433
|
|
|
467
|
-
function defineCustomElement(options, hydrate) {
|
|
468
|
-
const Comp = runtimeCore.defineComponent(options);
|
|
469
|
-
class VueCustomElement extends VueElement {
|
|
470
|
-
constructor(initialProps) {
|
|
471
|
-
super(Comp, initialProps, hydrate);
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
VueCustomElement.def = Comp;
|
|
475
|
-
return VueCustomElement;
|
|
476
|
-
}
|
|
477
|
-
const defineSSRCustomElement = ((options) => {
|
|
478
|
-
// @ts-ignore
|
|
479
|
-
return defineCustomElement(options, hydrate);
|
|
480
|
-
});
|
|
481
|
-
const BaseClass = (typeof HTMLElement !== 'undefined' ? HTMLElement : class {
|
|
482
|
-
});
|
|
483
|
-
class VueElement extends BaseClass {
|
|
484
|
-
constructor(_def, _props = {}, hydrate) {
|
|
485
|
-
super();
|
|
486
|
-
this._def = _def;
|
|
487
|
-
this._props = _props;
|
|
488
|
-
/**
|
|
489
|
-
* @internal
|
|
490
|
-
*/
|
|
491
|
-
this._instance = null;
|
|
492
|
-
this._connected = false;
|
|
493
|
-
this._resolved = false;
|
|
494
|
-
this._numberProps = null;
|
|
495
|
-
if (this.shadowRoot && hydrate) {
|
|
496
|
-
hydrate(this._createVNode(), this.shadowRoot);
|
|
497
|
-
}
|
|
498
|
-
else {
|
|
499
|
-
this.attachShadow({ mode: 'open' });
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
connectedCallback() {
|
|
503
|
-
this._connected = true;
|
|
504
|
-
if (!this._instance) {
|
|
505
|
-
this._resolveDef();
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
disconnectedCallback() {
|
|
509
|
-
this._connected = false;
|
|
510
|
-
runtimeCore.nextTick(() => {
|
|
511
|
-
if (!this._connected) {
|
|
512
|
-
render(null, this.shadowRoot);
|
|
513
|
-
this._instance = null;
|
|
514
|
-
}
|
|
515
|
-
});
|
|
516
|
-
}
|
|
517
|
-
/**
|
|
518
|
-
* resolve inner component definition (handle possible async component)
|
|
519
|
-
*/
|
|
520
|
-
_resolveDef() {
|
|
521
|
-
if (this._resolved) {
|
|
522
|
-
return;
|
|
523
|
-
}
|
|
524
|
-
this._resolved = true;
|
|
525
|
-
// set initial attrs
|
|
526
|
-
for (let i = 0; i < this.attributes.length; i++) {
|
|
527
|
-
this._setAttr(this.attributes[i].name);
|
|
528
|
-
}
|
|
529
|
-
// watch future attr changes
|
|
530
|
-
new MutationObserver(mutations => {
|
|
531
|
-
for (const m of mutations) {
|
|
532
|
-
this._setAttr(m.attributeName);
|
|
533
|
-
}
|
|
534
|
-
}).observe(this, { attributes: true });
|
|
535
|
-
const resolve = (def) => {
|
|
536
|
-
const { props, styles } = def;
|
|
537
|
-
const hasOptions = !shared.isArray(props);
|
|
538
|
-
const rawKeys = props ? (hasOptions ? Object.keys(props) : props) : [];
|
|
539
|
-
// cast Number-type props set before resolve
|
|
540
|
-
let numberProps;
|
|
541
|
-
if (hasOptions) {
|
|
542
|
-
for (const key in this._props) {
|
|
543
|
-
const opt = props[key];
|
|
544
|
-
if (opt === Number || (opt && opt.type === Number)) {
|
|
545
|
-
this._props[key] = shared.toNumber(this._props[key]);
|
|
546
|
-
(numberProps || (numberProps = Object.create(null)))[key] = true;
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
this._numberProps = numberProps;
|
|
551
|
-
// check if there are props set pre-upgrade or connect
|
|
552
|
-
for (const key of Object.keys(this)) {
|
|
553
|
-
if (key[0] !== '_') {
|
|
554
|
-
this._setProp(key, this[key], true, false);
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
// defining getter/setters on prototype
|
|
558
|
-
for (const key of rawKeys.map(shared.camelize)) {
|
|
559
|
-
Object.defineProperty(this, key, {
|
|
560
|
-
get() {
|
|
561
|
-
return this._getProp(key);
|
|
562
|
-
},
|
|
563
|
-
set(val) {
|
|
564
|
-
this._setProp(key, val);
|
|
565
|
-
}
|
|
566
|
-
});
|
|
567
|
-
}
|
|
568
|
-
// apply CSS
|
|
569
|
-
this._applyStyles(styles);
|
|
570
|
-
// initial render
|
|
571
|
-
this._update();
|
|
572
|
-
};
|
|
573
|
-
const asyncDef = this._def.__asyncLoader;
|
|
574
|
-
if (asyncDef) {
|
|
575
|
-
asyncDef().then(resolve);
|
|
576
|
-
}
|
|
577
|
-
else {
|
|
578
|
-
resolve(this._def);
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
_setAttr(key) {
|
|
582
|
-
let value = this.getAttribute(key);
|
|
583
|
-
if (this._numberProps && this._numberProps[key]) {
|
|
584
|
-
value = shared.toNumber(value);
|
|
585
|
-
}
|
|
586
|
-
this._setProp(shared.camelize(key), value, false);
|
|
587
|
-
}
|
|
588
|
-
/**
|
|
589
|
-
* @internal
|
|
590
|
-
*/
|
|
591
|
-
_getProp(key) {
|
|
592
|
-
return this._props[key];
|
|
593
|
-
}
|
|
594
|
-
/**
|
|
595
|
-
* @internal
|
|
596
|
-
*/
|
|
597
|
-
_setProp(key, val, shouldReflect = true, shouldUpdate = true) {
|
|
598
|
-
if (val !== this._props[key]) {
|
|
599
|
-
this._props[key] = val;
|
|
600
|
-
if (shouldUpdate && this._instance) {
|
|
601
|
-
this._update();
|
|
602
|
-
}
|
|
603
|
-
// reflect
|
|
604
|
-
if (shouldReflect) {
|
|
605
|
-
if (val === true) {
|
|
606
|
-
this.setAttribute(shared.hyphenate(key), '');
|
|
607
|
-
}
|
|
608
|
-
else if (typeof val === 'string' || typeof val === 'number') {
|
|
609
|
-
this.setAttribute(shared.hyphenate(key), val + '');
|
|
610
|
-
}
|
|
611
|
-
else if (!val) {
|
|
612
|
-
this.removeAttribute(shared.hyphenate(key));
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
_update() {
|
|
618
|
-
render(this._createVNode(), this.shadowRoot);
|
|
619
|
-
}
|
|
620
|
-
_createVNode() {
|
|
621
|
-
const vnode = runtimeCore.createVNode(this._def, shared.extend({}, this._props));
|
|
622
|
-
if (!this._instance) {
|
|
623
|
-
vnode.ce = instance => {
|
|
624
|
-
this._instance = instance;
|
|
625
|
-
instance.isCE = true;
|
|
626
|
-
// intercept emit
|
|
627
|
-
instance.emit = (event, ...args) => {
|
|
628
|
-
this.dispatchEvent(new CustomEvent(event, {
|
|
629
|
-
detail: args
|
|
630
|
-
}));
|
|
631
|
-
};
|
|
632
|
-
// locate nearest Vue custom element parent for provide/inject
|
|
633
|
-
let parent = this;
|
|
634
|
-
while ((parent =
|
|
635
|
-
parent && (parent.parentNode || parent.host))) {
|
|
636
|
-
if (parent instanceof VueElement) {
|
|
637
|
-
instance.parent = parent._instance;
|
|
638
|
-
break;
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
};
|
|
642
|
-
}
|
|
643
|
-
return vnode;
|
|
644
|
-
}
|
|
645
|
-
_applyStyles(styles) {
|
|
646
|
-
if (styles) {
|
|
647
|
-
styles.forEach(css => {
|
|
648
|
-
const s = document.createElement('style');
|
|
649
|
-
s.textContent = css;
|
|
650
|
-
this.shadowRoot.appendChild(s);
|
|
651
|
-
});
|
|
652
|
-
}
|
|
653
|
-
}
|
|
434
|
+
function defineCustomElement(options, hydrate) {
|
|
435
|
+
const Comp = runtimeCore.defineComponent(options);
|
|
436
|
+
class VueCustomElement extends VueElement {
|
|
437
|
+
constructor(initialProps) {
|
|
438
|
+
super(Comp, initialProps, hydrate);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
VueCustomElement.def = Comp;
|
|
442
|
+
return VueCustomElement;
|
|
443
|
+
}
|
|
444
|
+
const defineSSRCustomElement = ((options) => {
|
|
445
|
+
// @ts-ignore
|
|
446
|
+
return defineCustomElement(options, hydrate);
|
|
447
|
+
});
|
|
448
|
+
const BaseClass = (typeof HTMLElement !== 'undefined' ? HTMLElement : class {
|
|
449
|
+
});
|
|
450
|
+
class VueElement extends BaseClass {
|
|
451
|
+
constructor(_def, _props = {}, hydrate) {
|
|
452
|
+
super();
|
|
453
|
+
this._def = _def;
|
|
454
|
+
this._props = _props;
|
|
455
|
+
/**
|
|
456
|
+
* @internal
|
|
457
|
+
*/
|
|
458
|
+
this._instance = null;
|
|
459
|
+
this._connected = false;
|
|
460
|
+
this._resolved = false;
|
|
461
|
+
this._numberProps = null;
|
|
462
|
+
if (this.shadowRoot && hydrate) {
|
|
463
|
+
hydrate(this._createVNode(), this.shadowRoot);
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
this.attachShadow({ mode: 'open' });
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
connectedCallback() {
|
|
470
|
+
this._connected = true;
|
|
471
|
+
if (!this._instance) {
|
|
472
|
+
this._resolveDef();
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
disconnectedCallback() {
|
|
476
|
+
this._connected = false;
|
|
477
|
+
runtimeCore.nextTick(() => {
|
|
478
|
+
if (!this._connected) {
|
|
479
|
+
render(null, this.shadowRoot);
|
|
480
|
+
this._instance = null;
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* resolve inner component definition (handle possible async component)
|
|
486
|
+
*/
|
|
487
|
+
_resolveDef() {
|
|
488
|
+
if (this._resolved) {
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
this._resolved = true;
|
|
492
|
+
// set initial attrs
|
|
493
|
+
for (let i = 0; i < this.attributes.length; i++) {
|
|
494
|
+
this._setAttr(this.attributes[i].name);
|
|
495
|
+
}
|
|
496
|
+
// watch future attr changes
|
|
497
|
+
new MutationObserver(mutations => {
|
|
498
|
+
for (const m of mutations) {
|
|
499
|
+
this._setAttr(m.attributeName);
|
|
500
|
+
}
|
|
501
|
+
}).observe(this, { attributes: true });
|
|
502
|
+
const resolve = (def) => {
|
|
503
|
+
const { props, styles } = def;
|
|
504
|
+
const hasOptions = !shared.isArray(props);
|
|
505
|
+
const rawKeys = props ? (hasOptions ? Object.keys(props) : props) : [];
|
|
506
|
+
// cast Number-type props set before resolve
|
|
507
|
+
let numberProps;
|
|
508
|
+
if (hasOptions) {
|
|
509
|
+
for (const key in this._props) {
|
|
510
|
+
const opt = props[key];
|
|
511
|
+
if (opt === Number || (opt && opt.type === Number)) {
|
|
512
|
+
this._props[key] = shared.toNumber(this._props[key]);
|
|
513
|
+
(numberProps || (numberProps = Object.create(null)))[key] = true;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
this._numberProps = numberProps;
|
|
518
|
+
// check if there are props set pre-upgrade or connect
|
|
519
|
+
for (const key of Object.keys(this)) {
|
|
520
|
+
if (key[0] !== '_') {
|
|
521
|
+
this._setProp(key, this[key], true, false);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
// defining getter/setters on prototype
|
|
525
|
+
for (const key of rawKeys.map(shared.camelize)) {
|
|
526
|
+
Object.defineProperty(this, key, {
|
|
527
|
+
get() {
|
|
528
|
+
return this._getProp(key);
|
|
529
|
+
},
|
|
530
|
+
set(val) {
|
|
531
|
+
this._setProp(key, val);
|
|
532
|
+
}
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
// apply CSS
|
|
536
|
+
this._applyStyles(styles);
|
|
537
|
+
// initial render
|
|
538
|
+
this._update();
|
|
539
|
+
};
|
|
540
|
+
const asyncDef = this._def.__asyncLoader;
|
|
541
|
+
if (asyncDef) {
|
|
542
|
+
asyncDef().then(resolve);
|
|
543
|
+
}
|
|
544
|
+
else {
|
|
545
|
+
resolve(this._def);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
_setAttr(key) {
|
|
549
|
+
let value = this.getAttribute(key);
|
|
550
|
+
if (this._numberProps && this._numberProps[key]) {
|
|
551
|
+
value = shared.toNumber(value);
|
|
552
|
+
}
|
|
553
|
+
this._setProp(shared.camelize(key), value, false);
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* @internal
|
|
557
|
+
*/
|
|
558
|
+
_getProp(key) {
|
|
559
|
+
return this._props[key];
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* @internal
|
|
563
|
+
*/
|
|
564
|
+
_setProp(key, val, shouldReflect = true, shouldUpdate = true) {
|
|
565
|
+
if (val !== this._props[key]) {
|
|
566
|
+
this._props[key] = val;
|
|
567
|
+
if (shouldUpdate && this._instance) {
|
|
568
|
+
this._update();
|
|
569
|
+
}
|
|
570
|
+
// reflect
|
|
571
|
+
if (shouldReflect) {
|
|
572
|
+
if (val === true) {
|
|
573
|
+
this.setAttribute(shared.hyphenate(key), '');
|
|
574
|
+
}
|
|
575
|
+
else if (typeof val === 'string' || typeof val === 'number') {
|
|
576
|
+
this.setAttribute(shared.hyphenate(key), val + '');
|
|
577
|
+
}
|
|
578
|
+
else if (!val) {
|
|
579
|
+
this.removeAttribute(shared.hyphenate(key));
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
_update() {
|
|
585
|
+
render(this._createVNode(), this.shadowRoot);
|
|
586
|
+
}
|
|
587
|
+
_createVNode() {
|
|
588
|
+
const vnode = runtimeCore.createVNode(this._def, shared.extend({}, this._props));
|
|
589
|
+
if (!this._instance) {
|
|
590
|
+
vnode.ce = instance => {
|
|
591
|
+
this._instance = instance;
|
|
592
|
+
instance.isCE = true;
|
|
593
|
+
// intercept emit
|
|
594
|
+
instance.emit = (event, ...args) => {
|
|
595
|
+
this.dispatchEvent(new CustomEvent(event, {
|
|
596
|
+
detail: args
|
|
597
|
+
}));
|
|
598
|
+
};
|
|
599
|
+
// locate nearest Vue custom element parent for provide/inject
|
|
600
|
+
let parent = this;
|
|
601
|
+
while ((parent =
|
|
602
|
+
parent && (parent.parentNode || parent.host))) {
|
|
603
|
+
if (parent instanceof VueElement) {
|
|
604
|
+
instance.parent = parent._instance;
|
|
605
|
+
break;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
return vnode;
|
|
611
|
+
}
|
|
612
|
+
_applyStyles(styles) {
|
|
613
|
+
if (styles) {
|
|
614
|
+
styles.forEach(css => {
|
|
615
|
+
const s = document.createElement('style');
|
|
616
|
+
s.textContent = css;
|
|
617
|
+
this.shadowRoot.appendChild(s);
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
}
|
|
654
621
|
}
|
|
655
622
|
|
|
656
|
-
function useCssModule(name = '$style') {
|
|
657
|
-
/* istanbul ignore else */
|
|
658
|
-
{
|
|
659
|
-
const instance = runtimeCore.getCurrentInstance();
|
|
660
|
-
if (!instance) {
|
|
661
|
-
return shared.EMPTY_OBJ;
|
|
662
|
-
}
|
|
663
|
-
const modules = instance.type.__cssModules;
|
|
664
|
-
if (!modules) {
|
|
665
|
-
return shared.EMPTY_OBJ;
|
|
666
|
-
}
|
|
667
|
-
const mod = modules[name];
|
|
668
|
-
if (!mod) {
|
|
669
|
-
return shared.EMPTY_OBJ;
|
|
670
|
-
}
|
|
671
|
-
return mod;
|
|
672
|
-
}
|
|
623
|
+
function useCssModule(name = '$style') {
|
|
624
|
+
/* istanbul ignore else */
|
|
625
|
+
{
|
|
626
|
+
const instance = runtimeCore.getCurrentInstance();
|
|
627
|
+
if (!instance) {
|
|
628
|
+
return shared.EMPTY_OBJ;
|
|
629
|
+
}
|
|
630
|
+
const modules = instance.type.__cssModules;
|
|
631
|
+
if (!modules) {
|
|
632
|
+
return shared.EMPTY_OBJ;
|
|
633
|
+
}
|
|
634
|
+
const mod = modules[name];
|
|
635
|
+
if (!mod) {
|
|
636
|
+
return shared.EMPTY_OBJ;
|
|
637
|
+
}
|
|
638
|
+
return mod;
|
|
639
|
+
}
|
|
673
640
|
}
|
|
674
641
|
|
|
675
|
-
/**
|
|
676
|
-
* Runtime helper for SFC's CSS variable injection feature.
|
|
677
|
-
* @private
|
|
678
|
-
*/
|
|
679
|
-
function useCssVars(getter) {
|
|
680
|
-
return;
|
|
642
|
+
/**
|
|
643
|
+
* Runtime helper for SFC's CSS variable injection feature.
|
|
644
|
+
* @private
|
|
645
|
+
*/
|
|
646
|
+
function useCssVars(getter) {
|
|
647
|
+
return;
|
|
681
648
|
}
|
|
682
649
|
|
|
683
|
-
const TRANSITION = 'transition';
|
|
684
|
-
const ANIMATION = 'animation';
|
|
685
|
-
// DOM Transition is a higher-order-component based on the platform-agnostic
|
|
686
|
-
// base Transition component, with DOM-specific logic.
|
|
687
|
-
const Transition = (props, { slots }) => runtimeCore.h(runtimeCore.BaseTransition, resolveTransitionProps(props), slots);
|
|
688
|
-
Transition.displayName = 'Transition';
|
|
689
|
-
const DOMTransitionPropsValidators = {
|
|
690
|
-
name: String,
|
|
691
|
-
type: String,
|
|
692
|
-
css: {
|
|
693
|
-
type: Boolean,
|
|
694
|
-
default: true
|
|
695
|
-
},
|
|
696
|
-
duration: [String, Number, Object],
|
|
697
|
-
enterFromClass: String,
|
|
698
|
-
enterActiveClass: String,
|
|
699
|
-
enterToClass: String,
|
|
700
|
-
appearFromClass: String,
|
|
701
|
-
appearActiveClass: String,
|
|
702
|
-
appearToClass: String,
|
|
703
|
-
leaveFromClass: String,
|
|
704
|
-
leaveActiveClass: String,
|
|
705
|
-
leaveToClass: String
|
|
706
|
-
};
|
|
707
|
-
const TransitionPropsValidators = (Transition.props =
|
|
708
|
-
/*#__PURE__*/ shared.extend({}, runtimeCore.BaseTransition.props, DOMTransitionPropsValidators));
|
|
709
|
-
/**
|
|
710
|
-
* #3227 Incoming hooks may be merged into arrays when wrapping Transition
|
|
711
|
-
* with custom HOCs.
|
|
712
|
-
*/
|
|
713
|
-
const callHook = (hook, args = []) => {
|
|
714
|
-
if (shared.isArray(hook)) {
|
|
715
|
-
hook.forEach(h => h(...args));
|
|
716
|
-
}
|
|
717
|
-
else if (hook) {
|
|
718
|
-
hook(...args);
|
|
719
|
-
}
|
|
720
|
-
};
|
|
721
|
-
/**
|
|
722
|
-
* Check if a hook expects a callback (2nd arg), which means the user
|
|
723
|
-
* intends to explicitly control the end of the transition.
|
|
724
|
-
*/
|
|
725
|
-
const hasExplicitCallback = (hook) => {
|
|
726
|
-
return hook
|
|
727
|
-
? shared.isArray(hook)
|
|
728
|
-
? hook.some(h => h.length > 1)
|
|
729
|
-
: hook.length > 1
|
|
730
|
-
: false;
|
|
731
|
-
};
|
|
732
|
-
function resolveTransitionProps(rawProps) {
|
|
733
|
-
const baseProps = {};
|
|
734
|
-
for (const key in rawProps) {
|
|
735
|
-
if (!(key in DOMTransitionPropsValidators)) {
|
|
736
|
-
baseProps[key] = rawProps[key];
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
if (rawProps.css === false) {
|
|
740
|
-
return baseProps;
|
|
741
|
-
}
|
|
742
|
-
const { name = 'v', type, duration, enterFromClass = `${name}-enter-from`, enterActiveClass = `${name}-enter-active`, enterToClass = `${name}-enter-to`, appearFromClass = enterFromClass, appearActiveClass = enterActiveClass, appearToClass = enterToClass, leaveFromClass = `${name}-leave-from`, leaveActiveClass = `${name}-leave-active`, leaveToClass = `${name}-leave-to` } = rawProps;
|
|
743
|
-
const durations = normalizeDuration(duration);
|
|
744
|
-
const enterDuration = durations && durations[0];
|
|
745
|
-
const leaveDuration = durations && durations[1];
|
|
746
|
-
const { onBeforeEnter, onEnter, onEnterCancelled, onLeave, onLeaveCancelled, onBeforeAppear = onBeforeEnter, onAppear = onEnter, onAppearCancelled = onEnterCancelled } = baseProps;
|
|
747
|
-
const finishEnter = (el, isAppear, done) => {
|
|
748
|
-
removeTransitionClass(el, isAppear ? appearToClass : enterToClass);
|
|
749
|
-
removeTransitionClass(el, isAppear ? appearActiveClass : enterActiveClass);
|
|
750
|
-
done && done();
|
|
751
|
-
};
|
|
752
|
-
const finishLeave = (el, done) => {
|
|
753
|
-
el._isLeaving = false;
|
|
754
|
-
removeTransitionClass(el, leaveFromClass);
|
|
755
|
-
removeTransitionClass(el, leaveToClass);
|
|
756
|
-
removeTransitionClass(el, leaveActiveClass);
|
|
757
|
-
done && done();
|
|
758
|
-
};
|
|
759
|
-
const makeEnterHook = (isAppear) => {
|
|
760
|
-
return (el, done) => {
|
|
761
|
-
const hook = isAppear ? onAppear : onEnter;
|
|
762
|
-
const resolve = () => finishEnter(el, isAppear, done);
|
|
763
|
-
callHook(hook, [el, resolve]);
|
|
764
|
-
nextFrame(() => {
|
|
765
|
-
removeTransitionClass(el, isAppear ? appearFromClass : enterFromClass);
|
|
766
|
-
addTransitionClass(el, isAppear ? appearToClass : enterToClass);
|
|
767
|
-
if (!hasExplicitCallback(hook)) {
|
|
768
|
-
whenTransitionEnds(el, type, enterDuration, resolve);
|
|
769
|
-
}
|
|
770
|
-
});
|
|
771
|
-
};
|
|
772
|
-
};
|
|
773
|
-
return shared.extend(baseProps, {
|
|
774
|
-
onBeforeEnter(el) {
|
|
775
|
-
callHook(onBeforeEnter, [el]);
|
|
776
|
-
addTransitionClass(el, enterFromClass);
|
|
777
|
-
addTransitionClass(el, enterActiveClass);
|
|
778
|
-
},
|
|
779
|
-
onBeforeAppear(el) {
|
|
780
|
-
callHook(onBeforeAppear, [el]);
|
|
781
|
-
addTransitionClass(el, appearFromClass);
|
|
782
|
-
addTransitionClass(el, appearActiveClass);
|
|
783
|
-
},
|
|
784
|
-
onEnter: makeEnterHook(false),
|
|
785
|
-
onAppear: makeEnterHook(true),
|
|
786
|
-
onLeave(el, done) {
|
|
787
|
-
el._isLeaving = true;
|
|
788
|
-
const resolve = () => finishLeave(el, done);
|
|
789
|
-
addTransitionClass(el, leaveFromClass);
|
|
790
|
-
// force reflow so *-leave-from classes immediately take effect (#2593)
|
|
791
|
-
forceReflow();
|
|
792
|
-
addTransitionClass(el, leaveActiveClass);
|
|
793
|
-
nextFrame(() => {
|
|
794
|
-
if (!el._isLeaving) {
|
|
795
|
-
// cancelled
|
|
796
|
-
return;
|
|
797
|
-
}
|
|
798
|
-
removeTransitionClass(el, leaveFromClass);
|
|
799
|
-
addTransitionClass(el, leaveToClass);
|
|
800
|
-
if (!hasExplicitCallback(onLeave)) {
|
|
801
|
-
whenTransitionEnds(el, type, leaveDuration, resolve);
|
|
802
|
-
}
|
|
803
|
-
});
|
|
804
|
-
callHook(onLeave, [el, resolve]);
|
|
805
|
-
},
|
|
806
|
-
onEnterCancelled(el) {
|
|
807
|
-
finishEnter(el, false);
|
|
808
|
-
callHook(onEnterCancelled, [el]);
|
|
809
|
-
},
|
|
810
|
-
onAppearCancelled(el) {
|
|
811
|
-
finishEnter(el, true);
|
|
812
|
-
callHook(onAppearCancelled, [el]);
|
|
813
|
-
},
|
|
814
|
-
onLeaveCancelled(el) {
|
|
815
|
-
finishLeave(el);
|
|
816
|
-
callHook(onLeaveCancelled, [el]);
|
|
817
|
-
}
|
|
818
|
-
});
|
|
819
|
-
}
|
|
820
|
-
function normalizeDuration(duration) {
|
|
821
|
-
if (duration == null) {
|
|
822
|
-
return null;
|
|
823
|
-
}
|
|
824
|
-
else if (shared.isObject(duration)) {
|
|
825
|
-
return [NumberOf(duration.enter), NumberOf(duration.leave)];
|
|
826
|
-
}
|
|
827
|
-
else {
|
|
828
|
-
const n = NumberOf(duration);
|
|
829
|
-
return [n, n];
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
|
-
function NumberOf(val) {
|
|
833
|
-
const res = shared.toNumber(val);
|
|
834
|
-
return res;
|
|
835
|
-
}
|
|
836
|
-
function addTransitionClass(el, cls) {
|
|
837
|
-
cls.split(/\s+/).forEach(c => c && el.classList.add(c));
|
|
838
|
-
(el._vtc ||
|
|
839
|
-
(el._vtc = new Set())).add(cls);
|
|
840
|
-
}
|
|
841
|
-
function removeTransitionClass(el, cls) {
|
|
842
|
-
cls.split(/\s+/).forEach(c => c && el.classList.remove(c));
|
|
843
|
-
const { _vtc } = el;
|
|
844
|
-
if (_vtc) {
|
|
845
|
-
_vtc.delete(cls);
|
|
846
|
-
if (!_vtc.size) {
|
|
847
|
-
el._vtc = undefined;
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
function nextFrame(cb) {
|
|
852
|
-
requestAnimationFrame(() => {
|
|
853
|
-
requestAnimationFrame(cb);
|
|
854
|
-
});
|
|
855
|
-
}
|
|
856
|
-
let endId = 0;
|
|
857
|
-
function whenTransitionEnds(el, expectedType, explicitTimeout, resolve) {
|
|
858
|
-
const id = (el._endId = ++endId);
|
|
859
|
-
const resolveIfNotStale = () => {
|
|
860
|
-
if (id === el._endId) {
|
|
861
|
-
resolve();
|
|
862
|
-
}
|
|
863
|
-
};
|
|
864
|
-
if (explicitTimeout) {
|
|
865
|
-
return setTimeout(resolveIfNotStale, explicitTimeout);
|
|
866
|
-
}
|
|
867
|
-
const { type, timeout, propCount } = getTransitionInfo(el, expectedType);
|
|
868
|
-
if (!type) {
|
|
869
|
-
return resolve();
|
|
870
|
-
}
|
|
871
|
-
const endEvent = type + 'end';
|
|
872
|
-
let ended = 0;
|
|
873
|
-
const end = () => {
|
|
874
|
-
el.removeEventListener(endEvent, onEnd);
|
|
875
|
-
resolveIfNotStale();
|
|
876
|
-
};
|
|
877
|
-
const onEnd = (e) => {
|
|
878
|
-
if (e.target === el && ++ended >= propCount) {
|
|
879
|
-
end();
|
|
880
|
-
}
|
|
881
|
-
};
|
|
882
|
-
setTimeout(() => {
|
|
883
|
-
if (ended < propCount) {
|
|
884
|
-
end();
|
|
885
|
-
}
|
|
886
|
-
}, timeout + 1);
|
|
887
|
-
el.addEventListener(endEvent, onEnd);
|
|
888
|
-
}
|
|
889
|
-
function getTransitionInfo(el, expectedType) {
|
|
890
|
-
const styles = window.getComputedStyle(el);
|
|
891
|
-
// JSDOM may return undefined for transition properties
|
|
892
|
-
const getStyleProperties = (key) => (styles[key] || '').split(', ');
|
|
893
|
-
const transitionDelays = getStyleProperties(TRANSITION + 'Delay');
|
|
894
|
-
const transitionDurations = getStyleProperties(TRANSITION + 'Duration');
|
|
895
|
-
const transitionTimeout = getTimeout(transitionDelays, transitionDurations);
|
|
896
|
-
const animationDelays = getStyleProperties(ANIMATION + 'Delay');
|
|
897
|
-
const animationDurations = getStyleProperties(ANIMATION + 'Duration');
|
|
898
|
-
const animationTimeout = getTimeout(animationDelays, animationDurations);
|
|
899
|
-
let type = null;
|
|
900
|
-
let timeout = 0;
|
|
901
|
-
let propCount = 0;
|
|
902
|
-
/* istanbul ignore if */
|
|
903
|
-
if (expectedType === TRANSITION) {
|
|
904
|
-
if (transitionTimeout > 0) {
|
|
905
|
-
type = TRANSITION;
|
|
906
|
-
timeout = transitionTimeout;
|
|
907
|
-
propCount = transitionDurations.length;
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
else if (expectedType === ANIMATION) {
|
|
911
|
-
if (animationTimeout > 0) {
|
|
912
|
-
type = ANIMATION;
|
|
913
|
-
timeout = animationTimeout;
|
|
914
|
-
propCount = animationDurations.length;
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
else {
|
|
918
|
-
timeout = Math.max(transitionTimeout, animationTimeout);
|
|
919
|
-
type =
|
|
920
|
-
timeout > 0
|
|
921
|
-
? transitionTimeout > animationTimeout
|
|
922
|
-
? TRANSITION
|
|
923
|
-
: ANIMATION
|
|
924
|
-
: null;
|
|
925
|
-
propCount = type
|
|
926
|
-
? type === TRANSITION
|
|
927
|
-
? transitionDurations.length
|
|
928
|
-
: animationDurations.length
|
|
929
|
-
: 0;
|
|
930
|
-
}
|
|
931
|
-
const hasTransform = type === TRANSITION &&
|
|
932
|
-
/\b(transform|all)(,|$)/.test(styles[TRANSITION + 'Property']);
|
|
933
|
-
return {
|
|
934
|
-
type,
|
|
935
|
-
timeout,
|
|
936
|
-
propCount,
|
|
937
|
-
hasTransform
|
|
938
|
-
};
|
|
939
|
-
}
|
|
940
|
-
function getTimeout(delays, durations) {
|
|
941
|
-
while (delays.length < durations.length) {
|
|
942
|
-
delays = delays.concat(delays);
|
|
943
|
-
}
|
|
944
|
-
return Math.max(...durations.map((d, i) => toMs(d) + toMs(delays[i])));
|
|
945
|
-
}
|
|
946
|
-
// Old versions of Chromium (below 61.0.3163.100) formats floating pointer
|
|
947
|
-
// numbers in a locale-dependent way, using a comma instead of a dot.
|
|
948
|
-
// If comma is not replaced with a dot, the input will be rounded down
|
|
949
|
-
// (i.e. acting as a floor function) causing unexpected behaviors
|
|
950
|
-
function toMs(s) {
|
|
951
|
-
return Number(s.slice(0, -1).replace(',', '.')) * 1000;
|
|
952
|
-
}
|
|
953
|
-
// synchronously force layout to put elements into a certain state
|
|
954
|
-
function forceReflow() {
|
|
955
|
-
return document.body.offsetHeight;
|
|
650
|
+
const TRANSITION = 'transition';
|
|
651
|
+
const ANIMATION = 'animation';
|
|
652
|
+
// DOM Transition is a higher-order-component based on the platform-agnostic
|
|
653
|
+
// base Transition component, with DOM-specific logic.
|
|
654
|
+
const Transition = (props, { slots }) => runtimeCore.h(runtimeCore.BaseTransition, resolveTransitionProps(props), slots);
|
|
655
|
+
Transition.displayName = 'Transition';
|
|
656
|
+
const DOMTransitionPropsValidators = {
|
|
657
|
+
name: String,
|
|
658
|
+
type: String,
|
|
659
|
+
css: {
|
|
660
|
+
type: Boolean,
|
|
661
|
+
default: true
|
|
662
|
+
},
|
|
663
|
+
duration: [String, Number, Object],
|
|
664
|
+
enterFromClass: String,
|
|
665
|
+
enterActiveClass: String,
|
|
666
|
+
enterToClass: String,
|
|
667
|
+
appearFromClass: String,
|
|
668
|
+
appearActiveClass: String,
|
|
669
|
+
appearToClass: String,
|
|
670
|
+
leaveFromClass: String,
|
|
671
|
+
leaveActiveClass: String,
|
|
672
|
+
leaveToClass: String
|
|
673
|
+
};
|
|
674
|
+
const TransitionPropsValidators = (Transition.props =
|
|
675
|
+
/*#__PURE__*/ shared.extend({}, runtimeCore.BaseTransition.props, DOMTransitionPropsValidators));
|
|
676
|
+
/**
|
|
677
|
+
* #3227 Incoming hooks may be merged into arrays when wrapping Transition
|
|
678
|
+
* with custom HOCs.
|
|
679
|
+
*/
|
|
680
|
+
const callHook = (hook, args = []) => {
|
|
681
|
+
if (shared.isArray(hook)) {
|
|
682
|
+
hook.forEach(h => h(...args));
|
|
683
|
+
}
|
|
684
|
+
else if (hook) {
|
|
685
|
+
hook(...args);
|
|
686
|
+
}
|
|
687
|
+
};
|
|
688
|
+
/**
|
|
689
|
+
* Check if a hook expects a callback (2nd arg), which means the user
|
|
690
|
+
* intends to explicitly control the end of the transition.
|
|
691
|
+
*/
|
|
692
|
+
const hasExplicitCallback = (hook) => {
|
|
693
|
+
return hook
|
|
694
|
+
? shared.isArray(hook)
|
|
695
|
+
? hook.some(h => h.length > 1)
|
|
696
|
+
: hook.length > 1
|
|
697
|
+
: false;
|
|
698
|
+
};
|
|
699
|
+
function resolveTransitionProps(rawProps) {
|
|
700
|
+
const baseProps = {};
|
|
701
|
+
for (const key in rawProps) {
|
|
702
|
+
if (!(key in DOMTransitionPropsValidators)) {
|
|
703
|
+
baseProps[key] = rawProps[key];
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
if (rawProps.css === false) {
|
|
707
|
+
return baseProps;
|
|
708
|
+
}
|
|
709
|
+
const { name = 'v', type, duration, enterFromClass = `${name}-enter-from`, enterActiveClass = `${name}-enter-active`, enterToClass = `${name}-enter-to`, appearFromClass = enterFromClass, appearActiveClass = enterActiveClass, appearToClass = enterToClass, leaveFromClass = `${name}-leave-from`, leaveActiveClass = `${name}-leave-active`, leaveToClass = `${name}-leave-to` } = rawProps;
|
|
710
|
+
const durations = normalizeDuration(duration);
|
|
711
|
+
const enterDuration = durations && durations[0];
|
|
712
|
+
const leaveDuration = durations && durations[1];
|
|
713
|
+
const { onBeforeEnter, onEnter, onEnterCancelled, onLeave, onLeaveCancelled, onBeforeAppear = onBeforeEnter, onAppear = onEnter, onAppearCancelled = onEnterCancelled } = baseProps;
|
|
714
|
+
const finishEnter = (el, isAppear, done) => {
|
|
715
|
+
removeTransitionClass(el, isAppear ? appearToClass : enterToClass);
|
|
716
|
+
removeTransitionClass(el, isAppear ? appearActiveClass : enterActiveClass);
|
|
717
|
+
done && done();
|
|
718
|
+
};
|
|
719
|
+
const finishLeave = (el, done) => {
|
|
720
|
+
el._isLeaving = false;
|
|
721
|
+
removeTransitionClass(el, leaveFromClass);
|
|
722
|
+
removeTransitionClass(el, leaveToClass);
|
|
723
|
+
removeTransitionClass(el, leaveActiveClass);
|
|
724
|
+
done && done();
|
|
725
|
+
};
|
|
726
|
+
const makeEnterHook = (isAppear) => {
|
|
727
|
+
return (el, done) => {
|
|
728
|
+
const hook = isAppear ? onAppear : onEnter;
|
|
729
|
+
const resolve = () => finishEnter(el, isAppear, done);
|
|
730
|
+
callHook(hook, [el, resolve]);
|
|
731
|
+
nextFrame(() => {
|
|
732
|
+
removeTransitionClass(el, isAppear ? appearFromClass : enterFromClass);
|
|
733
|
+
addTransitionClass(el, isAppear ? appearToClass : enterToClass);
|
|
734
|
+
if (!hasExplicitCallback(hook)) {
|
|
735
|
+
whenTransitionEnds(el, type, enterDuration, resolve);
|
|
736
|
+
}
|
|
737
|
+
});
|
|
738
|
+
};
|
|
739
|
+
};
|
|
740
|
+
return shared.extend(baseProps, {
|
|
741
|
+
onBeforeEnter(el) {
|
|
742
|
+
callHook(onBeforeEnter, [el]);
|
|
743
|
+
addTransitionClass(el, enterFromClass);
|
|
744
|
+
addTransitionClass(el, enterActiveClass);
|
|
745
|
+
},
|
|
746
|
+
onBeforeAppear(el) {
|
|
747
|
+
callHook(onBeforeAppear, [el]);
|
|
748
|
+
addTransitionClass(el, appearFromClass);
|
|
749
|
+
addTransitionClass(el, appearActiveClass);
|
|
750
|
+
},
|
|
751
|
+
onEnter: makeEnterHook(false),
|
|
752
|
+
onAppear: makeEnterHook(true),
|
|
753
|
+
onLeave(el, done) {
|
|
754
|
+
el._isLeaving = true;
|
|
755
|
+
const resolve = () => finishLeave(el, done);
|
|
756
|
+
addTransitionClass(el, leaveFromClass);
|
|
757
|
+
// force reflow so *-leave-from classes immediately take effect (#2593)
|
|
758
|
+
forceReflow();
|
|
759
|
+
addTransitionClass(el, leaveActiveClass);
|
|
760
|
+
nextFrame(() => {
|
|
761
|
+
if (!el._isLeaving) {
|
|
762
|
+
// cancelled
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
removeTransitionClass(el, leaveFromClass);
|
|
766
|
+
addTransitionClass(el, leaveToClass);
|
|
767
|
+
if (!hasExplicitCallback(onLeave)) {
|
|
768
|
+
whenTransitionEnds(el, type, leaveDuration, resolve);
|
|
769
|
+
}
|
|
770
|
+
});
|
|
771
|
+
callHook(onLeave, [el, resolve]);
|
|
772
|
+
},
|
|
773
|
+
onEnterCancelled(el) {
|
|
774
|
+
finishEnter(el, false);
|
|
775
|
+
callHook(onEnterCancelled, [el]);
|
|
776
|
+
},
|
|
777
|
+
onAppearCancelled(el) {
|
|
778
|
+
finishEnter(el, true);
|
|
779
|
+
callHook(onAppearCancelled, [el]);
|
|
780
|
+
},
|
|
781
|
+
onLeaveCancelled(el) {
|
|
782
|
+
finishLeave(el);
|
|
783
|
+
callHook(onLeaveCancelled, [el]);
|
|
784
|
+
}
|
|
785
|
+
});
|
|
786
|
+
}
|
|
787
|
+
function normalizeDuration(duration) {
|
|
788
|
+
if (duration == null) {
|
|
789
|
+
return null;
|
|
790
|
+
}
|
|
791
|
+
else if (shared.isObject(duration)) {
|
|
792
|
+
return [NumberOf(duration.enter), NumberOf(duration.leave)];
|
|
793
|
+
}
|
|
794
|
+
else {
|
|
795
|
+
const n = NumberOf(duration);
|
|
796
|
+
return [n, n];
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
function NumberOf(val) {
|
|
800
|
+
const res = shared.toNumber(val);
|
|
801
|
+
return res;
|
|
802
|
+
}
|
|
803
|
+
function addTransitionClass(el, cls) {
|
|
804
|
+
cls.split(/\s+/).forEach(c => c && el.classList.add(c));
|
|
805
|
+
(el._vtc ||
|
|
806
|
+
(el._vtc = new Set())).add(cls);
|
|
807
|
+
}
|
|
808
|
+
function removeTransitionClass(el, cls) {
|
|
809
|
+
cls.split(/\s+/).forEach(c => c && el.classList.remove(c));
|
|
810
|
+
const { _vtc } = el;
|
|
811
|
+
if (_vtc) {
|
|
812
|
+
_vtc.delete(cls);
|
|
813
|
+
if (!_vtc.size) {
|
|
814
|
+
el._vtc = undefined;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
function nextFrame(cb) {
|
|
819
|
+
requestAnimationFrame(() => {
|
|
820
|
+
requestAnimationFrame(cb);
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
let endId = 0;
|
|
824
|
+
function whenTransitionEnds(el, expectedType, explicitTimeout, resolve) {
|
|
825
|
+
const id = (el._endId = ++endId);
|
|
826
|
+
const resolveIfNotStale = () => {
|
|
827
|
+
if (id === el._endId) {
|
|
828
|
+
resolve();
|
|
829
|
+
}
|
|
830
|
+
};
|
|
831
|
+
if (explicitTimeout) {
|
|
832
|
+
return setTimeout(resolveIfNotStale, explicitTimeout);
|
|
833
|
+
}
|
|
834
|
+
const { type, timeout, propCount } = getTransitionInfo(el, expectedType);
|
|
835
|
+
if (!type) {
|
|
836
|
+
return resolve();
|
|
837
|
+
}
|
|
838
|
+
const endEvent = type + 'end';
|
|
839
|
+
let ended = 0;
|
|
840
|
+
const end = () => {
|
|
841
|
+
el.removeEventListener(endEvent, onEnd);
|
|
842
|
+
resolveIfNotStale();
|
|
843
|
+
};
|
|
844
|
+
const onEnd = (e) => {
|
|
845
|
+
if (e.target === el && ++ended >= propCount) {
|
|
846
|
+
end();
|
|
847
|
+
}
|
|
848
|
+
};
|
|
849
|
+
setTimeout(() => {
|
|
850
|
+
if (ended < propCount) {
|
|
851
|
+
end();
|
|
852
|
+
}
|
|
853
|
+
}, timeout + 1);
|
|
854
|
+
el.addEventListener(endEvent, onEnd);
|
|
855
|
+
}
|
|
856
|
+
function getTransitionInfo(el, expectedType) {
|
|
857
|
+
const styles = window.getComputedStyle(el);
|
|
858
|
+
// JSDOM may return undefined for transition properties
|
|
859
|
+
const getStyleProperties = (key) => (styles[key] || '').split(', ');
|
|
860
|
+
const transitionDelays = getStyleProperties(TRANSITION + 'Delay');
|
|
861
|
+
const transitionDurations = getStyleProperties(TRANSITION + 'Duration');
|
|
862
|
+
const transitionTimeout = getTimeout(transitionDelays, transitionDurations);
|
|
863
|
+
const animationDelays = getStyleProperties(ANIMATION + 'Delay');
|
|
864
|
+
const animationDurations = getStyleProperties(ANIMATION + 'Duration');
|
|
865
|
+
const animationTimeout = getTimeout(animationDelays, animationDurations);
|
|
866
|
+
let type = null;
|
|
867
|
+
let timeout = 0;
|
|
868
|
+
let propCount = 0;
|
|
869
|
+
/* istanbul ignore if */
|
|
870
|
+
if (expectedType === TRANSITION) {
|
|
871
|
+
if (transitionTimeout > 0) {
|
|
872
|
+
type = TRANSITION;
|
|
873
|
+
timeout = transitionTimeout;
|
|
874
|
+
propCount = transitionDurations.length;
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
else if (expectedType === ANIMATION) {
|
|
878
|
+
if (animationTimeout > 0) {
|
|
879
|
+
type = ANIMATION;
|
|
880
|
+
timeout = animationTimeout;
|
|
881
|
+
propCount = animationDurations.length;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
else {
|
|
885
|
+
timeout = Math.max(transitionTimeout, animationTimeout);
|
|
886
|
+
type =
|
|
887
|
+
timeout > 0
|
|
888
|
+
? transitionTimeout > animationTimeout
|
|
889
|
+
? TRANSITION
|
|
890
|
+
: ANIMATION
|
|
891
|
+
: null;
|
|
892
|
+
propCount = type
|
|
893
|
+
? type === TRANSITION
|
|
894
|
+
? transitionDurations.length
|
|
895
|
+
: animationDurations.length
|
|
896
|
+
: 0;
|
|
897
|
+
}
|
|
898
|
+
const hasTransform = type === TRANSITION &&
|
|
899
|
+
/\b(transform|all)(,|$)/.test(styles[TRANSITION + 'Property']);
|
|
900
|
+
return {
|
|
901
|
+
type,
|
|
902
|
+
timeout,
|
|
903
|
+
propCount,
|
|
904
|
+
hasTransform
|
|
905
|
+
};
|
|
906
|
+
}
|
|
907
|
+
function getTimeout(delays, durations) {
|
|
908
|
+
while (delays.length < durations.length) {
|
|
909
|
+
delays = delays.concat(delays);
|
|
910
|
+
}
|
|
911
|
+
return Math.max(...durations.map((d, i) => toMs(d) + toMs(delays[i])));
|
|
912
|
+
}
|
|
913
|
+
// Old versions of Chromium (below 61.0.3163.100) formats floating pointer
|
|
914
|
+
// numbers in a locale-dependent way, using a comma instead of a dot.
|
|
915
|
+
// If comma is not replaced with a dot, the input will be rounded down
|
|
916
|
+
// (i.e. acting as a floor function) causing unexpected behaviors
|
|
917
|
+
function toMs(s) {
|
|
918
|
+
return Number(s.slice(0, -1).replace(',', '.')) * 1000;
|
|
919
|
+
}
|
|
920
|
+
// synchronously force layout to put elements into a certain state
|
|
921
|
+
function forceReflow() {
|
|
922
|
+
return document.body.offsetHeight;
|
|
956
923
|
}
|
|
957
924
|
|
|
958
|
-
const positionMap = new WeakMap();
|
|
959
|
-
const newPositionMap = new WeakMap();
|
|
960
|
-
const TransitionGroupImpl = {
|
|
961
|
-
name: 'TransitionGroup',
|
|
962
|
-
props: /*#__PURE__*/ shared.extend({}, TransitionPropsValidators, {
|
|
963
|
-
tag: String,
|
|
964
|
-
moveClass: String
|
|
965
|
-
}),
|
|
966
|
-
setup(props, { slots }) {
|
|
967
|
-
const instance = runtimeCore.getCurrentInstance();
|
|
968
|
-
const state = runtimeCore.useTransitionState();
|
|
969
|
-
let prevChildren;
|
|
970
|
-
let children;
|
|
971
|
-
runtimeCore.onUpdated(() => {
|
|
972
|
-
// children is guaranteed to exist after initial render
|
|
973
|
-
if (!prevChildren.length) {
|
|
974
|
-
return;
|
|
975
|
-
}
|
|
976
|
-
const moveClass = props.moveClass || `${props.name || 'v'}-move`;
|
|
977
|
-
if (!hasCSSTransform(prevChildren[0].el, instance.vnode.el, moveClass)) {
|
|
978
|
-
return;
|
|
979
|
-
}
|
|
980
|
-
// we divide the work into three loops to avoid mixing DOM reads and writes
|
|
981
|
-
// in each iteration - which helps prevent layout thrashing.
|
|
982
|
-
prevChildren.forEach(callPendingCbs);
|
|
983
|
-
prevChildren.forEach(recordPosition);
|
|
984
|
-
const movedChildren = prevChildren.filter(applyTranslation);
|
|
985
|
-
// force reflow to put everything in position
|
|
986
|
-
forceReflow();
|
|
987
|
-
movedChildren.forEach(c => {
|
|
988
|
-
const el = c.el;
|
|
989
|
-
const style = el.style;
|
|
990
|
-
addTransitionClass(el, moveClass);
|
|
991
|
-
style.transform = style.webkitTransform = style.transitionDuration = '';
|
|
992
|
-
const cb = (el._moveCb = (e) => {
|
|
993
|
-
if (e && e.target !== el) {
|
|
994
|
-
return;
|
|
995
|
-
}
|
|
996
|
-
if (!e || /transform$/.test(e.propertyName)) {
|
|
997
|
-
el.removeEventListener('transitionend', cb);
|
|
998
|
-
el._moveCb = null;
|
|
999
|
-
removeTransitionClass(el, moveClass);
|
|
1000
|
-
}
|
|
1001
|
-
});
|
|
1002
|
-
el.addEventListener('transitionend', cb);
|
|
1003
|
-
});
|
|
1004
|
-
});
|
|
1005
|
-
return () => {
|
|
1006
|
-
const rawProps = runtimeCore.toRaw(props);
|
|
1007
|
-
const cssTransitionProps = resolveTransitionProps(rawProps);
|
|
1008
|
-
let tag = rawProps.tag || runtimeCore.Fragment;
|
|
1009
|
-
prevChildren = children;
|
|
1010
|
-
children = slots.default ? runtimeCore.getTransitionRawChildren(slots.default()) : [];
|
|
1011
|
-
for (let i = 0; i < children.length; i++) {
|
|
1012
|
-
const child = children[i];
|
|
1013
|
-
if (child.key != null) {
|
|
1014
|
-
runtimeCore.setTransitionHooks(child, runtimeCore.resolveTransitionHooks(child, cssTransitionProps, state, instance));
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
if (prevChildren) {
|
|
1018
|
-
for (let i = 0; i < prevChildren.length; i++) {
|
|
1019
|
-
const child = prevChildren[i];
|
|
1020
|
-
runtimeCore.setTransitionHooks(child, runtimeCore.resolveTransitionHooks(child, cssTransitionProps, state, instance));
|
|
1021
|
-
positionMap.set(child, child.el.getBoundingClientRect());
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
return runtimeCore.createVNode(tag, null, children);
|
|
1025
|
-
};
|
|
1026
|
-
}
|
|
1027
|
-
};
|
|
1028
|
-
const TransitionGroup = TransitionGroupImpl;
|
|
1029
|
-
function callPendingCbs(c) {
|
|
1030
|
-
const el = c.el;
|
|
1031
|
-
if (el._moveCb) {
|
|
1032
|
-
el._moveCb();
|
|
1033
|
-
}
|
|
1034
|
-
if (el._enterCb) {
|
|
1035
|
-
el._enterCb();
|
|
1036
|
-
}
|
|
1037
|
-
}
|
|
1038
|
-
function recordPosition(c) {
|
|
1039
|
-
newPositionMap.set(c, c.el.getBoundingClientRect());
|
|
1040
|
-
}
|
|
1041
|
-
function applyTranslation(c) {
|
|
1042
|
-
const oldPos = positionMap.get(c);
|
|
1043
|
-
const newPos = newPositionMap.get(c);
|
|
1044
|
-
const dx = oldPos.left - newPos.left;
|
|
1045
|
-
const dy = oldPos.top - newPos.top;
|
|
1046
|
-
if (dx || dy) {
|
|
1047
|
-
const s = c.el.style;
|
|
1048
|
-
s.transform = s.webkitTransform = `translate(${dx}px,${dy}px)`;
|
|
1049
|
-
s.transitionDuration = '0s';
|
|
1050
|
-
return c;
|
|
1051
|
-
}
|
|
1052
|
-
}
|
|
1053
|
-
function hasCSSTransform(el, root, moveClass) {
|
|
1054
|
-
// Detect whether an element with the move class applied has
|
|
1055
|
-
// CSS transitions. Since the element may be inside an entering
|
|
1056
|
-
// transition at this very moment, we make a clone of it and remove
|
|
1057
|
-
// all other transition classes applied to ensure only the move class
|
|
1058
|
-
// is applied.
|
|
1059
|
-
const clone = el.cloneNode();
|
|
1060
|
-
if (el._vtc) {
|
|
1061
|
-
el._vtc.forEach(cls => {
|
|
1062
|
-
cls.split(/\s+/).forEach(c => c && clone.classList.remove(c));
|
|
1063
|
-
});
|
|
1064
|
-
}
|
|
1065
|
-
moveClass.split(/\s+/).forEach(c => c && clone.classList.add(c));
|
|
1066
|
-
clone.style.display = 'none';
|
|
1067
|
-
const container = (root.nodeType === 1 ? root : root.parentNode);
|
|
1068
|
-
container.appendChild(clone);
|
|
1069
|
-
const { hasTransform } = getTransitionInfo(clone);
|
|
1070
|
-
container.removeChild(clone);
|
|
1071
|
-
return hasTransform;
|
|
925
|
+
const positionMap = new WeakMap();
|
|
926
|
+
const newPositionMap = new WeakMap();
|
|
927
|
+
const TransitionGroupImpl = {
|
|
928
|
+
name: 'TransitionGroup',
|
|
929
|
+
props: /*#__PURE__*/ shared.extend({}, TransitionPropsValidators, {
|
|
930
|
+
tag: String,
|
|
931
|
+
moveClass: String
|
|
932
|
+
}),
|
|
933
|
+
setup(props, { slots }) {
|
|
934
|
+
const instance = runtimeCore.getCurrentInstance();
|
|
935
|
+
const state = runtimeCore.useTransitionState();
|
|
936
|
+
let prevChildren;
|
|
937
|
+
let children;
|
|
938
|
+
runtimeCore.onUpdated(() => {
|
|
939
|
+
// children is guaranteed to exist after initial render
|
|
940
|
+
if (!prevChildren.length) {
|
|
941
|
+
return;
|
|
942
|
+
}
|
|
943
|
+
const moveClass = props.moveClass || `${props.name || 'v'}-move`;
|
|
944
|
+
if (!hasCSSTransform(prevChildren[0].el, instance.vnode.el, moveClass)) {
|
|
945
|
+
return;
|
|
946
|
+
}
|
|
947
|
+
// we divide the work into three loops to avoid mixing DOM reads and writes
|
|
948
|
+
// in each iteration - which helps prevent layout thrashing.
|
|
949
|
+
prevChildren.forEach(callPendingCbs);
|
|
950
|
+
prevChildren.forEach(recordPosition);
|
|
951
|
+
const movedChildren = prevChildren.filter(applyTranslation);
|
|
952
|
+
// force reflow to put everything in position
|
|
953
|
+
forceReflow();
|
|
954
|
+
movedChildren.forEach(c => {
|
|
955
|
+
const el = c.el;
|
|
956
|
+
const style = el.style;
|
|
957
|
+
addTransitionClass(el, moveClass);
|
|
958
|
+
style.transform = style.webkitTransform = style.transitionDuration = '';
|
|
959
|
+
const cb = (el._moveCb = (e) => {
|
|
960
|
+
if (e && e.target !== el) {
|
|
961
|
+
return;
|
|
962
|
+
}
|
|
963
|
+
if (!e || /transform$/.test(e.propertyName)) {
|
|
964
|
+
el.removeEventListener('transitionend', cb);
|
|
965
|
+
el._moveCb = null;
|
|
966
|
+
removeTransitionClass(el, moveClass);
|
|
967
|
+
}
|
|
968
|
+
});
|
|
969
|
+
el.addEventListener('transitionend', cb);
|
|
970
|
+
});
|
|
971
|
+
});
|
|
972
|
+
return () => {
|
|
973
|
+
const rawProps = runtimeCore.toRaw(props);
|
|
974
|
+
const cssTransitionProps = resolveTransitionProps(rawProps);
|
|
975
|
+
let tag = rawProps.tag || runtimeCore.Fragment;
|
|
976
|
+
prevChildren = children;
|
|
977
|
+
children = slots.default ? runtimeCore.getTransitionRawChildren(slots.default()) : [];
|
|
978
|
+
for (let i = 0; i < children.length; i++) {
|
|
979
|
+
const child = children[i];
|
|
980
|
+
if (child.key != null) {
|
|
981
|
+
runtimeCore.setTransitionHooks(child, runtimeCore.resolveTransitionHooks(child, cssTransitionProps, state, instance));
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
if (prevChildren) {
|
|
985
|
+
for (let i = 0; i < prevChildren.length; i++) {
|
|
986
|
+
const child = prevChildren[i];
|
|
987
|
+
runtimeCore.setTransitionHooks(child, runtimeCore.resolveTransitionHooks(child, cssTransitionProps, state, instance));
|
|
988
|
+
positionMap.set(child, child.el.getBoundingClientRect());
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
return runtimeCore.createVNode(tag, null, children);
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
};
|
|
995
|
+
const TransitionGroup = TransitionGroupImpl;
|
|
996
|
+
function callPendingCbs(c) {
|
|
997
|
+
const el = c.el;
|
|
998
|
+
if (el._moveCb) {
|
|
999
|
+
el._moveCb();
|
|
1000
|
+
}
|
|
1001
|
+
if (el._enterCb) {
|
|
1002
|
+
el._enterCb();
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
function recordPosition(c) {
|
|
1006
|
+
newPositionMap.set(c, c.el.getBoundingClientRect());
|
|
1007
|
+
}
|
|
1008
|
+
function applyTranslation(c) {
|
|
1009
|
+
const oldPos = positionMap.get(c);
|
|
1010
|
+
const newPos = newPositionMap.get(c);
|
|
1011
|
+
const dx = oldPos.left - newPos.left;
|
|
1012
|
+
const dy = oldPos.top - newPos.top;
|
|
1013
|
+
if (dx || dy) {
|
|
1014
|
+
const s = c.el.style;
|
|
1015
|
+
s.transform = s.webkitTransform = `translate(${dx}px,${dy}px)`;
|
|
1016
|
+
s.transitionDuration = '0s';
|
|
1017
|
+
return c;
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
function hasCSSTransform(el, root, moveClass) {
|
|
1021
|
+
// Detect whether an element with the move class applied has
|
|
1022
|
+
// CSS transitions. Since the element may be inside an entering
|
|
1023
|
+
// transition at this very moment, we make a clone of it and remove
|
|
1024
|
+
// all other transition classes applied to ensure only the move class
|
|
1025
|
+
// is applied.
|
|
1026
|
+
const clone = el.cloneNode();
|
|
1027
|
+
if (el._vtc) {
|
|
1028
|
+
el._vtc.forEach(cls => {
|
|
1029
|
+
cls.split(/\s+/).forEach(c => c && clone.classList.remove(c));
|
|
1030
|
+
});
|
|
1031
|
+
}
|
|
1032
|
+
moveClass.split(/\s+/).forEach(c => c && clone.classList.add(c));
|
|
1033
|
+
clone.style.display = 'none';
|
|
1034
|
+
const container = (root.nodeType === 1 ? root : root.parentNode);
|
|
1035
|
+
container.appendChild(clone);
|
|
1036
|
+
const { hasTransform } = getTransitionInfo(clone);
|
|
1037
|
+
container.removeChild(clone);
|
|
1038
|
+
return hasTransform;
|
|
1072
1039
|
}
|
|
1073
1040
|
|
|
1074
|
-
const getModelAssigner = (vnode) => {
|
|
1075
|
-
const fn = vnode.props['onUpdate:modelValue'] ||
|
|
1076
|
-
(false );
|
|
1077
|
-
return shared.isArray(fn) ? value => shared.invokeArrayFns(fn, value) : fn;
|
|
1078
|
-
};
|
|
1079
|
-
function onCompositionStart(e) {
|
|
1080
|
-
e.target.composing = true;
|
|
1081
|
-
}
|
|
1082
|
-
function onCompositionEnd(e) {
|
|
1083
|
-
const target = e.target;
|
|
1084
|
-
if (target.composing) {
|
|
1085
|
-
target.composing = false;
|
|
1086
|
-
target.dispatchEvent(new Event('input'));
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
// We are exporting the v-model runtime directly as vnode hooks so that it can
|
|
1090
|
-
// be tree-shaken in case v-model is never used.
|
|
1091
|
-
const vModelText = {
|
|
1092
|
-
created(el, { modifiers: { lazy, trim, number } }, vnode) {
|
|
1093
|
-
el._assign = getModelAssigner(vnode);
|
|
1094
|
-
const castToNumber = number || (vnode.props && vnode.props.type === 'number');
|
|
1095
|
-
addEventListener(el, lazy ? 'change' : 'input', e => {
|
|
1096
|
-
if (e.target.composing)
|
|
1097
|
-
return;
|
|
1098
|
-
let domValue = el.value;
|
|
1099
|
-
if (trim) {
|
|
1100
|
-
domValue = domValue.trim();
|
|
1101
|
-
}
|
|
1102
|
-
if (castToNumber) {
|
|
1103
|
-
domValue = shared.toNumber(domValue);
|
|
1104
|
-
}
|
|
1105
|
-
el._assign(domValue);
|
|
1106
|
-
});
|
|
1107
|
-
if (trim) {
|
|
1108
|
-
addEventListener(el, 'change', () => {
|
|
1109
|
-
el.value = el.value.trim();
|
|
1110
|
-
});
|
|
1111
|
-
}
|
|
1112
|
-
if (!lazy) {
|
|
1113
|
-
addEventListener(el, 'compositionstart', onCompositionStart);
|
|
1114
|
-
addEventListener(el, 'compositionend', onCompositionEnd);
|
|
1115
|
-
// Safari < 10.2 & UIWebView doesn't fire compositionend when
|
|
1116
|
-
// switching focus before confirming composition choice
|
|
1117
|
-
// this also fixes the issue where some browsers e.g. iOS Chrome
|
|
1118
|
-
// fires "change" instead of "input" on autocomplete.
|
|
1119
|
-
addEventListener(el, 'change', onCompositionEnd);
|
|
1120
|
-
}
|
|
1121
|
-
},
|
|
1122
|
-
// set value on mounted so it's after min/max for type="range"
|
|
1123
|
-
mounted(el, { value }) {
|
|
1124
|
-
el.value = value == null ? '' : value;
|
|
1125
|
-
},
|
|
1126
|
-
beforeUpdate(el, { value, modifiers: { lazy, trim, number } }, vnode) {
|
|
1127
|
-
el._assign = getModelAssigner(vnode);
|
|
1128
|
-
// avoid clearing unresolved text. #2302
|
|
1129
|
-
if (el.composing)
|
|
1130
|
-
return;
|
|
1131
|
-
if (document.activeElement === el && el.type !== 'range') {
|
|
1132
|
-
if (lazy) {
|
|
1133
|
-
return;
|
|
1134
|
-
}
|
|
1135
|
-
if (trim && el.value.trim() === value) {
|
|
1136
|
-
return;
|
|
1137
|
-
}
|
|
1138
|
-
if ((number || el.type === 'number') && shared.toNumber(el.value) === value) {
|
|
1139
|
-
return;
|
|
1140
|
-
}
|
|
1141
|
-
}
|
|
1142
|
-
const newValue = value == null ? '' : value;
|
|
1143
|
-
if (el.value !== newValue) {
|
|
1144
|
-
el.value = newValue;
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
};
|
|
1148
|
-
const vModelCheckbox = {
|
|
1149
|
-
// #4096 array checkboxes need to be deep traversed
|
|
1150
|
-
deep: true,
|
|
1151
|
-
created(el, _, vnode) {
|
|
1152
|
-
el._assign = getModelAssigner(vnode);
|
|
1153
|
-
addEventListener(el, 'change', () => {
|
|
1154
|
-
const modelValue = el._modelValue;
|
|
1155
|
-
const elementValue = getValue(el);
|
|
1156
|
-
const checked = el.checked;
|
|
1157
|
-
const assign = el._assign;
|
|
1158
|
-
if (shared.isArray(modelValue)) {
|
|
1159
|
-
const index = shared.looseIndexOf(modelValue, elementValue);
|
|
1160
|
-
const found = index !== -1;
|
|
1161
|
-
if (checked && !found) {
|
|
1162
|
-
assign(modelValue.concat(elementValue));
|
|
1163
|
-
}
|
|
1164
|
-
else if (!checked && found) {
|
|
1165
|
-
const filtered = [...modelValue];
|
|
1166
|
-
filtered.splice(index, 1);
|
|
1167
|
-
assign(filtered);
|
|
1168
|
-
}
|
|
1169
|
-
}
|
|
1170
|
-
else if (shared.isSet(modelValue)) {
|
|
1171
|
-
const cloned = new Set(modelValue);
|
|
1172
|
-
if (checked) {
|
|
1173
|
-
cloned.add(elementValue);
|
|
1174
|
-
}
|
|
1175
|
-
else {
|
|
1176
|
-
cloned.delete(elementValue);
|
|
1177
|
-
}
|
|
1178
|
-
assign(cloned);
|
|
1179
|
-
}
|
|
1180
|
-
else {
|
|
1181
|
-
assign(getCheckboxValue(el, checked));
|
|
1182
|
-
}
|
|
1183
|
-
});
|
|
1184
|
-
},
|
|
1185
|
-
// set initial checked on mount to wait for true-value/false-value
|
|
1186
|
-
mounted: setChecked,
|
|
1187
|
-
beforeUpdate(el, binding, vnode) {
|
|
1188
|
-
el._assign = getModelAssigner(vnode);
|
|
1189
|
-
setChecked(el, binding, vnode);
|
|
1190
|
-
}
|
|
1191
|
-
};
|
|
1192
|
-
function setChecked(el, { value, oldValue }, vnode) {
|
|
1193
|
-
el._modelValue = value;
|
|
1194
|
-
if (shared.isArray(value)) {
|
|
1195
|
-
el.checked = shared.looseIndexOf(value, vnode.props.value) > -1;
|
|
1196
|
-
}
|
|
1197
|
-
else if (shared.isSet(value)) {
|
|
1198
|
-
el.checked = value.has(vnode.props.value);
|
|
1199
|
-
}
|
|
1200
|
-
else if (value !== oldValue) {
|
|
1201
|
-
el.checked = shared.looseEqual(value, getCheckboxValue(el, true));
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
const vModelRadio = {
|
|
1205
|
-
created(el, { value }, vnode) {
|
|
1206
|
-
el.checked = shared.looseEqual(value, vnode.props.value);
|
|
1207
|
-
el._assign = getModelAssigner(vnode);
|
|
1208
|
-
addEventListener(el, 'change', () => {
|
|
1209
|
-
el._assign(getValue(el));
|
|
1210
|
-
});
|
|
1211
|
-
},
|
|
1212
|
-
beforeUpdate(el, { value, oldValue }, vnode) {
|
|
1213
|
-
el._assign = getModelAssigner(vnode);
|
|
1214
|
-
if (value !== oldValue) {
|
|
1215
|
-
el.checked = shared.looseEqual(value, vnode.props.value);
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
};
|
|
1219
|
-
const vModelSelect = {
|
|
1220
|
-
// <select multiple> value need to be deep traversed
|
|
1221
|
-
deep: true,
|
|
1222
|
-
created(el, { value, modifiers: { number } }, vnode) {
|
|
1223
|
-
const isSetModel = shared.isSet(value);
|
|
1224
|
-
addEventListener(el, 'change', () => {
|
|
1225
|
-
const selectedVal = Array.prototype.filter
|
|
1226
|
-
.call(el.options, (o) => o.selected)
|
|
1227
|
-
.map((o) => number ? shared.toNumber(getValue(o)) : getValue(o));
|
|
1228
|
-
el._assign(el.multiple
|
|
1229
|
-
? isSetModel
|
|
1230
|
-
? new Set(selectedVal)
|
|
1231
|
-
: selectedVal
|
|
1232
|
-
: selectedVal[0]);
|
|
1233
|
-
});
|
|
1234
|
-
el._assign = getModelAssigner(vnode);
|
|
1235
|
-
},
|
|
1236
|
-
// set value in mounted & updated because <select> relies on its children
|
|
1237
|
-
// <option>s.
|
|
1238
|
-
mounted(el, { value }) {
|
|
1239
|
-
setSelected(el, value);
|
|
1240
|
-
},
|
|
1241
|
-
beforeUpdate(el, _binding, vnode) {
|
|
1242
|
-
el._assign = getModelAssigner(vnode);
|
|
1243
|
-
},
|
|
1244
|
-
updated(el, { value }) {
|
|
1245
|
-
setSelected(el, value);
|
|
1246
|
-
}
|
|
1247
|
-
};
|
|
1248
|
-
function setSelected(el, value) {
|
|
1249
|
-
const isMultiple = el.multiple;
|
|
1250
|
-
if (isMultiple && !shared.isArray(value) && !shared.isSet(value)) {
|
|
1251
|
-
return;
|
|
1252
|
-
}
|
|
1253
|
-
for (let i = 0, l = el.options.length; i < l; i++) {
|
|
1254
|
-
const option = el.options[i];
|
|
1255
|
-
const optionValue = getValue(option);
|
|
1256
|
-
if (isMultiple) {
|
|
1257
|
-
if (shared.isArray(value)) {
|
|
1258
|
-
option.selected = shared.looseIndexOf(value, optionValue) > -1;
|
|
1259
|
-
}
|
|
1260
|
-
else {
|
|
1261
|
-
option.selected = value.has(optionValue);
|
|
1262
|
-
}
|
|
1263
|
-
}
|
|
1264
|
-
else {
|
|
1265
|
-
if (shared.looseEqual(getValue(option), value)) {
|
|
1266
|
-
if (el.selectedIndex !== i)
|
|
1267
|
-
el.selectedIndex = i;
|
|
1268
|
-
return;
|
|
1269
|
-
}
|
|
1270
|
-
}
|
|
1271
|
-
}
|
|
1272
|
-
if (!isMultiple && el.selectedIndex !== -1) {
|
|
1273
|
-
el.selectedIndex = -1;
|
|
1274
|
-
}
|
|
1275
|
-
}
|
|
1276
|
-
// retrieve raw value set via :value bindings
|
|
1277
|
-
function getValue(el) {
|
|
1278
|
-
return '_value' in el ? el._value : el.value;
|
|
1279
|
-
}
|
|
1280
|
-
// retrieve raw value for true-value and false-value set via :true-value or :false-value bindings
|
|
1281
|
-
function getCheckboxValue(el, checked) {
|
|
1282
|
-
const key = checked ? '_trueValue' : '_falseValue';
|
|
1283
|
-
return key in el ? el[key] : checked;
|
|
1284
|
-
}
|
|
1285
|
-
const vModelDynamic = {
|
|
1286
|
-
created(el, binding, vnode) {
|
|
1287
|
-
callModelHook(el, binding, vnode, null, 'created');
|
|
1288
|
-
},
|
|
1289
|
-
mounted(el, binding, vnode) {
|
|
1290
|
-
callModelHook(el, binding, vnode, null, 'mounted');
|
|
1291
|
-
},
|
|
1292
|
-
beforeUpdate(el, binding, vnode, prevVNode) {
|
|
1293
|
-
callModelHook(el, binding, vnode, prevVNode, 'beforeUpdate');
|
|
1294
|
-
},
|
|
1295
|
-
updated(el, binding, vnode, prevVNode) {
|
|
1296
|
-
callModelHook(el, binding, vnode, prevVNode, 'updated');
|
|
1297
|
-
}
|
|
1298
|
-
};
|
|
1299
|
-
function resolveDynamicModel(tagName, type) {
|
|
1300
|
-
switch (tagName) {
|
|
1301
|
-
case 'SELECT':
|
|
1302
|
-
return vModelSelect;
|
|
1303
|
-
case 'TEXTAREA':
|
|
1304
|
-
return vModelText;
|
|
1305
|
-
default:
|
|
1306
|
-
switch (type) {
|
|
1307
|
-
case 'checkbox':
|
|
1308
|
-
return vModelCheckbox;
|
|
1309
|
-
case 'radio':
|
|
1310
|
-
return vModelRadio;
|
|
1311
|
-
default:
|
|
1312
|
-
return vModelText;
|
|
1313
|
-
}
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
function callModelHook(el, binding, vnode, prevVNode, hook) {
|
|
1317
|
-
const modelToUse = resolveDynamicModel(el.tagName, vnode.props && vnode.props.type);
|
|
1318
|
-
const fn = modelToUse[hook];
|
|
1319
|
-
fn && fn(el, binding, vnode, prevVNode);
|
|
1320
|
-
}
|
|
1321
|
-
// SSR vnode transforms, only used when user includes client-oriented render
|
|
1322
|
-
// function in SSR
|
|
1323
|
-
function initVModelForSSR() {
|
|
1324
|
-
vModelText.getSSRProps = ({ value }) => ({ value });
|
|
1325
|
-
vModelRadio.getSSRProps = ({ value }, vnode) => {
|
|
1326
|
-
if (vnode.props && shared.looseEqual(vnode.props.value, value)) {
|
|
1327
|
-
return { checked: true };
|
|
1328
|
-
}
|
|
1329
|
-
};
|
|
1330
|
-
vModelCheckbox.getSSRProps = ({ value }, vnode) => {
|
|
1331
|
-
if (shared.isArray(value)) {
|
|
1332
|
-
if (vnode.props && shared.looseIndexOf(value, vnode.props.value) > -1) {
|
|
1333
|
-
return { checked: true };
|
|
1334
|
-
}
|
|
1335
|
-
}
|
|
1336
|
-
else if (shared.isSet(value)) {
|
|
1337
|
-
if (vnode.props && value.has(vnode.props.value)) {
|
|
1338
|
-
return { checked: true };
|
|
1339
|
-
}
|
|
1340
|
-
}
|
|
1341
|
-
else if (value) {
|
|
1342
|
-
return { checked: true };
|
|
1343
|
-
}
|
|
1344
|
-
};
|
|
1345
|
-
vModelDynamic.getSSRProps = (binding, vnode) => {
|
|
1346
|
-
if (typeof vnode.type !== 'string') {
|
|
1347
|
-
return;
|
|
1348
|
-
}
|
|
1349
|
-
const modelToUse = resolveDynamicModel(
|
|
1350
|
-
// resolveDynamicModel expects an uppercase tag name, but vnode.type is lowercase
|
|
1351
|
-
vnode.type.toUpperCase(), vnode.props && vnode.props.type);
|
|
1352
|
-
if (modelToUse.getSSRProps) {
|
|
1353
|
-
return modelToUse.getSSRProps(binding, vnode);
|
|
1354
|
-
}
|
|
1355
|
-
};
|
|
1041
|
+
const getModelAssigner = (vnode) => {
|
|
1042
|
+
const fn = vnode.props['onUpdate:modelValue'] ||
|
|
1043
|
+
(false );
|
|
1044
|
+
return shared.isArray(fn) ? value => shared.invokeArrayFns(fn, value) : fn;
|
|
1045
|
+
};
|
|
1046
|
+
function onCompositionStart(e) {
|
|
1047
|
+
e.target.composing = true;
|
|
1048
|
+
}
|
|
1049
|
+
function onCompositionEnd(e) {
|
|
1050
|
+
const target = e.target;
|
|
1051
|
+
if (target.composing) {
|
|
1052
|
+
target.composing = false;
|
|
1053
|
+
target.dispatchEvent(new Event('input'));
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
// We are exporting the v-model runtime directly as vnode hooks so that it can
|
|
1057
|
+
// be tree-shaken in case v-model is never used.
|
|
1058
|
+
const vModelText = {
|
|
1059
|
+
created(el, { modifiers: { lazy, trim, number } }, vnode) {
|
|
1060
|
+
el._assign = getModelAssigner(vnode);
|
|
1061
|
+
const castToNumber = number || (vnode.props && vnode.props.type === 'number');
|
|
1062
|
+
addEventListener(el, lazy ? 'change' : 'input', e => {
|
|
1063
|
+
if (e.target.composing)
|
|
1064
|
+
return;
|
|
1065
|
+
let domValue = el.value;
|
|
1066
|
+
if (trim) {
|
|
1067
|
+
domValue = domValue.trim();
|
|
1068
|
+
}
|
|
1069
|
+
if (castToNumber) {
|
|
1070
|
+
domValue = shared.toNumber(domValue);
|
|
1071
|
+
}
|
|
1072
|
+
el._assign(domValue);
|
|
1073
|
+
});
|
|
1074
|
+
if (trim) {
|
|
1075
|
+
addEventListener(el, 'change', () => {
|
|
1076
|
+
el.value = el.value.trim();
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1079
|
+
if (!lazy) {
|
|
1080
|
+
addEventListener(el, 'compositionstart', onCompositionStart);
|
|
1081
|
+
addEventListener(el, 'compositionend', onCompositionEnd);
|
|
1082
|
+
// Safari < 10.2 & UIWebView doesn't fire compositionend when
|
|
1083
|
+
// switching focus before confirming composition choice
|
|
1084
|
+
// this also fixes the issue where some browsers e.g. iOS Chrome
|
|
1085
|
+
// fires "change" instead of "input" on autocomplete.
|
|
1086
|
+
addEventListener(el, 'change', onCompositionEnd);
|
|
1087
|
+
}
|
|
1088
|
+
},
|
|
1089
|
+
// set value on mounted so it's after min/max for type="range"
|
|
1090
|
+
mounted(el, { value }) {
|
|
1091
|
+
el.value = value == null ? '' : value;
|
|
1092
|
+
},
|
|
1093
|
+
beforeUpdate(el, { value, modifiers: { lazy, trim, number } }, vnode) {
|
|
1094
|
+
el._assign = getModelAssigner(vnode);
|
|
1095
|
+
// avoid clearing unresolved text. #2302
|
|
1096
|
+
if (el.composing)
|
|
1097
|
+
return;
|
|
1098
|
+
if (document.activeElement === el && el.type !== 'range') {
|
|
1099
|
+
if (lazy) {
|
|
1100
|
+
return;
|
|
1101
|
+
}
|
|
1102
|
+
if (trim && el.value.trim() === value) {
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
1105
|
+
if ((number || el.type === 'number') && shared.toNumber(el.value) === value) {
|
|
1106
|
+
return;
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
const newValue = value == null ? '' : value;
|
|
1110
|
+
if (el.value !== newValue) {
|
|
1111
|
+
el.value = newValue;
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
};
|
|
1115
|
+
const vModelCheckbox = {
|
|
1116
|
+
// #4096 array checkboxes need to be deep traversed
|
|
1117
|
+
deep: true,
|
|
1118
|
+
created(el, _, vnode) {
|
|
1119
|
+
el._assign = getModelAssigner(vnode);
|
|
1120
|
+
addEventListener(el, 'change', () => {
|
|
1121
|
+
const modelValue = el._modelValue;
|
|
1122
|
+
const elementValue = getValue(el);
|
|
1123
|
+
const checked = el.checked;
|
|
1124
|
+
const assign = el._assign;
|
|
1125
|
+
if (shared.isArray(modelValue)) {
|
|
1126
|
+
const index = shared.looseIndexOf(modelValue, elementValue);
|
|
1127
|
+
const found = index !== -1;
|
|
1128
|
+
if (checked && !found) {
|
|
1129
|
+
assign(modelValue.concat(elementValue));
|
|
1130
|
+
}
|
|
1131
|
+
else if (!checked && found) {
|
|
1132
|
+
const filtered = [...modelValue];
|
|
1133
|
+
filtered.splice(index, 1);
|
|
1134
|
+
assign(filtered);
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
else if (shared.isSet(modelValue)) {
|
|
1138
|
+
const cloned = new Set(modelValue);
|
|
1139
|
+
if (checked) {
|
|
1140
|
+
cloned.add(elementValue);
|
|
1141
|
+
}
|
|
1142
|
+
else {
|
|
1143
|
+
cloned.delete(elementValue);
|
|
1144
|
+
}
|
|
1145
|
+
assign(cloned);
|
|
1146
|
+
}
|
|
1147
|
+
else {
|
|
1148
|
+
assign(getCheckboxValue(el, checked));
|
|
1149
|
+
}
|
|
1150
|
+
});
|
|
1151
|
+
},
|
|
1152
|
+
// set initial checked on mount to wait for true-value/false-value
|
|
1153
|
+
mounted: setChecked,
|
|
1154
|
+
beforeUpdate(el, binding, vnode) {
|
|
1155
|
+
el._assign = getModelAssigner(vnode);
|
|
1156
|
+
setChecked(el, binding, vnode);
|
|
1157
|
+
}
|
|
1158
|
+
};
|
|
1159
|
+
function setChecked(el, { value, oldValue }, vnode) {
|
|
1160
|
+
el._modelValue = value;
|
|
1161
|
+
if (shared.isArray(value)) {
|
|
1162
|
+
el.checked = shared.looseIndexOf(value, vnode.props.value) > -1;
|
|
1163
|
+
}
|
|
1164
|
+
else if (shared.isSet(value)) {
|
|
1165
|
+
el.checked = value.has(vnode.props.value);
|
|
1166
|
+
}
|
|
1167
|
+
else if (value !== oldValue) {
|
|
1168
|
+
el.checked = shared.looseEqual(value, getCheckboxValue(el, true));
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
const vModelRadio = {
|
|
1172
|
+
created(el, { value }, vnode) {
|
|
1173
|
+
el.checked = shared.looseEqual(value, vnode.props.value);
|
|
1174
|
+
el._assign = getModelAssigner(vnode);
|
|
1175
|
+
addEventListener(el, 'change', () => {
|
|
1176
|
+
el._assign(getValue(el));
|
|
1177
|
+
});
|
|
1178
|
+
},
|
|
1179
|
+
beforeUpdate(el, { value, oldValue }, vnode) {
|
|
1180
|
+
el._assign = getModelAssigner(vnode);
|
|
1181
|
+
if (value !== oldValue) {
|
|
1182
|
+
el.checked = shared.looseEqual(value, vnode.props.value);
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
};
|
|
1186
|
+
const vModelSelect = {
|
|
1187
|
+
// <select multiple> value need to be deep traversed
|
|
1188
|
+
deep: true,
|
|
1189
|
+
created(el, { value, modifiers: { number } }, vnode) {
|
|
1190
|
+
const isSetModel = shared.isSet(value);
|
|
1191
|
+
addEventListener(el, 'change', () => {
|
|
1192
|
+
const selectedVal = Array.prototype.filter
|
|
1193
|
+
.call(el.options, (o) => o.selected)
|
|
1194
|
+
.map((o) => number ? shared.toNumber(getValue(o)) : getValue(o));
|
|
1195
|
+
el._assign(el.multiple
|
|
1196
|
+
? isSetModel
|
|
1197
|
+
? new Set(selectedVal)
|
|
1198
|
+
: selectedVal
|
|
1199
|
+
: selectedVal[0]);
|
|
1200
|
+
});
|
|
1201
|
+
el._assign = getModelAssigner(vnode);
|
|
1202
|
+
},
|
|
1203
|
+
// set value in mounted & updated because <select> relies on its children
|
|
1204
|
+
// <option>s.
|
|
1205
|
+
mounted(el, { value }) {
|
|
1206
|
+
setSelected(el, value);
|
|
1207
|
+
},
|
|
1208
|
+
beforeUpdate(el, _binding, vnode) {
|
|
1209
|
+
el._assign = getModelAssigner(vnode);
|
|
1210
|
+
},
|
|
1211
|
+
updated(el, { value }) {
|
|
1212
|
+
setSelected(el, value);
|
|
1213
|
+
}
|
|
1214
|
+
};
|
|
1215
|
+
function setSelected(el, value) {
|
|
1216
|
+
const isMultiple = el.multiple;
|
|
1217
|
+
if (isMultiple && !shared.isArray(value) && !shared.isSet(value)) {
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1220
|
+
for (let i = 0, l = el.options.length; i < l; i++) {
|
|
1221
|
+
const option = el.options[i];
|
|
1222
|
+
const optionValue = getValue(option);
|
|
1223
|
+
if (isMultiple) {
|
|
1224
|
+
if (shared.isArray(value)) {
|
|
1225
|
+
option.selected = shared.looseIndexOf(value, optionValue) > -1;
|
|
1226
|
+
}
|
|
1227
|
+
else {
|
|
1228
|
+
option.selected = value.has(optionValue);
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
else {
|
|
1232
|
+
if (shared.looseEqual(getValue(option), value)) {
|
|
1233
|
+
if (el.selectedIndex !== i)
|
|
1234
|
+
el.selectedIndex = i;
|
|
1235
|
+
return;
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
if (!isMultiple && el.selectedIndex !== -1) {
|
|
1240
|
+
el.selectedIndex = -1;
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
// retrieve raw value set via :value bindings
|
|
1244
|
+
function getValue(el) {
|
|
1245
|
+
return '_value' in el ? el._value : el.value;
|
|
1246
|
+
}
|
|
1247
|
+
// retrieve raw value for true-value and false-value set via :true-value or :false-value bindings
|
|
1248
|
+
function getCheckboxValue(el, checked) {
|
|
1249
|
+
const key = checked ? '_trueValue' : '_falseValue';
|
|
1250
|
+
return key in el ? el[key] : checked;
|
|
1251
|
+
}
|
|
1252
|
+
const vModelDynamic = {
|
|
1253
|
+
created(el, binding, vnode) {
|
|
1254
|
+
callModelHook(el, binding, vnode, null, 'created');
|
|
1255
|
+
},
|
|
1256
|
+
mounted(el, binding, vnode) {
|
|
1257
|
+
callModelHook(el, binding, vnode, null, 'mounted');
|
|
1258
|
+
},
|
|
1259
|
+
beforeUpdate(el, binding, vnode, prevVNode) {
|
|
1260
|
+
callModelHook(el, binding, vnode, prevVNode, 'beforeUpdate');
|
|
1261
|
+
},
|
|
1262
|
+
updated(el, binding, vnode, prevVNode) {
|
|
1263
|
+
callModelHook(el, binding, vnode, prevVNode, 'updated');
|
|
1264
|
+
}
|
|
1265
|
+
};
|
|
1266
|
+
function resolveDynamicModel(tagName, type) {
|
|
1267
|
+
switch (tagName) {
|
|
1268
|
+
case 'SELECT':
|
|
1269
|
+
return vModelSelect;
|
|
1270
|
+
case 'TEXTAREA':
|
|
1271
|
+
return vModelText;
|
|
1272
|
+
default:
|
|
1273
|
+
switch (type) {
|
|
1274
|
+
case 'checkbox':
|
|
1275
|
+
return vModelCheckbox;
|
|
1276
|
+
case 'radio':
|
|
1277
|
+
return vModelRadio;
|
|
1278
|
+
default:
|
|
1279
|
+
return vModelText;
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
function callModelHook(el, binding, vnode, prevVNode, hook) {
|
|
1284
|
+
const modelToUse = resolveDynamicModel(el.tagName, vnode.props && vnode.props.type);
|
|
1285
|
+
const fn = modelToUse[hook];
|
|
1286
|
+
fn && fn(el, binding, vnode, prevVNode);
|
|
1287
|
+
}
|
|
1288
|
+
// SSR vnode transforms, only used when user includes client-oriented render
|
|
1289
|
+
// function in SSR
|
|
1290
|
+
function initVModelForSSR() {
|
|
1291
|
+
vModelText.getSSRProps = ({ value }) => ({ value });
|
|
1292
|
+
vModelRadio.getSSRProps = ({ value }, vnode) => {
|
|
1293
|
+
if (vnode.props && shared.looseEqual(vnode.props.value, value)) {
|
|
1294
|
+
return { checked: true };
|
|
1295
|
+
}
|
|
1296
|
+
};
|
|
1297
|
+
vModelCheckbox.getSSRProps = ({ value }, vnode) => {
|
|
1298
|
+
if (shared.isArray(value)) {
|
|
1299
|
+
if (vnode.props && shared.looseIndexOf(value, vnode.props.value) > -1) {
|
|
1300
|
+
return { checked: true };
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
else if (shared.isSet(value)) {
|
|
1304
|
+
if (vnode.props && value.has(vnode.props.value)) {
|
|
1305
|
+
return { checked: true };
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
else if (value) {
|
|
1309
|
+
return { checked: true };
|
|
1310
|
+
}
|
|
1311
|
+
};
|
|
1312
|
+
vModelDynamic.getSSRProps = (binding, vnode) => {
|
|
1313
|
+
if (typeof vnode.type !== 'string') {
|
|
1314
|
+
return;
|
|
1315
|
+
}
|
|
1316
|
+
const modelToUse = resolveDynamicModel(
|
|
1317
|
+
// resolveDynamicModel expects an uppercase tag name, but vnode.type is lowercase
|
|
1318
|
+
vnode.type.toUpperCase(), vnode.props && vnode.props.type);
|
|
1319
|
+
if (modelToUse.getSSRProps) {
|
|
1320
|
+
return modelToUse.getSSRProps(binding, vnode);
|
|
1321
|
+
}
|
|
1322
|
+
};
|
|
1356
1323
|
}
|
|
1357
1324
|
|
|
1358
|
-
const systemModifiers = ['ctrl', 'shift', 'alt', 'meta'];
|
|
1359
|
-
const modifierGuards = {
|
|
1360
|
-
stop: e => e.stopPropagation(),
|
|
1361
|
-
prevent: e => e.preventDefault(),
|
|
1362
|
-
self: e => e.target !== e.currentTarget,
|
|
1363
|
-
ctrl: e => !e.ctrlKey,
|
|
1364
|
-
shift: e => !e.shiftKey,
|
|
1365
|
-
alt: e => !e.altKey,
|
|
1366
|
-
meta: e => !e.metaKey,
|
|
1367
|
-
left: e => 'button' in e && e.button !== 0,
|
|
1368
|
-
middle: e => 'button' in e && e.button !== 1,
|
|
1369
|
-
right: e => 'button' in e && e.button !== 2,
|
|
1370
|
-
exact: (e, modifiers) => systemModifiers.some(m => e[`${m}Key`] && !modifiers.includes(m))
|
|
1371
|
-
};
|
|
1372
|
-
/**
|
|
1373
|
-
* @private
|
|
1374
|
-
*/
|
|
1375
|
-
const withModifiers = (fn, modifiers) => {
|
|
1376
|
-
return (event, ...args) => {
|
|
1377
|
-
for (let i = 0; i < modifiers.length; i++) {
|
|
1378
|
-
const guard = modifierGuards[modifiers[i]];
|
|
1379
|
-
if (guard && guard(event, modifiers))
|
|
1380
|
-
return;
|
|
1381
|
-
}
|
|
1382
|
-
return fn(event, ...args);
|
|
1383
|
-
};
|
|
1384
|
-
};
|
|
1385
|
-
// Kept for 2.x compat.
|
|
1386
|
-
// Note: IE11 compat for `spacebar` and `del` is removed for now.
|
|
1387
|
-
const keyNames = {
|
|
1388
|
-
esc: 'escape',
|
|
1389
|
-
space: ' ',
|
|
1390
|
-
up: 'arrow-up',
|
|
1391
|
-
left: 'arrow-left',
|
|
1392
|
-
right: 'arrow-right',
|
|
1393
|
-
down: 'arrow-down',
|
|
1394
|
-
delete: 'backspace'
|
|
1395
|
-
};
|
|
1396
|
-
/**
|
|
1397
|
-
* @private
|
|
1398
|
-
*/
|
|
1399
|
-
const withKeys = (fn, modifiers) => {
|
|
1400
|
-
return (event) => {
|
|
1401
|
-
if (!('key' in event)) {
|
|
1402
|
-
return;
|
|
1403
|
-
}
|
|
1404
|
-
const eventKey = shared.hyphenate(event.key);
|
|
1405
|
-
if (modifiers.some(k => k === eventKey || keyNames[k] === eventKey)) {
|
|
1406
|
-
return fn(event);
|
|
1407
|
-
}
|
|
1408
|
-
};
|
|
1325
|
+
const systemModifiers = ['ctrl', 'shift', 'alt', 'meta'];
|
|
1326
|
+
const modifierGuards = {
|
|
1327
|
+
stop: e => e.stopPropagation(),
|
|
1328
|
+
prevent: e => e.preventDefault(),
|
|
1329
|
+
self: e => e.target !== e.currentTarget,
|
|
1330
|
+
ctrl: e => !e.ctrlKey,
|
|
1331
|
+
shift: e => !e.shiftKey,
|
|
1332
|
+
alt: e => !e.altKey,
|
|
1333
|
+
meta: e => !e.metaKey,
|
|
1334
|
+
left: e => 'button' in e && e.button !== 0,
|
|
1335
|
+
middle: e => 'button' in e && e.button !== 1,
|
|
1336
|
+
right: e => 'button' in e && e.button !== 2,
|
|
1337
|
+
exact: (e, modifiers) => systemModifiers.some(m => e[`${m}Key`] && !modifiers.includes(m))
|
|
1338
|
+
};
|
|
1339
|
+
/**
|
|
1340
|
+
* @private
|
|
1341
|
+
*/
|
|
1342
|
+
const withModifiers = (fn, modifiers) => {
|
|
1343
|
+
return (event, ...args) => {
|
|
1344
|
+
for (let i = 0; i < modifiers.length; i++) {
|
|
1345
|
+
const guard = modifierGuards[modifiers[i]];
|
|
1346
|
+
if (guard && guard(event, modifiers))
|
|
1347
|
+
return;
|
|
1348
|
+
}
|
|
1349
|
+
return fn(event, ...args);
|
|
1350
|
+
};
|
|
1351
|
+
};
|
|
1352
|
+
// Kept for 2.x compat.
|
|
1353
|
+
// Note: IE11 compat for `spacebar` and `del` is removed for now.
|
|
1354
|
+
const keyNames = {
|
|
1355
|
+
esc: 'escape',
|
|
1356
|
+
space: ' ',
|
|
1357
|
+
up: 'arrow-up',
|
|
1358
|
+
left: 'arrow-left',
|
|
1359
|
+
right: 'arrow-right',
|
|
1360
|
+
down: 'arrow-down',
|
|
1361
|
+
delete: 'backspace'
|
|
1362
|
+
};
|
|
1363
|
+
/**
|
|
1364
|
+
* @private
|
|
1365
|
+
*/
|
|
1366
|
+
const withKeys = (fn, modifiers) => {
|
|
1367
|
+
return (event) => {
|
|
1368
|
+
if (!('key' in event)) {
|
|
1369
|
+
return;
|
|
1370
|
+
}
|
|
1371
|
+
const eventKey = shared.hyphenate(event.key);
|
|
1372
|
+
if (modifiers.some(k => k === eventKey || keyNames[k] === eventKey)) {
|
|
1373
|
+
return fn(event);
|
|
1374
|
+
}
|
|
1375
|
+
};
|
|
1409
1376
|
};
|
|
1410
1377
|
|
|
1411
|
-
const vShow = {
|
|
1412
|
-
beforeMount(el, { value }, { transition }) {
|
|
1413
|
-
el._vod = el.style.display === 'none' ? '' : el.style.display;
|
|
1414
|
-
if (transition && value) {
|
|
1415
|
-
transition.beforeEnter(el);
|
|
1416
|
-
}
|
|
1417
|
-
else {
|
|
1418
|
-
setDisplay(el, value);
|
|
1419
|
-
}
|
|
1420
|
-
},
|
|
1421
|
-
mounted(el, { value }, { transition }) {
|
|
1422
|
-
if (transition && value) {
|
|
1423
|
-
transition.enter(el);
|
|
1424
|
-
}
|
|
1425
|
-
},
|
|
1426
|
-
updated(el, { value, oldValue }, { transition }) {
|
|
1427
|
-
if (!value === !oldValue)
|
|
1428
|
-
return;
|
|
1429
|
-
if (transition) {
|
|
1430
|
-
if (value) {
|
|
1431
|
-
transition.beforeEnter(el);
|
|
1432
|
-
setDisplay(el, true);
|
|
1433
|
-
transition.enter(el);
|
|
1434
|
-
}
|
|
1435
|
-
else {
|
|
1436
|
-
transition.leave(el, () => {
|
|
1437
|
-
setDisplay(el, false);
|
|
1438
|
-
});
|
|
1439
|
-
}
|
|
1440
|
-
}
|
|
1441
|
-
else {
|
|
1442
|
-
setDisplay(el, value);
|
|
1443
|
-
}
|
|
1444
|
-
},
|
|
1445
|
-
beforeUnmount(el, { value }) {
|
|
1446
|
-
setDisplay(el, value);
|
|
1447
|
-
}
|
|
1448
|
-
};
|
|
1449
|
-
function setDisplay(el, value) {
|
|
1450
|
-
el.style.display = value ? el._vod : 'none';
|
|
1451
|
-
}
|
|
1452
|
-
// SSR vnode transforms, only used when user includes client-oriented render
|
|
1453
|
-
// function in SSR
|
|
1454
|
-
function initVShowForSSR() {
|
|
1455
|
-
vShow.getSSRProps = ({ value }) => {
|
|
1456
|
-
if (!value) {
|
|
1457
|
-
return { style: { display: 'none' } };
|
|
1458
|
-
}
|
|
1459
|
-
};
|
|
1378
|
+
const vShow = {
|
|
1379
|
+
beforeMount(el, { value }, { transition }) {
|
|
1380
|
+
el._vod = el.style.display === 'none' ? '' : el.style.display;
|
|
1381
|
+
if (transition && value) {
|
|
1382
|
+
transition.beforeEnter(el);
|
|
1383
|
+
}
|
|
1384
|
+
else {
|
|
1385
|
+
setDisplay(el, value);
|
|
1386
|
+
}
|
|
1387
|
+
},
|
|
1388
|
+
mounted(el, { value }, { transition }) {
|
|
1389
|
+
if (transition && value) {
|
|
1390
|
+
transition.enter(el);
|
|
1391
|
+
}
|
|
1392
|
+
},
|
|
1393
|
+
updated(el, { value, oldValue }, { transition }) {
|
|
1394
|
+
if (!value === !oldValue)
|
|
1395
|
+
return;
|
|
1396
|
+
if (transition) {
|
|
1397
|
+
if (value) {
|
|
1398
|
+
transition.beforeEnter(el);
|
|
1399
|
+
setDisplay(el, true);
|
|
1400
|
+
transition.enter(el);
|
|
1401
|
+
}
|
|
1402
|
+
else {
|
|
1403
|
+
transition.leave(el, () => {
|
|
1404
|
+
setDisplay(el, false);
|
|
1405
|
+
});
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
else {
|
|
1409
|
+
setDisplay(el, value);
|
|
1410
|
+
}
|
|
1411
|
+
},
|
|
1412
|
+
beforeUnmount(el, { value }) {
|
|
1413
|
+
setDisplay(el, value);
|
|
1414
|
+
}
|
|
1415
|
+
};
|
|
1416
|
+
function setDisplay(el, value) {
|
|
1417
|
+
el.style.display = value ? el._vod : 'none';
|
|
1418
|
+
}
|
|
1419
|
+
// SSR vnode transforms, only used when user includes client-oriented render
|
|
1420
|
+
// function in SSR
|
|
1421
|
+
function initVShowForSSR() {
|
|
1422
|
+
vShow.getSSRProps = ({ value }) => {
|
|
1423
|
+
if (!value) {
|
|
1424
|
+
return { style: { display: 'none' } };
|
|
1425
|
+
}
|
|
1426
|
+
};
|
|
1460
1427
|
}
|
|
1461
1428
|
|
|
1462
|
-
const rendererOptions = /*#__PURE__*/ shared.extend({ patchProp }, nodeOps);
|
|
1463
|
-
// lazy create the renderer - this makes core renderer logic tree-shakable
|
|
1464
|
-
// in case the user only imports reactivity utilities from Vue.
|
|
1465
|
-
let renderer;
|
|
1466
|
-
let enabledHydration = false;
|
|
1467
|
-
function ensureRenderer() {
|
|
1468
|
-
return (renderer ||
|
|
1469
|
-
(renderer = runtimeCore.createRenderer(rendererOptions)));
|
|
1470
|
-
}
|
|
1471
|
-
function ensureHydrationRenderer() {
|
|
1472
|
-
renderer = enabledHydration
|
|
1473
|
-
? renderer
|
|
1474
|
-
: runtimeCore.createHydrationRenderer(rendererOptions);
|
|
1475
|
-
enabledHydration = true;
|
|
1476
|
-
return renderer;
|
|
1477
|
-
}
|
|
1478
|
-
// use explicit type casts here to avoid import() calls in rolled-up d.ts
|
|
1479
|
-
const render = ((...args) => {
|
|
1480
|
-
ensureRenderer().render(...args);
|
|
1481
|
-
});
|
|
1482
|
-
const hydrate = ((...args) => {
|
|
1483
|
-
ensureHydrationRenderer().hydrate(...args);
|
|
1484
|
-
});
|
|
1485
|
-
const createApp = ((...args) => {
|
|
1486
|
-
const app = ensureRenderer().createApp(...args);
|
|
1487
|
-
const { mount } = app;
|
|
1488
|
-
app.mount = (containerOrSelector) => {
|
|
1489
|
-
const container = normalizeContainer(containerOrSelector);
|
|
1490
|
-
if (!container)
|
|
1491
|
-
return;
|
|
1492
|
-
const component = app._component;
|
|
1493
|
-
if (!shared.isFunction(component) && !component.render && !component.template) {
|
|
1494
|
-
// __UNSAFE__
|
|
1495
|
-
// Reason: potential execution of JS expressions in in-DOM template.
|
|
1496
|
-
// The user must make sure the in-DOM template is trusted. If it's
|
|
1497
|
-
// rendered by the server, the template should not contain any user data.
|
|
1498
|
-
component.template = container.innerHTML;
|
|
1499
|
-
}
|
|
1500
|
-
// clear content before mounting
|
|
1501
|
-
container.innerHTML = '';
|
|
1502
|
-
const proxy = mount(container, false, container instanceof SVGElement);
|
|
1503
|
-
if (container instanceof Element) {
|
|
1504
|
-
container.removeAttribute('v-cloak');
|
|
1505
|
-
container.setAttribute('data-v-app', '');
|
|
1506
|
-
}
|
|
1507
|
-
return proxy;
|
|
1508
|
-
};
|
|
1509
|
-
return app;
|
|
1510
|
-
});
|
|
1511
|
-
const createSSRApp = ((...args) => {
|
|
1512
|
-
const app = ensureHydrationRenderer().createApp(...args);
|
|
1513
|
-
const { mount } = app;
|
|
1514
|
-
app.mount = (containerOrSelector) => {
|
|
1515
|
-
const container = normalizeContainer(containerOrSelector);
|
|
1516
|
-
if (container) {
|
|
1517
|
-
return mount(container, true, container instanceof SVGElement);
|
|
1518
|
-
}
|
|
1519
|
-
};
|
|
1520
|
-
return app;
|
|
1521
|
-
});
|
|
1522
|
-
function normalizeContainer(container) {
|
|
1523
|
-
if (shared.isString(container)) {
|
|
1524
|
-
const res = document.querySelector(container);
|
|
1525
|
-
return res;
|
|
1526
|
-
}
|
|
1527
|
-
return container;
|
|
1528
|
-
}
|
|
1529
|
-
let ssrDirectiveInitialized = false;
|
|
1530
|
-
/**
|
|
1531
|
-
* @internal
|
|
1532
|
-
*/
|
|
1533
|
-
const initDirectivesForSSR = () => {
|
|
1534
|
-
if (!ssrDirectiveInitialized) {
|
|
1535
|
-
ssrDirectiveInitialized = true;
|
|
1536
|
-
initVModelForSSR();
|
|
1537
|
-
initVShowForSSR();
|
|
1538
|
-
}
|
|
1539
|
-
}
|
|
1429
|
+
const rendererOptions = /*#__PURE__*/ shared.extend({ patchProp }, nodeOps);
|
|
1430
|
+
// lazy create the renderer - this makes core renderer logic tree-shakable
|
|
1431
|
+
// in case the user only imports reactivity utilities from Vue.
|
|
1432
|
+
let renderer;
|
|
1433
|
+
let enabledHydration = false;
|
|
1434
|
+
function ensureRenderer() {
|
|
1435
|
+
return (renderer ||
|
|
1436
|
+
(renderer = runtimeCore.createRenderer(rendererOptions)));
|
|
1437
|
+
}
|
|
1438
|
+
function ensureHydrationRenderer() {
|
|
1439
|
+
renderer = enabledHydration
|
|
1440
|
+
? renderer
|
|
1441
|
+
: runtimeCore.createHydrationRenderer(rendererOptions);
|
|
1442
|
+
enabledHydration = true;
|
|
1443
|
+
return renderer;
|
|
1444
|
+
}
|
|
1445
|
+
// use explicit type casts here to avoid import() calls in rolled-up d.ts
|
|
1446
|
+
const render = ((...args) => {
|
|
1447
|
+
ensureRenderer().render(...args);
|
|
1448
|
+
});
|
|
1449
|
+
const hydrate = ((...args) => {
|
|
1450
|
+
ensureHydrationRenderer().hydrate(...args);
|
|
1451
|
+
});
|
|
1452
|
+
const createApp = ((...args) => {
|
|
1453
|
+
const app = ensureRenderer().createApp(...args);
|
|
1454
|
+
const { mount } = app;
|
|
1455
|
+
app.mount = (containerOrSelector) => {
|
|
1456
|
+
const container = normalizeContainer(containerOrSelector);
|
|
1457
|
+
if (!container)
|
|
1458
|
+
return;
|
|
1459
|
+
const component = app._component;
|
|
1460
|
+
if (!shared.isFunction(component) && !component.render && !component.template) {
|
|
1461
|
+
// __UNSAFE__
|
|
1462
|
+
// Reason: potential execution of JS expressions in in-DOM template.
|
|
1463
|
+
// The user must make sure the in-DOM template is trusted. If it's
|
|
1464
|
+
// rendered by the server, the template should not contain any user data.
|
|
1465
|
+
component.template = container.innerHTML;
|
|
1466
|
+
}
|
|
1467
|
+
// clear content before mounting
|
|
1468
|
+
container.innerHTML = '';
|
|
1469
|
+
const proxy = mount(container, false, container instanceof SVGElement);
|
|
1470
|
+
if (container instanceof Element) {
|
|
1471
|
+
container.removeAttribute('v-cloak');
|
|
1472
|
+
container.setAttribute('data-v-app', '');
|
|
1473
|
+
}
|
|
1474
|
+
return proxy;
|
|
1475
|
+
};
|
|
1476
|
+
return app;
|
|
1477
|
+
});
|
|
1478
|
+
const createSSRApp = ((...args) => {
|
|
1479
|
+
const app = ensureHydrationRenderer().createApp(...args);
|
|
1480
|
+
const { mount } = app;
|
|
1481
|
+
app.mount = (containerOrSelector) => {
|
|
1482
|
+
const container = normalizeContainer(containerOrSelector);
|
|
1483
|
+
if (container) {
|
|
1484
|
+
return mount(container, true, container instanceof SVGElement);
|
|
1485
|
+
}
|
|
1486
|
+
};
|
|
1487
|
+
return app;
|
|
1488
|
+
});
|
|
1489
|
+
function normalizeContainer(container) {
|
|
1490
|
+
if (shared.isString(container)) {
|
|
1491
|
+
const res = document.querySelector(container);
|
|
1492
|
+
return res;
|
|
1493
|
+
}
|
|
1494
|
+
return container;
|
|
1495
|
+
}
|
|
1496
|
+
let ssrDirectiveInitialized = false;
|
|
1497
|
+
/**
|
|
1498
|
+
* @internal
|
|
1499
|
+
*/
|
|
1500
|
+
const initDirectivesForSSR = () => {
|
|
1501
|
+
if (!ssrDirectiveInitialized) {
|
|
1502
|
+
ssrDirectiveInitialized = true;
|
|
1503
|
+
initVModelForSSR();
|
|
1504
|
+
initVShowForSSR();
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1540
1507
|
;
|
|
1541
1508
|
|
|
1542
1509
|
Object.keys(runtimeCore).forEach(function (k) {
|