Created
February 13, 2017 19:13
-
-
Save NickMcSweeney/7b4bc1da7efb567f4c75b4a7ff23cfbe to your computer and use it in GitHub Desktop.
my web page
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | |
// shim for using process in browser | |
var process = module.exports = {}; | |
// cached from whatever global is present so that test runners that stub it | |
// don't break things. But we need to wrap it in a try catch in case it is | |
// wrapped in strict mode code which doesn't define any globals. It's inside a | |
// function because try/catches deoptimize in certain engines. | |
var cachedSetTimeout; | |
var cachedClearTimeout; | |
function defaultSetTimout() { | |
throw new Error('setTimeout has not been defined'); | |
} | |
function defaultClearTimeout () { | |
throw new Error('clearTimeout has not been defined'); | |
} | |
(function () { | |
try { | |
if (typeof setTimeout === 'function') { | |
cachedSetTimeout = setTimeout; | |
} else { | |
cachedSetTimeout = defaultSetTimout; | |
} | |
} catch (e) { | |
cachedSetTimeout = defaultSetTimout; | |
} | |
try { | |
if (typeof clearTimeout === 'function') { | |
cachedClearTimeout = clearTimeout; | |
} else { | |
cachedClearTimeout = defaultClearTimeout; | |
} | |
} catch (e) { | |
cachedClearTimeout = defaultClearTimeout; | |
} | |
} ()) | |
function runTimeout(fun) { | |
if (cachedSetTimeout === setTimeout) { | |
//normal enviroments in sane situations | |
return setTimeout(fun, 0); | |
} | |
// if setTimeout wasn't available but was latter defined | |
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { | |
cachedSetTimeout = setTimeout; | |
return setTimeout(fun, 0); | |
} | |
try { | |
// when when somebody has screwed with setTimeout but no I.E. maddness | |
return cachedSetTimeout(fun, 0); | |
} catch(e){ | |
try { | |
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally | |
return cachedSetTimeout.call(null, fun, 0); | |
} catch(e){ | |
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error | |
return cachedSetTimeout.call(this, fun, 0); | |
} | |
} | |
} | |
function runClearTimeout(marker) { | |
if (cachedClearTimeout === clearTimeout) { | |
//normal enviroments in sane situations | |
return clearTimeout(marker); | |
} | |
// if clearTimeout wasn't available but was latter defined | |
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { | |
cachedClearTimeout = clearTimeout; | |
return clearTimeout(marker); | |
} | |
try { | |
// when when somebody has screwed with setTimeout but no I.E. maddness | |
return cachedClearTimeout(marker); | |
} catch (e){ | |
try { | |
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally | |
return cachedClearTimeout.call(null, marker); | |
} catch (e){ | |
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. | |
// Some versions of I.E. have different rules for clearTimeout vs setTimeout | |
return cachedClearTimeout.call(this, marker); | |
} | |
} | |
} | |
var queue = []; | |
var draining = false; | |
var currentQueue; | |
var queueIndex = -1; | |
function cleanUpNextTick() { | |
if (!draining || !currentQueue) { | |
return; | |
} | |
draining = false; | |
if (currentQueue.length) { | |
queue = currentQueue.concat(queue); | |
} else { | |
queueIndex = -1; | |
} | |
if (queue.length) { | |
drainQueue(); | |
} | |
} | |
function drainQueue() { | |
if (draining) { | |
return; | |
} | |
var timeout = runTimeout(cleanUpNextTick); | |
draining = true; | |
var len = queue.length; | |
while(len) { | |
currentQueue = queue; | |
queue = []; | |
while (++queueIndex < len) { | |
if (currentQueue) { | |
currentQueue[queueIndex].run(); | |
} | |
} | |
queueIndex = -1; | |
len = queue.length; | |
} | |
currentQueue = null; | |
draining = false; | |
runClearTimeout(timeout); | |
} | |
process.nextTick = function (fun) { | |
var args = new Array(arguments.length - 1); | |
if (arguments.length > 1) { | |
for (var i = 1; i < arguments.length; i++) { | |
args[i - 1] = arguments[i]; | |
} | |
} | |
queue.push(new Item(fun, args)); | |
if (queue.length === 1 && !draining) { | |
runTimeout(drainQueue); | |
} | |
}; | |
// v8 likes predictible objects | |
function Item(fun, array) { | |
this.fun = fun; | |
this.array = array; | |
} | |
Item.prototype.run = function () { | |
this.fun.apply(null, this.array); | |
}; | |
process.title = 'browser'; | |
process.browser = true; | |
process.env = {}; | |
process.argv = []; | |
process.version = ''; // empty string to avoid regexp issues | |
process.versions = {}; | |
function noop() {} | |
process.on = noop; | |
process.addListener = noop; | |
process.once = noop; | |
process.off = noop; | |
process.removeListener = noop; | |
process.removeAllListeners = noop; | |
process.emit = noop; | |
process.binding = function (name) { | |
throw new Error('process.binding is not supported'); | |
}; | |
process.cwd = function () { return '/' }; | |
process.chdir = function (dir) { | |
throw new Error('process.chdir is not supported'); | |
}; | |
process.umask = function() { return 0; }; | |
},{}],2:[function(require,module,exports){ | |
module.exports = { | |
template: ` | |
<p class="links" align="center"> | |
<router-link to="/credentials"> | |
<a id="cred_link">Credentials</a> | |
</router-link> | |
 |   | |
<a target="_blank" title="follow me on instagram" href="http://www.instagram.com/nicholasjamesshindler"><img id="insta" alt="follow me on instagram" src="https://c866088.ssl.cf3.rackcdn.com/assets/instagram30x30.png" border=0></a> | |
</p> | |
` | |
} | |
},{}],3:[function(require,module,exports){ | |
module.exports = { | |
'welcome': require("../windows/main/index.js"), | |
'photography': require("../windows/photography/index.js"), | |
'design': require("../windows/design/index.js"), | |
'brewing': require("../windows/brewing/index.js"), | |
'programing': require("../windows/code/index.js"), | |
'credentials': require("../windows/credentials/index.js"), | |
'right-side-bar': require("./sideBar.js"), | |
'footer-bar': require("./footer.js"), | |
} | |
},{"../windows/brewing/index.js":10,"../windows/code/index.js":13,"../windows/credentials/index.js":15,"../windows/design/index.js":17,"../windows/main/index.js":25,"../windows/photography/index.js":31,"./footer.js":2,"./sideBar.js":4}],4:[function(require,module,exports){ | |
module.exports = { | |
components: { | |
}, | |
props: [], | |
data: function () { | |
return { | |
} | |
}, | |
methods: { | |
}, | |
template: ` | |
<div> | |
</div> | |
` | |
} | |
},{}],5:[function(require,module,exports){ | |
"use strict"; | |
const Vue = require("vue/dist/vue.js"); | |
const VueRouter = require('vue-router'); | |
function registerComponents(components) { | |
Object.keys(components).forEach(componentName => { | |
Vue.component(componentName, components[componentName]); | |
}); | |
} | |
function buildRouter(json) { | |
const routes = _parseRoutes(json); | |
return new VueRouter({ routes }); | |
} | |
function _parseRoutes(routes) { | |
return routes.map(route => { | |
if (route.component) { | |
route.component = Vue.component(route.component); | |
if (!route.component) console.warn(`No component found for route ${route.path}`); | |
if (route.children) { | |
// recursive for child routes... | |
route.children = _parseRoutes(route.children); | |
} | |
} | |
console.log(route); | |
return route; | |
}); | |
}; | |
module.exports = { | |
registerComponents, | |
buildRouter, | |
}; | |
},{"vue-router":69,"vue/dist/vue.js":70}],6:[function(require,module,exports){ | |
module.exports=[ | |
{ | |
"path": "/", | |
"name": "welcome", | |
"component": "welcome" | |
}, | |
{ | |
"path": "/photography", | |
"component": "photography", | |
"children": [ | |
{ | |
"path": "gallery", | |
"component": "photo-gallery" | |
}, | |
{ | |
"path": "lib", | |
"component": "photo-lib" | |
} | |
] | |
}, | |
{ | |
"path": "/design", | |
"name": "desing", | |
"component": "design" | |
}, | |
{ | |
"path": "/programing", | |
"name": "programing", | |
"component": "programing" | |
}, | |
{ | |
"path": "/brewing", | |
"name": "brewing", | |
"component": "brewing" | |
}, | |
{ | |
"path": "/credentials", | |
"name": "credentials", | |
"component": "credentials" | |
}, | |
] | |
},{}],7:[function(require,module,exports){ | |
module.exports = { | |
state: { | |
menu_view: false, | |
style_width: "width:100vw", | |
window: "welcome", | |
galleries: true, | |
gallery: false, | |
show_lib: "photo-lib", | |
gallery: "gallery_001" | |
}, | |
mutations: { | |
toggle_menu: function(state, value) { | |
state.menu_view = value; | |
}, | |
adj_width: function(state, value) { | |
state.style_width = value; | |
}, | |
} | |
} | |
},{}],8:[function(require,module,exports){ | |
const Vue = require("vue/dist/vue.js"); | |
const Vuex = require("vuex"); | |
const VueRouter = require('vue-router'); | |
const startup = require("../frontend/scripts/vueStartup.js"); | |
startup.registerComponents(require('../components')); | |
startup.registerComponents(require("./photography/components")); | |
startup.registerComponents(require("./main/components")); | |
startup.registerComponents(require("./design/components")); | |
startup.registerComponents(require("./brewing/components")); | |
startup.registerComponents(require("./code/components")); | |
startup.registerComponents(require("./credentials/components")); | |
Vue.use(Vuex); | |
Vue.use(VueRouter); | |
const store = new Vuex.Store(require("../store")); | |
const router = startup.buildRouter(require('../routes.json')); | |
const routerSync = require('vuex-router-sync'); | |
Vue.use(require("@welocalize/useful-shit").vue); | |
return new Vue({ | |
el: '#app', | |
router, | |
store, | |
template: ` | |
<transition name="component-fade" mode="out-in"> | |
<router-view></router-view> | |
</transition> | |
` | |
}); | |
// <router-view></router-view> | |
// <component :is="$store.state.window"></component> | |
},{"../components":3,"../frontend/scripts/vueStartup.js":5,"../routes.json":6,"../store":7,"./brewing/components":9,"./code/components":12,"./credentials/components":14,"./design/components":16,"./main/components":20,"./photography/components":27,"@welocalize/useful-shit":32,"vue-router":69,"vue/dist/vue.js":70,"vuex":72,"vuex-router-sync":71}],9:[function(require,module,exports){ | |
module.exports = { | |
} | |
},{}],10:[function(require,module,exports){ | |
module.exports = { | |
template: ` | |
` | |
} | |
},{}],11:[function(require,module,exports){ | |
module.exports = { | |
components: { | |
}, | |
props: [], | |
data: function () { | |
return { | |
} | |
}, | |
methods: { | |
}, | |
template: ` | |
` | |
}; | |
},{}],12:[function(require,module,exports){ | |
module.exports = { | |
'code-display': require("./codeDisplay.js"), | |
} | |
},{"./codeDisplay.js":11}],13:[function(require,module,exports){ | |
module.exports = { | |
data: function () { | |
return { | |
projects: [ | |
{header: 'proj 1', content: 'this is... { stuff 1 }'}, | |
{header: 'proj 2', content: 'this is... { stuff 2 }'}, | |
{header: 'proj 3', content: 'this is... { stuff 3 }'}, | |
] | |
} | |
}, | |
template: ` | |
<div id="page_view"> | |
<h1>{Code}</h1> | |
<div> | |
<tab-list> | |
<tab v-for="project in projects" :header="project.header"> | |
{{project.content}} | |
</tab> | |
</tab-list> | |
</div> | |
<footer-bar></footer-bar> | |
</div> | |
` | |
} | |
},{}],14:[function(require,module,exports){ | |
arguments[4][9][0].apply(exports,arguments) | |
},{"dup":9}],15:[function(require,module,exports){ | |
arguments[4][10][0].apply(exports,arguments) | |
},{"dup":10}],16:[function(require,module,exports){ | |
arguments[4][9][0].apply(exports,arguments) | |
},{"dup":9}],17:[function(require,module,exports){ | |
arguments[4][10][0].apply(exports,arguments) | |
},{"dup":10}],18:[function(require,module,exports){ | |
module.exports = { | |
components: { | |
}, | |
data: function () { | |
return { | |
} | |
}, | |
methods: { | |
}, | |
template: ` | |
<div class="side_bar_img"> | |
<img id="side_bar-bkgrnd-img" src="frontend/images/Cover_photo.png"> | |
</div> | |
` | |
}; | |
},{}],19:[function(require,module,exports){ | |
module.exports = { | |
components: { | |
}, | |
props: [], | |
data: function () { | |
return { | |
show: true, | |
} | |
}, | |
methods: { | |
pushCover() { | |
console.log("hello") | |
this.$store.commit('toggle_menu', this.show) | |
this.show = false | |
this.$store.commit('adj_width', "width:16vw") | |
}, | |
}, | |
template: ` | |
<div id="cont" :style="this.$store.state.style_width"> | |
<transition name="slide"> | |
<img v-if="show" class="background-img" src="frontend/images/Cover_photo.png"> | |
</transition> | |
<div id="hide"> | |
<transition name="slide-fade"> | |
<p v-if="show" @click="pushCover" class="prompt">click to enter . . . </p> | |
</transition> | |
<transition name="slide-fade"> | |
<img v-if="show" class="cvr-arrow" @click="pushCover" src="frontend/icons/arrow.png"> | |
</transition> | |
</div> | |
</div> | |
` | |
}; | |
},{}],20:[function(require,module,exports){ | |
module.exports = { | |
'main-menu': require("./menu.js"), | |
'side-bar': require("./sideBar.js"), | |
'cover-panel': require("./coverPanel.js"), | |
'cover-frame': require("./coverFrame.js"), | |
'link-bar': require("./linkBar.js"), | |
'menu-btn': require("./menuBtn.js") | |
} | |
},{"./coverFrame.js":18,"./coverPanel.js":19,"./linkBar.js":21,"./menu.js":22,"./menuBtn.js":23,"./sideBar.js":24}],21:[function(require,module,exports){ | |
module.exports = { | |
components: { | |
}, | |
template: ` | |
<p class="links"> | |
<router-link to="/credentials"> | |
<a id="cred_link">Credentials</a> | |
</router-link> | |
 |   | |
<a target="_blank" title="follow me on instagram" href="http://www.instagram.com/nicholasjamesshindler"><img id="insta" alt="follow me on instagram" src="https://c866088.ssl.cf3.rackcdn.com/assets/instagram30x30.png" border=0></a> | |
</p> | |
` | |
}; | |
},{}],22:[function(require,module,exports){ | |
module.exports = { | |
components: { | |
'menu-btn': require("./menuBtn.js") | |
}, | |
template: ` | |
<div class="myView"> | |
<menu-btn navTo="/photography/lib" btn_float="right_btn" name="photography" btn_img="frontend/images/photography.png"> | |
<h4 slot="title">Photography</h4> | |
<h6 slot="sub_title">nature & travel</h6> | |
</menu-btn> | |
<menu-btn navTo="/programing" btn_float="left_btn" name="programing" btn_img="frontend/images/programing.png"> | |
<h4 slot="title">Programing</h4> | |
<h6 slot="sub_title">applications and more</h6> | |
</menu-btn> | |
<menu-btn navTo="/brewing" btn_float="right_btn" name="brewing" btn_img="frontend/images/brewing.png"> | |
<h4 slot="title">Brewing</h4> | |
<h6 slot="sub_title">ideas, recipies, plans</h6> | |
</menu-btn> | |
<menu-btn navTo="/design" btn_float="left_btn" name="design" btn_img="frontend/images/design.png"> | |
<h4 slot="title">Design</h4> | |
<h6 slot="sub_title">projects I've designed</h6> | |
</menu-btn> | |
</div> | |
` | |
}; | |
},{"./menuBtn.js":23}],23:[function(require,module,exports){ | |
module.exports = { | |
props: ['btn_img','name','btn_float','navTo'], | |
template: ` | |
<router-link :to="navTo"> | |
<div :class="btn_float" :name="name"> | |
<div class="img"> | |
<img id='IMG' :src="btn_img"> | |
</div> | |
<div class="text"> | |
<slot name="title"></slot> | |
<slot name="sub_title"></slot> | |
</div> | |
</div> | |
</router-link> | |
` | |
} | |
},{}],24:[function(require,module,exports){ | |
module.exports = { | |
components: { | |
}, | |
template: ` | |
<div class="side-bar_menu"> | |
<h1 class="name_title"> | |
Nicholas James Shindler | |
</h1> | |
<transition name='fade-delay' mode="out-in"> | |
<ul class="side_menu" v-if="!$store.state.menu_view"> | |
<li><router-link to="/brewing">Brewing</router-link></li> | |
<li><router-link to="/photography/lib">Photography</router-link></li> | |
<li><router-link to="/design">Design</router-link></li> | |
<li><router-link to="/code">Programing</router-link></li> | |
<li><router-link to="/credentials">Credentials</router-link></li> | |
</ul> | |
<h5 class="side_description" v-if="$store.state.menu_view"> | |
This is some kind of blurb about some kind of bulshit kind of stuff. | |
</h5> | |
</transition> | |
</div> | |
` | |
}; | |
// <li><a>Brewing</a></li> | |
// <li><a>Photography</a></li> | |
// <li><a>Design</a></li> | |
// <li><a>Programing</a></li> | |
// <li><a>Credentials</a></li> | |
},{}],25:[function(require,module,exports){ | |
module.exports = { | |
template: ` | |
<div class="welcome_panel"> | |
<div class="side-bar" :style="this.$store.state.style_width"> | |
<side-bar></side-bar> | |
<cover-panel></cover-panel> | |
</div> | |
<transition name="fade"> | |
<div class="hidden_menu" v-if="$store.state.menu_view"> | |
<main-menu></main-menu> | |
<div id="btm-bar" align="center"> | |
<link-bar></link-bar> | |
</div> | |
</div> | |
</transition> | |
</div> | |
` | |
}; | |
},{}],26:[function(require,module,exports){ | |
module.exports = { | |
data: function () { | |
return { | |
img_source: "frontend/images/photo/" + this.$store.state.gallery + ".png" | |
} | |
}, | |
template: ` | |
<div> | |
<h1>hello world</h1> | |
<img :src=img_source> | |
</div> | |
` | |
} | |
},{}],27:[function(require,module,exports){ | |
module.exports = { | |
'photo-link': require("./links.js"), | |
'page-title': require("./title.js"), | |
'photo-lib': require("./lib.js"), | |
'photo-gallery': require("./gallery.js"), | |
} | |
},{"./gallery.js":26,"./lib.js":28,"./links.js":29,"./title.js":30}],28:[function(require,module,exports){ | |
module.exports = { | |
components: { | |
}, | |
data: function () { | |
return { | |
gallerys: [ | |
{name: "test_001", img_src: "frontend/images/photo/001.svg", orient_class: "landscape", style: "sm_lan"}, | |
{name: "test_002", img_src: "frontend/images/photo/002.svg", orient_class: "portrait", style: "lg_port"}, | |
{name: "test_003", img_src: "frontend/images/photo/003.png", orient_class: "portrait", style: "lg_port"}, | |
{name: "test_004", img_src: "frontend/images/photo/004.png", orient_class: "landscape", style: "sm_lan"}, | |
{name: "test_005", img_src: "frontend/images/photo/003.png", orient_class: "portrait", style: "lg_port"}, | |
{name: "test_006", img_src: "frontend/images/photo/002.svg", orient_class: "portrait", style: "lg_port"}, | |
{name: "test_007", img_src: "frontend/images/photo/004.png", orient_class: "landscape", style: "sm_lan"}, | |
{name: "test_008", img_src: "frontend/images/photo/001.svg", orient_class: "landscape", style: "sm_lan"}, | |
{name: "test_009", img_src: "frontend/images/photo/002.svg", orient_class: "portrait", style: "lg_port"}, | |
{name: "test_010", img_src: "frontend/images/photo/004.png", orient_class: "landscape", style: "sm_lan"}, | |
{name: "test_011", img_src: "frontend/images/photo/001.svg", orient_class: "landscape", style: "sm_lan"}, | |
{name: "test_012", img_src: "frontend/images/photo/003.png", orient_class: "portrait", style: "lg_port"}, | |
{name: "test_013", img_src: "frontend/images/photo/002.svg", orient_class: "portrait", style: "lg_port"}, | |
{name: "test_014", img_src: "frontend/images/photo/001.svg", orient_class: "landscape", style: "sm_lan"}, | |
{name: "test_015", img_src: "frontend/images/photo/004.png", orient_class: "landscape", style: "sm_lan"}, | |
{name: "test_014", img_src: "frontend/images/photo/003.png", orient_class: "portrait", style: "lg_port"}, | |
] | |
} | |
}, | |
template: ` | |
<div class="lib" align="center"> | |
<ul> | |
<li v-for="gallery in gallerys"><photo-link :class="gallery.orient_class" :name="gallery.name" :source="gallery.img_src" :imgStyle="gallery.style"></photo-link></li> | |
</ul> | |
</div> | |
` | |
} | |
},{}],29:[function(require,module,exports){ | |
module.exports = { | |
props: ['name', 'source', 'imgStyle'], | |
methods: { | |
toggle_gallery () { | |
console.log(this.$store.state.gallery) | |
this.$store.state.gallery = this.name | |
console.log(this.$store.state.gallery) | |
} | |
}, | |
template: ` | |
<div @click="toggle_gallery"> | |
<router-link to="/photography/gallery"> | |
<!-- --> | |
<img :class="imgStyle" :name="name" :src="source"></img> | |
<!-- --> | |
</router-link> | |
</div> | |
` | |
} | |
},{}],30:[function(require,module,exports){ | |
module.exports = { | |
template: ` | |
<div class="title-bar" align="center"> | |
<h1>Photography</h1> | |
</div> | |
` | |
} | |
},{}],31:[function(require,module,exports){ | |
module.exports = { | |
template: ` | |
<div class="photo_page"> | |
<page-title id="photo_title"></page-title> | |
<transition name="component-fade" mode="out-in"> | |
<router-view></router-view> | |
</transition> | |
<footer-bar></footer-bar> | |
</div> | |
` | |
}; | |
},{}],32:[function(require,module,exports){ | |
"use strict"; | |
module.exports = require("./src"); | |
},{"./src":33}],33:[function(require,module,exports){ | |
"use strict"; | |
module.exports = { | |
vue: require("./vue"), | |
// electron: require("./electron"), | |
}; | |
},{"./vue":63}],34:[function(require,module,exports){ | |
'use strict'; | |
module.exports = { | |
name: 'component-tree', | |
template: ` | |
<li :class="{ active: isActive, opened: open, children: hasChildren }"> | |
<a class="component-link" @click.prevent="select"> | |
<{{ component.$options.name || component.$options._componentTag}}> | |
<span class="count" v-if="hasChildren"> | |
{{ children.length }} {{ pluralChildren()}} | |
</span> | |
</a> | |
<ul v-if="hasChildren && open"> | |
<component-tree | |
v-for="comp in children" v-on:dataChange="dataChange" :activeKey="activeKey" :component="comp"> | |
</component-tree> | |
</ul> | |
</li> | |
`, | |
data() { | |
return { | |
int: 0, | |
open: false, | |
}; | |
}, | |
mounted() { | |
this.int = setInterval(() => { | |
this.$forceUpdate(); | |
}, 1000); | |
}, | |
beforeDetroy() { | |
clearInterval(this.int); | |
}, | |
props: ['component', 'activeKey'], | |
computed: { | |
children() { | |
return this.component.$children; | |
}, | |
hasChildren() { | |
return this.children.length > 0; | |
}, | |
isActive() { | |
return this.component._uid == this.activeKey; | |
} | |
}, | |
methods: { | |
dataChange(args) { | |
this.$emit('dataChange', args); | |
}, | |
pluralChildren() { | |
return this.children.length == 1 ? 'Child' : 'Children'; | |
}, | |
select() { | |
this.dataChange({ | |
name: this.component.$options.name, | |
id: this.component._uid, | |
data: { | |
data: this.component.$data, | |
props: this.component.$options.propsData | |
} | |
}); | |
this.toggle(); | |
}, | |
toggle() { | |
this.open = !this.open; | |
} | |
} | |
}; | |
},{}],35:[function(require,module,exports){ | |
'use strict'; | |
module.exports = { | |
name: 'debugger', | |
template: ` | |
<div class="vue-debugger container"> | |
<div class="vue-debugger pane" :class="{ opened: open }"> | |
<div class="vue-debugger toggle" @click.prevent="toggle">🔮</div> | |
<nav-tree | |
:components="components" | |
v-on:dataChange="dataChange" | |
:activeKey="activeKey" | |
v-if="keepAlive || open"> | |
</nav-tree> | |
<div class="vue-debugger main-pane" v-if="keepAlive || open"> | |
<obj-tree | |
v-for="value, key in dataSource" :name="key" :value="value"> | |
</obj-tree> | |
</div> | |
</div> | |
</div> | |
`, | |
mounted() { | |
window.addEventListener('keydown', (ev) => { | |
if (ev.ctrlKey && ev.code == 'KeyD') this.toggle(); | |
}); | |
}, | |
methods: { | |
shortcuts(ev) { | |
}, | |
showKey(key) { | |
this.activeKey = key; | |
}, | |
toggle() { | |
this.open = !this.open; | |
}, | |
dataChange(args) { | |
this.activeKey = args.id; | |
this.dataSource = args.data; | |
} | |
}, | |
props: ['components', 'keepAlive'], | |
components: { | |
'obj-tree': require('./obj-tree'), | |
'nav-tree': require('./nav-tree'), | |
}, | |
data() { | |
return { | |
activeKey: 'vuex', | |
open: false, | |
dataSource: this.$store.state | |
}; | |
} | |
}; | |
},{"./nav-tree":36,"./obj-tree":37}],36:[function(require,module,exports){ | |
'use strict'; | |
let int = 0; | |
module.exports = { | |
name: 'nav-tree', | |
props: ['components', 'activeKey'], | |
template: ` | |
<div class="vue-debugger nav-pane"> | |
<ul> | |
<li :class="{ active: activeKey == 'vuex' }"> | |
<a | |
@click.prevent="dataChange({ name: 'vuex', id: 'vuex', data: $store.state })"> | |
Vuex</a> | |
</li> | |
<component-tree | |
v-for="comp in components" | |
v-on:dataChange="dataChange" | |
v-if="comp.$options.name != 'debugger'" | |
:component="comp" | |
:activeKey="activeKey"> | |
</component-tree> | |
</ul> | |
</div> | |
`, | |
mounted() { | |
this.int = setInterval(() => { | |
this.$forceUpdate(); | |
}, 1000); | |
}, | |
beforeDetroy() { | |
clearInterval(this.int); | |
}, | |
methods: { | |
dataChange(args) { | |
this.$emit('dataChange', args); | |
} | |
}, | |
data() { | |
return { | |
int: 0 | |
}; | |
}, | |
components: { | |
'component-tree': require('./component-tree'), | |
}, | |
}; | |
},{"./component-tree":34}],37:[function(require,module,exports){ | |
'use strict'; | |
const Type = require('type-of-is'); | |
module.exports = { | |
name: 'obj-tree', | |
template: ` | |
<div class="vue-debugger obj-tree" :class="{ open: isOpen, empty: length == 0 }" > | |
<span class="key" | |
v-if="name" :class="type" @click.prevent="toggle"> | |
{{ name }}<span class="divider">: </span> | |
</span> | |
<span class="type" | |
v-if="hasChildren" @click.prevent="toggle" :class="type"> | |
{{ type }} {{ length }} | |
</span> | |
<span class="container" v-if="hasChildren && isOpen"> | |
<obj-tree | |
v-for="val, key in value" | |
:name="key.toString()" :parentOpen="type =='Array'" :value="val"> | |
</obj-tree> | |
</span> | |
<span class="value" :class="type" v-else-if="!hasChildren"> | |
{{ printValue() }} | |
</span> | |
</div> | |
`, | |
props: ['name', 'value', 'parentOpen'], | |
data() { | |
return { | |
beenClicked: false, | |
open: this.name ? false : true | |
}; | |
}, | |
computed: { | |
isOpen() { | |
if (!this.beenClicked && this.parentOpen) this.open = true; | |
return this.open; | |
}, | |
length() { | |
if (this.type == 'Object') return Object.keys(this.value).length; | |
if (this.type == 'Array') return this.value.length; | |
return 0; | |
}, | |
type() { | |
return Type.string(this.value); | |
}, | |
hasChildren() { | |
return this.length > 0; | |
}, | |
}, | |
methods: { | |
printValue() { | |
if (this.type == 'null') return 'null'; | |
if (this.value == undefined) return 'undefined'; | |
if (this.value == '' && this.type == 'String') return '""'; | |
if (this.type == 'Array' && this.value.length == 0) return '[]'; | |
if (this.type == 'Object' && Object.keys(this.value).length == 0) return '{}'; | |
return this.value.toString(); | |
}, | |
toggle() { | |
this.beenClicked = true; | |
this.open = !this.open; | |
}, | |
} | |
}; | |
},{"type-of-is":68}],38:[function(require,module,exports){ | |
"use strict"; | |
module.exports = { | |
name: "dropdown-menu", | |
template: ` | |
<div class="dropdown-container"> | |
<div | |
class="opener-container" | |
@click="openDialog" | |
> | |
<slot name="opener"> | |
<i class="icon-context-menu"></i> | |
</slot> | |
</div> | |
<dialog ref="dialog" :style="dialogStyle"> | |
<slot name="dialog"></slot> | |
</dialog> | |
</div> | |
`, | |
props: { | |
side: { | |
type: String, | |
default: () => "right", | |
}, | |
}, | |
computed: { | |
dialogStyle() { | |
const style = {}; | |
switch (this.side) { | |
case "right": | |
style.left = 0; | |
style.right = "auto"; | |
break; | |
case "right": | |
default: | |
style.right = 0; | |
style.left = "auto"; | |
break; | |
} | |
return style; | |
}, | |
}, | |
methods: { | |
openDialog(ev) { | |
if (this.$refs.dialog.open) return; | |
ev.preventDefault(); | |
ev.stopPropagation(); | |
this.$refs.dialog.show(); | |
document.body.addEventListener("click", this.dialogClickAway); | |
document.body.addEventListener("keydown", this.dialogEsc); | |
}, | |
closeDialog() { | |
this.$refs.dialog.close(); | |
document.body.removeEventListener("click", this.dialogClickAway); | |
document.body.removeEventListener("keydown", this.dialogEsc); | |
}, | |
dialogEsc(ev) { | |
if (ev.keyCode === 27) { | |
ev.preventDefault(); | |
ev.stopPropagation(); | |
this.closeDialog(); | |
} | |
}, | |
dialogClickAway(ev) { | |
if (!this.$refs.dialog.contains(ev.target) || ev.target.dataset.action === "close") { | |
this.closeDialog(); | |
} | |
}, | |
}, | |
}; | |
},{}],39:[function(require,module,exports){ | |
"use strict"; | |
/** | |
* File input creates an input tag with drag and drop for files, and a file upload button | |
* | |
* emits: | |
* add - payload: { FileList } | |
* event is emitted when files are added to the input | |
* | |
* When using this component be sure to add the following to index.html to prevent electron | |
* from bombing when dragging files onto the window: | |
* | |
* document.addEventListener("dragover", e => e.preventDefault()); | |
* document.addEventListener("drop", e => e.preventDefault()); | |
* | |
* could probably add those listeners in created() here but user may try to drag files onto app | |
* when this component has not been created yet | |
*/ | |
module.exports = { | |
name: "file-input", | |
template: ` | |
<div | |
class="file-drop" | |
droppable="true" | |
:class="dragClass" | |
@dragover="dragOver" | |
@dragleave="dragLeave" | |
@drop="drop" | |
> | |
<label :for="inputId"> | |
<slot name="label"> | |
<i class="icon icon-upload-solid"></i> | |
Drag file(s) or click here to upload | |
</slot> | |
<input | |
type="file" | |
name="files" | |
multiple | |
:id="inputId" | |
@change="change" | |
/> | |
</label> | |
<slot name="files"></slot> | |
<slot name="errors"></slot> | |
</div> | |
`, | |
data() { | |
return { | |
inputId: `upload-${Math.floor((1 + Math.random()) * 0x1000000000000).toString(36)}`, | |
dragging: false, | |
}; | |
}, | |
computed: { | |
dragClass() { | |
return { | |
"drag-over": this.dragging, | |
}; | |
}, | |
}, | |
methods: { | |
dragOver() { | |
this.dragging = true; | |
}, | |
dragLeave() { | |
this.dragging = false; | |
}, | |
drop(ev) { | |
this.dragging = false; | |
this.addFiles(ev.dataTransfer.files); | |
}, | |
change(ev) { | |
this.addFiles(ev.currentTarget.files); | |
}, | |
addFiles(fileList) { | |
this.$emit("add", { | |
fileList, | |
}); | |
}, | |
}, | |
}; | |
},{}],40:[function(require,module,exports){ | |
"use strict"; | |
let focusedInt; | |
module.exports = { | |
computed: { | |
inputSize() { | |
return this.search.length > 0 ? Math.ceil(this.search.length*1.5) : 1; | |
}, | |
}, | |
methods: { | |
onEnterKey(ev) { | |
if (this.matches.length > 0) { | |
if (this.editing) { | |
this.updateFilter(this.selected); | |
} else { | |
this.addFilter(this.selected); | |
} | |
} | |
}, | |
isMatch(key, str) { | |
return str.trim() == "" || key.toLowerCase().indexOf(str.toLowerCase()) === 0; | |
}, | |
arrowDown(ev) { | |
ev.stopPropagation(); | |
ev.preventDefault(); | |
this.arrow('down'); | |
return false; | |
}, | |
arrowUp(ev) { | |
ev.stopPropagation(); | |
ev.preventDefault(); | |
this.arrow('up'); | |
return false; | |
}, | |
arrow(dir) { | |
let index = this.matches.findIndex(match => match == this.selected); | |
index = dir == "down" ? index + 1 : index - 1; | |
if (this.matches[index]) { | |
this.selected = this.matches[index]; | |
this.scrollIntoView(); | |
} | |
}, | |
onBlur() { | |
focusedInt = setTimeout(() => { | |
this.focused = false; | |
this.$emit('edit', null); | |
}, 300); | |
}, | |
onFocus() { | |
if (focusedInt) clearInterval(focusedInt); | |
this.focused = true; | |
}, | |
focus() { | |
this.$el.querySelector('input').focus(); | |
}, | |
cancel() { | |
this.$el.querySelector('input').blur(); | |
}, | |
scrollIntoView() { | |
let el = this.$el.querySelector(`*[data-key="${this.selected}"]`); | |
if (el) el.scrollIntoView(); | |
}, | |
mark(match) { | |
let len = this.search.length; | |
return len == 0 ? match : `<mark>${match.substring(0, len)}</mark>${match.substring(len, match.length)}`; | |
}, | |
}, | |
}; | |
},{}],41:[function(require,module,exports){ | |
"use strict"; | |
module.exports = { | |
template: ` | |
<div class="add-filter"> | |
<input id="input" | |
@keyup.enter.prevent="addFilter(selected)" | |
@keyup.down.prevent="arrowDown" | |
@keyup.up.prevent="arrowUp" | |
@keydown.delete="onDelete" | |
@keyup.esc="cancel" | |
@blur="onBlur" | |
@focus="onFocus" | |
:size="inputSize" | |
v-model="search" | |
placeholder="Add Filter:" class="filter-input" type="text" /> | |
<ul class="menu" v-if="focused"> | |
<li v-for="match in matches" :data-key="match" :class="{ active: selected == match }"> | |
<a @click.prevent="addFilter(match)" v-html="mark(match)"></a> | |
</li> | |
</ul> | |
</div> | |
`, | |
name: 'filter-add', | |
mixins: [require('./filter-mixin')], | |
props: ['engaged', 'options'], | |
mounted() { | |
if (this.engaged) this.focus(); | |
}, | |
methods: { | |
onDelete() { | |
this.$emit('deleteLast'); | |
}, | |
addFilter(chosen) { | |
if (this.matches.length == 0) return; | |
this.$emit('add', {key: chosen}); | |
}, | |
}, | |
data() { | |
return { | |
search: '', | |
focused: false, | |
selected: '' | |
}; | |
}, | |
computed: { | |
matches() { | |
const matches = Object.keys(this.options).filter(key => this.isMatch(key, this.search) ); | |
this.selected = matches[0]; | |
return matches; | |
}, | |
}, | |
}; | |
},{"./filter-mixin":40}],42:[function(require,module,exports){ | |
"use strict"; | |
module.exports = { | |
template: ` | |
<div class="filter" :class="{error: !editing && filter.value == null }"> | |
<span @click.prevent="editFilter"> | |
<span>{{filter.key}}:</span> | |
<span v-if="!editing">{{filter.value}}</span> | |
</span> | |
<div v-if="editing" class="input-wrapper"> | |
<input id="input" | |
@keyup.enter.prevent="updateFilter(selected)" | |
@keyup.down.prevent="arrowDown" | |
@keyup.up.prevent="arrowUp" | |
@keydown.esc="cancel" | |
@blur="onBlur" | |
@focus="onFocus" | |
:value="search" | |
:size="inputSize" | |
v-focus | |
v-model="search" | |
class="filter-input" type="text" /> | |
</div> | |
<i class="icon-cancel" @click.prevent="removeFilter"></i> | |
<ul v-if="editing && focused" class="menu"> | |
<li v-for="match in matches" :data-key="match" :class="{ active: selected == match }"> | |
<a @click.prevent="updateFilter(match)" v-html="mark(match)"></a> | |
</li> | |
</ul> | |
</div> | |
`, | |
name: 'filter-edit', | |
mixins: [require('./filter-mixin')], | |
props: ['filter', 'editing', 'options', 'filters'], | |
data() { | |
return { | |
search: '', | |
selected: null, | |
focused: false | |
}; | |
}, | |
methods: { | |
updateFilter(chosen) { | |
if (this.matches.length == 0) return; | |
this.filter.value = this.search = chosen; | |
this.$emit('update', this.filter); | |
}, | |
removeFilter() { | |
this.$emit('remove', this.filter); | |
}, | |
editFilter() { | |
this.$emit('edit', this.filter); | |
}, | |
}, | |
computed: { | |
matches() { | |
const used = this.filters | |
.filter(filter => filter.key == this.filter.key && filter.value) | |
.map(filter => filter.value); | |
const matches = this.options[this.filter.key] | |
.filter(option => { | |
return this.isMatch(option, this.search) && !used.includes(option); | |
}); | |
this.selected = matches[0]; | |
return matches; | |
}, | |
} | |
}; | |
},{"./filter-mixin":40}],43:[function(require,module,exports){ | |
"use strict"; | |
module.exports = { | |
template: ` | |
<div @click="clicked" class="filter-container"> | |
<div class="filter-wrapper"> | |
<filter-edit | |
v-for="filter in filters" | |
:options="options" | |
:filter="filter" | |
:filters="filters" | |
:editing="isEditing(filter)" | |
v-on:update="updateFilter" | |
v-on:remove="removeFilter" | |
v-on:edit="editFilter"> | |
</filter-edit> | |
<filter-add | |
v-if="!filterEditing" | |
:engaged="receivedFocus" | |
:options="options" | |
v-on:add="addFilter" | |
v-on:deleteLast="deleteLastFilter"> | |
</filter-add> | |
</div> | |
</div> | |
`, | |
name: 'filter-bar', | |
props: ['options', 'active'], | |
components: { | |
'filter-add': require('./filterAdd'), | |
'filter-edit': require('./filterEdit'), | |
}, | |
computed: { | |
filters() { | |
return this.active.map(filter => Object.assign({}, filter)); | |
} | |
}, | |
methods: { | |
clicked() { | |
this.receivedFocus = true; | |
}, | |
isEditing(filter) { | |
return this.filterEditing | |
&& this.filterEditing.key == filter.key | |
&& this.filterEditing.value == filter.value; | |
}, | |
findIndex(searchFor) { | |
return this.filters.findIndex(filter => { | |
return filter.key == searchFor.key && filter.value == searchFor.value; | |
}); | |
}, | |
// listeners | |
deleteLastFilter() { | |
this.filters.pop(); | |
this.dispatchChange(); | |
}, | |
addFilter(filter) { | |
filter.index = this.filters.length; | |
this.filters.push(filter); | |
this.editFilter(filter); | |
}, | |
removeFilter(filter) { | |
const index = this.findIndex(filter); | |
this.filters.splice(index, 1); | |
this.editFilter(null); | |
this.dispatchChange(); | |
}, | |
editFilter(filter) { | |
this.filterEditing = filter; | |
if (filter == null) { | |
this.editingIndex = null; | |
this.findNeedsEditing(); | |
return; | |
} | |
this.editingIndex = this.findIndex(filter); | |
}, | |
updateFilter(filter) { | |
this.filters[this.editingIndex] = filter; | |
this.filterEditing = this.edtingIndex = null; | |
this.dispatchChange(); | |
}, | |
findNeedsEditing() { | |
this.filters.forEach((filter, index) => { | |
if (!filter.value) { | |
this.editingFilter = filter; | |
this.editingIndex = index; | |
} | |
}); | |
}, | |
dispatchChange() { | |
this.$emit('filters', this.filters); | |
} | |
}, | |
data() { | |
return { | |
receivedFocus: false, | |
editingIndex: null, | |
filterEditing: null | |
}; | |
}, | |
}; | |
},{"./filterAdd":41,"./filterEdit":42}],44:[function(require,module,exports){ | |
const components = { | |
tab: require("./tab"), | |
"tab-list": require("./tabList"), | |
"tag-list": require("./tagList"), | |
"dropdown-menu": require("./dropdownMenu"), | |
"debugger": require("./debugger"), | |
"file-input": require("./fileInput"), | |
"filter-bar": require("./filterBar"), | |
modal: require("./modal"), | |
"type-ahead": require("./typeAhead"), | |
spinner: require("./spinner"), | |
"multiple-choice": require("./multipleChoice"), | |
}; | |
function install(Vue, options) { | |
Object.keys(components).forEach(key => { | |
Vue.component(key, components[key]); | |
}); | |
} | |
module.exports = Object.assign({ install }, components); | |
},{"./debugger":35,"./dropdownMenu":38,"./fileInput":39,"./filterBar":43,"./modal":45,"./multipleChoice":46,"./spinner":47,"./tab":48,"./tabList":49,"./tagList":50,"./typeAhead":51}],45:[function(require,module,exports){ | |
"use strict"; | |
/*** | |
* emits: | |
* @close Parent should close the modal | |
* | |
* if using an @click event in the parent to toggle the "open" prop that this component | |
* receives, be sure to stop propagation on the event since it will trigger the modal | |
* to immediately close because of the clickAway handler | |
*/ | |
module.exports = { | |
name: "modal", | |
template: ` | |
<dialog | |
class="modal" | |
ref="modal" | |
:open="open" | |
:class="className" | |
> | |
<slot></slot> | |
</dialog> | |
`, | |
props: { | |
open: { | |
type: Boolean, | |
default: () => false, | |
}, | |
className: { | |
type: String, | |
}, | |
}, | |
watch: { | |
open(value) { | |
if (value) { | |
document.body.addEventListener("click", this.clickAway); | |
document.body.addEventListener("keydown", this.escKey); | |
} else { | |
document.body.removeEventListener("click", this.clickAway); | |
document.body.removeEventListener("keydown", this.escKey); | |
} | |
}, | |
}, | |
methods: { | |
clickAway(ev) { | |
if (!this.$refs.modal || !this.$refs.modal.contains(ev.target)) { | |
this.$emit("close", { ev }); | |
} | |
}, | |
escKey(ev) { | |
if (ev.target.tagName.toLowerCase() === "input") return; | |
if (ev.keyCode === 27) { | |
ev.preventDefault(); | |
ev.stopPropagation(); | |
this.$emit("close", { ev }); | |
} | |
}, | |
}, | |
beforeDestroy() { | |
document.body.removeEventListener("click", this.clickAway); | |
document.body.removeEventListener("keydown", this.escKey); | |
}, | |
}; | |
},{}],46:[function(require,module,exports){ | |
"use strict"; | |
module.exports = { | |
name: "multiple-choice", | |
template: ` | |
<span | |
class="multiple-choice-container" | |
tabindex="0" | |
@keydown="keydown" | |
> | |
<label v-for="(option, index) in options"> | |
<span class="shortcut-key">{{String.fromCharCode(shortcuts[index])}}</span> | |
{{option[displayKey]}} | |
<input | |
ref="input" | |
type="radio" | |
:name="name" | |
:value="option[valueKey]" | |
:checked="option[valueKey] === value" | |
@change="updateValue(index)" | |
/> | |
<i class="icon-check"></i> | |
</label> | |
</span> | |
`, | |
props: { | |
value: {}, | |
options: { | |
type: Array, | |
required: true, | |
}, | |
name: { | |
type: String, | |
required: true, | |
}, | |
displayKey: { | |
type: String, | |
required: true, | |
}, | |
valueKey: { | |
type: String, | |
required: true, | |
}, | |
keyCodes: { | |
type: Array, | |
}, | |
keyCodeStart: { | |
type: Number, | |
default: () => 49, | |
}, | |
}, | |
data() { | |
return { | |
shortcuts: this.options.map((option, index) => { | |
if (this.keyCodes && this.keyCodes[index]) return this.keyCodes[index]; | |
return this.keyCodeStart + index; | |
}), | |
}; | |
}, | |
methods: { | |
updateValue(index) { | |
// pass up original rather than casted to String version | |
const value = this.options[index][this.valueKey]; | |
this.$emit("input", value); | |
}, | |
keydown(ev) { | |
this.shortcuts.forEach((keyCode, index) => { | |
if (ev.keyCode === keyCode) { | |
this.$refs.input[index].checked = true; | |
this.updateValue(index); | |
} | |
}); | |
}, | |
}, | |
created() { | |
for (let i = 0; i < this.options.length; i++) { | |
const option = this.options[i]; | |
if (option[this.valueKey] === undefined) { | |
console.warn(`All options should contain the key "${this.valueKey}". Option at index ${i} does not contain this key.`); | |
break; | |
} | |
if (option[this.displayKey] === undefined) { | |
console.warn(`All options should contain the key "${this.displayKey}". Option at index ${i} does not contain this key.`); | |
break; | |
} | |
} | |
}, | |
}; | |
},{}],47:[function(require,module,exports){ | |
module.exports = { | |
name: "spinner", | |
template: ` | |
<span class="spinner"> | |
<i | |
v-if="spinning" | |
class="icon-spinner" | |
></i> | |
</span> | |
`, | |
props: { | |
spinning: Boolean, | |
required: true, | |
}, | |
} | |
},{}],48:[function(require,module,exports){ | |
// tab component must be globally defined for now rather than as a local component inside tabList | |
// because transcluded components render in the outer scope rather than in tabList's scope, | |
// so locally defined components in tabList will not be available to the outer component. | |
// If Vue gets an option to render a component in the inner scope then this can be moved | |
// as a local component for tabList: | |
// https://github.com/vuejs/Discussion/issues/179 | |
module.exports = { | |
name: "tab", | |
template: ` | |
<div | |
class="tab-list-content" | |
v-if="active" | |
> | |
<slot></slot> | |
</div> | |
`, | |
props: { | |
header: String, | |
}, | |
data() { | |
return { | |
active: false, | |
}; | |
}, | |
} | |
},{}],49:[function(require,module,exports){ | |
"use strict"; | |
/*** | |
Example usage | |
<tab-list> | |
<tab header="Tab 1"> | |
Tab 1 Content | |
</tab> | |
<tab header="Tab 2"> | |
Tab 2 Content | |
</tab> | |
<tab header="Tab 3"> | |
Tab 3 Content | |
</tab> | |
</tab-list> | |
***/ | |
// modes: fill, shrink | |
module.exports = { | |
name: "tabs", | |
template: ` | |
<div> | |
<ul class="tab-list"> | |
<li | |
class="tab" | |
v-for="(tab, index) in tabs" | |
@click="selectTab(index)" | |
:class="index === active ? 'active' : ''" | |
:style="tabStyle" | |
:ref="'tab' + index" | |
> | |
{{tab.header}} | |
</li> | |
</ul> | |
<div class="tab-bar"> | |
<div | |
class="active-tab" | |
:style="activeStyle" | |
></div> | |
</div> | |
<div class="tab-list-content"> | |
<slot></slot> | |
</div> | |
</div> | |
`, | |
data() { | |
return { | |
tabs: [], | |
active: -1, | |
}; | |
}, | |
props: { | |
mode: { | |
type: String, | |
default: () => "shrink", | |
}, | |
animate: { | |
type: Boolean, | |
default: () => true, | |
}, | |
}, | |
computed: { | |
tabStyle() { | |
const styleObj = {}; | |
if (this.mode === "fill") { | |
styleObj.flex = "1"; | |
} else if (this.mode === "shrink") { | |
styleObj.flex = "0"; | |
} | |
return styleObj; | |
}, | |
activeStyle() { | |
const styleObj = {}; | |
if (this.mode === "fill") { | |
const itemPercentage = 100 / this.tabs.length; | |
styleObj.left = itemPercentage * this.active + "%"; | |
styleObj.right = 100 - (itemPercentage * (this.active + 1)) + "%"; | |
} else if (this.mode === "shrink") { | |
let left = 0; | |
let width = 0; | |
for (let i = 0; i < this.active; i ++) { | |
const $elem = this.$refs[`tab${i}`][0]; | |
if (!$elem) break; | |
left += $elem.getBoundingClientRect().width; | |
} | |
const $activeElem = this.$refs[`tab${this.active}`]; | |
if ($activeElem) { | |
width = $activeElem[0].getBoundingClientRect().width; | |
} | |
styleObj.left = left + "px"; | |
styleObj.width = width + "px"; | |
} | |
return styleObj; | |
} | |
}, | |
watch: { | |
active(newVal, oldVal) { | |
this.$emit("change-tab", newVal); | |
if (this.tabs[oldVal]) this.tabs[oldVal].active = false; | |
if (this.tabs[newVal]) this.tabs[newVal].active = true; | |
}, | |
}, | |
mounted() { | |
this.$children.forEach(($child, index) => { | |
if (index === 0) $child.active = true; | |
if ($child.$options._componentTag === "tab") { | |
this.tabs.push($child); | |
} | |
}); | |
this.$nextTick(() => { | |
this.active = 0; | |
}); | |
}, | |
methods: { | |
selectTab(index) { | |
this.active = index; | |
}, | |
}, | |
}; | |
},{}],50:[function(require,module,exports){ | |
'use strict'; | |
module.exports = { | |
name: 'tag-list', | |
template: ` | |
<div class="tag-list"> | |
<input class="type-ahead" type="text" name="search" | |
v-model="input" | |
@keyup="isEditing = true" | |
@focus="isEditing = true" | |
@blur="blur" | |
@keyup.esc="escape" | |
@keydown.enter.prevent="addTag(selectedId)" | |
@keyup.down.prevent="arrowDown" | |
@keyup.up.prevent="arrowUp" | |
:placeholder="$t('typeToSearch')" | |
/> | |
<ul v-if="isEditing" class="menu"> | |
<li v-for="match in matches" :class="{ active: selectedId == match.id }" :data-id="match.id"> | |
<a @click.prevent="addTag(match.id)" v-html="mark(match)"></a> | |
</li> | |
</ul> | |
<div class="tag-container"> | |
<transition-group name="fadeIn"> | |
<div class="tag" v-for="tag in chosen" v-bind:key="tag.id"> | |
{{ tag[display] }} | |
<i class="icon-cancel" @click.prevent="remove(tag.id)"></i> | |
</div> | |
</transition-group> | |
</div> | |
</div> | |
`, | |
props: ['source', 'chosenIds', 'display'], | |
data() { | |
return { | |
input: "", | |
isEditing: false, | |
ids: [], | |
selectedId: null | |
}; | |
}, | |
created() { | |
// clone the array of ids | |
this.ids = this.chosenIds.slice(0); | |
}, | |
computed: { | |
matches() { | |
const matches = this.source.filter(item => { | |
return item[this.display].includes(this.input) && !this.ids.includes(item.id); | |
}); | |
this.selectedId = matches.length == 0 ? null : matches[0].id; | |
return matches; | |
}, | |
chosen() { | |
if (this.source.length == 0) return []; | |
return this.ids.map(id => { | |
return this.source.find(item => item.id == id ); | |
}); | |
}, | |
}, | |
methods: { | |
arrowDown(ev) { | |
ev.stopPropagation(); | |
ev.preventDefault(); | |
this.arrow('down'); | |
return false; | |
}, | |
arrowUp(ev) { | |
ev.stopPropagation(); | |
ev.preventDefault(); | |
this.arrow('up'); | |
return false; | |
}, | |
escape() { | |
this.isEditing = false; | |
this.input = ""; | |
this.$el.querySelector('.type-ahead').blur(); | |
}, | |
blur() { | |
setTimeout(() => { | |
this.isEditing = false; | |
}, 300); | |
}, | |
arrow(dir) { | |
let index = this.matches.findIndex(match => match.id == this.selectedId); | |
index = dir == "down" ? index + 1 : index - 1; | |
if (this.matches[index]) { | |
this.selectedId = this.matches[index].id; | |
this.scrollIntoView(); | |
} | |
}, | |
scrollIntoView() { | |
let el = this.$el.querySelector(`*[data-id="${this.selectedId}"]`); | |
if (el) el.scrollIntoView(); | |
}, | |
remove(id) { | |
const index = this.ids.indexOf(id); | |
this.ids.splice(index, 1); | |
this.$emit('update', this.ids); | |
}, | |
addTag(id) { | |
this.input = ""; | |
this.isEditing = false; | |
this.ids.push(id); | |
}, | |
mark(match) { | |
return this.input.length == 0 ? match[this.display] : match[this.display].replace(this.input, `<mark>${this.input}</mark>`); | |
}, | |
} | |
}; | |
},{}],51:[function(require,module,exports){ | |
"use strict"; | |
module.exports = { | |
name: "type-ahead", | |
template: ` | |
<label | |
class="type-ahead-label" | |
:class="className" | |
> | |
<input | |
type="text" | |
:placeholder="placeholder" | |
:tabindex="tabindex" | |
:name="name" | |
:value="inputText" | |
@input="updateText($event.target.value)" | |
:disabled="disabled" | |
@keydown.38.stop.prevent="selectPrevious" | |
@keydown.40.stop.prevent="selectNext" | |
/> | |
<ul | |
v-if="showMatches" | |
class="matches" | |
ref="matches" | |
> | |
<li v-if="matches.length === 0"> | |
<slot name="noMatchesMessage">No matches...</slot> | |
</li> | |
<li | |
v-else | |
class="option" | |
v-for="(match, index) in matches" | |
:class="{ selected: index === selectedIndex }" | |
@click.stop.prevent="selectIndex(index)" | |
> | |
{{match[display]}} | |
<cite v-if="cite">{{match[cite]}}</cite> | |
</li> | |
</ul> | |
<span class="arrows" @click.stop.prevent="clickDropdown"></span> | |
</label> | |
`, | |
props: { | |
placeholder: { | |
type: String, | |
}, | |
tabindex: { | |
type: Number, | |
default: () => 0, | |
}, | |
className: { | |
type: String, | |
}, | |
options: { | |
type: Array, | |
required: true, | |
}, | |
display: { | |
type: String, | |
required: true, | |
}, | |
name: { | |
type: String, | |
}, | |
cite: { | |
type: String, | |
}, | |
minimum: { | |
type: Number, | |
default: () => 3, | |
}, | |
disabled: { | |
type: Boolean, | |
}, | |
}, | |
data() { | |
return { | |
inputText: "", | |
selectedIndex: -1, | |
showMatches: false, | |
}; | |
}, | |
computed: { | |
matches() { | |
const cleanInput = this.inputText.trim().toLowerCase(); | |
return this.options.filter(option => option[this.display].trim().toLowerCase().includes(cleanInput)); | |
}, | |
}, | |
methods: { | |
updateText(value) { | |
this.clearSelection(); | |
this.inputText = value; | |
if (value.length === 0) { | |
this.closeMatches(); | |
} else if (value.length >= this.minimum) { | |
this.openMatches(); | |
} | |
}, | |
keydown(ev) { | |
if (ev.keyCode === 27) { | |
ev.stopPropagation(); | |
ev.preventDefault(); | |
this.showMatches = false; | |
} | |
}, | |
clickAway(ev) { | |
if (!this.$el.contains(ev.target)) { | |
this.closeMatches(); | |
} | |
}, | |
clickDropdown() { | |
if (this.showMatches) return this.closeMatches(); | |
this.openMatches(); | |
}, | |
openMatches() { | |
this.showMatches = true; | |
if (this.matches.length && this.selectedIndex === -1) this.selectedIndex = 0; | |
document.body.addEventListener("click", this.clickAway); | |
document.body.addEventListener("keydown", this.menuKey); | |
}, | |
closeMatches() { | |
this.showMatches = false; | |
document.body.removeEventListener("click", this.clickAway); | |
document.body.removeEventListener("keydown", this.menuKey); | |
}, | |
selectNext() { | |
if (!this.showMatches) return this.openMatches(); | |
if (this.selectedIndex < this.matches.length - 1) { | |
this.selectedIndex += 1; | |
} | |
}, | |
selectPrevious() { | |
if (!this.showMatches) return this.openMatches(); | |
if (this.selectedIndex > 0) { | |
this.selectedIndex -= 1; | |
} | |
}, | |
clearSelection() { | |
this.$emit("input", undefined); | |
}, | |
selectIndex(index) { | |
this.selectedIndex = -1; | |
this.$emit("input", this.matches[index]); | |
this.inputText = this.matches[index][this.display]; | |
this.$nextTick(() => { | |
this.closeMatches(); | |
}); | |
}, | |
menuKey(ev) { | |
if (ev.keyCode === 13) { | |
ev.preventDefault(); | |
ev.stopPropagation(); | |
if (this.matches.length && this.selectedIndex >= 0 && this.selectedIndex < this.matches.length) { | |
this.selectIndex(this.selectedIndex); | |
} | |
} | |
}, | |
}, | |
mounted() { | |
document.body.addEventListener("keydown", this.keydown); | |
}, | |
beforeDestroy() { | |
document.body.removeEventListener("keydown", this.keydown); | |
document.body.removeEventListener("click", this.clickAway); | |
document.body.removeEventListener("keydown", this.menuKey); | |
}, | |
}; | |
},{}],52:[function(require,module,exports){ | |
module.exports = { | |
name: "click-away", | |
bind(el, binding, vnode) { | |
const func = binding.value; | |
if (typeof func !== "function") { | |
return console.warn("click-away directive is meant to be used with a function."); | |
} | |
document.documentElement.removeEventListener("click", el._clickawayHandler); | |
// No clean way that I can find to share functions between bind and unbind w/o attaching them to el | |
el._clickawayHandler = function(ev) { | |
if (!el.contains(ev.target)) { | |
func(ev); | |
} | |
} | |
document.documentElement.addEventListener("click", el._clickawayHandler); | |
}, | |
unbind(el, binding) { | |
document.documentElement.removeEventListener("click", el._clickawayHandler); | |
delete el._clickawayHandler; | |
}, | |
}; | |
},{}],53:[function(require,module,exports){ | |
module.exports = { | |
name: 'focus', | |
inserted(el, binding) { | |
if (binding.value) el.focus(); | |
else el.blur(); | |
}, | |
componentUpdated(el, binding) { | |
if (binding.modifiers.lazy && Boolean(binding.value) === Boolean(binding.oldValue)) return; | |
if (binding.value) el.focus(); | |
else el.blur(); | |
}, | |
}; | |
},{}],54:[function(require,module,exports){ | |
const directives = { | |
"click-away": require("./clickAway"), | |
"prevent-paste": require("./preventPaste"), | |
"focus": require("./focus"), | |
}; | |
function install(Vue, options) { | |
Object.keys(directives).forEach(key => { | |
Vue.directive(key, directives[key]); | |
}); | |
} | |
module.exports = Object.assign({ install }, directives); | |
},{"./clickAway":52,"./focus":53,"./preventPaste":55}],55:[function(require,module,exports){ | |
module.exports = { | |
name: 'prevent-paste', | |
inserted(el) { | |
el.addEventListener('paste', ev => { | |
ev.preventDefault(); | |
ev.stopPropagation(); | |
return false; | |
}); | |
}, | |
}; | |
},{}],56:[function(require,module,exports){ | |
module.exports = function currencyFilter(value) { | |
if (typeof value === "string") { | |
return value.toLocaleString("en-US", { style: 'currency', currency: "USD" }); | |
} | |
if (typeof value === "number") { | |
const intl = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }) | |
return intl.format(value / 100); | |
} | |
}; | |
},{}],57:[function(require,module,exports){ | |
module.exports = function(value) { | |
const date = new Date(value); | |
const format = { year: 'numeric', month: 'numeric', day: 'numeric' }; | |
const formatter = new Intl.DateTimeFormat("en-US", format); | |
return formatter.format(date); | |
}; | |
},{}],58:[function(require,module,exports){ | |
module.exports = function humanize(value) { | |
if (!_.isString(value)) { | |
console.warn("you must pass a string to the humanize filter"); | |
return ""; | |
} | |
return value.split('_').map(seg => seg.charAt(0).toUpperCase() + seg.slice(1)).join(' '); | |
}; | |
},{}],59:[function(require,module,exports){ | |
const filters = { | |
humanize: require("./humanize"), | |
capitalize: (str) => str.charAt(0).toUpperCase() + str.substr(1), | |
timeOfDay: require("./timeOfDay"), | |
secsToTimecode: require("./secsToTimecode"), | |
currency: require("./currency"), | |
padZero: (num) => `${num}`.length > 1 ? num : `0${num}`, | |
time: require("./time"), | |
date: require("./date"), | |
}; | |
function install(Vue, options) { | |
Object.keys(filters).forEach(key => { | |
Vue.filter(key, filters[key]); | |
}); | |
} | |
module.exports = Object.assign({ install }, filters); | |
},{"./currency":56,"./date":57,"./humanize":58,"./secsToTimecode":60,"./time":61,"./timeOfDay":62}],60:[function(require,module,exports){ | |
module.exports = function secsToTimecode(secs) { | |
try { | |
return `${Math.floor(secs / 60 | 0)}:${padZero(Math.floor(secs % 60))}`; | |
} catch (error) { | |
console.warn(error.message, error.stack); | |
} | |
}; | |
},{}],61:[function(require,module,exports){ | |
module.exports = function timeFilter(value) { | |
const date = new Date(value); | |
const format = { hour: 'numeric', minute: 'numeric', second: 'numeric' }; | |
const formatter = new Intl.DateTimeFormat("en-US", format); | |
return formatter.format(date); | |
}; | |
},{}],62:[function(require,module,exports){ | |
module.exports = function timeOfDay(time) { | |
time = time instanceof Date ? time : new Date(time); | |
let hours = time.getHours(); | |
if (hours > 5 && hours <= 12) { | |
return 'morning'; | |
} else if (hours > 12 && hours <= 18) { | |
return 'afternoon'; | |
} else if (hours > 18 && hours <= 21) { | |
return 'night'; | |
} | |
}; | |
},{}],63:[function(require,module,exports){ | |
const tools = { | |
components: require("./components"), | |
directives: require("./directives"), | |
filters: require("./filters"), | |
mixins: require("./mixins"), | |
}; | |
function install(Vue, options) { | |
Vue.use(tools.components); | |
Vue.use(tools.directives); | |
Vue.use(tools.filters); | |
Vue.use(tools.mixins); | |
} | |
tools.install = install; | |
module.exports = tools; | |
},{"./components":44,"./directives":54,"./filters":59,"./mixins":64}],64:[function(require,module,exports){ | |
const mixins = { | |
validator: require("./validator"), | |
routeData: require("./routeData"), | |
}; | |
function install(Vue, options) { | |
Vue.mixins = mixins; | |
} | |
module.exports = Object.assign({ install }, mixins); | |
},{"./routeData":65,"./validator":66}],65:[function(require,module,exports){ | |
"use strict"; | |
module.exports = { | |
methods: { | |
$refreshKeyDown(ev) { | |
if (ev.keyCode === 82 && ev.metaKey) { | |
ev.preventDefault(); | |
ev.stopPropagation(); | |
this.fetchRouteData(); | |
} | |
}, | |
}, | |
beforeCreate() { | |
if (!this.$options.methods || !this.$options.methods.fetchRouteData) { | |
throw new Error("Component must have a fetchRouteData method in order to use routeData mixin."); | |
} | |
}, | |
created() { | |
window.addEventListener("keydown", this.$refreshKeyDown); | |
this.fetchRouteData(); | |
}, | |
beforeRouteUpdate(to, from, next) { | |
next(vm => { | |
vm.fetchRouteData(); | |
}); | |
}, | |
beforeDestroy() { | |
window.removeEventListener("keydown", this.$refreshKeyDown); | |
}, | |
}; | |
},{}],66:[function(require,module,exports){ | |
'use strict'; | |
const exampleSchema = { | |
validate: { | |
fieldName: { | |
required: true, | |
length: 9, | |
} | |
} | |
}; | |
const checkEvenBlank = ['required', 'eitherOr']; | |
module.exports = { | |
mixins: [require('./rules')], | |
mounted() { | |
if (!this.validate) { | |
console.warn('You must have a validate obejct on any component extending validator!'); | |
console.warn(JSON.stringify(exampleSchema, null, 2)); | |
return; | |
} | |
_getElements(this).forEach($field => { | |
$field._validate = this.$validate; | |
$field.addEventListener('blur', $field._validate); | |
}); | |
}, | |
beforeDestroy() { | |
_getElements(this).forEach($field => { | |
$field.removeEventListener('blur', $field._validate); | |
}); | |
}, | |
methods: { | |
$isValid() { | |
_getElements(this).forEach($el => { | |
$el._validate(null, $el); | |
}); | |
const invalidChildren = this.$children.map($child => { | |
if ($child.$isValid) return $child.$isValid(); | |
}); | |
return !this.$hasErrors && !invalidChildren.includes(false); | |
}, | |
$validate(ev, el) { | |
const $el = el || ev.currentTarget; | |
const name = $el.getAttribute('name'); | |
const rules = this.validate[name]; | |
Object.keys(rules) | |
.filter(key => key != 'errors') | |
.forEach(key => { | |
let isValid = false; | |
// no need to validate if the field is empty, required should handle that... | |
if (!checkEvenBlank.includes(key) && !this.$required($el.value)) { | |
isValid = true; | |
} else { | |
if (typeof rules[key] == 'function') { | |
isValid = rules[key]($el.value); | |
} else { | |
isValid = this[`$${key}`]($el.value, rules[key]); | |
} | |
} | |
this.$removeError(name, key); | |
if (!isValid) { | |
rules.errors.push({ | |
key: key, | |
msg: this.$translate(key, [rules[key]]), | |
value: rules[key] | |
}); | |
$el.classList.add('error'); | |
$el.parentElement.classList.add('error'); | |
} | |
// after validattion hooks for complicated ones like eitherOr... | |
const afterHookFn = this[`$${key}Hook`]; | |
if (typeof afterHookFn == 'function') afterHookFn(isValid, $el, rules[key]); | |
}); | |
}, | |
$translate(key, values) { | |
return this.$t('validation.' + key, values); | |
}, | |
$getField(name) { | |
return this.$el.querySelector(`*[name="${name}"]`); | |
}, | |
$removeError(name, key) { | |
const rules = this.validate[name]; | |
const index = rules.errors.findIndex(error => error.key == key ); | |
const $el = this.$getField(name); | |
if (index != -1) rules.errors.splice(index, 1); | |
if (!this.$errors[name] || this.$errors[name].length == 0) { | |
$el.classList.remove('error'); | |
$el.parentElement.classList.remove('error'); | |
} | |
}, | |
}, | |
computed: { | |
$errors() { | |
const errors = {}; | |
_getFieldKeys(this.validate).forEach(key => { | |
if (this.validate[key].errors && this.validate[key].errors.length > 0) { | |
errors[key] = this.validate[key].errors; | |
} | |
}); | |
return errors; | |
}, | |
$hasErrors() { | |
return _getFieldKeys(this.validate) | |
.some(key => { | |
return this.validate[key].errors && this.validate[key].errors.length > 0; | |
}); | |
}, | |
} | |
}; | |
function _getFieldKeys(obj) { | |
return Object.keys(obj).filter(key => key != 'hasChildErrors'); | |
} | |
function _getElements(inst) { | |
return _getFieldKeys(inst.validate).map(key => { | |
const $fields = Array.from(inst.$el.querySelectorAll(`*[name="${key}"]`)); | |
if (!inst.validate[key].errors) { | |
Vue.set(inst.validate[key], 'errors', []); | |
} | |
if ($fields.length == 0) { | |
console.warn(`Validator found no DOM element matching *[name="${key}"] it has been removed from the obj`); | |
Vue.delete(inst.validate, key); | |
return null; | |
} | |
return $fields; | |
}) | |
.reduce((a, b) => { | |
return a.concat(b); | |
}, []) | |
.filter($field => $field != null ); | |
} | |
},{"./rules":67}],67:[function(require,module,exports){ | |
'use strict'; | |
module.exports = { | |
methods: { | |
$name(value) { | |
return /^[a-zA-Zéüöêåø\s]*$/.test(value); | |
}, | |
$required(value) { | |
return value.trim() != ''; | |
}, | |
$numeric(value) { | |
return /[0-9]/.test(value); | |
}, | |
$email(value) { | |
return /^[\w._-]+[+]?[\w._-]+@[\w.-]+\.[a-zA-Z]{2,6}$/.test(value); | |
}, | |
$length(value, length) { | |
return value.trim().length == length; | |
}, | |
$phone(value) { | |
return /^(\([0-9]{3}\)\s*|[0-9]{3}\-)[0-9]{3}-[0-9]{4}$/.test(value); | |
}, | |
$eitherOr(value, otherField) { | |
const $el = this.$getField(otherField); | |
if (!$el) { | |
console.warn(`could not find other field with name="${otherField}"`); | |
return true; | |
} | |
return this.$required(value) || this.$required($el.value); | |
}, | |
$eitherOrHook(valid, $el, ruleValue) { | |
if (valid) this.$removeError(ruleValue, 'eitherOr'); | |
}, | |
$date(value, format) { | |
const formats = ['dd/mm/yyyy']; | |
format = format.toLowerCase(); | |
if (!formats.includes(format)) console.warn(`${format} is not a supported validation format for date`); | |
if (format == 'dd/mm/yyyy') return /^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/.test(value); | |
// we will add more formats as needed... | |
return true; | |
}, | |
} | |
}; | |
},{}],68:[function(require,module,exports){ | |
(function (factory) { | |
if (typeof exports == 'object') { | |
module.exports = factory(); | |
} else if ((typeof define == 'function') && define.amd) { | |
define(factory); | |
} | |
}(function () { | |
var isBuiltIn = (function () { | |
var built_ins = [ | |
Object, | |
Function, | |
Array, | |
String, | |
Boolean, | |
Number, | |
Date, | |
RegExp, | |
Error | |
]; | |
var built_ins_length = built_ins.length; | |
return function (_constructor) { | |
for (var i = 0; i < built_ins_length; i++) { | |
if (built_ins[i] === _constructor) { | |
return true; | |
} | |
} | |
return false; | |
}; | |
})(); | |
var stringType = (function () { | |
var _toString = ({}).toString; | |
return function (obj) { | |
// [object Blah] -> Blah | |
var stype = _toString.call(obj).slice(8, -1); | |
if ((obj === null) || (obj === undefined)) { | |
return stype.toLowerCase(); | |
} | |
var ctype = of(obj); | |
if (ctype && !isBuiltIn(ctype)) { | |
return ctype.name; | |
} else { | |
return stype; | |
} | |
}; | |
})(); | |
function of (obj) { | |
if ((obj === null) || (obj === undefined)) { | |
return obj; | |
} else { | |
return obj.constructor; | |
} | |
} | |
function is (obj, test) { | |
var typer = (of(test) === String) ? stringType : of; | |
return (typer(obj) === test); | |
} | |
function instance (obj, test) { | |
return (obj instanceof test); | |
} | |
function extension (_Extension, _Base) { | |
return instance(_Extension.prototype, _Base); | |
} | |
function any (obj, tests) { | |
if (!is(tests, Array)) { | |
throw ("Second argument to .any() should be array") | |
} | |
for (var i = 0; i < tests.length; i++) { | |
var test = tests[i]; | |
if (is(obj, test)) { | |
return true; | |
} | |
} | |
return false; | |
} | |
var exports = function (obj, type) { | |
if (arguments.length == 1) { | |
return of(obj); | |
} else { | |
if (is(type, Array)) { | |
return any(obj, type); | |
} else { | |
return is(obj, type); | |
} | |
} | |
} | |
exports.instance = instance; | |
exports.string = stringType; | |
exports.of = of; | |
exports.is = is; | |
exports.any = any; | |
exports.extension = extension; | |
return exports; | |
})); | |
},{}],69:[function(require,module,exports){ | |
(function (process){ | |
/** | |
* vue-router v2.2.0 | |
* (c) 2017 Evan You | |
* @license MIT | |
*/ | |
'use strict'; | |
/* */ | |
function assert (condition, message) { | |
if (!condition) { | |
throw new Error(("[vue-router] " + message)) | |
} | |
} | |
function warn (condition, message) { | |
if (!condition) { | |
typeof console !== 'undefined' && console.warn(("[vue-router] " + message)); | |
} | |
} | |
var View = { | |
name: 'router-view', | |
functional: true, | |
props: { | |
name: { | |
type: String, | |
default: 'default' | |
} | |
}, | |
render: function render (h, ref) { | |
var props = ref.props; | |
var children = ref.children; | |
var parent = ref.parent; | |
var data = ref.data; | |
data.routerView = true; | |
var name = props.name; | |
var route = parent.$route; | |
var cache = parent._routerViewCache || (parent._routerViewCache = {}); | |
// determine current view depth, also check to see if the tree | |
// has been toggled inactive but kept-alive. | |
var depth = 0; | |
var inactive = false; | |
while (parent) { | |
if (parent.$vnode && parent.$vnode.data.routerView) { | |
depth++; | |
} | |
if (parent._inactive) { | |
inactive = true; | |
} | |
parent = parent.$parent; | |
} | |
data.routerViewDepth = depth; | |
// render previous view if the tree is inactive and kept-alive | |
if (inactive) { | |
return h(cache[name], data, children) | |
} | |
var matched = route.matched[depth]; | |
// render empty node if no matched route | |
if (!matched) { | |
cache[name] = null; | |
return h() | |
} | |
var component = cache[name] = matched.components[name]; | |
// inject instance registration hooks | |
var hooks = data.hook || (data.hook = {}); | |
hooks.init = function (vnode) { | |
matched.instances[name] = vnode.child; | |
}; | |
hooks.prepatch = function (oldVnode, vnode) { | |
matched.instances[name] = vnode.child; | |
}; | |
hooks.destroy = function (vnode) { | |
if (matched.instances[name] === vnode.child) { | |
matched.instances[name] = undefined; | |
} | |
}; | |
// resolve props | |
data.props = resolveProps(route, matched.props && matched.props[name]); | |
return h(component, data, children) | |
} | |
}; | |
function resolveProps (route, config) { | |
switch (typeof config) { | |
case 'undefined': | |
return | |
case 'object': | |
return config | |
case 'function': | |
return config(route) | |
case 'boolean': | |
return config ? route.params : undefined | |
default: | |
warn(false, ("props in \"" + (route.path) + "\" is a " + (typeof config) + ", expecting an object, function or boolean.")); | |
} | |
} | |
/* */ | |
var encodeReserveRE = /[!'()*]/g; | |
var encodeReserveReplacer = function (c) { return '%' + c.charCodeAt(0).toString(16); }; | |
var commaRE = /%2C/g; | |
// fixed encodeURIComponent which is more comformant to RFC3986: | |
// - escapes [!'()*] | |
// - preserve commas | |
var encode = function (str) { return encodeURIComponent(str) | |
.replace(encodeReserveRE, encodeReserveReplacer) | |
.replace(commaRE, ','); }; | |
var decode = decodeURIComponent; | |
function resolveQuery ( | |
query, | |
extraQuery | |
) { | |
if ( extraQuery === void 0 ) extraQuery = {}; | |
if (query) { | |
var parsedQuery; | |
try { | |
parsedQuery = parseQuery(query); | |
} catch (e) { | |
process.env.NODE_ENV !== 'production' && warn(false, e.message); | |
parsedQuery = {}; | |
} | |
for (var key in extraQuery) { | |
parsedQuery[key] = extraQuery[key]; | |
} | |
return parsedQuery | |
} else { | |
return extraQuery | |
} | |
} | |
function parseQuery (query) { | |
var res = {}; | |
query = query.trim().replace(/^(\?|#|&)/, ''); | |
if (!query) { | |
return res | |
} | |
query.split('&').forEach(function (param) { | |
var parts = param.replace(/\+/g, ' ').split('='); | |
var key = decode(parts.shift()); | |
var val = parts.length > 0 | |
? decode(parts.join('=')) | |
: null; | |
if (res[key] === undefined) { | |
res[key] = val; | |
} else if (Array.isArray(res[key])) { | |
res[key].push(val); | |
} else { | |
res[key] = [res[key], val]; | |
} | |
}); | |
return res | |
} | |
function stringifyQuery (obj) { | |
var res = obj ? Object.keys(obj).map(function (key) { | |
var val = obj[key]; | |
if (val === undefined) { | |
return '' | |
} | |
if (val === null) { | |
return encode(key) | |
} | |
if (Array.isArray(val)) { | |
var result = []; | |
val.slice().forEach(function (val2) { | |
if (val2 === undefined) { | |
return | |
} | |
if (val2 === null) { | |
result.push(encode(key)); | |
} else { | |
result.push(encode(key) + '=' + encode(val2)); | |
} | |
}); | |
return result.join('&') | |
} | |
return encode(key) + '=' + encode(val) | |
}).filter(function (x) { return x.length > 0; }).join('&') : null; | |
return res ? ("?" + res) : '' | |
} | |
/* */ | |
var trailingSlashRE = /\/?$/; | |
function createRoute ( | |
record, | |
location, | |
redirectedFrom | |
) { | |
var route = { | |
name: location.name || (record && record.name), | |
meta: (record && record.meta) || {}, | |
path: location.path || '/', | |
hash: location.hash || '', | |
query: location.query || {}, | |
params: location.params || {}, | |
fullPath: getFullPath(location), | |
matched: record ? formatMatch(record) : [] | |
}; | |
if (redirectedFrom) { | |
route.redirectedFrom = getFullPath(redirectedFrom); | |
} | |
return Object.freeze(route) | |
} | |
// the starting route that represents the initial state | |
var START = createRoute(null, { | |
path: '/' | |
}); | |
function formatMatch (record) { | |
var res = []; | |
while (record) { | |
res.unshift(record); | |
record = record.parent; | |
} | |
return res | |
} | |
function getFullPath (ref) { | |
var path = ref.path; | |
var query = ref.query; if ( query === void 0 ) query = {}; | |
var hash = ref.hash; if ( hash === void 0 ) hash = ''; | |
return (path || '/') + stringifyQuery(query) + hash | |
} | |
function isSameRoute (a, b) { | |
if (b === START) { | |
return a === b | |
} else if (!b) { | |
return false | |
} else if (a.path && b.path) { | |
return ( | |
a.path.replace(trailingSlashRE, '') === b.path.replace(trailingSlashRE, '') && | |
a.hash === b.hash && | |
isObjectEqual(a.query, b.query) | |
) | |
} else if (a.name && b.name) { | |
return ( | |
a.name === b.name && | |
a.hash === b.hash && | |
isObjectEqual(a.query, b.query) && | |
isObjectEqual(a.params, b.params) | |
) | |
} else { | |
return false | |
} | |
} | |
function isObjectEqual (a, b) { | |
if ( a === void 0 ) a = {}; | |
if ( b === void 0 ) b = {}; | |
var aKeys = Object.keys(a); | |
var bKeys = Object.keys(b); | |
if (aKeys.length !== bKeys.length) { | |
return false | |
} | |
return aKeys.every(function (key) { return String(a[key]) === String(b[key]); }) | |
} | |
function isIncludedRoute (current, target) { | |
return ( | |
current.path.replace(trailingSlashRE, '/').indexOf( | |
target.path.replace(trailingSlashRE, '/') | |
) === 0 && | |
(!target.hash || current.hash === target.hash) && | |
queryIncludes(current.query, target.query) | |
) | |
} | |
function queryIncludes (current, target) { | |
for (var key in target) { | |
if (!(key in current)) { | |
return false | |
} | |
} | |
return true | |
} | |
/* */ | |
// work around weird flow bug | |
var toTypes = [String, Object]; | |
var eventTypes = [String, Array]; | |
var Link = { | |
name: 'router-link', | |
props: { | |
to: { | |
type: toTypes, | |
required: true | |
}, | |
tag: { | |
type: String, | |
default: 'a' | |
}, | |
exact: Boolean, | |
append: Boolean, | |
replace: Boolean, | |
activeClass: String, | |
event: { | |
type: eventTypes, | |
default: 'click' | |
} | |
}, | |
render: function render (h) { | |
var this$1 = this; | |
var router = this.$router; | |
var current = this.$route; | |
var ref = router.resolve(this.to, current, this.append); | |
var location = ref.location; | |
var route = ref.route; | |
var href = ref.href; | |
var classes = {}; | |
var activeClass = this.activeClass || router.options.linkActiveClass || 'router-link-active'; | |
var compareTarget = location.path ? createRoute(null, location) : route; | |
classes[activeClass] = this.exact | |
? isSameRoute(current, compareTarget) | |
: isIncludedRoute(current, compareTarget); | |
var handler = function (e) { | |
if (guardEvent(e)) { | |
if (this$1.replace) { | |
router.replace(location); | |
} else { | |
router.push(location); | |
} | |
} | |
}; | |
var on = { click: guardEvent }; | |
if (Array.isArray(this.event)) { | |
this.event.forEach(function (e) { on[e] = handler; }); | |
} else { | |
on[this.event] = handler; | |
} | |
var data = { | |
class: classes | |
}; | |
if (this.tag === 'a') { | |
data.on = on; | |
data.attrs = { href: href }; | |
} else { | |
// find the first <a> child and apply listener and href | |
var a = findAnchor(this.$slots.default); | |
if (a) { | |
// in case the <a> is a static node | |
a.isStatic = false; | |
var extend = _Vue.util.extend; | |
var aData = a.data = extend({}, a.data); | |
aData.on = on; | |
var aAttrs = a.data.attrs = extend({}, a.data.attrs); | |
aAttrs.href = href; | |
} else { | |
// doesn't have <a> child, apply listener to self | |
data.on = on; | |
} | |
} | |
return h(this.tag, data, this.$slots.default) | |
} | |
}; | |
function guardEvent (e) { | |
// don't redirect with control keys | |
if (e.metaKey || e.ctrlKey || e.shiftKey) { return } | |
// don't redirect when preventDefault called | |
if (e.defaultPrevented) { return } | |
// don't redirect on right click | |
if (e.button !== undefined && e.button !== 0) { return } | |
// don't redirect if `target="_blank"` | |
if (e.target && e.target.getAttribute) { | |
var target = e.target.getAttribute('target'); | |
if (/\b_blank\b/i.test(target)) { return } | |
} | |
// this may be a Weex event which doesn't have this method | |
if (e.preventDefault) { | |
e.preventDefault(); | |
} | |
return true | |
} | |
function findAnchor (children) { | |
if (children) { | |
var child; | |
for (var i = 0; i < children.length; i++) { | |
child = children[i]; | |
if (child.tag === 'a') { | |
return child | |
} | |
if (child.children && (child = findAnchor(child.children))) { | |
return child | |
} | |
} | |
} | |
} | |
var _Vue; | |
function install (Vue) { | |
if (install.installed) { return } | |
install.installed = true; | |
_Vue = Vue; | |
Object.defineProperty(Vue.prototype, '$router', { | |
get: function get () { return this.$root._router } | |
}); | |
Object.defineProperty(Vue.prototype, '$route', { | |
get: function get () { return this.$root._route } | |
}); | |
Vue.mixin({ | |
beforeCreate: function beforeCreate () { | |
if (this.$options.router) { | |
this._router = this.$options.router; | |
this._router.init(this); | |
Vue.util.defineReactive(this, '_route', this._router.history.current); | |
} | |
} | |
}); | |
Vue.component('router-view', View); | |
Vue.component('router-link', Link); | |
var strats = Vue.config.optionMergeStrategies; | |
// use the same hook merging strategy for route hooks | |
strats.beforeRouteEnter = strats.beforeRouteLeave = strats.created; | |
} | |
/* */ | |
var inBrowser = typeof window !== 'undefined'; | |
/* */ | |
function resolvePath ( | |
relative, | |
base, | |
append | |
) { | |
if (relative.charAt(0) === '/') { | |
return relative | |
} | |
if (relative.charAt(0) === '?' || relative.charAt(0) === '#') { | |
return base + relative | |
} | |
var stack = base.split('/'); | |
// remove trailing segment if: | |
// - not appending | |
// - appending to trailing slash (last segment is empty) | |
if (!append || !stack[stack.length - 1]) { | |
stack.pop(); | |
} | |
// resolve relative path | |
var segments = relative.replace(/^\//, '').split('/'); | |
for (var i = 0; i < segments.length; i++) { | |
var segment = segments[i]; | |
if (segment === '.') { | |
continue | |
} else if (segment === '..') { | |
stack.pop(); | |
} else { | |
stack.push(segment); | |
} | |
} | |
// ensure leading slash | |
if (stack[0] !== '') { | |
stack.unshift(''); | |
} | |
return stack.join('/') | |
} | |
function parsePath (path) { | |
var hash = ''; | |
var query = ''; | |
var hashIndex = path.indexOf('#'); | |
if (hashIndex >= 0) { | |
hash = path.slice(hashIndex); | |
path = path.slice(0, hashIndex); | |
} | |
var queryIndex = path.indexOf('?'); | |
if (queryIndex >= 0) { | |
query = path.slice(queryIndex + 1); | |
path = path.slice(0, queryIndex); | |
} | |
return { | |
path: path, | |
query: query, | |
hash: hash | |
} | |
} | |
function cleanPath (path) { | |
return path.replace(/\/\//g, '/') | |
} | |
/* */ | |
function createRouteMap ( | |
routes, | |
oldPathMap, | |
oldNameMap | |
) { | |
var pathMap = oldPathMap || Object.create(null); | |
var nameMap = oldNameMap || Object.create(null); | |
routes.forEach(function (route) { | |
addRouteRecord(pathMap, nameMap, route); | |
}); | |
return { | |
pathMap: pathMap, | |
nameMap: nameMap | |
} | |
} | |
function addRouteRecord ( | |
pathMap, | |
nameMap, | |
route, | |
parent, | |
matchAs | |
) { | |
var path = route.path; | |
var name = route.name; | |
if (process.env.NODE_ENV !== 'production') { | |
assert(path != null, "\"path\" is required in a route configuration."); | |
assert( | |
typeof route.component !== 'string', | |
"route config \"component\" for path: " + (String(path || name)) + " cannot be a " + | |
"string id. Use an actual component instead." | |
); | |
} | |
var record = { | |
path: normalizePath(path, parent), | |
components: route.components || { default: route.component }, | |
instances: {}, | |
name: name, | |
parent: parent, | |
matchAs: matchAs, | |
redirect: route.redirect, | |
beforeEnter: route.beforeEnter, | |
meta: route.meta || {}, | |
props: route.props == null | |
? {} | |
: route.components | |
? route.props | |
: { default: route.props } | |
}; | |
if (route.children) { | |
// Warn if route is named and has a default child route. | |
// If users navigate to this route by name, the default child will | |
// not be rendered (GH Issue #629) | |
if (process.env.NODE_ENV !== 'production') { | |
if (route.name && route.children.some(function (child) { return /^\/?$/.test(child.path); })) { | |
warn( | |
false, | |
"Named Route '" + (route.name) + "' has a default child route. " + | |
"When navigating to this named route (:to=\"{name: '" + (route.name) + "'\"), " + | |
"the default child route will not be rendered. Remove the name from " + | |
"this route and use the name of the default child route for named " + | |
"links instead." | |
); | |
} | |
} | |
route.children.forEach(function (child) { | |
var childMatchAs = matchAs | |
? cleanPath((matchAs + "/" + (child.path))) | |
: undefined; | |
addRouteRecord(pathMap, nameMap, child, record, childMatchAs); | |
}); | |
} | |
if (route.alias !== undefined) { | |
if (Array.isArray(route.alias)) { | |
route.alias.forEach(function (alias) { | |
var aliasRoute = { | |
path: alias, | |
children: route.children | |
}; | |
addRouteRecord(pathMap, nameMap, aliasRoute, parent, record.path); | |
}); | |
} else { | |
var aliasRoute = { | |
path: route.alias, | |
children: route.children | |
}; | |
addRouteRecord(pathMap, nameMap, aliasRoute, parent, record.path); | |
} | |
} | |
if (!pathMap[record.path]) { | |
pathMap[record.path] = record; | |
} | |
if (name) { | |
if (!nameMap[name]) { | |
nameMap[name] = record; | |
} else if (process.env.NODE_ENV !== 'production' && !matchAs) { | |
warn( | |
false, | |
"Duplicate named routes definition: " + | |
"{ name: \"" + name + "\", path: \"" + (record.path) + "\" }" | |
); | |
} | |
} | |
} | |
function normalizePath (path, parent) { | |
path = path.replace(/\/$/, ''); | |
if (path[0] === '/') { return path } | |
if (parent == null) { return path } | |
return cleanPath(((parent.path) + "/" + path)) | |
} | |
var index$1 = Array.isArray || function (arr) { | |
return Object.prototype.toString.call(arr) == '[object Array]'; | |
}; | |
var isarray = index$1; | |
/** | |
* Expose `pathToRegexp`. | |
*/ | |
var index = pathToRegexp; | |
var parse_1 = parse; | |
var compile_1 = compile; | |
var tokensToFunction_1 = tokensToFunction; | |
var tokensToRegExp_1 = tokensToRegExp; | |
/** | |
* The main path matching regexp utility. | |
* | |
* @type {RegExp} | |
*/ | |
var PATH_REGEXP = new RegExp([ | |
// Match escaped characters that would otherwise appear in future matches. | |
// This allows the user to escape special characters that won't transform. | |
'(\\\\.)', | |
// Match Express-style parameters and un-named parameters with a prefix | |
// and optional suffixes. Matches appear as: | |
// | |
// "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?", undefined] | |
// "/route(\\d+)" => [undefined, undefined, undefined, "\d+", undefined, undefined] | |
// "/*" => ["/", undefined, undefined, undefined, undefined, "*"] | |
'([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))' | |
].join('|'), 'g'); | |
/** | |
* Parse a string for the raw tokens. | |
* | |
* @param {string} str | |
* @param {Object=} options | |
* @return {!Array} | |
*/ | |
function parse (str, options) { | |
var tokens = []; | |
var key = 0; | |
var index = 0; | |
var path = ''; | |
var defaultDelimiter = options && options.delimiter || '/'; | |
var res; | |
while ((res = PATH_REGEXP.exec(str)) != null) { | |
var m = res[0]; | |
var escaped = res[1]; | |
var offset = res.index; | |
path += str.slice(index, offset); | |
index = offset + m.length; | |
// Ignore already escaped sequences. | |
if (escaped) { | |
path += escaped[1]; | |
continue | |
} | |
var next = str[index]; | |
var prefix = res[2]; | |
var name = res[3]; | |
var capture = res[4]; | |
var group = res[5]; | |
var modifier = res[6]; | |
var asterisk = res[7]; | |
// Push the current path onto the tokens. | |
if (path) { | |
tokens.push(path); | |
path = ''; | |
} | |
var partial = prefix != null && next != null && next !== prefix; | |
var repeat = modifier === '+' || modifier === '*'; | |
var optional = modifier === '?' || modifier === '*'; | |
var delimiter = res[2] || defaultDelimiter; | |
var pattern = capture || group; | |
tokens.push({ | |
name: name || key++, | |
prefix: prefix || '', | |
delimiter: delimiter, | |
optional: optional, | |
repeat: repeat, | |
partial: partial, | |
asterisk: !!asterisk, | |
pattern: pattern ? escapeGroup(pattern) : (asterisk ? '.*' : '[^' + escapeString(delimiter) + ']+?') | |
}); | |
} | |
// Match any characters still remaining. | |
if (index < str.length) { | |
path += str.substr(index); | |
} | |
// If the path exists, push it onto the end. | |
if (path) { | |
tokens.push(path); | |
} | |
return tokens | |
} | |
/** | |
* Compile a string to a template function for the path. | |
* | |
* @param {string} str | |
* @param {Object=} options | |
* @return {!function(Object=, Object=)} | |
*/ | |
function compile (str, options) { | |
return tokensToFunction(parse(str, options)) | |
} | |
/** | |
* Prettier encoding of URI path segments. | |
* | |
* @param {string} | |
* @return {string} | |
*/ | |
function encodeURIComponentPretty (str) { | |
return encodeURI(str).replace(/[\/?#]/g, function (c) { | |
return '%' + c.charCodeAt(0).toString(16).toUpperCase() | |
}) | |
} | |
/** | |
* Encode the asterisk parameter. Similar to `pretty`, but allows slashes. | |
* | |
* @param {string} | |
* @return {string} | |
*/ | |
function encodeAsterisk (str) { | |
return encodeURI(str).replace(/[?#]/g, function (c) { | |
return '%' + c.charCodeAt(0).toString(16).toUpperCase() | |
}) | |
} | |
/** | |
* Expose a method for transforming tokens into the path function. | |
*/ | |
function tokensToFunction (tokens) { | |
// Compile all the tokens into regexps. | |
var matches = new Array(tokens.length); | |
// Compile all the patterns before compilation. | |
for (var i = 0; i < tokens.length; i++) { | |
if (typeof tokens[i] === 'object') { | |
matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$'); | |
} | |
} | |
return function (obj, opts) { | |
var path = ''; | |
var data = obj || {}; | |
var options = opts || {}; | |
var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent; | |
for (var i = 0; i < tokens.length; i++) { | |
var token = tokens[i]; | |
if (typeof token === 'string') { | |
path += token; | |
continue | |
} | |
var value = data[token.name]; | |
var segment; | |
if (value == null) { | |
if (token.optional) { | |
// Prepend partial segment prefixes. | |
if (token.partial) { | |
path += token.prefix; | |
} | |
continue | |
} else { | |
throw new TypeError('Expected "' + token.name + '" to be defined') | |
} | |
} | |
if (isarray(value)) { | |
if (!token.repeat) { | |
throw new TypeError('Expected "' + token.name + '" to not repeat, but received `' + JSON.stringify(value) + '`') | |
} | |
if (value.length === 0) { | |
if (token.optional) { | |
continue | |
} else { | |
throw new TypeError('Expected "' + token.name + '" to not be empty') | |
} | |
} | |
for (var j = 0; j < value.length; j++) { | |
segment = encode(value[j]); | |
if (!matches[i].test(segment)) { | |
throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received `' + JSON.stringify(segment) + '`') | |
} | |
path += (j === 0 ? token.prefix : token.delimiter) + segment; | |
} | |
continue | |
} | |
segment = token.asterisk ? encodeAsterisk(value) : encode(value); | |
if (!matches[i].test(segment)) { | |
throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"') | |
} | |
path += token.prefix + segment; | |
} | |
return path | |
} | |
} | |
/** | |
* Escape a regular expression string. | |
* | |
* @param {string} str | |
* @return {string} | |
*/ | |
function escapeString (str) { | |
return str.replace(/([.+*?=^!:${}()[\]|\/\\])/g, '\\$1') | |
} | |
/** | |
* Escape the capturing group by escaping special characters and meaning. | |
* | |
* @param {string} group | |
* @return {string} | |
*/ | |
function escapeGroup (group) { | |
return group.replace(/([=!:$\/()])/g, '\\$1') | |
} | |
/** | |
* Attach the keys as a property of the regexp. | |
* | |
* @param {!RegExp} re | |
* @param {Array} keys | |
* @return {!RegExp} | |
*/ | |
function attachKeys (re, keys) { | |
re.keys = keys; | |
return re | |
} | |
/** | |
* Get the flags for a regexp from the options. | |
* | |
* @param {Object} options | |
* @return {string} | |
*/ | |
function flags (options) { | |
return options.sensitive ? '' : 'i' | |
} | |
/** | |
* Pull out keys from a regexp. | |
* | |
* @param {!RegExp} path | |
* @param {!Array} keys | |
* @return {!RegExp} | |
*/ | |
function regexpToRegexp (path, keys) { | |
// Use a negative lookahead to match only capturing groups. | |
var groups = path.source.match(/\((?!\?)/g); | |
if (groups) { | |
for (var i = 0; i < groups.length; i++) { | |
keys.push({ | |
name: i, | |
prefix: null, | |
delimiter: null, | |
optional: false, | |
repeat: false, | |
partial: false, | |
asterisk: false, | |
pattern: null | |
}); | |
} | |
} | |
return attachKeys(path, keys) | |
} | |
/** | |
* Transform an array into a regexp. | |
* | |
* @param {!Array} path | |
* @param {Array} keys | |
* @param {!Object} options | |
* @return {!RegExp} | |
*/ | |
function arrayToRegexp (path, keys, options) { | |
var parts = []; | |
for (var i = 0; i < path.length; i++) { | |
parts.push(pathToRegexp(path[i], keys, options).source); | |
} | |
var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options)); | |
return attachKeys(regexp, keys) | |
} | |
/** | |
* Create a path regexp from string input. | |
* | |
* @param {string} path | |
* @param {!Array} keys | |
* @param {!Object} options | |
* @return {!RegExp} | |
*/ | |
function stringToRegexp (path, keys, options) { | |
return tokensToRegExp(parse(path, options), keys, options) | |
} | |
/** | |
* Expose a function for taking tokens and returning a RegExp. | |
* | |
* @param {!Array} tokens | |
* @param {(Array|Object)=} keys | |
* @param {Object=} options | |
* @return {!RegExp} | |
*/ | |
function tokensToRegExp (tokens, keys, options) { | |
if (!isarray(keys)) { | |
options = /** @type {!Object} */ (keys || options); | |
keys = []; | |
} | |
options = options || {}; | |
var strict = options.strict; | |
var end = options.end !== false; | |
var route = ''; | |
// Iterate over the tokens and create our regexp string. | |
for (var i = 0; i < tokens.length; i++) { | |
var token = tokens[i]; | |
if (typeof token === 'string') { | |
route += escapeString(token); | |
} else { | |
var prefix = escapeString(token.prefix); | |
var capture = '(?:' + token.pattern + ')'; | |
keys.push(token); | |
if (token.repeat) { | |
capture += '(?:' + prefix + capture + ')*'; | |
} | |
if (token.optional) { | |
if (!token.partial) { | |
capture = '(?:' + prefix + '(' + capture + '))?'; | |
} else { | |
capture = prefix + '(' + capture + ')?'; | |
} | |
} else { | |
capture = prefix + '(' + capture + ')'; | |
} | |
route += capture; | |
} | |
} | |
var delimiter = escapeString(options.delimiter || '/'); | |
var endsWithDelimiter = route.slice(-delimiter.length) === delimiter; | |
// In non-strict mode we allow a slash at the end of match. If the path to | |
// match already ends with a slash, we remove it for consistency. The slash | |
// is valid at the end of a path match, not in the middle. This is important | |
// in non-ending mode, where "/test/" shouldn't match "/test//route". | |
if (!strict) { | |
route = (endsWithDelimiter ? route.slice(0, -delimiter.length) : route) + '(?:' + delimiter + '(?=$))?'; | |
} | |
if (end) { | |
route += '$'; | |
} else { | |
// In non-ending mode, we need the capturing groups to match as much as | |
// possible by using a positive lookahead to the end or next path segment. | |
route += strict && endsWithDelimiter ? '' : '(?=' + delimiter + '|$)'; | |
} | |
return attachKeys(new RegExp('^' + route, flags(options)), keys) | |
} | |
/** | |
* Normalize the given path string, returning a regular expression. | |
* | |
* An empty array can be passed in for the keys, which will hold the | |
* placeholder key descriptions. For example, using `/user/:id`, `keys` will | |
* contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`. | |
* | |
* @param {(string|RegExp|Array)} path | |
* @param {(Array|Object)=} keys | |
* @param {Object=} options | |
* @return {!RegExp} | |
*/ | |
function pathToRegexp (path, keys, options) { | |
if (!isarray(keys)) { | |
options = /** @type {!Object} */ (keys || options); | |
keys = []; | |
} | |
options = options || {}; | |
if (path instanceof RegExp) { | |
return regexpToRegexp(path, /** @type {!Array} */ (keys)) | |
} | |
if (isarray(path)) { | |
return arrayToRegexp(/** @type {!Array} */ (path), /** @type {!Array} */ (keys), options) | |
} | |
return stringToRegexp(/** @type {string} */ (path), /** @type {!Array} */ (keys), options) | |
} | |
index.parse = parse_1; | |
index.compile = compile_1; | |
index.tokensToFunction = tokensToFunction_1; | |
index.tokensToRegExp = tokensToRegExp_1; | |
/* */ | |
var regexpCache = Object.create(null); | |
function getRouteRegex (path) { | |
var hit = regexpCache[path]; | |
var keys, regexp; | |
if (hit) { | |
keys = hit.keys; | |
regexp = hit.regexp; | |
} else { | |
keys = []; | |
regexp = index(path, keys); | |
regexpCache[path] = { keys: keys, regexp: regexp }; | |
} | |
return { keys: keys, regexp: regexp } | |
} | |
var regexpCompileCache = Object.create(null); | |
function fillParams ( | |
path, | |
params, | |
routeMsg | |
) { | |
try { | |
var filler = | |
regexpCompileCache[path] || | |
(regexpCompileCache[path] = index.compile(path)); | |
return filler(params || {}, { pretty: true }) | |
} catch (e) { | |
if (process.env.NODE_ENV !== 'production') { | |
warn(false, ("missing param for " + routeMsg + ": " + (e.message))); | |
} | |
return '' | |
} | |
} | |
/* */ | |
function normalizeLocation ( | |
raw, | |
current, | |
append | |
) { | |
var next = typeof raw === 'string' ? { path: raw } : raw; | |
// named target | |
if (next.name || next._normalized) { | |
return next | |
} | |
// relative params | |
if (!next.path && next.params && current) { | |
next = assign({}, next); | |
next._normalized = true; | |
var params = assign(assign({}, current.params), next.params); | |
if (current.name) { | |
next.name = current.name; | |
next.params = params; | |
} else if (current.matched) { | |
var rawPath = current.matched[current.matched.length - 1].path; | |
next.path = fillParams(rawPath, params, ("path " + (current.path))); | |
} else if (process.env.NODE_ENV !== 'production') { | |
warn(false, "relative params navigation requires a current route."); | |
} | |
return next | |
} | |
var parsedPath = parsePath(next.path || ''); | |
var basePath = (current && current.path) || '/'; | |
var path = parsedPath.path | |
? resolvePath(parsedPath.path, basePath, append || next.append) | |
: (current && current.path) || '/'; | |
var query = resolveQuery(parsedPath.query, next.query); | |
var hash = next.hash || parsedPath.hash; | |
if (hash && hash.charAt(0) !== '#') { | |
hash = "#" + hash; | |
} | |
return { | |
_normalized: true, | |
path: path, | |
query: query, | |
hash: hash | |
} | |
} | |
function assign (a, b) { | |
for (var key in b) { | |
a[key] = b[key]; | |
} | |
return a | |
} | |
/* */ | |
function createMatcher (routes) { | |
var ref = createRouteMap(routes); | |
var pathMap = ref.pathMap; | |
var nameMap = ref.nameMap; | |
function addRoutes (routes) { | |
createRouteMap(routes, pathMap, nameMap); | |
} | |
function match ( | |
raw, | |
currentRoute, | |
redirectedFrom | |
) { | |
var location = normalizeLocation(raw, currentRoute); | |
var name = location.name; | |
if (name) { | |
var record = nameMap[name]; | |
if (process.env.NODE_ENV !== 'production') { | |
warn(record, ("Route with name '" + name + "' does not exist")); | |
} | |
var paramNames = getRouteRegex(record.path).keys | |
.filter(function (key) { return !key.optional; }) | |
.map(function (key) { return key.name; }); | |
if (typeof location.params !== 'object') { | |
location.params = {}; | |
} | |
if (currentRoute && typeof currentRoute.params === 'object') { | |
for (var key in currentRoute.params) { | |
if (!(key in location.params) && paramNames.indexOf(key) > -1) { | |
location.params[key] = currentRoute.params[key]; | |
} | |
} | |
} | |
if (record) { | |
location.path = fillParams(record.path, location.params, ("named route \"" + name + "\"")); | |
return _createRoute(record, location, redirectedFrom) | |
} | |
} else if (location.path) { | |
location.params = {}; | |
for (var path in pathMap) { | |
if (matchRoute(path, location.params, location.path)) { | |
return _createRoute(pathMap[path], location, redirectedFrom) | |
} | |
} | |
} | |
// no match | |
return _createRoute(null, location) | |
} | |
function redirect ( | |
record, | |
location | |
) { | |
var originalRedirect = record.redirect; | |
var redirect = typeof originalRedirect === 'function' | |
? originalRedirect(createRoute(record, location)) | |
: originalRedirect; | |
if (typeof redirect === 'string') { | |
redirect = { path: redirect }; | |
} | |
if (!redirect || typeof redirect !== 'object') { | |
process.env.NODE_ENV !== 'production' && warn( | |
false, ("invalid redirect option: " + (JSON.stringify(redirect))) | |
); | |
return _createRoute(null, location) | |
} | |
var re = redirect; | |
var name = re.name; | |
var path = re.path; | |
var query = location.query; | |
var hash = location.hash; | |
var params = location.params; | |
query = re.hasOwnProperty('query') ? re.query : query; | |
hash = re.hasOwnProperty('hash') ? re.hash : hash; | |
params = re.hasOwnProperty('params') ? re.params : params; | |
if (name) { | |
// resolved named direct | |
var targetRecord = nameMap[name]; | |
if (process.env.NODE_ENV !== 'production') { | |
assert(targetRecord, ("redirect failed: named route \"" + name + "\" not found.")); | |
} | |
return match({ | |
_normalized: true, | |
name: name, | |
query: query, | |
hash: hash, | |
params: params | |
}, undefined, location) | |
} else if (path) { | |
// 1. resolve relative redirect | |
var rawPath = resolveRecordPath(path, record); | |
// 2. resolve params | |
var resolvedPath = fillParams(rawPath, params, ("redirect route with path \"" + rawPath + "\"")); | |
// 3. rematch with existing query and hash | |
return match({ | |
_normalized: true, | |
path: resolvedPath, | |
query: query, | |
hash: hash | |
}, undefined, location) | |
} else { | |
warn(false, ("invalid redirect option: " + (JSON.stringify(redirect)))); | |
return _createRoute(null, location) | |
} | |
} | |
function alias ( | |
record, | |
location, | |
matchAs | |
) { | |
var aliasedPath = fillParams(matchAs, location.params, ("aliased route with path \"" + matchAs + "\"")); | |
var aliasedMatch = match({ | |
_normalized: true, | |
path: aliasedPath | |
}); | |
if (aliasedMatch) { | |
var matched = aliasedMatch.matched; | |
var aliasedRecord = matched[matched.length - 1]; | |
location.params = aliasedMatch.params; | |
return _createRoute(aliasedRecord, location) | |
} | |
return _createRoute(null, location) | |
} | |
function _createRoute ( | |
record, | |
location, | |
redirectedFrom | |
) { | |
if (record && record.redirect) { | |
return redirect(record, redirectedFrom || location) | |
} | |
if (record && record.matchAs) { | |
return alias(record, location, record.matchAs) | |
} | |
return createRoute(record, location, redirectedFrom) | |
} | |
return { | |
match: match, | |
addRoutes: addRoutes | |
} | |
} | |
function matchRoute ( | |
path, | |
params, | |
pathname | |
) { | |
var ref = getRouteRegex(path); | |
var regexp = ref.regexp; | |
var keys = ref.keys; | |
var m = pathname.match(regexp); | |
if (!m) { | |
return false | |
} else if (!params) { | |
return true | |
} | |
for (var i = 1, len = m.length; i < len; ++i) { | |
var key = keys[i - 1]; | |
var val = typeof m[i] === 'string' ? decodeURIComponent(m[i]) : m[i]; | |
if (key) { params[key.name] = val; } | |
} | |
return true | |
} | |
function resolveRecordPath (path, record) { | |
return resolvePath(path, record.parent ? record.parent.path : '/', true) | |
} | |
/* */ | |
var positionStore = Object.create(null); | |
function setupScroll () { | |
window.addEventListener('popstate', function (e) { | |
if (e.state && e.state.key) { | |
setStateKey(e.state.key); | |
} | |
}); | |
window.addEventListener('scroll', saveScrollPosition); | |
} | |
function handleScroll ( | |
router, | |
to, | |
from, | |
isPop | |
) { | |
if (!router.app) { | |
return | |
} | |
var behavior = router.options.scrollBehavior; | |
if (!behavior) { | |
return | |
} | |
if (process.env.NODE_ENV !== 'production') { | |
assert(typeof behavior === 'function', "scrollBehavior must be a function"); | |
} | |
// wait until re-render finishes before scrolling | |
router.app.$nextTick(function () { | |
var position = getScrollPosition(); | |
var shouldScroll = behavior(to, from, isPop ? position : null); | |
if (!shouldScroll) { | |
return | |
} | |
var isObject = typeof shouldScroll === 'object'; | |
if (isObject && typeof shouldScroll.selector === 'string') { | |
var el = document.querySelector(shouldScroll.selector); | |
if (el) { | |
position = getElementPosition(el); | |
} else if (isValidPosition(shouldScroll)) { | |
position = normalizePosition(shouldScroll); | |
} | |
} else if (isObject && isValidPosition(shouldScroll)) { | |
position = normalizePosition(shouldScroll); | |
} | |
if (position) { | |
window.scrollTo(position.x, position.y); | |
} | |
}); | |
} | |
function saveScrollPosition () { | |
var key = getStateKey(); | |
if (key) { | |
positionStore[key] = { | |
x: window.pageXOffset, | |
y: window.pageYOffset | |
}; | |
} | |
} | |
function getScrollPosition () { | |
var key = getStateKey(); | |
if (key) { | |
return positionStore[key] | |
} | |
} | |
function getElementPosition (el) { | |
var docRect = document.documentElement.getBoundingClientRect(); | |
var elRect = el.getBoundingClientRect(); | |
return { | |
x: elRect.left - docRect.left, | |
y: elRect.top - docRect.top | |
} | |
} | |
function isValidPosition (obj) { | |
return isNumber(obj.x) || isNumber(obj.y) | |
} | |
function normalizePosition (obj) { | |
return { | |
x: isNumber(obj.x) ? obj.x : window.pageXOffset, | |
y: isNumber(obj.y) ? obj.y : window.pageYOffset | |
} | |
} | |
function isNumber (v) { | |
return typeof v === 'number' | |
} | |
/* */ | |
var supportsPushState = inBrowser && (function () { | |
var ua = window.navigator.userAgent; | |
if ( | |
(ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && | |
ua.indexOf('Mobile Safari') !== -1 && | |
ua.indexOf('Chrome') === -1 && | |
ua.indexOf('Windows Phone') === -1 | |
) { | |
return false | |
} | |
return window.history && 'pushState' in window.history | |
})(); | |
// use User Timing api (if present) for more accurate key precision | |
var Time = inBrowser && window.performance && window.performance.now | |
? window.performance | |
: Date; | |
var _key = genKey(); | |
function genKey () { | |
return Time.now().toFixed(3) | |
} | |
function getStateKey () { | |
return _key | |
} | |
function setStateKey (key) { | |
_key = key; | |
} | |
function pushState (url, replace) { | |
// try...catch the pushState call to get around Safari | |
// DOM Exception 18 where it limits to 100 pushState calls | |
var history = window.history; | |
try { | |
if (replace) { | |
history.replaceState({ key: _key }, '', url); | |
} else { | |
_key = genKey(); | |
history.pushState({ key: _key }, '', url); | |
} | |
saveScrollPosition(); | |
} catch (e) { | |
window.location[replace ? 'replace' : 'assign'](url); | |
} | |
} | |
function replaceState (url) { | |
pushState(url, true); | |
} | |
/* */ | |
function runQueue (queue, fn, cb) { | |
var step = function (index) { | |
if (index >= queue.length) { | |
cb(); | |
} else { | |
if (queue[index]) { | |
fn(queue[index], function () { | |
step(index + 1); | |
}); | |
} else { | |
step(index + 1); | |
} | |
} | |
}; | |
step(0); | |
} | |
/* */ | |
var History = function History (router, base) { | |
this.router = router; | |
this.base = normalizeBase(base); | |
// start with a route object that stands for "nowhere" | |
this.current = START; | |
this.pending = null; | |
this.ready = false; | |
this.readyCbs = []; | |
}; | |
History.prototype.listen = function listen (cb) { | |
this.cb = cb; | |
}; | |
History.prototype.onReady = function onReady (cb) { | |
if (this.ready) { | |
cb(); | |
} else { | |
this.readyCbs.push(cb); | |
} | |
}; | |
History.prototype.transitionTo = function transitionTo (location, onComplete, onAbort) { | |
var this$1 = this; | |
var route = this.router.match(location, this.current); | |
this.confirmTransition(route, function () { | |
this$1.updateRoute(route); | |
onComplete && onComplete(route); | |
this$1.ensureURL(); | |
// fire ready cbs once | |
if (!this$1.ready) { | |
this$1.ready = true; | |
this$1.readyCbs.forEach(function (cb) { | |
cb(route); | |
}); | |
} | |
}, onAbort); | |
}; | |
History.prototype.confirmTransition = function confirmTransition (route, onComplete, onAbort) { | |
var this$1 = this; | |
var current = this.current; | |
var abort = function () { onAbort && onAbort(); }; | |
if ( | |
isSameRoute(route, current) && | |
// in the case the route map has been dynamically appended to | |
route.matched.length === current.matched.length | |
) { | |
this.ensureURL(); | |
return abort() | |
} | |
var ref = resolveQueue(this.current.matched, route.matched); | |
var updated = ref.updated; | |
var deactivated = ref.deactivated; | |
var activated = ref.activated; | |
var queue = [].concat( | |
// in-component leave guards | |
extractLeaveGuards(deactivated), | |
// global before hooks | |
this.router.beforeHooks, | |
// in-component update hooks | |
extractUpdateHooks(updated), | |
// in-config enter guards | |
activated.map(function (m) { return m.beforeEnter; }), | |
// async components | |
resolveAsyncComponents(activated) | |
); | |
this.pending = route; | |
var iterator = function (hook, next) { | |
if (this$1.pending !== route) { | |
return abort() | |
} | |
hook(route, current, function (to) { | |
if (to === false) { | |
// next(false) -> abort navigation, ensure current URL | |
this$1.ensureURL(true); | |
abort(); | |
} else if (typeof to === 'string' || typeof to === 'object') { | |
// next('/') or next({ path: '/' }) -> redirect | |
(typeof to === 'object' && to.replace) ? this$1.replace(to) : this$1.push(to); | |
abort(); | |
} else { | |
// confirm transition and pass on the value | |
next(to); | |
} | |
}); | |
}; | |
runQueue(queue, iterator, function () { | |
var postEnterCbs = []; | |
var isValid = function () { return this$1.current === route; }; | |
var enterGuards = extractEnterGuards(activated, postEnterCbs, isValid); | |
// wait until async components are resolved before | |
// extracting in-component enter guards | |
runQueue(enterGuards, iterator, function () { | |
if (this$1.pending !== route) { | |
return abort() | |
} | |
this$1.pending = null; | |
onComplete(route); | |
if (this$1.router.app) { | |
this$1.router.app.$nextTick(function () { | |
postEnterCbs.forEach(function (cb) { return cb(); }); | |
}); | |
} | |
}); | |
}); | |
}; | |
History.prototype.updateRoute = function updateRoute (route) { | |
var prev = this.current; | |
this.current = route; | |
this.cb && this.cb(route); | |
this.router.afterHooks.forEach(function (hook) { | |
hook && hook(route, prev); | |
}); | |
}; | |
function normalizeBase (base) { | |
if (!base) { | |
if (inBrowser) { | |
// respect <base> tag | |
var baseEl = document.querySelector('base'); | |
base = baseEl ? baseEl.getAttribute('href') : '/'; | |
} else { | |
base = '/'; | |
} | |
} | |
// make sure there's the starting slash | |
if (base.charAt(0) !== '/') { | |
base = '/' + base; | |
} | |
// remove trailing slash | |
return base.replace(/\/$/, '') | |
} | |
function resolveQueue ( | |
current, | |
next | |
) { | |
var i; | |
var max = Math.max(current.length, next.length); | |
for (i = 0; i < max; i++) { | |
if (current[i] !== next[i]) { | |
break | |
} | |
} | |
return { | |
updated: next.slice(0, i), | |
activated: next.slice(i), | |
deactivated: current.slice(i) | |
} | |
} | |
function extractGuards ( | |
records, | |
name, | |
bind, | |
reverse | |
) { | |
var guards = flatMapComponents(records, function (def, instance, match, key) { | |
var guard = extractGuard(def, name); | |
if (guard) { | |
return Array.isArray(guard) | |
? guard.map(function (guard) { return bind(guard, instance, match, key); }) | |
: bind(guard, instance, match, key) | |
} | |
}); | |
return flatten(reverse ? guards.reverse() : guards) | |
} | |
function extractGuard ( | |
def, | |
key | |
) { | |
if (typeof def !== 'function') { | |
// extend now so that global mixins are applied. | |
def = _Vue.extend(def); | |
} | |
return def.options[key] | |
} | |
function extractLeaveGuards (deactivated) { | |
return extractGuards(deactivated, 'beforeRouteLeave', bindGuard, true) | |
} | |
function extractUpdateHooks (updated) { | |
return extractGuards(updated, 'beforeRouteUpdate', bindGuard) | |
} | |
function bindGuard (guard, instance) { | |
return function boundRouteGuard () { | |
return guard.apply(instance, arguments) | |
} | |
} | |
function extractEnterGuards ( | |
activated, | |
cbs, | |
isValid | |
) { | |
return extractGuards(activated, 'beforeRouteEnter', function (guard, _, match, key) { | |
return bindEnterGuard(guard, match, key, cbs, isValid) | |
}) | |
} | |
function bindEnterGuard ( | |
guard, | |
match, | |
key, | |
cbs, | |
isValid | |
) { | |
return function routeEnterGuard (to, from, next) { | |
return guard(to, from, function (cb) { | |
next(cb); | |
if (typeof cb === 'function') { | |
cbs.push(function () { | |
// #750 | |
// if a router-view is wrapped with an out-in transition, | |
// the instance may not have been registered at this time. | |
// we will need to poll for registration until current route | |
// is no longer valid. | |
poll(cb, match.instances, key, isValid); | |
}); | |
} | |
}) | |
} | |
} | |
function poll ( | |
cb, // somehow flow cannot infer this is a function | |
instances, | |
key, | |
isValid | |
) { | |
if (instances[key]) { | |
cb(instances[key]); | |
} else if (isValid()) { | |
setTimeout(function () { | |
poll(cb, instances, key, isValid); | |
}, 16); | |
} | |
} | |
function resolveAsyncComponents (matched) { | |
return flatMapComponents(matched, function (def, _, match, key) { | |
// if it's a function and doesn't have Vue options attached, | |
// assume it's an async component resolve function. | |
// we are not using Vue's default async resolving mechanism because | |
// we want to halt the navigation until the incoming component has been | |
// resolved. | |
if (typeof def === 'function' && !def.options) { | |
return function (to, from, next) { | |
var resolve = once(function (resolvedDef) { | |
match.components[key] = resolvedDef; | |
next(); | |
}); | |
var reject = once(function (reason) { | |
warn(false, ("Failed to resolve async component " + key + ": " + reason)); | |
next(false); | |
}); | |
var res = def(resolve, reject); | |
if (res && typeof res.then === 'function') { | |
res.then(resolve, reject); | |
} | |
} | |
} | |
}) | |
} | |
function flatMapComponents ( | |
matched, | |
fn | |
) { | |
return flatten(matched.map(function (m) { | |
return Object.keys(m.components).map(function (key) { return fn( | |
m.components[key], | |
m.instances[key], | |
m, key | |
); }) | |
})) | |
} | |
function flatten (arr) { | |
return Array.prototype.concat.apply([], arr) | |
} | |
// in Webpack 2, require.ensure now also returns a Promise | |
// so the resolve/reject functions may get called an extra time | |
// if the user uses an arrow function shorthand that happens to | |
// return that Promise. | |
function once (fn) { | |
var called = false; | |
return function () { | |
if (called) { return } | |
called = true; | |
return fn.apply(this, arguments) | |
} | |
} | |
/* */ | |
var HTML5History = (function (History$$1) { | |
function HTML5History (router, base) { | |
var this$1 = this; | |
History$$1.call(this, router, base); | |
var expectScroll = router.options.scrollBehavior; | |
if (expectScroll) { | |
setupScroll(); | |
} | |
window.addEventListener('popstate', function (e) { | |
this$1.transitionTo(getLocation(this$1.base), function (route) { | |
if (expectScroll) { | |
handleScroll(router, route, this$1.current, true); | |
} | |
}); | |
}); | |
} | |
if ( History$$1 ) HTML5History.__proto__ = History$$1; | |
HTML5History.prototype = Object.create( History$$1 && History$$1.prototype ); | |
HTML5History.prototype.constructor = HTML5History; | |
HTML5History.prototype.go = function go (n) { | |
window.history.go(n); | |
}; | |
HTML5History.prototype.push = function push (location, onComplete, onAbort) { | |
var this$1 = this; | |
this.transitionTo(location, function (route) { | |
pushState(cleanPath(this$1.base + route.fullPath)); | |
handleScroll(this$1.router, route, this$1.current, false); | |
onComplete && onComplete(route); | |
}, onAbort); | |
}; | |
HTML5History.prototype.replace = function replace (location, onComplete, onAbort) { | |
var this$1 = this; | |
this.transitionTo(location, function (route) { | |
replaceState(cleanPath(this$1.base + route.fullPath)); | |
handleScroll(this$1.router, route, this$1.current, false); | |
onComplete && onComplete(route); | |
}, onAbort); | |
}; | |
HTML5History.prototype.ensureURL = function ensureURL (push) { | |
if (getLocation(this.base) !== this.current.fullPath) { | |
var current = cleanPath(this.base + this.current.fullPath); | |
push ? pushState(current) : replaceState(current); | |
} | |
}; | |
HTML5History.prototype.getCurrentLocation = function getCurrentLocation () { | |
return getLocation(this.base) | |
}; | |
return HTML5History; | |
}(History)); | |
function getLocation (base) { | |
var path = window.location.pathname; | |
if (base && path.indexOf(base) === 0) { | |
path = path.slice(base.length); | |
} | |
return (path || '/') + window.location.search + window.location.hash | |
} | |
/* */ | |
var HashHistory = (function (History$$1) { | |
function HashHistory (router, base, fallback) { | |
History$$1.call(this, router, base); | |
// check history fallback deeplinking | |
if (fallback && checkFallback(this.base)) { | |
return | |
} | |
ensureSlash(); | |
} | |
if ( History$$1 ) HashHistory.__proto__ = History$$1; | |
HashHistory.prototype = Object.create( History$$1 && History$$1.prototype ); | |
HashHistory.prototype.constructor = HashHistory; | |
// this is delayed until the app mounts | |
// to avoid the hashchange listener being fired too early | |
HashHistory.prototype.setupListeners = function setupListeners () { | |
var this$1 = this; | |
window.addEventListener('hashchange', function () { | |
if (!ensureSlash()) { | |
return | |
} | |
this$1.transitionTo(getHash(), function (route) { | |
replaceHash(route.fullPath); | |
}); | |
}); | |
}; | |
HashHistory.prototype.push = function push (location, onComplete, onAbort) { | |
this.transitionTo(location, function (route) { | |
pushHash(route.fullPath); | |
onComplete && onComplete(route); | |
}, onAbort); | |
}; | |
HashHistory.prototype.replace = function replace (location, onComplete, onAbort) { | |
this.transitionTo(location, function (route) { | |
replaceHash(route.fullPath); | |
onComplete && onComplete(route); | |
}, onAbort); | |
}; | |
HashHistory.prototype.go = function go (n) { | |
window.history.go(n); | |
}; | |
HashHistory.prototype.ensureURL = function ensureURL (push) { | |
var current = this.current.fullPath; | |
if (getHash() !== current) { | |
push ? pushHash(current) : replaceHash(current); | |
} | |
}; | |
HashHistory.prototype.getCurrentLocation = function getCurrentLocation () { | |
return getHash() | |
}; | |
return HashHistory; | |
}(History)); | |
function checkFallback (base) { | |
var location = getLocation(base); | |
if (!/^\/#/.test(location)) { | |
window.location.replace( | |
cleanPath(base + '/#' + location) | |
); | |
return true | |
} | |
} | |
function ensureSlash () { | |
var path = getHash(); | |
if (path.charAt(0) === '/') { | |
return true | |
} | |
replaceHash('/' + path); | |
return false | |
} | |
function getHash () { | |
// We can't use window.location.hash here because it's not | |
// consistent across browsers - Firefox will pre-decode it! | |
var href = window.location.href; | |
var index = href.indexOf('#'); | |
return index === -1 ? '' : href.slice(index + 1) | |
} | |
function pushHash (path) { | |
window.location.hash = path; | |
} | |
function replaceHash (path) { | |
var i = window.location.href.indexOf('#'); | |
window.location.replace( | |
window.location.href.slice(0, i >= 0 ? i : 0) + '#' + path | |
); | |
} | |
/* */ | |
var AbstractHistory = (function (History$$1) { | |
function AbstractHistory (router, base) { | |
History$$1.call(this, router, base); | |
this.stack = []; | |
this.index = -1; | |
} | |
if ( History$$1 ) AbstractHistory.__proto__ = History$$1; | |
AbstractHistory.prototype = Object.create( History$$1 && History$$1.prototype ); | |
AbstractHistory.prototype.constructor = AbstractHistory; | |
AbstractHistory.prototype.push = function push (location, onComplete, onAbort) { | |
var this$1 = this; | |
this.transitionTo(location, function (route) { | |
this$1.stack = this$1.stack.slice(0, this$1.index + 1).concat(route); | |
this$1.index++; | |
onComplete && onComplete(route); | |
}, onAbort); | |
}; | |
AbstractHistory.prototype.replace = function replace (location, onComplete, onAbort) { | |
var this$1 = this; | |
this.transitionTo(location, function (route) { | |
this$1.stack = this$1.stack.slice(0, this$1.index).concat(route); | |
onComplete && onComplete(route); | |
}, onAbort); | |
}; | |
AbstractHistory.prototype.go = function go (n) { | |
var this$1 = this; | |
var targetIndex = this.index + n; | |
if (targetIndex < 0 || targetIndex >= this.stack.length) { | |
return | |
} | |
var route = this.stack[targetIndex]; | |
this.confirmTransition(route, function () { | |
this$1.index = targetIndex; | |
this$1.updateRoute(route); | |
}); | |
}; | |
AbstractHistory.prototype.getCurrentLocation = function getCurrentLocation () { | |
var current = this.stack[this.stack.length - 1]; | |
return current ? current.fullPath : '/' | |
}; | |
AbstractHistory.prototype.ensureURL = function ensureURL () { | |
// noop | |
}; | |
return AbstractHistory; | |
}(History)); | |
/* */ | |
var VueRouter = function VueRouter (options) { | |
if ( options === void 0 ) options = {}; | |
this.app = null; | |
this.apps = []; | |
this.options = options; | |
this.beforeHooks = []; | |
this.afterHooks = []; | |
this.matcher = createMatcher(options.routes || []); | |
var mode = options.mode || 'hash'; | |
this.fallback = mode === 'history' && !supportsPushState; | |
if (this.fallback) { | |
mode = 'hash'; | |
} | |
if (!inBrowser) { | |
mode = 'abstract'; | |
} | |
this.mode = mode; | |
switch (mode) { | |
case 'history': | |
this.history = new HTML5History(this, options.base); | |
break | |
case 'hash': | |
this.history = new HashHistory(this, options.base, this.fallback); | |
break | |
case 'abstract': | |
this.history = new AbstractHistory(this, options.base); | |
break | |
default: | |
if (process.env.NODE_ENV !== 'production') { | |
assert(false, ("invalid mode: " + mode)); | |
} | |
} | |
}; | |
var prototypeAccessors = { currentRoute: {} }; | |
VueRouter.prototype.match = function match ( | |
raw, | |
current, | |
redirectedFrom | |
) { | |
return this.matcher.match(raw, current, redirectedFrom) | |
}; | |
prototypeAccessors.currentRoute.get = function () { | |
return this.history && this.history.current | |
}; | |
VueRouter.prototype.init = function init (app /* Vue component instance */) { | |
var this$1 = this; | |
process.env.NODE_ENV !== 'production' && assert( | |
install.installed, | |
"not installed. Make sure to call `Vue.use(VueRouter)` " + | |
"before creating root instance." | |
); | |
this.apps.push(app); | |
// main app already initialized. | |
if (this.app) { | |
return | |
} | |
this.app = app; | |
var history = this.history; | |
if (history instanceof HTML5History) { | |
history.transitionTo(history.getCurrentLocation()); | |
} else if (history instanceof HashHistory) { | |
var setupHashListener = function () { | |
history.setupListeners(); | |
}; | |
history.transitionTo( | |
history.getCurrentLocation(), | |
setupHashListener, | |
setupHashListener | |
); | |
} | |
history.listen(function (route) { | |
this$1.apps.forEach(function (app) { | |
app._route = route; | |
}); | |
}); | |
}; | |
VueRouter.prototype.beforeEach = function beforeEach (fn) { | |
this.beforeHooks.push(fn); | |
}; | |
VueRouter.prototype.afterEach = function afterEach (fn) { | |
this.afterHooks.push(fn); | |
}; | |
VueRouter.prototype.onReady = function onReady (cb) { | |
this.history.onReady(cb); | |
}; | |
VueRouter.prototype.push = function push (location, onComplete, onAbort) { | |
this.history.push(location, onComplete, onAbort); | |
}; | |
VueRouter.prototype.replace = function replace (location, onComplete, onAbort) { | |
this.history.replace(location, onComplete, onAbort); | |
}; | |
VueRouter.prototype.go = function go (n) { | |
this.history.go(n); | |
}; | |
VueRouter.prototype.back = function back () { | |
this.go(-1); | |
}; | |
VueRouter.prototype.forward = function forward () { | |
this.go(1); | |
}; | |
VueRouter.prototype.getMatchedComponents = function getMatchedComponents (to) { | |
var route = to | |
? this.resolve(to).route | |
: this.currentRoute; | |
if (!route) { | |
return [] | |
} | |
return [].concat.apply([], route.matched.map(function (m) { | |
return Object.keys(m.components).map(function (key) { | |
return m.components[key] | |
}) | |
})) | |
}; | |
VueRouter.prototype.resolve = function resolve ( | |
to, | |
current, | |
append | |
) { | |
var location = normalizeLocation(to, current || this.history.current, append); | |
var route = this.match(location, current); | |
var fullPath = route.redirectedFrom || route.fullPath; | |
var base = this.history.base; | |
var href = createHref(base, fullPath, this.mode); | |
return { | |
location: location, | |
route: route, | |
href: href, | |
// for backwards compat | |
normalizedTo: location, | |
resolved: route | |
} | |
}; | |
VueRouter.prototype.addRoutes = function addRoutes (routes) { | |
this.matcher.addRoutes(routes); | |
if (this.history.current !== START) { | |
this.history.transitionTo(this.history.getCurrentLocation()); | |
} | |
}; | |
Object.defineProperties( VueRouter.prototype, prototypeAccessors ); | |
function createHref (base, fullPath, mode) { | |
var path = mode === 'hash' ? '#' + fullPath : fullPath; | |
return base ? cleanPath(base + '/' + path) : path | |
} | |
VueRouter.install = install; | |
VueRouter.version = '2.2.0'; | |
if (inBrowser && window.Vue) { | |
window.Vue.use(VueRouter); | |
} | |
module.exports = VueRouter; | |
}).call(this,require('_process')) | |
},{"_process":1}],70:[function(require,module,exports){ | |
(function (global){ | |
/*! | |
* Vue.js v2.1.10 | |
* (c) 2014-2017 Evan You | |
* Released under the MIT License. | |
*/ | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : | |
typeof define === 'function' && define.amd ? define(factory) : | |
(global.Vue = factory()); | |
}(this, (function () { 'use strict'; | |
/* */ | |
/** | |
* Convert a value to a string that is actually rendered. | |
*/ | |
function _toString (val) { | |
return val == null | |
? '' | |
: typeof val === 'object' | |
? JSON.stringify(val, null, 2) | |
: String(val) | |
} | |
/** | |
* Convert a input value to a number for persistence. | |
* If the conversion fails, return original string. | |
*/ | |
function toNumber (val) { | |
var n = parseFloat(val); | |
return isNaN(n) ? val : n | |
} | |
/** | |
* Make a map and return a function for checking if a key | |
* is in that map. | |
*/ | |
function makeMap ( | |
str, | |
expectsLowerCase | |
) { | |
var map = Object.create(null); | |
var list = str.split(','); | |
for (var i = 0; i < list.length; i++) { | |
map[list[i]] = true; | |
} | |
return expectsLowerCase | |
? function (val) { return map[val.toLowerCase()]; } | |
: function (val) { return map[val]; } | |
} | |
/** | |
* Check if a tag is a built-in tag. | |
*/ | |
var isBuiltInTag = makeMap('slot,component', true); | |
/** | |
* Remove an item from an array | |
*/ | |
function remove$1 (arr, item) { | |
if (arr.length) { | |
var index = arr.indexOf(item); | |
if (index > -1) { | |
return arr.splice(index, 1) | |
} | |
} | |
} | |
/** | |
* Check whether the object has the property. | |
*/ | |
var hasOwnProperty = Object.prototype.hasOwnProperty; | |
function hasOwn (obj, key) { | |
return hasOwnProperty.call(obj, key) | |
} | |
/** | |
* Check if value is primitive | |
*/ | |
function isPrimitive (value) { | |
return typeof value === 'string' || typeof value === 'number' | |
} | |
/** | |
* Create a cached version of a pure function. | |
*/ | |
function cached (fn) { | |
var cache = Object.create(null); | |
return (function cachedFn (str) { | |
var hit = cache[str]; | |
return hit || (cache[str] = fn(str)) | |
}) | |
} | |
/** | |
* Camelize a hyphen-delimited string. | |
*/ | |
var camelizeRE = /-(\w)/g; | |
var camelize = cached(function (str) { | |
return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; }) | |
}); | |
/** | |
* Capitalize a string. | |
*/ | |
var capitalize = cached(function (str) { | |
return str.charAt(0).toUpperCase() + str.slice(1) | |
}); | |
/** | |
* Hyphenate a camelCase string. | |
*/ | |
var hyphenateRE = /([^-])([A-Z])/g; | |
var hyphenate = cached(function (str) { | |
return str | |
.replace(hyphenateRE, '$1-$2') | |
.replace(hyphenateRE, '$1-$2') | |
.toLowerCase() | |
}); | |
/** | |
* Simple bind, faster than native | |
*/ | |
function bind$1 (fn, ctx) { | |
function boundFn (a) { | |
var l = arguments.length; | |
return l | |
? l > 1 | |
? fn.apply(ctx, arguments) | |
: fn.call(ctx, a) | |
: fn.call(ctx) | |
} | |
// record original fn length | |
boundFn._length = fn.length; | |
return boundFn | |
} | |
/** | |
* Convert an Array-like object to a real Array. | |
*/ | |
function toArray (list, start) { | |
start = start || 0; | |
var i = list.length - start; | |
var ret = new Array(i); | |
while (i--) { | |
ret[i] = list[i + start]; | |
} | |
return ret | |
} | |
/** | |
* Mix properties into target object. | |
*/ | |
function extend (to, _from) { | |
for (var key in _from) { | |
to[key] = _from[key]; | |
} | |
return to | |
} | |
/** | |
* Quick object check - this is primarily used to tell | |
* Objects from primitive values when we know the value | |
* is a JSON-compliant type. | |
*/ | |
function isObject (obj) { | |
return obj !== null && typeof obj === 'object' | |
} | |
/** | |
* Strict object type check. Only returns true | |
* for plain JavaScript objects. | |
*/ | |
var toString = Object.prototype.toString; | |
var OBJECT_STRING = '[object Object]'; | |
function isPlainObject (obj) { | |
return toString.call(obj) === OBJECT_STRING | |
} | |
/** | |
* Merge an Array of Objects into a single Object. | |
*/ | |
function toObject (arr) { | |
var res = {}; | |
for (var i = 0; i < arr.length; i++) { | |
if (arr[i]) { | |
extend(res, arr[i]); | |
} | |
} | |
return res | |
} | |
/** | |
* Perform no operation. | |
*/ | |
function noop () {} | |
/** | |
* Always return false. | |
*/ | |
var no = function () { return false; }; | |
/** | |
* Return same value | |
*/ | |
var identity = function (_) { return _; }; | |
/** | |
* Generate a static keys string from compiler modules. | |
*/ | |
function genStaticKeys (modules) { | |
return modules.reduce(function (keys, m) { | |
return keys.concat(m.staticKeys || []) | |
}, []).join(',') | |
} | |
/** | |
* Check if two values are loosely equal - that is, | |
* if they are plain objects, do they have the same shape? | |
*/ | |
function looseEqual (a, b) { | |
var isObjectA = isObject(a); | |
var isObjectB = isObject(b); | |
if (isObjectA && isObjectB) { | |
return JSON.stringify(a) === JSON.stringify(b) | |
} else if (!isObjectA && !isObjectB) { | |
return String(a) === String(b) | |
} else { | |
return false | |
} | |
} | |
function looseIndexOf (arr, val) { | |
for (var i = 0; i < arr.length; i++) { | |
if (looseEqual(arr[i], val)) { return i } | |
} | |
return -1 | |
} | |
/* */ | |
var config = { | |
/** | |
* Option merge strategies (used in core/util/options) | |
*/ | |
optionMergeStrategies: Object.create(null), | |
/** | |
* Whether to suppress warnings. | |
*/ | |
silent: false, | |
/** | |
* Whether to enable devtools | |
*/ | |
devtools: "development" !== 'production', | |
/** | |
* Error handler for watcher errors | |
*/ | |
errorHandler: null, | |
/** | |
* Ignore certain custom elements | |
*/ | |
ignoredElements: [], | |
/** | |
* Custom user key aliases for v-on | |
*/ | |
keyCodes: Object.create(null), | |
/** | |
* Check if a tag is reserved so that it cannot be registered as a | |
* component. This is platform-dependent and may be overwritten. | |
*/ | |
isReservedTag: no, | |
/** | |
* Check if a tag is an unknown element. | |
* Platform-dependent. | |
*/ | |
isUnknownElement: no, | |
/** | |
* Get the namespace of an element | |
*/ | |
getTagNamespace: noop, | |
/** | |
* Parse the real tag name for the specific platform. | |
*/ | |
parsePlatformTagName: identity, | |
/** | |
* Check if an attribute must be bound using property, e.g. value | |
* Platform-dependent. | |
*/ | |
mustUseProp: no, | |
/** | |
* List of asset types that a component can own. | |
*/ | |
_assetTypes: [ | |
'component', | |
'directive', | |
'filter' | |
], | |
/** | |
* List of lifecycle hooks. | |
*/ | |
_lifecycleHooks: [ | |
'beforeCreate', | |
'created', | |
'beforeMount', | |
'mounted', | |
'beforeUpdate', | |
'updated', | |
'beforeDestroy', | |
'destroyed', | |
'activated', | |
'deactivated' | |
], | |
/** | |
* Max circular updates allowed in a scheduler flush cycle. | |
*/ | |
_maxUpdateCount: 100 | |
}; | |
/* */ | |
/** | |
* Check if a string starts with $ or _ | |
*/ | |
function isReserved (str) { | |
var c = (str + '').charCodeAt(0); | |
return c === 0x24 || c === 0x5F | |
} | |
/** | |
* Define a property. | |
*/ | |
function def (obj, key, val, enumerable) { | |
Object.defineProperty(obj, key, { | |
value: val, | |
enumerable: !!enumerable, | |
writable: true, | |
configurable: true | |
}); | |
} | |
/** | |
* Parse simple path. | |
*/ | |
var bailRE = /[^\w.$]/; | |
function parsePath (path) { | |
if (bailRE.test(path)) { | |
return | |
} else { | |
var segments = path.split('.'); | |
return function (obj) { | |
for (var i = 0; i < segments.length; i++) { | |
if (!obj) { return } | |
obj = obj[segments[i]]; | |
} | |
return obj | |
} | |
} | |
} | |
/* */ | |
/* globals MutationObserver */ | |
// can we use __proto__? | |
var hasProto = '__proto__' in {}; | |
// Browser environment sniffing | |
var inBrowser = typeof window !== 'undefined'; | |
var UA = inBrowser && window.navigator.userAgent.toLowerCase(); | |
var isIE = UA && /msie|trident/.test(UA); | |
var isIE9 = UA && UA.indexOf('msie 9.0') > 0; | |
var isEdge = UA && UA.indexOf('edge/') > 0; | |
var isAndroid = UA && UA.indexOf('android') > 0; | |
var isIOS = UA && /iphone|ipad|ipod|ios/.test(UA); | |
// this needs to be lazy-evaled because vue may be required before | |
// vue-server-renderer can set VUE_ENV | |
var _isServer; | |
var isServerRendering = function () { | |
if (_isServer === undefined) { | |
/* istanbul ignore if */ | |
if (!inBrowser && typeof global !== 'undefined') { | |
// detect presence of vue-server-renderer and avoid | |
// Webpack shimming the process | |
_isServer = global['process'].env.VUE_ENV === 'server'; | |
} else { | |
_isServer = false; | |
} | |
} | |
return _isServer | |
}; | |
// detect devtools | |
var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__; | |
/* istanbul ignore next */ | |
function isNative (Ctor) { | |
return /native code/.test(Ctor.toString()) | |
} | |
/** | |
* Defer a task to execute it asynchronously. | |
*/ | |
var nextTick = (function () { | |
var callbacks = []; | |
var pending = false; | |
var timerFunc; | |
function nextTickHandler () { | |
pending = false; | |
var copies = callbacks.slice(0); | |
callbacks.length = 0; | |
for (var i = 0; i < copies.length; i++) { | |
copies[i](); | |
} | |
} | |
// the nextTick behavior leverages the microtask queue, which can be accessed | |
// via either native Promise.then or MutationObserver. | |
// MutationObserver has wider support, however it is seriously bugged in | |
// UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It | |
// completely stops working after triggering a few times... so, if native | |
// Promise is available, we will use it: | |
/* istanbul ignore if */ | |
if (typeof Promise !== 'undefined' && isNative(Promise)) { | |
var p = Promise.resolve(); | |
var logError = function (err) { console.error(err); }; | |
timerFunc = function () { | |
p.then(nextTickHandler).catch(logError); | |
// in problematic UIWebViews, Promise.then doesn't completely break, but | |
// it can get stuck in a weird state where callbacks are pushed into the | |
// microtask queue but the queue isn't being flushed, until the browser | |
// needs to do some other work, e.g. handle a timer. Therefore we can | |
// "force" the microtask queue to be flushed by adding an empty timer. | |
if (isIOS) { setTimeout(noop); } | |
}; | |
} else if (typeof MutationObserver !== 'undefined' && ( | |
isNative(MutationObserver) || | |
// PhantomJS and iOS 7.x | |
MutationObserver.toString() === '[object MutationObserverConstructor]' | |
)) { | |
// use MutationObserver where native Promise is not available, | |
// e.g. PhantomJS IE11, iOS7, Android 4.4 | |
var counter = 1; | |
var observer = new MutationObserver(nextTickHandler); | |
var textNode = document.createTextNode(String(counter)); | |
observer.observe(textNode, { | |
characterData: true | |
}); | |
timerFunc = function () { | |
counter = (counter + 1) % 2; | |
textNode.data = String(counter); | |
}; | |
} else { | |
// fallback to setTimeout | |
/* istanbul ignore next */ | |
timerFunc = function () { | |
setTimeout(nextTickHandler, 0); | |
}; | |
} | |
return function queueNextTick (cb, ctx) { | |
var _resolve; | |
callbacks.push(function () { | |
if (cb) { cb.call(ctx); } | |
if (_resolve) { _resolve(ctx); } | |
}); | |
if (!pending) { | |
pending = true; | |
timerFunc(); | |
} | |
if (!cb && typeof Promise !== 'undefined') { | |
return new Promise(function (resolve) { | |
_resolve = resolve; | |
}) | |
} | |
} | |
})(); | |
var _Set; | |
/* istanbul ignore if */ | |
if (typeof Set !== 'undefined' && isNative(Set)) { | |
// use native Set when available. | |
_Set = Set; | |
} else { | |
// a non-standard Set polyfill that only works with primitive keys. | |
_Set = (function () { | |
function Set () { | |
this.set = Object.create(null); | |
} | |
Set.prototype.has = function has (key) { | |
return this.set[key] === true | |
}; | |
Set.prototype.add = function add (key) { | |
this.set[key] = true; | |
}; | |
Set.prototype.clear = function clear () { | |
this.set = Object.create(null); | |
}; | |
return Set; | |
}()); | |
} | |
var warn = noop; | |
var formatComponentName; | |
{ | |
var hasConsole = typeof console !== 'undefined'; | |
warn = function (msg, vm) { | |
if (hasConsole && (!config.silent)) { | |
console.error("[Vue warn]: " + msg + " " + ( | |
vm ? formatLocation(formatComponentName(vm)) : '' | |
)); | |
} | |
}; | |
formatComponentName = function (vm) { | |
if (vm.$root === vm) { | |
return 'root instance' | |
} | |
var name = vm._isVue | |
? vm.$options.name || vm.$options._componentTag | |
: vm.name; | |
return ( | |
(name ? ("component <" + name + ">") : "anonymous component") + | |
(vm._isVue && vm.$options.__file ? (" at " + (vm.$options.__file)) : '') | |
) | |
}; | |
var formatLocation = function (str) { | |
if (str === 'anonymous component') { | |
str += " - use the \"name\" option for better debugging messages."; | |
} | |
return ("\n(found in " + str + ")") | |
}; | |
} | |
/* */ | |
var uid$1 = 0; | |
/** | |
* A dep is an observable that can have multiple | |
* directives subscribing to it. | |
*/ | |
var Dep = function Dep () { | |
this.id = uid$1++; | |
this.subs = []; | |
}; | |
Dep.prototype.addSub = function addSub (sub) { | |
this.subs.push(sub); | |
}; | |
Dep.prototype.removeSub = function removeSub (sub) { | |
remove$1(this.subs, sub); | |
}; | |
Dep.prototype.depend = function depend () { | |
if (Dep.target) { | |
Dep.target.addDep(this); | |
} | |
}; | |
Dep.prototype.notify = function notify () { | |
// stablize the subscriber list first | |
var subs = this.subs.slice(); | |
for (var i = 0, l = subs.length; i < l; i++) { | |
subs[i].update(); | |
} | |
}; | |
// the current target watcher being evaluated. | |
// this is globally unique because there could be only one | |
// watcher being evaluated at any time. | |
Dep.target = null; | |
var targetStack = []; | |
function pushTarget (_target) { | |
if (Dep.target) { targetStack.push(Dep.target); } | |
Dep.target = _target; | |
} | |
function popTarget () { | |
Dep.target = targetStack.pop(); | |
} | |
/* | |
* not type checking this file because flow doesn't play well with | |
* dynamically accessing methods on Array prototype | |
*/ | |
var arrayProto = Array.prototype; | |
var arrayMethods = Object.create(arrayProto);[ | |
'push', | |
'pop', | |
'shift', | |
'unshift', | |
'splice', | |
'sort', | |
'reverse' | |
] | |
.forEach(function (method) { | |
// cache original method | |
var original = arrayProto[method]; | |
def(arrayMethods, method, function mutator () { | |
var arguments$1 = arguments; | |
// avoid leaking arguments: | |
// http://jsperf.com/closure-with-arguments | |
var i = arguments.length; | |
var args = new Array(i); | |
while (i--) { | |
args[i] = arguments$1[i]; | |
} | |
var result = original.apply(this, args); | |
var ob = this.__ob__; | |
var inserted; | |
switch (method) { | |
case 'push': | |
inserted = args; | |
break | |
case 'unshift': | |
inserted = args; | |
break | |
case 'splice': | |
inserted = args.slice(2); | |
break | |
} | |
if (inserted) { ob.observeArray(inserted); } | |
// notify change | |
ob.dep.notify(); | |
return result | |
}); | |
}); | |
/* */ | |
var arrayKeys = Object.getOwnPropertyNames(arrayMethods); | |
/** | |
* By default, when a reactive property is set, the new value is | |
* also converted to become reactive. However when passing down props, | |
* we don't want to force conversion because the value may be a nested value | |
* under a frozen data structure. Converting it would defeat the optimization. | |
*/ | |
var observerState = { | |
shouldConvert: true, | |
isSettingProps: false | |
}; | |
/** | |
* Observer class that are attached to each observed | |
* object. Once attached, the observer converts target | |
* object's property keys into getter/setters that | |
* collect dependencies and dispatches updates. | |
*/ | |
var Observer = function Observer (value) { | |
this.value = value; | |
this.dep = new Dep(); | |
this.vmCount = 0; | |
def(value, '__ob__', this); | |
if (Array.isArray(value)) { | |
var augment = hasProto | |
? protoAugment | |
: copyAugment; | |
augment(value, arrayMethods, arrayKeys); | |
this.observeArray(value); | |
} else { | |
this.walk(value); | |
} | |
}; | |
/** | |
* Walk through each property and convert them into | |
* getter/setters. This method should only be called when | |
* value type is Object. | |
*/ | |
Observer.prototype.walk = function walk (obj) { | |
var keys = Object.keys(obj); | |
for (var i = 0; i < keys.length; i++) { | |
defineReactive$$1(obj, keys[i], obj[keys[i]]); | |
} | |
}; | |
/** | |
* Observe a list of Array items. | |
*/ | |
Observer.prototype.observeArray = function observeArray (items) { | |
for (var i = 0, l = items.length; i < l; i++) { | |
observe(items[i]); | |
} | |
}; | |
// helpers | |
/** | |
* Augment an target Object or Array by intercepting | |
* the prototype chain using __proto__ | |
*/ | |
function protoAugment (target, src) { | |
/* eslint-disable no-proto */ | |
target.__proto__ = src; | |
/* eslint-enable no-proto */ | |
} | |
/** | |
* Augment an target Object or Array by defining | |
* hidden properties. | |
*/ | |
/* istanbul ignore next */ | |
function copyAugment (target, src, keys) { | |
for (var i = 0, l = keys.length; i < l; i++) { | |
var key = keys[i]; | |
def(target, key, src[key]); | |
} | |
} | |
/** | |
* Attempt to create an observer instance for a value, | |
* returns the new observer if successfully observed, | |
* or the existing observer if the value already has one. | |
*/ | |
function observe (value, asRootData) { | |
if (!isObject(value)) { | |
return | |
} | |
var ob; | |
if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) { | |
ob = value.__ob__; | |
} else if ( | |
observerState.shouldConvert && | |
!isServerRendering() && | |
(Array.isArray(value) || isPlainObject(value)) && | |
Object.isExtensible(value) && | |
!value._isVue | |
) { | |
ob = new Observer(value); | |
} | |
if (asRootData && ob) { | |
ob.vmCount++; | |
} | |
return ob | |
} | |
/** | |
* Define a reactive property on an Object. | |
*/ | |
function defineReactive$$1 ( | |
obj, | |
key, | |
val, | |
customSetter | |
) { | |
var dep = new Dep(); | |
var property = Object.getOwnPropertyDescriptor(obj, key); | |
if (property && property.configurable === false) { | |
return | |
} | |
// cater for pre-defined getter/setters | |
var getter = property && property.get; | |
var setter = property && property.set; | |
var childOb = observe(val); | |
Object.defineProperty(obj, key, { | |
enumerable: true, | |
configurable: true, | |
get: function reactiveGetter () { | |
var value = getter ? getter.call(obj) : val; | |
if (Dep.target) { | |
dep.depend(); | |
if (childOb) { | |
childOb.dep.depend(); | |
} | |
if (Array.isArray(value)) { | |
dependArray(value); | |
} | |
} | |
return value | |
}, | |
set: function reactiveSetter (newVal) { | |
var value = getter ? getter.call(obj) : val; | |
/* eslint-disable no-self-compare */ | |
if (newVal === value || (newVal !== newVal && value !== value)) { | |
return | |
} | |
/* eslint-enable no-self-compare */ | |
if ("development" !== 'production' && customSetter) { | |
customSetter(); | |
} | |
if (setter) { | |
setter.call(obj, newVal); | |
} else { | |
val = newVal; | |
} | |
childOb = observe(newVal); | |
dep.notify(); | |
} | |
}); | |
} | |
/** | |
* Set a property on an object. Adds the new property and | |
* triggers change notification if the property doesn't | |
* already exist. | |
*/ | |
function set$1 (obj, key, val) { | |
if (Array.isArray(obj)) { | |
obj.length = Math.max(obj.length, key); | |
obj.splice(key, 1, val); | |
return val | |
} | |
if (hasOwn(obj, key)) { | |
obj[key] = val; | |
return | |
} | |
var ob = obj.__ob__; | |
if (obj._isVue || (ob && ob.vmCount)) { | |
"development" !== 'production' && warn( | |
'Avoid adding reactive properties to a Vue instance or its root $data ' + | |
'at runtime - declare it upfront in the data option.' | |
); | |
return | |
} | |
if (!ob) { | |
obj[key] = val; | |
return | |
} | |
defineReactive$$1(ob.value, key, val); | |
ob.dep.notify(); | |
return val | |
} | |
/** | |
* Delete a property and trigger change if necessary. | |
*/ | |
function del (obj, key) { | |
var ob = obj.__ob__; | |
if (obj._isVue || (ob && ob.vmCount)) { | |
"development" !== 'production' && warn( | |
'Avoid deleting properties on a Vue instance or its root $data ' + | |
'- just set it to null.' | |
); | |
return | |
} | |
if (!hasOwn(obj, key)) { | |
return | |
} | |
delete obj[key]; | |
if (!ob) { | |
return | |
} | |
ob.dep.notify(); | |
} | |
/** | |
* Collect dependencies on array elements when the array is touched, since | |
* we cannot intercept array element access like property getters. | |
*/ | |
function dependArray (value) { | |
for (var e = (void 0), i = 0, l = value.length; i < l; i++) { | |
e = value[i]; | |
e && e.__ob__ && e.__ob__.dep.depend(); | |
if (Array.isArray(e)) { | |
dependArray(e); | |
} | |
} | |
} | |
/* */ | |
/** | |
* Option overwriting strategies are functions that handle | |
* how to merge a parent option value and a child option | |
* value into the final value. | |
*/ | |
var strats = config.optionMergeStrategies; | |
/** | |
* Options with restrictions | |
*/ | |
{ | |
strats.el = strats.propsData = function (parent, child, vm, key) { | |
if (!vm) { | |
warn( | |
"option \"" + key + "\" can only be used during instance " + | |
'creation with the `new` keyword.' | |
); | |
} | |
return defaultStrat(parent, child) | |
}; | |
} | |
/** | |
* Helper that recursively merges two data objects together. | |
*/ | |
function mergeData (to, from) { | |
if (!from) { return to } | |
var key, toVal, fromVal; | |
var keys = Object.keys(from); | |
for (var i = 0; i < keys.length; i++) { | |
key = keys[i]; | |
toVal = to[key]; | |
fromVal = from[key]; | |
if (!hasOwn(to, key)) { | |
set$1(to, key, fromVal); | |
} else if (isPlainObject(toVal) && isPlainObject(fromVal)) { | |
mergeData(toVal, fromVal); | |
} | |
} | |
return to | |
} | |
/** | |
* Data | |
*/ | |
strats.data = function ( | |
parentVal, | |
childVal, | |
vm | |
) { | |
if (!vm) { | |
// in a Vue.extend merge, both should be functions | |
if (!childVal) { | |
return parentVal | |
} | |
if (typeof childVal !== 'function') { | |
"development" !== 'production' && warn( | |
'The "data" option should be a function ' + | |
'that returns a per-instance value in component ' + | |
'definitions.', | |
vm | |
); | |
return parentVal | |
} | |
if (!parentVal) { | |
return childVal | |
} | |
// when parentVal & childVal are both present, | |
// we need to return a function that returns the | |
// merged result of both functions... no need to | |
// check if parentVal is a function here because | |
// it has to be a function to pass previous merges. | |
return function mergedDataFn () { | |
return mergeData( | |
childVal.call(this), | |
parentVal.call(this) | |
) | |
} | |
} else if (parentVal || childVal) { | |
return function mergedInstanceDataFn () { | |
// instance merge | |
var instanceData = typeof childVal === 'function' | |
? childVal.call(vm) | |
: childVal; | |
var defaultData = typeof parentVal === 'function' | |
? parentVal.call(vm) | |
: undefined; | |
if (instanceData) { | |
return mergeData(instanceData, defaultData) | |
} else { | |
return defaultData | |
} | |
} | |
} | |
}; | |
/** | |
* Hooks and param attributes are merged as arrays. | |
*/ | |
function mergeHook ( | |
parentVal, | |
childVal | |
) { | |
return childVal | |
? parentVal | |
? parentVal.concat(childVal) | |
: Array.isArray(childVal) | |
? childVal | |
: [childVal] | |
: parentVal | |
} | |
config._lifecycleHooks.forEach(function (hook) { | |
strats[hook] = mergeHook; | |
}); | |
/** | |
* Assets | |
* | |
* When a vm is present (instance creation), we need to do | |
* a three-way merge between constructor options, instance | |
* options and parent options. | |
*/ | |
function mergeAssets (parentVal, childVal) { | |
var res = Object.create(parentVal || null); | |
return childVal | |
? extend(res, childVal) | |
: res | |
} | |
config._assetTypes.forEach(function (type) { | |
strats[type + 's'] = mergeAssets; | |
}); | |
/** | |
* Watchers. | |
* | |
* Watchers hashes should not overwrite one | |
* another, so we merge them as arrays. | |
*/ | |
strats.watch = function (parentVal, childVal) { | |
/* istanbul ignore if */ | |
if (!childVal) { return parentVal } | |
if (!parentVal) { return childVal } | |
var ret = {}; | |
extend(ret, parentVal); | |
for (var key in childVal) { | |
var parent = ret[key]; | |
var child = childVal[key]; | |
if (parent && !Array.isArray(parent)) { | |
parent = [parent]; | |
} | |
ret[key] = parent | |
? parent.concat(child) | |
: [child]; | |
} | |
return ret | |
}; | |
/** | |
* Other object hashes. | |
*/ | |
strats.props = | |
strats.methods = | |
strats.computed = function (parentVal, childVal) { | |
if (!childVal) { return parentVal } | |
if (!parentVal) { return childVal } | |
var ret = Object.create(null); | |
extend(ret, parentVal); | |
extend(ret, childVal); | |
return ret | |
}; | |
/** | |
* Default strategy. | |
*/ | |
var defaultStrat = function (parentVal, childVal) { | |
return childVal === undefined | |
? parentVal | |
: childVal | |
}; | |
/** | |
* Validate component names | |
*/ | |
function checkComponents (options) { | |
for (var key in options.components) { | |
var lower = key.toLowerCase(); | |
if (isBuiltInTag(lower) || config.isReservedTag(lower)) { | |
warn( | |
'Do not use built-in or reserved HTML elements as component ' + | |
'id: ' + key | |
); | |
} | |
} | |
} | |
/** | |
* Ensure all props option syntax are normalized into the | |
* Object-based format. | |
*/ | |
function normalizeProps (options) { | |
var props = options.props; | |
if (!props) { return } | |
var res = {}; | |
var i, val, name; | |
if (Array.isArray(props)) { | |
i = props.length; | |
while (i--) { | |
val = props[i]; | |
if (typeof val === 'string') { | |
name = camelize(val); | |
res[name] = { type: null }; | |
} else { | |
warn('props must be strings when using array syntax.'); | |
} | |
} | |
} else if (isPlainObject(props)) { | |
for (var key in props) { | |
val = props[key]; | |
name = camelize(key); | |
res[name] = isPlainObject(val) | |
? val | |
: { type: val }; | |
} | |
} | |
options.props = res; | |
} | |
/** | |
* Normalize raw function directives into object format. | |
*/ | |
function normalizeDirectives (options) { | |
var dirs = options.directives; | |
if (dirs) { | |
for (var key in dirs) { | |
var def = dirs[key]; | |
if (typeof def === 'function') { | |
dirs[key] = { bind: def, update: def }; | |
} | |
} | |
} | |
} | |
/** | |
* Merge two option objects into a new one. | |
* Core utility used in both instantiation and inheritance. | |
*/ | |
function mergeOptions ( | |
parent, | |
child, | |
vm | |
) { | |
{ | |
checkComponents(child); | |
} | |
normalizeProps(child); | |
normalizeDirectives(child); | |
var extendsFrom = child.extends; | |
if (extendsFrom) { | |
parent = typeof extendsFrom === 'function' | |
? mergeOptions(parent, extendsFrom.options, vm) | |
: mergeOptions(parent, extendsFrom, vm); | |
} | |
if (child.mixins) { | |
for (var i = 0, l = child.mixins.length; i < l; i++) { | |
var mixin = child.mixins[i]; | |
if (mixin.prototype instanceof Vue$3) { | |
mixin = mixin.options; | |
} | |
parent = mergeOptions(parent, mixin, vm); | |
} | |
} | |
var options = {}; | |
var key; | |
for (key in parent) { | |
mergeField(key); | |
} | |
for (key in child) { | |
if (!hasOwn(parent, key)) { | |
mergeField(key); | |
} | |
} | |
function mergeField (key) { | |
var strat = strats[key] || defaultStrat; | |
options[key] = strat(parent[key], child[key], vm, key); | |
} | |
return options | |
} | |
/** | |
* Resolve an asset. | |
* This function is used because child instances need access | |
* to assets defined in its ancestor chain. | |
*/ | |
function resolveAsset ( | |
options, | |
type, | |
id, | |
warnMissing | |
) { | |
/* istanbul ignore if */ | |
if (typeof id !== 'string') { | |
return | |
} | |
var assets = options[type]; | |
// check local registration variations first | |
if (hasOwn(assets, id)) { return assets[id] } | |
var camelizedId = camelize(id); | |
if (hasOwn(assets, camelizedId)) { return assets[camelizedId] } | |
var PascalCaseId = capitalize(camelizedId); | |
if (hasOwn(assets, PascalCaseId)) { return assets[PascalCaseId] } | |
// fallback to prototype chain | |
var res = assets[id] || assets[camelizedId] || assets[PascalCaseId]; | |
if ("development" !== 'production' && warnMissing && !res) { | |
warn( | |
'Failed to resolve ' + type.slice(0, -1) + ': ' + id, | |
options | |
); | |
} | |
return res | |
} | |
/* */ | |
function validateProp ( | |
key, | |
propOptions, | |
propsData, | |
vm | |
) { | |
var prop = propOptions[key]; | |
var absent = !hasOwn(propsData, key); | |
var value = propsData[key]; | |
// handle boolean props | |
if (isType(Boolean, prop.type)) { | |
if (absent && !hasOwn(prop, 'default')) { | |
value = false; | |
} else if (!isType(String, prop.type) && (value === '' || value === hyphenate(key))) { | |
value = true; | |
} | |
} | |
// check default value | |
if (value === undefined) { | |
value = getPropDefaultValue(vm, prop, key); | |
// since the default value is a fresh copy, | |
// make sure to observe it. | |
var prevShouldConvert = observerState.shouldConvert; | |
observerState.shouldConvert = true; | |
observe(value); | |
observerState.shouldConvert = prevShouldConvert; | |
} | |
{ | |
assertProp(prop, key, value, vm, absent); | |
} | |
return value | |
} | |
/** | |
* Get the default value of a prop. | |
*/ | |
function getPropDefaultValue (vm, prop, key) { | |
// no default, return undefined | |
if (!hasOwn(prop, 'default')) { | |
return undefined | |
} | |
var def = prop.default; | |
// warn against non-factory defaults for Object & Array | |
if (isObject(def)) { | |
"development" !== 'production' && warn( | |
'Invalid default value for prop "' + key + '": ' + | |
'Props with type Object/Array must use a factory function ' + | |
'to return the default value.', | |
vm | |
); | |
} | |
// the raw prop value was also undefined from previous render, | |
// return previous default value to avoid unnecessary watcher trigger | |
if (vm && vm.$options.propsData && | |
vm.$options.propsData[key] === undefined && | |
vm[key] !== undefined) { | |
return vm[key] | |
} | |
// call factory function for non-Function types | |
return typeof def === 'function' && prop.type !== Function | |
? def.call(vm) | |
: def | |
} | |
/** | |
* Assert whether a prop is valid. | |
*/ | |
function assertProp ( | |
prop, | |
name, | |
value, | |
vm, | |
absent | |
) { | |
if (prop.required && absent) { | |
warn( | |
'Missing required prop: "' + name + '"', | |
vm | |
); | |
return | |
} | |
if (value == null && !prop.required) { | |
return | |
} | |
var type = prop.type; | |
var valid = !type || type === true; | |
var expectedTypes = []; | |
if (type) { | |
if (!Array.isArray(type)) { | |
type = [type]; | |
} | |
for (var i = 0; i < type.length && !valid; i++) { | |
var assertedType = assertType(value, type[i]); | |
expectedTypes.push(assertedType.expectedType || ''); | |
valid = assertedType.valid; | |
} | |
} | |
if (!valid) { | |
warn( | |
'Invalid prop: type check failed for prop "' + name + '".' + | |
' Expected ' + expectedTypes.map(capitalize).join(', ') + | |
', got ' + Object.prototype.toString.call(value).slice(8, -1) + '.', | |
vm | |
); | |
return | |
} | |
var validator = prop.validator; | |
if (validator) { | |
if (!validator(value)) { | |
warn( | |
'Invalid prop: custom validator check failed for prop "' + name + '".', | |
vm | |
); | |
} | |
} | |
} | |
/** | |
* Assert the type of a value | |
*/ | |
function assertType (value, type) { | |
var valid; | |
var expectedType = getType(type); | |
if (expectedType === 'String') { | |
valid = typeof value === (expectedType = 'string'); | |
} else if (expectedType === 'Number') { | |
valid = typeof value === (expectedType = 'number'); | |
} else if (expectedType === 'Boolean') { | |
valid = typeof value === (expectedType = 'boolean'); | |
} else if (expectedType === 'Function') { | |
valid = typeof value === (expectedType = 'function'); | |
} else if (expectedType === 'Object') { | |
valid = isPlainObject(value); | |
} else if (expectedType === 'Array') { | |
valid = Array.isArray(value); | |
} else { | |
valid = value instanceof type; | |
} | |
return { | |
valid: valid, | |
expectedType: expectedType | |
} | |
} | |
/** | |
* Use function string name to check built-in types, | |
* because a simple equality check will fail when running | |
* across different vms / iframes. | |
*/ | |
function getType (fn) { | |
var match = fn && fn.toString().match(/^\s*function (\w+)/); | |
return match && match[1] | |
} | |
function isType (type, fn) { | |
if (!Array.isArray(fn)) { | |
return getType(fn) === getType(type) | |
} | |
for (var i = 0, len = fn.length; i < len; i++) { | |
if (getType(fn[i]) === getType(type)) { | |
return true | |
} | |
} | |
/* istanbul ignore next */ | |
return false | |
} | |
var util = Object.freeze({ | |
defineReactive: defineReactive$$1, | |
_toString: _toString, | |
toNumber: toNumber, | |
makeMap: makeMap, | |
isBuiltInTag: isBuiltInTag, | |
remove: remove$1, | |
hasOwn: hasOwn, | |
isPrimitive: isPrimitive, | |
cached: cached, | |
camelize: camelize, | |
capitalize: capitalize, | |
hyphenate: hyphenate, | |
bind: bind$1, | |
toArray: toArray, | |
extend: extend, | |
isObject: isObject, | |
isPlainObject: isPlainObject, | |
toObject: toObject, | |
noop: noop, | |
no: no, | |
identity: identity, | |
genStaticKeys: genStaticKeys, | |
looseEqual: looseEqual, | |
looseIndexOf: looseIndexOf, | |
isReserved: isReserved, | |
def: def, | |
parsePath: parsePath, | |
hasProto: hasProto, | |
inBrowser: inBrowser, | |
UA: UA, | |
isIE: isIE, | |
isIE9: isIE9, | |
isEdge: isEdge, | |
isAndroid: isAndroid, | |
isIOS: isIOS, | |
isServerRendering: isServerRendering, | |
devtools: devtools, | |
nextTick: nextTick, | |
get _Set () { return _Set; }, | |
mergeOptions: mergeOptions, | |
resolveAsset: resolveAsset, | |
get warn () { return warn; }, | |
get formatComponentName () { return formatComponentName; }, | |
validateProp: validateProp | |
}); | |
/* not type checking this file because flow doesn't play well with Proxy */ | |
var initProxy; | |
{ | |
var allowedGlobals = makeMap( | |
'Infinity,undefined,NaN,isFinite,isNaN,' + | |
'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' + | |
'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' + | |
'require' // for Webpack/Browserify | |
); | |
var warnNonPresent = function (target, key) { | |
warn( | |
"Property or method \"" + key + "\" is not defined on the instance but " + | |
"referenced during render. Make sure to declare reactive data " + | |
"properties in the data option.", | |
target | |
); | |
}; | |
var hasProxy = | |
typeof Proxy !== 'undefined' && | |
Proxy.toString().match(/native code/); | |
if (hasProxy) { | |
var isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta'); | |
config.keyCodes = new Proxy(config.keyCodes, { | |
set: function set (target, key, value) { | |
if (isBuiltInModifier(key)) { | |
warn(("Avoid overwriting built-in modifier in config.keyCodes: ." + key)); | |
return false | |
} else { | |
target[key] = value; | |
return true | |
} | |
} | |
}); | |
} | |
var hasHandler = { | |
has: function has (target, key) { | |
var has = key in target; | |
var isAllowed = allowedGlobals(key) || key.charAt(0) === '_'; | |
if (!has && !isAllowed) { | |
warnNonPresent(target, key); | |
} | |
return has || !isAllowed | |
} | |
}; | |
var getHandler = { | |
get: function get (target, key) { | |
if (typeof key === 'string' && !(key in target)) { | |
warnNonPresent(target, key); | |
} | |
return target[key] | |
} | |
}; | |
initProxy = function initProxy (vm) { | |
if (hasProxy) { | |
// determine which proxy handler to use | |
var options = vm.$options; | |
var handlers = options.render && options.render._withStripped | |
? getHandler | |
: hasHandler; | |
vm._renderProxy = new Proxy(vm, handlers); | |
} else { | |
vm._renderProxy = vm; | |
} | |
}; | |
} | |
/* */ | |
var VNode = function VNode ( | |
tag, | |
data, | |
children, | |
text, | |
elm, | |
context, | |
componentOptions | |
) { | |
this.tag = tag; | |
this.data = data; | |
this.children = children; | |
this.text = text; | |
this.elm = elm; | |
this.ns = undefined; | |
this.context = context; | |
this.functionalContext = undefined; | |
this.key = data && data.key; | |
this.componentOptions = componentOptions; | |
this.componentInstance = undefined; | |
this.parent = undefined; | |
this.raw = false; | |
this.isStatic = false; | |
this.isRootInsert = true; | |
this.isComment = false; | |
this.isCloned = false; | |
this.isOnce = false; | |
}; | |
var prototypeAccessors = { child: {} }; | |
// DEPRECATED: alias for componentInstance for backwards compat. | |
/* istanbul ignore next */ | |
prototypeAccessors.child.get = function () { | |
return this.componentInstance | |
}; | |
Object.defineProperties( VNode.prototype, prototypeAccessors ); | |
var createEmptyVNode = function () { | |
var node = new VNode(); | |
node.text = ''; | |
node.isComment = true; | |
return node | |
}; | |
function createTextVNode (val) { | |
return new VNode(undefined, undefined, undefined, String(val)) | |
} | |
// optimized shallow clone | |
// used for static nodes and slot nodes because they may be reused across | |
// multiple renders, cloning them avoids errors when DOM manipulations rely | |
// on their elm reference. | |
function cloneVNode (vnode) { | |
var cloned = new VNode( | |
vnode.tag, | |
vnode.data, | |
vnode.children, | |
vnode.text, | |
vnode.elm, | |
vnode.context, | |
vnode.componentOptions | |
); | |
cloned.ns = vnode.ns; | |
cloned.isStatic = vnode.isStatic; | |
cloned.key = vnode.key; | |
cloned.isCloned = true; | |
return cloned | |
} | |
function cloneVNodes (vnodes) { | |
var res = new Array(vnodes.length); | |
for (var i = 0; i < vnodes.length; i++) { | |
res[i] = cloneVNode(vnodes[i]); | |
} | |
return res | |
} | |
/* */ | |
var hooks = { init: init, prepatch: prepatch, insert: insert, destroy: destroy$1 }; | |
var hooksToMerge = Object.keys(hooks); | |
function createComponent ( | |
Ctor, | |
data, | |
context, | |
children, | |
tag | |
) { | |
if (!Ctor) { | |
return | |
} | |
var baseCtor = context.$options._base; | |
if (isObject(Ctor)) { | |
Ctor = baseCtor.extend(Ctor); | |
} | |
if (typeof Ctor !== 'function') { | |
{ | |
warn(("Invalid Component definition: " + (String(Ctor))), context); | |
} | |
return | |
} | |
// async component | |
if (!Ctor.cid) { | |
if (Ctor.resolved) { | |
Ctor = Ctor.resolved; | |
} else { | |
Ctor = resolveAsyncComponent(Ctor, baseCtor, function () { | |
// it's ok to queue this on every render because | |
// $forceUpdate is buffered by the scheduler. | |
context.$forceUpdate(); | |
}); | |
if (!Ctor) { | |
// return nothing if this is indeed an async component | |
// wait for the callback to trigger parent update. | |
return | |
} | |
} | |
} | |
// resolve constructor options in case global mixins are applied after | |
// component constructor creation | |
resolveConstructorOptions(Ctor); | |
data = data || {}; | |
// extract props | |
var propsData = extractProps(data, Ctor); | |
// functional component | |
if (Ctor.options.functional) { | |
return createFunctionalComponent(Ctor, propsData, data, context, children) | |
} | |
// extract listeners, since these needs to be treated as | |
// child component listeners instead of DOM listeners | |
var listeners = data.on; | |
// replace with listeners with .native modifier | |
data.on = data.nativeOn; | |
if (Ctor.options.abstract) { | |
// abstract components do not keep anything | |
// other than props & listeners | |
data = {}; | |
} | |
// merge component management hooks onto the placeholder node | |
mergeHooks(data); | |
// return a placeholder vnode | |
var name = Ctor.options.name || tag; | |
var vnode = new VNode( | |
("vue-component-" + (Ctor.cid) + (name ? ("-" + name) : '')), | |
data, undefined, undefined, undefined, context, | |
{ Ctor: Ctor, propsData: propsData, listeners: listeners, tag: tag, children: children } | |
); | |
return vnode | |
} | |
function createFunctionalComponent ( | |
Ctor, | |
propsData, | |
data, | |
context, | |
children | |
) { | |
var props = {}; | |
var propOptions = Ctor.options.props; | |
if (propOptions) { | |
for (var key in propOptions) { | |
props[key] = validateProp(key, propOptions, propsData); | |
} | |
} | |
// ensure the createElement function in functional components | |
// gets a unique context - this is necessary for correct named slot check | |
var _context = Object.create(context); | |
var h = function (a, b, c, d) { return createElement(_context, a, b, c, d, true); }; | |
var vnode = Ctor.options.render.call(null, h, { | |
props: props, | |
data: data, | |
parent: context, | |
children: children, | |
slots: function () { return resolveSlots(children, context); } | |
}); | |
if (vnode instanceof VNode) { | |
vnode.functionalContext = context; | |
if (data.slot) { | |
(vnode.data || (vnode.data = {})).slot = data.slot; | |
} | |
} | |
return vnode | |
} | |
function createComponentInstanceForVnode ( | |
vnode, // we know it's MountedComponentVNode but flow doesn't | |
parent, // activeInstance in lifecycle state | |
parentElm, | |
refElm | |
) { | |
var vnodeComponentOptions = vnode.componentOptions; | |
var options = { | |
_isComponent: true, | |
parent: parent, | |
propsData: vnodeComponentOptions.propsData, | |
_componentTag: vnodeComponentOptions.tag, | |
_parentVnode: vnode, | |
_parentListeners: vnodeComponentOptions.listeners, | |
_renderChildren: vnodeComponentOptions.children, | |
_parentElm: parentElm || null, | |
_refElm: refElm || null | |
}; | |
// check inline-template render functions | |
var inlineTemplate = vnode.data.inlineTemplate; | |
if (inlineTemplate) { | |
options.render = inlineTemplate.render; | |
options.staticRenderFns = inlineTemplate.staticRenderFns; | |
} | |
return new vnodeComponentOptions.Ctor(options) | |
} | |
function init ( | |
vnode, | |
hydrating, | |
parentElm, | |
refElm | |
) { | |
if (!vnode.componentInstance || vnode.componentInstance._isDestroyed) { | |
var child = vnode.componentInstance = createComponentInstanceForVnode( | |
vnode, | |
activeInstance, | |
parentElm, | |
refElm | |
); | |
child.$mount(hydrating ? vnode.elm : undefined, hydrating); | |
} else if (vnode.data.keepAlive) { | |
// kept-alive components, treat as a patch | |
var mountedNode = vnode; // work around flow | |
prepatch(mountedNode, mountedNode); | |
} | |
} | |
function prepatch ( | |
oldVnode, | |
vnode | |
) { | |
var options = vnode.componentOptions; | |
var child = vnode.componentInstance = oldVnode.componentInstance; | |
child._updateFromParent( | |
options.propsData, // updated props | |
options.listeners, // updated listeners | |
vnode, // new parent vnode | |
options.children // new children | |
); | |
} | |
function insert (vnode) { | |
if (!vnode.componentInstance._isMounted) { | |
vnode.componentInstance._isMounted = true; | |
callHook(vnode.componentInstance, 'mounted'); | |
} | |
if (vnode.data.keepAlive) { | |
vnode.componentInstance._inactive = false; | |
callHook(vnode.componentInstance, 'activated'); | |
} | |
} | |
function destroy$1 (vnode) { | |
if (!vnode.componentInstance._isDestroyed) { | |
if (!vnode.data.keepAlive) { | |
vnode.componentInstance.$destroy(); | |
} else { | |
vnode.componentInstance._inactive = true; | |
callHook(vnode.componentInstance, 'deactivated'); | |
} | |
} | |
} | |
function resolveAsyncComponent ( | |
factory, | |
baseCtor, | |
cb | |
) { | |
if (factory.requested) { | |
// pool callbacks | |
factory.pendingCallbacks.push(cb); | |
} else { | |
factory.requested = true; | |
var cbs = factory.pendingCallbacks = [cb]; | |
var sync = true; | |
var resolve = function (res) { | |
if (isObject(res)) { | |
res = baseCtor.extend(res); | |
} | |
// cache resolved | |
factory.resolved = res; | |
// invoke callbacks only if this is not a synchronous resolve | |
// (async resolves are shimmed as synchronous during SSR) | |
if (!sync) { | |
for (var i = 0, l = cbs.length; i < l; i++) { | |
cbs[i](res); | |
} | |
} | |
}; | |
var reject = function (reason) { | |
"development" !== 'production' && warn( | |
"Failed to resolve async component: " + (String(factory)) + | |
(reason ? ("\nReason: " + reason) : '') | |
); | |
}; | |
var res = factory(resolve, reject); | |
// handle promise | |
if (res && typeof res.then === 'function' && !factory.resolved) { | |
res.then(resolve, reject); | |
} | |
sync = false; | |
// return in case resolved synchronously | |
return factory.resolved | |
} | |
} | |
function extractProps (data, Ctor) { | |
// we are only extracting raw values here. | |
// validation and default values are handled in the child | |
// component itself. | |
var propOptions = Ctor.options.props; | |
if (!propOptions) { | |
return | |
} | |
var res = {}; | |
var attrs = data.attrs; | |
var props = data.props; | |
var domProps = data.domProps; | |
if (attrs || props || domProps) { | |
for (var key in propOptions) { | |
var altKey = hyphenate(key); | |
checkProp(res, props, key, altKey, true) || | |
checkProp(res, attrs, key, altKey) || | |
checkProp(res, domProps, key, altKey); | |
} | |
} | |
return res | |
} | |
function checkProp ( | |
res, | |
hash, | |
key, | |
altKey, | |
preserve | |
) { | |
if (hash) { | |
if (hasOwn(hash, key)) { | |
res[key] = hash[key]; | |
if (!preserve) { | |
delete hash[key]; | |
} | |
return true | |
} else if (hasOwn(hash, altKey)) { | |
res[key] = hash[altKey]; | |
if (!preserve) { | |
delete hash[altKey]; | |
} | |
return true | |
} | |
} | |
return false | |
} | |
function mergeHooks (data) { | |
if (!data.hook) { | |
data.hook = {}; | |
} | |
for (var i = 0; i < hooksToMerge.length; i++) { | |
var key = hooksToMerge[i]; | |
var fromParent = data.hook[key]; | |
var ours = hooks[key]; | |
data.hook[key] = fromParent ? mergeHook$1(ours, fromParent) : ours; | |
} | |
} | |
function mergeHook$1 (one, two) { | |
return function (a, b, c, d) { | |
one(a, b, c, d); | |
two(a, b, c, d); | |
} | |
} | |
/* */ | |
function mergeVNodeHook (def, hookKey, hook, key) { | |
key = key + hookKey; | |
var injectedHash = def.__injected || (def.__injected = {}); | |
if (!injectedHash[key]) { | |
injectedHash[key] = true; | |
var oldHook = def[hookKey]; | |
if (oldHook) { | |
def[hookKey] = function () { | |
oldHook.apply(this, arguments); | |
hook.apply(this, arguments); | |
}; | |
} else { | |
def[hookKey] = hook; | |
} | |
} | |
} | |
/* */ | |
var normalizeEvent = cached(function (name) { | |
var once = name.charAt(0) === '~'; // Prefixed last, checked first | |
name = once ? name.slice(1) : name; | |
var capture = name.charAt(0) === '!'; | |
name = capture ? name.slice(1) : name; | |
return { | |
name: name, | |
once: once, | |
capture: capture | |
} | |
}); | |
function createEventHandle (fn) { | |
var handle = { | |
fn: fn, | |
invoker: function () { | |
var arguments$1 = arguments; | |
var fn = handle.fn; | |
if (Array.isArray(fn)) { | |
for (var i = 0; i < fn.length; i++) { | |
fn[i].apply(null, arguments$1); | |
} | |
} else { | |
fn.apply(null, arguments); | |
} | |
} | |
}; | |
return handle | |
} | |
function updateListeners ( | |
on, | |
oldOn, | |
add, | |
remove$$1, | |
vm | |
) { | |
var name, cur, old, event; | |
for (name in on) { | |
cur = on[name]; | |
old = oldOn[name]; | |
event = normalizeEvent(name); | |
if (!cur) { | |
"development" !== 'production' && warn( | |
"Invalid handler for event \"" + (event.name) + "\": got " + String(cur), | |
vm | |
); | |
} else if (!old) { | |
if (!cur.invoker) { | |
cur = on[name] = createEventHandle(cur); | |
} | |
add(event.name, cur.invoker, event.once, event.capture); | |
} else if (cur !== old) { | |
old.fn = cur; | |
on[name] = old; | |
} | |
} | |
for (name in oldOn) { | |
if (!on[name]) { | |
event = normalizeEvent(name); | |
remove$$1(event.name, oldOn[name].invoker, event.capture); | |
} | |
} | |
} | |
/* */ | |
// The template compiler attempts to minimize the need for normalization by | |
// statically analyzing the template at compile time. | |
// | |
// For plain HTML markup, normalization can be completely skipped because the | |
// generated render function is guaranteed to return Array<VNode>. There are | |
// two cases where extra normalization is needed: | |
// 1. When the children contains components - because a functional component | |
// may return an Array instead of a single root. In this case, just a simple | |
// nomralization is needed - if any child is an Array, we flatten the whole | |
// thing with Array.prototype.concat. It is guaranteed to be only 1-level deep | |
// because functional components already normalize their own children. | |
function simpleNormalizeChildren (children) { | |
for (var i = 0; i < children.length; i++) { | |
if (Array.isArray(children[i])) { | |
return Array.prototype.concat.apply([], children) | |
} | |
} | |
return children | |
} | |
// 2. When the children contains constrcuts that always generated nested Arrays, | |
// e.g. <template>, <slot>, v-for, or when the children is provided by user | |
// with hand-written render functions / JSX. In such cases a full normalization | |
// is needed to cater to all possible types of children values. | |
function normalizeChildren (children) { | |
return isPrimitive(children) | |
? [createTextVNode(children)] | |
: Array.isArray(children) | |
? normalizeArrayChildren(children) | |
: undefined | |
} | |
function normalizeArrayChildren (children, nestedIndex) { | |
var res = []; | |
var i, c, last; | |
for (i = 0; i < children.length; i++) { | |
c = children[i]; | |
if (c == null || typeof c === 'boolean') { continue } | |
last = res[res.length - 1]; | |
// nested | |
if (Array.isArray(c)) { | |
res.push.apply(res, normalizeArrayChildren(c, ((nestedIndex || '') + "_" + i))); | |
} else if (isPrimitive(c)) { | |
if (last && last.text) { | |
last.text += String(c); | |
} else if (c !== '') { | |
// convert primitive to vnode | |
res.push(createTextVNode(c)); | |
} | |
} else { | |
if (c.text && last && last.text) { | |
res[res.length - 1] = createTextVNode(last.text + c.text); | |
} else { | |
// default key for nested array children (likely generated by v-for) | |
if (c.tag && c.key == null && nestedIndex != null) { | |
c.key = "__vlist" + nestedIndex + "_" + i + "__"; | |
} | |
res.push(c); | |
} | |
} | |
} | |
return res | |
} | |
/* */ | |
function getFirstComponentChild (children) { | |
return children && children.filter(function (c) { return c && c.componentOptions; })[0] | |
} | |
/* */ | |
var SIMPLE_NORMALIZE = 1; | |
var ALWAYS_NORMALIZE = 2; | |
// wrapper function for providing a more flexible interface | |
// without getting yelled at by flow | |
function createElement ( | |
context, | |
tag, | |
data, | |
children, | |
normalizationType, | |
alwaysNormalize | |
) { | |
if (Array.isArray(data) || isPrimitive(data)) { | |
normalizationType = children; | |
children = data; | |
data = undefined; | |
} | |
if (alwaysNormalize) { normalizationType = ALWAYS_NORMALIZE; } | |
return _createElement(context, tag, data, children, normalizationType) | |
} | |
function _createElement ( | |
context, | |
tag, | |
data, | |
children, | |
normalizationType | |
) { | |
if (data && data.__ob__) { | |
"development" !== 'production' && warn( | |
"Avoid using observed data object as vnode data: " + (JSON.stringify(data)) + "\n" + | |
'Always create fresh vnode data objects in each render!', | |
context | |
); | |
return createEmptyVNode() | |
} | |
if (!tag) { | |
// in case of component :is set to falsy value | |
return createEmptyVNode() | |
} | |
// support single function children as default scoped slot | |
if (Array.isArray(children) && | |
typeof children[0] === 'function') { | |
data = data || {}; | |
data.scopedSlots = { default: children[0] }; | |
children.length = 0; | |
} | |
if (normalizationType === ALWAYS_NORMALIZE) { | |
children = normalizeChildren(children); | |
} else if (normalizationType === SIMPLE_NORMALIZE) { | |
children = simpleNormalizeChildren(children); | |
} | |
var vnode, ns; | |
if (typeof tag === 'string') { | |
var Ctor; | |
ns = config.getTagNamespace(tag); | |
if (config.isReservedTag(tag)) { | |
// platform built-in elements | |
vnode = new VNode( | |
config.parsePlatformTagName(tag), data, children, | |
undefined, undefined, context | |
); | |
} else if ((Ctor = resolveAsset(context.$options, 'components', tag))) { | |
// component | |
vnode = createComponent(Ctor, data, context, children, tag); | |
} else { | |
// unknown or unlisted namespaced elements | |
// check at runtime because it may get assigned a namespace when its | |
// parent normalizes children | |
vnode = new VNode( | |
tag, data, children, | |
undefined, undefined, context | |
); | |
} | |
} else { | |
// direct component options / constructor | |
vnode = createComponent(tag, data, context, children); | |
} | |
if (vnode) { | |
if (ns) { applyNS(vnode, ns); } | |
return vnode | |
} else { | |
return createEmptyVNode() | |
} | |
} | |
function applyNS (vnode, ns) { | |
vnode.ns = ns; | |
if (vnode.tag === 'foreignObject') { | |
// use default namespace inside foreignObject | |
return | |
} | |
if (vnode.children) { | |
for (var i = 0, l = vnode.children.length; i < l; i++) { | |
var child = vnode.children[i]; | |
if (child.tag && !child.ns) { | |
applyNS(child, ns); | |
} | |
} | |
} | |
} | |
/* */ | |
function initRender (vm) { | |
vm.$vnode = null; // the placeholder node in parent tree | |
vm._vnode = null; // the root of the child tree | |
vm._staticTrees = null; | |
var parentVnode = vm.$options._parentVnode; | |
var renderContext = parentVnode && parentVnode.context; | |
vm.$slots = resolveSlots(vm.$options._renderChildren, renderContext); | |
vm.$scopedSlots = {}; | |
// bind the createElement fn to this instance | |
// so that we get proper render context inside it. | |
// args order: tag, data, children, normalizationType, alwaysNormalize | |
// internal version is used by render functions compiled from templates | |
vm._c = function (a, b, c, d) { return createElement(vm, a, b, c, d, false); }; | |
// normalization is always applied for the public version, used in | |
// user-written render functions. | |
vm.$createElement = function (a, b, c, d) { return createElement(vm, a, b, c, d, true); }; | |
} | |
function renderMixin (Vue) { | |
Vue.prototype.$nextTick = function (fn) { | |
return nextTick(fn, this) | |
}; | |
Vue.prototype._render = function () { | |
var vm = this; | |
var ref = vm.$options; | |
var render = ref.render; | |
var staticRenderFns = ref.staticRenderFns; | |
var _parentVnode = ref._parentVnode; | |
if (vm._isMounted) { | |
// clone slot nodes on re-renders | |
for (var key in vm.$slots) { | |
vm.$slots[key] = cloneVNodes(vm.$slots[key]); | |
} | |
} | |
if (_parentVnode && _parentVnode.data.scopedSlots) { | |
vm.$scopedSlots = _parentVnode.data.scopedSlots; | |
} | |
if (staticRenderFns && !vm._staticTrees) { | |
vm._staticTrees = []; | |
} | |
// set parent vnode. this allows render functions to have access | |
// to the data on the placeholder node. | |
vm.$vnode = _parentVnode; | |
// render self | |
var vnode; | |
try { | |
vnode = render.call(vm._renderProxy, vm.$createElement); | |
} catch (e) { | |
/* istanbul ignore else */ | |
if (config.errorHandler) { | |
config.errorHandler.call(null, e, vm); | |
} else { | |
{ | |
warn(("Error when rendering " + (formatComponentName(vm)) + ":")); | |
} | |
throw e | |
} | |
// return previous vnode to prevent render error causing blank component | |
vnode = vm._vnode; | |
} | |
// return empty vnode in case the render function errored out | |
if (!(vnode instanceof VNode)) { | |
if ("development" !== 'production' && Array.isArray(vnode)) { | |
warn( | |
'Multiple root nodes returned from render function. Render function ' + | |
'should return a single root node.', | |
vm | |
); | |
} | |
vnode = createEmptyVNode(); | |
} | |
// set parent | |
vnode.parent = _parentVnode; | |
return vnode | |
}; | |
// toString for mustaches | |
Vue.prototype._s = _toString; | |
// convert text to vnode | |
Vue.prototype._v = createTextVNode; | |
// number conversion | |
Vue.prototype._n = toNumber; | |
// empty vnode | |
Vue.prototype._e = createEmptyVNode; | |
// loose equal | |
Vue.prototype._q = looseEqual; | |
// loose indexOf | |
Vue.prototype._i = looseIndexOf; | |
// render static tree by index | |
Vue.prototype._m = function renderStatic ( | |
index, | |
isInFor | |
) { | |
var tree = this._staticTrees[index]; | |
// if has already-rendered static tree and not inside v-for, | |
// we can reuse the same tree by doing a shallow clone. | |
if (tree && !isInFor) { | |
return Array.isArray(tree) | |
? cloneVNodes(tree) | |
: cloneVNode(tree) | |
} | |
// otherwise, render a fresh tree. | |
tree = this._staticTrees[index] = this.$options.staticRenderFns[index].call(this._renderProxy); | |
markStatic(tree, ("__static__" + index), false); | |
return tree | |
}; | |
// mark node as static (v-once) | |
Vue.prototype._o = function markOnce ( | |
tree, | |
index, | |
key | |
) { | |
markStatic(tree, ("__once__" + index + (key ? ("_" + key) : "")), true); | |
return tree | |
}; | |
function markStatic (tree, key, isOnce) { | |
if (Array.isArray(tree)) { | |
for (var i = 0; i < tree.length; i++) { | |
if (tree[i] && typeof tree[i] !== 'string') { | |
markStaticNode(tree[i], (key + "_" + i), isOnce); | |
} | |
} | |
} else { | |
markStaticNode(tree, key, isOnce); | |
} | |
} | |
function markStaticNode (node, key, isOnce) { | |
node.isStatic = true; | |
node.key = key; | |
node.isOnce = isOnce; | |
} | |
// filter resolution helper | |
Vue.prototype._f = function resolveFilter (id) { | |
return resolveAsset(this.$options, 'filters', id, true) || identity | |
}; | |
// render v-for | |
Vue.prototype._l = function renderList ( | |
val, | |
render | |
) { | |
var ret, i, l, keys, key; | |
if (Array.isArray(val) || typeof val === 'string') { | |
ret = new Array(val.length); | |
for (i = 0, l = val.length; i < l; i++) { | |
ret[i] = render(val[i], i); | |
} | |
} else if (typeof val === 'number') { | |
ret = new Array(val); | |
for (i = 0; i < val; i++) { | |
ret[i] = render(i + 1, i); | |
} | |
} else if (isObject(val)) { | |
keys = Object.keys(val); | |
ret = new Array(keys.length); | |
for (i = 0, l = keys.length; i < l; i++) { | |
key = keys[i]; | |
ret[i] = render(val[key], key, i); | |
} | |
} | |
return ret | |
}; | |
// renderSlot | |
Vue.prototype._t = function ( | |
name, | |
fallback, | |
props, | |
bindObject | |
) { | |
var scopedSlotFn = this.$scopedSlots[name]; | |
if (scopedSlotFn) { // scoped slot | |
props = props || {}; | |
if (bindObject) { | |
extend(props, bindObject); | |
} | |
return scopedSlotFn(props) || fallback | |
} else { | |
var slotNodes = this.$slots[name]; | |
// warn duplicate slot usage | |
if (slotNodes && "development" !== 'production') { | |
slotNodes._rendered && warn( | |
"Duplicate presence of slot \"" + name + "\" found in the same render tree " + | |
"- this will likely cause render errors.", | |
this | |
); | |
slotNodes._rendered = true; | |
} | |
return slotNodes || fallback | |
} | |
}; | |
// apply v-bind object | |
Vue.prototype._b = function bindProps ( | |
data, | |
tag, | |
value, | |
asProp | |
) { | |
if (value) { | |
if (!isObject(value)) { | |
"development" !== 'production' && warn( | |
'v-bind without argument expects an Object or Array value', | |
this | |
); | |
} else { | |
if (Array.isArray(value)) { | |
value = toObject(value); | |
} | |
for (var key in value) { | |
if (key === 'class' || key === 'style') { | |
data[key] = value[key]; | |
} else { | |
var type = data.attrs && data.attrs.type; | |
var hash = asProp || config.mustUseProp(tag, type, key) | |
? data.domProps || (data.domProps = {}) | |
: data.attrs || (data.attrs = {}); | |
hash[key] = value[key]; | |
} | |
} | |
} | |
} | |
return data | |
}; | |
// check v-on keyCodes | |
Vue.prototype._k = function checkKeyCodes ( | |
eventKeyCode, | |
key, | |
builtInAlias | |
) { | |
var keyCodes = config.keyCodes[key] || builtInAlias; | |
if (Array.isArray(keyCodes)) { | |
return keyCodes.indexOf(eventKeyCode) === -1 | |
} else { | |
return keyCodes !== eventKeyCode | |
} | |
}; | |
} | |
function resolveSlots ( | |
children, | |
context | |
) { | |
var slots = {}; | |
if (!children) { | |
return slots | |
} | |
var defaultSlot = []; | |
var name, child; | |
for (var i = 0, l = children.length; i < l; i++) { | |
child = children[i]; | |
// named slots should only be respected if the vnode was rendered in the | |
// same context. | |
if ((child.context === context || child.functionalContext === context) && | |
child.data && (name = child.data.slot)) { | |
var slot = (slots[name] || (slots[name] = [])); | |
if (child.tag === 'template') { | |
slot.push.apply(slot, child.children); | |
} else { | |
slot.push(child); | |
} | |
} else { | |
defaultSlot.push(child); | |
} | |
} | |
// ignore single whitespace | |
if (defaultSlot.length && !( | |
defaultSlot.length === 1 && | |
(defaultSlot[0].text === ' ' || defaultSlot[0].isComment) | |
)) { | |
slots.default = defaultSlot; | |
} | |
return slots | |
} | |
/* */ | |
function initEvents (vm) { | |
vm._events = Object.create(null); | |
vm._hasHookEvent = false; | |
// init parent attached events | |
var listeners = vm.$options._parentListeners; | |
if (listeners) { | |
updateComponentListeners(vm, listeners); | |
} | |
} | |
var target; | |
function add$1 (event, fn, once) { | |
if (once) { | |
target.$once(event, fn); | |
} else { | |
target.$on(event, fn); | |
} | |
} | |
function remove$2 (event, fn) { | |
target.$off(event, fn); | |
} | |
function updateComponentListeners ( | |
vm, | |
listeners, | |
oldListeners | |
) { | |
target = vm; | |
updateListeners(listeners, oldListeners || {}, add$1, remove$2, vm); | |
} | |
function eventsMixin (Vue) { | |
var hookRE = /^hook:/; | |
Vue.prototype.$on = function (event, fn) { | |
var vm = this;(vm._events[event] || (vm._events[event] = [])).push(fn); | |
// optimize hook:event cost by using a boolean flag marked at registration | |
// instead of a hash lookup | |
if (hookRE.test(event)) { | |
vm._hasHookEvent = true; | |
} | |
return vm | |
}; | |
Vue.prototype.$once = function (event, fn) { | |
var vm = this; | |
function on () { | |
vm.$off(event, on); | |
fn.apply(vm, arguments); | |
} | |
on.fn = fn; | |
vm.$on(event, on); | |
return vm | |
}; | |
Vue.prototype.$off = function (event, fn) { | |
var vm = this; | |
// all | |
if (!arguments.length) { | |
vm._events = Object.create(null); | |
return vm | |
} | |
// specific event | |
var cbs = vm._events[event]; | |
if (!cbs) { | |
return vm | |
} | |
if (arguments.length === 1) { | |
vm._events[event] = null; | |
return vm | |
} | |
// specific handler | |
var cb; | |
var i = cbs.length; | |
while (i--) { | |
cb = cbs[i]; | |
if (cb === fn || cb.fn === fn) { | |
cbs.splice(i, 1); | |
break | |
} | |
} | |
return vm | |
}; | |
Vue.prototype.$emit = function (event) { | |
var vm = this; | |
var cbs = vm._events[event]; | |
if (cbs) { | |
cbs = cbs.length > 1 ? toArray(cbs) : cbs; | |
var args = toArray(arguments, 1); | |
for (var i = 0, l = cbs.length; i < l; i++) { | |
cbs[i].apply(vm, args); | |
} | |
} | |
return vm | |
}; | |
} | |
/* */ | |
var activeInstance = null; | |
function initLifecycle (vm) { | |
var options = vm.$options; | |
// locate first non-abstract parent | |
var parent = options.parent; | |
if (parent && !options.abstract) { | |
while (parent.$options.abstract && parent.$parent) { | |
parent = parent.$parent; | |
} | |
parent.$children.push(vm); | |
} | |
vm.$parent = parent; | |
vm.$root = parent ? parent.$root : vm; | |
vm.$children = []; | |
vm.$refs = {}; | |
vm._watcher = null; | |
vm._inactive = false; | |
vm._isMounted = false; | |
vm._isDestroyed = false; | |
vm._isBeingDestroyed = false; | |
} | |
function lifecycleMixin (Vue) { | |
Vue.prototype._mount = function ( | |
el, | |
hydrating | |
) { | |
var vm = this; | |
vm.$el = el; | |
if (!vm.$options.render) { | |
vm.$options.render = createEmptyVNode; | |
{ | |
/* istanbul ignore if */ | |
if (vm.$options.template && vm.$options.template.charAt(0) !== '#') { | |
warn( | |
'You are using the runtime-only build of Vue where the template ' + | |
'option is not available. Either pre-compile the templates into ' + | |
'render functions, or use the compiler-included build.', | |
vm | |
); | |
} else { | |
warn( | |
'Failed to mount component: template or render function not defined.', | |
vm | |
); | |
} | |
} | |
} | |
callHook(vm, 'beforeMount'); | |
vm._watcher = new Watcher(vm, function updateComponent () { | |
vm._update(vm._render(), hydrating); | |
}, noop); | |
hydrating = false; | |
// manually mounted instance, call mounted on self | |
// mounted is called for render-created child components in its inserted hook | |
if (vm.$vnode == null) { | |
vm._isMounted = true; | |
callHook(vm, 'mounted'); | |
} | |
return vm | |
}; | |
Vue.prototype._update = function (vnode, hydrating) { | |
var vm = this; | |
if (vm._isMounted) { | |
callHook(vm, 'beforeUpdate'); | |
} | |
var prevEl = vm.$el; | |
var prevVnode = vm._vnode; | |
var prevActiveInstance = activeInstance; | |
activeInstance = vm; | |
vm._vnode = vnode; | |
// Vue.prototype.__patch__ is injected in entry points | |
// based on the rendering backend used. | |
if (!prevVnode) { | |
// initial render | |
vm.$el = vm.__patch__( | |
vm.$el, vnode, hydrating, false /* removeOnly */, | |
vm.$options._parentElm, | |
vm.$options._refElm | |
); | |
} else { | |
// updates | |
vm.$el = vm.__patch__(prevVnode, vnode); | |
} | |
activeInstance = prevActiveInstance; | |
// update __vue__ reference | |
if (prevEl) { | |
prevEl.__vue__ = null; | |
} | |
if (vm.$el) { | |
vm.$el.__vue__ = vm; | |
} | |
// if parent is an HOC, update its $el as well | |
if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) { | |
vm.$parent.$el = vm.$el; | |
} | |
// updated hook is called by the scheduler to ensure that children are | |
// updated in a parent's updated hook. | |
}; | |
Vue.prototype._updateFromParent = function ( | |
propsData, | |
listeners, | |
parentVnode, | |
renderChildren | |
) { | |
var vm = this; | |
var hasChildren = !!(vm.$options._renderChildren || renderChildren); | |
vm.$options._parentVnode = parentVnode; | |
vm.$vnode = parentVnode; // update vm's placeholder node without re-render | |
if (vm._vnode) { // update child tree's parent | |
vm._vnode.parent = parentVnode; | |
} | |
vm.$options._renderChildren = renderChildren; | |
// update props | |
if (propsData && vm.$options.props) { | |
observerState.shouldConvert = false; | |
{ | |
observerState.isSettingProps = true; | |
} | |
var propKeys = vm.$options._propKeys || []; | |
for (var i = 0; i < propKeys.length; i++) { | |
var key = propKeys[i]; | |
vm[key] = validateProp(key, vm.$options.props, propsData, vm); | |
} | |
observerState.shouldConvert = true; | |
{ | |
observerState.isSettingProps = false; | |
} | |
vm.$options.propsData = propsData; | |
} | |
// update listeners | |
if (listeners) { | |
var oldListeners = vm.$options._parentListeners; | |
vm.$options._parentListeners = listeners; | |
updateComponentListeners(vm, listeners, oldListeners); | |
} | |
// resolve slots + force update if has children | |
if (hasChildren) { | |
vm.$slots = resolveSlots(renderChildren, parentVnode.context); | |
vm.$forceUpdate(); | |
} | |
}; | |
Vue.prototype.$forceUpdate = function () { | |
var vm = this; | |
if (vm._watcher) { | |
vm._watcher.update(); | |
} | |
}; | |
Vue.prototype.$destroy = function () { | |
var vm = this; | |
if (vm._isBeingDestroyed) { | |
return | |
} | |
callHook(vm, 'beforeDestroy'); | |
vm._isBeingDestroyed = true; | |
// remove self from parent | |
var parent = vm.$parent; | |
if (parent && !parent._isBeingDestroyed && !vm.$options.abstract) { | |
remove$1(parent.$children, vm); | |
} | |
// teardown watchers | |
if (vm._watcher) { | |
vm._watcher.teardown(); | |
} | |
var i = vm._watchers.length; | |
while (i--) { | |
vm._watchers[i].teardown(); | |
} | |
// remove reference from data ob | |
// frozen object may not have observer. | |
if (vm._data.__ob__) { | |
vm._data.__ob__.vmCount--; | |
} | |
// call the last hook... | |
vm._isDestroyed = true; | |
callHook(vm, 'destroyed'); | |
// turn off all instance listeners. | |
vm.$off(); | |
// remove __vue__ reference | |
if (vm.$el) { | |
vm.$el.__vue__ = null; | |
} | |
// invoke destroy hooks on current rendered tree | |
vm.__patch__(vm._vnode, null); | |
}; | |
} | |
function callHook (vm, hook) { | |
var handlers = vm.$options[hook]; | |
if (handlers) { | |
for (var i = 0, j = handlers.length; i < j; i++) { | |
handlers[i].call(vm); | |
} | |
} | |
if (vm._hasHookEvent) { | |
vm.$emit('hook:' + hook); | |
} | |
} | |
/* */ | |
var queue = []; | |
var has$1 = {}; | |
var circular = {}; | |
var waiting = false; | |
var flushing = false; | |
var index = 0; | |
/** | |
* Reset the scheduler's state. | |
*/ | |
function resetSchedulerState () { | |
queue.length = 0; | |
has$1 = {}; | |
{ | |
circular = {}; | |
} | |
waiting = flushing = false; | |
} | |
/** | |
* Flush both queues and run the watchers. | |
*/ | |
function flushSchedulerQueue () { | |
flushing = true; | |
var watcher, id, vm; | |
// Sort queue before flush. | |
// This ensures that: | |
// 1. Components are updated from parent to child. (because parent is always | |
// created before the child) | |
// 2. A component's user watchers are run before its render watcher (because | |
// user watchers are created before the render watcher) | |
// 3. If a component is destroyed during a parent component's watcher run, | |
// its watchers can be skipped. | |
queue.sort(function (a, b) { return a.id - b.id; }); | |
// do not cache length because more watchers might be pushed | |
// as we run existing watchers | |
for (index = 0; index < queue.length; index++) { | |
watcher = queue[index]; | |
id = watcher.id; | |
has$1[id] = null; | |
watcher.run(); | |
// in dev build, check and stop circular updates. | |
if ("development" !== 'production' && has$1[id] != null) { | |
circular[id] = (circular[id] || 0) + 1; | |
if (circular[id] > config._maxUpdateCount) { | |
warn( | |
'You may have an infinite update loop ' + ( | |
watcher.user | |
? ("in watcher with expression \"" + (watcher.expression) + "\"") | |
: "in a component render function." | |
), | |
watcher.vm | |
); | |
break | |
} | |
} | |
} | |
// call updated hooks | |
index = queue.length; | |
while (index--) { | |
watcher = queue[index]; | |
vm = watcher.vm; | |
if (vm._watcher === watcher && vm._isMounted) { | |
callHook(vm, 'updated'); | |
} | |
} | |
// devtool hook | |
/* istanbul ignore if */ | |
if (devtools && config.devtools) { | |
devtools.emit('flush'); | |
} | |
resetSchedulerState(); | |
} | |
/** | |
* Push a watcher into the watcher queue. | |
* Jobs with duplicate IDs will be skipped unless it's | |
* pushed when the queue is being flushed. | |
*/ | |
function queueWatcher (watcher) { | |
var id = watcher.id; | |
if (has$1[id] == null) { | |
has$1[id] = true; | |
if (!flushing) { | |
queue.push(watcher); | |
} else { | |
// if already flushing, splice the watcher based on its id | |
// if already past its id, it will be run next immediately. | |
var i = queue.length - 1; | |
while (i >= 0 && queue[i].id > watcher.id) { | |
i--; | |
} | |
queue.splice(Math.max(i, index) + 1, 0, watcher); | |
} | |
// queue the flush | |
if (!waiting) { | |
waiting = true; | |
nextTick(flushSchedulerQueue); | |
} | |
} | |
} | |
/* */ | |
var uid$2 = 0; | |
/** | |
* A watcher parses an expression, collects dependencies, | |
* and fires callback when the expression value changes. | |
* This is used for both the $watch() api and directives. | |
*/ | |
var Watcher = function Watcher ( | |
vm, | |
expOrFn, | |
cb, | |
options | |
) { | |
this.vm = vm; | |
vm._watchers.push(this); | |
// options | |
if (options) { | |
this.deep = !!options.deep; | |
this.user = !!options.user; | |
this.lazy = !!options.lazy; | |
this.sync = !!options.sync; | |
} else { | |
this.deep = this.user = this.lazy = this.sync = false; | |
} | |
this.cb = cb; | |
this.id = ++uid$2; // uid for batching | |
this.active = true; | |
this.dirty = this.lazy; // for lazy watchers | |
this.deps = []; | |
this.newDeps = []; | |
this.depIds = new _Set(); | |
this.newDepIds = new _Set(); | |
this.expression = expOrFn.toString(); | |
// parse expression for getter | |
if (typeof expOrFn === 'function') { | |
this.getter = expOrFn; | |
} else { | |
this.getter = parsePath(expOrFn); | |
if (!this.getter) { | |
this.getter = function () {}; | |
"development" !== 'production' && warn( | |
"Failed watching path: \"" + expOrFn + "\" " + | |
'Watcher only accepts simple dot-delimited paths. ' + | |
'For full control, use a function instead.', | |
vm | |
); | |
} | |
} | |
this.value = this.lazy | |
? undefined | |
: this.get(); | |
}; | |
/** | |
* Evaluate the getter, and re-collect dependencies. | |
*/ | |
Watcher.prototype.get = function get () { | |
pushTarget(this); | |
var value = this.getter.call(this.vm, this.vm); | |
// "touch" every property so they are all tracked as | |
// dependencies for deep watching | |
if (this.deep) { | |
traverse(value); | |
} | |
popTarget(); | |
this.cleanupDeps(); | |
return value | |
}; | |
/** | |
* Add a dependency to this directive. | |
*/ | |
Watcher.prototype.addDep = function addDep (dep) { | |
var id = dep.id; | |
if (!this.newDepIds.has(id)) { | |
this.newDepIds.add(id); | |
this.newDeps.push(dep); | |
if (!this.depIds.has(id)) { | |
dep.addSub(this); | |
} | |
} | |
}; | |
/** | |
* Clean up for dependency collection. | |
*/ | |
Watcher.prototype.cleanupDeps = function cleanupDeps () { | |
var this$1 = this; | |
var i = this.deps.length; | |
while (i--) { | |
var dep = this$1.deps[i]; | |
if (!this$1.newDepIds.has(dep.id)) { | |
dep.removeSub(this$1); | |
} | |
} | |
var tmp = this.depIds; | |
this.depIds = this.newDepIds; | |
this.newDepIds = tmp; | |
this.newDepIds.clear(); | |
tmp = this.deps; | |
this.deps = this.newDeps; | |
this.newDeps = tmp; | |
this.newDeps.length = 0; | |
}; | |
/** | |
* Subscriber interface. | |
* Will be called when a dependency changes. | |
*/ | |
Watcher.prototype.update = function update () { | |
/* istanbul ignore else */ | |
if (this.lazy) { | |
this.dirty = true; | |
} else if (this.sync) { | |
this.run(); | |
} else { | |
queueWatcher(this); | |
} | |
}; | |
/** | |
* Scheduler job interface. | |
* Will be called by the scheduler. | |
*/ | |
Watcher.prototype.run = function run () { | |
if (this.active) { | |
var value = this.get(); | |
if ( | |
value !== this.value || | |
// Deep watchers and watchers on Object/Arrays should fire even | |
// when the value is the same, because the value may | |
// have mutated. | |
isObject(value) || | |
this.deep | |
) { | |
// set new value | |
var oldValue = this.value; | |
this.value = value; | |
if (this.user) { | |
try { | |
this.cb.call(this.vm, value, oldValue); | |
} catch (e) { | |
/* istanbul ignore else */ | |
if (config.errorHandler) { | |
config.errorHandler.call(null, e, this.vm); | |
} else { | |
"development" !== 'production' && warn( | |
("Error in watcher \"" + (this.expression) + "\""), | |
this.vm | |
); | |
throw e | |
} | |
} | |
} else { | |
this.cb.call(this.vm, value, oldValue); | |
} | |
} | |
} | |
}; | |
/** | |
* Evaluate the value of the watcher. | |
* This only gets called for lazy watchers. | |
*/ | |
Watcher.prototype.evaluate = function evaluate () { | |
this.value = this.get(); | |
this.dirty = false; | |
}; | |
/** | |
* Depend on all deps collected by this watcher. | |
*/ | |
Watcher.prototype.depend = function depend () { | |
var this$1 = this; | |
var i = this.deps.length; | |
while (i--) { | |
this$1.deps[i].depend(); | |
} | |
}; | |
/** | |
* Remove self from all dependencies' subscriber list. | |
*/ | |
Watcher.prototype.teardown = function teardown () { | |
var this$1 = this; | |
if (this.active) { | |
// remove self from vm's watcher list | |
// this is a somewhat expensive operation so we skip it | |
// if the vm is being destroyed. | |
if (!this.vm._isBeingDestroyed) { | |
remove$1(this.vm._watchers, this); | |
} | |
var i = this.deps.length; | |
while (i--) { | |
this$1.deps[i].removeSub(this$1); | |
} | |
this.active = false; | |
} | |
}; | |
/** | |
* Recursively traverse an object to evoke all converted | |
* getters, so that every nested property inside the object | |
* is collected as a "deep" dependency. | |
*/ | |
var seenObjects = new _Set(); | |
function traverse (val) { | |
seenObjects.clear(); | |
_traverse(val, seenObjects); | |
} | |
function _traverse (val, seen) { | |
var i, keys; | |
var isA = Array.isArray(val); | |
if ((!isA && !isObject(val)) || !Object.isExtensible(val)) { | |
return | |
} | |
if (val.__ob__) { | |
var depId = val.__ob__.dep.id; | |
if (seen.has(depId)) { | |
return | |
} | |
seen.add(depId); | |
} | |
if (isA) { | |
i = val.length; | |
while (i--) { _traverse(val[i], seen); } | |
} else { | |
keys = Object.keys(val); | |
i = keys.length; | |
while (i--) { _traverse(val[keys[i]], seen); } | |
} | |
} | |
/* */ | |
function initState (vm) { | |
vm._watchers = []; | |
var opts = vm.$options; | |
if (opts.props) { initProps(vm, opts.props); } | |
if (opts.methods) { initMethods(vm, opts.methods); } | |
if (opts.data) { | |
initData(vm); | |
} else { | |
observe(vm._data = {}, true /* asRootData */); | |
} | |
if (opts.computed) { initComputed(vm, opts.computed); } | |
if (opts.watch) { initWatch(vm, opts.watch); } | |
} | |
var isReservedProp = { key: 1, ref: 1, slot: 1 }; | |
function initProps (vm, props) { | |
var propsData = vm.$options.propsData || {}; | |
var keys = vm.$options._propKeys = Object.keys(props); | |
var isRoot = !vm.$parent; | |
// root instance props should be converted | |
observerState.shouldConvert = isRoot; | |
var loop = function ( i ) { | |
var key = keys[i]; | |
/* istanbul ignore else */ | |
{ | |
if (isReservedProp[key]) { | |
warn( | |
("\"" + key + "\" is a reserved attribute and cannot be used as component prop."), | |
vm | |
); | |
} | |
defineReactive$$1(vm, key, validateProp(key, props, propsData, vm), function () { | |
if (vm.$parent && !observerState.isSettingProps) { | |
warn( | |
"Avoid mutating a prop directly since the value will be " + | |
"overwritten whenever the parent component re-renders. " + | |
"Instead, use a data or computed property based on the prop's " + | |
"value. Prop being mutated: \"" + key + "\"", | |
vm | |
); | |
} | |
}); | |
} | |
}; | |
for (var i = 0; i < keys.length; i++) loop( i ); | |
observerState.shouldConvert = true; | |
} | |
function initData (vm) { | |
var data = vm.$options.data; | |
data = vm._data = typeof data === 'function' | |
? data.call(vm) | |
: data || {}; | |
if (!isPlainObject(data)) { | |
data = {}; | |
"development" !== 'production' && warn( | |
'data functions should return an object:\n' + | |
'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function', | |
vm | |
); | |
} | |
// proxy data on instance | |
var keys = Object.keys(data); | |
var props = vm.$options.props; | |
var i = keys.length; | |
while (i--) { | |
if (props && hasOwn(props, keys[i])) { | |
"development" !== 'production' && warn( | |
"The data property \"" + (keys[i]) + "\" is already declared as a prop. " + | |
"Use prop default value instead.", | |
vm | |
); | |
} else { | |
proxy(vm, keys[i]); | |
} | |
} | |
// observe data | |
observe(data, true /* asRootData */); | |
} | |
var computedSharedDefinition = { | |
enumerable: true, | |
configurable: true, | |
get: noop, | |
set: noop | |
}; | |
function initComputed (vm, computed) { | |
for (var key in computed) { | |
/* istanbul ignore if */ | |
if ("development" !== 'production' && key in vm) { | |
warn( | |
"existing instance property \"" + key + "\" will be " + | |
"overwritten by a computed property with the same name.", | |
vm | |
); | |
} | |
var userDef = computed[key]; | |
if (typeof userDef === 'function') { | |
computedSharedDefinition.get = makeComputedGetter(userDef, vm); | |
computedSharedDefinition.set = noop; | |
} else { | |
computedSharedDefinition.get = userDef.get | |
? userDef.cache !== false | |
? makeComputedGetter(userDef.get, vm) | |
: bind$1(userDef.get, vm) | |
: noop; | |
computedSharedDefinition.set = userDef.set | |
? bind$1(userDef.set, vm) | |
: noop; | |
} | |
Object.defineProperty(vm, key, computedSharedDefinition); | |
} | |
} | |
function makeComputedGetter (getter, owner) { | |
var watcher = new Watcher(owner, getter, noop, { | |
lazy: true | |
}); | |
return function computedGetter () { | |
if (watcher.dirty) { | |
watcher.evaluate(); | |
} | |
if (Dep.target) { | |
watcher.depend(); | |
} | |
return watcher.value | |
} | |
} | |
function initMethods (vm, methods) { | |
for (var key in methods) { | |
vm[key] = methods[key] == null ? noop : bind$1(methods[key], vm); | |
if ("development" !== 'production' && methods[key] == null) { | |
warn( | |
"method \"" + key + "\" has an undefined value in the component definition. " + | |
"Did you reference the function correctly?", | |
vm | |
); | |
} | |
} | |
} | |
function initWatch (vm, watch) { | |
for (var key in watch) { | |
var handler = watch[key]; | |
if (Array.isArray(handler)) { | |
for (var i = 0; i < handler.length; i++) { | |
createWatcher(vm, key, handler[i]); | |
} | |
} else { | |
createWatcher(vm, key, handler); | |
} | |
} | |
} | |
function createWatcher (vm, key, handler) { | |
var options; | |
if (isPlainObject(handler)) { | |
options = handler; | |
handler = handler.handler; | |
} | |
if (typeof handler === 'string') { | |
handler = vm[handler]; | |
} | |
vm.$watch(key, handler, options); | |
} | |
function stateMixin (Vue) { | |
// flow somehow has problems with directly declared definition object | |
// when using Object.defineProperty, so we have to procedurally build up | |
// the object here. | |
var dataDef = {}; | |
dataDef.get = function () { | |
return this._data | |
}; | |
{ | |
dataDef.set = function (newData) { | |
warn( | |
'Avoid replacing instance root $data. ' + | |
'Use nested data properties instead.', | |
this | |
); | |
}; | |
} | |
Object.defineProperty(Vue.prototype, '$data', dataDef); | |
Vue.prototype.$set = set$1; | |
Vue.prototype.$delete = del; | |
Vue.prototype.$watch = function ( | |
expOrFn, | |
cb, | |
options | |
) { | |
var vm = this; | |
options = options || {}; | |
options.user = true; | |
var watcher = new Watcher(vm, expOrFn, cb, options); | |
if (options.immediate) { | |
cb.call(vm, watcher.value); | |
} | |
return function unwatchFn () { | |
watcher.teardown(); | |
} | |
}; | |
} | |
function proxy (vm, key) { | |
if (!isReserved(key)) { | |
Object.defineProperty(vm, key, { | |
configurable: true, | |
enumerable: true, | |
get: function proxyGetter () { | |
return vm._data[key] | |
}, | |
set: function proxySetter (val) { | |
vm._data[key] = val; | |
} | |
}); | |
} | |
} | |
/* */ | |
var uid = 0; | |
function initMixin (Vue) { | |
Vue.prototype._init = function (options) { | |
var vm = this; | |
// a uid | |
vm._uid = uid++; | |
// a flag to avoid this being observed | |
vm._isVue = true; | |
// merge options | |
if (options && options._isComponent) { | |
// optimize internal component instantiation | |
// since dynamic options merging is pretty slow, and none of the | |
// internal component options needs special treatment. | |
initInternalComponent(vm, options); | |
} else { | |
vm.$options = mergeOptions( | |
resolveConstructorOptions(vm.constructor), | |
options || {}, | |
vm | |
); | |
} | |
/* istanbul ignore else */ | |
{ | |
initProxy(vm); | |
} | |
// expose real self | |
vm._self = vm; | |
initLifecycle(vm); | |
initEvents(vm); | |
initRender(vm); | |
callHook(vm, 'beforeCreate'); | |
initState(vm); | |
callHook(vm, 'created'); | |
if (vm.$options.el) { | |
vm.$mount(vm.$options.el); | |
} | |
}; | |
} | |
function initInternalComponent (vm, options) { | |
var opts = vm.$options = Object.create(vm.constructor.options); | |
// doing this because it's faster than dynamic enumeration. | |
opts.parent = options.parent; | |
opts.propsData = options.propsData; | |
opts._parentVnode = options._parentVnode; | |
opts._parentListeners = options._parentListeners; | |
opts._renderChildren = options._renderChildren; | |
opts._componentTag = options._componentTag; | |
opts._parentElm = options._parentElm; | |
opts._refElm = options._refElm; | |
if (options.render) { | |
opts.render = options.render; | |
opts.staticRenderFns = options.staticRenderFns; | |
} | |
} | |
function resolveConstructorOptions (Ctor) { | |
var options = Ctor.options; | |
if (Ctor.super) { | |
var superOptions = Ctor.super.options; | |
var cachedSuperOptions = Ctor.superOptions; | |
var extendOptions = Ctor.extendOptions; | |
if (superOptions !== cachedSuperOptions) { | |
// super option changed | |
Ctor.superOptions = superOptions; | |
extendOptions.render = options.render; | |
extendOptions.staticRenderFns = options.staticRenderFns; | |
extendOptions._scopeId = options._scopeId; | |
options = Ctor.options = mergeOptions(superOptions, extendOptions); | |
if (options.name) { | |
options.components[options.name] = Ctor; | |
} | |
} | |
} | |
return options | |
} | |
function Vue$3 (options) { | |
if ("development" !== 'production' && | |
!(this instanceof Vue$3)) { | |
warn('Vue is a constructor and should be called with the `new` keyword'); | |
} | |
this._init(options); | |
} | |
initMixin(Vue$3); | |
stateMixin(Vue$3); | |
eventsMixin(Vue$3); | |
lifecycleMixin(Vue$3); | |
renderMixin(Vue$3); | |
/* */ | |
function initUse (Vue) { | |
Vue.use = function (plugin) { | |
/* istanbul ignore if */ | |
if (plugin.installed) { | |
return | |
} | |
// additional parameters | |
var args = toArray(arguments, 1); | |
args.unshift(this); | |
if (typeof plugin.install === 'function') { | |
plugin.install.apply(plugin, args); | |
} else { | |
plugin.apply(null, args); | |
} | |
plugin.installed = true; | |
return this | |
}; | |
} | |
/* */ | |
function initMixin$1 (Vue) { | |
Vue.mixin = function (mixin) { | |
this.options = mergeOptions(this.options, mixin); | |
}; | |
} | |
/* */ | |
function initExtend (Vue) { | |
/** | |
* Each instance constructor, including Vue, has a unique | |
* cid. This enables us to create wrapped "child | |
* constructors" for prototypal inheritance and cache them. | |
*/ | |
Vue.cid = 0; | |
var cid = 1; | |
/** | |
* Class inheritance | |
*/ | |
Vue.extend = function (extendOptions) { | |
extendOptions = extendOptions || {}; | |
var Super = this; | |
var SuperId = Super.cid; | |
var cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {}); | |
if (cachedCtors[SuperId]) { | |
return cachedCtors[SuperId] | |
} | |
var name = extendOptions.name || Super.options.name; | |
{ | |
if (!/^[a-zA-Z][\w-]*$/.test(name)) { | |
warn( | |
'Invalid component name: "' + name + '". Component names ' + | |
'can only contain alphanumeric characters and the hyphen, ' + | |
'and must start with a letter.' | |
); | |
} | |
} | |
var Sub = function VueComponent (options) { | |
this._init(options); | |
}; | |
Sub.prototype = Object.create(Super.prototype); | |
Sub.prototype.constructor = Sub; | |
Sub.cid = cid++; | |
Sub.options = mergeOptions( | |
Super.options, | |
extendOptions | |
); | |
Sub['super'] = Super; | |
// allow further extension/mixin/plugin usage | |
Sub.extend = Super.extend; | |
Sub.mixin = Super.mixin; | |
Sub.use = Super.use; | |
// create asset registers, so extended classes | |
// can have their private assets too. | |
config._assetTypes.forEach(function (type) { | |
Sub[type] = Super[type]; | |
}); | |
// enable recursive self-lookup | |
if (name) { | |
Sub.options.components[name] = Sub; | |
} | |
// keep a reference to the super options at extension time. | |
// later at instantiation we can check if Super's options have | |
// been updated. | |
Sub.superOptions = Super.options; | |
Sub.extendOptions = extendOptions; | |
// cache constructor | |
cachedCtors[SuperId] = Sub; | |
return Sub | |
}; | |
} | |
/* */ | |
function initAssetRegisters (Vue) { | |
/** | |
* Create asset registration methods. | |
*/ | |
config._assetTypes.forEach(function (type) { | |
Vue[type] = function ( | |
id, | |
definition | |
) { | |
if (!definition) { | |
return this.options[type + 's'][id] | |
} else { | |
/* istanbul ignore if */ | |
{ | |
if (type === 'component' && config.isReservedTag(id)) { | |
warn( | |
'Do not use built-in or reserved HTML elements as component ' + | |
'id: ' + id | |
); | |
} | |
} | |
if (type === 'component' && isPlainObject(definition)) { | |
definition.name = definition.name || id; | |
definition = this.options._base.extend(definition); | |
} | |
if (type === 'directive' && typeof definition === 'function') { | |
definition = { bind: definition, update: definition }; | |
} | |
this.options[type + 's'][id] = definition; | |
return definition | |
} | |
}; | |
}); | |
} | |
/* */ | |
var patternTypes = [String, RegExp]; | |
function getComponentName (opts) { | |
return opts && (opts.Ctor.options.name || opts.tag) | |
} | |
function matches (pattern, name) { | |
if (typeof pattern === 'string') { | |
return pattern.split(',').indexOf(name) > -1 | |
} else { | |
return pattern.test(name) | |
} | |
} | |
function pruneCache (cache, filter) { | |
for (var key in cache) { | |
var cachedNode = cache[key]; | |
if (cachedNode) { | |
var name = getComponentName(cachedNode.componentOptions); | |
if (name && !filter(name)) { | |
pruneCacheEntry(cachedNode); | |
cache[key] = null; | |
} | |
} | |
} | |
} | |
function pruneCacheEntry (vnode) { | |
if (vnode) { | |
if (!vnode.componentInstance._inactive) { | |
callHook(vnode.componentInstance, 'deactivated'); | |
} | |
vnode.componentInstance.$destroy(); | |
} | |
} | |
var KeepAlive = { | |
name: 'keep-alive', | |
abstract: true, | |
props: { | |
include: patternTypes, | |
exclude: patternTypes | |
}, | |
created: function created () { | |
this.cache = Object.create(null); | |
}, | |
destroyed: function destroyed () { | |
var this$1 = this; | |
for (var key in this.cache) { | |
pruneCacheEntry(this$1.cache[key]); | |
} | |
}, | |
watch: { | |
include: function include (val) { | |
pruneCache(this.cache, function (name) { return matches(val, name); }); | |
}, | |
exclude: function exclude (val) { | |
pruneCache(this.cache, function (name) { return !matches(val, name); }); | |
} | |
}, | |
render: function render () { | |
var vnode = getFirstComponentChild(this.$slots.default); | |
var componentOptions = vnode && vnode.componentOptions; | |
if (componentOptions) { | |
// check pattern | |
var name = getComponentName(componentOptions); | |
if (name && ( | |
(this.include && !matches(this.include, name)) || | |
(this.exclude && matches(this.exclude, name)) | |
)) { | |
return vnode | |
} | |
var key = vnode.key == null | |
// same constructor may get registered as different local components | |
// so cid alone is not enough (#3269) | |
? componentOptions.Ctor.cid + (componentOptions.tag ? ("::" + (componentOptions.tag)) : '') | |
: vnode.key; | |
if (this.cache[key]) { | |
vnode.componentInstance = this.cache[key].componentInstance; | |
} else { | |
this.cache[key] = vnode; | |
} | |
vnode.data.keepAlive = true; | |
} | |
return vnode | |
} | |
}; | |
var builtInComponents = { | |
KeepAlive: KeepAlive | |
}; | |
/* */ | |
function initGlobalAPI (Vue) { | |
// config | |
var configDef = {}; | |
configDef.get = function () { return config; }; | |
{ | |
configDef.set = function () { | |
warn( | |
'Do not replace the Vue.config object, set individual fields instead.' | |
); | |
}; | |
} | |
Object.defineProperty(Vue, 'config', configDef); | |
Vue.util = util; | |
Vue.set = set$1; | |
Vue.delete = del; | |
Vue.nextTick = nextTick; | |
Vue.options = Object.create(null); | |
config._assetTypes.forEach(function (type) { | |
Vue.options[type + 's'] = Object.create(null); | |
}); | |
// this is used to identify the "base" constructor to extend all plain-object | |
// components with in Weex's multi-instance scenarios. | |
Vue.options._base = Vue; | |
extend(Vue.options.components, builtInComponents); | |
initUse(Vue); | |
initMixin$1(Vue); | |
initExtend(Vue); | |
initAssetRegisters(Vue); | |
} | |
initGlobalAPI(Vue$3); | |
Object.defineProperty(Vue$3.prototype, '$isServer', { | |
get: isServerRendering | |
}); | |
Vue$3.version = '2.1.10'; | |
/* */ | |
// attributes that should be using props for binding | |
var acceptValue = makeMap('input,textarea,option,select'); | |
var mustUseProp = function (tag, type, attr) { | |
return ( | |
(attr === 'value' && acceptValue(tag)) && type !== 'button' || | |
(attr === 'selected' && tag === 'option') || | |
(attr === 'checked' && tag === 'input') || | |
(attr === 'muted' && tag === 'video') | |
) | |
}; | |
var isEnumeratedAttr = makeMap('contenteditable,draggable,spellcheck'); | |
var isBooleanAttr = makeMap( | |
'allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,' + | |
'default,defaultchecked,defaultmuted,defaultselected,defer,disabled,' + | |
'enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,' + | |
'muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,' + | |
'required,reversed,scoped,seamless,selected,sortable,translate,' + | |
'truespeed,typemustmatch,visible' | |
); | |
var xlinkNS = 'http://www.w3.org/1999/xlink'; | |
var isXlink = function (name) { | |
return name.charAt(5) === ':' && name.slice(0, 5) === 'xlink' | |
}; | |
var getXlinkProp = function (name) { | |
return isXlink(name) ? name.slice(6, name.length) : '' | |
}; | |
var isFalsyAttrValue = function (val) { | |
return val == null || val === false | |
}; | |
/* */ | |
function genClassForVnode (vnode) { | |
var data = vnode.data; | |
var parentNode = vnode; | |
var childNode = vnode; | |
while (childNode.componentInstance) { | |
childNode = childNode.componentInstance._vnode; | |
if (childNode.data) { | |
data = mergeClassData(childNode.data, data); | |
} | |
} | |
while ((parentNode = parentNode.parent)) { | |
if (parentNode.data) { | |
data = mergeClassData(data, parentNode.data); | |
} | |
} | |
return genClassFromData(data) | |
} | |
function mergeClassData (child, parent) { | |
return { | |
staticClass: concat(child.staticClass, parent.staticClass), | |
class: child.class | |
? [child.class, parent.class] | |
: parent.class | |
} | |
} | |
function genClassFromData (data) { | |
var dynamicClass = data.class; | |
var staticClass = data.staticClass; | |
if (staticClass || dynamicClass) { | |
return concat(staticClass, stringifyClass(dynamicClass)) | |
} | |
/* istanbul ignore next */ | |
return '' | |
} | |
function concat (a, b) { | |
return a ? b ? (a + ' ' + b) : a : (b || '') | |
} | |
function stringifyClass (value) { | |
var res = ''; | |
if (!value) { | |
return res | |
} | |
if (typeof value === 'string') { | |
return value | |
} | |
if (Array.isArray(value)) { | |
var stringified; | |
for (var i = 0, l = value.length; i < l; i++) { | |
if (value[i]) { | |
if ((stringified = stringifyClass(value[i]))) { | |
res += stringified + ' '; | |
} | |
} | |
} | |
return res.slice(0, -1) | |
} | |
if (isObject(value)) { | |
for (var key in value) { | |
if (value[key]) { res += key + ' '; } | |
} | |
return res.slice(0, -1) | |
} | |
/* istanbul ignore next */ | |
return res | |
} | |
/* */ | |
var namespaceMap = { | |
svg: 'http://www.w3.org/2000/svg', | |
math: 'http://www.w3.org/1998/Math/MathML' | |
}; | |
var isHTMLTag = makeMap( | |
'html,body,base,head,link,meta,style,title,' + | |
'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' + | |
'div,dd,dl,dt,figcaption,figure,hr,img,li,main,ol,p,pre,ul,' + | |
'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' + | |
's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' + | |
'embed,object,param,source,canvas,script,noscript,del,ins,' + | |
'caption,col,colgroup,table,thead,tbody,td,th,tr,' + | |
'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' + | |
'output,progress,select,textarea,' + | |
'details,dialog,menu,menuitem,summary,' + | |
'content,element,shadow,template' | |
); | |
// this map is intentionally selective, only covering SVG elements that may | |
// contain child elements. | |
var isSVG = makeMap( | |
'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,' + | |
'font-face,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' + | |
'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view', | |
true | |
); | |
var isPreTag = function (tag) { return tag === 'pre'; }; | |
var isReservedTag = function (tag) { | |
return isHTMLTag(tag) || isSVG(tag) | |
}; | |
function getTagNamespace (tag) { | |
if (isSVG(tag)) { | |
return 'svg' | |
} | |
// basic support for MathML | |
// note it doesn't support other MathML elements being component roots | |
if (tag === 'math') { | |
return 'math' | |
} | |
} | |
var unknownElementCache = Object.create(null); | |
function isUnknownElement (tag) { | |
/* istanbul ignore if */ | |
if (!inBrowser) { | |
return true | |
} | |
if (isReservedTag(tag)) { | |
return false | |
} | |
tag = tag.toLowerCase(); | |
/* istanbul ignore if */ | |
if (unknownElementCache[tag] != null) { | |
return unknownElementCache[tag] | |
} | |
var el = document.createElement(tag); | |
if (tag.indexOf('-') > -1) { | |
// http://stackoverflow.com/a/28210364/1070244 | |
return (unknownElementCache[tag] = ( | |
el.constructor === window.HTMLUnknownElement || | |
el.constructor === window.HTMLElement | |
)) | |
} else { | |
return (unknownElementCache[tag] = /HTMLUnknownElement/.test(el.toString())) | |
} | |
} | |
/* */ | |
/** | |
* Query an element selector if it's not an element already. | |
*/ | |
function query (el) { | |
if (typeof el === 'string') { | |
var selector = el; | |
el = document.querySelector(el); | |
if (!el) { | |
"development" !== 'production' && warn( | |
'Cannot find element: ' + selector | |
); | |
return document.createElement('div') | |
} | |
} | |
return el | |
} | |
/* */ | |
function createElement$1 (tagName, vnode) { | |
var elm = document.createElement(tagName); | |
if (tagName !== 'select') { | |
return elm | |
} | |
if (vnode.data && vnode.data.attrs && 'multiple' in vnode.data.attrs) { | |
elm.setAttribute('multiple', 'multiple'); | |
} | |
return elm | |
} | |
function createElementNS (namespace, tagName) { | |
return document.createElementNS(namespaceMap[namespace], tagName) | |
} | |
function createTextNode (text) { | |
return document.createTextNode(text) | |
} | |
function createComment (text) { | |
return document.createComment(text) | |
} | |
function insertBefore (parentNode, newNode, referenceNode) { | |
parentNode.insertBefore(newNode, referenceNode); | |
} | |
function removeChild (node, child) { | |
node.removeChild(child); | |
} | |
function appendChild (node, child) { | |
node.appendChild(child); | |
} | |
function parentNode (node) { | |
return node.parentNode | |
} | |
function nextSibling (node) { | |
return node.nextSibling | |
} | |
function tagName (node) { | |
return node.tagName | |
} | |
function setTextContent (node, text) { | |
node.textContent = text; | |
} | |
function setAttribute (node, key, val) { | |
node.setAttribute(key, val); | |
} | |
var nodeOps = Object.freeze({ | |
createElement: createElement$1, | |
createElementNS: createElementNS, | |
createTextNode: createTextNode, | |
createComment: createComment, | |
insertBefore: insertBefore, | |
removeChild: removeChild, | |
appendChild: appendChild, | |
parentNode: parentNode, | |
nextSibling: nextSibling, | |
tagName: tagName, | |
setTextContent: setTextContent, | |
setAttribute: setAttribute | |
}); | |
/* */ | |
var ref = { | |
create: function create (_, vnode) { | |
registerRef(vnode); | |
}, | |
update: function update (oldVnode, vnode) { | |
if (oldVnode.data.ref !== vnode.data.ref) { | |
registerRef(oldVnode, true); | |
registerRef(vnode); | |
} | |
}, | |
destroy: function destroy (vnode) { | |
registerRef(vnode, true); | |
} | |
}; | |
function registerRef (vnode, isRemoval) { | |
var key = vnode.data.ref; | |
if (!key) { return } | |
var vm = vnode.context; | |
var ref = vnode.componentInstance || vnode.elm; | |
var refs = vm.$refs; | |
if (isRemoval) { | |
if (Array.isArray(refs[key])) { | |
remove$1(refs[key], ref); | |
} else if (refs[key] === ref) { | |
refs[key] = undefined; | |
} | |
} else { | |
if (vnode.data.refInFor) { | |
if (Array.isArray(refs[key]) && refs[key].indexOf(ref) < 0) { | |
refs[key].push(ref); | |
} else { | |
refs[key] = [ref]; | |
} | |
} else { | |
refs[key] = ref; | |
} | |
} | |
} | |
/** | |
* Virtual DOM patching algorithm based on Snabbdom by | |
* Simon Friis Vindum (@paldepind) | |
* Licensed under the MIT License | |
* https://github.com/paldepind/snabbdom/blob/master/LICENSE | |
* | |
* modified by Evan You (@yyx990803) | |
* | |
/* | |
* Not type-checking this because this file is perf-critical and the cost | |
* of making flow understand it is not worth it. | |
*/ | |
var emptyNode = new VNode('', {}, []); | |
var hooks$1 = ['create', 'activate', 'update', 'remove', 'destroy']; | |
function isUndef (s) { | |
return s == null | |
} | |
function isDef (s) { | |
return s != null | |
} | |
function sameVnode (vnode1, vnode2) { | |
return ( | |
vnode1.key === vnode2.key && | |
vnode1.tag === vnode2.tag && | |
vnode1.isComment === vnode2.isComment && | |
!vnode1.data === !vnode2.data | |
) | |
} | |
function createKeyToOldIdx (children, beginIdx, endIdx) { | |
var i, key; | |
var map = {}; | |
for (i = beginIdx; i <= endIdx; ++i) { | |
key = children[i].key; | |
if (isDef(key)) { map[key] = i; } | |
} | |
return map | |
} | |
function createPatchFunction (backend) { | |
var i, j; | |
var cbs = {}; | |
var modules = backend.modules; | |
var nodeOps = backend.nodeOps; | |
for (i = 0; i < hooks$1.length; ++i) { | |
cbs[hooks$1[i]] = []; | |
for (j = 0; j < modules.length; ++j) { | |
if (modules[j][hooks$1[i]] !== undefined) { cbs[hooks$1[i]].push(modules[j][hooks$1[i]]); } | |
} | |
} | |
function emptyNodeAt (elm) { | |
return new VNode(nodeOps.tagName(elm).toLowerCase(), {}, [], undefined, elm) | |
} | |
function createRmCb (childElm, listeners) { | |
function remove$$1 () { | |
if (--remove$$1.listeners === 0) { | |
removeNode(childElm); | |
} | |
} | |
remove$$1.listeners = listeners; | |
return remove$$1 | |
} | |
function removeNode (el) { | |
var parent = nodeOps.parentNode(el); | |
// element may have already been removed due to v-html / v-text | |
if (parent) { | |
nodeOps.removeChild(parent, el); | |
} | |
} | |
var inPre = 0; | |
function createElm (vnode, insertedVnodeQueue, parentElm, refElm, nested) { | |
vnode.isRootInsert = !nested; // for transition enter check | |
if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) { | |
return | |
} | |
var data = vnode.data; | |
var children = vnode.children; | |
var tag = vnode.tag; | |
if (isDef(tag)) { | |
{ | |
if (data && data.pre) { | |
inPre++; | |
} | |
if ( | |
!inPre && | |
!vnode.ns && | |
!(config.ignoredElements.length && config.ignoredElements.indexOf(tag) > -1) && | |
config.isUnknownElement(tag) | |
) { | |
warn( | |
'Unknown custom element: <' + tag + '> - did you ' + | |
'register the component correctly? For recursive components, ' + | |
'make sure to provide the "name" option.', | |
vnode.context | |
); | |
} | |
} | |
vnode.elm = vnode.ns | |
? nodeOps.createElementNS(vnode.ns, tag) | |
: nodeOps.createElement(tag, vnode); | |
setScope(vnode); | |
/* istanbul ignore if */ | |
{ | |
createChildren(vnode, children, insertedVnodeQueue); | |
if (isDef(data)) { | |
invokeCreateHooks(vnode, insertedVnodeQueue); | |
} | |
insert(parentElm, vnode.elm, refElm); | |
} | |
if ("development" !== 'production' && data && data.pre) { | |
inPre--; | |
} | |
} else if (vnode.isComment) { | |
vnode.elm = nodeOps.createComment(vnode.text); | |
insert(parentElm, vnode.elm, refElm); | |
} else { | |
vnode.elm = nodeOps.createTextNode(vnode.text); | |
insert(parentElm, vnode.elm, refElm); | |
} | |
} | |
function createComponent (vnode, insertedVnodeQueue, parentElm, refElm) { | |
var i = vnode.data; | |
if (isDef(i)) { | |
var isReactivated = isDef(vnode.componentInstance) && i.keepAlive; | |
if (isDef(i = i.hook) && isDef(i = i.init)) { | |
i(vnode, false /* hydrating */, parentElm, refElm); | |
} | |
// after calling the init hook, if the vnode is a child component | |
// it should've created a child instance and mounted it. the child | |
// component also has set the placeholder vnode's elm. | |
// in that case we can just return the element and be done. | |
if (isDef(vnode.componentInstance)) { | |
initComponent(vnode, insertedVnodeQueue); | |
if (isReactivated) { | |
reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm); | |
} | |
return true | |
} | |
} | |
} | |
function initComponent (vnode, insertedVnodeQueue) { | |
if (vnode.data.pendingInsert) { | |
insertedVnodeQueue.push.apply(insertedVnodeQueue, vnode.data.pendingInsert); | |
} | |
vnode.elm = vnode.componentInstance.$el; | |
if (isPatchable(vnode)) { | |
invokeCreateHooks(vnode, insertedVnodeQueue); | |
setScope(vnode); | |
} else { | |
// empty component root. | |
// skip all element-related modules except for ref (#3455) | |
registerRef(vnode); | |
// make sure to invoke the insert hook | |
insertedVnodeQueue.push(vnode); | |
} | |
} | |
function reactivateComponent (vnode, insertedVnodeQueue, parentElm, refElm) { | |
var i; | |
// hack for #4339: a reactivated component with inner transition | |
// does not trigger because the inner node's created hooks are not called | |
// again. It's not ideal to involve module-specific logic in here but | |
// there doesn't seem to be a better way to do it. | |
var innerNode = vnode; | |
while (innerNode.componentInstance) { | |
innerNode = innerNode.componentInstance._vnode; | |
if (isDef(i = innerNode.data) && isDef(i = i.transition)) { | |
for (i = 0; i < cbs.activate.length; ++i) { | |
cbs.activate[i](emptyNode, innerNode); | |
} | |
insertedVnodeQueue.push(innerNode); | |
break | |
} | |
} | |
// unlike a newly created component, | |
// a reactivated keep-alive component doesn't insert itself | |
insert(parentElm, vnode.elm, refElm); | |
} | |
function insert (parent, elm, ref) { | |
if (parent) { | |
if (ref) { | |
nodeOps.insertBefore(parent, elm, ref); | |
} else { | |
nodeOps.appendChild(parent, elm); | |
} | |
} | |
} | |
function createChildren (vnode, children, insertedVnodeQueue) { | |
if (Array.isArray(children)) { | |
for (var i = 0; i < children.length; ++i) { | |
createElm(children[i], insertedVnodeQueue, vnode.elm, null, true); | |
} | |
} else if (isPrimitive(vnode.text)) { | |
nodeOps.appendChild(vnode.elm, nodeOps.createTextNode(vnode.text)); | |
} | |
} | |
function isPatchable (vnode) { | |
while (vnode.componentInstance) { | |
vnode = vnode.componentInstance._vnode; | |
} | |
return isDef(vnode.tag) | |
} | |
function invokeCreateHooks (vnode, insertedVnodeQueue) { | |
for (var i$1 = 0; i$1 < cbs.create.length; ++i$1) { | |
cbs.create[i$1](emptyNode, vnode); | |
} | |
i = vnode.data.hook; // Reuse variable | |
if (isDef(i)) { | |
if (i.create) { i.create(emptyNode, vnode); } | |
if (i.insert) { insertedVnodeQueue.push(vnode); } | |
} | |
} | |
// set scope id attribute for scoped CSS. | |
// this is implemented as a special case to avoid the overhead | |
// of going through the normal attribute patching process. | |
function setScope (vnode) { | |
var i; | |
if (isDef(i = vnode.context) && isDef(i = i.$options._scopeId)) { | |
nodeOps.setAttribute(vnode.elm, i, ''); | |
} | |
if (isDef(i = activeInstance) && | |
i !== vnode.context && | |
isDef(i = i.$options._scopeId)) { | |
nodeOps.setAttribute(vnode.elm, i, ''); | |
} | |
} | |
function addVnodes (parentElm, refElm, vnodes, startIdx, endIdx, insertedVnodeQueue) { | |
for (; startIdx <= endIdx; ++startIdx) { | |
createElm(vnodes[startIdx], insertedVnodeQueue, parentElm, refElm); | |
} | |
} | |
function invokeDestroyHook (vnode) { | |
var i, j; | |
var data = vnode.data; | |
if (isDef(data)) { | |
if (isDef(i = data.hook) && isDef(i = i.destroy)) { i(vnode); } | |
for (i = 0; i < cbs.destroy.length; ++i) { cbs.destroy[i](vnode); } | |
} | |
if (isDef(i = vnode.children)) { | |
for (j = 0; j < vnode.children.length; ++j) { | |
invokeDestroyHook(vnode.children[j]); | |
} | |
} | |
} | |
function removeVnodes (parentElm, vnodes, startIdx, endIdx) { | |
for (; startIdx <= endIdx; ++startIdx) { | |
var ch = vnodes[startIdx]; | |
if (isDef(ch)) { | |
if (isDef(ch.tag)) { | |
removeAndInvokeRemoveHook(ch); | |
invokeDestroyHook(ch); | |
} else { // Text node | |
removeNode(ch.elm); | |
} | |
} | |
} | |
} | |
function removeAndInvokeRemoveHook (vnode, rm) { | |
if (rm || isDef(vnode.data)) { | |
var listeners = cbs.remove.length + 1; | |
if (!rm) { | |
// directly removing | |
rm = createRmCb(vnode.elm, listeners); | |
} else { | |
// we have a recursively passed down rm callback | |
// increase the listeners count | |
rm.listeners += listeners; | |
} | |
// recursively invoke hooks on child component root node | |
if (isDef(i = vnode.componentInstance) && isDef(i = i._vnode) && isDef(i.data)) { | |
removeAndInvokeRemoveHook(i, rm); | |
} | |
for (i = 0; i < cbs.remove.length; ++i) { | |
cbs.remove[i](vnode, rm); | |
} | |
if (isDef(i = vnode.data.hook) && isDef(i = i.remove)) { | |
i(vnode, rm); | |
} else { | |
rm(); | |
} | |
} else { | |
removeNode(vnode.elm); | |
} | |
} | |
function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) { | |
var oldStartIdx = 0; | |
var newStartIdx = 0; | |
var oldEndIdx = oldCh.length - 1; | |
var oldStartVnode = oldCh[0]; | |
var oldEndVnode = oldCh[oldEndIdx]; | |
var newEndIdx = newCh.length - 1; | |
var newStartVnode = newCh[0]; | |
var newEndVnode = newCh[newEndIdx]; | |
var oldKeyToIdx, idxInOld, elmToMove, refElm; | |
// removeOnly is a special flag used only by <transition-group> | |
// to ensure removed elements stay in correct relative positions | |
// during leaving transitions | |
var canMove = !removeOnly; | |
while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) { | |
if (isUndef(oldStartVnode)) { | |
oldStartVnode = oldCh[++oldStartIdx]; // Vnode has been moved left | |
} else if (isUndef(oldEndVnode)) { | |
oldEndVnode = oldCh[--oldEndIdx]; | |
} else if (sameVnode(oldStartVnode, newStartVnode)) { | |
patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue); | |
oldStartVnode = oldCh[++oldStartIdx]; | |
newStartVnode = newCh[++newStartIdx]; | |
} else if (sameVnode(oldEndVnode, newEndVnode)) { | |
patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue); | |
oldEndVnode = oldCh[--oldEndIdx]; | |
newEndVnode = newCh[--newEndIdx]; | |
} else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right | |
patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue); | |
canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm)); | |
oldStartVnode = oldCh[++oldStartIdx]; | |
newEndVnode = newCh[--newEndIdx]; | |
} else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left | |
patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue); | |
canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm); | |
oldEndVnode = oldCh[--oldEndIdx]; | |
newStartVnode = newCh[++newStartIdx]; | |
} else { | |
if (isUndef(oldKeyToIdx)) { oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx); } | |
idxInOld = isDef(newStartVnode.key) ? oldKeyToIdx[newStartVnode.key] : null; | |
if (isUndef(idxInOld)) { // New element | |
createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm); | |
newStartVnode = newCh[++newStartIdx]; | |
} else { | |
elmToMove = oldCh[idxInOld]; | |
/* istanbul ignore if */ | |
if ("development" !== 'production' && !elmToMove) { | |
warn( | |
'It seems there are duplicate keys that is causing an update error. ' + | |
'Make sure each v-for item has a unique key.' | |
); | |
} | |
if (sameVnode(elmToMove, newStartVnode)) { | |
patchVnode(elmToMove, newStartVnode, insertedVnodeQueue); | |
oldCh[idxInOld] = undefined; | |
canMove && nodeOps.insertBefore(parentElm, newStartVnode.elm, oldStartVnode.elm); | |
newStartVnode = newCh[++newStartIdx]; | |
} else { | |
// same key but different element. treat as new element | |
createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm); | |
newStartVnode = newCh[++newStartIdx]; | |
} | |
} | |
} | |
} | |
if (oldStartIdx > oldEndIdx) { | |
refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm; | |
addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue); | |
} else if (newStartIdx > newEndIdx) { | |
removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx); | |
} | |
} | |
function patchVnode (oldVnode, vnode, insertedVnodeQueue, removeOnly) { | |
if (oldVnode === vnode) { | |
return | |
} | |
// reuse element for static trees. | |
// note we only do this if the vnode is cloned - | |
// if the new node is not cloned it means the render functions have been | |
// reset by the hot-reload-api and we need to do a proper re-render. | |
if (vnode.isStatic && | |
oldVnode.isStatic && | |
vnode.key === oldVnode.key && | |
(vnode.isCloned || vnode.isOnce)) { | |
vnode.elm = oldVnode.elm; | |
vnode.componentInstance = oldVnode.componentInstance; | |
return | |
} | |
var i; | |
var data = vnode.data; | |
var hasData = isDef(data); | |
if (hasData && isDef(i = data.hook) && isDef(i = i.prepatch)) { | |
i(oldVnode, vnode); | |
} | |
var elm = vnode.elm = oldVnode.elm; | |
var oldCh = oldVnode.children; | |
var ch = vnode.children; | |
if (hasData && isPatchable(vnode)) { | |
for (i = 0; i < cbs.update.length; ++i) { cbs.update[i](oldVnode, vnode); } | |
if (isDef(i = data.hook) && isDef(i = i.update)) { i(oldVnode, vnode); } | |
} | |
if (isUndef(vnode.text)) { | |
if (isDef(oldCh) && isDef(ch)) { | |
if (oldCh !== ch) { updateChildren(elm, oldCh, ch, insertedVnodeQueue, removeOnly); } | |
} else if (isDef(ch)) { | |
if (isDef(oldVnode.text)) { nodeOps.setTextContent(elm, ''); } | |
addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue); | |
} else if (isDef(oldCh)) { | |
removeVnodes(elm, oldCh, 0, oldCh.length - 1); | |
} else if (isDef(oldVnode.text)) { | |
nodeOps.setTextContent(elm, ''); | |
} | |
} else if (oldVnode.text !== vnode.text) { | |
nodeOps.setTextContent(elm, vnode.text); | |
} | |
if (hasData) { | |
if (isDef(i = data.hook) && isDef(i = i.postpatch)) { i(oldVnode, vnode); } | |
} | |
} | |
function invokeInsertHook (vnode, queue, initial) { | |
// delay insert hooks for component root nodes, invoke them after the | |
// element is really inserted | |
if (initial && vnode.parent) { | |
vnode.parent.data.pendingInsert = queue; | |
} else { | |
for (var i = 0; i < queue.length; ++i) { | |
queue[i].data.hook.insert(queue[i]); | |
} | |
} | |
} | |
var bailed = false; | |
// list of modules that can skip create hook during hydration because they | |
// are already rendered on the client or has no need for initialization | |
var isRenderedModule = makeMap('attrs,style,class,staticClass,staticStyle,key'); | |
// Note: this is a browser-only function so we can assume elms are DOM nodes. | |
function hydrate (elm, vnode, insertedVnodeQueue) { | |
{ | |
if (!assertNodeMatch(elm, vnode)) { | |
return false | |
} | |
} | |
vnode.elm = elm; | |
var tag = vnode.tag; | |
var data = vnode.data; | |
var children = vnode.children; | |
if (isDef(data)) { | |
if (isDef(i = data.hook) && isDef(i = i.init)) { i(vnode, true /* hydrating */); } | |
if (isDef(i = vnode.componentInstance)) { | |
// child component. it should have hydrated its own tree. | |
initComponent(vnode, insertedVnodeQueue); | |
return true | |
} | |
} | |
if (isDef(tag)) { | |
if (isDef(children)) { | |
// empty element, allow client to pick up and populate children | |
if (!elm.hasChildNodes()) { | |
createChildren(vnode, children, insertedVnodeQueue); | |
} else { | |
var childrenMatch = true; | |
var childNode = elm.firstChild; | |
for (var i$1 = 0; i$1 < children.length; i$1++) { | |
if (!childNode || !hydrate(childNode, children[i$1], insertedVnodeQueue)) { | |
childrenMatch = false; | |
break | |
} | |
childNode = childNode.nextSibling; | |
} | |
// if childNode is not null, it means the actual childNodes list is | |
// longer than the virtual children list. | |
if (!childrenMatch || childNode) { | |
if ("development" !== 'production' && | |
typeof console !== 'undefined' && | |
!bailed) { | |
bailed = true; | |
console.warn('Parent: ', elm); | |
console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children); | |
} | |
return false | |
} | |
} | |
} | |
if (isDef(data)) { | |
for (var key in data) { | |
if (!isRenderedModule(key)) { | |
invokeCreateHooks(vnode, insertedVnodeQueue); | |
break | |
} | |
} | |
} | |
} else if (elm.data !== vnode.text) { | |
elm.data = vnode.text; | |
} | |
return true | |
} | |
function assertNodeMatch (node, vnode) { | |
if (vnode.tag) { | |
return ( | |
vnode.tag.indexOf('vue-component') === 0 || | |
vnode.tag.toLowerCase() === (node.tagName && node.tagName.toLowerCase()) | |
) | |
} else { | |
return node.nodeType === (vnode.isComment ? 8 : 3) | |
} | |
} | |
return function patch (oldVnode, vnode, hydrating, removeOnly, parentElm, refElm) { | |
if (!vnode) { | |
if (oldVnode) { invokeDestroyHook(oldVnode); } | |
return | |
} | |
var isInitialPatch = false; | |
var insertedVnodeQueue = []; | |
if (!oldVnode) { | |
// empty mount (likely as component), create new root element | |
isInitialPatch = true; | |
createElm(vnode, insertedVnodeQueue, parentElm, refElm); | |
} else { | |
var isRealElement = isDef(oldVnode.nodeType); | |
if (!isRealElement && sameVnode(oldVnode, vnode)) { | |
// patch existing root node | |
patchVnode(oldVnode, vnode, insertedVnodeQueue, removeOnly); | |
} else { | |
if (isRealElement) { | |
// mounting to a real element | |
// check if this is server-rendered content and if we can perform | |
// a successful hydration. | |
if (oldVnode.nodeType === 1 && oldVnode.hasAttribute('server-rendered')) { | |
oldVnode.removeAttribute('server-rendered'); | |
hydrating = true; | |
} | |
if (hydrating) { | |
if (hydrate(oldVnode, vnode, insertedVnodeQueue)) { | |
invokeInsertHook(vnode, insertedVnodeQueue, true); | |
return oldVnode | |
} else { | |
warn( | |
'The client-side rendered virtual DOM tree is not matching ' + | |
'server-rendered content. This is likely caused by incorrect ' + | |
'HTML markup, for example nesting block-level elements inside ' + | |
'<p>, or missing <tbody>. Bailing hydration and performing ' + | |
'full client-side render.' | |
); | |
} | |
} | |
// either not server-rendered, or hydration failed. | |
// create an empty node and replace it | |
oldVnode = emptyNodeAt(oldVnode); | |
} | |
// replacing existing element | |
var oldElm = oldVnode.elm; | |
var parentElm$1 = nodeOps.parentNode(oldElm); | |
createElm( | |
vnode, | |
insertedVnodeQueue, | |
// extremely rare edge case: do not insert if old element is in a | |
// leaving transition. Only happens when combining transition + | |
// keep-alive + HOCs. (#4590) | |
oldElm._leaveCb ? null : parentElm$1, | |
nodeOps.nextSibling(oldElm) | |
); | |
if (vnode.parent) { | |
// component root element replaced. | |
// update parent placeholder node element, recursively | |
var ancestor = vnode.parent; | |
while (ancestor) { | |
ancestor.elm = vnode.elm; | |
ancestor = ancestor.parent; | |
} | |
if (isPatchable(vnode)) { | |
for (var i = 0; i < cbs.create.length; ++i) { | |
cbs.create[i](emptyNode, vnode.parent); | |
} | |
} | |
} | |
if (parentElm$1 !== null) { | |
removeVnodes(parentElm$1, [oldVnode], 0, 0); | |
} else if (isDef(oldVnode.tag)) { | |
invokeDestroyHook(oldVnode); | |
} | |
} | |
} | |
invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch); | |
return vnode.elm | |
} | |
} | |
/* */ | |
var directives = { | |
create: updateDirectives, | |
update: updateDirectives, | |
destroy: function unbindDirectives (vnode) { | |
updateDirectives(vnode, emptyNode); | |
} | |
}; | |
function updateDirectives (oldVnode, vnode) { | |
if (oldVnode.data.directives || vnode.data.directives) { | |
_update(oldVnode, vnode); | |
} | |
} | |
function _update (oldVnode, vnode) { | |
var isCreate = oldVnode === emptyNode; | |
var isDestroy = vnode === emptyNode; | |
var oldDirs = normalizeDirectives$1(oldVnode.data.directives, oldVnode.context); | |
var newDirs = normalizeDirectives$1(vnode.data.directives, vnode.context); | |
var dirsWithInsert = []; | |
var dirsWithPostpatch = []; | |
var key, oldDir, dir; | |
for (key in newDirs) { | |
oldDir = oldDirs[key]; | |
dir = newDirs[key]; | |
if (!oldDir) { | |
// new directive, bind | |
callHook$1(dir, 'bind', vnode, oldVnode); | |
if (dir.def && dir.def.inserted) { | |
dirsWithInsert.push(dir); | |
} | |
} else { | |
// existing directive, update | |
dir.oldValue = oldDir.value; | |
callHook$1(dir, 'update', vnode, oldVnode); | |
if (dir.def && dir.def.componentUpdated) { | |
dirsWithPostpatch.push(dir); | |
} | |
} | |
} | |
if (dirsWithInsert.length) { | |
var callInsert = function () { | |
for (var i = 0; i < dirsWithInsert.length; i++) { | |
callHook$1(dirsWithInsert[i], 'inserted', vnode, oldVnode); | |
} | |
}; | |
if (isCreate) { | |
mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'insert', callInsert, 'dir-insert'); | |
} else { | |
callInsert(); | |
} | |
} | |
if (dirsWithPostpatch.length) { | |
mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'postpatch', function () { | |
for (var i = 0; i < dirsWithPostpatch.length; i++) { | |
callHook$1(dirsWithPostpatch[i], 'componentUpdated', vnode, oldVnode); | |
} | |
}, 'dir-postpatch'); | |
} | |
if (!isCreate) { | |
for (key in oldDirs) { | |
if (!newDirs[key]) { | |
// no longer present, unbind | |
callHook$1(oldDirs[key], 'unbind', oldVnode, oldVnode, isDestroy); | |
} | |
} | |
} | |
} | |
var emptyModifiers = Object.create(null); | |
function normalizeDirectives$1 ( | |
dirs, | |
vm | |
) { | |
var res = Object.create(null); | |
if (!dirs) { | |
return res | |
} | |
var i, dir; | |
for (i = 0; i < dirs.length; i++) { | |
dir = dirs[i]; | |
if (!dir.modifiers) { | |
dir.modifiers = emptyModifiers; | |
} | |
res[getRawDirName(dir)] = dir; | |
dir.def = resolveAsset(vm.$options, 'directives', dir.name, true); | |
} | |
return res | |
} | |
function getRawDirName (dir) { | |
return dir.rawName || ((dir.name) + "." + (Object.keys(dir.modifiers || {}).join('.'))) | |
} | |
function callHook$1 (dir, hook, vnode, oldVnode, isDestroy) { | |
var fn = dir.def && dir.def[hook]; | |
if (fn) { | |
fn(vnode.elm, dir, vnode, oldVnode, isDestroy); | |
} | |
} | |
var baseModules = [ | |
ref, | |
directives | |
]; | |
/* */ | |
function updateAttrs (oldVnode, vnode) { | |
if (!oldVnode.data.attrs && !vnode.data.attrs) { | |
return | |
} | |
var key, cur, old; | |
var elm = vnode.elm; | |
var oldAttrs = oldVnode.data.attrs || {}; | |
var attrs = vnode.data.attrs || {}; | |
// clone observed objects, as the user probably wants to mutate it | |
if (attrs.__ob__) { | |
attrs = vnode.data.attrs = extend({}, attrs); | |
} | |
for (key in attrs) { | |
cur = attrs[key]; | |
old = oldAttrs[key]; | |
if (old !== cur) { | |
setAttr(elm, key, cur); | |
} | |
} | |
// #4391: in IE9, setting type can reset value for input[type=radio] | |
/* istanbul ignore if */ | |
if (isIE9 && attrs.value !== oldAttrs.value) { | |
setAttr(elm, 'value', attrs.value); | |
} | |
for (key in oldAttrs) { | |
if (attrs[key] == null) { | |
if (isXlink(key)) { | |
elm.removeAttributeNS(xlinkNS, getXlinkProp(key)); | |
} else if (!isEnumeratedAttr(key)) { | |
elm.removeAttribute(key); | |
} | |
} | |
} | |
} | |
function setAttr (el, key, value) { | |
if (isBooleanAttr(key)) { | |
// set attribute for blank value | |
// e.g. <option disabled>Select one</option> | |
if (isFalsyAttrValue(value)) { | |
el.removeAttribute(key); | |
} else { | |
el.setAttribute(key, key); | |
} | |
} else if (isEnumeratedAttr(key)) { | |
el.setAttribute(key, isFalsyAttrValue(value) || value === 'false' ? 'false' : 'true'); | |
} else if (isXlink(key)) { | |
if (isFalsyAttrValue(value)) { | |
el.removeAttributeNS(xlinkNS, getXlinkProp(key)); | |
} else { | |
el.setAttributeNS(xlinkNS, key, value); | |
} | |
} else { | |
if (isFalsyAttrValue(value)) { | |
el.removeAttribute(key); | |
} else { | |
el.setAttribute(key, value); | |
} | |
} | |
} | |
var attrs = { | |
create: updateAttrs, | |
update: updateAttrs | |
}; | |
/* */ | |
function updateClass (oldVnode, vnode) { | |
var el = vnode.elm; | |
var data = vnode.data; | |
var oldData = oldVnode.data; | |
if (!data.staticClass && !data.class && | |
(!oldData || (!oldData.staticClass && !oldData.class))) { | |
return | |
} | |
var cls = genClassForVnode(vnode); | |
// handle transition classes | |
var transitionClass = el._transitionClasses; | |
if (transitionClass) { | |
cls = concat(cls, stringifyClass(transitionClass)); | |
} | |
// set the class | |
if (cls !== el._prevClass) { | |
el.setAttribute('class', cls); | |
el._prevClass = cls; | |
} | |
} | |
var klass = { | |
create: updateClass, | |
update: updateClass | |
}; | |
/* */ | |
var target$1; | |
function add$2 ( | |
event, | |
handler, | |
once, | |
capture | |
) { | |
if (once) { | |
var oldHandler = handler; | |
var _target = target$1; // save current target element in closure | |
handler = function (ev) { | |
remove$3(event, handler, capture, _target); | |
arguments.length === 1 | |
? oldHandler(ev) | |
: oldHandler.apply(null, arguments); | |
}; | |
} | |
target$1.addEventListener(event, handler, capture); | |
} | |
function remove$3 ( | |
event, | |
handler, | |
capture, | |
_target | |
) { | |
(_target || target$1).removeEventListener(event, handler, capture); | |
} | |
function updateDOMListeners (oldVnode, vnode) { | |
if (!oldVnode.data.on && !vnode.data.on) { | |
return | |
} | |
var on = vnode.data.on || {}; | |
var oldOn = oldVnode.data.on || {}; | |
target$1 = vnode.elm; | |
updateListeners(on, oldOn, add$2, remove$3, vnode.context); | |
} | |
var events = { | |
create: updateDOMListeners, | |
update: updateDOMListeners | |
}; | |
/* */ | |
function updateDOMProps (oldVnode, vnode) { | |
if (!oldVnode.data.domProps && !vnode.data.domProps) { | |
return | |
} | |
var key, cur; | |
var elm = vnode.elm; | |
var oldProps = oldVnode.data.domProps || {}; | |
var props = vnode.data.domProps || {}; | |
// clone observed objects, as the user probably wants to mutate it | |
if (props.__ob__) { | |
props = vnode.data.domProps = extend({}, props); | |
} | |
for (key in oldProps) { | |
if (props[key] == null) { | |
elm[key] = ''; | |
} | |
} | |
for (key in props) { | |
cur = props[key]; | |
// ignore children if the node has textContent or innerHTML, | |
// as these will throw away existing DOM nodes and cause removal errors | |
// on subsequent patches (#3360) | |
if (key === 'textContent' || key === 'innerHTML') { | |
if (vnode.children) { vnode.children.length = 0; } | |
if (cur === oldProps[key]) { continue } | |
} | |
if (key === 'value') { | |
// store value as _value as well since | |
// non-string values will be stringified | |
elm._value = cur; | |
// avoid resetting cursor position when value is the same | |
var strCur = cur == null ? '' : String(cur); | |
if (shouldUpdateValue(elm, vnode, strCur)) { | |
elm.value = strCur; | |
} | |
} else { | |
elm[key] = cur; | |
} | |
} | |
} | |
// check platforms/web/util/attrs.js acceptValue | |
function shouldUpdateValue ( | |
elm, | |
vnode, | |
checkVal | |
) { | |
return (!elm.composing && ( | |
vnode.tag === 'option' || | |
isDirty(elm, checkVal) || | |
isInputChanged(vnode, checkVal) | |
)) | |
} | |
function isDirty (elm, checkVal) { | |
// return true when textbox (.number and .trim) loses focus and its value is not equal to the updated value | |
return document.activeElement !== elm && elm.value !== checkVal | |
} | |
function isInputChanged (vnode, newVal) { | |
var value = vnode.elm.value; | |
var modifiers = vnode.elm._vModifiers; // injected by v-model runtime | |
if ((modifiers && modifiers.number) || vnode.elm.type === 'number') { | |
return toNumber(value) !== toNumber(newVal) | |
} | |
if (modifiers && modifiers.trim) { | |
return value.trim() !== newVal.trim() | |
} | |
return value !== newVal | |
} | |
var domProps = { | |
create: updateDOMProps, | |
update: updateDOMProps | |
}; | |
/* */ | |
var parseStyleText = cached(function (cssText) { | |
var res = {}; | |
var listDelimiter = /;(?![^(]*\))/g; | |
var propertyDelimiter = /:(.+)/; | |
cssText.split(listDelimiter).forEach(function (item) { | |
if (item) { | |
var tmp = item.split(propertyDelimiter); | |
tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim()); | |
} | |
}); | |
return res | |
}); | |
// merge static and dynamic style data on the same vnode | |
function normalizeStyleData (data) { | |
var style = normalizeStyleBinding(data.style); | |
// static style is pre-processed into an object during compilation | |
// and is always a fresh object, so it's safe to merge into it | |
return data.staticStyle | |
? extend(data.staticStyle, style) | |
: style | |
} | |
// normalize possible array / string values into Object | |
function normalizeStyleBinding (bindingStyle) { | |
if (Array.isArray(bindingStyle)) { | |
return toObject(bindingStyle) | |
} | |
if (typeof bindingStyle === 'string') { | |
return parseStyleText(bindingStyle) | |
} | |
return bindingStyle | |
} | |
/** | |
* parent component style should be after child's | |
* so that parent component's style could override it | |
*/ | |
function getStyle (vnode, checkChild) { | |
var res = {}; | |
var styleData; | |
if (checkChild) { | |
var childNode = vnode; | |
while (childNode.componentInstance) { | |
childNode = childNode.componentInstance._vnode; | |
if (childNode.data && (styleData = normalizeStyleData(childNode.data))) { | |
extend(res, styleData); | |
} | |
} | |
} | |
if ((styleData = normalizeStyleData(vnode.data))) { | |
extend(res, styleData); | |
} | |
var parentNode = vnode; | |
while ((parentNode = parentNode.parent)) { | |
if (parentNode.data && (styleData = normalizeStyleData(parentNode.data))) { | |
extend(res, styleData); | |
} | |
} | |
return res | |
} | |
/* */ | |
var cssVarRE = /^--/; | |
var importantRE = /\s*!important$/; | |
var setProp = function (el, name, val) { | |
/* istanbul ignore if */ | |
if (cssVarRE.test(name)) { | |
el.style.setProperty(name, val); | |
} else if (importantRE.test(val)) { | |
el.style.setProperty(name, val.replace(importantRE, ''), 'important'); | |
} else { | |
el.style[normalize(name)] = val; | |
} | |
}; | |
var prefixes = ['Webkit', 'Moz', 'ms']; | |
var testEl; | |
var normalize = cached(function (prop) { | |
testEl = testEl || document.createElement('div'); | |
prop = camelize(prop); | |
if (prop !== 'filter' && (prop in testEl.style)) { | |
return prop | |
} | |
var upper = prop.charAt(0).toUpperCase() + prop.slice(1); | |
for (var i = 0; i < prefixes.length; i++) { | |
var prefixed = prefixes[i] + upper; | |
if (prefixed in testEl.style) { | |
return prefixed | |
} | |
} | |
}); | |
function updateStyle (oldVnode, vnode) { | |
var data = vnode.data; | |
var oldData = oldVnode.data; | |
if (!data.staticStyle && !data.style && | |
!oldData.staticStyle && !oldData.style) { | |
return | |
} | |
var cur, name; | |
var el = vnode.elm; | |
var oldStaticStyle = oldVnode.data.staticStyle; | |
var oldStyleBinding = oldVnode.data.style || {}; | |
// if static style exists, stylebinding already merged into it when doing normalizeStyleData | |
var oldStyle = oldStaticStyle || oldStyleBinding; | |
var style = normalizeStyleBinding(vnode.data.style) || {}; | |
vnode.data.style = style.__ob__ ? extend({}, style) : style; | |
var newStyle = getStyle(vnode, true); | |
for (name in oldStyle) { | |
if (newStyle[name] == null) { | |
setProp(el, name, ''); | |
} | |
} | |
for (name in newStyle) { | |
cur = newStyle[name]; | |
if (cur !== oldStyle[name]) { | |
// ie9 setting to null has no effect, must use empty string | |
setProp(el, name, cur == null ? '' : cur); | |
} | |
} | |
} | |
var style = { | |
create: updateStyle, | |
update: updateStyle | |
}; | |
/* */ | |
/** | |
* Add class with compatibility for SVG since classList is not supported on | |
* SVG elements in IE | |
*/ | |
function addClass (el, cls) { | |
/* istanbul ignore if */ | |
if (!cls || !cls.trim()) { | |
return | |
} | |
/* istanbul ignore else */ | |
if (el.classList) { | |
if (cls.indexOf(' ') > -1) { | |
cls.split(/\s+/).forEach(function (c) { return el.classList.add(c); }); | |
} else { | |
el.classList.add(cls); | |
} | |
} else { | |
var cur = ' ' + el.getAttribute('class') + ' '; | |
if (cur.indexOf(' ' + cls + ' ') < 0) { | |
el.setAttribute('class', (cur + cls).trim()); | |
} | |
} | |
} | |
/** | |
* Remove class with compatibility for SVG since classList is not supported on | |
* SVG elements in IE | |
*/ | |
function removeClass (el, cls) { | |
/* istanbul ignore if */ | |
if (!cls || !cls.trim()) { | |
return | |
} | |
/* istanbul ignore else */ | |
if (el.classList) { | |
if (cls.indexOf(' ') > -1) { | |
cls.split(/\s+/).forEach(function (c) { return el.classList.remove(c); }); | |
} else { | |
el.classList.remove(cls); | |
} | |
} else { | |
var cur = ' ' + el.getAttribute('class') + ' '; | |
var tar = ' ' + cls + ' '; | |
while (cur.indexOf(tar) >= 0) { | |
cur = cur.replace(tar, ' '); | |
} | |
el.setAttribute('class', cur.trim()); | |
} | |
} | |
/* */ | |
var hasTransition = inBrowser && !isIE9; | |
var TRANSITION = 'transition'; | |
var ANIMATION = 'animation'; | |
// Transition property/event sniffing | |
var transitionProp = 'transition'; | |
var transitionEndEvent = 'transitionend'; | |
var animationProp = 'animation'; | |
var animationEndEvent = 'animationend'; | |
if (hasTransition) { | |
/* istanbul ignore if */ | |
if (window.ontransitionend === undefined && | |
window.onwebkittransitionend !== undefined) { | |
transitionProp = 'WebkitTransition'; | |
transitionEndEvent = 'webkitTransitionEnd'; | |
} | |
if (window.onanimationend === undefined && | |
window.onwebkitanimationend !== undefined) { | |
animationProp = 'WebkitAnimation'; | |
animationEndEvent = 'webkitAnimationEnd'; | |
} | |
} | |
// binding to window is necessary to make hot reload work in IE in strict mode | |
var raf = inBrowser && window.requestAnimationFrame | |
? window.requestAnimationFrame.bind(window) | |
: setTimeout; | |
function nextFrame (fn) { | |
raf(function () { | |
raf(fn); | |
}); | |
} | |
function addTransitionClass (el, cls) { | |
(el._transitionClasses || (el._transitionClasses = [])).push(cls); | |
addClass(el, cls); | |
} | |
function removeTransitionClass (el, cls) { | |
if (el._transitionClasses) { | |
remove$1(el._transitionClasses, cls); | |
} | |
removeClass(el, cls); | |
} | |
function whenTransitionEnds ( | |
el, | |
expectedType, | |
cb | |
) { | |
var ref = getTransitionInfo(el, expectedType); | |
var type = ref.type; | |
var timeout = ref.timeout; | |
var propCount = ref.propCount; | |
if (!type) { return cb() } | |
var event = type === TRANSITION ? transitionEndEvent : animationEndEvent; | |
var ended = 0; | |
var end = function () { | |
el.removeEventListener(event, onEnd); | |
cb(); | |
}; | |
var onEnd = function (e) { | |
if (e.target === el) { | |
if (++ended >= propCount) { | |
end(); | |
} | |
} | |
}; | |
setTimeout(function () { | |
if (ended < propCount) { | |
end(); | |
} | |
}, timeout + 1); | |
el.addEventListener(event, onEnd); | |
} | |
var transformRE = /\b(transform|all)(,|$)/; | |
function getTransitionInfo (el, expectedType) { | |
var styles = window.getComputedStyle(el); | |
var transitioneDelays = styles[transitionProp + 'Delay'].split(', '); | |
var transitionDurations = styles[transitionProp + 'Duration'].split(', '); | |
var transitionTimeout = getTimeout(transitioneDelays, transitionDurations); | |
var animationDelays = styles[animationProp + 'Delay'].split(', '); | |
var animationDurations = styles[animationProp + 'Duration'].split(', '); | |
var animationTimeout = getTimeout(animationDelays, animationDurations); | |
var type; | |
var timeout = 0; | |
var propCount = 0; | |
/* istanbul ignore if */ | |
if (expectedType === TRANSITION) { | |
if (transitionTimeout > 0) { | |
type = TRANSITION; | |
timeout = transitionTimeout; | |
propCount = transitionDurations.length; | |
} | |
} else if (expectedType === ANIMATION) { | |
if (animationTimeout > 0) { | |
type = ANIMATION; | |
timeout = animationTimeout; | |
propCount = animationDurations.length; | |
} | |
} else { | |
timeout = Math.max(transitionTimeout, animationTimeout); | |
type = timeout > 0 | |
? transitionTimeout > animationTimeout | |
? TRANSITION | |
: ANIMATION | |
: null; | |
propCount = type | |
? type === TRANSITION | |
? transitionDurations.length | |
: animationDurations.length | |
: 0; | |
} | |
var hasTransform = | |
type === TRANSITION && | |
transformRE.test(styles[transitionProp + 'Property']); | |
return { | |
type: type, | |
timeout: timeout, | |
propCount: propCount, | |
hasTransform: hasTransform | |
} | |
} | |
function getTimeout (delays, durations) { | |
/* istanbul ignore next */ | |
while (delays.length < durations.length) { | |
delays = delays.concat(delays); | |
} | |
return Math.max.apply(null, durations.map(function (d, i) { | |
return toMs(d) + toMs(delays[i]) | |
})) | |
} | |
function toMs (s) { | |
return Number(s.slice(0, -1)) * 1000 | |
} | |
/* */ | |
function enter (vnode, toggleDisplay) { | |
var el = vnode.elm; | |
// call leave callback now | |
if (el._leaveCb) { | |
el._leaveCb.cancelled = true; | |
el._leaveCb(); | |
} | |
var data = resolveTransition(vnode.data.transition); | |
if (!data) { | |
return | |
} | |
/* istanbul ignore if */ | |
if (el._enterCb || el.nodeType !== 1) { | |
return | |
} | |
var css = data.css; | |
var type = data.type; | |
var enterClass = data.enterClass; | |
var enterToClass = data.enterToClass; | |
var enterActiveClass = data.enterActiveClass; | |
var appearClass = data.appearClass; | |
var appearToClass = data.appearToClass; | |
var appearActiveClass = data.appearActiveClass; | |
var beforeEnter = data.beforeEnter; | |
var enter = data.enter; | |
var afterEnter = data.afterEnter; | |
var enterCancelled = data.enterCancelled; | |
var beforeAppear = data.beforeAppear; | |
var appear = data.appear; | |
var afterAppear = data.afterAppear; | |
var appearCancelled = data.appearCancelled; | |
// activeInstance will always be the <transition> component managing this | |
// transition. One edge case to check is when the <transition> is placed | |
// as the root node of a child component. In that case we need to check | |
// <transition>'s parent for appear check. | |
var context = activeInstance; | |
var transitionNode = activeInstance.$vnode; | |
while (transitionNode && transitionNode.parent) { | |
transitionNode = transitionNode.parent; | |
context = transitionNode.context; | |
} | |
var isAppear = !context._isMounted || !vnode.isRootInsert; | |
if (isAppear && !appear && appear !== '') { | |
return | |
} | |
var startClass = isAppear ? appearClass : enterClass; | |
var activeClass = isAppear ? appearActiveClass : enterActiveClass; | |
var toClass = isAppear ? appearToClass : enterToClass; | |
var beforeEnterHook = isAppear ? (beforeAppear || beforeEnter) : beforeEnter; | |
var enterHook = isAppear ? (typeof appear === 'function' ? appear : enter) : enter; | |
var afterEnterHook = isAppear ? (afterAppear || afterEnter) : afterEnter; | |
var enterCancelledHook = isAppear ? (appearCancelled || enterCancelled) : enterCancelled; | |
var expectsCSS = css !== false && !isIE9; | |
var userWantsControl = | |
enterHook && | |
// enterHook may be a bound method which exposes | |
// the length of original fn as _length | |
(enterHook._length || enterHook.length) > 1; | |
var cb = el._enterCb = once(function () { | |
if (expectsCSS) { | |
removeTransitionClass(el, toClass); | |
removeTransitionClass(el, activeClass); | |
} | |
if (cb.cancelled) { | |
if (expectsCSS) { | |
removeTransitionClass(el, startClass); | |
} | |
enterCancelledHook && enterCancelledHook(el); | |
} else { | |
afterEnterHook && afterEnterHook(el); | |
} | |
el._enterCb = null; | |
}); | |
if (!vnode.data.show) { | |
// remove pending leave element on enter by injecting an insert hook | |
mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'insert', function () { | |
var parent = el.parentNode; | |
var pendingNode = parent && parent._pending && parent._pending[vnode.key]; | |
if (pendingNode && | |
pendingNode.tag === vnode.tag && | |
pendingNode.elm._leaveCb) { | |
pendingNode.elm._leaveCb(); | |
} | |
enterHook && enterHook(el, cb); | |
}, 'transition-insert'); | |
} | |
// start enter transition | |
beforeEnterHook && beforeEnterHook(el); | |
if (expectsCSS) { | |
addTransitionClass(el, startClass); | |
addTransitionClass(el, activeClass); | |
nextFrame(function () { | |
addTransitionClass(el, toClass); | |
removeTransitionClass(el, startClass); | |
if (!cb.cancelled && !userWantsControl) { | |
whenTransitionEnds(el, type, cb); | |
} | |
}); | |
} | |
if (vnode.data.show) { | |
toggleDisplay && toggleDisplay(); | |
enterHook && enterHook(el, cb); | |
} | |
if (!expectsCSS && !userWantsControl) { | |
cb(); | |
} | |
} | |
function leave (vnode, rm) { | |
var el = vnode.elm; | |
// call enter callback now | |
if (el._enterCb) { | |
el._enterCb.cancelled = true; | |
el._enterCb(); | |
} | |
var data = resolveTransition(vnode.data.transition); | |
if (!data) { | |
return rm() | |
} | |
/* istanbul ignore if */ | |
if (el._leaveCb || el.nodeType !== 1) { | |
return | |
} | |
var css = data.css; | |
var type = data.type; | |
var leaveClass = data.leaveClass; | |
var leaveToClass = data.leaveToClass; | |
var leaveActiveClass = data.leaveActiveClass; | |
var beforeLeave = data.beforeLeave; | |
var leave = data.leave; | |
var afterLeave = data.afterLeave; | |
var leaveCancelled = data.leaveCancelled; | |
var delayLeave = data.delayLeave; | |
var expectsCSS = css !== false && !isIE9; | |
var userWantsControl = | |
leave && | |
// leave hook may be a bound method which exposes | |
// the length of original fn as _length | |
(leave._length || leave.length) > 1; | |
var cb = el._leaveCb = once(function () { | |
if (el.parentNode && el.parentNode._pending) { | |
el.parentNode._pending[vnode.key] = null; | |
} | |
if (expectsCSS) { | |
removeTransitionClass(el, leaveToClass); | |
removeTransitionClass(el, leaveActiveClass); | |
} | |
if (cb.cancelled) { | |
if (expectsCSS) { | |
removeTransitionClass(el, leaveClass); | |
} | |
leaveCancelled && leaveCancelled(el); | |
} else { | |
rm(); | |
afterLeave && afterLeave(el); | |
} | |
el._leaveCb = null; | |
}); | |
if (delayLeave) { | |
delayLeave(performLeave); | |
} else { | |
performLeave(); | |
} | |
function performLeave () { | |
// the delayed leave may have already been cancelled | |
if (cb.cancelled) { | |
return | |
} | |
// record leaving element | |
if (!vnode.data.show) { | |
(el.parentNode._pending || (el.parentNode._pending = {}))[vnode.key] = vnode; | |
} | |
beforeLeave && beforeLeave(el); | |
if (expectsCSS) { | |
addTransitionClass(el, leaveClass); | |
addTransitionClass(el, leaveActiveClass); | |
nextFrame(function () { | |
addTransitionClass(el, leaveToClass); | |
removeTransitionClass(el, leaveClass); | |
if (!cb.cancelled && !userWantsControl) { | |
whenTransitionEnds(el, type, cb); | |
} | |
}); | |
} | |
leave && leave(el, cb); | |
if (!expectsCSS && !userWantsControl) { | |
cb(); | |
} | |
} | |
} | |
function resolveTransition (def$$1) { | |
if (!def$$1) { | |
return | |
} | |
/* istanbul ignore else */ | |
if (typeof def$$1 === 'object') { | |
var res = {}; | |
if (def$$1.css !== false) { | |
extend(res, autoCssTransition(def$$1.name || 'v')); | |
} | |
extend(res, def$$1); | |
return res | |
} else if (typeof def$$1 === 'string') { | |
return autoCssTransition(def$$1) | |
} | |
} | |
var autoCssTransition = cached(function (name) { | |
return { | |
enterClass: (name + "-enter"), | |
leaveClass: (name + "-leave"), | |
appearClass: (name + "-enter"), | |
enterToClass: (name + "-enter-to"), | |
leaveToClass: (name + "-leave-to"), | |
appearToClass: (name + "-enter-to"), | |
enterActiveClass: (name + "-enter-active"), | |
leaveActiveClass: (name + "-leave-active"), | |
appearActiveClass: (name + "-enter-active") | |
} | |
}); | |
function once (fn) { | |
var called = false; | |
return function () { | |
if (!called) { | |
called = true; | |
fn(); | |
} | |
} | |
} | |
function _enter (_, vnode) { | |
if (!vnode.data.show) { | |
enter(vnode); | |
} | |
} | |
var transition = inBrowser ? { | |
create: _enter, | |
activate: _enter, | |
remove: function remove (vnode, rm) { | |
/* istanbul ignore else */ | |
if (!vnode.data.show) { | |
leave(vnode, rm); | |
} else { | |
rm(); | |
} | |
} | |
} : {}; | |
var platformModules = [ | |
attrs, | |
klass, | |
events, | |
domProps, | |
style, | |
transition | |
]; | |
/* */ | |
// the directive module should be applied last, after all | |
// built-in modules have been applied. | |
var modules = platformModules.concat(baseModules); | |
var patch$1 = createPatchFunction({ nodeOps: nodeOps, modules: modules }); | |
/** | |
* Not type checking this file because flow doesn't like attaching | |
* properties to Elements. | |
*/ | |
var modelableTagRE = /^input|select|textarea|vue-component-[0-9]+(-[0-9a-zA-Z_-]*)?$/; | |
/* istanbul ignore if */ | |
if (isIE9) { | |
// http://www.matts411.com/post/internet-explorer-9-oninput/ | |
document.addEventListener('selectionchange', function () { | |
var el = document.activeElement; | |
if (el && el.vmodel) { | |
trigger(el, 'input'); | |
} | |
}); | |
} | |
var model = { | |
inserted: function inserted (el, binding, vnode) { | |
{ | |
if (!modelableTagRE.test(vnode.tag)) { | |
warn( | |
"v-model is not supported on element type: <" + (vnode.tag) + ">. " + | |
'If you are working with contenteditable, it\'s recommended to ' + | |
'wrap a library dedicated for that purpose inside a custom component.', | |
vnode.context | |
); | |
} | |
} | |
if (vnode.tag === 'select') { | |
var cb = function () { | |
setSelected(el, binding, vnode.context); | |
}; | |
cb(); | |
/* istanbul ignore if */ | |
if (isIE || isEdge) { | |
setTimeout(cb, 0); | |
} | |
} else if (vnode.tag === 'textarea' || el.type === 'text') { | |
el._vModifiers = binding.modifiers; | |
if (!binding.modifiers.lazy) { | |
if (!isAndroid) { | |
el.addEventListener('compositionstart', onCompositionStart); | |
el.addEventListener('compositionend', onCompositionEnd); | |
} | |
/* istanbul ignore if */ | |
if (isIE9) { | |
el.vmodel = true; | |
} | |
} | |
} | |
}, | |
componentUpdated: function componentUpdated (el, binding, vnode) { | |
if (vnode.tag === 'select') { | |
setSelected(el, binding, vnode.context); | |
// in case the options rendered by v-for have changed, | |
// it's possible that the value is out-of-sync with the rendered options. | |
// detect such cases and filter out values that no longer has a matching | |
// option in the DOM. | |
var needReset = el.multiple | |
? binding.value.some(function (v) { return hasNoMatchingOption(v, el.options); }) | |
: binding.value !== binding.oldValue && hasNoMatchingOption(binding.value, el.options); | |
if (needReset) { | |
trigger(el, 'change'); | |
} | |
} | |
} | |
}; | |
function setSelected (el, binding, vm) { | |
var value = binding.value; | |
var isMultiple = el.multiple; | |
if (isMultiple && !Array.isArray(value)) { | |
"development" !== 'production' && warn( | |
"<select multiple v-model=\"" + (binding.expression) + "\"> " + | |
"expects an Array value for its binding, but got " + (Object.prototype.toString.call(value).slice(8, -1)), | |
vm | |
); | |
return | |
} | |
var selected, option; | |
for (var i = 0, l = el.options.length; i < l; i++) { | |
option = el.options[i]; | |
if (isMultiple) { | |
selected = looseIndexOf(value, getValue(option)) > -1; | |
if (option.selected !== selected) { | |
option.selected = selected; | |
} | |
} else { | |
if (looseEqual(getValue(option), value)) { | |
if (el.selectedIndex !== i) { | |
el.selectedIndex = i; | |
} | |
return | |
} | |
} | |
} | |
if (!isMultiple) { | |
el.selectedIndex = -1; | |
} | |
} | |
function hasNoMatchingOption (value, options) { | |
for (var i = 0, l = options.length; i < l; i++) { | |
if (looseEqual(getValue(options[i]), value)) { | |
return false | |
} | |
} | |
return true | |
} | |
function getValue (option) { | |
return '_value' in option | |
? option._value | |
: option.value | |
} | |
function onCompositionStart (e) { | |
e.target.composing = true; | |
} | |
function onCompositionEnd (e) { | |
e.target.composing = false; | |
trigger(e.target, 'input'); | |
} | |
function trigger (el, type) { | |
var e = document.createEvent('HTMLEvents'); | |
e.initEvent(type, true, true); | |
el.dispatchEvent(e); | |
} | |
/* */ | |
// recursively search for possible transition defined inside the component root | |
function locateNode (vnode) { | |
return vnode.componentInstance && (!vnode.data || !vnode.data.transition) | |
? locateNode(vnode.componentInstance._vnode) | |
: vnode | |
} | |
var show = { | |
bind: function bind (el, ref, vnode) { | |
var value = ref.value; | |
vnode = locateNode(vnode); | |
var transition = vnode.data && vnode.data.transition; | |
var originalDisplay = el.__vOriginalDisplay = | |
el.style.display === 'none' ? '' : el.style.display; | |
if (value && transition && !isIE9) { | |
vnode.data.show = true; | |
enter(vnode, function () { | |
el.style.display = originalDisplay; | |
}); | |
} else { | |
el.style.display = value ? originalDisplay : 'none'; | |
} | |
}, | |
update: function update (el, ref, vnode) { | |
var value = ref.value; | |
var oldValue = ref.oldValue; | |
/* istanbul ignore if */ | |
if (value === oldValue) { return } | |
vnode = locateNode(vnode); | |
var transition = vnode.data && vnode.data.transition; | |
if (transition && !isIE9) { | |
vnode.data.show = true; | |
if (value) { | |
enter(vnode, function () { | |
el.style.display = el.__vOriginalDisplay; | |
}); | |
} else { | |
leave(vnode, function () { | |
el.style.display = 'none'; | |
}); | |
} | |
} else { | |
el.style.display = value ? el.__vOriginalDisplay : 'none'; | |
} | |
}, | |
unbind: function unbind ( | |
el, | |
binding, | |
vnode, | |
oldVnode, | |
isDestroy | |
) { | |
if (!isDestroy) { | |
el.style.display = el.__vOriginalDisplay; | |
} | |
} | |
}; | |
var platformDirectives = { | |
model: model, | |
show: show | |
}; | |
/* */ | |
// Provides transition support for a single element/component. | |
// supports transition mode (out-in / in-out) | |
var transitionProps = { | |
name: String, | |
appear: Boolean, | |
css: Boolean, | |
mode: String, | |
type: String, | |
enterClass: String, | |
leaveClass: String, | |
enterToClass: String, | |
leaveToClass: String, | |
enterActiveClass: String, | |
leaveActiveClass: String, | |
appearClass: String, | |
appearActiveClass: String, | |
appearToClass: String | |
}; | |
// in case the child is also an abstract component, e.g. <keep-alive> | |
// we want to recursively retrieve the real component to be rendered | |
function getRealChild (vnode) { | |
var compOptions = vnode && vnode.componentOptions; | |
if (compOptions && compOptions.Ctor.options.abstract) { | |
return getRealChild(getFirstComponentChild(compOptions.children)) | |
} else { | |
return vnode | |
} | |
} | |
function extractTransitionData (comp) { | |
var data = {}; | |
var options = comp.$options; | |
// props | |
for (var key in options.propsData) { | |
data[key] = comp[key]; | |
} | |
// events. | |
// extract listeners and pass them directly to the transition methods | |
var listeners = options._parentListeners; | |
for (var key$1 in listeners) { | |
data[camelize(key$1)] = listeners[key$1].fn; | |
} | |
return data | |
} | |
function placeholder (h, rawChild) { | |
return /\d-keep-alive$/.test(rawChild.tag) | |
? h('keep-alive') | |
: null | |
} | |
function hasParentTransition (vnode) { | |
while ((vnode = vnode.parent)) { | |
if (vnode.data.transition) { | |
return true | |
} | |
} | |
} | |
function isSameChild (child, oldChild) { | |
return oldChild.key === child.key && oldChild.tag === child.tag | |
} | |
var Transition = { | |
name: 'transition', | |
props: transitionProps, | |
abstract: true, | |
render: function render (h) { | |
var this$1 = this; | |
var children = this.$slots.default; | |
if (!children) { | |
return | |
} | |
// filter out text nodes (possible whitespaces) | |
children = children.filter(function (c) { return c.tag; }); | |
/* istanbul ignore if */ | |
if (!children.length) { | |
return | |
} | |
// warn multiple elements | |
if ("development" !== 'production' && children.length > 1) { | |
warn( | |
'<transition> can only be used on a single element. Use ' + | |
'<transition-group> for lists.', | |
this.$parent | |
); | |
} | |
var mode = this.mode; | |
// warn invalid mode | |
if ("development" !== 'production' && | |
mode && mode !== 'in-out' && mode !== 'out-in') { | |
warn( | |
'invalid <transition> mode: ' + mode, | |
this.$parent | |
); | |
} | |
var rawChild = children[0]; | |
// if this is a component root node and the component's | |
// parent container node also has transition, skip. | |
if (hasParentTransition(this.$vnode)) { | |
return rawChild | |
} | |
// apply transition data to child | |
// use getRealChild() to ignore abstract components e.g. keep-alive | |
var child = getRealChild(rawChild); | |
/* istanbul ignore if */ | |
if (!child) { | |
return rawChild | |
} | |
if (this._leaving) { | |
return placeholder(h, rawChild) | |
} | |
// ensure a key that is unique to the vnode type and to this transition | |
// component instance. This key will be used to remove pending leaving nodes | |
// during entering. | |
var id = "__transition-" + (this._uid) + "-"; | |
var key = child.key = child.key == null | |
? id + child.tag | |
: isPrimitive(child.key) | |
? (String(child.key).indexOf(id) === 0 ? child.key : id + child.key) | |
: child.key; | |
var data = (child.data || (child.data = {})).transition = extractTransitionData(this); | |
var oldRawChild = this._vnode; | |
var oldChild = getRealChild(oldRawChild); | |
// mark v-show | |
// so that the transition module can hand over the control to the directive | |
if (child.data.directives && child.data.directives.some(function (d) { return d.name === 'show'; })) { | |
child.data.show = true; | |
} | |
if (oldChild && oldChild.data && !isSameChild(child, oldChild)) { | |
// replace old child transition data with fresh one | |
// important for dynamic transitions! | |
var oldData = oldChild && (oldChild.data.transition = extend({}, data)); | |
// handle transition mode | |
if (mode === 'out-in') { | |
// return placeholder node and queue update when leave finishes | |
this._leaving = true; | |
mergeVNodeHook(oldData, 'afterLeave', function () { | |
this$1._leaving = false; | |
this$1.$forceUpdate(); | |
}, key); | |
return placeholder(h, rawChild) | |
} else if (mode === 'in-out') { | |
var delayedLeave; | |
var performLeave = function () { delayedLeave(); }; | |
mergeVNodeHook(data, 'afterEnter', performLeave, key); | |
mergeVNodeHook(data, 'enterCancelled', performLeave, key); | |
mergeVNodeHook(oldData, 'delayLeave', function (leave) { | |
delayedLeave = leave; | |
}, key); | |
} | |
} | |
return rawChild | |
} | |
}; | |
/* */ | |
// Provides transition support for list items. | |
// supports move transitions using the FLIP technique. | |
// Because the vdom's children update algorithm is "unstable" - i.e. | |
// it doesn't guarantee the relative positioning of removed elements, | |
// we force transition-group to update its children into two passes: | |
// in the first pass, we remove all nodes that need to be removed, | |
// triggering their leaving transition; in the second pass, we insert/move | |
// into the final disired state. This way in the second pass removed | |
// nodes will remain where they should be. | |
var props = extend({ | |
tag: String, | |
moveClass: String | |
}, transitionProps); | |
delete props.mode; | |
var TransitionGroup = { | |
props: props, | |
render: function render (h) { | |
var tag = this.tag || this.$vnode.data.tag || 'span'; | |
var map = Object.create(null); | |
var prevChildren = this.prevChildren = this.children; | |
var rawChildren = this.$slots.default || []; | |
var children = this.children = []; | |
var transitionData = extractTransitionData(this); | |
for (var i = 0; i < rawChildren.length; i++) { | |
var c = rawChildren[i]; | |
if (c.tag) { | |
if (c.key != null && String(c.key).indexOf('__vlist') !== 0) { | |
children.push(c); | |
map[c.key] = c | |
;(c.data || (c.data = {})).transition = transitionData; | |
} else { | |
var opts = c.componentOptions; | |
var name = opts | |
? (opts.Ctor.options.name || opts.tag) | |
: c.tag; | |
warn(("<transition-group> children must be keyed: <" + name + ">")); | |
} | |
} | |
} | |
if (prevChildren) { | |
var kept = []; | |
var removed = []; | |
for (var i$1 = 0; i$1 < prevChildren.length; i$1++) { | |
var c$1 = prevChildren[i$1]; | |
c$1.data.transition = transitionData; | |
c$1.data.pos = c$1.elm.getBoundingClientRect(); | |
if (map[c$1.key]) { | |
kept.push(c$1); | |
} else { | |
removed.push(c$1); | |
} | |
} | |
this.kept = h(tag, null, kept); | |
this.removed = removed; | |
} | |
return h(tag, null, children) | |
}, | |
beforeUpdate: function beforeUpdate () { | |
// force removing pass | |
this.__patch__( | |
this._vnode, | |
this.kept, | |
false, // hydrating | |
true // removeOnly (!important, avoids unnecessary moves) | |
); | |
this._vnode = this.kept; | |
}, | |
updated: function updated () { | |
var children = this.prevChildren; | |
var moveClass = this.moveClass || ((this.name || 'v') + '-move'); | |
if (!children.length || !this.hasMove(children[0].elm, moveClass)) { | |
return | |
} | |
// we divide the work into three loops to avoid mixing DOM reads and writes | |
// in each iteration - which helps prevent layout thrashing. | |
children.forEach(callPendingCbs); | |
children.forEach(recordPosition); | |
children.forEach(applyTranslation); | |
// force reflow to put everything in position | |
var f = document.body.offsetHeight; // eslint-disable-line | |
children.forEach(function (c) { | |
if (c.data.moved) { | |
var el = c.elm; | |
var s = el.style; | |
addTransitionClass(el, moveClass); | |
s.transform = s.WebkitTransform = s.transitionDuration = ''; | |
el.addEventListener(transitionEndEvent, el._moveCb = function cb (e) { | |
if (!e || /transform$/.test(e.propertyName)) { | |
el.removeEventListener(transitionEndEvent, cb); | |
el._moveCb = null; | |
removeTransitionClass(el, moveClass); | |
} | |
}); | |
} | |
}); | |
}, | |
methods: { | |
hasMove: function hasMove (el, moveClass) { | |
/* istanbul ignore if */ | |
if (!hasTransition) { | |
return false | |
} | |
if (this._hasMove != null) { | |
return this._hasMove | |
} | |
addTransitionClass(el, moveClass); | |
var info = getTransitionInfo(el); | |
removeTransitionClass(el, moveClass); | |
return (this._hasMove = info.hasTransform) | |
} | |
} | |
}; | |
function callPendingCbs (c) { | |
/* istanbul ignore if */ | |
if (c.elm._moveCb) { | |
c.elm._moveCb(); | |
} | |
/* istanbul ignore if */ | |
if (c.elm._enterCb) { | |
c.elm._enterCb(); | |
} | |
} | |
function recordPosition (c) { | |
c.data.newPos = c.elm.getBoundingClientRect(); | |
} | |
function applyTranslation (c) { | |
var oldPos = c.data.pos; | |
var newPos = c.data.newPos; | |
var dx = oldPos.left - newPos.left; | |
var dy = oldPos.top - newPos.top; | |
if (dx || dy) { | |
c.data.moved = true; | |
var s = c.elm.style; | |
s.transform = s.WebkitTransform = "translate(" + dx + "px," + dy + "px)"; | |
s.transitionDuration = '0s'; | |
} | |
} | |
var platformComponents = { | |
Transition: Transition, | |
TransitionGroup: TransitionGroup | |
}; | |
/* */ | |
// install platform specific utils | |
Vue$3.config.isUnknownElement = isUnknownElement; | |
Vue$3.config.isReservedTag = isReservedTag; | |
Vue$3.config.getTagNamespace = getTagNamespace; | |
Vue$3.config.mustUseProp = mustUseProp; | |
// install platform runtime directives & components | |
extend(Vue$3.options.directives, platformDirectives); | |
extend(Vue$3.options.components, platformComponents); | |
// install platform patch function | |
Vue$3.prototype.__patch__ = inBrowser ? patch$1 : noop; | |
// wrap mount | |
Vue$3.prototype.$mount = function ( | |
el, | |
hydrating | |
) { | |
el = el && inBrowser ? query(el) : undefined; | |
return this._mount(el, hydrating) | |
}; | |
if ("development" !== 'production' && | |
inBrowser && typeof console !== 'undefined') { | |
console[console.info ? 'info' : 'log']( | |
"You are running Vue in development mode.\n" + | |
"Make sure to turn on production mode when deploying for production.\n" + | |
"See more tips at https://vuejs.org/guide/deployment.html" | |
); | |
} | |
// devtools global hook | |
/* istanbul ignore next */ | |
setTimeout(function () { | |
if (config.devtools) { | |
if (devtools) { | |
devtools.emit('init', Vue$3); | |
} else if ( | |
"development" !== 'production' && | |
inBrowser && !isEdge && /Chrome\/\d+/.test(window.navigator.userAgent) | |
) { | |
console[console.info ? 'info' : 'log']( | |
'Download the Vue Devtools extension for a better development experience:\n' + | |
'https://github.com/vuejs/vue-devtools' | |
); | |
} | |
} | |
}, 0); | |
/* */ | |
// check whether current browser encodes a char inside attribute values | |
function shouldDecode (content, encoded) { | |
var div = document.createElement('div'); | |
div.innerHTML = "<div a=\"" + content + "\">"; | |
return div.innerHTML.indexOf(encoded) > 0 | |
} | |
// #3663 | |
// IE encodes newlines inside attribute values while other browsers don't | |
var shouldDecodeNewlines = inBrowser ? shouldDecode('\n', ' ') : false; | |
/* */ | |
var decoder; | |
function decode (html) { | |
decoder = decoder || document.createElement('div'); | |
decoder.innerHTML = html; | |
return decoder.textContent | |
} | |
/* */ | |
var isUnaryTag = makeMap( | |
'area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' + | |
'link,meta,param,source,track,wbr', | |
true | |
); | |
// Elements that you can, intentionally, leave open | |
// (and which close themselves) | |
var canBeLeftOpenTag = makeMap( | |
'colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source', | |
true | |
); | |
// HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3 | |
// Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content | |
var isNonPhrasingTag = makeMap( | |
'address,article,aside,base,blockquote,body,caption,col,colgroup,dd,' + | |
'details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,' + | |
'h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,' + | |
'optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,' + | |
'title,tr,track', | |
true | |
); | |
/** | |
* Not type-checking this file because it's mostly vendor code. | |
*/ | |
/*! | |
* HTML Parser By John Resig (ejohn.org) | |
* Modified by Juriy "kangax" Zaytsev | |
* Original code by Erik Arvidsson, Mozilla Public License | |
* http://erik.eae.net/simplehtmlparser/simplehtmlparser.js | |
*/ | |
// Regular Expressions for parsing tags and attributes | |
var singleAttrIdentifier = /([^\s"'<>/=]+)/; | |
var singleAttrAssign = /(?:=)/; | |
var singleAttrValues = [ | |
// attr value double quotes | |
/"([^"]*)"+/.source, | |
// attr value, single quotes | |
/'([^']*)'+/.source, | |
// attr value, no quotes | |
/([^\s"'=<>`]+)/.source | |
]; | |
var attribute = new RegExp( | |
'^\\s*' + singleAttrIdentifier.source + | |
'(?:\\s*(' + singleAttrAssign.source + ')' + | |
'\\s*(?:' + singleAttrValues.join('|') + '))?' | |
); | |
// could use https://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-QName | |
// but for Vue templates we can enforce a simple charset | |
var ncname = '[a-zA-Z_][\\w\\-\\.]*'; | |
var qnameCapture = '((?:' + ncname + '\\:)?' + ncname + ')'; | |
var startTagOpen = new RegExp('^<' + qnameCapture); | |
var startTagClose = /^\s*(\/?)>/; | |
var endTag = new RegExp('^<\\/' + qnameCapture + '[^>]*>'); | |
var doctype = /^<!DOCTYPE [^>]+>/i; | |
var comment = /^<!--/; | |
var conditionalComment = /^<!\[/; | |
var IS_REGEX_CAPTURING_BROKEN = false; | |
'x'.replace(/x(.)?/g, function (m, g) { | |
IS_REGEX_CAPTURING_BROKEN = g === ''; | |
}); | |
// Special Elements (can contain anything) | |
var isScriptOrStyle = makeMap('script,style', true); | |
var reCache = {}; | |
var ltRE = /</g; | |
var gtRE = />/g; | |
var nlRE = / /g; | |
var ampRE = /&/g; | |
var quoteRE = /"/g; | |
function decodeAttr (value, shouldDecodeNewlines) { | |
if (shouldDecodeNewlines) { | |
value = value.replace(nlRE, '\n'); | |
} | |
return value | |
.replace(ltRE, '<') | |
.replace(gtRE, '>') | |
.replace(ampRE, '&') | |
.replace(quoteRE, '"') | |
} | |
function parseHTML (html, options) { | |
var stack = []; | |
var expectHTML = options.expectHTML; | |
var isUnaryTag$$1 = options.isUnaryTag || no; | |
var index = 0; | |
var last, lastTag; | |
while (html) { | |
last = html; | |
// Make sure we're not in a script or style element | |
if (!lastTag || !isScriptOrStyle(lastTag)) { | |
var textEnd = html.indexOf('<'); | |
if (textEnd === 0) { | |
// Comment: | |
if (comment.test(html)) { | |
var commentEnd = html.indexOf('-->'); | |
if (commentEnd >= 0) { | |
advance(commentEnd + 3); | |
continue | |
} | |
} | |
// http://en.wikipedia.org/wiki/Conditional_comment#Downlevel-revealed_conditional_comment | |
if (conditionalComment.test(html)) { | |
var conditionalEnd = html.indexOf(']>'); | |
if (conditionalEnd >= 0) { | |
advance(conditionalEnd + 2); | |
continue | |
} | |
} | |
// Doctype: | |
var doctypeMatch = html.match(doctype); | |
if (doctypeMatch) { | |
advance(doctypeMatch[0].length); | |
continue | |
} | |
// End tag: | |
var endTagMatch = html.match(endTag); | |
if (endTagMatch) { | |
var curIndex = index; | |
advance(endTagMatch[0].length); | |
parseEndTag(endTagMatch[1], curIndex, index); | |
continue | |
} | |
// Start tag: | |
var startTagMatch = parseStartTag(); | |
if (startTagMatch) { | |
handleStartTag(startTagMatch); | |
continue | |
} | |
} | |
var text = (void 0), rest$1 = (void 0), next = (void 0); | |
if (textEnd > 0) { | |
rest$1 = html.slice(textEnd); | |
while ( | |
!endTag.test(rest$1) && | |
!startTagOpen.test(rest$1) && | |
!comment.test(rest$1) && | |
!conditionalComment.test(rest$1) | |
) { | |
// < in plain text, be forgiving and treat it as text | |
next = rest$1.indexOf('<', 1); | |
if (next < 0) { break } | |
textEnd += next; | |
rest$1 = html.slice(textEnd); | |
} | |
text = html.substring(0, textEnd); | |
advance(textEnd); | |
} | |
if (textEnd < 0) { | |
text = html; | |
html = ''; | |
} | |
if (options.chars && text) { | |
options.chars(text); | |
} | |
} else { | |
var stackedTag = lastTag.toLowerCase(); | |
var reStackedTag = reCache[stackedTag] || (reCache[stackedTag] = new RegExp('([\\s\\S]*?)(</' + stackedTag + '[^>]*>)', 'i')); | |
var endTagLength = 0; | |
var rest = html.replace(reStackedTag, function (all, text, endTag) { | |
endTagLength = endTag.length; | |
if (stackedTag !== 'script' && stackedTag !== 'style' && stackedTag !== 'noscript') { | |
text = text | |
.replace(/<!--([\s\S]*?)-->/g, '$1') | |
.replace(/<!\[CDATA\[([\s\S]*?)]]>/g, '$1'); | |
} | |
if (options.chars) { | |
options.chars(text); | |
} | |
return '' | |
}); | |
index += html.length - rest.length; | |
html = rest; | |
parseEndTag(stackedTag, index - endTagLength, index); | |
} | |
if (html === last && options.chars) { | |
options.chars(html); | |
break | |
} | |
} | |
// Clean up any remaining tags | |
parseEndTag(); | |
function advance (n) { | |
index += n; | |
html = html.substring(n); | |
} | |
function parseStartTag () { | |
var start = html.match(startTagOpen); | |
if (start) { | |
var match = { | |
tagName: start[1], | |
attrs: [], | |
start: index | |
}; | |
advance(start[0].length); | |
var end, attr; | |
while (!(end = html.match(startTagClose)) && (attr = html.match(attribute))) { | |
advance(attr[0].length); | |
match.attrs.push(attr); | |
} | |
if (end) { | |
match.unarySlash = end[1]; | |
advance(end[0].length); | |
match.end = index; | |
return match | |
} | |
} | |
} | |
function handleStartTag (match) { | |
var tagName = match.tagName; | |
var unarySlash = match.unarySlash; | |
if (expectHTML) { | |
if (lastTag === 'p' && isNonPhrasingTag(tagName)) { | |
parseEndTag(lastTag); | |
} | |
if (canBeLeftOpenTag(tagName) && lastTag === tagName) { | |
parseEndTag(tagName); | |
} | |
} | |
var unary = isUnaryTag$$1(tagName) || tagName === 'html' && lastTag === 'head' || !!unarySlash; | |
var l = match.attrs.length; | |
var attrs = new Array(l); | |
for (var i = 0; i < l; i++) { | |
var args = match.attrs[i]; | |
// hackish work around FF bug https://bugzilla.mozilla.org/show_bug.cgi?id=369778 | |
if (IS_REGEX_CAPTURING_BROKEN && args[0].indexOf('""') === -1) { | |
if (args[3] === '') { delete args[3]; } | |
if (args[4] === '') { delete args[4]; } | |
if (args[5] === '') { delete args[5]; } | |
} | |
var value = args[3] || args[4] || args[5] || ''; | |
attrs[i] = { | |
name: args[1], | |
value: decodeAttr( | |
value, | |
options.shouldDecodeNewlines | |
) | |
}; | |
} | |
if (!unary) { | |
stack.push({ tag: tagName, lowerCasedTag: tagName.toLowerCase(), attrs: attrs }); | |
lastTag = tagName; | |
unarySlash = ''; | |
} | |
if (options.start) { | |
options.start(tagName, attrs, unary, match.start, match.end); | |
} | |
} | |
function parseEndTag (tagName, start, end) { | |
var pos, lowerCasedTagName; | |
if (start == null) { start = index; } | |
if (end == null) { end = index; } | |
if (tagName) { | |
lowerCasedTagName = tagName.toLowerCase(); | |
} | |
// Find the closest opened tag of the same type | |
if (tagName) { | |
for (pos = stack.length - 1; pos >= 0; pos--) { | |
if (stack[pos].lowerCasedTag === lowerCasedTagName) { | |
break | |
} | |
} | |
} else { | |
// If no tag name is provided, clean shop | |
pos = 0; | |
} | |
if (pos >= 0) { | |
// Close all the open elements, up the stack | |
for (var i = stack.length - 1; i >= pos; i--) { | |
if (options.end) { | |
options.end(stack[i].tag, start, end); | |
} | |
} | |
// Remove the open elements from the stack | |
stack.length = pos; | |
lastTag = pos && stack[pos - 1].tag; | |
} else if (lowerCasedTagName === 'br') { | |
if (options.start) { | |
options.start(tagName, [], true, start, end); | |
} | |
} else if (lowerCasedTagName === 'p') { | |
if (options.start) { | |
options.start(tagName, [], false, start, end); | |
} | |
if (options.end) { | |
options.end(tagName, start, end); | |
} | |
} | |
} | |
} | |
/* */ | |
function parseFilters (exp) { | |
var inSingle = false; | |
var inDouble = false; | |
var inTemplateString = false; | |
var inRegex = false; | |
var curly = 0; | |
var square = 0; | |
var paren = 0; | |
var lastFilterIndex = 0; | |
var c, prev, i, expression, filters; | |
for (i = 0; i < exp.length; i++) { | |
prev = c; | |
c = exp.charCodeAt(i); | |
if (inSingle) { | |
if (c === 0x27 && prev !== 0x5C) { inSingle = false; } | |
} else if (inDouble) { | |
if (c === 0x22 && prev !== 0x5C) { inDouble = false; } | |
} else if (inTemplateString) { | |
if (c === 0x60 && prev !== 0x5C) { inTemplateString = false; } | |
} else if (inRegex) { | |
if (c === 0x2f && prev !== 0x5C) { inRegex = false; } | |
} else if ( | |
c === 0x7C && // pipe | |
exp.charCodeAt(i + 1) !== 0x7C && | |
exp.charCodeAt(i - 1) !== 0x7C && | |
!curly && !square && !paren | |
) { | |
if (expression === undefined) { | |
// first filter, end of expression | |
lastFilterIndex = i + 1; | |
expression = exp.slice(0, i).trim(); | |
} else { | |
pushFilter(); | |
} | |
} else { | |
switch (c) { | |
case 0x22: inDouble = true; break // " | |
case 0x27: inSingle = true; break // ' | |
case 0x60: inTemplateString = true; break // ` | |
case 0x28: paren++; break // ( | |
case 0x29: paren--; break // ) | |
case 0x5B: square++; break // [ | |
case 0x5D: square--; break // ] | |
case 0x7B: curly++; break // { | |
case 0x7D: curly--; break // } | |
} | |
if (c === 0x2f) { // / | |
var j = i - 1; | |
var p = (void 0); | |
// find first non-whitespace prev char | |
for (; j >= 0; j--) { | |
p = exp.charAt(j); | |
if (p !== ' ') { break } | |
} | |
if (!p || !/[\w$]/.test(p)) { | |
inRegex = true; | |
} | |
} | |
} | |
} | |
if (expression === undefined) { | |
expression = exp.slice(0, i).trim(); | |
} else if (lastFilterIndex !== 0) { | |
pushFilter(); | |
} | |
function pushFilter () { | |
(filters || (filters = [])).push(exp.slice(lastFilterIndex, i).trim()); | |
lastFilterIndex = i + 1; | |
} | |
if (filters) { | |
for (i = 0; i < filters.length; i++) { | |
expression = wrapFilter(expression, filters[i]); | |
} | |
} | |
return expression | |
} | |
function wrapFilter (exp, filter) { | |
var i = filter.indexOf('('); | |
if (i < 0) { | |
// _f: resolveFilter | |
return ("_f(\"" + filter + "\")(" + exp + ")") | |
} else { | |
var name = filter.slice(0, i); | |
var args = filter.slice(i + 1); | |
return ("_f(\"" + name + "\")(" + exp + "," + args) | |
} | |
} | |
/* */ | |
var defaultTagRE = /\{\{((?:.|\n)+?)\}\}/g; | |
var regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g; | |
var buildRegex = cached(function (delimiters) { | |
var open = delimiters[0].replace(regexEscapeRE, '\\$&'); | |
var close = delimiters[1].replace(regexEscapeRE, '\\$&'); | |
return new RegExp(open + '((?:.|\\n)+?)' + close, 'g') | |
}); | |
function parseText ( | |
text, | |
delimiters | |
) { | |
var tagRE = delimiters ? buildRegex(delimiters) : defaultTagRE; | |
if (!tagRE.test(text)) { | |
return | |
} | |
var tokens = []; | |
var lastIndex = tagRE.lastIndex = 0; | |
var match, index; | |
while ((match = tagRE.exec(text))) { | |
index = match.index; | |
// push text token | |
if (index > lastIndex) { | |
tokens.push(JSON.stringify(text.slice(lastIndex, index))); | |
} | |
// tag token | |
var exp = parseFilters(match[1].trim()); | |
tokens.push(("_s(" + exp + ")")); | |
lastIndex = index + match[0].length; | |
} | |
if (lastIndex < text.length) { | |
tokens.push(JSON.stringify(text.slice(lastIndex))); | |
} | |
return tokens.join('+') | |
} | |
/* */ | |
function baseWarn (msg) { | |
console.error(("[Vue parser]: " + msg)); | |
} | |
function pluckModuleFunction ( | |
modules, | |
key | |
) { | |
return modules | |
? modules.map(function (m) { return m[key]; }).filter(function (_) { return _; }) | |
: [] | |
} | |
function addProp (el, name, value) { | |
(el.props || (el.props = [])).push({ name: name, value: value }); | |
} | |
function addAttr (el, name, value) { | |
(el.attrs || (el.attrs = [])).push({ name: name, value: value }); | |
} | |
function addDirective ( | |
el, | |
name, | |
rawName, | |
value, | |
arg, | |
modifiers | |
) { | |
(el.directives || (el.directives = [])).push({ name: name, rawName: rawName, value: value, arg: arg, modifiers: modifiers }); | |
} | |
function addHandler ( | |
el, | |
name, | |
value, | |
modifiers, | |
important | |
) { | |
// check capture modifier | |
if (modifiers && modifiers.capture) { | |
delete modifiers.capture; | |
name = '!' + name; // mark the event as captured | |
} | |
if (modifiers && modifiers.once) { | |
delete modifiers.once; | |
name = '~' + name; // mark the event as once | |
} | |
var events; | |
if (modifiers && modifiers.native) { | |
delete modifiers.native; | |
events = el.nativeEvents || (el.nativeEvents = {}); | |
} else { | |
events = el.events || (el.events = {}); | |
} | |
var newHandler = { value: value, modifiers: modifiers }; | |
var handlers = events[name]; | |
/* istanbul ignore if */ | |
if (Array.isArray(handlers)) { | |
important ? handlers.unshift(newHandler) : handlers.push(newHandler); | |
} else if (handlers) { | |
events[name] = important ? [newHandler, handlers] : [handlers, newHandler]; | |
} else { | |
events[name] = newHandler; | |
} | |
} | |
function getBindingAttr ( | |
el, | |
name, | |
getStatic | |
) { | |
var dynamicValue = | |
getAndRemoveAttr(el, ':' + name) || | |
getAndRemoveAttr(el, 'v-bind:' + name); | |
if (dynamicValue != null) { | |
return parseFilters(dynamicValue) | |
} else if (getStatic !== false) { | |
var staticValue = getAndRemoveAttr(el, name); | |
if (staticValue != null) { | |
return JSON.stringify(staticValue) | |
} | |
} | |
} | |
function getAndRemoveAttr (el, name) { | |
var val; | |
if ((val = el.attrsMap[name]) != null) { | |
var list = el.attrsList; | |
for (var i = 0, l = list.length; i < l; i++) { | |
if (list[i].name === name) { | |
list.splice(i, 1); | |
break | |
} | |
} | |
} | |
return val | |
} | |
var len; | |
var str; | |
var chr; | |
var index$1; | |
var expressionPos; | |
var expressionEndPos; | |
/** | |
* parse directive model to do the array update transform. a[idx] = val => $$a.splice($$idx, 1, val) | |
* | |
* for loop possible cases: | |
* | |
* - test | |
* - test[idx] | |
* - test[test1[idx]] | |
* - test["a"][idx] | |
* - xxx.test[a[a].test1[idx]] | |
* - test.xxx.a["asa"][test1[idx]] | |
* | |
*/ | |
function parseModel (val) { | |
str = val; | |
len = str.length; | |
index$1 = expressionPos = expressionEndPos = 0; | |
if (val.indexOf('[') < 0 || val.lastIndexOf(']') < len - 1) { | |
return { | |
exp: val, | |
idx: null | |
} | |
} | |
while (!eof()) { | |
chr = next(); | |
/* istanbul ignore if */ | |
if (isStringStart(chr)) { | |
parseString(chr); | |
} else if (chr === 0x5B) { | |
parseBracket(chr); | |
} | |
} | |
return { | |
exp: val.substring(0, expressionPos), | |
idx: val.substring(expressionPos + 1, expressionEndPos) | |
} | |
} | |
function next () { | |
return str.charCodeAt(++index$1) | |
} | |
function eof () { | |
return index$1 >= len | |
} | |
function isStringStart (chr) { | |
return chr === 0x22 || chr === 0x27 | |
} | |
function parseBracket (chr) { | |
var inBracket = 1; | |
expressionPos = index$1; | |
while (!eof()) { | |
chr = next(); | |
if (isStringStart(chr)) { | |
parseString(chr); | |
continue | |
} | |
if (chr === 0x5B) { inBracket++; } | |
if (chr === 0x5D) { inBracket--; } | |
if (inBracket === 0) { | |
expressionEndPos = index$1; | |
break | |
} | |
} | |
} | |
function parseString (chr) { | |
var stringQuote = chr; | |
while (!eof()) { | |
chr = next(); | |
if (chr === stringQuote) { | |
break | |
} | |
} | |
} | |
/* */ | |
var dirRE = /^v-|^@|^:/; | |
var forAliasRE = /(.*?)\s+(?:in|of)\s+(.*)/; | |
var forIteratorRE = /\((\{[^}]*\}|[^,]*),([^,]*)(?:,([^,]*))?\)/; | |
var bindRE = /^:|^v-bind:/; | |
var onRE = /^@|^v-on:/; | |
var argRE = /:(.*)$/; | |
var modifierRE = /\.[^.]+/g; | |
var decodeHTMLCached = cached(decode); | |
// configurable state | |
var warn$1; | |
var platformGetTagNamespace; | |
var platformMustUseProp; | |
var platformIsPreTag; | |
var preTransforms; | |
var transforms; | |
var postTransforms; | |
var delimiters; | |
/** | |
* Convert HTML string to AST. | |
*/ | |
function parse ( | |
template, | |
options | |
) { | |
warn$1 = options.warn || baseWarn; | |
platformGetTagNamespace = options.getTagNamespace || no; | |
platformMustUseProp = options.mustUseProp || no; | |
platformIsPreTag = options.isPreTag || no; | |
preTransforms = pluckModuleFunction(options.modules, 'preTransformNode'); | |
transforms = pluckModuleFunction(options.modules, 'transformNode'); | |
postTransforms = pluckModuleFunction(options.modules, 'postTransformNode'); | |
delimiters = options.delimiters; | |
var stack = []; | |
var preserveWhitespace = options.preserveWhitespace !== false; | |
var root; | |
var currentParent; | |
var inVPre = false; | |
var inPre = false; | |
var warned = false; | |
parseHTML(template, { | |
expectHTML: options.expectHTML, | |
isUnaryTag: options.isUnaryTag, | |
shouldDecodeNewlines: options.shouldDecodeNewlines, | |
start: function start (tag, attrs, unary) { | |
// check namespace. | |
// inherit parent ns if there is one | |
var ns = (currentParent && currentParent.ns) || platformGetTagNamespace(tag); | |
// handle IE svg bug | |
/* istanbul ignore if */ | |
if (isIE && ns === 'svg') { | |
attrs = guardIESVGBug(attrs); | |
} | |
var element = { | |
type: 1, | |
tag: tag, | |
attrsList: attrs, | |
attrsMap: makeAttrsMap(attrs), | |
parent: currentParent, | |
children: [] | |
}; | |
if (ns) { | |
element.ns = ns; | |
} | |
if (isForbiddenTag(element) && !isServerRendering()) { | |
element.forbidden = true; | |
"development" !== 'production' && warn$1( | |
'Templates should only be responsible for mapping the state to the ' + | |
'UI. Avoid placing tags with side-effects in your templates, such as ' + | |
"<" + tag + ">" + ', as they will not be parsed.' | |
); | |
} | |
// apply pre-transforms | |
for (var i = 0; i < preTransforms.length; i++) { | |
preTransforms[i](element, options); | |
} | |
if (!inVPre) { | |
processPre(element); | |
if (element.pre) { | |
inVPre = true; | |
} | |
} | |
if (platformIsPreTag(element.tag)) { | |
inPre = true; | |
} | |
if (inVPre) { | |
processRawAttrs(element); | |
} else { | |
processFor(element); | |
processIf(element); | |
processOnce(element); | |
processKey(element); | |
// determine whether this is a plain element after | |
// removing structural attributes | |
element.plain = !element.key && !attrs.length; | |
processRef(element); | |
processSlot(element); | |
processComponent(element); | |
for (var i$1 = 0; i$1 < transforms.length; i$1++) { | |
transforms[i$1](element, options); | |
} | |
processAttrs(element); | |
} | |
function checkRootConstraints (el) { | |
if ("development" !== 'production' && !warned) { | |
if (el.tag === 'slot' || el.tag === 'template') { | |
warned = true; | |
warn$1( | |
"Cannot use <" + (el.tag) + "> as component root element because it may " + | |
'contain multiple nodes:\n' + template | |
); | |
} | |
if (el.attrsMap.hasOwnProperty('v-for')) { | |
warned = true; | |
warn$1( | |
'Cannot use v-for on stateful component root element because ' + | |
'it renders multiple elements:\n' + template | |
); | |
} | |
} | |
} | |
// tree management | |
if (!root) { | |
root = element; | |
checkRootConstraints(root); | |
} else if (!stack.length) { | |
// allow root elements with v-if, v-else-if and v-else | |
if (root.if && (element.elseif || element.else)) { | |
checkRootConstraints(element); | |
addIfCondition(root, { | |
exp: element.elseif, | |
block: element | |
}); | |
} else if ("development" !== 'production' && !warned) { | |
warned = true; | |
warn$1( | |
"Component template should contain exactly one root element:" + | |
"\n\n" + template + "\n\n" + | |
"If you are using v-if on multiple elements, " + | |
"use v-else-if to chain them instead." | |
); | |
} | |
} | |
if (currentParent && !element.forbidden) { | |
if (element.elseif || element.else) { | |
processIfConditions(element, currentParent); | |
} else if (element.slotScope) { // scoped slot | |
currentParent.plain = false; | |
var name = element.slotTarget || 'default';(currentParent.scopedSlots || (currentParent.scopedSlots = {}))[name] = element; | |
} else { | |
currentParent.children.push(element); | |
element.parent = currentParent; | |
} | |
} | |
if (!unary) { | |
currentParent = element; | |
stack.push(element); | |
} | |
// apply post-transforms | |
for (var i$2 = 0; i$2 < postTransforms.length; i$2++) { | |
postTransforms[i$2](element, options); | |
} | |
}, | |
end: function end () { | |
// remove trailing whitespace | |
var element = stack[stack.length - 1]; | |
var lastNode = element.children[element.children.length - 1]; | |
if (lastNode && lastNode.type === 3 && lastNode.text === ' ') { | |
element.children.pop(); | |
} | |
// pop stack | |
stack.length -= 1; | |
currentParent = stack[stack.length - 1]; | |
// check pre state | |
if (element.pre) { | |
inVPre = false; | |
} | |
if (platformIsPreTag(element.tag)) { | |
inPre = false; | |
} | |
}, | |
chars: function chars (text) { | |
if (!currentParent) { | |
if ("development" !== 'production' && !warned && text === template) { | |
warned = true; | |
warn$1( | |
'Component template requires a root element, rather than just text:\n\n' + template | |
); | |
} | |
return | |
} | |
// IE textarea placeholder bug | |
/* istanbul ignore if */ | |
if (isIE && | |
currentParent.tag === 'textarea' && | |
currentParent.attrsMap.placeholder === text) { | |
return | |
} | |
var children = currentParent.children; | |
text = inPre || text.trim() | |
? decodeHTMLCached(text) | |
// only preserve whitespace if its not right after a starting tag | |
: preserveWhitespace && children.length ? ' ' : ''; | |
if (text) { | |
var expression; | |
if (!inVPre && text !== ' ' && (expression = parseText(text, delimiters))) { | |
children.push({ | |
type: 2, | |
expression: expression, | |
text: text | |
}); | |
} else if (text !== ' ' || children[children.length - 1].text !== ' ') { | |
currentParent.children.push({ | |
type: 3, | |
text: text | |
}); | |
} | |
} | |
} | |
}); | |
return root | |
} | |
function processPre (el) { | |
if (getAndRemoveAttr(el, 'v-pre') != null) { | |
el.pre = true; | |
} | |
} | |
function processRawAttrs (el) { | |
var l = el.attrsList.length; | |
if (l) { | |
var attrs = el.attrs = new Array(l); | |
for (var i = 0; i < l; i++) { | |
attrs[i] = { | |
name: el.attrsList[i].name, | |
value: JSON.stringify(el.attrsList[i].value) | |
}; | |
} | |
} else if (!el.pre) { | |
// non root node in pre blocks with no attributes | |
el.plain = true; | |
} | |
} | |
function processKey (el) { | |
var exp = getBindingAttr(el, 'key'); | |
if (exp) { | |
if ("development" !== 'production' && el.tag === 'template') { | |
warn$1("<template> cannot be keyed. Place the key on real elements instead."); | |
} | |
el.key = exp; | |
} | |
} | |
function processRef (el) { | |
var ref = getBindingAttr(el, 'ref'); | |
if (ref) { | |
el.ref = ref; | |
el.refInFor = checkInFor(el); | |
} | |
} | |
function processFor (el) { | |
var exp; | |
if ((exp = getAndRemoveAttr(el, 'v-for'))) { | |
var inMatch = exp.match(forAliasRE); | |
if (!inMatch) { | |
"development" !== 'production' && warn$1( | |
("Invalid v-for expression: " + exp) | |
); | |
return | |
} | |
el.for = inMatch[2].trim(); | |
var alias = inMatch[1].trim(); | |
var iteratorMatch = alias.match(forIteratorRE); | |
if (iteratorMatch) { | |
el.alias = iteratorMatch[1].trim(); | |
el.iterator1 = iteratorMatch[2].trim(); | |
if (iteratorMatch[3]) { | |
el.iterator2 = iteratorMatch[3].trim(); | |
} | |
} else { | |
el.alias = alias; | |
} | |
} | |
} | |
function processIf (el) { | |
var exp = getAndRemoveAttr(el, 'v-if'); | |
if (exp) { | |
el.if = exp; | |
addIfCondition(el, { | |
exp: exp, | |
block: el | |
}); | |
} else { | |
if (getAndRemoveAttr(el, 'v-else') != null) { | |
el.else = true; | |
} | |
var elseif = getAndRemoveAttr(el, 'v-else-if'); | |
if (elseif) { | |
el.elseif = elseif; | |
} | |
} | |
} | |
function processIfConditions (el, parent) { | |
var prev = findPrevElement(parent.children); | |
if (prev && prev.if) { | |
addIfCondition(prev, { | |
exp: el.elseif, | |
block: el | |
}); | |
} else { | |
warn$1( | |
"v-" + (el.elseif ? ('else-if="' + el.elseif + '"') : 'else') + " " + | |
"used on element <" + (el.tag) + "> without corresponding v-if." | |
); | |
} | |
} | |
function findPrevElement (children) { | |
var i = children.length; | |
while (i--) { | |
if (children[i].type === 1) { | |
return children[i] | |
} else { | |
if ("development" !== 'production' && children[i].text !== ' ') { | |
warn$1( | |
"text \"" + (children[i].text.trim()) + "\" between v-if and v-else(-if) " + | |
"will be ignored." | |
); | |
} | |
children.pop(); | |
} | |
} | |
} | |
function addIfCondition (el, condition) { | |
if (!el.ifConditions) { | |
el.ifConditions = []; | |
} | |
el.ifConditions.push(condition); | |
} | |
function processOnce (el) { | |
var once = getAndRemoveAttr(el, 'v-once'); | |
if (once != null) { | |
el.once = true; | |
} | |
} | |
function processSlot (el) { | |
if (el.tag === 'slot') { | |
el.slotName = getBindingAttr(el, 'name'); | |
if ("development" !== 'production' && el.key) { | |
warn$1( | |
"`key` does not work on <slot> because slots are abstract outlets " + | |
"and can possibly expand into multiple elements. " + | |
"Use the key on a wrapping element instead." | |
); | |
} | |
} else { | |
var slotTarget = getBindingAttr(el, 'slot'); | |
if (slotTarget) { | |
el.slotTarget = slotTarget === '""' ? '"default"' : slotTarget; | |
} | |
if (el.tag === 'template') { | |
el.slotScope = getAndRemoveAttr(el, 'scope'); | |
} | |
} | |
} | |
function processComponent (el) { | |
var binding; | |
if ((binding = getBindingAttr(el, 'is'))) { | |
el.component = binding; | |
} | |
if (getAndRemoveAttr(el, 'inline-template') != null) { | |
el.inlineTemplate = true; | |
} | |
} | |
function processAttrs (el) { | |
var list = el.attrsList; | |
var i, l, name, rawName, value, arg, modifiers, isProp; | |
for (i = 0, l = list.length; i < l; i++) { | |
name = rawName = list[i].name; | |
value = list[i].value; | |
if (dirRE.test(name)) { | |
// mark element as dynamic | |
el.hasBindings = true; | |
// modifiers | |
modifiers = parseModifiers(name); | |
if (modifiers) { | |
name = name.replace(modifierRE, ''); | |
} | |
if (bindRE.test(name)) { // v-bind | |
name = name.replace(bindRE, ''); | |
value = parseFilters(value); | |
isProp = false; | |
if (modifiers) { | |
if (modifiers.prop) { | |
isProp = true; | |
name = camelize(name); | |
if (name === 'innerHtml') { name = 'innerHTML'; } | |
} | |
if (modifiers.camel) { | |
name = camelize(name); | |
} | |
} | |
if (isProp || platformMustUseProp(el.tag, el.attrsMap.type, name)) { | |
addProp(el, name, value); | |
} else { | |
addAttr(el, name, value); | |
} | |
} else if (onRE.test(name)) { // v-on | |
name = name.replace(onRE, ''); | |
addHandler(el, name, value, modifiers); | |
} else { // normal directives | |
name = name.replace(dirRE, ''); | |
// parse arg | |
var argMatch = name.match(argRE); | |
if (argMatch && (arg = argMatch[1])) { | |
name = name.slice(0, -(arg.length + 1)); | |
} | |
addDirective(el, name, rawName, value, arg, modifiers); | |
if ("development" !== 'production' && name === 'model') { | |
checkForAliasModel(el, value); | |
} | |
} | |
} else { | |
// literal attribute | |
{ | |
var expression = parseText(value, delimiters); | |
if (expression) { | |
warn$1( | |
name + "=\"" + value + "\": " + | |
'Interpolation inside attributes has been removed. ' + | |
'Use v-bind or the colon shorthand instead. For example, ' + | |
'instead of <div id="{{ val }}">, use <div :id="val">.' | |
); | |
} | |
} | |
addAttr(el, name, JSON.stringify(value)); | |
} | |
} | |
} | |
function checkInFor (el) { | |
var parent = el; | |
while (parent) { | |
if (parent.for !== undefined) { | |
return true | |
} | |
parent = parent.parent; | |
} | |
return false | |
} | |
function parseModifiers (name) { | |
var match = name.match(modifierRE); | |
if (match) { | |
var ret = {}; | |
match.forEach(function (m) { ret[m.slice(1)] = true; }); | |
return ret | |
} | |
} | |
function makeAttrsMap (attrs) { | |
var map = {}; | |
for (var i = 0, l = attrs.length; i < l; i++) { | |
if ("development" !== 'production' && map[attrs[i].name] && !isIE) { | |
warn$1('duplicate attribute: ' + attrs[i].name); | |
} | |
map[attrs[i].name] = attrs[i].value; | |
} | |
return map | |
} | |
function isForbiddenTag (el) { | |
return ( | |
el.tag === 'style' || | |
(el.tag === 'script' && ( | |
!el.attrsMap.type || | |
el.attrsMap.type === 'text/javascript' | |
)) | |
) | |
} | |
var ieNSBug = /^xmlns:NS\d+/; | |
var ieNSPrefix = /^NS\d+:/; | |
/* istanbul ignore next */ | |
function guardIESVGBug (attrs) { | |
var res = []; | |
for (var i = 0; i < attrs.length; i++) { | |
var attr = attrs[i]; | |
if (!ieNSBug.test(attr.name)) { | |
attr.name = attr.name.replace(ieNSPrefix, ''); | |
res.push(attr); | |
} | |
} | |
return res | |
} | |
function checkForAliasModel (el, value) { | |
var _el = el; | |
while (_el) { | |
if (_el.for && _el.alias === value) { | |
warn$1( | |
"<" + (el.tag) + " v-model=\"" + value + "\">: " + | |
"You are binding v-model directly to a v-for iteration alias. " + | |
"This will not be able to modify the v-for source array because " + | |
"writing to the alias is like modifying a function local variable. " + | |
"Consider using an array of objects and use v-model on an object property instead." | |
); | |
} | |
_el = _el.parent; | |
} | |
} | |
/* */ | |
var isStaticKey; | |
var isPlatformReservedTag; | |
var genStaticKeysCached = cached(genStaticKeys$1); | |
/** | |
* Goal of the optimizer: walk the generated template AST tree | |
* and detect sub-trees that are purely static, i.e. parts of | |
* the DOM that never needs to change. | |
* | |
* Once we detect these sub-trees, we can: | |
* | |
* 1. Hoist them into constants, so that we no longer need to | |
* create fresh nodes for them on each re-render; | |
* 2. Completely skip them in the patching process. | |
*/ | |
function optimize (root, options) { | |
if (!root) { return } | |
isStaticKey = genStaticKeysCached(options.staticKeys || ''); | |
isPlatformReservedTag = options.isReservedTag || no; | |
// first pass: mark all non-static nodes. | |
markStatic(root); | |
// second pass: mark static roots. | |
markStaticRoots(root, false); | |
} | |
function genStaticKeys$1 (keys) { | |
return makeMap( | |
'type,tag,attrsList,attrsMap,plain,parent,children,attrs' + | |
(keys ? ',' + keys : '') | |
) | |
} | |
function markStatic (node) { | |
node.static = isStatic(node); | |
if (node.type === 1) { | |
// do not make component slot content static. this avoids | |
// 1. components not able to mutate slot nodes | |
// 2. static slot content fails for hot-reloading | |
if ( | |
!isPlatformReservedTag(node.tag) && | |
node.tag !== 'slot' && | |
node.attrsMap['inline-template'] == null | |
) { | |
return | |
} | |
for (var i = 0, l = node.children.length; i < l; i++) { | |
var child = node.children[i]; | |
markStatic(child); | |
if (!child.static) { | |
node.static = false; | |
} | |
} | |
} | |
} | |
function markStaticRoots (node, isInFor) { | |
if (node.type === 1) { | |
if (node.static || node.once) { | |
node.staticInFor = isInFor; | |
} | |
// For a node to qualify as a static root, it should have children that | |
// are not just static text. Otherwise the cost of hoisting out will | |
// outweigh the benefits and it's better off to just always render it fresh. | |
if (node.static && node.children.length && !( | |
node.children.length === 1 && | |
node.children[0].type === 3 | |
)) { | |
node.staticRoot = true; | |
return | |
} else { | |
node.staticRoot = false; | |
} | |
if (node.children) { | |
for (var i = 0, l = node.children.length; i < l; i++) { | |
markStaticRoots(node.children[i], isInFor || !!node.for); | |
} | |
} | |
if (node.ifConditions) { | |
walkThroughConditionsBlocks(node.ifConditions, isInFor); | |
} | |
} | |
} | |
function walkThroughConditionsBlocks (conditionBlocks, isInFor) { | |
for (var i = 1, len = conditionBlocks.length; i < len; i++) { | |
markStaticRoots(conditionBlocks[i].block, isInFor); | |
} | |
} | |
function isStatic (node) { | |
if (node.type === 2) { // expression | |
return false | |
} | |
if (node.type === 3) { // text | |
return true | |
} | |
return !!(node.pre || ( | |
!node.hasBindings && // no dynamic bindings | |
!node.if && !node.for && // not v-if or v-for or v-else | |
!isBuiltInTag(node.tag) && // not a built-in | |
isPlatformReservedTag(node.tag) && // not a component | |
!isDirectChildOfTemplateFor(node) && | |
Object.keys(node).every(isStaticKey) | |
)) | |
} | |
function isDirectChildOfTemplateFor (node) { | |
while (node.parent) { | |
node = node.parent; | |
if (node.tag !== 'template') { | |
return false | |
} | |
if (node.for) { | |
return true | |
} | |
} | |
return false | |
} | |
/* */ | |
var fnExpRE = /^\s*([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/; | |
var simplePathRE = /^\s*[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['.*?']|\[".*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*\s*$/; | |
// keyCode aliases | |
var keyCodes = { | |
esc: 27, | |
tab: 9, | |
enter: 13, | |
space: 32, | |
up: 38, | |
left: 37, | |
right: 39, | |
down: 40, | |
'delete': [8, 46] | |
}; | |
var modifierCode = { | |
stop: '$event.stopPropagation();', | |
prevent: '$event.preventDefault();', | |
self: 'if($event.target !== $event.currentTarget)return;', | |
ctrl: 'if(!$event.ctrlKey)return;', | |
shift: 'if(!$event.shiftKey)return;', | |
alt: 'if(!$event.altKey)return;', | |
meta: 'if(!$event.metaKey)return;' | |
}; | |
function genHandlers (events, native) { | |
var res = native ? 'nativeOn:{' : 'on:{'; | |
for (var name in events) { | |
res += "\"" + name + "\":" + (genHandler(name, events[name])) + ","; | |
} | |
return res.slice(0, -1) + '}' | |
} | |
function genHandler ( | |
name, | |
handler | |
) { | |
if (!handler) { | |
return 'function(){}' | |
} else if (Array.isArray(handler)) { | |
return ("[" + (handler.map(function (handler) { return genHandler(name, handler); }).join(',')) + "]") | |
} else if (!handler.modifiers) { | |
return fnExpRE.test(handler.value) || simplePathRE.test(handler.value) | |
? handler.value | |
: ("function($event){" + (handler.value) + "}") | |
} else { | |
var code = ''; | |
var keys = []; | |
for (var key in handler.modifiers) { | |
if (modifierCode[key]) { | |
code += modifierCode[key]; | |
} else { | |
keys.push(key); | |
} | |
} | |
if (keys.length) { | |
code = genKeyFilter(keys) + code; | |
} | |
var handlerCode = simplePathRE.test(handler.value) | |
? handler.value + '($event)' | |
: handler.value; | |
return 'function($event){' + code + handlerCode + '}' | |
} | |
} | |
function genKeyFilter (keys) { | |
return ("if(" + (keys.map(genFilterCode).join('&&')) + ")return;") | |
} | |
function genFilterCode (key) { | |
var keyVal = parseInt(key, 10); | |
if (keyVal) { | |
return ("$event.keyCode!==" + keyVal) | |
} | |
var alias = keyCodes[key]; | |
return ("_k($event.keyCode," + (JSON.stringify(key)) + (alias ? ',' + JSON.stringify(alias) : '') + ")") | |
} | |
/* */ | |
function bind$2 (el, dir) { | |
el.wrapData = function (code) { | |
return ("_b(" + code + ",'" + (el.tag) + "'," + (dir.value) + (dir.modifiers && dir.modifiers.prop ? ',true' : '') + ")") | |
}; | |
} | |
/* */ | |
var baseDirectives = { | |
bind: bind$2, | |
cloak: noop | |
}; | |
/* */ | |
// configurable state | |
var warn$2; | |
var transforms$1; | |
var dataGenFns; | |
var platformDirectives$1; | |
var isPlatformReservedTag$1; | |
var staticRenderFns; | |
var onceCount; | |
var currentOptions; | |
function generate ( | |
ast, | |
options | |
) { | |
// save previous staticRenderFns so generate calls can be nested | |
var prevStaticRenderFns = staticRenderFns; | |
var currentStaticRenderFns = staticRenderFns = []; | |
var prevOnceCount = onceCount; | |
onceCount = 0; | |
currentOptions = options; | |
warn$2 = options.warn || baseWarn; | |
transforms$1 = pluckModuleFunction(options.modules, 'transformCode'); | |
dataGenFns = pluckModuleFunction(options.modules, 'genData'); | |
platformDirectives$1 = options.directives || {}; | |
isPlatformReservedTag$1 = options.isReservedTag || no; | |
var code = ast ? genElement(ast) : '_c("div")'; | |
staticRenderFns = prevStaticRenderFns; | |
onceCount = prevOnceCount; | |
return { | |
render: ("with(this){return " + code + "}"), | |
staticRenderFns: currentStaticRenderFns | |
} | |
} | |
function genElement (el) { | |
if (el.staticRoot && !el.staticProcessed) { | |
return genStatic(el) | |
} else if (el.once && !el.onceProcessed) { | |
return genOnce(el) | |
} else if (el.for && !el.forProcessed) { | |
return genFor(el) | |
} else if (el.if && !el.ifProcessed) { | |
return genIf(el) | |
} else if (el.tag === 'template' && !el.slotTarget) { | |
return genChildren(el) || 'void 0' | |
} else if (el.tag === 'slot') { | |
return genSlot(el) | |
} else { | |
// component or element | |
var code; | |
if (el.component) { | |
code = genComponent(el.component, el); | |
} else { | |
var data = el.plain ? undefined : genData(el); | |
var children = el.inlineTemplate ? null : genChildren(el, true); | |
code = "_c('" + (el.tag) + "'" + (data ? ("," + data) : '') + (children ? ("," + children) : '') + ")"; | |
} | |
// module transforms | |
for (var i = 0; i < transforms$1.length; i++) { | |
code = transforms$1[i](el, code); | |
} | |
return code | |
} | |
} | |
// hoist static sub-trees out | |
function genStatic (el) { | |
el.staticProcessed = true; | |
staticRenderFns.push(("with(this){return " + (genElement(el)) + "}")); | |
return ("_m(" + (staticRenderFns.length - 1) + (el.staticInFor ? ',true' : '') + ")") | |
} | |
// v-once | |
function genOnce (el) { | |
el.onceProcessed = true; | |
if (el.if && !el.ifProcessed) { | |
return genIf(el) | |
} else if (el.staticInFor) { | |
var key = ''; | |
var parent = el.parent; | |
while (parent) { | |
if (parent.for) { | |
key = parent.key; | |
break | |
} | |
parent = parent.parent; | |
} | |
if (!key) { | |
"development" !== 'production' && warn$2( | |
"v-once can only be used inside v-for that is keyed. " | |
); | |
return genElement(el) | |
} | |
return ("_o(" + (genElement(el)) + "," + (onceCount++) + (key ? ("," + key) : "") + ")") | |
} else { | |
return genStatic(el) | |
} | |
} | |
function genIf (el) { | |
el.ifProcessed = true; // avoid recursion | |
return genIfConditions(el.ifConditions.slice()) | |
} | |
function genIfConditions (conditions) { | |
if (!conditions.length) { | |
return '_e()' | |
} | |
var condition = conditions.shift(); | |
if (condition.exp) { | |
return ("(" + (condition.exp) + ")?" + (genTernaryExp(condition.block)) + ":" + (genIfConditions(conditions))) | |
} else { | |
return ("" + (genTernaryExp(condition.block))) | |
} | |
// v-if with v-once should generate code like (a)?_m(0):_m(1) | |
function genTernaryExp (el) { | |
return el.once ? genOnce(el) : genElement(el) | |
} | |
} | |
function genFor (el) { | |
var exp = el.for; | |
var alias = el.alias; | |
var iterator1 = el.iterator1 ? ("," + (el.iterator1)) : ''; | |
var iterator2 = el.iterator2 ? ("," + (el.iterator2)) : ''; | |
el.forProcessed = true; // avoid recursion | |
return "_l((" + exp + ")," + | |
"function(" + alias + iterator1 + iterator2 + "){" + | |
"return " + (genElement(el)) + | |
'})' | |
} | |
function genData (el) { | |
var data = '{'; | |
// directives first. | |
// directives may mutate the el's other properties before they are generated. | |
var dirs = genDirectives(el); | |
if (dirs) { data += dirs + ','; } | |
// key | |
if (el.key) { | |
data += "key:" + (el.key) + ","; | |
} | |
// ref | |
if (el.ref) { | |
data += "ref:" + (el.ref) + ","; | |
} | |
if (el.refInFor) { | |
data += "refInFor:true,"; | |
} | |
// pre | |
if (el.pre) { | |
data += "pre:true,"; | |
} | |
// record original tag name for components using "is" attribute | |
if (el.component) { | |
data += "tag:\"" + (el.tag) + "\","; | |
} | |
// module data generation functions | |
for (var i = 0; i < dataGenFns.length; i++) { | |
data += dataGenFns[i](el); | |
} | |
// attributes | |
if (el.attrs) { | |
data += "attrs:{" + (genProps(el.attrs)) + "},"; | |
} | |
// DOM props | |
if (el.props) { | |
data += "domProps:{" + (genProps(el.props)) + "},"; | |
} | |
// event handlers | |
if (el.events) { | |
data += (genHandlers(el.events)) + ","; | |
} | |
if (el.nativeEvents) { | |
data += (genHandlers(el.nativeEvents, true)) + ","; | |
} | |
// slot target | |
if (el.slotTarget) { | |
data += "slot:" + (el.slotTarget) + ","; | |
} | |
// scoped slots | |
if (el.scopedSlots) { | |
data += (genScopedSlots(el.scopedSlots)) + ","; | |
} | |
// inline-template | |
if (el.inlineTemplate) { | |
var inlineTemplate = genInlineTemplate(el); | |
if (inlineTemplate) { | |
data += inlineTemplate + ","; | |
} | |
} | |
data = data.replace(/,$/, '') + '}'; | |
// v-bind data wrap | |
if (el.wrapData) { | |
data = el.wrapData(data); | |
} | |
return data | |
} | |
function genDirectives (el) { | |
var dirs = el.directives; | |
if (!dirs) { return } | |
var res = 'directives:['; | |
var hasRuntime = false; | |
var i, l, dir, needRuntime; | |
for (i = 0, l = dirs.length; i < l; i++) { | |
dir = dirs[i]; | |
needRuntime = true; | |
var gen = platformDirectives$1[dir.name] || baseDirectives[dir.name]; | |
if (gen) { | |
// compile-time directive that manipulates AST. | |
// returns true if it also needs a runtime counterpart. | |
needRuntime = !!gen(el, dir, warn$2); | |
} | |
if (needRuntime) { | |
hasRuntime = true; | |
res += "{name:\"" + (dir.name) + "\",rawName:\"" + (dir.rawName) + "\"" + (dir.value ? (",value:(" + (dir.value) + "),expression:" + (JSON.stringify(dir.value))) : '') + (dir.arg ? (",arg:\"" + (dir.arg) + "\"") : '') + (dir.modifiers ? (",modifiers:" + (JSON.stringify(dir.modifiers))) : '') + "},"; | |
} | |
} | |
if (hasRuntime) { | |
return res.slice(0, -1) + ']' | |
} | |
} | |
function genInlineTemplate (el) { | |
var ast = el.children[0]; | |
if ("development" !== 'production' && ( | |
el.children.length > 1 || ast.type !== 1 | |
)) { | |
warn$2('Inline-template components must have exactly one child element.'); | |
} | |
if (ast.type === 1) { | |
var inlineRenderFns = generate(ast, currentOptions); | |
return ("inlineTemplate:{render:function(){" + (inlineRenderFns.render) + "},staticRenderFns:[" + (inlineRenderFns.staticRenderFns.map(function (code) { return ("function(){" + code + "}"); }).join(',')) + "]}") | |
} | |
} | |
function genScopedSlots (slots) { | |
return ("scopedSlots:{" + (Object.keys(slots).map(function (key) { return genScopedSlot(key, slots[key]); }).join(',')) + "}") | |
} | |
function genScopedSlot (key, el) { | |
return key + ":function(" + (String(el.attrsMap.scope)) + "){" + | |
"return " + (el.tag === 'template' | |
? genChildren(el) || 'void 0' | |
: genElement(el)) + "}" | |
} | |
function genChildren (el, checkSkip) { | |
var children = el.children; | |
if (children.length) { | |
var el$1 = children[0]; | |
// optimize single v-for | |
if (children.length === 1 && | |
el$1.for && | |
el$1.tag !== 'template' && | |
el$1.tag !== 'slot') { | |
return genElement(el$1) | |
} | |
var normalizationType = getNormalizationType(children); | |
return ("[" + (children.map(genNode).join(',')) + "]" + (checkSkip | |
? normalizationType ? ("," + normalizationType) : '' | |
: '')) | |
} | |
} | |
// determine the normalization needed for the children array. | |
// 0: no normalization needed | |
// 1: simple normalization needed (possible 1-level deep nested array) | |
// 2: full normalization needed | |
function getNormalizationType (children) { | |
var res = 0; | |
for (var i = 0; i < children.length; i++) { | |
var el = children[i]; | |
if (el.type !== 1) { | |
continue | |
} | |
if (needsNormalization(el) || | |
(el.ifConditions && el.ifConditions.some(function (c) { return needsNormalization(c.block); }))) { | |
res = 2; | |
break | |
} | |
if (maybeComponent(el) || | |
(el.ifConditions && el.ifConditions.some(function (c) { return maybeComponent(c.block); }))) { | |
res = 1; | |
} | |
} | |
return res | |
} | |
function needsNormalization (el) { | |
return el.for !== undefined || el.tag === 'template' || el.tag === 'slot' | |
} | |
function maybeComponent (el) { | |
return !isPlatformReservedTag$1(el.tag) | |
} | |
function genNode (node) { | |
if (node.type === 1) { | |
return genElement(node) | |
} else { | |
return genText(node) | |
} | |
} | |
function genText (text) { | |
return ("_v(" + (text.type === 2 | |
? text.expression // no need for () because already wrapped in _s() | |
: transformSpecialNewlines(JSON.stringify(text.text))) + ")") | |
} | |
function genSlot (el) { | |
var slotName = el.slotName || '"default"'; | |
var children = genChildren(el); | |
var res = "_t(" + slotName + (children ? ("," + children) : ''); | |
var attrs = el.attrs && ("{" + (el.attrs.map(function (a) { return ((camelize(a.name)) + ":" + (a.value)); }).join(',')) + "}"); | |
var bind$$1 = el.attrsMap['v-bind']; | |
if ((attrs || bind$$1) && !children) { | |
res += ",null"; | |
} | |
if (attrs) { | |
res += "," + attrs; | |
} | |
if (bind$$1) { | |
res += (attrs ? '' : ',null') + "," + bind$$1; | |
} | |
return res + ')' | |
} | |
// componentName is el.component, take it as argument to shun flow's pessimistic refinement | |
function genComponent (componentName, el) { | |
var children = el.inlineTemplate ? null : genChildren(el, true); | |
return ("_c(" + componentName + "," + (genData(el)) + (children ? ("," + children) : '') + ")") | |
} | |
function genProps (props) { | |
var res = ''; | |
for (var i = 0; i < props.length; i++) { | |
var prop = props[i]; | |
res += "\"" + (prop.name) + "\":" + (transformSpecialNewlines(prop.value)) + ","; | |
} | |
return res.slice(0, -1) | |
} | |
// #3895, #4268 | |
function transformSpecialNewlines (text) { | |
return text | |
.replace(/\u2028/g, '\\u2028') | |
.replace(/\u2029/g, '\\u2029') | |
} | |
/* */ | |
/** | |
* Compile a template. | |
*/ | |
function compile$1 ( | |
template, | |
options | |
) { | |
var ast = parse(template.trim(), options); | |
optimize(ast, options); | |
var code = generate(ast, options); | |
return { | |
ast: ast, | |
render: code.render, | |
staticRenderFns: code.staticRenderFns | |
} | |
} | |
/* */ | |
// operators like typeof, instanceof and in are allowed | |
var prohibitedKeywordRE = new RegExp('\\b' + ( | |
'do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' + | |
'super,throw,while,yield,delete,export,import,return,switch,default,' + | |
'extends,finally,continue,debugger,function,arguments' | |
).split(',').join('\\b|\\b') + '\\b'); | |
// check valid identifier for v-for | |
var identRE = /[A-Za-z_$][\w$]*/; | |
// strip strings in expressions | |
var stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g; | |
// detect problematic expressions in a template | |
function detectErrors (ast) { | |
var errors = []; | |
if (ast) { | |
checkNode(ast, errors); | |
} | |
return errors | |
} | |
function checkNode (node, errors) { | |
if (node.type === 1) { | |
for (var name in node.attrsMap) { | |
if (dirRE.test(name)) { | |
var value = node.attrsMap[name]; | |
if (value) { | |
if (name === 'v-for') { | |
checkFor(node, ("v-for=\"" + value + "\""), errors); | |
} else { | |
checkExpression(value, (name + "=\"" + value + "\""), errors); | |
} | |
} | |
} | |
} | |
if (node.children) { | |
for (var i = 0; i < node.children.length; i++) { | |
checkNode(node.children[i], errors); | |
} | |
} | |
} else if (node.type === 2) { | |
checkExpression(node.expression, node.text, errors); | |
} | |
} | |
function checkFor (node, text, errors) { | |
checkExpression(node.for || '', text, errors); | |
checkIdentifier(node.alias, 'v-for alias', text, errors); | |
checkIdentifier(node.iterator1, 'v-for iterator', text, errors); | |
checkIdentifier(node.iterator2, 'v-for iterator', text, errors); | |
} | |
function checkIdentifier (ident, type, text, errors) { | |
if (typeof ident === 'string' && !identRE.test(ident)) { | |
errors.push(("- invalid " + type + " \"" + ident + "\" in expression: " + text)); | |
} | |
} | |
function checkExpression (exp, text, errors) { | |
try { | |
new Function(("return " + exp)); | |
} catch (e) { | |
var keywordMatch = exp.replace(stripStringRE, '').match(prohibitedKeywordRE); | |
if (keywordMatch) { | |
errors.push( | |
"- avoid using JavaScript keyword as property name: " + | |
"\"" + (keywordMatch[0]) + "\" in expression " + text | |
); | |
} else { | |
errors.push(("- invalid expression: " + text)); | |
} | |
} | |
} | |
/* */ | |
function transformNode (el, options) { | |
var warn = options.warn || baseWarn; | |
var staticClass = getAndRemoveAttr(el, 'class'); | |
if ("development" !== 'production' && staticClass) { | |
var expression = parseText(staticClass, options.delimiters); | |
if (expression) { | |
warn( | |
"class=\"" + staticClass + "\": " + | |
'Interpolation inside attributes has been removed. ' + | |
'Use v-bind or the colon shorthand instead. For example, ' + | |
'instead of <div class="{{ val }}">, use <div :class="val">.' | |
); | |
} | |
} | |
if (staticClass) { | |
el.staticClass = JSON.stringify(staticClass); | |
} | |
var classBinding = getBindingAttr(el, 'class', false /* getStatic */); | |
if (classBinding) { | |
el.classBinding = classBinding; | |
} | |
} | |
function genData$1 (el) { | |
var data = ''; | |
if (el.staticClass) { | |
data += "staticClass:" + (el.staticClass) + ","; | |
} | |
if (el.classBinding) { | |
data += "class:" + (el.classBinding) + ","; | |
} | |
return data | |
} | |
var klass$1 = { | |
staticKeys: ['staticClass'], | |
transformNode: transformNode, | |
genData: genData$1 | |
}; | |
/* */ | |
function transformNode$1 (el, options) { | |
var warn = options.warn || baseWarn; | |
var staticStyle = getAndRemoveAttr(el, 'style'); | |
if (staticStyle) { | |
/* istanbul ignore if */ | |
{ | |
var expression = parseText(staticStyle, options.delimiters); | |
if (expression) { | |
warn( | |
"style=\"" + staticStyle + "\": " + | |
'Interpolation inside attributes has been removed. ' + | |
'Use v-bind or the colon shorthand instead. For example, ' + | |
'instead of <div style="{{ val }}">, use <div :style="val">.' | |
); | |
} | |
} | |
el.staticStyle = JSON.stringify(parseStyleText(staticStyle)); | |
} | |
var styleBinding = getBindingAttr(el, 'style', false /* getStatic */); | |
if (styleBinding) { | |
el.styleBinding = styleBinding; | |
} | |
} | |
function genData$2 (el) { | |
var data = ''; | |
if (el.staticStyle) { | |
data += "staticStyle:" + (el.staticStyle) + ","; | |
} | |
if (el.styleBinding) { | |
data += "style:(" + (el.styleBinding) + "),"; | |
} | |
return data | |
} | |
var style$1 = { | |
staticKeys: ['staticStyle'], | |
transformNode: transformNode$1, | |
genData: genData$2 | |
}; | |
var modules$1 = [ | |
klass$1, | |
style$1 | |
]; | |
/* */ | |
var warn$3; | |
function model$1 ( | |
el, | |
dir, | |
_warn | |
) { | |
warn$3 = _warn; | |
var value = dir.value; | |
var modifiers = dir.modifiers; | |
var tag = el.tag; | |
var type = el.attrsMap.type; | |
{ | |
var dynamicType = el.attrsMap['v-bind:type'] || el.attrsMap[':type']; | |
if (tag === 'input' && dynamicType) { | |
warn$3( | |
"<input :type=\"" + dynamicType + "\" v-model=\"" + value + "\">:\n" + | |
"v-model does not support dynamic input types. Use v-if branches instead." | |
); | |
} | |
} | |
if (tag === 'select') { | |
genSelect(el, value, modifiers); | |
} else if (tag === 'input' && type === 'checkbox') { | |
genCheckboxModel(el, value, modifiers); | |
} else if (tag === 'input' && type === 'radio') { | |
genRadioModel(el, value, modifiers); | |
} else { | |
genDefaultModel(el, value, modifiers); | |
} | |
// ensure runtime directive metadata | |
return true | |
} | |
function genCheckboxModel ( | |
el, | |
value, | |
modifiers | |
) { | |
if ("development" !== 'production' && | |
el.attrsMap.checked != null) { | |
warn$3( | |
"<" + (el.tag) + " v-model=\"" + value + "\" checked>:\n" + | |
"inline checked attributes will be ignored when using v-model. " + | |
'Declare initial values in the component\'s data option instead.' | |
); | |
} | |
var number = modifiers && modifiers.number; | |
var valueBinding = getBindingAttr(el, 'value') || 'null'; | |
var trueValueBinding = getBindingAttr(el, 'true-value') || 'true'; | |
var falseValueBinding = getBindingAttr(el, 'false-value') || 'false'; | |
addProp(el, 'checked', | |
"Array.isArray(" + value + ")" + | |
"?_i(" + value + "," + valueBinding + ")>-1" + ( | |
trueValueBinding === 'true' | |
? (":(" + value + ")") | |
: (":_q(" + value + "," + trueValueBinding + ")") | |
) | |
); | |
addHandler(el, 'click', | |
"var $$a=" + value + "," + | |
'$$el=$event.target,' + | |
"$$c=$$el.checked?(" + trueValueBinding + "):(" + falseValueBinding + ");" + | |
'if(Array.isArray($$a)){' + | |
"var $$v=" + (number ? '_n(' + valueBinding + ')' : valueBinding) + "," + | |
'$$i=_i($$a,$$v);' + | |
"if($$c){$$i<0&&(" + value + "=$$a.concat($$v))}" + | |
"else{$$i>-1&&(" + value + "=$$a.slice(0,$$i).concat($$a.slice($$i+1)))}" + | |
"}else{" + value + "=$$c}", | |
null, true | |
); | |
} | |
function genRadioModel ( | |
el, | |
value, | |
modifiers | |
) { | |
if ("development" !== 'production' && | |
el.attrsMap.checked != null) { | |
warn$3( | |
"<" + (el.tag) + " v-model=\"" + value + "\" checked>:\n" + | |
"inline checked attributes will be ignored when using v-model. " + | |
'Declare initial values in the component\'s data option instead.' | |
); | |
} | |
var number = modifiers && modifiers.number; | |
var valueBinding = getBindingAttr(el, 'value') || 'null'; | |
valueBinding = number ? ("_n(" + valueBinding + ")") : valueBinding; | |
addProp(el, 'checked', ("_q(" + value + "," + valueBinding + ")")); | |
addHandler(el, 'click', genAssignmentCode(value, valueBinding), null, true); | |
} | |
function genDefaultModel ( | |
el, | |
value, | |
modifiers | |
) { | |
{ | |
if (el.tag === 'input' && el.attrsMap.value) { | |
warn$3( | |
"<" + (el.tag) + " v-model=\"" + value + "\" value=\"" + (el.attrsMap.value) + "\">:\n" + | |
'inline value attributes will be ignored when using v-model. ' + | |
'Declare initial values in the component\'s data option instead.' | |
); | |
} | |
if (el.tag === 'textarea' && el.children.length) { | |
warn$3( | |
"<textarea v-model=\"" + value + "\">:\n" + | |
'inline content inside <textarea> will be ignored when using v-model. ' + | |
'Declare initial values in the component\'s data option instead.' | |
); | |
} | |
} | |
var type = el.attrsMap.type; | |
var ref = modifiers || {}; | |
var lazy = ref.lazy; | |
var number = ref.number; | |
var trim = ref.trim; | |
var event = lazy || (isIE && type === 'range') ? 'change' : 'input'; | |
var needCompositionGuard = !lazy && type !== 'range'; | |
var isNative = el.tag === 'input' || el.tag === 'textarea'; | |
var valueExpression = isNative | |
? ("$event.target.value" + (trim ? '.trim()' : '')) | |
: trim ? "(typeof $event === 'string' ? $event.trim() : $event)" : "$event"; | |
valueExpression = number || type === 'number' | |
? ("_n(" + valueExpression + ")") | |
: valueExpression; | |
var code = genAssignmentCode(value, valueExpression); | |
if (isNative && needCompositionGuard) { | |
code = "if($event.target.composing)return;" + code; | |
} | |
// inputs with type="file" are read only and setting the input's | |
// value will throw an error. | |
if ("development" !== 'production' && | |
type === 'file') { | |
warn$3( | |
"<" + (el.tag) + " v-model=\"" + value + "\" type=\"file\">:\n" + | |
"File inputs are read only. Use a v-on:change listener instead." | |
); | |
} | |
addProp(el, 'value', isNative ? ("_s(" + value + ")") : ("(" + value + ")")); | |
addHandler(el, event, code, null, true); | |
if (trim || number || type === 'number') { | |
addHandler(el, 'blur', '$forceUpdate()'); | |
} | |
} | |
function genSelect ( | |
el, | |
value, | |
modifiers | |
) { | |
{ | |
el.children.some(checkOptionWarning); | |
} | |
var number = modifiers && modifiers.number; | |
var assignment = "Array.prototype.filter" + | |
".call($event.target.options,function(o){return o.selected})" + | |
".map(function(o){var val = \"_value\" in o ? o._value : o.value;" + | |
"return " + (number ? '_n(val)' : 'val') + "})" + | |
(el.attrsMap.multiple == null ? '[0]' : ''); | |
var code = genAssignmentCode(value, assignment); | |
addHandler(el, 'change', code, null, true); | |
} | |
function checkOptionWarning (option) { | |
if (option.type === 1 && | |
option.tag === 'option' && | |
option.attrsMap.selected != null) { | |
warn$3( | |
"<select v-model=\"" + (option.parent.attrsMap['v-model']) + "\">:\n" + | |
'inline selected attributes on <option> will be ignored when using v-model. ' + | |
'Declare initial values in the component\'s data option instead.' | |
); | |
return true | |
} | |
return false | |
} | |
function genAssignmentCode (value, assignment) { | |
var modelRs = parseModel(value); | |
if (modelRs.idx === null) { | |
return (value + "=" + assignment) | |
} else { | |
return "var $$exp = " + (modelRs.exp) + ", $$idx = " + (modelRs.idx) + ";" + | |
"if (!Array.isArray($$exp)){" + | |
value + "=" + assignment + "}" + | |
"else{$$exp.splice($$idx, 1, " + assignment + ")}" | |
} | |
} | |
/* */ | |
function text (el, dir) { | |
if (dir.value) { | |
addProp(el, 'textContent', ("_s(" + (dir.value) + ")")); | |
} | |
} | |
/* */ | |
function html (el, dir) { | |
if (dir.value) { | |
addProp(el, 'innerHTML', ("_s(" + (dir.value) + ")")); | |
} | |
} | |
var directives$1 = { | |
model: model$1, | |
text: text, | |
html: html | |
}; | |
/* */ | |
var cache = Object.create(null); | |
var baseOptions = { | |
expectHTML: true, | |
modules: modules$1, | |
staticKeys: genStaticKeys(modules$1), | |
directives: directives$1, | |
isReservedTag: isReservedTag, | |
isUnaryTag: isUnaryTag, | |
mustUseProp: mustUseProp, | |
getTagNamespace: getTagNamespace, | |
isPreTag: isPreTag | |
}; | |
function compile$$1 ( | |
template, | |
options | |
) { | |
options = options | |
? extend(extend({}, baseOptions), options) | |
: baseOptions; | |
return compile$1(template, options) | |
} | |
function compileToFunctions ( | |
template, | |
options, | |
vm | |
) { | |
var _warn = (options && options.warn) || warn; | |
// detect possible CSP restriction | |
/* istanbul ignore if */ | |
{ | |
try { | |
new Function('return 1'); | |
} catch (e) { | |
if (e.toString().match(/unsafe-eval|CSP/)) { | |
_warn( | |
'It seems you are using the standalone build of Vue.js in an ' + | |
'environment with Content Security Policy that prohibits unsafe-eval. ' + | |
'The template compiler cannot work in this environment. Consider ' + | |
'relaxing the policy to allow unsafe-eval or pre-compiling your ' + | |
'templates into render functions.' | |
); | |
} | |
} | |
} | |
var key = options && options.delimiters | |
? String(options.delimiters) + template | |
: template; | |
if (cache[key]) { | |
return cache[key] | |
} | |
var res = {}; | |
var compiled = compile$$1(template, options); | |
res.render = makeFunction(compiled.render); | |
var l = compiled.staticRenderFns.length; | |
res.staticRenderFns = new Array(l); | |
for (var i = 0; i < l; i++) { | |
res.staticRenderFns[i] = makeFunction(compiled.staticRenderFns[i]); | |
} | |
{ | |
if (res.render === noop || res.staticRenderFns.some(function (fn) { return fn === noop; })) { | |
_warn( | |
"failed to compile template:\n\n" + template + "\n\n" + | |
detectErrors(compiled.ast).join('\n') + | |
'\n\n', | |
vm | |
); | |
} | |
} | |
return (cache[key] = res) | |
} | |
function makeFunction (code) { | |
try { | |
return new Function(code) | |
} catch (e) { | |
return noop | |
} | |
} | |
/* */ | |
var idToTemplate = cached(function (id) { | |
var el = query(id); | |
return el && el.innerHTML | |
}); | |
var mount = Vue$3.prototype.$mount; | |
Vue$3.prototype.$mount = function ( | |
el, | |
hydrating | |
) { | |
el = el && query(el); | |
/* istanbul ignore if */ | |
if (el === document.body || el === document.documentElement) { | |
"development" !== 'production' && warn( | |
"Do not mount Vue to <html> or <body> - mount to normal elements instead." | |
); | |
return this | |
} | |
var options = this.$options; | |
// resolve template/el and convert to render function | |
if (!options.render) { | |
var template = options.template; | |
if (template) { | |
if (typeof template === 'string') { | |
if (template.charAt(0) === '#') { | |
template = idToTemplate(template); | |
/* istanbul ignore if */ | |
if ("development" !== 'production' && !template) { | |
warn( | |
("Template element not found or is empty: " + (options.template)), | |
this | |
); | |
} | |
} | |
} else if (template.nodeType) { | |
template = template.innerHTML; | |
} else { | |
{ | |
warn('invalid template option:' + template, this); | |
} | |
return this | |
} | |
} else if (el) { | |
template = getOuterHTML(el); | |
} | |
if (template) { | |
var ref = compileToFunctions(template, { | |
warn: warn, | |
shouldDecodeNewlines: shouldDecodeNewlines, | |
delimiters: options.delimiters | |
}, this); | |
var render = ref.render; | |
var staticRenderFns = ref.staticRenderFns; | |
options.render = render; | |
options.staticRenderFns = staticRenderFns; | |
} | |
} | |
return mount.call(this, el, hydrating) | |
}; | |
/** | |
* Get outerHTML of elements, taking care | |
* of SVG elements in IE as well. | |
*/ | |
function getOuterHTML (el) { | |
if (el.outerHTML) { | |
return el.outerHTML | |
} else { | |
var container = document.createElement('div'); | |
container.appendChild(el.cloneNode(true)); | |
return container.innerHTML | |
} | |
} | |
Vue$3.compile = compileToFunctions; | |
return Vue$3; | |
}))); | |
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) | |
},{}],71:[function(require,module,exports){ | |
exports.sync = function (store, router, options) { | |
var moduleName = (options || {}).moduleName || 'route' | |
store.registerModule(moduleName, { | |
state: cloneRoute(router.currentRoute), | |
mutations: { | |
'router/ROUTE_CHANGED': function (state, transition) { | |
store.state[moduleName] = cloneRoute(transition.to, transition.from) | |
} | |
} | |
}) | |
var isTimeTraveling = false | |
var currentPath | |
// sync router on store change | |
store.watch( | |
function (state) { return state[moduleName] }, | |
function (route) { | |
if (route.fullPath === currentPath) { | |
return | |
} | |
isTimeTraveling = true | |
currentPath = route.fullPath | |
router.push(route) | |
}, | |
{ sync: true } | |
) | |
// sync store on router navigation | |
router.afterEach(function (to, from) { | |
if (isTimeTraveling) { | |
isTimeTraveling = false | |
return | |
} | |
currentPath = to.fullPath | |
store.commit('router/ROUTE_CHANGED', { to: to, from: from }) | |
}) | |
} | |
function cloneRoute (to, from) { | |
var clone = { | |
name: to.name, | |
path: to.path, | |
hash: to.hash, | |
query: to.query, | |
params: to.params, | |
fullPath: to.fullPath, | |
meta: to.meta | |
} | |
if (from) { | |
clone.from = cloneRoute(from) | |
} | |
return Object.freeze(clone) | |
} | |
},{}],72:[function(require,module,exports){ | |
/** | |
* vuex v2.1.1 | |
* (c) 2016 Evan You | |
* @license MIT | |
*/ | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : | |
typeof define === 'function' && define.amd ? define(factory) : | |
(global.Vuex = factory()); | |
}(this, (function () { 'use strict'; | |
var devtoolHook = | |
typeof window !== 'undefined' && | |
window.__VUE_DEVTOOLS_GLOBAL_HOOK__ | |
function devtoolPlugin (store) { | |
if (!devtoolHook) { return } | |
store._devtoolHook = devtoolHook | |
devtoolHook.emit('vuex:init', store) | |
devtoolHook.on('vuex:travel-to-state', function (targetState) { | |
store.replaceState(targetState) | |
}) | |
store.subscribe(function (mutation, state) { | |
devtoolHook.emit('vuex:mutation', mutation, state) | |
}) | |
} | |
function applyMixin (Vue) { | |
var version = Number(Vue.version.split('.')[0]) | |
if (version >= 2) { | |
var usesInit = Vue.config._lifecycleHooks.indexOf('init') > -1 | |
Vue.mixin(usesInit ? { init: vuexInit } : { beforeCreate: vuexInit }) | |
} else { | |
// override init and inject vuex init procedure | |
// for 1.x backwards compatibility. | |
var _init = Vue.prototype._init | |
Vue.prototype._init = function (options) { | |
if ( options === void 0 ) options = {}; | |
options.init = options.init | |
? [vuexInit].concat(options.init) | |
: vuexInit | |
_init.call(this, options) | |
} | |
} | |
/** | |
* Vuex init hook, injected into each instances init hooks list. | |
*/ | |
function vuexInit () { | |
var options = this.$options | |
// store injection | |
if (options.store) { | |
this.$store = options.store | |
} else if (options.parent && options.parent.$store) { | |
this.$store = options.parent.$store | |
} | |
} | |
} | |
var mapState = normalizeNamespace(function (namespace, states) { | |
var res = {} | |
normalizeMap(states).forEach(function (ref) { | |
var key = ref.key; | |
var val = ref.val; | |
res[key] = function mappedState () { | |
var state = this.$store.state | |
var getters = this.$store.getters | |
if (namespace) { | |
var module = this.$store._modulesNamespaceMap[namespace] | |
if (!module) { | |
warnNamespace('mapState', namespace) | |
return | |
} | |
state = module.state | |
getters = module.context.getters | |
} | |
return typeof val === 'function' | |
? val.call(this, state, getters) | |
: state[val] | |
} | |
}) | |
return res | |
}) | |
var mapMutations = normalizeNamespace(function (namespace, mutations) { | |
var res = {} | |
normalizeMap(mutations).forEach(function (ref) { | |
var key = ref.key; | |
var val = ref.val; | |
val = namespace + val | |
res[key] = function mappedMutation () { | |
var args = [], len = arguments.length; | |
while ( len-- ) args[ len ] = arguments[ len ]; | |
return this.$store.commit.apply(this.$store, [val].concat(args)) | |
} | |
}) | |
return res | |
}) | |
var mapGetters = normalizeNamespace(function (namespace, getters) { | |
var res = {} | |
normalizeMap(getters).forEach(function (ref) { | |
var key = ref.key; | |
var val = ref.val; | |
val = namespace + val | |
res[key] = function mappedGetter () { | |
if (!(val in this.$store.getters)) { | |
console.error(("[vuex] unknown getter: " + val)) | |
} | |
return this.$store.getters[val] | |
} | |
}) | |
return res | |
}) | |
var mapActions = normalizeNamespace(function (namespace, actions) { | |
var res = {} | |
normalizeMap(actions).forEach(function (ref) { | |
var key = ref.key; | |
var val = ref.val; | |
val = namespace + val | |
res[key] = function mappedAction () { | |
var args = [], len = arguments.length; | |
while ( len-- ) args[ len ] = arguments[ len ]; | |
return this.$store.dispatch.apply(this.$store, [val].concat(args)) | |
} | |
}) | |
return res | |
}) | |
function normalizeMap (map) { | |
return Array.isArray(map) | |
? map.map(function (key) { return ({ key: key, val: key }); }) | |
: Object.keys(map).map(function (key) { return ({ key: key, val: map[key] }); }) | |
} | |
function normalizeNamespace (fn) { | |
return function (namespace, map) { | |
if (typeof namespace !== 'string') { | |
map = namespace | |
namespace = '' | |
} else if (namespace.charAt(namespace.length - 1) !== '/') { | |
namespace += '/' | |
} | |
return fn(namespace, map) | |
} | |
} | |
function warnNamespace (helper, namespace) { | |
console.error(("[vuex] module namespace not found in " + helper + "(): " + namespace)) | |
} | |
/** | |
* forEach for object | |
*/ | |
function forEachValue (obj, fn) { | |
Object.keys(obj).forEach(function (key) { return fn(obj[key], key); }) | |
} | |
function isObject (obj) { | |
return obj !== null && typeof obj === 'object' | |
} | |
function isPromise (val) { | |
return val && typeof val.then === 'function' | |
} | |
function assert (condition, msg) { | |
if (!condition) { throw new Error(("[vuex] " + msg)) } | |
} | |
var Module = function Module (rawModule, runtime) { | |
this.runtime = runtime | |
this._children = Object.create(null) | |
this._rawModule = rawModule | |
}; | |
var prototypeAccessors$1 = { state: {},namespaced: {} }; | |
prototypeAccessors$1.state.get = function () { | |
return this._rawModule.state || {} | |
}; | |
prototypeAccessors$1.namespaced.get = function () { | |
return !!this._rawModule.namespaced | |
}; | |
Module.prototype.addChild = function addChild (key, module) { | |
this._children[key] = module | |
}; | |
Module.prototype.removeChild = function removeChild (key) { | |
delete this._children[key] | |
}; | |
Module.prototype.getChild = function getChild (key) { | |
return this._children[key] | |
}; | |
Module.prototype.update = function update (rawModule) { | |
this._rawModule.namespaced = rawModule.namespaced | |
if (rawModule.actions) { | |
this._rawModule.actions = rawModule.actions | |
} | |
if (rawModule.mutations) { | |
this._rawModule.mutations = rawModule.mutations | |
} | |
if (rawModule.getters) { | |
this._rawModule.getters = rawModule.getters | |
} | |
}; | |
Module.prototype.forEachChild = function forEachChild (fn) { | |
forEachValue(this._children, fn) | |
}; | |
Module.prototype.forEachGetter = function forEachGetter (fn) { | |
if (this._rawModule.getters) { | |
forEachValue(this._rawModule.getters, fn) | |
} | |
}; | |
Module.prototype.forEachAction = function forEachAction (fn) { | |
if (this._rawModule.actions) { | |
forEachValue(this._rawModule.actions, fn) | |
} | |
}; | |
Module.prototype.forEachMutation = function forEachMutation (fn) { | |
if (this._rawModule.mutations) { | |
forEachValue(this._rawModule.mutations, fn) | |
} | |
}; | |
Object.defineProperties( Module.prototype, prototypeAccessors$1 ); | |
var ModuleCollection = function ModuleCollection (rawRootModule) { | |
var this$1 = this; | |
// register root module (Vuex.Store options) | |
this.root = new Module(rawRootModule, false) | |
// register all nested modules | |
if (rawRootModule.modules) { | |
forEachValue(rawRootModule.modules, function (rawModule, key) { | |
this$1.register([key], rawModule, false) | |
}) | |
} | |
}; | |
ModuleCollection.prototype.get = function get (path) { | |
return path.reduce(function (module, key) { | |
return module.getChild(key) | |
}, this.root) | |
}; | |
ModuleCollection.prototype.getNamespace = function getNamespace (path) { | |
var module = this.root | |
return path.reduce(function (namespace, key) { | |
module = module.getChild(key) | |
return namespace + (module.namespaced ? key + '/' : '') | |
}, '') | |
}; | |
ModuleCollection.prototype.update = function update$1 (rawRootModule) { | |
update(this.root, rawRootModule) | |
}; | |
ModuleCollection.prototype.register = function register (path, rawModule, runtime) { | |
var this$1 = this; | |
if ( runtime === void 0 ) runtime = true; | |
var parent = this.get(path.slice(0, -1)) | |
var newModule = new Module(rawModule, runtime) | |
parent.addChild(path[path.length - 1], newModule) | |
// register nested modules | |
if (rawModule.modules) { | |
forEachValue(rawModule.modules, function (rawChildModule, key) { | |
this$1.register(path.concat(key), rawChildModule, runtime) | |
}) | |
} | |
}; | |
ModuleCollection.prototype.unregister = function unregister (path) { | |
var parent = this.get(path.slice(0, -1)) | |
var key = path[path.length - 1] | |
if (!parent.getChild(key).runtime) { return } | |
parent.removeChild(key) | |
}; | |
function update (targetModule, newModule) { | |
// update target module | |
targetModule.update(newModule) | |
// update nested modules | |
if (newModule.modules) { | |
for (var key in newModule.modules) { | |
if (!targetModule.getChild(key)) { | |
console.warn( | |
"[vuex] trying to add a new module '" + key + "' on hot reloading, " + | |
'manual reload is needed' | |
) | |
return | |
} | |
update(targetModule.getChild(key), newModule.modules[key]) | |
} | |
} | |
} | |
var Vue // bind on install | |
var Store = function Store (options) { | |
var this$1 = this; | |
if ( options === void 0 ) options = {}; | |
assert(Vue, "must call Vue.use(Vuex) before creating a store instance.") | |
assert(typeof Promise !== 'undefined', "vuex requires a Promise polyfill in this browser.") | |
var state = options.state; if ( state === void 0 ) state = {}; | |
var plugins = options.plugins; if ( plugins === void 0 ) plugins = []; | |
var strict = options.strict; if ( strict === void 0 ) strict = false; | |
// store internal state | |
this._committing = false | |
this._actions = Object.create(null) | |
this._mutations = Object.create(null) | |
this._wrappedGetters = Object.create(null) | |
this._modules = new ModuleCollection(options) | |
this._modulesNamespaceMap = Object.create(null) | |
this._subscribers = [] | |
this._watcherVM = new Vue() | |
// bind commit and dispatch to self | |
var store = this | |
var ref = this; | |
var dispatch = ref.dispatch; | |
var commit = ref.commit; | |
this.dispatch = function boundDispatch (type, payload) { | |
return dispatch.call(store, type, payload) | |
} | |
this.commit = function boundCommit (type, payload, options) { | |
return commit.call(store, type, payload, options) | |
} | |
// strict mode | |
this.strict = strict | |
// init root module. | |
// this also recursively registers all sub-modules | |
// and collects all module getters inside this._wrappedGetters | |
installModule(this, state, [], this._modules.root) | |
// initialize the store vm, which is responsible for the reactivity | |
// (also registers _wrappedGetters as computed properties) | |
resetStoreVM(this, state) | |
// apply plugins | |
plugins.concat(devtoolPlugin).forEach(function (plugin) { return plugin(this$1); }) | |
}; | |
var prototypeAccessors = { state: {} }; | |
prototypeAccessors.state.get = function () { | |
return this._vm.$data.state | |
}; | |
prototypeAccessors.state.set = function (v) { | |
assert(false, "Use store.replaceState() to explicit replace store state.") | |
}; | |
Store.prototype.commit = function commit (_type, _payload, _options) { | |
var this$1 = this; | |
// check object-style commit | |
var ref = unifyObjectStyle(_type, _payload, _options); | |
var type = ref.type; | |
var payload = ref.payload; | |
var options = ref.options; | |
var mutation = { type: type, payload: payload } | |
var entry = this._mutations[type] | |
if (!entry) { | |
console.error(("[vuex] unknown mutation type: " + type)) | |
return | |
} | |
this._withCommit(function () { | |
entry.forEach(function commitIterator (handler) { | |
handler(payload) | |
}) | |
}) | |
this._subscribers.forEach(function (sub) { return sub(mutation, this$1.state); }) | |
if (options && options.silent) { | |
console.warn( | |
"[vuex] mutation type: " + type + ". Silent option has been removed. " + | |
'Use the filter functionality in the vue-devtools' | |
) | |
} | |
}; | |
Store.prototype.dispatch = function dispatch (_type, _payload) { | |
// check object-style dispatch | |
var ref = unifyObjectStyle(_type, _payload); | |
var type = ref.type; | |
var payload = ref.payload; | |
var entry = this._actions[type] | |
if (!entry) { | |
console.error(("[vuex] unknown action type: " + type)) | |
return | |
} | |
return entry.length > 1 | |
? Promise.all(entry.map(function (handler) { return handler(payload); })) | |
: entry[0](payload) | |
}; | |
Store.prototype.subscribe = function subscribe (fn) { | |
var subs = this._subscribers | |
if (subs.indexOf(fn) < 0) { | |
subs.push(fn) | |
} | |
return function () { | |
var i = subs.indexOf(fn) | |
if (i > -1) { | |
subs.splice(i, 1) | |
} | |
} | |
}; | |
Store.prototype.watch = function watch (getter, cb, options) { | |
var this$1 = this; | |
assert(typeof getter === 'function', "store.watch only accepts a function.") | |
return this._watcherVM.$watch(function () { return getter(this$1.state, this$1.getters); }, cb, options) | |
}; | |
Store.prototype.replaceState = function replaceState (state) { | |
var this$1 = this; | |
this._withCommit(function () { | |
this$1._vm.state = state | |
}) | |
}; | |
Store.prototype.registerModule = function registerModule (path, rawModule) { | |
if (typeof path === 'string') { path = [path] } | |
assert(Array.isArray(path), "module path must be a string or an Array.") | |
this._modules.register(path, rawModule) | |
installModule(this, this.state, path, this._modules.get(path)) | |
// reset store to update getters... | |
resetStoreVM(this, this.state) | |
}; | |
Store.prototype.unregisterModule = function unregisterModule (path) { | |
var this$1 = this; | |
if (typeof path === 'string') { path = [path] } | |
assert(Array.isArray(path), "module path must be a string or an Array.") | |
this._modules.unregister(path) | |
this._withCommit(function () { | |
var parentState = getNestedState(this$1.state, path.slice(0, -1)) | |
Vue.delete(parentState, path[path.length - 1]) | |
}) | |
resetStore(this) | |
}; | |
Store.prototype.hotUpdate = function hotUpdate (newOptions) { | |
this._modules.update(newOptions) | |
resetStore(this) | |
}; | |
Store.prototype._withCommit = function _withCommit (fn) { | |
var committing = this._committing | |
this._committing = true | |
fn() | |
this._committing = committing | |
}; | |
Object.defineProperties( Store.prototype, prototypeAccessors ); | |
function resetStore (store) { | |
store._actions = Object.create(null) | |
store._mutations = Object.create(null) | |
store._wrappedGetters = Object.create(null) | |
store._modulesNamespaceMap = Object.create(null) | |
var state = store.state | |
// init all modules | |
installModule(store, state, [], store._modules.root, true) | |
// reset vm | |
resetStoreVM(store, state) | |
} | |
function resetStoreVM (store, state) { | |
var oldVm = store._vm | |
// bind store public getters | |
store.getters = {} | |
var wrappedGetters = store._wrappedGetters | |
var computed = {} | |
forEachValue(wrappedGetters, function (fn, key) { | |
// use computed to leverage its lazy-caching mechanism | |
computed[key] = function () { return fn(store); } | |
Object.defineProperty(store.getters, key, { | |
get: function () { return store._vm[key]; }, | |
enumerable: true // for local getters | |
}) | |
}) | |
// use a Vue instance to store the state tree | |
// suppress warnings just in case the user has added | |
// some funky global mixins | |
var silent = Vue.config.silent | |
Vue.config.silent = true | |
store._vm = new Vue({ | |
data: { state: state }, | |
computed: computed | |
}) | |
Vue.config.silent = silent | |
// enable strict mode for new vm | |
if (store.strict) { | |
enableStrictMode(store) | |
} | |
if (oldVm) { | |
// dispatch changes in all subscribed watchers | |
// to force getter re-evaluation. | |
store._withCommit(function () { | |
oldVm.state = null | |
}) | |
Vue.nextTick(function () { return oldVm.$destroy(); }) | |
} | |
} | |
function installModule (store, rootState, path, module, hot) { | |
var isRoot = !path.length | |
var namespace = store._modules.getNamespace(path) | |
// register in namespace map | |
if (namespace) { | |
store._modulesNamespaceMap[namespace] = module | |
} | |
// set state | |
if (!isRoot && !hot) { | |
var parentState = getNestedState(rootState, path.slice(0, -1)) | |
var moduleName = path[path.length - 1] | |
store._withCommit(function () { | |
Vue.set(parentState, moduleName, module.state) | |
}) | |
} | |
var local = module.context = makeLocalContext(store, namespace) | |
module.forEachMutation(function (mutation, key) { | |
var namespacedType = namespace + key | |
registerMutation(store, namespacedType, mutation, path) | |
}) | |
module.forEachAction(function (action, key) { | |
var namespacedType = namespace + key | |
registerAction(store, namespacedType, action, local, path) | |
}) | |
module.forEachGetter(function (getter, key) { | |
var namespacedType = namespace + key | |
registerGetter(store, namespacedType, getter, local, path) | |
}) | |
module.forEachChild(function (child, key) { | |
installModule(store, rootState, path.concat(key), child, hot) | |
}) | |
} | |
/** | |
* make localized dispatch, commit and getters | |
* if there is no namespace, just use root ones | |
*/ | |
function makeLocalContext (store, namespace) { | |
var noNamespace = namespace === '' | |
var local = { | |
dispatch: noNamespace ? store.dispatch : function (_type, _payload, _options) { | |
var args = unifyObjectStyle(_type, _payload, _options) | |
var payload = args.payload; | |
var options = args.options; | |
var type = args.type; | |
if (!options || !options.root) { | |
type = namespace + type | |
if (!store._actions[type]) { | |
console.error(("[vuex] unknown local action type: " + (args.type) + ", global type: " + type)) | |
return | |
} | |
} | |
return store.dispatch(type, payload) | |
}, | |
commit: noNamespace ? store.commit : function (_type, _payload, _options) { | |
var args = unifyObjectStyle(_type, _payload, _options) | |
var payload = args.payload; | |
var options = args.options; | |
var type = args.type; | |
if (!options || !options.root) { | |
type = namespace + type | |
if (!store._mutations[type]) { | |
console.error(("[vuex] unknown local mutation type: " + (args.type) + ", global type: " + type)) | |
return | |
} | |
} | |
store.commit(type, payload, options) | |
} | |
} | |
// getters object must be gotten lazily | |
// because store.getters will be changed by vm update | |
Object.defineProperty(local, 'getters', { | |
get: noNamespace ? function () { return store.getters; } : function () { return makeLocalGetters(store, namespace); } | |
}) | |
return local | |
} | |
function makeLocalGetters (store, namespace) { | |
var gettersProxy = {} | |
var splitPos = namespace.length | |
Object.keys(store.getters).forEach(function (type) { | |
// skip if the target getter is not match this namespace | |
if (type.slice(0, splitPos) !== namespace) { return } | |
// extract local getter type | |
var localType = type.slice(splitPos) | |
// Add a port to the getters proxy. | |
// Define as getter property because | |
// we do not want to evaluate the getters in this time. | |
Object.defineProperty(gettersProxy, localType, { | |
get: function () { return store.getters[type]; }, | |
enumerable: true | |
}) | |
}) | |
return gettersProxy | |
} | |
function registerMutation (store, type, handler, path) { | |
var entry = store._mutations[type] || (store._mutations[type] = []) | |
entry.push(function wrappedMutationHandler (payload) { | |
handler(getNestedState(store.state, path), payload) | |
}) | |
} | |
function registerAction (store, type, handler, local, path) { | |
var entry = store._actions[type] || (store._actions[type] = []) | |
entry.push(function wrappedActionHandler (payload, cb) { | |
var res = handler({ | |
dispatch: local.dispatch, | |
commit: local.commit, | |
getters: local.getters, | |
state: getNestedState(store.state, path), | |
rootGetters: store.getters, | |
rootState: store.state | |
}, payload, cb) | |
if (!isPromise(res)) { | |
res = Promise.resolve(res) | |
} | |
if (store._devtoolHook) { | |
return res.catch(function (err) { | |
store._devtoolHook.emit('vuex:error', err) | |
throw err | |
}) | |
} else { | |
return res | |
} | |
}) | |
} | |
function registerGetter (store, type, rawGetter, local, path) { | |
if (store._wrappedGetters[type]) { | |
console.error(("[vuex] duplicate getter key: " + type)) | |
return | |
} | |
store._wrappedGetters[type] = function wrappedGetter (store) { | |
return rawGetter( | |
getNestedState(store.state, path), // local state | |
local.getters, // local getters | |
store.state, // root state | |
store.getters // root getters | |
) | |
} | |
} | |
function enableStrictMode (store) { | |
store._vm.$watch('state', function () { | |
assert(store._committing, "Do not mutate vuex store state outside mutation handlers.") | |
}, { deep: true, sync: true }) | |
} | |
function getNestedState (state, path) { | |
return path.length | |
? path.reduce(function (state, key) { return state[key]; }, state) | |
: state | |
} | |
function unifyObjectStyle (type, payload, options) { | |
if (isObject(type) && type.type) { | |
options = payload | |
payload = type | |
type = type.type | |
} | |
return { type: type, payload: payload, options: options } | |
} | |
function install (_Vue) { | |
if (Vue) { | |
console.error( | |
'[vuex] already installed. Vue.use(Vuex) should be called only once.' | |
) | |
return | |
} | |
Vue = _Vue | |
applyMixin(Vue) | |
} | |
// auto install in dist mode | |
if (typeof window !== 'undefined' && window.Vue) { | |
install(window.Vue) | |
} | |
var index = { | |
Store: Store, | |
install: install, | |
version: '2.1.1', | |
mapState: mapState, | |
mapMutations: mapMutations, | |
mapGetters: mapGetters, | |
mapActions: mapActions | |
} | |
return index; | |
}))); | |
},{}]},{},[8]); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Nicholas Shindler</title> | |
<!-- import fonts and stylesheets --> | |
</head> | |
<body> | |
<!-- App Body Here --> | |
<div id="app"></div> | |
<!-- external scripts --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.1.1/vuex.js"></script> | |
<link href="https://fonts.googleapis.com/css?family=Oswald|Roboto" rel="stylesheet"> | |
<!-- css scripts --> | |
<link rel="stylesheet" type="text/css" href="frontend/styles/global.css"> | |
<link rel="stylesheet" type="text/css" href="frontend/styles/frame.css"> | |
<link rel="stylesheet" type="text/css" href="frontend/styles/menu.css"> | |
<link rel="stylesheet" type="text/css" href="frontend/styles/photography.css"> | |
<script type="text/javascript" src="bundle.js"></script> | |
<!-- start window --> | |
<script> | |
// window.start("#app"); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment