├── README.md ├── build.js ├── index.js └── package.json /README.md: -------------------------------------------------------------------------------- 1 | # vue-template-compiler 2 | 3 | > This package is auto-generated. For pull requests please see [src/entries/web-compiler.js](https://github.com/vuejs/vue/blob/dev/src/entries/web-compiler.js). 4 | 5 | This package can be used to pre-compile Vue 2.0 templates into render functions to avoid runtime-compilation overhead and CSP restrictions. You will only need it if you are writing build tools with very specific needs. In most cases you should be using [vue-loader](https://github.com/vuejs/vue-loader) or [vueify](https://github.com/vuejs/vueify) instead, both of which use this package internally. 6 | 7 | ## Installation 8 | 9 | ``` bash 10 | npm install vue-template-compiler 11 | ``` 12 | 13 | ``` js 14 | const compiler = require('vue-template-compiler') 15 | ``` 16 | 17 | ## API 18 | 19 | ### compiler.compile(template, [options]) 20 | 21 | Compiles a template string and returns compiled JavaScript code. The returned result is an object of the following format: 22 | 23 | ``` js 24 | { 25 | render: string, // main render function code 26 | staticRenderFns: Array, // render code for static sub trees, if any 27 | errors: Array // template syntax errors, if any 28 | } 29 | ``` 30 | 31 | Note the returned function code uses `with` and thus cannot be used in strict mode code. 32 | 33 | #### Options 34 | 35 | It's possible to hook into the compilation process to support custom template features. **However, beware that by injecting custom compile-time modules, your templates will not work with other build tools built on standard built-in modules, e.g `vue-loader` and `vueify`.** 36 | 37 | The optional `options` object can contain the following: 38 | 39 | - `modules` 40 | 41 | An array of compiler modules. For details on compiler modules, refer to its [type definition](https://github.com/vuejs/vue/blob/dev/flow/compiler.js#L35) and the [built-in modules](https://github.com/vuejs/vue/tree/dev/src/platforms/web/compiler/modules). 42 | 43 | - `directives` 44 | 45 | An object where the key is the directive name and the value is a function that transforms an template AST node. For example: 46 | 47 | ``` js 48 | compiler.compile('
', { 49 | directives: { 50 | test (node, directiveMeta) { 51 | // transform node based on directiveMeta 52 | } 53 | }) 54 | ``` 55 | 56 | By default, a compile-time directive will extract the directive and the directive will not be present at runtime. If you want the directive to also be handled by a runtime definition, return `true` in the transform function. 57 | 58 | Refer to the implementation of some [built-in compile-time directives](https://github.com/vuejs/vue/tree/dev/src/platforms/web/compiler/directives). 59 | 60 | - `preserveWhitespace` 61 | 62 | Defaults to `true`. This means the compiled render function respects all the whitespaces between HTML tags. If set to `false`, all whitespaces between tags will be ignored. This can result in slightly better performance but may affect layout for inline elements. 63 | 64 | --- 65 | 66 | ### compiler.compileToFunctions(template) 67 | 68 | Similar to `compiler.compile`, but directly returns instantiated functions: 69 | 70 | ``` js 71 | { 72 | render: Function, 73 | staticRenderFns: Array 74 | } 75 | ``` 76 | 77 | This is only useful at runtime with pre-configured builds, so it doesn't accept any compile-time options. In addition, this method uses `new Function()` so it is not CSP-compliant. 78 | 79 | --- 80 | 81 | ### compiler.parseComponent(file, [options]) 82 | 83 | Parse a SFC (single-file component, or `*.vue` file) into a [descriptor](https://github.com/vuejs/vue/blob/dev/flow/compiler.js#L137). This is used in SFC build tools like `vue-loader` and `vueify`. 84 | 85 | #### Options 86 | 87 | - `pad`: with `{ pad: true }`, the extracted content for each block will be padded with newlines to ensure that the line numbers align with the original file. This is useful when you are piping the extracted content into other pre-processors, as you will get correct line numbers if there are any syntax errors. 88 | -------------------------------------------------------------------------------- /build.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { value: true }); 4 | 5 | function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } 6 | 7 | var he = require('he'); 8 | var deindent = _interopDefault(require('de-indent')); 9 | 10 | /* */ 11 | 12 | /** 13 | * Convert a value to a string that is actually rendered. 14 | */ 15 | function _toString (val) { 16 | return val == null 17 | ? '' 18 | : typeof val === 'object' 19 | ? JSON.stringify(val, null, 2) 20 | : String(val) 21 | } 22 | 23 | /** 24 | * Convert a input value to a number for persistence. 25 | * If the conversion fails, return original string. 26 | */ 27 | function toNumber (val) { 28 | var n = parseFloat(val, 10); 29 | return (n || n === 0) ? n : val 30 | } 31 | 32 | /** 33 | * Make a map and return a function for checking if a key 34 | * is in that map. 35 | */ 36 | function makeMap ( 37 | str, 38 | expectsLowerCase 39 | ) { 40 | var map = Object.create(null); 41 | var list = str.split(','); 42 | for (var i = 0; i < list.length; i++) { 43 | map[list[i]] = true; 44 | } 45 | return expectsLowerCase 46 | ? function (val) { return map[val.toLowerCase()]; } 47 | : function (val) { return map[val]; } 48 | } 49 | 50 | /** 51 | * Check if a tag is a built-in tag. 52 | */ 53 | var isBuiltInTag = makeMap('slot,component', true); 54 | 55 | /** 56 | * Remove an item from an array 57 | */ 58 | function remove (arr, item) { 59 | if (arr.length) { 60 | var index = arr.indexOf(item); 61 | if (index > -1) { 62 | return arr.splice(index, 1) 63 | } 64 | } 65 | } 66 | 67 | /** 68 | * Check whether the object has the property. 69 | */ 70 | var hasOwnProperty = Object.prototype.hasOwnProperty; 71 | function hasOwn (obj, key) { 72 | return hasOwnProperty.call(obj, key) 73 | } 74 | 75 | /** 76 | * Check if value is primitive 77 | */ 78 | function isPrimitive (value) { 79 | return typeof value === 'string' || typeof value === 'number' 80 | } 81 | 82 | /** 83 | * Create a cached version of a pure function. 84 | */ 85 | function cached (fn) { 86 | var cache = Object.create(null); 87 | return function cachedFn (str) { 88 | var hit = cache[str]; 89 | return hit || (cache[str] = fn(str)) 90 | } 91 | } 92 | 93 | /** 94 | * Camelize a hyphen-delmited string. 95 | */ 96 | var camelizeRE = /-(\w)/g; 97 | var camelize = cached(function (str) { 98 | return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; }) 99 | }); 100 | 101 | /** 102 | * Capitalize a string. 103 | */ 104 | var capitalize = cached(function (str) { 105 | return str.charAt(0).toUpperCase() + str.slice(1) 106 | }); 107 | 108 | /** 109 | * Hyphenate a camelCase string. 110 | */ 111 | var hyphenateRE = /([^-])([A-Z])/g; 112 | var hyphenate = cached(function (str) { 113 | return str 114 | .replace(hyphenateRE, '$1-$2') 115 | .replace(hyphenateRE, '$1-$2') 116 | .toLowerCase() 117 | }); 118 | 119 | /** 120 | * Simple bind, faster than native 121 | */ 122 | function bind (fn, ctx) { 123 | function boundFn (a) { 124 | var l = arguments.length; 125 | return l 126 | ? l > 1 127 | ? fn.apply(ctx, arguments) 128 | : fn.call(ctx, a) 129 | : fn.call(ctx) 130 | } 131 | // record original fn length 132 | boundFn._length = fn.length; 133 | return boundFn 134 | } 135 | 136 | /** 137 | * Convert an Array-like object to a real Array. 138 | */ 139 | function toArray (list, start) { 140 | start = start || 0; 141 | var i = list.length - start; 142 | var ret = new Array(i); 143 | while (i--) { 144 | ret[i] = list[i + start]; 145 | } 146 | return ret 147 | } 148 | 149 | /** 150 | * Mix properties into target object. 151 | */ 152 | function extend (to, _from) { 153 | for (var key in _from) { 154 | to[key] = _from[key]; 155 | } 156 | return to 157 | } 158 | 159 | /** 160 | * Quick object check - this is primarily used to tell 161 | * Objects from primitive values when we know the value 162 | * is a JSON-compliant type. 163 | */ 164 | function isObject (obj) { 165 | return obj !== null && typeof obj === 'object' 166 | } 167 | 168 | /** 169 | * Strict object type check. Only returns true 170 | * for plain JavaScript objects. 171 | */ 172 | var toString = Object.prototype.toString; 173 | var OBJECT_STRING = '[object Object]'; 174 | function isPlainObject (obj) { 175 | return toString.call(obj) === OBJECT_STRING 176 | } 177 | 178 | /** 179 | * Merge an Array of Objects into a single Object. 180 | */ 181 | function toObject (arr) { 182 | var res = {}; 183 | for (var i = 0; i < arr.length; i++) { 184 | if (arr[i]) { 185 | extend(res, arr[i]); 186 | } 187 | } 188 | return res 189 | } 190 | 191 | /** 192 | * Perform no operation. 193 | */ 194 | function noop () {} 195 | 196 | /** 197 | * Always return false. 198 | */ 199 | var no = function () { return false; }; 200 | 201 | /** 202 | * Generate a static keys string from compiler modules. 203 | */ 204 | function genStaticKeys (modules) { 205 | return modules.reduce(function (keys, m) { 206 | return keys.concat(m.staticKeys || []) 207 | }, []).join(',') 208 | } 209 | 210 | /** 211 | * Check if two values are loosely equal - that is, 212 | * if they are plain objects, do they have the same shape? 213 | */ 214 | function looseEqual (a, b) { 215 | /* eslint-disable eqeqeq */ 216 | return a == b || ( 217 | isObject(a) && isObject(b) 218 | ? JSON.stringify(a) === JSON.stringify(b) 219 | : false 220 | ) 221 | /* eslint-enable eqeqeq */ 222 | } 223 | 224 | function looseIndexOf (arr, val) { 225 | for (var i = 0; i < arr.length; i++) { 226 | if (looseEqual(arr[i], val)) { return i } 227 | } 228 | return -1 229 | } 230 | 231 | /* */ 232 | /* globals MutationObserver */ 233 | 234 | // can we use __proto__? 235 | var hasProto = '__proto__' in {}; 236 | 237 | // Browser environment sniffing 238 | var inBrowser = 239 | typeof window !== 'undefined' && 240 | Object.prototype.toString.call(window) !== '[object Object]'; 241 | 242 | var UA = inBrowser && window.navigator.userAgent.toLowerCase(); 243 | var isIE = UA && /msie|trident/.test(UA); 244 | var isIE9 = UA && UA.indexOf('msie 9.0') > 0; 245 | var isEdge = UA && UA.indexOf('edge/') > 0; 246 | var isAndroid = UA && UA.indexOf('android') > 0; 247 | var isIOS = UA && /iphone|ipad|ipod|ios/.test(UA); 248 | 249 | // detect devtools 250 | var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__; 251 | 252 | /* istanbul ignore next */ 253 | function isNative (Ctor) { 254 | return /native code/.test(Ctor.toString()) 255 | } 256 | 257 | /** 258 | * Defer a task to execute it asynchronously. 259 | */ 260 | var nextTick = (function () { 261 | var callbacks = []; 262 | var pending = false; 263 | var timerFunc; 264 | 265 | function nextTickHandler () { 266 | pending = false; 267 | var copies = callbacks.slice(0); 268 | callbacks.length = 0; 269 | for (var i = 0; i < copies.length; i++) { 270 | copies[i](); 271 | } 272 | } 273 | 274 | // the nextTick behavior leverages the microtask queue, which can be accessed 275 | // via either native Promise.then or MutationObserver. 276 | // MutationObserver has wider support, however it is seriously bugged in 277 | // UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It 278 | // completely stops working after triggering a few times... so, if native 279 | // Promise is available, we will use it: 280 | /* istanbul ignore if */ 281 | if (typeof Promise !== 'undefined' && isNative(Promise)) { 282 | var p = Promise.resolve(); 283 | timerFunc = function () { 284 | p.then(nextTickHandler); 285 | // in problematic UIWebViews, Promise.then doesn't completely break, but 286 | // it can get stuck in a weird state where callbacks are pushed into the 287 | // microtask queue but the queue isn't being flushed, until the browser 288 | // needs to do some other work, e.g. handle a timer. Therefore we can 289 | // "force" the microtask queue to be flushed by adding an empty timer. 290 | if (isIOS) { setTimeout(noop); } 291 | }; 292 | } else if (typeof MutationObserver !== 'undefined' && ( 293 | isNative(MutationObserver) || 294 | // PhantomJS and iOS 7.x 295 | MutationObserver.toString() === '[object MutationObserverConstructor]' 296 | )) { 297 | // use MutationObserver where native Promise is not available, 298 | // e.g. PhantomJS IE11, iOS7, Android 4.4 299 | var counter = 1; 300 | var observer = new MutationObserver(nextTickHandler); 301 | var textNode = document.createTextNode(String(counter)); 302 | observer.observe(textNode, { 303 | characterData: true 304 | }); 305 | timerFunc = function () { 306 | counter = (counter + 1) % 2; 307 | textNode.data = String(counter); 308 | }; 309 | } else { 310 | // fallback to setTimeout 311 | /* istanbul ignore next */ 312 | timerFunc = function () { 313 | setTimeout(nextTickHandler, 0); 314 | }; 315 | } 316 | 317 | return function queueNextTick (cb, ctx) { 318 | var func = ctx 319 | ? function () { cb.call(ctx); } 320 | : cb; 321 | callbacks.push(func); 322 | if (!pending) { 323 | pending = true; 324 | timerFunc(); 325 | } 326 | } 327 | })(); 328 | 329 | var _Set; 330 | /* istanbul ignore if */ 331 | if (typeof Set !== 'undefined' && isNative(Set)) { 332 | // use native Set when available. 333 | _Set = Set; 334 | } else { 335 | // a non-standard Set polyfill that only works with primitive keys. 336 | _Set = (function () { 337 | function Set () { 338 | this.set = Object.create(null); 339 | } 340 | Set.prototype.has = function has (key) { 341 | return this.set[key] !== undefined 342 | }; 343 | Set.prototype.add = function add (key) { 344 | this.set[key] = 1; 345 | }; 346 | Set.prototype.clear = function clear () { 347 | this.set = Object.create(null); 348 | }; 349 | 350 | return Set; 351 | }()); 352 | } 353 | 354 | /* */ 355 | 356 | var config = { 357 | /** 358 | * Option merge strategies (used in core/util/options) 359 | */ 360 | optionMergeStrategies: Object.create(null), 361 | 362 | /** 363 | * Whether to suppress warnings. 364 | */ 365 | silent: false, 366 | 367 | /** 368 | * Whether to enable devtools 369 | */ 370 | devtools: process.env.NODE_ENV !== 'production', 371 | 372 | /** 373 | * Error handler for watcher errors 374 | */ 375 | errorHandler: null, 376 | 377 | /** 378 | * Ignore certain custom elements 379 | */ 380 | ignoredElements: null, 381 | 382 | /** 383 | * Custom user key aliases for v-on 384 | */ 385 | keyCodes: Object.create(null), 386 | 387 | /** 388 | * Check if a tag is reserved so that it cannot be registered as a 389 | * component. This is platform-dependent and may be overwritten. 390 | */ 391 | isReservedTag: no, 392 | 393 | /** 394 | * Check if a tag is an unknown element. 395 | * Platform-dependent. 396 | */ 397 | isUnknownElement: no, 398 | 399 | /** 400 | * Get the namespace of an element 401 | */ 402 | getTagNamespace: noop, 403 | 404 | /** 405 | * Check if an attribute must be bound using property, e.g. value 406 | * Platform-dependent. 407 | */ 408 | mustUseProp: no, 409 | 410 | /** 411 | * List of asset types that a component can own. 412 | */ 413 | _assetTypes: [ 414 | 'component', 415 | 'directive', 416 | 'filter' 417 | ], 418 | 419 | /** 420 | * List of lifecycle hooks. 421 | */ 422 | _lifecycleHooks: [ 423 | 'beforeCreate', 424 | 'created', 425 | 'beforeMount', 426 | 'mounted', 427 | 'beforeUpdate', 428 | 'updated', 429 | 'beforeDestroy', 430 | 'destroyed', 431 | 'activated', 432 | 'deactivated' 433 | ], 434 | 435 | /** 436 | * Max circular updates allowed in a scheduler flush cycle. 437 | */ 438 | _maxUpdateCount: 100, 439 | 440 | /** 441 | * Server rendering? 442 | */ 443 | _isServer: process.env.VUE_ENV === 'server' 444 | }; 445 | 446 | var warn = noop; 447 | var formatComponentName; 448 | 449 | if (process.env.NODE_ENV !== 'production') { 450 | var hasConsole = typeof console !== 'undefined'; 451 | 452 | warn = function (msg, vm) { 453 | if (hasConsole && (!config.silent)) { 454 | console.error("[Vue warn]: " + msg + " " + ( 455 | vm ? formatLocation(formatComponentName(vm)) : '' 456 | )); 457 | } 458 | }; 459 | 460 | formatComponentName = function (vm) { 461 | if (vm.$root === vm) { 462 | return 'root instance' 463 | } 464 | var name = vm._isVue 465 | ? vm.$options.name || vm.$options._componentTag 466 | : vm.name; 467 | return ( 468 | (name ? ("component <" + name + ">") : "anonymous component") + 469 | (vm._isVue && vm.$options.__file ? (" at " + (vm.$options.__file)) : '') 470 | ) 471 | }; 472 | 473 | var formatLocation = function (str) { 474 | if (str === 'anonymous component') { 475 | str += " - use the \"name\" option for better debugging messages."; 476 | } 477 | return ("\n(found in " + str + ")") 478 | }; 479 | } 480 | 481 | /* */ 482 | 483 | /** 484 | * Check if a string starts with $ or _ 485 | */ 486 | function isReserved (str) { 487 | var c = (str + '').charCodeAt(0); 488 | return c === 0x24 || c === 0x5F 489 | } 490 | 491 | /** 492 | * Define a property. 493 | */ 494 | function def (obj, key, val, enumerable) { 495 | Object.defineProperty(obj, key, { 496 | value: val, 497 | enumerable: !!enumerable, 498 | writable: true, 499 | configurable: true 500 | }); 501 | } 502 | 503 | /** 504 | * Parse simple path. 505 | */ 506 | var bailRE = /[^\w.$]/; 507 | function parsePath (path) { 508 | if (bailRE.test(path)) { 509 | return 510 | } else { 511 | var segments = path.split('.'); 512 | return function (obj) { 513 | for (var i = 0; i < segments.length; i++) { 514 | if (!obj) { return } 515 | obj = obj[segments[i]]; 516 | } 517 | return obj 518 | } 519 | } 520 | } 521 | 522 | /* not type checking this file because flow doesn't play well with Proxy */ 523 | 524 | var hasProxy; 525 | var proxyHandlers; 526 | var initProxy; 527 | 528 | if (process.env.NODE_ENV !== 'production') { 529 | var allowedGlobals = makeMap( 530 | 'Infinity,undefined,NaN,isFinite,isNaN,' + 531 | 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' + 532 | 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' + 533 | 'require' // for Webpack/Browserify 534 | ); 535 | 536 | hasProxy = 537 | typeof Proxy !== 'undefined' && 538 | Proxy.toString().match(/native code/); 539 | 540 | proxyHandlers = { 541 | has: function has (target, key) { 542 | var has = key in target; 543 | var isAllowed = allowedGlobals(key) || key.charAt(0) === '_'; 544 | if (!has && !isAllowed) { 545 | warn( 546 | "Property or method \"" + key + "\" is not defined on the instance but " + 547 | "referenced during render. Make sure to declare reactive data " + 548 | "properties in the data option.", 549 | target 550 | ); 551 | } 552 | return has || !isAllowed 553 | } 554 | }; 555 | 556 | initProxy = function initProxy (vm) { 557 | if (hasProxy) { 558 | vm._renderProxy = new Proxy(vm, proxyHandlers); 559 | } else { 560 | vm._renderProxy = vm; 561 | } 562 | }; 563 | } 564 | 565 | /* */ 566 | 567 | 568 | var uid$2 = 0; 569 | 570 | /** 571 | * A dep is an observable that can have multiple 572 | * directives subscribing to it. 573 | */ 574 | var Dep = function Dep () { 575 | this.id = uid$2++; 576 | this.subs = []; 577 | }; 578 | 579 | Dep.prototype.addSub = function addSub (sub) { 580 | this.subs.push(sub); 581 | }; 582 | 583 | Dep.prototype.removeSub = function removeSub (sub) { 584 | remove(this.subs, sub); 585 | }; 586 | 587 | Dep.prototype.depend = function depend () { 588 | if (Dep.target) { 589 | Dep.target.addDep(this); 590 | } 591 | }; 592 | 593 | Dep.prototype.notify = function notify () { 594 | // stablize the subscriber list first 595 | var subs = this.subs.slice(); 596 | for (var i = 0, l = subs.length; i < l; i++) { 597 | subs[i].update(); 598 | } 599 | }; 600 | 601 | // the current target watcher being evaluated. 602 | // this is globally unique because there could be only one 603 | // watcher being evaluated at any time. 604 | Dep.target = null; 605 | var targetStack = []; 606 | 607 | function pushTarget (_target) { 608 | if (Dep.target) { targetStack.push(Dep.target); } 609 | Dep.target = _target; 610 | } 611 | 612 | function popTarget () { 613 | Dep.target = targetStack.pop(); 614 | } 615 | 616 | /* */ 617 | 618 | 619 | var queue = []; 620 | var has$1 = {}; 621 | var circular = {}; 622 | var waiting = false; 623 | var flushing = false; 624 | var index = 0; 625 | 626 | /** 627 | * Reset the scheduler's state. 628 | */ 629 | function resetSchedulerState () { 630 | queue.length = 0; 631 | has$1 = {}; 632 | if (process.env.NODE_ENV !== 'production') { 633 | circular = {}; 634 | } 635 | waiting = flushing = false; 636 | } 637 | 638 | /** 639 | * Flush both queues and run the watchers. 640 | */ 641 | function flushSchedulerQueue () { 642 | flushing = true; 643 | 644 | // Sort queue before flush. 645 | // This ensures that: 646 | // 1. Components are updated from parent to child. (because parent is always 647 | // created before the child) 648 | // 2. A component's user watchers are run before its render watcher (because 649 | // user watchers are created before the render watcher) 650 | // 3. If a component is destroyed during a parent component's watcher run, 651 | // its watchers can be skipped. 652 | queue.sort(function (a, b) { return a.id - b.id; }); 653 | 654 | // do not cache length because more watchers might be pushed 655 | // as we run existing watchers 656 | for (index = 0; index < queue.length; index++) { 657 | var watcher = queue[index]; 658 | var id = watcher.id; 659 | has$1[id] = null; 660 | watcher.run(); 661 | // in dev build, check and stop circular updates. 662 | if (process.env.NODE_ENV !== 'production' && has$1[id] != null) { 663 | circular[id] = (circular[id] || 0) + 1; 664 | if (circular[id] > config._maxUpdateCount) { 665 | warn( 666 | 'You may have an infinite update loop ' + ( 667 | watcher.user 668 | ? ("in watcher with expression \"" + (watcher.expression) + "\"") 669 | : "in a component render function." 670 | ), 671 | watcher.vm 672 | ); 673 | break 674 | } 675 | } 676 | } 677 | 678 | // devtool hook 679 | /* istanbul ignore if */ 680 | if (devtools && config.devtools) { 681 | devtools.emit('flush'); 682 | } 683 | 684 | resetSchedulerState(); 685 | } 686 | 687 | /** 688 | * Push a watcher into the watcher queue. 689 | * Jobs with duplicate IDs will be skipped unless it's 690 | * pushed when the queue is being flushed. 691 | */ 692 | function queueWatcher (watcher) { 693 | var id = watcher.id; 694 | if (has$1[id] == null) { 695 | has$1[id] = true; 696 | if (!flushing) { 697 | queue.push(watcher); 698 | } else { 699 | // if already flushing, splice the watcher based on its id 700 | // if already past its id, it will be run next immediately. 701 | var i = queue.length - 1; 702 | while (i >= 0 && queue[i].id > watcher.id) { 703 | i--; 704 | } 705 | queue.splice(Math.max(i, index) + 1, 0, watcher); 706 | } 707 | // queue the flush 708 | if (!waiting) { 709 | waiting = true; 710 | nextTick(flushSchedulerQueue); 711 | } 712 | } 713 | } 714 | 715 | /* */ 716 | 717 | var uid$1 = 0; 718 | 719 | /** 720 | * A watcher parses an expression, collects dependencies, 721 | * and fires callback when the expression value changes. 722 | * This is used for both the $watch() api and directives. 723 | */ 724 | var Watcher = function Watcher ( 725 | vm, 726 | expOrFn, 727 | cb, 728 | options 729 | ) { 730 | if ( options === void 0 ) options = {}; 731 | 732 | this.vm = vm; 733 | vm._watchers.push(this); 734 | // options 735 | this.deep = !!options.deep; 736 | this.user = !!options.user; 737 | this.lazy = !!options.lazy; 738 | this.sync = !!options.sync; 739 | this.expression = expOrFn.toString(); 740 | this.cb = cb; 741 | this.id = ++uid$1; // uid for batching 742 | this.active = true; 743 | this.dirty = this.lazy; // for lazy watchers 744 | this.deps = []; 745 | this.newDeps = []; 746 | this.depIds = new _Set(); 747 | this.newDepIds = new _Set(); 748 | // parse expression for getter 749 | if (typeof expOrFn === 'function') { 750 | this.getter = expOrFn; 751 | } else { 752 | this.getter = parsePath(expOrFn); 753 | if (!this.getter) { 754 | this.getter = function () {}; 755 | process.env.NODE_ENV !== 'production' && warn( 756 | "Failed watching path: \"" + expOrFn + "\" " + 757 | 'Watcher only accepts simple dot-delimited paths. ' + 758 | 'For full control, use a function instead.', 759 | vm 760 | ); 761 | } 762 | } 763 | this.value = this.lazy 764 | ? undefined 765 | : this.get(); 766 | }; 767 | 768 | /** 769 | * Evaluate the getter, and re-collect dependencies. 770 | */ 771 | Watcher.prototype.get = function get () { 772 | pushTarget(this); 773 | var value = this.getter.call(this.vm, this.vm); 774 | // "touch" every property so they are all tracked as 775 | // dependencies for deep watching 776 | if (this.deep) { 777 | traverse(value); 778 | } 779 | popTarget(); 780 | this.cleanupDeps(); 781 | return value 782 | }; 783 | 784 | /** 785 | * Add a dependency to this directive. 786 | */ 787 | Watcher.prototype.addDep = function addDep (dep) { 788 | var id = dep.id; 789 | if (!this.newDepIds.has(id)) { 790 | this.newDepIds.add(id); 791 | this.newDeps.push(dep); 792 | if (!this.depIds.has(id)) { 793 | dep.addSub(this); 794 | } 795 | } 796 | }; 797 | 798 | /** 799 | * Clean up for dependency collection. 800 | */ 801 | Watcher.prototype.cleanupDeps = function cleanupDeps () { 802 | var this$1 = this; 803 | 804 | var i = this.deps.length; 805 | while (i--) { 806 | var dep = this$1.deps[i]; 807 | if (!this$1.newDepIds.has(dep.id)) { 808 | dep.removeSub(this$1); 809 | } 810 | } 811 | var tmp = this.depIds; 812 | this.depIds = this.newDepIds; 813 | this.newDepIds = tmp; 814 | this.newDepIds.clear(); 815 | tmp = this.deps; 816 | this.deps = this.newDeps; 817 | this.newDeps = tmp; 818 | this.newDeps.length = 0; 819 | }; 820 | 821 | /** 822 | * Subscriber interface. 823 | * Will be called when a dependency changes. 824 | */ 825 | Watcher.prototype.update = function update () { 826 | /* istanbul ignore else */ 827 | if (this.lazy) { 828 | this.dirty = true; 829 | } else if (this.sync) { 830 | this.run(); 831 | } else { 832 | queueWatcher(this); 833 | } 834 | }; 835 | 836 | /** 837 | * Scheduler job interface. 838 | * Will be called by the scheduler. 839 | */ 840 | Watcher.prototype.run = function run () { 841 | if (this.active) { 842 | var value = this.get(); 843 | if ( 844 | value !== this.value || 845 | // Deep watchers and watchers on Object/Arrays should fire even 846 | // when the value is the same, because the value may 847 | // have mutated. 848 | isObject(value) || 849 | this.deep 850 | ) { 851 | // set new value 852 | var oldValue = this.value; 853 | this.value = value; 854 | if (this.user) { 855 | try { 856 | this.cb.call(this.vm, value, oldValue); 857 | } catch (e) { 858 | process.env.NODE_ENV !== 'production' && warn( 859 | ("Error in watcher \"" + (this.expression) + "\""), 860 | this.vm 861 | ); 862 | /* istanbul ignore else */ 863 | if (config.errorHandler) { 864 | config.errorHandler.call(null, e, this.vm); 865 | } else { 866 | throw e 867 | } 868 | } 869 | } else { 870 | this.cb.call(this.vm, value, oldValue); 871 | } 872 | } 873 | } 874 | }; 875 | 876 | /** 877 | * Evaluate the value of the watcher. 878 | * This only gets called for lazy watchers. 879 | */ 880 | Watcher.prototype.evaluate = function evaluate () { 881 | this.value = this.get(); 882 | this.dirty = false; 883 | }; 884 | 885 | /** 886 | * Depend on all deps collected by this watcher. 887 | */ 888 | Watcher.prototype.depend = function depend () { 889 | var this$1 = this; 890 | 891 | var i = this.deps.length; 892 | while (i--) { 893 | this$1.deps[i].depend(); 894 | } 895 | }; 896 | 897 | /** 898 | * Remove self from all dependencies' subscriber list. 899 | */ 900 | Watcher.prototype.teardown = function teardown () { 901 | var this$1 = this; 902 | 903 | if (this.active) { 904 | // remove self from vm's watcher list 905 | // this is a somewhat expensive operation so we skip it 906 | // if the vm is being destroyed or is performing a v-for 907 | // re-render (the watcher list is then filtered by v-for). 908 | if (!this.vm._isBeingDestroyed && !this.vm._vForRemoving) { 909 | remove(this.vm._watchers, this); 910 | } 911 | var i = this.deps.length; 912 | while (i--) { 913 | this$1.deps[i].removeSub(this$1); 914 | } 915 | this.active = false; 916 | } 917 | }; 918 | 919 | /** 920 | * Recursively traverse an object to evoke all converted 921 | * getters, so that every nested property inside the object 922 | * is collected as a "deep" dependency. 923 | */ 924 | var seenObjects = new _Set(); 925 | function traverse (val) { 926 | seenObjects.clear(); 927 | _traverse(val, seenObjects); 928 | } 929 | 930 | function _traverse (val, seen) { 931 | var i, keys; 932 | var isA = Array.isArray(val); 933 | if ((!isA && !isObject(val)) || !Object.isExtensible(val)) { 934 | return 935 | } 936 | if (val.__ob__) { 937 | var depId = val.__ob__.dep.id; 938 | if (seen.has(depId)) { 939 | return 940 | } 941 | seen.add(depId); 942 | } 943 | if (isA) { 944 | i = val.length; 945 | while (i--) { _traverse(val[i], seen); } 946 | } else { 947 | keys = Object.keys(val); 948 | i = keys.length; 949 | while (i--) { _traverse(val[keys[i]], seen); } 950 | } 951 | } 952 | 953 | /* 954 | * not type checking this file because flow doesn't play well with 955 | * dynamically accessing methods on Array prototype 956 | */ 957 | 958 | var arrayProto = Array.prototype; 959 | var arrayMethods = Object.create(arrayProto);[ 960 | 'push', 961 | 'pop', 962 | 'shift', 963 | 'unshift', 964 | 'splice', 965 | 'sort', 966 | 'reverse' 967 | ] 968 | .forEach(function (method) { 969 | // cache original method 970 | var original = arrayProto[method]; 971 | def(arrayMethods, method, function mutator () { 972 | var arguments$1 = arguments; 973 | 974 | // avoid leaking arguments: 975 | // http://jsperf.com/closure-with-arguments 976 | var i = arguments.length; 977 | var args = new Array(i); 978 | while (i--) { 979 | args[i] = arguments$1[i]; 980 | } 981 | var result = original.apply(this, args); 982 | var ob = this.__ob__; 983 | var inserted; 984 | switch (method) { 985 | case 'push': 986 | inserted = args; 987 | break 988 | case 'unshift': 989 | inserted = args; 990 | break 991 | case 'splice': 992 | inserted = args.slice(2); 993 | break 994 | } 995 | if (inserted) { ob.observeArray(inserted); } 996 | // notify change 997 | ob.dep.notify(); 998 | return result 999 | }); 1000 | }); 1001 | 1002 | /* */ 1003 | 1004 | var arrayKeys = Object.getOwnPropertyNames(arrayMethods); 1005 | 1006 | /** 1007 | * By default, when a reactive property is set, the new value is 1008 | * also converted to become reactive. However when passing down props, 1009 | * we don't want to force conversion because the value may be a nested value 1010 | * under a frozen data structure. Converting it would defeat the optimization. 1011 | */ 1012 | var observerState = { 1013 | shouldConvert: true, 1014 | isSettingProps: false 1015 | }; 1016 | 1017 | /** 1018 | * Observer class that are attached to each observed 1019 | * object. Once attached, the observer converts target 1020 | * object's property keys into getter/setters that 1021 | * collect dependencies and dispatches updates. 1022 | */ 1023 | var Observer = function Observer (value) { 1024 | this.value = value; 1025 | this.dep = new Dep(); 1026 | this.vmCount = 0; 1027 | def(value, '__ob__', this); 1028 | if (Array.isArray(value)) { 1029 | var augment = hasProto 1030 | ? protoAugment 1031 | : copyAugment; 1032 | augment(value, arrayMethods, arrayKeys); 1033 | this.observeArray(value); 1034 | } else { 1035 | this.walk(value); 1036 | } 1037 | }; 1038 | 1039 | /** 1040 | * Walk through each property and convert them into 1041 | * getter/setters. This method should only be called when 1042 | * value type is Object. 1043 | */ 1044 | Observer.prototype.walk = function walk (obj) { 1045 | var keys = Object.keys(obj); 1046 | for (var i = 0; i < keys.length; i++) { 1047 | defineReactive$$1(obj, keys[i], obj[keys[i]]); 1048 | } 1049 | }; 1050 | 1051 | /** 1052 | * Observe a list of Array items. 1053 | */ 1054 | Observer.prototype.observeArray = function observeArray (items) { 1055 | for (var i = 0, l = items.length; i < l; i++) { 1056 | observe(items[i]); 1057 | } 1058 | }; 1059 | 1060 | // helpers 1061 | 1062 | /** 1063 | * Augment an target Object or Array by intercepting 1064 | * the prototype chain using __proto__ 1065 | */ 1066 | function protoAugment (target, src) { 1067 | /* eslint-disable no-proto */ 1068 | target.__proto__ = src; 1069 | /* eslint-enable no-proto */ 1070 | } 1071 | 1072 | /** 1073 | * Augment an target Object or Array by defining 1074 | * hidden properties. 1075 | * 1076 | * istanbul ignore next 1077 | */ 1078 | function copyAugment (target, src, keys) { 1079 | for (var i = 0, l = keys.length; i < l; i++) { 1080 | var key = keys[i]; 1081 | def(target, key, src[key]); 1082 | } 1083 | } 1084 | 1085 | /** 1086 | * Attempt to create an observer instance for a value, 1087 | * returns the new observer if successfully observed, 1088 | * or the existing observer if the value already has one. 1089 | */ 1090 | function observe (value) { 1091 | if (!isObject(value)) { 1092 | return 1093 | } 1094 | var ob; 1095 | if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) { 1096 | ob = value.__ob__; 1097 | } else if ( 1098 | observerState.shouldConvert && 1099 | !config._isServer && 1100 | (Array.isArray(value) || isPlainObject(value)) && 1101 | Object.isExtensible(value) && 1102 | !value._isVue 1103 | ) { 1104 | ob = new Observer(value); 1105 | } 1106 | return ob 1107 | } 1108 | 1109 | /** 1110 | * Define a reactive property on an Object. 1111 | */ 1112 | function defineReactive$$1 ( 1113 | obj, 1114 | key, 1115 | val, 1116 | customSetter 1117 | ) { 1118 | var dep = new Dep(); 1119 | 1120 | var property = Object.getOwnPropertyDescriptor(obj, key); 1121 | if (property && property.configurable === false) { 1122 | return 1123 | } 1124 | 1125 | // cater for pre-defined getter/setters 1126 | var getter = property && property.get; 1127 | var setter = property && property.set; 1128 | 1129 | var childOb = observe(val); 1130 | Object.defineProperty(obj, key, { 1131 | enumerable: true, 1132 | configurable: true, 1133 | get: function reactiveGetter () { 1134 | var value = getter ? getter.call(obj) : val; 1135 | if (Dep.target) { 1136 | dep.depend(); 1137 | if (childOb) { 1138 | childOb.dep.depend(); 1139 | } 1140 | if (Array.isArray(value)) { 1141 | dependArray(value); 1142 | } 1143 | } 1144 | return value 1145 | }, 1146 | set: function reactiveSetter (newVal) { 1147 | var value = getter ? getter.call(obj) : val; 1148 | if (newVal === value) { 1149 | return 1150 | } 1151 | if (process.env.NODE_ENV !== 'production' && customSetter) { 1152 | customSetter(); 1153 | } 1154 | if (setter) { 1155 | setter.call(obj, newVal); 1156 | } else { 1157 | val = newVal; 1158 | } 1159 | childOb = observe(newVal); 1160 | dep.notify(); 1161 | } 1162 | }); 1163 | } 1164 | 1165 | /** 1166 | * Set a property on an object. Adds the new property and 1167 | * triggers change notification if the property doesn't 1168 | * already exist. 1169 | */ 1170 | function set (obj, key, val) { 1171 | if (Array.isArray(obj)) { 1172 | obj.length = Math.max(obj.length, key); 1173 | obj.splice(key, 1, val); 1174 | return val 1175 | } 1176 | if (hasOwn(obj, key)) { 1177 | obj[key] = val; 1178 | return 1179 | } 1180 | var ob = obj.__ob__; 1181 | if (obj._isVue || (ob && ob.vmCount)) { 1182 | process.env.NODE_ENV !== 'production' && warn( 1183 | 'Avoid adding reactive properties to a Vue instance or its root $data ' + 1184 | 'at runtime - declare it upfront in the data option.' 1185 | ); 1186 | return 1187 | } 1188 | if (!ob) { 1189 | obj[key] = val; 1190 | return 1191 | } 1192 | defineReactive$$1(ob.value, key, val); 1193 | ob.dep.notify(); 1194 | return val 1195 | } 1196 | 1197 | /** 1198 | * Delete a property and trigger change if necessary. 1199 | */ 1200 | function del (obj, key) { 1201 | var ob = obj.__ob__; 1202 | if (obj._isVue || (ob && ob.vmCount)) { 1203 | process.env.NODE_ENV !== 'production' && warn( 1204 | 'Avoid deleting properties on a Vue instance or its root $data ' + 1205 | '- just set it to null.' 1206 | ); 1207 | return 1208 | } 1209 | if (!hasOwn(obj, key)) { 1210 | return 1211 | } 1212 | delete obj[key]; 1213 | if (!ob) { 1214 | return 1215 | } 1216 | ob.dep.notify(); 1217 | } 1218 | 1219 | /** 1220 | * Collect dependencies on array elements when the array is touched, since 1221 | * we cannot intercept array element access like property getters. 1222 | */ 1223 | function dependArray (value) { 1224 | for (var e = (void 0), i = 0, l = value.length; i < l; i++) { 1225 | e = value[i]; 1226 | e && e.__ob__ && e.__ob__.dep.depend(); 1227 | if (Array.isArray(e)) { 1228 | dependArray(e); 1229 | } 1230 | } 1231 | } 1232 | 1233 | /* */ 1234 | 1235 | function initState (vm) { 1236 | vm._watchers = []; 1237 | initProps(vm); 1238 | initData(vm); 1239 | initComputed(vm); 1240 | initMethods(vm); 1241 | initWatch(vm); 1242 | } 1243 | 1244 | function initProps (vm) { 1245 | var props = vm.$options.props; 1246 | if (props) { 1247 | var propsData = vm.$options.propsData || {}; 1248 | var keys = vm.$options._propKeys = Object.keys(props); 1249 | var isRoot = !vm.$parent; 1250 | // root instance props should be converted 1251 | observerState.shouldConvert = isRoot; 1252 | var loop = function ( i ) { 1253 | var key = keys[i]; 1254 | /* istanbul ignore else */ 1255 | if (process.env.NODE_ENV !== 'production') { 1256 | defineReactive$$1(vm, key, validateProp(key, props, propsData, vm), function () { 1257 | if (vm.$parent && !observerState.isSettingProps) { 1258 | warn( 1259 | "Avoid mutating a prop directly since the value will be " + 1260 | "overwritten whenever the parent component re-renders. " + 1261 | "Instead, use a data or computed property based on the prop's " + 1262 | "value. Prop being mutated: \"" + key + "\"", 1263 | vm 1264 | ); 1265 | } 1266 | }); 1267 | } else { 1268 | defineReactive$$1(vm, key, validateProp(key, props, propsData, vm)); 1269 | } 1270 | }; 1271 | 1272 | for (var i = 0; i < keys.length; i++) loop( i ); 1273 | observerState.shouldConvert = true; 1274 | } 1275 | } 1276 | 1277 | function initData (vm) { 1278 | var data = vm.$options.data; 1279 | data = vm._data = typeof data === 'function' 1280 | ? data.call(vm) 1281 | : data || {}; 1282 | if (!isPlainObject(data)) { 1283 | data = {}; 1284 | process.env.NODE_ENV !== 'production' && warn( 1285 | 'data functions should return an object.', 1286 | vm 1287 | ); 1288 | } 1289 | // proxy data on instance 1290 | var keys = Object.keys(data); 1291 | var props = vm.$options.props; 1292 | var i = keys.length; 1293 | while (i--) { 1294 | if (props && hasOwn(props, keys[i])) { 1295 | process.env.NODE_ENV !== 'production' && warn( 1296 | "The data property \"" + (keys[i]) + "\" is already declared as a prop. " + 1297 | "Use prop default value instead.", 1298 | vm 1299 | ); 1300 | } else { 1301 | proxy(vm, keys[i]); 1302 | } 1303 | } 1304 | // observe data 1305 | observe(data); 1306 | data.__ob__ && data.__ob__.vmCount++; 1307 | } 1308 | 1309 | var computedSharedDefinition = { 1310 | enumerable: true, 1311 | configurable: true, 1312 | get: noop, 1313 | set: noop 1314 | }; 1315 | 1316 | function initComputed (vm) { 1317 | var computed = vm.$options.computed; 1318 | if (computed) { 1319 | for (var key in computed) { 1320 | var userDef = computed[key]; 1321 | if (typeof userDef === 'function') { 1322 | computedSharedDefinition.get = makeComputedGetter(userDef, vm); 1323 | computedSharedDefinition.set = noop; 1324 | } else { 1325 | computedSharedDefinition.get = userDef.get 1326 | ? userDef.cache !== false 1327 | ? makeComputedGetter(userDef.get, vm) 1328 | : bind(userDef.get, vm) 1329 | : noop; 1330 | computedSharedDefinition.set = userDef.set 1331 | ? bind(userDef.set, vm) 1332 | : noop; 1333 | } 1334 | Object.defineProperty(vm, key, computedSharedDefinition); 1335 | } 1336 | } 1337 | } 1338 | 1339 | function makeComputedGetter (getter, owner) { 1340 | var watcher = new Watcher(owner, getter, noop, { 1341 | lazy: true 1342 | }); 1343 | return function computedGetter () { 1344 | if (watcher.dirty) { 1345 | watcher.evaluate(); 1346 | } 1347 | if (Dep.target) { 1348 | watcher.depend(); 1349 | } 1350 | return watcher.value 1351 | } 1352 | } 1353 | 1354 | function initMethods (vm) { 1355 | var methods = vm.$options.methods; 1356 | if (methods) { 1357 | for (var key in methods) { 1358 | vm[key] = methods[key] == null ? noop : bind(methods[key], vm); 1359 | if (process.env.NODE_ENV !== 'production' && methods[key] == null) { 1360 | warn( 1361 | "method \"" + key + "\" has an undefined value in the component definition. " + 1362 | "Did you reference the function correctly?", 1363 | vm 1364 | ); 1365 | } 1366 | } 1367 | } 1368 | } 1369 | 1370 | function initWatch (vm) { 1371 | var watch = vm.$options.watch; 1372 | if (watch) { 1373 | for (var key in watch) { 1374 | var handler = watch[key]; 1375 | if (Array.isArray(handler)) { 1376 | for (var i = 0; i < handler.length; i++) { 1377 | createWatcher(vm, key, handler[i]); 1378 | } 1379 | } else { 1380 | createWatcher(vm, key, handler); 1381 | } 1382 | } 1383 | } 1384 | } 1385 | 1386 | function createWatcher (vm, key, handler) { 1387 | var options; 1388 | if (isPlainObject(handler)) { 1389 | options = handler; 1390 | handler = handler.handler; 1391 | } 1392 | if (typeof handler === 'string') { 1393 | handler = vm[handler]; 1394 | } 1395 | vm.$watch(key, handler, options); 1396 | } 1397 | 1398 | function stateMixin (Vue) { 1399 | // flow somehow has problems with directly declared definition object 1400 | // when using Object.defineProperty, so we have to procedurally build up 1401 | // the object here. 1402 | var dataDef = {}; 1403 | dataDef.get = function () { 1404 | return this._data 1405 | }; 1406 | if (process.env.NODE_ENV !== 'production') { 1407 | dataDef.set = function (newData) { 1408 | warn( 1409 | 'Avoid replacing instance root $data. ' + 1410 | 'Use nested data properties instead.', 1411 | this 1412 | ); 1413 | }; 1414 | } 1415 | Object.defineProperty(Vue.prototype, '$data', dataDef); 1416 | 1417 | Vue.prototype.$set = set; 1418 | Vue.prototype.$delete = del; 1419 | 1420 | Vue.prototype.$watch = function ( 1421 | expOrFn, 1422 | cb, 1423 | options 1424 | ) { 1425 | var vm = this; 1426 | options = options || {}; 1427 | options.user = true; 1428 | var watcher = new Watcher(vm, expOrFn, cb, options); 1429 | if (options.immediate) { 1430 | cb.call(vm, watcher.value); 1431 | } 1432 | return function unwatchFn () { 1433 | watcher.teardown(); 1434 | } 1435 | }; 1436 | } 1437 | 1438 | function proxy (vm, key) { 1439 | if (!isReserved(key)) { 1440 | Object.defineProperty(vm, key, { 1441 | configurable: true, 1442 | enumerable: true, 1443 | get: function proxyGetter () { 1444 | return vm._data[key] 1445 | }, 1446 | set: function proxySetter (val) { 1447 | vm._data[key] = val; 1448 | } 1449 | }); 1450 | } 1451 | } 1452 | 1453 | /* */ 1454 | 1455 | var VNode = function VNode ( 1456 | tag, 1457 | data, 1458 | children, 1459 | text, 1460 | elm, 1461 | ns, 1462 | context, 1463 | componentOptions 1464 | ) { 1465 | this.tag = tag; 1466 | this.data = data; 1467 | this.children = children; 1468 | this.text = text; 1469 | this.elm = elm; 1470 | this.ns = ns; 1471 | this.context = context; 1472 | this.functionalContext = undefined; 1473 | this.key = data && data.key; 1474 | this.componentOptions = componentOptions; 1475 | this.child = undefined; 1476 | this.parent = undefined; 1477 | this.raw = false; 1478 | this.isStatic = false; 1479 | this.isRootInsert = true; 1480 | this.isComment = false; 1481 | this.isCloned = false; 1482 | this.isOnce = false; 1483 | }; 1484 | 1485 | var emptyVNode = function () { 1486 | var node = new VNode(); 1487 | node.text = ''; 1488 | node.isComment = true; 1489 | return node 1490 | }; 1491 | 1492 | // optimized shallow clone 1493 | // used for static nodes and slot nodes because they may be reused across 1494 | // multiple renders, cloning them avoids errors when DOM manipulations rely 1495 | // on their elm reference. 1496 | function cloneVNode (vnode) { 1497 | var cloned = new VNode( 1498 | vnode.tag, 1499 | vnode.data, 1500 | vnode.children, 1501 | vnode.text, 1502 | vnode.elm, 1503 | vnode.ns, 1504 | vnode.context, 1505 | vnode.componentOptions 1506 | ); 1507 | cloned.isStatic = vnode.isStatic; 1508 | cloned.key = vnode.key; 1509 | cloned.isCloned = true; 1510 | return cloned 1511 | } 1512 | 1513 | function cloneVNodes (vnodes) { 1514 | var res = new Array(vnodes.length); 1515 | for (var i = 0; i < vnodes.length; i++) { 1516 | res[i] = cloneVNode(vnodes[i]); 1517 | } 1518 | return res 1519 | } 1520 | 1521 | /* */ 1522 | 1523 | /* */ 1524 | 1525 | function updateListeners ( 1526 | on, 1527 | oldOn, 1528 | add, 1529 | remove$$1, 1530 | vm 1531 | ) { 1532 | var name, cur, old, fn, event, capture; 1533 | for (name in on) { 1534 | cur = on[name]; 1535 | old = oldOn[name]; 1536 | if (!cur) { 1537 | process.env.NODE_ENV !== 'production' && warn( 1538 | "Invalid handler for event \"" + name + "\": got " + String(cur), 1539 | vm 1540 | ); 1541 | } else if (!old) { 1542 | capture = name.charAt(0) === '!'; 1543 | event = capture ? name.slice(1) : name; 1544 | if (Array.isArray(cur)) { 1545 | add(event, (cur.invoker = arrInvoker(cur)), capture); 1546 | } else { 1547 | if (!cur.invoker) { 1548 | fn = cur; 1549 | cur = on[name] = {}; 1550 | cur.fn = fn; 1551 | cur.invoker = fnInvoker(cur); 1552 | } 1553 | add(event, cur.invoker, capture); 1554 | } 1555 | } else if (cur !== old) { 1556 | if (Array.isArray(old)) { 1557 | old.length = cur.length; 1558 | for (var i = 0; i < old.length; i++) { old[i] = cur[i]; } 1559 | on[name] = old; 1560 | } else { 1561 | old.fn = cur; 1562 | on[name] = old; 1563 | } 1564 | } 1565 | } 1566 | for (name in oldOn) { 1567 | if (!on[name]) { 1568 | event = name.charAt(0) === '!' ? name.slice(1) : name; 1569 | remove$$1(event, oldOn[name].invoker); 1570 | } 1571 | } 1572 | } 1573 | 1574 | function arrInvoker (arr) { 1575 | return function (ev) { 1576 | var arguments$1 = arguments; 1577 | 1578 | var single = arguments.length === 1; 1579 | for (var i = 0; i < arr.length; i++) { 1580 | single ? arr[i](ev) : arr[i].apply(null, arguments$1); 1581 | } 1582 | } 1583 | } 1584 | 1585 | function fnInvoker (o) { 1586 | return function (ev) { 1587 | var single = arguments.length === 1; 1588 | single ? o.fn(ev) : o.fn.apply(null, arguments); 1589 | } 1590 | } 1591 | 1592 | /* */ 1593 | 1594 | function normalizeChildren ( 1595 | children, 1596 | ns, 1597 | nestedIndex 1598 | ) { 1599 | if (isPrimitive(children)) { 1600 | return [createTextVNode(children)] 1601 | } 1602 | if (Array.isArray(children)) { 1603 | var res = []; 1604 | for (var i = 0, l = children.length; i < l; i++) { 1605 | var c = children[i]; 1606 | var last = res[res.length - 1]; 1607 | // nested 1608 | if (Array.isArray(c)) { 1609 | res.push.apply(res, normalizeChildren(c, ns, ((nestedIndex || '') + "_" + i))); 1610 | } else if (isPrimitive(c)) { 1611 | if (last && last.text) { 1612 | last.text += String(c); 1613 | } else if (c !== '') { 1614 | // convert primitive to vnode 1615 | res.push(createTextVNode(c)); 1616 | } 1617 | } else if (c instanceof VNode) { 1618 | if (c.text && last && last.text) { 1619 | last.text += c.text; 1620 | } else { 1621 | // inherit parent namespace 1622 | if (ns) { 1623 | applyNS(c, ns); 1624 | } 1625 | // default key for nested array children (likely generated by v-for) 1626 | if (c.tag && c.key == null && nestedIndex != null) { 1627 | c.key = "__vlist" + nestedIndex + "_" + i + "__"; 1628 | } 1629 | res.push(c); 1630 | } 1631 | } 1632 | } 1633 | return res 1634 | } 1635 | } 1636 | 1637 | function createTextVNode (val) { 1638 | return new VNode(undefined, undefined, undefined, String(val)) 1639 | } 1640 | 1641 | function applyNS (vnode, ns) { 1642 | if (vnode.tag && !vnode.ns) { 1643 | vnode.ns = ns; 1644 | if (vnode.children) { 1645 | for (var i = 0, l = vnode.children.length; i < l; i++) { 1646 | applyNS(vnode.children[i], ns); 1647 | } 1648 | } 1649 | } 1650 | } 1651 | 1652 | /* */ 1653 | 1654 | /* */ 1655 | 1656 | var activeInstance = null; 1657 | 1658 | function initLifecycle (vm) { 1659 | var options = vm.$options; 1660 | 1661 | // locate first non-abstract parent 1662 | var parent = options.parent; 1663 | if (parent && !options.abstract) { 1664 | while (parent.$options.abstract && parent.$parent) { 1665 | parent = parent.$parent; 1666 | } 1667 | parent.$children.push(vm); 1668 | } 1669 | 1670 | vm.$parent = parent; 1671 | vm.$root = parent ? parent.$root : vm; 1672 | 1673 | vm.$children = []; 1674 | vm.$refs = {}; 1675 | 1676 | vm._watcher = null; 1677 | vm._inactive = false; 1678 | vm._isMounted = false; 1679 | vm._isDestroyed = false; 1680 | vm._isBeingDestroyed = false; 1681 | } 1682 | 1683 | function lifecycleMixin (Vue) { 1684 | Vue.prototype._mount = function ( 1685 | el, 1686 | hydrating 1687 | ) { 1688 | var vm = this; 1689 | vm.$el = el; 1690 | if (!vm.$options.render) { 1691 | vm.$options.render = emptyVNode; 1692 | if (process.env.NODE_ENV !== 'production') { 1693 | /* istanbul ignore if */ 1694 | if (vm.$options.template) { 1695 | warn( 1696 | 'You are using the runtime-only build of Vue where the template ' + 1697 | 'option is not available. Either pre-compile the templates into ' + 1698 | 'render functions, or use the compiler-included build.', 1699 | vm 1700 | ); 1701 | } else { 1702 | warn( 1703 | 'Failed to mount component: template or render function not defined.', 1704 | vm 1705 | ); 1706 | } 1707 | } 1708 | } 1709 | callHook(vm, 'beforeMount'); 1710 | vm._watcher = new Watcher(vm, function () { 1711 | vm._update(vm._render(), hydrating); 1712 | }, noop); 1713 | hydrating = false; 1714 | // manually mounted instance, call mounted on self 1715 | // mounted is called for render-created child components in its inserted hook 1716 | if (vm.$vnode == null) { 1717 | vm._isMounted = true; 1718 | callHook(vm, 'mounted'); 1719 | } 1720 | return vm 1721 | }; 1722 | 1723 | Vue.prototype._update = function (vnode, hydrating) { 1724 | var vm = this; 1725 | if (vm._isMounted) { 1726 | callHook(vm, 'beforeUpdate'); 1727 | } 1728 | var prevEl = vm.$el; 1729 | var prevActiveInstance = activeInstance; 1730 | activeInstance = vm; 1731 | var prevVnode = vm._vnode; 1732 | vm._vnode = vnode; 1733 | if (!prevVnode) { 1734 | // Vue.prototype.__patch__ is injected in entry points 1735 | // based on the rendering backend used. 1736 | vm.$el = vm.__patch__(vm.$el, vnode, hydrating); 1737 | } else { 1738 | vm.$el = vm.__patch__(prevVnode, vnode); 1739 | } 1740 | activeInstance = prevActiveInstance; 1741 | // update __vue__ reference 1742 | if (prevEl) { 1743 | prevEl.__vue__ = null; 1744 | } 1745 | if (vm.$el) { 1746 | vm.$el.__vue__ = vm; 1747 | } 1748 | // if parent is an HOC, update its $el as well 1749 | if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) { 1750 | vm.$parent.$el = vm.$el; 1751 | } 1752 | if (vm._isMounted) { 1753 | callHook(vm, 'updated'); 1754 | } 1755 | }; 1756 | 1757 | Vue.prototype._updateFromParent = function ( 1758 | propsData, 1759 | listeners, 1760 | parentVnode, 1761 | renderChildren 1762 | ) { 1763 | var vm = this; 1764 | var hasChildren = !!(vm.$options._renderChildren || renderChildren); 1765 | vm.$options._parentVnode = parentVnode; 1766 | vm.$options._renderChildren = renderChildren; 1767 | // update props 1768 | if (propsData && vm.$options.props) { 1769 | observerState.shouldConvert = false; 1770 | if (process.env.NODE_ENV !== 'production') { 1771 | observerState.isSettingProps = true; 1772 | } 1773 | var propKeys = vm.$options._propKeys || []; 1774 | for (var i = 0; i < propKeys.length; i++) { 1775 | var key = propKeys[i]; 1776 | vm[key] = validateProp(key, vm.$options.props, propsData, vm); 1777 | } 1778 | observerState.shouldConvert = true; 1779 | if (process.env.NODE_ENV !== 'production') { 1780 | observerState.isSettingProps = false; 1781 | } 1782 | } 1783 | // update listeners 1784 | if (listeners) { 1785 | var oldListeners = vm.$options._parentListeners; 1786 | vm.$options._parentListeners = listeners; 1787 | vm._updateListeners(listeners, oldListeners); 1788 | } 1789 | // resolve slots + force update if has children 1790 | if (hasChildren) { 1791 | vm.$slots = resolveSlots(renderChildren, vm._renderContext); 1792 | vm.$forceUpdate(); 1793 | } 1794 | }; 1795 | 1796 | Vue.prototype.$forceUpdate = function () { 1797 | var vm = this; 1798 | if (vm._watcher) { 1799 | vm._watcher.update(); 1800 | } 1801 | }; 1802 | 1803 | Vue.prototype.$destroy = function () { 1804 | var vm = this; 1805 | if (vm._isBeingDestroyed) { 1806 | return 1807 | } 1808 | callHook(vm, 'beforeDestroy'); 1809 | vm._isBeingDestroyed = true; 1810 | // remove self from parent 1811 | var parent = vm.$parent; 1812 | if (parent && !parent._isBeingDestroyed && !vm.$options.abstract) { 1813 | remove(parent.$children, vm); 1814 | } 1815 | // teardown watchers 1816 | if (vm._watcher) { 1817 | vm._watcher.teardown(); 1818 | } 1819 | var i = vm._watchers.length; 1820 | while (i--) { 1821 | vm._watchers[i].teardown(); 1822 | } 1823 | // remove reference from data ob 1824 | // frozen object may not have observer. 1825 | if (vm._data.__ob__) { 1826 | vm._data.__ob__.vmCount--; 1827 | } 1828 | // call the last hook... 1829 | vm._isDestroyed = true; 1830 | callHook(vm, 'destroyed'); 1831 | // turn off all instance listeners. 1832 | vm.$off(); 1833 | // remove __vue__ reference 1834 | if (vm.$el) { 1835 | vm.$el.__vue__ = null; 1836 | } 1837 | // invoke destroy hooks on current rendered tree 1838 | vm.__patch__(vm._vnode, null); 1839 | }; 1840 | } 1841 | 1842 | function callHook (vm, hook) { 1843 | var handlers = vm.$options[hook]; 1844 | if (handlers) { 1845 | for (var i = 0, j = handlers.length; i < j; i++) { 1846 | handlers[i].call(vm); 1847 | } 1848 | } 1849 | vm.$emit('hook:' + hook); 1850 | } 1851 | 1852 | /* */ 1853 | 1854 | var hooks = { init: init, prepatch: prepatch, insert: insert, destroy: destroy }; 1855 | var hooksToMerge = Object.keys(hooks); 1856 | 1857 | function createComponent ( 1858 | Ctor, 1859 | data, 1860 | context, 1861 | children, 1862 | tag 1863 | ) { 1864 | if (!Ctor) { 1865 | return 1866 | } 1867 | 1868 | if (isObject(Ctor)) { 1869 | Ctor = Vue.extend(Ctor); 1870 | } 1871 | 1872 | if (typeof Ctor !== 'function') { 1873 | if (process.env.NODE_ENV !== 'production') { 1874 | warn(("Invalid Component definition: " + (String(Ctor))), context); 1875 | } 1876 | return 1877 | } 1878 | 1879 | // resolve constructor options in case global mixins are applied after 1880 | // component constructor creation 1881 | resolveConstructorOptions(Ctor); 1882 | 1883 | // async component 1884 | if (!Ctor.cid) { 1885 | if (Ctor.resolved) { 1886 | Ctor = Ctor.resolved; 1887 | } else { 1888 | Ctor = resolveAsyncComponent(Ctor, function () { 1889 | // it's ok to queue this on every render because 1890 | // $forceUpdate is buffered by the scheduler. 1891 | context.$forceUpdate(); 1892 | }); 1893 | if (!Ctor) { 1894 | // return nothing if this is indeed an async component 1895 | // wait for the callback to trigger parent update. 1896 | return 1897 | } 1898 | } 1899 | } 1900 | 1901 | data = data || {}; 1902 | 1903 | // extract props 1904 | var propsData = extractProps(data, Ctor); 1905 | 1906 | // functional component 1907 | if (Ctor.options.functional) { 1908 | return createFunctionalComponent(Ctor, propsData, data, context, children) 1909 | } 1910 | 1911 | // extract listeners, since these needs to be treated as 1912 | // child component listeners instead of DOM listeners 1913 | var listeners = data.on; 1914 | // replace with listeners with .native modifier 1915 | data.on = data.nativeOn; 1916 | 1917 | if (Ctor.options.abstract) { 1918 | // abstract components do not keep anything 1919 | // other than props & listeners 1920 | data = {}; 1921 | } 1922 | 1923 | // merge component management hooks onto the placeholder node 1924 | mergeHooks(data); 1925 | 1926 | // return a placeholder vnode 1927 | var name = Ctor.options.name || tag; 1928 | var vnode = new VNode( 1929 | ("vue-component-" + (Ctor.cid) + (name ? ("-" + name) : '')), 1930 | data, undefined, undefined, undefined, undefined, context, 1931 | { Ctor: Ctor, propsData: propsData, listeners: listeners, tag: tag, children: children } 1932 | ); 1933 | return vnode 1934 | } 1935 | 1936 | function createFunctionalComponent ( 1937 | Ctor, 1938 | propsData, 1939 | data, 1940 | context, 1941 | children 1942 | ) { 1943 | var props = {}; 1944 | var propOptions = Ctor.options.props; 1945 | if (propOptions) { 1946 | for (var key in propOptions) { 1947 | props[key] = validateProp(key, propOptions, propsData); 1948 | } 1949 | } 1950 | var vnode = Ctor.options.render.call( 1951 | null, 1952 | // ensure the createElement function in functional components 1953 | // gets a unique context - this is necessary for correct named slot check 1954 | bind(createElement, { _self: Object.create(context) }), 1955 | { 1956 | props: props, 1957 | data: data, 1958 | parent: context, 1959 | children: normalizeChildren(children), 1960 | slots: function () { return resolveSlots(children, context); } 1961 | } 1962 | ); 1963 | if (vnode instanceof VNode) { 1964 | vnode.functionalContext = context; 1965 | if (data.slot) { 1966 | (vnode.data || (vnode.data = {})).slot = data.slot; 1967 | } 1968 | } 1969 | return vnode 1970 | } 1971 | 1972 | function createComponentInstanceForVnode ( 1973 | vnode, // we know it's MountedComponentVNode but flow doesn't 1974 | parent // activeInstance in lifecycle state 1975 | ) { 1976 | var vnodeComponentOptions = vnode.componentOptions; 1977 | var options = { 1978 | _isComponent: true, 1979 | parent: parent, 1980 | propsData: vnodeComponentOptions.propsData, 1981 | _componentTag: vnodeComponentOptions.tag, 1982 | _parentVnode: vnode, 1983 | _parentListeners: vnodeComponentOptions.listeners, 1984 | _renderChildren: vnodeComponentOptions.children 1985 | }; 1986 | // check inline-template render functions 1987 | var inlineTemplate = vnode.data.inlineTemplate; 1988 | if (inlineTemplate) { 1989 | options.render = inlineTemplate.render; 1990 | options.staticRenderFns = inlineTemplate.staticRenderFns; 1991 | } 1992 | return new vnodeComponentOptions.Ctor(options) 1993 | } 1994 | 1995 | function init (vnode, hydrating) { 1996 | if (!vnode.child || vnode.child._isDestroyed) { 1997 | var child = vnode.child = createComponentInstanceForVnode(vnode, activeInstance); 1998 | child.$mount(hydrating ? vnode.elm : undefined, hydrating); 1999 | } 2000 | } 2001 | 2002 | function prepatch ( 2003 | oldVnode, 2004 | vnode 2005 | ) { 2006 | var options = vnode.componentOptions; 2007 | var child = vnode.child = oldVnode.child; 2008 | child._updateFromParent( 2009 | options.propsData, // updated props 2010 | options.listeners, // updated listeners 2011 | vnode, // new parent vnode 2012 | options.children // new children 2013 | ); 2014 | } 2015 | 2016 | function insert (vnode) { 2017 | if (!vnode.child._isMounted) { 2018 | vnode.child._isMounted = true; 2019 | callHook(vnode.child, 'mounted'); 2020 | } 2021 | if (vnode.data.keepAlive) { 2022 | vnode.child._inactive = false; 2023 | callHook(vnode.child, 'activated'); 2024 | } 2025 | } 2026 | 2027 | function destroy (vnode) { 2028 | if (!vnode.child._isDestroyed) { 2029 | if (!vnode.data.keepAlive) { 2030 | vnode.child.$destroy(); 2031 | } else { 2032 | vnode.child._inactive = true; 2033 | callHook(vnode.child, 'deactivated'); 2034 | } 2035 | } 2036 | } 2037 | 2038 | function resolveAsyncComponent ( 2039 | factory, 2040 | cb 2041 | ) { 2042 | if (factory.requested) { 2043 | // pool callbacks 2044 | factory.pendingCallbacks.push(cb); 2045 | } else { 2046 | factory.requested = true; 2047 | var cbs = factory.pendingCallbacks = [cb]; 2048 | var sync = true; 2049 | 2050 | var resolve = function (res) { 2051 | if (isObject(res)) { 2052 | res = Vue.extend(res); 2053 | } 2054 | // cache resolved 2055 | factory.resolved = res; 2056 | // invoke callbacks only if this is not a synchronous resolve 2057 | // (async resolves are shimmed as synchronous during SSR) 2058 | if (!sync) { 2059 | for (var i = 0, l = cbs.length; i < l; i++) { 2060 | cbs[i](res); 2061 | } 2062 | } 2063 | }; 2064 | 2065 | var reject = function (reason) { 2066 | process.env.NODE_ENV !== 'production' && warn( 2067 | "Failed to resolve async component: " + (String(factory)) + 2068 | (reason ? ("\nReason: " + reason) : '') 2069 | ); 2070 | }; 2071 | 2072 | var res = factory(resolve, reject); 2073 | 2074 | // handle promise 2075 | if (res && typeof res.then === 'function' && !factory.resolved) { 2076 | res.then(resolve, reject); 2077 | } 2078 | 2079 | sync = false; 2080 | // return in case resolved synchronously 2081 | return factory.resolved 2082 | } 2083 | } 2084 | 2085 | function extractProps (data, Ctor) { 2086 | // we are only extracting raw values here. 2087 | // validation and default values are handled in the child 2088 | // component itself. 2089 | var propOptions = Ctor.options.props; 2090 | if (!propOptions) { 2091 | return 2092 | } 2093 | var res = {}; 2094 | var attrs = data.attrs; 2095 | var props = data.props; 2096 | var domProps = data.domProps; 2097 | if (attrs || props || domProps) { 2098 | for (var key in propOptions) { 2099 | var altKey = hyphenate(key); 2100 | checkProp(res, props, key, altKey, true) || 2101 | checkProp(res, attrs, key, altKey) || 2102 | checkProp(res, domProps, key, altKey); 2103 | } 2104 | } 2105 | return res 2106 | } 2107 | 2108 | function checkProp ( 2109 | res, 2110 | hash, 2111 | key, 2112 | altKey, 2113 | preserve 2114 | ) { 2115 | if (hash) { 2116 | if (hasOwn(hash, key)) { 2117 | res[key] = hash[key]; 2118 | if (!preserve) { 2119 | delete hash[key]; 2120 | } 2121 | return true 2122 | } else if (hasOwn(hash, altKey)) { 2123 | res[key] = hash[altKey]; 2124 | if (!preserve) { 2125 | delete hash[altKey]; 2126 | } 2127 | return true 2128 | } 2129 | } 2130 | return false 2131 | } 2132 | 2133 | function mergeHooks (data) { 2134 | if (!data.hook) { 2135 | data.hook = {}; 2136 | } 2137 | for (var i = 0; i < hooksToMerge.length; i++) { 2138 | var key = hooksToMerge[i]; 2139 | var fromParent = data.hook[key]; 2140 | var ours = hooks[key]; 2141 | data.hook[key] = fromParent ? mergeHook$1(ours, fromParent) : ours; 2142 | } 2143 | } 2144 | 2145 | function mergeHook$1 (a, b) { 2146 | // since all hooks have at most two args, use fixed args 2147 | // to avoid having to use fn.apply(). 2148 | return function (_, __) { 2149 | a(_, __); 2150 | b(_, __); 2151 | } 2152 | } 2153 | 2154 | /* */ 2155 | 2156 | // wrapper function for providing a more flexible interface 2157 | // without getting yelled at by flow 2158 | function createElement ( 2159 | tag, 2160 | data, 2161 | children 2162 | ) { 2163 | if (data && (Array.isArray(data) || typeof data !== 'object')) { 2164 | children = data; 2165 | data = undefined; 2166 | } 2167 | // make sure to use real instance instead of proxy as context 2168 | return _createElement(this._self, tag, data, children) 2169 | } 2170 | 2171 | function _createElement ( 2172 | context, 2173 | tag, 2174 | data, 2175 | children 2176 | ) { 2177 | if (data && data.__ob__) { 2178 | process.env.NODE_ENV !== 'production' && warn( 2179 | "Avoid using observed data object as vnode data: " + (JSON.stringify(data)) + "\n" + 2180 | 'Always create fresh vnode data objects in each render!', 2181 | context 2182 | ); 2183 | return 2184 | } 2185 | if (!tag) { 2186 | // in case of component :is set to falsy value 2187 | return emptyVNode() 2188 | } 2189 | if (typeof tag === 'string') { 2190 | var Ctor; 2191 | var ns = config.getTagNamespace(tag); 2192 | if (config.isReservedTag(tag)) { 2193 | // platform built-in elements 2194 | return new VNode( 2195 | tag, data, normalizeChildren(children, ns), 2196 | undefined, undefined, ns, context 2197 | ) 2198 | } else if ((Ctor = resolveAsset(context.$options, 'components', tag))) { 2199 | // component 2200 | return createComponent(Ctor, data, context, children, tag) 2201 | } else { 2202 | // unknown or unlisted namespaced elements 2203 | // check at runtime because it may get assigned a namespace when its 2204 | // parent normalizes children 2205 | return new VNode( 2206 | tag, data, normalizeChildren(children, ns), 2207 | undefined, undefined, ns, context 2208 | ) 2209 | } 2210 | } else { 2211 | // direct component options / constructor 2212 | return createComponent(tag, data, context, children) 2213 | } 2214 | } 2215 | 2216 | /* */ 2217 | 2218 | function initRender (vm) { 2219 | vm.$vnode = null; // the placeholder node in parent tree 2220 | vm._vnode = null; // the root of the child tree 2221 | vm._staticTrees = null; 2222 | vm._renderContext = vm.$options._parentVnode && vm.$options._parentVnode.context; 2223 | vm.$slots = resolveSlots(vm.$options._renderChildren, vm._renderContext); 2224 | // bind the public createElement fn to this instance 2225 | // so that we get proper render context inside it. 2226 | vm.$createElement = bind(createElement, vm); 2227 | if (vm.$options.el) { 2228 | vm.$mount(vm.$options.el); 2229 | } 2230 | } 2231 | 2232 | function renderMixin (Vue) { 2233 | Vue.prototype.$nextTick = function (fn) { 2234 | nextTick(fn, this); 2235 | }; 2236 | 2237 | Vue.prototype._render = function () { 2238 | var vm = this; 2239 | var ref = vm.$options; 2240 | var render = ref.render; 2241 | var staticRenderFns = ref.staticRenderFns; 2242 | var _parentVnode = ref._parentVnode; 2243 | 2244 | if (vm._isMounted) { 2245 | // clone slot nodes on re-renders 2246 | for (var key in vm.$slots) { 2247 | vm.$slots[key] = cloneVNodes(vm.$slots[key]); 2248 | } 2249 | } 2250 | 2251 | if (staticRenderFns && !vm._staticTrees) { 2252 | vm._staticTrees = []; 2253 | } 2254 | // set parent vnode. this allows render functions to have access 2255 | // to the data on the placeholder node. 2256 | vm.$vnode = _parentVnode; 2257 | // render self 2258 | var vnode; 2259 | try { 2260 | vnode = render.call(vm._renderProxy, vm.$createElement); 2261 | } catch (e) { 2262 | if (process.env.NODE_ENV !== 'production') { 2263 | warn(("Error when rendering " + (formatComponentName(vm)) + ":")); 2264 | } 2265 | /* istanbul ignore else */ 2266 | if (config.errorHandler) { 2267 | config.errorHandler.call(null, e, vm); 2268 | } else { 2269 | if (config._isServer) { 2270 | throw e 2271 | } else { 2272 | setTimeout(function () { throw e }, 0); 2273 | } 2274 | } 2275 | // return previous vnode to prevent render error causing blank component 2276 | vnode = vm._vnode; 2277 | } 2278 | // return empty vnode in case the render function errored out 2279 | if (!(vnode instanceof VNode)) { 2280 | if (process.env.NODE_ENV !== 'production' && Array.isArray(vnode)) { 2281 | warn( 2282 | 'Multiple root nodes returned from render function. Render function ' + 2283 | 'should return a single root node.', 2284 | vm 2285 | ); 2286 | } 2287 | vnode = emptyVNode(); 2288 | } 2289 | // set parent 2290 | vnode.parent = _parentVnode; 2291 | return vnode 2292 | }; 2293 | 2294 | // shorthands used in render functions 2295 | Vue.prototype._h = createElement; 2296 | // toString for mustaches 2297 | Vue.prototype._s = _toString; 2298 | // number conversion 2299 | Vue.prototype._n = toNumber; 2300 | // empty vnode 2301 | Vue.prototype._e = emptyVNode; 2302 | // loose equal 2303 | Vue.prototype._q = looseEqual; 2304 | // loose indexOf 2305 | Vue.prototype._i = looseIndexOf; 2306 | 2307 | // render static tree by index 2308 | Vue.prototype._m = function renderStatic ( 2309 | index, 2310 | isInFor 2311 | ) { 2312 | var tree = this._staticTrees[index]; 2313 | // if has already-rendered static tree and not inside v-for, 2314 | // we can reuse the same tree by doing a shallow clone. 2315 | if (tree && !isInFor) { 2316 | return Array.isArray(tree) 2317 | ? cloneVNodes(tree) 2318 | : cloneVNode(tree) 2319 | } 2320 | // otherwise, render a fresh tree. 2321 | tree = this._staticTrees[index] = this.$options.staticRenderFns[index].call(this._renderProxy); 2322 | markStatic(tree, ("__static__" + index), false); 2323 | return tree 2324 | }; 2325 | 2326 | // mark node as static (v-once) 2327 | Vue.prototype._o = function markOnce ( 2328 | tree, 2329 | index, 2330 | key 2331 | ) { 2332 | markStatic(tree, ("__once__" + index + (key ? ("_" + key) : "")), true); 2333 | return tree 2334 | }; 2335 | 2336 | function markStatic (tree, key, isOnce) { 2337 | if (Array.isArray(tree)) { 2338 | for (var i = 0; i < tree.length; i++) { 2339 | if (tree[i] && typeof tree[i] !== 'string') { 2340 | markStaticNode(tree[i], (key + "_" + i), isOnce); 2341 | } 2342 | } 2343 | } else { 2344 | markStaticNode(tree, key, isOnce); 2345 | } 2346 | } 2347 | 2348 | function markStaticNode (node, key, isOnce) { 2349 | node.isStatic = true; 2350 | node.key = key; 2351 | node.isOnce = isOnce; 2352 | } 2353 | 2354 | // filter resolution helper 2355 | var identity = function (_) { return _; }; 2356 | Vue.prototype._f = function resolveFilter (id) { 2357 | return resolveAsset(this.$options, 'filters', id, true) || identity 2358 | }; 2359 | 2360 | // render v-for 2361 | Vue.prototype._l = function renderList ( 2362 | val, 2363 | render 2364 | ) { 2365 | var ret, i, l, keys, key; 2366 | if (Array.isArray(val)) { 2367 | ret = new Array(val.length); 2368 | for (i = 0, l = val.length; i < l; i++) { 2369 | ret[i] = render(val[i], i); 2370 | } 2371 | } else if (typeof val === 'number') { 2372 | ret = new Array(val); 2373 | for (i = 0; i < val; i++) { 2374 | ret[i] = render(i + 1, i); 2375 | } 2376 | } else if (isObject(val)) { 2377 | keys = Object.keys(val); 2378 | ret = new Array(keys.length); 2379 | for (i = 0, l = keys.length; i < l; i++) { 2380 | key = keys[i]; 2381 | ret[i] = render(val[key], key, i); 2382 | } 2383 | } 2384 | return ret 2385 | }; 2386 | 2387 | // renderSlot 2388 | Vue.prototype._t = function ( 2389 | name, 2390 | fallback 2391 | ) { 2392 | var slotNodes = this.$slots[name]; 2393 | // warn duplicate slot usage 2394 | if (slotNodes && process.env.NODE_ENV !== 'production') { 2395 | slotNodes._rendered && warn( 2396 | "Duplicate presence of slot \"" + name + "\" found in the same render tree " + 2397 | "- this will likely cause render errors.", 2398 | this 2399 | ); 2400 | slotNodes._rendered = true; 2401 | } 2402 | return slotNodes || fallback 2403 | }; 2404 | 2405 | // apply v-bind object 2406 | Vue.prototype._b = function bindProps ( 2407 | data, 2408 | value, 2409 | asProp 2410 | ) { 2411 | if (value) { 2412 | if (!isObject(value)) { 2413 | process.env.NODE_ENV !== 'production' && warn( 2414 | 'v-bind without argument expects an Object or Array value', 2415 | this 2416 | ); 2417 | } else { 2418 | if (Array.isArray(value)) { 2419 | value = toObject(value); 2420 | } 2421 | for (var key in value) { 2422 | if (key === 'class' || key === 'style') { 2423 | data[key] = value[key]; 2424 | } else { 2425 | var hash = asProp || config.mustUseProp(key) 2426 | ? data.domProps || (data.domProps = {}) 2427 | : data.attrs || (data.attrs = {}); 2428 | hash[key] = value[key]; 2429 | } 2430 | } 2431 | } 2432 | } 2433 | return data 2434 | }; 2435 | 2436 | // expose v-on keyCodes 2437 | Vue.prototype._k = function getKeyCodes (key) { 2438 | return config.keyCodes[key] 2439 | }; 2440 | } 2441 | 2442 | function resolveSlots ( 2443 | renderChildren, 2444 | context 2445 | ) { 2446 | var slots = {}; 2447 | if (!renderChildren) { 2448 | return slots 2449 | } 2450 | var children = normalizeChildren(renderChildren) || []; 2451 | var defaultSlot = []; 2452 | var name, child; 2453 | for (var i = 0, l = children.length; i < l; i++) { 2454 | child = children[i]; 2455 | // named slots should only be respected if the vnode was rendered in the 2456 | // same context. 2457 | if ((child.context === context || child.functionalContext === context) && 2458 | child.data && (name = child.data.slot)) { 2459 | var slot = (slots[name] || (slots[name] = [])); 2460 | if (child.tag === 'template') { 2461 | slot.push.apply(slot, child.children); 2462 | } else { 2463 | slot.push(child); 2464 | } 2465 | } else { 2466 | defaultSlot.push(child); 2467 | } 2468 | } 2469 | // ignore single whitespace 2470 | if (defaultSlot.length && !( 2471 | defaultSlot.length === 1 && 2472 | (defaultSlot[0].text === ' ' || defaultSlot[0].isComment) 2473 | )) { 2474 | slots.default = defaultSlot; 2475 | } 2476 | return slots 2477 | } 2478 | 2479 | /* */ 2480 | 2481 | function initEvents (vm) { 2482 | vm._events = Object.create(null); 2483 | // init parent attached events 2484 | var listeners = vm.$options._parentListeners; 2485 | var on = bind(vm.$on, vm); 2486 | var off = bind(vm.$off, vm); 2487 | vm._updateListeners = function (listeners, oldListeners) { 2488 | updateListeners(listeners, oldListeners || {}, on, off, vm); 2489 | }; 2490 | if (listeners) { 2491 | vm._updateListeners(listeners); 2492 | } 2493 | } 2494 | 2495 | function eventsMixin (Vue) { 2496 | Vue.prototype.$on = function (event, fn) { 2497 | var vm = this;(vm._events[event] || (vm._events[event] = [])).push(fn); 2498 | return vm 2499 | }; 2500 | 2501 | Vue.prototype.$once = function (event, fn) { 2502 | var vm = this; 2503 | function on () { 2504 | vm.$off(event, on); 2505 | fn.apply(vm, arguments); 2506 | } 2507 | on.fn = fn; 2508 | vm.$on(event, on); 2509 | return vm 2510 | }; 2511 | 2512 | Vue.prototype.$off = function (event, fn) { 2513 | var vm = this; 2514 | // all 2515 | if (!arguments.length) { 2516 | vm._events = Object.create(null); 2517 | return vm 2518 | } 2519 | // specific event 2520 | var cbs = vm._events[event]; 2521 | if (!cbs) { 2522 | return vm 2523 | } 2524 | if (arguments.length === 1) { 2525 | vm._events[event] = null; 2526 | return vm 2527 | } 2528 | // specific handler 2529 | var cb; 2530 | var i = cbs.length; 2531 | while (i--) { 2532 | cb = cbs[i]; 2533 | if (cb === fn || cb.fn === fn) { 2534 | cbs.splice(i, 1); 2535 | break 2536 | } 2537 | } 2538 | return vm 2539 | }; 2540 | 2541 | Vue.prototype.$emit = function (event) { 2542 | var vm = this; 2543 | var cbs = vm._events[event]; 2544 | if (cbs) { 2545 | cbs = cbs.length > 1 ? toArray(cbs) : cbs; 2546 | var args = toArray(arguments, 1); 2547 | for (var i = 0, l = cbs.length; i < l; i++) { 2548 | cbs[i].apply(vm, args); 2549 | } 2550 | } 2551 | return vm 2552 | }; 2553 | } 2554 | 2555 | /* */ 2556 | 2557 | var uid = 0; 2558 | 2559 | function initMixin (Vue) { 2560 | Vue.prototype._init = function (options) { 2561 | var vm = this; 2562 | // a uid 2563 | vm._uid = uid++; 2564 | // a flag to avoid this being observed 2565 | vm._isVue = true; 2566 | // merge options 2567 | if (options && options._isComponent) { 2568 | // optimize internal component instantiation 2569 | // since dynamic options merging is pretty slow, and none of the 2570 | // internal component options needs special treatment. 2571 | initInternalComponent(vm, options); 2572 | } else { 2573 | vm.$options = mergeOptions( 2574 | resolveConstructorOptions(vm.constructor), 2575 | options || {}, 2576 | vm 2577 | ); 2578 | } 2579 | /* istanbul ignore else */ 2580 | if (process.env.NODE_ENV !== 'production') { 2581 | initProxy(vm); 2582 | } else { 2583 | vm._renderProxy = vm; 2584 | } 2585 | // expose real self 2586 | vm._self = vm; 2587 | initLifecycle(vm); 2588 | initEvents(vm); 2589 | callHook(vm, 'beforeCreate'); 2590 | initState(vm); 2591 | callHook(vm, 'created'); 2592 | initRender(vm); 2593 | }; 2594 | } 2595 | 2596 | function initInternalComponent (vm, options) { 2597 | var opts = vm.$options = Object.create(vm.constructor.options); 2598 | // doing this because it's faster than dynamic enumeration. 2599 | opts.parent = options.parent; 2600 | opts.propsData = options.propsData; 2601 | opts._parentVnode = options._parentVnode; 2602 | opts._parentListeners = options._parentListeners; 2603 | opts._renderChildren = options._renderChildren; 2604 | opts._componentTag = options._componentTag; 2605 | if (options.render) { 2606 | opts.render = options.render; 2607 | opts.staticRenderFns = options.staticRenderFns; 2608 | } 2609 | } 2610 | 2611 | function resolveConstructorOptions (Ctor) { 2612 | var options = Ctor.options; 2613 | if (Ctor.super) { 2614 | var superOptions = Ctor.super.options; 2615 | var cachedSuperOptions = Ctor.superOptions; 2616 | var extendOptions = Ctor.extendOptions; 2617 | if (superOptions !== cachedSuperOptions) { 2618 | // super option changed 2619 | Ctor.superOptions = superOptions; 2620 | extendOptions.render = options.render; 2621 | extendOptions.staticRenderFns = options.staticRenderFns; 2622 | options = Ctor.options = mergeOptions(superOptions, extendOptions); 2623 | if (options.name) { 2624 | options.components[options.name] = Ctor; 2625 | } 2626 | } 2627 | } 2628 | return options 2629 | } 2630 | 2631 | function Vue (options) { 2632 | if (process.env.NODE_ENV !== 'production' && 2633 | !(this instanceof Vue)) { 2634 | warn('Vue is a constructor and should be called with the `new` keyword'); 2635 | } 2636 | this._init(options); 2637 | } 2638 | 2639 | initMixin(Vue); 2640 | stateMixin(Vue); 2641 | eventsMixin(Vue); 2642 | lifecycleMixin(Vue); 2643 | renderMixin(Vue); 2644 | 2645 | /* */ 2646 | 2647 | /** 2648 | * Option overwriting strategies are functions that handle 2649 | * how to merge a parent option value and a child option 2650 | * value into the final value. 2651 | */ 2652 | var strats = config.optionMergeStrategies; 2653 | 2654 | /** 2655 | * Options with restrictions 2656 | */ 2657 | if (process.env.NODE_ENV !== 'production') { 2658 | strats.el = strats.propsData = function (parent, child, vm, key) { 2659 | if (!vm) { 2660 | warn( 2661 | "option \"" + key + "\" can only be used during instance " + 2662 | 'creation with the `new` keyword.' 2663 | ); 2664 | } 2665 | return defaultStrat(parent, child) 2666 | }; 2667 | } 2668 | 2669 | /** 2670 | * Helper that recursively merges two data objects together. 2671 | */ 2672 | function mergeData (to, from) { 2673 | var key, toVal, fromVal; 2674 | for (key in from) { 2675 | toVal = to[key]; 2676 | fromVal = from[key]; 2677 | if (!hasOwn(to, key)) { 2678 | set(to, key, fromVal); 2679 | } else if (isObject(toVal) && isObject(fromVal)) { 2680 | mergeData(toVal, fromVal); 2681 | } 2682 | } 2683 | return to 2684 | } 2685 | 2686 | /** 2687 | * Data 2688 | */ 2689 | strats.data = function ( 2690 | parentVal, 2691 | childVal, 2692 | vm 2693 | ) { 2694 | if (!vm) { 2695 | // in a Vue.extend merge, both should be functions 2696 | if (!childVal) { 2697 | return parentVal 2698 | } 2699 | if (typeof childVal !== 'function') { 2700 | process.env.NODE_ENV !== 'production' && warn( 2701 | 'The "data" option should be a function ' + 2702 | 'that returns a per-instance value in component ' + 2703 | 'definitions.', 2704 | vm 2705 | ); 2706 | return parentVal 2707 | } 2708 | if (!parentVal) { 2709 | return childVal 2710 | } 2711 | // when parentVal & childVal are both present, 2712 | // we need to return a function that returns the 2713 | // merged result of both functions... no need to 2714 | // check if parentVal is a function here because 2715 | // it has to be a function to pass previous merges. 2716 | return function mergedDataFn () { 2717 | return mergeData( 2718 | childVal.call(this), 2719 | parentVal.call(this) 2720 | ) 2721 | } 2722 | } else if (parentVal || childVal) { 2723 | return function mergedInstanceDataFn () { 2724 | // instance merge 2725 | var instanceData = typeof childVal === 'function' 2726 | ? childVal.call(vm) 2727 | : childVal; 2728 | var defaultData = typeof parentVal === 'function' 2729 | ? parentVal.call(vm) 2730 | : undefined; 2731 | if (instanceData) { 2732 | return mergeData(instanceData, defaultData) 2733 | } else { 2734 | return defaultData 2735 | } 2736 | } 2737 | } 2738 | }; 2739 | 2740 | /** 2741 | * Hooks and param attributes are merged as arrays. 2742 | */ 2743 | function mergeHook ( 2744 | parentVal, 2745 | childVal 2746 | ) { 2747 | return childVal 2748 | ? parentVal 2749 | ? parentVal.concat(childVal) 2750 | : Array.isArray(childVal) 2751 | ? childVal 2752 | : [childVal] 2753 | : parentVal 2754 | } 2755 | 2756 | config._lifecycleHooks.forEach(function (hook) { 2757 | strats[hook] = mergeHook; 2758 | }); 2759 | 2760 | /** 2761 | * Assets 2762 | * 2763 | * When a vm is present (instance creation), we need to do 2764 | * a three-way merge between constructor options, instance 2765 | * options and parent options. 2766 | */ 2767 | function mergeAssets (parentVal, childVal) { 2768 | var res = Object.create(parentVal || null); 2769 | return childVal 2770 | ? extend(res, childVal) 2771 | : res 2772 | } 2773 | 2774 | config._assetTypes.forEach(function (type) { 2775 | strats[type + 's'] = mergeAssets; 2776 | }); 2777 | 2778 | /** 2779 | * Watchers. 2780 | * 2781 | * Watchers hashes should not overwrite one 2782 | * another, so we merge them as arrays. 2783 | */ 2784 | strats.watch = function (parentVal, childVal) { 2785 | /* istanbul ignore if */ 2786 | if (!childVal) { return parentVal } 2787 | if (!parentVal) { return childVal } 2788 | var ret = {}; 2789 | extend(ret, parentVal); 2790 | for (var key in childVal) { 2791 | var parent = ret[key]; 2792 | var child = childVal[key]; 2793 | if (parent && !Array.isArray(parent)) { 2794 | parent = [parent]; 2795 | } 2796 | ret[key] = parent 2797 | ? parent.concat(child) 2798 | : [child]; 2799 | } 2800 | return ret 2801 | }; 2802 | 2803 | /** 2804 | * Other object hashes. 2805 | */ 2806 | strats.props = 2807 | strats.methods = 2808 | strats.computed = function (parentVal, childVal) { 2809 | if (!childVal) { return parentVal } 2810 | if (!parentVal) { return childVal } 2811 | var ret = Object.create(null); 2812 | extend(ret, parentVal); 2813 | extend(ret, childVal); 2814 | return ret 2815 | }; 2816 | 2817 | /** 2818 | * Default strategy. 2819 | */ 2820 | var defaultStrat = function (parentVal, childVal) { 2821 | return childVal === undefined 2822 | ? parentVal 2823 | : childVal 2824 | }; 2825 | 2826 | /** 2827 | * Make sure component options get converted to actual 2828 | * constructors. 2829 | */ 2830 | function normalizeComponents (options) { 2831 | if (options.components) { 2832 | var components = options.components; 2833 | var normalized = options.components = {}; 2834 | var def; 2835 | for (var key in components) { 2836 | var lower = key.toLowerCase(); 2837 | if (isBuiltInTag(lower) || config.isReservedTag(lower)) { 2838 | process.env.NODE_ENV !== 'production' && warn( 2839 | 'Do not use built-in or reserved HTML elements as component ' + 2840 | 'id: ' + key 2841 | ); 2842 | continue 2843 | } 2844 | def = components[key]; 2845 | normalized[key] = isPlainObject(def) ? Vue.extend(def) : def; 2846 | } 2847 | } 2848 | } 2849 | 2850 | /** 2851 | * Ensure all props option syntax are normalized into the 2852 | * Object-based format. 2853 | */ 2854 | function normalizeProps (options) { 2855 | var props = options.props; 2856 | if (!props) { return } 2857 | var res = {}; 2858 | var i, val, name; 2859 | if (Array.isArray(props)) { 2860 | i = props.length; 2861 | while (i--) { 2862 | val = props[i]; 2863 | if (typeof val === 'string') { 2864 | name = camelize(val); 2865 | res[name] = { type: null }; 2866 | } else if (process.env.NODE_ENV !== 'production') { 2867 | warn('props must be strings when using array syntax.'); 2868 | } 2869 | } 2870 | } else if (isPlainObject(props)) { 2871 | for (var key in props) { 2872 | val = props[key]; 2873 | name = camelize(key); 2874 | res[name] = isPlainObject(val) 2875 | ? val 2876 | : { type: val }; 2877 | } 2878 | } 2879 | options.props = res; 2880 | } 2881 | 2882 | /** 2883 | * Normalize raw function directives into object format. 2884 | */ 2885 | function normalizeDirectives (options) { 2886 | var dirs = options.directives; 2887 | if (dirs) { 2888 | for (var key in dirs) { 2889 | var def = dirs[key]; 2890 | if (typeof def === 'function') { 2891 | dirs[key] = { bind: def, update: def }; 2892 | } 2893 | } 2894 | } 2895 | } 2896 | 2897 | /** 2898 | * Merge two option objects into a new one. 2899 | * Core utility used in both instantiation and inheritance. 2900 | */ 2901 | function mergeOptions ( 2902 | parent, 2903 | child, 2904 | vm 2905 | ) { 2906 | normalizeComponents(child); 2907 | normalizeProps(child); 2908 | normalizeDirectives(child); 2909 | var extendsFrom = child.extends; 2910 | if (extendsFrom) { 2911 | parent = typeof extendsFrom === 'function' 2912 | ? mergeOptions(parent, extendsFrom.options, vm) 2913 | : mergeOptions(parent, extendsFrom, vm); 2914 | } 2915 | if (child.mixins) { 2916 | for (var i = 0, l = child.mixins.length; i < l; i++) { 2917 | var mixin = child.mixins[i]; 2918 | if (mixin.prototype instanceof Vue) { 2919 | mixin = mixin.options; 2920 | } 2921 | parent = mergeOptions(parent, mixin, vm); 2922 | } 2923 | } 2924 | var options = {}; 2925 | var key; 2926 | for (key in parent) { 2927 | mergeField(key); 2928 | } 2929 | for (key in child) { 2930 | if (!hasOwn(parent, key)) { 2931 | mergeField(key); 2932 | } 2933 | } 2934 | function mergeField (key) { 2935 | var strat = strats[key] || defaultStrat; 2936 | options[key] = strat(parent[key], child[key], vm, key); 2937 | } 2938 | return options 2939 | } 2940 | 2941 | /** 2942 | * Resolve an asset. 2943 | * This function is used because child instances need access 2944 | * to assets defined in its ancestor chain. 2945 | */ 2946 | function resolveAsset ( 2947 | options, 2948 | type, 2949 | id, 2950 | warnMissing 2951 | ) { 2952 | /* istanbul ignore if */ 2953 | if (typeof id !== 'string') { 2954 | return 2955 | } 2956 | var assets = options[type]; 2957 | var res = assets[id] || 2958 | // camelCase ID 2959 | assets[camelize(id)] || 2960 | // Pascal Case ID 2961 | assets[capitalize(camelize(id))]; 2962 | if (process.env.NODE_ENV !== 'production' && warnMissing && !res) { 2963 | warn( 2964 | 'Failed to resolve ' + type.slice(0, -1) + ': ' + id, 2965 | options 2966 | ); 2967 | } 2968 | return res 2969 | } 2970 | 2971 | /* */ 2972 | 2973 | function validateProp ( 2974 | key, 2975 | propOptions, 2976 | propsData, 2977 | vm 2978 | ) { 2979 | var prop = propOptions[key]; 2980 | var absent = !hasOwn(propsData, key); 2981 | var value = propsData[key]; 2982 | // handle boolean props 2983 | if (isBooleanType(prop.type)) { 2984 | if (absent && !hasOwn(prop, 'default')) { 2985 | value = false; 2986 | } else if (value === '' || value === hyphenate(key)) { 2987 | value = true; 2988 | } 2989 | } 2990 | // check default value 2991 | if (value === undefined) { 2992 | value = getPropDefaultValue(vm, prop, key); 2993 | // since the default value is a fresh copy, 2994 | // make sure to observe it. 2995 | var prevShouldConvert = observerState.shouldConvert; 2996 | observerState.shouldConvert = true; 2997 | observe(value); 2998 | observerState.shouldConvert = prevShouldConvert; 2999 | } 3000 | if (process.env.NODE_ENV !== 'production') { 3001 | assertProp(prop, key, value, vm, absent); 3002 | } 3003 | return value 3004 | } 3005 | 3006 | /** 3007 | * Get the default value of a prop. 3008 | */ 3009 | function getPropDefaultValue (vm, prop, name) { 3010 | // no default, return undefined 3011 | if (!hasOwn(prop, 'default')) { 3012 | return undefined 3013 | } 3014 | var def = prop.default; 3015 | // warn against non-factory defaults for Object & Array 3016 | if (isObject(def)) { 3017 | process.env.NODE_ENV !== 'production' && warn( 3018 | 'Invalid default value for prop "' + name + '": ' + 3019 | 'Props with type Object/Array must use a factory function ' + 3020 | 'to return the default value.', 3021 | vm 3022 | ); 3023 | } 3024 | // call factory function for non-Function types 3025 | return typeof def === 'function' && prop.type !== Function 3026 | ? def.call(vm) 3027 | : def 3028 | } 3029 | 3030 | /** 3031 | * Assert whether a prop is valid. 3032 | */ 3033 | function assertProp ( 3034 | prop, 3035 | name, 3036 | value, 3037 | vm, 3038 | absent 3039 | ) { 3040 | if (prop.required && absent) { 3041 | warn( 3042 | 'Missing required prop: "' + name + '"', 3043 | vm 3044 | ); 3045 | return 3046 | } 3047 | if (value == null && !prop.required) { 3048 | return 3049 | } 3050 | var type = prop.type; 3051 | var valid = !type || type === true; 3052 | var expectedTypes = []; 3053 | if (type) { 3054 | if (!Array.isArray(type)) { 3055 | type = [type]; 3056 | } 3057 | for (var i = 0; i < type.length && !valid; i++) { 3058 | var assertedType = assertType(value, type[i]); 3059 | expectedTypes.push(assertedType.expectedType); 3060 | valid = assertedType.valid; 3061 | } 3062 | } 3063 | if (!valid) { 3064 | warn( 3065 | 'Invalid prop: type check failed for prop "' + name + '".' + 3066 | ' Expected ' + expectedTypes.map(capitalize).join(', ') + 3067 | ', got ' + Object.prototype.toString.call(value).slice(8, -1) + '.', 3068 | vm 3069 | ); 3070 | return 3071 | } 3072 | var validator = prop.validator; 3073 | if (validator) { 3074 | if (!validator(value)) { 3075 | warn( 3076 | 'Invalid prop: custom validator check failed for prop "' + name + '".', 3077 | vm 3078 | ); 3079 | } 3080 | } 3081 | } 3082 | 3083 | /** 3084 | * Assert the type of a value 3085 | */ 3086 | function assertType (value, type) { 3087 | var valid; 3088 | var expectedType = getType(type); 3089 | if (expectedType === 'String') { 3090 | valid = typeof value === (expectedType = 'string'); 3091 | } else if (expectedType === 'Number') { 3092 | valid = typeof value === (expectedType = 'number'); 3093 | } else if (expectedType === 'Boolean') { 3094 | valid = typeof value === (expectedType = 'boolean'); 3095 | } else if (expectedType === 'Function') { 3096 | valid = typeof value === (expectedType = 'function'); 3097 | } else if (expectedType === 'Object') { 3098 | valid = isPlainObject(value); 3099 | } else if (expectedType === 'Array') { 3100 | valid = Array.isArray(value); 3101 | } else { 3102 | valid = value instanceof type; 3103 | } 3104 | return { 3105 | valid: valid, 3106 | expectedType: expectedType 3107 | } 3108 | } 3109 | 3110 | /** 3111 | * Use function string name to check built-in types, 3112 | * because a simple equality check will fail when running 3113 | * across different vms / iframes. 3114 | */ 3115 | function getType (fn) { 3116 | var match = fn && fn.toString().match(/^\s*function (\w+)/); 3117 | return match && match[1] 3118 | } 3119 | 3120 | function isBooleanType (fn) { 3121 | if (!Array.isArray(fn)) { 3122 | return getType(fn) === 'Boolean' 3123 | } 3124 | for (var i = 0, len = fn.length; i < len; i++) { 3125 | if (getType(fn[i]) === 'Boolean') { 3126 | return true 3127 | } 3128 | } 3129 | /* istanbul ignore next */ 3130 | return false 3131 | } 3132 | 3133 | /* */ 3134 | 3135 | // attributes that should be using props for binding 3136 | var mustUseProp = makeMap('value,selected,checked,muted'); 3137 | 3138 | var isEnumeratedAttr = makeMap('contenteditable,draggable,spellcheck'); 3139 | 3140 | var isBooleanAttr = makeMap( 3141 | 'allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,' + 3142 | 'default,defaultchecked,defaultmuted,defaultselected,defer,disabled,' + 3143 | 'enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,' + 3144 | 'muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,' + 3145 | 'required,reversed,scoped,seamless,selected,sortable,translate,' + 3146 | 'truespeed,typemustmatch,visible' 3147 | ); 3148 | 3149 | var isAttr = makeMap( 3150 | 'accept,accept-charset,accesskey,action,align,alt,async,autocomplete,' + 3151 | 'autofocus,autoplay,autosave,bgcolor,border,buffered,challenge,charset,' + 3152 | 'checked,cite,class,code,codebase,color,cols,colspan,content,http-equiv,' + 3153 | 'name,contenteditable,contextmenu,controls,coords,data,datetime,default,' + 3154 | 'defer,dir,dirname,disabled,download,draggable,dropzone,enctype,method,for,' + 3155 | 'form,formaction,headers,,height,hidden,high,href,hreflang,http-equiv,' + 3156 | 'icon,id,ismap,itemprop,keytype,kind,label,lang,language,list,loop,low,' + 3157 | 'manifest,max,maxlength,media,method,GET,POST,min,multiple,email,file,' + 3158 | 'muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,' + 3159 | 'preload,radiogroup,readonly,rel,required,reversed,rows,rowspan,sandbox,' + 3160 | 'scope,scoped,seamless,selected,shape,size,type,text,password,sizes,span,' + 3161 | 'spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,' + 3162 | 'target,title,type,usemap,value,width,wrap' 3163 | ); 3164 | 3165 | 3166 | 3167 | 3168 | 3169 | var isXlink = function (name) { 3170 | return name.charAt(5) === ':' && name.slice(0, 5) === 'xlink' 3171 | }; 3172 | 3173 | /* */ 3174 | 3175 | 3176 | 3177 | function mergeClassData (child, parent) { 3178 | return { 3179 | staticClass: concat(child.staticClass, parent.staticClass), 3180 | class: child.class 3181 | ? [child.class, parent.class] 3182 | : parent.class 3183 | } 3184 | } 3185 | 3186 | function genClassFromData (data) { 3187 | var dynamicClass = data.class; 3188 | var staticClass = data.staticClass; 3189 | if (staticClass || dynamicClass) { 3190 | return concat(staticClass, stringifyClass(dynamicClass)) 3191 | } 3192 | /* istanbul ignore next */ 3193 | return '' 3194 | } 3195 | 3196 | function concat (a, b) { 3197 | return a ? b ? (a + ' ' + b) : a : (b || '') 3198 | } 3199 | 3200 | function stringifyClass (value) { 3201 | var res = ''; 3202 | if (!value) { 3203 | return res 3204 | } 3205 | if (typeof value === 'string') { 3206 | return value 3207 | } 3208 | if (Array.isArray(value)) { 3209 | var stringified; 3210 | for (var i = 0, l = value.length; i < l; i++) { 3211 | if (value[i]) { 3212 | if ((stringified = stringifyClass(value[i]))) { 3213 | res += stringified + ' '; 3214 | } 3215 | } 3216 | } 3217 | return res.slice(0, -1) 3218 | } 3219 | if (isObject(value)) { 3220 | for (var key in value) { 3221 | if (value[key]) { res += key + ' '; } 3222 | } 3223 | return res.slice(0, -1) 3224 | } 3225 | /* istanbul ignore next */ 3226 | return res 3227 | } 3228 | 3229 | /* */ 3230 | 3231 | 3232 | 3233 | var isHTMLTag = makeMap( 3234 | 'html,body,base,head,link,meta,style,title,' + 3235 | 'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' + 3236 | 'div,dd,dl,dt,figcaption,figure,hr,img,li,main,ol,p,pre,ul,' + 3237 | 'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' + 3238 | 's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' + 3239 | 'embed,object,param,source,canvas,script,noscript,del,ins,' + 3240 | 'caption,col,colgroup,table,thead,tbody,td,th,tr,' + 3241 | 'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' + 3242 | 'output,progress,select,textarea,' + 3243 | 'details,dialog,menu,menuitem,summary,' + 3244 | 'content,element,shadow,template' 3245 | ); 3246 | 3247 | var isUnaryTag = makeMap( 3248 | 'area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' + 3249 | 'link,meta,param,source,track,wbr', 3250 | true 3251 | ); 3252 | 3253 | // Elements that you can, intentionally, leave open 3254 | // (and which close themselves) 3255 | var canBeLeftOpenTag = makeMap( 3256 | 'colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source', 3257 | true 3258 | ); 3259 | 3260 | // HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3 3261 | // Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content 3262 | var isNonPhrasingTag = makeMap( 3263 | 'address,article,aside,base,blockquote,body,caption,col,colgroup,dd,' + 3264 | 'details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,' + 3265 | 'h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,' + 3266 | 'optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,' + 3267 | 'title,tr,track', 3268 | true 3269 | ); 3270 | 3271 | // this map is intentionally selective, only covering SVG elements that may 3272 | // contain child elements. 3273 | var isSVG = makeMap( 3274 | 'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font,' + 3275 | 'font-face,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' + 3276 | 'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view', 3277 | true 3278 | ); 3279 | 3280 | var isPreTag = function (tag) { return tag === 'pre'; }; 3281 | 3282 | var isReservedTag = function (tag) { 3283 | return isHTMLTag(tag) || isSVG(tag) 3284 | }; 3285 | 3286 | function getTagNamespace (tag) { 3287 | if (isSVG(tag)) { 3288 | return 'svg' 3289 | } 3290 | // basic support for MathML 3291 | // note it doesn't support other MathML elements being component roots 3292 | if (tag === 'math') { 3293 | return 'math' 3294 | } 3295 | } 3296 | 3297 | var unknownElementCache = Object.create(null); 3298 | 3299 | /* */ 3300 | 3301 | /** 3302 | * Query an element selector if it's not an element already. 3303 | */ 3304 | 3305 | /** 3306 | * Not type-checking this file because it's mostly vendor code. 3307 | */ 3308 | 3309 | /*! 3310 | * HTML Parser By John Resig (ejohn.org) 3311 | * Modified by Juriy "kangax" Zaytsev 3312 | * Original code by Erik Arvidsson, Mozilla Public License 3313 | * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js 3314 | */ 3315 | 3316 | // Regular Expressions for parsing tags and attributes 3317 | var singleAttrIdentifier = /([^\s"'<>/=]+)/; 3318 | var singleAttrAssign = /(?:=)/; 3319 | var singleAttrValues = [ 3320 | // attr value double quotes 3321 | /"([^"]*)"+/.source, 3322 | // attr value, single quotes 3323 | /'([^']*)'+/.source, 3324 | // attr value, no quotes 3325 | /([^\s"'=<>`]+)/.source 3326 | ]; 3327 | var attribute = new RegExp( 3328 | '^\\s*' + singleAttrIdentifier.source + 3329 | '(?:\\s*(' + singleAttrAssign.source + ')' + 3330 | '\\s*(?:' + singleAttrValues.join('|') + '))?' 3331 | ); 3332 | 3333 | // could use https://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-QName 3334 | // but for Vue templates we can enforce a simple charset 3335 | var ncname = '[a-zA-Z_][\\w\\-\\.]*'; 3336 | var qnameCapture = '((?:' + ncname + '\\:)?' + ncname + ')'; 3337 | var startTagOpen = new RegExp('^<' + qnameCapture); 3338 | var startTagClose = /^\s*(\/?)>/; 3339 | var endTag = new RegExp('^<\\/' + qnameCapture + '[^>]*>'); 3340 | var doctype = /^]+>/i; 3341 | 3342 | var IS_REGEX_CAPTURING_BROKEN = false; 3343 | 'x'.replace(/x(.)?/g, function (m, g) { 3344 | IS_REGEX_CAPTURING_BROKEN = g === ''; 3345 | }); 3346 | 3347 | // Special Elements (can contain anything) 3348 | var isScriptOrStyle = makeMap('script,style', true); 3349 | var hasLang = function (attr) { return attr.name === 'lang' && attr.value !== 'html'; }; 3350 | var isSpecialTag = function (tag, isSFC, stack) { 3351 | if (isScriptOrStyle(tag)) { 3352 | return true 3353 | } 3354 | // top-level template that has a pre-processor 3355 | if ( 3356 | isSFC && 3357 | tag === 'template' && 3358 | stack.length === 1 && 3359 | stack[0].attrs.some(hasLang) 3360 | ) { 3361 | return true 3362 | } 3363 | return false 3364 | }; 3365 | 3366 | var reCache = {}; 3367 | 3368 | var ltRE = /</g; 3369 | var gtRE = />/g; 3370 | var nlRE = / /g; 3371 | var ampRE = /&/g; 3372 | var quoteRE = /"/g; 3373 | 3374 | function decodeAttr (value, shouldDecodeNewlines) { 3375 | if (shouldDecodeNewlines) { 3376 | value = value.replace(nlRE, '\n'); 3377 | } 3378 | return value 3379 | .replace(ltRE, '<') 3380 | .replace(gtRE, '>') 3381 | .replace(ampRE, '&') 3382 | .replace(quoteRE, '"') 3383 | } 3384 | 3385 | function parseHTML (html, options) { 3386 | var stack = []; 3387 | var expectHTML = options.expectHTML; 3388 | var isUnaryTag$$1 = options.isUnaryTag || no; 3389 | var index = 0; 3390 | var last, lastTag; 3391 | while (html) { 3392 | last = html; 3393 | // Make sure we're not in a script or style element 3394 | if (!lastTag || !isSpecialTag(lastTag, options.sfc, stack)) { 3395 | var textEnd = html.indexOf('<'); 3396 | if (textEnd === 0) { 3397 | // Comment: 3398 | if (/^'); 3400 | 3401 | if (commentEnd >= 0) { 3402 | advance(commentEnd + 3); 3403 | continue 3404 | } 3405 | } 3406 | 3407 | // http://en.wikipedia.org/wiki/Conditional_comment#Downlevel-revealed_conditional_comment 3408 | if (/^'); 3410 | 3411 | if (conditionalEnd >= 0) { 3412 | advance(conditionalEnd + 2); 3413 | continue 3414 | } 3415 | } 3416 | 3417 | // Doctype: 3418 | var doctypeMatch = html.match(doctype); 3419 | if (doctypeMatch) { 3420 | advance(doctypeMatch[0].length); 3421 | continue 3422 | } 3423 | 3424 | // End tag: 3425 | var endTagMatch = html.match(endTag); 3426 | if (endTagMatch) { 3427 | var curIndex = index; 3428 | advance(endTagMatch[0].length); 3429 | parseEndTag(endTagMatch[0], endTagMatch[1], curIndex, index); 3430 | continue 3431 | } 3432 | 3433 | // Start tag: 3434 | var startTagMatch = parseStartTag(); 3435 | if (startTagMatch) { 3436 | handleStartTag(startTagMatch); 3437 | continue 3438 | } 3439 | } 3440 | 3441 | var text = (void 0), rest$1 = (void 0); 3442 | if (textEnd > 0) { 3443 | rest$1 = html.slice(textEnd); 3444 | while (!startTagOpen.test(rest$1) && !endTag.test(rest$1)) { 3445 | // < in plain text, be forgiving and treat it as text 3446 | textEnd += rest$1.indexOf('<', 1); 3447 | rest$1 = html.slice(textEnd); 3448 | } 3449 | text = html.substring(0, textEnd); 3450 | advance(textEnd); 3451 | } 3452 | 3453 | if (textEnd < 0) { 3454 | text = html; 3455 | html = ''; 3456 | } 3457 | 3458 | if (options.chars && text) { 3459 | options.chars(text); 3460 | } 3461 | } else { 3462 | var stackedTag = lastTag.toLowerCase(); 3463 | var reStackedTag = reCache[stackedTag] || (reCache[stackedTag] = new RegExp('([\\s\\S]*?)(]*>)', 'i')); 3464 | var endTagLength = 0; 3465 | var rest = html.replace(reStackedTag, function (all, text, endTag) { 3466 | endTagLength = endTag.length; 3467 | if (stackedTag !== 'script' && stackedTag !== 'style' && stackedTag !== 'noscript') { 3468 | text = text 3469 | .replace(//g, '$1') 3470 | .replace(//g, '$1'); 3471 | } 3472 | if (options.chars) { 3473 | options.chars(text); 3474 | } 3475 | return '' 3476 | }); 3477 | index += html.length - rest.length; 3478 | html = rest; 3479 | parseEndTag('', stackedTag, index - endTagLength, index); 3480 | } 3481 | 3482 | if (html === last) { 3483 | throw new Error('Error parsing template:\n\n' + html) 3484 | } 3485 | } 3486 | 3487 | // Clean up any remaining tags 3488 | parseEndTag(); 3489 | 3490 | function advance (n) { 3491 | index += n; 3492 | html = html.substring(n); 3493 | } 3494 | 3495 | function parseStartTag () { 3496 | var start = html.match(startTagOpen); 3497 | if (start) { 3498 | var match = { 3499 | tagName: start[1], 3500 | attrs: [], 3501 | start: index 3502 | }; 3503 | advance(start[0].length); 3504 | var end, attr; 3505 | while (!(end = html.match(startTagClose)) && (attr = html.match(attribute))) { 3506 | advance(attr[0].length); 3507 | match.attrs.push(attr); 3508 | } 3509 | if (end) { 3510 | match.unarySlash = end[1]; 3511 | advance(end[0].length); 3512 | match.end = index; 3513 | return match 3514 | } 3515 | } 3516 | } 3517 | 3518 | function handleStartTag (match) { 3519 | var tagName = match.tagName; 3520 | var unarySlash = match.unarySlash; 3521 | 3522 | if (expectHTML) { 3523 | if (lastTag === 'p' && isNonPhrasingTag(tagName)) { 3524 | parseEndTag('', lastTag); 3525 | } 3526 | if (canBeLeftOpenTag(tagName) && lastTag === tagName) { 3527 | parseEndTag('', tagName); 3528 | } 3529 | } 3530 | 3531 | var unary = isUnaryTag$$1(tagName) || tagName === 'html' && lastTag === 'head' || !!unarySlash; 3532 | 3533 | var l = match.attrs.length; 3534 | var attrs = new Array(l); 3535 | for (var i = 0; i < l; i++) { 3536 | var args = match.attrs[i]; 3537 | // hackish work around FF bug https://bugzilla.mozilla.org/show_bug.cgi?id=369778 3538 | if (IS_REGEX_CAPTURING_BROKEN && args[0].indexOf('""') === -1) { 3539 | if (args[3] === '') { delete args[3]; } 3540 | if (args[4] === '') { delete args[4]; } 3541 | if (args[5] === '') { delete args[5]; } 3542 | } 3543 | var value = args[3] || args[4] || args[5] || ''; 3544 | attrs[i] = { 3545 | name: args[1], 3546 | value: decodeAttr( 3547 | value, 3548 | options.shouldDecodeNewlines 3549 | ) 3550 | }; 3551 | } 3552 | 3553 | if (!unary) { 3554 | stack.push({ tag: tagName, attrs: attrs }); 3555 | lastTag = tagName; 3556 | unarySlash = ''; 3557 | } 3558 | 3559 | if (options.start) { 3560 | options.start(tagName, attrs, unary, match.start, match.end); 3561 | } 3562 | } 3563 | 3564 | function parseEndTag (tag, tagName, start, end) { 3565 | var pos; 3566 | if (start == null) { start = index; } 3567 | if (end == null) { end = index; } 3568 | 3569 | // Find the closest opened tag of the same type 3570 | if (tagName) { 3571 | var needle = tagName.toLowerCase(); 3572 | for (pos = stack.length - 1; pos >= 0; pos--) { 3573 | if (stack[pos].tag.toLowerCase() === needle) { 3574 | break 3575 | } 3576 | } 3577 | } else { 3578 | // If no tag name is provided, clean shop 3579 | pos = 0; 3580 | } 3581 | 3582 | if (pos >= 0) { 3583 | // Close all the open elements, up the stack 3584 | for (var i = stack.length - 1; i >= pos; i--) { 3585 | if (options.end) { 3586 | options.end(stack[i].tag, start, end); 3587 | } 3588 | } 3589 | 3590 | // Remove the open elements from the stack 3591 | stack.length = pos; 3592 | lastTag = pos && stack[pos - 1].tag; 3593 | } else if (tagName.toLowerCase() === 'br') { 3594 | if (options.start) { 3595 | options.start(tagName, [], true, start, end); 3596 | } 3597 | } else if (tagName.toLowerCase() === 'p') { 3598 | if (options.start) { 3599 | options.start(tagName, [], false, start, end); 3600 | } 3601 | if (options.end) { 3602 | options.end(tagName, start, end); 3603 | } 3604 | } 3605 | } 3606 | } 3607 | 3608 | /* */ 3609 | 3610 | function parseFilters (exp) { 3611 | var inSingle = false; 3612 | var inDouble = false; 3613 | var curly = 0; 3614 | var square = 0; 3615 | var paren = 0; 3616 | var lastFilterIndex = 0; 3617 | var c, prev, i, expression, filters; 3618 | 3619 | for (i = 0; i < exp.length; i++) { 3620 | prev = c; 3621 | c = exp.charCodeAt(i); 3622 | if (inSingle) { 3623 | // check single quote 3624 | if (c === 0x27 && prev !== 0x5C) { inSingle = !inSingle; } 3625 | } else if (inDouble) { 3626 | // check double quote 3627 | if (c === 0x22 && prev !== 0x5C) { inDouble = !inDouble; } 3628 | } else if ( 3629 | c === 0x7C && // pipe 3630 | exp.charCodeAt(i + 1) !== 0x7C && 3631 | exp.charCodeAt(i - 1) !== 0x7C && 3632 | !curly && !square && !paren 3633 | ) { 3634 | if (expression === undefined) { 3635 | // first filter, end of expression 3636 | lastFilterIndex = i + 1; 3637 | expression = exp.slice(0, i).trim(); 3638 | } else { 3639 | pushFilter(); 3640 | } 3641 | } else { 3642 | switch (c) { 3643 | case 0x22: inDouble = true; break // " 3644 | case 0x27: inSingle = true; break // ' 3645 | case 0x28: paren++; break // ( 3646 | case 0x29: paren--; break // ) 3647 | case 0x5B: square++; break // [ 3648 | case 0x5D: square--; break // ] 3649 | case 0x7B: curly++; break // { 3650 | case 0x7D: curly--; break // } 3651 | } 3652 | } 3653 | } 3654 | 3655 | if (expression === undefined) { 3656 | expression = exp.slice(0, i).trim(); 3657 | } else if (lastFilterIndex !== 0) { 3658 | pushFilter(); 3659 | } 3660 | 3661 | function pushFilter () { 3662 | (filters || (filters = [])).push(exp.slice(lastFilterIndex, i).trim()); 3663 | lastFilterIndex = i + 1; 3664 | } 3665 | 3666 | if (filters) { 3667 | for (i = 0; i < filters.length; i++) { 3668 | expression = wrapFilter(expression, filters[i]); 3669 | } 3670 | } 3671 | 3672 | return expression 3673 | } 3674 | 3675 | function wrapFilter (exp, filter) { 3676 | var i = filter.indexOf('('); 3677 | if (i < 0) { 3678 | // _f: resolveFilter 3679 | return ("_f(\"" + filter + "\")(" + exp + ")") 3680 | } else { 3681 | var name = filter.slice(0, i); 3682 | var args = filter.slice(i + 1); 3683 | return ("_f(\"" + name + "\")(" + exp + "," + args) 3684 | } 3685 | } 3686 | 3687 | /* */ 3688 | 3689 | var defaultTagRE = /\{\{((?:.|\n)+?)\}\}/g; 3690 | var regexEscapeRE = /[-.*+?^${}()|[\]/\\]/g; 3691 | 3692 | var buildRegex = cached(function (delimiters) { 3693 | var open = delimiters[0].replace(regexEscapeRE, '\\$&'); 3694 | var close = delimiters[1].replace(regexEscapeRE, '\\$&'); 3695 | return new RegExp(open + '((?:.|\\n)+?)' + close, 'g') 3696 | }); 3697 | 3698 | function parseText ( 3699 | text, 3700 | delimiters 3701 | ) { 3702 | var tagRE = delimiters ? buildRegex(delimiters) : defaultTagRE; 3703 | if (!tagRE.test(text)) { 3704 | return 3705 | } 3706 | var tokens = []; 3707 | var lastIndex = tagRE.lastIndex = 0; 3708 | var match, index; 3709 | while ((match = tagRE.exec(text))) { 3710 | index = match.index; 3711 | // push text token 3712 | if (index > lastIndex) { 3713 | tokens.push(JSON.stringify(text.slice(lastIndex, index))); 3714 | } 3715 | // tag token 3716 | var exp = parseFilters(match[1].trim()); 3717 | tokens.push(("_s(" + exp + ")")); 3718 | lastIndex = index + match[0].length; 3719 | } 3720 | if (lastIndex < text.length) { 3721 | tokens.push(JSON.stringify(text.slice(lastIndex))); 3722 | } 3723 | return tokens.join('+') 3724 | } 3725 | 3726 | /* */ 3727 | 3728 | function baseWarn (msg) { 3729 | console.error(("[Vue parser]: " + msg)); 3730 | } 3731 | 3732 | function pluckModuleFunction ( 3733 | modules, 3734 | key 3735 | ) { 3736 | return modules 3737 | ? modules.map(function (m) { return m[key]; }).filter(function (_) { return _; }) 3738 | : [] 3739 | } 3740 | 3741 | function addProp (el, name, value) { 3742 | (el.props || (el.props = [])).push({ name: name, value: value }); 3743 | } 3744 | 3745 | function addAttr (el, name, value) { 3746 | (el.attrs || (el.attrs = [])).push({ name: name, value: value }); 3747 | } 3748 | 3749 | function addDirective ( 3750 | el, 3751 | name, 3752 | rawName, 3753 | value, 3754 | arg, 3755 | modifiers 3756 | ) { 3757 | (el.directives || (el.directives = [])).push({ name: name, rawName: rawName, value: value, arg: arg, modifiers: modifiers }); 3758 | } 3759 | 3760 | function addHandler ( 3761 | el, 3762 | name, 3763 | value, 3764 | modifiers, 3765 | important 3766 | ) { 3767 | // check capture modifier 3768 | if (modifiers && modifiers.capture) { 3769 | delete modifiers.capture; 3770 | name = '!' + name; // mark the event as captured 3771 | } 3772 | var events; 3773 | if (modifiers && modifiers.native) { 3774 | delete modifiers.native; 3775 | events = el.nativeEvents || (el.nativeEvents = {}); 3776 | } else { 3777 | events = el.events || (el.events = {}); 3778 | } 3779 | var newHandler = { value: value, modifiers: modifiers }; 3780 | var handlers = events[name]; 3781 | /* istanbul ignore if */ 3782 | if (Array.isArray(handlers)) { 3783 | important ? handlers.unshift(newHandler) : handlers.push(newHandler); 3784 | } else if (handlers) { 3785 | events[name] = important ? [newHandler, handlers] : [handlers, newHandler]; 3786 | } else { 3787 | events[name] = newHandler; 3788 | } 3789 | } 3790 | 3791 | function getBindingAttr ( 3792 | el, 3793 | name, 3794 | getStatic 3795 | ) { 3796 | var dynamicValue = 3797 | getAndRemoveAttr(el, ':' + name) || 3798 | getAndRemoveAttr(el, 'v-bind:' + name); 3799 | if (dynamicValue != null) { 3800 | return dynamicValue 3801 | } else if (getStatic !== false) { 3802 | var staticValue = getAndRemoveAttr(el, name); 3803 | if (staticValue != null) { 3804 | return JSON.stringify(staticValue) 3805 | } 3806 | } 3807 | } 3808 | 3809 | function getAndRemoveAttr (el, name) { 3810 | var val; 3811 | if ((val = el.attrsMap[name]) != null) { 3812 | var list = el.attrsList; 3813 | for (var i = 0, l = list.length; i < l; i++) { 3814 | if (list[i].name === name) { 3815 | list.splice(i, 1); 3816 | break 3817 | } 3818 | } 3819 | } 3820 | return val 3821 | } 3822 | 3823 | /* */ 3824 | 3825 | var dirRE = /^v-|^@|^:/; 3826 | var forAliasRE = /(.*?)\s+(?:in|of)\s+(.*)/; 3827 | var forIteratorRE = /\(([^,]*),([^,]*)(?:,([^,]*))?\)/; 3828 | var bindRE = /^:|^v-bind:/; 3829 | var onRE = /^@|^v-on:/; 3830 | var argRE = /:(.*)$/; 3831 | var modifierRE = /\.[^.]+/g; 3832 | var specialNewlineRE = /\u2028|\u2029/g; 3833 | 3834 | var decodeHTMLCached = cached(he.decode); 3835 | 3836 | // configurable state 3837 | var warn$1; 3838 | var platformGetTagNamespace; 3839 | var platformMustUseProp; 3840 | var platformIsPreTag; 3841 | var preTransforms; 3842 | var transforms; 3843 | var postTransforms; 3844 | var delimiters; 3845 | 3846 | /** 3847 | * Convert HTML string to AST. 3848 | */ 3849 | function parse ( 3850 | template, 3851 | options 3852 | ) { 3853 | warn$1 = options.warn || baseWarn; 3854 | platformGetTagNamespace = options.getTagNamespace || no; 3855 | platformMustUseProp = options.mustUseProp || no; 3856 | platformIsPreTag = options.isPreTag || no; 3857 | preTransforms = pluckModuleFunction(options.modules, 'preTransformNode'); 3858 | transforms = pluckModuleFunction(options.modules, 'transformNode'); 3859 | postTransforms = pluckModuleFunction(options.modules, 'postTransformNode'); 3860 | delimiters = options.delimiters; 3861 | var stack = []; 3862 | var preserveWhitespace = options.preserveWhitespace !== false; 3863 | var root; 3864 | var currentParent; 3865 | var inVPre = false; 3866 | var inPre = false; 3867 | var warned = false; 3868 | parseHTML(template, { 3869 | expectHTML: options.expectHTML, 3870 | isUnaryTag: options.isUnaryTag, 3871 | shouldDecodeNewlines: options.shouldDecodeNewlines, 3872 | start: function start (tag, attrs, unary) { 3873 | // check namespace. 3874 | // inherit parent ns if there is one 3875 | var ns = (currentParent && currentParent.ns) || platformGetTagNamespace(tag); 3876 | 3877 | // handle IE svg bug 3878 | /* istanbul ignore if */ 3879 | if (options.isIE && ns === 'svg') { 3880 | attrs = guardIESVGBug(attrs); 3881 | } 3882 | 3883 | var element = { 3884 | type: 1, 3885 | tag: tag, 3886 | attrsList: attrs, 3887 | attrsMap: makeAttrsMap(attrs, options.isIE), 3888 | parent: currentParent, 3889 | children: [] 3890 | }; 3891 | if (ns) { 3892 | element.ns = ns; 3893 | } 3894 | 3895 | if (process.env.VUE_ENV !== 'server' && isForbiddenTag(element)) { 3896 | element.forbidden = true; 3897 | process.env.NODE_ENV !== 'production' && warn$1( 3898 | 'Templates should only be responsible for mapping the state to the ' + 3899 | 'UI. Avoid placing tags with side-effects in your templates, such as ' + 3900 | "<" + tag + ">." 3901 | ); 3902 | } 3903 | 3904 | // apply pre-transforms 3905 | for (var i = 0; i < preTransforms.length; i++) { 3906 | preTransforms[i](element, options); 3907 | } 3908 | 3909 | if (!inVPre) { 3910 | processPre(element); 3911 | if (element.pre) { 3912 | inVPre = true; 3913 | } 3914 | } 3915 | if (platformIsPreTag(element.tag)) { 3916 | inPre = true; 3917 | } 3918 | if (inVPre) { 3919 | processRawAttrs(element); 3920 | } else { 3921 | processFor(element); 3922 | processIf(element); 3923 | processOnce(element); 3924 | processKey(element); 3925 | 3926 | // determine whether this is a plain element after 3927 | // removing structural attributes 3928 | element.plain = !element.key && !attrs.length; 3929 | 3930 | processRef(element); 3931 | processSlot(element); 3932 | processComponent(element); 3933 | for (var i$1 = 0; i$1 < transforms.length; i$1++) { 3934 | transforms[i$1](element, options); 3935 | } 3936 | processAttrs(element); 3937 | } 3938 | 3939 | function checkRootConstraints (el) { 3940 | if (process.env.NODE_ENV !== 'production' && !warned) { 3941 | if (el.tag === 'slot' || el.tag === 'template') { 3942 | warned = true; 3943 | warn$1( 3944 | "Cannot use <" + (el.tag) + "> as component root element because it may " + 3945 | 'contain multiple nodes:\n' + template 3946 | ); 3947 | } 3948 | if (el.attrsMap.hasOwnProperty('v-for')) { 3949 | warned = true; 3950 | warn$1( 3951 | 'Cannot use v-for on stateful component root element because ' + 3952 | 'it renders multiple elements:\n' + template 3953 | ); 3954 | } 3955 | } 3956 | } 3957 | 3958 | // tree management 3959 | if (!root) { 3960 | root = element; 3961 | checkRootConstraints(root); 3962 | } else if (!stack.length) { 3963 | // allow 2 root elements with v-if and v-else 3964 | if (root.if && element.else) { 3965 | checkRootConstraints(element); 3966 | root.elseBlock = element; 3967 | } else if (process.env.NODE_ENV !== 'production' && !warned) { 3968 | warned = true; 3969 | warn$1( 3970 | ("Component template should contain exactly one root element:\n\n" + template) 3971 | ); 3972 | } 3973 | } 3974 | if (currentParent && !element.forbidden) { 3975 | if (element.else) { 3976 | processElse(element, currentParent); 3977 | } else { 3978 | currentParent.children.push(element); 3979 | element.parent = currentParent; 3980 | } 3981 | } 3982 | if (!unary) { 3983 | currentParent = element; 3984 | stack.push(element); 3985 | } 3986 | // apply post-transforms 3987 | for (var i$2 = 0; i$2 < postTransforms.length; i$2++) { 3988 | postTransforms[i$2](element, options); 3989 | } 3990 | }, 3991 | 3992 | end: function end () { 3993 | // remove trailing whitespace 3994 | var element = stack[stack.length - 1]; 3995 | var lastNode = element.children[element.children.length - 1]; 3996 | if (lastNode && lastNode.type === 3 && lastNode.text === ' ') { 3997 | element.children.pop(); 3998 | } 3999 | // pop stack 4000 | stack.length -= 1; 4001 | currentParent = stack[stack.length - 1]; 4002 | // check pre state 4003 | if (element.pre) { 4004 | inVPre = false; 4005 | } 4006 | if (platformIsPreTag(element.tag)) { 4007 | inPre = false; 4008 | } 4009 | }, 4010 | 4011 | chars: function chars (text) { 4012 | if (!currentParent) { 4013 | if (process.env.NODE_ENV !== 'production' && !warned && text === template) { 4014 | warned = true; 4015 | warn$1( 4016 | 'Component template requires a root element, rather than just text:\n\n' + template 4017 | ); 4018 | } 4019 | return 4020 | } 4021 | text = inPre || text.trim() 4022 | ? decodeHTMLCached(text) 4023 | // only preserve whitespace if its not right after a starting tag 4024 | : preserveWhitespace && currentParent.children.length ? ' ' : ''; 4025 | if (text) { 4026 | var expression; 4027 | if (!inVPre && text !== ' ' && (expression = parseText(text, delimiters))) { 4028 | currentParent.children.push({ 4029 | type: 2, 4030 | expression: expression, 4031 | text: text 4032 | }); 4033 | } else { 4034 | // #3895 special character 4035 | text = text.replace(specialNewlineRE, ''); 4036 | currentParent.children.push({ 4037 | type: 3, 4038 | text: text 4039 | }); 4040 | } 4041 | } 4042 | } 4043 | }); 4044 | return root 4045 | } 4046 | 4047 | function processPre (el) { 4048 | if (getAndRemoveAttr(el, 'v-pre') != null) { 4049 | el.pre = true; 4050 | } 4051 | } 4052 | 4053 | function processRawAttrs (el) { 4054 | var l = el.attrsList.length; 4055 | if (l) { 4056 | var attrs = el.attrs = new Array(l); 4057 | for (var i = 0; i < l; i++) { 4058 | attrs[i] = { 4059 | name: el.attrsList[i].name, 4060 | value: JSON.stringify(el.attrsList[i].value) 4061 | }; 4062 | } 4063 | } else if (!el.pre) { 4064 | // non root node in pre blocks with no attributes 4065 | el.plain = true; 4066 | } 4067 | } 4068 | 4069 | function processKey (el) { 4070 | var exp = getBindingAttr(el, 'key'); 4071 | if (exp) { 4072 | if (process.env.NODE_ENV !== 'production' && el.tag === 'template') { 4073 | warn$1("