1var Vue = (function (exports) { 2 'use strict'; 3 4 /** 5 * Make a map and return a function for checking if a key 6 * is in that map. 7 * IMPORTANT: all calls of this function must be prefixed with 8 * \/\*#\_\_PURE\_\_\*\/ 9 * So that rollup can tree-shake them if necessary. 10 */ 11 function makeMap(str, expectsLowerCase) { 12 const map = Object.create(null); 13 const list = str.split(','); 14 for (let i = 0; i < list.length; i++) { 15 map[list[i]] = true; 16 } 17 return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val]; 18 } 19 20 /** 21 * dev only flag -> name mapping 22 */ 23 const PatchFlagNames = { 24 [1 /* PatchFlags.TEXT */]: `TEXT`, 25 [2 /* PatchFlags.CLASS */]: `CLASS`, 26 [4 /* PatchFlags.STYLE */]: `STYLE`, 27 [8 /* PatchFlags.PROPS */]: `PROPS`, 28 [16 /* PatchFlags.FULL_PROPS */]: `FULL_PROPS`, 29 [32 /* PatchFlags.HYDRATE_EVENTS */]: `HYDRATE_EVENTS`, 30 [64 /* PatchFlags.STABLE_FRAGMENT */]: `STABLE_FRAGMENT`, 31 [128 /* PatchFlags.KEYED_FRAGMENT */]: `KEYED_FRAGMENT`, 32 [256 /* PatchFlags.UNKEYED_FRAGMENT */]: `UNKEYED_FRAGMENT`, 33 [512 /* PatchFlags.NEED_PATCH */]: `NEED_PATCH`, 34 [1024 /* PatchFlags.DYNAMIC_SLOTS */]: `DYNAMIC_SLOTS`, 35 [2048 /* PatchFlags.DEV_ROOT_FRAGMENT */]: `DEV_ROOT_FRAGMENT`, 36 [-1 /* PatchFlags.HOISTED */]: `HOISTED`, 37 [-2 /* PatchFlags.BAIL */]: `BAIL` 38 }; 39 40 /** 41 * Dev only 42 */ 43 const slotFlagsText = { 44 [1 /* SlotFlags.STABLE */]: 'STABLE', 45 [2 /* SlotFlags.DYNAMIC */]: 'DYNAMIC', 46 [3 /* SlotFlags.FORWARDED */]: 'FORWARDED' 47 }; 48 49 const GLOBALS_WHITE_LISTED = 'Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,' + 50 'decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,' + 51 'Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt'; 52 const isGloballyWhitelisted = /*#__PURE__*/ makeMap(GLOBALS_WHITE_LISTED); 53 54 const range = 2; 55 function generateCodeFrame(source, start = 0, end = source.length) {
vendor: 4,204 bytes, lines 56-173
56 // Split the content into individual lines but capture the newline sequence 57 // that separated each line. This is important because the actual sequence is 58 // needed to properly take into account the full line length for offset 59 // comparison 60 let lines = source.split(/(\r?\n)/); 61 // Separate the lines and newline sequences into separate arrays for easier referencing 62 const newlineSequences = lines.filter((_, idx) => idx % 2 === 1); 63 lines = lines.filter((_, idx) => idx % 2 === 0); 64 let count = 0; 65 const res = []; 66 for (let i = 0; i < lines.length; i++) { 67 count += 68 lines[i].length + 69 ((newlineSequences[i] && newlineSequences[i].length) || 0); 70 if (count >= start) { 71 for (let j = i - range; j <= i + range || end > count; j++) { 72 if (j < 0 || j >= lines.length) 73 continue; 74 const line = j + 1; 75 res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`); 76 const lineLength = lines[j].length; 77 const newLineSeqLength = (newlineSequences[j] && newlineSequences[j].length) || 0; 78 if (j === i) { 79 // push underline 80 const pad = start - (count - (lineLength + newLineSeqLength)); 81 const length = Math.max(1, end > count ? lineLength - pad : end - start); 82 res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length)); 83 } 84 else if (j > i) { 85 if (end > count) { 86 const length = Math.max(Math.min(end - count, lineLength), 1); 87 res.push(` | ` + '^'.repeat(length)); 88 } 89 count += lineLength + newLineSeqLength; 90 } 91 } 92 break; 93 } 94 } 95 return res.join('\n'); 96 } 97 98 function normalizeStyle(value) { 99 if (isArray(value)) { 100 const res = {}; 101 for (let i = 0; i < value.length; i++) { 102 const item = value[i]; 103 const normalized = isString(item) 104 ? parseStringStyle(item) 105 : normalizeStyle(item); 106 if (normalized) { 107 for (const key in normalized) { 108 res[key] = normalized[key]; 109 } 110 } 111 } 112 return res; 113 } 114 else if (isString(value)) { 115 return value; 116 } 117 else if (isObject(value)) { 118 return value; 119 } 120 } 121 const listDelimiterRE = /;(?![^(]*\))/g; 122 const propertyDelimiterRE = /:([^]+)/; 123 const styleCommentRE = /\/\*.*?\*\//gs; 124 function parseStringStyle(cssText) { 125 const ret = {}; 126 cssText 127 .replace(styleCommentRE, '') 128 .split(listDelimiterRE) 129 .forEach(item => { 130 if (item) { 131 const tmp = item.split(propertyDelimiterRE); 132 tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim()); 133 } 134 }); 135 return ret; 136 } 137 function normalizeClass(value) { 138 let res = ''; 139 if (isString(value)) { 140 res = value; 141 } 142 else if (isArray(value)) { 143 for (let i = 0; i < value.length; i++) { 144 const normalized = normalizeClass(value[i]); 145 if (normalized) { 146 res += normalized + ' '; 147 } 148 } 149 } 150 else if (isObject(value)) { 151 for (const name in value) { 152 if (value[name]) { 153 res += name + ' '; 154 } 155 } 156 } 157 return res.trim(); 158 } 159 function normalizeProps(props) { 160 if (!props) 161 return null; 162 let { class: klass, style } = props; 163 if (klass && !isString(klass)) { 164 props.class = normalizeClass(klass); 165 } 166 if (style) { 167 props.style = normalizeStyle(style); 168 } 169 return props; 170 } 171 172 // These tag configs are shared between compiler-dom and runtime-dom, so they 173 // https://developer.mozilla.org/en-US/docs/Web/HTML/Element
174 const HTML_TAGS = 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' + 175 'header,hgroup,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,' + 176 'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' + 177 'data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,' + 178 'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' + 179 'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' + 180 'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' + 181 'option,output,progress,select,textarea,details,dialog,menu,' + 182 'summary,template,blockquote,iframe,tfoot'; 183 // https://developer.mozilla.org/en-US/docs/Web/SVG/Element 184 const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' + 185 'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' + 186 'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' + 187 'feDistantLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' + 188 'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' + 189 'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' + 190 'foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,' + 191 'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' + 192 'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' + 193 'text,textPath,title,tspan,unknown,use,view'; 194 const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr'; 195 /** 196 * Compiler only. 197 * Do NOT use in runtime code paths unless behind `true` flag. 198 */ 199 const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS); 200 /** 201 * Compiler only. 202 * Do NOT use in runtime code paths unless behind `true` flag. 203 */ 204 const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS); 205 /** 206 * Compiler only. 207 * Do NOT use in runtime code paths unless behind `true` flag. 208 */ 209 const isVoidTag = /*#__PURE__*/ makeMap(VOID_TAGS); 210 211 /** 212 * On the client we only need to offer special cases for boolean attributes that 213 * have different names from their corresponding dom properties: 214 * - itemscope -> N/A 215 * - allowfullscreen -> allowFullscreen 216 * - formnovalidate -> formNoValidate 217 * - ismap -> isMap 218 * - nomodule -> noModule 219 * - novalidate -> noValidate 220 * - readonly -> readOnly 221 */ 222 const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`; 223 const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs); 224 /** 225 * Boolean attributes should be included if the value is truthy or ''. 226 * e.g. `<select multiple>` compiles to `{ multiple: '' }` 227 */ 228 function includeBooleanAttr(value) { 229 return !!value || value === ''; 230 } 231 232 function looseCompareArrays(a, b) { 233 if (a.length !== b.length) 234 return false; 235 let equal = true; 236 for (let i = 0; equal && i < a.length; i++) { 237 equal = looseEqual(a[i], b[i]); 238 } 239 return equal; 240 } 241 function looseEqual(a, b) { 242 if (a === b) 243 return true; 244 let aValidType = isDate(a); 245 let bValidType = isDate(b); 246 if (aValidType || bValidType) { 247 return aValidType && bValidType ? a.getTime() === b.getTime() : false; 248 } 249 aValidType = isSymbol(a); 250 bValidType = isSymbol(b); 251 if (aValidType || bValidType) { 252 return a === b; 253 } 254 aValidType = isArray(a); 255 bValidType = isArray(b); 256 if (aValidType || bValidType) { 257 return aValidType && bValidType ? looseCompareArrays(a, b) : false; 258 } 259 aValidType = isObject(a); 260 bValidType = isObject(b); 261 if (aValidType || bValidType) { 262 /* istanbul ignore if: this if will probably never be called */ 263 if (!aValidType || !bValidType) { 264 return false; 265 } 266 const aKeysCount = Object.keys(a).length; 267 const bKeysCount = Object.keys(b).length; 268 if (aKeysCount !== bKeysCount) { 269 return false;
270 } 271 for (const key in a) { 272 const aHasKey = a.hasOwnProperty(key); 273 const bHasKey = b.hasOwnProperty(key); 274 if ((aHasKey && !bHasKey) || 275 (!aHasKey && bHasKey) || 276 !looseEqual(a[key], b[key])) { 277 return false; 278 } 279 } 280 } 281 return String(a) === String(b); 282 } 283 function looseIndexOf(arr, val) { 284 return arr.findIndex(item => looseEqual(item, val)); 285 } 286 287 /** 288 * For converting {{ interpolation }} values to displayed strings. 289 * @private 290 */ 291 const toDisplayString = (val) => { 292 return isString(val) 293 ? val 294 : val == null 295 ? '' 296 : isArray(val) || 297 (isObject(val) && 298 (val.toString === objectToString || !isFunction(val.toString))) 299 ? JSON.stringify(val, replacer, 2) 300 : String(val); 301 }; 302 const replacer = (_key, val) => { 303 // can't use isRef here since @vue/shared has no deps 304 if (val && val.__v_isRef) { 305 return replacer(_key, val.value); 306 } 307 else if (isMap(val)) { 308 return { 309 [`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val]) => { 310 entries[`${key} =>`] = val; 311 return entries; 312 }, {}) 313 }; 314 } 315 else if (isSet(val)) { 316 return { 317 [`Set(${val.size})`]: [...val.values()] 318 }; 319 } 320 else if (isObject(val) && !isArray(val) && !isPlainObject(val)) { 321 return String(val); 322 } 323 return val; 324 }; 325 326 const EMPTY_OBJ = Object.freeze({}) 327 ; 328 const EMPTY_ARR = Object.freeze([]) ; 329 const NOOP = () => { }; 330 /** 331 * Always return false. 332 */ 333 const NO = () => false; 334 const onRE = /^on[^a-z]/; 335 const isOn = (key) => onRE.test(key); 336 const isModelListener = (key) => key.startsWith('onUpdate:'); 337 const extend = Object.assign; 338 const remove = (arr, el) => { 339 const i = arr.indexOf(el); 340 if (i > -1) { 341 arr.splice(i, 1); 342 } 343 }; 344 const hasOwnProperty$1 = Object.prototype.hasOwnProperty; 345 const hasOwn = (val, key) => hasOwnProperty$1.call(val, key); 346 const isArray = Array.isArray; 347 const isMap = (val) => toTypeString(val) === '[object Map]'; 348 const isSet = (val) => toTypeString(val) === '[object Set]'; 349 const isDate = (val) => toTypeString(val) === '[object Date]'; 350 const isRegExp = (val) => toTypeString(val) === '[object RegExp]'; 351 const isFunction = (val) => typeof val === 'function'; 352 const isString = (val) => typeof val === 'string'; 353 const isSymbol = (val) => typeof val === 'symbol'; 354 const isObject = (val) => val !== null && typeof val === 'object'; 355 const isPromise = (val) => { 356 return isObject(val) && isFunction(val.then) && isFunction(val.catch); 357 }; 358 const objectToString = Object.prototype.toString; 359 const toTypeString = (value) => objectToString.call(value); 360 const toRawType = (value) => { 361 // extract "RawType" from strings like "[object RawType]" 362 return toTypeString(value).slice(8, -1); 363 }; 364 const isPlainObject = (val) => toTypeString(val) === '[object Object]'; 365 const isIntegerKey = (key) => isString(key) && 366 key !== 'NaN' && 367 key[0] !== '-' && 368 '' + parseInt(key, 10) === key; 369 const isReservedProp = /*#__PURE__*/ makeMap( 370 // the leading comma is intentional so empty string "" is also included 371 ',key,ref,ref_for,ref_key,' + 372 'onVnodeBeforeMount,onVnodeMounted,' + 373 'onVnodeBeforeUpdate,onVnodeUpdated,' + 374 'onVnodeBeforeUnmount,onVnodeUnmounted'); 375 const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo'); 376 const cacheStringFunction = (fn) => { 377 const cache = Object.create(null); 378 return ((str) => { 379 const hit = cache[str]; 380 return hit || (cache[str] = fn(str)); 381 }); 382 }; 383 const camelizeRE = /-(\w)/g; 384 /** 385 * @private 386 */ 387 const camelize = cacheStringFunction((str) => { 388 return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : '')); 389 }); 390 const hyphenateRE = /\B([A-Z])/g; 391 /** 392 * @private 393 */ 394 const hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, '-$1').toLowerCase()); 395 /** 396 * @private 397 */ 398 const capitalize = cacheStringFunction((str) => str.charAt(0).toUpperCase() + str.slice(1)); 399 /** 400 * @private 401 */ 402 const toHandlerKey = cacheStringFunction((str) => str ? `on${capitalize(str)}` : ``); 403 // compare whether a value has changed, accounting for NaN. 404 const hasChanged = (value, oldValue) => !Object.is(value, oldValue); 405 const invokeArrayFns = (fns, arg) => { 406 for (let i = 0; i < fns.length; i++) { 407 fns[i](arg); 408 } 409 }; 410 const def = (obj, key, value) => { 411 Object.defineProperty(obj, key, { 412 configurable: true, 413 enumerable: false, 414 value 415 }); 416 }; 417 /** 418 * "123-foo" will be parsed to 123 419 * This is used for the .number modifier in v-model 420 */ 421 const looseToNumber = (val) => { 422 const n = parseFloat(val); 423 return isNaN(n) ? val : n; 424 }; 425 /** 426 * Only conerces number-like strings 427 * "123-foo" will be returned as-is 428 */ 429 const toNumber = (val) => { 430 const n = isString(val) ? Number(val) : NaN; 431 return isNaN(n) ? val : n; 432 }; 433 let _globalThis; 434 const getGlobalThis = () => { 435 return (_globalThis || 436 (_globalThis = 437 typeof globalThis !== 'undefined' 438 ? globalThis 439 : typeof self !== 'undefined' 440 ? self 441 : typeof window !== 'undefined' 442 ? window 443 : typeof global !== 'undefined' 444 ? global 445 : {})); 446 }; 447 448 function warn$1(msg, ...args) { 449 console.warn(`[Vue warn] ${msg}`, ...args); 450 } 451 452 let activeEffectScope; 453 class EffectScope { 454 constructor(detached = false) { 455 this.detached = detached; 456 /** 457 * @internal 458 */ 459 this._active = true; 460 /** 461 * @internal 462 */ 463 this.effects = []; 464 /** 465 * @internal 466 */ 467 this.cleanups = []; 468 this.parent = activeEffectScope; 469 if (!detached && activeEffectScope) { 470 this.index = 471 (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(this) - 1; 472 } 473 } 474 get active() { 475 return this._active; 476 } 477 run(fn) { 478 if (this._active) { 479 const currentEffectScope = activeEffectScope; 480 try { 481 activeEffectScope = this; 482 return fn(); 483 } 484 finally { 485 activeEffectScope = currentEffectScope; 486 } 487 } 488 else { 489 warn$1(`cannot run an inactive effect scope.`); 490 } 491 } 492 /** 493 * This should only be called on non-detached scopes 494 * @internal 495 */ 496 on() { 497 activeEffectScope = this; 498 } 499 /** 500 * This should only be called on non-detached scopes 501 * @internal 502 */ 503 off() { 504 activeEffectScope = this.parent; 505 } 506 stop(fromParent) { 507 if (this._active) { 508 let i, l; 509 for (i = 0, l = this.effects.length; i < l; i++) { 510 this.effects[i].stop(); 511 } 512 for (i = 0, l = this.cleanups.length; i < l; i++) { 513 this.cleanups[i](); 514 } 515 if (this.scopes) { 516 for (i = 0, l = this.scopes.length; i < l; i++) { 517 this.scopes[i].stop(true); 518 } 519 } 520 // nested scope, dereference from parent to avoid memory leaks 521 if (!this.detached && this.parent && !fromParent) { 522 // optimized O(1) removal 523 const last = this.parent.scopes.pop(); 524 if (last && last !== this) { 525 this.parent.scopes[this.index] = last; 526 last.index = this.index; 527 } 528 } 529 this.parent = undefined; 530 this._active = false;
531 } 532 } 533 } 534 function effectScope(detached) { 535 return new EffectScope(detached); 536 } 537 function recordEffectScope(effect, scope = activeEffectScope) { 538 if (scope && scope.active) { 539 scope.effects.push(effect); 540 } 541 } 542 function getCurrentScope() { 543 return activeEffectScope; 544 } 545 function onScopeDispose(fn) { 546 if (activeEffectScope) { 547 activeEffectScope.cleanups.push(fn); 548 } 549 else { 550 warn$1(`onScopeDispose() is called when there is no active effect scope` + 551 ` to be associated with.`); 552 } 553 } 554 555 const createDep = (effects) => { 556 const dep = new Set(effects); 557 dep.w = 0; 558 dep.n = 0; 559 return dep; 560 }; 561 const wasTracked = (dep) => (dep.w & trackOpBit) > 0; 562 const newTracked = (dep) => (dep.n & trackOpBit) > 0; 563 const initDepMarkers = ({ deps }) => { 564 if (deps.length) { 565 for (let i = 0; i < deps.length; i++) { 566 deps[i].w |= trackOpBit; // set was tracked 567 } 568 } 569 }; 570 const finalizeDepMarkers = (effect) => { 571 const { deps } = effect; 572 if (deps.length) { 573 let ptr = 0; 574 for (let i = 0; i < deps.length; i++) { 575 const dep = deps[i]; 576 if (wasTracked(dep) && !newTracked(dep)) { 577 dep.delete(effect); 578 } 579 else { 580 deps[ptr++] = dep; 581 } 582 // clear bits 583 dep.w &= ~trackOpBit; 584 dep.n &= ~trackOpBit; 585 } 586 deps.length = ptr; 587 } 588 }; 589 590 const targetMap = new WeakMap(); 591 // The number of effects currently being tracked recursively. 592 let effectTrackDepth = 0; 593 let trackOpBit = 1; 594 /** 595 * The bitwise track markers support at most 30 levels of recursion. 596 * This value is chosen to enable modern JS engines to use a SMI on all platforms. 597 * When recursion depth is greater, fall back to using a full cleanup. 598 */ 599 const maxMarkerBits = 30; 600 let activeEffect; 601 const ITERATE_KEY = Symbol('iterate' ); 602 const MAP_KEY_ITERATE_KEY = Symbol('Map key iterate' ); 603 class ReactiveEffect { 604 constructor(fn, scheduler = null, scope) { 605 this.fn = fn; 606 this.scheduler = scheduler; 607 this.active = true; 608 this.deps = []; 609 this.parent = undefined; 610 recordEffectScope(this, scope); 611 } 612 run() { 613 if (!this.active) { 614 return this.fn(); 615 } 616 let parent = activeEffect; 617 let lastShouldTrack = shouldTrack; 618 while (parent) { 619 if (parent === this) { 620 return; 621 } 622 parent = parent.parent; 623 } 624 try { 625 this.parent = activeEffect; 626 activeEffect = this; 627 shouldTrack = true; 628 trackOpBit = 1 << ++effectTrackDepth; 629 if (effectTrackDepth <= maxMarkerBits) { 630 initDepMarkers(this); 631 } 632 else { 633 cleanupEffect(this); 634 } 635 return this.fn(); 636 } 637 finally { 638 if (effectTrackDepth <= maxMarkerBits) { 639 finalizeDepMarkers(this); 640 } 641 trackOpBit = 1 << --effectTrackDepth; 642 activeEffect = this.parent; 643 shouldTrack = lastShouldTrack; 644 this.parent = undefined; 645 if (this.deferStop) { 646 this.stop(); 647 } 648 } 649 } 650 stop() { 651 // stopped while running itself - defer the cleanup 652 if (activeEffect === this) { 653 this.deferStop = true; 654 } 655 else if (this.active) { 656 cleanupEffect(this); 657 if (this.onStop) { 658 this.onStop(); 659 } 660 this.active = false; 661 } 662 } 663 } 664 function cleanupEffect(effect) { 665 const { deps } = effect; 666 if (deps.length) { 667 for (let i = 0; i < deps.length; i++) { 668 deps[i].delete(effect); 669 } 670 deps.length = 0; 671 } 672 } 673 function effect(fn, options) { 674 if (fn.effect) { 675 fn = fn.effect.fn; 676 } 677 const _effect = new ReactiveEffect(fn); 678 if (options) { 679 extend(_effect, options); 680 if (options.scope) 681 recordEffectScope(_effect, options.scope); 682 } 683 if (!options || !options.lazy) { 684 _effect.run(); 685 } 686 const runner = _effect.run.bind(_effect); 687 runner.effect = _effect; 688 return runner; 689 } 690 function stop(runner) { 691 runner.effect.stop(); 692 } 693 let shouldTrack = true; 694 const trackStack = []; 695 function pauseTracking() { 696 trackStack.push(shouldTrack); 697 shouldTrack = false;
698 } 699 function resetTracking() { 700 const last = trackStack.pop(); 701 shouldTrack = last === undefined ? true : last; 702 } 703 function track(target, type, key) { 704 if (shouldTrack && activeEffect) { 705 let depsMap = targetMap.get(target); 706 if (!depsMap) { 707 targetMap.set(target, (depsMap = new Map())); 708 } 709 let dep = depsMap.get(key); 710 if (!dep) { 711 depsMap.set(key, (dep = createDep())); 712 } 713 const eventInfo = { effect: activeEffect, target, type, key } 714 ; 715 trackEffects(dep, eventInfo); 716 } 717 } 718 function trackEffects(dep, debuggerEventExtraInfo) { 719 let shouldTrack = false; 720 if (effectTrackDepth <= maxMarkerBits) { 721 if (!newTracked(dep)) { 722 dep.n |= trackOpBit; // set newly tracked 723 shouldTrack = !wasTracked(dep); 724 } 725 } 726 else { 727 // Full cleanup mode. 728 shouldTrack = !dep.has(activeEffect); 729 } 730 if (shouldTrack) { 731 dep.add(activeEffect); 732 activeEffect.deps.push(dep); 733 if (activeEffect.onTrack) { 734 activeEffect.onTrack(Object.assign({ effect: activeEffect }, debuggerEventExtraInfo)); 735 } 736 } 737 } 738 function trigger(target, type, key, newValue, oldValue, oldTarget) { 739 const depsMap = targetMap.get(target); 740 if (!depsMap) { 741 // never been tracked 742 return; 743 } 744 let deps = []; 745 if (type === "clear" /* TriggerOpTypes.CLEAR */) { 746 // collection being cleared 747 // trigger all effects for target 748 deps = [...depsMap.values()]; 749 } 750 else if (key === 'length' && isArray(target)) { 751 const newLength = Number(newValue); 752 depsMap.forEach((dep, key) => { 753 if (key === 'length' || key >= newLength) { 754 deps.push(dep); 755 } 756 }); 757 } 758 else { 759 // schedule runs for SET | ADD | DELETE 760 if (key !== void 0) { 761 deps.push(depsMap.get(key)); 762 } 763 // also run for iteration key on ADD | DELETE | Map.SET 764 switch (type) { 765 case "add" /* TriggerOpTypes.ADD */: 766 if (!isArray(target)) { 767 deps.push(depsMap.get(ITERATE_KEY)); 768 if (isMap(target)) { 769 deps.push(depsMap.get(MAP_KEY_ITERATE_KEY)); 770 } 771 } 772 else if (isIntegerKey(key)) { 773 // new index added to array -> length changes 774 deps.push(depsMap.get('length')); 775 } 776 break; 777 case "delete" /* TriggerOpTypes.DELETE */: 778 if (!isArray(target)) { 779 deps.push(depsMap.get(ITERATE_KEY)); 780 if (isMap(target)) { 781 deps.push(depsMap.get(MAP_KEY_ITERATE_KEY)); 782 } 783 } 784 break; 785 case "set" /* TriggerOpTypes.SET */: 786 if (isMap(target)) { 787 deps.push(depsMap.get(ITERATE_KEY)); 788 } 789 break; 790 } 791 } 792 const eventInfo = { target, type, key, newValue, oldValue, oldTarget } 793 ; 794 if (deps.length === 1) { 795 if (deps[0]) { 796 { 797 triggerEffects(deps[0], eventInfo); 798 } 799 } 800 } 801 else { 802 const effects = []; 803 for (const dep of deps) { 804 if (dep) { 805 effects.push(...dep); 806 } 807 } 808 { 809 triggerEffects(createDep(effects), eventInfo); 810 } 811 } 812 } 813 function triggerEffects(dep, debuggerEventExtraInfo) { 814 // spread into array for stabilization 815 const effects = isArray(dep) ? dep : [...dep]; 816 for (const effect of effects) { 817 if (effect.computed) { 818 triggerEffect(effect, debuggerEventExtraInfo); 819 } 820 } 821 for (const effect of effects) { 822 if (!effect.computed) { 823 triggerEffect(effect, debuggerEventExtraInfo); 824 } 825 } 826 } 827 function triggerEffect(effect, debuggerEventExtraInfo) { 828 if (effect !== activeEffect || effect.allowRecurse) { 829 if (effect.onTrigger) { 830 effect.onTrigger(extend({ effect }, debuggerEventExtraInfo)); 831 } 832 if (effect.scheduler) { 833 effect.scheduler(); 834 } 835 else { 836 effect.run(); 837 } 838 } 839 } 840 function getDepFromReactive(object, key) { 841 var _a; 842 return (_a = targetMap.get(object)) === null || _a === void 0 ? void 0 : _a.get(key); 843 } 844 845 const isNonTrackableKeys = /*#__PURE__*/ makeMap(`__proto__,__v_isRef,__isVue`);
846 const builtInSymbols = new Set( 847 /*#__PURE__*/ 848 Object.getOwnPropertyNames(Symbol) 849 // ios10.x Object.getOwnPropertyNames(Symbol) can enumerate 'arguments' and 'caller' 850 // but accessing them on Symbol leads to TypeError because Symbol is a strict mode 851 // function 852 .filter(key => key !== 'arguments' && key !== 'caller') 853 .map(key => Symbol[key]) 854 .filter(isSymbol)); 855 const get$1 = /*#__PURE__*/ createGetter(); 856 const shallowGet = /*#__PURE__*/ createGetter(false, true); 857 const readonlyGet = /*#__PURE__*/ createGetter(true); 858 const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true); 859 const arrayInstrumentations = /*#__PURE__*/ createArrayInstrumentations(); 860 function createArrayInstrumentations() { 861 const instrumentations = {}; 862 ['includes', 'indexOf', 'lastIndexOf'].forEach(key => { 863 instrumentations[key] = function (...args) { 864 const arr = toRaw(this); 865 for (let i = 0, l = this.length; i < l; i++) { 866 track(arr, "get" /* TrackOpTypes.GET */, i + ''); 867 } 868 // we run the method using the original args first (which may be reactive) 869 const res = arr[key](...args); 870 if (res === -1 || res === false) { 871 // if that didn't work, run it again using raw values. 872 return arr[key](...args.map(toRaw)); 873 } 874 else { 875 return res; 876 } 877 }; 878 }); 879 ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(key => { 880 instrumentations[key] = function (...args) { 881 pauseTracking(); 882 const res = toRaw(this)[key].apply(this, args); 883 resetTracking(); 884 return res; 885 }; 886 }); 887 return instrumentations; 888 } 889 function hasOwnProperty(key) { 890 const obj = toRaw(this); 891 track(obj, "has" /* TrackOpTypes.HAS */, key); 892 return obj.hasOwnProperty(key); 893 } 894 function createGetter(isReadonly = false, shallow = false) { 895 return function get(target, key, receiver) { 896 if (key === "__v_isReactive" /* ReactiveFlags.IS_REACTIVE */) { 897 return !isReadonly; 898 } 899 else if (key === "__v_isReadonly" /* ReactiveFlags.IS_READONLY */) { 900 return isReadonly; 901 } 902 else if (key === "__v_isShallow" /* ReactiveFlags.IS_SHALLOW */) { 903 return shallow; 904 } 905 else if (key === "__v_raw" /* ReactiveFlags.RAW */ && 906 receiver === 907 (isReadonly 908 ? shallow 909 ? shallowReadonlyMap 910 : readonlyMap 911 : shallow 912 ? shallowReactiveMap 913 : reactiveMap).get(target)) { 914 return target; 915 } 916 const targetIsArray = isArray(target); 917 if (!isReadonly) { 918 if (targetIsArray && hasOwn(arrayInstrumentations, key)) { 919 return Reflect.get(arrayInstrumentations, key, receiver); 920 } 921 if (key === 'hasOwnProperty') { 922 return hasOwnProperty; 923 } 924 } 925 const res = Reflect.get(target, key, receiver); 926 if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) { 927 return res; 928 } 929 if (!isReadonly) { 930 track(target, "get" /* TrackOpTypes.GET */, key); 931 } 932 if (shallow) { 933 return res; 934 } 935 if (isRef(res)) { 936 // ref unwrapping - skip unwrap for Array + integer key. 937 return targetIsArray && isIntegerKey(key) ? res : res.value; 938 } 939 if (isObject(res)) { 940 // Convert returned value into a proxy as well. we do the isObject check 941 // here to avoid invalid value warning. Also need to lazy access readonly 942 // and reactive here to avoid circular dependency. 943 return isReadonly ? readonly(res) : reactive(res); 944 } 945 return res; 946 }; 947 } 948 const set$1 = /*#__PURE__*/ createSetter(); 949 const shallowSet = /*#__PURE__*/ createSetter(true); 950 function createSetter(shallow = false) { 951 return function set(target, key, value, receiver) { 952 let oldValue = target[key]; 953 if (isReadonly(oldValue) && isRef(oldValue) && !isRef(value)) { 954 return false;
955 } 956 if (!shallow) { 957 if (!isShallow(value) && !isReadonly(value)) { 958 oldValue = toRaw(oldValue); 959 value = toRaw(value); 960 } 961 if (!isArray(target) && isRef(oldValue) && !isRef(value)) { 962 oldValue.value = value; 963 return true; 964 } 965 } 966 const hadKey = isArray(target) && isIntegerKey(key) 967 ? Number(key) < target.length 968 : hasOwn(target, key); 969 const result = Reflect.set(target, key, value, receiver); 970 // don't trigger if target is something up in the prototype chain of original 971 if (target === toRaw(receiver)) { 972 if (!hadKey) { 973 trigger(target, "add" /* TriggerOpTypes.ADD */, key, value); 974 } 975 else if (hasChanged(value, oldValue)) { 976 trigger(target, "set" /* TriggerOpTypes.SET */, key, value, oldValue); 977 } 978 } 979 return result; 980 }; 981 } 982 function deleteProperty(target, key) { 983 const hadKey = hasOwn(target, key); 984 const oldValue = target[key]; 985 const result = Reflect.deleteProperty(target, key); 986 if (result && hadKey) { 987 trigger(target, "delete" /* TriggerOpTypes.DELETE */, key, undefined, oldValue); 988 } 989 return result; 990 } 991 function has$1(target, key) { 992 const result = Reflect.has(target, key); 993 if (!isSymbol(key) || !builtInSymbols.has(key)) { 994 track(target, "has" /* TrackOpTypes.HAS */, key); 995 } 996 return result; 997 } 998 function ownKeys(target) { 999 track(target, "iterate" /* TrackOpTypes.ITERATE */, isArray(target) ? 'length' : ITERATE_KEY); 1000 return Reflect.ownKeys(target); 1001 } 1002 const mutableHandlers = { 1003 get: get$1, 1004 set: set$1, 1005 deleteProperty, 1006 has: has$1, 1007 ownKeys 1008 }; 1009 const readonlyHandlers = { 1010 get: readonlyGet, 1011 set(target, key) { 1012 { 1013 warn$1(`Set operation on key "${String(key)}" failed: target is readonly.`, target); 1014 } 1015 return true; 1016 }, 1017 deleteProperty(target, key) { 1018 { 1019 warn$1(`Delete operation on key "${String(key)}" failed: target is readonly.`, target); 1020 } 1021 return true; 1022 } 1023 }; 1024 const shallowReactiveHandlers = /*#__PURE__*/ extend({}, mutableHandlers, { 1025 get: shallowGet, 1026 set: shallowSet 1027 }); 1028 // Props handlers are special in the sense that it should not unwrap top-level 1029 // refs (in order to allow refs to be explicitly passed down), but should 1030 // retain the reactivity of the normal readonly object. 1031 const shallowReadonlyHandlers = /*#__PURE__*/ extend({}, readonlyHandlers, { 1032 get: shallowReadonlyGet 1033 }); 1034 1035 const toShallow = (value) => value; 1036 const getProto = (v) => Reflect.getPrototypeOf(v); 1037 function get(target, key, isReadonly = false, isShallow = false) { 1038 // #1772: readonly(reactive(Map)) should return readonly + reactive version 1039 // of the value 1040 target = target["__v_raw" /* ReactiveFlags.RAW */]; 1041 const rawTarget = toRaw(target); 1042 const rawKey = toRaw(key); 1043 if (!isReadonly) { 1044 if (key !== rawKey) { 1045 track(rawTarget, "get" /* TrackOpTypes.GET */, key); 1046 } 1047 track(rawTarget, "get" /* TrackOpTypes.GET */, rawKey); 1048 } 1049 const { has } = getProto(rawTarget); 1050 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive; 1051 if (has.call(rawTarget, key)) { 1052 return wrap(target.get(key)); 1053 } 1054 else if (has.call(rawTarget, rawKey)) { 1055 return wrap(target.get(rawKey)); 1056 } 1057 else if (target !== rawTarget) { 1058 // #3602 readonly(reactive(Map)) 1059 // ensure that the nested reactive `Map` can do tracking for itself 1060 target.get(key); 1061 } 1062 } 1063 function has(key, isReadonly = false) { 1064 const target = this["__v_raw" /* ReactiveFlags.RAW */]; 1065 const rawTarget = toRaw(target); 1066 const rawKey = toRaw(key); 1067 if (!isReadonly) {
1068 if (key !== rawKey) { 1069 track(rawTarget, "has" /* TrackOpTypes.HAS */, key); 1070 } 1071 track(rawTarget, "has" /* TrackOpTypes.HAS */, rawKey); 1072 } 1073 return key === rawKey 1074 ? target.has(key) 1075 : target.has(key) || target.has(rawKey); 1076 } 1077 function size(target, isReadonly = false) { 1078 target = target["__v_raw" /* ReactiveFlags.RAW */]; 1079 !isReadonly && track(toRaw(target), "iterate" /* TrackOpTypes.ITERATE */, ITERATE_KEY); 1080 return Reflect.get(target, 'size', target); 1081 } 1082 function add(value) { 1083 value = toRaw(value); 1084 const target = toRaw(this); 1085 const proto = getProto(target); 1086 const hadKey = proto.has.call(target, value); 1087 if (!hadKey) { 1088 target.add(value); 1089 trigger(target, "add" /* TriggerOpTypes.ADD */, value, value); 1090 } 1091 return this; 1092 } 1093 function set(key, value) { 1094 value = toRaw(value); 1095 const target = toRaw(this); 1096 const { has, get } = getProto(target); 1097 let hadKey = has.call(target, key); 1098 if (!hadKey) { 1099 key = toRaw(key); 1100 hadKey = has.call(target, key); 1101 } 1102 else { 1103 checkIdentityKeys(target, has, key); 1104 } 1105 const oldValue = get.call(target, key); 1106 target.set(key, value); 1107 if (!hadKey) { 1108 trigger(target, "add" /* TriggerOpTypes.ADD */, key, value); 1109 } 1110 else if (hasChanged(value, oldValue)) { 1111 trigger(target, "set" /* TriggerOpTypes.SET */, key, value, oldValue); 1112 } 1113 return this; 1114 } 1115 function deleteEntry(key) { 1116 const target = toRaw(this); 1117 const { has, get } = getProto(target); 1118 let hadKey = has.call(target, key); 1119 if (!hadKey) { 1120 key = toRaw(key); 1121 hadKey = has.call(target, key); 1122 } 1123 else { 1124 checkIdentityKeys(target, has, key); 1125 } 1126 const oldValue = get ? get.call(target, key) : undefined; 1127 // forward the operation before queueing reactions 1128 const result = target.delete(key); 1129 if (hadKey) { 1130 trigger(target, "delete" /* TriggerOpTypes.DELETE */, key, undefined, oldValue); 1131 } 1132 return result; 1133 } 1134 function clear() { 1135 const target = toRaw(this); 1136 const hadItems = target.size !== 0; 1137 const oldTarget = isMap(target) 1138 ? new Map(target) 1139 : new Set(target) 1140 ; 1141 // forward the operation before queueing reactions 1142 const result = target.clear(); 1143 if (hadItems) { 1144 trigger(target, "clear" /* TriggerOpTypes.CLEAR */, undefined, undefined, oldTarget); 1145 } 1146 return result; 1147 } 1148 function createForEach(isReadonly, isShallow) { 1149 return function forEach(callback, thisArg) { 1150 const observed = this; 1151 const target = observed["__v_raw" /* ReactiveFlags.RAW */]; 1152 const rawTarget = toRaw(target); 1153 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive; 1154 !isReadonly && track(rawTarget, "iterate" /* TrackOpTypes.ITERATE */, ITERATE_KEY); 1155 return target.forEach((value, key) => { 1156 // important: make sure the callback is 1157 // 1. invoked with the reactive map as `this` and 3rd arg 1158 // 2. the value received should be a corresponding reactive/readonly. 1159 return callback.call(thisArg, wrap(value), wrap(key), observed); 1160 }); 1161 }; 1162 } 1163 function createIterableMethod(method, isReadonly, isShallow) { 1164 return function (...args) { 1165 const target = this["__v_raw" /* ReactiveFlags.RAW */]; 1166 const rawTarget = toRaw(target); 1167 const targetIsMap = isMap(rawTarget); 1168 const isPair = method === 'entries' || (method === Symbol.iterator && targetIsMap); 1169 const isKeyOnly = method === 'keys' && targetIsMap; 1170 const innerIterator = target[method](...args); 1171 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive; 1172 !isReadonly && 1173 track(rawTarget, "iterate" /* TrackOpTypes.ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY); 1174 // return a wrapped iterator which returns observed versions of the 1175 // values emitted from the real iterator 1176 return { 1177 // iterator protocol 1178 next() { 1179 const { value, done } = innerIterator.next(); 1180 return done 1181 ? { value, done } 1182 : { 1183 value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),
1184 done 1185 }; 1186 }, 1187 // iterable protocol 1188 [Symbol.iterator]() { 1189 return this; 1190 } 1191 }; 1192 }; 1193 } 1194 function createReadonlyMethod(type) { 1195 return function (...args) { 1196 { 1197 const key = args[0] ? `on key "${args[0]}" ` : ``; 1198 console.warn(`${capitalize(type)} operation ${key}failed: target is readonly.`, toRaw(this)); 1199 } 1200 return type === "delete" /* TriggerOpTypes.DELETE */ ? false : this; 1201 }; 1202 } 1203 function createInstrumentations() { 1204 const mutableInstrumentations = { 1205 get(key) { 1206 return get(this, key); 1207 }, 1208 get size() { 1209 return size(this); 1210 }, 1211 has, 1212 add, 1213 set, 1214 delete: deleteEntry, 1215 clear, 1216 forEach: createForEach(false, false) 1217 }; 1218 const shallowInstrumentations = { 1219 get(key) { 1220 return get(this, key, false, true); 1221 }, 1222 get size() { 1223 return size(this); 1224 }, 1225 has, 1226 add, 1227 set, 1228 delete: deleteEntry, 1229 clear, 1230 forEach: createForEach(false, true) 1231 }; 1232 const readonlyInstrumentations = { 1233 get(key) { 1234 return get(this, key, true); 1235 }, 1236 get size() { 1237 return size(this, true); 1238 }, 1239 has(key) { 1240 return has.call(this, key, true); 1241 }, 1242 add: createReadonlyMethod("add" /* TriggerOpTypes.ADD */), 1243 set: createReadonlyMethod("set" /* TriggerOpTypes.SET */), 1244 delete: createReadonlyMethod("delete" /* TriggerOpTypes.DELETE */), 1245 clear: createReadonlyMethod("clear" /* TriggerOpTypes.CLEAR */), 1246 forEach: createForEach(true, false) 1247 }; 1248 const shallowReadonlyInstrumentations = { 1249 get(key) { 1250 return get(this, key, true, true); 1251 }, 1252 get size() { 1253 return size(this, true); 1254 }, 1255 has(key) { 1256 return has.call(this, key, true); 1257 }, 1258 add: createReadonlyMethod("add" /* TriggerOpTypes.ADD */), 1259 set: createReadonlyMethod("set" /* TriggerOpTypes.SET */), 1260 delete: createReadonlyMethod("delete" /* TriggerOpTypes.DELETE */), 1261 clear: createReadonlyMethod("clear" /* TriggerOpTypes.CLEAR */), 1262 forEach: createForEach(true, true) 1263 }; 1264 const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator]; 1265 iteratorMethods.forEach(method => { 1266 mutableInstrumentations[method] = createIterableMethod(method, false, false); 1267 readonlyInstrumentations[method] = createIterableMethod(method, true, false); 1268 shallowInstrumentations[method] = createIterableMethod(method, false, true); 1269 shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true); 1270 }); 1271 return [ 1272 mutableInstrumentations, 1273 readonlyInstrumentations, 1274 shallowInstrumentations, 1275 shallowReadonlyInstrumentations 1276 ]; 1277 } 1278 const [mutableInstrumentations, readonlyInstrumentations, shallowInstrumentations, shallowReadonlyInstrumentations] = /* #__PURE__*/ createInstrumentations(); 1279 function createInstrumentationGetter(isReadonly, shallow) { 1280 const instrumentations = shallow 1281 ? isReadonly 1282 ? shallowReadonlyInstrumentations 1283 : shallowInstrumentations 1284 : isReadonly 1285 ? readonlyInstrumentations 1286 : mutableInstrumentations; 1287 return (target, key, receiver) => { 1288 if (key === "__v_isReactive" /* ReactiveFlags.IS_REACTIVE */) { 1289 return !isReadonly; 1290 } 1291 else if (key === "__v_isReadonly" /* ReactiveFlags.IS_READONLY */) { 1292 return isReadonly; 1293 } 1294 else if (key === "__v_raw" /* ReactiveFlags.RAW */) { 1295 return target; 1296 } 1297 return Reflect.get(hasOwn(instrumentations, key) && key in target 1298 ? instrumentations 1299 : target, key, receiver); 1300 }; 1301 } 1302 const mutableCollectionHandlers = { 1303 get: /*#__PURE__*/ createInstrumentationGetter(false, false) 1304 }; 1305 const shallowCollectionHandlers = { 1306 get: /*#__PURE__*/ createInstrumentationGetter(false, true) 1307 }; 1308 const readonlyCollectionHandlers = { 1309 get: /*#__PURE__*/ createInstrumentationGetter(true, false) 1310 }; 1311 const shallowReadonlyCollectionHandlers = { 1312 get: /*#__PURE__*/ createInstrumentationGetter(true, true) 1313 }; 1314 function checkIdentityKeys(target, has, key) { 1315 const rawKey = toRaw(key); 1316 if (rawKey !== key && has.call(target, rawKey)) { 1317 const type = toRawType(target); 1318 console.warn(`Reactive ${type} contains both the raw and reactive ` + 1319 `versions of the same object${type === `Map` ? ` as keys` : ``}, ` + 1320 `which can lead to inconsistencies. ` + 1321 `Avoid differentiating between the raw and reactive versions ` + 1322 `of an object and only use the reactive version if possible.`); 1323 } 1324 } 1325 1326 const reactiveMap = new WeakMap(); 1327 const shallowReactiveMap = new WeakMap(); 1328 const readonlyMap = new WeakMap(); 1329 const shallowReadonlyMap = new WeakMap(); 1330 function targetTypeMap(rawType) { 1331 switch (rawType) { 1332 case 'Object': 1333 case 'Array': 1334 return 1 /* TargetType.COMMON */; 1335 case 'Map': 1336 case 'Set': 1337 case 'WeakMap': 1338 case 'WeakSet': 1339 return 2 /* TargetType.COLLECTION */; 1340 default: 1341 return 0 /* TargetType.INVALID */; 1342 } 1343 } 1344 function getTargetType(value) { 1345 return value["__v_skip" /* ReactiveFlags.SKIP */] || !Object.isExtensible(value) 1346 ? 0 /* TargetType.INVALID */ 1347 : targetTypeMap(toRawType(value)); 1348 } 1349 function reactive(target) { 1350 // if trying to observe a readonly proxy, return the readonly version. 1351 if (isReadonly(target)) { 1352 return target; 1353 } 1354 return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap); 1355 } 1356 /** 1357 * Return a shallowly-reactive copy of the original object, where only the root 1358 * level properties are reactive. It also does not auto-unwrap refs (even at the 1359 * root level). 1360 */ 1361 function shallowReactive(target) { 1362 return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap); 1363 } 1364 /** 1365 * Creates a readonly copy of the original object. Note the returned copy is not 1366 * made reactive, but `readonly` can be called on an already reactive object. 1367 */ 1368 function readonly(target) { 1369 return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap); 1370 } 1371 /** 1372 * Returns a reactive-copy of the original object, where only the root level 1373 * properties are readonly, and does NOT unwrap refs nor recursively convert 1374 * returned properties. 1375 * This is used for creating the props proxy object for stateful components. 1376 */ 1377 function shallowReadonly(target) { 1378 return createReactiveObject(target, true, shallowReadonlyHandlers, shallowReadonlyCollectionHandlers, shallowReadonlyMap); 1379 } 1380 function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) { 1381 if (!isObject(target)) { 1382 { 1383 console.warn(`value cannot be made reactive: ${String(target)}`); 1384 } 1385 return target; 1386 } 1387 // target is already a Proxy, return it. 1388 // exception: calling readonly() on a reactive object 1389 if (target["__v_raw" /* ReactiveFlags.RAW */] && 1390 !(isReadonly && target["__v_isReactive" /* ReactiveFlags.IS_REACTIVE */])) { 1391 return target; 1392 } 1393 // target already has corresponding Proxy 1394 const existingProxy = proxyMap.get(target); 1395 if (existingProxy) { 1396 return existingProxy; 1397 } 1398 // only specific value types can be observed. 1399 const targetType = getTargetType(target); 1400 if (targetType === 0 /* TargetType.INVALID */) { 1401 return target; 1402 } 1403 const proxy = new Proxy(target, targetType === 2 /* TargetType.COLLECTION */ ? collectionHandlers : baseHandlers); 1404 proxyMap.set(target, proxy); 1405 return proxy; 1406 } 1407 function isReactive(value) { 1408 if (isReadonly(value)) { 1409 return isReactive(value["__v_raw" /* ReactiveFlags.RAW */]); 1410 } 1411 return !!(value && value["__v_isReactive" /* ReactiveFlags.IS_REACTIVE */]); 1412 } 1413 function isReadonly(value) { 1414 return !!(value && value["__v_isReadonly" /* ReactiveFlags.IS_READONLY */]); 1415 } 1416 function isShallow(value) { 1417 return !!(value && value["__v_isShallow" /* ReactiveFlags.IS_SHALLOW */]); 1418 } 1419 function isProxy(value) { 1420 return isReactive(value) || isReadonly(value); 1421 } 1422 function toRaw(observed) { 1423 const raw = observed && observed["__v_raw" /* ReactiveFlags.RAW */]; 1424 return raw ? toRaw(raw) : observed; 1425 } 1426 function markRaw(value) { 1427 def(value, "__v_skip" /* ReactiveFlags.SKIP */, true); 1428 return value; 1429 } 1430 const toReactive = (value) => isObject(value) ? reactive(value) : value; 1431 const toReadonly = (value) => isObject(value) ? readonly(value) : value; 1432 1433 function trackRefValue(ref) { 1434 if (shouldTrack && activeEffect) { 1435 ref = toRaw(ref); 1436 { 1437 trackEffects(ref.dep || (ref.dep = createDep()), { 1438 target: ref, 1439 type: "get" /* TrackOpTypes.GET */, 1440 key: 'value' 1441 }); 1442 } 1443 } 1444 } 1445 function triggerRefValue(ref, newVal) { 1446 ref = toRaw(ref); 1447 const dep = ref.dep; 1448 if (dep) { 1449 { 1450 triggerEffects(dep, { 1451 target: ref, 1452 type: "set" /* TriggerOpTypes.SET */, 1453 key: 'value', 1454 newValue: newVal 1455 }); 1456 } 1457 } 1458 } 1459 function isRef(r) { 1460 return !!(r && r.__v_isRef === true); 1461 } 1462 function ref(value) { 1463 return createRef(value, false); 1464 } 1465 function shallowRef(value) { 1466 return createRef(value, true); 1467 } 1468 function createRef(rawValue, shallow) { 1469 if (isRef(rawValue)) { 1470 return rawValue; 1471 } 1472 return new RefImpl(rawValue, shallow); 1473 } 1474 class RefImpl { 1475 constructor(value, __v_isShallow) { 1476 this.__v_isShallow = __v_isShallow; 1477 this.dep = undefined; 1478 this.__v_isRef = true; 1479 this._rawValue = __v_isShallow ? value : toRaw(value); 1480 this._value = __v_isShallow ? value : toReactive(value); 1481 } 1482 get value() { 1483 trackRefValue(this); 1484 return this._value; 1485 } 1486 set value(newVal) { 1487 const useDirectValue = this.__v_isShallow || isShallow(newVal) || isReadonly(newVal); 1488 newVal = useDirectValue ? newVal : toRaw(newVal); 1489 if (hasChanged(newVal, this._rawValue)) { 1490 this._rawValue = newVal; 1491 this._value = useDirectValue ? newVal : toReactive(newVal); 1492 triggerRefValue(this, newVal); 1493 } 1494 } 1495 } 1496 function triggerRef(ref) { 1497 triggerRefValue(ref, ref.value ); 1498 } 1499 function unref(ref) { 1500 return isRef(ref) ? ref.value : ref; 1501 } 1502 const shallowUnwrapHandlers = { 1503 get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)), 1504 set: (target, key, value, receiver) => { 1505 const oldValue = target[key]; 1506 if (isRef(oldValue) && !isRef(value)) { 1507 oldValue.value = value; 1508 return true; 1509 } 1510 else { 1511 return Reflect.set(target, key, value, receiver); 1512 } 1513 } 1514 }; 1515 function proxyRefs(objectWithRefs) { 1516 return isReactive(objectWithRefs) 1517 ? objectWithRefs 1518 : new Proxy(objectWithRefs, shallowUnwrapHandlers); 1519 } 1520 class CustomRefImpl { 1521 constructor(factory) { 1522 this.dep = undefined; 1523 this.__v_isRef = true; 1524 const { get, set } = factory(() => trackRefValue(this), () => triggerRefValue(this)); 1525 this._get = get; 1526 this._set = set; 1527 } 1528 get value() { 1529 return this._get(); 1530 } 1531 set value(newVal) { 1532 this._set(newVal); 1533 } 1534 } 1535 function customRef(factory) { 1536 return new CustomRefImpl(factory); 1537 } 1538 function toRefs(object) { 1539 if (!isProxy(object)) { 1540 console.warn(`toRefs() expects a reactive object but received a plain one.`); 1541 } 1542 const ret = isArray(object) ? new Array(object.length) : {}; 1543 for (const key in object) { 1544 ret[key] = toRef(object, key); 1545 } 1546 return ret; 1547 } 1548 class ObjectRefImpl { 1549 constructor(_object, _key, _defaultValue) { 1550 this._object = _object; 1551 this._key = _key; 1552 this._defaultValue = _defaultValue; 1553 this.__v_isRef = true; 1554 } 1555 get value() { 1556 const val = this._object[this._key]; 1557 return val === undefined ? this._defaultValue : val; 1558 } 1559 set value(newVal) { 1560 this._object[this._key] = newVal; 1561 } 1562 get dep() { 1563 return getDepFromReactive(toRaw(this._object), this._key); 1564 } 1565 } 1566 function toRef(object, key, defaultValue) { 1567 const val = object[key]; 1568 return isRef(val) 1569 ? val 1570 : new ObjectRefImpl(object, key, defaultValue); 1571 } 1572 1573 var _a; 1574 class ComputedRefImpl { 1575 constructor(getter, _setter, isReadonly, isSSR) { 1576 this._setter = _setter; 1577 this.dep = undefined; 1578 this.__v_isRef = true; 1579 this[_a] = false;
1580 this._dirty = true; 1581 this.effect = new ReactiveEffect(getter, () => { 1582 if (!this._dirty) { 1583 this._dirty = true; 1584 triggerRefValue(this); 1585 } 1586 }); 1587 this.effect.computed = this; 1588 this.effect.active = this._cacheable = !isSSR; 1589 this["__v_isReadonly" /* ReactiveFlags.IS_READONLY */] = isReadonly; 1590 } 1591 get value() { 1592 // the computed ref may get wrapped by other proxies e.g. readonly() #3376 1593 const self = toRaw(this); 1594 trackRefValue(self); 1595 if (self._dirty || !self._cacheable) { 1596 self._dirty = false; 1597 self._value = self.effect.run(); 1598 } 1599 return self._value; 1600 } 1601 set value(newValue) { 1602 this._setter(newValue); 1603 } 1604 } 1605 _a = "__v_isReadonly" /* ReactiveFlags.IS_READONLY */; 1606 function computed$1(getterOrOptions, debugOptions, isSSR = false) { 1607 let getter; 1608 let setter; 1609 const onlyGetter = isFunction(getterOrOptions); 1610 if (onlyGetter) { 1611 getter = getterOrOptions; 1612 setter = () => { 1613 console.warn('Write operation failed: computed value is readonly'); 1614 } 1615 ; 1616 } 1617 else { 1618 getter = getterOrOptions.get; 1619 setter = getterOrOptions.set; 1620 } 1621 const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter, isSSR); 1622 if (debugOptions && !isSSR) { 1623 cRef.effect.onTrack = debugOptions.onTrack; 1624 cRef.effect.onTrigger = debugOptions.onTrigger; 1625 } 1626 return cRef; 1627 } 1628 1629 const stack = []; 1630 function pushWarningContext(vnode) { 1631 stack.push(vnode); 1632 } 1633 function popWarningContext() { 1634 stack.pop(); 1635 } 1636 function warn(msg, ...args) { 1637 // avoid props formatting or warn handler tracking deps that might be mutated 1638 // during patch, leading to infinite recursion. 1639 pauseTracking(); 1640 const instance = stack.length ? stack[stack.length - 1].component : null; 1641 const appWarnHandler = instance && instance.appContext.config.warnHandler; 1642 const trace = getComponentTrace(); 1643 if (appWarnHandler) { 1644 callWithErrorHandling(appWarnHandler, instance, 11 /* ErrorCodes.APP_WARN_HANDLER */, [ 1645 msg + args.join(''), 1646 instance && instance.proxy, 1647 trace 1648 .map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`) 1649 .join('\n'), 1650 trace 1651 ]); 1652 } 1653 else { 1654 const warnArgs = [`[Vue warn]: ${msg}`, ...args]; 1655 /* istanbul ignore if */ 1656 if (trace.length && 1657 // avoid spamming console during tests 1658 !false) { 1659 warnArgs.push(`\n`, ...formatTrace(trace)); 1660 } 1661 console.warn(...warnArgs); 1662 } 1663 resetTracking(); 1664 } 1665 function getComponentTrace() { 1666 let currentVNode = stack[stack.length - 1]; 1667 if (!currentVNode) { 1668 return []; 1669 } 1670 // we can't just use the stack because it will be incomplete during updates 1671 // that did not start from the root. Re-construct the parent chain using 1672 // instance parent pointers. 1673 const normalizedStack = []; 1674 while (currentVNode) { 1675 const last = normalizedStack[0]; 1676 if (last && last.vnode === currentVNode) { 1677 last.recurseCount++; 1678 } 1679 else { 1680 normalizedStack.push({ 1681 vnode: currentVNode, 1682 recurseCount: 0 1683 }); 1684 } 1685 const parentInstance = currentVNode.component && currentVNode.component.parent; 1686 currentVNode = parentInstance && parentInstance.vnode; 1687 } 1688 return normalizedStack; 1689 } 1690 /* istanbul ignore next */ 1691 function formatTrace(trace) { 1692 const logs = []; 1693 trace.forEach((entry, i) => { 1694 logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry)); 1695 }); 1696 return logs; 1697 } 1698 function formatTraceEntry({ vnode, recurseCount }) { 1699 const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``; 1700 const isRoot = vnode.component ? vnode.component.parent == null : false;
1701 const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`; 1702 const close = `>` + postfix; 1703 return vnode.props 1704 ? [open, ...formatProps(vnode.props), close] 1705 : [open + close]; 1706 } 1707 /* istanbul ignore next */ 1708 function formatProps(props) { 1709 const res = []; 1710 const keys = Object.keys(props); 1711 keys.slice(0, 3).forEach(key => { 1712 res.push(...formatProp(key, props[key])); 1713 }); 1714 if (keys.length > 3) { 1715 res.push(` ...`); 1716 } 1717 return res; 1718 } 1719 /* istanbul ignore next */ 1720 function formatProp(key, value, raw) { 1721 if (isString(value)) { 1722 value = JSON.stringify(value); 1723 return raw ? value : [`${key}=${value}`]; 1724 } 1725 else if (typeof value === 'number' || 1726 typeof value === 'boolean' || 1727 value == null) { 1728 return raw ? value : [`${key}=${value}`]; 1729 } 1730 else if (isRef(value)) { 1731 value = formatProp(key, toRaw(value.value), true); 1732 return raw ? value : [`${key}=Ref<`, value, `>`]; 1733 } 1734 else if (isFunction(value)) { 1735 return [`${key}=fn${value.name ? `<${value.name}>` : ``}`]; 1736 } 1737 else { 1738 value = toRaw(value); 1739 return raw ? value : [`${key}=`, value]; 1740 } 1741 } 1742 /** 1743 * @internal 1744 */ 1745 function assertNumber(val, type) { 1746 if (val === undefined) { 1747 return; 1748 } 1749 else if (typeof val !== 'number') { 1750 warn(`${type} is not a valid number - ` + `got ${JSON.stringify(val)}.`); 1751 } 1752 else if (isNaN(val)) { 1753 warn(`${type} is NaN - ` + 'the duration expression might be incorrect.'); 1754 } 1755 } 1756 1757 const ErrorTypeStrings = { 1758 ["sp" /* LifecycleHooks.SERVER_PREFETCH */]: 'serverPrefetch hook', 1759 ["bc" /* LifecycleHooks.BEFORE_CREATE */]: 'beforeCreate hook', 1760 ["c" /* LifecycleHooks.CREATED */]: 'created hook', 1761 ["bm" /* LifecycleHooks.BEFORE_MOUNT */]: 'beforeMount hook', 1762 ["m" /* LifecycleHooks.MOUNTED */]: 'mounted hook', 1763 ["bu" /* LifecycleHooks.BEFORE_UPDATE */]: 'beforeUpdate hook', 1764 ["u" /* LifecycleHooks.UPDATED */]: 'updated', 1765 ["bum" /* LifecycleHooks.BEFORE_UNMOUNT */]: 'beforeUnmount hook', 1766 ["um" /* LifecycleHooks.UNMOUNTED */]: 'unmounted hook', 1767 ["a" /* LifecycleHooks.ACTIVATED */]: 'activated hook', 1768 ["da" /* LifecycleHooks.DEACTIVATED */]: 'deactivated hook', 1769 ["ec" /* LifecycleHooks.ERROR_CAPTURED */]: 'errorCaptured hook', 1770 ["rtc" /* LifecycleHooks.RENDER_TRACKED */]: 'renderTracked hook', 1771 ["rtg" /* LifecycleHooks.RENDER_TRIGGERED */]: 'renderTriggered hook', 1772 [0 /* ErrorCodes.SETUP_FUNCTION */]: 'setup function', 1773 [1 /* ErrorCodes.RENDER_FUNCTION */]: 'render function', 1774 [2 /* ErrorCodes.WATCH_GETTER */]: 'watcher getter', 1775 [3 /* ErrorCodes.WATCH_CALLBACK */]: 'watcher callback', 1776 [4 /* ErrorCodes.WATCH_CLEANUP */]: 'watcher cleanup function', 1777 [5 /* ErrorCodes.NATIVE_EVENT_HANDLER */]: 'native event handler', 1778 [6 /* ErrorCodes.COMPONENT_EVENT_HANDLER */]: 'component event handler', 1779 [7 /* ErrorCodes.VNODE_HOOK */]: 'vnode hook', 1780 [8 /* ErrorCodes.DIRECTIVE_HOOK */]: 'directive hook', 1781 [9 /* ErrorCodes.TRANSITION_HOOK */]: 'transition hook', 1782 [10 /* ErrorCodes.APP_ERROR_HANDLER */]: 'app errorHandler', 1783 [11 /* ErrorCodes.APP_WARN_HANDLER */]: 'app warnHandler', 1784 [12 /* ErrorCodes.FUNCTION_REF */]: 'ref function', 1785 [13 /* ErrorCodes.ASYNC_COMPONENT_LOADER */]: 'async component loader', 1786 [14 /* ErrorCodes.SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' + 1787 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core' 1788 }; 1789 function callWithErrorHandling(fn, instance, type, args) { 1790 let res; 1791 try { 1792 res = args ? fn(...args) : fn(); 1793 } 1794 catch (err) { 1795 handleError(err, instance, type); 1796 } 1797 return res; 1798 } 1799 function callWithAsyncErrorHandling(fn, instance, type, args) { 1800 if (isFunction(fn)) { 1801 const res = callWithErrorHandling(fn, instance, type, args); 1802 if (res && isPromise(res)) { 1803 res.catch(err => { 1804 handleError(err, instance, type); 1805 }); 1806 } 1807 return res; 1808 } 1809 const values = []; 1810 for (let i = 0; i < fn.length; i++) { 1811 values.push(callWithAsyncErrorHandling(fn[i], instance, type, args)); 1812 } 1813 return values; 1814 } 1815 function handleError(err, instance, type, throwInDev = true) { 1816 const contextVNode = instance ? instance.vnode : null; 1817 if (instance) { 1818 let cur = instance.parent; 1819 // the exposed instance is the render proxy to keep it consistent with 2.x 1820 const exposedInstance = instance.proxy; 1821 // in production the hook receives only the error code 1822 const errorInfo = ErrorTypeStrings[type] ; 1823 while (cur) {
1824 const errorCapturedHooks = cur.ec; 1825 if (errorCapturedHooks) { 1826 for (let i = 0; i < errorCapturedHooks.length; i++) { 1827 if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) { 1828 return; 1829 } 1830 } 1831 } 1832 cur = cur.parent; 1833 } 1834 // app-level handling 1835 const appErrorHandler = instance.appContext.config.errorHandler; 1836 if (appErrorHandler) { 1837 callWithErrorHandling(appErrorHandler, null, 10 /* ErrorCodes.APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]); 1838 return; 1839 } 1840 } 1841 logError(err, type, contextVNode, throwInDev); 1842 } 1843 function logError(err, type, contextVNode, throwInDev = true) { 1844 { 1845 const info = ErrorTypeStrings[type]; 1846 if (contextVNode) { 1847 pushWarningContext(contextVNode); 1848 } 1849 warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`); 1850 if (contextVNode) { 1851 popWarningContext(); 1852 } 1853 // crash in dev by default so it's more noticeable 1854 if (throwInDev) { 1855 throw err; 1856 } 1857 else { 1858 console.error(err); 1859 } 1860 } 1861 } 1862 1863 let isFlushing = false; 1864 let isFlushPending = false; 1865 const queue = []; 1866 let flushIndex = 0; 1867 const pendingPostFlushCbs = []; 1868 let activePostFlushCbs = null; 1869 let postFlushIndex = 0; 1870 const resolvedPromise = /*#__PURE__*/ Promise.resolve(); 1871 let currentFlushPromise = null; 1872 const RECURSION_LIMIT = 100; 1873 function nextTick(fn) { 1874 const p = currentFlushPromise || resolvedPromise; 1875 return fn ? p.then(this ? fn.bind(this) : fn) : p; 1876 } 1877 // #2768 1878 // Use binary-search to find a suitable position in the queue, 1879 // so that the queue maintains the increasing order of job's id, 1880 // which can prevent the job from being skipped and also can avoid repeated patching. 1881 function findInsertionIndex(id) { 1882 // the start index should be `flushIndex + 1` 1883 let start = flushIndex + 1; 1884 let end = queue.length; 1885 while (start < end) { 1886 const middle = (start + end) >>> 1; 1887 const middleJobId = getId(queue[middle]); 1888 middleJobId < id ? (start = middle + 1) : (end = middle); 1889 } 1890 return start; 1891 } 1892 function queueJob(job) { 1893 // the dedupe search uses the startIndex argument of Array.includes() 1894 // by default the search index includes the current job that is being run 1895 // so it cannot recursively trigger itself again. 1896 // if the job is a watch() callback, the search will start with a +1 index to 1897 // allow it recursively trigger itself - it is the user's responsibility to 1898 // ensure it doesn't end up in an infinite loop. 1899 if (!queue.length || 1900 !queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)) { 1901 if (job.id == null) { 1902 queue.push(job); 1903 } 1904 else { 1905 queue.splice(findInsertionIndex(job.id), 0, job); 1906 } 1907 queueFlush(); 1908 } 1909 } 1910 function queueFlush() { 1911 if (!isFlushing && !isFlushPending) { 1912 isFlushPending = true; 1913 currentFlushPromise = resolvedPromise.then(flushJobs); 1914 } 1915 }
1916 function invalidateJob(job) { 1917 const i = queue.indexOf(job); 1918 if (i > flushIndex) { 1919 queue.splice(i, 1); 1920 } 1921 } 1922 function queuePostFlushCb(cb) { 1923 if (!isArray(cb)) { 1924 if (!activePostFlushCbs || 1925 !activePostFlushCbs.includes(cb, cb.allowRecurse ? postFlushIndex + 1 : postFlushIndex)) { 1926 pendingPostFlushCbs.push(cb); 1927 } 1928 } 1929 else { 1930 // if cb is an array, it is a component lifecycle hook which can only be 1931 // triggered by a job, which is already deduped in the main queue, so 1932 // we can skip duplicate check here to improve perf 1933 pendingPostFlushCbs.push(...cb); 1934 } 1935 queueFlush(); 1936 } 1937 function flushPreFlushCbs(seen, 1938 // if currently flushing, skip the current job itself 1939 i = isFlushing ? flushIndex + 1 : 0) { 1940 { 1941 seen = seen || new Map(); 1942 } 1943 for (; i < queue.length; i++) { 1944 const cb = queue[i]; 1945 if (cb && cb.pre) { 1946 if (checkRecursiveUpdates(seen, cb)) { 1947 continue; 1948 } 1949 queue.splice(i, 1); 1950 i--; 1951 cb(); 1952 } 1953 } 1954 } 1955 function flushPostFlushCbs(seen) { 1956 if (pendingPostFlushCbs.length) { 1957 const deduped = [...new Set(pendingPostFlushCbs)]; 1958 pendingPostFlushCbs.length = 0; 1959 // #1947 already has active queue, nested flushPostFlushCbs call 1960 if (activePostFlushCbs) { 1961 activePostFlushCbs.push(...deduped); 1962 return; 1963 } 1964 activePostFlushCbs = deduped; 1965 { 1966 seen = seen || new Map(); 1967 } 1968 activePostFlushCbs.sort((a, b) => getId(a) - getId(b)); 1969 for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) { 1970 if (checkRecursiveUpdates(seen, activePostFlushCbs[postFlushIndex])) { 1971 continue; 1972 } 1973 activePostFlushCbs[postFlushIndex](); 1974 } 1975 activePostFlushCbs = null; 1976 postFlushIndex = 0; 1977 } 1978 } 1979 const getId = (job) => job.id == null ? Infinity : job.id; 1980 const comparator = (a, b) => { 1981 const diff = getId(a) - getId(b); 1982 if (diff === 0) { 1983 if (a.pre && !b.pre) 1984 return -1; 1985 if (b.pre && !a.pre) 1986 return 1; 1987 } 1988 return diff; 1989 }; 1990 function flushJobs(seen) { 1991 isFlushPending = false; 1992 isFlushing = true; 1993 { 1994 seen = seen || new Map(); 1995 } 1996 // Sort queue before flush. 1997 // This ensures that: 1998 // 1. Components are updated from parent to child. (because parent is always 1999 // created before the child so its render effect will have smaller 2000 // priority number) 2001 // 2. If a component is unmounted during a parent component's update, 2002 // its update can be skipped. 2003 queue.sort(comparator); 2004 // conditional usage of checkRecursiveUpdate must be determined out of 2005 // try ... catch block since Rollup by default de-optimizes treeshaking 2006 // inside try-catch. This can leave all warning code unshaked. Although 2007 // they would get eventually shaken by a minifier like terser, some minifiers 2008 // would fail to do that (e.g. https://github.com/evanw/esbuild/issues/1610) 2009 const check = (job) => checkRecursiveUpdates(seen, job) 2010 ; 2011 try { 2012 for (flushIndex = 0; flushIndex < queue.length; flushIndex++) { 2013 const job = queue[flushIndex]; 2014 if (job && job.active !== false) { 2015 if (true && check(job)) { 2016 continue; 2017 } 2018 // console.log(`running:`, job.id) 2019 callWithErrorHandling(job, null, 14 /* ErrorCodes.SCHEDULER */); 2020 } 2021 } 2022 } 2023 finally { 2024 flushIndex = 0; 2025 queue.length = 0; 2026 flushPostFlushCbs(seen); 2027 isFlushing = false; 2028 currentFlushPromise = null; 2029 // some postFlushCb queued jobs! 2030 // keep flushing until it drains. 2031 if (queue.length || pendingPostFlushCbs.length) { 2032 flushJobs(seen); 2033 } 2034 } 2035 } 2036 function checkRecursiveUpdates(seen, fn) { 2037 if (!seen.has(fn)) { 2038 seen.set(fn, 1); 2039 } 2040 else { 2041 const count = seen.get(fn); 2042 if (count > RECURSION_LIMIT) { 2043 const instance = fn.ownerInstance; 2044 const componentName = instance && getComponentName(instance.type); 2045 warn(`Maximum recursive updates exceeded${componentName ? ` in component <${componentName}>` : ``}. ` + 2046 `This means you have a reactive effect that is mutating its own ` + 2047 `dependencies and thus recursively triggering itself. Possible sources ` + 2048 `include component template, render function, updated hook or ` + 2049 `watcher source function.`); 2050 return true; 2051 } 2052 else { 2053 seen.set(fn, count + 1); 2054 } 2055 } 2056 } 2057 2058 /* eslint-disable no-restricted-globals */ 2059 let isHmrUpdating = false;
2060 const hmrDirtyComponents = new Set(); 2061 // Expose the HMR runtime on the global object 2062 // This makes it entirely tree-shakable without polluting the exports and makes 2063 // it easier to be used in toolings like vue-loader 2064 // Note: for a component to be eligible for HMR it also needs the __hmrId option 2065 // to be set so that its instances can be registered / removed. 2066 { 2067 getGlobalThis().__VUE_HMR_RUNTIME__ = { 2068 createRecord: tryWrap(createRecord), 2069 rerender: tryWrap(rerender), 2070 reload: tryWrap(reload) 2071 }; 2072 } 2073 const map = new Map(); 2074 function registerHMR(instance) { 2075 const id = instance.type.__hmrId; 2076 let record = map.get(id); 2077 if (!record) { 2078 createRecord(id, instance.type); 2079 record = map.get(id); 2080 } 2081 record.instances.add(instance); 2082 } 2083 function unregisterHMR(instance) { 2084 map.get(instance.type.__hmrId).instances.delete(instance); 2085 } 2086 function createRecord(id, initialDef) { 2087 if (map.has(id)) { 2088 return false; 2089 } 2090 map.set(id, { 2091 initialDef: normalizeClassComponent(initialDef), 2092 instances: new Set() 2093 }); 2094 return true; 2095 } 2096 function normalizeClassComponent(component) { 2097 return isClassComponent(component) ? component.__vccOpts : component; 2098 } 2099 function rerender(id, newRender) { 2100 const record = map.get(id); 2101 if (!record) { 2102 return; 2103 } 2104 // update initial record (for not-yet-rendered component) 2105 record.initialDef.render = newRender; 2106 [...record.instances].forEach(instance => { 2107 if (newRender) { 2108 instance.render = newRender; 2109 normalizeClassComponent(instance.type).render = newRender; 2110 } 2111 instance.renderCache = []; 2112 // this flag forces child components with slot content to update 2113 isHmrUpdating = true; 2114 instance.update(); 2115 isHmrUpdating = false; 2116 }); 2117 } 2118 function reload(id, newComp) { 2119 const record = map.get(id); 2120 if (!record) 2121 return; 2122 newComp = normalizeClassComponent(newComp); 2123 // update initial def (for not-yet-rendered components) 2124 updateComponentDef(record.initialDef, newComp); 2125 // create a snapshot which avoids the set being mutated during updates 2126 const instances = [...record.instances]; 2127 for (const instance of instances) { 2128 const oldComp = normalizeClassComponent(instance.type); 2129 if (!hmrDirtyComponents.has(oldComp)) { 2130 // 1. Update existing comp definition to match new one 2131 if (oldComp !== record.initialDef) { 2132 updateComponentDef(oldComp, newComp); 2133 } 2134 // 2. mark definition dirty. This forces the renderer to replace the 2135 // component on patch. 2136 hmrDirtyComponents.add(oldComp); 2137 } 2138 // 3. invalidate options resolution cache 2139 instance.appContext.optionsCache.delete(instance.type); 2140 // 4. actually update 2141 if (instance.ceReload) { 2142 // custom element 2143 hmrDirtyComponents.add(oldComp); 2144 instance.ceReload(newComp.styles); 2145 hmrDirtyComponents.delete(oldComp); 2146 } 2147 else if (instance.parent) { 2148 // 4. Force the parent instance to re-render. This will cause all updated 2149 // components to be unmounted and re-mounted. Queue the update so that we 2150 // don't end up forcing the same parent to re-render multiple times. 2151 queueJob(instance.parent.update); 2152 } 2153 else if (instance.appContext.reload) { 2154 // root instance mounted via createApp() has a reload method 2155 instance.appContext.reload(); 2156 } 2157 else if (typeof window !== 'undefined') { 2158 // root instance inside tree created via raw render(). Force reload. 2159 window.location.reload(); 2160 } 2161 else { 2162 console.warn('[HMR] Root or manually mounted instance modified. Full reload required.'); 2163 } 2164 } 2165 // 5. make sure to cleanup dirty hmr components after update 2166 queuePostFlushCb(() => { 2167 for (const instance of instances) { 2168 hmrDirtyComponents.delete(normalizeClassComponent(instance.type)); 2169 } 2170 }); 2171 } 2172 function updateComponentDef(oldComp, newComp) { 2173 extend(oldComp, newComp); 2174 for (const key in oldComp) { 2175 if (key !== '__file' && !(key in newComp)) {
2176 delete oldComp[key]; 2177 } 2178 } 2179 } 2180 function tryWrap(fn) { 2181 return (id, arg) => { 2182 try { 2183 return fn(id, arg); 2184 } 2185 catch (e) { 2186 console.error(e); 2187 console.warn(`[HMR] Something went wrong during Vue component hot-reload. ` + 2188 `Full reload required.`); 2189 } 2190 }; 2191 } 2192 2193 exports.devtools = void 0; 2194 let buffer = []; 2195 let devtoolsNotInstalled = false; 2196 function emit$1(event, ...args) { 2197 if (exports.devtools) { 2198 exports.devtools.emit(event, ...args); 2199 } 2200 else if (!devtoolsNotInstalled) { 2201 buffer.push({ event, args }); 2202 } 2203 } 2204 function setDevtoolsHook(hook, target) { 2205 var _a, _b; 2206 exports.devtools = hook; 2207 if (exports.devtools) { 2208 exports.devtools.enabled = true; 2209 buffer.forEach(({ event, args }) => exports.devtools.emit(event, ...args)); 2210 buffer = []; 2211 } 2212 else if ( 2213 // handle late devtools injection - only do this if we are in an actual 2214 // browser environment to avoid the timer handle stalling test runner exit 2215 // (#4815) 2216 typeof window !== 'undefined' && 2217 // some envs mock window but not fully 2218 window.HTMLElement && 2219 // also exclude jsdom 2220 !((_b = (_a = window.navigator) === null || _a === void 0 ? void 0 : _a.userAgent) === null || _b === void 0 ? void 0 : _b.includes('jsdom'))) { 2221 const replay = (target.__VUE_DEVTOOLS_HOOK_REPLAY__ = 2222 target.__VUE_DEVTOOLS_HOOK_REPLAY__ || []); 2223 replay.push((newHook) => { 2224 setDevtoolsHook(newHook, target); 2225 }); 2226 // clear buffer after 3s - the user probably doesn't have devtools installed 2227 // at all, and keeping the buffer will cause memory leaks (#4738) 2228 setTimeout(() => { 2229 if (!exports.devtools) { 2230 target.__VUE_DEVTOOLS_HOOK_REPLAY__ = null; 2231 devtoolsNotInstalled = true; 2232 buffer = []; 2233 } 2234 }, 3000); 2235 } 2236 else { 2237 // non-browser env, assume not installed 2238 devtoolsNotInstalled = true; 2239 buffer = []; 2240 } 2241 } 2242 function devtoolsInitApp(app, version) { 2243 emit$1("app:init" /* DevtoolsHooks.APP_INIT */, app, version, { 2244 Fragment, 2245 Text, 2246 Comment, 2247 Static 2248 }); 2249 } 2250 function devtoolsUnmountApp(app) { 2251 emit$1("app:unmount" /* DevtoolsHooks.APP_UNMOUNT */, app); 2252 } 2253 const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook("component:added" /* DevtoolsHooks.COMPONENT_ADDED */); 2254 const devtoolsComponentUpdated = 2255 /*#__PURE__*/ createDevtoolsComponentHook("component:updated" /* DevtoolsHooks.COMPONENT_UPDATED */); 2256 const _devtoolsComponentRemoved = /*#__PURE__*/ createDevtoolsComponentHook("component:removed" /* DevtoolsHooks.COMPONENT_REMOVED */); 2257 const devtoolsComponentRemoved = (component) => { 2258 if (exports.devtools && 2259 typeof exports.devtools.cleanupBuffer === 'function' && 2260 // remove the component if it wasn't buffered 2261 !exports.devtools.cleanupBuffer(component)) { 2262 _devtoolsComponentRemoved(component); 2263 } 2264 }; 2265 function createDevtoolsComponentHook(hook) { 2266 return (component) => { 2267 emit$1(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined, component); 2268 }; 2269 } 2270 const devtoolsPerfStart = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:start" /* DevtoolsHooks.PERFORMANCE_START */); 2271 const devtoolsPerfEnd = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:end" /* DevtoolsHooks.PERFORMANCE_END */); 2272 function createDevtoolsPerformanceHook(hook) { 2273 return (component, type, time) => { 2274 emit$1(hook, component.appContext.app, component.uid, component, type, time); 2275 }; 2276 } 2277 function devtoolsComponentEmit(component, event, params) { 2278 emit$1("component:emit" /* DevtoolsHooks.COMPONENT_EMIT */, component.appContext.app, component, event, params); 2279 } 2280 2281 function emit(instance, event, ...rawArgs) { 2282 if (instance.isUnmounted) 2283 return; 2284 const props = instance.vnode.props || EMPTY_OBJ; 2285 { 2286 const { emitsOptions, propsOptions: [propsOptions] } = instance; 2287 if (emitsOptions) { 2288 if (!(event in emitsOptions) && 2289 !(false )) { 2290 if (!propsOptions || !(toHandlerKey(event) in propsOptions)) { 2291 warn(`Component emitted event "${event}" but it is neither declared in ` + 2292 `the emits option nor as an "${toHandlerKey(event)}" prop.`); 2293 } 2294 } 2295 else { 2296 const validator = emitsOptions[event];
2297 if (isFunction(validator)) { 2298 const isValid = validator(...rawArgs); 2299 if (!isValid) { 2300 warn(`Invalid event arguments: event validation failed for event "${event}".`); 2301 } 2302 } 2303 } 2304 } 2305 } 2306 let args = rawArgs; 2307 const isModelListener = event.startsWith('update:'); 2308 // for v-model update:xxx events, apply modifiers on args 2309 const modelArg = isModelListener && event.slice(7); 2310 if (modelArg && modelArg in props) { 2311 const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`; 2312 const { number, trim } = props[modifiersKey] || EMPTY_OBJ; 2313 if (trim) { 2314 args = rawArgs.map(a => (isString(a) ? a.trim() : a)); 2315 } 2316 if (number) { 2317 args = rawArgs.map(looseToNumber); 2318 } 2319 } 2320 { 2321 devtoolsComponentEmit(instance, event, args); 2322 } 2323 { 2324 const lowerCaseEvent = event.toLowerCase(); 2325 if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) { 2326 warn(`Event "${lowerCaseEvent}" is emitted in component ` + 2327 `${formatComponentName(instance, instance.type)} but the handler is registered for "${event}". ` + 2328 `Note that HTML attributes are case-insensitive and you cannot use ` + 2329 `v-on to listen to camelCase events when using in-DOM templates. ` + 2330 `You should probably use "${hyphenate(event)}" instead of "${event}".`); 2331 } 2332 } 2333 let handlerName; 2334 let handler = props[(handlerName = toHandlerKey(event))] || 2335 // also try camelCase event handler (#2249) 2336 props[(handlerName = toHandlerKey(camelize(event)))]; 2337 // for v-model update:xxx events, also trigger kebab-case equivalent 2338 // for props passed via kebab-case 2339 if (!handler && isModelListener) { 2340 handler = props[(handlerName = toHandlerKey(hyphenate(event)))]; 2341 } 2342 if (handler) { 2343 callWithAsyncErrorHandling(handler, instance, 6 /* ErrorCodes.COMPONENT_EVENT_HANDLER */, args); 2344 } 2345 const onceHandler = props[handlerName + `Once`]; 2346 if (onceHandler) { 2347 if (!instance.emitted) { 2348 instance.emitted = {}; 2349 } 2350 else if (instance.emitted[handlerName]) { 2351 return; 2352 } 2353 instance.emitted[handlerName] = true; 2354 callWithAsyncErrorHandling(onceHandler, instance, 6 /* ErrorCodes.COMPONENT_EVENT_HANDLER */, args); 2355 } 2356 } 2357 function normalizeEmitsOptions(comp, appContext, asMixin = false) { 2358 const cache = appContext.emitsCache; 2359 const cached = cache.get(comp); 2360 if (cached !== undefined) { 2361 return cached; 2362 } 2363 const raw = comp.emits; 2364 let normalized = {}; 2365 // apply mixin/extends props 2366 let hasExtends = false; 2367 if (!isFunction(comp)) { 2368 const extendEmits = (raw) => { 2369 const normalizedFromExtend = normalizeEmitsOptions(raw, appContext, true); 2370 if (normalizedFromExtend) { 2371 hasExtends = true; 2372 extend(normalized, normalizedFromExtend); 2373 } 2374 }; 2375 if (!asMixin && appContext.mixins.length) { 2376 appContext.mixins.forEach(extendEmits); 2377 } 2378 if (comp.extends) { 2379 extendEmits(comp.extends); 2380 } 2381 if (comp.mixins) { 2382 comp.mixins.forEach(extendEmits); 2383 } 2384 } 2385 if (!raw && !hasExtends) { 2386 if (isObject(comp)) { 2387 cache.set(comp, null); 2388 } 2389 return null; 2390 } 2391 if (isArray(raw)) { 2392 raw.forEach(key => (normalized[key] = null)); 2393 } 2394 else { 2395 extend(normalized, raw); 2396 } 2397 if (isObject(comp)) { 2398 cache.set(comp, normalized); 2399 } 2400 return normalized; 2401 } 2402 // Check if an incoming prop key is a declared emit event listener. 2403 // e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are 2404 // both considered matched listeners. 2405 function isEmitListener(options, key) { 2406 if (!options || !isOn(key)) { 2407 return false;
2408 } 2409 key = key.slice(2).replace(/Once$/, ''); 2410 return (hasOwn(options, key[0].toLowerCase() + key.slice(1)) || 2411 hasOwn(options, hyphenate(key)) || 2412 hasOwn(options, key)); 2413 } 2414 2415 /** 2416 * mark the current rendering instance for asset resolution (e.g. 2417 * resolveComponent, resolveDirective) during render 2418 */ 2419 let currentRenderingInstance = null; 2420 let currentScopeId = null; 2421 /** 2422 * Note: rendering calls maybe nested. The function returns the parent rendering 2423 * instance if present, which should be restored after the render is done: 2424 * 2425 * ```js 2426 * const prev = setCurrentRenderingInstance(i) 2427 * // ...render 2428 * setCurrentRenderingInstance(prev) 2429 * ``` 2430 */ 2431 function setCurrentRenderingInstance(instance) { 2432 const prev = currentRenderingInstance; 2433 currentRenderingInstance = instance; 2434 currentScopeId = (instance && instance.type.__scopeId) || null; 2435 return prev; 2436 } 2437 /** 2438 * Set scope id when creating hoisted vnodes. 2439 * @private compiler helper 2440 */ 2441 function pushScopeId(id) { 2442 currentScopeId = id; 2443 } 2444 /** 2445 * Technically we no longer need this after 3.0.8 but we need to keep the same 2446 * API for backwards compat w/ code generated by compilers. 2447 * @private 2448 */ 2449 function popScopeId() { 2450 currentScopeId = null; 2451 } 2452 /** 2453 * Only for backwards compat 2454 * @private 2455 */ 2456 const withScopeId = (_id) => withCtx; 2457 /** 2458 * Wrap a slot function to memoize current rendering instance 2459 * @private compiler helper 2460 */ 2461 function withCtx(fn, ctx = currentRenderingInstance, isNonScopedSlot // false only 2462 ) { 2463 if (!ctx) 2464 return fn; 2465 // already normalized 2466 if (fn._n) { 2467 return fn; 2468 } 2469 const renderFnWithContext = (...args) => { 2470 // If a user calls a compiled slot inside a template expression (#1745), it 2471 // can mess up block tracking, so by default we disable block tracking and 2472 // force bail out when invoking a compiled slot (indicated by the ._d flag). 2473 // This isn't necessary if rendering a compiled `<slot>`, so we flip the 2474 // ._d flag off when invoking the wrapped fn inside `renderSlot`. 2475 if (renderFnWithContext._d) { 2476 setBlockTracking(-1); 2477 } 2478 const prevInstance = setCurrentRenderingInstance(ctx); 2479 let res; 2480 try { 2481 res = fn(...args); 2482 } 2483 finally { 2484 setCurrentRenderingInstance(prevInstance); 2485 if (renderFnWithContext._d) { 2486 setBlockTracking(1); 2487 } 2488 } 2489 { 2490 devtoolsComponentUpdated(ctx); 2491 } 2492 return res; 2493 }; 2494 // mark normalized to avoid duplicated wrapping 2495 renderFnWithContext._n = true; 2496 // mark this as compiled by default 2497 // this is used in vnode.ts -> normalizeChildren() to set the slot 2498 // rendering flag. 2499 renderFnWithContext._c = true; 2500 // disable block tracking by default 2501 renderFnWithContext._d = true; 2502 return renderFnWithContext; 2503 } 2504 2505 /** 2506 * dev only flag to track whether $attrs was used during render. 2507 * If $attrs was used during render then the warning for failed attrs 2508 * fallthrough can be suppressed. 2509 */ 2510 let accessedAttrs = false; 2511 function markAttrsAccessed() { 2512 accessedAttrs = true; 2513 } 2514 function renderComponentRoot(instance) { 2515 const { type: Component, vnode, proxy, withProxy, props, propsOptions: [propsOptions], slots, attrs, emit, render, renderCache, data, setupState, ctx, inheritAttrs } = instance; 2516 let result; 2517 let fallthroughAttrs; 2518 const prev = setCurrentRenderingInstance(instance); 2519 { 2520 accessedAttrs = false; 2521 } 2522 try { 2523 if (vnode.shapeFlag & 4 /* ShapeFlags.STATEFUL_COMPONENT */) { 2524 // withProxy is a proxy with a different `has` trap only for 2525 // runtime-compiled render functions using `with` block. 2526 const proxyToUse = withProxy || proxy; 2527 result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx)); 2528 fallthroughAttrs = attrs; 2529 } 2530 else { 2531 // functional 2532 const render = Component; 2533 // in dev, mark attrs accessed if optional props (attrs === props) 2534 if (true && attrs === props) { 2535 markAttrsAccessed(); 2536 } 2537 result = normalizeVNode(render.length > 1 2538 ? render(props, true 2539 ? { 2540 get attrs() { 2541 markAttrsAccessed(); 2542 return attrs; 2543 }, 2544 slots, 2545 emit 2546 } 2547 : { attrs, slots, emit }) 2548 : render(props, null /* we know it doesn't need it */)); 2549 fallthroughAttrs = Component.props 2550 ? attrs 2551 : getFunctionalFallthrough(attrs); 2552 } 2553 } 2554 catch (err) { 2555 blockStack.length = 0; 2556 handleError(err, instance, 1 /* ErrorCodes.RENDER_FUNCTION */); 2557 result = createVNode(Comment); 2558 } 2559 // attr merging 2560 // in dev mode, comments are preserved, and it's possible for a template 2561 // to have comments along side the root element which makes it a fragment 2562 let root = result; 2563 let setRoot = undefined; 2564 if (result.patchFlag > 0 && 2565 result.patchFlag & 2048 /* PatchFlags.DEV_ROOT_FRAGMENT */) { 2566 [root, setRoot] = getChildRoot(result); 2567 } 2568 if (fallthroughAttrs && inheritAttrs !== false) {
2569 const keys = Object.keys(fallthroughAttrs); 2570 const { shapeFlag } = root; 2571 if (keys.length) { 2572 if (shapeFlag & (1 /* ShapeFlags.ELEMENT */ | 6 /* ShapeFlags.COMPONENT */)) { 2573 if (propsOptions && keys.some(isModelListener)) { 2574 // If a v-model listener (onUpdate:xxx) has a corresponding declared 2575 // prop, it indicates this component expects to handle v-model and 2576 // it should not fallthrough. 2577 // related: #1543, #1643, #1989 2578 fallthroughAttrs = filterModelListeners(fallthroughAttrs, propsOptions); 2579 } 2580 root = cloneVNode(root, fallthroughAttrs); 2581 } 2582 else if (!accessedAttrs && root.type !== Comment) { 2583 const allAttrs = Object.keys(attrs); 2584 const eventAttrs = []; 2585 const extraAttrs = []; 2586 for (let i = 0, l = allAttrs.length; i < l; i++) { 2587 const key = allAttrs[i]; 2588 if (isOn(key)) { 2589 // ignore v-model handlers when they fail to fallthrough 2590 if (!isModelListener(key)) { 2591 // remove `on`, lowercase first letter to reflect event casing 2592 // accurately 2593 eventAttrs.push(key[2].toLowerCase() + key.slice(3)); 2594 } 2595 } 2596 else { 2597 extraAttrs.push(key); 2598 } 2599 } 2600 if (extraAttrs.length) { 2601 warn(`Extraneous non-props attributes (` + 2602 `${extraAttrs.join(', ')}) ` + 2603 `were passed to component but could not be automatically inherited ` + 2604 `because component renders fragment or text root nodes.`); 2605 } 2606 if (eventAttrs.length) { 2607 warn(`Extraneous non-emits event listeners (` + 2608 `${eventAttrs.join(', ')}) ` + 2609 `were passed to component but could not be automatically inherited ` + 2610 `because component renders fragment or text root nodes. ` + 2611 `If the listener is intended to be a component custom event listener only, ` + 2612 `declare it using the "emits" option.`); 2613 } 2614 } 2615 } 2616 } 2617 // inherit directives 2618 if (vnode.dirs) { 2619 if (!isElementRoot(root)) { 2620 warn(`Runtime directive used on component with non-element root node. ` + 2621 `The directives will not function as intended.`); 2622 } 2623 // clone before mutating since the root may be a hoisted vnode 2624 root = cloneVNode(root); 2625 root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs; 2626 } 2627 // inherit transition data 2628 if (vnode.transition) { 2629 if (!isElementRoot(root)) { 2630 warn(`Component inside <Transition> renders non-element root node ` + 2631 `that cannot be animated.`); 2632 } 2633 root.transition = vnode.transition; 2634 } 2635 if (setRoot) { 2636 setRoot(root); 2637 } 2638 else { 2639 result = root; 2640 } 2641 setCurrentRenderingInstance(prev); 2642 return result; 2643 } 2644 /** 2645 * dev only 2646 * In dev mode, template root level comments are rendered, which turns the 2647 * template into a fragment root, but we need to locate the single element 2648 * root for attrs and scope id processing. 2649 */ 2650 const getChildRoot = (vnode) => { 2651 const rawChildren = vnode.children; 2652 const dynamicChildren = vnode.dynamicChildren; 2653 const childRoot = filterSingleRoot(rawChildren); 2654 if (!childRoot) { 2655 return [vnode, undefined]; 2656 } 2657 const index = rawChildren.indexOf(childRoot); 2658 const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1; 2659 const setRoot = (updatedRoot) => { 2660 rawChildren[index] = updatedRoot; 2661 if (dynamicChildren) { 2662 if (dynamicIndex > -1) { 2663 dynamicChildren[dynamicIndex] = updatedRoot; 2664 } 2665 else if (updatedRoot.patchFlag > 0) { 2666 vnode.dynamicChildren = [...dynamicChildren, updatedRoot]; 2667 } 2668 } 2669 }; 2670 return [normalizeVNode(childRoot), setRoot]; 2671 }; 2672 function filterSingleRoot(children) { 2673 let singleRoot; 2674 for (let i = 0; i < children.length; i++) { 2675 const child = children[i]; 2676 if (isVNode(child)) { 2677 // ignore user comment 2678 if (child.type !== Comment || child.children === 'v-if') { 2679 if (singleRoot) { 2680 // has more than 1 non-comment child, return now 2681 return; 2682 } 2683 else { 2684 singleRoot = child; 2685 } 2686 } 2687 } 2688 else { 2689 return; 2690 } 2691 } 2692 return singleRoot; 2693 } 2694 const getFunctionalFallthrough = (attrs) => { 2695 let res; 2696 for (const key in attrs) {
2697 if (key === 'class' || key === 'style' || isOn(key)) { 2698 (res || (res = {}))[key] = attrs[key]; 2699 } 2700 } 2701 return res; 2702 }; 2703 const filterModelListeners = (attrs, props) => { 2704 const res = {}; 2705 for (const key in attrs) { 2706 if (!isModelListener(key) || !(key.slice(9) in props)) { 2707 res[key] = attrs[key]; 2708 } 2709 } 2710 return res; 2711 }; 2712 const isElementRoot = (vnode) => { 2713 return (vnode.shapeFlag & (6 /* ShapeFlags.COMPONENT */ | 1 /* ShapeFlags.ELEMENT */) || 2714 vnode.type === Comment // potential v-if branch switch 2715 ); 2716 }; 2717 function shouldUpdateComponent(prevVNode, nextVNode, optimized) { 2718 const { props: prevProps, children: prevChildren, component } = prevVNode; 2719 const { props: nextProps, children: nextChildren, patchFlag } = nextVNode; 2720 const emits = component.emitsOptions; 2721 // Parent component's render function was hot-updated. Since this may have 2722 // caused the child component's slots content to have changed, we need to 2723 // force the child to update as well. 2724 if ((prevChildren || nextChildren) && isHmrUpdating) { 2725 return true; 2726 } 2727 // force child update for runtime directive or transition on component vnode. 2728 if (nextVNode.dirs || nextVNode.transition) { 2729 return true; 2730 } 2731 if (optimized && patchFlag >= 0) { 2732 if (patchFlag & 1024 /* PatchFlags.DYNAMIC_SLOTS */) { 2733 // slot content that references values that might have changed, 2734 // e.g. in a v-for 2735 return true; 2736 } 2737 if (patchFlag & 16 /* PatchFlags.FULL_PROPS */) { 2738 if (!prevProps) { 2739 return !!nextProps; 2740 } 2741 // presence of this flag indicates props are always non-null 2742 return hasPropsChanged(prevProps, nextProps, emits); 2743 } 2744 else if (patchFlag & 8 /* PatchFlags.PROPS */) { 2745 const dynamicProps = nextVNode.dynamicProps; 2746 for (let i = 0; i < dynamicProps.length; i++) { 2747 const key = dynamicProps[i]; 2748 if (nextProps[key] !== prevProps[key] && 2749 !isEmitListener(emits, key)) { 2750 return true; 2751 } 2752 } 2753 } 2754 } 2755 else { 2756 // this path is only taken by manually written render functions 2757 // so presence of any children leads to a forced update 2758 if (prevChildren || nextChildren) { 2759 if (!nextChildren || !nextChildren.$stable) { 2760 return true; 2761 } 2762 } 2763 if (prevProps === nextProps) { 2764 return false; 2765 } 2766 if (!prevProps) { 2767 return !!nextProps; 2768 } 2769 if (!nextProps) { 2770 return true; 2771 } 2772 return hasPropsChanged(prevProps, nextProps, emits); 2773 } 2774 return false; 2775 } 2776 function hasPropsChanged(prevProps, nextProps, emitsOptions) { 2777 const nextKeys = Object.keys(nextProps); 2778 if (nextKeys.length !== Object.keys(prevProps).length) { 2779 return true; 2780 } 2781 for (let i = 0; i < nextKeys.length; i++) { 2782 const key = nextKeys[i]; 2783 if (nextProps[key] !== prevProps[key] && 2784 !isEmitListener(emitsOptions, key)) { 2785 return true; 2786 } 2787 } 2788 return false; 2789 } 2790 function updateHOCHostEl({ vnode, parent }, el // HostNode 2791 ) { 2792 while (parent && parent.subTree === vnode) { 2793 (vnode = parent.vnode).el = el; 2794 parent = parent.parent; 2795 } 2796 } 2797 2798 const isSuspense = (type) => type.__isSuspense; 2799 // Suspense exposes a component-like API, and is treated like a component 2800 // in the compiler, but internally it's a special built-in type that hooks 2801 // directly into the renderer. 2802 const SuspenseImpl = { 2803 name: 'Suspense', 2804 // In order to make Suspense tree-shakable, we need to avoid importing it 2805 // directly in the renderer. The renderer checks for the __isSuspense flag 2806 // on a vnode's type and calls the `process` method, passing in renderer 2807 // internals. 2808 __isSuspense: true, 2809 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, 2810 // platform-specific impl passed from renderer 2811 rendererInternals) { 2812 if (n1 == null) { 2813 mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals); 2814 } 2815 else { 2816 patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, rendererInternals); 2817 } 2818 }, 2819 hydrate: hydrateSuspense, 2820 create: createSuspenseBoundary, 2821 normalize: normalizeSuspenseChildren 2822 }; 2823 // Force-casted public typing for h and TSX props inference 2824 const Suspense = (SuspenseImpl 2825 ); 2826 function triggerEvent(vnode, name) { 2827 const eventListener = vnode.props && vnode.props[name]; 2828 if (isFunction(eventListener)) { 2829 eventListener(); 2830 } 2831 } 2832 function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals) { 2833 const { p: patch, o: { createElement } } = rendererInternals; 2834 const hiddenContainer = createElement('div'); 2835 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals)); 2836 // start mounting the content subtree in an off-dom container 2837 patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds); 2838 // now check if we have encountered any async deps 2839 if (suspense.deps > 0) { 2840 // has async 2841 // invoke @fallback event 2842 triggerEvent(vnode, 'onPending'); 2843 triggerEvent(vnode, 'onFallback'); 2844 // mount the fallback tree 2845 patch(null, vnode.ssFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context 2846 isSVG, slotScopeIds);
2847 setActiveBranch(suspense, vnode.ssFallback); 2848 } 2849 else { 2850 // Suspense has no async deps. Just resolve. 2851 suspense.resolve(); 2852 } 2853 } 2854 function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, { p: patch, um: unmount, o: { createElement } }) { 2855 const suspense = (n2.suspense = n1.suspense); 2856 suspense.vnode = n2; 2857 n2.el = n1.el; 2858 const newBranch = n2.ssContent; 2859 const newFallback = n2.ssFallback; 2860 const { activeBranch, pendingBranch, isInFallback, isHydrating } = suspense; 2861 if (pendingBranch) { 2862 suspense.pendingBranch = newBranch; 2863 if (isSameVNodeType(newBranch, pendingBranch)) { 2864 // same root type but content may have changed. 2865 patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized); 2866 if (suspense.deps <= 0) { 2867 suspense.resolve(); 2868 } 2869 else if (isInFallback) { 2870 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context 2871 isSVG, slotScopeIds, optimized);
2872 setActiveBranch(suspense, newFallback); 2873 } 2874 } 2875 else { 2876 // toggled before pending tree is resolved 2877 suspense.pendingId++; 2878 if (isHydrating) { 2879 // if toggled before hydration is finished, the current DOM tree is 2880 // no longer valid. set it as the active branch so it will be unmounted 2881 // when resolved 2882 suspense.isHydrating = false; 2883 suspense.activeBranch = pendingBranch; 2884 } 2885 else { 2886 unmount(pendingBranch, parentComponent, suspense); 2887 } 2888 // increment pending ID. this is used to invalidate async callbacks 2889 // reset suspense state 2890 suspense.deps = 0; 2891 // discard effects from pending branch 2892 suspense.effects.length = 0; 2893 // discard previous container 2894 suspense.hiddenContainer = createElement('div'); 2895 if (isInFallback) { 2896 // already in fallback state 2897 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized); 2898 if (suspense.deps <= 0) { 2899 suspense.resolve(); 2900 } 2901 else { 2902 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context 2903 isSVG, slotScopeIds, optimized);
2904 setActiveBranch(suspense, newFallback); 2905 } 2906 } 2907 else if (activeBranch && isSameVNodeType(newBranch, activeBranch)) { 2908 // toggled "back" to current active branch 2909 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized); 2910 // force resolve 2911 suspense.resolve(true); 2912 } 2913 else { 2914 // switched to a 3rd branch 2915 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized); 2916 if (suspense.deps <= 0) { 2917 suspense.resolve(); 2918 } 2919 } 2920 } 2921 } 2922 else { 2923 if (activeBranch && isSameVNodeType(newBranch, activeBranch)) { 2924 // root did not change, just normal patch 2925 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2926 setActiveBranch(suspense, newBranch); 2927 } 2928 else { 2929 // root node toggled 2930 // invoke @pending event 2931 triggerEvent(n2, 'onPending'); 2932 // mount pending branch in off-dom container 2933 suspense.pendingBranch = newBranch; 2934 suspense.pendingId++; 2935 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized); 2936 if (suspense.deps <= 0) { 2937 // incoming branch has no async deps, resolve now. 2938 suspense.resolve(); 2939 } 2940 else { 2941 const { timeout, pendingId } = suspense; 2942 if (timeout > 0) { 2943 setTimeout(() => { 2944 if (suspense.pendingId === pendingId) { 2945 suspense.fallback(newFallback); 2946 } 2947 }, timeout); 2948 } 2949 else if (timeout === 0) { 2950 suspense.fallback(newFallback); 2951 } 2952 } 2953 } 2954 } 2955 } 2956 let hasWarned = false; 2957 function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals, isHydrating = false) { 2958 /* istanbul ignore if */ 2959 if (!hasWarned) { 2960 hasWarned = true; 2961 // @ts-ignore `console.info` cannot be null error 2962 console[console.info ? 'info' : 'log'](`<Suspense> is an experimental feature and its API will likely change.`); 2963 } 2964 const { p: patch, m: move, um: unmount, n: next, o: { parentNode, remove } } = rendererInternals; 2965 const timeout = vnode.props ? toNumber(vnode.props.timeout) : undefined; 2966 { 2967 assertNumber(timeout, `Suspense timeout`); 2968 } 2969 const suspense = { 2970 vnode, 2971 parent, 2972 parentComponent, 2973 isSVG, 2974 container, 2975 hiddenContainer, 2976 anchor, 2977 deps: 0, 2978 pendingId: 0, 2979 timeout: typeof timeout === 'number' ? timeout : -1, 2980 activeBranch: null, 2981 pendingBranch: null, 2982 isInFallback: true, 2983 isHydrating, 2984 isUnmounted: false, 2985 effects: [], 2986 resolve(resume = false) { 2987 { 2988 if (!resume && !suspense.pendingBranch) { 2989 throw new Error(`suspense.resolve() is called without a pending branch.`); 2990 } 2991 if (suspense.isUnmounted) { 2992 throw new Error(`suspense.resolve() is called on an already unmounted suspense boundary.`); 2993 } 2994 } 2995 const { vnode, activeBranch, pendingBranch, pendingId, effects, parentComponent, container } = suspense; 2996 if (suspense.isHydrating) { 2997 suspense.isHydrating = false; 2998 } 2999 else if (!resume) { 3000 const delayEnter = activeBranch && 3001 pendingBranch.transition && 3002 pendingBranch.transition.mode === 'out-in'; 3003 if (delayEnter) { 3004 activeBranch.transition.afterLeave = () => { 3005 if (pendingId === suspense.pendingId) { 3006 move(pendingBranch, container, anchor, 0 /* MoveType.ENTER */); 3007 } 3008 }; 3009 } 3010 // this is initial anchor on mount 3011 let { anchor } = suspense; 3012 // unmount current active tree 3013 if (activeBranch) { 3014 // if the fallback tree was mounted, it may have been moved 3015 // as part of a parent suspense. get the latest anchor for insertion 3016 anchor = next(activeBranch); 3017 unmount(activeBranch, parentComponent, suspense, true); 3018 } 3019 if (!delayEnter) { 3020 // move content from off-dom container to actual container 3021 move(pendingBranch, container, anchor, 0 /* MoveType.ENTER */); 3022 } 3023 }
3024 setActiveBranch(suspense, pendingBranch); 3025 suspense.pendingBranch = null; 3026 suspense.isInFallback = false; 3027 // flush buffered effects 3028 // check if there is a pending parent suspense 3029 let parent = suspense.parent; 3030 let hasUnresolvedAncestor = false; 3031 while (parent) { 3032 if (parent.pendingBranch) { 3033 // found a pending parent suspense, merge buffered post jobs 3034 // into that parent 3035 parent.effects.push(...effects); 3036 hasUnresolvedAncestor = true; 3037 break; 3038 } 3039 parent = parent.parent; 3040 } 3041 // no pending parent suspense, flush all jobs 3042 if (!hasUnresolvedAncestor) { 3043 queuePostFlushCb(effects); 3044 } 3045 suspense.effects = []; 3046 // invoke @resolve event 3047 triggerEvent(vnode, 'onResolve'); 3048 }, 3049 fallback(fallbackVNode) { 3050 if (!suspense.pendingBranch) { 3051 return; 3052 } 3053 const { vnode, activeBranch, parentComponent, container, isSVG } = suspense; 3054 // invoke @fallback event 3055 triggerEvent(vnode, 'onFallback'); 3056 const anchor = next(activeBranch); 3057 const mountFallback = () => { 3058 if (!suspense.isInFallback) { 3059 return; 3060 } 3061 // mount the fallback tree 3062 patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context 3063 isSVG, slotScopeIds, optimized);
3064 setActiveBranch(suspense, fallbackVNode); 3065 }; 3066 const delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in'; 3067 if (delayEnter) { 3068 activeBranch.transition.afterLeave = mountFallback; 3069 } 3070 suspense.isInFallback = true; 3071 // unmount current active branch 3072 unmount(activeBranch, parentComponent, null, // no suspense so unmount hooks fire now 3073 true // shouldRemove 3074 ); 3075 if (!delayEnter) { 3076 mountFallback(); 3077 } 3078 }, 3079 move(container, anchor, type) { 3080 suspense.activeBranch && 3081 move(suspense.activeBranch, container, anchor, type); 3082 suspense.container = container; 3083 }, 3084 next() { 3085 return suspense.activeBranch && next(suspense.activeBranch); 3086 }, 3087 registerDep(instance, setupRenderEffect) { 3088 const isInPendingSuspense = !!suspense.pendingBranch; 3089 if (isInPendingSuspense) { 3090 suspense.deps++; 3091 } 3092 const hydratedEl = instance.vnode.el; 3093 instance 3094 .asyncDep.catch(err => { 3095 handleError(err, instance, 0 /* ErrorCodes.SETUP_FUNCTION */); 3096 }) 3097 .then(asyncSetupResult => { 3098 // retry when the setup() promise resolves. 3099 // component may have been unmounted before resolve. 3100 if (instance.isUnmounted || 3101 suspense.isUnmounted || 3102 suspense.pendingId !== instance.suspenseId) { 3103 return; 3104 } 3105 // retry from this component 3106 instance.asyncResolved = true; 3107 const { vnode } = instance; 3108 { 3109 pushWarningContext(vnode); 3110 } 3111 handleSetupResult(instance, asyncSetupResult, false); 3112 if (hydratedEl) { 3113 // vnode may have been replaced if an update happened before the 3114 // async dep is resolved. 3115 vnode.el = hydratedEl; 3116 } 3117 const placeholder = !hydratedEl && instance.subTree.el; 3118 setupRenderEffect(instance, vnode, 3119 // component may have been moved before resolve. 3120 // if this is not a hydration, instance.subTree will be the comment 3121 // placeholder. 3122 parentNode(hydratedEl || instance.subTree.el), 3123 // anchor will not be used if this is hydration, so only need to 3124 // consider the comment placeholder case. 3125 hydratedEl ? null : next(instance.subTree), suspense, isSVG, optimized); 3126 if (placeholder) { 3127 remove(placeholder); 3128 } 3129 updateHOCHostEl(instance, vnode.el); 3130 { 3131 popWarningContext(); 3132 } 3133 // only decrease deps count if suspense is not already resolved 3134 if (isInPendingSuspense && --suspense.deps === 0) { 3135 suspense.resolve(); 3136 } 3137 }); 3138 }, 3139 unmount(parentSuspense, doRemove) { 3140 suspense.isUnmounted = true; 3141 if (suspense.activeBranch) { 3142 unmount(suspense.activeBranch, parentComponent, parentSuspense, doRemove); 3143 } 3144 if (suspense.pendingBranch) { 3145 unmount(suspense.pendingBranch, parentComponent, parentSuspense, doRemove); 3146 } 3147 } 3148 }; 3149 return suspense; 3150 } 3151 function hydrateSuspense(node, vnode, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals, hydrateNode) { 3152 /* eslint-disable no-restricted-globals */ 3153 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, node.parentNode, document.createElement('div'), null, isSVG, slotScopeIds, optimized, rendererInternals, true /* hydrating */)); 3154 // there are two possible scenarios for server-rendered suspense: 3155 // - success: ssr content should be fully resolved 3156 // - failure: ssr content should be the fallback branch. 3157 // however, on the client we don't really know if it has failed or not 3158 // attempt to hydrate the DOM assuming it has succeeded, but we still 3159 // need to construct a suspense boundary first 3160 const result = hydrateNode(node, (suspense.pendingBranch = vnode.ssContent), parentComponent, suspense, slotScopeIds, optimized); 3161 if (suspense.deps === 0) { 3162 suspense.resolve(); 3163 } 3164 return result; 3165 /* eslint-enable no-restricted-globals */ 3166 } 3167 function normalizeSuspenseChildren(vnode) { 3168 const { shapeFlag, children } = vnode; 3169 const isSlotChildren = shapeFlag & 32 /* ShapeFlags.SLOTS_CHILDREN */; 3170 vnode.ssContent = normalizeSuspenseSlot(isSlotChildren ? children.default : children); 3171 vnode.ssFallback = isSlotChildren 3172 ? normalizeSuspenseSlot(children.fallback) 3173 : createVNode(Comment); 3174 } 3175 function normalizeSuspenseSlot(s) { 3176 let block; 3177 if (isFunction(s)) { 3178 const trackBlock = isBlockTreeEnabled && s._c; 3179 if (trackBlock) { 3180 // disableTracking: false 3181 // allow block tracking for compiled slots 3182 // (see ./componentRenderContext.ts) 3183 s._d = false;
3184 openBlock(); 3185 } 3186 s = s(); 3187 if (trackBlock) { 3188 s._d = true; 3189 block = currentBlock; 3190 closeBlock(); 3191 } 3192 } 3193 if (isArray(s)) { 3194 const singleChild = filterSingleRoot(s); 3195 if (!singleChild) { 3196 warn(`<Suspense> slots expect a single root node.`); 3197 } 3198 s = singleChild; 3199 } 3200 s = normalizeVNode(s); 3201 if (block && !s.dynamicChildren) { 3202 s.dynamicChildren = block.filter(c => c !== s); 3203 } 3204 return s; 3205 } 3206 function queueEffectWithSuspense(fn, suspense) { 3207 if (suspense && suspense.pendingBranch) { 3208 if (isArray(fn)) { 3209 suspense.effects.push(...fn); 3210 } 3211 else { 3212 suspense.effects.push(fn); 3213 } 3214 } 3215 else { 3216 queuePostFlushCb(fn); 3217 } 3218 } 3219 function setActiveBranch(suspense, branch) { 3220 suspense.activeBranch = branch; 3221 const { vnode, parentComponent } = suspense; 3222 const el = (vnode.el = branch.el); 3223 // in case suspense is the root node of a component, 3224 // recursively update the HOC el 3225 if (parentComponent && parentComponent.subTree === vnode) { 3226 parentComponent.vnode.el = el; 3227 updateHOCHostEl(parentComponent, el); 3228 } 3229 } 3230 3231 function provide(key, value) { 3232 if (!currentInstance) { 3233 { 3234 warn(`provide() can only be used inside setup().`); 3235 } 3236 } 3237 else { 3238 let provides = currentInstance.provides; 3239 // by default an instance inherits its parent's provides object 3240 // but when it needs to provide values of its own, it creates its 3241 // own provides object using parent provides object as prototype. 3242 // this way in `inject` we can simply look up injections from direct 3243 // parent and let the prototype chain do the work. 3244 const parentProvides = currentInstance.parent && currentInstance.parent.provides; 3245 if (parentProvides === provides) { 3246 provides = currentInstance.provides = Object.create(parentProvides); 3247 } 3248 // TS doesn't allow symbol as index type 3249 provides[key] = value; 3250 } 3251 } 3252 function inject(key, defaultValue, treatDefaultAsFactory = false) { 3253 // fallback to `currentRenderingInstance` so that this can be called in 3254 // a functional component 3255 const instance = currentInstance || currentRenderingInstance; 3256 if (instance) { 3257 // #2400 3258 // to support `app.use` plugins, 3259 // fallback to appContext's `provides` if the instance is at root 3260 const provides = instance.parent == null 3261 ? instance.vnode.appContext && instance.vnode.appContext.provides 3262 : instance.parent.provides; 3263 if (provides && key in provides) { 3264 // TS doesn't allow symbol as index type 3265 return provides[key]; 3266 } 3267 else if (arguments.length > 1) { 3268 return treatDefaultAsFactory && isFunction(defaultValue) 3269 ? defaultValue.call(instance.proxy) 3270 : defaultValue; 3271 } 3272 else { 3273 warn(`injection "${String(key)}" not found.`); 3274 } 3275 } 3276 else { 3277 warn(`inject() can only be used inside setup() or functional components.`); 3278 } 3279 } 3280 3281 // Simple effect. 3282 function watchEffect(effect, options) { 3283 return doWatch(effect, null, options); 3284 } 3285 function watchPostEffect(effect, options) { 3286 return doWatch(effect, null, Object.assign(Object.assign({}, options), { flush: 'post' }) ); 3287 } 3288 function watchSyncEffect(effect, options) { 3289 return doWatch(effect, null, Object.assign(Object.assign({}, options), { flush: 'sync' }) ); 3290 } 3291 // initial value for watchers to trigger on undefined initial values 3292 const INITIAL_WATCHER_VALUE = {}; 3293 // implementation 3294 function watch(source, cb, options) { 3295 if (!isFunction(cb)) { 3296 warn(`\`watch(fn, options?)\` signature has been moved to a separate API. ` + 3297 `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` + 3298 `supports \`watch(source, cb, options?) signature.`); 3299 } 3300 return doWatch(source, cb, options); 3301 } 3302 function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EMPTY_OBJ) { 3303 if (!cb) { 3304 if (immediate !== undefined) { 3305 warn(`watch() "immediate" option is only respected when using the ` + 3306 `watch(source, callback, options?) signature.`); 3307 } 3308 if (deep !== undefined) { 3309 warn(`watch() "deep" option is only respected when using the ` + 3310 `watch(source, callback, options?) signature.`); 3311 } 3312 }
3313 const warnInvalidSource = (s) => { 3314 warn(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` + 3315 `a reactive object, or an array of these types.`); 3316 }; 3317 const instance = getCurrentScope() === (currentInstance === null || currentInstance === void 0 ? void 0 : currentInstance.scope) ? currentInstance : null; 3318 // const instance = currentInstance 3319 let getter; 3320 let forceTrigger = false; 3321 let isMultiSource = false; 3322 if (isRef(source)) { 3323 getter = () => source.value; 3324 forceTrigger = isShallow(source); 3325 } 3326 else if (isReactive(source)) { 3327 getter = () => source; 3328 deep = true; 3329 } 3330 else if (isArray(source)) { 3331 isMultiSource = true; 3332 forceTrigger = source.some(s => isReactive(s) || isShallow(s)); 3333 getter = () => source.map(s => { 3334 if (isRef(s)) { 3335 return s.value; 3336 } 3337 else if (isReactive(s)) { 3338 return traverse(s); 3339 } 3340 else if (isFunction(s)) { 3341 return callWithErrorHandling(s, instance, 2 /* ErrorCodes.WATCH_GETTER */); 3342 } 3343 else { 3344 warnInvalidSource(s); 3345 } 3346 }); 3347 } 3348 else if (isFunction(source)) { 3349 if (cb) { 3350 // getter with cb 3351 getter = () => callWithErrorHandling(source, instance, 2 /* ErrorCodes.WATCH_GETTER */); 3352 } 3353 else { 3354 // no cb -> simple effect 3355 getter = () => { 3356 if (instance && instance.isUnmounted) { 3357 return; 3358 } 3359 if (cleanup) { 3360 cleanup(); 3361 } 3362 return callWithAsyncErrorHandling(source, instance, 3 /* ErrorCodes.WATCH_CALLBACK */, [onCleanup]); 3363 }; 3364 } 3365 } 3366 else { 3367 getter = NOOP; 3368 warnInvalidSource(source); 3369 } 3370 if (cb && deep) { 3371 const baseGetter = getter; 3372 getter = () => traverse(baseGetter()); 3373 } 3374 let cleanup; 3375 let onCleanup = (fn) => { 3376 cleanup = effect.onStop = () => { 3377 callWithErrorHandling(fn, instance, 4 /* ErrorCodes.WATCH_CLEANUP */); 3378 }; 3379 }; 3380 let oldValue = isMultiSource 3381 ? new Array(source.length).fill(INITIAL_WATCHER_VALUE) 3382 : INITIAL_WATCHER_VALUE; 3383 const job = () => { 3384 if (!effect.active) { 3385 return; 3386 } 3387 if (cb) { 3388 // watch(source, cb) 3389 const newValue = effect.run(); 3390 if (deep || 3391 forceTrigger || 3392 (isMultiSource 3393 ? newValue.some((v, i) => hasChanged(v, oldValue[i])) 3394 : hasChanged(newValue, oldValue)) || 3395 (false )) { 3396 // cleanup before running cb again 3397 if (cleanup) { 3398 cleanup(); 3399 } 3400 callWithAsyncErrorHandling(cb, instance, 3 /* ErrorCodes.WATCH_CALLBACK */, [ 3401 newValue, 3402 // pass undefined as the old value when it's changed for the first time 3403 oldValue === INITIAL_WATCHER_VALUE 3404 ? undefined 3405 : isMultiSource && oldValue[0] === INITIAL_WATCHER_VALUE 3406 ? [] 3407 : oldValue, 3408 onCleanup 3409 ]); 3410 oldValue = newValue; 3411 } 3412 } 3413 else { 3414 // watchEffect 3415 effect.run(); 3416 } 3417 }; 3418 // important: mark the job as a watcher callback so that scheduler knows 3419 // it is allowed to self-trigger (#1727) 3420 job.allowRecurse = !!cb; 3421 let scheduler; 3422 if (flush === 'sync') { 3423 scheduler = job; // the scheduler function gets called directly 3424 } 3425 else if (flush === 'post') { 3426 scheduler = () => queuePostRenderEffect(job, instance && instance.suspense); 3427 } 3428 else { 3429 // default: 'pre' 3430 job.pre = true; 3431 if (instance) 3432 job.id = instance.uid; 3433 scheduler = () => queueJob(job); 3434 } 3435 const effect = new ReactiveEffect(getter, scheduler); 3436 { 3437 effect.onTrack = onTrack; 3438 effect.onTrigger = onTrigger; 3439 } 3440 // initial run 3441 if (cb) { 3442 if (immediate) { 3443 job(); 3444 } 3445 else { 3446 oldValue = effect.run(); 3447 } 3448 } 3449 else if (flush === 'post') { 3450 queuePostRenderEffect(effect.run.bind(effect), instance && instance.suspense); 3451 } 3452 else { 3453 effect.run(); 3454 } 3455 const unwatch = () => { 3456 effect.stop(); 3457 if (instance && instance.scope) { 3458 remove(instance.scope.effects, effect); 3459 } 3460 }; 3461 return unwatch; 3462 } 3463 // this.$watch 3464 function instanceWatch(source, value, options) { 3465 const publicThis = this.proxy; 3466 const getter = isString(source) 3467 ? source.includes('.') 3468 ? createPathGetter(publicThis, source) 3469 : () => publicThis[source] 3470 : source.bind(publicThis, publicThis); 3471 let cb; 3472 if (isFunction(value)) { 3473 cb = value; 3474 } 3475 else { 3476 cb = value.handler; 3477 options = value; 3478 } 3479 const cur = currentInstance; 3480 setCurrentInstance(this); 3481 const res = doWatch(getter, cb.bind(publicThis), options); 3482 if (cur) { 3483 setCurrentInstance(cur); 3484 } 3485 else { 3486 unsetCurrentInstance(); 3487 } 3488 return res; 3489 } 3490 function createPathGetter(ctx, path) { 3491 const segments = path.split('.'); 3492 return () => { 3493 let cur = ctx; 3494 for (let i = 0; i < segments.length && cur; i++) { 3495 cur = cur[segments[i]]; 3496 } 3497 return cur; 3498 }; 3499 } 3500 function traverse(value, seen) { 3501 if (!isObject(value) || value["__v_skip" /* ReactiveFlags.SKIP */]) { 3502 return value; 3503 } 3504 seen = seen || new Set(); 3505 if (seen.has(value)) { 3506 return value; 3507 } 3508 seen.add(value); 3509 if (isRef(value)) { 3510 traverse(value.value, seen); 3511 } 3512 else if (isArray(value)) { 3513 for (let i = 0; i < value.length; i++) { 3514 traverse(value[i], seen); 3515 } 3516 } 3517 else if (isSet(value) || isMap(value)) { 3518 value.forEach((v) => { 3519 traverse(v, seen); 3520 }); 3521 } 3522 else if (isPlainObject(value)) { 3523 for (const key in value) { 3524 traverse(value[key], seen); 3525 } 3526 } 3527 return value; 3528 } 3529 3530 function useTransitionState() { 3531 const state = { 3532 isMounted: false, 3533 isLeaving: false, 3534 isUnmounting: false, 3535 leavingVNodes: new Map() 3536 }; 3537 onMounted(() => { 3538 state.isMounted = true; 3539 }); 3540 onBeforeUnmount(() => { 3541 state.isUnmounting = true; 3542 }); 3543 return state; 3544 } 3545 const TransitionHookValidator = [Function, Array]; 3546 const BaseTransitionImpl = { 3547 name: `BaseTransition`, 3548 props: { 3549 mode: String, 3550 appear: Boolean, 3551 persisted: Boolean, 3552 // enter 3553 onBeforeEnter: TransitionHookValidator, 3554 onEnter: TransitionHookValidator, 3555 onAfterEnter: TransitionHookValidator, 3556 onEnterCancelled: TransitionHookValidator, 3557 // leave 3558 onBeforeLeave: TransitionHookValidator, 3559 onLeave: TransitionHookValidator, 3560 onAfterLeave: TransitionHookValidator, 3561 onLeaveCancelled: TransitionHookValidator, 3562 // appear 3563 onBeforeAppear: TransitionHookValidator, 3564 onAppear: TransitionHookValidator, 3565 onAfterAppear: TransitionHookValidator, 3566 onAppearCancelled: TransitionHookValidator 3567 }, 3568 setup(props, { slots }) { 3569 const instance = getCurrentInstance(); 3570 const state = useTransitionState(); 3571 let prevTransitionKey; 3572 return () => { 3573 const children = slots.default && getTransitionRawChildren(slots.default(), true); 3574 if (!children || !children.length) { 3575 return; 3576 } 3577 let child = children[0]; 3578 if (children.length > 1) { 3579 let hasFound = false;
3580 // locate first non-comment child 3581 for (const c of children) { 3582 if (c.type !== Comment) { 3583 if (hasFound) { 3584 // warn more than one non-comment child 3585 warn('<transition> can only be used on a single element or component. ' + 3586 'Use <transition-group> for lists.'); 3587 break; 3588 } 3589 child = c; 3590 hasFound = true; 3591 } 3592 } 3593 } 3594 // there's no need to track reactivity for these props so use the raw 3595 // props for a bit better perf 3596 const rawProps = toRaw(props); 3597 const { mode } = rawProps; 3598 // check mode 3599 if (mode && 3600 mode !== 'in-out' && 3601 mode !== 'out-in' && 3602 mode !== 'default') { 3603 warn(`invalid <transition> mode: ${mode}`); 3604 } 3605 if (state.isLeaving) { 3606 return emptyPlaceholder(child); 3607 } 3608 // in the case of <transition><keep-alive/></transition>, we need to 3609 // compare the type of the kept-alive children. 3610 const innerChild = getKeepAliveChild(child); 3611 if (!innerChild) { 3612 return emptyPlaceholder(child); 3613 } 3614 const enterHooks = resolveTransitionHooks(innerChild, rawProps, state, instance); 3615 setTransitionHooks(innerChild, enterHooks); 3616 const oldChild = instance.subTree; 3617 const oldInnerChild = oldChild && getKeepAliveChild(oldChild); 3618 let transitionKeyChanged = false; 3619 const { getTransitionKey } = innerChild.type; 3620 if (getTransitionKey) { 3621 const key = getTransitionKey(); 3622 if (prevTransitionKey === undefined) { 3623 prevTransitionKey = key; 3624 } 3625 else if (key !== prevTransitionKey) { 3626 prevTransitionKey = key; 3627 transitionKeyChanged = true; 3628 } 3629 } 3630 // handle mode 3631 if (oldInnerChild && 3632 oldInnerChild.type !== Comment && 3633 (!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)) { 3634 const leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance); 3635 // update old tree's hooks in case of dynamic transition 3636 setTransitionHooks(oldInnerChild, leavingHooks); 3637 // switching between different views 3638 if (mode === 'out-in') { 3639 state.isLeaving = true; 3640 // return placeholder node and queue update when leave finishes 3641 leavingHooks.afterLeave = () => { 3642 state.isLeaving = false; 3643 // #6835 3644 // it also needs to be updated when active is undefined 3645 if (instance.update.active !== false) { 3646 instance.update(); 3647 } 3648 }; 3649 return emptyPlaceholder(child); 3650 } 3651 else if (mode === 'in-out' && innerChild.type !== Comment) { 3652 leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => { 3653 const leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild); 3654 leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild; 3655 // early removal callback 3656 el._leaveCb = () => { 3657 earlyRemove(); 3658 el._leaveCb = undefined; 3659 delete enterHooks.delayedLeave; 3660 }; 3661 enterHooks.delayedLeave = delayedLeave; 3662 }; 3663 } 3664 } 3665 return child; 3666 }; 3667 } 3668 }; 3669 // export the public type for h/tsx inference 3670 // also to avoid inline import() in generated d.ts files 3671 const BaseTransition = BaseTransitionImpl; 3672 function getLeavingNodesForType(state, vnode) { 3673 const { leavingVNodes } = state;
3674 let leavingVNodesCache = leavingVNodes.get(vnode.type); 3675 if (!leavingVNodesCache) { 3676 leavingVNodesCache = Object.create(null); 3677 leavingVNodes.set(vnode.type, leavingVNodesCache); 3678 } 3679 return leavingVNodesCache; 3680 } 3681 // The transition hooks are attached to the vnode as vnode.transition 3682 // and will be called at appropriate timing in the renderer. 3683 function resolveTransitionHooks(vnode, props, state, instance) { 3684 const { appear, mode, persisted = false, onBeforeEnter, onEnter, onAfterEnter, onEnterCancelled, onBeforeLeave, onLeave, onAfterLeave, onLeaveCancelled, onBeforeAppear, onAppear, onAfterAppear, onAppearCancelled } = props; 3685 const key = String(vnode.key); 3686 const leavingVNodesCache = getLeavingNodesForType(state, vnode); 3687 const callHook = (hook, args) => { 3688 hook && 3689 callWithAsyncErrorHandling(hook, instance, 9 /* ErrorCodes.TRANSITION_HOOK */, args); 3690 }; 3691 const callAsyncHook = (hook, args) => { 3692 const done = args[1]; 3693 callHook(hook, args); 3694 if (isArray(hook)) { 3695 if (hook.every(hook => hook.length <= 1)) 3696 done(); 3697 } 3698 else if (hook.length <= 1) { 3699 done(); 3700 } 3701 }; 3702 const hooks = { 3703 mode, 3704 persisted, 3705 beforeEnter(el) { 3706 let hook = onBeforeEnter; 3707 if (!state.isMounted) { 3708 if (appear) { 3709 hook = onBeforeAppear || onBeforeEnter; 3710 } 3711 else { 3712 return; 3713 } 3714 } 3715 // for same element (v-show) 3716 if (el._leaveCb) { 3717 el._leaveCb(true /* cancelled */); 3718 } 3719 // for toggled element with same key (v-if) 3720 const leavingVNode = leavingVNodesCache[key]; 3721 if (leavingVNode && 3722 isSameVNodeType(vnode, leavingVNode) && 3723 leavingVNode.el._leaveCb) { 3724 // force early removal (not cancelled) 3725 leavingVNode.el._leaveCb(); 3726 } 3727 callHook(hook, [el]); 3728 }, 3729 enter(el) { 3730 let hook = onEnter; 3731 let afterHook = onAfterEnter; 3732 let cancelHook = onEnterCancelled; 3733 if (!state.isMounted) { 3734 if (appear) { 3735 hook = onAppear || onEnter; 3736 afterHook = onAfterAppear || onAfterEnter; 3737 cancelHook = onAppearCancelled || onEnterCancelled; 3738 } 3739 else { 3740 return; 3741 } 3742 } 3743 let called = false; 3744 const done = (el._enterCb = (cancelled) => { 3745 if (called) 3746 return; 3747 called = true; 3748 if (cancelled) { 3749 callHook(cancelHook, [el]); 3750 } 3751 else { 3752 callHook(afterHook, [el]); 3753 } 3754 if (hooks.delayedLeave) { 3755 hooks.delayedLeave(); 3756 } 3757 el._enterCb = undefined; 3758 }); 3759 if (hook) { 3760 callAsyncHook(hook, [el, done]); 3761 } 3762 else { 3763 done(); 3764 } 3765 }, 3766 leave(el, remove) { 3767 const key = String(vnode.key); 3768 if (el._enterCb) { 3769 el._enterCb(true /* cancelled */); 3770 } 3771 if (state.isUnmounting) { 3772 return remove(); 3773 } 3774 callHook(onBeforeLeave, [el]); 3775 let called = false; 3776 const done = (el._leaveCb = (cancelled) => { 3777 if (called) 3778 return; 3779 called = true; 3780 remove(); 3781 if (cancelled) { 3782 callHook(onLeaveCancelled, [el]); 3783 } 3784 else { 3785 callHook(onAfterLeave, [el]); 3786 } 3787 el._leaveCb = undefined; 3788 if (leavingVNodesCache[key] === vnode) { 3789 delete leavingVNodesCache[key]; 3790 } 3791 }); 3792 leavingVNodesCache[key] = vnode; 3793 if (onLeave) { 3794 callAsyncHook(onLeave, [el, done]); 3795 } 3796 else { 3797 done(); 3798 } 3799 }, 3800 clone(vnode) { 3801 return resolveTransitionHooks(vnode, props, state, instance); 3802 } 3803 }; 3804 return hooks; 3805 } 3806 // the placeholder really only handles one special case: KeepAlive 3807 // in the case of a KeepAlive in a leave phase we need to return a KeepAlive 3808 // placeholder with empty content to avoid the KeepAlive instance from being 3809 // unmounted. 3810 function emptyPlaceholder(vnode) { 3811 if (isKeepAlive(vnode)) { 3812 vnode = cloneVNode(vnode); 3813 vnode.children = null; 3814 return vnode; 3815 } 3816 } 3817 function getKeepAliveChild(vnode) { 3818 return isKeepAlive(vnode) 3819 ? vnode.children 3820 ? vnode.children[0] 3821 : undefined 3822 : vnode; 3823 } 3824 function setTransitionHooks(vnode, hooks) {
3825 if (vnode.shapeFlag & 6 /* ShapeFlags.COMPONENT */ && vnode.component) { 3826 setTransitionHooks(vnode.component.subTree, hooks); 3827 } 3828 else if (vnode.shapeFlag & 128 /* ShapeFlags.SUSPENSE */) { 3829 vnode.ssContent.transition = hooks.clone(vnode.ssContent); 3830 vnode.ssFallback.transition = hooks.clone(vnode.ssFallback); 3831 } 3832 else { 3833 vnode.transition = hooks; 3834 } 3835 } 3836 function getTransitionRawChildren(children, keepComment = false, parentKey) { 3837 let ret = []; 3838 let keyedFragmentCount = 0; 3839 for (let i = 0; i < children.length; i++) { 3840 let child = children[i]; 3841 // #5360 inherit parent key in case of <template v-for> 3842 const key = parentKey == null 3843 ? child.key 3844 : String(parentKey) + String(child.key != null ? child.key : i); 3845 // handle fragment children case, e.g. v-for 3846 if (child.type === Fragment) { 3847 if (child.patchFlag & 128 /* PatchFlags.KEYED_FRAGMENT */) 3848 keyedFragmentCount++; 3849 ret = ret.concat(getTransitionRawChildren(child.children, keepComment, key)); 3850 } 3851 // comment placeholders should be skipped, e.g. v-if 3852 else if (keepComment || child.type !== Comment) { 3853 ret.push(key != null ? cloneVNode(child, { key }) : child); 3854 } 3855 } 3856 // #1126 if a transition children list contains multiple sub fragments, these 3857 // fragments will be merged into a flat children array. Since each v-for 3858 // fragment may contain different static bindings inside, we need to de-op 3859 // these children to force full diffs to ensure correct behavior. 3860 if (keyedFragmentCount > 1) { 3861 for (let i = 0; i < ret.length; i++) { 3862 ret[i].patchFlag = -2 /* PatchFlags.BAIL */; 3863 } 3864 } 3865 return ret; 3866 } 3867 3868 // implementation, close to no-op 3869 function defineComponent(options) { 3870 return isFunction(options) ? { setup: options, name: options.name } : options; 3871 } 3872 3873 const isAsyncWrapper = (i) => !!i.type.__asyncLoader; 3874 function defineAsyncComponent(source) { 3875 if (isFunction(source)) { 3876 source = { loader: source }; 3877 } 3878 const { loader, loadingComponent, errorComponent, delay = 200, timeout, // undefined = never times out 3879 suspensible = true, onError: userOnError } = source; 3880 let pendingRequest = null; 3881 let resolvedComp; 3882 let retries = 0; 3883 const retry = () => { 3884 retries++; 3885 pendingRequest = null; 3886 return load(); 3887 }; 3888 const load = () => { 3889 let thisRequest; 3890 return (pendingRequest || 3891 (thisRequest = pendingRequest = 3892 loader() 3893 .catch(err => { 3894 err = err instanceof Error ? err : new Error(String(err)); 3895 if (userOnError) { 3896 return new Promise((resolve, reject) => { 3897 const userRetry = () => resolve(retry()); 3898 const userFail = () => reject(err); 3899 userOnError(err, userRetry, userFail, retries + 1); 3900 }); 3901 } 3902 else { 3903 throw err; 3904 } 3905 }) 3906 .then((comp) => { 3907 if (thisRequest !== pendingRequest && pendingRequest) { 3908 return pendingRequest; 3909 } 3910 if (!comp) { 3911 warn(`Async component loader resolved to undefined. ` + 3912 `If you are using retry(), make sure to return its return value.`); 3913 } 3914 // interop module default 3915 if (comp && 3916 (comp.__esModule || comp[Symbol.toStringTag] === 'Module')) { 3917 comp = comp.default; 3918 } 3919 if (comp && !isObject(comp) && !isFunction(comp)) { 3920 throw new Error(`Invalid async component load result: ${comp}`); 3921 } 3922 resolvedComp = comp; 3923 return comp; 3924 }))); 3925 }; 3926 return defineComponent({ 3927 name: 'AsyncComponentWrapper', 3928 __asyncLoader: load, 3929 get __asyncResolved() { 3930 return resolvedComp; 3931 }, 3932 setup() { 3933 const instance = currentInstance; 3934 // already resolved 3935 if (resolvedComp) { 3936 return () => createInnerComp(resolvedComp, instance); 3937 } 3938 const onError = (err) => { 3939 pendingRequest = null; 3940 handleError(err, instance, 13 /* ErrorCodes.ASYNC_COMPONENT_LOADER */, !errorComponent /* do not throw in dev if user provided error component */); 3941 }; 3942 // suspense-controlled or SSR. 3943 if ((suspensible && instance.suspense) || 3944 (false )) { 3945 return load() 3946 .then(comp => { 3947 return () => createInnerComp(comp, instance); 3948 }) 3949 .catch(err => { 3950 onError(err); 3951 return () => errorComponent 3952 ? createVNode(errorComponent, { 3953 error: err 3954 }) 3955 : null; 3956 }); 3957 } 3958 const loaded = ref(false); 3959 const error = ref(); 3960 const delayed = ref(!!delay); 3961 if (delay) { 3962 setTimeout(() => { 3963 delayed.value = false;
vendor: 5,627 bytes, lines 3964-4096
3964 }, delay); 3965 } 3966 if (timeout != null) { 3967 setTimeout(() => { 3968 if (!loaded.value && !error.value) { 3969 const err = new Error(`Async component timed out after ${timeout}ms.`); 3970 onError(err); 3971 error.value = err; 3972 } 3973 }, timeout); 3974 } 3975 load() 3976 .then(() => { 3977 loaded.value = true; 3978 if (instance.parent && isKeepAlive(instance.parent.vnode)) { 3979 // parent is keep-alive, force update so the loaded component's 3980 // name is taken into account 3981 queueJob(instance.parent.update); 3982 } 3983 }) 3984 .catch(err => { 3985 onError(err); 3986 error.value = err; 3987 }); 3988 return () => { 3989 if (loaded.value && resolvedComp) { 3990 return createInnerComp(resolvedComp, instance); 3991 } 3992 else if (error.value && errorComponent) { 3993 return createVNode(errorComponent, { 3994 error: error.value 3995 }); 3996 } 3997 else if (loadingComponent && !delayed.value) { 3998 return createVNode(loadingComponent); 3999 } 4000 }; 4001 } 4002 }); 4003 } 4004 function createInnerComp(comp, parent) { 4005 const { ref, props, children, ce } = parent.vnode; 4006 const vnode = createVNode(comp, props, children); 4007 // ensure inner component inherits the async wrapper's ref owner 4008 vnode.ref = ref; 4009 // pass the custom element callback on to the inner comp 4010 // and remove it from the async wrapper 4011 vnode.ce = ce; 4012 delete parent.vnode.ce; 4013 return vnode; 4014 } 4015 4016 const isKeepAlive = (vnode) => vnode.type.__isKeepAlive; 4017 const KeepAliveImpl = { 4018 name: `KeepAlive`, 4019 // Marker for special handling inside the renderer. We are not using a === 4020 // check directly on KeepAlive in the renderer, because importing it directly 4021 // would prevent it from being tree-shaken. 4022 __isKeepAlive: true, 4023 props: { 4024 include: [String, RegExp, Array], 4025 exclude: [String, RegExp, Array], 4026 max: [String, Number] 4027 }, 4028 setup(props, { slots }) { 4029 const instance = getCurrentInstance(); 4030 // KeepAlive communicates with the instantiated renderer via the 4031 // ctx where the renderer passes in its internals, 4032 // and the KeepAlive instance exposes activate/deactivate implementations. 4033 // The whole point of this is to avoid importing KeepAlive directly in the 4034 // renderer to facilitate tree-shaking. 4035 const sharedContext = instance.ctx; 4036 const cache = new Map(); 4037 const keys = new Set(); 4038 let current = null; 4039 { 4040 instance.__v_cache = cache; 4041 } 4042 const parentSuspense = instance.suspense; 4043 const { renderer: { p: patch, m: move, um: _unmount, o: { createElement } } } = sharedContext; 4044 const storageContainer = createElement('div'); 4045 sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => { 4046 const instance = vnode.component; 4047 move(vnode, container, anchor, 0 /* MoveType.ENTER */, parentSuspense); 4048 // in case props have changed 4049 patch(instance.vnode, vnode, container, anchor, instance, parentSuspense, isSVG, vnode.slotScopeIds, optimized); 4050 queuePostRenderEffect(() => { 4051 instance.isDeactivated = false; 4052 if (instance.a) { 4053 invokeArrayFns(instance.a); 4054 } 4055 const vnodeHook = vnode.props && vnode.props.onVnodeMounted; 4056 if (vnodeHook) { 4057 invokeVNodeHook(vnodeHook, instance.parent, vnode); 4058 } 4059 }, parentSuspense); 4060 { 4061 // Update components tree 4062 devtoolsComponentAdded(instance); 4063 } 4064 }; 4065 sharedContext.deactivate = (vnode) => { 4066 const instance = vnode.component; 4067 move(vnode, storageContainer, null, 1 /* MoveType.LEAVE */, parentSuspense); 4068 queuePostRenderEffect(() => { 4069 if (instance.da) { 4070 invokeArrayFns(instance.da); 4071 } 4072 const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted; 4073 if (vnodeHook) { 4074 invokeVNodeHook(vnodeHook, instance.parent, vnode); 4075 } 4076 instance.isDeactivated = true; 4077 }, parentSuspense); 4078 { 4079 // Update components tree 4080 devtoolsComponentAdded(instance); 4081 } 4082 }; 4083 function unmount(vnode) { 4084 // reset the shapeFlag so it can be properly unmounted 4085 resetShapeFlag(vnode); 4086 _unmount(vnode, instance, parentSuspense, true); 4087 } 4088 function pruneCache(filter) { 4089 cache.forEach((vnode, key) => { 4090 const name = getComponentName(vnode.type); 4091 if (name && (!filter || !filter(name))) { 4092 pruneCacheEntry(key); 4093 } 4094 }); 4095 } 4096 function pruneCacheEntry(key) {
4097 const cached = cache.get(key); 4098 if (!current || !isSameVNodeType(cached, current)) { 4099 unmount(cached); 4100 } 4101 else if (current) { 4102 // current active instance should no longer be kept-alive. 4103 // we can't unmount it now but it might be later, so reset its flag now. 4104 resetShapeFlag(current); 4105 } 4106 cache.delete(key); 4107 keys.delete(key); 4108 } 4109 // prune cache on include/exclude prop change 4110 watch(() => [props.include, props.exclude], ([include, exclude]) => { 4111 include && pruneCache(name => matches(include, name)); 4112 exclude && pruneCache(name => !matches(exclude, name)); 4113 }, 4114 // prune post-render after `current` has been updated 4115 { flush: 'post', deep: true }); 4116 // cache sub tree after render 4117 let pendingCacheKey = null; 4118 const cacheSubtree = () => { 4119 // fix #1621, the pendingCacheKey could be 0 4120 if (pendingCacheKey != null) { 4121 cache.set(pendingCacheKey, getInnerChild(instance.subTree)); 4122 } 4123 }; 4124 onMounted(cacheSubtree); 4125 onUpdated(cacheSubtree); 4126 onBeforeUnmount(() => { 4127 cache.forEach(cached => { 4128 const { subTree, suspense } = instance; 4129 const vnode = getInnerChild(subTree); 4130 if (cached.type === vnode.type && cached.key === vnode.key) { 4131 // current instance will be unmounted as part of keep-alive's unmount 4132 resetShapeFlag(vnode); 4133 // but invoke its deactivated hook here 4134 const da = vnode.component.da; 4135 da && queuePostRenderEffect(da, suspense); 4136 return; 4137 } 4138 unmount(cached); 4139 }); 4140 }); 4141 return () => { 4142 pendingCacheKey = null; 4143 if (!slots.default) { 4144 return null; 4145 } 4146 const children = slots.default(); 4147 const rawVNode = children[0]; 4148 if (children.length > 1) { 4149 { 4150 warn(`KeepAlive should contain exactly one component child.`); 4151 } 4152 current = null; 4153 return children; 4154 } 4155 else if (!isVNode(rawVNode) || 4156 (!(rawVNode.shapeFlag & 4 /* ShapeFlags.STATEFUL_COMPONENT */) && 4157 !(rawVNode.shapeFlag & 128 /* ShapeFlags.SUSPENSE */))) { 4158 current = null; 4159 return rawVNode; 4160 } 4161 let vnode = getInnerChild(rawVNode); 4162 const comp = vnode.type; 4163 // for async components, name check should be based in its loaded 4164 // inner component if available 4165 const name = getComponentName(isAsyncWrapper(vnode) 4166 ? vnode.type.__asyncResolved || {} 4167 : comp); 4168 const { include, exclude, max } = props; 4169 if ((include && (!name || !matches(include, name))) || 4170 (exclude && name && matches(exclude, name))) { 4171 current = vnode; 4172 return rawVNode; 4173 } 4174 const key = vnode.key == null ? comp : vnode.key; 4175 const cachedVNode = cache.get(key); 4176 // clone vnode if it's reused because we are going to mutate it 4177 if (vnode.el) { 4178 vnode = cloneVNode(vnode); 4179 if (rawVNode.shapeFlag & 128 /* ShapeFlags.SUSPENSE */) { 4180 rawVNode.ssContent = vnode; 4181 } 4182 } 4183 // #1513 it's possible for the returned vnode to be cloned due to attr 4184 // fallthrough or scopeId, so the vnode here may not be the final vnode 4185 // that is mounted. Instead of caching it directly, we store the pending 4186 // key and cache `instance.subTree` (the normalized vnode) in 4187 // beforeMount/beforeUpdate hooks. 4188 pendingCacheKey = key; 4189 if (cachedVNode) { 4190 // copy over mounted state 4191 vnode.el = cachedVNode.el; 4192 vnode.component = cachedVNode.component; 4193 if (vnode.transition) { 4194 // recursively update transition hooks on subTree 4195 setTransitionHooks(vnode, vnode.transition); 4196 } 4197 // avoid vnode being mounted as fresh
vendor: 4,611 bytes, lines 4198-4305
4198 vnode.shapeFlag |= 512 /* ShapeFlags.COMPONENT_KEPT_ALIVE */; 4199 // make this key the freshest 4200 keys.delete(key); 4201 keys.add(key); 4202 } 4203 else { 4204 keys.add(key); 4205 // prune oldest entry 4206 if (max && keys.size > parseInt(max, 10)) { 4207 pruneCacheEntry(keys.values().next().value); 4208 } 4209 } 4210 // avoid vnode being unmounted 4211 vnode.shapeFlag |= 256 /* ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE */; 4212 current = vnode; 4213 return isSuspense(rawVNode.type) ? rawVNode : vnode; 4214 }; 4215 } 4216 }; 4217 // export the public type for h/tsx inference 4218 // also to avoid inline import() in generated d.ts files 4219 const KeepAlive = KeepAliveImpl; 4220 function matches(pattern, name) { 4221 if (isArray(pattern)) { 4222 return pattern.some((p) => matches(p, name)); 4223 } 4224 else if (isString(pattern)) { 4225 return pattern.split(',').includes(name); 4226 } 4227 else if (isRegExp(pattern)) { 4228 return pattern.test(name); 4229 } 4230 /* istanbul ignore next */ 4231 return false; 4232 } 4233 function onActivated(hook, target) { 4234 registerKeepAliveHook(hook, "a" /* LifecycleHooks.ACTIVATED */, target); 4235 } 4236 function onDeactivated(hook, target) { 4237 registerKeepAliveHook(hook, "da" /* LifecycleHooks.DEACTIVATED */, target); 4238 } 4239 function registerKeepAliveHook(hook, type, target = currentInstance) { 4240 // cache the deactivate branch check wrapper for injected hooks so the same 4241 // hook can be properly deduped by the scheduler. "__wdc" stands for "with 4242 // deactivation check". 4243 const wrappedHook = hook.__wdc || 4244 (hook.__wdc = () => { 4245 // only fire the hook if the target instance is NOT in a deactivated branch. 4246 let current = target; 4247 while (current) { 4248 if (current.isDeactivated) { 4249 return; 4250 } 4251 current = current.parent; 4252 } 4253 return hook(); 4254 }); 4255 injectHook(type, wrappedHook, target); 4256 // In addition to registering it on the target instance, we walk up the parent 4257 // chain and register it on all ancestor instances that are keep-alive roots. 4258 // This avoids the need to walk the entire component tree when invoking these 4259 // hooks, and more importantly, avoids the need to track child components in 4260 // arrays. 4261 if (target) { 4262 let current = target.parent; 4263 while (current && current.parent) { 4264 if (isKeepAlive(current.parent.vnode)) { 4265 injectToKeepAliveRoot(wrappedHook, type, target, current); 4266 } 4267 current = current.parent; 4268 } 4269 } 4270 } 4271 function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) { 4272 // injectHook wraps the original for error handling, so make sure to remove 4273 // the wrapped version. 4274 const injected = injectHook(type, hook, keepAliveRoot, true /* prepend */); 4275 onUnmounted(() => { 4276 remove(keepAliveRoot[type], injected); 4277 }, target); 4278 } 4279 function resetShapeFlag(vnode) { 4280 // bitwise operations to remove keep alive flags 4281 vnode.shapeFlag &= ~256 /* ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE */; 4282 vnode.shapeFlag &= ~512 /* ShapeFlags.COMPONENT_KEPT_ALIVE */; 4283 } 4284 function getInnerChild(vnode) { 4285 return vnode.shapeFlag & 128 /* ShapeFlags.SUSPENSE */ ? vnode.ssContent : vnode; 4286 } 4287 4288 function injectHook(type, hook, target = currentInstance, prepend = false) { 4289 if (target) { 4290 const hooks = target[type] || (target[type] = []); 4291 // cache the error handling wrapper for injected hooks so the same hook 4292 // can be properly deduped by the scheduler. "__weh" stands for "with error 4293 // handling". 4294 const wrappedHook = hook.__weh || 4295 (hook.__weh = (...args) => { 4296 if (target.isUnmounted) { 4297 return; 4298 } 4299 // disable tracking inside all lifecycle hooks 4300 // since they can potentially be called inside effects. 4301 pauseTracking(); 4302 // Set currentInstance during hook invocation. 4303 // This assumes the hook does not synchronously trigger other hooks, which 4304 // can only be false when the user does something really funky. 4305 setCurrentInstance(target);
4306 const res = callWithAsyncErrorHandling(hook, target, type, args); 4307 unsetCurrentInstance(); 4308 resetTracking(); 4309 return res; 4310 }); 4311 if (prepend) { 4312 hooks.unshift(wrappedHook); 4313 } 4314 else { 4315 hooks.push(wrappedHook); 4316 } 4317 return wrappedHook; 4318 } 4319 else { 4320 const apiName = toHandlerKey(ErrorTypeStrings[type].replace(/ hook$/, '')); 4321 warn(`${apiName} is called when there is no active component instance to be ` + 4322 `associated with. ` + 4323 `Lifecycle injection APIs can only be used during execution of setup().` + 4324 (` If you are using async setup(), make sure to register lifecycle ` + 4325 `hooks before the first await statement.` 4326 )); 4327 } 4328 } 4329 const createHook = (lifecycle) => (hook, target = currentInstance) => 4330 // post-create lifecycle registrations are noops during SSR (except for serverPrefetch) 4331 (!isInSSRComponentSetup || lifecycle === "sp" /* LifecycleHooks.SERVER_PREFETCH */) && 4332 injectHook(lifecycle, (...args) => hook(...args), target); 4333 const onBeforeMount = createHook("bm" /* LifecycleHooks.BEFORE_MOUNT */); 4334 const onMounted = createHook("m" /* LifecycleHooks.MOUNTED */); 4335 const onBeforeUpdate = createHook("bu" /* LifecycleHooks.BEFORE_UPDATE */); 4336 const onUpdated = createHook("u" /* LifecycleHooks.UPDATED */); 4337 const onBeforeUnmount = createHook("bum" /* LifecycleHooks.BEFORE_UNMOUNT */); 4338 const onUnmounted = createHook("um" /* LifecycleHooks.UNMOUNTED */); 4339 const onServerPrefetch = createHook("sp" /* LifecycleHooks.SERVER_PREFETCH */); 4340 const onRenderTriggered = createHook("rtg" /* LifecycleHooks.RENDER_TRIGGERED */); 4341 const onRenderTracked = createHook("rtc" /* LifecycleHooks.RENDER_TRACKED */); 4342 function onErrorCaptured(hook, target = currentInstance) { 4343 injectHook("ec" /* LifecycleHooks.ERROR_CAPTURED */, hook, target); 4344 } 4345 4346 /** 4347 Runtime helper for applying directives to a vnode. Example usage: 4348 4349 const comp = resolveComponent('comp') 4350 const foo = resolveDirective('foo') 4351 const bar = resolveDirective('bar') 4352 4353 return withDirectives(h(comp), [ 4354 [foo, this.x], 4355 [bar, this.y] 4356 ]) 4357 */ 4358 function validateDirectiveName(name) { 4359 if (isBuiltInDirective(name)) { 4360 warn('Do not use built-in directive ids as custom directive id: ' + name); 4361 } 4362 } 4363 /** 4364 * Adds directives to a VNode. 4365 */ 4366 function withDirectives(vnode, directives) { 4367 const internalInstance = currentRenderingInstance; 4368 if (internalInstance === null) { 4369 warn(`withDirectives can only be used inside render functions.`); 4370 return vnode; 4371 } 4372 const instance = getExposeProxy(internalInstance) || 4373 internalInstance.proxy; 4374 const bindings = vnode.dirs || (vnode.dirs = []); 4375 for (let i = 0; i < directives.length; i++) { 4376 let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i]; 4377 if (dir) { 4378 if (isFunction(dir)) { 4379 dir = { 4380 mounted: dir, 4381 updated: dir 4382 }; 4383 } 4384 if (dir.deep) { 4385 traverse(value); 4386 } 4387 bindings.push({ 4388 dir, 4389 instance, 4390 value, 4391 oldValue: void 0, 4392 arg, 4393 modifiers 4394 }); 4395 } 4396 } 4397 return vnode; 4398 } 4399 function invokeDirectiveHook(vnode, prevVNode, instance, name) { 4400 const bindings = vnode.dirs; 4401 const oldBindings = prevVNode && prevVNode.dirs; 4402 for (let i = 0; i < bindings.length; i++) { 4403 const binding = bindings[i]; 4404 if (oldBindings) { 4405 binding.oldValue = oldBindings[i].value; 4406 } 4407 let hook = binding.dir[name]; 4408 if (hook) { 4409 // disable tracking inside all lifecycle hooks 4410 // since they can potentially be called inside effects. 4411 pauseTracking();
4412 callWithAsyncErrorHandling(hook, instance, 8 /* ErrorCodes.DIRECTIVE_HOOK */, [ 4413 vnode.el, 4414 binding, 4415 vnode, 4416 prevVNode 4417 ]); 4418 resetTracking(); 4419 } 4420 } 4421 } 4422 4423 const COMPONENTS = 'components'; 4424 const DIRECTIVES = 'directives'; 4425 /** 4426 * @private 4427 */ 4428 function resolveComponent(name, maybeSelfReference) { 4429 return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name; 4430 } 4431 const NULL_DYNAMIC_COMPONENT = Symbol(); 4432 /** 4433 * @private 4434 */ 4435 function resolveDynamicComponent(component) { 4436 if (isString(component)) { 4437 return resolveAsset(COMPONENTS, component, false) || component; 4438 } 4439 else { 4440 // invalid types will fallthrough to createVNode and raise warning 4441 return (component || NULL_DYNAMIC_COMPONENT); 4442 } 4443 } 4444 /** 4445 * @private 4446 */ 4447 function resolveDirective(name) { 4448 return resolveAsset(DIRECTIVES, name); 4449 } 4450 // implementation 4451 function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) { 4452 const instance = currentRenderingInstance || currentInstance; 4453 if (instance) { 4454 const Component = instance.type; 4455 // explicit self name has highest priority 4456 if (type === COMPONENTS) { 4457 const selfName = getComponentName(Component, false /* do not include inferred name to avoid breaking existing code */); 4458 if (selfName && 4459 (selfName === name || 4460 selfName === camelize(name) || 4461 selfName === capitalize(camelize(name)))) { 4462 return Component; 4463 } 4464 } 4465 const res = 4466 // local registration 4467 // check instance[type] first which is resolved for options API 4468 resolve(instance[type] || Component[type], name) || 4469 // global registration 4470 resolve(instance.appContext[type], name); 4471 if (!res && maybeSelfReference) { 4472 // fallback to implicit self-reference 4473 return Component; 4474 } 4475 if (warnMissing && !res) { 4476 const extra = type === COMPONENTS 4477 ? `\nIf this is a native custom element, make sure to exclude it from ` + 4478 `component resolution via compilerOptions.isCustomElement.` 4479 : ``; 4480 warn(`Failed to resolve ${type.slice(0, -1)}: ${name}${extra}`); 4481 } 4482 return res; 4483 } 4484 else { 4485 warn(`resolve${capitalize(type.slice(0, -1))} ` + 4486 `can only be used in render() or setup().`); 4487 } 4488 } 4489 function resolve(registry, name) { 4490 return (registry && 4491 (registry[name] || 4492 registry[camelize(name)] || 4493 registry[capitalize(camelize(name))])); 4494 } 4495 4496 /** 4497 * Actual implementation 4498 */ 4499 function renderList(source, renderItem, cache, index) { 4500 let ret; 4501 const cached = (cache && cache[index]); 4502 if (isArray(source) || isString(source)) { 4503 ret = new Array(source.length); 4504 for (let i = 0, l = source.length; i < l; i++) { 4505 ret[i] = renderItem(source[i], i, undefined, cached && cached[i]); 4506 } 4507 } 4508 else if (typeof source === 'number') { 4509 if (!Number.isInteger(source)) { 4510 warn(`The v-for range expect an integer value but got ${source}.`); 4511 } 4512 ret = new Array(source); 4513 for (let i = 0; i < source; i++) { 4514 ret[i] = renderItem(i + 1, i, undefined, cached && cached[i]); 4515 } 4516 } 4517 else if (isObject(source)) { 4518 if (source[Symbol.iterator]) { 4519 ret = Array.from(source, (item, i) => renderItem(item, i, undefined, cached && cached[i])); 4520 } 4521 else { 4522 const keys = Object.keys(source); 4523 ret = new Array(keys.length); 4524 for (let i = 0, l = keys.length; i < l; i++) { 4525 const key = keys[i]; 4526 ret[i] = renderItem(source[key], key, i, cached && cached[i]); 4527 } 4528 } 4529 } 4530 else { 4531 ret = []; 4532 } 4533 if (cache) { 4534 cache[index] = ret; 4535 } 4536 return ret; 4537 } 4538 4539 /** 4540 * Compiler runtime helper for creating dynamic slots object 4541 * @private 4542 */ 4543 function createSlots(slots, dynamicSlots) { 4544 for (let i = 0; i < dynamicSlots.length; i++) { 4545 const slot = dynamicSlots[i]; 4546 // array of dynamic slot generated by <template v-for="..." #[...]> 4547 if (isArray(slot)) { 4548 for (let j = 0; j < slot.length; j++) { 4549 slots[slot[j].name] = slot[j].fn; 4550 } 4551 } 4552 else if (slot) { 4553 // conditional single slot generated by <template v-if="..." #foo> 4554 slots[slot.name] = slot.key 4555 ? (...args) => { 4556 const res = slot.fn(...args); 4557 // attach branch key so each conditional branch is considered a 4558 // different fragment 4559 if (res) 4560 res.key = slot.key; 4561 return res; 4562 } 4563 : slot.fn; 4564 } 4565 } 4566 return slots; 4567 } 4568 4569 /** 4570 * Compiler runtime helper for rendering `<slot/>` 4571 * @private 4572 */
4573 function renderSlot(slots, name, props = {}, 4574 // this is not a user-facing function, so the fallback is always generated by 4575 // the compiler and guaranteed to be a function returning an array 4576 fallback, noSlotted) { 4577 if (currentRenderingInstance.isCE || 4578 (currentRenderingInstance.parent && 4579 isAsyncWrapper(currentRenderingInstance.parent) && 4580 currentRenderingInstance.parent.isCE)) { 4581 if (name !== 'default') 4582 props.name = name; 4583 return createVNode('slot', props, fallback && fallback()); 4584 } 4585 let slot = slots[name]; 4586 if (slot && slot.length > 1) { 4587 warn(`SSR-optimized slot function detected in a non-SSR-optimized render ` + 4588 `function. You need to mark this component with $dynamic-slots in the ` + 4589 `parent template.`); 4590 slot = () => []; 4591 } 4592 // a compiled slot disables block tracking by default to avoid manual 4593 // invocation interfering with template-based block tracking, but in 4594 // `renderSlot` we can be sure that it's template-based so we can force 4595 // enable it. 4596 if (slot && slot._c) { 4597 slot._d = false; 4598 } 4599 openBlock(); 4600 const validSlotContent = slot && ensureValidVNode(slot(props)); 4601 const rendered = createBlock(Fragment, { 4602 key: props.key || 4603 // slot content array of a dynamic conditional slot may have a branch 4604 // key attached in the `createSlots` helper, respect that 4605 (validSlotContent && validSlotContent.key) || 4606 `_${name}` 4607 }, validSlotContent || (fallback ? fallback() : []), validSlotContent && slots._ === 1 /* SlotFlags.STABLE */ 4608 ? 64 /* PatchFlags.STABLE_FRAGMENT */ 4609 : -2 /* PatchFlags.BAIL */); 4610 if (!noSlotted && rendered.scopeId) { 4611 rendered.slotScopeIds = [rendered.scopeId + '-s']; 4612 } 4613 if (slot && slot._c) { 4614 slot._d = true; 4615 } 4616 return rendered; 4617 } 4618 function ensureValidVNode(vnodes) { 4619 return vnodes.some(child => { 4620 if (!isVNode(child)) 4621 return true; 4622 if (child.type === Comment) 4623 return false; 4624 if (child.type === Fragment && 4625 !ensureValidVNode(child.children)) 4626 return false; 4627 return true; 4628 }) 4629 ? vnodes 4630 : null; 4631 } 4632 4633 /** 4634 * For prefixing keys in v-on="obj" with "on" 4635 * @private 4636 */ 4637 function toHandlers(obj, preserveCaseIfNecessary) { 4638 const ret = {}; 4639 if (!isObject(obj)) { 4640 warn(`v-on with no argument expects an object value.`); 4641 return ret; 4642 } 4643 for (const key in obj) { 4644 ret[preserveCaseIfNecessary && /[A-Z]/.test(key) 4645 ? `on:${key}` 4646 : toHandlerKey(key)] = obj[key]; 4647 } 4648 return ret; 4649 } 4650 4651 /** 4652 * #2437 In Vue 3, functional components do not have a public instance proxy but 4653 * they exist in the internal parent chain. For code that relies on traversing 4654 * public $parent chains, skip functional ones and go to the parent instead. 4655 */ 4656 const getPublicInstance = (i) => { 4657 if (!i) 4658 return null; 4659 if (isStatefulComponent(i)) 4660 return getExposeProxy(i) || i.proxy; 4661 return getPublicInstance(i.parent); 4662 }; 4663 const publicPropertiesMap = 4664 // Move PURE marker to new line to workaround compiler discarding it 4665 // due to type annotation 4666 /*#__PURE__*/ extend(Object.create(null), { 4667 $: i => i, 4668 $el: i => i.vnode.el, 4669 $data: i => i.data, 4670 $props: i => (shallowReadonly(i.props) ), 4671 $attrs: i => (shallowReadonly(i.attrs) ), 4672 $slots: i => (shallowReadonly(i.slots) ), 4673 $refs: i => (shallowReadonly(i.refs) ), 4674 $parent: i => getPublicInstance(i.parent), 4675 $root: i => getPublicInstance(i.root), 4676 $emit: i => i.emit, 4677 $options: i => (resolveMergedOptions(i) ), 4678 $forceUpdate: i => i.f || (i.f = () => queueJob(i.update)), 4679 $nextTick: i => i.n || (i.n = nextTick.bind(i.proxy)), 4680 $watch: i => (instanceWatch.bind(i) ) 4681 }); 4682 const isReservedPrefix = (key) => key === '_' || key === '$'; 4683 const hasSetupBinding = (state, key) => state !== EMPTY_OBJ && !state.__isScriptSetup && hasOwn(state, key); 4684 const PublicInstanceProxyHandlers = { 4685 get({ _: instance }, key) { 4686 const { ctx, setupState, data, props, accessCache, type, appContext } = instance; 4687 // for internal formatters to know that this is a Vue instance 4688 if (key === '__isVue') { 4689 return true; 4690 } 4691 // data / props / ctx 4692 // This getter gets called for every property access on the render context 4693 // during render and is a major hotspot. The most expensive part of this 4694 // is the multiple hasOwn() calls. It's much faster to do a simple property 4695 // access on a plain object, so we use an accessCache object (with null 4696 // prototype) to memoize what access type a key corresponds to. 4697 let normalizedProps; 4698 if (key[0] !== '$') { 4699 const n = accessCache[key]; 4700 if (n !== undefined) { 4701 switch (n) { 4702 case 1 /* AccessTypes.SETUP */: 4703 return setupState[key]; 4704 case 2 /* AccessTypes.DATA */: 4705 return data[key]; 4706 case 4 /* AccessTypes.CONTEXT */: 4707 return ctx[key]; 4708 case 3 /* AccessTypes.PROPS */: 4709 return props[key]; 4710 // default: just fallthrough 4711 } 4712 } 4713 else if (hasSetupBinding(setupState, key)) { 4714 accessCache[key] = 1 /* AccessTypes.SETUP */; 4715 return setupState[key]; 4716 } 4717 else if (data !== EMPTY_OBJ && hasOwn(data, key)) { 4718 accessCache[key] = 2 /* AccessTypes.DATA */; 4719 return data[key]; 4720 } 4721 else if ( 4722 // only cache other properties when instance has declared (thus stable) 4723 // props 4724 (normalizedProps = instance.propsOptions[0]) && 4725 hasOwn(normalizedProps, key)) { 4726 accessCache[key] = 3 /* AccessTypes.PROPS */; 4727 return props[key]; 4728 } 4729 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) { 4730 accessCache[key] = 4 /* AccessTypes.CONTEXT */; 4731 return ctx[key]; 4732 } 4733 else if (shouldCacheAccess) { 4734 accessCache[key] = 0 /* AccessTypes.OTHER */; 4735 } 4736 } 4737 const publicGetter = publicPropertiesMap[key]; 4738 let cssModule, globalProperties; 4739 // public $xxx properties 4740 if (publicGetter) { 4741 if (key === '$attrs') { 4742 track(instance, "get" /* TrackOpTypes.GET */, key); 4743 markAttrsAccessed(); 4744 } 4745 return publicGetter(instance); 4746 } 4747 else if ( 4748 // css module (injected by vue-loader) 4749 (cssModule = type.__cssModules) && 4750 (cssModule = cssModule[key])) { 4751 return cssModule; 4752 } 4753 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) { 4754 // user may set custom properties to `this` that start with `$` 4755 accessCache[key] = 4 /* AccessTypes.CONTEXT */; 4756 return ctx[key]; 4757 } 4758 else if ( 4759 // global properties 4760 ((globalProperties = appContext.config.globalProperties), 4761 hasOwn(globalProperties, key))) { 4762 { 4763 return globalProperties[key]; 4764 } 4765 } 4766 else if (currentRenderingInstance && 4767 (!isString(key) || 4768 // #1091 avoid internal isRef/isVNode checks on component instance leading 4769 // to infinite warning loop 4770 key.indexOf('__v') !== 0)) { 4771 if (data !== EMPTY_OBJ && isReservedPrefix(key[0]) && hasOwn(data, key)) { 4772 warn(`Property ${JSON.stringify(key)} must be accessed via $data because it starts with a reserved ` + 4773 `character ("$" or "_") and is not proxied on the render context.`); 4774 } 4775 else if (instance === currentRenderingInstance) { 4776 warn(`Property ${JSON.stringify(key)} was accessed during render ` + 4777 `but is not defined on instance.`); 4778 } 4779 } 4780 }, 4781 set({ _: instance }, key, value) { 4782 const { data, setupState, ctx } = instance; 4783 if (hasSetupBinding(setupState, key)) { 4784 setupState[key] = value; 4785 return true; 4786 } 4787 else if (setupState.__isScriptSetup && 4788 hasOwn(setupState, key)) { 4789 warn(`Cannot mutate <script setup> binding "${key}" from Options API.`); 4790 return false;
vendor: 4,400 bytes, lines 4791-4904
4791 } 4792 else if (data !== EMPTY_OBJ && hasOwn(data, key)) { 4793 data[key] = value; 4794 return true; 4795 } 4796 else if (hasOwn(instance.props, key)) { 4797 warn(`Attempting to mutate prop "${key}". Props are readonly.`); 4798 return false; 4799 } 4800 if (key[0] === '$' && key.slice(1) in instance) { 4801 warn(`Attempting to mutate public property "${key}". ` + 4802 `Properties starting with $ are reserved and readonly.`); 4803 return false; 4804 } 4805 else { 4806 if (key in instance.appContext.config.globalProperties) { 4807 Object.defineProperty(ctx, key, { 4808 enumerable: true, 4809 configurable: true, 4810 value 4811 }); 4812 } 4813 else { 4814 ctx[key] = value; 4815 } 4816 } 4817 return true; 4818 }, 4819 has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key) { 4820 let normalizedProps; 4821 return (!!accessCache[key] || 4822 (data !== EMPTY_OBJ && hasOwn(data, key)) || 4823 hasSetupBinding(setupState, key) || 4824 ((normalizedProps = propsOptions[0]) && hasOwn(normalizedProps, key)) || 4825 hasOwn(ctx, key) || 4826 hasOwn(publicPropertiesMap, key) || 4827 hasOwn(appContext.config.globalProperties, key)); 4828 }, 4829 defineProperty(target, key, descriptor) { 4830 if (descriptor.get != null) { 4831 // invalidate key cache of a getter based property #5417 4832 target._.accessCache[key] = 0; 4833 } 4834 else if (hasOwn(descriptor, 'value')) { 4835 this.set(target, key, descriptor.value, null); 4836 } 4837 return Reflect.defineProperty(target, key, descriptor); 4838 } 4839 }; 4840 { 4841 PublicInstanceProxyHandlers.ownKeys = (target) => { 4842 warn(`Avoid app logic that relies on enumerating keys on a component instance. ` + 4843 `The keys will be empty in production mode to avoid performance overhead.`); 4844 return Reflect.ownKeys(target); 4845 }; 4846 } 4847 const RuntimeCompiledPublicInstanceProxyHandlers = /*#__PURE__*/ extend({}, PublicInstanceProxyHandlers, { 4848 get(target, key) { 4849 // fast path for unscopables when using `with` block 4850 if (key === Symbol.unscopables) { 4851 return; 4852 } 4853 return PublicInstanceProxyHandlers.get(target, key, target); 4854 }, 4855 has(_, key) { 4856 const has = key[0] !== '_' && !isGloballyWhitelisted(key); 4857 if (!has && PublicInstanceProxyHandlers.has(_, key)) { 4858 warn(`Property ${JSON.stringify(key)} should not start with _ which is a reserved prefix for Vue internals.`); 4859 } 4860 return has; 4861 } 4862 }); 4863 // dev only 4864 // In dev mode, the proxy target exposes the same properties as seen on `this` 4865 // for easier console inspection. In prod mode it will be an empty object so 4866 // these properties definitions can be skipped. 4867 function createDevRenderContext(instance) { 4868 const target = {}; 4869 // expose internal instance for proxy handlers 4870 Object.defineProperty(target, `_`, { 4871 configurable: true, 4872 enumerable: false, 4873 get: () => instance 4874 }); 4875 // expose public properties 4876 Object.keys(publicPropertiesMap).forEach(key => { 4877 Object.defineProperty(target, key, { 4878 configurable: true, 4879 enumerable: false, 4880 get: () => publicPropertiesMap[key](instance), 4881 // intercepted by the proxy so no need for implementation, 4882 // but needed to prevent set errors 4883 set: NOOP 4884 }); 4885 }); 4886 return target; 4887 } 4888 // dev only 4889 function exposePropsOnRenderContext(instance) { 4890 const { ctx, propsOptions: [propsOptions] } = instance; 4891 if (propsOptions) { 4892 Object.keys(propsOptions).forEach(key => { 4893 Object.defineProperty(ctx, key, { 4894 enumerable: true, 4895 configurable: true, 4896 get: () => instance.props[key], 4897 set: NOOP 4898 }); 4899 }); 4900 } 4901 } 4902 // dev only 4903 function exposeSetupStateOnRenderContext(instance) { 4904 const { ctx, setupState } = instance;
4905 Object.keys(toRaw(setupState)).forEach(key => { 4906 if (!setupState.__isScriptSetup) { 4907 if (isReservedPrefix(key[0])) { 4908 warn(`setup() return property ${JSON.stringify(key)} should not start with "$" or "_" ` + 4909 `which are reserved prefixes for Vue internals.`); 4910 return; 4911 } 4912 Object.defineProperty(ctx, key, { 4913 enumerable: true, 4914 configurable: true, 4915 get: () => setupState[key], 4916 set: NOOP 4917 }); 4918 } 4919 }); 4920 } 4921 4922 function createDuplicateChecker() { 4923 const cache = Object.create(null); 4924 return (type, key) => { 4925 if (cache[key]) { 4926 warn(`${type} property "${key}" is already defined in ${cache[key]}.`); 4927 } 4928 else { 4929 cache[key] = type; 4930 } 4931 }; 4932 } 4933 let shouldCacheAccess = true; 4934 function applyOptions(instance) { 4935 const options = resolveMergedOptions(instance); 4936 const publicThis = instance.proxy; 4937 const ctx = instance.ctx; 4938 // do not cache property access on public proxy during state initialization 4939 shouldCacheAccess = false; 4940 // call beforeCreate first before accessing other options since 4941 // the hook may mutate resolved options (#2791) 4942 if (options.beforeCreate) { 4943 callHook$1(options.beforeCreate, instance, "bc" /* LifecycleHooks.BEFORE_CREATE */); 4944 } 4945 const { 4946 // state 4947 data: dataOptions, computed: computedOptions, methods, watch: watchOptions, provide: provideOptions, inject: injectOptions, 4948 // lifecycle 4949 created, beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeDestroy, beforeUnmount, destroyed, unmounted, render, renderTracked, renderTriggered, errorCaptured, serverPrefetch, 4950 // public API 4951 expose, inheritAttrs, 4952 // assets 4953 components, directives, filters } = options; 4954 const checkDuplicateProperties = createDuplicateChecker() ; 4955 { 4956 const [propsOptions] = instance.propsOptions; 4957 if (propsOptions) { 4958 for (const key in propsOptions) { 4959 checkDuplicateProperties("Props" /* OptionTypes.PROPS */, key); 4960 } 4961 } 4962 } 4963 // options initialization order (to be consistent with Vue 2): 4964 // - props (already done outside of this function) 4965 // - inject 4966 // - methods 4967 // - data (deferred since it relies on `this` access) 4968 // - computed 4969 // - watch (deferred since it relies on `this` access) 4970 if (injectOptions) { 4971 resolveInjections(injectOptions, ctx, checkDuplicateProperties, instance.appContext.config.unwrapInjectedRef); 4972 } 4973 if (methods) { 4974 for (const key in methods) { 4975 const methodHandler = methods[key]; 4976 if (isFunction(methodHandler)) { 4977 // In dev mode, we use the `createRenderContext` function to define 4978 // methods to the proxy target, and those are read-only but 4979 // reconfigurable, so it needs to be redefined here 4980 { 4981 Object.defineProperty(ctx, key, { 4982 value: methodHandler.bind(publicThis), 4983 configurable: true, 4984 enumerable: true, 4985 writable: true 4986 }); 4987 } 4988 { 4989 checkDuplicateProperties("Methods" /* OptionTypes.METHODS */, key); 4990 } 4991 } 4992 else { 4993 warn(`Method "${key}" has type "${typeof methodHandler}" in the component definition. ` + 4994 `Did you reference the function correctly?`); 4995 } 4996 } 4997 } 4998 if (dataOptions) { 4999 if (!isFunction(dataOptions)) { 5000 warn(`The data option must be a function. ` + 5001 `Plain object usage is no longer supported.`); 5002 } 5003 const data = dataOptions.call(publicThis, publicThis);
vendor: 6,154 bytes, lines 5004-5160
5004 if (isPromise(data)) { 5005 warn(`data() returned a Promise - note data() cannot be async; If you ` + 5006 `intend to perform data fetching before component renders, use ` + 5007 `async setup() + <Suspense>.`); 5008 } 5009 if (!isObject(data)) { 5010 warn(`data() should return an object.`); 5011 } 5012 else { 5013 instance.data = reactive(data); 5014 { 5015 for (const key in data) { 5016 checkDuplicateProperties("Data" /* OptionTypes.DATA */, key); 5017 // expose data on ctx during dev 5018 if (!isReservedPrefix(key[0])) { 5019 Object.defineProperty(ctx, key, { 5020 configurable: true, 5021 enumerable: true, 5022 get: () => data[key], 5023 set: NOOP 5024 }); 5025 } 5026 } 5027 } 5028 } 5029 } 5030 // state initialization complete at this point - start caching access 5031 shouldCacheAccess = true; 5032 if (computedOptions) { 5033 for (const key in computedOptions) { 5034 const opt = computedOptions[key]; 5035 const get = isFunction(opt) 5036 ? opt.bind(publicThis, publicThis) 5037 : isFunction(opt.get) 5038 ? opt.get.bind(publicThis, publicThis) 5039 : NOOP; 5040 if (get === NOOP) { 5041 warn(`Computed property "${key}" has no getter.`); 5042 } 5043 const set = !isFunction(opt) && isFunction(opt.set) 5044 ? opt.set.bind(publicThis) 5045 : () => { 5046 warn(`Write operation failed: computed property "${key}" is readonly.`); 5047 } 5048 ; 5049 const c = computed({ 5050 get, 5051 set 5052 }); 5053 Object.defineProperty(ctx, key, { 5054 enumerable: true, 5055 configurable: true, 5056 get: () => c.value, 5057 set: v => (c.value = v) 5058 }); 5059 { 5060 checkDuplicateProperties("Computed" /* OptionTypes.COMPUTED */, key); 5061 } 5062 } 5063 } 5064 if (watchOptions) { 5065 for (const key in watchOptions) { 5066 createWatcher(watchOptions[key], ctx, publicThis, key); 5067 } 5068 } 5069 if (provideOptions) { 5070 const provides = isFunction(provideOptions) 5071 ? provideOptions.call(publicThis) 5072 : provideOptions; 5073 Reflect.ownKeys(provides).forEach(key => { 5074 provide(key, provides[key]); 5075 }); 5076 } 5077 if (created) { 5078 callHook$1(created, instance, "c" /* LifecycleHooks.CREATED */); 5079 } 5080 function registerLifecycleHook(register, hook) { 5081 if (isArray(hook)) { 5082 hook.forEach(_hook => register(_hook.bind(publicThis))); 5083 } 5084 else if (hook) { 5085 register(hook.bind(publicThis)); 5086 } 5087 } 5088 registerLifecycleHook(onBeforeMount, beforeMount); 5089 registerLifecycleHook(onMounted, mounted); 5090 registerLifecycleHook(onBeforeUpdate, beforeUpdate); 5091 registerLifecycleHook(onUpdated, updated); 5092 registerLifecycleHook(onActivated, activated); 5093 registerLifecycleHook(onDeactivated, deactivated); 5094 registerLifecycleHook(onErrorCaptured, errorCaptured); 5095 registerLifecycleHook(onRenderTracked, renderTracked); 5096 registerLifecycleHook(onRenderTriggered, renderTriggered); 5097 registerLifecycleHook(onBeforeUnmount, beforeUnmount); 5098 registerLifecycleHook(onUnmounted, unmounted); 5099 registerLifecycleHook(onServerPrefetch, serverPrefetch); 5100 if (isArray(expose)) { 5101 if (expose.length) { 5102 const exposed = instance.exposed || (instance.exposed = {}); 5103 expose.forEach(key => { 5104 Object.defineProperty(exposed, key, { 5105 get: () => publicThis[key], 5106 set: val => (publicThis[key] = val) 5107 }); 5108 }); 5109 } 5110 else if (!instance.exposed) { 5111 instance.exposed = {}; 5112 } 5113 } 5114 // options that are handled when creating the instance but also need to be 5115 // applied from mixins 5116 if (render && instance.render === NOOP) { 5117 instance.render = render; 5118 } 5119 if (inheritAttrs != null) { 5120 instance.inheritAttrs = inheritAttrs; 5121 } 5122 // asset options. 5123 if (components) 5124 instance.components = components; 5125 if (directives) 5126 instance.directives = directives; 5127 } 5128 function resolveInjections(injectOptions, ctx, checkDuplicateProperties = NOOP, unwrapRef = false) { 5129 if (isArray(injectOptions)) { 5130 injectOptions = normalizeInject(injectOptions); 5131 } 5132 for (const key in injectOptions) { 5133 const opt = injectOptions[key]; 5134 let injected; 5135 if (isObject(opt)) { 5136 if ('default' in opt) { 5137 injected = inject(opt.from || key, opt.default, true /* treat default function as factory */); 5138 } 5139 else { 5140 injected = inject(opt.from || key); 5141 } 5142 } 5143 else { 5144 injected = inject(opt); 5145 } 5146 if (isRef(injected)) { 5147 // TODO remove the check in 3.3 5148 if (unwrapRef) { 5149 Object.defineProperty(ctx, key, { 5150 enumerable: true, 5151 configurable: true, 5152 get: () => injected.value, 5153 set: v => (injected.value = v) 5154 }); 5155 } 5156 else { 5157 { 5158 warn(`injected property "${key}" is a ref and will be auto-unwrapped ` + 5159 `and no longer needs \`.value\` in the next minor release. ` + 5160 `To opt-in to the new behavior now, ` +
vendor: 7,185 bytes, lines 5161-5384
5161 `set \`app.config.unwrapInjectedRef = true\` (this config is ` + 5162 `temporary and will not be needed in the future.)`); 5163 } 5164 ctx[key] = injected; 5165 } 5166 } 5167 else { 5168 ctx[key] = injected; 5169 } 5170 { 5171 checkDuplicateProperties("Inject" /* OptionTypes.INJECT */, key); 5172 } 5173 } 5174 } 5175 function callHook$1(hook, instance, type) { 5176 callWithAsyncErrorHandling(isArray(hook) 5177 ? hook.map(h => h.bind(instance.proxy)) 5178 : hook.bind(instance.proxy), instance, type); 5179 } 5180 function createWatcher(raw, ctx, publicThis, key) { 5181 const getter = key.includes('.') 5182 ? createPathGetter(publicThis, key) 5183 : () => publicThis[key]; 5184 if (isString(raw)) { 5185 const handler = ctx[raw]; 5186 if (isFunction(handler)) { 5187 watch(getter, handler); 5188 } 5189 else { 5190 warn(`Invalid watch handler specified by key "${raw}"`, handler); 5191 } 5192 } 5193 else if (isFunction(raw)) { 5194 watch(getter, raw.bind(publicThis)); 5195 } 5196 else if (isObject(raw)) { 5197 if (isArray(raw)) { 5198 raw.forEach(r => createWatcher(r, ctx, publicThis, key)); 5199 } 5200 else { 5201 const handler = isFunction(raw.handler) 5202 ? raw.handler.bind(publicThis) 5203 : ctx[raw.handler]; 5204 if (isFunction(handler)) { 5205 watch(getter, handler, raw); 5206 } 5207 else { 5208 warn(`Invalid watch handler specified by key "${raw.handler}"`, handler); 5209 } 5210 } 5211 } 5212 else { 5213 warn(`Invalid watch option: "${key}"`, raw); 5214 } 5215 } 5216 /** 5217 * Resolve merged options and cache it on the component. 5218 * This is done only once per-component since the merging does not involve 5219 * instances. 5220 */ 5221 function resolveMergedOptions(instance) { 5222 const base = instance.type; 5223 const { mixins, extends: extendsOptions } = base; 5224 const { mixins: globalMixins, optionsCache: cache, config: { optionMergeStrategies } } = instance.appContext; 5225 const cached = cache.get(base); 5226 let resolved; 5227 if (cached) { 5228 resolved = cached; 5229 } 5230 else if (!globalMixins.length && !mixins && !extendsOptions) { 5231 { 5232 resolved = base; 5233 } 5234 } 5235 else { 5236 resolved = {}; 5237 if (globalMixins.length) { 5238 globalMixins.forEach(m => mergeOptions(resolved, m, optionMergeStrategies, true)); 5239 } 5240 mergeOptions(resolved, base, optionMergeStrategies); 5241 } 5242 if (isObject(base)) { 5243 cache.set(base, resolved); 5244 } 5245 return resolved; 5246 } 5247 function mergeOptions(to, from, strats, asMixin = false) { 5248 const { mixins, extends: extendsOptions } = from; 5249 if (extendsOptions) { 5250 mergeOptions(to, extendsOptions, strats, true); 5251 } 5252 if (mixins) { 5253 mixins.forEach((m) => mergeOptions(to, m, strats, true)); 5254 } 5255 for (const key in from) { 5256 if (asMixin && key === 'expose') { 5257 warn(`"expose" option is ignored when declared in mixins or extends. ` + 5258 `It should only be declared in the base component itself.`); 5259 } 5260 else { 5261 const strat = internalOptionMergeStrats[key] || (strats && strats[key]); 5262 to[key] = strat ? strat(to[key], from[key]) : from[key]; 5263 } 5264 } 5265 return to; 5266 } 5267 const internalOptionMergeStrats = { 5268 data: mergeDataFn, 5269 props: mergeObjectOptions, 5270 emits: mergeObjectOptions, 5271 // objects 5272 methods: mergeObjectOptions, 5273 computed: mergeObjectOptions, 5274 // lifecycle 5275 beforeCreate: mergeAsArray$1, 5276 created: mergeAsArray$1, 5277 beforeMount: mergeAsArray$1, 5278 mounted: mergeAsArray$1, 5279 beforeUpdate: mergeAsArray$1, 5280 updated: mergeAsArray$1, 5281 beforeDestroy: mergeAsArray$1, 5282 beforeUnmount: mergeAsArray$1, 5283 destroyed: mergeAsArray$1, 5284 unmounted: mergeAsArray$1, 5285 activated: mergeAsArray$1, 5286 deactivated: mergeAsArray$1, 5287 errorCaptured: mergeAsArray$1, 5288 serverPrefetch: mergeAsArray$1, 5289 // assets 5290 components: mergeObjectOptions, 5291 directives: mergeObjectOptions, 5292 // watch 5293 watch: mergeWatchOptions, 5294 // provide / inject 5295 provide: mergeDataFn, 5296 inject: mergeInject 5297 }; 5298 function mergeDataFn(to, from) { 5299 if (!from) { 5300 return to; 5301 } 5302 if (!to) { 5303 return from; 5304 } 5305 return function mergedDataFn() { 5306 return (extend)(isFunction(to) ? to.call(this, this) : to, isFunction(from) ? from.call(this, this) : from); 5307 }; 5308 } 5309 function mergeInject(to, from) { 5310 return mergeObjectOptions(normalizeInject(to), normalizeInject(from)); 5311 } 5312 function normalizeInject(raw) { 5313 if (isArray(raw)) { 5314 const res = {}; 5315 for (let i = 0; i < raw.length; i++) { 5316 res[raw[i]] = raw[i]; 5317 } 5318 return res; 5319 } 5320 return raw; 5321 } 5322 function mergeAsArray$1(to, from) { 5323 return to ? [...new Set([].concat(to, from))] : from; 5324 } 5325 function mergeObjectOptions(to, from) { 5326 return to ? extend(extend(Object.create(null), to), from) : from; 5327 } 5328 function mergeWatchOptions(to, from) { 5329 if (!to) 5330 return from; 5331 if (!from) 5332 return to; 5333 const merged = extend(Object.create(null), to); 5334 for (const key in from) { 5335 merged[key] = mergeAsArray$1(to[key], from[key]); 5336 } 5337 return merged; 5338 } 5339 5340 function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison 5341 isSSR = false) { 5342 const props = {}; 5343 const attrs = {}; 5344 def(attrs, InternalObjectKey, 1); 5345 instance.propsDefaults = Object.create(null); 5346 setFullProps(instance, rawProps, props, attrs); 5347 // ensure all declared prop keys are present 5348 for (const key in instance.propsOptions[0]) { 5349 if (!(key in props)) { 5350 props[key] = undefined; 5351 } 5352 } 5353 // validation 5354 { 5355 validateProps(rawProps || {}, props, instance); 5356 } 5357 if (isStateful) { 5358 // stateful 5359 instance.props = isSSR ? props : shallowReactive(props); 5360 } 5361 else { 5362 if (!instance.type.props) { 5363 // functional w/ optional props, props === attrs 5364 instance.props = attrs; 5365 } 5366 else { 5367 // functional w/ declared props 5368 instance.props = props; 5369 } 5370 } 5371 instance.attrs = attrs; 5372 } 5373 function isInHmrContext(instance) { 5374 while (instance) { 5375 if (instance.type.__hmrId) 5376 return true; 5377 instance = instance.parent; 5378 } 5379 } 5380 function updateProps(instance, rawProps, rawPrevProps, optimized) { 5381 const { props, attrs, vnode: { patchFlag } } = instance; 5382 const rawCurrentProps = toRaw(props); 5383 const [options] = instance.propsOptions; 5384 let hasAttrsChanged = false;
5385 if ( 5386 // always force full diff in dev 5387 // - #1942 if hmr is enabled with sfc component 5388 // - vite#872 non-sfc component used by sfc component 5389 !(isInHmrContext(instance)) && 5390 (optimized || patchFlag > 0) && 5391 !(patchFlag & 16 /* PatchFlags.FULL_PROPS */)) { 5392 if (patchFlag & 8 /* PatchFlags.PROPS */) { 5393 // Compiler-generated props & no keys change, just set the updated 5394 // the props. 5395 const propsToUpdate = instance.vnode.dynamicProps; 5396 for (let i = 0; i < propsToUpdate.length; i++) { 5397 let key = propsToUpdate[i]; 5398 // skip if the prop key is a declared emit event listener 5399 if (isEmitListener(instance.emitsOptions, key)) { 5400 continue; 5401 } 5402 // PROPS flag guarantees rawProps to be non-null 5403 const value = rawProps[key]; 5404 if (options) { 5405 // attr / props separation was done on init and will be consistent 5406 // in this code path, so just check if attrs have it. 5407 if (hasOwn(attrs, key)) { 5408 if (value !== attrs[key]) { 5409 attrs[key] = value; 5410 hasAttrsChanged = true; 5411 } 5412 } 5413 else { 5414 const camelizedKey = camelize(key); 5415 props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance, false /* isAbsent */); 5416 } 5417 } 5418 else { 5419 if (value !== attrs[key]) { 5420 attrs[key] = value; 5421 hasAttrsChanged = true; 5422 } 5423 } 5424 } 5425 } 5426 } 5427 else { 5428 // full props update. 5429 if (setFullProps(instance, rawProps, props, attrs)) { 5430 hasAttrsChanged = true; 5431 } 5432 // in case of dynamic props, check if we need to delete keys from 5433 // the props object 5434 let kebabKey; 5435 for (const key in rawCurrentProps) { 5436 if (!rawProps || 5437 // for camelCase 5438 (!hasOwn(rawProps, key) && 5439 // it's possible the original props was passed in as kebab-case 5440 // and converted to camelCase (#955) 5441 ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey)))) { 5442 if (options) { 5443 if (rawPrevProps && 5444 // for camelCase 5445 (rawPrevProps[key] !== undefined || 5446 // for kebab-case 5447 rawPrevProps[kebabKey] !== undefined)) { 5448 props[key] = resolvePropValue(options, rawCurrentProps, key, undefined, instance, true /* isAbsent */); 5449 } 5450 } 5451 else { 5452 delete props[key]; 5453 } 5454 } 5455 } 5456 // in the case of functional component w/o props declaration, props and 5457 // attrs point to the same object so it should already have been updated. 5458 if (attrs !== rawCurrentProps) { 5459 for (const key in attrs) { 5460 if (!rawProps || 5461 (!hasOwn(rawProps, key) && 5462 (!false ))) { 5463 delete attrs[key]; 5464 hasAttrsChanged = true; 5465 } 5466 } 5467 } 5468 } 5469 // trigger updates for $attrs in case it's used in component slots 5470 if (hasAttrsChanged) { 5471 trigger(instance, "set" /* TriggerOpTypes.SET */, '$attrs'); 5472 } 5473 { 5474 validateProps(rawProps || {}, props, instance); 5475 } 5476 } 5477 function setFullProps(instance, rawProps, props, attrs) { 5478 const [options, needCastKeys] = instance.propsOptions; 5479 let hasAttrsChanged = false;
vendor: 4,396 bytes, lines 5480-5599
5480 let rawCastValues; 5481 if (rawProps) { 5482 for (let key in rawProps) { 5483 // key, ref are reserved and never passed down 5484 if (isReservedProp(key)) { 5485 continue; 5486 } 5487 const value = rawProps[key]; 5488 // prop option names are camelized during normalization, so to support 5489 // kebab -> camel conversion here we need to camelize the key. 5490 let camelKey; 5491 if (options && hasOwn(options, (camelKey = camelize(key)))) { 5492 if (!needCastKeys || !needCastKeys.includes(camelKey)) { 5493 props[camelKey] = value; 5494 } 5495 else { 5496 (rawCastValues || (rawCastValues = {}))[camelKey] = value; 5497 } 5498 } 5499 else if (!isEmitListener(instance.emitsOptions, key)) { 5500 if (!(key in attrs) || value !== attrs[key]) { 5501 attrs[key] = value; 5502 hasAttrsChanged = true; 5503 } 5504 } 5505 } 5506 } 5507 if (needCastKeys) { 5508 const rawCurrentProps = toRaw(props); 5509 const castValues = rawCastValues || EMPTY_OBJ; 5510 for (let i = 0; i < needCastKeys.length; i++) { 5511 const key = needCastKeys[i]; 5512 props[key] = resolvePropValue(options, rawCurrentProps, key, castValues[key], instance, !hasOwn(castValues, key)); 5513 } 5514 } 5515 return hasAttrsChanged; 5516 } 5517 function resolvePropValue(options, props, key, value, instance, isAbsent) { 5518 const opt = options[key]; 5519 if (opt != null) { 5520 const hasDefault = hasOwn(opt, 'default'); 5521 // default values 5522 if (hasDefault && value === undefined) { 5523 const defaultValue = opt.default; 5524 if (opt.type !== Function && isFunction(defaultValue)) { 5525 const { propsDefaults } = instance; 5526 if (key in propsDefaults) { 5527 value = propsDefaults[key]; 5528 } 5529 else { 5530 setCurrentInstance(instance); 5531 value = propsDefaults[key] = defaultValue.call(null, props); 5532 unsetCurrentInstance(); 5533 } 5534 } 5535 else { 5536 value = defaultValue; 5537 } 5538 } 5539 // boolean casting 5540 if (opt[0 /* BooleanFlags.shouldCast */]) { 5541 if (isAbsent && !hasDefault) { 5542 value = false; 5543 } 5544 else if (opt[1 /* BooleanFlags.shouldCastTrue */] && 5545 (value === '' || value === hyphenate(key))) { 5546 value = true; 5547 } 5548 } 5549 } 5550 return value; 5551 } 5552 function normalizePropsOptions(comp, appContext, asMixin = false) { 5553 const cache = appContext.propsCache; 5554 const cached = cache.get(comp); 5555 if (cached) { 5556 return cached; 5557 } 5558 const raw = comp.props; 5559 const normalized = {}; 5560 const needCastKeys = []; 5561 // apply mixin/extends props 5562 let hasExtends = false; 5563 if (!isFunction(comp)) { 5564 const extendProps = (raw) => { 5565 hasExtends = true; 5566 const [props, keys] = normalizePropsOptions(raw, appContext, true); 5567 extend(normalized, props); 5568 if (keys) 5569 needCastKeys.push(...keys); 5570 }; 5571 if (!asMixin && appContext.mixins.length) { 5572 appContext.mixins.forEach(extendProps); 5573 } 5574 if (comp.extends) { 5575 extendProps(comp.extends); 5576 } 5577 if (comp.mixins) { 5578 comp.mixins.forEach(extendProps); 5579 } 5580 } 5581 if (!raw && !hasExtends) { 5582 if (isObject(comp)) { 5583 cache.set(comp, EMPTY_ARR); 5584 } 5585 return EMPTY_ARR; 5586 } 5587 if (isArray(raw)) { 5588 for (let i = 0; i < raw.length; i++) { 5589 if (!isString(raw[i])) { 5590 warn(`props must be strings when using array syntax.`, raw[i]); 5591 } 5592 const normalizedKey = camelize(raw[i]); 5593 if (validatePropName(normalizedKey)) { 5594 normalized[normalizedKey] = EMPTY_OBJ; 5595 } 5596 } 5597 } 5598 else if (raw) { 5599 if (!isObject(raw)) {
5600 warn(`invalid props options`, raw); 5601 } 5602 for (const key in raw) { 5603 const normalizedKey = camelize(key); 5604 if (validatePropName(normalizedKey)) { 5605 const opt = raw[key]; 5606 const prop = (normalized[normalizedKey] = 5607 isArray(opt) || isFunction(opt) ? { type: opt } : Object.assign({}, opt)); 5608 if (prop) { 5609 const booleanIndex = getTypeIndex(Boolean, prop.type); 5610 const stringIndex = getTypeIndex(String, prop.type); 5611 prop[0 /* BooleanFlags.shouldCast */] = booleanIndex > -1; 5612 prop[1 /* BooleanFlags.shouldCastTrue */] = 5613 stringIndex < 0 || booleanIndex < stringIndex; 5614 // if the prop needs boolean casting or default value 5615 if (booleanIndex > -1 || hasOwn(prop, 'default')) { 5616 needCastKeys.push(normalizedKey); 5617 } 5618 } 5619 } 5620 } 5621 } 5622 const res = [normalized, needCastKeys]; 5623 if (isObject(comp)) { 5624 cache.set(comp, res); 5625 } 5626 return res; 5627 } 5628 function validatePropName(key) { 5629 if (key[0] !== '$') { 5630 return true; 5631 } 5632 else { 5633 warn(`Invalid prop name: "${key}" is a reserved property.`); 5634 } 5635 return false; 5636 } 5637 // use function string name to check type constructors 5638 // so that it works across vms / iframes. 5639 function getType(ctor) { 5640 const match = ctor && ctor.toString().match(/^\s*(function|class) (\w+)/); 5641 return match ? match[2] : ctor === null ? 'null' : ''; 5642 } 5643 function isSameType(a, b) { 5644 return getType(a) === getType(b); 5645 } 5646 function getTypeIndex(type, expectedTypes) { 5647 if (isArray(expectedTypes)) { 5648 return expectedTypes.findIndex(t => isSameType(t, type)); 5649 } 5650 else if (isFunction(expectedTypes)) { 5651 return isSameType(expectedTypes, type) ? 0 : -1; 5652 } 5653 return -1; 5654 } 5655 /** 5656 * dev only 5657 */ 5658 function validateProps(rawProps, props, instance) { 5659 const resolvedValues = toRaw(props); 5660 const options = instance.propsOptions[0]; 5661 for (const key in options) { 5662 let opt = options[key]; 5663 if (opt == null) 5664 continue; 5665 validateProp(key, resolvedValues[key], opt, !hasOwn(rawProps, key) && !hasOwn(rawProps, hyphenate(key))); 5666 } 5667 } 5668 /** 5669 * dev only 5670 */ 5671 function validateProp(name, value, prop, isAbsent) { 5672 const { type, required, validator } = prop; 5673 // required! 5674 if (required && isAbsent) { 5675 warn('Missing required prop: "' + name + '"'); 5676 return; 5677 } 5678 // missing but optional 5679 if (value == null && !prop.required) { 5680 return; 5681 } 5682 // type check 5683 if (type != null && type !== true) { 5684 let isValid = false; 5685 const types = isArray(type) ? type : [type]; 5686 const expectedTypes = []; 5687 // value is valid as long as one of the specified types match 5688 for (let i = 0; i < types.length && !isValid; i++) { 5689 const { valid, expectedType } = assertType(value, types[i]); 5690 expectedTypes.push(expectedType || ''); 5691 isValid = valid; 5692 } 5693 if (!isValid) { 5694 warn(getInvalidTypeMessage(name, value, expectedTypes)); 5695 return; 5696 } 5697 } 5698 // custom validator 5699 if (validator && !validator(value)) { 5700 warn('Invalid prop: custom validator check failed for prop "' + name + '".'); 5701 } 5702 } 5703 const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol,BigInt'); 5704 /** 5705 * dev only 5706 */ 5707 function assertType(value, type) { 5708 let valid; 5709 const expectedType = getType(type); 5710 if (isSimpleType(expectedType)) { 5711 const t = typeof value; 5712 valid = t === expectedType.toLowerCase(); 5713 // for primitive wrapper objects 5714 if (!valid && t === 'object') { 5715 valid = value instanceof type; 5716 } 5717 } 5718 else if (expectedType === 'Object') { 5719 valid = isObject(value); 5720 } 5721 else if (expectedType === 'Array') { 5722 valid = isArray(value); 5723 } 5724 else if (expectedType === 'null') { 5725 valid = value === null; 5726 } 5727 else { 5728 valid = value instanceof type; 5729 } 5730 return { 5731 valid, 5732 expectedType 5733 }; 5734 } 5735 /** 5736 * dev only 5737 */ 5738 function getInvalidTypeMessage(name, value, expectedTypes) { 5739 let message = `Invalid prop: type check failed for prop "${name}".` + 5740 ` Expected ${expectedTypes.map(capitalize).join(' | ')}`; 5741 const expectedType = expectedTypes[0]; 5742 const receivedType = toRawType(value); 5743 const expectedValue = styleValue(value, expectedType); 5744 const receivedValue = styleValue(value, receivedType); 5745 // check if we need to specify expected value 5746 if (expectedTypes.length === 1 && 5747 isExplicable(expectedType) && 5748 !isBoolean(expectedType, receivedType)) { 5749 message += ` with value ${expectedValue}`; 5750 } 5751 message += `, got ${receivedType} `; 5752 // check if we need to specify received value 5753 if (isExplicable(receivedType)) { 5754 message += `with value ${receivedValue}.`; 5755 } 5756 return message; 5757 } 5758 /** 5759 * dev only 5760 */ 5761 function styleValue(value, type) { 5762 if (type === 'String') { 5763 return `"${value}"`; 5764 } 5765 else if (type === 'Number') { 5766 return `${Number(value)}`; 5767 } 5768 else { 5769 return `${value}`; 5770 } 5771 } 5772 /** 5773 * dev only 5774 */ 5775 function isExplicable(type) { 5776 const explicitTypes = ['string', 'number', 'boolean']; 5777 return explicitTypes.some(elem => type.toLowerCase() === elem); 5778 } 5779 /** 5780 * dev only 5781 */ 5782 function isBoolean(...args) { 5783 return args.some(elem => elem.toLowerCase() === 'boolean'); 5784 } 5785 5786 const isInternalKey = (key) => key[0] === '_' || key === '$stable'; 5787 const normalizeSlotValue = (value) => isArray(value) 5788 ? value.map(normalizeVNode) 5789 : [normalizeVNode(value)]; 5790 const normalizeSlot = (key, rawSlot, ctx) => { 5791 if (rawSlot._n) { 5792 // already normalized - #5353 5793 return rawSlot; 5794 } 5795 const normalized = withCtx((...args) => { 5796 if (true && currentInstance) { 5797 warn(`Slot "${key}" invoked outside of the render function: ` + 5798 `this will not track dependencies used in the slot. ` + 5799 `Invoke the slot function inside the render function instead.`); 5800 } 5801 return normalizeSlotValue(rawSlot(...args)); 5802 }, ctx); 5803 normalized._c = false;
5804 return normalized; 5805 }; 5806 const normalizeObjectSlots = (rawSlots, slots, instance) => { 5807 const ctx = rawSlots._ctx; 5808 for (const key in rawSlots) { 5809 if (isInternalKey(key)) 5810 continue; 5811 const value = rawSlots[key]; 5812 if (isFunction(value)) { 5813 slots[key] = normalizeSlot(key, value, ctx); 5814 } 5815 else if (value != null) { 5816 { 5817 warn(`Non-function value encountered for slot "${key}". ` + 5818 `Prefer function slots for better performance.`); 5819 } 5820 const normalized = normalizeSlotValue(value); 5821 slots[key] = () => normalized; 5822 } 5823 } 5824 }; 5825 const normalizeVNodeSlots = (instance, children) => { 5826 if (!isKeepAlive(instance.vnode) && 5827 !(false )) { 5828 warn(`Non-function value encountered for default slot. ` + 5829 `Prefer function slots for better performance.`); 5830 } 5831 const normalized = normalizeSlotValue(children); 5832 instance.slots.default = () => normalized; 5833 }; 5834 const initSlots = (instance, children) => { 5835 if (instance.vnode.shapeFlag & 32 /* ShapeFlags.SLOTS_CHILDREN */) { 5836 const type = children._; 5837 if (type) { 5838 // users can get the shallow readonly version of the slots object through `this.$slots`, 5839 // we should avoid the proxy object polluting the slots of the internal instance 5840 instance.slots = toRaw(children); 5841 // make compiler marker non-enumerable 5842 def(children, '_', type); 5843 } 5844 else { 5845 normalizeObjectSlots(children, (instance.slots = {})); 5846 } 5847 } 5848 else { 5849 instance.slots = {}; 5850 if (children) { 5851 normalizeVNodeSlots(instance, children); 5852 } 5853 } 5854 def(instance.slots, InternalObjectKey, 1); 5855 }; 5856 const updateSlots = (instance, children, optimized) => { 5857 const { vnode, slots } = instance; 5858 let needDeletionCheck = true; 5859 let deletionComparisonTarget = EMPTY_OBJ; 5860 if (vnode.shapeFlag & 32 /* ShapeFlags.SLOTS_CHILDREN */) { 5861 const type = children._; 5862 if (type) { 5863 // compiled slots. 5864 if (isHmrUpdating) { 5865 // Parent was HMR updated so slot content may have changed. 5866 // force update slots and mark instance for hmr as well 5867 extend(slots, children); 5868 } 5869 else if (optimized && type === 1 /* SlotFlags.STABLE */) { 5870 // compiled AND stable. 5871 // no need to update, and skip stale slots removal. 5872 needDeletionCheck = false; 5873 } 5874 else { 5875 // compiled but dynamic (v-if/v-for on slots) - update slots, but skip 5876 // normalization. 5877 extend(slots, children); 5878 // #2893 5879 // when rendering the optimized slots by manually written render function, 5880 // we need to delete the `slots._` flag if necessary to make subsequent updates reliable, 5881 // i.e. let the `renderSlot` create the bailed Fragment 5882 if (!optimized && type === 1 /* SlotFlags.STABLE */) { 5883 delete slots._; 5884 } 5885 } 5886 } 5887 else { 5888 needDeletionCheck = !children.$stable; 5889 normalizeObjectSlots(children, slots); 5890 }
5891 deletionComparisonTarget = children; 5892 } 5893 else if (children) { 5894 // non slot object children (direct value) passed to a component 5895 normalizeVNodeSlots(instance, children); 5896 deletionComparisonTarget = { default: 1 }; 5897 } 5898 // delete stale slots 5899 if (needDeletionCheck) { 5900 for (const key in slots) { 5901 if (!isInternalKey(key) && !(key in deletionComparisonTarget)) { 5902 delete slots[key]; 5903 } 5904 } 5905 } 5906 }; 5907 5908 function createAppContext() { 5909 return { 5910 app: null, 5911 config: { 5912 isNativeTag: NO, 5913 performance: false, 5914 globalProperties: {}, 5915 optionMergeStrategies: {}, 5916 errorHandler: undefined, 5917 warnHandler: undefined, 5918 compilerOptions: {} 5919 }, 5920 mixins: [], 5921 components: {}, 5922 directives: {}, 5923 provides: Object.create(null), 5924 optionsCache: new WeakMap(), 5925 propsCache: new WeakMap(), 5926 emitsCache: new WeakMap() 5927 }; 5928 } 5929 let uid$1 = 0; 5930 function createAppAPI(render, hydrate) { 5931 return function createApp(rootComponent, rootProps = null) { 5932 if (!isFunction(rootComponent)) { 5933 rootComponent = Object.assign({}, rootComponent); 5934 } 5935 if (rootProps != null && !isObject(rootProps)) { 5936 warn(`root props passed to app.mount() must be an object.`); 5937 rootProps = null; 5938 } 5939 const context = createAppContext(); 5940 const installedPlugins = new Set(); 5941 let isMounted = false; 5942 const app = (context.app = { 5943 _uid: uid$1++, 5944 _component: rootComponent, 5945 _props: rootProps, 5946 _container: null, 5947 _context: context, 5948 _instance: null, 5949 version, 5950 get config() { 5951 return context.config; 5952 }, 5953 set config(v) { 5954 { 5955 warn(`app.config cannot be replaced. Modify individual options instead.`); 5956 } 5957 }, 5958 use(plugin, ...options) { 5959 if (installedPlugins.has(plugin)) { 5960 warn(`Plugin has already been applied to target app.`); 5961 } 5962 else if (plugin && isFunction(plugin.install)) { 5963 installedPlugins.add(plugin); 5964 plugin.install(app, ...options); 5965 } 5966 else if (isFunction(plugin)) { 5967 installedPlugins.add(plugin); 5968 plugin(app, ...options); 5969 } 5970 else { 5971 warn(`A plugin must either be a function or an object with an "install" ` + 5972 `function.`); 5973 } 5974 return app; 5975 }, 5976 mixin(mixin) { 5977 { 5978 if (!context.mixins.includes(mixin)) { 5979 context.mixins.push(mixin); 5980 } 5981 else { 5982 warn('Mixin has already been applied to target app' + 5983 (mixin.name ? `: ${mixin.name}` : '')); 5984 } 5985 } 5986 return app; 5987 }, 5988 component(name, component) { 5989 { 5990 validateComponentName(name, context.config); 5991 } 5992 if (!component) { 5993 return context.components[name]; 5994 } 5995 if (context.components[name]) { 5996 warn(`Component "${name}" has already been registered in target app.`); 5997 } 5998 context.components[name] = component; 5999 return app; 6000 }, 6001 directive(name, directive) { 6002 { 6003 validateDirectiveName(name); 6004 } 6005 if (!directive) { 6006 return context.directives[name]; 6007 } 6008 if (context.directives[name]) { 6009 warn(`Directive "${name}" has already been registered in target app.`); 6010 } 6011 context.directives[name] = directive; 6012 return app; 6013 }, 6014 mount(rootContainer, isHydrate, isSVG) { 6015 if (!isMounted) { 6016 // #5571 6017 if (rootContainer.__vue_app__) { 6018 warn(`There is already an app instance mounted on the host container.\n` + 6019 ` If you want to mount another app on the same host container,` + 6020 ` you need to unmount the previous app by calling \`app.unmount()\` first.`); 6021 } 6022 const vnode = createVNode(rootComponent, rootProps); 6023 // store app context on the root VNode. 6024 // this will be set on the root instance on initial mount. 6025 vnode.appContext = context; 6026 // HMR root reload 6027 { 6028 context.reload = () => { 6029 render(cloneVNode(vnode), rootContainer, isSVG); 6030 }; 6031 } 6032 if (isHydrate && hydrate) { 6033 hydrate(vnode, rootContainer); 6034 } 6035 else { 6036 render(vnode, rootContainer, isSVG); 6037 } 6038 isMounted = true; 6039 app._container = rootContainer; 6040 rootContainer.__vue_app__ = app; 6041 { 6042 app._instance = vnode.component; 6043 devtoolsInitApp(app, version); 6044 } 6045 return getExposeProxy(vnode.component) || vnode.component.proxy; 6046 } 6047 else { 6048 warn(`App has already been mounted.\n` + 6049 `If you want to remount the same app, move your app creation logic ` + 6050 `into a factory function and create fresh app instances for each ` + 6051 `mount - e.g. \`const createMyApp = () => createApp(App)\``); 6052 } 6053 }, 6054 unmount() { 6055 if (isMounted) { 6056 render(null, app._container); 6057 { 6058 app._instance = null; 6059 devtoolsUnmountApp(app); 6060 } 6061 delete app._container.__vue_app__; 6062 } 6063 else { 6064 warn(`Cannot unmount an app that is not mounted.`); 6065 } 6066 }, 6067 provide(key, value) { 6068 if (key in context.provides) { 6069 warn(`App already provides property with key "${String(key)}". ` + 6070 `It will be overwritten with the new value.`); 6071 } 6072 context.provides[key] = value; 6073 return app; 6074 } 6075 }); 6076 return app; 6077 }; 6078 } 6079 6080 /** 6081 * Function for handling a template ref 6082 */ 6083 function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) { 6084 if (isArray(rawRef)) { 6085 rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount)); 6086 return; 6087 } 6088 if (isAsyncWrapper(vnode) && !isUnmount) { 6089 // when mounting async components, nothing needs to be done, 6090 // because the template ref is forwarded to inner component 6091 return; 6092 } 6093 const refValue = vnode.shapeFlag & 4 /* ShapeFlags.STATEFUL_COMPONENT */ 6094 ? getExposeProxy(vnode.component) || vnode.component.proxy 6095 : vnode.el; 6096 const value = isUnmount ? null : refValue; 6097 const { i: owner, r: ref } = rawRef; 6098 if (!owner) { 6099 warn(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` + 6100 `A vnode with ref must be created inside the render function.`); 6101 return; 6102 } 6103 const oldRef = oldRawRef && oldRawRef.r; 6104 const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs; 6105 const setupState = owner.setupState; 6106 // dynamic ref changed. unset old ref
6107 if (oldRef != null && oldRef !== ref) { 6108 if (isString(oldRef)) { 6109 refs[oldRef] = null; 6110 if (hasOwn(setupState, oldRef)) { 6111 setupState[oldRef] = null; 6112 } 6113 } 6114 else if (isRef(oldRef)) { 6115 oldRef.value = null; 6116 } 6117 } 6118 if (isFunction(ref)) { 6119 callWithErrorHandling(ref, owner, 12 /* ErrorCodes.FUNCTION_REF */, [value, refs]); 6120 } 6121 else { 6122 const _isString = isString(ref); 6123 const _isRef = isRef(ref); 6124 if (_isString || _isRef) { 6125 const doSet = () => { 6126 if (rawRef.f) { 6127 const existing = _isString 6128 ? hasOwn(setupState, ref) 6129 ? setupState[ref] 6130 : refs[ref] 6131 : ref.value; 6132 if (isUnmount) { 6133 isArray(existing) && remove(existing, refValue); 6134 } 6135 else { 6136 if (!isArray(existing)) { 6137 if (_isString) { 6138 refs[ref] = [refValue]; 6139 if (hasOwn(setupState, ref)) { 6140 setupState[ref] = refs[ref]; 6141 } 6142 } 6143 else { 6144 ref.value = [refValue]; 6145 if (rawRef.k) 6146 refs[rawRef.k] = ref.value; 6147 } 6148 } 6149 else if (!existing.includes(refValue)) { 6150 existing.push(refValue); 6151 } 6152 } 6153 } 6154 else if (_isString) { 6155 refs[ref] = value; 6156 if (hasOwn(setupState, ref)) { 6157 setupState[ref] = value; 6158 } 6159 } 6160 else if (_isRef) { 6161 ref.value = value; 6162 if (rawRef.k) 6163 refs[rawRef.k] = value; 6164 } 6165 else { 6166 warn('Invalid template ref type:', ref, `(${typeof ref})`); 6167 } 6168 }; 6169 if (value) { 6170 doSet.id = -1; 6171 queuePostRenderEffect(doSet, parentSuspense); 6172 } 6173 else { 6174 doSet(); 6175 } 6176 } 6177 else { 6178 warn('Invalid template ref type:', ref, `(${typeof ref})`); 6179 } 6180 } 6181 } 6182 6183 let hasMismatch = false; 6184 const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject'; 6185 const isComment = (node) => node.nodeType === 8 /* DOMNodeTypes.COMMENT */; 6186 // Note: hydration is DOM-specific 6187 // But we have to place it in core due to tight coupling with core - splitting 6188 // it out creates a ton of unnecessary complexity. 6189 // Hydration also depends on some renderer internal logic which needs to be 6190 // passed in via arguments. 6191 function createHydrationFunctions(rendererInternals) { 6192 const { mt: mountComponent, p: patch, o: { patchProp, createText, nextSibling, parentNode, remove, insert, createComment } } = rendererInternals; 6193 const hydrate = (vnode, container) => { 6194 if (!container.hasChildNodes()) { 6195 warn(`Attempting to hydrate existing markup but container is empty. ` + 6196 `Performing full mount instead.`); 6197 patch(null, vnode, container); 6198 flushPostFlushCbs(); 6199 container._vnode = vnode; 6200 return; 6201 } 6202 hasMismatch = false; 6203 hydrateNode(container.firstChild, vnode, null, null, null); 6204 flushPostFlushCbs(); 6205 container._vnode = vnode; 6206 if (hasMismatch && !false) { 6207 // this error should show up in production 6208 console.error(`Hydration completed but contains mismatches.`); 6209 } 6210 }; 6211 const hydrateNode = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized = false) => { 6212 const isFragmentStart = isComment(node) && node.data === '['; 6213 const onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragmentStart); 6214 const { type, ref, shapeFlag, patchFlag } = vnode; 6215 let domType = node.nodeType; 6216 vnode.el = node; 6217 if (patchFlag === -2 /* PatchFlags.BAIL */) { 6218 optimized = false;
6219 vnode.dynamicChildren = null; 6220 } 6221 let nextNode = null; 6222 switch (type) { 6223 case Text: 6224 if (domType !== 3 /* DOMNodeTypes.TEXT */) { 6225 // #5728 empty text node inside a slot can cause hydration failure 6226 // because the server rendered HTML won't contain a text node 6227 if (vnode.children === '') { 6228 insert((vnode.el = createText('')), parentNode(node), node); 6229 nextNode = node; 6230 } 6231 else { 6232 nextNode = onMismatch(); 6233 } 6234 } 6235 else { 6236 if (node.data !== vnode.children) { 6237 hasMismatch = true; 6238 warn(`Hydration text mismatch:` + 6239 `\n- Client: ${JSON.stringify(node.data)}` + 6240 `\n- Server: ${JSON.str
6240ingify(vnode.children)}`); 6241 node.data = vnode.children; 6242 } 6243 nextNode = nextSibling(node); 6244 } 6245 break; 6246 case Comment: 6247 if (domType !== 8 /* DOMNodeTypes.COMMENT */ || isFragmentStart) { 6248 nextNode = onMismatch(); 6249 } 6250 else { 6251 nextNode = nextSibling(node); 6252 } 6253 break; 6254 case Static: 6255 if (isFragmentStart) { 6256 // entire template is static but SSRed as a fragment 6257 node = nextSibling(node); 6258 domType = node.nodeType; 6259 } 6260 if (domType === 1 /* DOMNodeTypes.ELEMENT */ || domType === 3 /* DOMNodeTypes.TEXT */) { 6261 // determine anchor, adopt content 6262 nextNode = node; 6263 // if the static vnode has its content stripped during build, 6264 // adopt it from the server-rendered HTML. 6265 const needToAdoptContent = !vnode.children.length; 6266 for (let i = 0; i < vnode.staticCount; i++) { 6267 if (needToAdoptContent) 6268 vnode.children += 6269 nextNode.nodeType === 1 /* DOMNodeTypes.ELEMENT */ 6270 ? nextNode.outerHTML 6271 : nextNode.data; 6272 if (i === vnode.staticCount - 1) { 6273 vnode.anchor = nextNode; 6274 } 6275 nextNode = nextSibling(nextNode); 6276 } 6277 return isFragmentStart ? nextSibling(nextNode) : nextNode; 6278 } 6279 else { 6280 onMismatch(); 6281 } 6282 break; 6283 case Fragment: 6284 if (!isFragmentStart) { 6285 nextNode = onMismatch(); 6286 } 6287 else { 6288 nextNode = hydrateFragment(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized); 6289 } 6290 break; 6291 default: 6292 if (shapeFlag & 1 /* ShapeFlags.ELEMENT */) { 6293 if (domType !== 1 /* DOMNodeTypes.ELEMENT */ || 6294 vnode.type.toLowerCase() !== 6295 node.tagName.toLowerCase()) { 6296 nextNode = onMismatch(); 6297 } 6298 else { 6299 nextNode = hydrateElement(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized); 6300 } 6301 } 6302 else if (shapeFlag & 6 /* ShapeFlags.COMPONENT */) { 6303 // when setting up the render effect, if the initial vnode already 6304 // has .el set, the component will perform hydration instead of mount 6305 // on its sub-tree. 6306 vnode.slotScopeIds = slotScopeIds; 6307 const container = parentNode(node); 6308 mountComponent(vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), optimized); 6309 // component may be async, so in the case of fragments we cannot rely 6310 // on component's rendered output to determine the end of the fragment 6311 // instead, we do a lookahead to find the end anchor node. 6312 nextNode = isFragmentStart 6313 ? locateClosingAsyncAnchor(node) 6314 : nextSibling(node); 6315 // #4293 teleport as component root 6316 if (nextNode && 6317 isComment(nextNode) && 6318 nextNode.data === 'teleport end') { 6319 nextNode = nextSibling(nextNode); 6320 } 6321 // #3787 6322 // if component is async, it may get moved / unmounted before its 6323 // inner component is loaded, so we need to give it a placeholder 6324 // vnode that matches its adopted DOM. 6325 if (isAsyncWrapper(vnode)) { 6326 let subTree; 6327 if (isFragmentStart) { 6328 subTree = createVNode(Fragment); 6329 subTree.anchor = nextNode 6330 ? nextNode.previousSibling 6331 : container.lastChild; 6332 } 6333 else { 6334 subTree = 6335 node.nodeType === 3 ? createTextVNode('') : createVNode('div'); 6336 } 6337 subTree.el = node; 6338 vnode.component.subTree = subTree; 6339 } 6340 } 6341 else if (shapeFlag & 64 /* ShapeFlags.TELEPORT */) { 6342 if (domType !== 8 /* DOMNodeTypes.COMMENT */) { 6343 nextNode = onMismatch(); 6344 } 6345 else { 6346 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, rendererInternals, hydrateChildren); 6347 } 6348 } 6349 else if (shapeFlag & 128 /* ShapeFlags.SUSPENSE */) { 6350 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, isSVGContainer(parentNode(node)), slotScopeIds, optimized, rendererInternals, hydrateNode); 6351 } 6352 else { 6353 warn('Invalid HostVNode type:', type, `(${typeof type})`); 6354 } 6355 } 6356 if (ref != null) { 6357 setRef(ref, null, parentSuspense, vnode); 6358 } 6359 return nextNode; 6360 }; 6361 const hydrateElement = (el, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => { 6362 optimized = optimized || !!vnode.dynamicChildren; 6363 const { type, props, patchFlag, shapeFlag, dirs } = vnode; 6364 // #4006 for form elements with non-string v-model value bindings 6365 // e.g. <option :value="obj">, <input type="checkbox" :true-value="1"> 6366 const forcePatchValue = (type === 'input' && dirs) || type === 'option';
6367 // skip props & children if this is hoisted static nodes 6368 // #5405 in dev, always hydrate children for HMR 6369 { 6370 if (dirs) { 6371 invokeDirectiveHook(vnode, null, parentComponent, 'created'); 6372 } 6373 // props 6374 if (props) { 6375 if (forcePatchValue || 6376 !optimized || 6377 patchFlag & (16 /* PatchFlags.FULL_PROPS */ | 32 /* PatchFlags.HYDRATE_EVENTS */)) { 6378 for (const key in props) { 6379 if ((forcePatchValue && key.endsWith('value')) || 6380 (isOn(key) && !isReservedProp(key))) { 6381 patchProp(el, key, null, props[key], false, undefined, parentComponent); 6382 } 6383 } 6384 } 6385 else if (props.onClick) { 6386 // Fast path for click listeners (which is most often) to avoid 6387 // iterating through props. 6388 patchProp(el, 'onClick', null, props.onClick, false, undefined, parentComponent); 6389 } 6390 } 6391 // vnode / directive hooks 6392 let vnodeHooks; 6393 if ((vnodeHooks = props && props.onVnodeBeforeMount)) { 6394 invokeVNodeHook(vnodeHooks, parentComponent, vnode); 6395 } 6396 if (dirs) { 6397 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount'); 6398 } 6399 if ((vnodeHooks = props && props.onVnodeMounted) || dirs) { 6400 queueEffectWithSuspense(() => { 6401 vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode); 6402 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted'); 6403 }, parentSuspense); 6404 } 6405 // children 6406 if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */ && 6407 // skip if element has innerHTML / textContent 6408 !(props && (props.innerHTML || props.textContent))) { 6409 let next = hydrateChildren(el.firstChild, vnode, el, parentComponent, parentSuspense, slotScopeIds, optimized); 6410 let hasWarned = false; 6411 while (next) { 6412 hasMismatch = true; 6413 if (!hasWarned) { 6414 warn(`Hydration children mismatch in <${vnode.type}>: ` + 6415 `server rendered element contains more child nodes than client vdom.`); 6416 hasWarned = true; 6417 } 6418 // The SSRed DOM contains more nodes than it should. Remove them. 6419 const cur = next; 6420 next = next.nextSibling; 6421 remove(cur); 6422 } 6423 } 6424 else if (shapeFlag & 8 /* ShapeFlags.TEXT_CHILDREN */) { 6425 if (el.textContent !== vnode.children) { 6426 hasMismatch = true; 6427 warn(`Hydration text content mismatch in <${vnode.type}>:\n` + 6428 `- Client: ${el.textContent}\n` + 6429 `- Server: ${vnode.children}`); 6430 el.textContent = vnode.children; 6431 } 6432 } 6433 } 6434 return el.nextSibling; 6435 }; 6436 const hydrateChildren = (node, parentVNode, container, parentComponent, parentSuspense, slotScopeIds, optimized) => { 6437 optimized = optimized || !!parentVNode.dynamicChildren; 6438 const children = parentVNode.children; 6439 const l = children.length; 6440 let hasWarned = false; 6441 for (let i = 0; i < l; i++) { 6442 const vnode = optimized 6443 ? children[i] 6444 : (children[i] = normalizeVNode(children[i])); 6445 if (node) { 6446 node = hydrateNode(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized); 6447 } 6448 else if (vnode.type === Text && !vnode.children) { 6449 continue; 6450 } 6451 else { 6452 hasMismatch = true; 6453 if (!hasWarned) { 6454 warn(`Hydration children mismatch in <${container.tagName.toLowerCase()}>: ` + 6455 `server rendered element contains fewer child nodes than client vdom.`); 6456 hasWarned = true; 6457 } 6458 // the SSRed DOM didn't contain enough nodes. Mount the missing ones. 6459 patch(null, vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds); 6460 } 6461 } 6462 return node; 6463 }; 6464 const hydrateFragment = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => { 6465 const { slotScopeIds: fragmentSlotScopeIds } = vnode; 6466 if (fragmentSlotScopeIds) { 6467 slotScopeIds = slotScopeIds 6468 ? slotScopeIds.concat(fragmentSlotScopeIds) 6469 : fragmentSlotScopeIds; 6470 } 6471 const container = parentNode(node); 6472 const next = hydrateChildren(nextSibling(node), vnode, container, parentComponent, parentSuspense, slotScopeIds, optimized); 6473 if (next && isComment(next) && next.data === ']') { 6474 return nextSibling((vnode.anchor = next)); 6475 } 6476 else { 6477 // fragment didn't hydrate successfully, since we didn't get a end anchor 6478 // back. This should have led to node/children mismatch warnings. 6479 hasMismatch = true;
6480 // since the anchor is missing, we need to create one and insert it 6481 insert((vnode.anchor = createComment(`]`)), container, next); 6482 return next; 6483 } 6484 }; 6485 const handleMismatch = (node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragment) => { 6486 hasMismatch = true; 6487 warn(`Hydration node mismatch:\n- Client vnode:`, vnode.type, `\n- Server rendered DOM:`, node, node.nodeType === 3 /* DOMNodeTypes.TEXT */ 6488 ? `(text)` 6489 : isComment(node) && node.data === '[' 6490 ? `(start of fragment)` 6491 : ``); 6492 vnode.el = null; 6493 if (isFragment) { 6494 // remove excessive fragment nodes 6495 const end = locateClosingAsyncAnchor(node); 6496 while (true) { 6497 const next = nextSibling(node); 6498 if (next && next !== end) { 6499 remove(next); 6500 } 6501 else { 6502 break; 6503 } 6504 } 6505 } 6506 const next = nextSibling(node); 6507 const container = parentNode(node); 6508 remove(node); 6509 patch(null, vnode, container, next, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds); 6510 return next; 6511 }; 6512 const locateClosingAsyncAnchor = (node) => { 6513 let match = 0; 6514 while (node) { 6515 node = nextSibling(node); 6516 if (node && isComment(node)) { 6517 if (node.data === '[') 6518 match++; 6519 if (node.data === ']') { 6520 if (match === 0) { 6521 return nextSibling(node); 6522 } 6523 else { 6524 match--; 6525 } 6526 } 6527 } 6528 } 6529 return node; 6530 }; 6531 return [hydrate, hydrateNode]; 6532 } 6533 6534 /* eslint-disable no-restricted-globals */ 6535 let supported; 6536 let perf; 6537 function startMeasure(instance, type) { 6538 if (instance.appContext.config.performance && isSupported()) { 6539 perf.mark(`vue-${type}-${instance.uid}`); 6540 } 6541 { 6542 devtoolsPerfStart(instance, type, isSupported() ? perf.now() : Date.now()); 6543 } 6544 } 6545 function endMeasure(instance, type) { 6546 if (instance.appContext.config.performance && isSupported()) { 6547 const startTag = `vue-${type}-${instance.uid}`; 6548 const endTag = startTag + `:end`; 6549 perf.mark(endTag); 6550 perf.measure(`<${formatComponentName(instance, instance.type)}> ${type}`, startTag, endTag); 6551 perf.clearMarks(startTag); 6552 perf.clearMarks(endTag); 6553 } 6554 { 6555 devtoolsPerfEnd(instance, type, isSupported() ? perf.now() : Date.now()); 6556 } 6557 } 6558 function isSupported() { 6559 if (supported !== undefined) { 6560 return supported; 6561 } 6562 if (typeof window !== 'undefined' && window.performance) { 6563 supported = true; 6564 perf = window.performance; 6565 } 6566 else { 6567 supported = false; 6568 } 6569 return supported; 6570 } 6571 6572 const queuePostRenderEffect = queueEffectWithSuspense 6573 ; 6574 /** 6575 * The createRenderer function accepts two generic arguments: 6576 * HostNode and HostElement, corresponding to Node and Element types in the 6577 * host environment. For example, for runtime-dom, HostNode would be the DOM 6578 * `Node` interface and HostElement would be the DOM `Element` interface. 6579 * 6580 * Custom renderers can pass in the platform specific types like this: 6581 * 6582 * ``` js 6583 * const { render, createApp } = createRenderer<Node, Element>({ 6584 * patchProp, 6585 * ...nodeOps 6586 * }) 6587 * ``` 6588 */ 6589 function createRenderer(options) { 6590 return baseCreateRenderer(options); 6591 } 6592 // Separate API for creating hydration-enabled renderer. 6593 // Hydration logic is only used when calling this function, making it 6594 // tree-shakable. 6595 function createHydrationRenderer(options) { 6596 return baseCreateRenderer(options, createHydrationFunctions); 6597 } 6598 // implementation 6599 function baseCreateRenderer(options, createHydrationFns) { 6600 const target = getGlobalThis(); 6601 target.__VUE__ = true; 6602 { 6603 setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__, target); 6604 } 6605 const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, setScopeId: hostSetScopeId =
vendor: 7,015 bytes, lines 6605-6758
6605NOOP, insertStaticContent: hostInsertStaticContent } = options; 6606 // Note: functions inside this closure should use `const xxx = () => {}` 6607 // style in order to prevent being inlined by minifiers. 6608 const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, slotScopeIds = null, optimized = isHmrUpdating ? false : !!n2.dynamicChildren) => { 6609 if (n1 === n2) { 6610 return; 6611 } 6612 // patching & not same type, unmount old tree 6613 if (n1 && !isSameVNodeType(n1, n2)) { 6614 anchor = getNextHostNode(n1); 6615 unmount(n1, parentComponent, parentSuspense, true); 6616 n1 = null; 6617 } 6618 if (n2.patchFlag === -2 /* PatchFlags.BAIL */) { 6619 optimized = false; 6620 n2.dynamicChildren = null; 6621 } 6622 const { type, ref, shapeFlag } = n2; 6623 switch (type) { 6624 case Text: 6625 processText(n1, n2, container, anchor); 6626 break; 6627 case Comment: 6628 processCommentNode(n1, n2, container, anchor); 6629 break; 6630 case Static: 6631 if (n1 == null) { 6632 mountStaticNode(n2, container, anchor, isSVG); 6633 } 6634 else { 6635 patchStaticNode(n1, n2, container, isSVG); 6636 } 6637 break; 6638 case Fragment: 6639 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); 6640 break; 6641 default: 6642 if (shapeFlag & 1 /* ShapeFlags.ELEMENT */) { 6643 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); 6644 } 6645 else if (shapeFlag & 6 /* ShapeFlags.COMPONENT */) { 6646 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); 6647 } 6648 else if (shapeFlag & 64 /* ShapeFlags.TELEPORT */) { 6649 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals); 6650 } 6651 else if (shapeFlag & 128 /* ShapeFlags.SUSPENSE */) { 6652 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals); 6653 } 6654 else { 6655 warn('Invalid VNode type:', type, `(${typeof type})`); 6656 } 6657 } 6658 // set ref 6659 if (ref != null && parentComponent) { 6660 setRef(ref, n1 && n1.ref, parentSuspense, n2 || n1, !n2); 6661 } 6662 }; 6663 const processText = (n1, n2, container, anchor) => { 6664 if (n1 == null) { 6665 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor); 6666 } 6667 else { 6668 const el = (n2.el = n1.el); 6669 if (n2.children !== n1.children) { 6670 hostSetText(el, n2.children); 6671 } 6672 } 6673 }; 6674 const processCommentNode = (n1, n2, container, anchor) => { 6675 if (n1 == null) { 6676 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor); 6677 } 6678 else { 6679 // there's no support for dynamic comments 6680 n2.el = n1.el; 6681 } 6682 }; 6683 const mountStaticNode = (n2, container, anchor, isSVG) => { 6684 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG, n2.el, n2.anchor); 6685 }; 6686 /** 6687 * Dev / HMR only 6688 */ 6689 const patchStaticNode = (n1, n2, container, isSVG) => { 6690 // static nodes are only patched during dev for HMR 6691 if (n2.children !== n1.children) { 6692 const anchor = hostNextSibling(n1.anchor); 6693 // remove existing 6694 removeStaticNode(n1); 6695 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG); 6696 } 6697 else { 6698 n2.el = n1.el; 6699 n2.anchor = n1.anchor; 6700 } 6701 }; 6702 const moveStaticNode = ({ el, anchor }, container, nextSibling) => { 6703 let next; 6704 while (el && el !== anchor) { 6705 next = hostNextSibling(el); 6706 hostInsert(el, container, nextSibling); 6707 el = next; 6708 } 6709 hostInsert(anchor, container, nextSibling); 6710 }; 6711 const removeStaticNode = ({ el, anchor }) => { 6712 let next; 6713 while (el && el !== anchor) { 6714 next = hostNextSibling(el); 6715 hostRemove(el); 6716 el = next; 6717 } 6718 hostRemove(anchor); 6719 }; 6720 const processElement = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => { 6721 isSVG = isSVG || n2.type === 'svg'; 6722 if (n1 == null) { 6723 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); 6724 } 6725 else { 6726 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); 6727 } 6728 }; 6729 const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => { 6730 let el; 6731 let vnodeHook; 6732 const { type, props, shapeFlag, transition, dirs } = vnode; 6733 el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is, props); 6734 // mount children first, since some props may rely on child content 6735 // being already rendered, e.g. `<select value>` 6736 if (shapeFlag & 8 /* ShapeFlags.TEXT_CHILDREN */) { 6737 hostSetElementText(el, vnode.children); 6738 } 6739 else if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) { 6740 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', slotScopeIds, optimized); 6741 } 6742 if (dirs) { 6743 invokeDirectiveHook(vnode, null, parentComponent, 'created'); 6744 } 6745 // scopeId 6746 setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent); 6747 // props 6748 if (props) { 6749 for (const key in props) { 6750 if (key !== 'value' && !isReservedProp(key)) { 6751 hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren); 6752 } 6753 } 6754 /** 6755 * Special case for setting value on DOM elements: 6756 * - it can be order-sensitive (e.g. should be set *after* min/max, #2325, #4024) 6757 * - it needs to be forced (#1471) 6758 * #2353 proposes adding another renderer option to configure this, but
6759 * the properties affects are so finite it is worth special casing it 6760 * here to reduce the complexity. (Special casing it also should not 6761 * affect non-DOM renderers) 6762 */ 6763 if ('value' in props) { 6764 hostPatchProp(el, 'value', null, props.value); 6765 } 6766 if ((vnodeHook = props.onVnodeBeforeMount)) { 6767 invokeVNodeHook(vnodeHook, parentComponent, vnode); 6768 } 6769 } 6770 { 6771 Object.defineProperty(el, '__vnode', { 6772 value: vnode, 6773 enumerable: false 6774 }); 6775 Object.defineProperty(el, '__vueParentComponent', { 6776 value: parentComponent, 6777 enumerable: false 6778 }); 6779 } 6780 if (dirs) { 6781 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount'); 6782 } 6783 // #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved 6784 // #1689 For inside suspense + suspense resolved case, just call it 6785 const needCallTransitionHooks = (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) && 6786 transition && 6787 !transition.persisted; 6788 if (needCallTransitionHooks) { 6789 transition.beforeEnter(el); 6790 } 6791 hostInsert(el, container, anchor); 6792 if ((vnodeHook = props && props.onVnodeMounted) || 6793 needCallTransitionHooks || 6794 dirs) { 6795 queuePostRenderEffect(() => { 6796 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode); 6797 needCallTransitionHooks && transition.enter(el); 6798 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted'); 6799 }, parentSuspense); 6800 } 6801 }; 6802 const setScopeId = (el, vnode, scopeId, slotScopeIds, parentComponent) => { 6803 if (scopeId) { 6804 hostSetScopeId(el, scopeId); 6805 } 6806 if (slotScopeIds) { 6807 for (let i = 0; i < slotScopeIds.length; i++) { 6808 hostSetScopeId(el, slotScopeIds[i]); 6809 } 6810 } 6811 if (parentComponent) { 6812 let subTree = parentComponent.subTree; 6813 if (subTree.patchFlag > 0 && 6814 subTree.patchFlag & 2048 /* PatchFlags.DEV_ROOT_FRAGMENT */) { 6815 subTree = 6816 filterSingleRoot(subTree.children) || subTree; 6817 } 6818 if (vnode === subTree) { 6819 const parentVNode = parentComponent.vnode; 6820 setScopeId(el, parentVNode, parentVNode.scopeId, parentVNode.slotScopeIds, parentComponent.parent); 6821 } 6822 } 6823 }; 6824 const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, start = 0) => { 6825 for (let i = start; i < children.length; i++) { 6826 const child = (children[i] = optimized 6827 ? cloneIfMounted(children[i]) 6828 : normalizeVNode(children[i])); 6829 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); 6830 } 6831 }; 6832 const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => { 6833 const el = (n2.el = n1.el); 6834 let { patchFlag, dynamicChildren, dirs } = n2; 6835 // #1426 take the old vnode's patch flag into account since user may clone a 6836 // compiler-generated vnode, which de-opts to FULL_PROPS 6837 patchFlag |= n1.patchFlag & 16 /* PatchFlags.FULL_PROPS */; 6838 const oldProps = n1.props || EMPTY_OBJ; 6839 const newProps = n2.props || EMPTY_OBJ; 6840 let vnodeHook; 6841 // disable recurse in beforeUpdate hooks 6842 parentComponent && toggleRecurse(parentComponent, false); 6843 if ((vnodeHook = newProps.onVnodeBeforeUpdate)) { 6844 invokeVNodeHook(vnodeHook, parentComponent, n2, n1); 6845 } 6846 if (dirs) { 6847 invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate'); 6848 } 6849 parentComponent && toggleRecurse(parentComponent, true); 6850 if (isHmrUpdating) { 6851 // HMR updated, force full diff 6852 patchFlag = 0; 6853 optimized = false;
vendor: 5,096 bytes, lines 6854-6944
6854 dynamicChildren = null; 6855 } 6856 const areChildrenSVG = isSVG && n2.type !== 'foreignObject'; 6857 if (dynamicChildren) { 6858 patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds); 6859 if (parentComponent && parentComponent.type.__hmrId) { 6860 traverseStaticChildren(n1, n2); 6861 } 6862 } 6863 else if (!optimized) { 6864 // full diff 6865 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds, false); 6866 } 6867 if (patchFlag > 0) { 6868 // the presence of a patchFlag means this element's render code was 6869 // generated by the compiler and can take the fast path. 6870 // in this path old node and new node are guaranteed to have the same shape 6871 // (i.e. at the exact same position in the source template) 6872 if (patchFlag & 16 /* PatchFlags.FULL_PROPS */) { 6873 // element props contain dynamic keys, full diff needed 6874 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG); 6875 } 6876 else { 6877 // class 6878 // this flag is matched when the element has dynamic class bindings. 6879 if (patchFlag & 2 /* PatchFlags.CLASS */) { 6880 if (oldProps.class !== newProps.class) { 6881 hostPatchProp(el, 'class', null, newProps.class, isSVG); 6882 } 6883 } 6884 // style 6885 // this flag is matched when the element has dynamic style bindings 6886 if (patchFlag & 4 /* PatchFlags.STYLE */) { 6887 hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG); 6888 } 6889 // props 6890 // This flag is matched when the element has dynamic prop/attr bindings 6891 // other than class and style. The keys of dynamic prop/attrs are saved for 6892 // faster iteration. 6893 // Note dynamic keys like :[foo]="bar" will cause this optimization to 6894 // bail out and go through a full diff because we need to unset the old key 6895 if (patchFlag & 8 /* PatchFlags.PROPS */) { 6896 // if the flag is present then dynamicProps must be non-null 6897 const propsToUpdate = n2.dynamicProps; 6898 for (let i = 0; i < propsToUpdate.length; i++) { 6899 const key = propsToUpdate[i]; 6900 const prev = oldProps[key]; 6901 const next = newProps[key]; 6902 // #1471 force patch value 6903 if (next !== prev || key === 'value') { 6904 hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren); 6905 } 6906 } 6907 } 6908 } 6909 // text 6910 // This flag is matched when the element has only dynamic text children. 6911 if (patchFlag & 1 /* PatchFlags.TEXT */) { 6912 if (n1.children !== n2.children) { 6913 hostSetElementText(el, n2.children); 6914 } 6915 } 6916 } 6917 else if (!optimized && dynamicChildren == null) { 6918 // unoptimized, full diff 6919 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG); 6920 } 6921 if ((vnodeHook = newProps.onVnodeUpdated) || dirs) { 6922 queuePostRenderEffect(() => { 6923 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1); 6924 dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated'); 6925 }, parentSuspense); 6926 } 6927 }; 6928 // The fast path for blocks. 6929 const patchBlockChildren = (oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG, slotScopeIds) => { 6930 for (let i = 0; i < newChildren.length; i++) { 6931 const oldVNode = oldChildren[i]; 6932 const newVNode = newChildren[i]; 6933 // Determine the container (parent element) for the patch. 6934 const container = 6935 // oldVNode may be an errored async setup() component inside Suspense 6936 // which will not have a mounted element 6937 oldVNode.el && 6938 // - In the case of a Fragment, we need to provide the actual parent 6939 // of the Fragment itself so it can move its children. 6940 (oldVNode.type === Fragment || 6941 // - In the case of different nodes, there is going to be a replacement 6942 // which also requires the correct parent container 6943 !isSameVNodeType(oldVNode, newVNode) || 6944 // - In the case of a component, it could contain anything.
6945 oldVNode.shapeFlag & (6 /* ShapeFlags.COMPONENT */ | 64 /* ShapeFlags.TELEPORT */)) 6946 ? hostParentNode(oldVNode.el) 6947 : // In other cases, the parent container is not actually used so we 6948 // just pass the block element here to avoid a DOM parentNode call. 6949 fallbackContainer; 6950 patch(oldVNode, newVNode, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, true); 6951 } 6952 }; 6953 const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => { 6954 if (oldProps !== newProps) { 6955 if (oldProps !== EMPTY_OBJ) { 6956 for (const key in oldProps) { 6957 if (!isReservedProp(key) && !(key in newProps)) { 6958 hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren); 6959 } 6960 } 6961 } 6962 for (const key in newProps) { 6963 // empty string is not valid prop 6964 if (isReservedProp(key)) 6965 continue; 6966 const next = newProps[key]; 6967 const prev = oldProps[key]; 6968 // defer patching value 6969 if (next !== prev && key !== 'value') { 6970 hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren); 6971 } 6972 } 6973 if ('value' in newProps) { 6974 hostPatchProp(el, 'value', oldProps.value, newProps.value); 6975 } 6976 } 6977 }; 6978 const processFragment = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => { 6979 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText('')); 6980 const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText('')); 6981 let { patchFlag, dynamicChildren, slotScopeIds: fragmentSlotScopeIds } = n2; 6982 if (// #5523 dev root fragment may inherit directives 6983 (isHmrUpdating || patchFlag & 2048 /* PatchFlags.DEV_ROOT_FRAGMENT */)) { 6984 // HMR updated / Dev root fragment (w/ comments), force full diff 6985 patchFlag = 0; 6986 optimized = false; 6987 dynamicChildren = null; 6988 } 6989 // check if this is a slot fragment with :slotted scope ids 6990 if (fragmentSlotScopeIds) { 6991 slotScopeIds = slotScopeIds 6992 ? slotScopeIds.concat(fragmentSlotScopeIds) 6993 : fragmentSlotScopeIds; 6994 } 6995 if (n1 == null) { 6996 hostInsert(fragmentStartAnchor, container, anchor); 6997 hostInsert(fragmentEndAnchor, container, anchor); 6998 // a fragment can only have array children 6999 // since they are either generated by the compiler, or implicitly created 7000 // from arrays. 7001 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); 7002 } 7003 else { 7004 if (patchFlag > 0 && 7005 patchFlag & 64 /* PatchFlags.STABLE_FRAGMENT */ && 7006 dynamicChildren && 7007 // #2715 the previous fragment could've been a BAILed one as a result 7008 // of renderSlot() with no valid children 7009 n1.dynamicChildren) { 7010 // a stable fragment (template root or <template v-for>) doesn't need to 7011 // patch children order, but it may contain dynamicChildren. 7012 patchBlockChildren(n1.dynamicChildren, dynamicChildren, container, parentComponent, parentSuspense, isSVG, slotScopeIds); 7013 if (parentComponent && parentComponent.type.__hmrId) { 7014 traverseStaticChildren(n1, n2); 7015 } 7016 else if ( 7017 // #2080 if the stable fragment has a key, it's a <template v-for> that may 7018 // get moved around. Make sure all root level vnodes inherit el. 7019 // #2134 or if it's a component root, it may al
7019so get moved around 7020 // as the component is being moved. 7021 n2.key != null || 7022 (parentComponent && n2 === parentComponent.subTree)) { 7023 traverseStaticChildren(n1, n2, true /* shallow */); 7024 } 7025 } 7026 else { 7027 // keyed / unkeyed, or manual fragments. 7028 // for keyed & unkeyed, since they are compiler generated from v-for, 7029 // each child is guaranteed to be a block so the fragment will never 7030 // have dynamicChildren. 7031 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); 7032 } 7033 } 7034 }; 7035 const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => { 7036 n2.slotScopeIds = slotScopeIds; 7037 if (n1 == null) { 7038 if (n2.shapeFlag & 512 /* ShapeFlags.COMPONENT_KEPT_ALIVE */) { 7039 parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized); 7040 } 7041 else { 7042 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized); 7043 } 7044 } 7045 else { 7046 updateComponent(n1, n2, optimized); 7047 } 7048 }; 7049 const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => { 7050 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense)); 7051 if (instance.type.__hmrId) { 7052 registerHMR(instance); 7053 } 7054 { 7055 pushWarningContext(initialVNode); 7056 startMeasure(instance, `mount`); 7057 } 7058 // inject renderer internals for keepAlive 7059 if (isKeepAlive(initialVNode)) { 7060 instance.ctx.renderer = internals; 7061 } 7062 // resolve props and slots for setup context 7063 { 7064 { 7065 startMeasure(instance, `init`); 7066 } 7067 setupComponent(instance); 7068 { 7069 endMeasure(instance, `init`); 7070 } 7071 } 7072 // setup() is async. This component relies on async logic to be resolved 7073 // before proceeding 7074 if (instance.asyncDep) { 7075 parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect); 7076 // Give it a placeholder if this is not hydration 7077 // TODO handle self-defined fallback 7078 if (!initialVNode.el) { 7079 const placeholder = (instance.subTree = createVNode(Comment)); 7080 processCommentNode(null, placeholder, container, anchor); 7081 } 7082 return; 7083 } 7084 setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized); 7085 { 7086 popWarningContext(); 7087 endMeasure(instance, `mount`); 7088 } 7089 }; 7090 const updateComponent = (n1, n2, optimized) => { 7091 const instance = (n2.component = n1.component); 7092 if (shouldUpdateComponent(n1, n2, optimized)) { 7093 if (instance.asyncDep && 7094 !instance.asyncResolved) { 7095 // async & still pending - just update props and slots 7096 // since the component's reactive effect for render isn't set-up yet 7097 { 7098 pushWarningContext(n2); 7099 } 7100 updateComponentPreRender(instance, n2, optimized); 7101 { 7102 popWarningContext(); 7103 } 7104 return; 7105 } 7106 else { 7107 // normal update 7108 instance.next = n2; 7109 // in case the child component is also queued, remove it to avoid 7110 // double updating the same child component in the same flush. 7111 invalidateJob(instance.update); 7112 // instance.update is the reactive effect.
7113 instance.update(); 7114 } 7115 } 7116 else { 7117 // no update needed. just copy over properties 7118 n2.el = n1.el; 7119 instance.vnode = n2; 7120 } 7121 }; 7122 const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => { 7123 const componentUpdateFn = () => { 7124 if (!instance.isMounted) { 7125 let vnodeHook; 7126 const { el, props } = initialVNode; 7127 const { bm, m, parent } = instance; 7128 const isAsyncWrapperVNode = isAsyncWrapper(initialVNode); 7129 toggleRecurse(instance, false); 7130 // beforeMount hook 7131 if (bm) { 7132 invokeArrayFns(bm); 7133 } 7134 // onVnodeBeforeMount 7135 if (!isAsyncWrapperVNode && 7136 (vnodeHook = props && props.onVnodeBeforeMount)) { 7137 invokeVNodeHook(vnodeHook, parent, initialVNode); 7138 } 7139 toggleRecurse(instance, true); 7140 if (el && hydrateNode) { 7141 // vnode has adopted host node - perform hydration instead of mount. 7142 const hydrateSubTree = () => { 7143 { 7144 startMeasure(instance, `render`); 7145 } 7146 instance.subTree = renderComponentRoot(instance); 7147 { 7148 endMeasure(instance, `render`); 7149 } 7150 { 7151 startMeasure(instance, `hydrate`); 7152 } 7153 hydrateNode(el, instance.subTree, instance, parentSuspense, null); 7154 { 7155 endMeasure(instance, `hydrate`); 7156 } 7157 }; 7158 if (isAsyncWrapperVNode) { 7159 initialVNode.type.__asyncLoader().then( 7160 // note: we are moving the render call into an async callback, 7161 // which means it won't track dependencies - but it's ok because 7162 // a server-rendered async wrapper is already in resolved state 7163 // and it will never need to change. 7164 () => !instance.isUnmounted && hydrateSubTree()); 7165 } 7166 else { 7167 hydrateSubTree(); 7168 } 7169 } 7170 else { 7171 { 7172 startMeasure(instance, `render`); 7173 } 7174 const subTree = (instance.subTree = renderComponentRoot(instance)); 7175 { 7176 endMeasure(instance, `render`); 7177 } 7178 { 7179 startMeasure(instance, `patch`); 7180 } 7181 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG); 7182 { 7183 endMeasure(instance, `patch`); 7184 } 7185 initialVNode.el = subTree.el; 7186 } 7187 // mounted hook 7188 if (m) { 7189 queuePostRenderEffect(m, parentSuspense); 7190 } 7191 // onVnodeMounted 7192 if (!isAsyncWrapperVNode && 7193 (vnodeHook = props && props.onVnodeMounted)) { 7194 const scopedInitialVNode = initialVNode; 7195 queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, scopedInitialVNode), parentSuspense); 7196 } 7197 // activated hook for keep-alive roots. 7198 // #1742 activated hook must be accessed after first render 7199 // since the hook may be injected by a child keep-alive 7200 if (initialVNode.shapeFlag & 256 /* ShapeFlags.
vendor: 16,495 bytes, lines 7200-7566
7200COMPONENT_SHOULD_KEEP_ALIVE */ || 7201 (parent && 7202 isAsyncWrapper(parent.vnode) && 7203 parent.vnode.shapeFlag & 256 /* ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE */)) { 7204 instance.a && queuePostRenderEffect(instance.a, parentSuspense); 7205 } 7206 instance.isMounted = true; 7207 { 7208 devtoolsComponentAdded(instance); 7209 } 7210 // #2458: deference mount-only object parameters to prevent memleaks 7211 initialVNode = container = anchor = null; 7212 } 7213 else { 7214 // updateComponent 7215 // This is triggered by mutation of component's own state (next: null) 7216 // OR parent calling processComponent (next: VNode) 7217 let { next, bu, u, parent, vnode } = instance; 7218 let originNext = next; 7219 let vnodeHook; 7220 { 7221 pushWarningContext(next || instance.vnode); 7222 } 7223 // Disallow component effect recursion during pre-lifecycle hooks. 7224 toggleRecurse(instance, false); 7225 if (next) { 7226 next.el = vnode.el; 7227 updateComponentPreRender(instance, next, optimized); 7228 } 7229 else { 7230 next = vnode; 7231 } 7232 // beforeUpdate hook 7233 if (bu) { 7234 invokeArrayFns(bu); 7235 } 7236 // onVnodeBeforeUpdate 7237 if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) { 7238 invokeVNodeHook(vnodeHook, parent, next, vnode); 7239 } 7240 toggleRecurse(instance, true); 7241 // render 7242 { 7243 startMeasure(instance, `render`); 7244 } 7245 const nextTree = renderComponentRoot(instance); 7246 { 7247 endMeasure(instance, `render`); 7248 } 7249 const prevTree = instance.subTree; 7250 instance.subTree = nextTree; 7251 { 7252 startMeasure(instance, `patch`); 7253 } 7254 patch(prevTree, nextTree, 7255 // parent may have changed if it's in a teleport 7256 hostParentNode(prevTree.el), 7257 // anchor may have changed if it's in a fragment 7258 getNextHostNode(prevTree), instance, parentSuspense, isSVG); 7259 { 7260 endMeasure(instance, `patch`); 7261 } 7262 next.el = nextTree.el; 7263 if (originNext === null) { 7264 // self-triggered update. In case of HOC, update parent component 7265 // vnode el. HOC is indicated by parent instance's subTree pointing 7266 // to child component's vnode 7267 updateHOCHostEl(instance, nextTree.el); 7268 } 7269 // updated hook 7270 if (u) { 7271 queuePostRenderEffect(u, parentSuspense); 7272 } 7273 // onVnodeUpdated 7274 if ((vnodeHook = next.props && next.props.onVnodeUpdated)) { 7275 queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, next, vnode), parentSuspense); 7276 } 7277 { 7278 devtoolsComponentUpdated(instance); 7279 } 7280 { 7281 popWarningContext(); 7282 } 7283 } 7284 }; 7285 // create reactive effect for rendering 7286 const effect = (instance.effect = new ReactiveEffect(componentUpdateFn, () => queueJob(update), instance.scope // track it in component's effect scope 7287 )); 7288 const update = (instance.update = () => effect.run()); 7289 update.id = instance.uid; 7290 // allowRecurse 7291 // #1801, #2043 component render effects should allow recursive updates 7292 toggleRecurse(instance, true); 7293 { 7294 effect.onTrack = instance.rtc 7295 ? e => invokeArrayFns(instance.rtc, e) 7296 : void 0; 7297 effect.onTrigger = instance.rtg 7298 ? e => invokeArrayFns(instance.rtg, e) 7299 : void 0; 7300 update.ownerInstance = instance; 7301 } 7302 update(); 7303 }; 7304 const updateComponentPreRender = (instance, nextVNode, optimized) => { 7305 nextVNode.component = instance; 7306 const prevProps = instance.vnode.props; 7307 instance.vnode = nextVNode; 7308 instance.next = null; 7309 updateProps(instance, nextVNode.props, prevProps, optimized); 7310 updateSlots(instance, nextVNode.children, optimized); 7311 pauseTracking(); 7312 // props update may have triggered pre-flush watchers. 7313 // flush them before the render update. 7314 flushPreFlushCbs(); 7315 resetTracking(); 7316 }; 7317 const patchChildren = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized = false) => { 7318 const c1 = n1 && n1.children; 7319 const prevShapeFlag = n1 ? n1.shapeFlag : 0; 7320 const c2 = n2.children; 7321 const { patchFlag, shapeFlag } = n2; 7322 // fast path 7323 if (patchFlag > 0) { 7324 if (patchFlag & 128 /* PatchFlags.KEYED_FRAGMENT */) { 7325 // this could be either fully-keyed or mixed (some keyed some not) 7326 // presence of patchFlag means children are guaranteed to be arrays 7327 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); 7328 return; 7329 } 7330 else if (patchFlag & 256 /* PatchFlags.UNKEYED_FRAGMENT */) { 7331 // unkeyed 7332 patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); 7333 return; 7334 } 7335 } 7336 // children has 3 possibilities: text, array or no children. 7337 if (shapeFlag & 8 /* ShapeFlags.TEXT_CHILDREN */) { 7338 // text children fast path 7339 if (prevShapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) { 7340 unmountChildren(c1, parentComponent, parentSuspense); 7341 } 7342 if (c2 !== c1) { 7343 hostSetElementText(container, c2); 7344 } 7345 } 7346 else { 7347 if (prevShapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) { 7348 // prev children was array 7349 if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) { 7350 // two arrays, cannot assume anything, do full diff 7351 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); 7352 } 7353 else { 7354 // no new children, just unmount old 7355 unmountChildren(c1, parentComponent, parentSuspense, true); 7356 } 7357 } 7358 else { 7359 // prev children was text OR null 7360 // new children is array OR null 7361 if (prevShapeFlag & 8 /* ShapeFlags.TEXT_CHILDREN */) { 7362 hostSetElementText(container, ''); 7363 } 7364 // mount new if array 7365 if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) { 7366 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); 7367 } 7368 } 7369 } 7370 }; 7371 const patchUnkeyedChildren = (c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => { 7372 c1 = c1 || EMPTY_ARR; 7373 c2 = c2 || EMPTY_ARR; 7374 const oldLength = c1.length; 7375 const newLength = c2.length; 7376 const commonLength = Math.min(oldLength, newLength); 7377 let i; 7378 for (i = 0; i < commonLength; i++) { 7379 const nextChild = (c2[i] = optimized 7380 ? cloneIfMounted(c2[i]) 7381 : normalizeVNode(c2[i])); 7382 patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); 7383 } 7384 if (oldLength > newLength) { 7385 // remove old 7386 unmountChildren(c1, parentComponent, parentSuspense, true, false, commonLength); 7387 } 7388 else { 7389 // mount new 7390 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, commonLength); 7391 } 7392 }; 7393 // can be all-keyed or mixed 7394 const patchKeyedChildren = (c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => { 7395 let i = 0; 7396 const l2 = c2.length; 7397 let e1 = c1.length - 1; // prev ending index 7398 let e2 = l2 - 1; // next ending index 7399 // 1. sync from start 7400 // (a b) c 7401 // (a b) d e 7402 while (i <= e1 && i <= e2) { 7403 const n1 = c1[i]; 7404 const n2 = (c2[i] = optimized 7405 ? cloneIfMounted(c2[i]) 7406 : normalizeVNode(c2[i])); 7407 if (isSameVNodeType(n1, n2)) { 7408 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); 7409 } 7410 else { 7411 break; 7412 } 7413 i++; 7414 } 7415 // 2. sync from end 7416 // a (b c) 7417 // d e (b c) 7418 while (i <= e1 && i <= e2) { 7419 const n1 = c1[e1]; 7420 const n2 = (c2[e2] = optimized 7421 ? cloneIfMounted(c2[e2]) 7422 : normalizeVNode(c2[e2])); 7423 if (isSameVNodeType(n1, n2)) { 7424 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); 7425 } 7426 else { 7427 break; 7428 } 7429 e1--; 7430 e2--; 7431 } 7432 // 3. common sequence + mount 7433 // (a b) 7434 // (a b) c 7435 // i = 2, e1 = 1, e2 = 2 7436 // (a b) 7437 // c (a b) 7438 // i = 0, e1 = -1, e2 = 0 7439 if (i > e1) { 7440 if (i <= e2) { 7441 const nextPos = e2 + 1; 7442 const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor; 7443 while (i <= e2) { 7444 patch(null, (c2[i] = optimized 7445 ? cloneIfMounted(c2[i]) 7446 : normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); 7447 i++; 7448 } 7449 } 7450 } 7451 // 4. common sequence + unmount 7452 // (a b) c 7453 // (a b) 7454 // i = 2, e1 = 2, e2 = 1 7455 // a (b c) 7456 // (b c) 7457 // i = 0, e1 = 0, e2 = -1 7458 else if (i > e2) { 7459 while (i <= e1) { 7460 unmount(c1[i], parentComponent, parentSuspense, true); 7461 i++; 7462 } 7463 } 7464 // 5. unknown sequence 7465 // [i ... e1 + 1]: a b [c d e] f g 7466 // [i ... e2 + 1]: a b [e d c h] f g 7467 // i = 2, e1 = 4, e2 = 5 7468 else { 7469 const s1 = i; // prev starting index 7470 const s2 = i; // next starting index 7471 // 5.1 build key:index map for newChildren 7472 const keyToNewIndexMap = new Map(); 7473 for (i = s2; i <= e2; i++) { 7474 const nextChild = (c2[i] = optimized 7475 ? cloneIfMounted(c2[i]) 7476 : normalizeVNode(c2[i])); 7477 if (nextChild.key != null) { 7478 if (keyToNewIndexMap.has(nextChild.key)) { 7479 warn(`Duplicate keys found during update:`, JSON.stringify(nextChild.key), `Make sure keys are unique.`); 7480 } 7481 keyToNewIndexMap.set(nextChild.key, i); 7482 } 7483 } 7484 // 5.2 loop through old children left to be patched and try to patch 7485 // matching nodes & remove nodes that are no longer present 7486 let j; 7487 let patched = 0; 7488 const toBePatched = e2 - s2 + 1; 7489 let moved = false; 7490 // used to track whether any node has moved 7491 let maxNewIndexSoFar = 0; 7492 // works as Map<newIndex, oldIndex> 7493 // Note that oldIndex is offset by +1 7494 // and oldIndex = 0 is a special value indicating the new node has 7495 // no corresponding old node. 7496 // used for determining longest stable subsequence 7497 const newIndexToOldIndexMap = new Array(toBePatched); 7498 for (i = 0; i < toBePatched; i++) 7499 newIndexToOldIndexMap[i] = 0; 7500 for (i = s1; i <= e1; i++) { 7501 const prevChild = c1[i]; 7502 if (patched >= toBePatched) { 7503 // all new children have been patched so this can only be a removal 7504 unmount(prevChild, parentComponent, parentSuspense, true); 7505 continue; 7506 } 7507 let newIndex; 7508 if (prevChild.key != null) { 7509 newIndex = keyToNewIndexMap.get(prevChild.key); 7510 } 7511 else { 7512 // key-less node, try to locate a key-less node of the same type 7513 for (j = s2; j <= e2; j++) { 7514 if (newIndexToOldIndexMap[j - s2] === 0 && 7515 isSameVNodeType(prevChild, c2[j])) { 7516 newIndex = j; 7517 break; 7518 } 7519 } 7520 } 7521 if (newIndex === undefined) { 7522 unmount(prevChild, parentComponent, parentSuspense, true); 7523 } 7524 else { 7525 newIndexToOldIndexMap[newIndex - s2] = i + 1; 7526 if (newIndex >= maxNewIndexSoFar) { 7527 maxNewIndexSoFar = newIndex; 7528 } 7529 else { 7530 moved = true; 7531 } 7532 patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); 7533 patched++; 7534 } 7535 } 7536 // 5.3 move and mount 7537 // generate longest stable subsequence only when nodes have moved 7538 const increasingNewIndexSequence = moved 7539 ? getSequence(newIndexToOldIndexMap) 7540 : EMPTY_ARR; 7541 j = increasingNewIndexSequence.length - 1; 7542 // looping backwards so that we can use last patched node as anchor 7543 for (i = toBePatched - 1; i >= 0; i--) { 7544 const nextIndex = s2 + i; 7545 const nextChild = c2[nextIndex]; 7546 const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : parentAnchor; 7547 if (newIndexToOldIndexMap[i] === 0) { 7548 // mount new 7549 patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); 7550 } 7551 else if (moved) { 7552 // move if: 7553 // There is no stable subsequence (e.g. a reverse) 7554 // OR current node is not among the stable sequence 7555 if (j < 0 || i !== increasingNewIndexSequence[j]) { 7556 move(nextChild, container, anchor, 2 /* MoveType.REORDER */); 7557 } 7558 else { 7559 j--; 7560 } 7561 } 7562 } 7563 } 7564 }; 7565 const move = (vnode, container, anchor, moveType, parentSuspense = null) => { 7566 const { el, type, transition, children, shapeFlag } = vnode;
7567 if (shapeFlag & 6 /* ShapeFlags.COMPONENT */) { 7568 move(vnode.component.subTree, container, anchor, moveType); 7569 return; 7570 } 7571 if (shapeFlag & 128 /* ShapeFlags.SUSPENSE */) { 7572 vnode.suspense.move(container, anchor, moveType); 7573 return; 7574 } 7575 if (shapeFlag & 64 /* ShapeFlags.TELEPORT */) { 7576 type.move(vnode, container, anchor, internals); 7577 return; 7578 } 7579 if (type === Fragment) { 7580 hostInsert(el, container, anchor); 7581 for (let i = 0; i < children.length; i++) { 7582 move(children[i], container, anchor, moveType); 7583 } 7584 hostInsert(vnode.anchor, container, anchor); 7585 return; 7586 } 7587 if (type === Static) { 7588 moveStaticNode(vnode, container, anchor); 7589 return; 7590 } 7591 // single nodes 7592 const needTransition = moveType !== 2 /* MoveType.REORDER */ && 7593 shapeFlag & 1 /* ShapeFlags.ELEMENT */ && 7594 transition; 7595 if (needTransition) { 7596 if (moveType === 0 /* MoveType.ENTER */) { 7597 transition.beforeEnter(el); 7598 hostInsert(el, container, anchor); 7599 queuePostRenderEffect(() => transition.enter(el), parentSuspense); 7600 } 7601 else { 7602 const { leave, delayLeave, afterLeave } = transition; 7603 const remove = () => hostInsert(el, container, anchor); 7604 const performLeave = () => { 7605 leave(el, () => { 7606 remove(); 7607 afterLeave && afterLeave(); 7608 }); 7609 }; 7610 if (delayLeave) { 7611 delayLeave(el, remove, performLeave); 7612 } 7613 else { 7614 performLeave(); 7615 } 7616 } 7617 } 7618 else { 7619 hostInsert(el, container, anchor); 7620 } 7621 }; 7622 const unmount = (vnode, parentComponent, parentSuspense, doRemove = false, optimized = false) => { 7623 const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode; 7624 // unset ref 7625 if (ref != null) { 7626 setRef(ref, null, parentSuspense, vnode, true); 7627 } 7628 if (shapeFlag & 256 /* ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE */) { 7629 parentComponent.ctx.deactivate(vnode); 7630 return; 7631 } 7632 const shouldInvokeDirs = shapeFlag & 1 /* ShapeFlags.ELEMENT */ && dirs; 7633 const shouldInvokeVnodeHook = !isAsyncWrapper(vnode); 7634 let vnodeHook; 7635 if (shouldInvokeVnodeHook && 7636 (vnodeHook = props && props.onVnodeBeforeUnmount)) { 7637 invokeVNodeHook(vnodeHook, parentComponent, vnode); 7638 } 7639 if (shapeFlag & 6 /* ShapeFlags.COMPONENT */) { 7640 unmountComponent(vnode.component, parentSuspense, doRemove); 7641 } 7642 else { 7643 if (shapeFlag & 128 /* ShapeFlags.SUSPENSE */) { 7644 vnode.suspense.unmount(parentSuspense, doRemove); 7645 return; 7646 } 7647 if (shouldInvokeDirs) { 7648 invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount'); 7649 } 7650 if (shapeFlag & 64 /* ShapeFlags.TELEPORT */) { 7651 vnode.type.remove(vnode, parentComponent, parentSuspense, optimized, internals, doRemove); 7652 } 7653 else if (dynamicChildren && 7654 // #1153: fast path should not be taken for non-stable (v-for) fragments 7655 (type !== Fragment || 7656 (patchFlag > 0 && patchFlag & 64 /* PatchFlags.STABLE_FRAGMENT */))) { 7657 // fast path for block nodes: only need to unmount dynamic children. 7658 unmountChildren(dynamicChildren, parentComponent, parentSuspense, false, true); 7659 } 7660 else if ((type === Fragment && 7661 patchFlag & 7662 (128 /* PatchFlags.KEYED_FRAGMENT */ | 256 /* PatchFlags.UNKEYED_FRAGMENT */)) || 7663 (!optimized && shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */)) { 7664 unmountChildren(children, parentComponent, parentSuspense); 7665 } 7666 if (doRemove) { 7667 remove(vnode); 7668 } 7669 } 7670 if ((shouldInvokeVnodeHook && 7671 (vnodeHook = props && props.onVnodeUnmounted)) || 7672 shouldInvokeDirs) { 7673 queuePostRenderEffect(() => { 7674 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode); 7675 shouldInvokeDirs && 7676 invokeDirectiveHook(vnode, null, parentComponent, 'unmounted'); 7677 }, parentSuspense); 7678 } 7679 }; 7680 const remove = vnode => { 7681 const { type, el, anchor, transition } = vnode; 7682 if (type === Fragment) { 7683 if (vnode.patchFlag > 0 && 7684 vnode.patchFlag & 2048 /* PatchFlags.DEV_ROOT_FRAGMENT */ && 7685 transition && 7686 !transition.persisted) {
7687 vnode.children.forEach(child => { 7688 if (child.type === Comment) { 7689 hostRemove(child.el); 7690 } 7691 else { 7692 remove(child); 7693 } 7694 }); 7695 } 7696 else { 7697 removeFragment(el, anchor); 7698 } 7699 return; 7700 } 7701 if (type === Static) { 7702 removeStaticNode(vnode); 7703 return; 7704 } 7705 const performRemove = () => { 7706 hostRemove(el); 7707 if (transition && !transition.persisted && transition.afterLeave) { 7708 transition.afterLeave(); 7709 } 7710 }; 7711 if (vnode.shapeFlag & 1 /* ShapeFlags.ELEMENT */ && 7712 transition && 7713 !transition.persisted) { 7714 const { leave, delayLeave } = transition; 7715 const performLeave = () => leave(el, performRemove); 7716 if (delayLeave) { 7717 delayLeave(vnode.el, performRemove, performLeave); 7718 } 7719 else { 7720 performLeave(); 7721 } 7722 } 7723 else { 7724 performRemove(); 7725 } 7726 }; 7727 const removeFragment = (cur, end) => { 7728 // For fragments, directly remove all contained DOM nodes. 7729 // (fragment child nodes cannot have transition) 7730 let next; 7731 while (cur !== end) { 7732 next = hostNextSibling(cur); 7733 hostRemove(cur); 7734 cur = next; 7735 } 7736 hostRemove(end); 7737 }; 7738 const unmountComponent = (instance, parentSuspense, doRemove) => { 7739 if (instance.type.__hmrId) { 7740 unregisterHMR(instance); 7741 } 7742 const { bum, scope, update, subTree, um } = instance; 7743 // beforeUnmount hook 7744 if (bum) { 7745 invokeArrayFns(bum); 7746 } 7747 // stop effects in component scope 7748 scope.stop(); 7749 // update may be null if a component is unmounted before its async 7750 // setup has resolved. 7751 if (update) { 7752 // so that scheduler will no longer invoke it 7753 update.active = false; 7754 unmount(subTree, instance, parentSuspense, doRemove); 7755 } 7756 // unmounted hook 7757 if (um) { 7758 queuePostRenderEffect(um, parentSuspense); 7759 } 7760 queuePostRenderEffect(() => { 7761 instance.isUnmounted = true; 7762 }, parentSuspense); 7763 // A component with async dep inside a pending suspense is unmounted before 7764 // its async dep resolves. This should remove the dep from the suspense, and 7765 // cause the suspense to resolve immediately if that was the last dep. 7766 if (parentSuspense && 7767 parentSuspense.pendingBranch && 7768 !parentSuspense.isUnmounted && 7769 instance.asyncDep && 7770 !instance.asyncResolved && 7771 instance.suspenseId === parentSuspense.pendingId) { 7772 parentSuspense.deps--; 7773 if (parentSuspense.deps === 0) { 7774 parentSuspense.resolve(); 7775 } 7776 } 7777 { 7778 devtoolsComponentRemoved(instance); 7779 } 7780 }; 7781 const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, optimized = false, start = 0) => { 7782 for (let i = start; i < children.length; i++) { 7783 unmount(children[i], parentComponent, parentSuspense, doRemove, optimized); 7784 } 7785 }; 7786 const getNextHostNode = vnode => { 7787 if (vnode.shapeFlag & 6 /* ShapeFlags.COMPONENT */) { 7788 return getNextHostNode(vnode.component.subTree); 7789 } 7790 if (vnode.shapeFlag & 128 /* ShapeFlags.SUSPENSE */) { 7791 return vnode.suspense.next(); 7792 } 7793 return hostNextSibling((vnode.anchor || vnode.el)); 7794 }; 7795 const render = (vnode, container, isSVG) => { 7796 if (vnode == null) { 7797 if (container._vnode) { 7798 unmount(container._vnode, null, null, true); 7799 } 7800 } 7801 else { 7802 patch(container._vnode || null, vnode, container, null, null, null, isSVG); 7803 } 7804 flushPreFlushCbs(); 7805 flushPostFlushCbs(); 7806 container._vnode = vnode; 7807 }; 7808 const internals = { 7809 p: patch, 7810 um: unmount, 7811 m: move, 7812 r: remove, 7813 mt: mountComponent, 7814 mc: mountChildren, 7815 pc: patchChildren, 7816 pbc: patchBlockChildren, 7817 n: getNextHostNode, 7818 o: options 7819 }; 7820 let hydrate; 7821 let hydrateNode; 7822 if (createHydrationFns) { 7823 [hydrate, hydrateNode] = createHydrationFns(internals); 7824 } 7825 return { 7826 render, 7827 hydrate, 7828 createApp: createAppAPI(render, hydrate) 7829 }; 7830 } 7831 function toggleRecurse({ effect, update }, allowed) { 7832 effect.allowRecurse = update.allowRecurse = allowed; 7833 } 7834 /** 7835 * #1156 7836 * When a component is HMR-enabled, we need to make sure that all static no
7836des 7837 * inside a block also inherit the DOM element from the previous tree so that 7838 * HMR updates (which are full updates) can retrieve the element for patching. 7839 * 7840 * #2080 7841 * Inside keyed `template` fragment static children, if a fragment is moved, 7842 * the children will always be moved. Therefore, in order to ensure correct move 7843 * position, el should be inherited from previous nodes. 7844 */ 7845 function traverseStaticChildren(n1, n2, shallow = false) { 7846 const ch1 = n1.children; 7847 const ch2 = n2.children; 7848 if (isArray(ch1) && isArray(ch2)) { 7849 for (let i = 0; i < ch1.length; i++) { 7850 // this is only called in the optimized path so array children are 7851 // guaranteed to be vnodes 7852 const c1 = ch1[i]; 7853 let c2 = ch2[i]; 7854 if (c2.shapeFlag & 1 /* ShapeFlags.ELEMENT */ && !c2.dynamicChildren) { 7855 if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* PatchFlags.HYDRATE_EVENTS */) { 7856 c2 = ch2[i] = cloneIfMounted(ch2[i]); 7857 c2.el = c1.el; 7858 } 7859 if (!shallow) 7860 traverseStaticChildren(c1, c2); 7861 } 7862 // #6852 also inherit for text nodes 7863 if (c2.type === Text) { 7864 c2.el = c1.el; 7865 } 7866 // also inherit for comment nodes, but not placeholders (e.g. v-if which 7867 // would have received .el during block patch) 7868 if (c2.type === Comment && !c2.el) { 7869 c2.el = c1.el; 7870 } 7871 } 7872 } 7873 } 7874 // https://en.wikipedia.org/wiki/Longest_increasing_subsequence 7875 function getSequence(arr) { 7876 const p = arr.slice(); 7877 const result = [0]; 7878 let i, j, u, v, c; 7879 const len = arr.length; 7880 for (i = 0; i < len; i++) { 7881 const arrI = arr[i]; 7882 if (arrI !== 0) { 7883 j = result[result.length - 1]; 7884 if (arr[j] < arrI) { 7885 p[i] = j; 7886 result.push(i); 7887 continue; 7888 } 7889 u = 0; 7890 v = result.length - 1; 7891 while (u < v) { 7892 c = (u + v) >> 1; 7893 if (arr[result[c]] < arrI) { 7894 u = c + 1; 7895 } 7896 else { 7897 v = c; 7898 } 7899 } 7900 if (arrI < arr[result[u]]) { 7901 if (u > 0) { 7902 p[i] = result[u - 1]; 7903 } 7904 result[u] = i; 7905 } 7906 } 7907 } 7908 u = result.length; 7909 v = result[u - 1]; 7910 while (u-- > 0) { 7911 result[u] = v; 7912 v = p[v]; 7913 } 7914 return result; 7915 } 7916 7917 const isTeleport = (type) => type.__isTeleport; 7918 const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === ''); 7919 const isTargetSVG = (target) => typeof SVGElement !== 'undefined' && target instanceof SVGElement; 7920 const resolveTarget = (props, select) => { 7921 const targetSelector = props && props.to; 7922 if (isString(targetSelector)) { 7923 if (!select) { 7924 warn(`Current renderer does not support string target for Teleports. ` + 7925 `(missing querySelector renderer option)`); 7926 return null; 7927 } 7928 else { 7929 const target = select(targetSelector); 7930 if (!target) { 7931 warn(`Failed to locate Teleport target with selector "${targetSelector}". ` + 7932 `Note the target element must exist before the component is mounted - ` + 7933 `i.e. the target cannot be rendered by the component itself, and ` + 7934 `ideally should be outside of the entire Vue component tree.`); 7935 } 7936 return target; 7937 } 7938 } 7939 else { 7940 if (!targetSelector && !isTeleportDisabled(props)) { 7941 warn(`Invalid Teleport target: ${targetSelector}`); 7942 } 7943 return targetSelector; 7944 } 7945 }; 7946 const TeleportImpl = { 7947 __isTeleport: true, 7948 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals) { 7949 const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals; 7950 const disabled = isTeleportDisabled(n2.props); 7951 let { shapeFlag, children, dynamicChildren } = n2; 7952 // #3302 7953 // HMR updated, force full diff 7954 if (isHmrUpdating) { 7955 optimized = false;
7956 dynamicChildren = null; 7957 } 7958 if (n1 == null) { 7959 // insert anchors in the main view 7960 const placeholder = (n2.el = createComment('teleport start') 7961 ); 7962 const mainAnchor = (n2.anchor = createComment('teleport end') 7963 ); 7964 insert(placeholder, container, anchor); 7965 insert(mainAnchor, container, anchor); 7966 const target = (n2.target = resolveTarget(n2.props, querySelector)); 7967 const targetAnchor = (n2.targetAnchor = createText('')); 7968 if (target) { 7969 insert(targetAnchor, target); 7970 // #2652 we could be teleporting from a non-SVG tree into an SVG tree 7971 isSVG = isSVG || isTargetSVG(target); 7972 } 7973 else if (!disabled) { 7974 warn('Invalid Teleport target on mount:', target, `(${typeof target})`); 7975 } 7976 const mount = (container, anchor) => { 7977 // Teleport *always* has Array children. This is enforced in both the 7978 // compiler and vnode children normalization. 7979 if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) { 7980 mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); 7981 } 7982 }; 7983 if (disabled) { 7984 mount(container, mainAnchor); 7985 } 7986 else if (target) { 7987 mount(target, targetAnchor); 7988 } 7989 } 7990 else { 7991 // update content 7992 n2.el = n1.el; 7993 const mainAnchor = (n2.anchor = n1.anchor); 7994 const target = (n2.target = n1.target); 7995 const targetAnchor = (n2.targetAnchor = n1.targetAnchor); 7996 const wasDisabled = isTeleportDisabled(n1.props); 7997 const currentContainer = wasDisabled ? container : target; 7998 const currentAnchor = wasDisabled ? mainAnchor : targetAnchor; 7999 isSVG = isSVG || isTargetSVG(target); 8000 if (dynamicChildren) { 8001 // fast path when the teleport happens to be a block root 8002 patchBlockChildren(n1.dynamicChildren, dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG, slotScopeIds); 8003 // even in block tree mode we need to make sure all root-level nodes 8004 // in the teleport inherit previous DOM references so that they can 8005 // be moved in future patches. 8006 traverseStaticChildren(n1, n2, true); 8007 } 8008 else if (!optimized) { 8009 patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, false); 8010 } 8011 if (disabled) { 8012 if (!wasDisabled) { 8013 // enabled -> disabled 8014 // move into main container 8015 moveTeleport(n2, container, mainAnchor, internals, 1 /* TeleportMoveTypes.TOGGLE */); 8016 } 8017 } 8018 else { 8019 // target changed 8020 if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) { 8021 const nextTarget = (n2.target = resolveTarget(n2.props, querySelector)); 8022 if (nextTarget) { 8023 moveTeleport(n2, nextTarget, null, internals, 0 /* TeleportMoveTypes.TARGET_CHANGE */); 8024 } 8025 else { 8026 warn('Invalid Teleport target on update:', target, `(${typeof target})`); 8027 } 8028 } 8029 else if (wasDisabled) { 8030 // disabled -> enabled 8031 // move into teleport target 8032 moveTeleport(n2, target, targetAnchor, internals, 1 /* TeleportMoveTypes.TOGGLE */); 8033 } 8034 } 8035 } 8036 updateCssVars(n2); 8037 }, 8038 remove(vnode, parentComponent, parentSuspense, optimized, { um: unmount, o: { remove: hostRemove } }, doRemove) { 8039 const { shapeFlag, children, anchor, targetAnchor, target, props } = vnode; 8040 if (target) { 8041 hostRemove(targetAnchor); 8042 } 8043 // an unmounted teleport should always remove its children if not disabled 8044 if (doRemove || !isTeleportDisabled(props)) { 8045 hostRemove(anchor); 8046 if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) { 8047 for (let i = 0; i < children.length; i++) { 8048 const child = children[i]; 8049 unmount(child, parentComponent, parentSuspense, true, !!child.dynamicChildren); 8050 } 8051 } 8052 } 8053 }, 8054 move: moveTeleport, 8055 hydrate: hydrateTeleport 8056 }; 8057 function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* TeleportMoveTypes.REORDER */) { 8058 // move target anchor if this is a target change. 8059 if (moveType === 0 /* TeleportMoveTypes.TARGET_CHANGE */) { 8060 insert(vnode.targetAnchor, container, parentAnchor); 8061 } 8062 const { el, anchor, shapeFlag, children, props } = vnode; 8063 const isReorder = moveType === 2 /* TeleportMoveTypes.REORDER */; 8064 // move main view anchor if this is a re-order. 8065 if (isReorder) { 8066 insert(el, container, parentAnchor); 8067 } 8068 // if this is a re-order and teleport is enabled (content is in target) 8069 // do not move children. So the opposite is: only move children if this 8070 // is not a reorder, or the teleport is disabled 8071 if (!isReorder || isTeleportDisabled(props)) { 8072 // Teleport has either Array children or no children. 8073 if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) { 8074 for (let i = 0; i < children.length; i++) { 8075 move(children[i], container, parentAnchor, 2 /* MoveType.REORDER */); 8076 } 8077 } 8078 } 8079 // move main view anchor if this is a re-order. 8080 if (isReorder) { 8081 insert(anchor, container, parentAnchor); 8082 } 8083 } 8084 function hydrateTeleport(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) { 8085 const target = (vnode.target = resolveTarget(vnode.props, querySelector)); 8086 if (target) { 8087 // if multiple teleports rendered to the same target element, we need to 8088 // pick up from where the last teleport finished instead of the first node 8089 const targetNode = target._lpa || target.firstChild; 8090 if (vnode.shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) { 8091 if (isTeleportDisabled(vnode.props)) { 8092 vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, slotScopeIds, optimized); 8093 vnode.targetAnchor = targetNode;
8094 } 8095 else { 8096 vnode.anchor = nextSibling(node); 8097 // lookahead until we find the target anchor 8098 // we cannot rely on return value of hydrateChildren() because there 8099 // could be nested teleports 8100 let targetAnchor = targetNode; 8101 while (targetAnchor) { 8102 targetAnchor = nextSibling(targetAnchor); 8103 if (targetAnchor && 8104 targetAnchor.nodeType === 8 && 8105 targetAnchor.data === 'teleport anchor') { 8106 vnode.targetAnchor = targetAnchor; 8107 target._lpa = 8108 vnode.targetAnchor && nextSibling(vnode.targetAnchor); 8109 break; 8110 } 8111 } 8112 hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, slotScopeIds, optimized); 8113 } 8114 } 8115 updateCssVars(vnode); 8116 } 8117 return vnode.anchor && nextSibling(vnode.anchor); 8118 } 8119 // Force-casted public typing for h and TSX props inference 8120 const Teleport = TeleportImpl; 8121 function updateCssVars(vnode) { 8122 // presence of .ut method indicates owner component uses css vars. 8123 // code path here can assume browser environment. 8124 const ctx = vnode.ctx; 8125 if (ctx && ctx.ut) { 8126 let node = vnode.children[0].el; 8127 while (node !== vnode.targetAnchor) { 8128 if (node.nodeType === 1) 8129 node.setAttribute('data-v-owner', ctx.uid); 8130 node = node.nextSibling; 8131 } 8132 ctx.ut(); 8133 } 8134 } 8135 8136 const Fragment = Symbol('Fragment' ); 8137 const Text = Symbol('Text' ); 8138 const Comment = Symbol('Comment' ); 8139 const Static = Symbol('Static' ); 8140 // Since v-if and v-for are the two possible ways node structure can dynamically 8141 // change, once we consider v-if branches and each v-for fragment a block, we 8142 // can divide a template into nested blocks, and within each block the node 8143 // structure would be stable. This allows us to skip most children diffing 8144 // and only worry about the dynamic nodes (indicated by patch flags). 8145 const blockStack = []; 8146 let currentBlock = null; 8147 /** 8148 * Open a block. 8149 * This must be called before `createBlock`. It cannot be part of `createBlock` 8150 * because the children of the block are evaluated before `createBlock` itself 8151 * is called. The generated code typically looks like this: 8152 * 8153 * ```js 8154 * function render() { 8155 * return (openBlock(),createBlock('div', null, [...])) 8156 * } 8157 * ``` 8158 * disableTracking is true when creating a v-for fragment block, since a v-for 8159 * fragment always diffs its children. 8160 * 8161 * @private 8162 */ 8163 function openBlock(disableTracking = false) { 8164 blockStack.push((currentBlock = disableTracking ? null : [])); 8165 } 8166 function closeBlock() { 8167 blockStack.pop(); 8168 currentBlock = blockStack[blockStack.length - 1] || null; 8169 } 8170 // Whether we should be tracking dynamic child nodes inside a block. 8171 // Only tracks when this value is > 0 8172 // We are not using a simple boolean because this value may need to be 8173 // incremented/decremented by nested usage of v-once (see below) 8174 let isBlockTreeEnabled = 1; 8175 /** 8176 * Block tracking sometimes needs to be disabled, for example during the 8177 * creation of a tree that needs to be cached by v-once. The compiler generates 8178 * code like this: 8179 * 8180 * ``` js 8181 * _cache[1] || ( 8182 * setBlockTracking(-1), 8183 * _cache[1] = createVNode(...), 8184 * setBlockTracking(1), 8185 * _cache[1] 8186 * ) 8187 * ``` 8188 * 8189 * @private 8190 */ 8191 function setBlockTracking(value) { 8192 isBlockTreeEnabled += value; 8193 } 8194 function setupBlock(vnode) { 8195 // save current block children on the block vnode 8196 vnode.dynamicChildren = 8197 isBlockTreeEnabled > 0 ? currentBlock || EMPTY_ARR : null; 8198 // close block 8199 closeBlock(); 8200 // a block is always going to be patched, so track it as a child of its 8201 // parent block 8202 if (isBlockTreeEnabled > 0 && currentBlock) {
8203 currentBlock.push(vnode); 8204 } 8205 return vnode; 8206 } 8207 /** 8208 * @private 8209 */ 8210 function createElementBlock(type, props, children, patchFlag, dynamicProps, shapeFlag) { 8211 return setupBlock(createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, true /* isBlock */)); 8212 } 8213 /** 8214 * Create a block root vnode. Takes the same exact arguments as `createVNode`. 8215 * A block root keeps track of dynamic nodes within the block in the 8216 * `dynamicChildren` array. 8217 * 8218 * @private 8219 */ 8220 function createBlock(type, props, children, patchFlag, dynamicProps) { 8221 return setupBlock(createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */)); 8222 } 8223 function isVNode(value) { 8224 return value ? value.__v_isVNode === true : false; 8225 } 8226 function isSameVNodeType(n1, n2) { 8227 if (n2.shapeFlag & 6 /* ShapeFlags.COMPONENT */ && 8228 hmrDirtyComponents.has(n2.type)) { 8229 // #7042, ensure the vnode being unmounted during HMR 8230 // bitwise operations to remove keep alive flags 8231 n1.shapeFlag &= ~256 /* ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE */; 8232 n2.shapeFlag &= ~512 /* ShapeFlags.COMPONENT_KEPT_ALIVE */; 8233 // HMR only: if the component has been hot-updated, force a reload. 8234 return false; 8235 } 8236 return n1.type === n2.type && n1.key === n2.key; 8237 } 8238 let vnodeArgsTransformer; 8239 /** 8240 * Internal API for registering an arguments transform for createVNode 8241 * used for creating stubs in the test-utils 8242 * It is *internal* but needs to be exposed for test-utils to pick up proper 8243 * typings 8244 */ 8245 function transformVNodeArgs(transformer) { 8246 vnodeArgsTransformer = transformer; 8247 } 8248 const createVNodeWithArgsTransform = (...args) => { 8249 return _createVNode(...(vnodeArgsTransformer 8250 ? vnodeArgsTransformer(args, currentRenderingInstance) 8251 : args)); 8252 }; 8253 const InternalObjectKey = `__vInternal`; 8254 const normalizeKey = ({ key }) => key != null ? key : null; 8255 const normalizeRef = ({ ref, ref_key, ref_for }) => { 8256 return (ref != null 8257 ? isString(ref) || isRef(ref) || isFunction(ref) 8258 ? { i: currentRenderingInstance, r: ref, k: ref_key, f: !!ref_for } 8259 : ref 8260 : null); 8261 }; 8262 function createBaseVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, shapeFlag = type === Fragment ? 0 : 1 /* ShapeFlags.ELEMENT */, isBlockNode = false, needFullChildrenNormalization = false) { 8263 const vnode = { 8264 __v_isVNode: true, 8265 __v_skip: true, 8266 type, 8267 props, 8268 key: props && normalizeKey(props), 8269 ref: props && normalizeRef(props), 8270 scopeId: currentScopeId, 8271 slotScopeIds: null, 8272 children, 8273 component: null, 8274 suspense: null, 8275 ssContent: null, 8276 ssFallback: null, 8277 dirs: null, 8278 transition: null, 8279 el: null, 8280 anchor: null, 8281 target: null, 8282 targetAnchor: null, 8283 staticCount: 0, 8284 shapeFlag, 8285 patchFlag, 8286 dynamicProps, 8287 dynamicChildren: null, 8288 appContext: null, 8289 ctx: currentRenderingInstance 8290 }; 8291 if (needFullChildrenNormalization) { 8292 normalizeChildren(vnode, children); 8293 // normalize suspense children 8294 if (shapeFlag & 128 /* ShapeFlags.SUSPENSE */) { 8295 type.normalize(vnode); 8296 } 8297 } 8298 else if (children) { 8299 // compiled element vnode - if children is passed, only possible types are 8300 // string or Array. 8301 vnode.shapeFlag |= isString(children) 8302 ? 8 /* ShapeFlags.TEXT_CHILDREN */ 8303 : 16 /* ShapeFlags.ARRAY_CHILDREN */; 8304 } 8305 // validate key 8306 if (vnode.key !== vnode.key) { 8307 warn(`VNode created with invalid key (NaN). VNode type:`, vnode.type); 8308 } 8309 // track vnode for block tree 8310 if (isBlockTreeEnabled > 0 && 8311 // avoid a block node from tracking itself 8312 !isBlockNode && 8313 // has current parent block 8314 currentBlock && 8315 // presence of a patch flag indicates this node needs patching on updates. 8316 // component nodes also should always be patched, because even if the 8317 // component doesn't need to update, it needs to persist the instance on to 8318 // the next vnode so that it can be properly unmounted later. 8319 (vnode.patchFlag >
vendor: 6,033 bytes, lines 8319-8449
8319 0 || shapeFlag & 6 /* ShapeFlags.COMPONENT */) && 8320 // the EVENTS flag is only for hydration and if it is the only flag, the 8321 // vnode should not be considered dynamic due to handler caching. 8322 vnode.patchFlag !== 32 /* PatchFlags.HYDRATE_EVENTS */) { 8323 currentBlock.push(vnode); 8324 } 8325 return vnode; 8326 } 8327 const createVNode = (createVNodeWithArgsTransform ); 8328 function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) { 8329 if (!type || type === NULL_DYNAMIC_COMPONENT) { 8330 if (!type) { 8331 warn(`Invalid vnode type when creating vnode: ${type}.`); 8332 } 8333 type = Comment; 8334 } 8335 if (isVNode(type)) { 8336 // createVNode receiving an existing vnode. This happens in cases like 8337 // <component :is="vnode"/> 8338 // #2078 make sure to merge refs during the clone instead of overwriting it 8339 const cloned = cloneVNode(type, props, true /* mergeRef: true */); 8340 if (children) { 8341 normalizeChildren(cloned, children); 8342 } 8343 if (isBlockTreeEnabled > 0 && !isBlockNode && currentBlock) { 8344 if (cloned.shapeFlag & 6 /* ShapeFlags.COMPONENT */) { 8345 currentBlock[currentBlock.indexOf(type)] = cloned; 8346 } 8347 else { 8348 currentBlock.push(cloned); 8349 } 8350 } 8351 cloned.patchFlag |= -2 /* PatchFlags.BAIL */; 8352 return cloned; 8353 } 8354 // class component normalization. 8355 if (isClassComponent(type)) { 8356 type = type.__vccOpts; 8357 } 8358 // class & style normalization. 8359 if (props) { 8360 // for reactive or proxy objects, we need to clone it to enable mutation. 8361 props = guardReactiveProps(props); 8362 let { class: klass, style } = props; 8363 if (klass && !isString(klass)) { 8364 props.class = normalizeClass(klass); 8365 } 8366 if (isObject(style)) { 8367 // reactive state objects need to be cloned since they are likely to be 8368 // mutated 8369 if (isProxy(style) && !isArray(style)) { 8370 style = extend({}, style); 8371 } 8372 props.style = normalizeStyle(style); 8373 } 8374 } 8375 // encode the vnode type information into a bitmap 8376 const shapeFlag = isString(type) 8377 ? 1 /* ShapeFlags.ELEMENT */ 8378 : isSuspense(type) 8379 ? 128 /* ShapeFlags.SUSPENSE */ 8380 : isTeleport(type) 8381 ? 64 /* ShapeFlags.TELEPORT */ 8382 : isObject(type) 8383 ? 4 /* ShapeFlags.STATEFUL_COMPONENT */ 8384 : isFunction(type) 8385 ? 2 /* ShapeFlags.FUNCTIONAL_COMPONENT */ 8386 : 0; 8387 if (shapeFlag & 4 /* ShapeFlags.STATEFUL_COMPONENT */ && isProxy(type)) { 8388 type = toRaw(type); 8389 warn(`Vue received a Component which was made a reactive object. This can ` + 8390 `lead to unnecessary performance overhead, and should be avoided by ` + 8391 `marking the component with \`markRaw\` or using \`shallowRef\` ` + 8392 `instead of \`ref\`.`, `\nComponent that was made reactive: `, type); 8393 } 8394 return createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, isBlockNode, true); 8395 } 8396 function guardReactiveProps(props) { 8397 if (!props) 8398 return null; 8399 return isProxy(props) || InternalObjectKey in props 8400 ? extend({}, props) 8401 : props; 8402 } 8403 function cloneVNode(vnode, extraProps, mergeRef = false) { 8404 // This is intentionally NOT using spread or extend to avoid the runtime 8405 // key enumeration cost. 8406 const { props, ref, patchFlag, children } = vnode; 8407 const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props; 8408 const cloned = { 8409 __v_isVNode: true, 8410 __v_skip: true, 8411 type: vnode.type, 8412 props: mergedProps, 8413 key: mergedProps && normalizeKey(mergedProps), 8414 ref: extraProps && extraProps.ref 8415 ? // #2078 in the case of <component :is="vnode" ref="extra"/> 8416 // if the vnode itself already has a ref, cloneVNode will need to merge 8417 // the refs so the single vnode can be set on multiple refs 8418 mergeRef && ref 8419 ? isArray(ref) 8420 ? ref.concat(normalizeRef(extraProps)) 8421 : [ref, normalizeRef(extraProps)] 8422 : normalizeRef(extraProps) 8423 : ref, 8424 scopeId: vnode.scopeId, 8425 slotScopeIds: vnode.slotScopeIds, 8426 children: patchFlag === -1 /* PatchFlags.HOISTED */ && isArray(children) 8427 ? children.map(deepCloneVNode) 8428 : children, 8429 target: vnode.target, 8430 targetAnchor: vnode.targetAnchor, 8431 staticCount: vnode.staticCount, 8432 shapeFlag: vnode.shapeFlag, 8433 // if the vnode is cloned with extra props, we can no longer assume its 8434 // existing patch flag to be reliable and need to add the FULL_PROPS flag. 8435 // note: preserve flag for fragments since they use the flag for children 8436 // fast paths only. 8437 patchFlag: extraProps && vnode.type !== Fragment 8438 ? patchFlag === -1 // hoisted node 8439 ? 16 /* PatchFlags.FULL_PROPS */ 8440 : patchFlag | 16 /* PatchFlags.FULL_PROPS */ 8441 : patchFlag, 8442 dynamicProps: vnode.dynamicProps, 8443 dynamicChildren: vnode.dynamicChildren, 8444 appContext: vnode.appContext, 8445 dirs: vnode.dirs, 8446 transition: vnode.transition, 8447 // These should technically only be non-null on mounted VNodes. However, 8448 // they *should* be copied for kept-alive vnodes. So we just always copy 8449 // them since them being non-null during a mount doesn't affect the logic as
vendor: 5,362 bytes, lines 8450-8597
8450 // they will simply be overwritten. 8451 component: vnode.component, 8452 suspense: vnode.suspense, 8453 ssContent: vnode.ssContent && cloneVNode(vnode.ssContent), 8454 ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback), 8455 el: vnode.el, 8456 anchor: vnode.anchor, 8457 ctx: vnode.ctx, 8458 ce: vnode.ce 8459 }; 8460 return cloned; 8461 } 8462 /** 8463 * Dev only, for HMR of hoisted vnodes reused in v-for 8464 * https://github.com/vitejs/vite/issues/2022 8465 */ 8466 function deepCloneVNode(vnode) { 8467 const cloned = cloneVNode(vnode); 8468 if (isArray(vnode.children)) { 8469 cloned.children = vnode.children.map(deepCloneVNode); 8470 } 8471 return cloned; 8472 } 8473 /** 8474 * @private 8475 */ 8476 function createTextVNode(text = ' ', flag = 0) { 8477 return createVNode(Text, null, text, flag); 8478 } 8479 /** 8480 * @private 8481 */ 8482 function createStaticVNode(content, numberOfNodes) { 8483 // A static vnode can contain multiple stringified elements, and the number 8484 // of elements is necessary for hydration. 8485 const vnode = createVNode(Static, null, content); 8486 vnode.staticCount = numberOfNodes; 8487 return vnode; 8488 } 8489 /** 8490 * @private 8491 */ 8492 function createCommentVNode(text = '', 8493 // when used as the v-else branch, the comment node must be created as a 8494 // block to ensure correct updates. 8495 asBlock = false) { 8496 return asBlock 8497 ? (openBlock(), createBlock(Comment, null, text)) 8498 : createVNode(Comment, null, text); 8499 } 8500 function normalizeVNode(child) { 8501 if (child == null || typeof child === 'boolean') { 8502 // empty placeholder 8503 return createVNode(Comment); 8504 } 8505 else if (isArray(child)) { 8506 // fragment 8507 return createVNode(Fragment, null, 8508 // #3666, avoid reference pollution when reusing vnode 8509 child.slice()); 8510 } 8511 else if (typeof child === 'object') { 8512 // already vnode, this should be the most common since compiled templates 8513 // always produce all-vnode children arrays 8514 return cloneIfMounted(child); 8515 } 8516 else { 8517 // strings and numbers 8518 return createVNode(Text, null, String(child)); 8519 } 8520 } 8521 // optimized normalization for template-compiled render fns 8522 function cloneIfMounted(child) { 8523 return (child.el === null && child.patchFlag !== -1 /* PatchFlags.HOISTED */) || 8524 child.memo 8525 ? child 8526 : cloneVNode(child); 8527 } 8528 function normalizeChildren(vnode, children) { 8529 let type = 0; 8530 const { shapeFlag } = vnode; 8531 if (children == null) { 8532 children = null; 8533 } 8534 else if (isArray(children)) { 8535 type = 16 /* ShapeFlags.ARRAY_CHILDREN */; 8536 } 8537 else if (typeof children === 'object') { 8538 if (shapeFlag & (1 /* ShapeFlags.ELEMENT */ | 64 /* ShapeFlags.TELEPORT */)) { 8539 // Normalize slot to plain children for plain element and Teleport 8540 const slot = children.default; 8541 if (slot) { 8542 // _c marker is added by withCtx() indicating this is a compiled slot 8543 slot._c && (slot._d = false); 8544 normalizeChildren(vnode, slot()); 8545 slot._c && (slot._d = true); 8546 } 8547 return; 8548 } 8549 else { 8550 type = 32 /* ShapeFlags.SLOTS_CHILDREN */; 8551 const slotFlag = children._; 8552 if (!slotFlag && !(InternalObjectKey in children)) { 8553 children._ctx = currentRenderingInstance; 8554 } 8555 else if (slotFlag === 3 /* SlotFlags.FORWARDED */ && currentRenderingInstance) { 8556 // a child component receives forwarded slots from the parent. 8557 // its slot type is determined by its parent's slot type. 8558 if (currentRenderingInstance.slots._ === 1 /* SlotFlags.STABLE */) { 8559 children._ = 1 /* SlotFlags.STABLE */; 8560 } 8561 else { 8562 children._ = 2 /* SlotFlags.DYNAMIC */; 8563 vnode.patchFlag |= 1024 /* PatchFlags.DYNAMIC_SLOTS */; 8564 } 8565 } 8566 } 8567 } 8568 else if (isFunction(children)) { 8569 children = { default: children, _ctx: currentRenderingInstance }; 8570 type = 32 /* ShapeFlags.SLOTS_CHILDREN */; 8571 } 8572 else { 8573 children = String(children); 8574 // force teleport children to array so it can be moved around 8575 if (shapeFlag & 64 /* ShapeFlags.TELEPORT */) { 8576 type = 16 /* ShapeFlags.ARRAY_CHILDREN */; 8577 children = [createTextVNode(children)]; 8578 } 8579 else { 8580 type = 8 /* ShapeFlags.TEXT_CHILDREN */; 8581 } 8582 } 8583 vnode.children = children; 8584 vnode.shapeFlag |= type; 8585 } 8586 function mergeProps(...args) { 8587 const ret = {}; 8588 for (let i = 0; i < args.length; i++) { 8589 const toMerge = args[i]; 8590 for (const key in toMerge) { 8591 if (key === 'class') { 8592 if (ret.class !== toMerge.class) { 8593 ret.class = normalizeClass([ret.class, toMerge.class]); 8594 } 8595 } 8596 else if (key === 'style') { 8597 ret.style = normalizeStyle([ret.style, toMerge.
8597style]); 8598 } 8599 else if (isOn(key)) { 8600 const existing = ret[key]; 8601 const incoming = toMerge[key]; 8602 if (incoming && 8603 existing !== incoming && 8604 !(isArray(existing) && existing.includes(incoming))) { 8605 ret[key] = existing 8606 ? [].concat(existing, incoming) 8607 : incoming; 8608 } 8609 } 8610 else if (key !== '') { 8611 ret[key] = toMerge[key]; 8612 } 8613 } 8614 } 8615 return ret; 8616 } 8617 function invokeVNodeHook(hook, instance, vnode, prevVNode = null) { 8618 callWithAsyncErrorHandling(hook, instance, 7 /* ErrorCodes.VNODE_HOOK */, [ 8619 vnode, 8620 prevVNode 8621 ]); 8622 } 8623 8624 const emptyAppContext = createAppContext(); 8625 let uid = 0; 8626 function createComponentInstance(vnode, parent, suspense) { 8627 const type = vnode.type; 8628 // inherit parent app context - or - if root, adopt from root vnode 8629 const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext; 8630 const instance = { 8631 uid: uid++, 8632 vnode, 8633 type, 8634 parent, 8635 appContext, 8636 root: null, 8637 next: null, 8638 subTree: null, 8639 effect: null, 8640 update: null, 8641 scope: new EffectScope(true /* detached */), 8642 render: null, 8643 proxy: null, 8644 exposed: null, 8645 exposeProxy: null, 8646 withProxy: null, 8647 provides: parent ? parent.provides : Object.create(appContext.provides), 8648 accessCache: null, 8649 renderCache: [], 8650 // local resolved assets 8651 components: null, 8652 directives: null, 8653 // resolved props and emits options 8654 propsOptions: normalizePropsOptions(type, appContext), 8655 emitsOptions: normalizeEmitsOptions(type, appContext), 8656 // emit 8657 emit: null, 8658 emitted: null, 8659 // props default value 8660 propsDefaults: EMPTY_OBJ, 8661 // inheritAttrs 8662 inheritAttrs: type.inheritAttrs, 8663 // state 8664 ctx: EMPTY_OBJ, 8665 data: EMPTY_OBJ, 8666 props: EMPTY_OBJ, 8667 attrs: EMPTY_OBJ, 8668 slots: EMPTY_OBJ, 8669 refs: EMPTY_OBJ, 8670 setupState: EMPTY_OBJ, 8671 setupContext: null, 8672 // suspense related 8673 suspense, 8674 suspenseId: suspense ? suspense.pendingId : 0, 8675 asyncDep: null, 8676 asyncResolved: false, 8677 // lifecycle hooks 8678 // not using enums here because it results in computed properties 8679 isMounted: false, 8680 isUnmounted: false, 8681 isDeactivated: false, 8682 bc: null, 8683 c: null, 8684 bm: null, 8685 m: null, 8686 bu: null, 8687 u: null, 8688 um: null, 8689 bum: null, 8690 da: null, 8691 a: null, 8692 rtg: null, 8693 rtc: null, 8694 ec: null, 8695 sp: null 8696 }; 8697 { 8698 instance.ctx = createDevRenderContext(instance); 8699 } 8700 instance.root = parent ? parent.root : instance; 8701 instance.emit = emit.bind(null, instance); 8702 // apply custom element special handling 8703 if (vnode.ce) { 8704 vnode.ce(instance); 8705 } 8706 return instance; 8707 } 8708 let currentInstance = null; 8709 const getCurrentInstance = () => currentInstance || currentRenderingInstance; 8710 const setCurrentInstance = (instance) => { 8711 currentInstance = instance; 8712 instance.scope.on(); 8713 }; 8714 const unsetCurrentInstance = () => { 8715 currentInstance && currentInstance.scope.off(); 8716 currentInstance = null; 8717 }; 8718 const isBuiltInTag = /*#__PURE__*/ makeMap('slot,component'); 8719 function validateComponentName(name, config) { 8720 const appIsNativeTag = config.isNativeTag || NO; 8721 if (isBuiltInTag(name) || appIsNativeTag(name)) { 8722 warn('Do not use built-in or reserved HTML elements as component id: ' + name); 8723 } 8724 } 8725 function isStatefulComponent(instance) { 8726 return instance.vnode.shapeFlag & 4 /* ShapeFlags.STATEFUL_COMPONENT */; 8727 } 8728 let isInSSRComponentSetup = false;
8729 function setupComponent(instance, isSSR = false) { 8730 isInSSRComponentSetup = isSSR; 8731 const { props, children } = instance.vnode; 8732 const isStateful = isStatefulComponent(instance); 8733 initProps(instance, props, isStateful, isSSR); 8734 initSlots(instance, children); 8735 const setupResult = isStateful 8736 ? setupStatefulComponent(instance, isSSR) 8737 : undefined; 8738 isInSSRComponentSetup = false; 8739 return setupResult; 8740 } 8741 function setupStatefulComponent(instance, isSSR) { 8742 var _a; 8743 const Component = instance.type; 8744 { 8745 if (Component.name) { 8746 validateComponentName(Component.name, instance.appContext.config); 8747 } 8748 if (Component.components) { 8749 const names = Object.keys(Component.components); 8750 for (let i = 0; i < names.length; i++) { 8751 validateComponentName(names[i], instance.appContext.config); 8752 } 8753 } 8754 if (Component.directives) { 8755 const names = Object.keys(Component.directives); 8756 for (let i = 0; i < names.length; i++) { 8757 validateDirectiveName(names[i]); 8758 } 8759 } 8760 if (Component.compilerOptions && isRuntimeOnly()) { 8761 warn(`"compilerOptions" is only supported when using a build of Vue that ` + 8762 `includes the runtime compiler. Since you are using a runtime-only ` + 8763 `build, the options should be passed via your build tool config instead.`); 8764 } 8765 } 8766 // 0. create render proxy property access cache 8767 instance.accessCache = Object.create(null); 8768 // 1. create public instance / render proxy 8769 // also mark it raw so it's never observed 8770 instance.proxy = markRaw(new Proxy(instance.ctx, PublicInstanceProxyHandlers)); 8771 { 8772 exposePropsOnRenderContext(instance); 8773 } 8774 // 2. call setup() 8775 const { setup } = Component; 8776 if (setup) { 8777 const setupContext = (instance.setupContext = 8778 setup.length > 1 ? createSetupContext(instance) : null); 8779 setCurrentInstance(instance); 8780 pauseTracking(); 8781 const setupResult = callWithErrorHandling(setup, instance, 0 /* ErrorCodes.SETUP_FUNCTION */, [shallowReadonly(instance.props) , setupContext]); 8782 resetTracking(); 8783 unsetCurrentInstance(); 8784 if (isPromise(setupResult)) { 8785 setupResult.then(unsetCurrentInstance, unsetCurrentInstance); 8786 if (isSSR) { 8787 // return the promise so server-renderer can wait on it 8788 return setupResult 8789 .then((resolvedResult) => { 8790 handleSetupResult(instance, resolvedResult, isSSR); 8791 }) 8792 .catch(e => { 8793 handleError(e, instance, 0 /* ErrorCodes.SETUP_FUNCTION */); 8794 }); 8795 } 8796 else { 8797 // async setup returned Promise. 8798 // bail here and wait for re-entry. 8799 instance.asyncDep = setupResult; 8800 if (!instance.suspense) { 8801 const name = (_a = Component.name) !== null && _a !== void 0 ? _a : 'Anonymous'; 8802 warn(`Component <${name}>: setup function returned a promise, but no ` + 8803 `<Suspense> boundary was found in the parent component tree. ` + 8804 `A component with async setup() must be nested in a <Suspense> ` + 8805 `in order to be rendered.`); 8806 } 8807 } 8808 } 8809 else { 8810 handleSetupResult(instance, setupResult, isSSR); 8811 } 8812 } 8813 else { 8814 finishComponentSetup(instance, isSSR); 8815 } 8816 } 8817 function handleSetupResult(instance, setupResult, isSSR) { 8818 if (isFunction(setupResult)) { 8819 // setup returned an inline render function 8820 { 8821 instance.render = setupResult; 8822 } 8823 } 8824 else if (isObject(setupResult)) { 8825 if (isVNode(setupResult)) { 8826 warn(`setup() should not return VNodes directly - ` + 8827 `return a render function instead.`); 8828 } 8829 // setup returned bindings. 8830 // assuming a render function compiled from template is present. 8831 { 8832 instance.devtoolsRawSetupState = setupResult; 8833 } 8834 instance.setupState = proxyRefs(setupResult); 8835 { 8836 exposeSetupStateOnRenderContext(instance); 8837 } 8838 } 8839 else if (setupResult !== undefined) { 8840 warn(`setup() should return an object. Received: ${setupResult === null ? 'null' : typeof setupResult}`); 8841 } 8842 finishComponentSetup(instance, isSSR); 8843 } 8844 let compile$1; 8845 let installWithProxy; 8846 /** 8847 * For runtime-dom to register the compiler. 8848 * Note the exported method uses any to avoid d.ts relying on the compiler types. 8849 */ 8850 function registerRuntimeCompiler(_compile) { 8851 compile$1 = _compile; 8852 installWithProxy = i => { 8853 if (i.render._rc) { 8854 i.withProxy = new Proxy(i.ctx, RuntimeCompiledPublicInstanceProxyHandlers); 8855 } 8856 }; 8857 } 8858 // dev only 8859 const isRuntimeOnly = () => !compile$1; 8860 function finishComponentSetup(instance, isSSR, skipOptions) { 8861 const Component = instance.type; 8862 // template / render function normalization 8863 // could be already set when returned from setup() 8864 if (!instance.render) { 8865 // only do on-the-fly compile if not in SSR - SSR on-the-fly compilation 8866 // is done by server-renderer 8867 if (!isSSR && compile$1 && !Component.render) { 8868 const template = Component.template || 8869 resolveMergedOptions(instance).template; 8870 if (template) { 8871 { 8872 startMeasure(instance, `compile`); 8873 } 8874 const { isCustomElement, compilerOptions } = instance.appContext.config; 8875 const { delimiters, compilerOptions: componentCompilerOptions } = Component; 8876 const finalCompilerOptions = extend(extend({ 8877 isCustomElement, 8878 delimiters 8879 }, compilerOptions), componentCompilerOptions); 8880 Component.render = compile$1(template, finalCompilerOptions); 8881 { 8882 endMeasure(instance, `compile`); 8883 } 8884 } 8885 } 8886 instance.render = (Component.render || NOOP); 8887 // for runtime-compiled render functions using `with` blocks, the render 8888 // proxy used needs a different `has` handler which is more performant and 8889 // also only allows a whitelist of globals to fallthrough. 8890 if (installWithProxy) { 8891 installWithProxy(instance); 8892 } 8893 } 8894 // support for 2.x options 8895 { 8896 setCurrentInstance(instance); 8897 pauseTracking(); 8898 applyOptions(instance); 8899 resetTracking(); 8900 unsetCurrentInstance(); 8901 } 8902 // warn missing template/render 8903 // the runtime compilation of template in SSR is done by server-render 8904 if (!Component.render && instance.render === NOOP && !isSSR) { 8905 /* istanbul ignore if */ 8906 if (!compile$1 && Component.template) { 8907 warn(`Component provided template option but ` + 8908 `runtime compilation is not supported in this build of Vue.` + 8909 (` Use "vue.global.js" instead.` 8910 ) /* should not happen */); 8911 } 8912 else { 8913 warn(`Component is missing template or render function.`); 8914 } 8915 } 8916 } 8917 function createAttrsProxy(instance) { 8918 return new Proxy(instance.attrs, { 8919 get(target, key) { 8920 markAttrsAccessed(); 8921 track(instance, "get" /* TrackOpTypes.GET */, '$attrs'); 8922 return target[key]; 8923 }, 8924 set() { 8925 warn(`setupContext.attrs is readonly.`); 8926 return false;
8927 }, 8928 deleteProperty() { 8929 warn(`setupContext.attrs is readonly.`); 8930 return false; 8931 } 8932 } 8933 ); 8934 } 8935 function createSetupContext(instance) { 8936 const expose = exposed => { 8937 { 8938 if (instance.exposed) { 8939 warn(`expose() should be called only once per setup().`); 8940 } 8941 if (exposed != null) { 8942 let exposedType = typeof exposed; 8943 if (exposedType === 'object') { 8944 if (isArray(exposed)) { 8945 exposedType = 'array'; 8946 } 8947 else if (isRef(exposed)) { 8948 exposedType = 'ref'; 8949 } 8950 } 8951 if (exposedType !== 'object') { 8952 warn(`expose() should be passed a plain object, received ${exposedType}.`); 8953 } 8954 } 8955 } 8956 instance.exposed = exposed || {}; 8957 }; 8958 let attrs; 8959 { 8960 // We use getters in dev in case libs like test-utils overwrite instance 8961 // properties (overwrites should not be done in prod) 8962 return Object.freeze({ 8963 get attrs() { 8964 return attrs || (attrs = createAttrsProxy(instance)); 8965 }, 8966 get slots() { 8967 return shallowReadonly(instance.slots); 8968 },
8969 get emit() { 8970 return (event, ...args) => instance.emit(event, ...args); 8971 }, 8972 expose 8973 }); 8974 } 8975 } 8976 function getExposeProxy(instance) { 8977 if (instance.exposed) { 8978 return (instance.exposeProxy || 8979 (instance.exposeProxy = new Proxy(proxyRefs(markRaw(instance.exposed)), { 8980 get(target, key) { 8981 if (key in target) { 8982 return target[key]; 8983 } 8984 else if (key in publicPropertiesMap) { 8985 return publicPropertiesMap[key](instance); 8986 } 8987 }, 8988 has(target, key) { 8989 return key in target || key in publicPropertiesMap; 8990 } 8991 }))); 8992 } 8993 } 8994 const classifyRE = /(?:^|[-_])(\w)/g; 8995 const classify = (str) => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, ''); 8996 function getComponentName(Component, includeInferred = true) { 8997 return isFunction(Component) 8998 ? Component.displayName || Component.name 8999 : Component.name || (includeInferred && Component.__name); 9000 } 9001 /* istanbul ignore next */ 9002 function formatComponentName(instance, Component, isRoot = false) { 9003 let name = getComponentName(Component); 9004 if (!name && Component.__file) { 9005 const match = Component.__file.match(/([^/\\]+)\.\w+$/); 9006 if (match) { 9007 name = match[1]; 9008 } 9009 } 9010 if (!name && instance && instance.parent) { 9011 // try to infer the name based on reverse resolution 9012 const inferFromRegistry = (registry) => { 9013 for (const key in registry) { 9014 if (registry[key] === Component) { 9015 return key; 9016 } 9017 } 9018 }; 9019 name = 9020 inferFromRegistry(instance.components || 9021 instance.parent.type.components) || inferFromRegistry(instance.appContext.components); 9022 } 9023 return name ? classify(name) : isRoot ? `App` : `Anonymous`; 9024 } 9025 function isClassComponent(value) { 9026 return isFunction(value) && '__vccOpts' in value; 9027 } 9028 9029 const computed = ((getterOrOptions, debugOptions) => { 9030 // @ts-ignore 9031 return computed$1(getterOrOptions, debugOptions, isInSSRComponentSetup); 9032 }); 9033 9034 // dev only 9035 const warnRuntimeUsage = (method) => warn(`${method}() is a compiler-hint helper that is only usable inside ` + 9036 `<script setup> of a single file component. Its arguments should be ` + 9037 `compiled away and passing it at runtime has no effect.`); 9038 // implementation 9039 function defineProps() { 9040 { 9041 warnRuntimeUsage(`defineProps`); 9042 } 9043 return null; 9044 } 9045 // implementation 9046 function defineEmits() { 9047 { 9048 warnRuntimeUsage(`defineEmits`); 9049 } 9050 return null; 9051 } 9052 /** 9053 * Vue `<script setup>` compiler macro for declaring a component's exposed 9054 * instance properties when it is accessed by a parent component via template 9055 * refs. 9056 * 9057 * `<script setup>` components are closed by default - i.e. variables inside 9058 * the `<script setup>` scope is not exposed to parent unless explicitly exposed 9059 * via `defineExpose`. 9060 * 9061 * This is only usable inside `<script setup>`, is compiled away in the 9062 * output and should **not** be actually called at runtime. 9063 */ 9064 function defineExpose(exposed) { 9065 { 9066 warnRuntimeUsage(`defineExpose`); 9067 } 9068 } 9069 /** 9070 * Vue `<script setup>` compiler macro for providing props default values when 9071 * using type-based `defineProps` declaration. 9072 * 9073 * Example usage: 9074 * ```ts 9075 * withDefaults(defineProps<{ 9076 * size?: number 9077 * labels?: string[] 9078 * }>(), { 9079 * size: 3, 9080 * labels: () => ['default label'] 9081 * }) 9082 * ``` 9083 * 9084 * This is only usable inside `<script setup>`, is compiled away in the output 9085 * and should **not** be actually called at runtime. 9086 */ 9087 function withDefaults(props, defaults) { 9088 { 9089 warnRuntimeUsage(`withDefaults`); 9090 } 9091 return null; 9092 } 9093 function useSlots() { 9094 return getContext().slots; 9095 } 9096 function useAttrs() { 9097 return getContext().attrs; 9098 } 9099 function getContext() { 9100 const i = getCurrentInstance(); 9101 if (!i) { 9102 warn(`useContext() called without active instance.`); 9103 } 9104 return i.setupContext || (i.setupContext = createSetupContext(i)); 9105 } 9106 /** 9107 * Runtime helper for merging default declarations. Imported by compiled code 9108 * only. 9109 * @internal 9110 */ 9111 function mergeDefaults(raw, defaults) { 9112 const props = isArray(raw) 9113 ? raw.reduce((normalized, p) => ((normalized[p] = {}), normalized), {}) 9114 : raw; 9115 for (const key in defaults) { 9116 const opt = props[key]; 9117 if (opt) { 9118 if (isArray(opt) || isFunction(opt)) { 9119 props[key] = { type: opt, default: defaults[key] }; 9120 } 9121 else { 9122 opt.default = defaults[key]; 9123 } 9124 } 9125 else if (opt === null) { 9126 props[key] = { default: defaults[key] }; 9127 } 9128 else { 9129 warn(`props default key "${key}" has no corresponding declaration.`); 9130 } 9131 } 9132 return props; 9133 } 9134 /** 9135 * Used to create a proxy for the rest element when destructuring props with 9136 * defineProps(). 9137 * @internal 9138 */ 9139 function createPropsRestProxy(props, excludedKeys) { 9140 const ret = {}; 9141 for (const key in props) { 9142 if (!excludedKeys.includes(key)) { 9143 Object.defineProperty(ret, key, { 9144 enumerable: true, 9145 get: () => props[key] 9146 }); 9147 } 9148 } 9149 return ret; 9150 } 9151 /** 9152 * `<script setup>` helper for persisting the current instance context over 9153 * async/await flows. 9154 * 9155 * `@vue/compiler-sfc` converts the following: 9156 * 9157 * ```ts 9158 * const x = await foo() 9159 * ``` 9160 * 9161 * into: 9162 * 9163 * ```ts 9164 * let __temp, __restore 9165 * const x = (([__temp, __restore] = withAsyncContext(() =>
9165 foo())),__temp=await __temp,__restore(),__temp) 9166 * ``` 9167 * @internal 9168 */ 9169 function withAsyncContext(getAwaitable) { 9170 const ctx = getCurrentInstance(); 9171 if (!ctx) { 9172 warn(`withAsyncContext called without active current instance. ` + 9173 `This is likely a bug.`); 9174 } 9175 let awaitable = getAwaitable(); 9176 unsetCurrentInstance(); 9177 if (isPromise(awaitable)) { 9178 awaitable = awaitable.catch(e => { 9179 setCurrentInstance(ctx); 9180 throw e; 9181 }); 9182 } 9183 return [awaitable, () => setCurrentInstance(ctx)]; 9184 } 9185 9186 // Actual implementation 9187 function h(type, propsOrChildren, children) { 9188 const l = arguments.length; 9189 if (l === 2) { 9190 if (isObject(propsOrChildren) && !isArray(propsOrChildren)) { 9191 // single vnode without props 9192 if (isVNode(propsOrChildren)) { 9193 return createVNode(type, null, [propsOrChildren]); 9194 } 9195 // props without children 9196 return createVNode(type, propsOrChildren); 9197 } 9198 else { 9199 // omit props 9200 return createVNode(type, null, propsOrChildren); 9201 } 9202 } 9203 else { 9204 if (l > 3) { 9205 children = Array.prototype.slice.call(arguments, 2); 9206 } 9207 else if (l === 3 && isVNode(children)) { 9208 children = [children]; 9209 } 9210 return createVNode(type, propsOrChildren, children); 9211 } 9212 } 9213 9214 const ssrContextKey = Symbol(`ssrContext` ); 9215 const useSSRContext = () => { 9216 { 9217 warn(`useSSRContext() is not supported in the global build.`); 9218 } 9219 }; 9220 9221 function initCustomFormatter() { 9222 /* eslint-disable no-restricted-globals */ 9223 if (typeof window === 'undefined') { 9224 return; 9225 } 9226 const vueStyle = { style: 'color:#3ba776' }; 9227 const numberStyle = { style: 'color:#0b1bc9' }; 9228 const stringStyle = { style: 'color:#b62e24' }; 9229 const keywordStyle = { style: 'color:#9d288c' }; 9230 // custom formatter for Chrome 9231 // https://www.mattzeunert.com/2016/02/19/custom-chrome-devtools-object-formatters.html 9232 const formatter = { 9233 header(obj) { 9234 // TODO also format ComponentPublicInstance & ctx.slots/attrs in setup 9235 if (!isObject(obj)) { 9236 return null; 9237 } 9238 if (obj.__isVue) { 9239 return ['div', vueStyle, `VueInstance`]; 9240 } 9241 else if (isRef(obj)) { 9242 return [ 9243 'div', 9244 {}, 9245 ['span', vueStyle, genRefFlag(obj)], 9246 '<', 9247 formatValue(obj.value), 9248 `>` 9249 ]; 9250 } 9251 else if (isReactive(obj)) { 9252 return [ 9253 'div', 9254 {}, 9255 ['span', vueStyle, isShallow(obj) ? 'ShallowReactive' : 'Reactive'], 9256 '<', 9257 formatValue(obj), 9258 `>${isReadonly(obj) ? ` (readonly)` : ``}` 9259 ]; 9260 } 9261 else if (isReadonly(obj)) { 9262 return [ 9263 'div', 9264 {}, 9265 ['span', vueStyle, isShallow(obj) ? 'ShallowReadonly' : 'Readonly'], 9266 '<', 9267 formatValue(obj), 9268 '>' 9269 ]; 9270 } 9271 return null; 9272 }, 9273 hasBody(obj) { 9274 return obj && obj.__isVue; 9275 }, 9276 body(obj) { 9277 if (obj && obj.__isVue) { 9278 return [ 9279 'div', 9280 {}, 9281 ...formatInstance(obj.$) 9282 ]; 9283 } 9284 } 9285 }; 9286 function formatInstance(instance) { 9287 const blocks = []; 9288 if (instance.type.props && instance.props) { 9289 blocks.push(createInstanceBlock('props', toRaw(instance.props))); 9290 } 9291 if (instance.setupState !== EMPTY_OBJ) { 9292 blocks.push(createInstanceBlock('setup', instance.setupState)); 9293 } 9294 if (instance.data !== EMPTY_OBJ) { 9295 blocks.push(createInstanceBlock('data', toRaw(instance.data))); 9296 } 9297 const computed = extractKeys(instance, 'computed'); 9298 if (computed) { 9299 blocks.push(createInstanceBlock('computed', computed)); 9300 } 9301 const injected = extractKeys(instance, 'inject'); 9302 if (injected) { 9303 blocks.push(createInstanceBlock('injected', injected)); 9304 } 9305 blocks.push([ 9306 'div', 9307 {}, 9308 [ 9309 'span', 9310 { 9311 style: keywordStyle.style + ';opacity:0.66' 9312 }, 9313 '$ (internal): ' 9314 ], 9315 ['object', { object: instance }] 9316 ]); 9317 return blocks; 9318 } 9319 function createInstanceBlock(type, target) { 9320 target = extend({}, target); 9321 if (!Object.keys(target).length) { 9322 return ['span', {}]; 9323 } 9324 return [ 9325 'div', 9326 { style: 'line-height:1.25em;margin-bottom:0.6em' }, 9327 [ 9328 'div', 9329 { 9330 style: 'color:#476582' 9331 }, 9332 type 9333 ], 9334 [ 9335 'div', 9336 { 9337 style: 'padding-left:1.25em' 9338 }, 9339 ...Object.keys(target).map(key => { 9340 return [ 9341 'div', 9342 {}, 9343 ['span', keywordStyle, key + ': '], 9344 formatValue(target[key], false) 9345 ]; 9346 }) 9347 ] 9348 ]; 9349 } 9350 function formatValue(v, asRaw = true) { 9351 if (typeof v === 'number') { 9352 return ['span', numberStyle, v]; 9353 } 9354 else if (typeof v === 'string') { 9355 return ['span', stringStyle, JSON.stringify(v)]; 9356 } 9357 else if (typeof v === 'boolean') { 9358 return ['span', keywordStyle, v]; 9359 } 9360 else if (isObject(v)) { 9361 return ['object', { object: asRaw ? toRaw(v) : v }]; 9362 } 9363 else { 9364 return ['span', stringStyle, String(v)]; 9365 } 9366 } 9367 function extractKeys(instance, type) { 9368 const Comp = instance.type; 9369 if (isFunction(Comp)) { 9370 return; 9371 } 9372 const extracted = {}; 9373 for (const key in instance.ctx) { 9374 if (isKeyOfType(Comp, key, type)) { 9375 extracted[key] = instance.ctx[key]; 9376 } 9377 } 9378 return extracted; 9379 } 9380 function isKeyOfType(Comp, key, type) { 9381 const opts = Comp[type]; 9382 if ((isArray(opts) && opts.includes(key)) || 9383 (isObject(opts) && key in opts)) { 9384 return true; 9385 } 9386 if (Comp.extends && isKeyOfType(Comp.extends, key, type)) { 9387 return true; 9388 } 9389 if (Comp.mixins && Comp.mixins.some(m => isKeyOfType(m, key, type))) { 9390 return true; 9391 } 9392 } 9393 function genRefFlag(v) { 9394 if (isShallow(v)) { 9395 return `ShallowRef`; 9396 } 9397 if (v.effect) { 9398 return `ComputedRef`; 9399 } 9400 return `Ref`; 9401 } 9402 if (window.devtoolsFormatters) { 9403 window.devtoolsFormatters.push(formatter); 9404 } 9405 else { 9406 window.devtoolsFormatters = [formatter]; 9407 } 9408 } 9409 9410 function withMemo(memo, render, cache, index) {
9411 const cached = cache[index]; 9412 if (cached && isMemoSame(cached, memo)) { 9413 return cached; 9414 } 9415 const ret = render(); 9416 // shallow clone 9417 ret.memo = memo.slice(); 9418 return (cache[index] = ret); 9419 } 9420 function isMemoSame(cached, memo) { 9421 const prev = cached.memo; 9422 if (prev.length != memo.length) { 9423 return false; 9424 } 9425 for (let i = 0; i < prev.length; i++) { 9426 if (hasChanged(prev[i], memo[i])) { 9427 return false; 9428 } 9429 } 9430 // make sure to let parent block track it when returning cached 9431 if (isBlockTreeEnabled > 0 && currentBlock) { 9432 currentBlock.push(cached); 9433 } 9434 return true; 9435 } 9436 9437 // Core API ------------------------------------------------------------------ 9438 const version = "3.2.47"; 9439 /** 9440 * SSR utils for \@vue/server-renderer. Only exposed in ssr-possible builds. 9441 * @internal 9442 */ 9443 const ssrUtils = (null); 9444 /** 9445 * @internal only exposed in compat builds 9446 */ 9447 const resolveFilter = null; 9448 /** 9449 * @internal only exposed in compat builds. 9450 */ 9451 const compatUtils = (null); 9452 9453 const svgNS = 'http://www.w3.org/2000/svg'; 9454 const doc = (typeof document !== 'undefined' ? document : null); 9455 const templateContainer = doc && /*#__PURE__*/ doc.createElement('template'); 9456 const nodeOps = { 9457 insert: (child, parent, anchor) => { 9458 parent.insertBefore(child, anchor || null); 9459 }, 9460 remove: child => { 9461 const parent = child.parentNode; 9462 if (parent) { 9463 parent.removeChild(child); 9464 } 9465 }, 9466 createElement: (tag, isSVG, is, props) => { 9467 const el = isSVG 9468 ? doc.createElementNS(svgNS, tag) 9469 : doc.createElement(tag, is ? { is } : undefined); 9470 if (tag === 'select' && props && props.multiple != null) { 9471 el.setAttribute('multiple', props.multiple); 9472 } 9473 return el; 9474 }, 9475 createText: text => doc.createTextNode(text), 9476 createComment: text => doc.createComment(text), 9477 setText: (node, text) => { 9478 node.nodeValue = text; 9479 }, 9480 setElementText: (el, text) => { 9481 el.textContent = text; 9482 }, 9483 parentNode: node => node.parentNode,
9484 nextSibling: node => node.nextSibling, 9485 querySelector: selector => doc.querySelector(selector), 9486 setScopeId(el, id) { 9487 el.setAttribute(id, ''); 9488 }, 9489 // __UNSAFE__ 9490 // Reason: innerHTML. 9491 // Static content here can only come from compiled templates. 9492 // As long as the user only uses trusted templates, this is safe. 9493 insertStaticContent(content, parent, anchor, isSVG, start, end) { 9494 // <parent> before | first ... last | anchor </parent> 9495 const before = anchor ? anchor.previousSibling : parent.lastChild; 9496 // #5308 can only take cached path if: 9497 // - has a single root node 9498 // - nextSibling info is still available 9499 if (start && (start === end || start.nextSibling)) { 9500 // cached 9501 while (true) { 9502 parent.insertBefore(start.cloneNode(true), anchor); 9503 if (start === end || !(start = start.nextSibling)) 9504 break; 9505 } 9506 } 9507 else { 9508 // fresh insert 9509 templateContainer.innerHTML = isSVG ? `<svg>${content}</svg>` : content; 9510 const template = templateContainer.content; 9511 if (isSVG) { 9512 // remove outer svg wrapper 9513 const wrapper = template.firstChild; 9514 while (wrapper.firstChild) { 9515 template.appendChild(wrapper.firstChild); 9516 } 9517 template.removeChild(wrapper); 9518 } 9519 parent.insertBefore(template, anchor); 9520 } 9521 return [ 9522 // first 9523 before ? before.nextSibling : parent.firstChild, 9524 // last 9525 anchor ? anchor.previousSibling : parent.lastChild 9526 ]; 9527 } 9528 }; 9529 9530 // compiler should normalize class + :class bindings on the same element 9531 // into a single binding ['staticClass', dynamic] 9532 function patchClass(el, value, isSVG) { 9533 // directly setting className should be faster than setAttribute in theory 9534 // if this is an element during a transition, take the temporary transition 9535 // classes into account. 9536 const transitionClasses = el._vtc; 9537 if (transitionClasses) { 9538 value = (value ? [value, ...transitionClasses] : [...transitionClasses]).join(' '); 9539 } 9540 if (value == null) { 9541 el.removeAttribute('class'); 9542 } 9543 else if (isSVG) { 9544 el.setAttribute('class', value); 9545 } 9546 else { 9547 el.className = value; 9548 } 9549 } 9550 9551 function patchStyle(el, prev, next) { 9552 const style = el.style; 9553 const isCssString = isString(next); 9554 if (next && !isCssString) { 9555 if (prev && !isString(prev)) { 9556 for (const key in prev) { 9557 if (next[key] == null) { 9558 setStyle(style, key, ''); 9559 } 9560 } 9561 } 9562 for (const key in next) { 9563 setStyle(style, key, next[key]); 9564 } 9565 } 9566 else { 9567 const currentDisplay = style.display; 9568 if (isCssString) { 9569 if (prev !== next) { 9570 style.cssText = next; 9571 } 9572 } 9573 else if (prev) { 9574 el.removeAttribute('style'); 9575 } 9576 // indicates that the `display` of the element is controlled by `v-show`, 9577 // so we always keep the current `display` value regardless of the `style` 9578 // value, thus handing over control to `v-show`. 9579 if ('_vod' in el) { 9580 style.display = currentDisplay; 9581 } 9582 } 9583 } 9584 const semicolonRE = /[^\\];\s*$/; 9585 const importantRE = /\s*!important$/; 9586 function setStyle(style, name, val) { 9587 if (isArray(val)) { 9588 val.forEach(v => setStyle(style, name, v)); 9589 } 9590 else { 9591 if (val == null) 9592 val = ''; 9593 { 9594 if (semicolonRE.test(val)) { 9595 warn(`Unexpected semicolon at the end of '${name}' style value: '${val}'`); 9596 } 9597 } 9598 if (name.startsWith('--')) { 9599 // custom property definition 9600 style.setProperty(name, val); 9601 } 9602 else { 9603 const prefixed = autoPrefix(style, name); 9604 if (importantRE.test(val)) { 9605 // !important 9606 style.setProperty(hyphenate(prefixed), val.replace(importantRE, ''), 'important'); 9607 } 9608 else { 9609 style[prefixed] = val; 9610 } 9611 } 9612 } 9613 } 9614 const prefixes = ['Webkit', 'Moz', 'ms']; 9615 const prefixCache = {}; 9616 function autoPrefix(style, rawName) { 9617 const cached = prefixCache[rawName]; 9618 if (cached) { 9619 return cached; 9620 } 9621 let name = camelize(rawName); 9622 if (name !== 'filter' && name in style) { 9623 return (prefixCache[rawName] = name); 9624 } 9625 name = capitalize(name); 9626 for (let i = 0; i < prefixes.length; i++) { 9627 const prefixed = prefixes[i] + name; 9628 if (prefixed in style) { 9629 return (prefixCache[rawName] = prefixed); 9630 } 9631 } 9632 return rawName; 9633 } 9634 9635 const xlinkNS = 'http://www.w3.org/1999/xlink'; 9636 function patchAttr(el, key, value, isSVG, instance) { 9637 if (isSVG && key.startsWith('xlink:')) { 9638 if (value == null) { 9639 el.removeAttributeNS(xlinkNS, key.slice(6, key.length)); 9640 } 9641 else { 9642 el.setAttributeNS(xlinkNS, key, value); 9643 } 9644 } 9645 else { 9646 // note we are only checking boolean attributes that don't have a 9647 // corresponding dom prop of the same name here. 9648 const isBoolean = isSpecialBooleanAttr(key); 9649 if (value == null || (isBoolean && !includeBooleanAttr(value))) { 9650 el.removeAttribute(key); 9651 } 9652 else { 9653 el.setAttribute(key, isBoolean ? '' : value); 9654 } 9655 } 9656 } 9657 9658 // __UNSAFE__ 9659 // functions. The user is responsible for using them with only trusted content. 9660 function patchDOMProp(el, key, value, 9661 // the following args are passed only due to potential innerHTML/textContent 9662 // overriding existing VNodes, in which case the old tree must be properly 9663 // unmounted. 9664 prevChildren, parentComponent, parentSuspense, unmountChildren) {
9665 if (key === 'innerHTML' || key === 'textContent') { 9666 if (prevChildren) { 9667 unmountChildren(prevChildren, parentComponent, parentSuspense); 9668 } 9669 el[key] = value == null ? '' : value; 9670 return; 9671 } 9672 if (key === 'value' && 9673 el.tagName !== 'PROGRESS' && 9674 // custom elements may use _value internally 9675 !el.tagName.includes('-')) { 9676 // store value as _value as well since 9677 // non-string values will be stringified. 9678 el._value = value; 9679 const newValue = value == null ? '' : value; 9680 if (el.value !== newValue || 9681 // #4956: always set for OPTION elements because its value falls back to 9682 // textContent if no value attribute is present. And setting .value for 9683 // OPTION has no side effect 9684 el.tagName === 'OPTION') { 9685 el.value = newValue; 9686 } 9687 if (value == null) { 9688 el.removeAttribute(key); 9689 } 9690 return; 9691 } 9692 let needRemove = false; 9693 if (value === '' || value == null) { 9694 const type = typeof el[key]; 9695 if (type === 'boolean') { 9696 // e.g. <select multiple> compiles to { multiple: '' } 9697 value = includeBooleanAttr(value); 9698 } 9699 else if (value == null && type === 'string') { 9700 // e.g. <div :id="null"> 9701 value = ''; 9702 needRemove = true; 9703 } 9704 else if (type === 'number') { 9705 // e.g. <img :width="null"> 9706 value = 0; 9707 needRemove = true; 9708 } 9709 } 9710 // some properties perform value validation and throw, 9711 // some properties has getter, no setter, will error in 'use strict' 9712 // eg. <select :type="null"></select> <select :willValidate="null"></select> 9713 try { 9714 el[key] = value; 9715 } 9716 catch (e) { 9717 // do not warn if value is auto-coerced from nullish values 9718 if (!needRemove) { 9719 warn(`Failed setting prop "${key}" on <${el.tagName.toLowerCase()}>: ` + 9720 `value ${value} is invalid.`, e); 9721 } 9722 } 9723 needRemove && el.removeAttribute(key); 9724 } 9725 9726 function addEventListener(el, event, handler, options) { 9727 el.addEventListener(event, handler, options); 9728 } 9729 function removeEventListener(el, event, handler, options) { 9730 el.removeEventListener(event, handler, options); 9731 } 9732 function patchEvent(el, rawName, prevValue, nextValue, instance = null) { 9733 // vei = vue event invokers 9734 const invokers = el._vei || (el._vei = {}); 9735 const existingInvoker = invokers[rawName];
9736 if (nextValue && existingInvoker) { 9737 // patch 9738 existingInvoker.value = nextValue; 9739 } 9740 else { 9741 const [name, options] = parseName(rawName); 9742 if (nextValue) { 9743 // add 9744 const invoker = (invokers[rawName] = createInvoker(nextValue, instance)); 9745 addEventListener(el, name, invoker, options); 9746 } 9747 else if (existingInvoker) { 9748 // remove 9749 removeEventListener(el, name, existingInvoker, options); 9750 invokers[rawName] = undefined; 9751 } 9752 } 9753 } 9754 const optionsModifierRE = /(?:Once|Passive|Capture)$/; 9755 function parseName(name) { 9756 let options; 9757 if (optionsModifierRE.test(name)) { 9758 options = {}; 9759 let m; 9760 while ((m = name.match(optionsModifierRE))) { 9761 name = name.slice(0, name.length - m[0].length); 9762 options[m[0].toLowerCase()] = true; 9763 } 9764 } 9765 const event = name[2] === ':' ? name.slice(3) : hyphenate(name.slice(2)); 9766 return [event, options]; 9767 } 9768 // To avoid the overhead of repeatedly calling Date.now(), we cache 9769 // and use the same timestamp for all event listeners attached in the same tick. 9770 let cachedNow = 0; 9771 const p = /*#__PURE__*/ Promise.resolve(); 9772 const getNow = () => cachedNow || (p.then(() => (cachedNow = 0)), (cachedNow = Date.now())); 9773 function createInvoker(initialValue, instance) { 9774 const invoker = (e) => { 9775 // async edge case vuejs/vue#6566 9776 // inner click event triggers patch, event handler 9777 // attached to outer element during patch, and triggered again. This 9778 // happens because browsers fire microtask ticks between event propagation. 9779 // this no longer happens for templates in Vue 3, but could still be 9780 // theoretically possible for hand-written render functions. 9781 // the solution: we save the timestamp when a handler is attached, 9782 // and also attach the timestamp to any event that was handled by vue 9783 // for the first time (to avoid inconsistent event timestamp implementations 9784 // or events fired from iframes, e.g. #2513) 9785 // The handler would only fire if the event passed to it was fired 9786 // AFTER it was attached. 9787 if (!e._vts) { 9788 e._vts = Date.now(); 9789 } 9790 else if (e._vts <= invoker.attached) { 9791 return; 9792 } 9793 callWithAsyncErrorHandling(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* ErrorCodes.NATIVE_EVENT_HANDLER */, [e]); 9794 }; 9795 invoker.value = initialValue; 9796 invoker.attached = getNow(); 9797 return invoker; 9798 } 9799 function patchStopImmediatePropagation(e, value) { 9800 if (isArray(value)) { 9801 const originalStop = e.stopImmediatePropagation; 9802 e.stopImmediatePropagation = () => { 9803 originalStop.call(e); 9804 e._stopped = true; 9805 }; 9806 return value.map(fn => (e) => !e._stopped && fn && fn(e)); 9807 } 9808 else { 9809 return value; 9810 } 9811 } 9812 9813 const nativeOnRE = /^on[a-z]/; 9814 const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren) => { 9815 if (key === 'class') { 9816 patchClass(el, nextValue, isSVG); 9817 } 9818 else if (key === 'style') { 9819 patchStyle(el, prevValue, nextValue); 9820 } 9821 else if (isOn(key)) { 9822 // ignore v-model listeners 9823 if (!isModelListener(key)) { 9824 patchEvent(el, key, prevValue, nextValue, parentComponent); 9825 } 9826 } 9827 else if (key[0] === '.' 9828 ? ((key = key.slice(1)), true) 9829 : key[0] === '^' 9830 ? ((key = key.slice(1)), false) 9831 : shouldSetAsProp(el, key, nextValue, isSVG)) { 9832 patchDOMProp(el, key, nextValue, prevChildren, parentComponent, parentSuspense, unmountChildren); 9833 } 9834 else { 9835 // special case for <input v-model type="checkbox"> with 9836 // :true-value & :false-value 9837 // store value as dom properties since non-string values will be 9838 // stringified. 9839 if (key === 'true-value') { 9840 el._trueValue = nextValue; 9841 } 9842 else if (key === 'false-value') { 9843 el._falseValue = nextValue; 9844 } 9845 patchAttr(el, key, nextValue, isSVG); 9846 } 9847 }; 9848 function shouldSetAsProp(el, key, value, isSVG) { 9849 if (isSVG) { 9850 // most keys must be set as attribute on svg elements to work 9851 // ...except innerHTML & textContent
9852 if (key === 'innerHTML' || key === 'textContent') { 9853 return true; 9854 } 9855 // or native onclick with function values 9856 if (key in el && nativeOnRE.test(key) && isFunction(value)) { 9857 return true; 9858 } 9859 return false; 9860 } 9861 // these are enumerated attrs, however their corresponding DOM properties 9862 // are actually booleans - this leads to setting it with a string "false" 9863 // value leading it to be coerced to `true`, so we need to always treat 9864 // them as attributes. 9865 // Note that `contentEditable` doesn't have this problem: its DOM 9866 // property is also enumerated string values. 9867 if (key === 'spellcheck' || key === 'draggable' || key === 'translate') { 9868 return false; 9869 } 9870 // #1787, #2840 form property on form elements is readonly and must be set as 9871 // attribute. 9872 if (key === 'form') { 9873 return false; 9874 } 9875 // #1526 <input list> must be set as attribute 9876 if (key === 'list' && el.tagName === 'INPUT') { 9877 return false; 9878 } 9879 // #2766 <textarea type> must be set as attribute 9880 if (key === 'type' && el.tagName === 'TEXTAREA') { 9881 return false; 9882 } 9883 // native onclick with string value, must be set as attribute 9884 if (nativeOnRE.test(key) && isString(value)) { 9885 return false; 9886 } 9887 return key in el; 9888 } 9889 9890 function defineCustomElement(options, hydrate) { 9891 const Comp = defineComponent(options); 9892 class VueCustomElement extends VueElement { 9893 constructor(initialProps) { 9894 super(Comp, initialProps, hydrate); 9895 } 9896 } 9897 VueCustomElement.def = Comp; 9898 return VueCustomElement; 9899 } 9900 const defineSSRCustomElement = ((options) => { 9901 // @ts-ignore 9902 return defineCustomElement(options, hydrate); 9903 }); 9904 const BaseClass = (typeof HTMLElement !== 'undefined' ? HTMLElement : class { 9905 }); 9906 class VueElement extends BaseClass { 9907 constructor(_def, _props = {}, hydrate) { 9908 super(); 9909 this._def = _def; 9910 this._props = _props; 9911 /** 9912 * @internal 9913 */ 9914 this._instance = null; 9915 this._connected = false; 9916 this._resolved = false; 9917 this._numberProps = null; 9918 if (this.shadowRoot && hydrate) { 9919 hydrate(this._createVNode(), this.shadowRoot); 9920 } 9921 else { 9922 if (this.shadowRoot) { 9923 warn(`Custom element has pre-rendered declarative shadow root but is not ` + 9924 `defined as hydratable. Use \`defineSSRCustomElement\`.`); 9925 } 9926 this.attachShadow({ mode: 'open' }); 9927 if (!this._def.__asyncLoader) { 9928 // for sync component defs we can immediately resolve props 9929 this._resolveProps(this._def); 9930 } 9931 } 9932 } 9933 connectedCallback() { 9934 this._connected = true; 9935 if (!this._instance) { 9936 if (this._resolved) { 9937 this._update(); 9938 } 9939 else { 9940 this._resolveDef(); 9941 } 9942 } 9943 } 9944 disconnectedCallback() { 9945 this._connected = false; 9946 nextTick(() => { 9947 if (!this._connected) { 9948 render(null, this.shadowRoot); 9949 this._instance = null; 9950 } 9951 }); 9952 } 9953 /** 9954 * resolve inner component definition (handle possible async component) 9955 */ 9956 _resolveDef() { 9957 this._resolved = true; 9958 // set initial attrs 9959 for (let i = 0; i < this.attributes.length; i++) { 9960 this._setAttr(this.attributes[i].name); 9961 } 9962 // watch future attr changes 9963 new MutationObserver(mutations => { 9964 for (const m of mutations) { 9965 this._setAttr(m.attributeName); 9966 } 9967 }).observe(this, { attributes: true }); 9968 const resolve = (def, isAsync = false) => { 9969 const { props, styles } = def; 9970 // cast Number-type props set before resolve 9971 let numberProps; 9972 if (props && !isArray(props)) { 9973 for (const key in props) { 9974 const opt = props[key]; 9975 if (opt === Number || (opt && opt.type === Number)) { 9976 if (key in this._props) { 9977 this._props[key] = toNumber(this._props[key]); 9978 } 9979 (numberProps || (numberProps = Object.create(null)))[
9979camelize(key)] = true; 9980 } 9981 } 9982 } 9983 this._numberProps = numberProps; 9984 if (isAsync) { 9985 // defining getter/setters on prototype 9986 // for sync defs, this already happened in the constructor 9987 this._resolveProps(def); 9988 } 9989 // apply CSS 9990 this._applyStyles(styles); 9991 // initial render 9992 this._update(); 9993 }; 9994 const asyncDef = this._def.__asyncLoader; 9995 if (asyncDef) { 9996 asyncDef().then(def => resolve(def, true)); 9997 } 9998 else { 9999 resolve(this._def); 10000 } 10001 } 10002 _resolveProps(def) { 10003 const { props } = def; 10004 const declaredPropKeys = isArray(props) ? props : Object.keys(props || {}); 10005 // check if there are props set pre-upgrade or connect 10006 for (const key of Object.keys(this)) { 10007 if (key[0] !== '_' && declaredPropKeys.includes(key)) { 10008 this._setProp(key, this[key], true, false); 10009 } 10010 } 10011 // defining getter/setters on prototype 10012 for (const key of declaredPropKeys.map(camelize)) { 10013 Object.defineProperty(this, key, { 10014 get() { 10015 return this._getProp(key); 10016 }, 10017 set(val) { 10018 this._setProp(key, val); 10019 } 10020 }); 10021 } 10022 } 10023 _setAttr(key) { 10024 let value = this.getAttribute(key); 10025 const camelKey = camelize(key); 10026 if (this._numberProps && this._numberProps[camelKey]) { 10027 value = toNumber(value); 10028 } 10029 this._setProp(camelKey, value, false); 10030 } 10031 /** 10032 * @internal 10033 */ 10034 _getProp(key) { 10035 return this._props[key]; 10036 } 10037 /** 10038 * @internal 10039 */ 10040 _setProp(key, val, shouldReflect = true, shouldUpdate = true) { 10041 if (val !== this._props[key]) { 10042 this._props[key] = val; 10043 if (shouldUpdate && this._instance) { 10044 this._update(); 10045 } 10046 // reflect 10047 if (shouldReflect) { 10048 if (val === true) { 10049 this.setAttribute(hyphenate(key), ''); 10050 } 10051 else if (typeof val === 'string' || typeof val === 'number') { 10052 this.setAttribute(hyphenate(key), val + ''); 10053 } 10054 else if (!val) { 10055 this.removeAttribute(hyphenate(key)); 10056 } 10057 } 10058 } 10059 } 10060 _update() { 10061 render(this._createVNode(), this.shadowRoot); 10062 } 10063 _createVNode() { 10064 const vnode = createVNode(this._def, extend({}, this._props)); 10065 if (!this._instance) { 10066 vnode.ce = instance => { 10067 this._instance = instance; 10068 instance.isCE = true; 10069 // HMR 10070 { 10071 instance.ceReload = newStyles => { 10072 // always reset styles 10073 if (this._styles) { 10074 this._styles.forEach(s => this.shadowRoot.removeChild(s)); 10075 this._styles.length = 0; 10076 } 10077 this._applyStyles(newStyles); 10078 this._instance = null; 10079 this._update(); 10080 }; 10081 } 10082 const dispatch = (event, args) => { 10083 this.dispatchEvent(new CustomEvent(event, { 10084 detail: args 10085 })); 10086 }; 10087 // intercept emit 10088 instance.emit = (event, ...args) => { 10089 // dispatch both the raw and hyphenated versions of an event 10090 // to match Vue behavior 10091 dispatch(event, args); 10092 if (hyphenate(event) !== event) { 10093 dispatch(hyphenate(event), args); 10094 } 10095 }; 10096 // locate nearest Vue custom element parent for provide/inject 10097 let parent = this; 10098 while ((parent = 10099 parent && (parent.parentNode || parent.host))) { 10100 if (parent instanceof VueElement) { 10101 instance.parent = parent._instance; 10102 instance.provides = parent._instance.provides; 10103 break; 10104 } 10105 } 10106 }; 10107 } 10108 return vnode; 10109 } 10110 _applyStyles(styles) { 10111 if (styles) {
10112 styles.forEach(css => { 10113 const s = document.createElement('style'); 10114 s.textContent = css; 10115 this.shadowRoot.appendChild(s); 10116 // record for HMR 10117 { 10118 (this._styles || (this._styles = [])).push(s); 10119 } 10120 }); 10121 } 10122 } 10123 } 10124 10125 function useCssModule(name = '$style') { 10126 /* istanbul ignore else */ 10127 { 10128 { 10129 warn(`useCssModule() is not supported in the global build.`); 10130 } 10131 return EMPTY_OBJ; 10132 } 10133 } 10134 10135 /** 10136 * Runtime helper for SFC's CSS variable injection feature. 10137 * @private 10138 */ 10139 function useCssVars(getter) { 10140 const instance = getCurrentInstance(); 10141 /* istanbul ignore next */ 10142 if (!instance) { 10143 warn(`useCssVars is called without current active component instance.`); 10144 return; 10145 } 10146 const updateTeleports = (instance.ut = (vars = getter(instance.proxy)) => { 10147 Array.from(document.querySelectorAll(`[data-v-owner="${instance.uid}"]`)).forEach(node => setVarsOnNode(node, vars)); 10148 }); 10149 const setVars = () => { 10150 const vars = getter(instance.proxy); 10151 setVarsOnVNode(instance.subTree, vars); 10152 updateTeleports(vars); 10153 }; 10154 watchPostEffect(setVars); 10155 onMounted(() => { 10156 const ob = new MutationObserver(setVars); 10157 ob.observe(instance.subTree.el.parentNode, { childList: true }); 10158 onUnmounted(() => ob.disconnect()); 10159 }); 10160 } 10161 function setVarsOnVNode(vnode, vars) { 10162 if (vnode.shapeFlag & 128 /* ShapeFlags.SUSPENSE */) { 10163 const suspense = vnode.suspense; 10164 vnode = suspense.activeBranch; 10165 if (suspense.pendingBranch && !suspense.isHydrating) { 10166 suspense.effects.push(() => { 10167 setVarsOnVNode(suspense.activeBranch, vars); 10168 }); 10169 } 10170 } 10171 // drill down HOCs until it's a non-component vnode 10172 while (vnode.component) { 10173 vnode = vnode.component.subTree; 10174 } 10175 if (vnode.shapeFlag & 1 /* ShapeFlags.ELEMENT */ && vnode.el) { 10176 setVarsOnNode(vnode.el, vars); 10177 } 10178 else if (vnode.type === Fragment) { 10179 vnode.children.forEach(c => setVarsOnVNode(c, vars)); 10180 } 10181 else if (vnode.type === Static) { 10182 let { el, anchor } = vnode; 10183 while (el) { 10184 setVarsOnNode(el, vars); 10185 if (el === anchor) 10186 break; 10187 el = el.nextSibling; 10188 } 10189 } 10190 } 10191 function setVarsOnNode(el, vars) { 10192 if (el.nodeType === 1) { 10193 const style = el.style; 10194 for (const key in vars) { 10195 style.setProperty(`--${key}`, vars[key]); 10196 } 10197 } 10198 } 10199 10200 const TRANSITION$1 = 'transition'; 10201 const ANIMATION = 'animation'; 10202 // DOM Transition is a higher-order-component based on the platform-agnostic 10203 // base Transition component, with DOM-specific logic. 10204 const Transition = (props, { slots }) => h(BaseTransition, resolveTransitionProps(props), slots); 10205 Transition.displayName = 'Transition'; 10206 const DOMTransitionPropsValidators = { 10207 name: String, 10208 type: String, 10209 css: { 10210 type: Boolean, 10211 default: true 10212 }, 10213 duration: [String, Number, Object], 10214 enterFromClass: String, 10215 enterActiveClass: String, 10216 enterToClass: String, 10217 appearFromClass: String, 10218 appearActiveClass: String, 10219 appearToClass: String, 10220 leaveFromClass: String, 10221 leaveActiveClass: String, 10222 leaveToClass: String 10223 }; 10224 const TransitionPropsValidators = (Transition.props = 10225 /*#__PURE__*/ extend({}, BaseTransition.props, DOMTransitionPropsValidators)); 10226 /** 10227 * #3227 Incoming hooks may be merged into arrays when wrapping Transition 10228 * with custom HOCs. 10229 */ 10230 const callHook = (hook, args = []) => { 10231 if (isArray(hook)) { 10232 hook.forEach(h => h(...args)); 10233 } 10234 else if (hook) { 10235 hook(...args); 10236 } 10237 }; 10238 /** 10239 * Check if a hook expects a callback (2nd arg), which means the user 10240 * intends to explicitly control the end of the transition. 10241 */ 10242 const hasExplicitCallback = (hook) => { 10243 return hook 10244 ? isArray(hook) 10245 ? hook.some(h => h.length > 1) 10246 : hook.length > 1 10247 : false;
vendor: 4,215 bytes, lines 10248-10344
10248 }; 10249 function resolveTransitionProps(rawProps) { 10250 const baseProps = {}; 10251 for (const key in rawProps) { 10252 if (!(key in DOMTransitionPropsValidators)) { 10253 baseProps[key] = rawProps[key]; 10254 } 10255 } 10256 if (rawProps.css === false) { 10257 return baseProps; 10258 } 10259 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; 10260 const durations = normalizeDuration(duration); 10261 const enterDuration = durations && durations[0]; 10262 const leaveDuration = durations && durations[1]; 10263 const { onBeforeEnter, onEnter, onEnterCancelled, onLeave, onLeaveCancelled, onBeforeAppear = onBeforeEnter, onAppear = onEnter, onAppearCancelled = onEnterCancelled } = baseProps; 10264 const finishEnter = (el, isAppear, done) => { 10265 removeTransitionClass(el, isAppear ? appearToClass : enterToClass); 10266 removeTransitionClass(el, isAppear ? appearActiveClass : enterActiveClass); 10267 done && done(); 10268 }; 10269 const finishLeave = (el, done) => { 10270 el._isLeaving = false; 10271 removeTransitionClass(el, leaveFromClass); 10272 removeTransitionClass(el, leaveToClass); 10273 removeTransitionClass(el, leaveActiveClass); 10274 done && done(); 10275 }; 10276 const makeEnterHook = (isAppear) => { 10277 return (el, done) => { 10278 const hook = isAppear ? onAppear : onEnter; 10279 const resolve = () => finishEnter(el, isAppear, done); 10280 callHook(hook, [el, resolve]); 10281 nextFrame(() => { 10282 removeTransitionClass(el, isAppear ? appearFromClass : enterFromClass); 10283 addTransitionClass(el, isAppear ? appearToClass : enterToClass); 10284 if (!hasExplicitCallback(hook)) { 10285 whenTransitionEnds(el, type, enterDuration, resolve); 10286 } 10287 }); 10288 }; 10289 }; 10290 return extend(baseProps, { 10291 onBeforeEnter(el) { 10292 callHook(onBeforeEnter, [el]); 10293 addTransitionClass(el, enterFromClass); 10294 addTransitionClass(el, enterActiveClass); 10295 }, 10296 onBeforeAppear(el) { 10297 callHook(onBeforeAppear, [el]); 10298 addTransitionClass(el, appearFromClass); 10299 addTransitionClass(el, appearActiveClass); 10300 }, 10301 onEnter: makeEnterHook(false), 10302 onAppear: makeEnterHook(true), 10303 onLeave(el, done) { 10304 el._isLeaving = true; 10305 const resolve = () => finishLeave(el, done); 10306 addTransitionClass(el, leaveFromClass); 10307 // force reflow so *-leave-from classes immediately take effect (#2593) 10308 forceReflow(); 10309 addTransitionClass(el, leaveActiveClass); 10310 nextFrame(() => { 10311 if (!el._isLeaving) { 10312 // cancelled 10313 return; 10314 } 10315 removeTransitionClass(el, leaveFromClass); 10316 addTransitionClass(el, leaveToClass); 10317 if (!hasExplicitCallback(onLeave)) { 10318 whenTransitionEnds(el, type, leaveDuration, resolve); 10319 } 10320 }); 10321 callHook(onLeave, [el, resolve]); 10322 }, 10323 onEnterCancelled(el) { 10324 finishEnter(el, false); 10325 callHook(onEnterCancelled, [el]); 10326 }, 10327 onAppearCancelled(el) { 10328 finishEnter(el, true); 10329 callHook(onAppearCancelled, [el]); 10330 }, 10331 onLeaveCancelled(el) { 10332 finishLeave(el); 10333 callHook(onLeaveCancelled, [el]); 10334 } 10335 }); 10336 } 10337 function normalizeDuration(duration) { 10338 if (duration == null) { 10339 return null; 10340 } 10341 else if (isObject(duration)) { 10342 return [NumberOf(duration.enter), NumberOf(duration.leave)]; 10343 } 10344 else {
10345 const n = NumberOf(duration); 10346 return [n, n]; 10347 } 10348 } 10349 function NumberOf(val) { 10350 const res = toNumber(val); 10351 { 10352 assertNumber(res, '<transition> explicit duration'); 10353 } 10354 return res; 10355 } 10356 function addTransitionClass(el, cls) { 10357 cls.split(/\s+/).forEach(c => c && el.classList.add(c)); 10358 (el._vtc || 10359 (el._vtc = new Set())).add(cls); 10360 } 10361 function removeTransitionClass(el, cls) { 10362 cls.split(/\s+/).forEach(c => c && el.classList.remove(c)); 10363 const { _vtc } = el; 10364 if (_vtc) { 10365 _vtc.delete(cls); 10366 if (!_vtc.size) { 10367 el._vtc = undefined; 10368 } 10369 } 10370 } 10371 function nextFrame(cb) { 10372 requestAnimationFrame(() => { 10373 requestAnimationFrame(cb); 10374 }); 10375 } 10376 let endId = 0; 10377 function whenTransitionEnds(el, expectedType, explicitTimeout, resolve) { 10378 const id = (el._endId = ++endId); 10379 const resolveIfNotStale = () => { 10380 if (id === el._endId) { 10381 resolve(); 10382 } 10383 }; 10384 if (explicitTimeout) { 10385 return setTimeout(resolveIfNotStale, explicitTimeout); 10386 } 10387 const { type, timeout, propCount } = getTransitionInfo(el, expectedType); 10388 if (!type) { 10389 return resolve(); 10390 } 10391 const endEvent = type + 'end'; 10392 let ended = 0; 10393 const end = () => { 10394 el.removeEventListener(endEvent, onEnd); 10395 resolveIfNotStale(); 10396 }; 10397 const onEnd = (e) => { 10398 if (e.target === el && ++ended >= propCount) { 10399 end(); 10400 } 10401 }; 10402 setTimeout(() => { 10403 if (ended < propCount) { 10404 end(); 10405 } 10406 }, timeout + 1); 10407 el.addEventListener(endEvent, onEnd); 10408 } 10409 function getTransitionInfo(el, expectedType) { 10410 const styles = window.getComputedStyle(el); 10411 // JSDOM may return undefined for transition properties 10412 const getStyleProperties = (key) => (styles[key] || '').split(', '); 10413 const transitionDelays = getStyleProperties(`${TRANSITION$1}Delay`); 10414 const transitionDurations = getStyleProperties(`${TRANSITION$1}Duration`); 10415 const transitionTimeout = getTimeout(transitionDelays, transitionDurations); 10416 const animationDelays = getStyleProperties(`${ANIMATION}Delay`); 10417 const animationDurations = getStyleProperties(`${ANIMATION}Duration`); 10418 const animationTimeout = getTimeout(animationDelays, animationDurations); 10419 let type = null; 10420 let timeout = 0; 10421 let propCount = 0; 10422 /* istanbul ignore if */ 10423 if (expectedType === TRANSITION$1) { 10424 if (transitionTimeout > 0) { 10425 type = TRANSITION$1; 10426 timeout = transitionTimeout; 10427 propCount = transitionDurations.length; 10428 } 10429 } 10430 else if (expectedType === ANIMATION) { 10431 if (animationTimeout > 0) { 10432 type = ANIMATION; 10433 timeout = animationTimeout; 10434 propCount = animationDurations.length; 10435 } 10436 } 10437 else { 10438 timeout = Math.max(transitionTimeout, animationTimeout); 10439 type = 10440 timeout > 0 10441 ? transitionTimeout > animationTimeout 10442 ? TRANSITION$1 10443 : ANIMATION 10444 : null; 10445 propCount = type 10446 ? type === TRANSITION$1 10447 ? transitionDurations.length 10448 : animationDurations.length 10449 : 0; 10450 } 10451 const hasTransform = type === TRANSITION$1 && 10452 /\b(transform|all)(,|$)/.test(getStyleProperties(`${TRANSITION$1}Property`).toString()); 10453 return { 10454 type, 10455 timeout, 10456 propCount, 10457 hasTransform 10458 }; 10459 } 10460 function getTimeout(delays, durations) { 10461 while (delays.length < durations.length) { 10462 delays = delays.concat(delays); 10463 } 10464 return Math.max(...durations.map((d, i) => toMs(d) + toMs(delays[i]))); 10465 } 10466 // Old versions of Chromium (below 61.0.3163.100) formats floating pointer 10467 // numbers in a locale-dependent way, using a comma instead of a dot. 10468 // If comma is not replaced with a dot, the input will be rounded down 10469 // (i.e. acting as a floor function) causing unexpected behaviors 10470 function toMs(s) { 10471 return Number(s.slice(0, -1).replace(',', '.')) * 1000; 10472 } 10473 // synchronously force layout to put elements into a certain state 10474 function forceReflow() { 10475 return document.body.offsetHeight; 10476 } 10477 10478 const positionMap = new WeakMap(); 10479 const newPositionMap = new WeakMap(); 10480 const TransitionGroupImpl = { 10481 name: 'TransitionGroup', 10482 props: /*#__PURE__*/ extend({}, TransitionPropsValidators, { 10483 tag: String, 10484 moveClass: String 10485 }), 10486 setup(props, { slots }) { 10487 const instance = getCurrentInstance(); 10488 const state = useTransitionState(); 10489 let prevChildren; 10490 let children; 10491 onUpdated(() => { 10492 // children is guaranteed to exist after initial render 10493 if (!prevChildren.length) { 10494 return; 10495 } 10496 const moveClass = props.moveClass || `${props.name || 'v'}-move`; 10497 if (!hasCSSTransform(prevChildren[0].el, instance.vnode.el, moveClass)) { 10498 return; 10499 } 10500 // we divide the work into three loops to avoid mixing DOM reads and writes 10501 // in each iteration - which helps prevent layout thrashing.
10502 prevChildren.forEach(callPendingCbs); 10503 prevChildren.forEach(recordPosition); 10504 const movedChildren = prevChildren.filter(applyTranslation); 10505 // force reflow to put everything in position 10506 forceReflow(); 10507 movedChildren.forEach(c => { 10508 const el = c.el; 10509 const style = el.style; 10510 addTransitionClass(el, moveClass); 10511 style.transform = style.webkitTransform = style.transitionDuration = ''; 10512 const cb = (el._moveCb = (e) => { 10513 if (e && e.target !== el) { 10514 return; 10515 } 10516 if (!e || /transform$/.test(e.propertyName)) { 10517 el.removeEventListener('transitionend', cb); 10518 el._moveCb = null; 10519 removeTransitionClass(el, moveClass); 10520 } 10521 }); 10522 el.addEventListener('transitionend', cb); 10523 }); 10524 }); 10525 return () => { 10526 const rawProps = toRaw(props); 10527 const cssTransitionProps = resolveTransitionProps(rawProps); 10528 let tag = rawProps.tag || Fragment; 10529 prevChildren = children; 10530 children = slots.default ? getTransitionRawChildren(slots.default()) : []; 10531 for (let i = 0; i < children.length; i++) { 10532 const child = children[i]; 10533 if (child.key != null) { 10534 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance)); 10535 } 10536 else { 10537 warn(`<TransitionGroup> children must be keyed.`); 10538 } 10539 } 10540 if (prevChildren) { 10541 for (let i = 0; i < prevChildren.length; i++) { 10542 const child = prevChildren[i]; 10543 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance)); 10544 positionMap.set(child, child.el.getBoundingClientRect()); 10545 } 10546 } 10547 return createVNode(tag, null, children); 10548 }; 10549 } 10550 }; 10551 /** 10552 * TransitionGroup does not support "mode" so we need to remove it from the 10553 * props declarations, but direct delete operation is considered a side effect 10554 * and will make the entire transition feature non-tree-shakeable, so we do it 10555 * in a function and mark the function's invocation as pure. 10556 */ 10557 const removeMode = (props) => delete props.mode; 10558 /*#__PURE__*/ removeMode(TransitionGroupImpl.props); 10559 const TransitionGroup = TransitionGroupImpl; 10560 function callPendingCbs(c) { 10561 const el = c.el; 10562 if (el._moveCb) { 10563 el._moveCb(); 10564 } 10565 if (el._enterCb) { 10566 el._enterCb(); 10567 } 10568 } 10569 function recordPosition(c) { 10570 newPositionMap.set(c, c.el.getBoundingClientRect()); 10571 } 10572 function applyTranslation(c) { 10573 const oldPos = positionMap.get(c); 10574 const newPos = newPositionMap.get(c); 10575 const dx = oldPos.left - newPos.left; 10576 const dy = oldPos.top - newPos.top; 10577 if (dx || dy) { 10578 const s = c.el.style; 10579 s.transform = s.webkitTransform = `translate(${dx}px,${dy}px)`; 10580 s.transitionDuration = '0s'; 10581 return c; 10582 } 10583 } 10584 function hasCSSTransform(el, root, moveClass) { 10585 // Detect whether an element with the move class applied has 10586 // CSS transitions. Since the element may be inside an entering 10587 // transition at this very moment, we make a clone of it and remove 10588 // all other transition classes applied to ensure only the move class 10589 // is applied. 10590 const clone = el.cloneNode(); 10591 if (el._vtc) { 10592 el._vtc.forEach(cls => { 10593 cls.split(/\s+/).forEach(c => c && clone.classList.remove(c)); 10594 }); 10595 } 10596 moveClass.split(/\s+/).forEach(c => c && clone.classList.add(c)); 10597 clone.style.display = 'none'; 10598 const container = (root.nodeType === 1 ? root : root.parentNode); 10599 container.appendChild(clone); 10600 const { hasTransform } = getTransitionInfo(clone); 10601 container.removeChild(clone); 10602 return hasTransform; 10603 } 10604 10605 const getModelAssigner = (vnode) => { 10606 const fn = vnode.props['onUpdate:modelValue'] || 10607 (false ); 10608 return isArray(fn) ? value => invokeArrayFns(fn, value) : fn; 10609 }; 10610 function onCompositionStart(e) { 10611 e.target.composing = true; 10612 } 10613 function onCompositionEnd(e) { 10614 const target = e.target; 10615 if (target.composing) { 10616 target.composing = false;
10617 target.dispatchEvent(new Event('input')); 10618 } 10619 } 10620 // We are exporting the v-model runtime directly as vnode hooks so that it can 10621 // be tree-shaken in case v-model is never used. 10622 const vModelText = { 10623 created(el, { modifiers: { lazy, trim, number } }, vnode) { 10624 el._assign = getModelAssigner(vnode); 10625 const castToNumber = number || (vnode.props && vnode.props.type === 'number'); 10626 addEventListener(el, lazy ? 'change' : 'input', e => { 10627 if (e.target.composing) 10628 return; 10629 let domValue = el.value; 10630 if (trim) { 10631 domValue = domValue.trim(); 10632 } 10633 if (castToNumber) { 10634 domValue = looseToNumber(domValue); 10635 } 10636 el._assign(domValue); 10637 }); 10638 if (trim) { 10639 addEventListener(el, 'change', () => { 10640 el.value = el.value.trim(); 10641 }); 10642 } 10643 if (!lazy) { 10644 addEventListener(el, 'compositionstart', onCompositionStart); 10645 addEventListener(el, 'compositionend', onCompositionEnd); 10646 // Safari < 10.2 & UIWebView doesn't fire compositionend when 10647 // switching focus before confirming composition choice 10648 // this also fixes the issue where some browsers e.g. iOS Chrome 10649 // fires "change" instead of "input" on autocomplete. 10650 addEventListener(el, 'change', onCompositionEnd); 10651 } 10652 }, 10653 // set value on mounted so it's after min/max for type="range" 10654 mounted(el, { value }) { 10655 el.value = value == null ? '' : value; 10656 }, 10657 beforeUpdate(el, { value, modifiers: { lazy, trim, number } }, vnode) { 10658 el._assign = getModelAssigner(vnode); 10659 // avoid clearing unresolved text. #2302 10660 if (el.composing) 10661 return; 10662 if (document.activeElement === el && el.type !== 'range') { 10663 if (lazy) { 10664 return; 10665 } 10666 if (trim && el.value.trim() === value) { 10667 return; 10668 } 10669 if ((number || el.type === 'number') && 10670 looseToNumber(el.value) === value) { 10671 return; 10672 } 10673 } 10674 const newValue = value == null ? '' : value; 10675 if (el.value !== newValue) { 10676 el.value = newValue; 10677 } 10678 } 10679 }; 10680 const vModelCheckbox = { 10681 // #4096 array checkboxes need to be deep traversed 10682 deep: true, 10683 created(el, _, vnode) { 10684 el._assign = getModelAssigner(vnode); 10685 addEventListener(el, 'change', () => { 10686 const modelValue = el._modelValue; 10687 const elementValue = getValue(el); 10688 const checked = el.checked; 10689 const assign = el._assign; 10690 if (isArray(modelValue)) { 10691 const index = looseIndexOf(modelValue, elementValue); 10692 const found = index !== -1; 10693 if (checked && !found) { 10694 assign(modelValue.concat(elementValue)); 10695 } 10696 else if (!checked && found) { 10697 const filtered = [...modelValue]; 10698 filtered.splice(index, 1); 10699 assign(filtered); 10700 } 10701 } 10702 else if (isSet(modelValue)) { 10703 const cloned = new Set(modelValue); 10704 if (checked) { 10705 cloned.add(elementValue); 10706 } 10707 else { 10708 cloned.delete(elementValue); 10709 } 10710 assign(cloned); 10711 } 10712 else { 10713 assign(getCheckboxValue(el, checked)); 10714 } 10715 }); 10716 }, 10717 // set initial checked on mount to wait for true-value/false-value 10718 mounted: setChecked, 10719 beforeUpdate(el, binding, vnode) { 10720 el._assign = getModelAssigner(vnode); 10721 setChecked(el, binding, vnode); 10722 } 10723 }; 10724 function setChecked(el, { value, oldValue }, vnode) { 10725 el._modelValue = value; 10726 if (isArray(value)) { 10727 el.checked = looseIndexOf(value, vnode.props.value) > -1; 10728 } 10729 else if (isSet(value)) { 10730 el.checked = value.has(vnode.props.value); 10731 } 10732 else if (value !== oldValue) { 10733 el.checked = looseEqual(value, getCheckboxValue(el, true)); 10734 } 10735 } 10736 const vModelRadio = { 10737 created(el, { value }, vnode) { 10738 el.checked = looseEqual(value, vnode.props.value); 10739 el._assign = getModelAssigner(vnode); 10740 addEventListener(el, 'change', () => { 10741 el._assign(getValue(el)); 10742 }); 10743 }, 10744 beforeUpdate(el, { value, oldValue }, vnode) { 10745 el._assign = getModelAssigner(vnode); 10746 if (value !== oldValue) { 10747 el.checked = looseEqual(value, vnode.props.value); 10748 } 10749 } 10750 }; 10751 const vModelSelect = { 10752 // <select multiple> value need to be deep traversed 10753 deep: true, 10754 created(el, { value, modifiers: { number } }, vnode) { 10755 const isSetModel = isSet(value); 10756 addEventListener(el, 'change', () => { 10757 const selectedVal = Array.prototype.filter 10758 .call(el.options, (o) => o.selected) 10759 .map((o) => number ? looseToNumber(getValue(o)) : getValue(o)); 10760 el._assign(el.multiple 10761 ? isSetModel 10762 ? new Set(selectedVal) 10763 : selectedVal 10764 : selectedVal[0]); 10765 }); 10766 el._assign = getModelAssigner(vnode); 10767 }, 10768 // set value in mounted & updated because <select> relies on its children 10769 // <option>s. 10770 mounted(el, { value }) { 10771 setSelected(el, value); 10772 }, 10773 beforeUpdate(el, _binding, vnode) { 10774 el._assign = getModelAssigner(vnode); 10775 }, 10776 updated(el, { value }) { 10777 setSelected(el, value); 10778 } 10779 }; 10780 function setSelected(el, value) { 10781 const isMultiple = el.multiple; 10782 if (isMultiple && !isArray(value) && !isSet(value)) { 10783 warn(`<select multiple v-model> expects an Array or Set value for its binding, ` + 10784 `but got ${Object.prototype.toString.call(value).slice(8, -1)}.`); 10785 return; 10786 } 10787 for (let i = 0, l = el.options.length; i < l; i++) { 10788 const option = el.options[i]; 10789 const optionValue = getValue(option); 10790 if (isMultiple) { 10791 if (isArray(value)) { 10792 option.selected = looseIndexOf(value, optionValue) > -1; 10793 } 10794 else { 10795 option.selected = value.has(optionValue); 10796 } 10797 } 10798 else { 10799 if (looseEqual(getValue(option), value)) { 10800 if (el.selectedIndex !== i) 10801 el.selectedIndex = i; 10802 return; 10803 } 10804 } 10805 } 10806 if (!isMultiple && el.selectedIndex !== -1) { 10807 el.selectedIndex = -1; 10808 } 10809 } 10810 // retrieve raw value set via :value bindings 10811 function getValue(el) { 10812 return '_value' in el ? el._value : el.value; 10813 } 10814 // retrieve raw value for true-value and false-value set via :true-value or :false-value bindings 10815 function getCheckboxValue(el, checked) {
10816 const key = checked ? '_trueValue' : '_falseValue'; 10817 return key in el ? el[key] : checked; 10818 } 10819 const vModelDynamic = { 10820 created(el, binding, vnode) { 10821 callModelHook(el, binding, vnode, null, 'created'); 10822 }, 10823 mounted(el, binding, vnode) { 10824 callModelHook(el, binding, vnode, null, 'mounted'); 10825 }, 10826 beforeUpdate(el, binding, vnode, prevVNode) { 10827 callModelHook(el, binding, vnode, prevVNode, 'beforeUpdate'); 10828 }, 10829 updated(el, binding, vnode, prevVNode) { 10830 callModelHook(el, binding, vnode, prevVNode, 'updated'); 10831 } 10832 }; 10833 function resolveDynamicModel(tagName, type) { 10834 switch (tagName) { 10835 case 'SELECT': 10836 return vModelSelect; 10837 case 'TEXTAREA': 10838 return vModelText; 10839 default: 10840 switch (type) { 10841 case 'checkbox': 10842 return vModelCheckbox; 10843 case 'radio': 10844 return vModelRadio; 10845 default: 10846 return vModelText; 10847 } 10848 } 10849 } 10850 function callModelHook(el, binding, vnode, prevVNode, hook) { 10851 const modelToUse = resolveDynamicModel(el.tagName, vnode.props && vnode.props.type); 10852 const fn = modelToUse[hook]; 10853 fn && fn(el, binding, vnode, prevVNode); 10854 } 10855 10856 const systemModifiers = ['ctrl', 'shift', 'alt', 'meta']; 10857 const modifierGuards = { 10858 stop: e => e.stopPropagation(), 10859 prevent: e => e.preventDefault(), 10860 self: e => e.target !== e.currentTarget, 10861 ctrl: e => !e.ctrlKey, 10862 shift: e => !e.shiftKey, 10863 alt: e => !e.altKey, 10864 meta: e => !e.metaKey, 10865 left: e => 'button' in e && e.button !== 0, 10866 middle: e => 'button' in e && e.button !== 1, 10867 right: e => 'button' in e && e.button !== 2, 10868 exact: (e, modifiers) => systemModifiers.some(m => e[`${m}Key`] && !modifiers.includes(m)) 10869 }; 10870 /** 10871 * @private 10872 */ 10873 const withModifiers = (fn, modifiers) => { 10874 return (event, ...args) => { 10875 for (let i = 0; i < modifiers.length; i++) { 10876 const guard = modifierGuards[modifiers[i]]; 10877 if (guard && guard(event, modifiers)) 10878 return; 10879 } 10880 return fn(event, ...args); 10881 }; 10882 }; 10883 // Kept for 2.x compat. 10884 // Note: IE11 compat for `spacebar` and `del` is removed for now. 10885 const keyNames = { 10886 esc: 'escape', 10887 space: ' ', 10888 up: 'arrow-up', 10889 left: 'arrow-left', 10890 right: 'arrow-right', 10891 down: 'arrow-down', 10892 delete: 'backspace' 10893 }; 10894 /** 10895 * @private 10896 */ 10897 const withKeys = (fn, modifiers) => { 10898 return (event) => { 10899 if (!('key' in event)) { 10900 return; 10901 } 10902 const eventKey = hyphenate(event.key); 10903 if (modifiers.some(k => k === eventKey || keyNames[k] === eventKey)) { 10904 return fn(event); 10905 } 10906 }; 10907 }; 10908 10909 const vShow = { 10910 beforeMount(el, { value }, { transition }) { 10911 el._vod = el.style.display === 'none' ? '' : el.style.display; 10912 if (transition && value) { 10913 transition.beforeEnter(el); 10914 } 10915 else { 10916 setDisplay(el, value); 10917 } 10918 }, 10919 mounted(el, { value }, { transition }) { 10920 if (transition && value) { 10921 transition.enter(el); 10922 } 10923 }, 10924 updated(el, { value, oldValue }, { transition }) { 10925 if (!value === !oldValue) 10926 return; 10927 if (transition) { 10928 if (value) { 10929 transition.beforeEnter(el); 10930 setDisplay(el, true); 10931 transition.enter(el); 10932 } 10933 else { 10934 transition.leave(el, () => { 10935 setDisplay(el, false); 10936 }); 10937 } 10938 } 10939 else { 10940 setDisplay(el, value); 10941 } 10942 }, 10943 beforeUnmount(el, { value }) { 10944 setDisplay(el, value); 10945 } 10946 }; 10947 function setDisplay(el, value) { 10948 el.style.display = value ? el._vod : 'none'; 10949 } 10950 10951 const rendererOptions = /*#__PURE__*/ extend({ patchProp }, nodeOps); 10952 // lazy create the renderer - this makes core renderer logic tree-shakable 10953 // in case the user only imports reactivity utilities from Vue. 10954 let renderer; 10955 let enabledHydration = false;
10956 function ensureRenderer() { 10957 return (renderer || 10958 (renderer = createRenderer(rendererOptions))); 10959 } 10960 function ensureHydrationRenderer() { 10961 renderer = enabledHydration 10962 ? renderer 10963 : createHydrationRenderer(rendererOptions); 10964 enabledHydration = true; 10965 return renderer; 10966 } 10967 // use explicit type casts here to avoid import() calls in rolled-up d.ts 10968 const render = ((...args) => { 10969 ensureRenderer().render(...args); 10970 }); 10971 const hydrate = ((...args) => { 10972 ensureHydrationRenderer().hydrate(...args); 10973 }); 10974 const createApp = ((...args) => { 10975 const app = ensureRenderer().createApp(...args); 10976 { 10977 injectNativeTagCheck(app); 10978 injectCompilerOptionsCheck(app); 10979 } 10980 const { mount } = app; 10981 app.mount = (containerOrSelector) => { 10982 const container = normalizeContainer(containerOrSelector); 10983 if (!container) 10984 return; 10985 const component = app._component; 10986 if (!isFunction(component) && !component.render && !component.template) { 10987 // __UNSAFE__ 10988 // Reason: potential execution of JS expressions in in-DOM template. 10989 // The user must make sure the in-DOM template is trusted. If it's 10990 // rendered by the server, the template should not contain any user data. 10991 component.template = container.innerHTML; 10992 } 10993 // clear content before mounting 10994 container.innerHTML = ''; 10995 const proxy = mount(container, false, container instanceof SVGElement); 10996 if (container instanceof Element) { 10997 container.removeAttribute('v-cloak'); 10998 container.setAttribute('data-v-app', ''); 10999 } 11000 return proxy; 11001 }; 11002 return app; 11003 }); 11004 const createSSRApp = ((...args) => { 11005 const app = ensureHydrationRenderer().createApp(...args); 11006 { 11007 injectNativeTagCheck(app); 11008 injectCompilerOptionsCheck(app); 11009 } 11010 const { mount } = app; 11011 app.mount = (containerOrSelector) => { 11012 const container = normalizeContainer(containerOrSelector); 11013 if (container) { 11014 return mount(container, true, container instanceof SVGElement); 11015 } 11016 }; 11017 return app; 11018 }); 11019 function injectNativeTagCheck(app) { 11020 // Inject `isNativeTag` 11021 // this is used for component name validation (dev only) 11022 Object.defineProperty(app.config, 'isNativeTag', { 11023 value: (tag) => isHTMLTag(tag) || isSVGTag(tag), 11024 writable: false 11025 }); 11026 } 11027 // dev only 11028 function injectCompilerOptionsCheck(app) { 11029 if (isRuntimeOnly()) { 11030 const isCustomElement = app.config.isCustomElement; 11031 Object.defineProperty(app.config, 'isCustomElement', { 11032 get() { 11033 return isCustomElement; 11034 }, 11035 set() { 11036 warn(`The \`isCustomElement\` config option is deprecated. Use ` + 11037 `\`compilerOptions.isCustomElement\` instead.`); 11038 } 11039 }); 11040 const compilerOptions = app.config.compilerOptions; 11041 const msg = `The \`compilerOptions\` config option is only respected when using ` + 11042 `a build of Vue.js that includes the runtime compiler (aka "full build"). ` + 11043 `Since you are using the runtime-only build, \`compilerOptions\` ` + 11044 `must be passed to \`@vue/compiler-dom\` in the build setup instead.\n` + 11045 `- For vue-loader: pass it via vue-loader's \`compilerOptions\` loader option.\n` + 11046 `- For vue-cli: see https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-loader\n` + 11047 `- For vite: pass it via @vitejs/plugin-vue options. See https://github.com/vitejs/vite/tree/main/packages/plugin-vue#example-for-passing-options-to-vuecompiler-dom`; 11048 Object.defineProperty(app.config, 'compilerOptions', { 11049 get() { 11050 warn(msg); 11051 return compilerOptions; 11052 }, 11053 set() { 11054 warn(msg); 11055 } 11056 }); 11057 } 11058 } 11059 function normalizeContainer(container) { 11060 if (isString(container)) { 11061 const res = document.querySelector(container); 11062 if (!res) { 11063 warn(`Failed to mount app: mount target selector "${container}" returned null.`); 11064 } 11065 return res; 11066 } 11067 if (window.ShadowRoot && 11068 container instanceof window.ShadowRoot && 11069 container.mode === 'closed') { 11070 warn(`mounting on a ShadowRoot with \`{mode: "closed"}\` may lead to unpredictable bugs`); 11071 } 11072 return container; 11073 } 11074 /** 11075 * @internal 11076 */ 11077 const initDirectivesForSSR = NOOP; 11078 11079 function initDev() { 11080 { 11081 /* istanbul ignore if */ 11082 { 11083 console.info(`You are running a development build of Vue.\n` + 11084 `Make sure to use the production build (*.prod.js) when deploying for production.`); 11085 } 11086 initCustomFormatter(); 11087 } 11088 } 11089 11090 function defaultOnError(error) { 11091 throw error; 11092 } 11093 function defaultOnWarn(msg) { 11094 console.warn(`[Vue warn] ${msg.message}`); 11095 } 11096 function createCompilerError(code, loc, messages, additionalMe
11096ssage) { 11097 const msg = (messages || errorMessages)[code] + (additionalMessage || ``) 11098 ; 11099 const error = new SyntaxError(String(msg)); 11100 error.code = code; 11101 error.loc = loc; 11102 return error; 11103 } 11104 const errorMessages = { 11105 // parse errors 11106 [0 /* ErrorCodes.ABRUPT_CLOSING_OF_EMPTY_COMMENT */]: 'Illegal comment.', 11107 [1 /* ErrorCodes.CDATA_IN_HTML_CONTENT */]: 'CDATA section is allowed only in XML context.', 11108 [2 /* ErrorCodes.DUPLICATE_ATTRIBUTE */]: 'Duplicate attribute.', 11109 [3 /* ErrorCodes.END_TAG_WITH_ATTRIBUTES */]: 'End tag cannot have attributes.', 11110 [4 /* ErrorCodes.END_TAG_WITH_TRAILING_SOLIDUS */]: "Illegal '/' in tags.", 11111 [5 /* ErrorCodes.EOF_BEFORE_TAG_NAME */]: 'Unexpected EOF in tag.', 11112 [6 /* ErrorCodes.EOF_IN_CDATA */]: 'Unexpected EOF in CDATA section.', 11113 [7 /* ErrorCodes.EOF_IN_COMMENT */]: 'Unexpected EOF in comment.', 11114 [8 /* ErrorCodes.EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */]: 'Unexpected EOF in script.', 11115 [9 /* ErrorCodes.EOF_IN_TAG */]: 'Unexpected EOF in tag.', 11116 [10 /* ErrorCodes.INCORRECTLY_CLOSED_COMMENT */]: 'Incorrectly closed comment.', 11117 [11 /* ErrorCodes.INCORRECTLY_OPENED_COMMENT */]: 'Incorrectly opened comment.', 11118 [12 /* ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME */]: "Illegal tag name. Use '<' to print '<'.", 11119 [13 /* ErrorCodes.MISSING_ATTRIBUTE_VALUE */]: 'Attribute value was expected.', 11120 [14 /* ErrorCodes.MISSING_END_TAG_NAME */]: 'End tag name was expected.', 11121 [15 /* ErrorCodes.MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */]: 'Whitespace was expected.', 11122 [16 /* ErrorCodes.NESTED_COMMENT */]: "Unexpected '<!--' in comment.", 11123 [17 /* ErrorCodes.UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */]: 'Attribute name cannot contain U+0022 ("), U+0027 (\'), and U+003C (<).', 11124 [18 /* ErrorCodes.UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */]: 'Unquoted attribute value cannot contain U+0022 ("), U+0027 (\'), U+003C (<), U+003D (=), and U+0060 (`).', 11125 [19 /* ErrorCodes.UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */]: "Attribute name cannot start with '='.", 11126 [21 /* ErrorCodes.UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */]: "'<?' is allowed only in XML context.", 11127 [20 /* ErrorCodes.UNEXPECTED_NULL_CHARACTER */]: `Unexpected null character.`, 11128 [22 /* ErrorCodes.UNEXPECTED_SOLIDUS_IN_TAG */]: "Illegal '/' in tags.", 11129 // Vue-specific parse errors 11130 [23 /* ErrorCodes.X_INVALID_END_TAG */]: 'Invalid end tag.', 11131 [24 /* ErrorCodes.X_MISSING_END_TAG */]: 'Element is missing end tag.', 11132 [25 /* ErrorCodes.X_MISSING_INTERPOLATION_END */]: 'Interpolation end sign was not found.', 11133 [27 /* ErrorCodes.X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */]: 'End bracket for dynamic directive argument was not found. ' + 11134 'Note that dynamic directive argument cannot contain spaces.', 11135 [26 /* ErrorCodes.X_MISSING_DIRECTIVE_NAME */]: 'Legal directive name was expected.', 11136 // transform errors 11137 [28 /* ErrorCodes.X_V_IF_NO_EXPRESSION */]: `v-if/v-else-if is missing expression.`, 11138 [29 /* ErrorCodes.X_V_IF_SAME_KEY */]: `v-if/else branches must use unique keys.`, 11139 [30 /* ErrorCodes.X_V_ELSE_NO_ADJACENT_IF */]: `v-else/v-else-if has no adjacent v-if or v-else-if.`, 11140 [31 /* ErrorCodes.X_V_FOR_NO_EXPRESSION */]: `v-for is missing expression.`, 11141 [32 /* ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION */]: `v-for has invalid expression.`, 11142 [33 /* ErrorCodes.X_V_FOR_TEMPLATE_KEY_PLACEMENT */]: `<template v-for> key should be placed on the <template> tag.`, 11143 [34 /* ErrorCodes.X_V_BIND_NO_EXPRESSION */]: `v-bind is missing expression.`, 11144 [35 /* ErrorCodes.X_V_ON_NO_EXPRESSION */]: `v-on is missing expression.`, 11145 [36 /* ErrorCodes.X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */]: `Unexpected custom directive on <slot> outlet.`, 11146 [37 /* ErrorCodes.X_V_SLOT_MIXED_SLOT_USAGE */]: `Mixed v-slot usage on both the component and nested <template>. ` + 11147 `When there are multiple named slots, all slots should use <template> ` + 11148 `syntax to avoid scope ambiguity.`, 11149 [38 /* ErrorCodes.X_V_SLOT_DUPLICATE_SLOT_NAMES */]: `Duplicate slot names found. `, 11150 [39 /* ErrorCodes.X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */]: `Extraneous children found when component already has explicitly named ` +
11151 `default slot. These children will be ignored.`, 11152 [40 /* ErrorCodes.X_V_SLOT_MISPLACED */]: `v-slot can only be used on components or <template> tags.`, 11153 [41 /* ErrorCodes.X_V_MODEL_NO_EXPRESSION */]: `v-model is missing expression.`, 11154 [42 /* ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION */]: `v-model value must be a valid JavaScript member expression.`, 11155 [43 /* ErrorCodes.X_V_MODEL_ON_SCOPE_VARIABLE */]: `v-model cannot be used on v-for or v-slot scope variables because they are not writable.`, 11156 [44 /* ErrorCodes.X_V_MODEL_ON_PROPS */]: `v-model cannot be used on a prop, because local prop bindings are not writable.\nUse a v-bind binding combined with a v-on listener that emits update:x event instead.`, 11157 [45 /* ErrorCodes.X_INVALID_EXPRESSION */]: `Error parsing JavaScript expression: `, 11158 [46 /* ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN */]: `<KeepAlive> expects exactly one child component.`, 11159 // generic errors 11160 [47 /* ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED */]: `"prefixIdentifiers" option is not supported in this build of compiler.`, 11161 [48 /* ErrorCodes.X_MODULE_MODE_NOT_SUPPORTED */]: `ES module mode is not supported in this build of compiler.`, 11162 [49 /* ErrorCodes.X_CACHE_HANDLER_NOT_SUPPORTED */]: `"cacheHandlers" option is only supported when the "prefixIdentifiers" option is enabled.`, 11163 [50 /* ErrorCodes.X_SCOPE_ID_NOT_SUPPORTED */]: `"scopeId" option is only supported in module mode.`, 11164 // just to fulfill types 11165 [51 /* ErrorCodes.__EXTEND_POINT__ */]: `` 11166 }; 11167 11168 const FRAGMENT = Symbol(`Fragment` ); 11169 const TELEPORT = Symbol(`Teleport` ); 11170 const SUSPENSE = Symbol(`Suspense` ); 11171 const KEEP_ALIVE = Symbol(`KeepAlive` ); 11172 const BASE_TRANSITION = Symbol(`BaseTransition` ); 11173 const OPEN_BLOCK = Symbol(`openBlock` ); 11174 const CREATE_BLOCK = Symbol(`createBlock` ); 11175 const CREATE_ELEMENT_BLOCK = Symbol(`createElementBlock` ); 11176 const CREATE_VNODE = Symbol(`createVNode` ); 11177 const CREATE_ELEMENT_VNODE = Symbol(`createElementVNode` ); 11178 const CREATE_COMMENT = Symbol(`createCommentVNode` ); 11179 const CREATE_TEXT = Symbol(`createTextVNode` ); 11180 const CREATE_STATIC = Symbol(`createStaticVNode` ); 11181 const RESOLVE_COMPONENT = Symbol(`resolveComponent` ); 11182 const RESOLVE_DYNAMIC_COMPONENT = Symbol(`resolveDynamicComponent` ); 11183 const RESOLVE_DIRECTIVE = Symbol(`resolveDirective` ); 11184 const RESOLVE_FILTER = Symbol(`resolveFilter` ); 11185 const WITH_DIRECTIVES = Symbol(`withDirectives` ); 11186 const RENDER_LIST = Symbol(`renderList` ); 11187 const RENDER_SLOT = Symbol(`renderSlot` ); 11188 const CREATE_SLOTS = Symbol(`createSlots` ); 11189 const TO_DISPLAY_STRING = Symbol(`toDisplayString` ); 11190 const MERGE_PROPS = Symbol(`mergeProps` ); 11191 const NORMALIZE_CLASS = Symbol(`normalizeClass` ); 11192 const NORMALIZE_STYLE = Symbol(`normalizeStyle` ); 11193 const NORMALIZE_PROPS = Symbol(`normalizeProps` ); 11194 const GUARD_REACTIVE_PROPS = Symbol(`guardReactiveProps` ); 11195 const TO_HANDLERS = Symbol(`toHandlers` ); 11196 const CAMELIZE = Symbol(`camelize` ); 11197 const CAPITALIZE = Symbol(`capitalize` ); 11198 const TO_HANDLER_KEY = Symbol(`toHandlerKey` ); 11199 const SET_BLOCK_TRACKING = Symbol(`setBlockTracking` ); 11200 const PUSH_SCOPE_ID = Symbol(`pushScopeId` ); 11201 const POP_SCOPE_ID = Symbol(`popScopeId` ); 11202 const WITH_CTX = Symbol(`withCtx` ); 11203 const UNREF = Symbol(`unref` ); 11204 const IS_REF = Symbol(`isRef` ); 11205 const WITH_MEMO = Symbol(`withMemo` ); 11206 const IS_MEMO_SAME = Symbol(`isMemoSame` ); 11207 // Name mapping for runtime helpers that need to be imported from 'vue' in 11208 // generated code. Make sure these are correctly exported in the runtime! 11209 const helperNameMap = { 11210 [FRAGMENT]: `Fragment`, 11211 [TELEPORT]: `Teleport`, 11212 [SUSPENSE]: `Suspense`, 11213 [KEEP_ALIVE]: `KeepAlive`, 11214 [BASE_TRANSITION]: `BaseTransition`, 11215 [OPEN_BLOCK]: `openBlock`, 11216 [CREATE_BLOCK]: `createBlock`, 11217 [CREATE_ELEMENT_BLOCK]: `createElementBlock`, 11218 [CREATE_VNODE]: `createVNode`, 11219 [CREATE_ELEMENT_VNODE]: `createElementVNode`, 11220 [CREATE_COMMENT]: `createCommentVNode`, 11221 [CREATE_TEXT]: `createTextVNode`, 11222 [CREATE_STATIC]: `createStaticVNode`, 11223 [RESOLVE_COMPONENT]: `resolveComponent`, 11224 [RESOLVE_DYNAMIC_COMPONENT]: `resolveDynamicComponent`, 11225 [RESOLVE_DIRECTIVE]: `resolveDirective`, 11226 [RESOLVE_FILTER]: `resolveFilter`, 11227 [WITH_DIRECTIVES]: `withDirectives`, 11228 [RENDER_LIST]: `renderList`, 11229 [RENDER_SLOT]: `renderSlot`, 11230 [CREATE_SLOTS]: `createSlots`, 11231 [TO_DISPLAY_STRING]: `toDisplayString`, 11232 [MERGE_PROPS]: `mergeProps`, 11233 [NORMALIZE_CLASS]: `normalizeClass`, 11234 [NORMALIZE_STYLE]: `normalizeStyle`, 11235 [NORMALIZE_PROPS]: `normalizeProps`,
11236 [GUARD_REACTIVE_PROPS]: `guardReactiveProps`, 11237 [TO_HANDLERS]: `toHandlers`, 11238 [CAMELIZE]: `camelize`, 11239 [CAPITALIZE]: `capitalize`, 11240 [TO_HANDLER_KEY]: `toHandlerKey`, 11241 [SET_BLOCK_TRACKING]: `setBlockTracking`, 11242 [PUSH_SCOPE_ID]: `pushScopeId`, 11243 [POP_SCOPE_ID]: `popScopeId`, 11244 [WITH_CTX]: `withCtx`, 11245 [UNREF]: `unref`, 11246 [IS_REF]: `isRef`, 11247 [WITH_MEMO]: `withMemo`, 11248 [IS_MEMO_SAME]: `isMemoSame` 11249 }; 11250 function registerRuntimeHelpers(helpers) { 11251 Object.getOwnPropertySymbols(helpers).forEach(s => { 11252 helperNameMap[s] = helpers[s]; 11253 }); 11254 } 11255 11256 // AST Utilities --------------------------------------------------------------- 11257 // Some expressions, e.g. sequence and conditional expressions, are never 11258 // associated with template nodes, so their source locations are just a stub. 11259 // Container types like CompoundExpression also don't need a real location. 11260 const locStub = { 11261 source: '', 11262 start: { line: 1, column: 1, offset: 0 }, 11263 end: { line: 1, column: 1, offset: 0 } 11264 }; 11265 function createRoot(children, loc = locStub) { 11266 return { 11267 type: 0 /* NodeTypes.ROOT */, 11268 children, 11269 helpers: new Set(), 11270 components: [], 11271 directives: [], 11272 hoists: [], 11273 imports: [], 11274 cached: 0, 11275 temps: 0, 11276 codegenNode: undefined, 11277 loc 11278 }; 11279 } 11280 function createVNodeCall(context, tag, props, children, patchFlag, dynamicProps, directives, isBlock = false, disableTracking = false, isComponent = false, loc = locStub) { 11281 if (context) { 11282 if (isBlock) { 11283 context.helper(OPEN_BLOCK); 11284 context.helper(getVNodeBlockHelper(context.inSSR, isComponent)); 11285 } 11286 else { 11287 context.helper(getVNodeHelper(context.inSSR, isComponent)); 11288 } 11289 if (directives) { 11290 context.helper(WITH_DIRECTIVES); 11291 } 11292 } 11293 return { 11294 type: 13 /* NodeTypes.VNODE_CALL */, 11295 tag, 11296 props, 11297 children, 11298 patchFlag, 11299 dynamicProps, 11300 directives, 11301 isBlock, 11302 disableTracking, 11303 isComponent, 11304 loc 11305 }; 11306 } 11307 function createArrayExpression(elements, loc = locStub) { 11308 return { 11309 type: 17 /* NodeTypes.JS_ARRAY_EXPRESSION */, 11310 loc, 11311 elements 11312 }; 11313 } 11314 function createObjectExpression(properties, loc = locStub) { 11315 return { 11316 type: 15 /* NodeTypes.JS_OBJECT_EXPRESSION */, 11317 loc, 11318 properties 11319 }; 11320 } 11321 function createObjectProperty(key, value) { 11322 return { 11323 type: 16 /* NodeTypes.JS_PROPERTY */, 11324 loc: locStub, 11325 key: isString(key) ? createSimpleExpression(key, true) : key, 11326 value 11327 }; 11328 } 11329 function createSimpleExpression(content, isStatic = false, loc = locStub, constType = 0 /* ConstantTypes.NOT_CONSTANT */) { 11330 return { 11331 type: 4 /* NodeTypes.SIMPLE_EXPRESSION */, 11332 loc, 11333 content, 11334 isStatic, 11335 constType: isStatic ? 3 /* ConstantTypes.CAN_STRINGIFY */ : constType 11336 }; 11337 } 11338 function createCompoundExpression(children, loc = locStub) { 11339 return { 11340 type: 8 /* NodeTypes.COMPOUND_EXPRESSION */, 11341 loc, 11342 children 11343 }; 11344 } 11345 function createCallExpression(callee, args = [], loc = locStub) { 11346 return { 11347 type: 14 /* NodeTypes.JS_CALL_EXPRESSION */, 11348 loc, 11349 callee, 11350 arguments: args 11351 }; 11352 } 11353 function createFunctionExpression(params, returns = undefined, newline = false, isSlot = false, loc = locStub) { 11354 return { 11355 type: 18 /* NodeTypes.JS_FUNCTION_EXPRESSION */, 11356 params, 11357 returns, 11358 newline, 11359 isSlot, 11360 loc 11361 }; 11362 } 11363 function createConditionalExpression(test, consequent, alternate, newline = true) { 11364 return { 11365 type: 19 /* NodeTypes.JS_CONDITIONAL_EXPRESSION */, 11366 test, 11367 consequent, 11368 alternate, 11369 newline, 11370 loc: locStub 11371 }; 11372 } 11373 function createCacheExpression(index, value, isVNode = false) { 11374 return { 11375 type: 20 /* NodeTypes.JS_CACHE_EXPRESSION */, 11376 index, 11377 value, 11378 isVNode, 11379 loc: locStub 11380 }; 11381 }
11382 function createBlockStatement(body) { 11383 return { 11384 type: 21 /* NodeTypes.JS_BLOCK_STATEMENT */, 11385 body, 11386 loc: locStub 11387 }; 11388 } 11389 11390 const isStaticExp = (p) => p.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && p.isStatic; 11391 const isBuiltInType = (tag, expected) => tag === expected || tag === hyphenate(expected); 11392 function isCoreComponent(tag) { 11393 if (isBuiltInType(tag, 'Teleport')) { 11394 return TELEPORT; 11395 } 11396 else if (isBuiltInType(tag, 'Suspense')) { 11397 return SUSPENSE; 11398 } 11399 else if (isBuiltInType(tag, 'KeepAlive')) { 11400 return KEEP_ALIVE; 11401 } 11402 else if (isBuiltInType(tag, 'BaseTransition')) { 11403 return BASE_TRANSITION; 11404 } 11405 } 11406 const nonIdentifierRE = /^\d|[^\$\w]/; 11407 const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name); 11408 const validFirstIdentCharRE = /[A-Za-z_$\xA0-\uFFFF]/; 11409 const validIdentCharRE = /[\.\?\w$\xA0-\uFFFF]/; 11410 const whitespaceRE = /\s+[.[]\s*|\s*[.[]\s+/g; 11411 /** 11412 * Simple lexer to check if an expression is a member expression. This is 11413 * lax and only checks validity at the root level (i.e. does not validate exps 11414 * inside square brackets), but it's ok since these are only used on template 11415 * expressions and false positives are invalid expressions in the first place. 11416 */ 11417 const isMemberExpressionBrowser = (path) => { 11418 // remove whitespaces around . or [ first 11419 path = path.trim().replace(whitespaceRE, s => s.trim()); 11420 let state = 0 /* MemberExpLexState.inMemberExp */; 11421 let stateStack = []; 11422 let currentOpenBracketCount = 0; 11423 let currentOpenParensCount = 0; 11424 let currentStringType = null; 11425 for (let i = 0; i < path.length; i++) { 11426 const char = path.charAt(i); 11427 switch (state) { 11428 case 0 /* MemberExpLexState.inMemberExp */: 11429 if (char === '[') { 11430 stateStack.push(state); 11431 state = 1 /* MemberExpLexState.inBrackets */; 11432 currentOpenBracketCount++; 11433 } 11434 else if (char === '(') { 11435 stateStack.push(state); 11436 state = 2 /* MemberExpLexState.inParens */; 11437 currentOpenParensCount++; 11438 } 11439 else if (!(i === 0 ? validFirstIdentCharRE : validIdentCharRE).test(char)) { 11440 return false; 11441 } 11442 break; 11443 case 1 /* MemberExpLexState.inBrackets */: 11444 if (char === `'` || char === `"` || char === '`') { 11445 stateStack.push(state); 11446 state = 3 /* MemberExpLexState.inString */; 11447 currentStringType = char; 11448 } 11449 else if (char === `[`) { 11450 currentOpenBracketCount++; 11451 } 11452 else if (char === `]`) { 11453 if (!--currentOpenBracketCount) { 11454 state = stateStack.pop(); 11455 } 11456 } 11457 break; 11458 case 2 /* MemberExpLexState.inParens */: 11459 if (char === `'` || char === `"` || char === '`') { 11460 stateStack.push(state); 11461 state = 3 /* MemberExpLexState.inString */; 11462 currentStringType = char; 11463 } 11464 else if (char === `(`) { 11465 currentOpenParensCount++; 11466 } 11467 else if (char === `)`) { 11468 // if the exp ends as a call then it should not be considered valid 11469 if (i === path.length - 1) { 11470 return false; 11471 } 11472 if (!--currentOpenParensCount) { 11473 state = stateStack.pop(); 11474 } 11475 } 11476 break;
vendor: 7,136 bytes, lines 11477-11661
11477 case 3 /* MemberExpLexState.inString */: 11478 if (char === currentStringType) { 11479 state = stateStack.pop(); 11480 currentStringType = null; 11481 } 11482 break; 11483 } 11484 } 11485 return !currentOpenBracketCount && !currentOpenParensCount; 11486 }; 11487 const isMemberExpression = isMemberExpressionBrowser 11488 ; 11489 function getInnerRange(loc, offset, length) { 11490 const source = loc.source.slice(offset, offset + length); 11491 const newLoc = { 11492 source, 11493 start: advancePositionWithClone(loc.start, loc.source, offset), 11494 end: loc.end 11495 }; 11496 if (length != null) { 11497 newLoc.end = advancePositionWithClone(loc.start, loc.source, offset + length); 11498 } 11499 return newLoc; 11500 } 11501 function advancePositionWithClone(pos, source, numberOfCharacters = source.length) { 11502 return advancePositionWithMutation(extend({}, pos), source, numberOfCharacters); 11503 } 11504 // advance by mutation without cloning (for performance reasons), since this 11505 // gets called a lot in the parser 11506 function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) { 11507 let linesCount = 0; 11508 let lastNewLinePos = -1; 11509 for (let i = 0; i < numberOfCharacters; i++) { 11510 if (source.charCodeAt(i) === 10 /* newline char code */) { 11511 linesCount++; 11512 lastNewLinePos = i; 11513 } 11514 } 11515 pos.offset += numberOfCharacters; 11516 pos.line += linesCount; 11517 pos.column = 11518 lastNewLinePos === -1 11519 ? pos.column + numberOfCharacters 11520 : numberOfCharacters - lastNewLinePos; 11521 return pos; 11522 } 11523 function assert(condition, msg) { 11524 /* istanbul ignore if */ 11525 if (!condition) { 11526 throw new Error(msg || `unexpected compiler condition`); 11527 } 11528 } 11529 function findDir(node, name, allowEmpty = false) { 11530 for (let i = 0; i < node.props.length; i++) { 11531 const p = node.props[i]; 11532 if (p.type === 7 /* NodeTypes.DIRECTIVE */ && 11533 (allowEmpty || p.exp) && 11534 (isString(name) ? p.name === name : name.test(p.name))) { 11535 return p; 11536 } 11537 } 11538 } 11539 function findProp(node, name, dynamicOnly = false, allowEmpty = false) { 11540 for (let i = 0; i < node.props.length; i++) { 11541 const p = node.props[i]; 11542 if (p.type === 6 /* NodeTypes.ATTRIBUTE */) { 11543 if (dynamicOnly) 11544 continue; 11545 if (p.name === name && (p.value || allowEmpty)) { 11546 return p; 11547 } 11548 } 11549 else if (p.name === 'bind' && 11550 (p.exp || allowEmpty) && 11551 isStaticArgOf(p.arg, name)) { 11552 return p; 11553 } 11554 } 11555 } 11556 function isStaticArgOf(arg, name) { 11557 return !!(arg && isStaticExp(arg) && arg.content === name); 11558 } 11559 function hasDynamicKeyVBind(node) { 11560 return node.props.some(p => p.type === 7 /* NodeTypes.DIRECTIVE */ && 11561 p.name === 'bind' && 11562 (!p.arg || // v-bind="obj" 11563 p.arg.type !== 4 /* NodeTypes.SIMPLE_EXPRESSION */ || // v-bind:[_ctx.foo] 11564 !p.arg.isStatic) // v-bind:[foo] 11565 ); 11566 } 11567 function isText$1(node) { 11568 return node.type === 5 /* NodeTypes.INTERPOLATION */ || node.type === 2 /* NodeTypes.TEXT */; 11569 } 11570 function isVSlot(p) { 11571 return p.type === 7 /* NodeTypes.DIRECTIVE */ && p.name === 'slot'; 11572 } 11573 function isTemplateNode(node) { 11574 return (node.type === 1 /* NodeTypes.ELEMENT */ && node.tagType === 3 /* ElementTypes.TEMPLATE */); 11575 } 11576 function isSlotOutlet(node) { 11577 return node.type === 1 /* NodeTypes.ELEMENT */ && node.tagType === 2 /* ElementTypes.SLOT */; 11578 } 11579 function getVNodeHelper(ssr, isComponent) { 11580 return ssr || isComponent ? CREATE_VNODE : CREATE_ELEMENT_VNODE; 11581 } 11582 function getVNodeBlockHelper(ssr, isComponent) { 11583 return ssr || isComponent ? CREATE_BLOCK : CREATE_ELEMENT_BLOCK; 11584 } 11585 const propsHelperSet = new Set([NORMALIZE_PROPS, GUARD_REACTIVE_PROPS]); 11586 function getUnnormalizedProps(props, callPath = []) { 11587 if (props && 11588 !isString(props) && 11589 props.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */) { 11590 const callee = props.callee; 11591 if (!isString(callee) && propsHelperSet.has(callee)) { 11592 return getUnnormalizedProps(props.arguments[0], callPath.concat(props)); 11593 } 11594 } 11595 return [props, callPath]; 11596 } 11597 function injectProp(node, prop, context) { 11598 let propsWithInjection; 11599 /** 11600 * 1. mergeProps(...) 11601 * 2. toHandlers(...) 11602 * 3. normalizeProps(...) 11603 * 4. normalizeProps(guardReactiveProps(...)) 11604 * 11605 * we need to get the real props before normalization 11606 */ 11607 let props = node.type === 13 /* NodeTypes.VNODE_CALL */ ? node.props : node.arguments[2]; 11608 let callPath = []; 11609 let parentCall; 11610 if (props && 11611 !isString(props) && 11612 props.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */) { 11613 const ret = getUnnormalizedProps(props); 11614 props = ret[0]; 11615 callPath = ret[1]; 11616 parentCall = callPath[callPath.length - 1]; 11617 } 11618 if (props == null || isString(props)) { 11619 propsWithInjection = createObjectExpression([prop]); 11620 } 11621 else if (props.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */) { 11622 // merged props... add ours 11623 // only inject key to object literal if it's the first argument so that 11624 // if doesn't override user provided keys 11625 const first = props.arguments[0]; 11626 if (!isString(first) && first.type === 15 /* NodeTypes.JS_OBJECT_EXPRESSION */) { 11627 // #6631 11628 if (!hasProp(prop, first)) { 11629 first.properties.unshift(prop); 11630 } 11631 } 11632 else { 11633 if (props.callee === TO_HANDLERS) { 11634 // #2366 11635 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [ 11636 createObjectExpression([prop]), 11637 props 11638 ]); 11639 } 11640 else { 11641 props.arguments.unshift(createObjectExpression([prop])); 11642 } 11643 } 11644 !propsWithInjection && (propsWithInjection = props); 11645 } 11646 else if (props.type === 15 /* NodeTypes.JS_OBJECT_EXPRESSION */) { 11647 if (!hasProp(prop, props)) { 11648 props.properties.unshift(prop); 11649 } 11650 propsWithInjection = props; 11651 } 11652 else { 11653 // single v-bind with expression, return a merged replacement 11654 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [ 11655 createObjectExpression([prop]), 11656 props 11657 ]); 11658 // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(props))`, 11659 // it will be rewritten as `normalizeProps(mergeProps({ key: 0 }, props))`, 11660 // the `guardReactiveProps` will no longer be needed 11661 if (parentCall && parentCall.callee === GUARD_REACTIVE_PROP
11661S) { 11662 parentCall = callPath[callPath.length - 2]; 11663 } 11664 } 11665 if (node.type === 13 /* NodeTypes.VNODE_CALL */) { 11666 if (parentCall) { 11667 parentCall.arguments[0] = propsWithInjection; 11668 } 11669 else { 11670 node.props = propsWithInjection; 11671 } 11672 } 11673 else { 11674 if (parentCall) { 11675 parentCall.arguments[0] = propsWithInjection; 11676 } 11677 else { 11678 node.arguments[2] = propsWithInjection; 11679 } 11680 } 11681 } 11682 // check existing key to avoid overriding user provided keys 11683 function hasProp(prop, props) { 11684 let result = false; 11685 if (prop.key.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) { 11686 const propKeyName = prop.key.content; 11687 result = props.properties.some(p => p.key.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && 11688 p.key.content === propKeyName); 11689 } 11690 return result; 11691 } 11692 function toValidAssetId(name, type) { 11693 // see issue#4422, we need adding identifier on validAssetId if variable `name` has specific character 11694 return `_${type}_${name.replace(/[^\w]/g, (searchValue, replaceValue) => { 11695 return searchValue === '-' ? '_' : name.charCodeAt(replaceValue).toString(); 11696 })}`; 11697 } 11698 function getMemoedVNodeCall(node) { 11699 if (node.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */ && node.callee === WITH_MEMO) { 11700 return node.arguments[1].returns; 11701 } 11702 else { 11703 return node; 11704 } 11705 } 11706 function makeBlock(node, { helper, removeHelper, inSSR }) { 11707 if (!node.isBlock) { 11708 node.isBlock = true; 11709 removeHelper(getVNodeHelper(inSSR, node.isComponent)); 11710 helper(OPEN_BLOCK); 11711 helper(getVNodeBlockHelper(inSSR, node.isComponent)); 11712 } 11713 } 11714 11715 const deprecationData = { 11716 ["COMPILER_IS_ON_ELEMENT" /* CompilerDeprecationTypes.COMPILER_IS_ON_ELEMENT */]: { 11717 message: `Platform-native elements with "is" prop will no longer be ` + 11718 `treated as components in Vue 3 unless the "is" value is explicitly ` + 11719 `prefixed with "vue:".`, 11720 link: `https://v3-migration.vuejs.org/breaking-changes/custom-elements-interop.html` 11721 }, 11722 ["COMPILER_V_BIND_SYNC" /* CompilerDeprecationTypes.COMPILER_V_BIND_SYNC */]: { 11723 message: key => `.sync modifier for v-bind has been removed. Use v-model with ` + 11724 `argument instead. \`v-bind:${key}.sync\` should be changed to ` + 11725 `\`v-model:${key}\`.`, 11726 link: `https://v3-migration.vuejs.org/breaking-changes/v
11726-model.html` 11727 }, 11728 ["COMPILER_V_BIND_PROP" /* CompilerDeprecationTypes.COMPILER_V_BIND_PROP */]: { 11729 message: `.prop modifier for v-bind has been removed and no longer necessary. ` + 11730 `Vue 3 will automatically set a binding as DOM property when appropriate.` 11731 }, 11732 ["COMPILER_V_BIND_OBJECT_ORDER" /* CompilerDeprecationTypes.COMPILER_V_BIND_OBJECT_ORDER */]: { 11733 message: `v-bind="obj" usage is now order sensitive and behaves like JavaScript ` + 11734 `object spread: it will now overwrite an existing non-mergeable attribute ` + 11735 `that appears before v-bind in the case of conflict. ` + 11736 `To retain 2.x behavior, move v-bind to make it the first attribute. ` + 11737 `You can also suppress this warning if the usage is intended.`, 11738 link: `https://v3-migration.vuejs.org/breaking-changes/v-bind.html` 11739 }, 11740 ["COMPILER_V_ON_NATIVE" /* CompilerDeprecationTypes.COMPILER_V_ON_NATIVE */]: { 11741 message: `.native modifier for v-on has been removed as is no longer necessary.`, 11742 link: `https://v3-migration.vuejs.org/breaking-changes/v
11742-on-native-modifier-removed.html` 11743 }, 11744 ["COMPILER_V_IF_V_FOR_PRECEDENCE" /* CompilerDeprecationTypes.COMPILER_V_IF_V_FOR_PRECEDENCE */]: { 11745 message: `v-if / v-for precedence when used on the same element has changed ` + 11746 `in Vue 3: v-if now takes higher precedence and will no longer have ` + 11747 `access to v-for scope variables. It is best to avoid the ambiguity ` + 11748 `with <template> tags or use a computed property that filters v-for ` + 11749 `data source.`, 11750 link: `https://v3-migration.vuejs.org/breaking-changes/v-if-v-for.html` 11751 }, 11752 ["COMPILER_NATIVE_TEMPLATE" /* CompilerDeprecationTypes.COMPILER_NATIVE_TEMPLATE */]: { 11753 message: `<template> with no special directives will render as a native template ` + 11754 `element instead of its inner content in Vue 3.` 11755 }, 11756 ["COMPILER_INLINE_TEMPLATE" /* CompilerDeprecationTypes.COMPILER_INLINE_TEMPLATE */]: { 11757 message: `"inline-template" has been removed in Vue 3.`, 11758 link: `https://v3-migration.vuejs.org/breaking-changes/inline-template-attribute.html` 11759 }, 11760 ["COMPILER_FILTER" /* CompilerDeprecationTypes.COMPILER_FILTERS */]: { 11761 message: `filters have been removed in Vue 3. ` + 11762 `The "|" symbol will be treated as native JavaScript bitwise OR operator. ` + 11763 `Use method calls or computed properties instead.`, 11764 link: `https://v3-migration.vuejs.org/breaking-changes/filters.html` 11765 } 11766 }; 11767 function getCompatValue(key, context) { 11768 const config = context.options 11769 ? context.options.compatConfig 11770 : context.compatConfig; 11771 const value = config && config[key]; 11772 if (key === 'MODE') { 11773 return value || 3; // compiler defaults to v3 behavior 11774 } 11775 else { 11776 return value; 11777 } 11778 } 11779 function isCompatEnabled(key, context) { 11780 const mode = getCompatValue('MODE', context); 11781 const value = getCompatValue(key, context); 11782 // in v3 mode, only enable if explicitly set to true 11783 // otherwise enable for any non-false value 11784 return mode === 3 ? value === true : value !== false; 11785 } 11786 function checkCompatEnabled(key, context, loc, ...args) { 11787 const enabled = isCompatEnabled(key, context); 11788 if (enabled) { 11789 warnDeprecation(key, context, loc, ...args); 11790 } 11791 return enabled; 11792 } 11793 function warnDeprecation(key, context, loc, ...args) { 11794 const val = getCompatValue(key, context); 11795 if (val === 'suppress-warning') { 11796 return; 11797 } 11798 const { message, link } = deprecationData[key]; 11799 const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n Details: ${link}` : ``}`; 11800 const err = new SyntaxError(msg); 11801 err.code = key; 11802 if (loc) 11803 err.loc = loc; 11804 context.onWarn(err); 11805 } 11806 11807 // The default decoder only provides escapes for characters reserved as part of 11808 // the template syntax, and is only used if the custom renderer did not provide 11809 // a platform-specific decoder. 11810 const decodeRE = /&(gt|lt|amp|apos|quot);/g; 11811 const decodeMap = { 11812 gt: '>', 11813 lt: '<', 11814 amp: '&', 11815 apos: "'", 11816 quot: '"' 11817 }; 11818 const defaultParserOptions = { 11819 delimiters: [`{{`, `}}`], 11820 getNamespace: () => 0 /* Namespaces.HTML */, 11821 getTextMode: () => 0 /* TextModes.DATA */, 11822 isVoidTag: NO, 11823 isPreTag: NO, 11824 isCustomElement: NO, 11825 decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]), 11826 onError: defaultOnError, 11827 onWarn: defaultOnWarn, 11828 comments: true 11829 }; 11830 function baseParse(content, options = {}) { 11831 const context = createParserContext(content, options); 11832 const start = getCursor(context); 11833 return createRoot(parseChildren(context, 0 /* TextModes.DATA */, []), getSelection(context, start)); 11834 } 11835 function createParserContext(content, rawOptions) { 11836 const options = extend({}, defaultParserOptions); 11837 let key; 11838 for (key in rawOptions) { 11839 // @ts-ignore 11840 options[key] = 11841 rawOptions[key] === undefined 11842 ? defaultParserOptions[key] 11843 : rawOptions[key]; 11844 } 11845 return { 11846 options, 11847 column: 1, 11848 line: 1, 11849 offset: 0, 11850 originalSource: content, 11851 source: content, 11852 inPre: false, 11853 inVPre: false, 11854 onWarn: options.onWarn 11855 }; 11856 } 11857 function parseChildren(context, mode, ancestors) { 11858 const parent = last(ancestors); 11859 const ns = parent ? parent.ns : 0 /* Namespaces.HTML */; 11860 const nodes = []; 11861 while (!isEnd(context, mode, ancestors)) { 11862 const s = context.source; 11863 let node = undefined; 11864 if (mode === 0 /* TextModes.DATA */ || mode === 1 /* TextModes.RCDATA */) { 11865 if (!context.inVPre && startsWith(s, context.options.delimiters[0])) { 11866 // '{{' 11867 node = parseInterpolation(context, mode); 11868 } 11869 else if (mode === 0 /* TextModes.DATA */ && s[0] === '<') { 11870 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state 11871 if (s.length === 1) { 11872 emitError(context, 5 /* ErrorCodes.EOF_BEFORE_TAG_NAME */, 1); 11873 } 11874 else if (s[1] === '!') { 11875 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state 11876 if (startsWith(s, '<!--')) { 11877 node = parseComment(context); 11878 } 11879 else if (startsWith(s, '<!DOCTYPE')) { 11880 // Ignore DOCTYPE by a limitation. 11881 node = parseBogusComment(context); 11882 } 11883 else if (startsWith(s, '<![CDATA[')) { 11884 if (ns !== 0 /* Namespaces.HTML */) { 11885 node = parseCDATA(context, ancestors); 11886 } 11887 else { 11888 emitError(context, 1 /* ErrorCodes.CDATA_IN_HTML_CONTENT */); 11889 node = parseBogusComment(context); 11890 } 11891 } 11892 else { 11893 emitError(context, 11 /* ErrorCodes.INCORRECTLY_OPENED_COMMENT */); 11894 node = parseBogusComment(context); 11895 } 11896 } 11897 else if (s[1] === '/') { 11898 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state 11899 if (s.length === 2) { 11900 emitError(context, 5 /* ErrorCodes.EOF_BEFORE_TAG_NAME */, 2); 11901 } 11902 else if (s[2] === '>') { 11903 emitError(context, 14 /* ErrorCodes.MISSING_END_TAG_NAME */, 2); 11904 advanceBy(context, 3); 11905 continue; 11906 } 11907 else if (/[a-z]/i.test(s[2])) { 11908 emitError(context, 23 /* ErrorCodes.X_INVALID_END_TAG */); 11909 parseTag(context, 1 /* TagType.End */, parent); 11910 continue; 11911 } 11912 else { 11913 emitError(context, 12 /* ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2); 11914 node = parseBogusComment(context); 11915 } 11916 } 11917 else if (/[a-z]/i.test(s[1])) { 11918 node = parseElement(context, ancestors); 11919 } 11920 else if (s[1] === '?') { 11921 emitError(context, 21 /* ErrorCodes.UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1); 11922 node = parseBogusComment(context); 11923 } 11924 else { 11925 emitError(context, 12 /* ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1); 11926 } 11927 } 11928 } 11929 if (!node) { 11930 node = parseText(context, mode); 11931 } 11932 if (isArray(node)) { 11933 for (let i = 0; i < node.length; i++) { 11934 pushNode(nodes, node[i]); 11935 } 11936 } 11937 else { 11938 pushNode(nodes, node); 11939 } 11940 } 11941 // Whitespace handling strategy like v2 11942 let removedWhitespace = false;
11943 if (mode !== 2 /* TextModes.RAWTEXT */ && mode !== 1 /* TextModes.RCDATA */) { 11944 const shouldCondense = context.options.whitespace !== 'preserve'; 11945 for (let i = 0; i < nodes.length; i++) { 11946 const node = nodes[i]; 11947 if (node.type === 2 /* NodeTypes.TEXT */) { 11948 if (!context.inPre) { 11949 if (!/[^\t\r\n\f ]/.test(node.content)) { 11950 const prev = nodes[i - 1]; 11951 const next = nodes[i + 1]; 11952 // Remove if: 11953 // - the whitespace is the first or last node, or: 11954 // - (condense mode) the whitespace is between twos comments, or: 11955 // - (condense mode) the whitespace is between comment and element, or: 11956 // - (condense mode) the whitespace is between two elements AND contains newline 11957 if (!prev || 11958 !next || 11959 (shouldCondense && 11960 ((prev.type === 3 /* NodeTypes.COMMENT */ && 11961 next.type === 3 /* NodeTypes.COMMENT */) || 11962 (prev.type === 3 /* NodeTypes.COMMENT */ && 11963 next.type === 1 /* NodeTypes.ELEMENT */) || 11964 (prev.type === 1 /* NodeTypes.ELEMENT */ && 11965 next.type === 3 /* NodeTypes.COMMENT */) || 11966 (prev.type === 1 /* NodeTypes.ELEMENT */ && 11967 next.type === 1 /* NodeTypes.ELEMENT */ && 11968 /[\r\n]/.test(node.content))))) { 11969 removedWhitespace = true; 11970 nodes[i] = null; 11971 } 11972 else { 11973 // Otherwise, the whitespace is condensed into a single space 11974 node.content = ' '; 11975 } 11976 } 11977 else if (shouldCondense) { 11978 // in condense mode, consecutive whitespaces in text are condensed 11979 // down to a single space. 11980 node.content = node.content.replace(/[\t\r\n\f ]+/g, ' '); 11981 } 11982 } 11983 else { 11984 // #6410 normalize windows newlines in <pre>: 11985 // in SSR, browsers normalize server-rendered \r\n into a single \n 11986 // in the DOM 11987 node.content = node.content.replace(/\r\n/g, '\n'); 11988 } 11989 } 11990 // Remove comment nodes if desired by configuration. 11991 else if (node.type === 3 /* NodeTypes.COMMENT */ && !context.options.comments) { 11992 removedWhitespace = true; 11993 nodes[i] = null; 11994 } 11995 } 11996 if (context.inPre && parent && context.options.isPreTag(parent.tag)) { 11997 // remove leading newline per html spec 11998 // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element 11999 const first = nodes[0]; 12000 if (first && first.type === 2 /* NodeTypes.TEXT */) { 12001 first.content = first.content.replace(/^\r?\n/, ''); 12002 } 12003 } 12004 } 12005 return removedWhitespace ? nodes.filter(Boolean) : nodes; 12006 } 12007 function pushNode(nodes, node) { 12008 if (node.type === 2 /* NodeTypes.TEXT */) { 12009 const prev = last(nodes); 12010 // Merge if both this and the previous node are text and those are 12011 // consecutive. This happens for cases like "a < b". 12012 if (prev && 12013 prev.type === 2 /* NodeTypes.TEXT */ && 12014 prev.loc.end.offset === node.loc.start.offset) { 12015 prev.content += node.content; 12016 prev.loc.end = node.loc.end; 12017 prev.loc.source += node.loc.source; 12018 return; 12019 } 12020 } 12021 nodes.push(node); 12022 } 12023 function parseCDATA(context, ancestors) { 12024 advanceBy(context, 9); 12025 const nodes = parseChildren(context, 3 /* TextModes.CDATA */, ancestors); 12026 if (context.source.length === 0) { 12027 emitError(context, 6 /* ErrorCodes.EOF_IN_CDATA */); 12028 } 12029 else { 12030 advanceBy(context, 3); 12031 } 12032 return nodes; 12033 } 12034 function parseComment(context) { 12035 const start = getCursor(context); 12036 let content; 12037 // Regular comment. 12038 const match = /--(\!)?>/.exec(context.source); 12039 if (!match) { 12040 content = context.source.slice(4); 12041 advanceBy(context, context.source.length); 12042 emitError(context, 7 /* ErrorCodes.EOF_IN_COMMENT */); 12043 } 12044 else { 12045 if (match.index <= 3) { 12046 emitError(context, 0 /* ErrorCodes.ABRUPT_CLOSING_OF_EMPTY_COMMENT */); 12047 } 12048 if (match[1]) { 12049 emitError(context, 10 /* ErrorCodes.INCORRECTLY_CLOSED_COMMENT */); 12050 } 12051 content = context.source.slice(4, match.index); 12052 // Advancing with reporting nested comments. 12053 const s = context.source.slice(0, match.index); 12054 let prevIndex = 1, nestedIndex = 0; 12055 while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) { 12056 advanceBy(context, nestedIndex - prevIndex + 1); 12057 if (nestedIndex + 4 < s.length) { 12058 emitError(context, 16 /* ErrorCodes.NESTED_COMMENT */); 12059 } 12060 prevIndex = nestedIndex + 1; 12061 } 12062 advanceBy(context, match.index + match[0].length - prevIndex + 1); 12063 } 12064 return { 12065 type: 3 /* NodeTypes.COMMENT */, 12066 content, 12067 loc: getSelection(context, start) 12068 }; 12069 } 12070 function parseBogusComment(context) { 12071 const start = getCursor(context); 12072 const contentStart = context.source[1] === '?' ? 1 : 2; 12073 let content; 12074 const closeIndex = context.source.indexOf('>'); 12075 if (closeIndex === -1) { 12076 content = context.source.slice(contentStart); 12077 advanceBy(context, context.source.length); 12078 } 12079 else { 12080 content = context.source.slice(contentStart, closeIndex); 12081 advanceBy(context, closeIndex + 1); 12082 } 12083 return { 12084 type: 3 /* NodeTypes.COMMENT */, 12085 content, 12086 loc: getSelection(context, start) 12087 }; 12088 } 12089 function parseElement(context, ancestors) { 12090 // Start tag.
12091 const wasInPre = context.inPre; 12092 const wasInVPre = context.inVPre; 12093 const parent = last(ancestors); 12094 const element = parseTag(context, 0 /* TagType.Start */, parent); 12095 const isPreBoundary = context.inPre && !wasInPre; 12096 const isVPreBoundary = context.inVPre && !wasInVPre; 12097 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) { 12098 // #4030 self-closing <pre> tag 12099 if (isPreBoundary) { 12100 context.inPre = false; 12101 } 12102 if (isVPreBoundary) { 12103 context.inVPre = false; 12104 } 12105 return element; 12106 } 12107 // Children. 12108 ancestors.push(element); 12109 const mode = context.options.getTextMode(element, parent); 12110 const children = parseChildren(context, mode, ancestors); 12111 ancestors.pop(); 12112 element.children = children; 12113 // End tag. 12114 if (startsWithEndTagOpen(context.source, element.tag)) { 12115 parseTag(context, 1 /* TagType.End */, parent); 12116 } 12117 else { 12118 emitError(context, 24 /* ErrorCodes.X_MISSING_END_TAG */, 0, element.loc.start); 12119 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') { 12120 const first = children[0]; 12121 if (first && startsWith(first.loc.source, '<!--')) { 12122 emitError(context, 8 /* ErrorCodes.EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */); 12123 } 12124 } 12125 } 12126 element.loc = getSelection(context, element.loc.start); 12127 if (isPreBoundary) { 12128 context.inPre = false; 12129 } 12130 if (isVPreBoundary) { 12131 context.inVPre = false; 12132 } 12133 return element; 12134 } 12135 const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`); 12136 function parseTag(context, type, parent) { 12137 // Tag open. 12138 const start = getCursor(context); 12139 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source); 12140 const tag = match[1]; 12141 const ns = context.options.getNamespace(tag, parent); 12142 advanceBy(context, match[0].length); 12143 advanceSpaces(context); 12144 // save current state in case we need to re-parse attributes with v-pre 12145 const cursor = getCursor(context); 12146 const currentSource = context.source; 12147 // check <pre> tag 12148 if (context.options.isPreTag(tag)) { 12149 context.inPre = true; 12150 } 12151 // Attributes. 12152 let props = parseAttributes(context, type); 12153 // check v-pre 12154 if (type === 0 /* TagType.Start */ && 12155 !context.inVPre && 12156 props.some(p => p.type === 7 /* NodeTypes.DIRECTIVE */ && p.name === 'pre')) { 12157 context.inVPre = true; 12158 // reset context 12159 extend(context, cursor); 12160 context.source = currentSource; 12161 // re-parse attrs and filter out v-pre itself 12162 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre'); 12163 } 12164 // Tag close. 12165 let isSelfClosing = false; 12166 if (context.source.length === 0) { 12167 emitError(context, 9 /* ErrorCodes.EOF_IN_TAG */); 12168 } 12169 else { 12170 isSelfClosing = startsWith(context.source, '/>'); 12171 if (type === 1 /* TagType.End */ && isSelfClosing) { 12172 emitError(context, 4 /* ErrorCodes.END_TAG_WITH_TRAILING_SOLIDUS */); 12173 } 12174 advanceBy(context, isSelfClosing ? 2 : 1); 12175 } 12176 if (type === 1 /* TagType.End */) { 12177 return; 12178 } 12179 let tagType = 0 /* ElementTypes.ELEMENT */; 12180 if (!context.inVPre) { 12181 if (tag === 'slot') { 12182 tagType = 2 /* ElementTypes.SLOT */; 12183 } 12184 else if (tag === 'template') { 12185 if (props.some(p => p.type === 7 /* NodeTypes.DIRECTIVE */ && isSpecialTemplateDirective(p.name))) { 12186 tagType = 3 /* ElementTypes.TEMPLATE */; 12187 } 12188 } 12189 else if (isComponent(tag, props, context)) { 12190 tagType = 1 /* ElementTypes.COMPONENT */; 12191 } 12192 } 12193 return { 12194 type: 1 /* NodeTypes.ELEMENT */, 12195 ns, 12196 tag, 12197 tagType, 12198 props, 12199 isSelfClosing, 12200 children: [], 12201 loc: getSelection(context, start), 12202 codegenNode: undefined // to be created during transform phase 12203 }; 12204 } 12205 function isComponent(tag, props, context) { 12206 const options = context.options; 12207 if (options.isCustomElement(tag)) { 12208 return false;
12209 } 12210 if (tag === 'component' || 12211 /^[A-Z]/.test(tag) || 12212 isCoreComponent(tag) || 12213 (options.isBuiltInComponent && options.isBuiltInComponent(tag)) || 12214 (options.isNativeTag && !options.isNativeTag(tag))) { 12215 return true; 12216 } 12217 // at this point the tag should be a native tag, but check for potential "is" 12218 // casting 12219 for (let i = 0; i < props.length; i++) { 12220 const p = props[i]; 12221 if (p.type === 6 /* NodeTypes.ATTRIBUTE */) { 12222 if (p.name === 'is' && p.value) { 12223 if (p.value.content.startsWith('vue:')) { 12224 return true; 12225 } 12226 } 12227 } 12228 else { 12229 // directive 12230 // v-is (TODO Deprecate) 12231 if (p.name === 'is') { 12232 return true; 12233 } 12234 else if ( 12235 // :is on plain element - only treat as component in compat mode 12236 p.name === 'bind' && 12237 isStaticArgOf(p.arg, 'is') && 12238 false && 12239 checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* CompilerDeprecationTypes.COMPILER_IS_ON_ELEMENT */, context, p.loc)) { 12240 return true; 12241 } 12242 } 12243 } 12244 } 12245 function parseAttributes(context, type) { 12246 const props = []; 12247 const attributeNames = new Set(); 12248 while (context.source.length > 0 && 12249 !startsWith(context.source, '>') && 12250 !startsWith(context.source, '/>')) { 12251 if (startsWith(context.source, '/')) { 12252 emitError(context, 22 /* ErrorCodes.UNEXPECTED_SOLIDUS_IN_TAG */); 12253 advanceBy(context, 1); 12254 advanceSpaces(context); 12255 continue; 12256 } 12257 if (type === 1 /* TagType.End */) { 12258 emitError(context, 3 /* ErrorCodes.END_TAG_WITH_ATTRIBUTES */); 12259 } 12260 const attr = parseAttribute(context, attributeNames); 12261 // Trim whitespace between class 12262 // https://github.com/vuejs/core/issues/4251 12263 if (attr.type === 6 /* NodeTypes.ATTRIBUTE */ && 12264 attr.value && 12265 attr.name === 'class') { 12266 attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim(); 12267 } 12268 if (type === 0 /* TagType.Start */) { 12269 props.push(attr); 12270 } 12271 if (/^[^\t\r\n\f />]/.test(context.source)) { 12272 emitError(context, 15 /* ErrorCodes.MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */); 12273 } 12274 advanceSpaces(context); 12275 } 12276 return props; 12277 } 12278 function parseAttribute(context, nameSet) { 12279 // Name. 12280 const start = getCursor(context); 12281 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source); 12282 const name = match[0]; 12283 if (nameSet.has(name)) { 12284 emitError(context, 2 /* ErrorCodes.DUPLICATE_ATTRIBUTE */); 12285 } 12286 nameSet.add(name); 12287 if (name[0] === '=') { 12288 emitError(context, 19 /* ErrorCodes.UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */); 12289 } 12290 { 12291 const pattern = /["'<]/g; 12292 let m; 12293 while ((m = pattern.exec(name))) { 12294 emitError(context, 17 /* ErrorCodes.UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index); 12295 } 12296 } 12297 advanceBy(context, name.length); 12298 // Value 12299 let value = undefined; 12300 if (/^[\t\r\n\f ]*=/.test(context.source)) { 12301 advanceSpaces(context); 12302 advanceBy(context, 1); 12303 advanceSpaces(context); 12304 value = parseAttributeValue(context); 12305 if (!value) { 12306 emitError(context, 13 /* ErrorCodes.MISSING_ATTRIBUTE_VALUE */); 12307 } 12308 } 12309 const loc = getSelection(context, start); 12310 if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) { 12311 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name); 12312 let isPropShorthand = startsWith(name, '.'); 12313 let dirName = match[1] || 12314 (isPropShorthand || startsWith(name, ':') 12315 ? 'bind' 12316 : startsWith(name, '@') 12317 ? 'on' 12318 : 'slot'); 12319 let arg; 12320 if (match[2]) { 12321 const isSlot = dirName === 'slot'; 12322 const startOffset = name.lastIndexOf(match[2]); 12323 const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length)); 12324 let content = match[2]; 12325 let isStatic = true; 12326 if (content.startsWith('[')) { 12327 isStatic = false;
12328 if (!content.endsWith(']')) { 12329 emitError(context, 27 /* ErrorCodes.X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */); 12330 content = content.slice(1); 12331 } 12332 else { 12333 content = content.slice(1, content.length - 1); 12334 } 12335 } 12336 else if (isSlot) { 12337 // #1241 special case for v-slot: vuetify relies extensively on slot 12338 // names containing dots. v-slot doesn't have any modifiers and Vue 2.x 12339 // supports such usage so we are keeping it consistent with 2.x. 12340 content += match[3] || ''; 12341 } 12342 arg = { 12343 type: 4 /* NodeTypes.SIMPLE_EXPRESSION */, 12344 content, 12345 isStatic, 12346 constType: isStatic 12347 ? 3 /* ConstantTypes.CAN_STRINGIFY */ 12348 : 0 /* ConstantTypes.NOT_CONSTANT */, 12349 loc 12350 }; 12351 } 12352 if (value && value.isQuoted) { 12353 const valueLoc = value.loc; 12354 valueLoc.start.offset++; 12355 valueLoc.start.column++; 12356 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content); 12357 valueLoc.source = valueLoc.source.slice(1, -1); 12358 } 12359 const modifiers = match[3] ? match[3].slice(1).split('.') : []; 12360 if (isPropShorthand) 12361 modifiers.push('prop'); 12362 return { 12363 type: 7 /* NodeTypes.DIRECTIVE */, 12364 name: dirName, 12365 exp: value && { 12366 type: 4 /* NodeTypes.SIMPLE_EXPRESSION */, 12367 content: value.content, 12368 isStatic: false, 12369 // Treat as non-constant by default. This can be potentially set to 12370 // other values by `transformExpression` to make it eligible for hoisting. 12371 constType: 0 /* ConstantTypes.NOT_CONSTANT */, 12372 loc: value.loc 12373 }, 12374 arg, 12375 modifiers, 12376 loc 12377 }; 12378 } 12379 // missing directive name or illegal directive name 12380 if (!context.inVPre && startsWith(name, 'v-')) { 12381 emitError(context, 26 /* ErrorCodes.X_MISSING_DIRECTIVE_NAME */); 12382 } 12383 return { 12384 type: 6 /* NodeTypes.ATTRIBUTE */, 12385 name, 12386 value: value && { 12387 type: 2 /* NodeTypes.TEXT */, 12388 content: value.content, 12389 loc: value.loc 12390 }, 12391 loc 12392 }; 12393 } 12394 function parseAttributeValue(context) { 12395 const start = getCursor(context); 12396 let content; 12397 const quote = context.source[0]; 12398 const isQuoted = quote === `"` || quote === `'`; 12399 if (isQuoted) { 12400 // Quoted value. 12401 advanceBy(context, 1); 12402 const endIndex = context.source.indexOf(quote); 12403 if (endIndex === -1) { 12404 content = parseTextData(context, context.source.length, 4 /* TextModes.ATTRIBUTE_VALUE */); 12405 } 12406 else { 12407 content = parseTextData(context, endIndex, 4 /* TextModes.ATTRIBUTE_VALUE */); 12408 advanceBy(context, 1); 12409 } 12410 } 12411 else { 12412 // Unquoted 12413 const match = /^[^\t\r\n\f >]+/.exec(context.source); 12414 if (!match) { 12415 return undefined; 12416 } 12417 const unexpectedChars = /["'<=`]/g; 12418 let m; 12419 while ((m = unexpectedChars.exec(match[0]))) { 12420 emitError(context, 18 /* ErrorCodes.UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index); 12421 } 12422 content = parseTextData(context, match[0].length, 4 /* TextModes.ATTRIBUTE_VALUE */); 12423 } 12424 return { content, isQuoted, loc: getSelection(context, start) }; 12425 } 12426 function parseInterpolation(context, mode) { 12427 const [open, close] = context.options.delimiters; 12428 const closeIndex = context.source.indexOf(close, open.length); 12429 if (closeIndex === -1) { 12430 emitError(context, 25 /* ErrorCodes.X_MISSING_INTERPOLATION_END */); 12431 return undefined; 12432 } 12433 const start = getCursor(context); 12434 advanceBy(context, open.length); 12435 const innerStart = getCursor(context); 12436 const innerEnd = getCursor(context); 12437 const rawContentLength = closeIndex - open.length; 12438 const rawContent = context.source.slice(0, rawContentLength); 12439 const preTrimContent = parseTextData(context, rawContentLength, mode); 12440 const content = preTrimContent.trim(); 12441 const startOffset = preTrimContent.indexOf(content); 12442 if (startOffset > 0) { 12443 advancePositionWithMutation(innerStart, rawContent, startOffset); 12444 } 12445 const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset); 12446 advancePositionWithMutation(innerEnd, rawContent, endOffset); 12447 advanceBy(context, close.length); 12448 return { 12449 type: 5 /* NodeTypes.INTERPOLATION */, 12450 content: { 12451 type: 4 /* NodeTypes.SIMPLE_EXPRESSION */, 12452 isStatic: false, 12453 // Set `isConstant` to false by default and will decide in transformExpression 12454 constType: 0 /* ConstantTypes.NOT_CONSTANT */, 12455 content, 12456 loc: getSelection(context, innerStart, innerEnd) 12457 }, 12458 loc: getSelection(context, start) 12459 }; 12460 } 12461 function parseText(context, mode) { 12462 const endTokens = mode === 3 /* TextModes.CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]]; 12463 let endIndex = context.source.length; 12464 for (let i = 0; i < endTokens.length; i++) { 12465 const index = context.source.indexOf(endTokens[i], 1); 12466 if (index !== -1 && endIndex > index) { 12467 endIndex = index; 12468 } 12469 } 12470 const start = getCursor(context); 12471 const content = parseTextData(context, endIndex, mode); 12472 return { 12473 type: 2 /* NodeTypes.TEXT */, 12474 content, 12475 loc: getSelection(context, start) 12476 }; 12477 } 12478 /** 12479 * Get text data with a given length from the current location. 12480 * This translates HTML entities in the text data. 12481 */ 12482 function parseTextData(context, length, mode) { 12483 const rawText = context.source.slice(0, length); 12484 advanceBy(context, length); 12485 if (mode === 2 /* TextModes.RAWTEXT */ || 12486 mode === 3 /* TextModes.CDATA */ || 12487 !rawText.includes('&')) { 12488 return rawText; 12489 } 12490 else { 12491 // DATA or RCDATA containing "&"". Entity decoding required. 12492 return context.options.decodeEntities(rawText, mode === 4 /* TextModes.ATTRIBUTE_VALUE */); 12493 } 12494 } 12495 function getCursor(context) { 12496 const { column, line, offset } = context; 12497 return { column, line, offset }; 12498 } 12499 function getSelection(context, start, end) { 12500 end = end || getCursor(context); 12501 return { 12502 start, 12503 end, 12504 source: context.originalSource.slice(start.offset, end.offset) 12505 }; 12506 } 12507 function last(xs) { 12508 return xs[xs.length - 1]; 12509 } 12510 function startsWith(source, searchString) { 12511 return source.startsWith(searchString); 12512 } 12513 function advanceBy(context, numberOfCharacters) { 12514 const { source }
12514 = context; 12515 advancePositionWithMutation(context, source, numberOfCharacters); 12516 context.source = source.slice(numberOfCharacters); 12517 } 12518 function advanceSpaces(context) { 12519 const match = /^[\t\r\n\f ]+/.exec(context.source); 12520 if (match) { 12521 advanceBy(context, match[0].length); 12522 } 12523 } 12524 function getNewPosition(context, start, numberOfCharacters) { 12525 return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters); 12526 } 12527 function emitError(context, code, offset, loc = getCursor(context)) { 12528 if (offset) { 12529 loc.offset += offset; 12530 loc.column += offset; 12531 } 12532 context.options.onError(createCompilerError(code, { 12533 start: loc, 12534 end: loc, 12535 source: '' 12536 })); 12537 } 12538 function isEnd(context, mode, ancestors) { 12539 const s = context.source; 12540 switch (mode) { 12541 case 0 /* TextModes.DATA */: 12542 if (startsWith(s, '</')) { 12543 // TODO: probably bad performance 12544 for (let i = ancestors.length - 1; i >= 0; --i) { 12545 if (startsWithEndTagOpen(s, ancestors[i].tag)) { 12546 return true; 12547 } 12548 } 12549 } 12550 break; 12551 case 1 /* TextModes.RCDATA */: 12552 case 2 /* TextModes.RAWTEXT */: { 12553 const parent = last(ancestors); 12554 if (parent && startsWithEndTagOpen(s, parent.tag)) { 12555 return true; 12556 } 12557 break; 12558 } 12559 case 3 /* TextModes.CDATA */: 12560 if (startsWith(s, ']]>')) { 12561 return true; 12562 } 12563 break; 12564 } 12565 return !s; 12566 } 12567 function startsWithEndTagOpen(source, tag) { 12568 return (startsWith(source, '</') && 12569 source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() && 12570 /[\t\r\n\f />]/.test(source[2 + tag.length] || '>')); 12571 } 12572 12573 function hoistStatic(root, context) { 12574 walk(root, context, 12575 // Root node is unfortunately non-hoistable due to potential parent 12576 // fallthrough attributes. 12577 isSingleElementRoot(root, root.children[0])); 12578 } 12579 function isSingleElementRoot(root, child) { 12580 const { children } = root; 12581 return (children.length === 1 && 12582 child.type === 1 /* NodeTypes.ELEMENT */ && 12583 !isSlotOutlet(child)); 12584 } 12585 function walk(node, context, doNotHoistNode = false) { 12586 const { children } = node; 12587 const originalCount = children.length; 12588 let hoistedCount = 0; 12589 for (let i = 0; i < children.length; i++) { 12590 const child = children[i]; 12591 // only plain elements & text calls are eligible for hoisting. 12592 if (child.type === 1 /* NodeTypes.ELEMENT */ && 12593 child.tagType === 0 /* ElementTypes.ELEMENT */) { 12594 const constantType = doNotHoistNode 12595 ? 0 /* ConstantTypes.NOT_CONSTANT */ 12596 : getConstantType(child, context); 12597 if (constantType > 0 /* ConstantTypes.NOT_CONSTANT */) { 12598 if (constantType >= 2 /* ConstantTypes.CAN_HOIST */) { 12599 child.codegenNode.patchFlag = 12600 -1 /* PatchFlags.HOISTED */ + (` /* HOISTED */` ); 12601 child.codegenNode = context.hoist(child.codegenNode); 12602 hoistedCount++; 12603 continue; 12604 } 12605 } 12606 else { 12607 // node may contain dynamic children, but its props may be eligible for 12608 // hoisting. 12609 const codegenNode = child.codegenNode; 12610 if (codegenNode.type === 13 /* NodeTypes.VNODE_CALL */) { 12611 const flag = getPatchFlag(codegenNode); 12612 if ((!flag || 12613 flag === 512 /* PatchFlags.NEED_PATCH */ || 12614 flag === 1 /* PatchFlags.TEXT */) && 12615 getGeneratedPropsConstantType(child, context) >= 12616 2 /* ConstantTypes.CAN_HOIST */) { 12617 const props = getNodeProps(child); 12618 if (props) { 12619 codegenNode.props = context.hoist(props); 12620 } 12621 } 12622 if (codegenNode.dynamicProps) { 12623 codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps); 12624 } 12625 } 12626 } 12627 } 12628 // walk further 12629 if (child.type === 1 /* NodeTypes.ELEMENT */) { 12630 const isComponent = child.tagType === 1 /* ElementTypes.COMPONENT */; 12631 if (isComponent) { 12632 context.scopes.vSlot++; 12633 }
12634 walk(child, context); 12635 if (isComponent) { 12636 context.scopes.vSlot--; 12637 } 12638 } 12639 else if (child.type === 11 /* NodeTypes.FOR */) { 12640 // Do not hoist v-for single child because it has to be a block 12641 walk(child, context, child.children.length === 1); 12642 } 12643 else if (child.type === 9 /* NodeTypes.IF */) { 12644 for (let i = 0; i < child.branches.length; i++) { 12645 // Do not hoist v-if single child because it has to be a block 12646 walk(child.branches[i], context, child.branches[i].children.length === 1); 12647 } 12648 } 12649 } 12650 if (hoistedCount && context.transformHoist) { 12651 context.transformHoist(children, context, node); 12652 } 12653 // all children were hoisted - the entire children array is hoistable. 12654 if (hoistedCount && 12655 hoistedCount === originalCount && 12656 node.type === 1 /* NodeTypes.ELEMENT */ && 12657 node.tagType === 0 /* ElementTypes.ELEMENT */ && 12658 node.codegenNode && 12659 node.codegenNode.type === 13 /* NodeTypes.VNODE_CALL */ && 12660 isArray(node.codegenNode.children)) { 12661 node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children)); 12662 } 12663 } 12664 function getConstantType(node, context) { 12665 const { constantCache } = context; 12666 switch (node.type) { 12667 case 1 /* NodeTypes.ELEMENT */: 12668 if (node.tagType !== 0 /* ElementTypes.ELEMENT */) { 12669 return 0 /* ConstantTypes.NOT_CONSTANT */; 12670 } 12671 const cached = constantCache.get(node); 12672 if (cached !== undefined) { 12673 return cached; 12674 } 12675 const codegenNode = node.codegenNode; 12676 if (codegenNode.type !== 13 /* NodeTypes.VNODE_CALL */) { 12677 return 0 /* ConstantTypes.NOT_CONSTANT */; 12678 } 12679 if (codegenNode.isBlock && 12680 node.tag !== 'svg' && 12681 node.tag !== 'foreignObject') { 12682 return 0 /* ConstantTypes.NOT_CONSTANT */; 12683 } 12684 const flag = getPatchFlag(codegenNode); 12685 if (!flag) { 12686 let returnType = 3 /* ConstantTypes.CAN_STRINGIFY */; 12687 // Element itself has no patch flag. However we still need to check: 12688 // 1. Even for a node with no patch flag, it is possible for it to contain 12689 // non-hoistable expressions that refers to scope variables, e.g. compiler 12690 // injected keys or cached event handlers. Therefore we need to always 12691 // check the codegenNode's props to be sure. 12692 const generatedPropsType = getGeneratedPropsConstantType(node, context); 12693 if (generatedPropsType === 0 /* ConstantTypes.NOT_CONSTANT */) { 12694 constantCache.set(node, 0 /* ConstantTypes.NOT_CONSTANT */); 12695 return 0 /* ConstantTypes.NOT_CONSTANT */; 12696 } 12697 if (generatedPropsType < returnType) { 12698 returnType = generatedPropsType; 12699 } 12700 // 2. its children. 12701 for (let i = 0; i < node.children.length; i++) { 12702 const childType = getConstantType(node.children[i], context); 12703 if (childType === 0 /* ConstantTypes.NOT_CONSTANT */) { 12704 constantCache.set(node, 0 /* ConstantTypes.NOT_CONSTANT */); 12705 return 0 /* ConstantTypes.NOT_CONSTANT */; 12706 } 12707 if (childType < returnType) { 12708 returnType = childType; 12709 } 12710 } 12711 // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-0 12712 // type, check if any of the props can cause the type to be lowered 12713 // we can skip can_patch because it's guaranteed by the absence of a 12714 // patchFlag. 12715 if (returnType > 1 /* ConstantTypes.CAN_SKIP_PATCH */) { 12716 for (let i = 0; i < node.props.length; i++) { 12717 const p = node.props[i]; 12718 if (p.type === 7 /* NodeTypes.DIRECTIVE */ && p.name === 'bind' && p.exp) { 12719 const expType = getConstantType(p.exp, context); 12720 if (expType === 0 /* ConstantTypes.NOT_CONSTANT */) {
vendor: 10,650 bytes, lines 12721-12982
12721 constantCache.set(node, 0 /* ConstantTypes.NOT_CONSTANT */); 12722 return 0 /* ConstantTypes.NOT_CONSTANT */; 12723 } 12724 if (expType < returnType) { 12725 returnType = expType; 12726 } 12727 } 12728 } 12729 } 12730 // only svg/foreignObject could be block here, however if they are 12731 // static then they don't need to be blocks since there will be no 12732 // nested updates. 12733 if (codegenNode.isBlock) { 12734 // except set custom directives. 12735 for (let i = 0; i < node.props.length; i++) { 12736 const p = node.props[i]; 12737 if (p.type === 7 /* NodeTypes.DIRECTIVE */) { 12738 constantCache.set(node, 0 /* ConstantTypes.NOT_CONSTANT */); 12739 return 0 /* ConstantTypes.NOT_CONSTANT */; 12740 } 12741 } 12742 context.removeHelper(OPEN_BLOCK); 12743 context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent)); 12744 codegenNode.isBlock = false; 12745 context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent)); 12746 } 12747 constantCache.set(node, returnType); 12748 return returnType; 12749 } 12750 else { 12751 constantCache.set(node, 0 /* ConstantTypes.NOT_CONSTANT */); 12752 return 0 /* ConstantTypes.NOT_CONSTANT */; 12753 } 12754 case 2 /* NodeTypes.TEXT */: 12755 case 3 /* NodeTypes.COMMENT */: 12756 return 3 /* ConstantTypes.CAN_STRINGIFY */; 12757 case 9 /* NodeTypes.IF */: 12758 case 11 /* NodeTypes.FOR */: 12759 case 10 /* NodeTypes.IF_BRANCH */: 12760 return 0 /* ConstantTypes.NOT_CONSTANT */; 12761 case 5 /* NodeTypes.INTERPOLATION */: 12762 case 12 /* NodeTypes.TEXT_CALL */: 12763 return getConstantType(node.content, context); 12764 case 4 /* NodeTypes.SIMPLE_EXPRESSION */: 12765 return node.constType; 12766 case 8 /* NodeTypes.COMPOUND_EXPRESSION */: 12767 let returnType = 3 /* ConstantTypes.CAN_STRINGIFY */; 12768 for (let i = 0; i < node.children.length; i++) { 12769 const child = node.children[i]; 12770 if (isString(child) || isSymbol(child)) { 12771 continue; 12772 } 12773 const childType = getConstantType(child, context); 12774 if (childType === 0 /* ConstantTypes.NOT_CONSTANT */) { 12775 return 0 /* ConstantTypes.NOT_CONSTANT */; 12776 } 12777 else if (childType < returnType) { 12778 returnType = childType; 12779 } 12780 } 12781 return returnType; 12782 default: 12783 return 0 /* ConstantTypes.NOT_CONSTANT */; 12784 } 12785 } 12786 const allowHoistedHelperSet = new Set([ 12787 NORMALIZE_CLASS, 12788 NORMALIZE_STYLE, 12789 NORMALIZE_PROPS, 12790 GUARD_REACTIVE_PROPS 12791 ]); 12792 function getConstantTypeOfHelperCall(value, context) { 12793 if (value.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */ && 12794 !isString(value.callee) && 12795 allowHoistedHelperSet.has(value.callee)) { 12796 const arg = value.arguments[0]; 12797 if (arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) { 12798 return getConstantType(arg, context); 12799 } 12800 else if (arg.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */) { 12801 // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))` 12802 return getConstantTypeOfHelperCall(arg, context); 12803 } 12804 } 12805 return 0 /* ConstantTypes.NOT_CONSTANT */; 12806 } 12807 function getGeneratedPropsConstantType(node, context) { 12808 let returnType = 3 /* ConstantTypes.CAN_STRINGIFY */; 12809 const props = getNodeProps(node); 12810 if (props && props.type === 15 /* NodeTypes.JS_OBJECT_EXPRESSION */) { 12811 const { properties } = props; 12812 for (let i = 0; i < properties.length; i++) { 12813 const { key, value } = properties[i]; 12814 const keyType = getConstantType(key, context); 12815 if (keyType === 0 /* ConstantTypes.NOT_CONSTANT */) { 12816 return keyType; 12817 } 12818 if (keyType < returnType) { 12819 returnType = keyType; 12820 } 12821 let valueType; 12822 if (value.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) { 12823 valueType = getConstantType(value, context); 12824 } 12825 else if (value.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */) { 12826 // some helper calls can be hoisted, 12827 // such as the `normalizeProps` generated by the compiler for pre-normalize class, 12828 // in this case we need to respect the ConstantType of the helper's arguments 12829 valueType = getConstantTypeOfHelperCall(value, context); 12830 } 12831 else { 12832 valueType = 0 /* ConstantTypes.NOT_CONSTANT */; 12833 } 12834 if (valueType === 0 /* ConstantTypes.NOT_CONSTANT */) { 12835 return valueType; 12836 } 12837 if (valueType < returnType) { 12838 returnType = valueType; 12839 } 12840 } 12841 } 12842 return returnType; 12843 } 12844 function getNodeProps(node) { 12845 const codegenNode = node.codegenNode; 12846 if (codegenNode.type === 13 /* NodeTypes.VNODE_CALL */) { 12847 return codegenNode.props; 12848 } 12849 } 12850 function getPatchFlag(node) { 12851 const flag = node.patchFlag; 12852 return flag ? parseInt(flag, 10) : undefined; 12853 } 12854 12855 function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = NOOP, isCustomElement = NOOP, expressionPlugins = [], scopeId = null, slotted = true, ssr = false, inSSR = false, ssrCssVars = ``, bindingMetadata = EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError, onWarn = defaultOnWarn, compatConfig }) { 12856 const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/); 12857 const context = { 12858 // options 12859 selfName: nameMatch && capitalize(camelize(nameMatch[1])), 12860 prefixIdentifiers, 12861 hoistStatic, 12862 cacheHandlers, 12863 nodeTransforms, 12864 directiveTransforms, 12865 transformHoist, 12866 isBuiltInComponent, 12867 isCustomElement, 12868 expressionPlugins, 12869 scopeId, 12870 slotted, 12871 ssr, 12872 inSSR, 12873 ssrCssVars, 12874 bindingMetadata, 12875 inline, 12876 isTS, 12877 onError, 12878 onWarn, 12879 compatConfig, 12880 // state 12881 root, 12882 helpers: new Map(), 12883 components: new Set(), 12884 directives: new Set(), 12885 hoists: [], 12886 imports: [], 12887 constantCache: new Map(), 12888 temps: 0, 12889 cached: 0, 12890 identifiers: Object.create(null), 12891 scopes: { 12892 vFor: 0, 12893 vSlot: 0, 12894 vPre: 0, 12895 vOnce: 0 12896 }, 12897 parent: null, 12898 currentNode: root, 12899 childIndex: 0, 12900 inVOnce: false, 12901 // methods 12902 helper(name) { 12903 const count = context.helpers.get(name) || 0; 12904 context.helpers.set(name, count + 1); 12905 return name; 12906 }, 12907 removeHelper(name) { 12908 const count = context.helpers.get(name); 12909 if (count) { 12910 const currentCount = count - 1; 12911 if (!currentCount) { 12912 context.helpers.delete(name); 12913 } 12914 else { 12915 context.helpers.set(name, currentCount); 12916 } 12917 } 12918 }, 12919 helperString(name) { 12920 return `_${helperNameMap[context.helper(name)]}`; 12921 }, 12922 replaceNode(node) { 12923 /* istanbul ignore if */ 12924 { 12925 if (!context.currentNode) { 12926 throw new Error(`Node being replaced is already removed.`); 12927 } 12928 if (!context.parent) { 12929 throw new Error(`Cannot replace root node.`); 12930 } 12931 } 12932 context.parent.children[context.childIndex] = context.currentNode = node; 12933 }, 12934 removeNode(node) { 12935 if (!context.parent) { 12936 throw new Error(`Cannot remove root node.`); 12937 } 12938 const list = context.parent.children; 12939 const removalIndex = node 12940 ? list.indexOf(node) 12941 : context.currentNode 12942 ? context.childIndex 12943 : -1; 12944 /* istanbul ignore if */ 12945 if (removalIndex < 0) { 12946 throw new Error(`node being removed is not a child of current parent`); 12947 } 12948 if (!node || node === context.currentNode) { 12949 // current node removed 12950 context.currentNode = null; 12951 context.onNodeRemoved(); 12952 } 12953 else { 12954 // sibling node removed 12955 if (context.childIndex > removalIndex) { 12956 context.childIndex--; 12957 context.onNodeRemoved(); 12958 } 12959 } 12960 context.parent.children.splice(removalIndex, 1); 12961 }, 12962 onNodeRemoved: () => { }, 12963 addIdentifiers(exp) { 12964 }, 12965 removeIdentifiers(exp) { 12966 }, 12967 hoist(exp) { 12968 if (isString(exp)) 12969 exp = createSimpleExpression(exp); 12970 context.hoists.push(exp); 12971 const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* ConstantTypes.CAN_HOIST */); 12972 identifier.hoisted = exp; 12973 return identifier; 12974 }, 12975 cache(exp, isVNode = false) { 12976 return createCacheExpression(context.cached++, exp, isVNode); 12977 } 12978 }; 12979 return context; 12980 } 12981 function transform(root, options) { 12982 const context = createTransformContext(root, options);
12983 traverseNode(root, context); 12984 if (options.hoistStatic) { 12985 hoistStatic(root, context); 12986 } 12987 if (!options.ssr) { 12988 createRootCodegen(root, context); 12989 } 12990 // finalize meta information 12991 root.helpers = new Set([...context.helpers.keys()]); 12992 root.components = [...context.components]; 12993 root.directives = [...context.directives]; 12994 root.imports = context.imports; 12995 root.hoists = context.hoists; 12996 root.temps = context.temps; 12997 root.cached = context.cached; 12998 } 12999 function createRootCodegen(root, context) { 13000 const { helper } = context; 13001 const { children } = root; 13002 if (children.length === 1) { 13003 const child = children[0]; 13004 // if the single child is an element, turn it into a block. 13005 if (isSingleElementRoot(root, child) && child.codegenNode) { 13006 // single element root is never hoisted so codegenNode will never be 13007 // SimpleExpressionNode 13008 const codegenNode = child.codegenNode; 13009 if (codegenNode.type === 13 /* NodeTypes.VNODE_CALL */) { 13010 makeBlock(codegenNode, context); 13011 } 13012 root.codegenNode = codegenNode; 13013 } 13014 else { 13015 // - single <slot/>, IfNode, ForNode: already blocks. 13016 // - single text node: always patched. 13017 // root codegen falls through via genNode() 13018 root.codegenNode = child; 13019 } 13020 } 13021 else if (children.length > 1) { 13022 // root has multiple nodes - return a fragment block. 13023 let patchFlag = 64 /* PatchFlags.STABLE_FRAGMENT */; 13024 let patchFlagText = PatchFlagNames[64 /* PatchFlags.STABLE_FRAGMENT */]; 13025 // check if the fragment actually contains a single valid child with 13026 // the rest being comments 13027 if (children.filter(c => c.type !== 3 /* NodeTypes.COMMENT */).length === 1) { 13028 patchFlag |= 2048 /* PatchFlags.DEV_ROOT_FRAGMENT */; 13029 patchFlagText += `, ${PatchFlagNames[2048 /* PatchFlags.DEV_ROOT_FRAGMENT */]}`; 13030 } 13031 root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, undefined, false /* isComponent */); 13032 } 13033 else ; 13034 } 13035 function traverseChildren(parent, context) { 13036 let i = 0; 13037 const nodeRemoved = () => { 13038 i--; 13039 }; 13040 for (; i < parent.children.length; i++) { 13041 const child = parent.children[i]; 13042 if (isString(child)) 13043 continue; 13044 context.parent = parent; 13045 context.childIndex = i; 13046 context.onNodeRemoved = nodeRemoved; 13047 traverseNode(child, context); 13048 } 13049 } 13050 function traverseNode(node, context) { 13051 context.currentNode = node; 13052 // apply transform plugins 13053 const { nodeTransforms } = context; 13054 const exitFns = []; 13055 for (let i = 0; i < nodeTransforms.length; i++) { 13056 const onExit = nodeTransforms[i](node, context); 13057 if (onExit) { 13058 if (isArray(onExit)) { 13059 exitFns.push(...onExit); 13060 } 13061 else { 13062 exitFns.push(onExit); 13063 } 13064 } 13065 if (!context.currentNode) { 13066 // node was removed 13067 return; 13068 } 13069 else { 13070 // node may have been replaced 13071 node = context.currentNode; 13072 } 13073 } 13074 switch (node.type) { 13075 case 3 /* NodeTypes.COMMENT */: 13076 if (!context.ssr) { 13077 // inject import for the Comment symbol, which is needed for creating 13078 // comment nodes with `createVNode` 13079 context.helper(CREATE_COMMENT); 13080 } 13081 break; 13082 case 5 /* NodeTypes.INTERPOLATION */: 13083 // no need to traverse, but we need to inject toString helper 13084 if (!context.ssr) { 13085 context.helper(TO_DISPLAY_STRING); 13086 } 13087 break; 13088 // for container types, further traverse downwards 13089 case 9 /* NodeTypes.IF */: 13090 for (let i = 0; i < node.branches.length; i++) {
vendor: 3,861 bytes, lines 13091-13196
13091 traverseNode(node.branches[i], context); 13092 } 13093 break; 13094 case 10 /* NodeTypes.IF_BRANCH */: 13095 case 11 /* NodeTypes.FOR */: 13096 case 1 /* NodeTypes.ELEMENT */: 13097 case 0 /* NodeTypes.ROOT */: 13098 traverseChildren(node, context); 13099 break; 13100 } 13101 // exit transforms 13102 context.currentNode = node; 13103 let i = exitFns.length; 13104 while (i--) { 13105 exitFns[i](); 13106 } 13107 } 13108 function createStructuralDirectiveTransform(name, fn) { 13109 const matches = isString(name) 13110 ? (n) => n === name 13111 : (n) => name.test(n); 13112 return (node, context) => { 13113 if (node.type === 1 /* NodeTypes.ELEMENT */) { 13114 const { props } = node; 13115 // structural directive transforms are not concerned with slots 13116 // as they are handled separately in vSlot.ts 13117 if (node.tagType === 3 /* ElementTypes.TEMPLATE */ && props.some(isVSlot)) { 13118 return; 13119 } 13120 const exitFns = []; 13121 for (let i = 0; i < props.length; i++) { 13122 const prop = props[i]; 13123 if (prop.type === 7 /* NodeTypes.DIRECTIVE */ && matches(prop.name)) { 13124 // structural directives are removed to avoid infinite recursion 13125 // also we remove them *before* applying so that it can further 13126 // traverse itself in case it moves the node around 13127 props.splice(i, 1); 13128 i--; 13129 const onExit = fn(node, prop, context); 13130 if (onExit) 13131 exitFns.push(onExit); 13132 } 13133 } 13134 return exitFns; 13135 } 13136 }; 13137 } 13138 13139 const PURE_ANNOTATION = `/*#__PURE__*/`; 13140 const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`; 13141 function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssrRuntimeModuleName = 'vue/server-renderer', ssr = false, isTS = false, inSSR = false }) { 13142 const context = { 13143 mode, 13144 prefixIdentifiers, 13145 sourceMap, 13146 filename, 13147 scopeId, 13148 optimizeImports, 13149 runtimeGlobalName, 13150 runtimeModuleName, 13151 ssrRuntimeModuleName, 13152 ssr, 13153 isTS, 13154 inSSR, 13155 source: ast.loc.source, 13156 code: ``, 13157 column: 1, 13158 line: 1, 13159 offset: 0, 13160 indentLevel: 0, 13161 pure: false, 13162 map: undefined, 13163 helper(key) { 13164 return `_${helperNameMap[key]}`; 13165 }, 13166 push(code, node) { 13167 context.code += code; 13168 }, 13169 indent() { 13170 newline(++context.indentLevel); 13171 }, 13172 deindent(withoutNewLine = false) { 13173 if (withoutNewLine) { 13174 --context.indentLevel; 13175 } 13176 else { 13177 newline(--context.indentLevel); 13178 } 13179 }, 13180 newline() { 13181 newline(context.indentLevel); 13182 } 13183 }; 13184 function newline(n) { 13185 context.push('\n' + ` `.repeat(n)); 13186 } 13187 return context; 13188 } 13189 function generate(ast, options = {}) { 13190 const context = createCodegenContext(ast, options); 13191 if (options.onContextCreated) 13192 options.onContextCreated(context); 13193 const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context; 13194 const helpers = Array.from(ast.helpers); 13195 const hasHelpers = helpers.length > 0; 13196 const useWithBlock = !prefixIdentifiers && mode !== 'module';
13197 const isSetupInlined = !true ; 13198 // preambles 13199 // in setup() inline mode, the preamble is generated in a sub context 13200 // and returned separately. 13201 const preambleContext = isSetupInlined 13202 ? createCodegenContext(ast, options) 13203 : context; 13204 { 13205 genFunctionPreamble(ast, preambleContext); 13206 } 13207 // enter render function 13208 const functionName = ssr ? `ssrRender` : `render`; 13209 const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache']; 13210 const signature = args.join(', '); 13211 { 13212 push(`function ${functionName}(${signature}) {`); 13213 } 13214 indent(); 13215 if (useWithBlock) { 13216 push(`with (_ctx) {`); 13217 indent(); 13218 // function mode const declarations should be inside with block 13219 // also they should be renamed to avoid collision with user properties 13220 if (hasHelpers) { 13221 push(`const { ${helpers.map(aliasHelper).join(', ')} } = _Vue`); 13222 push(`\n`); 13223 newline(); 13224 } 13225 } 13226 // generate asset resolution statements 13227 if (ast.components.length) { 13228 genAssets(ast.components, 'component', context); 13229 if (ast.directives.length || ast.temps > 0) { 13230 newline(); 13231 } 13232 } 13233 if (ast.directives.length) { 13234 genAssets(ast.directives, 'directive', context); 13235 if (ast.temps > 0) { 13236 newline(); 13237 } 13238 } 13239 if (ast.temps > 0) { 13240 push(`let `); 13241 for (let i = 0; i < ast.temps; i++) { 13242 push(`${i > 0 ? `, ` : ``}_temp${i}`); 13243 } 13244 } 13245 if (ast.components.length || ast.directives.length || ast.temps) { 13246 push(`\n`); 13247 newline(); 13248 } 13249 // generate the VNode tree expression 13250 if (!ssr) { 13251 push(`return `); 13252 } 13253 if (ast.codegenNode) { 13254 genNode(ast.codegenNode, context); 13255 } 13256 else { 13257 push(`null`); 13258 } 13259 if (useWithBlock) { 13260 deindent(); 13261 push(`}`); 13262 } 13263 deindent(); 13264 push(`}`); 13265 return { 13266 ast, 13267 code: context.code, 13268 preamble: isSetupInlined ? preambleContext.code : ``, 13269 // SourceMapGenerator does have toJSON() method but it's not in the types 13270 map: context.map ? context.map.toJSON() : undefined 13271 }; 13272 } 13273 function genFunctionPreamble(ast, context) { 13274 const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context; 13275 const VueBinding = runtimeGlobalName; 13276 // Generate const declaration for helpers 13277 // In prefix mode, we place the const declaration at top so it's done 13278 // only once; But if we not prefixing, we place the declaration inside the 13279 // with block so it doesn't incur the `in` check cost for every helper access. 13280 const helpers = Array.from(ast.helpers); 13281 if (helpers.length > 0) { 13282 { 13283 // "with" mode. 13284 // save Vue in a separate variable to avoid collision 13285 push(`const _Vue = ${VueBinding}\n`); 13286 // in "with" mode, helpers are declared inside the with block to avoid 13287 // has check cost, but hoists are lifted out of the function - we need 13288 // to provide the helper here. 13289 if (ast.hoists.length) { 13290 const staticHelpers = [ 13291 CREATE_VNODE, 13292 CREATE_ELEMENT_VNODE, 13293 CREATE_COMMENT, 13294 CREATE_TEXT, 13295 CREATE_STATIC 13296 ] 13297 .filter(helper => helpers.includes(helper)) 13298 .map(aliasHelper) 13299 .join(', '); 13300 push(`const { ${staticHelpers} } = _Vue\n`); 13301 } 13302 } 13303 } 13304 genHoists(ast.hoists, context); 13305 newline(); 13306 push(`return `); 13307 } 13308 function genAssets(assets, type, { helper, push, newline, isTS }) { 13309 const resolver = helper(type === 'component' 13310 ? RESOLVE_COMPONENT 13311 : RESOLVE_DIRECTIVE); 13312 for (let i = 0; i < assets.length; i++) { 13313 let id = assets[i]; 13314 // potential component implicit self-reference inferred from SFC filename 13315 const maybeSelfReference = id.endsWith('__self'); 13316 if (maybeSelfReference) { 13317 id = id.slice(0, -6); 13318 } 13319 push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`); 13320 if (i < assets.length - 1) { 13321 newline(); 13322 } 13323 } 13324 } 13325 function genHoists(hoists, context) { 13326 if (!hoists.length) { 13327 return; 13328 } 13329 context.pure = true; 13330 const { push, newline, helper, scopeId, mode } = context; 13331 newline(); 13332 for (let i = 0; i < hoists.length; i++) { 13333 const exp = hoists[i]; 13334 if (exp) { 13335 push(`const _hoisted_${i + 1} = ${``}`); 13336 genNode(exp, context); 13337 newline(); 13338 } 13339 } 13340 context.pure = false;
13341 } 13342 function isText(n) { 13343 return (isString(n) || 13344 n.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ || 13345 n.type === 2 /* NodeTypes.TEXT */ || 13346 n.type === 5 /* NodeTypes.INTERPOLATION */ || 13347 n.type === 8 /* NodeTypes.COMPOUND_EXPRESSION */); 13348 } 13349 function genNodeListAsArray(nodes, context) { 13350 const multilines = nodes.length > 3 || 13351 (nodes.some(n => isArray(n) || !isText(n))); 13352 context.push(`[`); 13353 multilines && context.indent(); 13354 genNodeList(nodes, context, multilines); 13355 multilines && context.deindent(); 13356 context.push(`]`); 13357 } 13358 function genNodeList(nodes, context, multilines = false, comma = true) { 13359 const { push, newline } = context; 13360 for (let i = 0; i < nodes.length; i++) { 13361 const node = nodes[i]; 13362 if (isString(node)) { 13363 push(node); 13364 } 13365 else if (isArray(node)) { 13366 genNodeListAsArray(node, context); 13367 } 13368 else { 13369 genNode(node, context); 13370 } 13371 if (i < nodes.length - 1) { 13372 if (multilines) { 13373 comma && push(','); 13374 newline(); 13375 } 13376 else { 13377 comma && push(', '); 13378 } 13379 } 13380 } 13381 } 13382 function genNode(node, context) { 13383 if (isString(node)) { 13384 context.push(node); 13385 return; 13386 } 13387 if (isSymbol(node)) { 13388 context.push(context.helper(node)); 13389 return; 13390 } 13391 switch (node.type) { 13392 case 1 /* NodeTypes.ELEMENT */: 13393 case 9 /* NodeTypes.IF */: 13394 case 11 /* NodeTypes.FOR */: 13395 assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` + 13396 `Apply appropriate transforms first.`); 13397 genNode(node.codegenNode, context); 13398 break; 13399 case 2 /* NodeTypes.TEXT */: 13400 genText(node, context); 13401 break; 13402 case 4 /* NodeTypes.SIMPLE_EXPRESSION */: 13403 genExpression(node, context); 13404 break; 13405 case 5 /* NodeTypes.INTERPOLATION */: 13406 genInterpolation(node, context); 13407 break; 13408 case 12 /* NodeTypes.TEXT_CALL */: 13409 genNode(node.codegenNode, context); 13410 break; 13411 case 8 /* NodeTypes.COMPOUND_EXPRESSION */: 13412 genCompoundExpression(node, context); 13413 break; 13414 case 3 /* NodeTypes.COMMENT */: 13415 genComment(node, context); 13416 break; 13417 case 13 /* NodeTypes.VNODE_CALL */: 13418 genVNodeCall(node, context); 13419 break; 13420 case 14 /* NodeTypes.JS_CALL_EXPRESSION */: 13421 genCallExpression(node, context); 13422 break; 13423 case 15 /* NodeTypes.JS_OBJECT_EXPRESSION */: 13424 genObjectExpression(node, context); 13425 break; 13426 case 17 /* NodeTypes.JS_ARRAY_EXPRESSION */: 13427 genArrayExpression(node, context); 13428 break; 13429 case 18 /* NodeTypes.JS_FUNCTION_EXPRESSION */: 13430 genFunctionExpression(node, context); 13431 break; 13432 case 19 /* NodeTypes.JS_CONDITIONAL_EXPRESSION */: 13433 genConditionalExpression(node, context); 13434 break; 13435 case 20 /* NodeTypes.JS_CACHE_EXPRESSION */: 13436 genCacheExpression(node, context); 13437 break; 13438 case 21 /* NodeTypes.JS_BLOCK_STATEMENT */: 13439 genNodeList(node.body, context, true, false); 13440 break; 13441 // SSR only types 13442 case 22 /* NodeTypes.JS_TEMPLATE_LITERAL */: 13443 break; 13444 case 23 /* NodeTypes.JS_IF_STATEMENT */: 13445 break; 13446 case 24 /* NodeTypes.JS_ASSIGNMENT_EXPRESSION */: 13447 break; 13448 case 25 /* NodeTypes.JS_SEQUENCE_EXPRESSION */: 13449 break; 13450 case 26 /* NodeTypes.JS_RETURN_STATEMENT */: 13451 break; 13452 /* istanbul ignore next */ 13453 case 10 /* NodeTypes.IF_BRANCH */: 13454 // noop 13455 break; 13456 default: 13457 { 13458 assert(false, `unhandled codegen node type: ${node.type}`); 13459 // make sure we exhaust all possible types 13460 const exhaustiveCheck = node; 13461 return exhaustiveCheck; 13462 } 13463 } 13464 } 13465 function genText(node, context) { 13466 context.push(JSON.stringify(node.content), node); 13467 } 13468 function genExpression(node, context) { 13469 const { content, isStatic } = node; 13470 context.push(isStatic ? JSON.stringify(content) : content, node); 13471 } 13472 function genInterpolation(node, context) { 13473 const { push, helper, pure } = context; 13474 if (pure) 13475 push(PURE_ANNOTATION); 13476 push(`${helper(TO_DISPLAY_STRING)}(`); 13477 genNode(node.content, context); 13478 push(`)`); 13479 } 13480 function genCompoundExpression(node, context) { 13481 for (let i = 0; i < node.children.length; i++) { 13482 const child = node.children[i]; 13483 if (isString(child)) { 13484 context.push(child); 13485 } 13486 else {
vendor: 4,933 bytes, lines 13487-13647
13487 genNode(child, context); 13488 } 13489 } 13490 } 13491 function genExpressionAsPropertyKey(node, context) { 13492 const { push } = context; 13493 if (node.type === 8 /* NodeTypes.COMPOUND_EXPRESSION */) { 13494 push(`[`); 13495 genCompoundExpression(node, context); 13496 push(`]`); 13497 } 13498 else if (node.isStatic) { 13499 // only quote keys if necessary 13500 const text = isSimpleIdentifier(node.content) 13501 ? node.content 13502 : JSON.stringify(node.content); 13503 push(text, node); 13504 } 13505 else { 13506 push(`[${node.content}]`, node); 13507 } 13508 } 13509 function genComment(node, context) { 13510 const { push, helper, pure } = context; 13511 if (pure) { 13512 push(PURE_ANNOTATION); 13513 } 13514 push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node); 13515 } 13516 function genVNodeCall(node, context) { 13517 const { push, helper, pure } = context; 13518 const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node; 13519 if (directives) { 13520 push(helper(WITH_DIRECTIVES) + `(`); 13521 } 13522 if (isBlock) { 13523 push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `); 13524 } 13525 if (pure) { 13526 push(PURE_ANNOTATION); 13527 } 13528 const callHelper = isBlock 13529 ? getVNodeBlockHelper(context.inSSR, isComponent) 13530 : getVNodeHelper(context.inSSR, isComponent); 13531 push(helper(callHelper) + `(`, node); 13532 genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context); 13533 push(`)`); 13534 if (isBlock) { 13535 push(`)`); 13536 } 13537 if (directives) { 13538 push(`, `); 13539 genNode(directives, context); 13540 push(`)`); 13541 } 13542 } 13543 function genNullableArgs(args) { 13544 let i = args.length; 13545 while (i--) { 13546 if (args[i] != null) 13547 break; 13548 } 13549 return args.slice(0, i + 1).map(arg => arg || `null`); 13550 } 13551 // JavaScript 13552 function genCallExpression(node, context) { 13553 const { push, helper, pure } = context; 13554 const callee = isString(node.callee) ? node.callee : helper(node.callee); 13555 if (pure) { 13556 push(PURE_ANNOTATION); 13557 } 13558 push(callee + `(`, node); 13559 genNodeList(node.arguments, context); 13560 push(`)`); 13561 } 13562 function genObjectExpression(node, context) { 13563 const { push, indent, deindent, newline } = context; 13564 const { properties } = node; 13565 if (!properties.length) { 13566 push(`{}`, node); 13567 return; 13568 } 13569 const multilines = properties.length > 1 || 13570 (properties.some(p => p.value.type !== 4 /* NodeTypes.SIMPLE_EXPRESSION */)); 13571 push(multilines ? `{` : `{ `); 13572 multilines && indent(); 13573 for (let i = 0; i < properties.length; i++) { 13574 const { key, value } = properties[i]; 13575 // key 13576 genExpressionAsPropertyKey(key, context); 13577 push(`: `); 13578 // value 13579 genNode(value, context); 13580 if (i < properties.length - 1) { 13581 // will only reach this if it's multilines 13582 push(`,`); 13583 newline(); 13584 } 13585 } 13586 multilines && deindent(); 13587 push(multilines ? `}` : ` }`); 13588 } 13589 function genArrayExpression(node, context) { 13590 genNodeListAsArray(node.elements, context); 13591 } 13592 function genFunctionExpression(node, context) { 13593 const { push, indent, deindent } = context; 13594 const { params, returns, body, newline, isSlot } = node; 13595 if (isSlot) { 13596 // wrap slot functions with owner context 13597 push(`_${helperNameMap[WITH_CTX]}(`); 13598 } 13599 push(`(`, node); 13600 if (isArray(params)) { 13601 genNodeList(params, context); 13602 } 13603 else if (params) { 13604 genNode(params, context); 13605 } 13606 push(`) => `); 13607 if (newline || body) { 13608 push(`{`); 13609 indent(); 13610 } 13611 if (returns) { 13612 if (newline) { 13613 push(`return `); 13614 } 13615 if (isArray(returns)) { 13616 genNodeListAsArray(returns, context); 13617 } 13618 else { 13619 genNode(returns, context); 13620 } 13621 } 13622 else if (body) { 13623 genNode(body, context); 13624 } 13625 if (newline || body) { 13626 deindent(); 13627 push(`}`); 13628 } 13629 if (isSlot) { 13630 push(`)`); 13631 } 13632 } 13633 function genConditionalExpression(node, context) { 13634 const { test, consequent, alternate, newline: needNewline } = node; 13635 const { push, indent, deindent, newline } = context; 13636 if (test.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) { 13637 const needsParens = !isSimpleIdentifier(test.content); 13638 needsParens && push(`(`); 13639 genExpression(test, context); 13640 needsParens && push(`)`); 13641 } 13642 else { 13643 push(`(`); 13644 genNode(test, context); 13645 push(`)`); 13646 } 13647 needNewline && indent();
13648 context.indentLevel++; 13649 needNewline || push(` `); 13650 push(`? `); 13651 genNode(consequent, context); 13652 context.indentLevel--; 13653 needNewline && newline(); 13654 needNewline || push(` `); 13655 push(`: `); 13656 const isNested = alternate.type === 19 /* NodeTypes.JS_CONDITIONAL_EXPRESSION */; 13657 if (!isNested) { 13658 context.indentLevel++; 13659 } 13660 genNode(alternate, context); 13661 if (!isNested) { 13662 context.indentLevel--; 13663 } 13664 needNewline && deindent(true /* without newline */); 13665 } 13666 function genCacheExpression(node, context) { 13667 const { push, helper, indent, deindent, newline } = context; 13668 push(`_cache[${node.index}] || (`); 13669 if (node.isVNode) { 13670 indent(); 13671 push(`${helper(SET_BLOCK_TRACKING)}(-1),`); 13672 newline(); 13673 } 13674 push(`_cache[${node.index}] = `); 13675 genNode(node.value, context); 13676 if (node.isVNode) { 13677 push(`,`); 13678 newline(); 13679 push(`${helper(SET_BLOCK_TRACKING)}(1),`); 13680 newline(); 13681 push(`_cache[${node.index}]`); 13682 deindent(); 13683 } 13684 push(`)`); 13685 } 13686 13687 // these keywords should not appear inside expressions, but operators like 13688 // 'typeof', 'instanceof', and 'in' are allowed 13689 const prohibitedKeywordRE = new RegExp('\\b' + 13690 ('arguments,await,break,case,catch,class,const,continue,debugger,default,' + 13691 'delete,do,else,export,extends,finally,for,function,if,import,let,new,' + 13692 'return,super,switch,throw,try,var,void,while,with,yield') 13693 .split(',') 13694 .join('\\b|\\b') + 13695 '\\b'); 13696 // strip strings in expressions 13697 const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g; 13698 /** 13699 * Validate a non-prefixed expression. 13700 * This is only called when using the in-browser runtime compiler since it 13701 * doesn't prefix expressions. 13702 */ 13703 function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) { 13704 const exp = node.content; 13705 // empty expressions are validated per-directive since some directives 13706 // do allow empty expressions. 13707 if (!exp.trim()) { 13708 return; 13709 } 13710 try { 13711 new Function(asRawStatements 13712 ? ` ${exp} ` 13713 : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`); 13714 } 13715 catch (e) { 13716 let message = e.message; 13717 const keywordMatch = exp 13718 .replace(stripStringRE, '') 13719 .match(prohibitedKeywordRE); 13720 if (keywordMatch) { 13721 message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`; 13722 } 13723 context.onError(createCompilerError(45 /* ErrorCodes.X_INVALID_EXPRESSION */, node.loc, undefined, message)); 13724 } 13725 } 13726 13727 const transformExpression = (node, context) => { 13728 if (node.type === 5 /* NodeTypes.INTERPOLATION */) { 13729 node.content = processExpression(node.content, context); 13730 } 13731 else if (node.type === 1 /* NodeTypes.ELEMENT */) { 13732 // handle directives on element 13733 for (let i = 0; i < node.props.length; i++) { 13734 const dir = node.props[i]; 13735 // do not process for v-on & v-for since they are special handled 13736 if (dir.type === 7 /* NodeTypes.DIRECTIVE */ && dir.name !== 'for') { 13737 const exp = dir.exp; 13738 const arg = dir.arg; 13739 // do not process exp if this is v-on:arg - we need special handling 13740 // for wrapping inline statements. 13741 if (exp && 13742 exp.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && 13743 !(dir.name === 'on' && arg)) { 13744 dir.exp = processExpression(exp, context, 13745 // slot args must be processed as function params 13746 dir.name === 'slot'); 13747 } 13748 if (arg && arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && !arg.isStatic) { 13749 dir.arg = processExpression(arg, context); 13750 } 13751 } 13752 } 13753 } 13754 };
vendor: 4,700 bytes, lines 13755-13859
13755 // Important: since this function uses Node.js only dependencies, it should 13756 // always be used with a leading !true check so that it can be 13757 // tree-shaken from the browser build. 13758 function processExpression(node, context, 13759 // some expressions like v-slot props & v-for aliases should be parsed as 13760 // function params 13761 asParams = false, 13762 // v-on handler values may contain multiple statements 13763 asRawStatements = false, localVars = Object.create(context.identifiers)) { 13764 { 13765 { 13766 // simple in-browser validation (same logic in 2.x) 13767 validateBrowserExpression(node, context, asParams, asRawStatements); 13768 } 13769 return node; 13770 } 13771 } 13772 13773 const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => { 13774 return processIf(node, dir, context, (ifNode, branch, isRoot) => { 13775 // #1587: We need to dynamically increment the key based on the current 13776 // node's sibling nodes, since chained v-if/else branches are 13777 // rendered at the same depth 13778 const siblings = context.parent.children; 13779 let i = siblings.indexOf(ifNode); 13780 let key = 0; 13781 while (i-- >= 0) { 13782 const sibling = siblings[i]; 13783 if (sibling && sibling.type === 9 /* NodeTypes.IF */) { 13784 key += sibling.branches.length; 13785 } 13786 } 13787 // Exit callback. Complete the codegenNode when all children have been 13788 // transformed. 13789 return () => { 13790 if (isRoot) { 13791 ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context); 13792 } 13793 else { 13794 // attach this branch's codegen node to the v-if root. 13795 const parentCondition = getParentCondition(ifNode.codegenNode); 13796 parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context); 13797 } 13798 }; 13799 }); 13800 }); 13801 // target-agnostic transform used for both Client and SSR 13802 function processIf(node, dir, context, processCodegen) { 13803 if (dir.name !== 'else' && 13804 (!dir.exp || !dir.exp.content.trim())) { 13805 const loc = dir.exp ? dir.exp.loc : node.loc; 13806 context.onError(createCompilerError(28 /* ErrorCodes.X_V_IF_NO_EXPRESSION */, dir.loc)); 13807 dir.exp = createSimpleExpression(`true`, false, loc); 13808 } 13809 if (dir.exp) { 13810 validateBrowserExpression(dir.exp, context); 13811 } 13812 if (dir.name === 'if') { 13813 const branch = createIfBranch(node, dir); 13814 const ifNode = { 13815 type: 9 /* NodeTypes.IF */, 13816 loc: node.loc, 13817 branches: [branch] 13818 }; 13819 context.replaceNode(ifNode); 13820 if (processCodegen) { 13821 return processCodegen(ifNode, branch, true); 13822 } 13823 } 13824 else { 13825 // locate the adjacent v-if 13826 const siblings = context.parent.children; 13827 const comments = []; 13828 let i = siblings.indexOf(node); 13829 while (i-- >= -1) { 13830 const sibling = siblings[i]; 13831 if (sibling && sibling.type === 3 /* NodeTypes.COMMENT */) { 13832 context.removeNode(sibling); 13833 comments.unshift(sibling); 13834 continue; 13835 } 13836 if (sibling && 13837 sibling.type === 2 /* NodeTypes.TEXT */ && 13838 !sibling.content.trim().length) { 13839 context.removeNode(sibling); 13840 continue; 13841 } 13842 if (sibling && sibling.type === 9 /* NodeTypes.IF */) { 13843 // Check if v-else was followed by v-else-if 13844 if (dir.name === 'else-if' && 13845 sibling.branches[sibling.branches.length - 1].condition === undefined) { 13846 context.onError(createCompilerError(30 /* ErrorCodes.X_V_ELSE_NO_ADJACENT_IF */, node.loc)); 13847 } 13848 // move the node to the if node's branches 13849 context.removeNode(); 13850 const branch = createIfBranch(node, dir); 13851 if (comments.length && 13852 // #3619 ignore comments if the v-if is direct child of <transition> 13853 !(context.parent && 13854 context.parent.type === 1 /* NodeTypes.ELEMENT */ && 13855 isBuiltInType(context.parent.tag, 'transition'))) { 13856 branch.children = [...comments, ...branch.children]; 13857 } 13858 // check if user is forcing same key on different branches 13859 {
13860 const key = branch.userKey; 13861 if (key) { 13862 sibling.branches.forEach(({ userKey }) => { 13863 if (isSameKey(userKey, key)) { 13864 context.onError(createCompilerError(29 /* ErrorCodes.X_V_IF_SAME_KEY */, branch.userKey.loc)); 13865 } 13866 }); 13867 } 13868 } 13869 sibling.branches.push(branch); 13870 const onExit = processCodegen && processCodegen(sibling, branch, false); 13871 // since the branch was removed, it will not be traversed. 13872 // make sure to traverse here. 13873 traverseNode(branch, context); 13874 // call on exit 13875 if (onExit) 13876 onExit(); 13877 // make sure to reset currentNode after traversal to indicate this 13878 // node has been removed. 13879 context.currentNode = null; 13880 } 13881 else { 13882 context.onError(createCompilerError(30 /* ErrorCodes.X_V_ELSE_NO_ADJACENT_IF */, node.loc)); 13883 } 13884 break; 13885 } 13886 } 13887 } 13888 function createIfBranch(node, dir) { 13889 const isTemplateIf = node.tagType === 3 /* ElementTypes.TEMPLATE */; 13890 return { 13891 type: 10 /* NodeTypes.IF_BRANCH */, 13892 loc: node.loc, 13893 condition: dir.name === 'else' ? undefined : dir.exp, 13894 children: isTemplateIf && !findDir(node, 'for') ? node.children : [node], 13895 userKey: findProp(node, `key`), 13896 isTemplateIf 13897 }; 13898 } 13899 function createCodegenNodeForBranch(branch, keyIndex, context) { 13900 if (branch.condition) { 13901 return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context), 13902 // make sure to pass in asBlock: true so that the comment node call 13903 // closes the current block. 13904 createCallExpression(context.helper(CREATE_COMMENT), [ 13905 '"v-if"' , 13906 'true' 13907 ])); 13908 } 13909 else { 13910 return createChildrenCodegenNode(branch, keyIndex, context); 13911 } 13912 } 13913 function createChildrenCodegenNode(branch, keyIndex, context) { 13914 const { helper } = context; 13915 const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* ConstantTypes.CAN_HOIST */)); 13916 const { children } = branch; 13917 const firstChild = children[0]; 13918 const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* NodeTypes.ELEMENT */; 13919 if (needFragmentWrapper) { 13920 if (children.length === 1 && firstChild.type === 11 /* NodeTypes.FOR */) { 13921 // optimize away nested fragments when child is a ForNode 13922 const vnodeCall = firstChild.codegenNode; 13923 injectProp(vnodeCall, keyProperty, context); 13924 return vnodeCall; 13925 } 13926 else { 13927 let patchFlag = 64 /* PatchFlags.STABLE_FRAGMENT */; 13928 let patchFlagText = PatchFlagNames[64 /* PatchFlags.STABLE_FRAGMENT */]; 13929 // check if the fragment actually contains a single valid child with 13930 // the rest being comments 13931 if (!branch.isTemplateIf && 13932 children.filter(c => c.type !== 3 /* NodeTypes.COMMENT */).length === 1) { 13933 patchFlag |= 2048 /* PatchFlags.DEV_ROOT_FRAGMENT */; 13934 patchFlagText += `, ${PatchFlagNames[2048 /* PatchFlags.DEV_ROOT_FRAGMENT */]}`; 13935 } 13936 return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, false, false /* isComponent */, branch.loc); 13937 } 13938 } 13939 else { 13940 const ret = firstChild.codegenNode; 13941 const vnodeCall = getMemoedVNodeCall(ret); 13942 // Change createVNode to createBlock. 13943 if (vnodeCall.type === 13 /* NodeTypes.VNODE_CALL */) { 13944 makeBlock(vnodeCall, context); 13945 } 13946 // inject branch key
13947 injectProp(vnodeCall, keyProperty, context); 13948 return ret; 13949 } 13950 } 13951 function isSameKey(a, b) { 13952 if (!a || a.type !== b.type) { 13953 return false; 13954 } 13955 if (a.type === 6 /* NodeTypes.ATTRIBUTE */) { 13956 if (a.value.content !== b.value.content) { 13957 return false; 13958 } 13959 } 13960 else { 13961 // directive 13962 const exp = a.exp; 13963 const branchExp = b.exp; 13964 if (exp.type !== branchExp.type) { 13965 return false; 13966 } 13967 if (exp.type !== 4 /* NodeTypes.SIMPLE_EXPRESSION */ || 13968 exp.isStatic !== branchExp.isStatic || 13969 exp.content !== branchExp.content) { 13970 return false; 13971 } 13972 } 13973 return true; 13974 } 13975 function getParentCondition(node) { 13976 while (true) { 13977 if (node.type === 19 /* NodeTypes.JS_CONDITIONAL_EXPRESSION */) { 13978 if (node.alternate.type === 19 /* NodeTypes.JS_CONDITIONAL_EXPRESSION */) { 13979 node = node.alternate; 13980 } 13981 else { 13982 return node; 13983 } 13984 } 13985 else if (node.type === 20 /* NodeTypes.JS_CACHE_EXPRESSION */) { 13986 node = node.value; 13987 } 13988 } 13989 } 13990 13991 const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => { 13992 const { helper, removeHelper } = context; 13993 return processFor(node, dir, context, forNode => { 13994 // create the loop render function expression now, and add the 13995 // iterator on exit after all children have been traversed 13996 const renderExp = createCallExpression(helper(RENDER_LIST), [ 13997 forNode.source 13998 ]); 13999 const isTemplate = isTemplateNode(node); 14000 const memo = findDir(node, 'memo'); 14001 const keyProp = findProp(node, `key`); 14002 const keyExp = keyProp && 14003 (keyProp.type === 6 /* NodeTypes.ATTRIBUTE */ 14004 ? createSimpleExpression(keyProp.value.content, true) 14005 : keyProp.exp); 14006 const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null; 14007 const isStableFragment = forNode.source.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && 14008 forNode.source.constType > 0 /* ConstantTypes.NOT_CONSTANT */; 14009 const fragmentFlag = isStableFragment 14010 ? 64 /* PatchFlags.STABLE_FRAGMENT */ 14011 : keyProp 14012 ? 128 /* PatchFlags.KEYED_FRAGMENT */ 14013 : 256 /* PatchFlags.UNKEYED_FRAGMENT */; 14014 forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag + 14015 (` /* ${PatchFlagNames[fragmentFlag]} */` ), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc); 14016 return () => { 14017 // finish the codegen now that all children have been traversed 14018 let childBlock; 14019 const { children } = forNode; 14020 // check <template v-for> key placement 14021 if (isTemplate) { 14022 node.children.some(c => { 14023 if (c.type === 1 /* NodeTypes.ELEMENT */) { 14024 const key = findProp(c, 'key'); 14025 if (key) { 14026 context.onError(createCompilerError(33 /* ErrorCodes.X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc)); 14027 return true; 14028 } 14029 } 14030 }); 14031 } 14032 const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* NodeTypes.ELEMENT */; 14033 const slotOutlet = isSlotOutlet(node) 14034 ? node 14035 : isTemplate && 14036 node.children.length === 1 && 14037 isSlotOutlet(node.children[0]) 14038 ? node.children[0] // api-extractor somehow fails to infer this 14039 : null; 14040 if (slotOutlet) { 14041 // <slot v-for="..."> or <template v-for="..."><slot/></template> 14042 childBlock = slotOutlet.codegenNode; 14043 if (isTemplate && keyProperty) { 14044 // <template v-for="..." :key="..."><slot/></template> 14045 // we need to inject the key to the renderSlot() call. 14046 // the props for renderSlot is passed as the 3rd argument. 14047 injectProp(childBlock, keyProperty, context); 14048 } 14049 } 14050 else if (needFragmentWrapper) { 14051 // <template v-for="..."> with text or multi-elements 14052 // should generate a fragment block for each loop 14053 childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* PatchFlags.STABLE_FRAGMENT */ + 14054 (` /* ${PatchFlagNames[64 /* PatchFlags.STABLE_FRAGMENT */]} */` 14055 ), undefined, undefined, true, undefined, false /* isComponent */); 14056 } 14057 else { 14058 // Normal element v-for. Directly use the child's codegenNode 14059 // but mark it as a block. 14060 childBlock = children[0] 14061 .codegenNode; 14062 if (isTemplate && keyProperty) { 14063 injectProp(childBlock, keyProperty, context); 14064 } 14065 if (childBlock.isBlock !== !isStableFragment) { 14066 if (childBlock.isBlock) { 14067 // switch from block to vnode 14068 removeHelper(OPEN_BLOCK); 14069 removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent)); 14070 } 14071 else { 14072 // switch from vnode to block 14073 removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent)); 14074 } 14075 } 14076 childBlock.isBlock = !isStableFragment; 14077 if (childBlock.isBlock) { 14078 helper(OPEN_BLOCK); 14079 helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent)); 14080 } 14081 else { 14082 helper(getVNodeHelper(context.inSSR, childBlock.isComponent)); 14083 } 14084 } 14085 if (memo) { 14086 const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [ 14087 createSimpleExpression(`_cached`) 14088 ]));
14089 loop.body = createBlockStatement([ 14090 createCompoundExpression([`const _memo = (`, memo.exp, `)`]), 14091 createCompoundExpression([ 14092 `if (_cached`, 14093 ...(keyExp ? [` && _cached.key === `, keyExp] : []), 14094 ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached` 14095 ]), 14096 createCompoundExpression([`const _item = `, childBlock]), 14097 createSimpleExpression(`_item.memo = _memo`), 14098 createSimpleExpression(`return _item`) 14099 ]); 14100 renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++))); 14101 } 14102 else { 14103 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */)); 14104 } 14105 }; 14106 }); 14107 }); 14108 // target-agnostic transform used for both Client and SSR 14109 function processFor(node, dir, context, processCodegen) { 14110 if (!dir.exp) { 14111 context.onError(createCompilerError(31 /* ErrorCodes.X_V_FOR_NO_EXPRESSION */, dir.loc)); 14112 return; 14113 } 14114 const parseResult = parseForExpression( 14115 // can only be simple expression because vFor transform is applied 14116 // before expression transform. 14117 dir.exp, context); 14118 if (!parseResult) { 14119 context.onError(createCompilerError(32 /* ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION */, dir.loc)); 14120 return; 14121 } 14122 const { addIdentifiers, removeIdentifiers, scopes } = context; 14123 const { source, value, key, index } = parseResult; 14124 const forNode = { 14125 type: 11 /* NodeTypes.FOR */, 14126 loc: dir.loc, 14127 source, 14128 valueAlias: value, 14129 keyAlias: key, 14130 objectIndexAlias: index, 14131 parseResult, 14132 children: isTemplateNode(node) ? node.children : [node] 14133 }; 14134 context.replaceNode(forNode); 14135 // bookkeeping 14136 scopes.vFor++; 14137 const onExit = processCodegen && processCodegen(forNode); 14138 return () => { 14139 scopes.vFor--; 14140 if (onExit) 14141 onExit(); 14142 }; 14143 } 14144 const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/; 14145 // This regex doesn't cover the case if key or index aliases have destructuring, 14146 // but those do not make sense in the first place, so this works in practice. 14147 const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/; 14148 const stripParensRE = /^\(|\)$/g; 14149 function parseForExpression(input, context) { 14150 const loc = input.loc; 14151 const exp = input.content; 14152 const inMatch = exp.match(forAliasRE); 14153 if (!inMatch) 14154 return; 14155 const [, LHS, RHS] = inMatch; 14156 const result = { 14157 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)), 14158 value: undefined, 14159 key: undefined, 14160 index: undefined 14161 }; 14162 { 14163 validateBrowserExpression(result.source, context); 14164 } 14165 let valueContent = LHS.trim().replace(stripParensRE, '').trim(); 14166 const trimmedOffset = LHS.indexOf(valueContent); 14167 const iteratorMatch = valueContent.match(forIteratorRE); 14168 if (iteratorMatch) { 14169 valueContent = valueContent.replace(forIteratorRE, '').trim(); 14170 const keyContent = iteratorMatch[1].trim(); 14171 let keyOffset; 14172 if (keyContent) { 14173 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length); 14174 result.key = createAliasExpression(loc, keyContent, keyOffset); 14175 { 14176 validateBrowserExpression(result.key, context, true); 14177 } 14178 } 14179 if (iteratorMatch[2]) { 14180 const indexContent = iteratorMatch[2].trim(); 14181 if (indexContent) { 14182 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key 14183 ? keyOffset + keyContent.length 14184 : trimmedOffset + valueContent.length)); 14185 { 14186 validateBrowserExpression(result.index, context, true); 14187 } 14188 } 14189 } 14190 }
14191 if (valueContent) { 14192 result.value = createAliasExpression(loc, valueContent, trimmedOffset); 14193 { 14194 validateBrowserExpression(result.value, context, true); 14195 } 14196 } 14197 return result; 14198 } 14199 function createAliasExpression(range, content, offset) { 14200 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length)); 14201 } 14202 function createForLoopParams({ value, key, index }, memoArgs = []) { 14203 return createParamsList([value, key, index, ...memoArgs]); 14204 } 14205 function createParamsList(args) { 14206 let i = args.length; 14207 while (i--) { 14208 if (args[i]) 14209 break; 14210 } 14211 return args 14212 .slice(0, i + 1) 14213 .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false)); 14214 } 14215 14216 const defaultFallback = createSimpleExpression(`undefined`, false); 14217 // A NodeTransform that: 14218 // 1. Tracks scope identifiers for scoped slots so that they don't get prefixed 14219 // by transformExpression. This is only applied in non-browser builds with 14220 // { prefixIdentifiers: true }. 14221 // 2. Track v-slot depths so that we know a slot is inside another slot. 14222 // Note the exit callback is executed before buildSlots() on the same node, 14223 // so only nested slots see positive numbers. 14224 const trackSlotScopes = (node, context) => { 14225 if (node.type === 1 /* NodeTypes.ELEMENT */ && 14226 (node.tagType === 1 /* ElementTypes.COMPONENT */ || 14227 node.tagType === 3 /* ElementTypes.TEMPLATE */)) { 14228 // We are only checking non-empty v-slot here 14229 // since we only care about slots that introduce scope variables. 14230 const vSlot = findDir(node, 'slot'); 14231 if (vSlot) { 14232 vSlot.exp; 14233 context.scopes.vSlot++; 14234 return () => { 14235 context.scopes.vSlot--; 14236 }; 14237 } 14238 } 14239 }; 14240 const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc); 14241 // Instead of being a DirectiveTransform, v-slot processing is called during 14242 // transformElement to build the slots object for a component. 14243 function buildSlots(node, context, buildSlotFn = buildClientSlotFn) { 14244 context.helper(WITH_CTX); 14245 const { children, loc } = node; 14246 const slotsProperties = []; 14247 const dynamicSlots = []; 14248 // If the slot is inside a v-for or another v-slot, force it to be dynamic 14249 // since it likely uses a scope variable. 14250 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0; 14251 // 1. Check for slot with slotProps on component itself. 14252 // <Comp v-slot="{ prop }"/> 14253 const onComponentSlot = findDir(node, 'slot', true); 14254 if (onComponentSlot) { 14255 const { arg, exp } = onComponentSlot; 14256 if (arg && !isStaticExp(arg)) { 14257 hasDynamicSlots = true; 14258 } 14259 slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc))); 14260 } 14261 // 2. Iterate through children and check for template slots 14262 // <template v-slot:foo="{ prop }"> 14263 let hasTemplateSlots = false; 14264 let hasNamedDefaultSlot = false; 14265 const implicitDefaultChildren = []; 14266 const seenSlotNames = new Set(); 14267 let conditionalBranchIndex = 0; 14268 for (let i = 0; i < children.length; i++) { 14269 const slotElement = children[i]; 14270 let slotDir; 14271 if (!isTemplateNode(slotElement) || 14272 !(slotDir = findDir(slotElement, 'slot', true))) { 14273 // not a <template v-slot>, skip. 14274 if (slotElement.type !== 3 /* NodeTypes.COMMENT */) { 14275 implicitDefaultChildren.push(slotElement); 14276 } 14277 continue; 14278 } 14279 if (onComponentSlot) { 14280 // already has on-component slot - this is incorrect usage. 14281 context.onError(createCompilerError(37 /* ErrorCodes.X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc)); 14282 break; 14283 } 14284 hasTemplateSlots = true; 14285 const { children: slotChildren, loc: slotLoc } = slotElement; 14286 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir; 14287 // check if name is dynamic. 14288 let staticSlotName; 14289 if (isStaticExp(slotName)) { 14290 staticSlotName = slotName ? slotName.content : `default`; 14291 } 14292 else { 14293 hasDynamicSlots = true; 14294 } 14295 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc); 14296 // check if this slot is conditional (v-if/v-for) 14297 let vIf; 14298 let vElse; 14299 let vFor; 14300 if ((vIf = findDir(slotElement, 'if'))) { 14301 hasDynamicSlots = true; 14302 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction, conditionalBranchIndex++), defaultFallback)); 14303 } 14304 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) { 14305 // find adjacent v-if 14306 let j = i; 14307 let prev; 14308 while (j--) { 14309 prev = children[j]; 14310 if (prev.type !== 3 /* NodeTypes.COMMENT */) { 14311 break; 14312 } 14313 } 14314 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) { 14315 // remove node 14316 children.splice(i, 1); 14317 i--;
14318 // attach this slot to previous conditional 14319 let conditional = dynamicSlots[dynamicSlots.length - 1]; 14320 while (conditional.alternate.type === 19 /* NodeTypes.JS_CONDITIONAL_EXPRESSION */) { 14321 conditional = conditional.alternate; 14322 } 14323 conditional.alternate = vElse.exp 14324 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction, conditionalBranchIndex++), defaultFallback) 14325 : buildDynamicSlot(slotName, slotFunction, conditionalBranchIndex++); 14326 } 14327 else { 14328 context.onError(createCompilerError(30 /* ErrorCodes.X_V_ELSE_NO_ADJACENT_IF */, vElse.loc)); 14329 } 14330 } 14331 else if ((vFor = findDir(slotElement, 'for'))) { 14332 hasDynamicSlots = true; 14333 const parseResult = vFor.parseResult || 14334 parseForExpression(vFor.exp, context); 14335 if (parseResult) { 14336 // Render the dynamic slots as an array and add it to the createSlot() 14337 // args. The runtime knows how to handle it appropriately. 14338 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [ 14339 parseResult.source, 14340 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */) 14341 ])); 14342 } 14343 else { 14344 context.onError(createCompilerError(32 /* ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc)); 14345 } 14346 } 14347 else { 14348 // check duplicate static names 14349 if (staticSlotName) { 14350 if (seenSlotNames.has(staticSlotName)) { 14351 context.onError(createCompilerError(38 /* ErrorCodes.X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc)); 14352 continue; 14353 } 14354 seenSlotNames.add(staticSlotName); 14355 if (staticSlotName === 'default') { 14356 hasNamedDefaultSlot = true; 14357 } 14358 } 14359 slotsProperties.push(createObjectProperty(slotName, slotFunction)); 14360 } 14361 } 14362 if (!onComponentSlot) { 14363 const buildDefaultSlotProperty = (props, children) => { 14364 const fn = buildSlotFn(props, children, loc); 14365 return createObjectProperty(`default`, fn); 14366 }; 14367 if (!hasTemplateSlots) { 14368 // implicit default slot (on component) 14369 slotsProperties.push(buildDefaultSlotProperty(undefined, children)); 14370 } 14371 else if (implicitDefaultChildren.length && 14372 // #3766 14373 // with whitespace: 'preserve', whitespaces between slots will end up in 14374 // implicitDefaultChildren. Ignore if all implicit children are whitespaces. 14375 implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) { 14376 // implicit default slot (mixed with named slots) 14377 if (hasNamedDefaultSlot) { 14378 context.onError(createCompilerError(39 /* ErrorCodes.X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc)); 14379 } 14380 else { 14381 slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren)); 14382 } 14383 } 14384 } 14385 const slotFlag = hasDynamicSlots 14386 ? 2 /* SlotFlags.DYNAMIC */ 14387 : hasForwardedSlots(node.children) 14388 ? 3 /* SlotFlags.FORWARDED */ 14389 : 1 /* SlotFlags.STABLE */; 14390 let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, 14391 // 2 = compiled but dynamic = can skip normalization, but must run diff 14392 // 1 = compiled and static = can skip normalization AND diff as optimized 14393 createSimpleExpression(slotFlag + (` /* ${slotFlagsText[slotFlag]} */` ), false))), loc); 14394 if (dynamicSlots.length) { 14395 slots = createCallExpression(context.helper(CREATE_SLOTS), [ 14396 slots, 14397 createArrayExpression(dynamicSlots) 14398 ]); 14399 } 14400 return { 14401 slots, 14402 hasDynamicSlots 14403 }; 14404 } 14405 function buildDynamicSlot(name, fn, index) { 14406 const props = [ 14407 createObjectProperty(`name`, name), 14408 createObjectProperty(`fn`, fn) 14409 ]; 14410 if (index != null) { 14411 props.push(createObjectProperty(`key`, createSimpleExpression(String(index), true))); 14412 } 14413 return createObjectExpression(props); 14414 } 14415 function hasForwardedSlots(children) { 14416 for (let i = 0; i < children.length; i++) { 14417 const child = children[i]; 14418 switch (child.type) { 14419 case 1 /* NodeTypes.ELEMENT */: 14420 if (child.tagType === 2 /* ElementTypes.SLOT */ || 14421 hasForwardedSlots(child.children)) { 14422 return true; 14423 } 14424 break; 14425 case 9 /* NodeTypes.IF */: 14426 if (hasForwardedSlots(child.branches)) 14427 return true; 14428 break; 14429 case 10 /* NodeTypes.IF_BRANCH */: 14430 case 11 /* NodeTypes.FOR */: 14431 if (hasForwardedSlots(child.children)) 14432 return true; 14433 break; 14434 } 14435 } 14436 return false;
14437 } 14438 function isNonWhitespaceContent(node) { 14439 if (node.type !== 2 /* NodeTypes.TEXT */ && node.type !== 12 /* NodeTypes.TEXT_CALL */) 14440 return true; 14441 return node.type === 2 /* NodeTypes.TEXT */ 14442 ? !!node.content.trim() 14443 : isNonWhitespaceContent(node.content); 14444 } 14445 14446 // some directive transforms (e.g. v-model) may return a symbol for runtime 14447 // import, which should be used instead of a resolveDirective call. 14448 const directiveImportMap = new WeakMap(); 14449 // generate a JavaScript AST for this element's codegen 14450 const transformElement = (node, context) => { 14451 // perform the work on exit, after all child expressions have been 14452 // processed and merged. 14453 return function postTransformElement() { 14454 node = context.currentNode; 14455 if (!(node.type === 1 /* NodeTypes.ELEMENT */ && 14456 (node.tagType === 0 /* ElementTypes.ELEMENT */ || 14457 node.tagType === 1 /* ElementTypes.COMPONENT */))) { 14458 return; 14459 } 14460 const { tag, props } = node; 14461 const isComponent = node.tagType === 1 /* ElementTypes.COMPONENT */; 14462 // The goal of the transform is to create a codegenNode implementing the 14463 // VNodeCall interface. 14464 let vnodeTag = isComponent 14465 ? resolveComponentType(node, context) 14466 : `"${tag}"`; 14467 const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT; 14468 let vnodeProps; 14469 let vnodeChildren; 14470 let vnodePatchFlag; 14471 let patchFlag = 0; 14472 let vnodeDynamicProps; 14473 let dynamicPropNames; 14474 let vnodeDirectives; 14475 let shouldUseBlock = 14476 // dynamic component may resolve to plain elements 14477 isDynamicComponent || 14478 vnodeTag === TELEPORT || 14479 vnodeTag === SUSPENSE || 14480 (!isComponent && 14481 // <svg> and <foreignObject> must be forced into blocks so that block 14482 // updates inside get proper isSVG flag at runtime. (#639, #643) 14483 // This is technically web-specific, but splitting the logic out of core 14484 // leads to too much unnecessary complexity. 14485 (tag === 'svg' || tag === 'foreignObject')); 14486 // props 14487 if (props.length > 0) { 14488 const propsBuildResult = buildProps(node, context, undefined, isComponent, isDynamicComponent); 14489 vnodeProps = propsBuildResult.props; 14490 patchFlag = propsBuildResult.patchFlag; 14491 dynamicPropNames = propsBuildResult.dynamicPropNames; 14492 const directives = propsBuildResult.directives; 14493 vnodeDirectives = 14494 directives && directives.length 14495 ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context))) 14496 : undefined; 14497 if (propsBuildResult.shouldUseBlock) { 14498 shouldUseBlock = true; 14499 } 14500 } 14501 // children 14502 if (node.children.length > 0) { 14503 if (vnodeTag === KEEP_ALIVE) { 14504 // Although a built-in component, we compile KeepAlive with raw children 14505 // instead of slot functions so that it can be used inside Transition 14506 // or other Transition-wrapping HOCs. 14507 // To ensure correct updates with block optimizations, we need to: 14508 // 1. Force keep-alive into a block. This avoids its children being 14509 // collected by a parent block. 14510 shouldUseBlock = true; 14511 // 2. Force keep-alive to always be updated, since it uses raw children. 14512 patchFlag |= 1024 /* PatchFlags.DYNAMIC_SLOTS */; 14513 if (node.children.length > 1) { 14514 context.onError(createCompilerError(46 /* ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN */, { 14515 start: node.children[0].loc.start, 14516 end: node.children[node.children.length - 1].loc.end, 14517 source: '' 14518 })); 14519 } 14520 } 14521 const shouldBuildAsSlots = isComponent && 14522 // Teleport is not a real component and has dedicated runtime handling 14523 vnodeTag !== TELEPORT && 14524 // explained above. 14525 vnodeTag !== KEEP_ALIVE; 14526 if (shouldBuildAsSlots) { 14527 const { slots, hasDynamicSlots } = buildSlots(node, context); 14528 vnodeChildren = slots; 14529 if (hasDynamicSlots) { 14530 patchFlag |= 1024 /* PatchFlags.DYNAMIC_SLOTS */; 14531 } 14532 } 14533 else if (node.children.length === 1 && vnodeTag !== TELEPORT) { 14534 const child = node.children[0]; 14535 const type = child.type; 14536 // check for dynamic text children 14537 const hasDynamicTextChild = type === 5 /* NodeTypes.INTERPOLATION */ || 14538 type === 8 /* NodeTypes.COMPOUND_EXPRESSION */; 14539 if (hasDynamicTextChild &&
14540 getConstantType(child, context) === 0 /* ConstantTypes.NOT_CONSTANT */) { 14541 patchFlag |= 1 /* PatchFlags.TEXT */; 14542 } 14543 // pass directly if the only child is a text node 14544 // (plain / interpolation / expression) 14545 if (hasDynamicTextChild || type === 2 /* NodeTypes.TEXT */) { 14546 vnodeChildren = child; 14547 } 14548 else { 14549 vnodeChildren = node.children; 14550 } 14551 } 14552 else { 14553 vnodeChildren = node.children; 14554 } 14555 } 14556 // patchFlag & dynamicPropNames 14557 if (patchFlag !== 0) { 14558 { 14559 if (patchFlag < 0) { 14560 // special flags (negative and mutually exclusive) 14561 vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`; 14562 } 14563 else { 14564 // bitwise flags 14565 const flagNames = Object.keys(PatchFlagNames) 14566 .map(Number) 14567 .filter(n => n > 0 && patchFlag & n) 14568 .map(n => PatchFlagNames[n]) 14569 .join(`, `); 14570 vnodePatchFlag = patchFlag + ` /* ${flagNames} */`; 14571 } 14572 } 14573 if (dynamicPropNames && dynamicPropNames.length) { 14574 vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames); 14575 } 14576 } 14577 node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc); 14578 }; 14579 }; 14580 function resolveComponentType(node, context, ssr = false) { 14581 let { tag } = node; 14582 // 1. dynamic component 14583 const isExplicitDynamic = isComponentTag(tag); 14584 const isProp = findProp(node, 'is'); 14585 if (isProp) { 14586 if (isExplicitDynamic || 14587 (false )) { 14588 const exp = isProp.type === 6 /* NodeTypes.ATTRIBUTE */ 14589 ? isProp.value && createSimpleExpression(isProp.value.content, true) 14590 : isProp.exp; 14591 if (exp) { 14592 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [ 14593 exp 14594 ]); 14595 } 14596 } 14597 else if (isProp.type === 6 /* NodeTypes.ATTRIBUTE */ && 14598 isProp.value.content.startsWith('vue:')) { 14599 // <button is="vue:xxx"> 14600 // if not <component>, only is value that starts with "vue:" will be 14601 // treated as component by the parse phase and reach here, unless it's 14602 // compat mode where all is values are considered components 14603 tag = isProp.value.content.slice(4); 14604 } 14605 } 14606 // 1.5 v-is (TODO: Deprecate) 14607 const isDir = !isExplicitDynamic && findDir(node, 'is'); 14608 if (isDir && isDir.exp) { 14609 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [ 14610 isDir.exp 14611 ]); 14612 } 14613 // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...) 14614 const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag); 14615 if (builtIn) { 14616 // built-ins are simply fallthroughs / have special handling during ssr 14617 // so we don't need to import their runtime equivalents 14618 if (!ssr) 14619 context.helper(builtIn); 14620 return builtIn; 14621 } 14622 // 5. user component (resolve) 14623 context.helper(RESOLVE_COMPONENT); 14624 context.components.add(tag); 14625 return toValidAssetId(tag, `component`); 14626 } 14627 function buildProps(node, context, props = node.props, isComponent, isDynamicComponent, ssr = false) { 14628 const { tag, loc: elementLoc, children } = node; 14629 let properties = []; 14630 const mergeArgs = []; 14631 const runtimeDirectives = []; 14632 const hasChildren = children.length > 0; 14633 let shouldUseBlock = false;
14634 // patchFlag analysis 14635 let patchFlag = 0; 14636 let hasRef = false; 14637 let hasClassBinding = false; 14638 let hasStyleBinding = false; 14639 let hasHydrationEventBinding = false; 14640 let hasDynamicKeys = false; 14641 let hasVnodeHook = false; 14642 const dynamicPropNames = []; 14643 const pushMergeArg = (arg) => { 14644 if (properties.length) { 14645 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc)); 14646 properties = []; 14647 } 14648 if (arg) 14649 mergeArgs.push(arg); 14650 }; 14651 const analyzePatchFlag = ({ key, value }) => { 14652 if (isStaticExp(key)) { 14653 const name = key.content; 14654 const isEventHandler = isOn(name); 14655 if (isEventHandler && 14656 (!isComponent || isDynamicComponent) && 14657 // omit the flag for click handlers because hydration gives click 14658 // dedicated fast path. 14659 name.toLowerCase() !== 'onclick' && 14660 // omit v-model handlers 14661 name !== 'onUpdate:modelValue' && 14662 // omit onVnodeXXX hooks 14663 !isReservedProp(name)) { 14664 hasHydrationEventBinding = true; 14665 } 14666 if (isEventHandler && isReservedProp(name)) { 14667 hasVnodeHook = true; 14668 } 14669 if (value.type === 20 /* NodeTypes.JS_CACHE_EXPRESSION */ || 14670 ((value.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ || 14671 value.type === 8 /* NodeTypes.COMPOUND_EXPRESSION */) && 14672 getConstantType(value, context) > 0)) { 14673 // skip if the prop is a cached handler or has constant value 14674 return; 14675 } 14676 if (name === 'ref') { 14677 hasRef = true; 14678 } 14679 else if (name === 'class') { 14680 hasClassBinding = true; 14681 } 14682 else if (name === 'style') { 14683 hasStyleBinding = true; 14684 } 14685 else if (name !== 'key' && !dynamicPropNames.includes(name)) { 14686 dynamicPropNames.push(name); 14687 } 14688 // treat the dynamic class and style binding of the component as dynamic props 14689 if (isComponent && 14690 (name === 'class' || name === 'style') && 14691 !dynamicPropNames.includes(name)) { 14692 dynamicPropNames.push(name); 14693 } 14694 } 14695 else { 14696 hasDynamicKeys = true; 14697 } 14698 }; 14699 for (let i = 0; i < props.length; i++) { 14700 // static attribute 14701 const prop = props[i]; 14702 if (prop.type === 6 /* NodeTypes.ATTRIBUTE */) { 14703 const { loc, name, value } = prop; 14704 let isStatic = true; 14705 if (name === 'ref') { 14706 hasRef = true; 14707 if (context.scopes.vFor > 0) { 14708 properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true'))); 14709 } 14710 } 14711 // skip is on <component>, or is="vue:xxx" 14712 if (name === 'is' && 14713 (isComponentTag(tag) || 14714 (value && value.content.startsWith('vue:')) || 14715 (false ))) { 14716 continue; 14717 } 14718 properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc))); 14719 } 14720 else { 14721 // directives 14722 const { name, arg, exp, loc } = prop; 14723 const isVBind = name === 'bind'; 14724 const isVOn = name === 'on'; 14725 // skip v-slot - it is handled by its dedicated transform. 14726 if (name === 'slot') { 14727 if (!isComponent) { 14728 context.onError(createCompilerError(40 /* ErrorCodes.X_V_SLOT_MISPLACED */, loc)); 14729 } 14730 continue; 14731 } 14732 // skip v-once/v-memo - they are handled by dedicated transforms. 14733 if (name === 'once' || name === 'memo') { 14734 continue; 14735 } 14736 // skip v-is and :is on <component> 14737 if (name === 'is' || 14738 (isVBind && 14739 isStaticArgOf(arg, 'is') && 14740 (isComponentTag(tag) || 14741 (false )))) { 14742 continue; 14743 } 14744 // skip v-on in SSR compilation 14745 if (isVOn && ssr) { 14746 continue; 14747 } 14748 if ( 14749 // #938: elements with dynamic keys should be forced into blocks 14750 (isVBind && isStaticArgOf(arg, 'key')) || 14751 // inline before-update hooks need to force block so that it is invoked 14752 // before children 14753 (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) { 14754 shouldUseBlock = true; 14755 } 14756 if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) { 14757 properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true'))); 14758 } 14759 // special case for v-bind and v-on with no argument 14760 if (!arg && (isVBind || isVOn)) { 14761 hasDynamicKeys = true; 14762 if (exp) { 14763 if (isVBind) { 14764 // have to merge early for compat build check 14765 pushMergeArg(); 14766 mergeArgs.push(exp); 14767 } 14768 else { 14769 // v-on="obj" -> toHandlers(obj) 14770 pushMergeArg({ 14771 type: 14 /* NodeTypes.JS_CALL_EXPRESSION */, 14772 loc, 14773 callee: context.helper(TO_HANDLERS),
14774 arguments: isComponent ? [exp] : [exp, `true`] 14775 }); 14776 } 14777 } 14778 else { 14779 context.onError(createCompilerError(isVBind 14780 ? 34 /* ErrorCodes.X_V_BIND_NO_EXPRESSION */ 14781 : 35 /* ErrorCodes.X_V_ON_NO_EXPRESSION */, loc)); 14782 } 14783 continue; 14784 } 14785 const directiveTransform = context.directiveTransforms[name]; 14786 if (directiveTransform) { 14787 // has built-in directive transform. 14788 const { props, needRuntime } = directiveTransform(prop, node, context); 14789 !ssr && props.forEach(analyzePatchFlag); 14790 if (isVOn && arg && !isStaticExp(arg)) { 14791 pushMergeArg(createObjectExpression(props, elementLoc)); 14792 } 14793 else { 14794 properties.push(...props); 14795 } 14796 if (needRuntime) { 14797 runtimeDirectives.push(prop); 14798 if (isSymbol(needRuntime)) { 14799 directiveImportMap.set(prop, needRuntime); 14800 } 14801 } 14802 } 14803 else if (!isBuiltInDirective(name)) { 14804 // no built-in transform, this is a user custom directive. 14805 runtimeDirectives.push(prop); 14806 // custom dirs may use beforeUpdate so they need to force blocks 14807 // to ensure before-update gets called before children update 14808 if (hasChildren) { 14809 shouldUseBlock = true; 14810 } 14811 } 14812 } 14813 } 14814 let propsExpression = undefined; 14815 // has v-bind="object" or v-on="object", wrap with mergeProps 14816 if (mergeArgs.length) { 14817 // close up any not-yet-merged props 14818 pushMergeArg(); 14819 if (mergeArgs.length > 1) { 14820 propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc); 14821 } 14822 else { 14823 // single v-bind with nothing else - no need for a mergeProps call 14824 propsExpression = mergeArgs[0]; 14825 } 14826 } 14827 else if (properties.length) { 14828 propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc); 14829 } 14830 // patchFlag analysis 14831 if (hasDynamicKeys) { 14832 patchFlag |= 16 /* PatchFlags.FULL_PROPS */; 14833 } 14834 else { 14835 if (hasClassBinding && !isComponent) { 14836 patchFlag |= 2 /* PatchFlags.CLASS */; 14837 } 14838 if (hasStyleBinding && !isComponent) { 14839 patchFlag |= 4 /* PatchFlags.STYLE */; 14840 } 14841 if (dynamicPropNames.length) { 14842 patchFlag |= 8 /* PatchFlags.PROPS */; 14843 } 14844 if (hasHydrationEventBinding) { 14845 patchFlag |= 32 /* PatchFlags.HYDRATE_EVENTS */; 14846 } 14847 } 14848 if (!shouldUseBlock && 14849 (patchFlag === 0 || patchFlag === 32 /* PatchFlags.HYDRATE_EVENTS */) && 14850 (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) { 14851 patchFlag |= 512 /* PatchFlags.NEED_PATCH */; 14852 } 14853 // pre-normalize props, SSR is skipped for now 14854 if (!context.inSSR && propsExpression) { 14855 switch (propsExpression.type) { 14856 case 15 /* NodeTypes.JS_OBJECT_EXPRESSION */: 14857 // means that there is no v-bind, 14858 // but still need to deal with dynamic key binding 14859 let classKeyIndex = -1; 14860 let styleKeyIndex = -1; 14861 let hasDynamicKey = false; 14862 for (let i = 0; i < propsExpression.properties.length; i++) { 14863 const key = propsExpression.properties[i].key; 14864 if (isStaticExp(key)) { 14865 if (key.content === 'class') { 14866 classKeyIndex = i; 14867 } 14868 else if (key.content === 'style') { 14869 styleKeyIndex = i; 14870 } 14871 } 14872 else if (!key.isHandlerKey) { 14873 hasDynamicKey = true; 14874 } 14875 } 14876 const classProp = propsExpression.properties[classKeyIndex]; 14877 const styleProp = propsExpression.properties[styleKeyIndex]; 14878 // no dynamic key 14879 if (!hasDynamicKey) { 14880 if (classProp && !isStaticExp(classProp.value)) { 14881 classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]); 14882 } 14883 if (styleProp && 14884 // the static style is compiled into an object, 14885 // so use `hasStyleBinding` to ensure that it is a dynamic style binding 14886 (hasStyleBinding || 14887 (styleProp.value.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && 14888 styleProp.value.content.trim()[0] === `[`) || 14889 // v-bind:style and style both exist, 14890 // v-bind:style with static literal object 14891 styleProp.value.type === 17 /* NodeTypes.JS_ARRAY_EXPRESSION */)
vendor: 6,864 bytes, lines 14891-15079
14891) { 14892 styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]); 14893 } 14894 } 14895 else { 14896 // dynamic key binding, wrap with `normalizeProps` 14897 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]); 14898 } 14899 break; 14900 case 14 /* NodeTypes.JS_CALL_EXPRESSION */: 14901 // mergeProps call, do nothing 14902 break; 14903 default: 14904 // single v-bind 14905 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [ 14906 createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [ 14907 propsExpression 14908 ]) 14909 ]); 14910 break; 14911 } 14912 } 14913 return { 14914 props: propsExpression, 14915 directives: runtimeDirectives, 14916 patchFlag, 14917 dynamicPropNames, 14918 shouldUseBlock 14919 }; 14920 } 14921 // Dedupe props in an object literal. 14922 // Literal duplicated attributes would have been warned during the parse phase, 14923 // however, it's possible to encounter duplicated `onXXX` handlers with different 14924 // modifiers. We also need to merge static and dynamic class / style attributes. 14925 // - onXXX handlers / style: merge into array 14926 // - class: merge into single expression with concatenation 14927 function dedupeProperties(properties) { 14928 const knownProps = new Map(); 14929 const deduped = []; 14930 for (let i = 0; i < properties.length; i++) { 14931 const prop = properties[i]; 14932 // dynamic keys are always allowed 14933 if (prop.key.type === 8 /* NodeTypes.COMPOUND_EXPRESSION */ || !prop.key.isStatic) { 14934 deduped.push(prop); 14935 continue; 14936 } 14937 const name = prop.key.content; 14938 const existing = knownProps.get(name); 14939 if (existing) { 14940 if (name === 'style' || name === 'class' || isOn(name)) { 14941 mergeAsArray(existing, prop); 14942 } 14943 // unexpected duplicate, should have emitted error during parse 14944 } 14945 else { 14946 knownProps.set(name, prop); 14947 deduped.push(prop); 14948 } 14949 } 14950 return deduped; 14951 } 14952 function mergeAsArray(existing, incoming) { 14953 if (existing.value.type === 17 /* NodeTypes.JS_ARRAY_EXPRESSION */) { 14954 existing.value.elements.push(incoming.value); 14955 } 14956 else { 14957 existing.value = createArrayExpression([existing.value, incoming.value], existing.loc); 14958 } 14959 } 14960 function buildDirectiveArgs(dir, context) { 14961 const dirArgs = []; 14962 const runtime = directiveImportMap.get(dir); 14963 if (runtime) { 14964 // built-in directive with runtime 14965 dirArgs.push(context.helperString(runtime)); 14966 } 14967 else { 14968 { 14969 // inject statement for resolving directive 14970 context.helper(RESOLVE_DIRECTIVE); 14971 context.directives.add(dir.name); 14972 dirArgs.push(toValidAssetId(dir.name, `directive`)); 14973 } 14974 } 14975 const { loc } = dir; 14976 if (dir.exp) 14977 dirArgs.push(dir.exp); 14978 if (dir.arg) { 14979 if (!dir.exp) { 14980 dirArgs.push(`void 0`); 14981 } 14982 dirArgs.push(dir.arg); 14983 } 14984 if (Object.keys(dir.modifiers).length) { 14985 if (!dir.arg) { 14986 if (!dir.exp) { 14987 dirArgs.push(`void 0`); 14988 } 14989 dirArgs.push(`void 0`); 14990 } 14991 const trueExpression = createSimpleExpression(`true`, false, loc); 14992 dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc)); 14993 } 14994 return createArrayExpression(dirArgs, dir.loc); 14995 } 14996 function stringifyDynamicPropNames(props) { 14997 let propsNamesString = `[`; 14998 for (let i = 0, l = props.length; i < l; i++) { 14999 propsNamesString += JSON.stringify(props[i]); 15000 if (i < l - 1) 15001 propsNamesString += ', '; 15002 } 15003 return propsNamesString + `]`; 15004 } 15005 function isComponentTag(tag) { 15006 return tag === 'component' || tag === 'Component'; 15007 } 15008 15009 const transformSlotOutlet = (node, context) => { 15010 if (isSlotOutlet(node)) { 15011 const { children, loc } = node; 15012 const { slotName, slotProps } = processSlotOutlet(node, context); 15013 const slotArgs = [ 15014 context.prefixIdentifiers ? `_ctx.$slots` : `$slots`, 15015 slotName, 15016 '{}', 15017 'undefined', 15018 'true' 15019 ]; 15020 let expectedLen = 2; 15021 if (slotProps) { 15022 slotArgs[2] = slotProps; 15023 expectedLen = 3; 15024 } 15025 if (children.length) { 15026 slotArgs[3] = createFunctionExpression([], children, false, false, loc); 15027 expectedLen = 4; 15028 } 15029 if (context.scopeId && !context.slotted) { 15030 expectedLen = 5; 15031 } 15032 slotArgs.splice(expectedLen); // remove unused arguments 15033 node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc); 15034 } 15035 }; 15036 function processSlotOutlet(node, context) { 15037 let slotName = `"default"`; 15038 let slotProps = undefined; 15039 const nonNameProps = []; 15040 for (let i = 0; i < node.props.length; i++) { 15041 const p = node.props[i]; 15042 if (p.type === 6 /* NodeTypes.ATTRIBUTE */) { 15043 if (p.value) { 15044 if (p.name === 'name') { 15045 slotName = JSON.stringify(p.value.content); 15046 } 15047 else { 15048 p.name = camelize(p.name); 15049 nonNameProps.push(p); 15050 } 15051 } 15052 } 15053 else { 15054 if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) { 15055 if (p.exp) 15056 slotName = p.exp; 15057 } 15058 else { 15059 if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) { 15060 p.arg.content = camelize(p.arg.content); 15061 } 15062 nonNameProps.push(p); 15063 } 15064 } 15065 } 15066 if (nonNameProps.length > 0) { 15067 const { props, directives } = buildProps(node, context, nonNameProps, false, false); 15068 slotProps = props; 15069 if (directives.length) { 15070 context.onError(createCompilerError(36 /* ErrorCodes.X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc)); 15071 } 15072 } 15073 return { 15074 slotName, 15075 slotProps 15076 }; 15077 } 15078 15079 const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*(:[^=]+)?=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/;
15080 const transformOn$1 = (dir, node, context, augmentor) => { 15081 const { loc, modifiers, arg } = dir; 15082 if (!dir.exp && !modifiers.length) { 15083 context.onError(createCompilerError(35 /* ErrorCodes.X_V_ON_NO_EXPRESSION */, loc)); 15084 } 15085 let eventName; 15086 if (arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) { 15087 if (arg.isStatic) { 15088 let rawName = arg.content; 15089 // TODO deprecate @vnodeXXX usage 15090 if (rawName.startsWith('vue:')) { 15091 rawName = `vnode-${rawName.slice(4)}`; 15092 } 15093 const eventString = node.tagType !== 0 /* ElementTypes.ELEMENT */ || 15094 rawName.startsWith('vnode') || 15095 !/[A-Z]/.test(rawName) 15096 ? // for non-element and vnode lifecycle event listeners, auto convert 15097 // it to camelCase. See issue #2249 15098 toHandlerKey(camelize(rawName)) 15099 : // preserve case for plain element listeners that have uppercase 15100 // letters, as these may be custom elements' custom events 15101 `on:${rawName}`; 15102 eventName = createSimpleExpression(eventString, true, arg.loc); 15103 } 15104 else { 15105 // #2388 15106 eventName = createCompoundExpression([ 15107 `${context.helperString(TO_HANDLER_KEY)}(`, 15108 arg, 15109 `)` 15110 ]); 15111 } 15112 } 15113 else { 15114 // already a compound expression. 15115 eventName = arg; 15116 eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`); 15117 eventName.children.push(`)`); 15118 } 15119 // handler processing 15120 let exp = dir.exp; 15121 if (exp && !exp.content.trim()) { 15122 exp = undefined; 15123 } 15124 let shouldCache = context.cacheHandlers && !exp && !context.inVOnce; 15125 if (exp) { 15126 const isMemberExp = isMemberExpression(exp.content); 15127 const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content)); 15128 const hasMultipleStatements = exp.content.includes(`;`); 15129 { 15130 validateBrowserExpression(exp, context, false, hasMultipleStatements); 15131 } 15132 if (isInlineStatement || (shouldCache && isMemberExp)) { 15133 // wrap inline statement in a function expression 15134 exp = createCompoundExpression([ 15135 `${isInlineStatement 15136 ? `$event` 15137 : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`, 15138 exp, 15139 hasMultipleStatements ? `}` : `)` 15140 ]); 15141 } 15142 } 15143 let ret = { 15144 props: [ 15145 createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc)) 15146 ] 15147 }; 15148 // apply extended compiler augmentor 15149 if (augmentor) { 15150 ret = augmentor(ret); 15151 } 15152 if (shouldCache) { 15153 // cache handlers so that it's always the same handler being passed down. 15154 // this avoids unnecessary re-renders when users use inline handlers on 15155 // components. 15156 ret.props[0].value = context.cache(ret.props[0].value); 15157 } 15158 // mark the key as handler for props normalization check 15159 ret.props.forEach(p => (p.key.isHandlerKey = true)); 15160 return ret; 15161 }; 15162 15163 // v-bind without arg is handled directly in ./transformElements.ts due to it affecting 15164 // codegen for the entire props object. This transform here is only for v-bind 15165 // *with* args. 15166 const transformBind = (dir, _node, context) => { 15167 const { exp, modifiers, loc } = dir; 15168 const arg = dir.arg; 15169 if (arg.type !== 4 /* NodeTypes.SIMPLE_EXPRESSION */) { 15170 arg.children.unshift(`(`); 15171 arg.children.push(`) || ""`); 15172 } 15173 else if (!arg.isStatic) { 15174 arg.content = `${arg.content} || ""`; 15175 } 15176 // .sync is replaced by v-model:arg 15177 if (modifiers.includes('camel')) { 15178 if (arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) { 15179 if (arg.isStatic) { 15180 arg.content = camelize(arg.content); 15181 } 15182 else { 15183 arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`; 15184 } 15185 } 15186 else { 15187 arg.children.unshift(`${context.helperString(CAMELIZE)}(`); 15188 arg.children.push(`)`); 15189 } 15190 } 15191 if (!context.inSSR) { 15192 if (modifiers.includes('prop')) { 15193 injectPrefix(arg, '.'); 15194 } 15195 if (modifiers.includes('attr')) { 15196 injectPrefix(arg, '^'); 15197 } 15198 } 15199 if (!exp || 15200 (exp.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && !exp.content.trim())) { 15201 context.onError(createCompilerError(34 /* ErrorCodes.X_V_BIND_NO_EXPRESSION */, loc)); 15202 return { 15203 props: [createObjectProperty(arg, createSimpleExpression('', true, loc))] 15204 }; 15205 } 15206 return { 15207 props: [createObjectProperty(arg, exp)] 15208 }; 15209 }; 15210 const injectPrefix = (arg, prefix) => { 15211 if (arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) { 15212 if (arg.isStatic) { 15213 arg.content = prefix + arg.content; 15214 } 15215 else { 15216 arg.content = `\`${prefix}\${${arg.content}}\``; 15217 } 15218 } 15219 else { 15220 arg.children.unshift(`'${prefix}' + (`); 15221 arg.children.push(`)`); 15222 } 15223 }; 15224 15225 // Merge adjacent text nodes and expressions into a single expression 15226 // e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child. 15227 const transformText = (node, context) => { 15228 if (node.type === 0 /* NodeTypes.ROOT */ || 15229 node.type === 1 /* NodeTypes.ELEMENT */ || 15230 node.type === 11 /* NodeTypes.FOR */ || 15231 node.type === 10 /* NodeTypes.IF_BRANCH */) { 15232 // perform the transform on node exit so that all expressions have already 15233 // been processed. 15234 return () => { 15235 const children = node.children; 15236 let currentContainer = undefined; 15237 let hasText = false;
15238 for (let i = 0; i < children.length; i++) { 15239 const child = children[i]; 15240 if (isText$1(child)) { 15241 hasText = true; 15242 for (let j = i + 1; j < children.length; j++) { 15243 const next = children[j]; 15244 if (isText$1(next)) { 15245 if (!currentContainer) { 15246 currentContainer = children[i] = createCompoundExpression([child], child.loc); 15247 } 15248 // merge adjacent text node into current 15249 currentContainer.children.push(` + `, next); 15250 children.splice(j, 1); 15251 j--; 15252 } 15253 else { 15254 currentContainer = undefined; 15255 break; 15256 } 15257 } 15258 } 15259 } 15260 if (!hasText || 15261 // if this is a plain element with a single text child, leave it 15262 // as-is since the runtime has dedicated fast path for this by directly 15263 // setting textContent of the element. 15264 // for component root it's always normalized anyway. 15265 (children.length === 1 && 15266 (node.type === 0 /* NodeTypes.ROOT */ || 15267 (node.type === 1 /* NodeTypes.ELEMENT */ && 15268 node.tagType === 0 /* ElementTypes.ELEMENT */ && 15269 // #3756 15270 // custom directives can potentially add DOM elements arbitrarily, 15271 // we need to avoid setting textContent of the element at runtime 15272 // to avoid accidentally overwriting the DOM elements added 15273 // by the user through custom directives. 15274 !node.props.find(p => p.type === 7 /* NodeTypes.DIRECTIVE */ && 15275 !context.directiveTransforms[p.name]) && 15276 // in compat mode, <template> tags with no special directives 15277 // will be rendered as a fragment so its children must be 15278 // converted into vnodes. 15279 !(false ))))) { 15280 return; 15281 } 15282 // pre-convert text nodes into createTextVNode(text) calls to avoid 15283 // runtime normalization. 15284 for (let i = 0; i < children.length; i++) { 15285 const child = children[i]; 15286 if (isText$1(child) || child.type === 8 /* NodeTypes.COMPOUND_EXPRESSION */) { 15287 const callArgs = []; 15288 // createTextVNode defaults to single whitespace, so if it is a 15289 // single space the code could be an empty call to save bytes. 15290 if (child.type !== 2 /* NodeTypes.TEXT */ || child.content !== ' ') { 15291 callArgs.push(child); 15292 } 15293 // mark dynamic text with flag so it gets patched inside a block 15294 if (!context.ssr && 15295 getConstantType(child, context) === 0 /* ConstantTypes.NOT_CONSTANT */) { 15296 callArgs.push(1 /* PatchFlags.TEXT */ + 15297 (` /* ${PatchFlagNames[1 /* PatchFlags.TEXT */]} */` )); 15298 } 15299 children[i] = { 15300 type: 12 /* NodeTypes.TEXT_CALL */, 15301 content: child, 15302 loc: child.loc, 15303 codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs) 15304 }; 15305 } 15306 } 15307 }; 15308 } 15309 }; 15310 15311 const seen$1 = new WeakSet(); 15312 const transformOnce = (node, context) => { 15313 if (node.type === 1 /* NodeTypes.ELEMENT */ && findDir(node, 'once', true)) {
15314 if (seen$1.has(node) || context.inVOnce) { 15315 return; 15316 } 15317 seen$1.add(node); 15318 context.inVOnce = true; 15319 context.helper(SET_BLOCK_TRACKING); 15320 return () => { 15321 context.inVOnce = false; 15322 const cur = context.currentNode; 15323 if (cur.codegenNode) { 15324 cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */); 15325 } 15326 }; 15327 } 15328 }; 15329 15330 const transformModel$1 = (dir, node, context) => { 15331 const { exp, arg } = dir; 15332 if (!exp) { 15333 context.onError(createCompilerError(41 /* ErrorCodes.X_V_MODEL_NO_EXPRESSION */, dir.loc)); 15334 return createTransformProps(); 15335 } 15336 const rawExp = exp.loc.source; 15337 const expString = exp.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ ? exp.content : rawExp; 15338 // im SFC <script setup> inline mode, the exp may have been transformed into 15339 // _unref(exp) 15340 const bindingType = context.bindingMetadata[rawExp]; 15341 // check props 15342 if (bindingType === "props" /* BindingTypes.PROPS */ || 15343 bindingType === "props-aliased" /* BindingTypes.PROPS_ALIASED */) { 15344 context.onError(createCompilerError(44 /* ErrorCodes.X_V_MODEL_ON_PROPS */, exp.loc)); 15345 return createTransformProps(); 15346 } 15347 const maybeRef = !true ; 15348 if (!expString.trim() || 15349 (!isMemberExpression(expString) && !maybeRef)) { 15350 context.onError(createCompilerError(42 /* ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc)); 15351 return createTransformProps(); 15352 } 15353 const propName = arg ? arg : createSimpleExpression('modelValue', true); 15354 const eventName = arg 15355 ? isStaticExp(arg) 15356 ? `onUpdate:${camelize(arg.content)}` 15357 : createCompoundExpression(['"onUpdate:" + ', arg]) 15358 : `onUpdate:modelValue`; 15359 let assignmentExp; 15360 const eventArg = context.isTS ? `($event: any)` : `$event`; 15361 { 15362 assignmentExp = createCompoundExpression([ 15363 `${eventArg} => ((`, 15364 exp, 15365 `) = $event)` 15366 ]); 15367 } 15368 const props = [ 15369 // modelValue: foo 15370 createObjectProperty(propName, dir.exp), 15371 // "onUpdate:modelValue": $event => (foo = $event) 15372 createObjectProperty(eventName, assignmentExp) 15373 ]; 15374 // modelModifiers: { foo: true, "bar-baz": true } 15375 if (dir.modifiers.length && node.tagType === 1 /* ElementTypes.COMPONENT */) { 15376 const modifiers = dir.modifiers 15377 .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`) 15378 .join(`, `); 15379 const modifiersKey = arg 15380 ? isStaticExp(arg) 15381 ? `${arg.content}Modifiers` 15382 : createCompoundExpression([arg, ' + "Modifiers"']) 15383 : `modelModifiers`; 15384 props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* ConstantTypes.CAN_HOIST */))); 15385 } 15386 return createTransformProps(props); 15387 }; 15388 function createTransformProps(props = []) { 15389 return { props }; 15390 } 15391 15392 const seen = new WeakSet(); 15393 const transformMemo = (node, context) => { 15394 if (node.type === 1 /* NodeTypes.ELEMENT */) { 15395 const dir = findDir(node, 'memo'); 15396 if (!dir || seen.has(node)) { 15397 return; 15398 } 15399 seen.add(node); 15400 return () => { 15401 const codegenNode = node.codegenNode || 15402 context.currentNode.codegenNode; 15403 if (codegenNode && codegenNode.type === 13 /* NodeTypes.VNODE_CALL */) { 15404 // non-component sub tree should be turned into a block 15405 if (node.tagType !== 1 /* ElementTypes.COMPONENT */) { 15406 makeBlock(codegenNode, context); 15407 } 15408 node.codegenNode = createCallExpression(context.helper(WITH_MEMO), [ 15409 dir.exp, 15410 createFunctionExpression(undefined, codegenNode), 15411 `_cache`, 15412 String(context.cached++) 15413 ]); 15414 } 15415 }; 15416 } 15417 }; 15418 15419 function getBaseTransformPreset(prefixIdentifiers) { 15420 return [ 15421 [ 15422 transformOnce, 15423 transformIf, 15424 transformMemo, 15425 transformFor, 15426 ...([]), 15427 ...([transformExpression] 15428 ), 15429 transformSlotOutlet, 15430 transformElement, 15431 trackSlotScopes, 15432 transformText 15433 ], 15434 {
15435 on: transformOn$1, 15436 bind: transformBind, 15437 model: transformModel$1 15438 } 15439 ]; 15440 } 15441 // we name it `baseCompile` so that higher order compilers like 15442 // @vue/compiler-dom can export `compile` while re-exporting everything else. 15443 function baseCompile(template, options = {}) { 15444 const onError = options.onError || defaultOnError; 15445 const isModuleMode = options.mode === 'module'; 15446 /* istanbul ignore if */ 15447 { 15448 if (options.prefixIdentifiers === true) { 15449 onError(createCompilerError(47 /* ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED */)); 15450 } 15451 else if (isModuleMode) { 15452 onError(createCompilerError(48 /* ErrorCodes.X_MODULE_MODE_NOT_SUPPORTED */)); 15453 } 15454 } 15455 const prefixIdentifiers = !true ; 15456 if (options.cacheHandlers) { 15457 onError(createCompilerError(49 /* ErrorCodes.X_CACHE_HANDLER_NOT_SUPPORTED */)); 15458 } 15459 if (options.scopeId && !isModuleMode) { 15460 onError(createCompilerError(50 /* ErrorCodes.X_SCOPE_ID_NOT_SUPPORTED */)); 15461 } 15462 const ast = isString(template) ? baseParse(template, options) : template; 15463 const [nodeTransforms, directiveTransforms] = getBaseTransformPreset(); 15464 transform(ast, extend({}, options, { 15465 prefixIdentifiers, 15466 nodeTransforms: [ 15467 ...nodeTransforms, 15468 ...(options.nodeTransforms || []) // user transforms 15469 ], 15470 directiveTransforms: extend({}, directiveTransforms, options.directiveTransforms || {} // user transforms 15471 ) 15472 })); 15473 return generate(ast, extend({}, options, { 15474 prefixIdentifiers 15475 })); 15476 } 15477 15478 const noopDirectiveTransform = () => ({ props: [] }); 15479 15480 const V_MODEL_RADIO = Symbol(`vModelRadio` ); 15481 const V_MODEL_CHECKBOX = Symbol(`vModelCheckbox` ); 15482 const V_MODEL_TEXT = Symbol(`vModelText` ); 15483 const V_MODEL_SELECT = Symbol(`vModelSelect` ); 15484 const V_MODEL_DYNAMIC = Symbol(`vModelDynamic` ); 15485 const V_ON_WITH_MODIFIERS = Symbol(`vOnModifiersGuard` ); 15486 const V_ON_WITH_KEYS = Symbol(`vOnKeysGuard` ); 15487 const V_SHOW = Symbol(`vShow` ); 15488 const TRANSITION = Symbol(`Transition` ); 15489 const TRANSITION_GROUP = Symbol(`TransitionGroup` ); 15490 registerRuntimeHelpers({ 15491 [V_MODEL_RADIO]: `vModelRadio`, 15492 [V_MODEL_CHECKBOX]: `vModelCheckbox`, 15493 [V_MODEL_TEXT]: `vModelText`, 15494 [V_MODEL_SELECT]: `vModelSelect`, 15495 [V_MODEL_DYNAMIC]: `vModelDynamic`, 15496 [V_ON_WITH_MODIFIERS]: `withModifiers`, 15497 [V_ON_WITH_KEYS]: `withKeys`, 15498 [V_SHOW]: `vShow`, 15499 [TRANSITION]: `Transition`, 15500 [TRANSITION_GROUP]: `TransitionGroup` 15501 }); 15502 15503 /* eslint-disable no-restricted-globals */ 15504 let decoder; 15505 function decodeHtmlBrowser(raw, asAttr = false) { 15506 if (!decoder) { 15507 decoder = document.createElement('div'); 15508 } 15509 if (asAttr) { 15510 decoder.innerHTML = `<div foo="${raw.replace(/"/g, '"')}">`; 15511 return decoder.children[0].getAttribute('foo'); 15512 } 15513 else { 15514 decoder.innerHTML = raw; 15515 return decoder.textContent; 15516 } 15517 } 15518 15519 const isRawTextContainer = /*#__PURE__*/ makeMap('style,iframe,script,noscript', true); 15520 const parserOptions = { 15521 isVoidTag, 15522 isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag), 15523 isPreTag: tag => tag === 'pre', 15524 decodeEntities: decodeHtmlBrowser , 15525 isBuiltInComponent: (tag) => { 15526 if (isBuiltInType(tag, `Transition`)) { 15527 return TRANSITION; 15528 } 15529 else if (isBuiltInType(tag, `TransitionGroup`)) { 15530 return TRANSITION_GROUP; 15531 } 15532 }, 15533 // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher 15534 getNamespace(tag, parent) { 15535 let ns = parent ? parent.ns : 0 /* DOMNamespaces.HTML */; 15536 if (parent && ns === 2 /* DOMNamespaces.MATH_ML */) { 15537 if (parent.tag === 'annotation-xml') { 15538 if (tag === 'svg') { 15539 return 1 /* DOMNamespaces.SVG */; 15540 } 15541 if (parent.props.some(a => a.type === 6 /* NodeTypes.ATTRIBUTE */ && 15542 a.name === 'encoding' && 15543 a.value != null && 15544 (a.value.content === 'text/html' || 15545 a.value.content === 'application/xhtml+xml'))) { 15546 ns = 0 /* DOMNamespaces.HTML */; 15547 } 15548 } 15549 else if (/^m(?:[ions]|text)$/.test(parent.tag) && 15550 tag !== 'mglyph' && 15551 tag !== 'malignmark') { 15552 ns = 0 /* DOMNamespaces.HTML */; 15553 } 15554 } 15555 else if (parent && ns === 1 /* DOMNamespaces.SVG */) { 15556 if (parent.tag === 'foreignObject' || 15557 parent.tag === 'desc' || 15558 parent.tag === 'title') { 15559 ns = 0 /* DOMNamespaces.HTML */; 15560 } 15561 } 15562 if (ns === 0 /* DOMNamespaces.HTML */) { 15563 if (tag === 'svg') { 15564 return 1 /* DOMNamespaces.SVG */; 15565 } 15566 if (tag === 'math') { 15567 return 2 /* DOMNamespaces.MATH_ML */; 15568 } 15569 } 15570 return ns; 15571 }, 15572 // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments 15573 getTextMode({ tag, ns }) { 15574 if (ns === 0 /* DOMNamespaces.HTML */) { 15575 if (tag === 'textarea' || tag === 'title') { 15576 return 1 /* TextModes.RCDATA */; 15577 } 15578 if (isRawTextContainer(tag)) { 15579 return 2 /* TextModes.RAWTEXT */; 15580 } 15581 } 15582 return 0 /* TextModes.DATA */; 15583 } 15584 }; 15585 15586 // Parse inline CSS strings for static style attributes into an object. 15587 // This is a NodeTransform since it works on the static `style` attribute and 15588 // converts it into a dynamic equivalent: 15589 // style="color: red" -> :style='{ "color": "red" }' 15590 // It is then processed by `transformElement` and included in the generated 15591 // props.
vendor: 11,956 bytes, lines 15592-15871
15592 const transformStyle = node => { 15593 if (node.type === 1 /* NodeTypes.ELEMENT */) { 15594 node.props.forEach((p, i) => { 15595 if (p.type === 6 /* NodeTypes.ATTRIBUTE */ && p.name === 'style' && p.value) { 15596 // replace p with an expression node 15597 node.props[i] = { 15598 type: 7 /* NodeTypes.DIRECTIVE */, 15599 name: `bind`, 15600 arg: createSimpleExpression(`style`, true, p.loc), 15601 exp: parseInlineCSS(p.value.content, p.loc), 15602 modifiers: [], 15603 loc: p.loc 15604 }; 15605 } 15606 }); 15607 } 15608 }; 15609 const parseInlineCSS = (cssText, loc) => { 15610 const normalized = parseStringStyle(cssText); 15611 return createSimpleExpression(JSON.stringify(normalized), false, loc, 3 /* ConstantTypes.CAN_STRINGIFY */); 15612 }; 15613 15614 function createDOMCompilerError(code, loc) { 15615 return createCompilerError(code, loc, DOMErrorMessages ); 15616 } 15617 const DOMErrorMessages = { 15618 [51 /* DOMErrorCodes.X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`, 15619 [52 /* DOMErrorCodes.X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`, 15620 [53 /* DOMErrorCodes.X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`, 15621 [54 /* DOMErrorCodes.X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`, 15622 [55 /* DOMErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`, 15623 [56 /* DOMErrorCodes.X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`, 15624 [57 /* DOMErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT */]: `v-model cannot be used on file inputs since they are read-only. Use a v-on:change listener instead.`, 15625 [58 /* DOMErrorCodes.X_V_MODEL_UNNECESSARY_VALUE */]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`, 15626 [59 /* DOMErrorCodes.X_V_SHOW_NO_EXPRESSION */]: `v-show is missing expression.`, 15627 [60 /* DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN */]: `<Transition> expects exactly one child element or component.`, 15628 [61 /* DOMErrorCodes.X_IGNORED_SIDE_EFFECT_TAG */]: `Tags with side effect (<script> and <style>) are ignored in client component templates.` 15629 }; 15630 15631 const transformVHtml = (dir, node, context) => { 15632 const { exp, loc } = dir; 15633 if (!exp) { 15634 context.onError(createDOMCompilerError(51 /* DOMErrorCodes.X_V_HTML_NO_EXPRESSION */, loc)); 15635 } 15636 if (node.children.length) { 15637 context.onError(createDOMCompilerError(52 /* DOMErrorCodes.X_V_HTML_WITH_CHILDREN */, loc)); 15638 node.children.length = 0; 15639 } 15640 return { 15641 props: [ 15642 createObjectProperty(createSimpleExpression(`innerHTML`, true, loc), exp || createSimpleExpression('', true)) 15643 ] 15644 }; 15645 }; 15646 15647 const transformVText = (dir, node, context) => { 15648 const { exp, loc } = dir; 15649 if (!exp) { 15650 context.onError(createDOMCompilerError(53 /* DOMErrorCodes.X_V_TEXT_NO_EXPRESSION */, loc)); 15651 } 15652 if (node.children.length) { 15653 context.onError(createDOMCompilerError(54 /* DOMErrorCodes.X_V_TEXT_WITH_CHILDREN */, loc)); 15654 node.children.length = 0; 15655 } 15656 return { 15657 props: [ 15658 createObjectProperty(createSimpleExpression(`textContent`, true), exp 15659 ? getConstantType(exp, context) > 0 15660 ? exp 15661 : createCallExpression(context.helperString(TO_DISPLAY_STRING), [exp], loc) 15662 : createSimpleExpression('', true)) 15663 ] 15664 }; 15665 }; 15666 15667 const transformModel = (dir, node, context) => { 15668 const baseResult = transformModel$1(dir, node, context); 15669 // base transform has errors OR component v-model (only need props) 15670 if (!baseResult.props.length || node.tagType === 1 /* ElementTypes.COMPONENT */) { 15671 return baseResult; 15672 } 15673 if (dir.arg) { 15674 context.onError(createDOMCompilerError(56 /* DOMErrorCodes.X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc)); 15675 } 15676 function checkDuplicatedValue() { 15677 const value = findProp(node, 'value'); 15678 if (value) { 15679 context.onError(createDOMCompilerError(58 /* DOMErrorCodes.X_V_MODEL_UNNECESSARY_VALUE */, value.loc)); 15680 } 15681 } 15682 const { tag } = node; 15683 const isCustomElement = context.isCustomElement(tag); 15684 if (tag === 'input' || 15685 tag === 'textarea' || 15686 tag === 'select' || 15687 isCustomElement) { 15688 let directiveToUse = V_MODEL_TEXT; 15689 let isInvalidType = false; 15690 if (tag === 'input' || isCustomElement) { 15691 const type = findProp(node, `type`); 15692 if (type) { 15693 if (type.type === 7 /* NodeTypes.DIRECTIVE */) { 15694 // :type="foo" 15695 directiveToUse = V_MODEL_DYNAMIC; 15696 } 15697 else if (type.value) { 15698 switch (type.value.content) { 15699 case 'radio': 15700 directiveToUse = V_MODEL_RADIO; 15701 break; 15702 case 'checkbox': 15703 directiveToUse = V_MODEL_CHECKBOX; 15704 break; 15705 case 'file': 15706 isInvalidType = true; 15707 context.onError(createDOMCompilerError(57 /* DOMErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc)); 15708 break; 15709 default: 15710 // text type 15711 checkDuplicatedValue(); 15712 break; 15713 } 15714 } 15715 } 15716 else if (hasDynamicKeyVBind(node)) { 15717 // element has bindings with dynamic keys, which can possibly contain 15718 // "type". 15719 directiveToUse = V_MODEL_DYNAMIC; 15720 } 15721 else { 15722 // text type 15723 checkDuplicatedValue(); 15724 } 15725 } 15726 else if (tag === 'select') { 15727 directiveToUse = V_MODEL_SELECT; 15728 } 15729 else { 15730 // textarea 15731 checkDuplicatedValue(); 15732 } 15733 // inject runtime directive 15734 // by returning the helper symbol via needRuntime 15735 // the import will replaced a resolveDirective call. 15736 if (!isInvalidType) { 15737 baseResult.needRuntime = context.helper(directiveToUse); 15738 } 15739 } 15740 else { 15741 context.onError(createDOMCompilerError(55 /* DOMErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc)); 15742 } 15743 // native vmodel doesn't need the `modelValue` props since they are also 15744 // passed to the runtime as `binding.value`. removing it reduces code size. 15745 baseResult.props = baseResult.props.filter(p => !(p.key.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && 15746 p.key.content === 'modelValue')); 15747 return baseResult; 15748 }; 15749 15750 const isEventOptionModifier = /*#__PURE__*/ makeMap(`passive,once,capture`); 15751 const isNonKeyModifier = /*#__PURE__*/ makeMap( 15752 // event propagation management 15753`stop,prevent,self,` + 15754 // system modifiers + exact 15755 `ctrl,shift,alt,meta,exact,` + 15756 // mouse 15757 `middle`); 15758 // left & right could be mouse or key modifiers based on event type 15759 const maybeKeyModifier = /*#__PURE__*/ makeMap('left,right'); 15760 const isKeyboardEvent = /*#__PURE__*/ makeMap(`onkeyup,onkeydown,onkeypress`, true); 15761 const resolveModifiers = (key, modifiers, context, loc) => { 15762 const keyModifiers = []; 15763 const nonKeyModifiers = []; 15764 const eventOptionModifiers = []; 15765 for (let i = 0; i < modifiers.length; i++) { 15766 const modifier = modifiers[i]; 15767 if (isEventOptionModifier(modifier)) { 15768 // eventOptionModifiers: modifiers for addEventListener() options, 15769 // e.g. .passive & .capture 15770 eventOptionModifiers.push(modifier); 15771 } 15772 else { 15773 // runtimeModifiers: modifiers that needs runtime guards 15774 if (maybeKeyModifier(modifier)) { 15775 if (isStaticExp(key)) { 15776 if (isKeyboardEvent(key.content)) { 15777 keyModifiers.push(modifier); 15778 } 15779 else { 15780 nonKeyModifiers.push(modifier); 15781 } 15782 } 15783 else { 15784 keyModifiers.push(modifier); 15785 nonKeyModifiers.push(modifier); 15786 } 15787 } 15788 else { 15789 if (isNonKeyModifier(modifier)) { 15790 nonKeyModifiers.push(modifier); 15791 } 15792 else { 15793 keyModifiers.push(modifier); 15794 } 15795 } 15796 } 15797 } 15798 return { 15799 keyModifiers, 15800 nonKeyModifiers, 15801 eventOptionModifiers 15802 }; 15803 }; 15804 const transformClick = (key, event) => { 15805 const isStaticClick = isStaticExp(key) && key.content.toLowerCase() === 'onclick'; 15806 return isStaticClick 15807 ? createSimpleExpression(event, true) 15808 : key.type !== 4 /* NodeTypes.SIMPLE_EXPRESSION */ 15809 ? createCompoundExpression([ 15810 `(`, 15811 key, 15812 `) === "onClick" ? "${event}" : (`, 15813 key, 15814 `)` 15815 ]) 15816 : key; 15817 }; 15818 const transformOn = (dir, node, context) => { 15819 return transformOn$1(dir, node, context, baseResult => { 15820 const { modifiers } = dir; 15821 if (!modifiers.length) 15822 return baseResult; 15823 let { key, value: handlerExp } = baseResult.props[0]; 15824 const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = resolveModifiers(key, modifiers, context, dir.loc); 15825 // normalize click.right and click.middle since they don't actually fire 15826 if (nonKeyModifiers.includes('right')) { 15827 key = transformClick(key, `onContextmenu`); 15828 } 15829 if (nonKeyModifiers.includes('middle')) { 15830 key = transformClick(key, `onMouseup`); 15831 } 15832 if (nonKeyModifiers.length) { 15833 handlerExp = createCallExpression(context.helper(V_ON_WITH_MODIFIERS), [ 15834 handlerExp, 15835 JSON.stringify(nonKeyModifiers) 15836 ]); 15837 } 15838 if (keyModifiers.length && 15839 // if event name is dynamic, always wrap with keys guard 15840 (!isStaticExp(key) || isKeyboardEvent(key.content))) { 15841 handlerExp = createCallExpression(context.helper(V_ON_WITH_KEYS), [ 15842 handlerExp, 15843 JSON.stringify(keyModifiers) 15844 ]); 15845 } 15846 if (eventOptionModifiers.length) { 15847 const modifierPostfix = eventOptionModifiers.map(capitalize).join(''); 15848 key = isStaticExp(key) 15849 ? createSimpleExpression(`${key.content}${modifierPostfix}`, true) 15850 : createCompoundExpression([`(`, key, `) + "${modifierPostfix}"`]); 15851 } 15852 return { 15853 props: [createObjectProperty(key, handlerExp)] 15854 }; 15855 }); 15856 }; 15857 15858 const transformShow = (dir, node, context) => { 15859 const { exp, loc } = dir; 15860 if (!exp) { 15861 context.onError(createDOMCompilerError(59 /* DOMErrorCodes.X_V_SHOW_NO_EXPRESSION */, loc)); 15862 } 15863 return { 15864 props: [], 15865 needRuntime: context.helper(V_SHOW) 15866 }; 15867 }; 15868 15869 const transformTransition = (node, context) => { 15870 if (node.type === 1 /* NodeTypes.ELEMENT */ && 15871 node.tagType === 1 /* ElementTypes.COMPONENT */) {
15872 const component = context.isBuiltInComponent(node.tag); 15873 if (component === TRANSITION) { 15874 return () => { 15875 if (!node.children.length) { 15876 return; 15877 } 15878 // warn multiple transition children 15879 if (hasMultipleChildren(node)) { 15880 context.onError(createDOMCompilerError(60 /* DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN */, { 15881 start: node.children[0].loc.start, 15882 end: node.children[node.children.length - 1].loc.end, 15883 source: '' 15884 })); 15885 } 15886 // check if it's s single child w/ v-show 15887 // if yes, inject "persisted: true" to the transition props 15888 const child = node.children[0]; 15889 if (child.type === 1 /* NodeTypes.ELEMENT */) { 15890 for (const p of child.props) { 15891 if (p.type === 7 /* NodeTypes.DIRECTIVE */ && p.name === 'show') { 15892 node.props.push({ 15893 type: 6 /* NodeTypes.ATTRIBUTE */, 15894 name: 'persisted', 15895 value: undefined, 15896 loc: node.loc 15897 }); 15898 } 15899 } 15900 } 15901 }; 15902 } 15903 } 15904 }; 15905 function hasMultipleChildren(node) { 15906 // #1352 filter out potential comment nodes. 15907 const children = (node.children = node.children.filter(c => c.type !== 3 /* NodeTypes.COMMENT */ && 15908 !(c.type === 2 /* NodeTypes.TEXT */ && !c.content.trim()))); 15909 const child = children[0]; 15910 return (children.length !== 1 || 15911 child.type === 11 /* NodeTypes.FOR */ || 15912 (child.type === 9 /* NodeTypes.IF */ && child.branches.some(hasMultipleChildren))); 15913 } 15914 15915 const ignoreSideEffectTags = (node, context) => { 15916 if (node.type === 1 /* NodeTypes.ELEMENT */ && 15917 node.tagType === 0 /* ElementTypes.ELEMENT */ && 15918 (node.tag === 'script' || node.tag === 'style')) { 15919 context.onError(createDOMCompilerError(61 /* DOMErrorCodes.X_IGNORED_SIDE_EFFECT_TAG */, node.loc)); 15920 context.removeNode(); 15921 } 15922 }; 15923 15924 const DOMNodeTransforms = [ 15925 transformStyle, 15926 ...([transformTransition] ) 15927 ]; 15928 const DOMDirectiveTransforms = { 15929 cloak: noopDirectiveTransform, 15930 html: transformVHtml, 15931 text: transformVText, 15932 model: transformModel, 15933 on: transformOn, 15934 show: transformShow 15935 }; 15936 function compile(template, options = {}) { 15937 return baseCompile(template, extend({}, parserOptions, options, { 15938 nodeTransforms: [ 15939 // ignore <script> and <tag> 15940 // this is not put inside DOMNodeTransforms because that list is used 15941 // by compiler-ssr to generate vnode fallback branches 15942 ignoreSideEffectTags, 15943 ...DOMNodeTransforms, 15944 ...(options.nodeTransforms || []) 15945 ], 15946 directiveTransforms: extend({}, DOMDirectiveTransforms, options.directiveTransforms || {}), 15947 transformHoist: null 15948 })); 15949 } 15950 15951 // This entry is the "full-build" that includes both the runtime 15952 { 15953 initDev(); 15954 } 15955 const compileCache = Object.create(null); 15956 function compileToFunction(template, options) { 15957 if (!isString(template)) { 15958 if (template.nodeType) { 15959 template = template.innerHTML; 15960 } 15961 else { 15962 warn(`invalid template option: `, template); 15963 return NOOP; 15964 } 15965 } 15966 const key = template; 15967 const cached = compileCache[key]; 15968 if (cached) { 15969 return cached; 15970 } 15971 if (template[0] === '#') { 15972 const el = document.querySelector(template); 15973 if (!el) { 15974 warn(`Template element not found or is empty: ${template}`); 15975 } 15976 // __UNSAFE__ 15977 // Reason: potential execution of JS expressions in in-DOM template. 15978 // The user must make sure the in-DOM template is trusted. If it's rendered 15979 // by the server, the template should not contain any user data. 15980 template = el ? el.innerHTML : ``; 15981 } 15982 const opts = extend({ 15983 hoistStatic: true, 15984 onError: onError , 15985 onWarn: e => onError(e, true) 15986 }, options); 15987 if (!opts.isCustomElement && typeof customElements !== 'undefined') { 15988 opts.isCustomElement = tag => !!customElements.get(tag); 15989 } 15990 const { code } = compile(template, opts); 15991 function onError(err, asWarning = false) { 15992 const message = asWarning 15993 ? err.message 15994 : `Template compilation error: ${err.message}`; 15995 const codeFrame = err.loc && 15996 generateCodeFrame(template, err.loc.start.offset, err.loc.end.offset); 15997 warn(codeFrame ? `${message}\n${codeFrame}` : message); 15998 } 15999 // The wildcard import results in a huge object with every export 16000 // with keys that cannot be mangled, and can be quite heavy size-wise. 16001 // In the global build we know `Vue` is available globally so we can avoid 16002 // the wildcard object. 16003 const render = (new Function(code)() ); 16004 render._rc = true; 16005 return (compileCache[key] = render); 16006 } 16007 registerRuntimeCompiler(compileToFunction); 16008 16009 exports.BaseTransition = BaseTransition; 16010 exports.Comment = Comment; 16011 exports.EffectScope = EffectScope; 16012 exports.Fragment = Fragment; 16013 exports.KeepAlive = KeepAlive; 16014 exports.ReactiveEffect = ReactiveEffect; 16015 exports.Static = Static; 16016 exports.Suspense = Suspense; 16017 exports.Teleport = Teleport; 16018 exports.Text = Text; 16019 exports.Transition = Transition; 16020 exports.TransitionGroup = TransitionGroup; 16021 exports.VueElement = VueElement; 16022 exports.assertNumber = assertNumber; 16023 exports.callWithAsyncErrorHandling = callWithAsyncErrorHandling; 16024 exports.callWithErrorHandling = callWithErrorHandling; 16025 exports.camelize = camelize; 16026 exports.capitalize = capitalize; 16027 exports.cloneVNode = cloneVNode; 16028 exports.compatUtils = compatUtils; 16029 exports.compile = compileToFunction; 16030 exports.computed = computed; 16031 exports.createApp = createApp; 16032 exports.createBlock = createBlock; 16033 exports.createCommentVNode = createCommentVNode; 16034 exports.createElementBlock = createElementBlock; 16035 exports.createElementVNode = createBaseVNode; 16036 exports.createHydrationRenderer = createHydrationRenderer; 16037 exports.createPropsRestProxy = createPropsRestProxy; 16038 exports.createRenderer = createRenderer; 16039 exports.createSSRApp = createSSRApp; 16040 exports.createSlots = createSlots; 16041 exports.createStaticVNode = createStaticVNode; 16042 exports.createTextVNode = createTextVNode; 16043 exports.createVNode = createVNode; 16044 exports.customRef = customRef; 16045 exports.defineAsyncComponent = defineAsyncComponent; 16046 exports.defineComponent = defineComponent; 16047 exports.defineCustomElement = defineCustomElement; 16048 exports.defineEmits = defineEmits; 16049 exports.defineExpose = defineExpose; 16050 exports.defineProps = defineProps; 16051 exports.defineSSRCustomElement = defineSSRCustomElement; 16052 exports.effect = effect; 16053 exports.effectScope = effectScope; 16054 exports.getCurrentInstance = getCurrentInstance; 16055 exports.getCurrentScope = getCurrentScope; 16056 exports.getTransitionRawChildren = getTransitionRawChildren; 16057 exports.guardReactiveProps = guardReactiveProps; 16058 exports.h = h; 16059 exports.handleError = handleError; 16060 exports.hydrate = hydrate;
16061 exports.initCustomFormatter = initCustomFormatter; 16062 exports.initDirectivesForSSR = initDirectivesForSSR; 16063 exports.inject = inject; 16064 exports.isMemoSame = isMemoSame; 16065 exports.isProxy = isProxy; 16066 exports.isReactive = isReactive; 16067 exports.isReadonly = isReadonly; 16068 exports.isRef = isRef; 16069 exports.isRuntimeOnly = isRuntimeOnly; 16070 exports.isShallow = isShallow; 16071 exports.isVNode = isVNode; 16072 exports.markRaw = markRaw; 16073 exports.mergeDefaults = mergeDefaults; 16074 exports.mergeProps = mergeProps; 16075 exports.nextTick = nextTick; 16076 exports.normalizeClass = normalizeClass; 16077 exports.normalizeProps = normalizeProps; 16078 exports.normalizeStyle = normalizeStyle; 16079 exports.onActivated = onActivated; 16080 exports.onBeforeMount = onBeforeMount; 16081 exports.onBeforeUnmount = onBeforeUnmount; 16082 exports.onBeforeUpdate = onBeforeUpdate; 16083 exports.onDeactivated = onDeactivated; 16084 exports.onErrorCaptured = onErrorCaptured; 16085 exports.onMounted = onMounted; 16086 exports.onRenderTracked = onRenderTracked; 16087 exports.onRenderTriggered = onRenderTriggered; 16088 exports.onScopeDispose = onScopeDispose; 16089 exports.onServerPrefetch = onServerPrefetch; 16090 exports.onUnmounted = onUnmounted; 16091 exports.onUpdated = onUpdated; 16092 exports.openBlock = openBlock; 16093 exports.popScopeId = popScopeId; 16094 exports.provide = provide; 16095 exports.proxyRefs = proxyRefs; 16096 exports.pushScopeId = pushScopeId; 16097 exports.queuePostFlushCb = queuePostFlushCb; 16098 exports.reactive = reactive; 16099 exports.readonly = readonly; 16100 exports.ref = ref; 16101 exports.registerRuntimeCompiler = registerRuntimeCompiler; 16102 exports.render = render; 16103 exports.renderList = renderList; 16104 exports.renderSlot = renderSlot; 16105 exports.resolveComponent = resolveComponent; 16106 exports.resolveDirective = resolveDirective; 16107 exports.resolveDynamicComponent = resolveDynamicComponent; 16108 exports.resolveFilter = resolveFilter; 16109 exports.resolveTransitionHooks = resolveTransitionHooks; 16110 exports.setBlockTracking = setBlockTracking; 16111 exports.setDevtoolsHook = setDevtoolsHook; 16112 exports.setTransitionHooks = setTransitionHooks; 16113 exports.shallowReactive = shallowReactive; 16114 exports.shallowReadonly = shallowReadonly; 16115 exports.shallowRef = shallowRef; 16116 exports.ssrContextKey = ssrContextKey; 16117 exports.ssrUtils = ssrUtils; 16118 exports.stop = stop; 16119 exports.toDisplayString = toDisplayString; 16120 exports.toHandlerKey = toHandlerKey; 16121 exports.toHandlers = toHandlers; 16122 exports.toRaw = toRaw; 16123 exports.toRef = toRef; 16124 exports.toRefs = toRefs; 16125 exports.transformVNodeArgs = transformVNodeArgs; 16126 exports.triggerRef = triggerRef; 16127 exports.unref = unref; 16128 exports.useAttrs = useAttrs; 16129 exports.useCssModule = useCssModule; 16130 exports.useCssVars = useCssVars; 16131 exports.useSSRContext = useSSRContext; 16132 exports.useSlots = useSlots; 16133 exports.useTransitionState = useTransitionState; 16134 exports.vModelCheckbox = vModelCheckbox; 16135 exports.vModelDynamic = vModelDynamic; 16136 exports.vModelRadio = vModelRadio; 16137 exports.vModelSelect = vModelSelect; 16138 exports.vModelText = vModelText; 16139 exports.vShow = vShow; 16140 exports.version = version; 16141 exports.warn = warn; 16142 exports.watch = watch; 16143 exports.watchEffect = watchEffect; 16144 exports.watchPostEffect = watchPostEffect; 16145 exports.watchSyncEffect = watchSyncEffect; 16146 exports.withAsyncContext = withAsyncContext; 16147 exports.withCtx = withCtx; 16148 exports.withDefaults = withDefaults; 16149 exports.withDirectives = withDirectives; 16150 exports.withKeys = withKeys; 16151 exports.withMemo = withMemo; 16152 exports.withModifiers = withModifiers; 16153 exports.withScopeId = withScopeId; 16154 16155 Object.defineProperty(exports, '__esModule', { value: true }); 16156 16157 return exports; 16158 16159})({}); 16160 16161/*! 16162 * vue-i18n v9.1.0 16163 * (c) 2021 kazuya kawaguchi 16164 * Released under the MIT License. 16165 */ 16166var VueI18n = (function (exports, vue) { 16167 'use strict'; 16168 16169 /** 16170 * Original Utilities 16171 * written by kazuya kawaguchi 16172 */ 16173 const inBrowser = typeof window !== 'undefined'; 16174 let mark; 16175 let measure; 16176 { 16177 const perf = inBrowser && window.performance; 16178 if (perf && 16179 perf.mark && 16180 perf.measure && 16181 perf.clearMarks && 16182 perf.clearMeasures) { 16183 mark = (tag) => perf.mark(tag); 16184 measure = (name, startTag, endTag) => { 16185 perf.measure(name, startTag, endTag); 16186 perf.clearMarks(startTag); 16187 perf.clearMarks(endTag); 16188 }; 16189 } 16190 } 16191 const RE_ARGS = /\{([0-9a-zA-Z]+)\}/g; 16192 /* eslint-disable */ 16193 function format(message, ...args) { 16194 if (args.length === 1 && isObject(args[0])) { 16195 args = args[0]; 16196 } 16197 if (!args || !args.hasOwnProperty) { 16198 args = {}; 16199 } 16200 return message.replace(RE_ARGS, (match, identifier) => { 16201 return args.hasOwnProperty(identifier) ? args[identifier] : ''; 16202 }); 16203 } 16204 const hasSymbol = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol'; 16205 const makeSymbol = (name) => hasSymbol ? Symbol(name) : name; 16206 const generateFormatCacheKey = (locale, key, source) => friendlyJSONstringify({ l: locale, k: key, s: source }); 16207 const friendlyJSONstringify = (json) => JSON.stringify(json) 16208 .replace(/\u2028/g, '\\u2028') 16209 .replace(/\u2029/g, '\\u2029') 16210 .replace(/\u0027/g, '\\u0027'); 16211 const isNumber = (val) => typeof val === 'number' && isFinite(val); 16212 const isDate = (val) => toTypeString(val) === '[object Date]'; 16213 const isRegExp = (val) => toTypeString(val) === '[object RegExp]'; 16214 const isEmptyObject = (val) => isPlainObject(val) && Object.keys(val).length === 0; 16215 function warn(msg, err) { 16216 if (typeof console !== 'undefined') { 16217 console.warn(`[intlify] ` + msg); 16218 /* istanbul ignore if */ 16219 if (err) { 16220 console.warn(err.stack); 16221 } 16222 } 16223 } 16224 const assign = Object.assign; 16225 let _globalThis; 16226 const getGlobalThis = () => { 16227 // prettier-ignore 16228 return (_globalThis || 16229 (_globalThis = 16230 typeof globalThis !== 'undefined' 16231 ? globalThis 16232 : typeof self !== 'undefined' 16233 ? self 16234 : typeof window !== 'undefined' 16235 ? window 16236 : typeof global !== 'undefined' 16237 ? global 16238 : {})); 16239 }; 16240 function escapeHtml(rawText) { 16241 return rawText 16242 .replace(/</g, '<') 16243 .replace(/>/g, '>') 16244 .replace(/"/g, '"') 16245 .replace(/'/g, '''); 16246 } 16247 const hasOwnProperty = Object.prototype.hasOwnProperty; 16248 function hasOwn(obj, key) { 16249 return hasOwnProperty.call(obj, key); 16250 } 16251 /* eslint-enable */ 16252 /** 16253 * Useful Utilities By Evan you 16254 * Modified by kazuya kawaguchi 16255 * MIT License 16256 * https://github.com/vuejs/vue-next/blob/master/packages/shared/src/index.ts 16257 * https://github.com/vuejs/vue-next/blob/master/packages/shared/src/codeframe.ts 16258 */ 16259 const isArray = Array.isArray; 16260 const isFunction = (val) => typeof val === 'function'; 16261 const isString = (val) => typeof val === 'string'; 16262 const isBoolean = (val) => typeof val === 'boolean'; 16263 const isObject = (val) => // eslint-disable-line 16264 val !== null && typeof val === 'object'; 16265 const objectToString = Object.prototype.toString; 16266 const toTypeString = (value) => objectToString.call(value); 16267 const isPlainObject = (val) => toTypeString(val) === '[object Object]'; 16268 // for converting list and named values to displayed strings. 16269 const toDisplayString = (val) => { 16270 return val == null 16271 ? '' 16272 : isArray(val) || (isPlainObject(val) && val.toString === objectToString) 16273 ? JSON.stringify(val, null, 2) 16274 : String(val); 16275 }; 16276 const RANGE = 2; 16277 function generateCodeFrame(source, start = 0, end = source.length) { 16278 const lines = source.split(/\r?\n/); 16279 let count = 0; 16280 const res = []; 16281 for (let i = 0; i < lines.length; i++) { 16282 count += lines[i].length + 1; 16283 if (count >= start) { 16284 for (let j = i - RANGE;
vendor: 7,789 bytes, lines 16284-16514
16284 j <= i + RANGE || end > count; j++) { 16285 if (j < 0 || j >= lines.length) 16286 continue; 16287 const line = j + 1; 16288 res.push(`${line}${' '.repeat(3 - String(line).length)}| ${lines[j]}`); 16289 const lineLength = lines[j].length; 16290 if (j === i) { 16291 // push underline 16292 const pad = start - (count - lineLength) + 1; 16293 const length = Math.max(1, end > count ? lineLength - pad : end - start); 16294 res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length)); 16295 } 16296 else if (j > i) { 16297 if (end > count) { 16298 const length = Math.max(Math.min(end - count, lineLength), 1); 16299 res.push(` | ` + '^'.repeat(length)); 16300 } 16301 count += lineLength + 1; 16302 } 16303 } 16304 break; 16305 } 16306 } 16307 return res.join('\n'); 16308 } 16309 16310 /** 16311 * Event emitter, forked from the below: 16312 * - original repository url: https://github.com/developit/mitt 16313 * - code url: https://github.com/developit/mitt/blob/master/src/index.ts 16314 * - author: Jason Miller (https://github.com/developit) 16315 * - license: MIT 16316 */ 16317 /** 16318 * Create a event emitter 16319 * 16320 * @returns An event emitter 16321 */ 16322 function createEmitter() { 16323 const events = new Map(); 16324 const emitter = { 16325 events, 16326 on(event, handler) { 16327 const handlers = events.get(event); 16328 const added = handlers && handlers.push(handler); 16329 if (!added) { 16330 events.set(event, [handler]); 16331 } 16332 }, 16333 off(event, handler) { 16334 const handlers = events.get(event); 16335 if (handlers) { 16336 handlers.splice(handlers.indexOf(handler) >>> 0, 1); 16337 } 16338 }, 16339 emit(event, payload) { 16340 (events.get(event) || []) 16341 .slice() 16342 .map(handler => handler(payload)); 16343 (events.get('*') || []) 16344 .slice() 16345 .map(handler => handler(event, payload)); 16346 } 16347 }; 16348 return emitter; 16349 } 16350 16351 const pathStateMachine = []; 16352 pathStateMachine[0 /* BEFORE_PATH */] = { 16353 ["w" /* WORKSPACE */]: [0 /* BEFORE_PATH */], 16354 ["i" /* IDENT */]: [3 /* IN_IDENT */, 0 /* APPEND */], 16355 ["[" /* LEFT_BRACKET */]: [4 /* IN_SUB_PATH */], 16356 ["o" /* END_OF_FAIL */]: [7 /* AFTER_PATH */] 16357 }; 16358 pathStateMachine[1 /* IN_PATH */] = { 16359 ["w" /* WORKSPACE */]: [1 /* IN_PATH */], 16360 ["." /* DOT */]: [2 /* BEFORE_IDENT */], 16361 ["[" /* LEFT_BRACKET */]: [4 /* IN_SUB_PATH */], 16362 ["o" /* END_OF_FAIL */]: [7 /* AFTER_PATH */] 16363 }; 16364 pathStateMachine[2 /* BEFORE_IDENT */] = { 16365 ["w" /* WORKSPACE */]: [2 /* BEFORE_IDENT */], 16366 ["i" /* IDENT */]: [3 /* IN_IDENT */, 0 /* APPEND */], 16367 ["0" /* ZERO */]: [3 /* IN_IDENT */, 0 /* APPEND */] 16368 }; 16369 pathStateMachine[3 /* IN_IDENT */] = { 16370 ["i" /* IDENT */]: [3 /* IN_IDENT */, 0 /* APPEND */], 16371 ["0" /* ZERO */]: [3 /* IN_IDENT */, 0 /* APPEND */], 16372 ["w" /* WORKSPACE */]: [1 /* IN_PATH */, 1 /* PUSH */], 16373 ["." /* DOT */]: [2 /* BEFORE_IDENT */, 1 /* PUSH */], 16374 ["[" /* LEFT_BRACKET */]: [4 /* IN_SUB_PATH */, 1 /* PUSH */], 16375 ["o" /* END_OF_FAIL */]: [7 /* AFTER_PATH */, 1 /* PUSH */] 16376 }; 16377 pathStateMachine[4 /* IN_SUB_PATH */] = { 16378 ["'" /* SINGLE_QUOTE */]: [5 /* IN_SINGLE_QUOTE */, 0 /* APPEND */], 16379 ["\"" /* DOUBLE_QUOTE */]: [6 /* IN_DOUBLE_QUOTE */, 0 /* APPEND */], 16380 ["[" /* LEFT_BRACKET */]: [ 16381 4 /* IN_SUB_PATH */, 16382 2 /* INC_SUB_PATH_DEPTH */ 16383 ], 16384 ["]" /* RIGHT_BRACKET */]: [1 /* IN_PATH */, 3 /* PUSH_SUB_PATH */], 16385 ["o" /* END_OF_FAIL */]: 8 /* ERROR */, 16386 ["l" /* ELSE */]: [4 /* IN_SUB_PATH */, 0 /* APPEND */] 16387 }; 16388 pathStateMachine[5 /* IN_SINGLE_QUOTE */] = { 16389 ["'" /* SINGLE_QUOTE */]: [4 /* IN_SUB_PATH */, 0 /* APPEND */], 16390 ["o" /* END_OF_FAIL */]: 8 /* ERROR */, 16391 ["l" /* ELSE */]: [5 /* IN_SINGLE_QUOTE */, 0 /* APPEND */] 16392 }; 16393 pathStateMachine[6 /* IN_DOUBLE_QUOTE */] = { 16394 ["\"" /* DOUBLE_QUOTE */]: [4 /* IN_SUB_PATH */, 0 /* APPEND */], 16395 ["o" /* END_OF_FAIL */]: 8 /* ERROR */, 16396 ["l" /* ELSE */]: [6 /* IN_DOUBLE_QUOTE */, 0 /* APPEND */] 16397 }; 16398 /** 16399 * Check if an expression is a literal value. 16400 */ 16401 const literalValueRE = /^\s?(?:true|false|-?[\d.]+|'[^']*'|"[^"]*")\s?$/; 16402 function isLiteral(exp) { 16403 return literalValueRE.test(exp); 16404 } 16405 /** 16406 * Strip quotes from a string 16407 */ 16408 function stripQuotes(str) { 16409 const a = str.charCodeAt(0); 16410 const b = str.charCodeAt(str.length - 1); 16411 return a === b && (a === 0x22 || a === 0x27) ? str.slice(1, -1) : str; 16412 } 16413 /** 16414 * Determine the type of a character in a keypath. 16415 */ 16416 function getPathCharType(ch) { 16417 if (ch === undefined || ch === null) { 16418 return "o" /* END_OF_FAIL */; 16419 } 16420 const code = ch.charCodeAt(0); 16421 switch (code) { 16422 case 0x5b: // [ 16423 case 0x5d: // ] 16424 case 0x2e: // . 16425 case 0x22: // " 16426 case 0x27: // ' 16427 return ch; 16428 case 0x5f: // _ 16429 case 0x24: // $ 16430 case 0x2d: // - 16431 return "i" /* IDENT */; 16432 case 0x09: // Tab (HT) 16433 case 0x0a: // Newline (LF) 16434 case 0x0d: // Return (CR) 16435 case 0xa0: // No-break space (NBSP) 16436 case 0xfeff: // Byte Order Mark (BOM) 16437 case 0x2028: // Line Separator (LS) 16438 case 0x2029: // Paragraph Separator (PS) 16439 return "w" /* WORKSPACE */; 16440 } 16441 return "i" /* IDENT */; 16442 } 16443 /** 16444 * Format a subPath, return its plain form if it is 16445 * a literal string or number. Otherwise prepend the 16446 * dynamic indicator (*). 16447 */ 16448 function formatSubPath(path) { 16449 const trimmed = path.trim(); 16450 // invalid leading 0 16451 if (path.charAt(0) === '0' && isNaN(parseInt(path))) { 16452 return false; 16453 } 16454 return isLiteral(trimmed) 16455 ? stripQuotes(trimmed) 16456 : "*" /* ASTARISK */ + trimmed; 16457 } 16458 /** 16459 * Parse a string path into an array of segments 16460 */ 16461 function parse(path) { 16462 const keys = []; 16463 let index = -1; 16464 let mode = 0 /* BEFORE_PATH */; 16465 let subPathDepth = 0; 16466 let c; 16467 let key; // eslint-disable-line 16468 let newChar; 16469 let type; 16470 let transition; 16471 let action; 16472 let typeMap; 16473 const actions = []; 16474 actions[0 /* APPEND */] = () => { 16475 if (key === undefined) { 16476 key = newChar; 16477 } 16478 else { 16479 key += newChar; 16480 } 16481 }; 16482 actions[1 /* PUSH */] = () => { 16483 if (key !== undefined) { 16484 keys.push(key); 16485 key = undefined; 16486 } 16487 }; 16488 actions[2 /* INC_SUB_PATH_DEPTH */] = () => { 16489 actions[0 /* APPEND */](); 16490 subPathDepth++; 16491 }; 16492 actions[3 /* PUSH_SUB_PATH */] = () => { 16493 if (subPathDepth > 0) { 16494 subPathDepth--; 16495 mode = 4 /* IN_SUB_PATH */; 16496 actions[0 /* APPEND */](); 16497 } 16498 else { 16499 subPathDepth = 0; 16500 if (key === undefined) { 16501 return false; 16502 } 16503 key = formatSubPath(key); 16504 if (key === false) { 16505 return false; 16506 } 16507 else { 16508 actions[1 /* PUSH */](); 16509 } 16510 } 16511 }; 16512 function maybeUnescapeQuote() { 16513 const nextChar = path[index + 1]; 16514 if ((mode === 5 /* IN_SINGLE_QUOTE */ &&
vendor: 5,897 bytes, lines 16515-16696
16515 nextChar === "'" /* SINGLE_QUOTE */) || 16516 (mode === 6 /* IN_DOUBLE_QUOTE */ && 16517 nextChar === "\"" /* DOUBLE_QUOTE */)) { 16518 index++; 16519 newChar = '\\' + nextChar; 16520 actions[0 /* APPEND */](); 16521 return true; 16522 } 16523 } 16524 while (mode !== null) { 16525 index++; 16526 c = path[index]; 16527 if (c === '\\' && maybeUnescapeQuote()) { 16528 continue; 16529 } 16530 type = getPathCharType(c); 16531 typeMap = pathStateMachine[mode]; 16532 transition = typeMap[type] || typeMap["l" /* ELSE */] || 8 /* ERROR */; 16533 // check parse error 16534 if (transition === 8 /* ERROR */) { 16535 return; 16536 } 16537 mode = transition[0]; 16538 if (transition[1] !== undefined) { 16539 action = actions[transition[1]]; 16540 if (action) { 16541 newChar = c; 16542 if (action() === false) { 16543 return; 16544 } 16545 } 16546 } 16547 // check parse finish 16548 if (mode === 7 /* AFTER_PATH */) { 16549 return keys; 16550 } 16551 } 16552 } 16553 // path token cache 16554 const cache = new Map(); 16555 function resolveValue(obj, path) { 16556 // check object 16557 if (!isObject(obj)) { 16558 return null; 16559 } 16560 // parse path 16561 let hit = cache.get(path); 16562 if (!hit) { 16563 hit = parse(path); 16564 if (hit) { 16565 cache.set(path, hit); 16566 } 16567 } 16568 // check hit 16569 if (!hit) { 16570 return null; 16571 } 16572 // resolve path value 16573 const len = hit.length; 16574 let last = obj; 16575 let i = 0; 16576 while (i < len) { 16577 const val = last[hit[i]]; 16578 if (val === undefined) { 16579 return null; 16580 } 16581 last = val; 16582 i++; 16583 } 16584 return last; 16585 } 16586 /** 16587 * Transform flat json in obj to normal json in obj 16588 */ 16589 function handleFlatJson(obj) { 16590 // check obj 16591 if (!isObject(obj)) { 16592 return obj; 16593 } 16594 for (const key in obj) { 16595 // check key 16596 if (!hasOwn(obj, key)) { 16597 continue; 16598 } 16599 // handle for normal json 16600 if (!key.includes("." /* DOT */)) { 16601 // recursive process value if value is also a object 16602 if (isObject(obj[key])) { 16603 handleFlatJson(obj[key]); 16604 } 16605 } 16606 // handle for flat json, transform to normal json 16607 else { 16608 // go to the last object 16609 const subKeys = key.split("." /* DOT */); 16610 const lastIndex = subKeys.length - 1; 16611 let currentObj = obj; 16612 for (let i = 0; i < lastIndex; i++) { 16613 if (!(subKeys[i] in currentObj)) { 16614 currentObj[subKeys[i]] = {}; 16615 } 16616 currentObj = currentObj[subKeys[i]]; 16617 } 16618 // update last object value, delete old property 16619 currentObj[subKeys[lastIndex]] = obj[key]; 16620 delete obj[key]; 16621 // recursive process value if value is also a object 16622 if (isObject(currentObj[subKeys[lastIndex]])) { 16623 handleFlatJson(currentObj[subKeys[lastIndex]]); 16624 } 16625 } 16626 } 16627 return obj; 16628 } 16629 16630 const DEFAULT_MODIFIER = (str) => str; 16631 const DEFAULT_MESSAGE = (ctx) => ''; // eslint-disable-line 16632 const DEFAULT_MESSAGE_DATA_TYPE = 'text'; 16633 const DEFAULT_NORMALIZE = (values) => values.length === 0 ? '' : values.join(''); 16634 const DEFAULT_INTERPOLATE = toDisplayString; 16635 function pluralDefault(choice, choicesLength) { 16636 choice = Math.abs(choice); 16637 if (choicesLength === 2) { 16638 // prettier-ignore 16639 return choice 16640 ? choice > 1 16641 ? 1 16642 : 0 16643 : 1; 16644 } 16645 return choice ? Math.min(choice, 2) : 0; 16646 } 16647 function getPluralIndex(options) { 16648 // prettier-ignore 16649 const index = isNumber(options.pluralIndex) 16650 ? options.pluralIndex 16651 : -1; 16652 // prettier-ignore 16653 return options.named && (isNumber(options.named.count) || isNumber(options.named.n)) 16654 ? isNumber(options.named.count) 16655 ? options.named.count 16656 : isNumber(options.named.n) 16657 ? options.named.n 16658 : index 16659 : index; 16660 } 16661 function normalizeNamed(pluralIndex, props) { 16662 if (!props.count) { 16663 props.count = pluralIndex; 16664 } 16665 if (!props.n) { 16666 props.n = pluralIndex; 16667 } 16668 } 16669 function createMessageContext(options = {}) { 16670 const locale = options.locale; 16671 const pluralIndex = getPluralIndex(options); 16672 const pluralRule = isObject(options.pluralRules) && 16673 isString(locale) && 16674 isFunction(options.pluralRules[locale]) 16675 ? options.pluralRules[locale] 16676 : pluralDefault; 16677 const orgPluralRule = isObject(options.pluralRules) && 16678 isString(locale) && 16679 isFunction(options.pluralRules[locale]) 16680 ? pluralDefault 16681 : undefined; 16682 const plural = (messages) => messages[pluralRule(pluralIndex, messages.length, orgPluralRule)]; 16683 const _list = options.list || []; 16684 const list = (index) => _list[index]; 16685 // eslint-disable-next-line @typescript-eslint/no-explicit-any 16686 const _named = options.named || {}; 16687 isNumber(options.pluralIndex) && normalizeNamed(pluralIndex, _named); 16688 const named = (key) => _named[key]; 16689 // TODO: need to design resolve message function? 16690 function message(key) { 16691 // prettier-ignore 16692 const msg = isFunction(options.messages) 16693 ? options.messages(key) 16694 : isObject(options.messages) 16695 ? options.messages[key] 16696 : false;
16697 return !msg 16698 ? options.parent 16699 ? options.parent.message(key) // resolve from parent messages 16700 : DEFAULT_MESSAGE 16701 : msg; 16702 } 16703 const _modifier = (name) => options.modifiers 16704 ? options.modifiers[name] 16705 : DEFAULT_MODIFIER; 16706 const normalize = isPlainObject(options.processor) && isFunction(options.processor.normalize) 16707 ? options.processor.normalize 16708 : DEFAULT_NORMALIZE; 16709 const interpolate = isPlainObject(options.processor) && 16710 isFunction(options.processor.interpolate) 16711 ? options.processor.interpolate 16712 : DEFAULT_INTERPOLATE; 16713 const type = isPlainObject(options.processor) && isString(options.processor.type) 16714 ? options.processor.type 16715 : DEFAULT_MESSAGE_DATA_TYPE; 16716 const ctx = { 16717 ["list" /* LIST */]: list, 16718 ["named" /* NAMED */]: named, 16719 ["plural" /* PLURAL */]: plural, 16720 ["linked" /* LINKED */]: (key, modifier) => { 16721 // TODO: should check `key` 16722 const msg = message(key)(ctx); 16723 return isString(modifier) ? _modifier(modifier)(msg) : msg; 16724 }, 16725 ["message" /* MESSAGE */]: message, 16726 ["type" /* TYPE */]: type, 16727 ["interpolate" /* INTERPOLATE */]: interpolate, 16728 ["normalize" /* NORMALIZE */]: normalize 16729 }; 16730 return ctx; 16731 } 16732 16733 /** @internal */ 16734 const errorMessages$2 = { 16735 // tokenizer error messages 16736 [0 /* EXPECTED_TOKEN */]: `Expected token: '{0}'`, 16737 [1 /* INVALID_TOKEN_IN_PLACEHOLDER */]: `Invalid token in placeholder: '{0}'`, 16738 [2 /* UNTERMINATED_SINGLE_QUOTE_IN_PLACEHOLDER */]: `Unterminated single quote in placeholder`, 16739 [3 /* UNKNOWN_ESCAPE_SEQUENCE */]: `Unknown escape sequence: \\{0}`, 16740 [4 /* INVALID_UNICODE_ESCAPE_SEQUENCE */]: `Invalid unicode escape sequence: {0}`, 16741 [5 /* UNBALANCED_CLOSING_BRACE */]: `Unbalanced closing brace`, 16742 [6 /* UNTERMINATED_CLOSING_BRACE */]: `Unterminated closing brace`, 16743 [7 /* EMPTY_PLACEHOLDER */]: `Empty placeholder`, 16744 [8 /* NOT_ALLOW_NEST_PLACEHOLDER */]: `Not allowed nest placeholder`, 16745 [9 /* INVALID_LINKED_FORMAT */]: `Invalid linked format`, 16746 // parser error messages 16747 [10 /* MUST_HAVE_MESSAGES_IN_PLURAL */]: `Plural must have messages`, 16748 [11 /* UNEXPECTED_EMPTY_LINKED_MODIFIER */]: `Unexpected empty linked modifier`, 16749 [12 /* UNEXPECTED_EMPTY_LINKED_KEY */]: `Unexpected empty linked key`, 16750 [13 /* UNEXPECTED_LEXICAL_ANALYSIS */]: `Unexpected lexical analysis in token: '{0}'` 16751 }; 16752 function createCompileError(code, loc, options = {}) { 16753 const { domain, messages, args } = options; 16754 const msg = format((messages || errorMessages$2)[code] || '', ...(args || [])) 16755 ; 16756 const error = new SyntaxError(String(msg)); 16757 error.code = code; 16758 if (loc) { 16759 error.location = loc; 16760 } 16761 error.domain = domain; 16762 return error; 16763 } 16764 /** @internal */ 16765 function defaultOnError(error) { 16766 throw error; 16767 } 16768 16769 function createPosition(line, column, offset) { 16770 return { line, column, offset }; 16771 } 16772 function createLocation(start, end, source) { 16773 const loc = { start, end }; 16774 if (source != null) { 16775 loc.source = source; 16776 } 16777 return loc; 16778 } 16779 16780 const CHAR_SP = ' '; 16781 const CHAR_CR = '\r'; 16782 const CHAR_LF = '\n'; 16783 const CHAR_LS = String.fromCharCode(0x2028); 16784 const CHAR_PS = String.fromCharCode(0x2029); 16785 function createScanner(str) { 16786 const _buf = str; 16787 let _index = 0; 16788 let _line = 1; 16789 let _column = 1; 16790 let _peekOffset = 0; 16791 const isCRLF = (index) => _buf[index] === CHAR_CR && _buf[index + 1] === CHAR_LF; 16792 const isLF = (index) => _buf[index] === CHAR_LF; 16793 const isPS = (index) => _buf[index] === CHAR_PS; 16794 const isLS = (index) => _buf[index] === CHAR_LS; 16795 const isLineEnd = (index) => isCRLF(index) || isLF(index) || isPS(index) || isLS(index); 16796 const index = () => _index; 16797 const line = () => _line; 16798 const column = () => _column; 16799 const peekOffset = () => _peekOffset; 16800 const charAt = (offset) => isCRLF(offset) || isPS(offset) || isLS(offset) ? CHAR_LF : _buf[offset]; 16801 const currentChar = () => charAt(_index); 16802 const currentPeek = () => charAt(_index + _peekOffset); 16803 function next() { 16804 _peekOffset = 0; 16805 if (isLineEnd(_index)) { 16806 _line++; 16807 _column = 0; 16808 } 16809 if (isCRLF(_index)) { 16810 _index++; 16811 } 16812 _index++; 16813 _column++; 16814 return _buf[_index]; 16815 } 16816 function peek() { 16817 if (isCRLF(_index + _peekOffset)) { 16818 _peekOffset++; 16819 } 16820 _peekOffset++; 16821 return _buf[_index + _peekOffset]; 16822 } 16823 function reset() { 16824 _index = 0; 16825 _line = 1; 16826 _column = 1; 16827 _peekOffset = 0; 16828 } 16829 function resetPeek(offset = 0) { 16830 _peekOffset = offset; 16831 } 16832 function skipToPeek() { 16833 const target = _index + _peekOffset; 16834 // eslint-disable-next-line no-unmodified-loop-condition 16835 while (target !== _index) { 16836 next(); 16837 } 16838 _peekOffset = 0; 16839 } 16840 return { 16841 index, 16842 line, 16843 column, 16844 peekOffset, 16845 charAt, 16846 currentChar, 16847 currentPeek, 16848 next, 16849 peek, 16850 reset, 16851 resetPeek, 16852 skipToPeek 16853 }; 16854 } 16855 16856 const EOF = undefined; 16857 const LITERAL_DELIMITER = "'";
vendor: 4,132 bytes, lines 16858-16981
16858 const ERROR_DOMAIN$1 = 'tokenizer'; 16859 function createTokenizer(source, options = {}) { 16860 const location = options.location !== false; 16861 const _scnr = createScanner(source); 16862 const currentOffset = () => _scnr.index(); 16863 const currentPosition = () => createPosition(_scnr.line(), _scnr.column(), _scnr.index()); 16864 const _initLoc = currentPosition(); 16865 const _initOffset = currentOffset(); 16866 const _context = { 16867 currentType: 14 /* EOF */, 16868 offset: _initOffset, 16869 startLoc: _initLoc, 16870 endLoc: _initLoc, 16871 lastType: 14 /* EOF */, 16872 lastOffset: _initOffset, 16873 lastStartLoc: _initLoc, 16874 lastEndLoc: _initLoc, 16875 braceNest: 0, 16876 inLinked: false, 16877 text: '' 16878 }; 16879 const context = () => _context; 16880 const { onError } = options; 16881 function emitError(code, pos, offset, ...args) { 16882 const ctx = context(); 16883 pos.column += offset; 16884 pos.offset += offset; 16885 if (onError) { 16886 const loc = createLocation(ctx.startLoc, pos); 16887 const err = createCompileError(code, loc, { 16888 domain: ERROR_DOMAIN$1, 16889 args 16890 }); 16891 onError(err); 16892 } 16893 } 16894 function getToken(context, type, value) { 16895 context.endLoc = currentPosition(); 16896 context.currentType = type; 16897 const token = { type }; 16898 if (location) { 16899 token.loc = createLocation(context.startLoc, context.endLoc); 16900 } 16901 if (value != null) { 16902 token.value = value; 16903 } 16904 return token; 16905 } 16906 const getEndToken = (context) => getToken(context, 14 /* EOF */); 16907 function eat(scnr, ch) { 16908 if (scnr.currentChar() === ch) { 16909 scnr.next(); 16910 return ch; 16911 } 16912 else { 16913 emitError(0 /* EXPECTED_TOKEN */, currentPosition(), 0, ch); 16914 return ''; 16915 } 16916 } 16917 function peekSpaces(scnr) { 16918 let buf = ''; 16919 while (scnr.currentPeek() === CHAR_SP || scnr.currentPeek() === CHAR_LF) { 16920 buf += scnr.currentPeek(); 16921 scnr.peek(); 16922 } 16923 return buf; 16924 } 16925 function skipSpaces(scnr) { 16926 const buf = peekSpaces(scnr); 16927 scnr.skipToPeek(); 16928 return buf; 16929 } 16930 function isIdentifierStart(ch) { 16931 if (ch === EOF) { 16932 return false; 16933 } 16934 const cc = ch.charCodeAt(0); 16935 return ((cc >= 97 && cc <= 122) || // a-z 16936 (cc >= 65 && cc <= 90) || // A-Z 16937 cc === 95 // _ 16938 ); 16939 } 16940 function isNumberStart(ch) { 16941 if (ch === EOF) { 16942 return false; 16943 } 16944 const cc = ch.charCodeAt(0); 16945 return cc >= 48 && cc <= 57; // 0-9 16946 } 16947 function isNamedIdentifierStart(scnr, context) { 16948 const { currentType } = context; 16949 if (currentType !== 2 /* BraceLeft */) { 16950 return false; 16951 } 16952 peekSpaces(scnr); 16953 const ret = isIdentifierStart(scnr.currentPeek()); 16954 scnr.resetPeek(); 16955 return ret; 16956 } 16957 function isListIdentifierStart(scnr, context) { 16958 const { currentType } = context; 16959 if (currentType !== 2 /* BraceLeft */) { 16960 return false; 16961 } 16962 peekSpaces(scnr); 16963 const ch = scnr.currentPeek() === '-' ? scnr.peek() : scnr.currentPeek(); 16964 const ret = isNumberStart(ch); 16965 scnr.resetPeek(); 16966 return ret; 16967 } 16968 function isLiteralStart(scnr, context) { 16969 const { currentType } = context; 16970 if (currentType !== 2 /* BraceLeft */) { 16971 return false; 16972 } 16973 peekSpaces(scnr); 16974 const ret = scnr.currentPeek() === LITERAL_DELIMITER; 16975 scnr.resetPeek(); 16976 return ret; 16977 } 16978 function isLinkedDotStart(scnr, context) { 16979 const { currentType } = context; 16980 if (currentType !== 8 /* LinkedAlias */) { 16981 return false;
vendor: 4,241 bytes, lines 16982-17105
16982 } 16983 peekSpaces(scnr); 16984 const ret = scnr.currentPeek() === "." /* LinkedDot */; 16985 scnr.resetPeek(); 16986 return ret; 16987 } 16988 function isLinkedModifierStart(scnr, context) { 16989 const { currentType } = context; 16990 if (currentType !== 9 /* LinkedDot */) { 16991 return false; 16992 } 16993 peekSpaces(scnr); 16994 const ret = isIdentifierStart(scnr.currentPeek()); 16995 scnr.resetPeek(); 16996 return ret; 16997 } 16998 function isLinkedDelimiterStart(scnr, context) { 16999 const { currentType } = context; 17000 if (!(currentType === 8 /* LinkedAlias */ || 17001 currentType === 12 /* LinkedModifier */)) { 17002 return false; 17003 } 17004 peekSpaces(scnr); 17005 const ret = scnr.currentPeek() === ":" /* LinkedDelimiter */; 17006 scnr.resetPeek(); 17007 return ret; 17008 } 17009 function isLinkedReferStart(scnr, context) { 17010 const { currentType } = context; 17011 if (currentType !== 10 /* LinkedDelimiter */) { 17012 return false; 17013 } 17014 const fn = () => { 17015 const ch = scnr.currentPeek(); 17016 if (ch === "{" /* BraceLeft */) { 17017 return isIdentifierStart(scnr.peek()); 17018 } 17019 else if (ch === "@" /* LinkedAlias */ || 17020 ch === "%" /* Modulo */ || 17021 ch === "|" /* Pipe */ || 17022 ch === ":" /* LinkedDelimiter */ || 17023 ch === "." /* LinkedDot */ || 17024 ch === CHAR_SP || 17025 !ch) { 17026 return false; 17027 } 17028 else if (ch === CHAR_LF) { 17029 scnr.peek(); 17030 return fn(); 17031 } 17032 else { 17033 // other characters 17034 return isIdentifierStart(ch); 17035 } 17036 }; 17037 const ret = fn(); 17038 scnr.resetPeek(); 17039 return ret; 17040 } 17041 function isPluralStart(scnr) { 17042 peekSpaces(scnr); 17043 const ret = scnr.currentPeek() === "|" /* Pipe */; 17044 scnr.resetPeek(); 17045 return ret; 17046 } 17047 function isTextStart(scnr, reset = true) { 17048 const fn = (hasSpace = false, prev = '', detectModulo = false) => { 17049 const ch = scnr.currentPeek(); 17050 if (ch === "{" /* BraceLeft */) { 17051 return prev === "%" /* Modulo */ ? false : hasSpace; 17052 } 17053 else if (ch === "@" /* LinkedAlias */ || !ch) { 17054 return prev === "%" /* Modulo */ ? true : hasSpace; 17055 } 17056 else if (ch === "%" /* Modulo */) { 17057 scnr.peek(); 17058 return fn(hasSpace, "%" /* Modulo */, true); 17059 } 17060 else if (ch === "|" /* Pipe */) { 17061 return prev === "%" /* Modulo */ || detectModulo 17062 ? true 17063 : !(prev === CHAR_SP || prev === CHAR_LF); 17064 } 17065 else if (ch === CHAR_SP) { 17066 scnr.peek(); 17067 return fn(true, CHAR_SP, detectModulo); 17068 } 17069 else if (ch === CHAR_LF) { 17070 scnr.peek(); 17071 return fn(true, CHAR_LF, detectModulo); 17072 } 17073 else { 17074 return true; 17075 } 17076 }; 17077 const ret = fn(); 17078 reset && scnr.resetPeek(); 17079 return ret; 17080 } 17081 function takeChar(scnr, fn) { 17082 const ch = scnr.currentChar(); 17083 if (ch === EOF) { 17084 return EOF; 17085 } 17086 if (fn(ch)) { 17087 scnr.next(); 17088 return ch; 17089 } 17090 return null; 17091 } 17092 function takeIdentifierChar(scnr) { 17093 const closure = (ch) => { 17094 const cc = ch.charCodeAt(0); 17095 return ((cc >= 97 && cc <= 122) || // a-z 17096 (cc >= 65 && cc <= 90) || // A-Z 17097 (cc >= 48 && cc <= 57) || // 0-9 17098 cc === 95 || // _ 17099 cc === 36 // $ 17100 ); 17101 }; 17102 return takeChar(scnr, closure); 17103 } 17104 function takeDigit(scnr) { 17105 const closure = (ch) => {
17106 const cc = ch.charCodeAt(0); 17107 return cc >= 48 && cc <= 57; // 0-9 17108 }; 17109 return takeChar(scnr, closure); 17110 } 17111 function takeHexDigit(scnr) { 17112 const closure = (ch) => { 17113 const cc = ch.charCodeAt(0); 17114 return ((cc >= 48 && cc <= 57) || // 0-9 17115 (cc >= 65 && cc <= 70) || // A-F 17116 (cc >= 97 && cc <= 102)); // a-f 17117 }; 17118 return takeChar(scnr, closure); 17119 } 17120 function getDigits(scnr) { 17121 let ch = ''; 17122 let num = ''; 17123 while ((ch = takeDigit(scnr))) { 17124 num += ch; 17125 } 17126 return num; 17127 } 17128 function readText(scnr) { 17129 const fn = (buf) => { 17130 const ch = scnr.currentChar(); 17131 if (ch === "{" /* BraceLeft */ || 17132 ch === "}" /* BraceRight */ || 17133 ch === "@" /* LinkedAlias */ || 17134 !ch) { 17135 return buf; 17136 } 17137 else if (ch === "%" /* Modulo */) { 17138 if (isTextStart(scnr)) { 17139 buf += ch; 17140 scnr.next(); 17141 return fn(buf); 17142 } 17143 else { 17144 return buf; 17145 } 17146 } 17147 else if (ch === "|" /* Pipe */) { 17148 return buf; 17149 } 17150 else if (ch === CHAR_SP || ch === CHAR_LF) { 17151 if (isTextStart(scnr)) { 17152 buf += ch; 17153 scnr.next(); 17154 return fn(buf); 17155 } 17156 else if (isPluralStart(scnr)) { 17157 return buf; 17158 } 17159 else { 17160 buf += ch; 17161 scnr.next(); 17162 return fn(buf); 17163 } 17164 } 17165 else { 17166 buf += ch; 17167 scnr.next(); 17168 return fn(buf); 17169 } 17170 }; 17171 return fn(''); 17172 } 17173 function readNamedIdentifier(scnr) { 17174 skipSpaces(scnr); 17175 let ch = ''; 17176 let name = ''; 17177 while ((ch = takeIdentifierChar(scnr))) { 17178 name += ch; 17179 } 17180 if (scnr.currentChar() === EOF) { 17181 emitError(6 /* UNTERMINATED_CLOSING_BRACE */, currentPosition(), 0); 17182 } 17183 return name; 17184 } 17185 function readListIdentifier(scnr) { 17186 skipSpaces(scnr); 17187 let value = ''; 17188 if (scnr.currentChar() === '-') { 17189 scnr.next(); 17190 value += `-${getDigits(scnr)}`; 17191 } 17192 else { 17193 value += getDigits(scnr); 17194 } 17195 if (scnr.currentChar() === EOF) { 17196 emitError(6 /* UNTERMINATED_CLOSING_BRACE */, currentPosition(), 0); 17197 } 17198 return value; 17199 } 17200 function readLiteral(scnr) { 17201 skipSpaces(scnr); 17202 eat(scnr, `\'`); 17203 let ch = ''; 17204 let literal = ''; 17205 const fn = (x) => x !== LITERAL_DELIMITER && x !== CHAR_LF; 17206 while ((ch = takeChar(scnr, fn))) { 17207 if (ch === '\\') { 17208 literal += readEscapeSequence(scnr); 17209 } 17210 else { 17211 literal += ch; 17212 } 17213 } 17214 const current = scnr.currentChar(); 17215 if (current === CHAR_LF || current === EOF) { 17216 emitError(2 /* UNTERMINATED_SINGLE_QUOTE_IN_PLACEHOLDER */, currentPosition(), 0); 17217 // TODO: Is it correct really? 17218 if (current === CHAR_LF) { 17219 scnr.next(); 17220 eat(scnr, `\'`); 17221 } 17222 return literal; 17223 } 17224 eat(scnr, `\'`); 17225 return literal; 17226 } 17227 function readEscapeSequence(scnr) { 17228 const ch = scnr.currentChar(); 17229 switch (ch) { 17230 case '\\': 17231 case `\'`: 17232 scnr.next(); 17233 return `\\${ch}`; 17234 case 'u': 17235 return readUnicodeEscapeSequence(scnr, ch, 4); 17236 case 'U': 17237 return readUnicodeEscapeSequence(scnr, ch, 6); 17238 default: 17239 emitError(3 /* UNKNOWN_ESCAPE_SEQUENCE */, currentPosition(), 0, ch); 17240 return ''; 17241 } 17242 } 17243 function readUnicodeEscapeSequence(scnr, unicode, digits) { 17244 eat(scnr, unicode); 17245 let sequence = ''; 17246 for (let i = 0; i < digits; i++) { 17247 const ch = takeHexDigit(scnr); 17248 if (!ch) {
17249 emitError(4 /* INVALID_UNICODE_ESCAPE_SEQUENCE */, currentPosition(), 0, `\\${unicode}${sequence}${scnr.currentChar()}`); 17250 break; 17251 } 17252 sequence += ch; 17253 } 17254 return `\\${unicode}${sequence}`; 17255 } 17256 function readInvalidIdentifier(scnr) { 17257 skipSpaces(scnr); 17258 let ch = ''; 17259 let identifiers = ''; 17260 const closure = (ch) => ch !== "{" /* BraceLeft */ && 17261 ch !== "}" /* BraceRight */ && 17262 ch !== CHAR_SP && 17263 ch !== CHAR_LF; 17264 while ((ch = takeChar(scnr, closure))) { 17265 identifiers += ch; 17266 } 17267 return identifiers; 17268 } 17269 function readLinkedModifier(scnr) { 17270 let ch = ''; 17271 let name = ''; 17272 while ((ch = takeIdentifierChar(scnr))) { 17273 name += ch; 17274 } 17275 return name; 17276 } 17277 function readLinkedRefer(scnr) { 17278 const fn = (detect = false, buf) => { 17279 const ch = scnr.currentChar(); 17280 if (ch === "{" /* BraceLeft */ || 17281 ch === "%" /* Modulo */ || 17282 ch === "@" /* LinkedAlias */ || 17283 ch === "|" /* Pipe */ || 17284 !ch) { 17285 return buf; 17286 } 17287 else if (ch === CHAR_SP) { 17288 return buf; 17289 } 17290 else if (ch === CHAR_LF) { 17291 buf += ch; 17292 scnr.next(); 17293 return fn(detect, buf); 17294 } 17295 else { 17296 buf += ch; 17297 scnr.next(); 17298 return fn(true, buf); 17299 } 17300 }; 17301 return fn(false, ''); 17302 } 17303 function readPlural(scnr) { 17304 skipSpaces(scnr); 17305 const plural = eat(scnr, "|" /* Pipe */); 17306 skipSpaces(scnr); 17307 return plural; 17308 } 17309 // TODO: We need refactoring of token parsing ... 17310 function readTokenInPlaceholder(scnr, context) { 17311 let token = null; 17312 const ch = scnr.currentChar(); 17313 switch (ch) { 17314 case "{" /* BraceLeft */: 17315 if (context.braceNest >= 1) { 17316 emitError(8 /* NOT_ALLOW_NEST_PLACEHOLDER */, currentPosition(), 0); 17317 } 17318 scnr.next(); 17319 token = getToken(context, 2 /* BraceLeft */, "{" /* BraceLeft */); 17320 skipSpaces(scnr); 17321 context.braceNest++; 17322 return token; 17323 case "}" /* BraceRight */: 17324 if (context.braceNest > 0 && 17325 context.currentType === 2 /* BraceLeft */) { 17326 emitError(7 /* EMPTY_PLACEHOLDER */, currentPosition(), 0); 17327 } 17328 scnr.next(); 17329 token = getToken(context, 3 /* BraceRight */, "}" /* BraceRight */); 17330 context.braceNest--; 17331 context.braceNest > 0 && skipSpaces(scnr); 17332 if (context.inLinked && context.braceNest === 0) { 17333 context.inLinked = false; 17334 } 17335 return token; 17336 case "@" /* LinkedAlias */: 17337 if (context.braceNest > 0) { 17338 emitError(6 /* UNTERMINATED_CLOSING_BRACE */, currentPosition(), 0); 17339 } 17340 token = readTokenInLinked(scnr, context) || getEndToken(context); 17341 context.braceNest = 0; 17342 return token; 17343 default: 17344 let validNamedIdentifier = true; 17345 let validListIdentifier = true; 17346 let validLiteral = true; 17347 if (isPluralStart(scnr)) { 17348 if (context.braceNest > 0) { 17349 emitError(6 /* UNTERMINATED_CLOSING_BRACE */, currentPosition(), 0); 17350 } 17351 token = getToken(context, 1 /* Pipe */, readPlural(scnr)); 17352 // reset 17353 context.braceNest = 0;
vendor: 2,438 bytes, lines 17354-17400
17354 context.inLinked = false; 17355 return token; 17356 } 17357 if (context.braceNest > 0 && 17358 (context.currentType === 5 /* Named */ || 17359 context.currentType === 6 /* List */ || 17360 context.currentType === 7 /* Literal */)) { 17361 emitError(6 /* UNTERMINATED_CLOSING_BRACE */, currentPosition(), 0); 17362 context.braceNest = 0; 17363 return readToken(scnr, context); 17364 } 17365 if ((validNamedIdentifier = isNamedIdentifierStart(scnr, context))) { 17366 token = getToken(context, 5 /* Named */, readNamedIdentifier(scnr)); 17367 skipSpaces(scnr); 17368 return token; 17369 } 17370 if ((validListIdentifier = isListIdentifierStart(scnr, context))) { 17371 token = getToken(context, 6 /* List */, readListIdentifier(scnr)); 17372 skipSpaces(scnr); 17373 return token; 17374 } 17375 if ((validLiteral = isLiteralStart(scnr, context))) { 17376 token = getToken(context, 7 /* Literal */, readLiteral(scnr)); 17377 skipSpaces(scnr); 17378 return token; 17379 } 17380 if (!validNamedIdentifier && !validListIdentifier && !validLiteral) { 17381 // TODO: we should be re-designed invalid cases, when we will extend message syntax near the future ... 17382 token = getToken(context, 13 /* InvalidPlace */, readInvalidIdentifier(scnr)); 17383 emitError(1 /* INVALID_TOKEN_IN_PLACEHOLDER */, currentPosition(), 0, token.value); 17384 skipSpaces(scnr); 17385 return token; 17386 } 17387 break; 17388 } 17389 return token; 17390 } 17391 // TODO: We need refactoring of token parsing ... 17392 function readTokenInLinked(scnr, context) { 17393 const { currentType } = context; 17394 let token = null; 17395 const ch = scnr.currentChar(); 17396 if ((currentType === 8 /* LinkedAlias */ || 17397 currentType === 9 /* LinkedDot */ || 17398 currentType === 12 /* LinkedModifier */ || 17399 currentType === 10 /* LinkedDelimiter */) && 17400 (ch === CHAR_LF || ch === CHAR_SP)) {
vendor: 7,142 bytes, lines 17401-17579
17401 emitError(9 /* INVALID_LINKED_FORMAT */, currentPosition(), 0); 17402 } 17403 switch (ch) { 17404 case "@" /* LinkedAlias */: 17405 scnr.next(); 17406 token = getToken(context, 8 /* LinkedAlias */, "@" /* LinkedAlias */); 17407 context.inLinked = true; 17408 return token; 17409 case "." /* LinkedDot */: 17410 skipSpaces(scnr); 17411 scnr.next(); 17412 return getToken(context, 9 /* LinkedDot */, "." /* LinkedDot */); 17413 case ":" /* LinkedDelimiter */: 17414 skipSpaces(scnr); 17415 scnr.next(); 17416 return getToken(context, 10 /* LinkedDelimiter */, ":" /* LinkedDelimiter */); 17417 default: 17418 if (isPluralStart(scnr)) { 17419 token = getToken(context, 1 /* Pipe */, readPlural(scnr)); 17420 // reset 17421 context.braceNest = 0; 17422 context.inLinked = false; 17423 return token; 17424 } 17425 if (isLinkedDotStart(scnr, context) || 17426 isLinkedDelimiterStart(scnr, context)) { 17427 skipSpaces(scnr); 17428 return readTokenInLinked(scnr, context); 17429 } 17430 if (isLinkedModifierStart(scnr, context)) { 17431 skipSpaces(scnr); 17432 return getToken(context, 12 /* LinkedModifier */, readLinkedModifier(scnr)); 17433 } 17434 if (isLinkedReferStart(scnr, context)) { 17435 skipSpaces(scnr); 17436 if (ch === "{" /* BraceLeft */) { 17437 // scan the placeholder 17438 return readTokenInPlaceholder(scnr, context) || token; 17439 } 17440 else { 17441 return getToken(context, 11 /* LinkedKey */, readLinkedRefer(scnr)); 17442 } 17443 } 17444 if (currentType === 8 /* LinkedAlias */) { 17445 emitError(9 /* INVALID_LINKED_FORMAT */, currentPosition(), 0); 17446 } 17447 context.braceNest = 0; 17448 context.inLinked = false; 17449 return readToken(scnr, context); 17450 } 17451 } 17452 // TODO: We need refactoring of token parsing ... 17453 function readToken(scnr, context) { 17454 let token = { type: 14 /* EOF */ }; 17455 if (context.braceNest > 0) { 17456 return readTokenInPlaceholder(scnr, context) || getEndToken(context); 17457 } 17458 if (context.inLinked) { 17459 return readTokenInLinked(scnr, context) || getEndToken(context); 17460 } 17461 const ch = scnr.currentChar(); 17462 switch (ch) { 17463 case "{" /* BraceLeft */: 17464 return readTokenInPlaceholder(scnr, context) || getEndToken(context); 17465 case "}" /* BraceRight */: 17466 emitError(5 /* UNBALANCED_CLOSING_BRACE */, currentPosition(), 0); 17467 scnr.next(); 17468 return getToken(context, 3 /* BraceRight */, "}" /* BraceRight */); 17469 case "@" /* LinkedAlias */: 17470 return readTokenInLinked(scnr, context) || getEndToken(context); 17471 default: 17472 if (isPluralStart(scnr)) { 17473 token = getToken(context, 1 /* Pipe */, readPlural(scnr)); 17474 // reset 17475 context.braceNest = 0; 17476 context.inLinked = false; 17477 return token; 17478 } 17479 if (isTextStart(scnr)) { 17480 return getToken(context, 0 /* Text */, readText(scnr)); 17481 } 17482 if (ch === "%" /* Modulo */) { 17483 scnr.next(); 17484 return getToken(context, 4 /* Modulo */, "%" /* Modulo */); 17485 } 17486 break; 17487 } 17488 return token; 17489 } 17490 function nextToken() { 17491 const { currentType, offset, startLoc, endLoc } = _context; 17492 _context.lastType = currentType; 17493 _context.lastOffset = offset; 17494 _context.lastStartLoc = startLoc; 17495 _context.lastEndLoc = endLoc; 17496 _context.offset = currentOffset(); 17497 _context.startLoc = currentPosition(); 17498 if (_scnr.currentChar() === EOF) { 17499 return getToken(_context, 14 /* EOF */); 17500 } 17501 return readToken(_scnr, _context); 17502 } 17503 return { 17504 nextToken, 17505 currentOffset, 17506 currentPosition, 17507 context 17508 }; 17509 } 17510 17511 const ERROR_DOMAIN = 'parser'; 17512 // Backslash backslash, backslash quote, uHHHH, UHHHHHH. 17513 const KNOWN_ESCAPES = /(?:\\\\|\\'|\\u([0-9a-fA-F]{4})|\\U([0-9a-fA-F]{6}))/g; 17514 function fromEscapeSequence(match, codePoint4, codePoint6) { 17515 switch (match) { 17516 case `\\\\`: 17517 return `\\`; 17518 case `\\\'`: 17519 return `\'`; 17520 default: { 17521 const codePoint = parseInt(codePoint4 || codePoint6, 16); 17522 if (codePoint <= 0xd7ff || codePoint >= 0xe000) { 17523 return String.fromCodePoint(codePoint); 17524 } 17525 // invalid ... 17526 // Replace them with U+FFFD REPLACEMENT CHARACTER. 17527 return '�'; 17528 } 17529 } 17530 } 17531 function createParser(options = {}) { 17532 const location = options.location !== false; 17533 const { onError } = options; 17534 function emitError(tokenzer, code, start, offset, ...args) { 17535 const end = tokenzer.currentPosition(); 17536 end.offset += offset; 17537 end.column += offset; 17538 if (onError) { 17539 const loc = createLocation(start, end); 17540 const err = createCompileError(code, loc, { 17541 domain: ERROR_DOMAIN, 17542 args 17543 }); 17544 onError(err); 17545 } 17546 } 17547 function startNode(type, offset, loc) { 17548 const node = { 17549 type, 17550 start: offset, 17551 end: offset 17552 }; 17553 if (location) { 17554 node.loc = { start: loc, end: loc }; 17555 } 17556 return node; 17557 } 17558 function endNode(node, offset, pos, type) { 17559 node.end = offset; 17560 if (type) { 17561 node.type = type; 17562 } 17563 if (location && node.loc) { 17564 node.loc.end = pos; 17565 } 17566 } 17567 function parseText(tokenizer, value) { 17568 const context = tokenizer.context(); 17569 const node = startNode(3 /* Text */, context.offset, context.startLoc); 17570 node.value = value; 17571 endNode(node, tokenizer.currentOffset(), tokenizer.currentPosition()); 17572 return node; 17573 } 17574 function parseList(tokenizer, index) { 17575 const context = tokenizer.context(); 17576 const { lastOffset: offset, lastStartLoc: loc } = context; // get brace left loc 17577 const node = startNode(5 /* List */, offset, loc); 17578 node.index = parseInt(index, 10); 17579 tokenizer.nextToken();
vendor: 10,971 bytes, lines 17579-17819
17579 // skip brach right 17580 endNode(node, tokenizer.currentOffset(), tokenizer.currentPosition()); 17581 return node; 17582 } 17583 function parseNamed(tokenizer, key) { 17584 const context = tokenizer.context(); 17585 const { lastOffset: offset, lastStartLoc: loc } = context; // get brace left loc 17586 const node = startNode(4 /* Named */, offset, loc); 17587 node.key = key; 17588 tokenizer.nextToken(); // skip brach right 17589 endNode(node, tokenizer.currentOffset(), tokenizer.currentPosition()); 17590 return node; 17591 } 17592 function parseLiteral(tokenizer, value) { 17593 const context = tokenizer.context(); 17594 const { lastOffset: offset, lastStartLoc: loc } = context; // get brace left loc 17595 const node = startNode(9 /* Literal */, offset, loc); 17596 node.value = value.replace(KNOWN_ESCAPES, fromEscapeSequence); 17597 tokenizer.nextToken(); // skip brach right 17598 endNode(node, tokenizer.currentOffset(), tokenizer.currentPosition()); 17599 return node; 17600 } 17601 function parseLinkedModifier(tokenizer) { 17602 const token = tokenizer.nextToken(); 17603 const context = tokenizer.context(); 17604 const { lastOffset: offset, lastStartLoc: loc } = context; // get linked dot loc 17605 const node = startNode(8 /* LinkedModifier */, offset, loc); 17606 if (token.type !== 12 /* LinkedModifier */) { 17607 // empty modifier 17608 emitError(tokenizer, 11 /* UNEXPECTED_EMPTY_LINKED_MODIFIER */, context.lastStartLoc, 0); 17609 node.value = ''; 17610 endNode(node, offset, loc); 17611 return { 17612 nextConsumeToken: token, 17613 node 17614 }; 17615 } 17616 // check token 17617 if (token.value == null) { 17618 emitError(tokenizer, 13 /* UNEXPECTED_LEXICAL_ANALYSIS */, context.lastStartLoc, 0, getTokenCaption(token)); 17619 } 17620 node.value = token.value || ''; 17621 endNode(node, tokenizer.currentOffset(), tokenizer.currentPosition()); 17622 return { 17623 node 17624 }; 17625 } 17626 function parseLinkedKey(tokenizer, value) { 17627 const context = tokenizer.context(); 17628 const node = startNode(7 /* LinkedKey */, context.offset, context.startLoc); 17629 node.value = value; 17630 endNode(node, tokenizer.currentOffset(), tokenizer.currentPosition()); 17631 return node; 17632 } 17633 function parseLinked(tokenizer) { 17634 const context = tokenizer.context(); 17635 const linkedNode = startNode(6 /* Linked */, context.offset, context.startLoc); 17636 let token = tokenizer.nextToken(); 17637 if (token.type === 9 /* LinkedDot */) { 17638 const parsed = parseLinkedModifier(tokenizer); 17639 linkedNode.modifier = parsed.node; 17640 token = parsed.nextConsumeToken || tokenizer.nextToken(); 17641 } 17642 // asset check token 17643 if (token.type !== 10 /* LinkedDelimiter */) { 17644 emitError(tokenizer, 13 /* UNEXPECTED_LEXICAL_ANALYSIS */, context.lastStartLoc, 0, getTokenCaption(token)); 17645 } 17646 token = tokenizer.nextToken(); 17647 // skip brace left 17648 if (token.type === 2 /* BraceLeft */) { 17649 token = tokenizer.nextToken(); 17650 } 17651 switch (token.type) { 17652 case 11 /* LinkedKey */: 17653 if (token.value == null) { 17654 emitError(tokenizer, 13 /* UNEXPECTED_LEXICAL_ANALYSIS */, context.lastStartLoc, 0, getTokenCaption(token)); 17655 } 17656 linkedNode.key = parseLinkedKey(tokenizer, token.value || ''); 17657 break; 17658 case 5 /* Named */: 17659 if (token.value == null) { 17660 emitError(tokenizer, 13 /* UNEXPECTED_LEXICAL_ANALYSIS */, context.lastStartLoc, 0, getTokenCaption(token)); 17661 } 17662 linkedNode.key = parseNamed(tokenizer, token.value || ''); 17663 break; 17664 case 6 /* List */: 17665 if (token.value == null) { 17666 emitError(tokenizer, 13 /* UNEXPECTED_LEXICAL_ANALYSIS */, context.lastStartLoc, 0, getTokenCaption(token)); 17667 } 17668 linkedNode.key = parseList(tokenizer, token.value || ''); 17669 break; 17670 case 7 /* Literal */: 17671 if (token.value == null) { 17672 emitError(tokenizer, 13 /* UNEXPECTED_LEXICAL_ANALYSIS */, context.lastStartLoc, 0, getTokenCaption(token)); 17673 } 17674 linkedNode.key = parseLiteral(tokenizer, token.value || ''); 17675 break; 17676 default: 17677 // empty key 17678 emitError(tokenizer, 12 /* UNEXPECTED_EMPTY_LINKED_KEY */, context.lastStartLoc, 0); 17679 const nextContext = tokenizer.context(); 17680 const emptyLinkedKeyNode = startNode(7 /* LinkedKey */, nextContext.offset, nextContext.startLoc); 17681 emptyLinkedKeyNode.value = ''; 17682 endNode(emptyLinkedKeyNode, nextContext.offset, nextContext.startLoc); 17683 linkedNode.key = emptyLinkedKeyNode; 17684 endNode(linkedNode, nextContext.offset, nextContext.startLoc); 17685 return { 17686 nextConsumeToken: token, 17687 node: linkedNode 17688 }; 17689 } 17690 endNode(linkedNode, tokenizer.currentOffset(), tokenizer.currentPosition()); 17691 return { 17692 node: linkedNode 17693 }; 17694 } 17695 function parseMessage(tokenizer) { 17696 const context = tokenizer.context(); 17697 const startOffset = context.currentType === 1 /* Pipe */ 17698 ? tokenizer.currentOffset() 17699 : context.offset; 17700 const startLoc = context.currentType === 1 /* Pipe */ 17701 ? context.endLoc 17702 : context.startLoc; 17703 const node = startNode(2 /* Message */, startOffset, startLoc); 17704 node.items = []; 17705 let nextToken = null; 17706 do { 17707 const token = nextToken || tokenizer.nextToken(); 17708 nextToken = null; 17709 switch (token.type) { 17710 case 0 /* Text */: 17711 if (token.value == null) { 17712 emitError(tokenizer, 13 /* UNEXPECTED_LEXICAL_ANALYSIS */, context.lastStartLoc, 0, getTokenCaption(token)); 17713 } 17714 node.items.push(parseText(tokenizer, token.value || '')); 17715 break; 17716 case 6 /* List */: 17717 if (token.value == null) { 17718 emitError(tokenizer, 13 /* UNEXPECTED_LEXICAL_ANALYSIS */, context.lastStartLoc, 0, getTokenCaption(token)); 17719 } 17720 node.items.push(parseList(tokenizer, token.value || '')); 17721 break; 17722 case 5 /* Named */: 17723 if (token.value == null) { 17724 emitError(tokenizer, 13 /* UNEXPECTED_LEXICAL_ANALYSIS */, context.lastStartLoc, 0, getTokenCaption(token)); 17725 } 17726 node.items.push(parseNamed(tokenizer, token.value || '')); 17727 break; 17728 case 7 /* Literal */: 17729 if (token.value == null) { 17730 emitError(tokenizer, 13 /* UNEXPECTED_LEXICAL_ANALYSIS */, context.lastStartLoc, 0, getTokenCaption(token)); 17731 } 17732 node.items.push(parseLiteral(tokenizer, token.value || '')); 17733 break; 17734 case 8 /* LinkedAlias */: 17735 const parsed = parseLinked(tokenizer); 17736 node.items.push(parsed.node); 17737 nextToken = parsed.nextConsumeToken || null; 17738 break; 17739 } 17740 } while (context.currentType !== 14 /* EOF */ && 17741 context.currentType !== 1 /* Pipe */); 17742 // adjust message node loc 17743 const endOffset = context.currentType === 1 /* Pipe */ 17744 ? context.lastOffset 17745 : tokenizer.currentOffset(); 17746 const endLoc = context.currentType === 1 /* Pipe */ 17747 ? context.lastEndLoc 17748 : tokenizer.currentPosition(); 17749 endNode(node, endOffset, endLoc); 17750 return node; 17751 } 17752 function parsePlural(tokenizer, offset, loc, msgNode) { 17753 const context = tokenizer.context(); 17754 let hasEmptyMessage = msgNode.items.length === 0; 17755 const node = startNode(1 /* Plural */, offset, loc); 17756 node.cases = []; 17757 node.cases.push(msgNode); 17758 do { 17759 const msg = parseMessage(tokenizer); 17760 if (!hasEmptyMessage) { 17761 hasEmptyMessage = msg.items.length === 0; 17762 } 17763 node.cases.push(msg); 17764 } while (context.currentType !== 14 /* EOF */); 17765 if (hasEmptyMessage) { 17766 emitError(tokenizer, 10 /* MUST_HAVE_MESSAGES_IN_PLURAL */, loc, 0); 17767 } 17768 endNode(node, tokenizer.currentOffset(), tokenizer.currentPosition()); 17769 return node; 17770 } 17771 function parseResource(tokenizer) { 17772 const context = tokenizer.context(); 17773 const { offset, startLoc } = context; 17774 const msgNode = parseMessage(tokenizer); 17775 if (context.currentType === 14 /* EOF */) { 17776 return msgNode; 17777 } 17778 else { 17779 return parsePlural(tokenizer, offset, startLoc, msgNode); 17780 } 17781 } 17782 function parse(source) { 17783 const tokenizer = createTokenizer(source, assign({}, options)); 17784 const context = tokenizer.context(); 17785 const node = startNode(0 /* Resource */, context.offset, context.startLoc); 17786 if (location && node.loc) { 17787 node.loc.source = source; 17788 } 17789 node.body = parseResource(tokenizer); 17790 // assert whether achieved to EOF 17791 if (context.currentType !== 14 /* EOF */) { 17792 emitError(tokenizer, 13 /* UNEXPECTED_LEXICAL_ANALYSIS */, context.lastStartLoc, 0, source[context.offset] || ''); 17793 } 17794 endNode(node, tokenizer.currentOffset(), tokenizer.currentPosition()); 17795 return node; 17796 } 17797 return { parse }; 17798 } 17799 function getTokenCaption(token) { 17800 if (token.type === 14 /* EOF */) { 17801 return 'EOF'; 17802 } 17803 const name = (token.value || '').replace(/\r?\n/gu, '\\n'); 17804 return name.length > 10 ? name.slice(0, 9) + 'â¦' : name; 17805 } 17806 17807 function createTransformer(ast, options = {} // eslint-disable-line 17808 ) { 17809 const _context = { 17810 ast, 17811 helpers: new Set() 17812 }; 17813 const context = () => _context; 17814 const helper = (name) => { 17815 _context.helpers.add(name); 17816 return name; 17817 }; 17818 return { context, helper }; 17819 }
17820 function traverseNodes(nodes, transformer) { 17821 for (let i = 0; i < nodes.length; i++) { 17822 traverseNode(nodes[i], transformer); 17823 } 17824 } 17825 function traverseNode(node, transformer) { 17826 // TODO: if we need pre-hook of transform, should be implemented to here 17827 switch (node.type) { 17828 case 1 /* Plural */: 17829 traverseNodes(node.cases, transformer); 17830 transformer.helper("plural" /* PLURAL */); 17831 break; 17832 case 2 /* Message */: 17833 traverseNodes(node.items, transformer); 17834 break; 17835 case 6 /* Linked */: 17836 const linked = node; 17837 traverseNode(linked.key, transformer); 17838 transformer.helper("linked" /* LINKED */); 17839 break; 17840 case 5 /* List */: 17841 transformer.helper("interpolate" /* INTERPOLATE */); 17842 transformer.helper("list" /* LIST */); 17843 break; 17844 case 4 /* Named */: 17845 transformer.helper("interpolate" /* INTERPOLATE */); 17846 transformer.helper("named" /* NAMED */); 17847 break; 17848 } 17849 // TODO: if we need post-hook of transform, should be implemented to here 17850 } 17851 // transform AST 17852 function transform(ast, options = {} // eslint-disable-line 17853 ) { 17854 const transformer = createTransformer(ast); 17855 transformer.helper("normalize" /* NORMALIZE */); 17856 // traverse 17857 ast.body && traverseNode(ast.body, transformer); 17858 // set meta information 17859 const context = transformer.context(); 17860 ast.helpers = Array.from(context.helpers); 17861 } 17862 17863 function createCodeGenerator(ast, options) { 17864 const { sourceMap, filename, breakLineCode, needIndent: _needIndent } = options; 17865 const _context = { 17866 source: ast.loc.source, 17867 filename, 17868 code: '', 17869 column: 1, 17870 line: 1, 17871 offset: 0, 17872 map: undefined, 17873 breakLineCode, 17874 needIndent: _needIndent, 17875 indentLevel: 0 17876 }; 17877 const context = () => _context; 17878 function push(code, node) { 17879 _context.code += code; 17880 } 17881 function _newline(n, withBreakLine = true) { 17882 const _breakLineCode = withBreakLine ? breakLineCode : ''; 17883 push(_needIndent ? _breakLineCode + ` `.repeat(n) : _breakLineCode); 17884 } 17885 function indent(withNewLine = true) { 17886 const level = ++_context.indentLevel; 17887 withNewLine && _newline(level); 17888 } 17889 function deindent(withNewLine = true) { 17890 const level = --_context.indentLevel; 17891 withNewLine && _newline(level); 17892 } 17893 function newline() {
vendor: 6,057 bytes, lines 17894-18071
17894 _newline(_context.indentLevel); 17895 } 17896 const helper = (key) => `_${key}`; 17897 const needIndent = () => _context.needIndent; 17898 return { 17899 context, 17900 push, 17901 indent, 17902 deindent, 17903 newline, 17904 helper, 17905 needIndent 17906 }; 17907 } 17908 function generateLinkedNode(generator, node) { 17909 const { helper } = generator; 17910 generator.push(`${helper("linked" /* LINKED */)}(`); 17911 generateNode(generator, node.key); 17912 if (node.modifier) { 17913 generator.push(`, `); 17914 generateNode(generator, node.modifier); 17915 } 17916 generator.push(`)`); 17917 } 17918 function generateMessageNode(generator, node) { 17919 const { helper, needIndent } = generator; 17920 generator.push(`${helper("normalize" /* NORMALIZE */)}([`); 17921 generator.indent(needIndent()); 17922 const length = node.items.length; 17923 for (let i = 0; i < length; i++) { 17924 generateNode(generator, node.items[i]); 17925 if (i === length - 1) { 17926 break; 17927 } 17928 generator.push(', '); 17929 } 17930 generator.deindent(needIndent()); 17931 generator.push('])'); 17932 } 17933 function generatePluralNode(generator, node) { 17934 const { helper, needIndent } = generator; 17935 if (node.cases.length > 1) { 17936 generator.push(`${helper("plural" /* PLURAL */)}([`); 17937 generator.indent(needIndent()); 17938 const length = node.cases.length; 17939 for (let i = 0; i < length; i++) { 17940 generateNode(generator, node.cases[i]); 17941 if (i === length - 1) { 17942 break; 17943 } 17944 generator.push(', '); 17945 } 17946 generator.deindent(needIndent()); 17947 generator.push(`])`); 17948 } 17949 } 17950 function generateResource(generator, node) { 17951 if (node.body) { 17952 generateNode(generator, node.body); 17953 } 17954 else { 17955 generator.push('null'); 17956 } 17957 } 17958 function generateNode(generator, node) { 17959 const { helper } = generator; 17960 switch (node.type) { 17961 case 0 /* Resource */: 17962 generateResource(generator, node); 17963 break; 17964 case 1 /* Plural */: 17965 generatePluralNode(generator, node); 17966 break; 17967 case 2 /* Message */: 17968 generateMessageNode(generator, node); 17969 break; 17970 case 6 /* Linked */: 17971 generateLinkedNode(generator, node); 17972 break; 17973 case 8 /* LinkedModifier */: 17974 generator.push(JSON.stringify(node.value), node); 17975 break; 17976 case 7 /* LinkedKey */: 17977 generator.push(JSON.stringify(node.value), node); 17978 break; 17979 case 5 /* List */: 17980 generator.push(`${helper("interpolate" /* INTERPOLATE */)}(${helper("list" /* LIST */)}(${node.index}))`, node); 17981 break; 17982 case 4 /* Named */: 17983 generator.push(`${helper("interpolate" /* INTERPOLATE */)}(${helper("named" /* NAMED */)}(${JSON.stringify(node.key)}))`, node); 17984 break; 17985 case 9 /* Literal */: 17986 generator.push(JSON.stringify(node.value), node); 17987 break; 17988 case 3 /* Text */: 17989 generator.push(JSON.stringify(node.value), node); 17990 break; 17991 default: 17992 { 17993 throw new Error(`unhandled codegen node type: ${node.type}`); 17994 } 17995 } 17996 } 17997 // generate code from AST 17998 const generate = (ast, options = {} // eslint-disable-line 17999 ) => { 18000 const mode = isString(options.mode) ? options.mode : 'normal'; 18001 const filename = isString(options.filename) 18002 ? options.filename 18003 : 'message.intl'; 18004 const sourceMap = !!options.sourceMap; 18005 // prettier-ignore 18006 const breakLineCode = options.breakLineCode != null 18007 ? options.breakLineCode 18008 : mode === 'arrow' 18009 ? ';' 18010 : '\n'; 18011 const needIndent = options.needIndent ? options.needIndent : mode !== 'arrow'; 18012 const helpers = ast.helpers || []; 18013 const generator = createCodeGenerator(ast, { 18014 mode, 18015 filename, 18016 sourceMap, 18017 breakLineCode, 18018 needIndent 18019 }); 18020 generator.push(mode === 'normal' ? `function __msg__ (ctx) {` : `(ctx) => {`); 18021 generator.indent(needIndent); 18022 if (helpers.length > 0) { 18023 generator.push(`const { ${helpers.map(s => `${s}: _${s}`).join(', ')} } = ctx`); 18024 generator.newline(); 18025 } 18026 generator.push(`return `); 18027 generateNode(generator, ast); 18028 generator.deindent(needIndent); 18029 generator.push(`}`); 18030 const { code, map } = generator.context(); 18031 return { 18032 ast, 18033 code, 18034 map: map ? map.toJSON() : undefined // eslint-disable-line @typescript-eslint/no-explicit-any 18035 }; 18036 }; 18037 18038 function baseCompile(source, options = {}) { 18039 const assignedOptions = assign({}, options); 18040 // parse source codes 18041 const parser = createParser(assignedOptions); 18042 const ast = parser.parse(source); 18043 // transform ASTs 18044 transform(ast, assignedOptions); 18045 // generate javascript codes 18046 return generate(ast, assignedOptions); 18047 } 18048 18049 let devtools = null; 18050 function setDevToolsHook(hook) { 18051 devtools = hook; 18052 } 18053 function initI18nDevTools(i18n, version, meta) { 18054 // TODO: queue if devtools is undefined 18055 devtools && 18056 devtools.emit("i18n:init" /* I18N_INIT */, { 18057 timestamp: Date.now(), 18058 i18n, 18059 version, 18060 meta 18061 }); 18062 } 18063 const translateDevTools = /* #__PURE__*/ createDevToolsHook("function:translate" /* FUNCTION_TRANSLATE */); 18064 function createDevToolsHook(hook) { 18065 return (payloads) => devtools && devtools.emit(hook, payloads); 18066 } 18067 18068 /** @internal */ 18069 const warnMessages$1 = { 18070 [0 /* NOT_FOUND_KEY */]: `Not found '{key}' key in '{locale}' locale messages.`, 18071 [1 /* FALLBACK_TO_TRANSLATE */]: `Fall back to translate '{key}' key with '{target}' locale.`,
18072 [2 /* CANNOT_FORMAT_NUMBER */]: `Cannot format a number value due to not supported Intl.NumberFormat.`, 18073 [3 /* FALLBACK_TO_NUMBER_FORMAT */]: `Fall back to number format '{key}' key with '{target}' locale.`, 18074 [4 /* CANNOT_FORMAT_DATE */]: `Cannot format a date value due to not supported Intl.DateTimeFormat.`, 18075 [5 /* FALLBACK_TO_DATE_FORMAT */]: `Fall back to datetime format '{key}' key with '{target}' locale.` 18076 }; 18077 function getWarnMessage$1(code, ...args) { 18078 return format(warnMessages$1[code], ...args); 18079 } 18080 18081 /** 18082 * Intlify core-base version 18083 * @internal 18084 */ 18085 const VERSION$1 = '9.1.0'; 18086 const NOT_REOSLVED = -1; 18087 const MISSING_RESOLVE_VALUE = ''; 18088 function getDefaultLinkedModifiers() { 18089 return { 18090 upper: (val) => (isString(val) ? val.toUpperCase() : val), 18091 lower: (val) => (isString(val) ? val.toLowerCase() : val), 18092 // prettier-ignore 18093 capitalize: (val) => (isString(val) 18094 ? `${val.charAt(0).toLocaleUpperCase()}${val.substr(1)}` 18095 : val) 18096 }; 18097 } 18098 let _compiler; 18099 function registerMessageCompiler(compiler) { 18100 _compiler = compiler; 18101 } 18102 // ID for CoreContext 18103 let _cid = 0; 18104 function createCoreContext(options = {}) { 18105 // setup options 18106 const locale = isString(options.locale) ? options.locale : 'en-US'; 18107 const fallbackLocale = isArray(options.fallbackLocale) || 18108 isPlainObject(options.fallbackLocale) || 18109 isString(options.fallbackLocale) || 18110 options.fallbackLocale === false 18111 ? options.fallbackLocale 18112 : locale; 18113 const messages = isPlainObject(options.messages) 18114 ? options.messages 18115 : { [locale]: {} }; 18116 const datetimeFormats = isPlainObject(options.datetimeFormats) 18117 ? options.datetimeFormats 18118 : { [locale]: {} }; 18119 const numberFormats = isPlainObject(options.numberFormats) 18120 ? options.numberFormats 18121 : { [locale]: {} }; 18122 const modifiers = Object.assign({}, options.modifiers || {}, getDefaultLinkedModifiers()); 18123 const pluralRules = options.pluralRules || {}; 18124 const missing = isFunction(options.missing) ? options.missing : null; 18125 const missingWarn = isBoolean(options.missingWarn) || isRegExp(options.missingWarn) 18126 ? options.missingWarn 18127 : true; 18128 const fallbackWarn = isBoolean(options.fallbackWarn) || isRegExp(options.fallbackWarn) 18129 ? options.fallbackWarn 18130 : true; 18131 const fallbackFormat = !!options.fallbackFormat; 18132 const unresolving = !!options.unresolving; 18133 const postTranslation = isFunction(options.postTranslation) 18134 ? options.postTranslation 18135 : null; 18136 const processor = isPlainObject(options.processor) ? options.processor : null; 18137 const warnHtmlMessage = isBoolean(options.warnHtmlMessage) 18138 ? options.warnHtmlMessage 18139 : true; 18140 const escapeParameter = !!options.escapeParameter; 18141 const messageCompiler = isFunction(options.messageCompiler) 18142 ? options.messageCompiler 18143 : _compiler; 18144 const onWarn = isFunction(options.onWarn) ? options.onWarn : warn; 18145 // setup internal options 18146 const internalOptions = options; 18147 const __datetimeFormatters = isObject(internalOptions.__datetimeFormatters) 18148 ? internalOptions.__datetimeFormatters 18149 : new Map(); 18150 const __numberFormatters = isObject(internalOptions.__numberFormatters) 18151 ? internalOptions.__numberFormatters 18152 : new Map(); 18153 const { __meta } = internalOptions; 18154 _cid++; 18155 const context = { 18156 cid: _cid, 18157 locale, 18158 fallbackLocale, 18159 messages, 18160 datetimeFormats, 18161 numberFormats, 18162 modifiers, 18163 pluralRules, 18164 missing, 18165 missingWarn, 18166 fallbackWarn, 18167 fallbackFormat, 18168 unresolving, 18169 postTranslation, 18170 processor, 18171 warnHtmlMessage, 18172 escapeParameter, 18173 messageCompiler, 18174 onWarn, 18175 __datetimeFormatters, 18176 __numberFormatters, 18177 __meta 18178 }; 18179 // for vue-devtools timeline event 18180 { 18181 context.__v_emitter = 18182 internalOptions.__v_emitter != null 18183 ? internalOptions.__v_emitter 18184 : undefined; 18185 } 18186 // NOTE: experimental !! 18187 { 18188 initI18nDevTools(context, VERSION$1, __meta); 18189 } 18190 return context; 18191 } 18192 /** @internal */ 18193 function isTranslateFallbackWarn(fallback, key) { 18194 return fallback instanceof RegExp ? fallback.test(key) : fallback; 18195 } 18196 /** @internal */ 18197 function isTranslateMissingWarn(missing, key) { 18198 return missing instanceof RegExp ? missing.test(key) : missing; 18199 } 18200 /** @internal */ 18201 function handleMissing(context, key, locale, missingWarn, type) { 18202 const { missing, onWarn } = context; 18203 // for vue-devtools timeline event 18204 { 18205 const emitter = context.__v_emitter; 18206 if (emitter) { 18207 emitter.emit("missing" /* MISSING */, { 18208 locale, 18209 key, 18210 type, 18211 groupId: `${type}:${key}` 18212 }); 18213 } 18214 } 18215 if (missing !== null) { 18216 const ret = missing(context, locale, key, type); 18217 return isString(ret) ? ret : key; 18218 } 18219 else { 18220 if (isTranslateMissingWarn(missingWarn, key)) { 18221 onWarn(getWarnMessage$1(0 /* NOT_FOUND_KEY */, { key, locale })); 18222 } 18223 return key; 18224 } 18225 } 18226 /** @internal */ 18227 function getLocaleChain(ctx, fallback, start) { 18228 const context = ctx; 18229 if (!context.__localeChainCache) { 18230 context.__localeChainCache = new Map(); 18231 } 18232 let chain = context.__localeChainCache.get(start); 18233 if (!chain) { 18234 chain = []; 18235 // first block defined by start 18236 let block = [start]; 18237 // while any intervening block found 18238 while (isArray(block)) { 18239 block = appendBlockToChain(chain, block, fallback); 18240 } 18241 // prettier-ignore 18242 // last block defined by default 18243 const defaults = isArray(fallback) 18244 ? fallback 18245 : isPlainObject(fallback) 18246 ? fallback['default'] 18247 ? fallback['default'] 18248 : null 18249 : fallback; 18250 // convert defaults to array 18251 block = isString(defaults) ? [defaults] : defaults; 18252 if (isArray(block)) { 18253 appendBlockToChain(chain, block, false); 18254 } 18255 context.__localeChainCache.set(start, chain); 18256 } 18257 return chain; 18258 } 18259 function appendBlockToChain(chain, block, blocks) { 18260 let follow = true; 18261 for (let i = 0; i < block.length && isBoolean(follow); i++) { 18262 const locale = block[i]; 18263 if (isString(locale)) { 18264 follow = appendLocaleToChain(chain, block[i], blocks); 18265 } 18266 } 18267 return follow; 18268 } 18269 function appendLocaleToChain(chain, locale, blocks) { 18270 let follow; 18271 const tokens = locale.split('-'); 18272 do { 18273 const target = tokens.join('-'); 18274 follow = appendItemToChain(chain, target, blocks); 18275 tokens.splice(-1, 1); 18276 } while (tokens.length && follow === true); 18277 return follow; 18278 } 18279 function appendItemToChain(chain, target, blocks) { 18280 let follow = false;
18281 if (!chain.includes(target)) { 18282 follow = true; 18283 if (target) { 18284 follow = target[target.length - 1] !== '!'; 18285 const locale = target.replace(/!/g, ''); 18286 chain.push(locale); 18287 if ((isArray(blocks) || isPlainObject(blocks)) && 18288 blocks[locale] // eslint-disable-line @typescript-eslint/no-explicit-any 18289 ) { 18290 // eslint-disable-next-line @typescript-eslint/no-explicit-any 18291 follow = blocks[locale]; 18292 } 18293 } 18294 } 18295 return follow; 18296 } 18297 /** @internal */ 18298 function updateFallbackLocale(ctx, locale, fallback) { 18299 const context = ctx; 18300 context.__localeChainCache = new Map(); 18301 getLocaleChain(ctx, fallback, locale); 18302 } 18303 18304 const RE_HTML_TAG = /<\/?[\w\s="/.':;#-\/]+>/; 18305 const WARN_MESSAGE = `Detected HTML in '{source}' message. Recommend not using HTML messages to avoid XSS.`; 18306 function checkHtmlMessage(source, options) { 18307 const warnHtmlMessage = isBoolean(options.warnHtmlMessage) 18308 ? options.warnHtmlMessage 18309 : true; 18310 if (warnHtmlMessage && RE_HTML_TAG.test(source)) { 18311 warn(format(WARN_MESSAGE, { source })); 18312 } 18313 } 18314 const defaultOnCacheKey = (source) => source; 18315 let compileCache = Object.create(null); 18316 function compileToFunction(source, options = {}) { 18317 { 18318 // check HTML message 18319 checkHtmlMessage(source, options); 18320 // check caches 18321 const onCacheKey = options.onCacheKey || defaultOnCacheKey; 18322 const key = onCacheKey(source); 18323 const cached = compileCache[key]; 18324 if (cached) { 18325 return cached; 18326 } 18327 // compile error detecting 18328 let occurred = false; 18329 const onError = options.onError || defaultOnError; 18330 options.onError = (err) => { 18331 occurred = true; 18332 onError(err); 18333 }; 18334 // compile 18335 const { code } = baseCompile(source, options); 18336 // evaluate function 18337 const msg = new Function(`return ${code}`)(); 18338 // if occurred compile error, don't cache 18339 return !occurred ? (compileCache[key] = msg) : msg; 18340 } 18341 } 18342 18343 function createCoreError(code) { 18344 return createCompileError(code, null, { messages: errorMessages$1 } ); 18345 } 18346 /** @internal */ 18347 const errorMessages$1 = { 18348 [14 /* INVALID_ARGUMENT */]: 'Invalid arguments', 18349 [15 /* INVALID_DATE_ARGUMENT */]: 'The date provided is an invalid Date object.' + 18350 'Make sure your Date represents a valid date.', 18351 [16 /* INVALID_ISO_DATE_ARGUMENT */]: 'The argument provided is not a valid ISO date string' 18352 }; 18353 18354 const NOOP_MESSAGE_FUNCTION = () => ''; 18355 const isMessageFunction = (val) => isFunction(val); 18356 // implementation of `translate` function 18357 function translate(context, ...args) { 18358 const { fallbackFormat, postTranslation, unresolving, fallbackLocale, messages } = context; 18359 const [key, options] = parseTranslateArgs(...args); 18360 const missingWarn = isBoolean(options.missingWarn) 18361 ? options.missingWarn 18362 : context.missingWarn; 18363 const fallbackWarn = isBoolean(options.fallbackWarn) 18364 ? options.fallbackWarn 18365 : context.fallbackWarn; 18366 const escapeParameter = isBoolean(options.escapeParameter) 18367 ? options.escapeParameter 18368 : context.escapeParameter; 18369 const resolvedMessage = !!options.resolvedMessage; 18370 // prettier-ignore 18371 const defaultMsgOrKey = isString(options.default) || isBoolean(options.default) // default by function option 18372 ? !isBoolean(options.default) 18373 ? options.default 18374 : key 18375 : fallbackFormat // default by `fallbackFormat` option 18376 ? key 18377 : ''; 18378 const enableDefaultMsg = fallbackFormat || defaultMsgOrKey !== ''; 18379 const locale = isString(options.locale) ? options.locale : context.locale; 18380 // escape params 18381 escapeParameter && escapeParams(options); 18382 // resolve message format 18383 // eslint-disable-next-line prefer-const
18384 let [format, targetLocale, message] = !resolvedMessage 18385 ? resolveMessageFormat(context, key, locale, fallbackLocale, fallbackWarn, missingWarn) 18386 : [ 18387 key, 18388 locale, 18389 messages[locale] || {} 18390 ]; 18391 // if you use default message, set it as message format! 18392 let cacheBaseKey = key; 18393 if (!resolvedMessage && 18394 !(isString(format) || isMessageFunction(format))) { 18395 if (enableDefaultMsg) { 18396 format = defaultMsgOrKey; 18397 cacheBaseKey = format; 18398 } 18399 } 18400 // checking message format and target locale 18401 if (!resolvedMessage && 18402 (!(isString(format) || isMessageFunction(format)) || 18403 !isString(targetLocale))) { 18404 return unresolving ? NOT_REOSLVED : key; 18405 } 18406 if (isString(format) && context.messageCompiler == null) { 18407 warn(`The message format compilation is not supported in this build. ` + 18408 `Because message compiler isn't included. ` + 18409 `You need to pre-compilation all message format. ` + 18410 `So translate function return '${key}'.`); 18411 return key; 18412 } 18413 // setup compile error detecting 18414 let occurred = false; 18415 const errorDetector = () => { 18416 occurred = true; 18417 }; 18418 // compile message format 18419 const msg = !isMessageFunction(format) 18420 ? compileMessageFormat(context, key, targetLocale, format, cacheBaseKey, errorDetector) 18421 : format; 18422 // if occurred compile error, return the message format 18423 if (occurred) { 18424 return format; 18425 } 18426 // evaluate message with context 18427 const ctxOptions = getMessageContextOptions(context, targetLocale, message, options); 18428 const msgContext = createMessageContext(ctxOptions); 18429 const messaged = evaluateMessage(context, msg, msgContext); 18430 // if use post translation option, proceed it with handler 18431 const ret = postTranslation ? postTranslation(messaged) : messaged; 18432 // NOTE: experimental !! 18433 { 18434 const payloads = { 18435 timestamp: Date.now(), 18436 key: !isMessageFunction(format) && isString(key) 18437 ? key 18438 : format.key, 18439 locale: targetLocale, 18440 format: !isMessageFunction(format) && isString(format) 18441 ? format 18442 : format.source, 18443 message: ret 18444 }; 18445 if (context.__meta) { 18446 payloads.meta = context.__meta; 18447 } 18448 translateDevTools(payloads); 18449 } 18450 return ret; 18451 } 18452 function escapeParams(options) { 18453 if (isArray(options.list)) { 18454 options.list = options.list.map(item => isString(item) ? escapeHtml(item) : item); 18455 } 18456 else if (isObject(options.named)) { 18457 Object.keys(options.named).forEach(key => { 18458 if (isString(options.named[key])) { 18459 options.named[key] = escapeHtml(options.named[key]); 18460 } 18461 }); 18462 } 18463 } 18464 function resolveMessageFormat(context, key, locale, fallbackLocale, fallbackWarn, missingWarn) { 18465 const { messages, onWarn } = context; 18466 const locales = getLocaleChain(context, fallbackLocale, locale); 18467 let message = {}; 18468 let targetLocale; 18469 let format = null; 18470 let from = locale; 18471 let to = null; 18472 const type = 'translate'; 18473 for (let i = 0; i < locales.length; i++) { 18474 targetLocale = to = locales[i]; 18475 if (locale !== targetLocale && 18476 isTranslateFallbackWarn(fallbackWarn, key)) { 18477 onWarn(getWarnMessage$1(1 /* FALLBACK_TO_TRANSLATE */, { 18478 key, 18479 target: targetLocale 18480 })); 18481 } 18482 // for vue-devtools timeline event 18483 if (locale !== targetLocale) { 18484 const emitter = context.__v_emitter; 18485 if (emitter) { 18486 emitter.emit("fallback" /* FALBACK */, { 18487 type, 18488 key, 18489 from, 18490 to, 18491 groupId: `${type}:${key}` 18492 }); 18493 } 18494 } 18495 message =
18496 messages[targetLocale] || {}; 18497 // for vue-devtools timeline event 18498 let start = null; 18499 let startTag; 18500 let endTag; 18501 if (inBrowser) { 18502 start = window.performance.now(); 18503 startTag = 'intlify-message-resolve-start'; 18504 endTag = 'intlify-message-resolve-end'; 18505 mark && mark(startTag); 18506 } 18507 if ((format = resolveValue(message, key)) === null) { 18508 // if null, resolve with object key path 18509 format = message[key]; // eslint-disable-line @typescript-eslint/no-explicit-any 18510 } 18511 // for vue-devtools timeline event 18512 if (inBrowser) { 18513 const end = window.performance.now(); 18514 const emitter = context.__v_emitter; 18515 if (emitter && start && format) { 18516 emitter.emit("message-resolve" /* MESSAGE_RESOLVE */, { 18517 type: "message-resolve" /* MESSAGE_RESOLVE */, 18518 key, 18519 message: format, 18520 time: end - start, 18521 groupId: `${type}:${key}` 18522 }); 18523 } 18524 if (startTag && endTag && mark && measure) { 18525 mark(endTag); 18526 measure('intlify message resolve', startTag, endTag); 18527 } 18528 } 18529 if (isString(format) || isFunction(format)) 18530 break; 18531 const missingRet = handleMissing(context, key, targetLocale, missingWarn, type); 18532 if (missingRet !== key) { 18533 format = missingRet; 18534 } 18535 from = to; 18536 } 18537 return [format, targetLocale, message]; 18538 } 18539 function compileMessageFormat(context, key, targetLocale, format, cacheBaseKey, errorDetector) { 18540 const { messageCompiler, warnHtmlMessage } = context; 18541 if (isMessageFunction(format)) { 18542 const msg = format; 18543 msg.locale = msg.locale || targetLocale; 18544 msg.key = msg.key || key; 18545 return msg; 18546 } 18547 // for vue-devtools timeline event 18548 let start = null; 18549 let startTag; 18550 let endTag; 18551 if (inBrowser) { 18552 start = window.performance.now(); 18553 startTag = 'intlify-message-compilation-start'; 18554 endTag = 'intlify-message-compilation-end'; 18555 mark && mark(startTag); 18556 } 18557 const msg = messageCompiler(format, getCompileOptions(context, targetLocale, cacheBaseKey, format, warnHtmlMessage, errorDetector)); 18558 // for vue-devtools timeline event 18559 if (inBrowser) { 18560 const end = window.performance.now(); 18561 const emitter = context.__v_emitter; 18562 if (emitter && start) { 18563 emitter.emit("message-compilation" /* MESSAGE_COMPILATION */, { 18564 type: "message-compilation" /* MESSAGE_COMPILATION */, 18565 message: format, 18566 time: end - start, 18567 groupId: `${'translate'}:${key}` 18568 }); 18569 } 18570 if (startTag && endTag && mark && measure) { 18571 mark(endTag); 18572 measure('intlify message compilation', startTag, endTag); 18573 } 18574 } 18575 msg.locale = targetLocale; 18576 msg.key = key; 18577 msg.source = format; 18578 return msg; 18579 } 18580 function evaluateMessage(context, msg, msgCtx) { 18581 // for vue-devtools timeline event 18582 let start = null; 18583 let startTag; 18584 let endTag; 18585 if (inBrowser) { 18586 start = window.performance.now(); 18587 startTag = 'intlify-message-evaluation-start'; 18588 endTag = 'intlify-message-evaluation-end'; 18589 mark && mark(startTag); 18590 } 18591 const messaged = msg(msgCtx); 18592 // for vue-devtools timeline event 18593 if (inBrowser) { 18594 const end = window.performance.now(); 18595 const emitter = context.__v_emitter; 18596 if (emitter && start) { 18597 emitter.emit("message-evaluation" /* MESSAGE_EVALUATION */, { 18598 type: "message-evaluation" /* MESSAGE_EVALUATION */, 18599 value: messaged, 18600 time: end - start, 18601 groupId: `${'translate'}:${msg.key}` 18602 }); 18603 } 18604 if (startTag && endTag && mark && measure) { 18605 mark(endTag); 18606 measure('intlify message evaluation', startTag, endTag); 18607 } 18608 } 18609 return messaged; 18610 } 18611 /** @internal */ 18612 function parseTranslateArgs(...args) { 18613 const [arg1, arg2, arg3] = args; 18614 const options = {}; 18615 if (!isString(arg1) && !isNumber(arg1) && !isMessageFunction(arg1)) {
18616 throw createCoreError(14 /* INVALID_ARGUMENT */); 18617 } 18618 // prettier-ignore 18619 const key = isNumber(arg1) 18620 ? String(arg1) 18621 : isMessageFunction(arg1) 18622 ? arg1 18623 : arg1; 18624 if (isNumber(arg2)) { 18625 options.plural = arg2; 18626 } 18627 else if (isString(arg2)) { 18628 options.default = arg2; 18629 } 18630 else if (isPlainObject(arg2) && !isEmptyObject(arg2)) { 18631 options.named = arg2; 18632 } 18633 else if (isArray(arg2)) { 18634 options.list = arg2; 18635 } 18636 if (isNumber(arg3)) { 18637 options.plural = arg3; 18638 } 18639 else if (isString(arg3)) { 18640 options.default = arg3; 18641 } 18642 else if (isPlainObject(arg3)) { 18643 Object.assign(options, arg3); 18644 } 18645 return [key, options]; 18646 } 18647 function getCompileOptions(context, locale, key, source, warnHtmlMessage, errorDetector) { 18648 return { 18649 warnHtmlMessage, 18650 onError: (err) => { 18651 errorDetector && errorDetector(err); 18652 { 18653 const message = `Message compilation error: ${err.message}`; 18654 const codeFrame = err.location && 18655 generateCodeFrame(source, err.location.start.offset, err.location.end.offset); 18656 const emitter = context 18657 .__v_emitter; 18658 if (emitter) { 18659 emitter.emit("compile-error" /* COMPILE_ERROR */, { 18660 message: source, 18661 error: err.message, 18662 start: err.location && err.location.start.offset, 18663 end: err.location && err.location.end.offset, 18664 groupId: `${'translate'}:${key}` 18665 }); 18666 } 18667 console.error(codeFrame ? `${message}\n${codeFrame}` : message); 18668 } 18669 }, 18670 onCacheKey: (source) => generateFormatCacheKey(locale, key, source) 18671 }; 18672 } 18673 function getMessageContextOptions(context, locale, message, options) { 18674 const { modifiers, pluralRules } = context; 18675 const resolveMessage = (key) => { 18676 const val = resolveValue(message, key); 18677 if (isString(val)) { 18678 let occurred = false; 18679 const errorDetector = () => { 18680 occurred = true; 18681 }; 18682 const msg = compileMessageFormat(context, key, locale, val, key, errorDetector); 18683 return !occurred 18684 ? msg 18685 : NOOP_MESSAGE_FUNCTION; 18686 } 18687 else if (isMessageFunction(val)) { 18688 return val; 18689 } 18690 else { 18691 // TODO: should be implemented warning message 18692 return NOOP_MESSAGE_FUNCTION; 18693 } 18694 }; 18695 const ctxOptions = { 18696 locale, 18697 modifiers, 18698 pluralRules, 18699 messages: resolveMessage 18700 }; 18701 if (context.processor) { 18702 ctxOptions.processor = context.processor; 18703 } 18704 if (options.list) { 18705 ctxOptions.list = options.list; 18706 } 18707 if (options.named) { 18708 ctxOptions.named = options.named; 18709 } 18710 if (isNumber(options.plural)) { 18711 ctxOptions.pluralIndex = options.plural; 18712 } 18713 return ctxOptions; 18714 } 18715 18716 const intlDefined = typeof Intl !== 'undefined'; 18717 const Availabilities = { 18718 dateTimeFormat: intlDefined && typeof Intl.DateTimeFormat !== 'undefined', 18719 numberFormat: intlDefined && typeof Intl.NumberFormat !== 'undefined' 18720 }; 18721 18722 // implementation of `datetime` function 18723 function datetime(context, ...args) { 18724 const { datetimeFormats, unresolving, fallbackLocale, onWarn } = context; 18725 const { __datetimeFormatters } = context; 18726 if (!Availabilities.dateTimeFormat) { 18727 onWarn(getWarnMessage$1(4 /* CANNOT_FORMAT_DATE */)); 18728 return MISSING_RESOLVE_VALUE; 18729 } 18730 const [key, value, options, overrides] = parseDateTimeArgs(...args); 18731 const missingWarn = isBoolean(options.missingWarn) 18732 ? options.missingWarn 18733 : context.missingWarn; 18734 const fallbackWarn = isBoolean(options.fallbackWarn) 18735 ? options.fallbackWarn 18736 : context.fallbackWarn; 18737 const part = !!options.part; 18738 const locale = isString(options.locale) ? options.locale : context.locale; 18739 const locales = getLocaleChain(context, fallbackLocale, locale); 18740 if (!isString(key) || key === '') { 18741 return new Intl.DateTimeFormat(locale).format(value); 18742 } 18743 // resolve format 18744 let datetimeFormat = {};
18745 let targetLocale; 18746 let format = null; 18747 let from = locale; 18748 let to = null; 18749 const type = 'datetime format'; 18750 for (let i = 0; i < locales.length; i++) { 18751 targetLocale = to = locales[i]; 18752 if (locale !== targetLocale && 18753 isTranslateFallbackWarn(fallbackWarn, key)) { 18754 onWarn(getWarnMessage$1(5 /* FALLBACK_TO_DATE_FORMAT */, { 18755 key, 18756 target: targetLocale 18757 })); 18758 } 18759 // for vue-devtools timeline event 18760 if (locale !== targetLocale) { 18761 const emitter = context.__v_emitter; 18762 if (emitter) { 18763 emitter.emit("fallback" /* FALBACK */, { 18764 type, 18765 key, 18766 from, 18767 to, 18768 groupId: `${type}:${key}` 18769 }); 18770 } 18771 } 18772 datetimeFormat = 18773 datetimeFormats[targetLocale] || {}; 18774 format = datetimeFormat[key]; 18775 if (isPlainObject(format)) 18776 break; 18777 handleMissing(context, key, targetLocale, missingWarn, type); 18778 from = to; 18779 } 18780 // checking format and target locale 18781 if (!isPlainObject(format) || !isString(targetLocale)) { 18782 return unresolving ? NOT_REOSLVED : key; 18783 } 18784 let id = `${targetLocale}__${key}`; 18785 if (!isEmptyObject(overrides)) { 18786 id = `${id}__${JSON.stringify(overrides)}`; 18787 } 18788 let formatter = __datetimeFormatters.get(id); 18789 if (!formatter) { 18790 formatter = new Intl.DateTimeFormat(targetLocale, Object.assign({}, format, overrides)); 18791 __datetimeFormatters.set(id, formatter); 18792 } 18793 return !part ? formatter.format(value) : formatter.formatToParts(value); 18794 } 18795 /** @internal */ 18796 function parseDateTimeArgs(...args) { 18797 const [arg1, arg2, arg3, arg4] = args; 18798 let options = {}; 18799 let overrides = {}; 18800 let value; 18801 if (isString(arg1)) { 18802 // Only allow ISO strings - other date formats are often supported, 18803 // but may cause different results in different browsers. 18804 if (!/\d{4}-\d{2}-\d{2}(T.*)?/.test(arg1)) { 18805 throw createCoreError(16 /* INVALID_ISO_DATE_ARGUMENT */); 18806 } 18807 value = new Date(arg1); 18808 try { 18809 // This will fail if the date is not valid 18810 value.toISOString(); 18811 } 18812 catch (e) { 18813 throw createCoreError(16 /* INVALID_ISO_DATE_ARGUMENT */); 18814 } 18815 } 18816 else if (isDate(arg1)) { 18817 if (isNaN(arg1.getTime())) { 18818 throw createCoreError(15 /* INVALID_DATE_ARGUMENT */); 18819 } 18820 value = arg1; 18821 } 18822 else if (isNumber(arg1)) { 18823 value = arg1; 18824 } 18825 else { 18826 throw createCoreError(14 /* INVALID_ARGUMENT */); 18827 } 18828 if (isString(arg2)) { 18829 options.key = arg2; 18830 } 18831 else if (isPlainObject(arg2)) { 18832 options = arg2; 18833 } 18834 if (isString(arg3)) { 18835 options.locale = arg3; 18836 } 18837 else if (isPlainObject(arg3)) { 18838 overrides = arg3; 18839 } 18840 if (isPlainObject(arg4)) { 18841 overrides = arg4; 18842 } 18843 return [options.key || '', value, options, overrides]; 18844 } 18845 /** @internal */ 18846 function clearDateTimeFormat(ctx, locale, format) { 18847 const context = ctx; 18848 for (const key in format) { 18849 const id = `${locale}__${key}`; 18850 if (!context.__datetimeFormatters.has(id)) { 18851 continue; 18852 } 18853 context.__datetimeFormatters.delete(id); 18854 } 18855 } 18856 18857 // implementation of `number` function 18858 function number(context, ...args) { 18859 const { numberFormats, unresolving, fallbackLocale, onWarn } = context; 18860 const { __numberFormatters } = context; 18861 if (!Availabilities.numberFormat) { 18862 onWarn(getWarnMessage$1(2 /* CANNOT_FORMAT_NUMBER */)); 18863 return MISSING_RESOLVE_VALUE; 18864 } 18865 const [key, value, options, overrides] = parseNumberArgs(...args); 18866 const missingWarn = isBoolean(options.missingWarn) 18867 ? options.missingWarn 18868 : context.missingWarn; 18869 const fallbackWarn = isBoolean(options.fallbackWarn) 18870 ? options.fallbackWarn 18871 : context.fallbackWarn; 18872 const part = !!options.part; 18873 const locale = isString(options.locale) ? options.locale : context.locale; 18874 const locales = getLocaleChain(context, fallbackLocale, locale); 18875 if (!isString(key) || key === '') { 18876 return new Intl.NumberFormat(locale).format(value); 18877 } 18878 // resolve format 18879 let numberFormat = {};
18880 let targetLocale; 18881 let format = null; 18882 let from = locale; 18883 let to = null; 18884 const type = 'number format'; 18885 for (let i = 0; i < locales.length; i++) { 18886 targetLocale = to = locales[i]; 18887 if (locale !== targetLocale && 18888 isTranslateFallbackWarn(fallbackWarn, key)) { 18889 onWarn(getWarnMessage$1(3 /* FALLBACK_TO_NUMBER_FORMAT */, { 18890 key, 18891 target: targetLocale 18892 })); 18893 } 18894 // for vue-devtools timeline event 18895 if (locale !== targetLocale) { 18896 const emitter = context.__v_emitter; 18897 if (emitter) { 18898 emitter.emit("fallback" /* FALBACK */, { 18899 type, 18900 key, 18901 from, 18902 to, 18903 groupId: `${type}:${key}` 18904 }); 18905 } 18906 } 18907 numberFormat = 18908 numberFormats[targetLocale] || {}; 18909 format = numberFormat[key]; 18910 if (isPlainObject(format)) 18911 break; 18912 handleMissing(context, key, targetLocale, missingWarn, type); 18913 from = to; 18914 } 18915 // checking format and target locale 18916 if (!isPlainObject(format) || !isString(targetLocale)) { 18917 return unresolving ? NOT_REOSLVED : key; 18918 } 18919 let id = `${targetLocale}__${key}`; 18920 if (!isEmptyObject(overrides)) { 18921 id = `${id}__${JSON.stringify(overrides)}`; 18922 } 18923 let formatter = __numberFormatters.get(id); 18924 if (!formatter) { 18925 formatter = new Intl.NumberFormat(targetLocale, Object.assign({}, format, overrides)); 18926 __numberFormatters.set(id, formatter); 18927 } 18928 return !part ? formatter.format(value) : formatter.formatToParts(value); 18929 } 18930 /** @internal */ 18931 function parseNumberArgs(...args) { 18932 const [arg1, arg2, arg3, arg4] = args; 18933 let options = {}; 18934 let overrides = {}; 18935 if (!isNumber(arg1)) { 18936 throw createCoreError(14 /* INVALID_ARGUMENT */); 18937 } 18938 const value = arg1; 18939 if (isString(arg2)) { 18940 options.key = arg2; 18941 } 18942 else if (isPlainObject(arg2)) { 18943 options = arg2; 18944 } 18945 if (isString(arg3)) { 18946 options.locale = arg3; 18947 } 18948 else if (isPlainObject(arg3)) { 18949 overrides = arg3; 18950 } 18951 if (isPlainObject(arg4)) { 18952 overrides = arg4; 18953 } 18954 return [options.key || '', value, options, overrides]; 18955 } 18956 /** @internal */ 18957 function clearNumberFormat(ctx, locale, format) { 18958 const context = ctx; 18959 for (const key in format) { 18960 const id = `${locale}__${key}`; 18961 if (!context.__numberFormatters.has(id)) { 18962 continue; 18963 } 18964 context.__numberFormatters.delete(id); 18965 } 18966 } 18967 18968 /** 18969 * Vue I18n Version 18970 * 18971 * @remarks 18972 * Semver format. Same format as the package.json `version` field. 18973 * 18974 * @VueI18nGeneral 18975 */ 18976 const VERSION = '9.1.0'; 18977 /** 18978 * This is only called development env 18979 * istanbul-ignore-next 18980 */ 18981 function initDev() { 18982 { 18983 console.info(`You are running a development build of vue-i18n.\n` + 18984 `Make sure to use the production build (*.prod.js) when deploying for production.`); 18985 } 18986 } 18987 18988 const warnMessages = { 18989 [6 /* FALLBACK_TO_ROOT */]: `Fall back to {type} '{key}' with root locale.`, 18990 [7 /* NOT_SUPPORTED_PRESERVE */]: `Not supported 'preserve'.`, 18991 [8 /* NOT_SUPPORTED_FORMATTER */]: `Not supported 'formatter'.`, 18992 [9 /* NOT_SUPPORTED_PRESERVE_DIRECTIVE */]: `Not supported 'preserveDirectiveContent'.`, 18993 [10 /* NOT_SUPPORTED_GET_CHOICE_INDEX */]: `Not supported 'getChoiceIndex'.`, 18994 [11 /* COMPONENT_NAME_LEGACY_COMPATIBLE */]: `Component name legacy compatible: '{name}' -> 'i18n'`, 18995 [12 /* NOT_FOUND_PARENT_SCOPE */]: `Not found parent scope. use the global scope.` 18996 }; 18997 function getWarnMessage(code, ...args) { 18998 return format(warnMessages[code], ...args); 18999 } 19000 19001 function createI18nError(code, ...args) { 19002 return createCompileError(code, null, { messages: errorMessages, args } ); 19003 } 19004 const errorMessages = { 19005 [14 /* UNEXPECTED_RETURN_TYPE */]: 'Unexpected return type in composer', 19006 [15 /* INVALID_ARGUMENT */]: 'Invalid argument', 19007 [16 /* MUST_BE_CALL_SETUP_TOP */]: 'Must be called at the top of a `setup` function', 19008 [17 /* NOT_INSLALLED */]: 'Need to install with `app.use` function', 19009 [22 /* UNEXPECTED_ERROR */]: 'Unexpected error', 19010 [18 /* NOT_AVAILABLE_IN_LEGACY_MODE */]: 'Not available in legacy mode', 19011 [19 /* REQUIRED_VALUE */]: `Required in value: {0}`, 19012 [20 /* INVALID_VALUE */]: `Invalid value`, 19013 [21 /* CANNOT_SETUP_VUE_DEVTOOLS_PLUGIN */]: `Cannot setup vue-devtools plugin` 19014 }; 19015 19016 const DEVTOOLS_META = '__INTLIFY_META__'; 19017 const TransrateVNodeSymbol = makeSymbol('__transrateVNode'); 19018 const DatetimePartsSymbol = makeSymbol('__datetimeParts'); 19019 const NumberPartsSymbol = makeSymbol('__numberParts'); 19020 const EnableEmitter = makeSymbol('__enableEmitter'); 19021 const DisableEmitter = makeSymbol('__disableEmitter'); 19022 const SetPluralRulesSymbol = makeSymbol('__setPluralRules'); 19023 const DevToolsMetaSymbol = makeSymbol('__intlifyMeta'); 19024 let composerID = 0; 19025 function defineCoreMissingHandler(missing) { 19026 return ((ctx, locale, key, type) => { 19027 return missing(locale, key, vue.getCurrentInstance() || undefined, type); 19028 }); 19029 } 19030 function getLocaleMessages(locale, options) { 19031 const { messages, __i18n } = options; 19032 // prettier-ignore 19033 const ret = isPlainObject(messages) 19034 ? messages 19035 : isArray(__i18n) 19036 ? {} 19037 : { [locale]: {} }; 19038 // merge locale messages of i18n custom block 19039 if (isArray(__i18n)) {
19040 __i18n.forEach(({ locale, resource }) => { 19041 if (locale) { 19042 ret[locale] = ret[locale] || {}; 19043 deepCopy(resource, ret[locale]); 19044 } 19045 else { 19046 deepCopy(resource, ret); 19047 } 19048 }); 19049 } 19050 // handle messages for flat json 19051 if (options.flatJson) { 19052 for (const key in ret) { 19053 if (hasOwn(ret, key)) { 19054 handleFlatJson(ret[key]); 19055 } 19056 } 19057 } 19058 return ret; 19059 } 19060 const isNotObjectOrIsArray = (val) => !isObject(val) || isArray(val); 19061 // eslint-disable-next-line @typescript-eslint/no-explicit-any 19062 function deepCopy(src, des) { 19063 // src and des should both be objects, and non of then can be a array 19064 if (isNotObjectOrIsArray(src) || isNotObjectOrIsArray(des)) { 19065 throw createI18nError(20 /* INVALID_VALUE */); 19066 } 19067 for (const key in src) { 19068 if (hasOwn(src, key)) { 19069 if (isNotObjectOrIsArray(src[key]) || isNotObjectOrIsArray(des[key])) { 19070 // replace with src[key] when: 19071 // src[key] or des[key] is not a object, or 19072 // src[key] or des[key] is a array 19073 des[key] = src[key]; 19074 } 19075 else { 19076 // src[key] and des[key] are both object, merge them 19077 deepCopy(src[key], des[key]); 19078 } 19079 } 19080 } 19081 } 19082 /** 19083 * Create composer interface factory 19084 * 19085 * @internal 19086 */ 19087 function createComposer(options = {}) { 19088 const { __root, __meta } = options; 19089 const _isGlobal = __root === undefined; 19090 let _inheritLocale = isBoolean(options.inheritLocale) 19091 ? options.inheritLocale 19092 : true; 19093 const _locale = vue.ref( 19094 // prettier-ignore 19095 __root && _inheritLocale 19096 ? __root.locale.value 19097 : isString(options.locale) 19098 ? options.locale 19099 : 'en-US'); 19100 const _fallbackLocale = vue.ref( 19101 // prettier-ignore 19102 __root && _inheritLocale 19103 ? __root.fallbackLocale.value 19104 : isString(options.fallbackLocale) || 19105 isArray(options.fallbackLocale) || 19106 isPlainObject(options.fallbackLocale) || 19107 options.fallbackLocale === false 19108 ? options.fallbackLocale 19109 : _locale.value); 19110 const _messages = vue.ref(getLocaleMessages(_locale.value, options)); 19111 const _datetimeFormats = vue.ref(isPlainObject(options.datetimeFormats) 19112 ? options.datetimeFormats 19113 : { [_locale.value]: {} }); 19114 const _numberFormats = vue.ref(isPlainObject(options.numberFormats) 19115 ? options.numberFormats 19116 : { [_locale.value]: {} }); 19117 // warning suppress options 19118 // prettier-ignore 19119 let _missingWarn = __root 19120 ? __root.missingWarn 19121 : isBoolean(options.missingWarn) || isRegExp(options.missingWarn) 19122 ? options.missingWarn 19123 : true; 19124 // prettier-ignore 19125 let _fallbackWarn = __root 19126 ? __root.fallbackWarn 19127 : isBoolean(options.fallbackWarn) || isRegExp(options.fallbackWarn) 19128 ? options.fallbackWarn 19129 : true; 19130 // prettier-ignore 19131 let _fallbackRoot = __root 19132 ? __root.fallbackRoot 19133 : isBoolean(options.fallbackRoot) 19134 ? options.fallbackRoot 19135 : true; 19136 // configure fall back to root 19137 let _fallbackFormat = !!options.fallbackFormat; 19138 // runtime missing 19139 let _missing = isFunction(options.missing) ? options.missing : null; 19140 let _runtimeMissing = isFunction(options.missing) 19141 ? defineCoreMissingHandler(options.missing) 19142 : null; 19143 // postTranslation handler 19144 let _postTranslation = isFunction(options.postTranslation) 19145 ? options.postTranslation 19146 : null; 19147 let _warnHtmlMessage = isBoolean(options.warnHtmlMessage) 19148 ? options.warnHtmlMessage 19149 : true; 19150 let _escapeParameter = !!options.escapeParameter; 19151 // custom linked modifiers 19152 // prettier-ignore 19153 const _modifiers = __root 19154 ? __root.modifiers 19155 : isPlainObject(options.modifiers) 19156 ? options.modifiers 19157 : {}; 19158 // pluralRules 19159 let _pluralRules = options.pluralRules || (__root && __root.pluralRules); 19160 // runtime context 19161 // eslint-disable-next-line prefer-const 19162 let _context; 19163 function getCoreContext() { 19164 return createCoreContext({ 19165 locale: _locale.value, 19166 fallbackLocale: _fallbackLocale.value, 19167 messages: _messages.value, 19168 datetimeFormats: _datetimeFormats.value, 19169 numberFormats: _numberFormats.value, 19170 modifiers: _modifiers, 19171 pluralRules: _pluralRules, 19172 missing: _runtimeMissing === null ? undefined : _runtimeMissing, 19173 missingWarn: _missingWarn, 19174 fallbackWarn: _fallbackWarn, 19175 fallbackFormat: _fallbackFormat, 19176 unresolving: true, 19177 postTranslation: _postTranslation === null ? undefined : _postTranslation, 19178 warnHtmlMessage: _warnHtmlMessage, 19179 escapeParameter: _escapeParameter, 19180 __datetimeFormatters: isPlainObject(_context) 19181 ? _context.__datetimeFormatters 19182 : undefined, 19183 __numberFormatters: isPlainObject(_context) 19184 ? _context.__numberFormatters 19185 : undefined, 19186 __v_emitter: isPlainObject(_context) 19187 ? _context.__v_emitter 19188 : undefined, 19189 __meta: Object.assign({ framework: 'vue' }, __meta || {}) 19190 }); 19191 } 19192 _context = getCoreContext(); 19193 updateFallbackLocale(_context, _locale.value, _fallbackLocale.value); 19194 // track reactivity 19195 function trackReactivityValues() { 19196 return [ 19197 _locale.value, 19198 _fallbackLocale.value, 19199 _messages.value, 19200 _datetimeFormats.value, 19201 _numberFormats.value 19202 ]; 19203 } 19204 // locale 19205 const locale = vue.computed({ 19206 get: () => _locale.value, 19207 set: val => { 19208 _locale.value = val; 19209 _context.locale = _locale.value; 19210 } 19211 }); 19212 // fallbackLocale 19213 const fallbackLocale = vue.computed({ 19214 get: () => _fallbackLocale.value, 19215 set: val => { 19216 _fallbackLocale.value = val; 19217 _context.fallbackLocale = _fallbackLocale.value; 19218 updateFallbackLocale(_context, _locale.value, val); 19219 } 19220 }); 19221 // messages 19222 const messages = vue.computed(() => _messages.value); 19223 // datetimeFormats 19224 const datetimeFormats = vue.computed(() => _datetimeFormats.value); 19225 // numberFormats 19226 const numberFormats = vue.computed(() => _numberFormats.value); 19227 // getPostTranslationHandler 19228 function getPostTranslationHandler() { 19229 return isFunction(_postTranslation) ? _postTranslation : null; 19230 } 19231 // setPostTranslationHandler 19232 function setPostTranslationHandler(handler) { 19233 _postTranslation = handler; 19234 _context.postTranslation = handler; 19235 } 19236 // getMissingHandler 19237 function getMissingHandler() { 19238 return _missing; 19239 } 19240 // setMissingHandler 19241 function setMissingHandler(handler) { 19242 if (handler !== null) { 19243 _runtimeMissing = defineCoreMissingHandler(handler); 19244 } 19245 _missing = handler; 19246 _context.missing = _runtimeMissing; 19247 } 19248 function isResolvedTranslateMessage(type, arg // eslint-disable-line @typescript-eslint/no-explicit-any 19249 ) { 19250 return type !== 'translate' || !!arg.resolvedMessage === false; 19251 } 19252 function wrapWithDeps(fn, argumentParser, warnType, fallbackSuccess, fallbackFail, successCondition) { 19253 trackReactivityValues(); // track reactive dependency 19254 const ret = fn(_context); 19255 if (isNumber(ret) && ret === NOT_REOSLVED) { 19256 const [key, arg2] = argumentParser(); 19257 if (__root && 19258 isString(key) && 19259 isResolvedTranslateMessage(warnType, arg2)) { 19260 if (_fallbackRoot && 19261 (isTranslateFallbackWarn(_fallbackWarn, key) || 19262 isTranslateMissingWarn(_missingWarn, key))) { 19263 warn(getWarnMessage(6 /* FALLBACK_TO_ROOT */, { 19264 key, 19265 type: warnType 19266 })); 19267 } 19268 // for vue-devtools timeline event 19269 { 19270 const { __v_emitter: emitter } = _context; 19271 if (emitter && _fallbackRoot) { 19272 emitter.emit("fallback" /* FALBACK */, { 19273 type: warnType, 19274 key, 19275 to: 'global', 19276 groupId: `${warnType}:${key}` 19277 }); 19278 } 19279 } 19280 } 19281 return __root && _fallbackRoot 19282 ? fallbackSuccess(__root) 19283 : fallbackFail(key); 19284 } 19285 else if (successCondition(ret)) { 19286 return ret; 19287 } 19288 else { 19289 /* istanbul ignore next */ 19290 throw createI18nError(14 /* UNEXPECTED_RETURN_TYPE */); 19291 } 19292 } 19293 // t 19294 function t(...args) { 19295 return wrapWithDeps(context => translate(context, ...args), () => parseTranslateArgs(...args), 'translate', root => root.t(...args), key => key, val => isString(val)); 19296 } 19297 // rt 19298 function rt(...args) { 19299 const [arg1, arg2, arg3] = args; 19300 if (arg3 && !isObject(arg3)) { 19301 throw createI18nError(15 /* INVALID_ARGUMENT */); 19302 } 19303 return t(...[arg1, arg2, Object.assign({ resolvedMessage: true }, arg3 || {})]); 19304 } 19305 // d 19306 function d(...args) { 19307 return wrapWithDeps(context => datetime(context, ...args), () => parseDateTimeArgs(...args), 'datetime format', root => root.d(...args), () => MISSING_RESOLVE_VALUE, val => isString(val)); 19308 } 19309 // n 19310 function n(...args) { 19311 return wrapWithDeps(context => number(context, ...args), () => parseNumberArgs(...args), 'number format', root => root.n(...args), () => MISSING_RESOLVE_VALUE, val => isString(val)); 19312 } 19313 // for custom processor 19314 function normalize(values) { 19315 return values.map(val => isString(val) ? vue.createVNode(vue.Text, null, val, 0) : val); 19316 } 19317 const interpolate = (val) => val; 19318 const processor = { 19319 normalize, 19320 interpolate, 19321 type: 'vnode' 19322 }; 19323 // transrateVNode, using for `i18n-t` component 19324 function transrateVNode(...args) { 19325 return wrapWithDeps(context => { 19326 let ret; 19327 const _context = context; 19328 try { 19329 _context.processor = processor; 19330 ret = translate(_context, ...args); 19331 } 19332 finally { 19333 _context.processor = null; 19334 } 19335 return ret; 19336 }, () => parseTranslateArgs(...args), 'translate', 19337 // eslint-disable-next-line @typescript-eslint/no-explicit-any 19338 root => root[TransrateVNodeSymbol](...args), key => [vue.createVNode(vue.Text, null, key, 0)], val => isArray(val)); 19339 } 19340 // numberParts, using for `i18n-n` component 19341 function numberParts(...args) { 19342 return wrapWithDeps(context => number(context, ...args), () => parseNumberArgs(...args), 'number format', 19343 // eslint-disable-next-line @typescript-eslint/no-explicit-any 19344 root => root[NumberPartsSymbol](...args), () => [], val => isString(val) || isArray(val)); 19345 } 19346 // datetimeParts, using for `i18n-d` component 19347 function datetimeParts(...args) { 19348 return wrapWithDeps(context => datetime(context, ...args), () => parseDateTimeArgs(...args), 'datetime format', 19349 // eslint-disable-next-line @typescript-eslint/no-explicit-any 19350 root => root[DatetimePartsSymbol](...args), () => [], val => isString(val) || isArray(val)); 19351 } 19352 function setPluralRules(rules) { 19353 _pluralRules = rules; 19354 _context.pluralRules = _pluralRules; 19355 } 19356 // te 19357 function te(key, locale) {
19358 const targetLocale = isString(locale) ? locale : _locale.value; 19359 const message = getLocaleMessage(targetLocale); 19360 return resolveValue(message, key) !== null; 19361 } 19362 function resolveMessages(key) { 19363 let messages = null; 19364 const locales = getLocaleChain(_context, _fallbackLocale.value, _locale.value); 19365 for (let i = 0; i < locales.length; i++) { 19366 const targetLocaleMessages = _messages.value[locales[i]] || {}; 19367 const messageValue = resolveValue(targetLocaleMessages, key); 19368 if (messageValue != null) { 19369 messages = messageValue; 19370 break; 19371 } 19372 } 19373 return messages; 19374 } 19375 // tm 19376 function tm(key) { 19377 const messages = resolveMessages(key); 19378 // prettier-ignore 19379 return messages != null 19380 ? messages 19381 : __root 19382 ? __root.tm(key) || {} 19383 : {}; 19384 } 19385 // getLocaleMessage 19386 function getLocaleMessage(locale) { 19387 return (_messages.value[locale] || {}); 19388 } 19389 // setLocaleMessage 19390 function setLocaleMessage(locale, message) { 19391 _messages.value[locale] = message; 19392 _context.messages = _messages.value; 19393 } 19394 // mergeLocaleMessage 19395 function mergeLocaleMessage(locale, message) { 19396 _messages.value[locale] = _messages.value[locale] || {}; 19397 deepCopy(message, _messages.value[locale]); 19398 _context.messages = _messages.value; 19399 } 19400 // getDateTimeFormat 19401 function getDateTimeFormat(locale) { 19402 return _datetimeFormats.value[locale] || {}; 19403 } 19404 // setDateTimeFormat 19405 function setDateTimeFormat(locale, format) { 19406 _datetimeFormats.value[locale] = format; 19407 _context.datetimeFormats = _datetimeFormats.value; 19408 clearDateTimeFormat(_context, locale, format); 19409 } 19410 // mergeDateTimeFormat 19411 function mergeDateTimeFormat(locale, format) { 19412 _datetimeFormats.value[locale] = Object.assign(_datetimeFormats.value[locale] || {}, format); 19413 _context.datetimeFormats = _datetimeFormats.value; 19414 clearDateTimeFormat(_context, locale, format); 19415 } 19416 // getNumberFormat 19417 function getNumberFormat(locale) { 19418 return _numberFormats.value[locale] || {}; 19419 } 19420 // setNumberFormat 19421 function setNumberFormat(locale, format) { 19422 _numberFormats.value[locale] = format; 19423 _context.numberFormats = _numberFormats.value; 19424 clearNumberFormat(_context, locale, format); 19425 } 19426 // mergeNumberFormat 19427 function mergeNumberFormat(locale, format) { 19428 _numberFormats.value[locale] = Object.assign(_numberFormats.value[locale] || {}, format); 19429 _context.numberFormats = _numberFormats.value; 19430 clearNumberFormat(_context, locale, format); 19431 } 19432 // for debug 19433 composerID++; 19434 // watch root locale & fallbackLocale 19435 if (__root) { 19436 vue.watch(__root.locale, (val) => { 19437 if (_inheritLocale) { 19438 _locale.value = val; 19439 _context.locale = val; 19440 updateFallbackLocale(_context, _locale.value, _fallbackLocale.value); 19441 } 19442 }); 19443 vue.watch(__root.fallbackLocale, (val) => { 19444 if (_inheritLocale) { 19445 _fallbackLocale.value = val; 19446 _context.fallbackLocale = val; 19447 updateFallbackLocale(_context, _locale.value, _fallbackLocale.value); 19448 } 19449 }); 19450 } 19451 // define composition API! 19452 const composer = { 19453 id: composerID, 19454 locale, 19455 fallbackLocale, 19456 get inheritLocale() { 19457 return _inheritLocale; 19458 }, 19459 set inheritLocale(val) { 19460 _inheritLocale = val; 19461 if (val && __root) { 19462 _locale.value = __root.locale.value; 19463 _fallbackLocale.value = __root.fallbackLocale.value; 19464 updateFallbackLocale(_context, _locale.value, _fallbackLocale.value); 19465 } 19466 }, 19467 get availableLocales() { 19468 return Object.keys(_messages.value).sort(); 19469 }, 19470 messages, 19471 datetimeFormats, 19472 numberFormats, 19473 get modifiers() { 19474 return _modifiers; 19475 }, 19476 get pluralRules() { 19477 return _pluralRules || {}; 19478 }, 19479 get isGlobal() { 19480 return _isGlobal; 19481 }, 19482 get missingWarn() { 19483 return _missingWarn; 19484 }, 19485 set missingWarn(val) { 19486 _missingWarn = val; 19487 _context.missingWarn = _missingWarn; 19488 }, 19489 get fallbackWarn() { 19490 return _fallbackWarn; 19491 }, 19492 set fallbackWarn(val) { 19493 _fallbackWarn = val; 19494 _context.fallbackWarn = _fallbackWarn; 19495 }, 19496 get fallbackRoot() { 19497 return _fallbackRoot; 19498 }, 19499 set fallbackRoot(val) { 19500 _fallbackRoot = val; 19501 }, 19502 get fallbackFormat() { 19503 return _fallbackFormat; 19504 }, 19505 set fallbackFormat(val) { 19506 _fallbackFormat = val; 19507 _context.fallbackFormat = _fallbackFormat; 19508 }, 19509 get warnHtmlMessage() { 19510 return _warnHtmlMessage; 19511 }, 19512 set warnHtmlMessage(val) { 19513 _warnHtmlMessage = val; 19514 _context.warnHtmlMessage = val; 19515 }, 19516 get escapeParameter() { 19517 return _escapeParameter; 19518 }, 19519 set escapeParameter(val) { 19520 _escapeParameter = val; 19521 _context.escapeParameter = val; 19522 }, 19523 t, 19524 rt, 19525 d, 19526 n, 19527 te, 19528 tm, 19529 getLocaleMessage, 19530 setLocaleMessage, 19531 mergeLocaleMessage, 19532 getDateTimeFormat, 19533 setDateTimeFormat, 19534 mergeDateTimeFormat, 19535 getNumberFormat, 19536 setNumberFormat, 19537 mergeNumberFormat, 19538 getPostTranslationHandler, 19539 setPostTranslationHandler, 19540 getMissingHandler, 19541 setMissingHandler, 19542 [TransrateVNodeSymbol]: transrateVNode, 19543 [NumberPartsSymbol]: numberParts, 19544 [DatetimePartsSymbol]: datetimeParts, 19545 [SetPluralRulesSymbol]: setPluralRules, 19546 [DevToolsMetaSymbol]: __meta 19547 }; 19548 // for vue-devtools timeline event 19549 { 19550 composer[EnableEmitter] = (emitter) => { 19551 _context.__v_emitter = emitter; 19552 }; 19553 composer[DisableEmitter] = () => { 19554 _context.__v_emitter = undefined; 19555 }; 19556 } 19557 return composer; 19558 } 19559 19560 /** 19561 * Convert to I18n Composer Options from VueI18n Options 19562 * 19563 * @internal 19564 */ 19565 function convertComposerOptions(options) { 19566 const locale = isString(options.locale) ? options.locale : 'en-US'; 19567 const fallbackLocale = isString(options.fallbackLocale) || 19568 isArray(options.fallbackLocale) || 19569 isPlainObject(options.fallbackLocale) || 19570 options.fallbackLocale === false 19571 ? options.fallbackLocale 19572 : locale; 19573 const missing = isFunction(options.missing) ? options.missing : undefined; 19574 const missingWarn = isBoolean(options.silentTranslationWarn) || 19575 isRegExp(options.silentTranslationWarn) 19576 ? !options.silentTranslationWarn 19577 : true; 19578 const fallbackWarn = isBoolean(options.silentFallbackWarn) || 19579 isRegExp(options.silentFallbackWarn) 19580 ? !options.silentFallbackWarn 19581 : true; 19582 const fallbackRoot = isBoolean(options.fallbackRoot) 19583 ? options.fallbackRoot 19584 : true; 19585 const fallbackFormat = !!options.formatFallbackMessages; 19586 const modifiers = isPlainObject(options.modifiers) ? options.modifiers : {}; 19587 const pluralizationRules = options.pluralizationRules; 19588 const postTranslation = isFunction(options.postTranslation) 19589 ? options.postTranslation 19590 : undefined; 19591 const warnHtmlMessage = isString(options.warnHtmlInMessage) 19592 ? options.warnHtmlInMessage !== 'off' 19593 : true; 19594 const escapeParameter = !!options.escapeParameterHtml; 19595 const inheritLocale = isBoolean(options.sync) ? options.sync : true; 19596 if (options.formatter) { 19597 warn(getWarnMessage(8 /* NOT_SUPPORTED_FORMATTER */)); 19598 } 19599 if (options.preserveDirectiveContent) { 19600 warn(getWarnMessage(9 /* NOT_SUPPORTED_PRESERVE_DIRECTIVE */)); 19601 } 19602 let messages = options.messages; 19603 if (isPlainObject(options.sharedMessages)) { 19604 const sharedMessages = options.sharedMessages; 19605 const locales = Object.keys(sharedMessages); 19606 messages = locales.reduce((messages, locale) => { 19607 const message = messages[locale] || (messages[locale] = {}); 19608 Object.assign(message, sharedMessages[locale]); 19609 return messages; 19610 }, (messages || {})); 19611 } 19612 const { __i18n, __root, __meta } = options; 19613 const datetimeFormats = options.datetimeFormats; 19614 const numberFormats = options.numberFormats; 19615 const flatJson = options.flatJson; 19616 return { 19617 locale, 19618 fallbackLocale, 19619 messages, 19620 flatJson, 19621 datetimeFormats, 19622 numberFormats, 19623 missing, 19624 missingWarn, 19625 fallbackWarn, 19626 fallbackRoot, 19627 fallbackFormat, 19628 modifiers, 19629 pluralRules: pluralizationRules, 19630 postTranslation, 19631 warnHtmlMessage, 19632 escapeParameter, 19633 inheritLocale, 19634 __i18n, 19635 __root, 19636 __meta 19637 }; 19638 } 19639 /** 19640 * create VueI18n interface factory 19641 * 19642 * @internal 19643 */ 19644 function createVueI18n(options = {}) { 19645 const composer = createComposer(convertComposerOptions(options)); 19646 // defines VueI18n 19647 const vueI18n = { 19648 // id 19649 id: composer.id, 19650 // locale 19651 get locale() { 19652 return composer.locale.value; 19653 }, 19654 set locale(val) { 19655 composer.locale.value = val; 19656 }, 19657 // fallbackLocale 19658 get fallbackLocale() { 19659 return composer.fallbackLocale.value; 19660 }, 19661 set fallbackLocale(val) { 19662 composer.fallbackLocale.value = val; 19663 }, 19664 // messages 19665 get messages() { 19666 return composer.messages.value; 19667 }, 19668 // datetimeFormats 19669 get datetimeFormats() { 19670 return composer.datetimeFormats.value; 19671 }, 19672 // numberFormats 19673 get numberFormats() { 19674 return composer.numberFormats.value; 19675 }, 19676 // availableLocales 19677 get availableLocales() { 19678 return composer.availableLocales; 19679 }, 19680 // formatter 19681 get formatter() { 19682 warn(getWarnMessage(8 /* NOT_SUPPORTED_FORMATTER */)); 19683 // dummy 19684 return { 19685 interpolate() { 19686 return []; 19687 } 19688 }; 19689 }, 19690 set formatter(val) { 19691 warn(getWarnMessage(8 /* NOT_SUPPORTED_FORMATTER */)); 19692 }, 19693 // missing 19694 get missing() { 19695 return composer.getMissingHandler(); 19696 }, 19697 set missing(handler) { 19698 composer.setMissingHandler(handler); 19699 }, 19700 // silentTranslationWarn 19701 get silentTranslationWarn() { 19702 return isBoolean(composer.missingWarn) 19703 ? !composer.missingWarn 19704 : composer.missingWarn; 19705 }, 19706 set silentTranslationWarn(val) { 19707 composer.missingWarn = isBoolean(val) ? !val : val; 19708 }, 19709 // silentFallbackWarn 19710 get silentFallbackWarn() { 19711 return isBoolean(composer.fallbackWarn) 19712 ? !composer.fallbackWarn 19713 : composer.fallbackWarn; 19714 }, 19715 set silentFallbackWarn(val) { 19716 composer.fallbackWarn = isBoolean(val) ? !val : val; 19717 }, 19718 // modifiers 19719 get modifiers() { 19720 return composer.modifiers; 19721 }, 19722 // formatFallbackMessages 19723 get formatFallbackMessages() { 19724 return composer.fallbackFormat; 19725 }, 19726 set formatFallbackMessages(val) { 19727 composer.fallbackFormat = val; 19728 }, 19729 // postTranslation 19730 get postTranslation() { 19731 return composer.getPostTranslationHandler(); 19732 }, 19733 set postTranslation(handler) { 19734 composer.setPostTranslationHandler(handler); 19735 }, 19736 // sync 19737 get sync() { 19738 return composer.inheritLocale; 19739 }, 19740 set sync(val) { 19741 composer.inheritLocale = val; 19742 }, 19743 // warnInHtmlMessage 19744 get warnHtmlInMessage() { 19745 return composer.warnHtmlMessage ? 'warn' : 'off'; 19746 }, 19747 set warnHtmlInMessage(val) { 19748 composer.warnHtmlMessage = val !== 'off'; 19749 }, 19750 // escapeParameterHtml 19751 get escapeParameterHtml() { 19752 return composer.escapeParameter; 19753 }, 19754 set escapeParameterHtml(val) { 19755 composer.escapeParameter = val; 19756 }, 19757 // preserveDirectiveContent 19758 get preserveDirectiveContent() { 19759 warn(getWarnMessage(9 /* NOT_SUPPORTED_PRESERVE_DIRECTIVE */)); 19760 return true; 19761 }, 19762 set preserveDirectiveContent(val) { 19763 warn(getWarnMessage(9 /* NOT_SUPPORTED_PRESERVE_DIRECTIVE */)); 19764 }, 19765 // pluralizationRules 19766 get pluralizationRules() { 19767 return composer.pluralRules || {}; 19768 }, 19769 // for internal 19770 __composer: composer, 19771 // t 19772 t(...args) { 19773 const [arg1, arg2, arg3] = args; 19774 const options = {}; 19775 let list = null; 19776 let named = null; 19777 if (!isString(arg1)) { 19778 throw createI18nError(15 /* INVALID_ARGUMENT */); 19779 }
19780 const key = arg1; 19781 if (isString(arg2)) { 19782 options.locale = arg2; 19783 } 19784 else if (isArray(arg2)) { 19785 list = arg2; 19786 } 19787 else if (isPlainObject(arg2)) { 19788 named = arg2; 19789 } 19790 if (isArray(arg3)) { 19791 list = arg3; 19792 } 19793 else if (isPlainObject(arg3)) { 19794 named = arg3; 19795 } 19796 return composer.t(key, list || named || {}, options); 19797 }, 19798 rt(...args) { 19799 return composer.rt(...args); 19800 }, 19801 // tc 19802 tc(...args) { 19803 const [arg1, arg2, arg3] = args; 19804 const options = { plural: 1 }; 19805 let list = null; 19806 let named = null; 19807 if (!isString(arg1)) { 19808 throw createI18nError(15 /* INVALID_ARGUMENT */); 19809 } 19810 const key = arg1; 19811 if (isString(arg2)) { 19812 options.locale = arg2; 19813 } 19814 else if (isNumber(arg2)) { 19815 options.plural = arg2; 19816 } 19817 else if (isArray(arg2)) { 19818 list = arg2; 19819 } 19820 else if (isPlainObject(arg2)) { 19821 named = arg2; 19822 } 19823 if (isString(arg3)) { 19824 options.locale = arg3; 19825 } 19826 else if (isArray(arg3)) { 19827 list = arg3; 19828 } 19829 else if (isPlainObject(arg3)) { 19830 named = arg3; 19831 } 19832 return composer.t(key, list || named || {}, options); 19833 }, 19834 // te 19835 te(key, locale) { 19836 return composer.te(key, locale); 19837 }, 19838 // tm 19839 tm(key) { 19840 return composer.tm(key); 19841 }, 19842 // getLocaleMessage 19843 getLocaleMessage(locale) { 19844 return composer.getLocaleMessage(locale); 19845 }, 19846 // setLocaleMessage 19847 setLocaleMessage(locale, message) { 19848 composer.setLocaleMessage(locale, message); 19849 }, 19850 // mergeLocaleMessage 19851 mergeLocaleMessage(locale, message) { 19852 composer.mergeLocaleMessage(locale, message); 19853 }, 19854 // d 19855 d(...args) { 19856 return composer.d(...args); 19857 }, 19858 // getDateTimeFormat 19859 getDateTimeFormat(locale) { 19860 return composer.getDateTimeFormat(locale); 19861 }, 19862 // setDateTimeFormat 19863 setDateTimeFormat(locale, format) { 19864 composer.setDateTimeFormat(locale, format); 19865 }, 19866 // mergeDateTimeFormat 19867 mergeDateTimeFormat(locale, format) { 19868 composer.mergeDateTimeFormat(locale, format); 19869 }, 19870 // n 19871 n(...args) { 19872 return composer.n(...args); 19873 }, 19874 // getNumberFormat 19875 getNumberFormat(locale) { 19876 return composer.getNumberFormat(locale); 19877 }, 19878 // setNumberFormat 19879 setNumberFormat(locale, format) { 19880 composer.setNumberFormat(locale, format); 19881 }, 19882 // mergeNumberFormat 19883 mergeNumberFormat(locale, format) { 19884 composer.mergeNumberFormat(locale, format); 19885 }, 19886 // getChoiceIndex 19887 // eslint-disable-next-line @typescript-eslint/no-unused-vars 19888 getChoiceIndex(choice, choicesLength) { 19889 warn(getWarnMessage(10 /* NOT_SUPPORTED_GET_CHOICE_INDEX */)); 19890 return -1; 19891 }, 19892 // for internal 19893 __onComponentInstanceCreated(target) { 19894 const { componentInstanceCreatedListener } = options; 19895 if (componentInstanceCreatedListener) { 19896 componentInstanceCreatedListener(target, vueI18n); 19897 } 19898 } 19899 }; 19900 // for vue-devtools timeline event 19901 { 19902 vueI18n.__enableEmitter = (emitter) => { 19903 // eslint-disable-next-line @typescript-eslint/no-explicit-any 19904 const __composer = composer; 19905 __composer[EnableEmitter] && __composer[EnableEmitter](emitter); 19906 }; 19907 vueI18n.__disableEmitter = () => { 19908 // eslint-disable-next-line @typescript-eslint/no-explicit-any 19909 const __composer = composer; 19910 __composer[DisableEmitter] && __composer[DisableEmitter](); 19911 }; 19912 } 19913 return vueI18n; 19914 } 19915 19916 const baseFormatProps = { 19917 tag: { 19918 type: [String, Object] 19919 }, 19920 locale: { 19921 type: String 19922 }, 19923 scope: { 19924 type: String, 19925 validator: (val) => val === 'parent' || val === 'global', 19926 default: 'parent' 19927 } 19928 }; 19929 19930 /** 19931 * Translation Component 19932 * 19933 * @remarks 19934 * See the following items for property about details 19935 * 19936 * @VueI18nSee [TranslationProps](component#translationprops) 19937 * @VueI18nSee [BaseFormatProps](component#baseformatprops) 19938 * @VueI18nSee [Component Interpolation](../../guide/advanced/component) 19939 * 19940 * @example 19941 * ```html 19942 * <div id="app"> 19943 * <!-- ... -->
19944 * <i18n path="term" tag="label" for="tos"> 19945 * <a :href="url" target="_blank">{{ $t('tos') }}</a> 19946 * </i18n> 19947 * <!-- ... --> 19948 * </div> 19949 * ``` 19950 * ```js 19951 * import { createApp } from 'vue' 19952 * import { createI18n } from 'vue-i18n' 19953 * 19954 * const messages = { 19955 * en: { 19956 * tos: 'Term of Service', 19957 * term: 'I accept xxx {0}.' 19958 * }, 19959 * ja: { 19960 * tos: 'å©ç¨è¦ç´', 19961 * term: 'ç§ã¯ xxx ã®{0}ã«åæãã¾ãã' 19962 * } 19963 * } 19964 * 19965 * const i18n = createI18n({ 19966 * locale: 'en', 19967 * messages 19968 * }) 19969 * 19970 * const app = createApp({ 19971 * data: { 19972 * url: '/term' 19973 * } 19974 * }).use(i18n).mount('#app') 19975 * ``` 19976 * 19977 * @VueI18nComponent 19978 */ 19979 const Translation = { 19980 /* eslint-disable */ 19981 name: 'i18n-t', 19982 props: assign({ 19983 keypath: { 19984 type: String, 19985 required: true 19986 }, 19987 plural: { 19988 type: [Number, String], 19989 // eslint-disable-next-line @typescript-eslint/no-explicit-any 19990 validator: (val) => isNumber(val) || !isNaN(val) 19991 } 19992 }, baseFormatProps), 19993 /* eslint-enable */ 19994 setup(props, context) { 19995 const { slots, attrs } = context; 19996 const i18n = useI18n({ useScope: props.scope }); 19997 const keys = Object.keys(slots).filter(key => key !== '_'); 19998 return () => { 19999 const options = {}; 20000 if (props.locale) { 20001 options.locale = props.locale; 20002 } 20003 if (props.plural !== undefined) { 20004 options.plural = isString(props.plural) ? +props.plural : props.plural; 20005 } 20006 const arg = getInterpolateArg(context, keys); 20007 // eslint-disable-next-line @typescript-eslint/no-explicit-any 20008 const children = i18n[TransrateVNodeSymbol](props.keypath, arg, options); 20009 const assignedAttrs = assign({}, attrs); 20010 // prettier-ignore 20011 return isString(props.tag) 20012 ? vue.h(props.tag, assignedAttrs, children) 20013 : isObject(props.tag) 20014 ? vue.h(props.tag, assignedAttrs, children) 20015 : vue.h(vue.Fragment, assignedAttrs, children); 20016 }; 20017 } 20018 }; 20019 function getInterpolateArg({ slots }, keys) { 20020 if (keys.length === 1 && keys[0] === 'default') { 20021 // default slot only 20022 return slots.default ? slots.default() : []; 20023 } 20024 else { 20025 // named slots 20026 return keys.reduce((arg, key) => { 20027 const slot = slots[key]; 20028 if (slot) { 20029 arg[key] = slot(); 20030 } 20031 return arg; 20032 }, {}); 20033 } 20034 } 20035 20036 function renderFormatter(props, context, slotKeys, partFormatter) { 20037 const { slots, attrs } = context; 20038 return () => { 20039 const options = { part: true }; 20040 let overrides = {}; 20041 if (props.locale) { 20042 options.locale = props.locale; 20043 } 20044 if (isString(props.format)) { 20045 options.key = props.format; 20046 } 20047 else if (isObject(props.format)) { 20048 // eslint-disable-next-line @typescript-eslint/no-explicit-any 20049 if (isString(props.format.key)) { 20050 // eslint-disable-next-line @typescript-eslint/no-explicit-any 20051 options.key = props.format.key; 20052 } 20053 // Filter out number format options only 20054 overrides = Object.keys(props.format).reduce((options, prop) => { 20055 return slotKeys.includes(prop) 20056 ? Object.assign({}, options, { [prop]: props.format[prop] }) // eslint-disable-line @typescript-eslint/no-explicit-any 20057 : options; 20058 }, {}); 20059 } 20060 const parts = partFormatter(...[props.value, options, overrides]); 20061 let children = [options.key]; 20062 if (isArray(parts)) { 20063 children = parts.map((part, index) => { 20064 const slot = slots[part.type]; 20065 return slot 20066 ? slot({ [part.type]: part.value, index, parts }) 20067 : [part.value]; 20068 }); 20069 } 20070 else if (isString(parts)) { 20071 children = [parts]; 20072 } 20073 const assignedAttrs = assign({}, attrs); 20074 // prettier-ignore 20075 return isString(props.tag) 20076 ? vue.h(props.tag, assignedAttrs, children) 20077 : isObject(props.tag) 20078 ? vue.h(props.tag, assignedAttrs, children) 20079 : vue.h(vue.Fragment, assignedAttrs, children); 20080 }; 20081 } 20082 20083 const NUMBER_FORMAT_KEYS = [ 20084 'localeMatcher', 20085 'style', 20086 'unit', 20087 'unitDisplay', 20088 'currency', 20089 'currencyDisplay', 20090 'useGrouping', 20091 'numberingSystem', 20092 'minimumIntegerDigits', 20093 'minimumFractionDigits', 20094 'maximumFractionDigits', 20095 'minimumSignificantDigits', 20096 'maximumSignificantDigits', 20097 'notation', 20098 'formatMatcher' 20099 ]; 20100 /** 20101 * Number Format Component 20102 * 20103 * @remarks 20104 * See the following items for property about details 20105 * 20106 * @VueI18nSee [FormattableProps](component#formattableprops) 20107 * @VueI18nSee [BaseFormatProps](component#baseformatprops) 20108 * @VueI18nSee [Custom Formatting](../../guide/essentials/number#custom-formatting) 20109 * 20110 * @VueI18nDanger 20111 * Not supported IE, due to no support `Intl.NumberFormat#formatToParts` in [IE](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/formatToParts) 20112 * 20113 * If you want to use it, you need to use [polyfill](https://github.com/formatjs/formatjs/tree/main/packages/intl-numberformat) 20114 * 20115 * @VueI18nComponent 20116 */ 20117 const NumberFormat = { 20118 /* eslint-disable */ 20119 name: 'i18n-n', 20120 props: assign({ 20121 value: { 20122 type: Number, 20123 required: true 20124 }, 20125 format: { 20126 type: [String, Object] 20127 } 20128 }, baseFormatProps), 20129 /* eslint-enable */ 20130 setup(props, context) { 20131 const i18n = useI18n({ useScope: 'parent' }); 20132 return renderFormatter(props, context, NUMBER_FORMAT_KEYS, (...args) => 20133 // eslint-disable-next-line @typescript-eslint/no-explicit-any 20134 i18n[NumberPartsSymbol](...args)); 20135 } 20136 }; 20137 20138 const DATETIME_FORMAT_KEYS = [ 20139 'dateStyle', 20140 'timeStyle', 20141 'fractionalSecondDigits', 20142 'calendar', 20143 'dayPeriod', 20144 'numberingSystem', 20145 'localeMatcher', 20146 'timeZone', 20147 'hour12', 20148 'hourCycle', 20149 'formatMatcher', 20150 'weekday', 20151 'era', 20152 'year', 20153 'month', 20154 'day', 20155 'hour', 20156 'minute', 20157 'second', 20158 'timeZoneName' 20159 ]; 20160 /** 20161 * Datetime Format Component 20162 * 20163 * @remarks 20164 * See the following items for property about details 20165 * 20166 * @VueI18nSee [FormattableProps](component#formattableprops) 20167 * @VueI18nSee [BaseFormatProps](component#baseformatprops)
20168 * @VueI18nSee [Custom Formatting](../../guide/essentials/datetime#custom-formatting) 20169 * 20170 * @VueI18nDanger 20171 * Not supported IE, due to no support `Intl.DateTimeFormat#formatToParts` in [IE](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/formatToParts) 20172 * 20173 * If you want to use it, you need to use [polyfill](https://github.com/formatjs/formatjs/tree/main/packages/intl-datetimeformat) 20174 * 20175 * @VueI18nComponent 20176 */ 20177 const DatetimeFormat = { 20178 /* eslint-disable */ 20179 name: 'i18n-d', 20180 props: assign({ 20181 value: { 20182 type: [Number, Date], 20183 required: true 20184 }, 20185 format: { 20186 type: [String, Object] 20187 } 20188 }, baseFormatProps), 20189 /* eslint-enable */ 20190 setup(props, context) { 20191 const i18n = useI18n({ useScope: 'parent' }); 20192 return renderFormatter(props, context, DATETIME_FORMAT_KEYS, (...args) => 20193 // eslint-disable-next-line @typescript-eslint/no-explicit-any 20194 i18n[DatetimePartsSymbol](...args)); 20195 } 20196 }; 20197 20198 function getComposer$2(i18n, instance) { 20199 const i18nInternal = i18n; 20200 if (i18n.mode === 'composition') { 20201 return (i18nInternal.__getInstance(instance) || i18n.global); 20202 } 20203 else { 20204 const vueI18n = i18nInternal.__getInstance(instance); 20205 return vueI18n != null 20206 ? vueI18n.__composer 20207 : i18n.global.__composer; 20208 } 20209 } 20210 function vTDirective(i18n) { 20211 const bind = (el, { instance, value, modifiers }) => { 20212 /* istanbul ignore if */ 20213 if (!instance || !instance.$) { 20214 throw createI18nError(22 /* UNEXPECTED_ERROR */); 20215 } 20216 const composer = getComposer$2(i18n, instance.$); 20217 if (modifiers.preserve) { 20218 warn(getWarnMessage(7 /* NOT_SUPPORTED_PRESERVE */)); 20219 } 20220 const parsedValue = parseValue(value); 20221 el.textContent = composer.t(...makeParams(parsedValue)); 20222 }; 20223 return { 20224 beforeMount: bind, 20225 beforeUpdate: bind 20226 }; 20227 } 20228 function parseValue(value) { 20229 if (isString(value)) { 20230 return { path: value }; 20231 } 20232 else if (isPlainObject(value)) { 20233 if (!('path' in value)) { 20234 throw createI18nError(19 /* REQUIRED_VALUE */, 'path'); 20235 } 20236 return value; 20237 } 20238 else { 20239 throw createI18nError(20 /* INVALID_VALUE */); 20240 } 20241 } 20242 function makeParams(value) { 20243 const { path, locale, args, choice, plural } = value; 20244 const options = {}; 20245 const named = args || {}; 20246 if (isString(locale)) { 20247 options.locale = locale; 20248 } 20249 if (isNumber(choice)) { 20250 options.plural = choice; 20251 } 20252 if (isNumber(plural)) { 20253 options.plural = plural; 20254 } 20255 return [path, named, options]; 20256 } 20257 20258 function apply(app, i18n, ...options) { 20259 const pluginOptions = isPlainObject(options[0]) 20260 ? options[0] 20261 : {}; 20262 const useI18nComponentName = !!pluginOptions.useI18nComponentName; 20263 const globalInstall = isBoolean(pluginOptions.globalInstall) 20264 ? pluginOptions.globalInstall 20265 : true; 20266 if (globalInstall && useI18nComponentName) { 20267 warn(getWarnMessage(11 /* COMPONENT_NAME_LEGACY_COMPATIBLE */, { 20268 name: Translation.name 20269 })); 20270 } 20271 if (globalInstall) { 20272 // install components 20273 app.component(!useI18nComponentName ? Translation.name : 'i18n', Translation); 20274 app.component(NumberFormat.name, NumberFormat); 20275 app.component(DatetimeFormat.name, DatetimeFormat); 20276 } 20277 // install directive 20278 app.directive('t', vTDirective(i18n)); 20279 } 20280 20281 var global$1 = (typeof global !== "undefined" ? global : 20282 typeof self !== "undefined" ? self : 20283 typeof window !== "undefined" ? window : {}); 20284 20285 function getDevtoolsGlobalHook() { 20286 return getTarget().__VUE_DEVTOOLS_GLOBAL_HOOK__; 20287 } 20288 function getTarget() { 20289 // @ts-ignore 20290 return typeof navigator !== 'undefined' 20291 ? window 20292 : typeof global$1 !== 'undefined' 20293 ? global$1 20294 : {}; 20295 } 20296 20297 const HOOK_SETUP = 'devtools-plugin:setup'; 20298 20299 function setupDevtoolsPlugin(pluginDescriptor, setupFn) { 20300 const hook = getDevtoolsGlobalHook(); 20301 if (hook) { 20302 hook.emit(HOOK_SETUP, pluginDescriptor, setupFn); 20303 } 20304 else { 20305 const target = getTarget(); 20306 const list = target.__VUE_DEVTOOLS_PLUGINS__ = target.__VUE_DEVTOOLS_PLUGINS__ || []; 20307 list.push({ 20308 pluginDescriptor, 20309 setupFn 20310 }); 20311 } 20312 } 20313 20314 const VueDevToolsLabels = { 20315 ["vue-devtools-plugin-vue-i18n" /* PLUGIN */]: 'Vue I18n devtools', 20316 ["vue-i18n-resource-inspector" /* CUSTOM_INSPECTOR */]: 'I18n Resources', 20317 ["vue-i18n-timeline" /* TIMELINE */]: 'Vue I18n' 20318 }; 20319 const VueDevToolsPlaceholders = { 20320 ["vue-i18n-resource-inspector" /* CUSTOM_INSPECTOR */]: 'Search for scopes ...' 20321 }; 20322 const VueDevToolsTimelineColors = { 20323 ["vue-i18n-timeline" /* TIMELINE */]: 0xffcd19 20324 }; 20325 20326 const VUE_I18N_COMPONENT_TYPES = 'vue-i18n: composer properties'; 20327 let devtoolsApi; 20328 async function enableDevTools(app, i18n) { 20329 return new Promise((resolve, reject) => { 20330 try { 20331 setupDevtoolsPlugin({ 20332 id: "vue-devtools-plugin-vue-i18n" /* PLUGIN */, 20333 label: VueDevToolsLabels["vue-devtools-plugin-vue-i18n" /* PLUGIN */], 20334 packageName: 'vue-i18n', 20335 homepage: 'https://vue-i18n.intlify.dev', 20336 logo: 'https://vue-i18n.intlify.dev/vue-i18n-devtools-logo.png', 20337 componentStateTypes: [VUE_I18N_COMPONENT_TYPES], 20338 app 20339 }, api => { 20340 devtoolsApi = api; 20341 api.on.visitComponentTree(({ componentInstance, treeNode }) => { 20342 updateComponentTreeTags(componentInstance, treeNode, i18n); 20343 }); 20344 api.on.inspectComponent(({ componentInstance, instanceData }) => { 20345 if (componentInstance.vnode.el.__VUE_I18N__ && instanceData) { 20346 if (i18n.mode === 'legacy') { 20347 // ignore global scope on legacy mode 20348 if (componentInstance.vnode.el.__VUE_I18N__ !== 20349 i18n.global.__composer) { 20350 inspectComposer(instanceData, componentInstance.vnode.el.__VUE_I18N__); 20351 } 20352 } 20353 else { 20354 inspectComposer(instanceData, componentInstance.vnode.el.__VUE_I18N__); 20355 } 20356 } 20357 }); 20358 api.addInspector({ 20359 id: "vue-i18n-resource-inspector" /* CUSTOM_INSPECTOR */, 20360 label: VueDevToolsLabels["vue-i18n-resource-inspector" /* CUSTOM_INSPECTOR */], 20361 icon: 'language', 20362 treeFilterPlaceholder: VueDevToolsPlaceholders["vue-i18n-resource-inspector" /* CUSTOM_INSPECTOR */] 20363 }); 20364 api.on.getInspectorTree(payload => { 20365 if (payload.app === app && 20366 payload.inspectorId === "vue-i18n-resource-inspector" /* CUSTOM_INSPECTOR */) { 20367 registerScope(payload, i18n); 20368 } 20369 }); 20370 api.on.getInspectorState(payload => { 20371 if (payload.app === app && 20372 payload.inspectorId === "vue-i18n-resource-inspector" /* CUSTOM_INSPECTOR */) { 20373 inspectScope(payload, i18n); 20374 } 20375 }); 20376 api.on.editInspectorState(payload => { 20377 if (payload.app === app && 20378 payload.inspectorId === "vue-i18n-resource-inspector" /* CUSTOM_INSPECTOR */) { 20379 editScope(payload, i18n); 20380 } 20381 }); 20382 api.addTimelineLayer({ 20383 id: "vue-i18n-timeline" /* TIMELINE */, 20384 label: VueDevToolsLabels["vue-i18n-timeline" /* TIMELINE */], 20385 color: VueDevToolsTimelineColors["vue-i18n-timeline" /* TIMELINE */] 20386 }); 20387 resolve(true); 20388 }); 20389 } 20390 catch (e) { 20391 console.error(e); 20392 reject(false); 20393 } 20394 }); 20395 } 20396 function updateComponentTreeTags(instance, // eslint-disable-line @typescript-eslint/no-explicit-any 20397 treeNode, i18n) { 20398 // prettier-ignore 20399 const global = i18n.mode === 'composition' 20400 ? i18n.global 20401 : i18n.global.__composer; 20402 if (instance && instance.vnode.el.__VUE_I18N__) { 20403 // add custom tags local scope only 20404 if (instance.vnode.el.__VUE_I18N__ !== global) {
vendor: 7,611 bytes, lines 20405-20648
20405 const label = instance.type.name || instance.type.displayName || instance.type.__file; 20406 const tag = { 20407 label: `i18n (${label} Scope)`, 20408 textColor: 0x000000, 20409 backgroundColor: 0xffcd19 20410 }; 20411 treeNode.tags.push(tag); 20412 } 20413 } 20414 } 20415 function inspectComposer(instanceData, composer) { 20416 const type = VUE_I18N_COMPONENT_TYPES; 20417 instanceData.state.push({ 20418 type, 20419 key: 'locale', 20420 editable: true, 20421 value: composer.locale.value 20422 }); 20423 instanceData.state.push({ 20424 type, 20425 key: 'availableLocales', 20426 editable: false, 20427 value: composer.availableLocales 20428 }); 20429 instanceData.state.push({ 20430 type, 20431 key: 'fallbackLocale', 20432 editable: true, 20433 value: composer.fallbackLocale.value 20434 }); 20435 instanceData.state.push({ 20436 type, 20437 key: 'inheritLocale', 20438 editable: true, 20439 value: composer.inheritLocale 20440 }); 20441 instanceData.state.push({ 20442 type, 20443 key: 'messages', 20444 editable: false, 20445 value: getLocaleMessageValue(composer.messages.value) 20446 }); 20447 instanceData.state.push({ 20448 type, 20449 key: 'datetimeFormats', 20450 editable: false, 20451 value: composer.datetimeFormats.value 20452 }); 20453 instanceData.state.push({ 20454 type, 20455 key: 'numberFormats', 20456 editable: false, 20457 value: composer.numberFormats.value 20458 }); 20459 } 20460 // eslint-disable-next-line @typescript-eslint/no-explicit-any 20461 function getLocaleMessageValue(messages) { 20462 const value = {}; 20463 Object.keys(messages).forEach((key) => { 20464 const v = messages[key]; 20465 if (isFunction(v) && 'source' in v) { 20466 value[key] = getMessageFunctionDetails(v); 20467 } 20468 else if (isObject(v)) { 20469 value[key] = getLocaleMessageValue(v); 20470 } 20471 else { 20472 value[key] = v; 20473 } 20474 }); 20475 return value; 20476 } 20477 const ESC = { 20478 '<': '<', 20479 '>': '>', 20480 '"': '"', 20481 '&': '&' 20482 }; 20483 function escape(s) { 20484 return s.replace(/[<>"&]/g, escapeChar); 20485 } 20486 function escapeChar(a) { 20487 return ESC[a] || a; 20488 } 20489 // eslint-disable-next-line @typescript-eslint/no-explicit-any 20490 function getMessageFunctionDetails(func) { 20491 const argString = func.source ? `("${escape(func.source)}")` : `(?)`; 20492 return { 20493 _custom: { 20494 type: 'function', 20495 display: `<span>Æ</span> ${argString}` 20496 } 20497 }; 20498 } 20499 function registerScope(payload, i18n) { 20500 payload.rootNodes.push({ 20501 id: 'global', 20502 label: 'Global Scope' 20503 }); 20504 // prettier-ignore 20505 const global = i18n.mode === 'composition' 20506 ? i18n.global 20507 : i18n.global.__composer; 20508 for (const [keyInstance, instance] of i18n.__instances) { 20509 // prettier-ignore 20510 const composer = i18n.mode === 'composition' 20511 ? instance 20512 : instance.__composer; 20513 if (global === composer) { 20514 continue; 20515 } 20516 const label = keyInstance.type.name || 20517 keyInstance.type.displayName || 20518 keyInstance.type.__file; 20519 payload.rootNodes.push({ 20520 id: composer.id.toString(), 20521 label: `${label} Scope` 20522 }); 20523 } 20524 } 20525 function getComposer$1(nodeId, i18n) { 20526 if (nodeId === 'global') { 20527 return i18n.mode === 'composition' 20528 ? i18n.global 20529 : i18n.global.__composer; 20530 } 20531 else { 20532 const instance = Array.from(i18n.__instances.values()).find(item => item.id.toString() === nodeId); 20533 if (instance) { 20534 return i18n.mode === 'composition' 20535 ? instance 20536 : instance.__composer; 20537 } 20538 else { 20539 return null; 20540 } 20541 } 20542 } 20543 function inspectScope(payload, i18n) { 20544 const composer = getComposer$1(payload.nodeId, i18n); 20545 if (composer) { 20546 payload.state = makeScopeInspectState(composer); 20547 } 20548 } 20549 function makeScopeInspectState(composer) { 20550 const state = {}; 20551 const localeType = 'Locale related info'; 20552 const localeStates = [ 20553 { 20554 type: localeType, 20555 key: 'locale', 20556 editable: true, 20557 value: composer.locale.value 20558 }, 20559 { 20560 type: localeType, 20561 key: 'fallbackLocale', 20562 editable: true, 20563 value: composer.fallbackLocale.value 20564 }, 20565 { 20566 type: localeType, 20567 key: 'availableLocales', 20568 editable: false, 20569 value: composer.availableLocales 20570 }, 20571 { 20572 type: localeType, 20573 key: 'inheritLocale', 20574 editable: true, 20575 value: composer.inheritLocale 20576 } 20577 ]; 20578 state[localeType] = localeStates; 20579 const localeMessagesType = 'Locale messages info'; 20580 const localeMessagesStates = [ 20581 { 20582 type: localeMessagesType, 20583 key: 'messages', 20584 editable: false, 20585 value: getLocaleMessageValue(composer.messages.value) 20586 } 20587 ]; 20588 state[localeMessagesType] = localeMessagesStates; 20589 const datetimeFormatsType = 'Datetime formats info'; 20590 const datetimeFormatsStates = [ 20591 { 20592 type: datetimeFormatsType, 20593 key: 'datetimeFormats', 20594 editable: false, 20595 value: composer.datetimeFormats.value 20596 } 20597 ]; 20598 state[datetimeFormatsType] = datetimeFormatsStates; 20599 const numberFormatsType = 'Datetime formats info'; 20600 const numberFormatsStates = [ 20601 { 20602 type: numberFormatsType, 20603 key: 'numberFormats', 20604 editable: false, 20605 value: composer.numberFormats.value 20606 } 20607 ]; 20608 state[numberFormatsType] = numberFormatsStates; 20609 return state; 20610 } 20611 function addTimelineEvent(event, payload) { 20612 if (devtoolsApi) { 20613 let groupId; 20614 if (payload && 'groupId' in payload) { 20615 groupId = payload.groupId; 20616 delete payload.groupId; 20617 } 20618 devtoolsApi.addTimelineEvent({ 20619 layerId: "vue-i18n-timeline" /* TIMELINE */, 20620 event: { 20621 title: event, 20622 groupId, 20623 time: Date.now(), 20624 meta: {}, 20625 data: payload || {}, 20626 logType: event === "compile-error" /* COMPILE_ERROR */ 20627 ? 'error' 20628 : event === "fallback" /* FALBACK */ || 20629 event === "missing" /* MISSING */ 20630 ? 'warning' 20631 : 'default' 20632 } 20633 }); 20634 } 20635 } 20636 function editScope(payload, i18n) { 20637 const composer = getComposer$1(payload.nodeId, i18n); 20638 if (composer) { 20639 const [field] = payload.path; 20640 if (field === 'locale' && isString(payload.state.value)) { 20641 composer.locale.value = payload.state.value; 20642 } 20643 else if (field === 'fallbackLocale' && 20644 (isString(payload.state.value) || 20645 isArray(payload.state.value) || 20646 isObject(payload.state.value))) { 20647 composer.fallbackLocale.value = payload.state.value; 20648 }
20649 else if (field === 'inheritLocale' && isBoolean(payload.state.value)) { 20650 composer.inheritLocale = payload.state.value; 20651 } 20652 } 20653 } 20654 20655 // supports compatibility for legacy vue-i18n APIs 20656 function defineMixin(vuei18n, composer, i18n) { 20657 return { 20658 beforeCreate() { 20659 const instance = vue.getCurrentInstance(); 20660 /* istanbul ignore if */ 20661 if (!instance) { 20662 throw createI18nError(22 /* UNEXPECTED_ERROR */); 20663 } 20664 const options = this.$options; 20665 if (options.i18n) { 20666 const optionsI18n = options.i18n; 20667 if (options.__i18n) { 20668 optionsI18n.__i18n = options.__i18n; 20669 } 20670 optionsI18n.__meta = options[DEVTOOLS_META] 20671 ? { [DEVTOOLS_META]: options[DEVTOOLS_META] } 20672 : {}; 20673 optionsI18n.__root = composer; 20674 if (this === this.$root) { 20675 this.$i18n = mergeToRoot(vuei18n, optionsI18n); 20676 } 20677 else { 20678 this.$i18n = createVueI18n(optionsI18n); 20679 } 20680 } 20681 else if (options.__i18n) { 20682 if (this === this.$root) { 20683 this.$i18n = mergeToRoot(vuei18n, options); 20684 } 20685 else { 20686 this.$i18n = createVueI18n({ 20687 __i18n: options.__i18n, 20688 __meta: options[DEVTOOLS_META] 20689 ? { [DEVTOOLS_META]: options[DEVTOOLS_META] } 20690 : {}, 20691 __root: composer 20692 }); 20693 } 20694 } 20695 else { 20696 // set global 20697 this.$i18n = vuei18n; 20698 } 20699 vuei18n.__onComponentInstanceCreated(this.$i18n); 20700 i18n.__setInstance(instance, this.$i18n); 20701 // defines vue-i18n legacy APIs 20702 this.$t = (...args) => this.$i18n.t(...args); 20703 this.$rt = (...args) => this.$i18n.rt(...args); 20704 this.$tc = (...args) => this.$i18n.tc(...args); 20705 this.$te = (key, locale) => this.$i18n.te(key, locale); 20706 this.$d = (...args) => this.$i18n.d(...args); 20707 this.$n = (...args) => this.$i18n.n(...args); 20708 this.$tm = (key) => this.$i18n.tm(key); 20709 }, 20710 mounted() { 20711 /* istanbul ignore if */ 20712 { 20713 this.$el.__VUE_I18N__ = this.$i18n.__composer; 20714 const emitter = (this.__v_emitter = createEmitter()); 20715 const _vueI18n = this.$i18n; 20716 _vueI18n.__enableEmitter && _vueI18n.__enableEmitter(emitter); 20717 emitter.on('*', addTimelineEvent); 20718 } 20719 }, 20720 beforeUnmount() { 20721 const instance = vue.getCurrentInstance(); 20722 /* istanbul ignore if */ 20723 if (!instance) { 20724 throw createI18nError(22 /* UNEXPECTED_ERROR */); 20725 } 20726 /* istanbul ignore if */ 20727 { 20728 if (this.__v_emitter) { 20729 this.__v_emitter.off('*', addTimelineEvent); 20730 delete this.__v_emitter; 20731 } 20732 const _vueI18n = this.$i18n; 20733 _vueI18n.__disableEmitter && _vueI18n.__disableEmitter(); 20734 delete this.$el.__VUE_I18N__; 20735 } 20736 delete this.$t; 20737 delete this.$rt; 20738 delete this.$tc; 20739 delete this.$te; 20740 delete this.$d; 20741 delete this.$n; 20742 delete this.$tm; 20743 i18n.__deleteInstance(instance); 20744 delete this.$i18n; 20745 } 20746 }; 20747 } 20748 function mergeToRoot(root, options) { 20749 root.locale = options.locale || root.locale; 20750 root.fallbackLocale = options.fallbackLocale || root.fallbackLocale; 20751 root.missing = options.missing || root.missing; 20752 root.silentTranslationWarn = 20753 options.silentTranslationWarn || root.silentFallbackWarn; 20754 root.silentFallbackWarn = 20755 options.silentFallbackWarn || root.silentFallbackWarn; 20756 root.formatFallbackMessages = 20757 options.formatFallbackMessages || root.formatFallbackMessages; 20758 root.postTranslation = options.postTranslation || root.postTranslation; 20759 root.warnHtmlInMessage = options.warnHtmlInMessage || root.warnHtmlInMessage; 20760 root.escapeParameterHtml = 20761 options.escapeParameterHtml || root.escapeParameterHtml; 20762 root.sync = options.sync || root.sync; 20763 root.__composer[SetPluralRulesSymbol](options.pluralizationRules || root.pluralizationRules); 20764 /* eslint-disable @typescript-eslint/no-explicit-any */ 20765 if (options[DEVTOOLS_META] &&
20766 !root.__composer[DevToolsMetaSymbol]) { 20767 root.__composer[DevToolsMetaSymbol] = { 20768 [DEVTOOLS_META]: options[DEVTOOLS_META] 20769 }; 20770 } 20771 /* eslint-enable @typescript-eslint/no-explicit-any */ 20772 const messages = getLocaleMessages(root.locale, { 20773 messages: options.messages, 20774 __i18n: options.__i18n 20775 }); 20776 Object.keys(messages).forEach(locale => root.mergeLocaleMessage(locale, messages[locale])); 20777 if (options.datetimeFormats) { 20778 Object.keys(options.datetimeFormats).forEach(locale => root.mergeDateTimeFormat(locale, options.datetimeFormats[locale])); 20779 } 20780 if (options.numberFormats) { 20781 Object.keys(options.numberFormats).forEach(locale => root.mergeNumberFormat(locale, options.numberFormats[locale])); 20782 } 20783 return root; 20784 } 20785 20786 /** 20787 * Vue I18n factory 20788 * 20789 * @param options - An options, see the {@link I18nOptions} 20790 * 20791 * @returns {@link I18n} instance 20792 * 20793 * @remarks 20794 * If you use Legacy API mode, you need toto specify {@link VueI18nOptions} and `legacy: true` option. 20795 * 20796 * If you use composition API mode, you need to specify {@link ComposerOptions}. 20797 * 20798 * @VueI18nSee [Getting Started](../../guide/) 20799 * @VueI18nSee [Composition API](../../guide/advanced/composition) 20800 * 20801 * @example 20802 * case: for Legacy API 20803 * ```js 20804 * import { createApp } from 'vue' 20805 * import { createI18n } from 'vue-i18n' 20806 * 20807 * // call with I18n option 20808 * const i18n = createI18n({ 20809 * locale: 'ja', 20810 * messages: { 20811 * en: { ... }, 20812 * ja: { ... } 20813 * } 20814 * }) 20815 * 20816 * const App = { 20817 * // ... 20818 * } 20819 * 20820 * const app = createApp(App) 20821 * 20822 * // install! 20823 * app.use(i18n) 20824 * app.mount('#app') 20825 * ``` 20826 * 20827 * @example 20828 * case: for composition API 20829 * ```js 20830 * import { createApp } from 'vue' 20831 * import { createI18n, useI18n } from 'vue-i18n' 20832 * 20833 * // call with I18n option 20834 * const i18n = createI18n({ 20835 * legacy: false, // you must specify 'legacy: false' option 20836 * locale: 'ja', 20837 * messages: { 20838 * en: { ... }, 20839 * ja: { ... } 20840 * } 20841 * }) 20842 * 20843 * const App = { 20844 * setup() { 20845 * // ... 20846 * const { t } = useI18n({ ... }) 20847 * return { ... , t } 20848 * } 20849 * } 20850 * 20851 * const app = createApp(App) 20852 * 20853 * // install! 20854 * app.use(i18n) 20855 * app.mount('#app') 20856 * ``` 20857 * 20858 * @VueI18nGeneral 20859 */ 20860 function createI18n(options = {}) { 20861 // prettier-ignore 20862 const __legacyMode = isBoolean(options.legacy) 20863 ? options.legacy 20864 : true; 20865 const __globalInjection = !!options.globalInjection; 20866 const __instances = new Map(); 20867 // prettier-ignore 20868 const __global = __legacyMode 20869 ? createVueI18n(options) 20870 : createComposer(options); 20871 const symbol = makeSymbol('vue-i18n' ); 20872 const i18n = { 20873 // mode 20874 get mode() { 20875 // prettier-ignore 20876 return __legacyMode 20877 ? 'legacy' 20878 : 'composition' 20879 ; 20880 }, 20881 // install plugin 20882 async install(app, ...options) { 20883 { 20884 app.__VUE_I18N__ = i18n; 20885 } 20886 // setup global provider 20887 app.__VUE_I18N_SYMBOL__ = symbol; 20888 app.provide(app.__VUE_I18N_SYMBOL__, i18n); 20889 // global method and properties injection for Composition API 20890 if (!__legacyMode && __globalInjection) { 20891 injectGlobalFields(app, i18n.global); 20892 } 20893 // install built-in components and directive 20894 { 20895 apply(app, i18n, ...options); 20896 } 20897 // setup mixin for Legacy API 20898 if (__legacyMode) { 20899 app.mixin(defineMixin(__global, __global.__composer, i18n)); 20900 } 20901 // setup vue-devtools plugin 20902 { 20903 const ret = await enableDevTools(app, i18n); 20904 if (!ret) { 20905 throw createI18nError(21 /* CANNOT_SETUP_VUE_DEVTOOLS_PLUGIN */); 20906 } 20907 const emitter = createEmitter(); 20908 if (__legacyMode) { 20909 const _vueI18n = __global; 20910 _vueI18n.__enableEmitter && _vueI18n.__enableEmitter(emitter); 20911 } 20912 else { 20913 // eslint-disable-next-line @typescript-eslint/no-explicit-any 20914 const _composer = __global; 20915 _composer[EnableEmitter] && _composer[EnableEmitter](emitter); 20916 } 20917 emitter.on('*', addTimelineEvent); 20918 } 20919 }, 20920 // global accessor 20921 get global() { 20922 return __global; 20923 }, 20924 // @internal 20925 __instances, 20926 // @internal 20927 __getInstance(component) { 20928 return __instances.get(component) || null; 20929 }, 20930 // @internal 20931 __setInstance(component, instance) { 20932 __instances.set(component, instance); 20933 }, 20934 // @internal 20935 __deleteInstance(component) { 20936 __instances.delete(component); 20937 } 20938 }; 20939 return i18n; 20940 } 20941 /** 20942 * Use Composition API for Vue I18n 20943 * 20944 * @param options - An options, see {@link UseI18nOptions} 20945 * 20946 * @returns {@link Composer} instance 20947 * 20948 * @remarks 20949 * This function is mainly used by `setup`. 20950 * 20951 * If options are specified, Composer instance is created for each component and
20951you can be localized on the component. 20952 * 20953 * If options are not specified, you can be localized using the global Composer. 20954 * 20955 * @example 20956 * case: Component resource base localization 20957 * ```html 20958 * <template> 20959 * <form> 20960 * <label>{{ t('language') }}</label> 20961 * <select v-model="locale"> 20962 * <option value="en">en</option> 20963 * <option value="ja">ja</option> 20964 * </select> 20965 * </form> 20966 * <p>message: {{ t('hello') }}</p> 20967 * </template> 20968 * 20969 * <script> 20970 * import { useI18n } from 'vue-i18n' 20971 * 20972 * export default { 20973 * setup() { 20974 * const { t, locale } = useI18n({ 20975 * locale: 'ja', 20976 * messages: { 20977 * en: { ... }, 20978 * ja: { ... } 20979 * } 20980 * }) 20981 * // Something to do ... 20982 * 20983 * return { ..., t, locale } 20984 * } 20985 * } 20986 * </script> 20987 * ``` 20988 * 20989 * @VueI18nComposition 20990 */ 20991 function useI18n(options = {}) { 20992 const instance = vue.getCurrentInstance(); 20993 if (instance == null) { 20994 throw createI18nError(16 /* MUST_BE_CALL_SETUP_TOP */); 20995 } 20996 if (!instance.appContext.app.__VUE_I18N_SYMBOL__) { 20997 throw createI18nError(17 /* NOT_INSLALLED */); 20998 } 20999 const i18n = vue.inject(instance.appContext.app.__VUE_I18N_SYMBOL__); 21000 /* istanbul ignore if */ 21001 if (!i18n) { 21002 throw createI18nError(22 /* UNEXPECTED_ERROR */); 21003 } 21004 // prettier-ignore 21005 const global = i18n.mode === 'composition' 21006 ? i18n.global 21007 : i18n.global.__composer; 21008 // prettier-ignore 21009 const scope = isEmptyObject(options) 21010 ? ('__i18n' in instance.type) 21011 ? 'local' 21012 : 'global' 21013 : !options.useScope 21014 ? 'local' 21015 : options.useScope; 21016 if (scope === 'global') { 21017 let messages = isObject(options.messages) ? options.messages : {}; 21018 if ('__i18nGlobal' in instance.type) { 21019 messages = getLocaleMessages(global.locale.value, { 21020 messages, 21021 __i18n: instance.type.__i18nGlobal 21022 }); 21023 } 21024 // merge locale messages 21025 const locales = Object.keys(messages); 21026 if (locales.length) { 21027 locales.forEach(locale => { 21028 global.mergeLocaleMessage(locale, messages[locale]); 21029 }); 21030 } 21031 // merge datetime formats 21032 if (isObject(options.datetimeFormats)) { 21033 const locales = Object.keys(options.datetimeFormats); 21034 if (locales.length) { 21035 locales.forEach(locale => { 21036 global.mergeDateTimeFormat(locale, options.datetimeFormats[locale]); 21037 }); 21038 } 21039 } 21040 // merge number formats 21041 if (isObject(options.numberFormats)) { 21042 const locales = Object.keys(options.numberFormats); 21043 if (locales.length) { 21044 locales.forEach(locale => { 21045 global.mergeNumberFormat(locale, options.numberFormats[locale]); 21046 }); 21047 } 21048 } 21049 return global; 21050 } 21051 if (scope === 'parent') { 21052 let composer = getComposer(i18n, instance); 21053 if (composer == null) { 21054 { 21055 warn(getWarnMessage(12 /* NOT_FOUND_PARENT_SCOPE */)); 21056 } 21057 composer = global; 21058 } 21059 return composer; 21060 } 21061 // scope 'local' case 21062 if (i18n.mode === 'legacy') { 21063 throw createI18nError(18 /* NOT_AVAILABLE_IN_LEGACY_MODE */); 21064 } 21065 const i18nInternal = i18n; 21066 let composer = i18nInternal.__getInstance(instance); 21067 if (composer == null) { 21068 const type = instance.type; 21069 const composerOptions = { 21070 ...options 21071 }; 21072 if (type.__i18n) { 21073 composerOptions.__i18n = type.__i18n; 21074 } 21075 if (type[DEVTOOLS_META]) { 21076 composerOptions.__meta = composerOptions.__meta || {}; 21077 composerOptions.__meta[DEVTOOLS_META] = type[DEVTOOLS_META]; 21078 } 21079 if (global) { 21080 composerOptions.__root = global; 21081 } 21082 composer = createComposer(composerOptions); 21083 setupLifeCycle(i18nInternal, instance, composer); 21084 i18nInternal.__setInstance(instance, composer); 21085 } 21086 return composer; 21087 } 21088 function getComposer(i18n, target) { 21089 let composer = null; 21090 const root = target.root; 21091 let current = target.parent; 21092 while (current != null) { 21093 const i18nInternal = i18n; 21094 if (i18n.mode === 'composition') { 21095 composer = i18nInternal.__getInstance(current); 21096 } 21097 else { 21098 const vueI18n = i18nInternal.__getInstance(current); 21099 if (vueI18n != null) { 21100 composer = vueI18n 21101 .__composer; 21102 } 21103 } 21104 if (composer != null) { 21105 break; 21106 } 21107 if (root === current) { 21108 break; 21109 } 21110 current = current.parent; 21111 } 21112 return composer; 21113 } 21114 function setupLifeCycle(i18n, target, composer) { 21115 let emitter = null; 21116 vue.onMounted(() => { 21117 // inject composer instance to DOM for intlify-devtools 21118 if (target.vnode.el) { 21119 target.vnode.el.__VUE_I18N__ = composer; 21120 emitter = createEmitter(); 21121 // eslint-disable-next-line @typescript-eslint/no-explicit-any 21122 const _composer = composer; 21123 _composer[EnableEmitter] && _composer[EnableEmitter](emitter); 21124 emitter.on('*', addTimelineEvent); 21125 } 21126 }, target); 21127 vue.onUnmounted(() => { 21128 // remove composer instance from DOM for intlify-devtools 21129 if (target.vnode.el && 21130 target.vnode.el.__VUE_I18N__) { 21131 emitter && emitter.off('*', addTimelineEvent); 21132 // eslint-disable-next-line @typescript-eslint/no-explicit-any 21133 const _composer = composer; 21134 _composer[DisableEmitter] && _composer[DisableEmitter](); 21135 delete target.vnode.el.__VUE_I18N__; 21136 } 21137 i18n.__deleteInstance(target); 21138 }, target); 21139 } 21140 const globalExportProps = [ 21141 'locale', 21142 'fallbackLocale', 21143 'availableLocales' 21144 ]; 21145 const globalExportMethods = ['t', 'rt', 'd', 'n', 'tm']; 21146 function injectGlobalFields(app, composer) { 21147 const i18n = Object.create(null); 21148 globalExportProps.forEach(prop => { 21149 const desc = Object.getOwnPropertyDescriptor(composer, prop); 21150 if (!desc) { 21151 throw createI18nError(22 /* UNEXPECTED_ERROR */); 21152 } 21153 const wrap = vue.isRef(desc.value) // check computed props 21154 ? { 21155 get() { 21156 return desc.value.value; 21157 }, 21158 // eslint-disable-next-line @typescript-eslint/no-explicit-any 21159 set(val) { 21160 desc.value.value = val; 21161 } 21162 } 21163 : { 21164 get() { 21165 return desc.get && desc.get(); 21166 } 21167 }; 21168 Object.defineProperty(i18n, prop, wrap); 21169 }); 21170 app.config.globalProperties.$i18n = i18n; 21171 globalExportMethods.forEach(method => { 21172 const desc = Object.getOwnPropertyDescriptor(composer, method); 21173 if (!desc) { 21174 throw createI18nError(22 /* UNEXPECTED_ERROR */); 21175 } 21176 Object.defineProperty(app.config.globalProperties, `$${method}`, desc); 21177 }); 21178 } 21179 21180 // register message compiler at vue-i18n 21181 registerMessageCompiler(compileToFunction); 21182 // NOTE: experimental !! 21183 { 21184 const target = getGlobalThis(); 21185 target.__INTLIFY__ = true; 21186 setDevToolsHook(target.__INTLIFY_DEVTOOLS_GLOBAL_HOOK__); 21187 } 21188 { 21189 initDev(); 21190 } 21191 21192 exports.DatetimeFormat = DatetimeFormat; 21193 exports.NumberFormat = NumberFormat; 21194 exports.Translation = Translation; 21195 exports.VERSION = VERSION; 21196 exports.createI18n = createI18n; 21197 exports.useI18n = useI18n; 21198 exports.vTDirective = vTDirective; 21199 21200 Object.defineProperty(exports, '__esModule', { value: true }); 21201 21202 return exports; 21203 21204}({}, Vue)); 21205 21206const { createApp } = Vue; 21207 21208createApp({ 21209 data() { 21210 return { 21211 isLoading: true, 21212 newUser: false, 21213 language: "en", 21214 messages: null, 21215 options: null, 21216 jurisdiction: "", 21217 jurisdictions: "", 21218 userType: "", 21219 userTypeText: "Individual Investor", 21220 userTypes: null, 21221 languageType: "", 21222 languageTypes: null, 21223 multiLingual: false, 21224 checkBoxValidation: false, 21225 preset: null, 21226 isAuthorMode: false 21227 }; 21228 }, 21229 mounted() { 21230 21231 // fetch data on init 21232 this.fetchData(); 21233 }, 21234 methods: { 21235 async fetchData() { 21236 21237 const urlOptions = `/content/dam/imemea/web/json/countryLanguageAttestation.json`; 21238 let result = await (await fetch(urlOptions)).json(); 21239 this.options = result; 21240 21241 const urlTranslations = `/content/dam/imemea/web/json/translation.json`; 21242 let messages = await (await fetch(urlTranslations)).json(); 21243 this.messages = messages; 21244 21245 //user has not visited site before. 21246 this.newUser = true; 21247 21248 //get langauge from url for global landing page. 21249 let currentLocation = new URL(window.location); 21250 let langPath = currentLocation.pathname; 21251 21252 let lastSlashIndex = langPath.lastIndexOf('/'); 21253 let lastDotIndex = langPath.lastIndexOf('.'); 21254 21255 if (document.getElementById('language')) { 21256 this.language = document.getElementById('language').textContent; 21257 } 21258 else if (langPath.length > 1) { 21259 this.language = langPath.substring(lastSlashIndex + 1, lastDotIndex); 21260 } else { 21261 this.language = 'en' 21262 } 21263 this.language = 'en'; 21264 21265 //check for settings in head and update - for new users who land on internal page. 21266 let currentConsentPaths = getLocalStorage("consentPath"); 21267 var clientTypeRole = $("#role").html(); 21268 setIMNAClientTypeCookie(clientTypeRole); 21269 if(currentConsentPaths){ 21270 setTimeout(() => { 21271 21272 21273 if (currentConsentPaths.includes('https://') && currentConsentPaths.includes('/investments/')) { 21274 var splitStr = currentConsentPaths.split('https://'); 21275 var url = new URL('https://' + splitStr[1]); 21276 var pathName = url.pathname; 21277 var investmentIndex = pathName.indexOf('/investments/'); 21278 if (investmentIndex !== -1) { 21279 currentConsentPaths = "/"+pathName.substring(investmentIndex+'/investments/'.length); // Outputs: /us/en/individual 21280 } 21281 }else { 21282 if(currentConsentPaths.includes('https://')){ 21283 var consentUrlPath = new URL(currentConsentPaths); 21284 currentConsentPaths = consentUrlPath.pathname; 21285 } 21286 21287 } 21288 21289 this.jurisdiction = currentConsentPaths.split("/")[1]; 21290 this.updateUserTypes(this.jurisdiction); 21291 this.userType = this.userTypeCheck(currentConsentPaths.split("/")[3]); 21292 this.language = currentConsentPaths.split("/")[2]; 21293 this.checkLanguages(); 21294 }, 100); 21295 21296 setTimeout(() => { 21297 //need to set userType again as removed in jurisdiction watcher. 21298 this.userType = this.userTypeCheck(currentConsentPaths.split("/")[3]); 21299 this.userTypeText = this.options[this.jurisdiction]['role'][this.userType].metadata.title; 21300 this.setUserTypeTextGrammar(this.userTypeText); 21301 this.checkLanguages(); 21302 document.getElementById("listbox-jurisdiction").setAttribute("aria-activedescendant", "j-" + this.jurisdiction); 21303 document.getElementById("listbox-usertype").setAttribute("aria-activedescendant", "u-" + this.userType); 21304 this.isLoading = false;
21305 21306 }, 125); 21307 21308 }else{ 21309 if (document.getElementById('country')) { 21310 if($('#publishRunMode').html() === 'true'){ 21311 var geoDetectedObject = {}; 21312 let currentDate = new Date().getDate(); 21313 const lifeLine = ["2332e6917a9fd8", "d57f3bbb66ea92", "e282d0546e785b", "b7c0ef2accfb32", "e35720d5bd9109", "f2d1534456ac08", "b4ed04d20566a6", "4b350e2dc2bfdf", "0cdde413b910a0", "3eb8620a77bb1a"]; 21314 let todaysLifeLine = lifeLine[currentDate % lifeLine.length]; 21315 //geoDetectedObject = await (await fetch("https://ipinfo.io/json?token=" + todaysLifeLine)).json(); 21316 var geoDetectedCountry = "NA";//this.getCountry(geoDetectedObject); 21317 } 21318 21319 setTimeout(() => { 21320 if($('#publishRunMode').html() === 'true') { 21321 if (this.options.hasOwnProperty(geoDetectedCountry)) { 21322 this.jurisdiction = geoDetectedCountry; 21323 } else { 21324 this.jurisdiction = document.getElementById('country').textContent; 21325 } 21326 } 21327 if($('#authorRunMode').html() === 'true'){ 21328 this.jurisdiction = document.getElementById('country').textContent; 21329 } 21330 this.updateUserTypes(this.jurisdiction); 21331 this.userType = this.userTypeCheck(document.getElementById('role').textContent); 21332 this.language = document.getElementById('language').textContent; 21333 this.checkLanguages(); 21334 }, 100); 21335 21336 setTimeout(() => { 21337 //need to set userType again as removed in jurisdiction watcher. 21338 this.userType = this.userTypeCheck(document.getElementById('role').textContent); 21339 this.userTypeText = this.options[this.jurisdiction]['role'][this.userType].metadata.title; 21340 this.setUserTypeTextGrammar(this.userTypeText); 21341 this.checkLanguages(); 21342 document.getElementById("listbox-jurisdiction").setAttribute("aria-activedescendant", "j-" + this.jurisdiction); 21343 document.getElementById("listbox-usertype").setAttribute("aria-activedescendant", "u-" + this.userType); 21344 this.isLoading = false; 21345 21346 }, 125); 21347 } 21348 } 21349 21350 this.isLoading = false; 21351 this.newUser = false; 21352 this.isAuthorMode = $('#authorRunMode').html() == 'true'; 21353 21354 }, 21355 getCountry: function(geoDetectedObject){ 21356 if(geoDetectedObject.country !== undefined && geoDetectedObject.country !== null && geoDetectedObject.country !== '') { 21357 if (geoDetectedObject.country.toLowerCase() === 'gb') { 21358 return 'uk'; 21359 } 21360 return geoDetectedObject.country.toLowerCase(); 21361 } 21362 return ''; 21363 }, 21364 setUserTypeTextGrammar: function(userTypeText){ 21365 const vowels = ["A","E","I","O","U"]; 21366 if (!(vowels.includes(userTypeText.at(0))) && this.language === 'en') { 21367 document.getElementsByClassName('selector-form-section')[1].getElementsByTagName('label')[0].setAttribute('data-i18n-en', 'and I am a'); 21368 document.getElementsByClassName('selector-form-section')[1].getElementsByTagName('label')[0].innerText = "and I am a"; 21369 document.getElementsByClassName('roleBasedClass')[0].setAttribute('data-i18n-en', 'I am a'); 21370 document.getElementsByClassName('roleBasedClass')[0].innerText = "I am a"; 21371 } 21372 if (vowels.includes(userTypeText.at(0)) && this.language === 'en') { 21373 document.getElementsByClassName('selector-form-section')[1].getElementsByTagName('label')[0].setAttribute('data-i18n-en', 'and I am an'); 21374 document.getElementsByClassName('selector-form-section')[1].getElementsByTagName('label')[0].innerText = "and I am an"; 21375 document.getElementsByClassName('roleBasedClass')[0].setAttribute('data-i18n-en', 'I am an'); 21376 document.getElementsByClassName('roleBasedClass')[0].innerText = "I am an"; 21377 } 21378 }, 21379 userTypeCheck: function(user) { 21380 if(this.jurisdiction == 'hk'){ 21381 if(user == 'individual') { 21382 return 'individual-or-intermediary'; 21383 } 21384 } 21385 if(this.jurisdiction == 'sg'){ 21386 if(user == 'individual') { 21387 return 'individual-private'; 21388 } 21389 if(user == 'institutional') { 21390 return 'institutional-investor-or-accredited'; 21391 } 21392 } 21393 return user; 21394 }, 21395 initLang: function () { 21396 const stored = localStorage.getItem("globalLang"); 21397 if (stored === null) { 21398 console.log("Nothing stored; default to `true`"); 21399 return "en"; 21400 } else { 21401 console.log("Using stored value " + stored); 21402 return stored; 21403 } 21404 }, 21405 i18nStringBuilder: function (section, index) { 21406 // console.log("s", section) 21407 // console.log("i", index) 21408 // return this.$t(`${section}.${index}`); 21409 }, 21410 21411 getFlag(countryCode) { 21412 return `/content/dam/imemea/web/images/flags/${countryCode}.svg`; 21413 }, 21414 21415 updateUserTypes(selectedCountry) { 21416 // reset usertype 21417 if (!this.newUser) { 21418 this.userType = ""; 21419 } 21420 21421 document.getElementById("listbox-usertype").setAttribute("aria-activedescendant", ""); 21422 let availableOptions = document.getElementById("listbox-usertype").querySelectorAll('li'); 21423 availableOptions.forEach((el) => { 21424 el.setAttribute("aria-selected", false) 21425 }) 21426 // populate userTypes 21427 this.userTypes = this.options[selectedCountry].role; 21428 21429 if (selectedCountry === "be") { 21430 this.language = "en"; 21431 } 21432 else { 21433 21434 //get language(s) for selected country 21435 let a = Object.values(this.userTypes); 21436 21437 //get all langs for selected jurisdiction 21438 let countryLangs = []; 21439 a.forEach(obj => { 21440 countryLangs.push(Object.keys(obj.language) ) 21441 }) 21442 countryLangs = countryLangs.flat() 21443 //if selected jurisdiction does not have current language use first available 21444 if ( !countryLangs.includes(this.language) ) { 21445 let firstLanguage = Object.keys(a[0].language)[0]; 21446 this.language = firstLanguage; 21447 } 21448 21449 } 21450 21451 }, 21452 21453 updateLanguages(availableLanguages) { 21454 this.languageTypes = availableLanguages; 21455 }, 21456 formSubmit(e) { 21457 e.preventDefault(); 21458 let redirectUrl = this.options[this.jurisdiction]["role"][this.userType]["language"][this.language]["path"]; 21459 if ($('#authorRunMode').html() === 'true') { 21460 if (!redirectUrl.includes('/content/imemea')) { 21461 redirectUrl = '/content/imemea' + redirectUrl; 21462 } 21463 } 21464 let currentPageUrl = window.location.pathname; 21465 let queryParams = window.location.search; 21466 var newRedirectPagePath; 21467 21468 var currentRole = $("#role").html(); 21469 if (currentRole && $('#publishRunMode').html() === 'true'){ 21470 let toBeTranslatedStringArray = currentPageUrl.split('/'); 21471 let toBeTranslatedStringArticle = toBeTranslatedStringArray[toBeTranslatedStringArray.length - 1]; 21472 21473 for (let i = 5 ; (toBeTranslatedStringArray.length > 6) ? (i <= toBeTranslatedStringArray.length - 2) : (i <= toBeTranslatedStringArray.length - 1); i++) { 21474 let toBeTranslatedString = toBeTranslatedStringArray[i]; 21475 if (toBeTranslatedString !== undefined) { 21476 let requiredTranslationObject = Object.values(this.messages).find(obj => { 21477 return obj[toBeTranslatedStringArray[3]] === toBeTranslatedString.replace('.html', ''); 21478 }); 21479 if (requiredTranslationObject !== undefined) { 21480 if (toBeTranslatedString.includes('.html')) { 21481 toBeTranslatedString = requiredTranslationObject[this.language] + '.html'; 21482 } else { 21483 toBeTranslatedString = requiredTranslationObject[this.language] 21484 } 21485 toBeTranslatedStringArray[i] = toBeTranslatedString; 21486 } 21487 } 21488 } 21489 21490 if(toBeTranslatedStringArray.length > 5 && toBeTranslatedStringArticle !== undefined) { 21491 if (document.getElementById('languageSpecificUrls') !== null) { 21492 var languageUrlArray = []; 21493 languageUrlArray = document.getElementById('languageSpecificUrls').textContent.trim().split(','); 21494 var languageUrlObject = {}; 21495 languageUrlObject.en = languageUrlArray[0] !== "undefined" ? languageUrlArray[0] : ''; 21496 languageUrlObject.fr = languageUrlArray[1] !== "undefined" ? languageUrlArray[1] : ''; 21497 languageUrlObject.de = languageUrlArray[2] !== "undefined" ? languageUrlArray[2] : ''; 21498 languageUrlObject.es = languageUrlArray[3] !== "undefined" ? languageUrlArray[3] : ''; 21499 languageUrlObject.it = languageUrlArray[4] !== "undefined" ? languageUrlArray[4] : ''; 21500 21501 if (languageUrlObject[this.language] !== '' && languageUrlObject[this.language] !== undefined) { 21502 if (toBeTranslatedStringArticle.includes('.html')) { 21503 toBeTranslatedStringArticle = languageUrlObject[this.language] + '.html'; 21504 } else { 21505 toBeTranslatedStringArticle = languageUrlObject[this.language]; 21506 } 21507 toBeTranslatedStringArray[toBeTranslatedStringArray.length - 1] = toBeTranslatedStringArticle; 21508 } 21509 } 21510 } 21511 let newPage = ""; 21512 if (toBeTranslatedStringArray.length !== 4) { 21513 newPage = '/' + toBeTranslatedStringArray.toString().replaceAll(',', '/').split('/' + currentRole + '/')[1]; 21514 } else { 21515 newPage = toBeTranslatedStringArray.toString().replaceAll(',', '/').split(currentRole)[1]; 21516 } 21517 let newRolePath = redirectUrl.split(".html")[0]; 21518 if (queryParams !== '') { 21519 newRedirectPagePath = newRolePath + newPage + queryParams; 21520 } else { 21521 newRedirectPagePath = newRolePath + newPage; 21522 } 21523 } 21524 if (currentRole && $('#authorRunMode').html() === 'true') { 21525 let newPage = currentPageUrl.split(currentRole)[1]; 21526 let newRolePath = redirectUrl.split(".html")[0]; 21527 newRedirectPagePath = newRolePath + newPage; 21528 } 21529 // --START-- changes for jurisdiction selecton model from header 21530 let currentConsentPaths = getLocalStorage('consentPath') 21531 let currentConsentPathsArray = getLocalStorage('consentPathArray'); 21532 if (currentConsentPaths) { 21533 var isCurrentPathPresent = false;
21534 var pagePathToAdd = redirectUrl.split(".html")[0]; 21535 if (pagePathToAdd.includes(currentConsentPaths)) { 21536 isCurrentPathPresent = true; 21537 } 21538 21539 if (!isCurrentPathPresent) { 21540 currentConsentPaths = redirectUrl.split(".html")[0]; 21541 } 21542 } else { 21543 currentConsentPaths = redirectUrl.split(".html")[0]; 21544 } 21545 if (!currentConsentPathsArray) { 21546 currentConsentPathsArray = ''; 21547 } 21548 setLocalStorage("consentPath", currentConsentPaths); 21549 if (currentConsentPathsArray.indexOf(currentConsentPaths) === -1) { 21550 currentConsentPathsArray += currentConsentPaths + ','; 21551 } 21552 setLocalStorage("consentPathArray", currentConsentPathsArray); 21553 // --END-- changes for jurisdiction selecton model from header 21554 var currentPath = window.location.pathname; 21555 if (currentPath.includes('/investments/')) { 21556 var domain1 = 'https://imaem.uat.bnymellon.com'; 21557 var domain2 = 'https://im.bnymellon.com'; 21558 if(newRedirectPagePath){ 21559 if (!newRedirectPagePath.includes('/investments/') && ((!newRedirectPagePath.includes(domain1)) && (!newRedirectPagePath.includes(domain2)))) { 21560 if (newRedirectPagePath.includes('https://')) { 21561 var parts = newRedirectPagePath.split('/'); 21562 var domain = parts[2]; 21563 var path = parts.slice(3).join('/'); 21564 newRedirectPagePath = 'https://' + domain + '/investments/' + path; 21565 } else { 21566 newRedirectPagePath = '/investments' + newRedirectPagePath; 21567 } 21568 } 21569 } 21570 } 21571 /*handling domain redirect */ 21572 if(newRedirectPagePath){ 21573 if(newRedirectPagePath.includes('/us/en/')){ 21574 if(currentRole){ 21575 if((newRedirectPagePath.includes("https://"))){ 21576 if(!newRedirectPagePath.includes("undefined")){ 21577 location.href = newRedirectPagePath; 21578 }else{ 21579 location.href = redirectUrl; 21580 } 21581 } 21582 } 21583 } 21584 } 21585 if (newRedirectPagePath) { 21586 $.get(newRedirectPagePath) 21587 .done(function () { 21588 location.href = newRedirectPagePath; 21589 }) 21590 .fail(function () { 21591 location.href = redirectUrl; 21592 }); 21593 } else { 21594 location.href = redirectUrl; 21595 } 21596 }, 21597 closeDropDown(which, opener, e) { 21598 e.stopPropagation(); 21599 e.preventDefault(); 21600 21601 let activeSelectOpener = this.$refs[opener]; 21602 activeSelectOpener.classList.toggle('active'); 21603 21604 let activeSelect = this.$refs[which]; 21605 activeSelect.setAttribute( 21606 'aria-expanded', 21607 'false' 21608 ); 21609 }, 21610 showDropDown(which, listitems, e) { 21611 21612 let countryDropdown = document.getElementById('country-select'); 21613 let roleDropdown = document.getElementById('usertype-select'); 21614 console.log("Selected dropdown html ID = "+e.target.parentElement.id); 21615 if (e.target.parentElement.id == 'country-select'){ 21616 console.log("Country dropdown selected"); 21617 document.getElementById("usertype-select").classList.remove('active'); 21618 document.getElementById("listbox-usertype").setAttribute( 21619 'aria-expanded', 21620 'false' 21621 ); 21622 if(document.getElementById("language-select") != null){ 21623 document.getElementById("language-select").classList.remove('active'); 21624 document.getElementById("listbox-language").setAttribute( 21625 'aria-expanded', 21626 'false' 21627 ); 21628 } 21629 } 21630 else if(e.target.parentElement.id == 'usertype-select'){ 21631 document.getElementById("country-select").classList.remove('active'); 21632 document.getElementById("listbox-jurisdiction").setAttribute( 21633 'aria-expanded', 21634 'false' 21635 ); 21636 if(document.getElementById("language-select") != null){ 21637 document.getElementById("language-select").classList.remove('active'); 21638 document.getElementById("listbox-language").setAttribute( 21639 'aria-expanded', 21640 'false' 21641 ); 21642 } 21643 } 21644 else if(e.target.parentElement.id == 'language-select'){ 21645 document.getElementById("country-select").classList.remove('active'); 21646 document.getElementById("usertype-select").classList.remove('active'); 21647 document.getElementById("listbox-jurisdiction").setAttribute( 21648 'aria-expanded', 21649 'false' 21650 ); 21651 document.getElementById("listbox-usertype").setAttribute( 21652 'aria-expanded', 21653 'false' 21654 ); 21655 21656 } 21657 else{ 21658 console.log("No Dropdown selected"); 21659 } 21660 21661 21662 e.stopPropagation(); 21663 e.preventDefault(); 21664 let activeSelectOpener = e.target; 21665 activeSelectOpener.parentElement.classList.toggle("active"); 21666 21667 let activeSelect = this.$refs[which]; 21668 let selectedOption = activeSelect.getAttribute("aria-activedescendant"); 21669 let availableOptions = this.$refs[listitems]; 21670 21671 // update Aria 21672 let state = activeSelect.getAttribute("aria-expanded");
21673 if (state === "false") { 21674 activeSelect.setAttribute("aria-expanded", "true"); 21675 } else { 21676 activeSelect.setAttribute("aria-expanded", "false"); 21677 } 21678 21679 if (!selectedOption) { 21680 availableOptions[0].focus(); 21681 availableOptions[0].setAttribute("aria-selected", true); 21682 activeSelect.setAttribute("aria-activedescendant", availableOptions[0].id); 21683 availableOptions[0].scrollIntoView({ 21684 behavior: "smooth", 21685 block: "center", 21686 inline: "nearest", 21687 }); 21688 } else { 21689 availableOptions.forEach((el, index) => { 21690 if (el.id === selectedOption) { 21691 availableOptions[index].focus(); 21692 el.scrollIntoView({ 21693 behavior: "smooth", 21694 block: "center", 21695 inline: "nearest", 21696 }); 21697 } 21698 }); 21699 } 21700 }, 21701 21702 listItemDown(options, element) { 21703 let availableOptions = this.$refs[options]; 21704 let nextSibling = element.nextElementSibling; 21705 21706 if (nextSibling) { 21707 nextSibling.focus(); 21708 nextSibling.scrollIntoView({ 21709 behavior: "smooth", 21710 block: "center", 21711 inline: "nearest", 21712 }); 21713 } else { 21714 availableOptions[0].focus(); 21715 } 21716 }, 21717 21718 listItemUp(options, element) { 21719 let availableOptions = this.$refs[options]; 21720 let prevSibling = element.previousElementSibling; 21721 if (prevSibling) { 21722 prevSibling.scrollIntoView({ 21723 behavior: "smooth", 21724 block: "center", 21725 inline: "nearest", 21726 }); 21727 prevSibling.focus(); 21728 } else { 21729 availableOptions[0].focus(); 21730 } 21731 }, 21732 21733 listItemKeyEvent(options, e) { 21734 e.preventDefault(); 21735 let key = e.key || e.code; 21736 21737 switch (key) { 21738 case "ArrowDown": 21739 this.listItemDown(options, e.target); 21740 break; 21741 case "ArrowUp": 21742 this.listItemUp(options, e.target); 21743 break; 21744 default: 21745 break; 21746 } 21747 }, 21748 21749 setCountry(value, controller, event) { 21750 // unset previous selected 21751 this.ariaUnsetSelected(event.target.parentNode.children); 21752 21753 //update selected 21754 event.target.ariaSelected = "true"; 21755 document.getElementById(controller).setAttribute("aria-activedescendant", event.target.id); 21756 document.getElementById("country-select").classList.remove("active"); 21757 // set jurisdiction & get userTypes 21758 this.jurisdiction = value; 21759 this.updateUserTypes(this.jurisdiction); 21760 }, 21761 21762 setUserType(value, controller, text, event) { 21763 event.stopPropagation(); 21764 // unset previous selected 21765 this.ariaUnsetSelected(event.target.parentNode.children); 21766 21767 //update selected 21768 event.target.ariaSelected = "true"; 21769 document.getElementById(controller).setAttribute("aria-activedescendant", event.target.id); 21770 // document.getElementById(controller).classList.remove('active'); 21771 document.getElementById("usertype-select").classList.toggle("active"); 21772 21773 //set userType 21774 this.userType = value; 21775 this.userTypeText = text; 21776 21777 //reset language options. 21778 this.languageTypes = null; 21779 this.multiLingual = false; 21780 this.checkBoxValidation = false; 21781 this.checkLanguages(); 21782 21783 document.getElementById("listbox-usertype").setAttribute('aria-expanded','false'); 21784 21785 const vowels = ["A","E","I","O","U"]; 21786 if(vowels.includes(this.userTypeText.at(0)) && this.language === 'en'){ 21787 document.getElementsByClassName('selector-form-section')[1].getElementsByTagName('label')[0].setAttribute('data-i18n-en','and I am an'); 21788 document.getElementsByClassName('selector-form-section')[1].getElementsByTagName('label')[0].innerText="and I am an"; 21789 document.getElementsByClassName('roleBasedClass')[0].setAttribute('data-i18n-en','I am an'); 21790 document.getElementsByClassName('roleBasedClass')[0].innerText="I am an"; 21791 } 21792 if(!(vowels.includes(this.userTypeText.at(0))) && this.language === 'en'){ 21793 document.getElementsByClassName('selector-form-section')[1].getElementsByTagName('label')[0].setAttribute('data-i18n-en','and I am a'); 21794 document.getElementsByClassName('selector-form-section')[1].getElementsByTagName('label')[0].innerText="and I am a"; 21795 document.getElementsByClassName('roleBasedClass')[0].setAttribute('data-i18n-en','I am a'); 21796 document.getElementsByClassName('roleBasedClass')[0].innerText="I am a"; 21797 } 21798 21799 }, 21800 checkLanguages() { 21801 let languageCount = 0; 21802 // let firstElement = Object.keys(this.userTypes)[0]; 21803 let availableLanguages = this.options[this.jurisdiction].role[this.userType].language; 21804
21805 Object.keys(availableLanguages).forEach(function () { 21806 languageCount++; 21807 }); 21808 21809 if (languageCount > 1) { 21810 //show language dropdown (ex HK/China) 21811 this.multiLingual = true; 21812 this.updateLanguages(availableLanguages); 21813 } else { 21814 // update language - some usertype may have different language from jurisdiction default - eg Belgium Intermediary 21815 this.language = Object.keys(availableLanguages)[0]; 21816 } 21817 }, 21818 setLanguage(value, controller, event) { 21819 // unset previous selected 21820 this.ariaUnsetSelected(event.target.parentNode.children); 21821 21822 //update selected 21823 event.target.ariaSelected = "true"; 21824 document.getElementById(controller).setAttribute("aria-activedescendant", event.target.id); 21825 document.getElementById(controller).classList.remove("active"); 21826 21827 // language 21828 this.languageType = value; 21829 this.language = value; 21830 }, 21831 ariaUnsetSelected(items) { 21832 Array.from(items).forEach((element) => { 21833 element.setAttribute("aria-selected", "false"); 21834 }); 21835 }, 21836 }, 21837 watch: { 21838 jurisdiction(newJurisdiction, oldJurisdiction) { 21839 if (newJurisdiction === oldJurisdiction) return; 21840 21841 if (newJurisdiction !== oldJurisdiction) { 21842 if (!this.newUser) { 21843 this.userType = ""; 21844 } 21845 21846 this.languageTypes = ""; 21847 this.multiLingual = false; 21848 this.checkBoxValidation = false; 21849 } 21850 this.updateUserTypes(newJurisdiction); 21851 21852 if (document.getElementById("country-select")) { 21853 document.getElementById("country-select").classList.remove("active"); 21854 document.getElementById("listbox-jurisdiction").setAttribute("aria-expanded", "false"); 21855 } 21856 }, 21857 languageType() { 21858 document.getElementById("language-select").classList.toggle("active"); 21859 }, 21860 }, 21861}) 21862 .directive("i18n", { 21863 mounted: (el, binding) => { 21864 let instance = binding.instance; // ref to component 21865 let selectedLanguage = binding.instance.language; 21866 let phrase = el.dataset.i18nEn; 21867 // safeguard - remove any extra spaces 21868 phrase = phrase.replace(/\s+/g, " ").trim(); 21869 if (instance.messages[phrase]) { 21870 el.textContent = instance.messages[phrase][selectedLanguage]; 21871 } else { 21872 el.textContent = "** Translation N/A **"; //instance.messages[phrase].en; 21873 } 21874 }, 21875 updated: (el, binding) => { 21876 let instance = binding.instance; // ref to component 21877 let selectedLanguage = binding.instance.language; 21878 let phrase = el.dataset.i18nEn; 21879 // safeguard - remove any extra spaces 21880 phrase = phrase.replace(/\s+/g, " ").trim(); 21881 21882 if (instance.messages[phrase]) { 21883 el.textContent = instance.messages[phrase][selectedLanguage]; 21884 } else { 21885 el.textContent = "** Translation N/A **"; 21886 //el.textContent = instance.messages[phrase].en; 21887 } 21888 }, 21889 }) 21890 .mount("#im-jurisdiction"); 21891 21892window.onclick = function (event) { 21893 document.getElementById("country-select").classList.remove('active'); 21894 document.getElementById("listbox-jurisdiction").setAttribute( 21895 'aria-expanded', 21896 'false' 21897 ); 21898 21899 document.getElementById("usertype-select").classList.remove('active'); 21900 document.getElementById("listbox-usertype").setAttribute( 21901 'aria-expanded', 21902 'false' 21903 ); 21904 21905 if (document.getElementById("language-select") != null) { 21906 document.getElementById("language-select").classList.remove('active'); 21907 document.getElementById("listbox-language").setAttribute( 21908 'aria-expanded', 21909 'false' 21910 ); 21911 } 21912} 21913var locaStoreTtl = 15552000000; 21914 21915function setLocalStorage(key, value) { 21916 var now = new Date(); 21917 var item = {value: value, expiry: now.getTime() + locaStoreTtl,} 21918 localStorage.setItem(key, JSON.stringify(item)) 21919} 21920
21921function getLocalStorage(key) { 21922 var now = new Date(); 21923 let value = localStorage.getItem(key); 21924 if (value) { 21925 try { 21926 var valueObj = JSON.parse(value); 21927 if (typeof (valueObj.value) != "undefined" && typeof (valueObj.expiry) != "undefined") { 21928 var expTime = valueObj.expiry; 21929 if (expTime > now.getTime()) { 21930 return valueObj.value; 21931 } else { 21932 return false; 21933 } 21934 } else { 21935 return false; 21936 } 21937 } catch (e) { 21938 if (typeof (value) != "string") { 21939 return value; 21940 } else { 21941 return false; 21942 } 21943 } 21944 } else { 21945 return false; 21946 } 21947} 21948 21949function getClientTypeCookie(name) { 21950 var nameEQ = name + "="; 21951 var ca = document.cookie.split(';'); 21952 for(var i=0;i < ca.length;i++) { 21953 var c = ca[i]; 21954 while (c.charAt(0)==' ') c = c.substring(1,c.length); 21955 if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); 21956 } 21957 return null; 21958} 21959 21960function setIMNAClientTypeCookie(val) { 21961 var cookieExpiryTime = "Sun, 01 Jan 2073 12:00:00 UTC"; 21962 var cookieVal = val; 21963 document.cookie = "ect=" + cookieVal + "; expires="+ cookieExpiryTime + "; path=/"; 21964 document.cookie = "clientType=" + cookieVal + "; expires="+ cookieExpiryTime + "; path=/"; 21965} 21966 21967 21968 21969// app; 21970// app.mount('#im-jurisdiction');
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.