PageRenderTime 32ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/files/vue/1.0.18/vue.js

https://gitlab.com/Mirros/jsdelivr
JavaScript | 2092 lines | 1375 code | 171 blank | 546 comment | 195 complexity | 541669ad989225c1e2e30d4e8c21e9d3 MD5 | raw file
  1. /*!
  2. * Vue.js v1.0.18
  3. * (c) 2016 Evan You
  4. * Released under the MIT License.
  5. */
  6. (function (global, factory) {
  7. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  8. typeof define === 'function' && define.amd ? define(factory) :
  9. (global.Vue = factory());
  10. }(this, function () { 'use strict';
  11. function set(obj, key, val) {
  12. if (hasOwn(obj, key)) {
  13. obj[key] = val;
  14. return;
  15. }
  16. if (obj._isVue) {
  17. set(obj._data, key, val);
  18. return;
  19. }
  20. var ob = obj.__ob__;
  21. if (!ob) {
  22. obj[key] = val;
  23. return;
  24. }
  25. ob.convert(key, val);
  26. ob.dep.notify();
  27. if (ob.vms) {
  28. var i = ob.vms.length;
  29. while (i--) {
  30. var vm = ob.vms[i];
  31. vm._proxy(key);
  32. vm._digest();
  33. }
  34. }
  35. return val;
  36. }
  37. /**
  38. * Delete a property and trigger change if necessary.
  39. *
  40. * @param {Object} obj
  41. * @param {String} key
  42. */
  43. function del(obj, key) {
  44. if (!hasOwn(obj, key)) {
  45. return;
  46. }
  47. delete obj[key];
  48. var ob = obj.__ob__;
  49. if (!ob) {
  50. return;
  51. }
  52. ob.dep.notify();
  53. if (ob.vms) {
  54. var i = ob.vms.length;
  55. while (i--) {
  56. var vm = ob.vms[i];
  57. vm._unproxy(key);
  58. vm._digest();
  59. }
  60. }
  61. }
  62. var hasOwnProperty = Object.prototype.hasOwnProperty;
  63. /**
  64. * Check whether the object has the property.
  65. *
  66. * @param {Object} obj
  67. * @param {String} key
  68. * @return {Boolean}
  69. */
  70. function hasOwn(obj, key) {
  71. return hasOwnProperty.call(obj, key);
  72. }
  73. /**
  74. * Check if an expression is a literal value.
  75. *
  76. * @param {String} exp
  77. * @return {Boolean}
  78. */
  79. var literalValueRE = /^\s?(true|false|-?[\d\.]+|'[^']*'|"[^"]*")\s?$/;
  80. function isLiteral(exp) {
  81. return literalValueRE.test(exp);
  82. }
  83. /**
  84. * Check if a string starts with $ or _
  85. *
  86. * @param {String} str
  87. * @return {Boolean}
  88. */
  89. function isReserved(str) {
  90. var c = (str + '').charCodeAt(0);
  91. return c === 0x24 || c === 0x5F;
  92. }
  93. /**
  94. * Guard text output, make sure undefined outputs
  95. * empty string
  96. *
  97. * @param {*} value
  98. * @return {String}
  99. */
  100. function _toString(value) {
  101. return value == null ? '' : value.toString();
  102. }
  103. /**
  104. * Check and convert possible numeric strings to numbers
  105. * before setting back to data
  106. *
  107. * @param {*} value
  108. * @return {*|Number}
  109. */
  110. function toNumber(value) {
  111. if (typeof value !== 'string') {
  112. return value;
  113. } else {
  114. var parsed = Number(value);
  115. return isNaN(parsed) ? value : parsed;
  116. }
  117. }
  118. /**
  119. * Convert string boolean literals into real booleans.
  120. *
  121. * @param {*} value
  122. * @return {*|Boolean}
  123. */
  124. function toBoolean(value) {
  125. return value === 'true' ? true : value === 'false' ? false : value;
  126. }
  127. /**
  128. * Strip quotes from a string
  129. *
  130. * @param {String} str
  131. * @return {String | false}
  132. */
  133. function stripQuotes(str) {
  134. var a = str.charCodeAt(0);
  135. var b = str.charCodeAt(str.length - 1);
  136. return a === b && (a === 0x22 || a === 0x27) ? str.slice(1, -1) : str;
  137. }
  138. /**
  139. * Camelize a hyphen-delmited string.
  140. *
  141. * @param {String} str
  142. * @return {String}
  143. */
  144. var camelizeRE = /-(\w)/g;
  145. function camelize(str) {
  146. return str.replace(camelizeRE, toUpper);
  147. }
  148. function toUpper(_, c) {
  149. return c ? c.toUpperCase() : '';
  150. }
  151. /**
  152. * Hyphenate a camelCase string.
  153. *
  154. * @param {String} str
  155. * @return {String}
  156. */
  157. var hyphenateRE = /([a-z\d])([A-Z])/g;
  158. function hyphenate(str) {
  159. return str.replace(hyphenateRE, '$1-$2').toLowerCase();
  160. }
  161. /**
  162. * Converts hyphen/underscore/slash delimitered names into
  163. * camelized classNames.
  164. *
  165. * e.g. my-component => MyComponent
  166. * some_else => SomeElse
  167. * some/comp => SomeComp
  168. *
  169. * @param {String} str
  170. * @return {String}
  171. */
  172. var classifyRE = /(?:^|[-_\/])(\w)/g;
  173. function classify(str) {
  174. return str.replace(classifyRE, toUpper);
  175. }
  176. /**
  177. * Simple bind, faster than native
  178. *
  179. * @param {Function} fn
  180. * @param {Object} ctx
  181. * @return {Function}
  182. */
  183. function bind(fn, ctx) {
  184. return function (a) {
  185. var l = arguments.length;
  186. return l ? l > 1 ? fn.apply(ctx, arguments) : fn.call(ctx, a) : fn.call(ctx);
  187. };
  188. }
  189. /**
  190. * Convert an Array-like object to a real Array.
  191. *
  192. * @param {Array-like} list
  193. * @param {Number} [start] - start index
  194. * @return {Array}
  195. */
  196. function toArray(list, start) {
  197. start = start || 0;
  198. var i = list.length - start;
  199. var ret = new Array(i);
  200. while (i--) {
  201. ret[i] = list[i + start];
  202. }
  203. return ret;
  204. }
  205. /**
  206. * Mix properties into target object.
  207. *
  208. * @param {Object} to
  209. * @param {Object} from
  210. */
  211. function extend(to, from) {
  212. var keys = Object.keys(from);
  213. var i = keys.length;
  214. while (i--) {
  215. to[keys[i]] = from[keys[i]];
  216. }
  217. return to;
  218. }
  219. /**
  220. * Quick object check - this is primarily used to tell
  221. * Objects from primitive values when we know the value
  222. * is a JSON-compliant type.
  223. *
  224. * @param {*} obj
  225. * @return {Boolean}
  226. */
  227. function isObject(obj) {
  228. return obj !== null && typeof obj === 'object';
  229. }
  230. /**
  231. * Strict object type check. Only returns true
  232. * for plain JavaScript objects.
  233. *
  234. * @param {*} obj
  235. * @return {Boolean}
  236. */
  237. var toString = Object.prototype.toString;
  238. var OBJECT_STRING = '[object Object]';
  239. function isPlainObject(obj) {
  240. return toString.call(obj) === OBJECT_STRING;
  241. }
  242. /**
  243. * Array type check.
  244. *
  245. * @param {*} obj
  246. * @return {Boolean}
  247. */
  248. var isArray = Array.isArray;
  249. /**
  250. * Define a property.
  251. *
  252. * @param {Object} obj
  253. * @param {String} key
  254. * @param {*} val
  255. * @param {Boolean} [enumerable]
  256. */
  257. function def(obj, key, val, enumerable) {
  258. Object.defineProperty(obj, key, {
  259. value: val,
  260. enumerable: !!enumerable,
  261. writable: true,
  262. configurable: true
  263. });
  264. }
  265. /**
  266. * Debounce a function so it only gets called after the
  267. * input stops arriving after the given wait period.
  268. *
  269. * @param {Function} func
  270. * @param {Number} wait
  271. * @return {Function} - the debounced function
  272. */
  273. function _debounce(func, wait) {
  274. var timeout, args, context, timestamp, result;
  275. var later = function later() {
  276. var last = Date.now() - timestamp;
  277. if (last < wait && last >= 0) {
  278. timeout = setTimeout(later, wait - last);
  279. } else {
  280. timeout = null;
  281. result = func.apply(context, args);
  282. if (!timeout) context = args = null;
  283. }
  284. };
  285. return function () {
  286. context = this;
  287. args = arguments;
  288. timestamp = Date.now();
  289. if (!timeout) {
  290. timeout = setTimeout(later, wait);
  291. }
  292. return result;
  293. };
  294. }
  295. /**
  296. * Manual indexOf because it's slightly faster than
  297. * native.
  298. *
  299. * @param {Array} arr
  300. * @param {*} obj
  301. */
  302. function indexOf(arr, obj) {
  303. var i = arr.length;
  304. while (i--) {
  305. if (arr[i] === obj) return i;
  306. }
  307. return -1;
  308. }
  309. /**
  310. * Make a cancellable version of an async callback.
  311. *
  312. * @param {Function} fn
  313. * @return {Function}
  314. */
  315. function cancellable(fn) {
  316. var cb = function cb() {
  317. if (!cb.cancelled) {
  318. return fn.apply(this, arguments);
  319. }
  320. };
  321. cb.cancel = function () {
  322. cb.cancelled = true;
  323. };
  324. return cb;
  325. }
  326. /**
  327. * Check if two values are loosely equal - that is,
  328. * if they are plain objects, do they have the same shape?
  329. *
  330. * @param {*} a
  331. * @param {*} b
  332. * @return {Boolean}
  333. */
  334. function looseEqual(a, b) {
  335. /* eslint-disable eqeqeq */
  336. return a == b || (isObject(a) && isObject(b) ? JSON.stringify(a) === JSON.stringify(b) : false);
  337. /* eslint-enable eqeqeq */
  338. }
  339. var hasProto = ('__proto__' in {});
  340. // Browser environment sniffing
  341. var inBrowser = typeof window !== 'undefined' && Object.prototype.toString.call(window) !== '[object Object]';
  342. // detect devtools
  343. var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
  344. // UA sniffing for working around browser-specific quirks
  345. var UA = inBrowser && window.navigator.userAgent.toLowerCase();
  346. var isIE9 = UA && UA.indexOf('msie 9.0') > 0;
  347. var isAndroid = UA && UA.indexOf('android') > 0;
  348. var transitionProp = undefined;
  349. var transitionEndEvent = undefined;
  350. var animationProp = undefined;
  351. var animationEndEvent = undefined;
  352. // Transition property/event sniffing
  353. if (inBrowser && !isIE9) {
  354. var isWebkitTrans = window.ontransitionend === undefined && window.onwebkittransitionend !== undefined;
  355. var isWebkitAnim = window.onanimationend === undefined && window.onwebkitanimationend !== undefined;
  356. transitionProp = isWebkitTrans ? 'WebkitTransition' : 'transition';
  357. transitionEndEvent = isWebkitTrans ? 'webkitTransitionEnd' : 'transitionend';
  358. animationProp = isWebkitAnim ? 'WebkitAnimation' : 'animation';
  359. animationEndEvent = isWebkitAnim ? 'webkitAnimationEnd' : 'animationend';
  360. }
  361. /**
  362. * Defer a task to execute it asynchronously. Ideally this
  363. * should be executed as a microtask, so we leverage
  364. * MutationObserver if it's available, and fallback to
  365. * setTimeout(0).
  366. *
  367. * @param {Function} cb
  368. * @param {Object} ctx
  369. */
  370. var nextTick = (function () {
  371. var callbacks = [];
  372. var pending = false;
  373. var timerFunc;
  374. function nextTickHandler() {
  375. pending = false;
  376. var copies = callbacks.slice(0);
  377. callbacks = [];
  378. for (var i = 0; i < copies.length; i++) {
  379. copies[i]();
  380. }
  381. }
  382. /* istanbul ignore if */
  383. if (typeof MutationObserver !== 'undefined') {
  384. var counter = 1;
  385. var observer = new MutationObserver(nextTickHandler);
  386. var textNode = document.createTextNode(counter);
  387. observer.observe(textNode, {
  388. characterData: true
  389. });
  390. timerFunc = function () {
  391. counter = (counter + 1) % 2;
  392. textNode.data = counter;
  393. };
  394. } else {
  395. // webpack attempts to inject a shim for setImmediate
  396. // if it is used as a global, so we have to work around that to
  397. // avoid bundling unnecessary code.
  398. var context = inBrowser ? window : typeof global !== 'undefined' ? global : {};
  399. timerFunc = context.setImmediate || setTimeout;
  400. }
  401. return function (cb, ctx) {
  402. var func = ctx ? function () {
  403. cb.call(ctx);
  404. } : cb;
  405. callbacks.push(func);
  406. if (pending) return;
  407. pending = true;
  408. timerFunc(nextTickHandler, 0);
  409. };
  410. })();
  411. function Cache(limit) {
  412. this.size = 0;
  413. this.limit = limit;
  414. this.head = this.tail = undefined;
  415. this._keymap = Object.create(null);
  416. }
  417. var p = Cache.prototype;
  418. /**
  419. * Put <value> into the cache associated with <key>.
  420. * Returns the entry which was removed to make room for
  421. * the new entry. Otherwise undefined is returned.
  422. * (i.e. if there was enough room already).
  423. *
  424. * @param {String} key
  425. * @param {*} value
  426. * @return {Entry|undefined}
  427. */
  428. p.put = function (key, value) {
  429. var removed;
  430. if (this.size === this.limit) {
  431. removed = this.shift();
  432. }
  433. var entry = this.get(key, true);
  434. if (!entry) {
  435. entry = {
  436. key: key
  437. };
  438. this._keymap[key] = entry;
  439. if (this.tail) {
  440. this.tail.newer = entry;
  441. entry.older = this.tail;
  442. } else {
  443. this.head = entry;
  444. }
  445. this.tail = entry;
  446. this.size++;
  447. }
  448. entry.value = value;
  449. return removed;
  450. };
  451. /**
  452. * Purge the least recently used (oldest) entry from the
  453. * cache. Returns the removed entry or undefined if the
  454. * cache was empty.
  455. */
  456. p.shift = function () {
  457. var entry = this.head;
  458. if (entry) {
  459. this.head = this.head.newer;
  460. this.head.older = undefined;
  461. entry.newer = entry.older = undefined;
  462. this._keymap[entry.key] = undefined;
  463. this.size--;
  464. }
  465. return entry;
  466. };
  467. /**
  468. * Get and register recent use of <key>. Returns the value
  469. * associated with <key> or undefined if not in cache.
  470. *
  471. * @param {String} key
  472. * @param {Boolean} returnEntry
  473. * @return {Entry|*}
  474. */
  475. p.get = function (key, returnEntry) {
  476. var entry = this._keymap[key];
  477. if (entry === undefined) return;
  478. if (entry === this.tail) {
  479. return returnEntry ? entry : entry.value;
  480. }
  481. // HEAD--------------TAIL
  482. // <.older .newer>
  483. // <--- add direction --
  484. // A B C <D> E
  485. if (entry.newer) {
  486. if (entry === this.head) {
  487. this.head = entry.newer;
  488. }
  489. entry.newer.older = entry.older; // C <-- E.
  490. }
  491. if (entry.older) {
  492. entry.older.newer = entry.newer; // C. --> E
  493. }
  494. entry.newer = undefined; // D --x
  495. entry.older = this.tail; // D. --> E
  496. if (this.tail) {
  497. this.tail.newer = entry; // E. <-- D
  498. }
  499. this.tail = entry;
  500. return returnEntry ? entry : entry.value;
  501. };
  502. var cache$1 = new Cache(1000);
  503. var filterTokenRE = /[^\s'"]+|'[^']*'|"[^"]*"/g;
  504. var reservedArgRE = /^in$|^-?\d+/;
  505. /**
  506. * Parser state
  507. */
  508. var str;
  509. var dir;
  510. var c;
  511. var prev;
  512. var i;
  513. var l;
  514. var lastFilterIndex;
  515. var inSingle;
  516. var inDouble;
  517. var curly;
  518. var square;
  519. var paren;
  520. /**
  521. * Push a filter to the current directive object
  522. */
  523. function pushFilter() {
  524. var exp = str.slice(lastFilterIndex, i).trim();
  525. var filter;
  526. if (exp) {
  527. filter = {};
  528. var tokens = exp.match(filterTokenRE);
  529. filter.name = tokens[0];
  530. if (tokens.length > 1) {
  531. filter.args = tokens.slice(1).map(processFilterArg);
  532. }
  533. }
  534. if (filter) {
  535. (dir.filters = dir.filters || []).push(filter);
  536. }
  537. lastFilterIndex = i + 1;
  538. }
  539. /**
  540. * Check if an argument is dynamic and strip quotes.
  541. *
  542. * @param {String} arg
  543. * @return {Object}
  544. */
  545. function processFilterArg(arg) {
  546. if (reservedArgRE.test(arg)) {
  547. return {
  548. value: toNumber(arg),
  549. dynamic: false
  550. };
  551. } else {
  552. var stripped = stripQuotes(arg);
  553. var dynamic = stripped === arg;
  554. return {
  555. value: dynamic ? arg : stripped,
  556. dynamic: dynamic
  557. };
  558. }
  559. }
  560. /**
  561. * Parse a directive value and extract the expression
  562. * and its filters into a descriptor.
  563. *
  564. * Example:
  565. *
  566. * "a + 1 | uppercase" will yield:
  567. * {
  568. * expression: 'a + 1',
  569. * filters: [
  570. * { name: 'uppercase', args: null }
  571. * ]
  572. * }
  573. *
  574. * @param {String} str
  575. * @return {Object}
  576. */
  577. function parseDirective(s) {
  578. var hit = cache$1.get(s);
  579. if (hit) {
  580. return hit;
  581. }
  582. // reset parser state
  583. str = s;
  584. inSingle = inDouble = false;
  585. curly = square = paren = 0;
  586. lastFilterIndex = 0;
  587. dir = {};
  588. for (i = 0, l = str.length; i < l; i++) {
  589. prev = c;
  590. c = str.charCodeAt(i);
  591. if (inSingle) {
  592. // check single quote
  593. if (c === 0x27 && prev !== 0x5C) inSingle = !inSingle;
  594. } else if (inDouble) {
  595. // check double quote
  596. if (c === 0x22 && prev !== 0x5C) inDouble = !inDouble;
  597. } else if (c === 0x7C && // pipe
  598. str.charCodeAt(i + 1) !== 0x7C && str.charCodeAt(i - 1) !== 0x7C) {
  599. if (dir.expression == null) {
  600. // first filter, end of expression
  601. lastFilterIndex = i + 1;
  602. dir.expression = str.slice(0, i).trim();
  603. } else {
  604. // already has filter
  605. pushFilter();
  606. }
  607. } else {
  608. switch (c) {
  609. case 0x22:
  610. inDouble = true;break; // "
  611. case 0x27:
  612. inSingle = true;break; // '
  613. case 0x28:
  614. paren++;break; // (
  615. case 0x29:
  616. paren--;break; // )
  617. case 0x5B:
  618. square++;break; // [
  619. case 0x5D:
  620. square--;break; // ]
  621. case 0x7B:
  622. curly++;break; // {
  623. case 0x7D:
  624. curly--;break; // }
  625. }
  626. }
  627. }
  628. if (dir.expression == null) {
  629. dir.expression = str.slice(0, i).trim();
  630. } else if (lastFilterIndex !== 0) {
  631. pushFilter();
  632. }
  633. cache$1.put(s, dir);
  634. return dir;
  635. }
  636. var directive = Object.freeze({
  637. parseDirective: parseDirective
  638. });
  639. var regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g;
  640. var cache = undefined;
  641. var tagRE = undefined;
  642. var htmlRE = undefined;
  643. /**
  644. * Escape a string so it can be used in a RegExp
  645. * constructor.
  646. *
  647. * @param {String} str
  648. */
  649. function escapeRegex(str) {
  650. return str.replace(regexEscapeRE, '\\$&');
  651. }
  652. function compileRegex() {
  653. var open = escapeRegex(config.delimiters[0]);
  654. var close = escapeRegex(config.delimiters[1]);
  655. var unsafeOpen = escapeRegex(config.unsafeDelimiters[0]);
  656. var unsafeClose = escapeRegex(config.unsafeDelimiters[1]);
  657. tagRE = new RegExp(unsafeOpen + '(.+?)' + unsafeClose + '|' + open + '(.+?)' + close, 'g');
  658. htmlRE = new RegExp('^' + unsafeOpen + '.*' + unsafeClose + '$');
  659. // reset cache
  660. cache = new Cache(1000);
  661. }
  662. /**
  663. * Parse a template text string into an array of tokens.
  664. *
  665. * @param {String} text
  666. * @return {Array<Object> | null}
  667. * - {String} type
  668. * - {String} value
  669. * - {Boolean} [html]
  670. * - {Boolean} [oneTime]
  671. */
  672. function parseText(text) {
  673. if (!cache) {
  674. compileRegex();
  675. }
  676. var hit = cache.get(text);
  677. if (hit) {
  678. return hit;
  679. }
  680. text = text.replace(/\n/g, '');
  681. if (!tagRE.test(text)) {
  682. return null;
  683. }
  684. var tokens = [];
  685. var lastIndex = tagRE.lastIndex = 0;
  686. var match, index, html, value, first, oneTime;
  687. /* eslint-disable no-cond-assign */
  688. while (match = tagRE.exec(text)) {
  689. /* eslint-enable no-cond-assign */
  690. index = match.index;
  691. // push text token
  692. if (index > lastIndex) {
  693. tokens.push({
  694. value: text.slice(lastIndex, index)
  695. });
  696. }
  697. // tag token
  698. html = htmlRE.test(match[0]);
  699. value = html ? match[1] : match[2];
  700. first = value.charCodeAt(0);
  701. oneTime = first === 42; // *
  702. value = oneTime ? value.slice(1) : value;
  703. tokens.push({
  704. tag: true,
  705. value: value.trim(),
  706. html: html,
  707. oneTime: oneTime
  708. });
  709. lastIndex = index + match[0].length;
  710. }
  711. if (lastIndex < text.length) {
  712. tokens.push({
  713. value: text.slice(lastIndex)
  714. });
  715. }
  716. cache.put(text, tokens);
  717. return tokens;
  718. }
  719. /**
  720. * Format a list of tokens into an expression.
  721. * e.g. tokens parsed from 'a {{b}} c' can be serialized
  722. * into one single expression as '"a " + b + " c"'.
  723. *
  724. * @param {Array} tokens
  725. * @param {Vue} [vm]
  726. * @return {String}
  727. */
  728. function tokensToExp(tokens, vm) {
  729. if (tokens.length > 1) {
  730. return tokens.map(function (token) {
  731. return formatToken(token, vm);
  732. }).join('+');
  733. } else {
  734. return formatToken(tokens[0], vm, true);
  735. }
  736. }
  737. /**
  738. * Format a single token.
  739. *
  740. * @param {Object} token
  741. * @param {Vue} [vm]
  742. * @param {Boolean} [single]
  743. * @return {String}
  744. */
  745. function formatToken(token, vm, single) {
  746. return token.tag ? token.oneTime && vm ? '"' + vm.$eval(token.value) + '"' : inlineFilters(token.value, single) : '"' + token.value + '"';
  747. }
  748. /**
  749. * For an attribute with multiple interpolation tags,
  750. * e.g. attr="some-{{thing | filter}}", in order to combine
  751. * the whole thing into a single watchable expression, we
  752. * have to inline those filters. This function does exactly
  753. * that. This is a bit hacky but it avoids heavy changes
  754. * to directive parser and watcher mechanism.
  755. *
  756. * @param {String} exp
  757. * @param {Boolean} single
  758. * @return {String}
  759. */
  760. var filterRE = /[^|]\|[^|]/;
  761. function inlineFilters(exp, single) {
  762. if (!filterRE.test(exp)) {
  763. return single ? exp : '(' + exp + ')';
  764. } else {
  765. var dir = parseDirective(exp);
  766. if (!dir.filters) {
  767. return '(' + exp + ')';
  768. } else {
  769. return 'this._applyFilters(' + dir.expression + // value
  770. ',null,' + // oldValue (null for read)
  771. JSON.stringify(dir.filters) + // filter descriptors
  772. ',false)'; // write?
  773. }
  774. }
  775. }
  776. var text = Object.freeze({
  777. compileRegex: compileRegex,
  778. parseText: parseText,
  779. tokensToExp: tokensToExp
  780. });
  781. var delimiters = ['{{', '}}'];
  782. var unsafeDelimiters = ['{{{', '}}}'];
  783. var config = Object.defineProperties({
  784. /**
  785. * Whether to print debug messages.
  786. * Also enables stack trace for warnings.
  787. *
  788. * @type {Boolean}
  789. */
  790. debug: false,
  791. /**
  792. * Whether to suppress warnings.
  793. *
  794. * @type {Boolean}
  795. */
  796. silent: false,
  797. /**
  798. * Whether to use async rendering.
  799. */
  800. async: true,
  801. /**
  802. * Whether to warn against errors caught when evaluating
  803. * expressions.
  804. */
  805. warnExpressionErrors: true,
  806. /**
  807. * Whether to allow devtools inspection.
  808. * Disabled by default in production builds.
  809. */
  810. devtools: 'development' !== 'production',
  811. /**
  812. * Internal flag to indicate the delimiters have been
  813. * changed.
  814. *
  815. * @type {Boolean}
  816. */
  817. _delimitersChanged: true,
  818. /**
  819. * List of asset types that a component can own.
  820. *
  821. * @type {Array}
  822. */
  823. _assetTypes: ['component', 'directive', 'elementDirective', 'filter', 'transition', 'partial'],
  824. /**
  825. * prop binding modes
  826. */
  827. _propBindingModes: {
  828. ONE_WAY: 0,
  829. TWO_WAY: 1,
  830. ONE_TIME: 2
  831. },
  832. /**
  833. * Max circular updates allowed in a batcher flush cycle.
  834. */
  835. _maxUpdateCount: 100
  836. }, {
  837. delimiters: { /**
  838. * Interpolation delimiters. Changing these would trigger
  839. * the text parser to re-compile the regular expressions.
  840. *
  841. * @type {Array<String>}
  842. */
  843. get: function get() {
  844. return delimiters;
  845. },
  846. set: function set(val) {
  847. delimiters = val;
  848. compileRegex();
  849. },
  850. configurable: true,
  851. enumerable: true
  852. },
  853. unsafeDelimiters: {
  854. get: function get() {
  855. return unsafeDelimiters;
  856. },
  857. set: function set(val) {
  858. unsafeDelimiters = val;
  859. compileRegex();
  860. },
  861. configurable: true,
  862. enumerable: true
  863. }
  864. });
  865. var warn = undefined;
  866. if ('development' !== 'production') {
  867. (function () {
  868. var hasConsole = typeof console !== 'undefined';
  869. warn = function (msg, e) {
  870. if (hasConsole && (!config.silent || config.debug)) {
  871. console.warn('[Vue warn]: ' + msg);
  872. /* istanbul ignore if */
  873. if (config.debug) {
  874. if (e) {
  875. throw e;
  876. } else {
  877. console.warn(new Error('Warning Stack Trace').stack);
  878. }
  879. }
  880. }
  881. };
  882. })();
  883. }
  884. /**
  885. * Append with transition.
  886. *
  887. * @param {Element} el
  888. * @param {Element} target
  889. * @param {Vue} vm
  890. * @param {Function} [cb]
  891. */
  892. function appendWithTransition(el, target, vm, cb) {
  893. applyTransition(el, 1, function () {
  894. target.appendChild(el);
  895. }, vm, cb);
  896. }
  897. /**
  898. * InsertBefore with transition.
  899. *
  900. * @param {Element} el
  901. * @param {Element} target
  902. * @param {Vue} vm
  903. * @param {Function} [cb]
  904. */
  905. function beforeWithTransition(el, target, vm, cb) {
  906. applyTransition(el, 1, function () {
  907. before(el, target);
  908. }, vm, cb);
  909. }
  910. /**
  911. * Remove with transition.
  912. *
  913. * @param {Element} el
  914. * @param {Vue} vm
  915. * @param {Function} [cb]
  916. */
  917. function removeWithTransition(el, vm, cb) {
  918. applyTransition(el, -1, function () {
  919. remove(el);
  920. }, vm, cb);
  921. }
  922. /**
  923. * Apply transitions with an operation callback.
  924. *
  925. * @param {Element} el
  926. * @param {Number} direction
  927. * 1: enter
  928. * -1: leave
  929. * @param {Function} op - the actual DOM operation
  930. * @param {Vue} vm
  931. * @param {Function} [cb]
  932. */
  933. function applyTransition(el, direction, op, vm, cb) {
  934. var transition = el.__v_trans;
  935. if (!transition ||
  936. // skip if there are no js hooks and CSS transition is
  937. // not supported
  938. !transition.hooks && !transitionEndEvent ||
  939. // skip transitions for initial compile
  940. !vm._isCompiled ||
  941. // if the vm is being manipulated by a parent directive
  942. // during the parent's compilation phase, skip the
  943. // animation.
  944. vm.$parent && !vm.$parent._isCompiled) {
  945. op();
  946. if (cb) cb();
  947. return;
  948. }
  949. var action = direction > 0 ? 'enter' : 'leave';
  950. transition[action](op, cb);
  951. }
  952. var transition = Object.freeze({
  953. appendWithTransition: appendWithTransition,
  954. beforeWithTransition: beforeWithTransition,
  955. removeWithTransition: removeWithTransition,
  956. applyTransition: applyTransition
  957. });
  958. /**
  959. * Query an element selector if it's not an element already.
  960. *
  961. * @param {String|Element} el
  962. * @return {Element}
  963. */
  964. function query(el) {
  965. if (typeof el === 'string') {
  966. var selector = el;
  967. el = document.querySelector(el);
  968. if (!el) {
  969. 'development' !== 'production' && warn('Cannot find element: ' + selector);
  970. }
  971. }
  972. return el;
  973. }
  974. /**
  975. * Check if a node is in the document.
  976. * Note: document.documentElement.contains should work here
  977. * but always returns false for comment nodes in phantomjs,
  978. * making unit tests difficult. This is fixed by doing the
  979. * contains() check on the node's parentNode instead of
  980. * the node itself.
  981. *
  982. * @param {Node} node
  983. * @return {Boolean}
  984. */
  985. function inDoc(node) {
  986. var doc = document.documentElement;
  987. var parent = node && node.parentNode;
  988. return doc === node || doc === parent || !!(parent && parent.nodeType === 1 && doc.contains(parent));
  989. }
  990. /**
  991. * Get and remove an attribute from a node.
  992. *
  993. * @param {Node} node
  994. * @param {String} _attr
  995. */
  996. function getAttr(node, _attr) {
  997. var val = node.getAttribute(_attr);
  998. if (val !== null) {
  999. node.removeAttribute(_attr);
  1000. }
  1001. return val;
  1002. }
  1003. /**
  1004. * Get an attribute with colon or v-bind: prefix.
  1005. *
  1006. * @param {Node} node
  1007. * @param {String} name
  1008. * @return {String|null}
  1009. */
  1010. function getBindAttr(node, name) {
  1011. var val = getAttr(node, ':' + name);
  1012. if (val === null) {
  1013. val = getAttr(node, 'v-bind:' + name);
  1014. }
  1015. return val;
  1016. }
  1017. /**
  1018. * Check the presence of a bind attribute.
  1019. *
  1020. * @param {Node} node
  1021. * @param {String} name
  1022. * @return {Boolean}
  1023. */
  1024. function hasBindAttr(node, name) {
  1025. return node.hasAttribute(name) || node.hasAttribute(':' + name) || node.hasAttribute('v-bind:' + name);
  1026. }
  1027. /**
  1028. * Insert el before target
  1029. *
  1030. * @param {Element} el
  1031. * @param {Element} target
  1032. */
  1033. function before(el, target) {
  1034. target.parentNode.insertBefore(el, target);
  1035. }
  1036. /**
  1037. * Insert el after target
  1038. *
  1039. * @param {Element} el
  1040. * @param {Element} target
  1041. */
  1042. function after(el, target) {
  1043. if (target.nextSibling) {
  1044. before(el, target.nextSibling);
  1045. } else {
  1046. target.parentNode.appendChild(el);
  1047. }
  1048. }
  1049. /**
  1050. * Remove el from DOM
  1051. *
  1052. * @param {Element} el
  1053. */
  1054. function remove(el) {
  1055. el.parentNode.removeChild(el);
  1056. }
  1057. /**
  1058. * Prepend el to target
  1059. *
  1060. * @param {Element} el
  1061. * @param {Element} target
  1062. */
  1063. function prepend(el, target) {
  1064. if (target.firstChild) {
  1065. before(el, target.firstChild);
  1066. } else {
  1067. target.appendChild(el);
  1068. }
  1069. }
  1070. /**
  1071. * Replace target with el
  1072. *
  1073. * @param {Element} target
  1074. * @param {Element} el
  1075. */
  1076. function replace(target, el) {
  1077. var parent = target.parentNode;
  1078. if (parent) {
  1079. parent.replaceChild(el, target);
  1080. }
  1081. }
  1082. /**
  1083. * Add event listener shorthand.
  1084. *
  1085. * @param {Element} el
  1086. * @param {String} event
  1087. * @param {Function} cb
  1088. * @param {Boolean} [useCapture]
  1089. */
  1090. function on(el, event, cb, useCapture) {
  1091. el.addEventListener(event, cb, useCapture);
  1092. }
  1093. /**
  1094. * Remove event listener shorthand.
  1095. *
  1096. * @param {Element} el
  1097. * @param {String} event
  1098. * @param {Function} cb
  1099. */
  1100. function off(el, event, cb) {
  1101. el.removeEventListener(event, cb);
  1102. }
  1103. /**
  1104. * In IE9, setAttribute('class') will result in empty class
  1105. * if the element also has the :class attribute; However in
  1106. * PhantomJS, setting `className` does not work on SVG elements...
  1107. * So we have to do a conditional check here.
  1108. *
  1109. * @param {Element} el
  1110. * @param {String} cls
  1111. */
  1112. function setClass(el, cls) {
  1113. /* istanbul ignore if */
  1114. if (isIE9 && !/svg$/.test(el.namespaceURI)) {
  1115. el.className = cls;
  1116. } else {
  1117. el.setAttribute('class', cls);
  1118. }
  1119. }
  1120. /**
  1121. * Add class with compatibility for IE & SVG
  1122. *
  1123. * @param {Element} el
  1124. * @param {String} cls
  1125. */
  1126. function addClass(el, cls) {
  1127. if (el.classList) {
  1128. el.classList.add(cls);
  1129. } else {
  1130. var cur = ' ' + (el.getAttribute('class') || '') + ' ';
  1131. if (cur.indexOf(' ' + cls + ' ') < 0) {
  1132. setClass(el, (cur + cls).trim());
  1133. }
  1134. }
  1135. }
  1136. /**
  1137. * Remove class with compatibility for IE & SVG
  1138. *
  1139. * @param {Element} el
  1140. * @param {String} cls
  1141. */
  1142. function removeClass(el, cls) {
  1143. if (el.classList) {
  1144. el.classList.remove(cls);
  1145. } else {
  1146. var cur = ' ' + (el.getAttribute('class') || '') + ' ';
  1147. var tar = ' ' + cls + ' ';
  1148. while (cur.indexOf(tar) >= 0) {
  1149. cur = cur.replace(tar, ' ');
  1150. }
  1151. setClass(el, cur.trim());
  1152. }
  1153. if (!el.className) {
  1154. el.removeAttribute('class');
  1155. }
  1156. }
  1157. /**
  1158. * Extract raw content inside an element into a temporary
  1159. * container div
  1160. *
  1161. * @param {Element} el
  1162. * @param {Boolean} asFragment
  1163. * @return {Element|DocumentFragment}
  1164. */
  1165. function extractContent(el, asFragment) {
  1166. var child;
  1167. var rawContent;
  1168. /* istanbul ignore if */
  1169. if (isTemplate(el) && isFragment(el.content)) {
  1170. el = el.content;
  1171. }
  1172. if (el.hasChildNodes()) {
  1173. trimNode(el);
  1174. rawContent = asFragment ? document.createDocumentFragment() : document.createElement('div');
  1175. /* eslint-disable no-cond-assign */
  1176. while (child = el.firstChild) {
  1177. /* eslint-enable no-cond-assign */
  1178. rawContent.appendChild(child);
  1179. }
  1180. }
  1181. return rawContent;
  1182. }
  1183. /**
  1184. * Trim possible empty head/tail text and comment
  1185. * nodes inside a parent.
  1186. *
  1187. * @param {Node} node
  1188. */
  1189. function trimNode(node) {
  1190. var child;
  1191. /* eslint-disable no-sequences */
  1192. while ((child = node.firstChild, isTrimmable(child))) {
  1193. node.removeChild(child);
  1194. }
  1195. while ((child = node.lastChild, isTrimmable(child))) {
  1196. node.removeChild(child);
  1197. }
  1198. /* eslint-enable no-sequences */
  1199. }
  1200. function isTrimmable(node) {
  1201. return node && (node.nodeType === 3 && !node.data.trim() || node.nodeType === 8);
  1202. }
  1203. /**
  1204. * Check if an element is a template tag.
  1205. * Note if the template appears inside an SVG its tagName
  1206. * will be in lowercase.
  1207. *
  1208. * @param {Element} el
  1209. */
  1210. function isTemplate(el) {
  1211. return el.tagName && el.tagName.toLowerCase() === 'template';
  1212. }
  1213. /**
  1214. * Create an "anchor" for performing dom insertion/removals.
  1215. * This is used in a number of scenarios:
  1216. * - fragment instance
  1217. * - v-html
  1218. * - v-if
  1219. * - v-for
  1220. * - component
  1221. *
  1222. * @param {String} content
  1223. * @param {Boolean} persist - IE trashes empty textNodes on
  1224. * cloneNode(true), so in certain
  1225. * cases the anchor needs to be
  1226. * non-empty to be persisted in
  1227. * templates.
  1228. * @return {Comment|Text}
  1229. */
  1230. function createAnchor(content, persist) {
  1231. var anchor = config.debug ? document.createComment(content) : document.createTextNode(persist ? ' ' : '');
  1232. anchor.__v_anchor = true;
  1233. return anchor;
  1234. }
  1235. /**
  1236. * Find a component ref attribute that starts with $.
  1237. *
  1238. * @param {Element} node
  1239. * @return {String|undefined}
  1240. */
  1241. var refRE = /^v-ref:/;
  1242. function findRef(node) {
  1243. if (node.hasAttributes()) {
  1244. var attrs = node.attributes;
  1245. for (var i = 0, l = attrs.length; i < l; i++) {
  1246. var name = attrs[i].name;
  1247. if (refRE.test(name)) {
  1248. return camelize(name.replace(refRE, ''));
  1249. }
  1250. }
  1251. }
  1252. }
  1253. /**
  1254. * Map a function to a range of nodes .
  1255. *
  1256. * @param {Node} node
  1257. * @param {Node} end
  1258. * @param {Function} op
  1259. */
  1260. function mapNodeRange(node, end, op) {
  1261. var next;
  1262. while (node !== end) {
  1263. next = node.nextSibling;
  1264. op(node);
  1265. node = next;
  1266. }
  1267. op(end);
  1268. }
  1269. /**
  1270. * Remove a range of nodes with transition, store
  1271. * the nodes in a fragment with correct ordering,
  1272. * and call callback when done.
  1273. *
  1274. * @param {Node} start
  1275. * @param {Node} end
  1276. * @param {Vue} vm
  1277. * @param {DocumentFragment} frag
  1278. * @param {Function} cb
  1279. */
  1280. function removeNodeRange(start, end, vm, frag, cb) {
  1281. var done = false;
  1282. var removed = 0;
  1283. var nodes = [];
  1284. mapNodeRange(start, end, function (node) {
  1285. if (node === end) done = true;
  1286. nodes.push(node);
  1287. removeWithTransition(node, vm, onRemoved);
  1288. });
  1289. function onRemoved() {
  1290. removed++;
  1291. if (done && removed >= nodes.length) {
  1292. for (var i = 0; i < nodes.length; i++) {
  1293. frag.appendChild(nodes[i]);
  1294. }
  1295. cb && cb();
  1296. }
  1297. }
  1298. }
  1299. /**
  1300. * Check if a node is a DocumentFragment.
  1301. *
  1302. * @param {Node} node
  1303. * @return {Boolean}
  1304. */
  1305. function isFragment(node) {
  1306. return node && node.nodeType === 11;
  1307. }
  1308. /**
  1309. * Get outerHTML of elements, taking care
  1310. * of SVG elements in IE as well.
  1311. *
  1312. * @param {Element} el
  1313. * @return {String}
  1314. */
  1315. function getOuterHTML(el) {
  1316. if (el.outerHTML) {
  1317. return el.outerHTML;
  1318. } else {
  1319. var container = document.createElement('div');
  1320. container.appendChild(el.cloneNode(true));
  1321. return container.innerHTML;
  1322. }
  1323. }
  1324. var uid$1 = 0;
  1325. /**
  1326. * A dep is an observable that can have multiple
  1327. * directives subscribing to it.
  1328. *
  1329. * @constructor
  1330. */
  1331. function Dep() {
  1332. this.id = uid$1++;
  1333. this.subs = [];
  1334. }
  1335. // the current target watcher being evaluated.
  1336. // this is globally unique because there could be only one
  1337. // watcher being evaluated at any time.
  1338. Dep.target = null;
  1339. /**
  1340. * Add a directive subscriber.
  1341. *
  1342. * @param {Directive} sub
  1343. */
  1344. Dep.prototype.addSub = function (sub) {
  1345. this.subs.push(sub);
  1346. };
  1347. /**
  1348. * Remove a directive subscriber.
  1349. *
  1350. * @param {Directive} sub
  1351. */
  1352. Dep.prototype.removeSub = function (sub) {
  1353. this.subs.$remove(sub);
  1354. };
  1355. /**
  1356. * Add self as a dependency to the target watcher.
  1357. */
  1358. Dep.prototype.depend = function () {
  1359. Dep.target.addDep(this);
  1360. };
  1361. /**
  1362. * Notify all subscribers of a new value.
  1363. */
  1364. Dep.prototype.notify = function () {
  1365. // stablize the subscriber list first
  1366. var subs = toArray(this.subs);
  1367. for (var i = 0, l = subs.length; i < l; i++) {
  1368. subs[i].update();
  1369. }
  1370. };
  1371. var arrayProto = Array.prototype;
  1372. var arrayMethods = Object.create(arrayProto)
  1373. /**
  1374. * Intercept mutating methods and emit events
  1375. */
  1376. ;['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(function (method) {
  1377. // cache original method
  1378. var original = arrayProto[method];
  1379. def(arrayMethods, method, function mutator() {
  1380. // avoid leaking arguments:
  1381. // http://jsperf.com/closure-with-arguments
  1382. var i = arguments.length;
  1383. var args = new Array(i);
  1384. while (i--) {
  1385. args[i] = arguments[i];
  1386. }
  1387. var result = original.apply(this, args);
  1388. var ob = this.__ob__;
  1389. var inserted;
  1390. switch (method) {
  1391. case 'push':
  1392. inserted = args;
  1393. break;
  1394. case 'unshift':
  1395. inserted = args;
  1396. break;
  1397. case 'splice':
  1398. inserted = args.slice(2);
  1399. break;
  1400. }
  1401. if (inserted) ob.observeArray(inserted);
  1402. // notify change
  1403. ob.dep.notify();
  1404. return result;
  1405. });
  1406. });
  1407. /**
  1408. * Swap the element at the given index with a new value
  1409. * and emits corresponding event.
  1410. *
  1411. * @param {Number} index
  1412. * @param {*} val
  1413. * @return {*} - replaced element
  1414. */
  1415. def(arrayProto, '$set', function $set(index, val) {
  1416. if (index >= this.length) {
  1417. this.length = Number(index) + 1;
  1418. }
  1419. return this.splice(index, 1, val)[0];
  1420. });
  1421. /**
  1422. * Convenience method to remove the element at given index.
  1423. *
  1424. * @param {Number} index
  1425. * @param {*} val
  1426. */
  1427. def(arrayProto, '$remove', function $remove(item) {
  1428. /* istanbul ignore if */
  1429. if (!this.length) return;
  1430. var index = indexOf(this, item);
  1431. if (index > -1) {
  1432. return this.splice(index, 1);
  1433. }
  1434. });
  1435. var arrayKeys = Object.getOwnPropertyNames(arrayMethods);
  1436. /**
  1437. * Observer class that are attached to each observed
  1438. * object. Once attached, the observer converts target
  1439. * object's property keys into getter/setters that
  1440. * collect dependencies and dispatches updates.
  1441. *
  1442. * @param {Array|Object} value
  1443. * @constructor
  1444. */
  1445. function Observer(value) {
  1446. this.value = value;
  1447. this.dep = new Dep();
  1448. def(value, '__ob__', this);
  1449. if (isArray(value)) {
  1450. var augment = hasProto ? protoAugment : copyAugment;
  1451. augment(value, arrayMethods, arrayKeys);
  1452. this.observeArray(value);
  1453. } else {
  1454. this.walk(value);
  1455. }
  1456. }
  1457. // Instance methods
  1458. /**
  1459. * Walk through each property and convert them into
  1460. * getter/setters. This method should only be called when
  1461. * value type is Object.
  1462. *
  1463. * @param {Object} obj
  1464. */
  1465. Observer.prototype.walk = function (obj) {
  1466. var keys = Object.keys(obj);
  1467. for (var i = 0, l = keys.length; i < l; i++) {
  1468. this.convert(keys[i], obj[keys[i]]);
  1469. }
  1470. };
  1471. /**
  1472. * Observe a list of Array items.
  1473. *
  1474. * @param {Array} items
  1475. */
  1476. Observer.prototype.observeArray = function (items) {
  1477. for (var i = 0, l = items.length; i < l; i++) {
  1478. observe(items[i]);
  1479. }
  1480. };
  1481. /**
  1482. * Convert a property into getter/setter so we can emit
  1483. * the events when the property is accessed/changed.
  1484. *
  1485. * @param {String} key
  1486. * @param {*} val
  1487. */
  1488. Observer.prototype.convert = function (key, val) {
  1489. defineReactive(this.value, key, val);
  1490. };
  1491. /**
  1492. * Add an owner vm, so that when $set/$delete mutations
  1493. * happen we can notify owner vms to proxy the keys and
  1494. * digest the watchers. This is only called when the object
  1495. * is observed as an instance's root $data.
  1496. *
  1497. * @param {Vue} vm
  1498. */
  1499. Observer.prototype.addVm = function (vm) {
  1500. (this.vms || (this.vms = [])).push(vm);
  1501. };
  1502. /**
  1503. * Remove an owner vm. This is called when the object is
  1504. * swapped out as an instance's $data object.
  1505. *
  1506. * @param {Vue} vm
  1507. */
  1508. Observer.prototype.removeVm = function (vm) {
  1509. this.vms.$remove(vm);
  1510. };
  1511. // helpers
  1512. /**
  1513. * Augment an target Object or Array by intercepting
  1514. * the prototype chain using __proto__
  1515. *
  1516. * @param {Object|Array} target
  1517. * @param {Object} proto
  1518. */
  1519. function protoAugment(target, src) {
  1520. /* eslint-disable no-proto */
  1521. target.__proto__ = src;
  1522. /* eslint-enable no-proto */
  1523. }
  1524. /**
  1525. * Augment an target Object or Array by defining
  1526. * hidden properties.
  1527. *
  1528. * @param {Object|Array} target
  1529. * @param {Object} proto
  1530. */
  1531. function copyAugment(target, src, keys) {
  1532. for (var i = 0, l = keys.length; i < l; i++) {
  1533. var key = keys[i];
  1534. def(target, key, src[key]);
  1535. }
  1536. }
  1537. /**
  1538. * Attempt to create an observer instance for a value,
  1539. * returns the new observer if successfully observed,
  1540. * or the existing observer if the value already has one.
  1541. *
  1542. * @param {*} value
  1543. * @param {Vue} [vm]
  1544. * @return {Observer|undefined}
  1545. * @static
  1546. */
  1547. function observe(value, vm) {
  1548. if (!value || typeof value !== 'object') {
  1549. return;
  1550. }
  1551. var ob;
  1552. if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
  1553. ob = value.__ob__;
  1554. } else if ((isArray(value) || isPlainObject(value)) && Object.isExtensible(value) && !value._isVue) {
  1555. ob = new Observer(value);
  1556. }
  1557. if (ob && vm) {
  1558. ob.addVm(vm);
  1559. }
  1560. return ob;
  1561. }
  1562. /**
  1563. * Define a reactive property on an Object.
  1564. *
  1565. * @param {Object} obj
  1566. * @param {String} key
  1567. * @param {*} val
  1568. * @param {Boolean} doNotObserve
  1569. */
  1570. function defineReactive(obj, key, val, doNotObserve) {
  1571. var dep = new Dep();
  1572. var property = Object.getOwnPropertyDescriptor(obj, key);
  1573. if (property && property.configurable === false) {
  1574. return;
  1575. }
  1576. // cater for pre-defined getter/setters
  1577. var getter = property && property.get;
  1578. var setter = property && property.set;
  1579. // if doNotObserve is true, only use the child value observer
  1580. // if it already exists, and do not attempt to create it.
  1581. // this allows freezing a large object from the root and
  1582. // avoid unnecessary observation inside v-for fragments.
  1583. var childOb = doNotObserve ? isObject(val) && val.__ob__ : observe(val);
  1584. Object.defineProperty(obj, key, {
  1585. enumerable: true,
  1586. configurable: true,
  1587. get: function reactiveGetter() {
  1588. var value = getter ? getter.call(obj) : val;
  1589. if (Dep.target) {
  1590. dep.depend();
  1591. if (childOb) {
  1592. childOb.dep.depend();
  1593. }
  1594. if (isArray(value)) {
  1595. for (var e, i = 0, l = value.length; i < l; i++) {
  1596. e = value[i];
  1597. e && e.__ob__ && e.__ob__.dep.depend();
  1598. }
  1599. }
  1600. }
  1601. return value;
  1602. },
  1603. set: function reactiveSetter(newVal) {
  1604. var value = getter ? getter.call(obj) : val;
  1605. if (newVal === value) {
  1606. return;
  1607. }
  1608. if (setter) {
  1609. setter.call(obj, newVal);
  1610. } else {
  1611. val = newVal;
  1612. }
  1613. childOb = doNotObserve ? isObject(newVal) && newVal.__ob__ : observe(newVal);
  1614. dep.notify();
  1615. }
  1616. });
  1617. }
  1618. var commonTagRE = /^(div|p|span|img|a|b|i|br|ul|ol|li|h1|h2|h3|h4|h5|h6|code|pre|table|th|td|tr|form|label|input|select|option|nav|article|section|header|footer)$/i;
  1619. var reservedTagRE = /^(slot|partial|component)$/i;
  1620. var isUnknownElement = undefined;
  1621. if ('development' !== 'production') {
  1622. isUnknownElement = function (el, tag) {
  1623. if (tag.indexOf('-') > -1) {
  1624. // http://stackoverflow.com/a/28210364/1070244
  1625. return el.constructor === window.HTMLUnknownElement || el.constructor === window.HTMLElement;
  1626. } else {
  1627. return (/HTMLUnknownElement/.test(el.toString()) &&
  1628. // Chrome returns unknown for several HTML5 elements.
  1629. // https://code.google.com/p/chromium/issues/detail?id=540526
  1630. !/^(data|time|rtc|rb)$/.test(tag)
  1631. );
  1632. }
  1633. };
  1634. }
  1635. /**
  1636. * Check if an element is a component, if yes return its
  1637. * component id.
  1638. *
  1639. * @param {Element} el
  1640. * @param {Object} options
  1641. * @return {Object|undefined}
  1642. */
  1643. function checkComponentAttr(el, options) {
  1644. var tag = el.tagName.toLowerCase();
  1645. var hasAttrs = el.hasAttributes();
  1646. if (!commonTagRE.test(tag) && !reservedTagRE.test(tag)) {
  1647. if (resolveAsset(options, 'components', tag)) {
  1648. return { id: tag };
  1649. } else {
  1650. var is = hasAttrs && getIsBinding(el);
  1651. if (is) {
  1652. return is;
  1653. } else if ('development' !== 'production') {
  1654. var expectedTag = options._componentNameMap && options._componentNameMap[tag];
  1655. if (expectedTag) {
  1656. warn('Unknown custom element: <' + tag + '> - ' + 'did you mean <' + expectedTag + '>? ' + 'HTML is case-insensitive, remember to use kebab-case in templates.');
  1657. } else if (isUnknownElement(el, tag)) {
  1658. warn('Unknown custom element: <' + tag + '> - did you ' + 'register the component correctly? For recursive components, ' + 'make sure to provide the "name" option.');
  1659. }
  1660. }
  1661. }
  1662. } else if (hasAttrs) {
  1663. return getIsBinding(el);
  1664. }
  1665. }
  1666. /**
  1667. * Get "is" binding from an element.
  1668. *
  1669. * @param {Element} el
  1670. * @return {Object|undefined}
  1671. */
  1672. function getIsBinding(el) {
  1673. // dynamic syntax
  1674. var exp = getAttr(el, 'is');
  1675. if (exp != null) {
  1676. return { id: exp };
  1677. } else {
  1678. exp = getBindAttr(el, 'is');
  1679. if (exp != null) {
  1680. return { id: exp, dynamic: true };
  1681. }
  1682. }
  1683. }
  1684. /**
  1685. * Set a prop's initial value on a vm and its data object.
  1686. *
  1687. * @param {Vue} vm
  1688. * @param {Object} prop
  1689. * @param {*} value
  1690. */
  1691. function initProp(vm, prop, value) {
  1692. var key = prop.path;
  1693. value = coerceProp(prop, value);
  1694. if (value === undefined) {
  1695. value = getPropDefaultValue(vm, prop.options);
  1696. }
  1697. if (assertProp(prop, value)) {
  1698. defineReactive(vm, key, value, true /* doNotObserve */);
  1699. }
  1700. }
  1701. /**
  1702. * Get the default value of a prop.
  1703. *
  1704. * @param {Vue} vm
  1705. * @param {Object} options
  1706. * @return {*}
  1707. */
  1708. function getPropDefaultValue(vm, options) {
  1709. // no default, return undefined
  1710. if (!hasOwn(options, 'default')) {
  1711. // absent boolean value defaults to false
  1712. return options.type === Boolean ? false : undefined;
  1713. }
  1714. var def = options['default'];
  1715. // warn against non-factory defaults for Object & Array
  1716. if (isObject(def)) {
  1717. 'development' !== 'production' && warn('Object/Array as default prop values will be shared ' + 'across multiple instances. Use a factory function ' + 'to return the default value instead.');
  1718. }
  1719. // call factory function for non-Function types
  1720. return typeof def === 'function' && options.type !== Function ? def.call(vm) : def;
  1721. }
  1722. /**
  1723. * Assert whether a prop is valid.
  1724. *
  1725. * @param {Object} prop
  1726. * @param {*} value
  1727. */
  1728. function assertProp(prop, value) {
  1729. if (!prop.options.required && ( // non-required
  1730. prop.raw === null || // abscent
  1731. value == null) // null or undefined
  1732. ) {
  1733. return true;
  1734. }
  1735. var options = prop.options;
  1736. var type = options.type;
  1737. var valid = true;
  1738. var expectedType;
  1739. if (type) {
  1740. if (type === String) {
  1741. expectedType = 'string';
  1742. valid = typeof value === expectedType;
  1743. } else if (type === Number) {
  1744. expectedType = 'number';
  1745. valid = typeof value === 'number';
  1746. } else if (type === Boolean) {
  1747. expectedType = 'boolean';
  1748. valid = typeof value === 'boolean';
  1749. } else if (type === Function) {
  1750. expectedType = 'function';
  1751. valid = typeof value === 'function';
  1752. } else if (type === Object) {
  1753. expectedType = 'object';
  1754. valid = isPlainObject(value);
  1755. } else if (type === Array) {
  1756. expectedType = 'array';
  1757. valid = isArray(value);
  1758. } else {
  1759. valid = value instanceof type;
  1760. }
  1761. }
  1762. if (!valid) {
  1763. 'development' !== 'production' && warn('Invalid prop: type check failed for ' + prop.path + '="' + prop.raw + '".' + ' Expected ' + formatType(expectedType) + ', got ' + formatValue(value) + '.');
  1764. return false;
  1765. }
  1766. var validator = options.validator;
  1767. if (validator) {
  1768. if (!validator(value)) {
  1769. 'development' !== 'production' && warn('Invalid prop: custom validator check failed for ' + prop.path + '="' + prop.raw + '"');
  1770. return false;
  1771. }
  1772. }
  1773. return true;
  1774. }
  1775. /**
  1776. * Force parsing value with coerce option.
  1777. *
  1778. * @param {*} value
  1779. * @param {Object} options
  1780. * @return {*}
  1781. */
  1782. function coerceProp(prop, value) {
  1783. var coerce = prop.options.coerce;
  1784. if (!coerce) {
  1785. return value;
  1786. }
  1787. // coerce is a function
  1788. return coerce(value);
  1789. }
  1790. function formatType(val) {
  1791. return val ? val.charAt(0).toUpperCase() + val.slice(1) : 'custom type';
  1792. }
  1793. function formatValue(val) {
  1794. return Object.prototype.toString.call(val).slice(8, -1);
  1795. }
  1796. /**
  1797. * Option overwriting strategies are functions that handle
  1798. * how to merge a parent option value and a child option
  1799. * value into the final value.
  1800. *
  1801. * All strategy functions follow the same signature:
  1802. *
  1803. * @param {*} parentVal
  1804. * @param {*} childVal
  1805. * @param {Vue} [vm]
  1806. */
  1807. var strats = config.optionMergeStrategies = Object.create(null);
  1808. /**
  1809. * Helper that recursively merges two data objects together.
  1810. */
  1811. function mergeData(to, from) {
  1812. var key, toVal, fromVal;
  1813. for (key in from) {
  1814. toVal = to[key];
  1815. fromVal = from[key];
  1816. if (!hasOwn(to, key)) {
  1817. set(to, key, fromVal);
  1818. } else if (isObject(toVal) && isObject(fromVal)) {
  1819. mergeData(toVal, fromVal);
  1820. }
  1821. }
  1822. return to;
  1823. }
  1824. /**
  1825. * Data
  1826. */
  1827. strats.data = function (parentVal, childVal, vm) {
  1828. if (!vm) {
  1829. // in a Vue.extend merge, both should be functions
  1830. if (!childVal) {
  1831. return parentVal;
  1832. }
  1833. if (typeof childVal !== 'function') {
  1834. 'development' !== 'production' && warn('The "data" option should be a function ' + 'that returns a per-instance value in component ' + 'definitions.');
  1835. return parentVal;
  1836. }
  1837. if (!parentVal) {
  1838. return childVal;
  1839. }
  1840. // when parentVal & childVal are both present,
  1841. // we need to return a function that returns the
  1842. // merged result of both functions... no need to
  1843. // check if parentVal is a function here because
  1844. // it has to be a function to pass previous merges.
  1845. return function mergedDataFn() {
  1846. return mergeData(childVal.call(this), parentVal.call(this));
  1847. };
  1848. } else if (p