PageRenderTime 69ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/files/vue/1.0.16/vue.js

https://gitlab.com/Mirros/jsdelivr
JavaScript | 2083 lines | 1391 code | 166 blank | 526 comment | 196 complexity | ea55236215126d20f8e878ef76205283 MD5 | raw file
  1. /*!
  2. * Vue.js v1.0.16
  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$1(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 non-enumerable 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. var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
  343. var isIE9 = inBrowser && navigator.userAgent.toLowerCase().indexOf('msie 9.0') > 0;
  344. var isAndroid = inBrowser && navigator.userAgent.toLowerCase().indexOf('android') > 0;
  345. var transitionProp = undefined;
  346. var transitionEndEvent = undefined;
  347. var animationProp = undefined;
  348. var animationEndEvent = undefined;
  349. // Transition property/event sniffing
  350. if (inBrowser && !isIE9) {
  351. var isWebkitTrans = window.ontransitionend === undefined && window.onwebkittransitionend !== undefined;
  352. var isWebkitAnim = window.onanimationend === undefined && window.onwebkitanimationend !== undefined;
  353. transitionProp = isWebkitTrans ? 'WebkitTransition' : 'transition';
  354. transitionEndEvent = isWebkitTrans ? 'webkitTransitionEnd' : 'transitionend';
  355. animationProp = isWebkitAnim ? 'WebkitAnimation' : 'animation';
  356. animationEndEvent = isWebkitAnim ? 'webkitAnimationEnd' : 'animationend';
  357. }
  358. /**
  359. * Defer a task to execute it asynchronously. Ideally this
  360. * should be executed as a microtask, so we leverage
  361. * MutationObserver if it's available, and fallback to
  362. * setTimeout(0).
  363. *
  364. * @param {Function} cb
  365. * @param {Object} ctx
  366. */
  367. var nextTick = (function () {
  368. var callbacks = [];
  369. var pending = false;
  370. var timerFunc;
  371. function nextTickHandler() {
  372. pending = false;
  373. var copies = callbacks.slice(0);
  374. callbacks = [];
  375. for (var i = 0; i < copies.length; i++) {
  376. copies[i]();
  377. }
  378. }
  379. /* istanbul ignore if */
  380. if (typeof MutationObserver !== 'undefined') {
  381. var counter = 1;
  382. var observer = new MutationObserver(nextTickHandler);
  383. var textNode = document.createTextNode(counter);
  384. observer.observe(textNode, {
  385. characterData: true
  386. });
  387. timerFunc = function () {
  388. counter = (counter + 1) % 2;
  389. textNode.data = counter;
  390. };
  391. } else {
  392. // webpack attempts to inject a shim for setImmediate
  393. // if it is used as a global, so we have to work around that to
  394. // avoid bundling unnecessary code.
  395. var context = inBrowser ? window : typeof global !== 'undefined' ? global : {};
  396. timerFunc = context.setImmediate || setTimeout;
  397. }
  398. return function (cb, ctx) {
  399. var func = ctx ? function () {
  400. cb.call(ctx);
  401. } : cb;
  402. callbacks.push(func);
  403. if (pending) return;
  404. pending = true;
  405. timerFunc(nextTickHandler, 0);
  406. };
  407. })();
  408. function Cache(limit) {
  409. this.size = 0;
  410. this.limit = limit;
  411. this.head = this.tail = undefined;
  412. this._keymap = Object.create(null);
  413. }
  414. var p = Cache.prototype;
  415. /**
  416. * Put <value> into the cache associated with <key>.
  417. * Returns the entry which was removed to make room for
  418. * the new entry. Otherwise undefined is returned.
  419. * (i.e. if there was enough room already).
  420. *
  421. * @param {String} key
  422. * @param {*} value
  423. * @return {Entry|undefined}
  424. */
  425. p.put = function (key, value) {
  426. var removed;
  427. if (this.size === this.limit) {
  428. removed = this.shift();
  429. }
  430. var entry = this.get(key, true);
  431. if (!entry) {
  432. entry = {
  433. key: key
  434. };
  435. this._keymap[key] = entry;
  436. if (this.tail) {
  437. this.tail.newer = entry;
  438. entry.older = this.tail;
  439. } else {
  440. this.head = entry;
  441. }
  442. this.tail = entry;
  443. this.size++;
  444. }
  445. entry.value = value;
  446. return removed;
  447. };
  448. /**
  449. * Purge the least recently used (oldest) entry from the
  450. * cache. Returns the removed entry or undefined if the
  451. * cache was empty.
  452. */
  453. p.shift = function () {
  454. var entry = this.head;
  455. if (entry) {
  456. this.head = this.head.newer;
  457. this.head.older = undefined;
  458. entry.newer = entry.older = undefined;
  459. this._keymap[entry.key] = undefined;
  460. this.size--;
  461. }
  462. return entry;
  463. };
  464. /**
  465. * Get and register recent use of <key>. Returns the value
  466. * associated with <key> or undefined if not in cache.
  467. *
  468. * @param {String} key
  469. * @param {Boolean} returnEntry
  470. * @return {Entry|*}
  471. */
  472. p.get = function (key, returnEntry) {
  473. var entry = this._keymap[key];
  474. if (entry === undefined) return;
  475. if (entry === this.tail) {
  476. return returnEntry ? entry : entry.value;
  477. }
  478. // HEAD--------------TAIL
  479. // <.older .newer>
  480. // <--- add direction --
  481. // A B C <D> E
  482. if (entry.newer) {
  483. if (entry === this.head) {
  484. this.head = entry.newer;
  485. }
  486. entry.newer.older = entry.older; // C <-- E.
  487. }
  488. if (entry.older) {
  489. entry.older.newer = entry.newer; // C. --> E
  490. }
  491. entry.newer = undefined; // D --x
  492. entry.older = this.tail; // D. --> E
  493. if (this.tail) {
  494. this.tail.newer = entry; // E. <-- D
  495. }
  496. this.tail = entry;
  497. return returnEntry ? entry : entry.value;
  498. };
  499. var cache$1 = new Cache(1000);
  500. var filterTokenRE = /[^\s'"]+|'[^']*'|"[^"]*"/g;
  501. var reservedArgRE = /^in$|^-?\d+/;
  502. /**
  503. * Parser state
  504. */
  505. var str;
  506. var dir;
  507. var c;
  508. var prev;
  509. var i;
  510. var l;
  511. var lastFilterIndex;
  512. var inSingle;
  513. var inDouble;
  514. var curly;
  515. var square;
  516. var paren;
  517. /**
  518. * Push a filter to the current directive object
  519. */
  520. function pushFilter() {
  521. var exp = str.slice(lastFilterIndex, i).trim();
  522. var filter;
  523. if (exp) {
  524. filter = {};
  525. var tokens = exp.match(filterTokenRE);
  526. filter.name = tokens[0];
  527. if (tokens.length > 1) {
  528. filter.args = tokens.slice(1).map(processFilterArg);
  529. }
  530. }
  531. if (filter) {
  532. (dir.filters = dir.filters || []).push(filter);
  533. }
  534. lastFilterIndex = i + 1;
  535. }
  536. /**
  537. * Check if an argument is dynamic and strip quotes.
  538. *
  539. * @param {String} arg
  540. * @return {Object}
  541. */
  542. function processFilterArg(arg) {
  543. if (reservedArgRE.test(arg)) {
  544. return {
  545. value: toNumber(arg),
  546. dynamic: false
  547. };
  548. } else {
  549. var stripped = stripQuotes(arg);
  550. var dynamic = stripped === arg;
  551. return {
  552. value: dynamic ? arg : stripped,
  553. dynamic: dynamic
  554. };
  555. }
  556. }
  557. /**
  558. * Parse a directive value and extract the expression
  559. * and its filters into a descriptor.
  560. *
  561. * Example:
  562. *
  563. * "a + 1 | uppercase" will yield:
  564. * {
  565. * expression: 'a + 1',
  566. * filters: [
  567. * { name: 'uppercase', args: null }
  568. * ]
  569. * }
  570. *
  571. * @param {String} str
  572. * @return {Object}
  573. */
  574. function parseDirective(s) {
  575. var hit = cache$1.get(s);
  576. if (hit) {
  577. return hit;
  578. }
  579. // reset parser state
  580. str = s;
  581. inSingle = inDouble = false;
  582. curly = square = paren = 0;
  583. lastFilterIndex = 0;
  584. dir = {};
  585. for (i = 0, l = str.length; i < l; i++) {
  586. prev = c;
  587. c = str.charCodeAt(i);
  588. if (inSingle) {
  589. // check single quote
  590. if (c === 0x27 && prev !== 0x5C) inSingle = !inSingle;
  591. } else if (inDouble) {
  592. // check double quote
  593. if (c === 0x22 && prev !== 0x5C) inDouble = !inDouble;
  594. } else if (c === 0x7C && // pipe
  595. str.charCodeAt(i + 1) !== 0x7C && str.charCodeAt(i - 1) !== 0x7C) {
  596. if (dir.expression == null) {
  597. // first filter, end of expression
  598. lastFilterIndex = i + 1;
  599. dir.expression = str.slice(0, i).trim();
  600. } else {
  601. // already has filter
  602. pushFilter();
  603. }
  604. } else {
  605. switch (c) {
  606. case 0x22:
  607. inDouble = true;break; // "
  608. case 0x27:
  609. inSingle = true;break; // '
  610. case 0x28:
  611. paren++;break; // (
  612. case 0x29:
  613. paren--;break; // )
  614. case 0x5B:
  615. square++;break; // [
  616. case 0x5D:
  617. square--;break; // ]
  618. case 0x7B:
  619. curly++;break; // {
  620. case 0x7D:
  621. curly--;break; // }
  622. }
  623. }
  624. }
  625. if (dir.expression == null) {
  626. dir.expression = str.slice(0, i).trim();
  627. } else if (lastFilterIndex !== 0) {
  628. pushFilter();
  629. }
  630. cache$1.put(s, dir);
  631. return dir;
  632. }
  633. var directive = Object.freeze({
  634. parseDirective: parseDirective
  635. });
  636. var regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g;
  637. var cache = undefined;
  638. var tagRE = undefined;
  639. var htmlRE = undefined;
  640. /**
  641. * Escape a string so it can be used in a RegExp
  642. * constructor.
  643. *
  644. * @param {String} str
  645. */
  646. function escapeRegex(str) {
  647. return str.replace(regexEscapeRE, '\\$&');
  648. }
  649. function compileRegex() {
  650. var open = escapeRegex(config.delimiters[0]);
  651. var close = escapeRegex(config.delimiters[1]);
  652. var unsafeOpen = escapeRegex(config.unsafeDelimiters[0]);
  653. var unsafeClose = escapeRegex(config.unsafeDelimiters[1]);
  654. tagRE = new RegExp(unsafeOpen + '(.+?)' + unsafeClose + '|' + open + '(.+?)' + close, 'g');
  655. htmlRE = new RegExp('^' + unsafeOpen + '.*' + unsafeClose + '$');
  656. // reset cache
  657. cache = new Cache(1000);
  658. }
  659. /**
  660. * Parse a template text string into an array of tokens.
  661. *
  662. * @param {String} text
  663. * @return {Array<Object> | null}
  664. * - {String} type
  665. * - {String} value
  666. * - {Boolean} [html]
  667. * - {Boolean} [oneTime]
  668. */
  669. function parseText(text) {
  670. if (!cache) {
  671. compileRegex();
  672. }
  673. var hit = cache.get(text);
  674. if (hit) {
  675. return hit;
  676. }
  677. text = text.replace(/\n/g, '');
  678. if (!tagRE.test(text)) {
  679. return null;
  680. }
  681. var tokens = [];
  682. var lastIndex = tagRE.lastIndex = 0;
  683. var match, index, html, value, first, oneTime;
  684. /* eslint-disable no-cond-assign */
  685. while (match = tagRE.exec(text)) {
  686. /* eslint-enable no-cond-assign */
  687. index = match.index;
  688. // push text token
  689. if (index > lastIndex) {
  690. tokens.push({
  691. value: text.slice(lastIndex, index)
  692. });
  693. }
  694. // tag token
  695. html = htmlRE.test(match[0]);
  696. value = html ? match[1] : match[2];
  697. first = value.charCodeAt(0);
  698. oneTime = first === 42; // *
  699. value = oneTime ? value.slice(1) : value;
  700. tokens.push({
  701. tag: true,
  702. value: value.trim(),
  703. html: html,
  704. oneTime: oneTime
  705. });
  706. lastIndex = index + match[0].length;
  707. }
  708. if (lastIndex < text.length) {
  709. tokens.push({
  710. value: text.slice(lastIndex)
  711. });
  712. }
  713. cache.put(text, tokens);
  714. return tokens;
  715. }
  716. /**
  717. * Format a list of tokens into an expression.
  718. * e.g. tokens parsed from 'a {{b}} c' can be serialized
  719. * into one single expression as '"a " + b + " c"'.
  720. *
  721. * @param {Array} tokens
  722. * @param {Vue} [vm]
  723. * @return {String}
  724. */
  725. function tokensToExp(tokens, vm) {
  726. if (tokens.length > 1) {
  727. return tokens.map(function (token) {
  728. return formatToken(token, vm);
  729. }).join('+');
  730. } else {
  731. return formatToken(tokens[0], vm, true);
  732. }
  733. }
  734. /**
  735. * Format a single token.
  736. *
  737. * @param {Object} token
  738. * @param {Vue} [vm]
  739. * @param {Boolean} [single]
  740. * @return {String}
  741. */
  742. function formatToken(token, vm, single) {
  743. return token.tag ? token.oneTime && vm ? '"' + vm.$eval(token.value) + '"' : inlineFilters(token.value, single) : '"' + token.value + '"';
  744. }
  745. /**
  746. * For an attribute with multiple interpolation tags,
  747. * e.g. attr="some-{{thing | filter}}", in order to combine
  748. * the whole thing into a single watchable expression, we
  749. * have to inline those filters. This function does exactly
  750. * that. This is a bit hacky but it avoids heavy changes
  751. * to directive parser and watcher mechanism.
  752. *
  753. * @param {String} exp
  754. * @param {Boolean} single
  755. * @return {String}
  756. */
  757. var filterRE$1 = /[^|]\|[^|]/;
  758. function inlineFilters(exp, single) {
  759. if (!filterRE$1.test(exp)) {
  760. return single ? exp : '(' + exp + ')';
  761. } else {
  762. var dir = parseDirective(exp);
  763. if (!dir.filters) {
  764. return '(' + exp + ')';
  765. } else {
  766. return 'this._applyFilters(' + dir.expression + // value
  767. ',null,' + // oldValue (null for read)
  768. JSON.stringify(dir.filters) + // filter descriptors
  769. ',false)'; // write?
  770. }
  771. }
  772. }
  773. var text$1 = Object.freeze({
  774. compileRegex: compileRegex,
  775. parseText: parseText,
  776. tokensToExp: tokensToExp
  777. });
  778. var delimiters = ['{{', '}}'];
  779. var unsafeDelimiters = ['{{{', '}}}'];
  780. var config = Object.defineProperties({
  781. /**
  782. * Whether to print debug messages.
  783. * Also enables stack trace for warnings.
  784. *
  785. * @type {Boolean}
  786. */
  787. debug: false,
  788. /**
  789. * Whether to suppress warnings.
  790. *
  791. * @type {Boolean}
  792. */
  793. silent: false,
  794. /**
  795. * Whether to use async rendering.
  796. */
  797. async: true,
  798. /**
  799. * Whether to warn against errors caught when evaluating
  800. * expressions.
  801. */
  802. warnExpressionErrors: true,
  803. /**
  804. * Whether or not to handle fully object properties which
  805. * are already backed by getters and seters. Depending on
  806. * use case and environment, this might introduce non-neglible
  807. * performance penalties.
  808. */
  809. convertAllProperties: false,
  810. /**
  811. * Internal flag to indicate the delimiters have been
  812. * changed.
  813. *
  814. * @type {Boolean}
  815. */
  816. _delimitersChanged: true,
  817. /**
  818. * List of asset types that a component can own.
  819. *
  820. * @type {Array}
  821. */
  822. _assetTypes: ['component', 'directive', 'elementDirective', 'filter', 'transition', 'partial'],
  823. /**
  824. * prop binding modes
  825. */
  826. _propBindingModes: {
  827. ONE_WAY: 0,
  828. TWO_WAY: 1,
  829. ONE_TIME: 2
  830. },
  831. /**
  832. * Max circular updates allowed in a batcher flush cycle.
  833. */
  834. _maxUpdateCount: 100
  835. }, {
  836. delimiters: { /**
  837. * Interpolation delimiters. Changing these would trigger
  838. * the text parser to re-compile the regular expressions.
  839. *
  840. * @type {Array<String>}
  841. */
  842. get: function get() {
  843. return delimiters;
  844. },
  845. set: function set(val) {
  846. delimiters = val;
  847. compileRegex();
  848. },
  849. configurable: true,
  850. enumerable: true
  851. },
  852. unsafeDelimiters: {
  853. get: function get() {
  854. return unsafeDelimiters;
  855. },
  856. set: function set(val) {
  857. unsafeDelimiters = val;
  858. compileRegex();
  859. },
  860. configurable: true,
  861. enumerable: true
  862. }
  863. });
  864. var warn = undefined;
  865. if ('development' !== 'production') {
  866. (function () {
  867. var hasConsole = typeof console !== 'undefined';
  868. warn = function (msg, e) {
  869. if (hasConsole && (!config.silent || config.debug)) {
  870. console.warn('[Vue warn]: ' + msg);
  871. /* istanbul ignore if */
  872. if (config.debug) {
  873. if (e) {
  874. throw e;
  875. } else {
  876. console.warn(new Error('Warning Stack Trace').stack);
  877. }
  878. }
  879. }
  880. };
  881. })();
  882. }
  883. /**
  884. * Append with transition.
  885. *
  886. * @param {Element} el
  887. * @param {Element} target
  888. * @param {Vue} vm
  889. * @param {Function} [cb]
  890. */
  891. function appendWithTransition(el, target, vm, cb) {
  892. applyTransition(el, 1, function () {
  893. target.appendChild(el);
  894. }, vm, cb);
  895. }
  896. /**
  897. * InsertBefore with transition.
  898. *
  899. * @param {Element} el
  900. * @param {Element} target
  901. * @param {Vue} vm
  902. * @param {Function} [cb]
  903. */
  904. function beforeWithTransition(el, target, vm, cb) {
  905. applyTransition(el, 1, function () {
  906. before(el, target);
  907. }, vm, cb);
  908. }
  909. /**
  910. * Remove with transition.
  911. *
  912. * @param {Element} el
  913. * @param {Vue} vm
  914. * @param {Function} [cb]
  915. */
  916. function removeWithTransition(el, vm, cb) {
  917. applyTransition(el, -1, function () {
  918. remove(el);
  919. }, vm, cb);
  920. }
  921. /**
  922. * Apply transitions with an operation callback.
  923. *
  924. * @param {Element} el
  925. * @param {Number} direction
  926. * 1: enter
  927. * -1: leave
  928. * @param {Function} op - the actual DOM operation
  929. * @param {Vue} vm
  930. * @param {Function} [cb]
  931. */
  932. function applyTransition(el, direction, op, vm, cb) {
  933. var transition = el.__v_trans;
  934. if (!transition ||
  935. // skip if there are no js hooks and CSS transition is
  936. // not supported
  937. !transition.hooks && !transitionEndEvent ||
  938. // skip transitions for initial compile
  939. !vm._isCompiled ||
  940. // if the vm is being manipulated by a parent directive
  941. // during the parent's compilation phase, skip the
  942. // animation.
  943. vm.$parent && !vm.$parent._isCompiled) {
  944. op();
  945. if (cb) cb();
  946. return;
  947. }
  948. var action = direction > 0 ? 'enter' : 'leave';
  949. transition[action](op, cb);
  950. }
  951. /**
  952. * Query an element selector if it's not an element already.
  953. *
  954. * @param {String|Element} el
  955. * @return {Element}
  956. */
  957. function query(el) {
  958. if (typeof el === 'string') {
  959. var selector = el;
  960. el = document.querySelector(el);
  961. if (!el) {
  962. 'development' !== 'production' && warn('Cannot find element: ' + selector);
  963. }
  964. }
  965. return el;
  966. }
  967. /**
  968. * Check if a node is in the document.
  969. * Note: document.documentElement.contains should work here
  970. * but always returns false for comment nodes in phantomjs,
  971. * making unit tests difficult. This is fixed by doing the
  972. * contains() check on the node's parentNode instead of
  973. * the node itself.
  974. *
  975. * @param {Node} node
  976. * @return {Boolean}
  977. */
  978. function inDoc(node) {
  979. var doc = document.documentElement;
  980. var parent = node && node.parentNode;
  981. return doc === node || doc === parent || !!(parent && parent.nodeType === 1 && doc.contains(parent));
  982. }
  983. /**
  984. * Get and remove an attribute from a node.
  985. *
  986. * @param {Node} node
  987. * @param {String} _attr
  988. */
  989. function getAttr(node, _attr) {
  990. var val = node.getAttribute(_attr);
  991. if (val !== null) {
  992. node.removeAttribute(_attr);
  993. }
  994. return val;
  995. }
  996. /**
  997. * Get an attribute with colon or v-bind: prefix.
  998. *
  999. * @param {Node} node
  1000. * @param {String} name
  1001. * @return {String|null}
  1002. */
  1003. function getBindAttr(node, name) {
  1004. var val = getAttr(node, ':' + name);
  1005. if (val === null) {
  1006. val = getAttr(node, 'v-bind:' + name);
  1007. }
  1008. return val;
  1009. }
  1010. /**
  1011. * Check the presence of a bind attribute.
  1012. *
  1013. * @param {Node} node
  1014. * @param {String} name
  1015. * @return {Boolean}
  1016. */
  1017. function hasBindAttr(node, name) {
  1018. return node.hasAttribute(name) || node.hasAttribute(':' + name) || node.hasAttribute('v-bind:' + name);
  1019. }
  1020. /**
  1021. * Insert el before target
  1022. *
  1023. * @param {Element} el
  1024. * @param {Element} target
  1025. */
  1026. function before(el, target) {
  1027. target.parentNode.insertBefore(el, target);
  1028. }
  1029. /**
  1030. * Insert el after target
  1031. *
  1032. * @param {Element} el
  1033. * @param {Element} target
  1034. */
  1035. function after(el, target) {
  1036. if (target.nextSibling) {
  1037. before(el, target.nextSibling);
  1038. } else {
  1039. target.parentNode.appendChild(el);
  1040. }
  1041. }
  1042. /**
  1043. * Remove el from DOM
  1044. *
  1045. * @param {Element} el
  1046. */
  1047. function remove(el) {
  1048. el.parentNode.removeChild(el);
  1049. }
  1050. /**
  1051. * Prepend el to target
  1052. *
  1053. * @param {Element} el
  1054. * @param {Element} target
  1055. */
  1056. function prepend(el, target) {
  1057. if (target.firstChild) {
  1058. before(el, target.firstChild);
  1059. } else {
  1060. target.appendChild(el);
  1061. }
  1062. }
  1063. /**
  1064. * Replace target with el
  1065. *
  1066. * @param {Element} target
  1067. * @param {Element} el
  1068. */
  1069. function replace(target, el) {
  1070. var parent = target.parentNode;
  1071. if (parent) {
  1072. parent.replaceChild(el, target);
  1073. }
  1074. }
  1075. /**
  1076. * Add event listener shorthand.
  1077. *
  1078. * @param {Element} el
  1079. * @param {String} event
  1080. * @param {Function} cb
  1081. * @param {Boolean} [useCapture]
  1082. */
  1083. function on$1(el, event, cb, useCapture) {
  1084. el.addEventListener(event, cb, useCapture);
  1085. }
  1086. /**
  1087. * Remove event listener shorthand.
  1088. *
  1089. * @param {Element} el
  1090. * @param {String} event
  1091. * @param {Function} cb
  1092. */
  1093. function off(el, event, cb) {
  1094. el.removeEventListener(event, cb);
  1095. }
  1096. /**
  1097. * In IE9, setAttribute('class') will result in empty class
  1098. * if the element also has the :class attribute; However in
  1099. * PhantomJS, setting `className` does not work on SVG elements...
  1100. * So we have to do a conditional check here.
  1101. *
  1102. * @param {Element} el
  1103. * @param {String} cls
  1104. */
  1105. function setClass(el, cls) {
  1106. /* istanbul ignore if */
  1107. if (isIE9 && !(el instanceof SVGElement)) {
  1108. el.className = cls;
  1109. } else {
  1110. el.setAttribute('class', cls);
  1111. }
  1112. }
  1113. /**
  1114. * Add class with compatibility for IE & SVG
  1115. *
  1116. * @param {Element} el
  1117. * @param {String} cls
  1118. */
  1119. function addClass(el, cls) {
  1120. if (el.classList) {
  1121. el.classList.add(cls);
  1122. } else {
  1123. var cur = ' ' + (el.getAttribute('class') || '') + ' ';
  1124. if (cur.indexOf(' ' + cls + ' ') < 0) {
  1125. setClass(el, (cur + cls).trim());
  1126. }
  1127. }
  1128. }
  1129. /**
  1130. * Remove class with compatibility for IE & SVG
  1131. *
  1132. * @param {Element} el
  1133. * @param {String} cls
  1134. */
  1135. function removeClass(el, cls) {
  1136. if (el.classList) {
  1137. el.classList.remove(cls);
  1138. } else {
  1139. var cur = ' ' + (el.getAttribute('class') || '') + ' ';
  1140. var tar = ' ' + cls + ' ';
  1141. while (cur.indexOf(tar) >= 0) {
  1142. cur = cur.replace(tar, ' ');
  1143. }
  1144. setClass(el, cur.trim());
  1145. }
  1146. if (!el.className) {
  1147. el.removeAttribute('class');
  1148. }
  1149. }
  1150. /**
  1151. * Extract raw content inside an element into a temporary
  1152. * container div
  1153. *
  1154. * @param {Element} el
  1155. * @param {Boolean} asFragment
  1156. * @return {Element}
  1157. */
  1158. function extractContent(el, asFragment) {
  1159. var child;
  1160. var rawContent;
  1161. /* istanbul ignore if */
  1162. if (isTemplate(el) && el.content instanceof DocumentFragment) {
  1163. el = el.content;
  1164. }
  1165. if (el.hasChildNodes()) {
  1166. trimNode(el);
  1167. rawContent = asFragment ? document.createDocumentFragment() : document.createElement('div');
  1168. /* eslint-disable no-cond-assign */
  1169. while (child = el.firstChild) {
  1170. /* eslint-enable no-cond-assign */
  1171. rawContent.appendChild(child);
  1172. }
  1173. }
  1174. return rawContent;
  1175. }
  1176. /**
  1177. * Trim possible empty head/tail text and comment
  1178. * nodes inside a parent.
  1179. *
  1180. * @param {Node} node
  1181. */
  1182. function trimNode(node) {
  1183. var child;
  1184. /* eslint-disable no-sequences */
  1185. while ((child = node.firstChild, isTrimmable(child))) {
  1186. node.removeChild(child);
  1187. }
  1188. while ((child = node.lastChild, isTrimmable(child))) {
  1189. node.removeChild(child);
  1190. }
  1191. /* eslint-enable no-sequences */
  1192. }
  1193. function isTrimmable(node) {
  1194. return node && (node.nodeType === 3 && !node.data.trim() || node.nodeType === 8);
  1195. }
  1196. /**
  1197. * Check if an element is a template tag.
  1198. * Note if the template appears inside an SVG its tagName
  1199. * will be in lowercase.
  1200. *
  1201. * @param {Element} el
  1202. */
  1203. function isTemplate(el) {
  1204. return el.tagName && el.tagName.toLowerCase() === 'template';
  1205. }
  1206. /**
  1207. * Create an "anchor" for performing dom insertion/removals.
  1208. * This is used in a number of scenarios:
  1209. * - fragment instance
  1210. * - v-html
  1211. * - v-if
  1212. * - v-for
  1213. * - component
  1214. *
  1215. * @param {String} content
  1216. * @param {Boolean} persist - IE trashes empty textNodes on
  1217. * cloneNode(true), so in certain
  1218. * cases the anchor needs to be
  1219. * non-empty to be persisted in
  1220. * templates.
  1221. * @return {Comment|Text}
  1222. */
  1223. function createAnchor(content, persist) {
  1224. var anchor = config.debug ? document.createComment(content) : document.createTextNode(persist ? ' ' : '');
  1225. anchor.__vue_anchor = true;
  1226. return anchor;
  1227. }
  1228. /**
  1229. * Find a component ref attribute that starts with $.
  1230. *
  1231. * @param {Element} node
  1232. * @return {String|undefined}
  1233. */
  1234. var refRE = /^v-ref:/;
  1235. function findRef(node) {
  1236. if (node.hasAttributes()) {
  1237. var attrs = node.attributes;
  1238. for (var i = 0, l = attrs.length; i < l; i++) {
  1239. var name = attrs[i].name;
  1240. if (refRE.test(name)) {
  1241. return camelize(name.replace(refRE, ''));
  1242. }
  1243. }
  1244. }
  1245. }
  1246. /**
  1247. * Map a function to a range of nodes .
  1248. *
  1249. * @param {Node} node
  1250. * @param {Node} end
  1251. * @param {Function} op
  1252. */
  1253. function mapNodeRange(node, end, op) {
  1254. var next;
  1255. while (node !== end) {
  1256. next = node.nextSibling;
  1257. op(node);
  1258. node = next;
  1259. }
  1260. op(end);
  1261. }
  1262. /**
  1263. * Remove a range of nodes with transition, store
  1264. * the nodes in a fragment with correct ordering,
  1265. * and call callback when done.
  1266. *
  1267. * @param {Node} start
  1268. * @param {Node} end
  1269. * @param {Vue} vm
  1270. * @param {DocumentFragment} frag
  1271. * @param {Function} cb
  1272. */
  1273. function removeNodeRange(start, end, vm, frag, cb) {
  1274. var done = false;
  1275. var removed = 0;
  1276. var nodes = [];
  1277. mapNodeRange(start, end, function (node) {
  1278. if (node === end) done = true;
  1279. nodes.push(node);
  1280. removeWithTransition(node, vm, onRemoved);
  1281. });
  1282. function onRemoved() {
  1283. removed++;
  1284. if (done && removed >= nodes.length) {
  1285. for (var i = 0; i < nodes.length; i++) {
  1286. frag.appendChild(nodes[i]);
  1287. }
  1288. cb && cb();
  1289. }
  1290. }
  1291. }
  1292. 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)$/;
  1293. var reservedTagRE = /^(slot|partial|component)$/;
  1294. /**
  1295. * Check if an element is a component, if yes return its
  1296. * component id.
  1297. *
  1298. * @param {Element} el
  1299. * @param {Object} options
  1300. * @return {Object|undefined}
  1301. */
  1302. function checkComponentAttr(el, options) {
  1303. var tag = el.tagName.toLowerCase();
  1304. var hasAttrs = el.hasAttributes();
  1305. if (!commonTagRE.test(tag) && !reservedTagRE.test(tag)) {
  1306. if (resolveAsset(options, 'components', tag)) {
  1307. return { id: tag };
  1308. } else {
  1309. var is = hasAttrs && getIsBinding(el);
  1310. if (is) {
  1311. return is;
  1312. } else if ('development' !== 'production') {
  1313. if (tag.indexOf('-') > -1 || /HTMLUnknownElement/.test(el.toString()) &&
  1314. // Chrome returns unknown for several HTML5 elements.
  1315. // https://code.google.com/p/chromium/issues/detail?id=540526
  1316. !/^(data|time|rtc|rb)$/.test(tag)) {
  1317. warn('Unknown custom element: <' + tag + '> - did you ' + 'register the component correctly? For recursive components, ' + 'make sure to provide the "name" option.');
  1318. }
  1319. }
  1320. }
  1321. } else if (hasAttrs) {
  1322. return getIsBinding(el);
  1323. }
  1324. }
  1325. /**
  1326. * Get "is" binding from an element.
  1327. *
  1328. * @param {Element} el
  1329. * @return {Object|undefined}
  1330. */
  1331. function getIsBinding(el) {
  1332. // dynamic syntax
  1333. var exp = getAttr(el, 'is');
  1334. if (exp != null) {
  1335. return { id: exp };
  1336. } else {
  1337. exp = getBindAttr(el, 'is');
  1338. if (exp != null) {
  1339. return { id: exp, dynamic: true };
  1340. }
  1341. }
  1342. }
  1343. /**
  1344. * Set a prop's initial value on a vm and its data object.
  1345. *
  1346. * @param {Vue} vm
  1347. * @param {Object} prop
  1348. * @param {*} value
  1349. */
  1350. function initProp(vm, prop, value) {
  1351. var key = prop.path;
  1352. value = coerceProp(prop, value);
  1353. vm[key] = vm._data[key] = assertProp(prop, value) ? value : undefined;
  1354. }
  1355. /**
  1356. * Assert whether a prop is valid.
  1357. *
  1358. * @param {Object} prop
  1359. * @param {*} value
  1360. */
  1361. function assertProp(prop, value) {
  1362. // if a prop is not provided and is not required,
  1363. // skip the check.
  1364. if (prop.raw === null && !prop.required) {
  1365. return true;
  1366. }
  1367. var options = prop.options;
  1368. var type = options.type;
  1369. var valid = true;
  1370. var expectedType;
  1371. if (type) {
  1372. if (type === String) {
  1373. expectedType = 'string';
  1374. valid = typeof value === expectedType;
  1375. } else if (type === Number) {
  1376. expectedType = 'number';
  1377. valid = typeof value === 'number';
  1378. } else if (type === Boolean) {
  1379. expectedType = 'boolean';
  1380. valid = typeof value === 'boolean';
  1381. } else if (type === Function) {
  1382. expectedType = 'function';
  1383. valid = typeof value === 'function';
  1384. } else if (type === Object) {
  1385. expectedType = 'object';
  1386. valid = isPlainObject(value);
  1387. } else if (type === Array) {
  1388. expectedType = 'array';
  1389. valid = isArray(value);
  1390. } else {
  1391. valid = value instanceof type;
  1392. }
  1393. }
  1394. if (!valid) {
  1395. 'development' !== 'production' && warn('Invalid prop: type check failed for ' + prop.path + '="' + prop.raw + '".' + ' Expected ' + formatType(expectedType) + ', got ' + formatValue(value) + '.');
  1396. return false;
  1397. }
  1398. var validator = options.validator;
  1399. if (validator) {
  1400. if (!validator.call(null, value)) {
  1401. 'development' !== 'production' && warn('Invalid prop: custom validator check failed for ' + prop.path + '="' + prop.raw + '"');
  1402. return false;
  1403. }
  1404. }
  1405. return true;
  1406. }
  1407. /**
  1408. * Force parsing value with coerce option.
  1409. *
  1410. * @param {*} value
  1411. * @param {Object} options
  1412. * @return {*}
  1413. */
  1414. function coerceProp(prop, value) {
  1415. var coerce = prop.options.coerce;
  1416. if (!coerce) {
  1417. return value;
  1418. }
  1419. // coerce is a function
  1420. return coerce(value);
  1421. }
  1422. function formatType(val) {
  1423. return val ? val.charAt(0).toUpperCase() + val.slice(1) : 'custom type';
  1424. }
  1425. function formatValue(val) {
  1426. return Object.prototype.toString.call(val).slice(8, -1);
  1427. }
  1428. /**
  1429. * Option overwriting strategies are functions that handle
  1430. * how to merge a parent option value and a child option
  1431. * value into the final value.
  1432. *
  1433. * All strategy functions follow the same signature:
  1434. *
  1435. * @param {*} parentVal
  1436. * @param {*} childVal
  1437. * @param {Vue} [vm]
  1438. */
  1439. var strats = config.optionMergeStrategies = Object.create(null);
  1440. /**
  1441. * Helper that recursively merges two data objects together.
  1442. */
  1443. function mergeData(to, from) {
  1444. var key, toVal, fromVal;
  1445. for (key in from) {
  1446. toVal = to[key];
  1447. fromVal = from[key];
  1448. if (!hasOwn(to, key)) {
  1449. set(to, key, fromVal);
  1450. } else if (isObject(toVal) && isObject(fromVal)) {
  1451. mergeData(toVal, fromVal);
  1452. }
  1453. }
  1454. return to;
  1455. }
  1456. /**
  1457. * Data
  1458. */
  1459. strats.data = function (parentVal, childVal, vm) {
  1460. if (!vm) {
  1461. // in a Vue.extend merge, both should be functions
  1462. if (!childVal) {
  1463. return parentVal;
  1464. }
  1465. if (typeof childVal !== 'function') {
  1466. 'development' !== 'production' && warn('The "data" option should be a function ' + 'that returns a per-instance value in component ' + 'definitions.');
  1467. return parentVal;
  1468. }
  1469. if (!parentVal) {
  1470. return childVal;
  1471. }
  1472. // when parentVal & childVal are both present,
  1473. // we need to return a function that returns the
  1474. // merged result of both functions... no need to
  1475. // check if parentVal is a function here because
  1476. // it has to be a function to pass previous merges.
  1477. return function mergedDataFn() {
  1478. return mergeData(childVal.call(this), parentVal.call(this));
  1479. };
  1480. } else if (parentVal || childVal) {
  1481. return function mergedInstanceDataFn() {
  1482. // instance merge
  1483. var instanceData = typeof childVal === 'function' ? childVal.call(vm) : childVal;
  1484. var defaultData = typeof parentVal === 'function' ? parentVal.call(vm) : undefined;
  1485. if (instanceData) {
  1486. return mergeData(instanceData, defaultData);
  1487. } else {
  1488. return defaultData;
  1489. }
  1490. };
  1491. }
  1492. };
  1493. /**
  1494. * El
  1495. */
  1496. strats.el = function (parentVal, childVal, vm) {
  1497. if (!vm && childVal && typeof childVal !== 'function') {
  1498. 'development' !== 'production' && warn('The "el" option should be a function ' + 'that returns a per-instance value in component ' + 'definitions.');
  1499. return;
  1500. }
  1501. var ret = childVal || parentVal;
  1502. // invoke the element factory if this is instance merge
  1503. return vm && typeof ret === 'function' ? ret.call(vm) : ret;
  1504. };
  1505. /**
  1506. * Hooks and param attributes are merged as arrays.
  1507. */
  1508. strats.init = strats.created = strats.ready = strats.attached = strats.detached = strats.beforeCompile = strats.compiled = strats.beforeDestroy = strats.destroyed = function (parentVal, childVal) {
  1509. return childVal ? parentVal ? parentVal.concat(childVal) : isArray(childVal) ? childVal : [childVal] : parentVal;
  1510. };
  1511. /**
  1512. * 0.11 deprecation warning
  1513. */
  1514. strats.paramAttributes = function () {
  1515. /* istanbul ignore next */
  1516. 'development' !== 'production' && warn('"paramAttributes" option has been deprecated in 0.12. ' + 'Use "props" instead.');
  1517. };
  1518. /**
  1519. * Assets
  1520. *
  1521. * When a vm is present (instance creation), we need to do
  1522. * a three-way merge between constructor options, instance
  1523. * options and parent options.
  1524. */
  1525. function mergeAssets(parentVal, childVal) {
  1526. var res = Object.create(parentVal);
  1527. return childVal ? extend(res, guardArrayAssets(childVal)) : res;
  1528. }
  1529. config._assetTypes.forEach(function (type) {
  1530. strats[type + 's'] = mergeAssets;
  1531. });
  1532. /**
  1533. * Events & Watchers.
  1534. *
  1535. * Events & watchers hashes should not overwrite one
  1536. * another, so we merge them as arrays.
  1537. */
  1538. strats.watch = strats.events = function (parentVal, childVal) {
  1539. if (!childVal) return parentVal;
  1540. if (!parentVal) return childVal;
  1541. var ret = {};
  1542. extend(ret, parentVal);
  1543. for (var key in childVal) {
  1544. var parent = ret[key];
  1545. var child = childVal[key];
  1546. if (parent && !isArray(parent)) {
  1547. parent = [parent];
  1548. }
  1549. ret[key] = parent ? parent.concat(child) : [child];
  1550. }
  1551. return ret;
  1552. };
  1553. /**
  1554. * Other object hashes.
  1555. */
  1556. strats.props = strats.methods = strats.computed = function (parentVal, childVal) {
  1557. if (!childVal) return parentVal;
  1558. if (!parentVal) return childVal;
  1559. var ret = Object.create(null);
  1560. extend(ret, parentVal);
  1561. extend(ret, childVal);
  1562. return ret;
  1563. };
  1564. /**
  1565. * Default strategy.
  1566. */
  1567. var defaultStrat = function defaultStrat(parentVal, childVal) {
  1568. return childVal === undefined ? parentVal : childVal;
  1569. };
  1570. /**
  1571. * Make sure component options get converted to actual
  1572. * constructors.
  1573. *
  1574. * @param {Object} options
  1575. */
  1576. function guardComponents(options) {
  1577. if (options.components) {
  1578. var components = options.components = guardArrayAssets(options.components);
  1579. var def;
  1580. var ids = Object.keys(components);
  1581. for (var i = 0, l = ids.length; i < l; i++) {
  1582. var key = ids[i];
  1583. if (commonTagRE.test(key) || reservedTagRE.test(key)) {
  1584. 'development' !== 'production' && warn('Do not use built-in or reserved HTML elements as component ' + 'id: ' + key);
  1585. continue;
  1586. }
  1587. def = components[key];
  1588. if (isPlainObject(def)) {
  1589. components[key] = Vue.extend(def);
  1590. }
  1591. }
  1592. }
  1593. }
  1594. /**
  1595. * Ensure all props option syntax are normalized into the
  1596. * Object-based format.
  1597. *
  1598. * @param {Object} options
  1599. */
  1600. function guardProps(options) {
  1601. var props = options.props;
  1602. var i, val;
  1603. if (isArray(props)) {
  1604. options.props = {};
  1605. i = props.length;
  1606. while (i--) {
  1607. val = props[i];
  1608. if (typeof val === 'string') {
  1609. options.props[val] = null;
  1610. } else if (val.name) {
  1611. options.props[val.name] = val;
  1612. }
  1613. }
  1614. } else if (isPlainObject(props)) {
  1615. var keys = Object.keys(props);
  1616. i = keys.length;
  1617. while (i--) {
  1618. val = props[keys[i]];
  1619. if (typeof val === 'function') {
  1620. props[keys[i]] = { type: val };
  1621. }
  1622. }
  1623. }
  1624. }
  1625. /**
  1626. * Guard an Array-format assets option and converted it
  1627. * into the key-value Object format.
  1628. *
  1629. * @param {Object|Array} assets
  1630. * @return {Object}
  1631. */
  1632. function guardArrayAssets(assets) {
  1633. if (isArray(assets)) {
  1634. var res = {};
  1635. var i = assets.length;
  1636. var asset;
  1637. while (i--) {
  1638. asset = assets[i];
  1639. var id = typeof asset === 'function' ? asset.options && asset.options.name || asset.id : asset.name || asset.id;
  1640. if (!id) {
  1641. 'development' !== 'production' && warn('Array-syntax assets must provide a "name" or "id" field.');
  1642. } else {
  1643. res[id] = asset;
  1644. }
  1645. }
  1646. return res;
  1647. }
  1648. return assets;
  1649. }
  1650. /**
  1651. * Merge two option objects into a new one.
  1652. * Core utility used in both instantiation and inheritance.
  1653. *
  1654. * @param {Object} parent
  1655. * @param {Object} child
  1656. * @param {Vue} [vm] - if vm is present, indicates this is
  1657. * an instantiation merge.
  1658. */
  1659. function mergeOptions(parent, child, vm) {
  1660. guardComponents(child);
  1661. guardProps(child);
  1662. var options = {};
  1663. var key;
  1664. if (child.mixins) {
  1665. for (var i = 0, l = child.mixins.length; i < l; i++) {
  1666. parent = mergeOptions(parent, child.mixins[i], vm);
  1667. }
  1668. }
  1669. for (key in parent) {
  1670. mergeField(key);
  1671. }
  1672. for (key in child) {
  1673. if (!hasOwn(parent, key)) {
  1674. mergeField(key);
  1675. }
  1676. }
  1677. function mergeField(key) {
  1678. var strat = strats[key] || defaultStrat;
  1679. options[key] = strat(parent[key], child[key], vm, key);
  1680. }
  1681. return options;
  1682. }
  1683. /**
  1684. * Resolve an asset.
  1685. * This function is used because child instances need access
  1686. * to assets defined in its ancestor chain.
  1687. *
  1688. * @param {Object} options
  1689. * @param {String} type
  1690. * @param {String} id
  1691. * @return {Object|Function}
  1692. */
  1693. function resolveAsset(options, type, id) {
  1694. /* istanbul ignore if */
  1695. if (typeof id !== 'string') {
  1696. return;
  1697. }
  1698. var assets = options[type];
  1699. var camelizedId;
  1700. return assets[id] ||
  1701. // camelCase ID
  1702. assets[camelizedId = camelize(id)] ||
  1703. // Pascal Case ID
  1704. assets[camelizedId.charAt(0).toUpperCase() + camelizedId.slice(1)];
  1705. }
  1706. /**
  1707. * Assert asset exists
  1708. */
  1709. function assertAsset(val, type, id) {
  1710. if (!val) {
  1711. 'development' !== 'production' && warn('Failed to resolve ' + type + ': ' + id);
  1712. }
  1713. }
  1714. var arrayProto = Array.prototype;
  1715. var arrayMethods = Object.create(arrayProto)
  1716. /**
  1717. * Intercept mutating methods and emit events
  1718. */
  1719. ;['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(function (method) {
  1720. // cache original method
  1721. var original = arrayProto[method];
  1722. def(arrayMethods, method, function mutator() {
  1723. // avoid leaking arguments:
  1724. // http://jsperf.com/closure-with-arguments
  1725. var i = arguments.length;
  1726. var args = new Array(i);
  1727. while (i--) {
  1728. args[i] = arguments[i];
  1729. }
  1730. var result = original.apply(this, args);
  1731. var ob = this.__ob__;
  1732. var inserted;
  1733. switch (method) {
  1734. case 'push':
  1735. inserted = args;
  1736. break;
  1737. case 'unshift':
  1738. inserted = args;
  1739. break;
  1740. case 'splice':
  1741. inserted = args.slice(2);
  1742. break;
  1743. }
  1744. if (inserted) ob.observeArray(inserted);
  1745. // notify change
  1746. ob.dep.notify();
  1747. return result;
  1748. });
  1749. });
  1750. /**
  1751. * Swap the element at the given index with a new value
  1752. * and emits corresponding event.
  1753. *
  1754. * @param {Number} index
  1755. * @param {*} val
  1756. * @return {*} - replaced element
  1757. */
  1758. def(arrayProto, '$set', function $set(index, val) {
  1759. if (index >= this.length) {
  1760. this.length = Number(index) + 1;
  1761. }
  1762. return this.splice(index, 1, val)[0];
  1763. });
  1764. /**
  1765. * Convenience method to remove the element at given index.
  1766. *
  1767. * @param {Number} index
  1768. * @param {*} val
  1769. */
  1770. def(arrayProto, '$remove', function $remove(item) {
  1771. /* istanbul ignore if */
  1772. if (!this.length) return;
  1773. var index = indexOf(this, item);
  1774. if (index > -1) {
  1775. return this.splice(index, 1);
  1776. }
  1777. });
  1778. var uid$3 = 0;
  1779. /**
  1780. * A dep is an observable that can have multiple
  1781. * directives subscribing to it.
  1782. *
  1783. * @constructor
  1784. */
  1785. function Dep() {
  1786. this.id = uid$3++;
  1787. this.subs = [];
  1788. }
  1789. // the current target watcher being evaluated.
  1790. // this is globally unique because there could be only one
  1791. // watcher being evaluated at any time.
  1792. Dep.target = null;
  1793. /**
  1794. * Add a directive subscriber.
  1795. *
  1796. * @param {Directive} sub
  1797. */
  1798. Dep.prototype.addSub = function (sub) {
  1799. this.subs.push(sub);
  1800. };
  1801. /**
  1802. * Remove a directive subscriber.
  1803. *
  1804. * @param {Directive} sub
  1805. */
  1806. Dep.prototype.removeSub = function (sub) {
  1807. this.subs.$remove(sub);
  1808. };
  1809. /**
  1810. * Add self as a dependency to the target watcher.
  1811. */
  1812. Dep.prototype.depend = function () {
  1813. Dep.target.addDep(this);
  1814. };
  1815. /**
  1816. * Notify all subscribers of a new value.
  1817. */
  1818. Dep.prototype.notify = function () {
  1819. // stablize the subscriber list first
  1820. var subs = toArray(this.subs);
  1821. for (var i = 0, l = subs.length; i < l; i++) {
  1822. subs[i].update();
  1823. }
  1824. };
  1825. var arrayKeys = Object.getOwnPropertyNames(arrayMethods);
  1826. /**
  1827. * Observer class that are attached to each observed
  1828. * object. Once attached, the observer converts target
  1829. * object's property keys into getter/setters that
  1830. * collect dependencies and dispatches updates.
  1831. *
  1832. * @param {Array|Object} value
  1833. * @constructor
  1834. */
  1835. function Observer(value) {
  1836. this.value = value;
  1837. this.dep = new Dep();
  1838. def(value, '__ob__', this);
  1839. if (isArray(value)) {
  1840. var augment = hasProto ? protoAugment : copyAugment;
  1841. augment(value, arrayMethods, arrayKeys);
  1842. this.observeArray(value