From f69b2c158e67cfca39dbf4ba7b0fe2299e89c88a Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Wed, 3 Jul 2019 16:27:32 +0200 Subject: [PATCH 01/30] chore(release): 3.0.7 --- dist/vue-router.common.js | 19 +++++++++++-------- dist/vue-router.esm.browser.js | 19 +++++++++++-------- dist/vue-router.esm.browser.min.js | 4 ++-- dist/vue-router.esm.js | 19 +++++++++++-------- dist/vue-router.js | 19 +++++++++++-------- dist/vue-router.min.js | 4 ++-- package.json | 2 +- 7 files changed, 49 insertions(+), 37 deletions(-) diff --git a/dist/vue-router.common.js b/dist/vue-router.common.js index dbf4c7a28..a97bfb988 100644 --- a/dist/vue-router.common.js +++ b/dist/vue-router.common.js @@ -1,5 +1,5 @@ /*! - * vue-router v3.0.6 + * vue-router v3.0.7 * (c) 2019 Evan You * @license MIT */ @@ -1389,10 +1389,8 @@ function createMatcher ( } } - if (record) { - location.path = fillParams(record.path, location.params, ("named route \"" + name + "\"")); - return _createRoute(record, location, redirectedFrom) - } + location.path = fillParams(record.path, location.params, ("named route \"" + name + "\"")); + return _createRoute(record, location, redirectedFrom) } else if (location.path) { location.params = {}; for (var i = 0; i < pathList.length; i++) { @@ -1547,7 +1545,12 @@ var positionStore = Object.create(null); function setupScroll () { // Fix for #1585 for Firefox // Fix for #2195 Add optional third attribute to workaround a bug in safari https://bugs.webkit.org/show_bug.cgi?id=182678 - window.history.replaceState({ key: getStateKey() }, '', window.location.href.replace(window.location.origin, '')); + // Fix for #2774 Support for apps loaded from Windows file shares not mapped to network drives: replaced location.origin with + // window.location.protocol + '//' + window.location.host + // location.host contains the port and location.hostname doesn't + var protocolAndPath = window.location.protocol + '//' + window.location.host; + var absolutePath = window.location.href.replace(protocolAndPath, ''); + window.history.replaceState({ key: getStateKey() }, '', absolutePath); window.addEventListener('popstate', function (e) { saveScrollPosition(); if (e.state && e.state.key) { @@ -2119,7 +2122,6 @@ function bindEnterGuard ( ) { return function routeEnterGuard (to, from, next) { return guard(to, from, function (cb) { - next(cb); if (typeof cb === 'function') { cbs.push(function () { // #750 @@ -2130,6 +2132,7 @@ function bindEnterGuard ( poll(cb, match.instances, key, isValid); }); } + next(cb); }) } } @@ -2664,7 +2667,7 @@ function createHref (base, fullPath, mode) { } VueRouter.install = install; -VueRouter.version = '3.0.6'; +VueRouter.version = '3.0.7'; if (inBrowser && window.Vue) { window.Vue.use(VueRouter); diff --git a/dist/vue-router.esm.browser.js b/dist/vue-router.esm.browser.js index 064681d1d..2602ba302 100644 --- a/dist/vue-router.esm.browser.js +++ b/dist/vue-router.esm.browser.js @@ -1,5 +1,5 @@ /*! - * vue-router v3.0.6 + * vue-router v3.0.7 * (c) 2019 Evan You * @license MIT */ @@ -1364,10 +1364,8 @@ function createMatcher ( } } - if (record) { - location.path = fillParams(record.path, location.params, `named route "${name}"`); - return _createRoute(record, location, redirectedFrom) - } + location.path = fillParams(record.path, location.params, `named route "${name}"`); + return _createRoute(record, location, redirectedFrom) } else if (location.path) { location.params = {}; for (let i = 0; i < pathList.length; i++) { @@ -1519,7 +1517,12 @@ const positionStore = Object.create(null); function setupScroll () { // Fix for #1585 for Firefox // Fix for #2195 Add optional third attribute to workaround a bug in safari https://bugs.webkit.org/show_bug.cgi?id=182678 - window.history.replaceState({ key: getStateKey() }, '', window.location.href.replace(window.location.origin, '')); + // Fix for #2774 Support for apps loaded from Windows file shares not mapped to network drives: replaced location.origin with + // window.location.protocol + '//' + window.location.host + // location.host contains the port and location.hostname doesn't + const protocolAndPath = window.location.protocol + '//' + window.location.host; + const absolutePath = window.location.href.replace(protocolAndPath, ''); + window.history.replaceState({ key: getStateKey() }, '', absolutePath); window.addEventListener('popstate', e => { saveScrollPosition(); if (e.state && e.state.key) { @@ -2104,7 +2107,6 @@ function bindEnterGuard ( ) { return function routeEnterGuard (to, from, next) { return guard(to, from, cb => { - next(cb); if (typeof cb === 'function') { cbs.push(() => { // #750 @@ -2115,6 +2117,7 @@ function bindEnterGuard ( poll(cb, match.instances, key, isValid); }); } + next(cb); }) } } @@ -2622,7 +2625,7 @@ function createHref (base, fullPath, mode) { } VueRouter.install = install; -VueRouter.version = '3.0.6'; +VueRouter.version = '3.0.7'; if (inBrowser && window.Vue) { window.Vue.use(VueRouter); diff --git a/dist/vue-router.esm.browser.min.js b/dist/vue-router.esm.browser.min.js index 39ad79be8..d8ada1d8b 100644 --- a/dist/vue-router.esm.browser.min.js +++ b/dist/vue-router.esm.browser.min.js @@ -1,6 +1,6 @@ /*! - * vue-router v3.0.6 + * vue-router v3.0.7 * (c) 2019 Evan You * @license MIT */ -function t(t){return Object.prototype.toString.call(t).indexOf("Error")>-1}function e(t,e){for(const n in e)t[n]=e[n];return t}var n={name:"RouterView",functional:!0,props:{name:{type:String,default:"default"}},render(t,{props:n,children:r,parent:o,data:i}){i.routerView=!0;const s=o.$createElement,a=n.name,c=o.$route,u=o._routerViewCache||(o._routerViewCache={});let h=0,p=!1;for(;o&&o._routerRoot!==o;){const t=o.$vnode&&o.$vnode.data;t&&(t.routerView&&h++,t.keepAlive&&o._inactive&&(p=!0)),o=o.$parent}if(i.routerViewDepth=h,p)return s(u[a],i,r);const l=c.matched[h];if(!l)return u[a]=null,s();const f=u[a]=l.components[a];i.registerRouteInstance=((t,e)=>{const n=l.instances[a];(e&&n!==t||!e&&n===t)&&(l.instances[a]=e)}),(i.hook||(i.hook={})).prepatch=((t,e)=>{l.instances[a]=e.componentInstance}),i.hook.init=(t=>{t.data.keepAlive&&t.componentInstance&&t.componentInstance!==l.instances[a]&&(l.instances[a]=t.componentInstance)});let d=i.props=function(t,e){switch(typeof e){case"undefined":return;case"object":return e;case"function":return e(t);case"boolean":return e?t.params:void 0}}(c,l.props&&l.props[a]);if(d){d=i.props=e({},d);const t=i.attrs=i.attrs||{};for(const e in d)f.props&&e in f.props||(t[e]=d[e],delete d[e])}return s(f,i,r)}};const r=/[!'()*]/g,o=t=>"%"+t.charCodeAt(0).toString(16),i=/%2C/g,s=t=>encodeURIComponent(t).replace(r,o).replace(i,","),a=decodeURIComponent;function c(t){const e={};return(t=t.trim().replace(/^(\?|#|&)/,""))?(t.split("&").forEach(t=>{const n=t.replace(/\+/g," ").split("="),r=a(n.shift()),o=n.length>0?a(n.join("=")):null;void 0===e[r]?e[r]=o:Array.isArray(e[r])?e[r].push(o):e[r]=[e[r],o]}),e):e}function u(t){const e=t?Object.keys(t).map(e=>{const n=t[e];if(void 0===n)return"";if(null===n)return s(e);if(Array.isArray(n)){const t=[];return n.forEach(n=>{void 0!==n&&(null===n?t.push(s(e)):t.push(s(e)+"="+s(n)))}),t.join("&")}return s(e)+"="+s(n)}).filter(t=>t.length>0).join("&"):null;return e?`?${e}`:""}const h=/\/?$/;function p(t,e,n,r){const o=r&&r.options.stringifyQuery;let i=e.query||{};try{i=l(i)}catch(t){}const s={name:e.name||t&&t.name,meta:t&&t.meta||{},path:e.path||"/",hash:e.hash||"",query:i,params:e.params||{},fullPath:y(e,o),matched:t?d(t):[]};return n&&(s.redirectedFrom=y(n,o)),Object.freeze(s)}function l(t){if(Array.isArray(t))return t.map(l);if(t&&"object"==typeof t){const e={};for(const n in t)e[n]=l(t[n]);return e}return t}const f=p(null,{path:"/"});function d(t){const e=[];for(;t;)e.unshift(t),t=t.parent;return e}function y({path:t,query:e={},hash:n=""},r){return(t||"/")+(r||u)(e)+n}function m(t,e){return e===f?t===e:!!e&&(t.path&&e.path?t.path.replace(h,"")===e.path.replace(h,"")&&t.hash===e.hash&&g(t.query,e.query):!(!t.name||!e.name)&&(t.name===e.name&&t.hash===e.hash&&g(t.query,e.query)&&g(t.params,e.params)))}function g(t={},e={}){if(!t||!e)return t===e;const n=Object.keys(t),r=Object.keys(e);return n.length===r.length&&n.every(n=>{const r=t[n],o=e[n];return"object"==typeof r&&"object"==typeof o?g(r,o):String(r)===String(o)})}const b=[String,Object],w=[String,Array];var v={name:"RouterLink",props:{to:{type:b,required:!0},tag:{type:String,default:"a"},exact:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,event:{type:w,default:"click"}},render(t){const n=this.$router,r=this.$route,{location:o,route:i,href:s}=n.resolve(this.to,r,this.append),a={},c=n.options.linkActiveClass,u=n.options.linkExactActiveClass,l=null==c?"router-link-active":c,f=null==u?"router-link-exact-active":u,d=null==this.activeClass?l:this.activeClass,y=null==this.exactActiveClass?f:this.exactActiveClass,g=o.path?p(null,o,null,n):i;a[y]=m(r,g),a[d]=this.exact?a[y]:function(t,e){return 0===t.path.replace(h,"/").indexOf(e.path.replace(h,"/"))&&(!e.hash||t.hash===e.hash)&&function(t,e){for(const n in e)if(!(n in t))return!1;return!0}(t.query,e.query)}(r,g);const b=t=>{x(t)&&(this.replace?n.replace(o):n.push(o))},w={click:x};Array.isArray(this.event)?this.event.forEach(t=>{w[t]=b}):w[this.event]=b;const v={class:a};if("a"===this.tag)v.on=w,v.attrs={href:s};else{const t=function t(e){if(e){let n;for(let r=0;r{!function t(e,n,r,o,i,s){const{path:a,name:c}=o;const u=o.pathToRegexpOptions||{};const h=function(t,e,n){n||(t=t.replace(/\/$/,""));return"/"===t[0]?t:null==e?t:O(`${e.path}/${t}`)}(a,i,u.strict);"boolean"==typeof o.caseSensitive&&(u.sensitive=o.caseSensitive);const p={path:h,regex:K(h,u),components:o.components||{default:o.component},instances:{},name:c,parent:i,matchAs:s,redirect:o.redirect,beforeEnter:o.beforeEnter,meta:o.meta||{},props:null==o.props?{}:o.components?o.props:{default:o.props}};o.children&&o.children.forEach(o=>{const i=s?O(`${s}/${o.path}`):void 0;t(e,n,r,o,p,i)});if(void 0!==o.alias){const s=Array.isArray(o.alias)?o.alias:[o.alias];s.forEach(s=>{const a={path:s,children:o.children};t(e,n,r,a,i,p.path||"/")})}n[p.path]||(e.push(p.path),n[p.path]=p);c&&(r[c]||(r[c]=p))}(o,i,s,t)});for(let t=0,e=o.length;t=0&&(e=t.slice(r),t=t.slice(0,r));const o=t.indexOf("?");return o>=0&&(n=t.slice(o+1),t=t.slice(0,o)),{path:t,query:n,hash:e}}(i.path||""),a=n&&n.path||"/",u=s.path?E(s.path,a,r||i.append):a,h=function(t,e={},n){const r=n||c;let o;try{o=r(t||"")}catch(t){o={}}for(const t in e)o[t]=e[t];return o}(s.query,i.query,o&&o.options.parseQuery);let p=i.hash||s.hash;return p&&"#"!==p.charAt(0)&&(p=`#${p}`),{_normalized:!0,path:u,query:h,hash:p}}function N(t,e){const{pathList:n,pathMap:r,nameMap:o}=F(t);function i(t,i,s){const c=J(t,i,!1,e),{name:u}=c;if(u){const t=o[u];if(!t)return a(null,c);const e=t.regex.keys.filter(t=>!t.optional).map(t=>t.name);if("object"!=typeof c.params&&(c.params={}),i&&"object"==typeof i.params)for(const t in i.params)!(t in c.params)&&e.indexOf(t)>-1&&(c.params[t]=i.params[t]);if(t)return c.path=D(t.path,c.params),a(t,c,s)}else if(c.path){c.params={};for(let t=0;t{G(),t.state&&t.state.key&&function(t){it=t}(t.state.key)})}function W(t,e,n,r){if(!t.app)return;const o=t.options.scrollBehavior;o&&t.app.$nextTick(()=>{const i=function(){const t=at();if(t)return X[t]}(),s=o.call(t,e,n,r?i:null);s&&("function"==typeof s.then?s.then(t=>{nt(t,i)}).catch(t=>{}):nt(s,i))})}function G(){const t=at();t&&(X[t]={x:window.pageXOffset,y:window.pageYOffset})}function Z(t){return et(t.x)||et(t.y)}function tt(t){return{x:et(t.x)?t.x:window.pageXOffset,y:et(t.y)?t.y:window.pageYOffset}}function et(t){return"number"==typeof t}function nt(t,e){const n="object"==typeof t;if(n&&"string"==typeof t.selector){const n=document.querySelector(t.selector);if(n){let o=t.offset&&"object"==typeof t.offset?t.offset:{};e=function(t,e){const n=document.documentElement.getBoundingClientRect(),r=t.getBoundingClientRect();return{x:r.left-n.left-e.x,y:r.top-n.top-e.y}}(n,o={x:et((r=o).x)?r.x:0,y:et(r.y)?r.y:0})}else Z(t)&&(e=tt(t))}else n&&Z(t)&&(e=tt(t));var r;e&&window.scrollTo(e.x,e.y)}const rt=R&&function(){const t=window.navigator.userAgent;return(-1===t.indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&(window.history&&"pushState"in window.history)}(),ot=R&&window.performance&&window.performance.now?window.performance:Date;let it=st();function st(){return ot.now().toFixed(3)}function at(){return it}function ct(t,e){G();const n=window.history;try{e?n.replaceState({key:it},"",t):(it=st(),n.pushState({key:it},"",t))}catch(n){window.location[e?"replace":"assign"](t)}}function ut(t){ct(t,!0)}function ht(t,e,n){const r=o=>{o>=t.length?n():t[o]?e(t[o],()=>{r(o+1)}):r(o+1)};r(0)}function pt(e){return(n,r,o)=>{let i=!1,s=0,a=null;lt(e,(e,n,r,c)=>{if("function"==typeof e&&void 0===e.cid){i=!0,s++;const n=yt(t=>{(function(t){return t.__esModule||dt&&"Module"===t[Symbol.toStringTag]})(t)&&(t=t.default),e.resolved="function"==typeof t?t:k.extend(t),r.components[c]=t,--s<=0&&o()}),u=yt(e=>{const n=`Failed to resolve async component ${c}: ${e}`;a||(a=t(e)?e:new Error(n),o(a))});let h;try{h=e(n,u)}catch(t){u(t)}if(h)if("function"==typeof h.then)h.then(n,u);else{const t=h.component;t&&"function"==typeof t.then&&t.then(n,u)}}}),i||o()}}function lt(t,e){return ft(t.map(t=>Object.keys(t.components).map(n=>e(t.components[n],t.instances[n],t,n))))}function ft(t){return Array.prototype.concat.apply([],t)}const dt="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function yt(t){let e=!1;return function(...n){if(!e)return e=!0,t.apply(this,n)}}class mt{constructor(t,e){this.router=t,this.base=function(t){if(!t)if(R){const e=document.querySelector("base");t=(t=e&&e.getAttribute("href")||"/").replace(/^https?:\/\/[^\/]+/,"")}else t="/";"/"!==t.charAt(0)&&(t="/"+t);return t.replace(/\/$/,"")}(e),this.current=f,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[]}listen(t){this.cb=t}onReady(t,e){this.ready?t():(this.readyCbs.push(t),e&&this.readyErrorCbs.push(e))}onError(t){this.errorCbs.push(t)}transitionTo(t,e,n){const r=this.router.match(t,this.current);this.confirmTransition(r,()=>{this.updateRoute(r),e&&e(r),this.ensureURL(),this.ready||(this.ready=!0,this.readyCbs.forEach(t=>{t(r)}))},t=>{n&&n(t),t&&!this.ready&&(this.ready=!0,this.readyErrorCbs.forEach(e=>{e(t)}))})}confirmTransition(e,n,r){const o=this.current,i=e=>{t(e)&&(this.errorCbs.length?this.errorCbs.forEach(t=>{t(e)}):console.error(e)),r&&r(e)};if(m(e,o)&&e.matched.length===o.matched.length)return this.ensureURL(),i();const{updated:s,deactivated:a,activated:c}=function(t,e){let n;const r=Math.max(t.length,e.length);for(n=0;nt.beforeEnter),pt(c));this.pending=e;const h=(n,r)=>{if(this.pending!==e)return i();try{n(e,o,e=>{!1===e||t(e)?(this.ensureURL(!0),i(e)):"string"==typeof e||"object"==typeof e&&("string"==typeof e.path||"string"==typeof e.name)?(i(),"object"==typeof e&&e.replace?this.replace(e):this.push(e)):r(e)})}catch(t){i(t)}};ht(u,h,()=>{const t=[];ht(function(t,e,n){return gt(t,"beforeRouteEnter",(t,r,o,i)=>(function(t,e,n,r,o){return function(i,s,a){return t(i,s,t=>{a(t),"function"==typeof t&&r.push(()=>{!function t(e,n,r,o){n[r]&&!n[r]._isBeingDestroyed?e(n[r]):o()&&setTimeout(()=>{t(e,n,r,o)},16)}(t,e.instances,n,o)})})}})(t,o,i,e,n))}(c,t,()=>this.current===e).concat(this.router.resolveHooks),h,()=>{if(this.pending!==e)return i();this.pending=null,n(e),this.router.app&&this.router.app.$nextTick(()=>{t.forEach(t=>{t()})})})})}updateRoute(t){const e=this.current;this.current=t,this.cb&&this.cb(t),this.router.afterHooks.forEach(n=>{n&&n(t,e)})}}function gt(t,e,n,r){const o=lt(t,(t,r,o,i)=>{const s=function(t,e){"function"!=typeof t&&(t=k.extend(t));return t.options[e]}(t,e);if(s)return Array.isArray(s)?s.map(t=>n(t,r,o,i)):n(s,r,o,i)});return ft(r?o.reverse():o)}function bt(t,e){if(e)return function(){return t.apply(e,arguments)}}class wt extends mt{constructor(t,e){super(t,e);const n=t.options.scrollBehavior,r=rt&&n;r&&Y();const o=vt(this.base);window.addEventListener("popstate",e=>{const n=this.current,i=vt(this.base);this.current===f&&i===o||this.transitionTo(i,e=>{r&&W(t,e,n,!0)})})}go(t){window.history.go(t)}push(t,e,n){const{current:r}=this;this.transitionTo(t,t=>{ct(O(this.base+t.fullPath)),W(this.router,t,r,!1),e&&e(t)},n)}replace(t,e,n){const{current:r}=this;this.transitionTo(t,t=>{ut(O(this.base+t.fullPath)),W(this.router,t,r,!1),e&&e(t)},n)}ensureURL(t){if(vt(this.base)!==this.current.fullPath){const e=O(this.base+this.current.fullPath);t?ct(e):ut(e)}}getCurrentLocation(){return vt(this.base)}}function vt(t){let e=decodeURI(window.location.pathname);return t&&0===e.indexOf(t)&&(e=e.slice(t.length)),(e||"/")+window.location.search+window.location.hash}class xt extends mt{constructor(t,e,n){super(t,e),n&&function(t){const e=vt(t);if(!/^\/#/.test(e))return window.location.replace(O(t+"/#"+e)),!0}(this.base)||kt()}setupListeners(){const t=this.router.options.scrollBehavior,e=rt&&t;e&&Y(),window.addEventListener(rt?"popstate":"hashchange",()=>{const t=this.current;kt()&&this.transitionTo(Rt(),n=>{e&&W(this.router,n,t,!0),rt||At(n.fullPath)})})}push(t,e,n){const{current:r}=this;this.transitionTo(t,t=>{Ot(t.fullPath),W(this.router,t,r,!1),e&&e(t)},n)}replace(t,e,n){const{current:r}=this;this.transitionTo(t,t=>{At(t.fullPath),W(this.router,t,r,!1),e&&e(t)},n)}go(t){window.history.go(t)}ensureURL(t){const e=this.current.fullPath;Rt()!==e&&(t?Ot(e):At(e))}getCurrentLocation(){return Rt()}}function kt(){const t=Rt();return"/"===t.charAt(0)||(At("/"+t),!1)}function Rt(){let t=window.location.href;const e=t.indexOf("#");if(e<0)return"";const n=(t=t.slice(e+1)).indexOf("?");if(n<0){const e=t.indexOf("#");t=e>-1?decodeURI(t.slice(0,e))+t.slice(e):decodeURI(t)}else n>-1&&(t=decodeURI(t.slice(0,n))+t.slice(n));return t}function Et(t){const e=window.location.href,n=e.indexOf("#");return`${n>=0?e.slice(0,n):e}#${t}`}function Ot(t){rt?ct(Et(t)):window.location.hash=t}function At(t){rt?ut(Et(t)):window.location.replace(Et(t))}class Ct extends mt{constructor(t,e){super(t,e),this.stack=[],this.index=-1}push(t,e,n){this.transitionTo(t,t=>{this.stack=this.stack.slice(0,this.index+1).concat(t),this.index++,e&&e(t)},n)}replace(t,e,n){this.transitionTo(t,t=>{this.stack=this.stack.slice(0,this.index).concat(t),e&&e(t)},n)}go(t){const e=this.index+t;if(e<0||e>=this.stack.length)return;const n=this.stack[e];this.confirmTransition(n,()=>{this.index=e,this.updateRoute(n)})}getCurrentLocation(){const t=this.stack[this.stack.length-1];return t?t.fullPath:"/"}ensureURL(){}}class $t{constructor(t={}){this.app=null,this.apps=[],this.options=t,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=N(t.routes||[],this);let e=t.mode||"hash";switch(this.fallback="history"===e&&!rt&&!1!==t.fallback,this.fallback&&(e="hash"),R||(e="abstract"),this.mode=e,e){case"history":this.history=new wt(this,t.base);break;case"hash":this.history=new xt(this,t.base,this.fallback);break;case"abstract":this.history=new Ct(this,t.base)}}match(t,e,n){return this.matcher.match(t,e,n)}get currentRoute(){return this.history&&this.history.current}init(t){if(this.apps.push(t),t.$once("hook:destroyed",()=>{const e=this.apps.indexOf(t);e>-1&&this.apps.splice(e,1),this.app===t&&(this.app=this.apps[0]||null)}),this.app)return;this.app=t;const e=this.history;if(e instanceof wt)e.transitionTo(e.getCurrentLocation());else if(e instanceof xt){const t=()=>{e.setupListeners()};e.transitionTo(e.getCurrentLocation(),t,t)}e.listen(t=>{this.apps.forEach(e=>{e._route=t})})}beforeEach(t){return jt(this.beforeHooks,t)}beforeResolve(t){return jt(this.resolveHooks,t)}afterEach(t){return jt(this.afterHooks,t)}onReady(t,e){this.history.onReady(t,e)}onError(t){this.history.onError(t)}push(t,e,n){this.history.push(t,e,n)}replace(t,e,n){this.history.replace(t,e,n)}go(t){this.history.go(t)}back(){this.go(-1)}forward(){this.go(1)}getMatchedComponents(t){const e=t?t.matched?t:this.resolve(t).route:this.currentRoute;return e?[].concat.apply([],e.matched.map(t=>Object.keys(t.components).map(e=>t.components[e]))):[]}resolve(t,e,n){const r=J(t,e=e||this.history.current,n,this),o=this.match(r,e),i=o.redirectedFrom||o.fullPath;return{location:r,route:o,href:function(t,e,n){var r="hash"===n?"#"+e:e;return t?O(t+"/"+r):r}(this.history.base,i,this.mode),normalizedTo:r,resolved:o}}addRoutes(t){this.matcher.addRoutes(t),this.history.current!==f&&this.history.transitionTo(this.history.getCurrentLocation())}}function jt(t,e){return t.push(e),()=>{const n=t.indexOf(e);n>-1&&t.splice(n,1)}}$t.install=function t(e){if(t.installed&&k===e)return;t.installed=!0,k=e;const r=t=>void 0!==t,o=(t,e)=>{let n=t.$options._parentVnode;r(n)&&r(n=n.data)&&r(n=n.registerRouteInstance)&&n(t,e)};e.mixin({beforeCreate(){r(this.$options.router)?(this._routerRoot=this,this._router=this.$options.router,this._router.init(this),e.util.defineReactive(this,"_route",this._router.history.current)):this._routerRoot=this.$parent&&this.$parent._routerRoot||this,o(this,this)},destroyed(){o(this)}}),Object.defineProperty(e.prototype,"$router",{get(){return this._routerRoot._router}}),Object.defineProperty(e.prototype,"$route",{get(){return this._routerRoot._route}}),e.component("RouterView",n),e.component("RouterLink",v);const i=e.config.optionMergeStrategies;i.beforeRouteEnter=i.beforeRouteLeave=i.beforeRouteUpdate=i.created},$t.version="3.0.6",R&&window.Vue&&window.Vue.use($t);export default $t; \ No newline at end of file +function t(t){return Object.prototype.toString.call(t).indexOf("Error")>-1}function e(t,e){for(const n in e)t[n]=e[n];return t}var n={name:"RouterView",functional:!0,props:{name:{type:String,default:"default"}},render(t,{props:n,children:r,parent:o,data:i}){i.routerView=!0;const s=o.$createElement,a=n.name,c=o.$route,u=o._routerViewCache||(o._routerViewCache={});let h=0,p=!1;for(;o&&o._routerRoot!==o;){const t=o.$vnode&&o.$vnode.data;t&&(t.routerView&&h++,t.keepAlive&&o._inactive&&(p=!0)),o=o.$parent}if(i.routerViewDepth=h,p)return s(u[a],i,r);const l=c.matched[h];if(!l)return u[a]=null,s();const f=u[a]=l.components[a];i.registerRouteInstance=(t,e)=>{const n=l.instances[a];(e&&n!==t||!e&&n===t)&&(l.instances[a]=e)},(i.hook||(i.hook={})).prepatch=(t,e)=>{l.instances[a]=e.componentInstance},i.hook.init=t=>{t.data.keepAlive&&t.componentInstance&&t.componentInstance!==l.instances[a]&&(l.instances[a]=t.componentInstance)};let d=i.props=function(t,e){switch(typeof e){case"undefined":return;case"object":return e;case"function":return e(t);case"boolean":return e?t.params:void 0}}(c,l.props&&l.props[a]);if(d){d=i.props=e({},d);const t=i.attrs=i.attrs||{};for(const e in d)f.props&&e in f.props||(t[e]=d[e],delete d[e])}return s(f,i,r)}};const r=/[!'()*]/g,o=t=>"%"+t.charCodeAt(0).toString(16),i=/%2C/g,s=t=>encodeURIComponent(t).replace(r,o).replace(i,","),a=decodeURIComponent;function c(t){const e={};return(t=t.trim().replace(/^(\?|#|&)/,""))?(t.split("&").forEach(t=>{const n=t.replace(/\+/g," ").split("="),r=a(n.shift()),o=n.length>0?a(n.join("=")):null;void 0===e[r]?e[r]=o:Array.isArray(e[r])?e[r].push(o):e[r]=[e[r],o]}),e):e}function u(t){const e=t?Object.keys(t).map(e=>{const n=t[e];if(void 0===n)return"";if(null===n)return s(e);if(Array.isArray(n)){const t=[];return n.forEach(n=>{void 0!==n&&(null===n?t.push(s(e)):t.push(s(e)+"="+s(n)))}),t.join("&")}return s(e)+"="+s(n)}).filter(t=>t.length>0).join("&"):null;return e?`?${e}`:""}const h=/\/?$/;function p(t,e,n,r){const o=r&&r.options.stringifyQuery;let i=e.query||{};try{i=l(i)}catch(t){}const s={name:e.name||t&&t.name,meta:t&&t.meta||{},path:e.path||"/",hash:e.hash||"",query:i,params:e.params||{},fullPath:y(e,o),matched:t?d(t):[]};return n&&(s.redirectedFrom=y(n,o)),Object.freeze(s)}function l(t){if(Array.isArray(t))return t.map(l);if(t&&"object"==typeof t){const e={};for(const n in t)e[n]=l(t[n]);return e}return t}const f=p(null,{path:"/"});function d(t){const e=[];for(;t;)e.unshift(t),t=t.parent;return e}function y({path:t,query:e={},hash:n=""},r){return(t||"/")+(r||u)(e)+n}function m(t,e){return e===f?t===e:!!e&&(t.path&&e.path?t.path.replace(h,"")===e.path.replace(h,"")&&t.hash===e.hash&&g(t.query,e.query):!(!t.name||!e.name)&&(t.name===e.name&&t.hash===e.hash&&g(t.query,e.query)&&g(t.params,e.params)))}function g(t={},e={}){if(!t||!e)return t===e;const n=Object.keys(t),r=Object.keys(e);return n.length===r.length&&n.every(n=>{const r=t[n],o=e[n];return"object"==typeof r&&"object"==typeof o?g(r,o):String(r)===String(o)})}const w=[String,Object],b=[String,Array];var v={name:"RouterLink",props:{to:{type:w,required:!0},tag:{type:String,default:"a"},exact:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,event:{type:b,default:"click"}},render(t){const n=this.$router,r=this.$route,{location:o,route:i,href:s}=n.resolve(this.to,r,this.append),a={},c=n.options.linkActiveClass,u=n.options.linkExactActiveClass,l=null==c?"router-link-active":c,f=null==u?"router-link-exact-active":u,d=null==this.activeClass?l:this.activeClass,y=null==this.exactActiveClass?f:this.exactActiveClass,g=o.path?p(null,o,null,n):i;a[y]=m(r,g),a[d]=this.exact?a[y]:function(t,e){return 0===t.path.replace(h,"/").indexOf(e.path.replace(h,"/"))&&(!e.hash||t.hash===e.hash)&&function(t,e){for(const n in e)if(!(n in t))return!1;return!0}(t.query,e.query)}(r,g);const w=t=>{x(t)&&(this.replace?n.replace(o):n.push(o))},b={click:x};Array.isArray(this.event)?this.event.forEach(t=>{b[t]=w}):b[this.event]=w;const v={class:a};if("a"===this.tag)v.on=b,v.attrs={href:s};else{const t=function t(e){if(e){let n;for(let r=0;r{!function t(e,n,r,o,i,s){const{path:a,name:c}=o;const u=o.pathToRegexpOptions||{};const h=function(t,e,n){n||(t=t.replace(/\/$/,""));return"/"===t[0]?t:null==e?t:O(`${e.path}/${t}`)}(a,i,u.strict);"boolean"==typeof o.caseSensitive&&(u.sensitive=o.caseSensitive);const p={path:h,regex:K(h,u),components:o.components||{default:o.component},instances:{},name:c,parent:i,matchAs:s,redirect:o.redirect,beforeEnter:o.beforeEnter,meta:o.meta||{},props:null==o.props?{}:o.components?o.props:{default:o.props}};o.children&&o.children.forEach(o=>{const i=s?O(`${s}/${o.path}`):void 0;t(e,n,r,o,p,i)});if(void 0!==o.alias){const s=Array.isArray(o.alias)?o.alias:[o.alias];s.forEach(s=>{const a={path:s,children:o.children};t(e,n,r,a,i,p.path||"/")})}n[p.path]||(e.push(p.path),n[p.path]=p);c&&(r[c]||(r[c]=p))}(o,i,s,t)});for(let t=0,e=o.length;t=0&&(e=t.slice(r),t=t.slice(0,r));const o=t.indexOf("?");return o>=0&&(n=t.slice(o+1),t=t.slice(0,o)),{path:t,query:n,hash:e}}(i.path||""),a=n&&n.path||"/",u=s.path?E(s.path,a,r||i.append):a,h=function(t,e={},n){const r=n||c;let o;try{o=r(t||"")}catch(t){o={}}for(const t in e)o[t]=e[t];return o}(s.query,i.query,o&&o.options.parseQuery);let p=i.hash||s.hash;return p&&"#"!==p.charAt(0)&&(p=`#${p}`),{_normalized:!0,path:u,query:h,hash:p}}function N(t,e){const{pathList:n,pathMap:r,nameMap:o}=F(t);function i(t,i,s){const c=J(t,i,!1,e),{name:u}=c;if(u){const t=o[u];if(!t)return a(null,c);const e=t.regex.keys.filter(t=>!t.optional).map(t=>t.name);if("object"!=typeof c.params&&(c.params={}),i&&"object"==typeof i.params)for(const t in i.params)!(t in c.params)&&e.indexOf(t)>-1&&(c.params[t]=i.params[t]);return c.path=D(t.path,c.params),a(t,c,s)}if(c.path){c.params={};for(let t=0;t{G(),t.state&&t.state.key&&function(t){it=t}(t.state.key)})}function W(t,e,n,r){if(!t.app)return;const o=t.options.scrollBehavior;o&&t.app.$nextTick(()=>{const i=function(){const t=at();if(t)return X[t]}(),s=o.call(t,e,n,r?i:null);s&&("function"==typeof s.then?s.then(t=>{nt(t,i)}).catch(t=>{}):nt(s,i))})}function G(){const t=at();t&&(X[t]={x:window.pageXOffset,y:window.pageYOffset})}function Z(t){return et(t.x)||et(t.y)}function tt(t){return{x:et(t.x)?t.x:window.pageXOffset,y:et(t.y)?t.y:window.pageYOffset}}function et(t){return"number"==typeof t}function nt(t,e){const n="object"==typeof t;if(n&&"string"==typeof t.selector){const n=document.querySelector(t.selector);if(n){let o=t.offset&&"object"==typeof t.offset?t.offset:{};e=function(t,e){const n=document.documentElement.getBoundingClientRect(),r=t.getBoundingClientRect();return{x:r.left-n.left-e.x,y:r.top-n.top-e.y}}(n,o={x:et((r=o).x)?r.x:0,y:et(r.y)?r.y:0})}else Z(t)&&(e=tt(t))}else n&&Z(t)&&(e=tt(t));var r;e&&window.scrollTo(e.x,e.y)}const rt=R&&function(){const t=window.navigator.userAgent;return(-1===t.indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&(window.history&&"pushState"in window.history)}(),ot=R&&window.performance&&window.performance.now?window.performance:Date;let it=st();function st(){return ot.now().toFixed(3)}function at(){return it}function ct(t,e){G();const n=window.history;try{e?n.replaceState({key:it},"",t):(it=st(),n.pushState({key:it},"",t))}catch(n){window.location[e?"replace":"assign"](t)}}function ut(t){ct(t,!0)}function ht(t,e,n){const r=o=>{o>=t.length?n():t[o]?e(t[o],()=>{r(o+1)}):r(o+1)};r(0)}function pt(e){return(n,r,o)=>{let i=!1,s=0,a=null;lt(e,(e,n,r,c)=>{if("function"==typeof e&&void 0===e.cid){i=!0,s++;const n=yt(t=>{(function(t){return t.__esModule||dt&&"Module"===t[Symbol.toStringTag]})(t)&&(t=t.default),e.resolved="function"==typeof t?t:k.extend(t),r.components[c]=t,--s<=0&&o()}),u=yt(e=>{const n=`Failed to resolve async component ${c}: ${e}`;a||(a=t(e)?e:new Error(n),o(a))});let h;try{h=e(n,u)}catch(t){u(t)}if(h)if("function"==typeof h.then)h.then(n,u);else{const t=h.component;t&&"function"==typeof t.then&&t.then(n,u)}}}),i||o()}}function lt(t,e){return ft(t.map(t=>Object.keys(t.components).map(n=>e(t.components[n],t.instances[n],t,n))))}function ft(t){return Array.prototype.concat.apply([],t)}const dt="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function yt(t){let e=!1;return function(...n){if(!e)return e=!0,t.apply(this,n)}}class mt{constructor(t,e){this.router=t,this.base=function(t){if(!t)if(R){const e=document.querySelector("base");t=(t=e&&e.getAttribute("href")||"/").replace(/^https?:\/\/[^\/]+/,"")}else t="/";"/"!==t.charAt(0)&&(t="/"+t);return t.replace(/\/$/,"")}(e),this.current=f,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[]}listen(t){this.cb=t}onReady(t,e){this.ready?t():(this.readyCbs.push(t),e&&this.readyErrorCbs.push(e))}onError(t){this.errorCbs.push(t)}transitionTo(t,e,n){const r=this.router.match(t,this.current);this.confirmTransition(r,()=>{this.updateRoute(r),e&&e(r),this.ensureURL(),this.ready||(this.ready=!0,this.readyCbs.forEach(t=>{t(r)}))},t=>{n&&n(t),t&&!this.ready&&(this.ready=!0,this.readyErrorCbs.forEach(e=>{e(t)}))})}confirmTransition(e,n,r){const o=this.current,i=e=>{t(e)&&(this.errorCbs.length?this.errorCbs.forEach(t=>{t(e)}):console.error(e)),r&&r(e)};if(m(e,o)&&e.matched.length===o.matched.length)return this.ensureURL(),i();const{updated:s,deactivated:a,activated:c}=function(t,e){let n;const r=Math.max(t.length,e.length);for(n=0;nt.beforeEnter),pt(c));this.pending=e;const h=(n,r)=>{if(this.pending!==e)return i();try{n(e,o,e=>{!1===e||t(e)?(this.ensureURL(!0),i(e)):"string"==typeof e||"object"==typeof e&&("string"==typeof e.path||"string"==typeof e.name)?(i(),"object"==typeof e&&e.replace?this.replace(e):this.push(e)):r(e)})}catch(t){i(t)}};ht(u,h,()=>{const t=[];ht(function(t,e,n){return gt(t,"beforeRouteEnter",(t,r,o,i)=>(function(t,e,n,r,o){return function(i,s,a){return t(i,s,t=>{"function"==typeof t&&r.push(()=>{!function t(e,n,r,o){n[r]&&!n[r]._isBeingDestroyed?e(n[r]):o()&&setTimeout(()=>{t(e,n,r,o)},16)}(t,e.instances,n,o)}),a(t)})}})(t,o,i,e,n))}(c,t,()=>this.current===e).concat(this.router.resolveHooks),h,()=>{if(this.pending!==e)return i();this.pending=null,n(e),this.router.app&&this.router.app.$nextTick(()=>{t.forEach(t=>{t()})})})})}updateRoute(t){const e=this.current;this.current=t,this.cb&&this.cb(t),this.router.afterHooks.forEach(n=>{n&&n(t,e)})}}function gt(t,e,n,r){const o=lt(t,(t,r,o,i)=>{const s=function(t,e){"function"!=typeof t&&(t=k.extend(t));return t.options[e]}(t,e);if(s)return Array.isArray(s)?s.map(t=>n(t,r,o,i)):n(s,r,o,i)});return ft(r?o.reverse():o)}function wt(t,e){if(e)return function(){return t.apply(e,arguments)}}class bt extends mt{constructor(t,e){super(t,e);const n=t.options.scrollBehavior,r=rt&&n;r&&Y();const o=vt(this.base);window.addEventListener("popstate",e=>{const n=this.current,i=vt(this.base);this.current===f&&i===o||this.transitionTo(i,e=>{r&&W(t,e,n,!0)})})}go(t){window.history.go(t)}push(t,e,n){const{current:r}=this;this.transitionTo(t,t=>{ct(O(this.base+t.fullPath)),W(this.router,t,r,!1),e&&e(t)},n)}replace(t,e,n){const{current:r}=this;this.transitionTo(t,t=>{ut(O(this.base+t.fullPath)),W(this.router,t,r,!1),e&&e(t)},n)}ensureURL(t){if(vt(this.base)!==this.current.fullPath){const e=O(this.base+this.current.fullPath);t?ct(e):ut(e)}}getCurrentLocation(){return vt(this.base)}}function vt(t){let e=decodeURI(window.location.pathname);return t&&0===e.indexOf(t)&&(e=e.slice(t.length)),(e||"/")+window.location.search+window.location.hash}class xt extends mt{constructor(t,e,n){super(t,e),n&&function(t){const e=vt(t);if(!/^\/#/.test(e))return window.location.replace(O(t+"/#"+e)),!0}(this.base)||kt()}setupListeners(){const t=this.router.options.scrollBehavior,e=rt&&t;e&&Y(),window.addEventListener(rt?"popstate":"hashchange",()=>{const t=this.current;kt()&&this.transitionTo(Rt(),n=>{e&&W(this.router,n,t,!0),rt||At(n.fullPath)})})}push(t,e,n){const{current:r}=this;this.transitionTo(t,t=>{Ot(t.fullPath),W(this.router,t,r,!1),e&&e(t)},n)}replace(t,e,n){const{current:r}=this;this.transitionTo(t,t=>{At(t.fullPath),W(this.router,t,r,!1),e&&e(t)},n)}go(t){window.history.go(t)}ensureURL(t){const e=this.current.fullPath;Rt()!==e&&(t?Ot(e):At(e))}getCurrentLocation(){return Rt()}}function kt(){const t=Rt();return"/"===t.charAt(0)||(At("/"+t),!1)}function Rt(){let t=window.location.href;const e=t.indexOf("#");if(e<0)return"";const n=(t=t.slice(e+1)).indexOf("?");if(n<0){const e=t.indexOf("#");t=e>-1?decodeURI(t.slice(0,e))+t.slice(e):decodeURI(t)}else n>-1&&(t=decodeURI(t.slice(0,n))+t.slice(n));return t}function Et(t){const e=window.location.href,n=e.indexOf("#");return`${n>=0?e.slice(0,n):e}#${t}`}function Ot(t){rt?ct(Et(t)):window.location.hash=t}function At(t){rt?ut(Et(t)):window.location.replace(Et(t))}class Ct extends mt{constructor(t,e){super(t,e),this.stack=[],this.index=-1}push(t,e,n){this.transitionTo(t,t=>{this.stack=this.stack.slice(0,this.index+1).concat(t),this.index++,e&&e(t)},n)}replace(t,e,n){this.transitionTo(t,t=>{this.stack=this.stack.slice(0,this.index).concat(t),e&&e(t)},n)}go(t){const e=this.index+t;if(e<0||e>=this.stack.length)return;const n=this.stack[e];this.confirmTransition(n,()=>{this.index=e,this.updateRoute(n)})}getCurrentLocation(){const t=this.stack[this.stack.length-1];return t?t.fullPath:"/"}ensureURL(){}}class $t{constructor(t={}){this.app=null,this.apps=[],this.options=t,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=N(t.routes||[],this);let e=t.mode||"hash";switch(this.fallback="history"===e&&!rt&&!1!==t.fallback,this.fallback&&(e="hash"),R||(e="abstract"),this.mode=e,e){case"history":this.history=new bt(this,t.base);break;case"hash":this.history=new xt(this,t.base,this.fallback);break;case"abstract":this.history=new Ct(this,t.base)}}match(t,e,n){return this.matcher.match(t,e,n)}get currentRoute(){return this.history&&this.history.current}init(t){if(this.apps.push(t),t.$once("hook:destroyed",()=>{const e=this.apps.indexOf(t);e>-1&&this.apps.splice(e,1),this.app===t&&(this.app=this.apps[0]||null)}),this.app)return;this.app=t;const e=this.history;if(e instanceof bt)e.transitionTo(e.getCurrentLocation());else if(e instanceof xt){const t=()=>{e.setupListeners()};e.transitionTo(e.getCurrentLocation(),t,t)}e.listen(t=>{this.apps.forEach(e=>{e._route=t})})}beforeEach(t){return jt(this.beforeHooks,t)}beforeResolve(t){return jt(this.resolveHooks,t)}afterEach(t){return jt(this.afterHooks,t)}onReady(t,e){this.history.onReady(t,e)}onError(t){this.history.onError(t)}push(t,e,n){this.history.push(t,e,n)}replace(t,e,n){this.history.replace(t,e,n)}go(t){this.history.go(t)}back(){this.go(-1)}forward(){this.go(1)}getMatchedComponents(t){const e=t?t.matched?t:this.resolve(t).route:this.currentRoute;return e?[].concat.apply([],e.matched.map(t=>Object.keys(t.components).map(e=>t.components[e]))):[]}resolve(t,e,n){const r=J(t,e=e||this.history.current,n,this),o=this.match(r,e),i=o.redirectedFrom||o.fullPath;return{location:r,route:o,href:function(t,e,n){var r="hash"===n?"#"+e:e;return t?O(t+"/"+r):r}(this.history.base,i,this.mode),normalizedTo:r,resolved:o}}addRoutes(t){this.matcher.addRoutes(t),this.history.current!==f&&this.history.transitionTo(this.history.getCurrentLocation())}}function jt(t,e){return t.push(e),()=>{const n=t.indexOf(e);n>-1&&t.splice(n,1)}}$t.install=function t(e){if(t.installed&&k===e)return;t.installed=!0,k=e;const r=t=>void 0!==t,o=(t,e)=>{let n=t.$options._parentVnode;r(n)&&r(n=n.data)&&r(n=n.registerRouteInstance)&&n(t,e)};e.mixin({beforeCreate(){r(this.$options.router)?(this._routerRoot=this,this._router=this.$options.router,this._router.init(this),e.util.defineReactive(this,"_route",this._router.history.current)):this._routerRoot=this.$parent&&this.$parent._routerRoot||this,o(this,this)},destroyed(){o(this)}}),Object.defineProperty(e.prototype,"$router",{get(){return this._routerRoot._router}}),Object.defineProperty(e.prototype,"$route",{get(){return this._routerRoot._route}}),e.component("RouterView",n),e.component("RouterLink",v);const i=e.config.optionMergeStrategies;i.beforeRouteEnter=i.beforeRouteLeave=i.beforeRouteUpdate=i.created},$t.version="3.0.7",R&&window.Vue&&window.Vue.use($t);export default $t; \ No newline at end of file diff --git a/dist/vue-router.esm.js b/dist/vue-router.esm.js index 2d85b57b6..34e4483cb 100644 --- a/dist/vue-router.esm.js +++ b/dist/vue-router.esm.js @@ -1,5 +1,5 @@ /*! - * vue-router v3.0.6 + * vue-router v3.0.7 * (c) 2019 Evan You * @license MIT */ @@ -1387,10 +1387,8 @@ function createMatcher ( } } - if (record) { - location.path = fillParams(record.path, location.params, ("named route \"" + name + "\"")); - return _createRoute(record, location, redirectedFrom) - } + location.path = fillParams(record.path, location.params, ("named route \"" + name + "\"")); + return _createRoute(record, location, redirectedFrom) } else if (location.path) { location.params = {}; for (var i = 0; i < pathList.length; i++) { @@ -1545,7 +1543,12 @@ var positionStore = Object.create(null); function setupScroll () { // Fix for #1585 for Firefox // Fix for #2195 Add optional third attribute to workaround a bug in safari https://bugs.webkit.org/show_bug.cgi?id=182678 - window.history.replaceState({ key: getStateKey() }, '', window.location.href.replace(window.location.origin, '')); + // Fix for #2774 Support for apps loaded from Windows file shares not mapped to network drives: replaced location.origin with + // window.location.protocol + '//' + window.location.host + // location.host contains the port and location.hostname doesn't + var protocolAndPath = window.location.protocol + '//' + window.location.host; + var absolutePath = window.location.href.replace(protocolAndPath, ''); + window.history.replaceState({ key: getStateKey() }, '', absolutePath); window.addEventListener('popstate', function (e) { saveScrollPosition(); if (e.state && e.state.key) { @@ -2117,7 +2120,6 @@ function bindEnterGuard ( ) { return function routeEnterGuard (to, from, next) { return guard(to, from, function (cb) { - next(cb); if (typeof cb === 'function') { cbs.push(function () { // #750 @@ -2128,6 +2130,7 @@ function bindEnterGuard ( poll(cb, match.instances, key, isValid); }); } + next(cb); }) } } @@ -2662,7 +2665,7 @@ function createHref (base, fullPath, mode) { } VueRouter.install = install; -VueRouter.version = '3.0.6'; +VueRouter.version = '3.0.7'; if (inBrowser && window.Vue) { window.Vue.use(VueRouter); diff --git a/dist/vue-router.js b/dist/vue-router.js index 0a5769ca1..f8ac657d5 100644 --- a/dist/vue-router.js +++ b/dist/vue-router.js @@ -1,5 +1,5 @@ /*! - * vue-router v3.0.6 + * vue-router v3.0.7 * (c) 2019 Evan You * @license MIT */ @@ -1393,10 +1393,8 @@ function createMatcher ( } } - if (record) { - location.path = fillParams(record.path, location.params, ("named route \"" + name + "\"")); - return _createRoute(record, location, redirectedFrom) - } + location.path = fillParams(record.path, location.params, ("named route \"" + name + "\"")); + return _createRoute(record, location, redirectedFrom) } else if (location.path) { location.params = {}; for (var i = 0; i < pathList.length; i++) { @@ -1551,7 +1549,12 @@ var positionStore = Object.create(null); function setupScroll () { // Fix for #1585 for Firefox // Fix for #2195 Add optional third attribute to workaround a bug in safari https://bugs.webkit.org/show_bug.cgi?id=182678 - window.history.replaceState({ key: getStateKey() }, '', window.location.href.replace(window.location.origin, '')); + // Fix for #2774 Support for apps loaded from Windows file shares not mapped to network drives: replaced location.origin with + // window.location.protocol + '//' + window.location.host + // location.host contains the port and location.hostname doesn't + var protocolAndPath = window.location.protocol + '//' + window.location.host; + var absolutePath = window.location.href.replace(protocolAndPath, ''); + window.history.replaceState({ key: getStateKey() }, '', absolutePath); window.addEventListener('popstate', function (e) { saveScrollPosition(); if (e.state && e.state.key) { @@ -2123,7 +2126,6 @@ function bindEnterGuard ( ) { return function routeEnterGuard (to, from, next) { return guard(to, from, function (cb) { - next(cb); if (typeof cb === 'function') { cbs.push(function () { // #750 @@ -2134,6 +2136,7 @@ function bindEnterGuard ( poll(cb, match.instances, key, isValid); }); } + next(cb); }) } } @@ -2668,7 +2671,7 @@ function createHref (base, fullPath, mode) { } VueRouter.install = install; -VueRouter.version = '3.0.6'; +VueRouter.version = '3.0.7'; if (inBrowser && window.Vue) { window.Vue.use(VueRouter); diff --git a/dist/vue-router.min.js b/dist/vue-router.min.js index 91fa208d3..7f0392bb2 100644 --- a/dist/vue-router.min.js +++ b/dist/vue-router.min.js @@ -1,6 +1,6 @@ /*! - * vue-router v3.0.6 + * vue-router v3.0.7 * (c) 2019 Evan You * @license MIT */ -var t,e;t=this,e=function(){"use strict";function t(t){return Object.prototype.toString.call(t).indexOf("Error")>-1}function e(t,e){for(var r in e)t[r]=e[r];return t}var r={name:"RouterView",functional:!0,props:{name:{type:String,default:"default"}},render:function(t,r){var n=r.props,o=r.children,i=r.parent,a=r.data;a.routerView=!0;for(var u=i.$createElement,c=n.name,s=i.$route,p=i._routerViewCache||(i._routerViewCache={}),f=0,h=!1;i&&i._routerRoot!==i;){var l=i.$vnode&&i.$vnode.data;l&&(l.routerView&&f++,l.keepAlive&&i._inactive&&(h=!0)),i=i.$parent}if(a.routerViewDepth=f,h)return u(p[c],a,o);var d=s.matched[f];if(!d)return p[c]=null,u();var v=p[c]=d.components[c];a.registerRouteInstance=function(t,e){var r=d.instances[c];(e&&r!==t||!e&&r===t)&&(d.instances[c]=e)},(a.hook||(a.hook={})).prepatch=function(t,e){d.instances[c]=e.componentInstance},a.hook.init=function(t){t.data.keepAlive&&t.componentInstance&&t.componentInstance!==d.instances[c]&&(d.instances[c]=t.componentInstance)};var y=a.props=function(t,e){switch(typeof e){case"undefined":return;case"object":return e;case"function":return e(t);case"boolean":return e?t.params:void 0}}(s,d.props&&d.props[c]);if(y){y=a.props=e({},y);var m=a.attrs=a.attrs||{};for(var g in y)v.props&&g in v.props||(m[g]=y[g],delete y[g])}return u(v,a,o)}},n=/[!'()*]/g,o=function(t){return"%"+t.charCodeAt(0).toString(16)},i=/%2C/g,a=function(t){return encodeURIComponent(t).replace(n,o).replace(i,",")},u=decodeURIComponent;function c(t){var e={};return(t=t.trim().replace(/^(\?|#|&)/,""))?(t.split("&").forEach(function(t){var r=t.replace(/\+/g," ").split("="),n=u(r.shift()),o=r.length>0?u(r.join("=")):null;void 0===e[n]?e[n]=o:Array.isArray(e[n])?e[n].push(o):e[n]=[e[n],o]}),e):e}function s(t){var e=t?Object.keys(t).map(function(e){var r=t[e];if(void 0===r)return"";if(null===r)return a(e);if(Array.isArray(r)){var n=[];return r.forEach(function(t){void 0!==t&&(null===t?n.push(a(e)):n.push(a(e)+"="+a(t)))}),n.join("&")}return a(e)+"="+a(r)}).filter(function(t){return t.length>0}).join("&"):null;return e?"?"+e:""}var p=/\/?$/;function f(t,e,r,n){var o=n&&n.options.stringifyQuery,i=e.query||{};try{i=h(i)}catch(t){}var a={name:e.name||t&&t.name,meta:t&&t.meta||{},path:e.path||"/",hash:e.hash||"",query:i,params:e.params||{},fullPath:v(e,o),matched:t?d(t):[]};return r&&(a.redirectedFrom=v(r,o)),Object.freeze(a)}function h(t){if(Array.isArray(t))return t.map(h);if(t&&"object"==typeof t){var e={};for(var r in t)e[r]=h(t[r]);return e}return t}var l=f(null,{path:"/"});function d(t){for(var e=[];t;)e.unshift(t),t=t.parent;return e}function v(t,e){var r=t.path,n=t.query;void 0===n&&(n={});var o=t.hash;return void 0===o&&(o=""),(r||"/")+(e||s)(n)+o}function y(t,e){return e===l?t===e:!!e&&(t.path&&e.path?t.path.replace(p,"")===e.path.replace(p,"")&&t.hash===e.hash&&m(t.query,e.query):!(!t.name||!e.name)&&(t.name===e.name&&t.hash===e.hash&&m(t.query,e.query)&&m(t.params,e.params)))}function m(t,e){if(void 0===t&&(t={}),void 0===e&&(e={}),!t||!e)return t===e;var r=Object.keys(t),n=Object.keys(e);return r.length===n.length&&r.every(function(r){var n=t[r],o=e[r];return"object"==typeof n&&"object"==typeof o?m(n,o):String(n)===String(o)})}var g,b=[String,Object],w=[String,Array],x={name:"RouterLink",props:{to:{type:b,required:!0},tag:{type:String,default:"a"},exact:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,event:{type:w,default:"click"}},render:function(t){var r=this,n=this.$router,o=this.$route,i=n.resolve(this.to,o,this.append),a=i.location,u=i.route,c=i.href,s={},h=n.options.linkActiveClass,l=n.options.linkExactActiveClass,d=null==h?"router-link-active":h,v=null==l?"router-link-exact-active":l,m=null==this.activeClass?d:this.activeClass,g=null==this.exactActiveClass?v:this.exactActiveClass,b=a.path?f(null,a,null,n):u;s[g]=y(o,b),s[m]=this.exact?s[g]:function(t,e){return 0===t.path.replace(p,"/").indexOf(e.path.replace(p,"/"))&&(!e.hash||t.hash===e.hash)&&function(t,e){for(var r in e)if(!(r in t))return!1;return!0}(t.query,e.query)}(o,b);var w=function(t){k(t)&&(r.replace?n.replace(a):n.push(a))},x={click:k};Array.isArray(this.event)?this.event.forEach(function(t){x[t]=w}):x[this.event]=w;var R={class:s};if("a"===this.tag)R.on=x,R.attrs={href:c};else{var E=function t(e){if(e)for(var r,n=0;n=0&&(e=t.slice(n),t=t.slice(0,n));var o=t.indexOf("?");return o>=0&&(r=t.slice(o+1),t=t.slice(0,o)),{path:t,query:r,hash:e}}(i.path||""),p=r&&r.path||"/",f=s.path?E(s.path,p,n||i.append):p,h=function(t,e,r){void 0===e&&(e={});var n,o=r||c;try{n=o(t||"")}catch(t){n={}}for(var i in e)n[i]=e[i];return n}(s.query,i.query,o&&o.options.parseQuery),l=i.hash||s.hash;return l&&"#"!==l.charAt(0)&&(l="#"+l),{_normalized:!0,path:f,query:h,hash:l}}function N(t,e){var r=F(t),n=r.pathList,o=r.pathMap,i=r.nameMap;function a(t,r,a){var u=J(t,r,!1,e),s=u.name;if(s){var p=i[s];if(!p)return c(null,u);var f=p.regex.keys.filter(function(t){return!t.optional}).map(function(t){return t.name});if("object"!=typeof u.params&&(u.params={}),r&&"object"==typeof r.params)for(var h in r.params)!(h in u.params)&&f.indexOf(h)>-1&&(u.params[h]=r.params[h]);if(p)return u.path=D(p.path,u.params),c(p,u,a)}else if(u.path){u.params={};for(var l=0;l=t.length?r():t[o]?e(t[o],function(){n(o+1)}):n(o+1)};n(0)}function ht(e){return function(r,n,o){var i=!1,a=0,u=null;lt(e,function(e,r,n,c){if("function"==typeof e&&void 0===e.cid){i=!0,a++;var s,p=yt(function(t){var r;((r=t).__esModule||vt&&"Module"===r[Symbol.toStringTag])&&(t=t.default),e.resolved="function"==typeof t?t:g.extend(t),n.components[c]=t,--a<=0&&o()}),f=yt(function(e){var r="Failed to resolve async component "+c+": "+e;u||(u=t(e)?e:new Error(r),o(u))});try{s=e(p,f)}catch(t){f(t)}if(s)if("function"==typeof s.then)s.then(p,f);else{var h=s.component;h&&"function"==typeof h.then&&h.then(p,f)}}}),i||o()}}function lt(t,e){return dt(t.map(function(t){return Object.keys(t.components).map(function(r){return e(t.components[r],t.instances[r],t,r)})}))}function dt(t){return Array.prototype.concat.apply([],t)}var vt="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function yt(t){var e=!1;return function(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];if(!e)return e=!0,t.apply(this,r)}}var mt=function(t,e){this.router=t,this.base=function(t){if(!t)if(R){var e=document.querySelector("base");t=(t=e&&e.getAttribute("href")||"/").replace(/^https?:\/\/[^\/]+/,"")}else t="/";"/"!==t.charAt(0)&&(t="/"+t);return t.replace(/\/$/,"")}(e),this.current=l,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[]};function gt(t,e,r,n){var o=lt(t,function(t,n,o,i){var a=function(t,e){"function"!=typeof t&&(t=g.extend(t));return t.options[e]}(t,e);if(a)return Array.isArray(a)?a.map(function(t){return r(t,n,o,i)}):r(a,n,o,i)});return dt(n?o.reverse():o)}function bt(t,e){if(e)return function(){return t.apply(e,arguments)}}mt.prototype.listen=function(t){this.cb=t},mt.prototype.onReady=function(t,e){this.ready?t():(this.readyCbs.push(t),e&&this.readyErrorCbs.push(e))},mt.prototype.onError=function(t){this.errorCbs.push(t)},mt.prototype.transitionTo=function(t,e,r){var n=this,o=this.router.match(t,this.current);this.confirmTransition(o,function(){n.updateRoute(o),e&&e(o),n.ensureURL(),n.ready||(n.ready=!0,n.readyCbs.forEach(function(t){t(o)}))},function(t){r&&r(t),t&&!n.ready&&(n.ready=!0,n.readyErrorCbs.forEach(function(e){e(t)}))})},mt.prototype.confirmTransition=function(e,r,n){var o=this,i=this.current,a=function(e){t(e)&&(o.errorCbs.length?o.errorCbs.forEach(function(t){t(e)}):console.error(e)),n&&n(e)};if(y(e,i)&&e.matched.length===i.matched.length)return this.ensureURL(),a();var u=function(t,e){var r,n=Math.max(t.length,e.length);for(r=0;r-1?decodeURI(t.slice(0,n))+t.slice(n):decodeURI(t)}else r>-1&&(t=decodeURI(t.slice(0,r))+t.slice(r));return t}function Ot(t){var e=window.location.href,r=e.indexOf("#");return(r>=0?e.slice(0,r):e)+"#"+t}function At(t){ot?st(Ot(t)):window.location.hash=t}function Ct(t){ot?pt(Ot(t)):window.location.replace(Ot(t))}var jt=function(t){function e(e,r){t.call(this,e,r),this.stack=[],this.index=-1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.push=function(t,e,r){var n=this;this.transitionTo(t,function(t){n.stack=n.stack.slice(0,n.index+1).concat(t),n.index++,e&&e(t)},r)},e.prototype.replace=function(t,e,r){var n=this;this.transitionTo(t,function(t){n.stack=n.stack.slice(0,n.index).concat(t),e&&e(t)},r)},e.prototype.go=function(t){var e=this,r=this.index+t;if(!(r<0||r>=this.stack.length)){var n=this.stack[r];this.confirmTransition(n,function(){e.index=r,e.updateRoute(n)})}},e.prototype.getCurrentLocation=function(){var t=this.stack[this.stack.length-1];return t?t.fullPath:"/"},e.prototype.ensureURL=function(){},e}(mt),_t=function(t){void 0===t&&(t={}),this.app=null,this.apps=[],this.options=t,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=N(t.routes||[],this);var e=t.mode||"hash";switch(this.fallback="history"===e&&!ot&&!1!==t.fallback,this.fallback&&(e="hash"),R||(e="abstract"),this.mode=e,e){case"history":this.history=new wt(this,t.base);break;case"hash":this.history=new kt(this,t.base,this.fallback);break;case"abstract":this.history=new jt(this,t.base)}},Tt={currentRoute:{configurable:!0}};function St(t,e){return t.push(e),function(){var r=t.indexOf(e);r>-1&&t.splice(r,1)}}return _t.prototype.match=function(t,e,r){return this.matcher.match(t,e,r)},Tt.currentRoute.get=function(){return this.history&&this.history.current},_t.prototype.init=function(t){var e=this;if(this.apps.push(t),t.$once("hook:destroyed",function(){var r=e.apps.indexOf(t);r>-1&&e.apps.splice(r,1),e.app===t&&(e.app=e.apps[0]||null)}),!this.app){this.app=t;var r=this.history;if(r instanceof wt)r.transitionTo(r.getCurrentLocation());else if(r instanceof kt){var n=function(){r.setupListeners()};r.transitionTo(r.getCurrentLocation(),n,n)}r.listen(function(t){e.apps.forEach(function(e){e._route=t})})}},_t.prototype.beforeEach=function(t){return St(this.beforeHooks,t)},_t.prototype.beforeResolve=function(t){return St(this.resolveHooks,t)},_t.prototype.afterEach=function(t){return St(this.afterHooks,t)},_t.prototype.onReady=function(t,e){this.history.onReady(t,e)},_t.prototype.onError=function(t){this.history.onError(t)},_t.prototype.push=function(t,e,r){this.history.push(t,e,r)},_t.prototype.replace=function(t,e,r){this.history.replace(t,e,r)},_t.prototype.go=function(t){this.history.go(t)},_t.prototype.back=function(){this.go(-1)},_t.prototype.forward=function(){this.go(1)},_t.prototype.getMatchedComponents=function(t){var e=t?t.matched?t:this.resolve(t).route:this.currentRoute;return e?[].concat.apply([],e.matched.map(function(t){return Object.keys(t.components).map(function(e){return t.components[e]})})):[]},_t.prototype.resolve=function(t,e,r){var n=J(t,e=e||this.history.current,r,this),o=this.match(n,e),i=o.redirectedFrom||o.fullPath;return{location:n,route:o,href:function(t,e,r){var n="hash"===r?"#"+e:e;return t?O(t+"/"+n):n}(this.history.base,i,this.mode),normalizedTo:n,resolved:o}},_t.prototype.addRoutes=function(t){this.matcher.addRoutes(t),this.history.current!==l&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(_t.prototype,Tt),_t.install=function t(e){if(!t.installed||g!==e){t.installed=!0,g=e;var n=function(t){return void 0!==t},o=function(t,e){var r=t.$options._parentVnode;n(r)&&n(r=r.data)&&n(r=r.registerRouteInstance)&&r(t,e)};e.mixin({beforeCreate:function(){n(this.$options.router)?(this._routerRoot=this,this._router=this.$options.router,this._router.init(this),e.util.defineReactive(this,"_route",this._router.history.current)):this._routerRoot=this.$parent&&this.$parent._routerRoot||this,o(this,this)},destroyed:function(){o(this)}}),Object.defineProperty(e.prototype,"$router",{get:function(){return this._routerRoot._router}}),Object.defineProperty(e.prototype,"$route",{get:function(){return this._routerRoot._route}}),e.component("RouterView",r),e.component("RouterLink",x);var i=e.config.optionMergeStrategies;i.beforeRouteEnter=i.beforeRouteLeave=i.beforeRouteUpdate=i.created}},_t.version="3.0.6",R&&window.Vue&&window.Vue.use(_t),_t},"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.VueRouter=e(); \ No newline at end of file +var t,e;t=this,e=function(){"use strict";function t(t){return Object.prototype.toString.call(t).indexOf("Error")>-1}function e(t,e){for(var r in e)t[r]=e[r];return t}var r={name:"RouterView",functional:!0,props:{name:{type:String,default:"default"}},render:function(t,r){var n=r.props,o=r.children,i=r.parent,a=r.data;a.routerView=!0;for(var u=i.$createElement,c=n.name,s=i.$route,p=i._routerViewCache||(i._routerViewCache={}),f=0,h=!1;i&&i._routerRoot!==i;){var l=i.$vnode&&i.$vnode.data;l&&(l.routerView&&f++,l.keepAlive&&i._inactive&&(h=!0)),i=i.$parent}if(a.routerViewDepth=f,h)return u(p[c],a,o);var d=s.matched[f];if(!d)return p[c]=null,u();var v=p[c]=d.components[c];a.registerRouteInstance=function(t,e){var r=d.instances[c];(e&&r!==t||!e&&r===t)&&(d.instances[c]=e)},(a.hook||(a.hook={})).prepatch=function(t,e){d.instances[c]=e.componentInstance},a.hook.init=function(t){t.data.keepAlive&&t.componentInstance&&t.componentInstance!==d.instances[c]&&(d.instances[c]=t.componentInstance)};var y=a.props=function(t,e){switch(typeof e){case"undefined":return;case"object":return e;case"function":return e(t);case"boolean":return e?t.params:void 0}}(s,d.props&&d.props[c]);if(y){y=a.props=e({},y);var m=a.attrs=a.attrs||{};for(var g in y)v.props&&g in v.props||(m[g]=y[g],delete y[g])}return u(v,a,o)}},n=/[!'()*]/g,o=function(t){return"%"+t.charCodeAt(0).toString(16)},i=/%2C/g,a=function(t){return encodeURIComponent(t).replace(n,o).replace(i,",")},u=decodeURIComponent;function c(t){var e={};return(t=t.trim().replace(/^(\?|#|&)/,""))?(t.split("&").forEach(function(t){var r=t.replace(/\+/g," ").split("="),n=u(r.shift()),o=r.length>0?u(r.join("=")):null;void 0===e[n]?e[n]=o:Array.isArray(e[n])?e[n].push(o):e[n]=[e[n],o]}),e):e}function s(t){var e=t?Object.keys(t).map(function(e){var r=t[e];if(void 0===r)return"";if(null===r)return a(e);if(Array.isArray(r)){var n=[];return r.forEach(function(t){void 0!==t&&(null===t?n.push(a(e)):n.push(a(e)+"="+a(t)))}),n.join("&")}return a(e)+"="+a(r)}).filter(function(t){return t.length>0}).join("&"):null;return e?"?"+e:""}var p=/\/?$/;function f(t,e,r,n){var o=n&&n.options.stringifyQuery,i=e.query||{};try{i=h(i)}catch(t){}var a={name:e.name||t&&t.name,meta:t&&t.meta||{},path:e.path||"/",hash:e.hash||"",query:i,params:e.params||{},fullPath:v(e,o),matched:t?d(t):[]};return r&&(a.redirectedFrom=v(r,o)),Object.freeze(a)}function h(t){if(Array.isArray(t))return t.map(h);if(t&&"object"==typeof t){var e={};for(var r in t)e[r]=h(t[r]);return e}return t}var l=f(null,{path:"/"});function d(t){for(var e=[];t;)e.unshift(t),t=t.parent;return e}function v(t,e){var r=t.path,n=t.query;void 0===n&&(n={});var o=t.hash;return void 0===o&&(o=""),(r||"/")+(e||s)(n)+o}function y(t,e){return e===l?t===e:!!e&&(t.path&&e.path?t.path.replace(p,"")===e.path.replace(p,"")&&t.hash===e.hash&&m(t.query,e.query):!(!t.name||!e.name)&&(t.name===e.name&&t.hash===e.hash&&m(t.query,e.query)&&m(t.params,e.params)))}function m(t,e){if(void 0===t&&(t={}),void 0===e&&(e={}),!t||!e)return t===e;var r=Object.keys(t),n=Object.keys(e);return r.length===n.length&&r.every(function(r){var n=t[r],o=e[r];return"object"==typeof n&&"object"==typeof o?m(n,o):String(n)===String(o)})}var g,b=[String,Object],w=[String,Array],x={name:"RouterLink",props:{to:{type:b,required:!0},tag:{type:String,default:"a"},exact:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,event:{type:w,default:"click"}},render:function(t){var r=this,n=this.$router,o=this.$route,i=n.resolve(this.to,o,this.append),a=i.location,u=i.route,c=i.href,s={},h=n.options.linkActiveClass,l=n.options.linkExactActiveClass,d=null==h?"router-link-active":h,v=null==l?"router-link-exact-active":l,m=null==this.activeClass?d:this.activeClass,g=null==this.exactActiveClass?v:this.exactActiveClass,b=a.path?f(null,a,null,n):u;s[g]=y(o,b),s[m]=this.exact?s[g]:function(t,e){return 0===t.path.replace(p,"/").indexOf(e.path.replace(p,"/"))&&(!e.hash||t.hash===e.hash)&&function(t,e){for(var r in e)if(!(r in t))return!1;return!0}(t.query,e.query)}(o,b);var w=function(t){k(t)&&(r.replace?n.replace(a):n.push(a))},x={click:k};Array.isArray(this.event)?this.event.forEach(function(t){x[t]=w}):x[this.event]=w;var R={class:s};if("a"===this.tag)R.on=x,R.attrs={href:c};else{var E=function t(e){if(e)for(var r,n=0;n=0&&(e=t.slice(n),t=t.slice(0,n));var o=t.indexOf("?");return o>=0&&(r=t.slice(o+1),t=t.slice(0,o)),{path:t,query:r,hash:e}}(i.path||""),p=r&&r.path||"/",f=s.path?E(s.path,p,n||i.append):p,h=function(t,e,r){void 0===e&&(e={});var n,o=r||c;try{n=o(t||"")}catch(t){n={}}for(var i in e)n[i]=e[i];return n}(s.query,i.query,o&&o.options.parseQuery),l=i.hash||s.hash;return l&&"#"!==l.charAt(0)&&(l="#"+l),{_normalized:!0,path:f,query:h,hash:l}}function N(t,e){var r=F(t),n=r.pathList,o=r.pathMap,i=r.nameMap;function a(t,r,a){var u=J(t,r,!1,e),s=u.name;if(s){var p=i[s];if(!p)return c(null,u);var f=p.regex.keys.filter(function(t){return!t.optional}).map(function(t){return t.name});if("object"!=typeof u.params&&(u.params={}),r&&"object"==typeof r.params)for(var h in r.params)!(h in u.params)&&f.indexOf(h)>-1&&(u.params[h]=r.params[h]);return u.path=D(p.path,u.params),c(p,u,a)}if(u.path){u.params={};for(var l=0;l=t.length?r():t[o]?e(t[o],function(){n(o+1)}):n(o+1)};n(0)}function ht(e){return function(r,n,o){var i=!1,a=0,u=null;lt(e,function(e,r,n,c){if("function"==typeof e&&void 0===e.cid){i=!0,a++;var s,p=yt(function(t){var r;((r=t).__esModule||vt&&"Module"===r[Symbol.toStringTag])&&(t=t.default),e.resolved="function"==typeof t?t:g.extend(t),n.components[c]=t,--a<=0&&o()}),f=yt(function(e){var r="Failed to resolve async component "+c+": "+e;u||(u=t(e)?e:new Error(r),o(u))});try{s=e(p,f)}catch(t){f(t)}if(s)if("function"==typeof s.then)s.then(p,f);else{var h=s.component;h&&"function"==typeof h.then&&h.then(p,f)}}}),i||o()}}function lt(t,e){return dt(t.map(function(t){return Object.keys(t.components).map(function(r){return e(t.components[r],t.instances[r],t,r)})}))}function dt(t){return Array.prototype.concat.apply([],t)}var vt="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function yt(t){var e=!1;return function(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];if(!e)return e=!0,t.apply(this,r)}}var mt=function(t,e){this.router=t,this.base=function(t){if(!t)if(R){var e=document.querySelector("base");t=(t=e&&e.getAttribute("href")||"/").replace(/^https?:\/\/[^\/]+/,"")}else t="/";"/"!==t.charAt(0)&&(t="/"+t);return t.replace(/\/$/,"")}(e),this.current=l,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[]};function gt(t,e,r,n){var o=lt(t,function(t,n,o,i){var a=function(t,e){"function"!=typeof t&&(t=g.extend(t));return t.options[e]}(t,e);if(a)return Array.isArray(a)?a.map(function(t){return r(t,n,o,i)}):r(a,n,o,i)});return dt(n?o.reverse():o)}function bt(t,e){if(e)return function(){return t.apply(e,arguments)}}mt.prototype.listen=function(t){this.cb=t},mt.prototype.onReady=function(t,e){this.ready?t():(this.readyCbs.push(t),e&&this.readyErrorCbs.push(e))},mt.prototype.onError=function(t){this.errorCbs.push(t)},mt.prototype.transitionTo=function(t,e,r){var n=this,o=this.router.match(t,this.current);this.confirmTransition(o,function(){n.updateRoute(o),e&&e(o),n.ensureURL(),n.ready||(n.ready=!0,n.readyCbs.forEach(function(t){t(o)}))},function(t){r&&r(t),t&&!n.ready&&(n.ready=!0,n.readyErrorCbs.forEach(function(e){e(t)}))})},mt.prototype.confirmTransition=function(e,r,n){var o=this,i=this.current,a=function(e){t(e)&&(o.errorCbs.length?o.errorCbs.forEach(function(t){t(e)}):console.error(e)),n&&n(e)};if(y(e,i)&&e.matched.length===i.matched.length)return this.ensureURL(),a();var u=function(t,e){var r,n=Math.max(t.length,e.length);for(r=0;r-1?decodeURI(t.slice(0,n))+t.slice(n):decodeURI(t)}else r>-1&&(t=decodeURI(t.slice(0,r))+t.slice(r));return t}function Ot(t){var e=window.location.href,r=e.indexOf("#");return(r>=0?e.slice(0,r):e)+"#"+t}function At(t){ot?st(Ot(t)):window.location.hash=t}function Ct(t){ot?pt(Ot(t)):window.location.replace(Ot(t))}var jt=function(t){function e(e,r){t.call(this,e,r),this.stack=[],this.index=-1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.push=function(t,e,r){var n=this;this.transitionTo(t,function(t){n.stack=n.stack.slice(0,n.index+1).concat(t),n.index++,e&&e(t)},r)},e.prototype.replace=function(t,e,r){var n=this;this.transitionTo(t,function(t){n.stack=n.stack.slice(0,n.index).concat(t),e&&e(t)},r)},e.prototype.go=function(t){var e=this,r=this.index+t;if(!(r<0||r>=this.stack.length)){var n=this.stack[r];this.confirmTransition(n,function(){e.index=r,e.updateRoute(n)})}},e.prototype.getCurrentLocation=function(){var t=this.stack[this.stack.length-1];return t?t.fullPath:"/"},e.prototype.ensureURL=function(){},e}(mt),_t=function(t){void 0===t&&(t={}),this.app=null,this.apps=[],this.options=t,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=N(t.routes||[],this);var e=t.mode||"hash";switch(this.fallback="history"===e&&!ot&&!1!==t.fallback,this.fallback&&(e="hash"),R||(e="abstract"),this.mode=e,e){case"history":this.history=new wt(this,t.base);break;case"hash":this.history=new kt(this,t.base,this.fallback);break;case"abstract":this.history=new jt(this,t.base)}},Tt={currentRoute:{configurable:!0}};function St(t,e){return t.push(e),function(){var r=t.indexOf(e);r>-1&&t.splice(r,1)}}return _t.prototype.match=function(t,e,r){return this.matcher.match(t,e,r)},Tt.currentRoute.get=function(){return this.history&&this.history.current},_t.prototype.init=function(t){var e=this;if(this.apps.push(t),t.$once("hook:destroyed",function(){var r=e.apps.indexOf(t);r>-1&&e.apps.splice(r,1),e.app===t&&(e.app=e.apps[0]||null)}),!this.app){this.app=t;var r=this.history;if(r instanceof wt)r.transitionTo(r.getCurrentLocation());else if(r instanceof kt){var n=function(){r.setupListeners()};r.transitionTo(r.getCurrentLocation(),n,n)}r.listen(function(t){e.apps.forEach(function(e){e._route=t})})}},_t.prototype.beforeEach=function(t){return St(this.beforeHooks,t)},_t.prototype.beforeResolve=function(t){return St(this.resolveHooks,t)},_t.prototype.afterEach=function(t){return St(this.afterHooks,t)},_t.prototype.onReady=function(t,e){this.history.onReady(t,e)},_t.prototype.onError=function(t){this.history.onError(t)},_t.prototype.push=function(t,e,r){this.history.push(t,e,r)},_t.prototype.replace=function(t,e,r){this.history.replace(t,e,r)},_t.prototype.go=function(t){this.history.go(t)},_t.prototype.back=function(){this.go(-1)},_t.prototype.forward=function(){this.go(1)},_t.prototype.getMatchedComponents=function(t){var e=t?t.matched?t:this.resolve(t).route:this.currentRoute;return e?[].concat.apply([],e.matched.map(function(t){return Object.keys(t.components).map(function(e){return t.components[e]})})):[]},_t.prototype.resolve=function(t,e,r){var n=J(t,e=e||this.history.current,r,this),o=this.match(n,e),i=o.redirectedFrom||o.fullPath;return{location:n,route:o,href:function(t,e,r){var n="hash"===r?"#"+e:e;return t?O(t+"/"+n):n}(this.history.base,i,this.mode),normalizedTo:n,resolved:o}},_t.prototype.addRoutes=function(t){this.matcher.addRoutes(t),this.history.current!==l&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(_t.prototype,Tt),_t.install=function t(e){if(!t.installed||g!==e){t.installed=!0,g=e;var n=function(t){return void 0!==t},o=function(t,e){var r=t.$options._parentVnode;n(r)&&n(r=r.data)&&n(r=r.registerRouteInstance)&&r(t,e)};e.mixin({beforeCreate:function(){n(this.$options.router)?(this._routerRoot=this,this._router=this.$options.router,this._router.init(this),e.util.defineReactive(this,"_route",this._router.history.current)):this._routerRoot=this.$parent&&this.$parent._routerRoot||this,o(this,this)},destroyed:function(){o(this)}}),Object.defineProperty(e.prototype,"$router",{get:function(){return this._routerRoot._router}}),Object.defineProperty(e.prototype,"$route",{get:function(){return this._routerRoot._route}}),e.component("RouterView",r),e.component("RouterLink",x);var i=e.config.optionMergeStrategies;i.beforeRouteEnter=i.beforeRouteLeave=i.beforeRouteUpdate=i.created}},_t.version="3.0.7",R&&window.Vue&&window.Vue.use(_t),_t},"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.VueRouter=e(); \ No newline at end of file diff --git a/package.json b/package.json index 5224e9e41..4422f41d2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue-router", - "version": "3.0.6", + "version": "3.0.7", "description": "Official router for Vue.js 2", "author": "Evan You", "license": "MIT", From da1a1143cd7439a21189cac8de9ffe1cd2cfa968 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Wed, 3 Jul 2019 16:31:43 +0200 Subject: [PATCH 02/30] chore(changelog): 3.0.7 --- CHANGELOG.md | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba612e2e8..79796a9db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,47 +1,43 @@ -## [3.0.6](https://github.com/vuejs/vue-router/compare/v3.0.3...v3.0.6) (2019-04-17) - +## [3.0.7](https://github.com/vuejs/vue-router/compare/v3.0.6...v3.0.7) (2019-07-03) ### Bug Fixes -* revert [#2713](https://github.com/vuejs/vue-router/issues/2713) ([#2723](https://github.com/vuejs/vue-router/issues/2723)) ([ec6eab7](https://github.com/vuejs/vue-router/commit/ec6eab7)), closes [#2719](https://github.com/vuejs/vue-router/issues/2719) +- apps loaded from Windows file shares not mapped to network drives ([#2774](https://github.com/vuejs/vue-router/issues/2774)) ([c2c78a3](https://github.com/vuejs/vue-router/commit/c2c78a3)) +- make callback of next in beforeRouterEnter more consistent ([#2738](https://github.com/vuejs/vue-router/issues/2738)) ([8ac478f](https://github.com/vuejs/vue-router/commit/8ac478f)), closes [#2761](https://github.com/vuejs/vue-router/issues/2761) [#2728](https://github.com/vuejs/vue-router/issues/2728) +## [3.0.6](https://github.com/vuejs/vue-router/compare/v3.0.5...v3.0.6) (2019-04-17) -## [3.0.5](https://github.com/vuejs/vue-router/compare/v3.0.3...v3.0.5) (2019-04-15) +### Bug Fixes +- revert [#2713](https://github.com/vuejs/vue-router/issues/2713) ([#2723](https://github.com/vuejs/vue-router/issues/2723)) ([ec6eab7](https://github.com/vuejs/vue-router/commit/ec6eab7)), closes [#2719](https://github.com/vuejs/vue-router/issues/2719) -### Bug Fixes +## [3.0.5](https://github.com/vuejs/vue-router/compare/v3.0.4...v3.0.5) (2019-04-15) -* prevent memory leaks by removing app references ([#2706](https://github.com/vuejs/vue-router/issues/2706)) ([8056105](https://github.com/vuejs/vue-router/commit/8056105)), closes [#2639](https://github.com/vuejs/vue-router/issues/2639) -* push before creating Vue instance ([#2713](https://github.com/vuejs/vue-router/issues/2713)) ([6974a6f](https://github.com/vuejs/vue-router/commit/6974a6f)), closes [#2712](https://github.com/vuejs/vue-router/issues/2712) -* **router-view:** add condition to see whether the tree is inactive (fix [#2552](https://github.com/vuejs/vue-router/issues/2552)) ([#2592](https://github.com/vuejs/vue-router/issues/2592)) ([e6d8fd2](https://github.com/vuejs/vue-router/commit/e6d8fd2)) -* **router-view:** register instance in init hook ([c3abdf6](https://github.com/vuejs/vue-router/commit/c3abdf6)), closes [#2561](https://github.com/vuejs/vue-router/issues/2561) [#2689](https://github.com/vuejs/vue-router/issues/2689) [#2561](https://github.com/vuejs/vue-router/issues/2561) [#2561](https://github.com/vuejs/vue-router/issues/2561) +### Bug Fixes +- push before creating Vue instance ([#2713](https://github.com/vuejs/vue-router/issues/2713)) ([6974a6f](https://github.com/vuejs/vue-router/commit/6974a6f)), closes [#2712](https://github.com/vuejs/vue-router/issues/2712) +- **router-view:** add condition to see whether the tree is inactive (fix [#2552](https://github.com/vuejs/vue-router/issues/2552)) ([#2592](https://github.com/vuejs/vue-router/issues/2592)) ([e6d8fd2](https://github.com/vuejs/vue-router/commit/e6d8fd2)) +- **router-view:** register instance in init hook ([c3abdf6](https://github.com/vuejs/vue-router/commit/c3abdf6)), closes [#2561](https://github.com/vuejs/vue-router/issues/2561) [#2689](https://github.com/vuejs/vue-router/issues/2689) [#2561](https://github.com/vuejs/vue-router/issues/2561) [#2561](https://github.com/vuejs/vue-router/issues/2561) ## [3.0.4](https://github.com/vuejs/vue-router/compare/v3.0.3...v3.0.4) (2019-04-12) - ### Bug Fixes -* prevent memory leaks by removing app references ([#2706](https://github.com/vuejs/vue-router/issues/2706)) ([8056105](https://github.com/vuejs/vue-router/commit/8056105)), closes [#2639](https://github.com/vuejs/vue-router/issues/2639) -* **hash:** prevent double decoding ([#2711](https://github.com/vuejs/vue-router/issues/2711)) ([a775fb1](https://github.com/vuejs/vue-router/commit/a775fb1)), closes [#2708](https://github.com/vuejs/vue-router/issues/2708) - +- prevent memory leaks by removing app references ([#2706](https://github.com/vuejs/vue-router/issues/2706)) ([8056105](https://github.com/vuejs/vue-router/commit/8056105)), closes [#2639](https://github.com/vuejs/vue-router/issues/2639) +- **hash:** prevent double decoding ([#2711](https://github.com/vuejs/vue-router/issues/2711)) ([a775fb1](https://github.com/vuejs/vue-router/commit/a775fb1)), closes [#2708](https://github.com/vuejs/vue-router/issues/2708) ### Features -* **esm build:** build ES modules for browser ([#2705](https://github.com/vuejs/vue-router/issues/2705)) ([627027f](https://github.com/vuejs/vue-router/commit/627027f)) - +- **esm build:** build ES modules for browser ([#2705](https://github.com/vuejs/vue-router/issues/2705)) ([627027f](https://github.com/vuejs/vue-router/commit/627027f)) ## [3.0.3](https://github.com/vuejs/vue-router/compare/v3.0.2...v3.0.3) (2019-04-08) - ### Bug Fixes -* removes warning resolving asterisk routes ([e224637](https://github.com/vuejs/vue-router/commit/e224637)), closes [#2505](https://github.com/vuejs/vue-router/issues/2505) [#2505](https://github.com/vuejs/vue-router/issues/2505) -* **normalizeLocation:** create a copy with named locations ([#2286](https://github.com/vuejs/vue-router/issues/2286)) ([53cce99](https://github.com/vuejs/vue-router/commit/53cce99)), closes [#2121](https://github.com/vuejs/vue-router/issues/2121) -* **resolve:** use current location if not provided ([#2390](https://github.com/vuejs/vue-router/issues/2390)) ([7ff4de4](https://github.com/vuejs/vue-router/commit/7ff4de4)), closes [#2385](https://github.com/vuejs/vue-router/issues/2385) -* **types:** allow null/undefined in query params ([ca30a75](https://github.com/vuejs/vue-router/commit/ca30a75)), closes [#2605](https://github.com/vuejs/vue-router/issues/2605) - - +- removes warning resolving asterisk routes ([e224637](https://github.com/vuejs/vue-router/commit/e224637)), closes [#2505](https://github.com/vuejs/vue-router/issues/2505) [#2505](https://github.com/vuejs/vue-router/issues/2505) +- **normalizeLocation:** create a copy with named locations ([#2286](https://github.com/vuejs/vue-router/issues/2286)) ([53cce99](https://github.com/vuejs/vue-router/commit/53cce99)), closes [#2121](https://github.com/vuejs/vue-router/issues/2121) +- **resolve:** use current location if not provided ([#2390](https://github.com/vuejs/vue-router/issues/2390)) ([7ff4de4](https://github.com/vuejs/vue-router/commit/7ff4de4)), closes [#2385](https://github.com/vuejs/vue-router/issues/2385) +- **types:** allow null/undefined in query params ([ca30a75](https://github.com/vuejs/vue-router/commit/ca30a75)), closes [#2605](https://github.com/vuejs/vue-router/issues/2605) ## [3.0.2](https://github.com/vuejs/vue-router/compare/v3.0.1...v3.0.2) (2018-11-23) From 64785a9f59dfa960d2025faaa03480a488dfef94 Mon Sep 17 00:00:00 2001 From: Francois Hendriks <31185922+Domino9697@users.noreply.github.com> Date: Fri, 5 Jul 2019 11:22:31 +0200 Subject: [PATCH 03/30] fix(link): Fix active links when parent link redirects to child (#2772) * fix(ActiveLink): Fix active links when parent link redirects to child Fix active parent link when parent link redirects to a child and when the user navigates between child links fix #2724 * test(active-links): add more tests for redirects * chore(lint): add prettier conf to specs for longer lines * test(active-links): adapt redirect tests to added content * chore(link): remove commented code --- examples/active-links/app.js | 46 ++++++++++++++++++++++++++++++++-- src/components/link.js | 44 +++++++++++++++++++------------- test/e2e/specs/.prettierrc | 3 +++ test/e2e/specs/active-links.js | 21 +++++++++++++++- 4 files changed, 93 insertions(+), 21 deletions(-) create mode 100644 test/e2e/specs/.prettierrc diff --git a/examples/active-links/app.js b/examples/active-links/app.js index a1a3238d4..1715d58b6 100644 --- a/examples/active-links/app.js +++ b/examples/active-links/app.js @@ -17,15 +17,48 @@ const Users = { const User = { template: '
{{ $route.params.username }}
' } +const Gallery = { + template: ` +
+

Gallery

+ +
+ ` +} + +const Image = { template: '
{{ $route.params.imageId }}
' } + const router = new VueRouter({ mode: 'history', base: __dirname, routes: [ { path: '/', component: Home }, { path: '/about', component: About }, - { path: '/users', component: Users, + { + path: '/redirect-gallery', + name: 'redirect-gallery', + redirect: { name: 'gallery' } + }, + { + path: '/redirect-image', + name: 'redirect-image', + redirect: { name: 'image', params: { imageId: 'image1' }} + }, + { + path: '/users', + component: Users, + children: [{ path: ':username', name: 'user', component: User }] + }, + { + path: '/gallery', + component: Gallery, children: [ - { path: ':username', name: 'user', component: User } + { + path: '', + name: 'gallery', + redirect: { name: 'image', params: { imageId: 'image1' }} + }, + { path: ':imageId', component: Image, name: 'image' } ] } ] @@ -66,6 +99,15 @@ new Vue({ /about (active class on outer element) + +
  • /gallery (redirect to /gallery/image1)
  • +
  • /gallery named link (redirect to /gallery/image1)
  • +
  • /gallery/image2
  • +
  • /gallery/image1
  • +
  • /redirect-gallery (redirect to /gallery)
  • +
  • /redirect-gallery named (redirect to /gallery)
  • +
  • /redirect-image (redirect to /gallery/image1)
  • +
  • /redirect-image named (redirect to /gallery/image1)
  • diff --git a/src/components/link.js b/src/components/link.js index 2662d8263..d944e8b82 100644 --- a/src/components/link.js +++ b/src/components/link.js @@ -2,6 +2,7 @@ import { createRoute, isSameRoute, isIncludedRoute } from '../util/route' import { extend } from '../util/misc' +import { normalizeLocation } from '../util/location' // work around weird flow bug const toTypes: Array = [String, Object] @@ -31,26 +32,31 @@ export default { render (h: Function) { const router = this.$router const current = this.$route - const { location, route, href } = router.resolve(this.to, current, this.append) + const { location, route, href } = router.resolve( + this.to, + current, + this.append + ) const classes = {} const globalActiveClass = router.options.linkActiveClass const globalExactActiveClass = router.options.linkExactActiveClass // Support global empty active class - const activeClassFallback = globalActiveClass == null - ? 'router-link-active' - : globalActiveClass - const exactActiveClassFallback = globalExactActiveClass == null - ? 'router-link-exact-active' - : globalExactActiveClass - const activeClass = this.activeClass == null - ? activeClassFallback - : this.activeClass - const exactActiveClass = this.exactActiveClass == null - ? exactActiveClassFallback - : this.exactActiveClass - const compareTarget = location.path - ? createRoute(null, location, null, router) + const activeClassFallback = + globalActiveClass == null ? 'router-link-active' : globalActiveClass + const exactActiveClassFallback = + globalExactActiveClass == null + ? 'router-link-exact-active' + : globalExactActiveClass + const activeClass = + this.activeClass == null ? activeClassFallback : this.activeClass + const exactActiveClass = + this.exactActiveClass == null + ? exactActiveClassFallback + : this.exactActiveClass + + const compareTarget = route.redirectedFrom + ? createRoute(null, normalizeLocation(route.redirectedFrom), null, router) : route classes[exactActiveClass] = isSameRoute(current, compareTarget) @@ -70,7 +76,9 @@ export default { const on = { click: guardEvent } if (Array.isArray(this.event)) { - this.event.forEach(e => { on[e] = handler }) + this.event.forEach(e => { + on[e] = handler + }) } else { on[this.event] = handler } @@ -88,9 +96,9 @@ export default { if (a) { // in case the is a static node a.isStatic = false - const aData = a.data = extend({}, a.data) + const aData = (a.data = extend({}, a.data)) aData.on = on - const aAttrs = a.data.attrs = extend({}, a.data.attrs) + const aAttrs = (a.data.attrs = extend({}, a.data.attrs)) aAttrs.href = href } else { // doesn't have child, apply listener to self diff --git a/test/e2e/specs/.prettierrc b/test/e2e/specs/.prettierrc new file mode 100644 index 000000000..963354f23 --- /dev/null +++ b/test/e2e/specs/.prettierrc @@ -0,0 +1,3 @@ +{ + "printWidth": 120 +} diff --git a/test/e2e/specs/active-links.js b/test/e2e/specs/active-links.js index fd142e4e5..686e94af2 100644 --- a/test/e2e/specs/active-links.js +++ b/test/e2e/specs/active-links.js @@ -9,7 +9,7 @@ module.exports = { browser .url('http://localhost:8080/active-links/') .waitForElementVisible('#app', 1000) - .assert.count('li a', 11) + .assert.count('li a', 19) // assert correct href with base .assert.attributeContains('li:nth-child(1) a', 'href', '/active-links/') .assert.attributeContains('li:nth-child(2) a', 'href', '/active-links/') @@ -22,6 +22,14 @@ module.exports = { .assert.attributeContains('li:nth-child(9) a', 'href', '/active-links/users/evan?foo=bar&baz=qux') .assert.attributeContains('li:nth-child(10) a', 'href', '/active-links/about') .assert.attributeContains('li:nth-child(11) a', 'href', '/active-links/about') + .assert.attributeContains('li:nth-child(12) a', 'href', '/active-links/gallery') + .assert.attributeContains('li:nth-child(13) a', 'href', '/active-links/gallery/') + .assert.attributeContains('li:nth-child(14) a', 'href', '/active-links/gallery/image2') + .assert.attributeContains('li:nth-child(15) a', 'href', '/active-links/gallery/image1') + .assert.attributeContains('li:nth-child(16) a', 'href', '/active-links/redirect-gallery') + .assert.attributeContains('li:nth-child(17) a', 'href', '/active-links/redirect-gallery') + .assert.attributeContains('li:nth-child(18) a', 'href', '/active-links/redirect-image') + .assert.attributeContains('li:nth-child(19) a', 'href', '/active-links/redirect-image') .assert.containsText('.view', 'Home') assertActiveLinks(1, [1, 2], null, [1, 2]) @@ -36,6 +44,17 @@ module.exports = { assertActiveLinks(10, [1, 10], [11], [10], [11]) assertActiveLinks(11, [1, 10], [11], [10], [11]) + // redirects + assertActiveLinks(12, [1, 12, 13, 15], null, [15]) + assertActiveLinks(13, [1, 12, 13, 15], null, [15]) + assertActiveLinks(14, [1, 12, 13, 14], null, [14]) + assertActiveLinks(15, [1, 12, 13, 15], null, [15]) + // different level redirect + assertActiveLinks(16, [1, 12, 13, 15], null, [15]) + assertActiveLinks(17, [1, 12, 13, 15], null, [15]) + assertActiveLinks(18, [1, 12, 13, 15], null, [15]) + assertActiveLinks(19, [1, 12, 13, 15], null, [15]) + browser.end() function assertActiveLinks (n, activeA, activeLI, exactActiveA, exactActiveLI) { From 891097970dec1c02b12d2b406448c1fb02d007d6 Mon Sep 17 00:00:00 2001 From: Francois Hendriks <31185922+Domino9697@users.noreply.github.com> Date: Fri, 5 Jul 2019 15:20:31 +0200 Subject: [PATCH 04/30] fix(abstract history): allow router.back in abstract mode when 2 consecutive same routes appear in history stack (#2771) * fix(AbstractHistory): Fix router.back in abstract mode Fix abstract mode's router.back() when 2 consecutive same routes appear in the history stack array fix #2607 * refactor(history): use an Error object when navigatin to the same place --- src/history/abstract.js | 21 ++++++++++++++------ src/history/base.js | 37 ++++++++++++++++++++---------------- src/history/errors.js | 6 ++++++ test/unit/specs/node.spec.js | 36 ++++++++++++++++++++++++++++++++--- 4 files changed, 75 insertions(+), 25 deletions(-) create mode 100644 src/history/errors.js diff --git a/src/history/abstract.js b/src/history/abstract.js index 00e09392d..eb8a3ad11 100644 --- a/src/history/abstract.js +++ b/src/history/abstract.js @@ -2,10 +2,11 @@ import type Router from '../index' import { History } from './base' +import { NavigationDuplicated } from './errors' export class AbstractHistory extends History { - index: number; - stack: Array; + index: number + stack: Array constructor (router: Router, base: ?string) { super(router, base) @@ -34,10 +35,18 @@ export class AbstractHistory extends History { return } const route = this.stack[targetIndex] - this.confirmTransition(route, () => { - this.index = targetIndex - this.updateRoute(route) - }) + this.confirmTransition( + route, + () => { + this.index = targetIndex + this.updateRoute(route) + }, + err => { + if (err instanceof NavigationDuplicated) { + this.index = targetIndex + } + } + ) } getCurrentLocation () { diff --git a/src/history/base.js b/src/history/base.js index fbdf25696..6ecdbd727 100644 --- a/src/history/base.js +++ b/src/history/base.js @@ -11,24 +11,25 @@ import { flatMapComponents, resolveAsyncComponents } from '../util/resolve-components' +import { NavigationDuplicated } from './errors' export class History { - router: Router; - base: string; - current: Route; - pending: ?Route; - cb: (r: Route) => void; - ready: boolean; - readyCbs: Array; - readyErrorCbs: Array; - errorCbs: Array; + router: Router + base: string + current: Route + pending: ?Route + cb: (r: Route) => void + ready: boolean + readyCbs: Array + readyErrorCbs: Array + errorCbs: Array // implemented by sub-classes - +go: (n: number) => void; - +push: (loc: RawLocation) => void; - +replace: (loc: RawLocation) => void; - +ensureURL: (push?: boolean) => void; - +getCurrentLocation: () => string; + +go: (n: number) => void + +push: (loc: RawLocation) => void + +replace: (loc: RawLocation) => void + +ensureURL: (push?: boolean) => void + +getCurrentLocation: () => string constructor (router: Router, base: ?string) { this.router = router @@ -87,7 +88,11 @@ export class History { confirmTransition (route: Route, onComplete: Function, onAbort?: Function) { const current = this.current const abort = err => { - if (isError(err)) { + // after merging https://github.com/vuejs/vue-router/pull/2771 we + // When the user navigates through history through back/forward buttons + // we do not want to throw the error. We only throw it if directly calling + // push/replace. That's why it's not included in isError + if (!(err instanceof NavigationDuplicated) && isError(err)) { if (this.errorCbs.length) { this.errorCbs.forEach(cb => { cb(err) }) } else { @@ -103,7 +108,7 @@ export class History { route.matched.length === current.matched.length ) { this.ensureURL() - return abort() + return abort(new NavigationDuplicated(route)) } const { diff --git a/src/history/errors.js b/src/history/errors.js new file mode 100644 index 000000000..24117a51d --- /dev/null +++ b/src/history/errors.js @@ -0,0 +1,6 @@ +export class NavigationDuplicated extends Error { + constructor () { + super('Navigating to current location is not allowed') + Object.setPrototypeOf(this, new.target.prototype) + } +} diff --git a/test/unit/specs/node.spec.js b/test/unit/specs/node.spec.js index d155982d3..6c9d0178b 100644 --- a/test/unit/specs/node.spec.js +++ b/test/unit/specs/node.spec.js @@ -27,12 +27,42 @@ describe('Usage in Node', () => { const router = new VueRouter({ routes: [ { path: '/', component: Foo }, - { path: '/bar', component: Bar, children: [ - { path: 'baz', component: Baz } - ] } + { + path: '/bar', + component: Bar, + children: [{ path: 'baz', component: Baz }] + } ] }) expect(router.getMatchedComponents('/')).toEqual([Foo]) expect(router.getMatchedComponents('/bar/baz')).toEqual([Bar, Baz]) }) + + it('should navigate through history with same consecutive routes in history stack', () => { + const success = jasmine.createSpy('complete') + const error = jasmine.createSpy('error') + const router = new VueRouter({ + routes: [ + { path: '/', component: { name: 'foo' }}, + { path: '/bar', component: { name: 'bar' }} + ] + }) + router.push('/', success, error) + expect(success).toHaveBeenCalledTimes(1) + expect(error).toHaveBeenCalledTimes(0) + router.push('/bar', success, error) + expect(success).toHaveBeenCalledTimes(2) + expect(error).toHaveBeenCalledTimes(0) + router.push('/', success, error) + expect(success).toHaveBeenCalledTimes(3) + expect(error).toHaveBeenCalledTimes(0) + router.replace('/bar', success, error) + expect(success).toHaveBeenCalledTimes(4) + expect(error).toHaveBeenCalledTimes(0) + spyOn(console, 'warn') + router.back() + expect(router.history.current.path).toBe('/bar') + router.back() + expect(router.history.current.path).toBe('/') + }) }) From 0ec4713a1d465928fc187a1dc192553027f2ee95 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Fri, 5 Jul 2019 15:51:21 +0200 Subject: [PATCH 05/30] refactor: suppress usage of setPrototypeOf --- src/history/errors.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/history/errors.js b/src/history/errors.js index 24117a51d..d82b1211c 100644 --- a/src/history/errors.js +++ b/src/history/errors.js @@ -1,6 +1,6 @@ export class NavigationDuplicated extends Error { constructor () { super('Navigating to current location is not allowed') - Object.setPrototypeOf(this, new.target.prototype) + this.name = this.constructor.name } } From 4e14d857f66c18772d1211b611fcdbcaee1cd563 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Fri, 5 Jul 2019 16:19:48 +0200 Subject: [PATCH 06/30] refactor: fix extended error usage --- src/history/abstract.js | 29 +++++++++++++++++++---------- src/history/base.js | 8 +++++--- src/history/errors.js | 2 +- src/util/warn.js | 4 ++++ test/unit/specs/node.spec.js | 3 ++- 5 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/history/abstract.js b/src/history/abstract.js index eb8a3ad11..7b6bdf2a8 100644 --- a/src/history/abstract.js +++ b/src/history/abstract.js @@ -3,6 +3,7 @@ import type Router from '../index' import { History } from './base' import { NavigationDuplicated } from './errors' +import { isExtendedError } from '../util/warn' export class AbstractHistory extends History { index: number @@ -15,18 +16,26 @@ export class AbstractHistory extends History { } push (location: RawLocation, onComplete?: Function, onAbort?: Function) { - this.transitionTo(location, route => { - this.stack = this.stack.slice(0, this.index + 1).concat(route) - this.index++ - onComplete && onComplete(route) - }, onAbort) + this.transitionTo( + location, + route => { + this.stack = this.stack.slice(0, this.index + 1).concat(route) + this.index++ + onComplete && onComplete(route) + }, + onAbort + ) } replace (location: RawLocation, onComplete?: Function, onAbort?: Function) { - this.transitionTo(location, route => { - this.stack = this.stack.slice(0, this.index).concat(route) - onComplete && onComplete(route) - }, onAbort) + this.transitionTo( + location, + route => { + this.stack = this.stack.slice(0, this.index).concat(route) + onComplete && onComplete(route) + }, + onAbort + ) } go (n: number) { @@ -42,7 +51,7 @@ export class AbstractHistory extends History { this.updateRoute(route) }, err => { - if (err instanceof NavigationDuplicated) { + if (isExtendedError(NavigationDuplicated, err)) { this.index = targetIndex } } diff --git a/src/history/base.js b/src/history/base.js index 6ecdbd727..c1f85db69 100644 --- a/src/history/base.js +++ b/src/history/base.js @@ -4,7 +4,7 @@ import { _Vue } from '../install' import type Router from '../index' import { inBrowser } from '../util/dom' import { runQueue } from '../util/async' -import { warn, isError } from '../util/warn' +import { warn, isError, isExtendedError } from '../util/warn' import { START, isSameRoute } from '../util/route' import { flatten, @@ -92,9 +92,11 @@ export class History { // When the user navigates through history through back/forward buttons // we do not want to throw the error. We only throw it if directly calling // push/replace. That's why it's not included in isError - if (!(err instanceof NavigationDuplicated) && isError(err)) { + if (!isExtendedError(NavigationDuplicated, err) && isError(err)) { if (this.errorCbs.length) { - this.errorCbs.forEach(cb => { cb(err) }) + this.errorCbs.forEach(cb => { + cb(err) + }) } else { warn(false, 'uncaught error during route navigation:') console.error(err) diff --git a/src/history/errors.js b/src/history/errors.js index d82b1211c..f95352ed2 100644 --- a/src/history/errors.js +++ b/src/history/errors.js @@ -1,6 +1,6 @@ export class NavigationDuplicated extends Error { constructor () { super('Navigating to current location is not allowed') - this.name = this.constructor.name + this.name = 'NavigationDuplicated' } } diff --git a/src/util/warn.js b/src/util/warn.js index 65f1cec4f..f45dec98c 100644 --- a/src/util/warn.js +++ b/src/util/warn.js @@ -15,3 +15,7 @@ export function warn (condition: any, message: string) { export function isError (err: any): boolean { return Object.prototype.toString.call(err).indexOf('Error') > -1 } + +export function isExtendedError (constructor: Function, err: any): boolean { + return err instanceof constructor || (err && err.name === constructor.name) +} diff --git a/test/unit/specs/node.spec.js b/test/unit/specs/node.spec.js index 6c9d0178b..292b7ea48 100644 --- a/test/unit/specs/node.spec.js +++ b/test/unit/specs/node.spec.js @@ -59,7 +59,8 @@ describe('Usage in Node', () => { router.replace('/bar', success, error) expect(success).toHaveBeenCalledTimes(4) expect(error).toHaveBeenCalledTimes(0) - spyOn(console, 'warn') + + expect(router.history.current.path).toBe('/bar') router.back() expect(router.history.current.path).toBe('/bar') router.back() From fc42d9cf8e1d381b885c9af37003198dce6f1161 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Fri, 5 Jul 2019 16:23:36 +0200 Subject: [PATCH 07/30] refactor(history-base): use prettier --- src/history/base.js | 77 +++++++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 31 deletions(-) diff --git a/src/history/base.js b/src/history/base.js index c1f85db69..2b12e1967 100644 --- a/src/history/base.js +++ b/src/history/base.js @@ -62,27 +62,39 @@ export class History { this.errorCbs.push(errorCb) } - transitionTo (location: RawLocation, onComplete?: Function, onAbort?: Function) { + transitionTo ( + location: RawLocation, + onComplete?: Function, + onAbort?: Function + ) { const route = this.router.match(location, this.current) - this.confirmTransition(route, () => { - this.updateRoute(route) - onComplete && onComplete(route) - this.ensureURL() + this.confirmTransition( + route, + () => { + this.updateRoute(route) + onComplete && onComplete(route) + this.ensureURL() - // fire ready cbs once - if (!this.ready) { - this.ready = true - this.readyCbs.forEach(cb => { cb(route) }) - } - }, err => { - if (onAbort) { - onAbort(err) - } - if (err && !this.ready) { - this.ready = true - this.readyErrorCbs.forEach(cb => { cb(err) }) + // fire ready cbs once + if (!this.ready) { + this.ready = true + this.readyCbs.forEach(cb => { + cb(route) + }) + } + }, + err => { + if (onAbort) { + onAbort(err) + } + if (err && !this.ready) { + this.ready = true + this.readyErrorCbs.forEach(cb => { + cb(err) + }) + } } - }) + ) } confirmTransition (route: Route, onComplete: Function, onAbort?: Function) { @@ -113,11 +125,10 @@ export class History { return abort(new NavigationDuplicated(route)) } - const { - updated, - deactivated, - activated - } = resolveQueue(this.current.matched, route.matched) + const { updated, deactivated, activated } = resolveQueue( + this.current.matched, + route.matched + ) const queue: Array = [].concat( // in-component leave guards @@ -145,10 +156,8 @@ export class History { abort(to) } else if ( typeof to === 'string' || - (typeof to === 'object' && ( - typeof to.path === 'string' || - typeof to.name === 'string' - )) + (typeof to === 'object' && + (typeof to.path === 'string' || typeof to.name === 'string')) ) { // next('/') or next({ path: '/' }) -> redirect abort() @@ -182,7 +191,9 @@ export class History { onComplete(route) if (this.router.app) { this.router.app.$nextTick(() => { - postEnterCbs.forEach(cb => { cb() }) + postEnterCbs.forEach(cb => { + cb() + }) }) } }) @@ -290,9 +301,13 @@ function extractEnterGuards ( cbs: Array, isValid: () => boolean ): Array { - return extractGuards(activated, 'beforeRouteEnter', (guard, _, match, key) => { - return bindEnterGuard(guard, match, key, cbs, isValid) - }) + return extractGuards( + activated, + 'beforeRouteEnter', + (guard, _, match, key) => { + return bindEnterGuard(guard, match, key, cbs, isValid) + } + ) } function bindEnterGuard ( From 8df4123a6a4c0e6d274bbd5920492821345e4dd0 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Mon, 8 Jul 2019 14:38:03 +0200 Subject: [PATCH 08/30] test(e2e): add more space to scroll behavior test --- examples/scroll-behavior/app.js | 5 +++-- examples/scroll-behavior/index.html | 26 ++++++++++++++------------ test/e2e/runner.js | 1 + 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/examples/scroll-behavior/app.js b/examples/scroll-behavior/app.js index 4f1bbb3d1..81a539f0c 100644 --- a/examples/scroll-behavior/app.js +++ b/examples/scroll-behavior/app.js @@ -9,9 +9,10 @@ const Bar = { template: `
    bar -
    +

    Anchor

    -

    Anchor2

    +

    Anchor2

    +

    with number

    ` } diff --git a/examples/scroll-behavior/index.html b/examples/scroll-behavior/index.html index cf75cc05e..c6087064b 100644 --- a/examples/scroll-behavior/index.html +++ b/examples/scroll-behavior/index.html @@ -1,17 +1,19 @@ - +
    ← Examples index
    diff --git a/test/e2e/runner.js b/test/e2e/runner.js index e0167e08b..b912d6ef1 100644 --- a/test/e2e/runner.js +++ b/test/e2e/runner.js @@ -12,6 +12,7 @@ * * If you are already running the dev server with `yarn run serve`, you can pass the --dev option to avoid launching the server * $ node test/e2e/runner.js --dev + * **Make sure to pass the option at the end** * * __For maintainers only__ * You can trigger tests on Browserstack on other browsers by passing the --local option From 799ceca94ae98aac900d7f0fc38e3b17cecbdc33 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Mon, 8 Jul 2019 14:55:05 +0200 Subject: [PATCH 09/30] feat(scroll): handle id selectors starting with a number Closes #2163 --- examples/scroll-behavior/app.js | 4 +++- src/util/scroll.js | 37 ++++++++++++++++++++++--------- test/e2e/specs/scroll-behavior.js | 12 +++++++++- 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/examples/scroll-behavior/app.js b/examples/scroll-behavior/app.js index 81a539f0c..afdccb049 100644 --- a/examples/scroll-behavior/app.js +++ b/examples/scroll-behavior/app.js @@ -37,7 +37,8 @@ const scrollBehavior = function (to, from, savedPosition) { position.offset = { y: 100 } } - if (document.querySelector(to.hash)) { + // bypass #1number check + if (/^#\d/.test(to.hash) || document.querySelector(to.hash)) { return position } @@ -87,6 +88,7 @@ new Vue({
  • /bar
  • /bar#anchor
  • /bar#anchor2
  • +
  • /bar#1number
  • diff --git a/src/util/scroll.js b/src/util/scroll.js index ec949c062..1d444f3ec 100644 --- a/src/util/scroll.js +++ b/src/util/scroll.js @@ -45,20 +45,27 @@ export function handleScroll ( // wait until re-render finishes before scrolling router.app.$nextTick(() => { const position = getScrollPosition() - const shouldScroll = behavior.call(router, to, from, isPop ? position : null) + const shouldScroll = behavior.call( + router, + to, + from, + isPop ? position : null + ) if (!shouldScroll) { return } if (typeof shouldScroll.then === 'function') { - shouldScroll.then(shouldScroll => { - scrollToPosition((shouldScroll: any), position) - }).catch(err => { - if (process.env.NODE_ENV !== 'production') { - assert(false, err.toString()) - } - }) + shouldScroll + .then(shouldScroll => { + scrollToPosition((shouldScroll: any), position) + }) + .catch(err => { + if (process.env.NODE_ENV !== 'production') { + assert(false, err.toString()) + } + }) } else { scrollToPosition(shouldScroll, position) } @@ -114,12 +121,22 @@ function isNumber (v: any): boolean { return typeof v === 'number' } +const hashStartsWithNumberRE = /^#\d/ + function scrollToPosition (shouldScroll, position) { const isObject = typeof shouldScroll === 'object' if (isObject && typeof shouldScroll.selector === 'string') { - const el = document.querySelector(shouldScroll.selector) + // getElementById would still fail if the selector contains a more complicated query like #main[data-attr] + // but at the same time, it doesn't make much sense to select an element with an id and an extra selector + const el = hashStartsWithNumberRE.test(shouldScroll.selector) // $flow-disable-line + ? document.getElementById(shouldScroll.selector.slice(1)) // $flow-disable-line + : document.querySelector(shouldScroll.selector) + if (el) { - let offset = shouldScroll.offset && typeof shouldScroll.offset === 'object' ? shouldScroll.offset : {} + let offset = + shouldScroll.offset && typeof shouldScroll.offset === 'object' + ? shouldScroll.offset + : {} offset = normalizeOffset(offset) position = getElementPosition(el, offset) } else if (isValidPosition(shouldScroll)) { diff --git a/test/e2e/specs/scroll-behavior.js b/test/e2e/specs/scroll-behavior.js index 9ececb493..6cc371fee 100644 --- a/test/e2e/specs/scroll-behavior.js +++ b/test/e2e/specs/scroll-behavior.js @@ -11,7 +11,7 @@ module.exports = { browser .url('http://localhost:8080/scroll-behavior/') .waitForElementVisible('#app', 1000) - .assert.count('li a', 5) + .assert.count('li a', 6) .assert.containsText('.view', 'home') .execute(function () { @@ -117,6 +117,16 @@ module.exports = { null, 'scroll to anchor with offset' ) + .execute(function () { + document.querySelector('li:nth-child(6) a').click() + }) + .assert.evaluate( + function () { + return document.getElementById('1number').getBoundingClientRect().top < 1 + }, + null, + 'scroll to anchor that starts with number' + ) .end() } } From 04a02c0b2082475434ad7355809a21f7e5ecc6a0 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Tue, 9 Jul 2019 21:08:45 +0200 Subject: [PATCH 10/30] feat(alias): warn against redundant aliases Fix #2461, #2462 --- src/create-route-map.js | 92 ++++++++++++++++++------------ test/unit/specs/create-map.spec.js | 71 +++++++++++++++++++---- 2 files changed, 118 insertions(+), 45 deletions(-) diff --git a/src/create-route-map.js b/src/create-route-map.js index 560e05fdd..0f790108c 100644 --- a/src/create-route-map.js +++ b/src/create-route-map.js @@ -10,9 +10,9 @@ export function createRouteMap ( oldPathMap?: Dictionary, oldNameMap?: Dictionary ): { - pathList: Array; - pathMap: Dictionary; - nameMap: Dictionary; + pathList: Array, + pathMap: Dictionary, + nameMap: Dictionary } { // the path list is used to control path matching priority const pathList: Array = oldPathList || [] @@ -54,17 +54,15 @@ function addRouteRecord ( 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.` + `route config "component" for path: ${String( + path || name + )} cannot be a ` + `string id. Use an actual component instead.` ) } - const pathToRegexpOptions: PathToRegexpOptions = route.pathToRegexpOptions || {} - const normalizedPath = normalizePath( - path, - parent, - pathToRegexpOptions.strict - ) + const pathToRegexpOptions: PathToRegexpOptions = + route.pathToRegexpOptions || {} + const normalizedPath = normalizePath(path, parent, pathToRegexpOptions.strict) if (typeof route.caseSensitive === 'boolean') { pathToRegexpOptions.sensitive = route.caseSensitive @@ -81,11 +79,12 @@ function addRouteRecord ( redirect: route.redirect, beforeEnter: route.beforeEnter, meta: route.meta || {}, - props: route.props == null - ? {} - : route.components - ? route.props - : { default: route.props } + props: + route.props == null + ? {} + : route.components + ? route.props + : { default: route.props } } if (route.children) { @@ -93,14 +92,20 @@ function addRouteRecord ( // 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.redirect && route.children.some(child => /^\/?$/.test(child.path))) { + if ( + route.name && + !route.redirect && + route.children.some(child => /^\/?$/.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.` + `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.` ) } } @@ -112,12 +117,24 @@ function addRouteRecord ( }) } + if (!pathMap[record.path]) { + pathList.push(record.path) + pathMap[record.path] = record + } + if (route.alias !== undefined) { - const aliases = Array.isArray(route.alias) - ? route.alias - : [route.alias] + const aliases = Array.isArray(route.alias) ? route.alias : [route.alias] + for (let i = 0; i < aliases.length; ++i) { + const alias = aliases[i] + if (process.env.NODE_ENV !== 'production' && alias === path) { + warn( + false, + `Found an alias with the same value as the path: "${path}". You have to remove that alias. It will be ignored in development.` + ) + // skip in dev to make it work + continue + } - aliases.forEach(alias => { const aliasRoute = { path: alias, children: route.children @@ -130,12 +147,7 @@ function addRouteRecord ( parent, record.path || '/' // matchAs ) - }) - } - - if (!pathMap[record.path]) { - pathList.push(record.path) - pathMap[record.path] = record + } } if (name) { @@ -145,25 +157,35 @@ function addRouteRecord ( warn( false, `Duplicate named routes definition: ` + - `{ name: "${name}", path: "${record.path}" }` + `{ name: "${name}", path: "${record.path}" }` ) } } } -function compileRouteRegex (path: string, pathToRegexpOptions: PathToRegexpOptions): RouteRegExp { +function compileRouteRegex ( + path: string, + pathToRegexpOptions: PathToRegexpOptions +): RouteRegExp { const regex = Regexp(path, [], pathToRegexpOptions) if (process.env.NODE_ENV !== 'production') { const keys: any = Object.create(null) regex.keys.forEach(key => { - warn(!keys[key.name], `Duplicate param keys in route with path: "${path}"`) + warn( + !keys[key.name], + `Duplicate param keys in route with path: "${path}"` + ) keys[key.name] = true }) } return regex } -function normalizePath (path: string, parent?: RouteRecord, strict?: boolean): string { +function normalizePath ( + path: string, + parent?: RouteRecord, + strict?: boolean +): string { if (!strict) path = path.replace(/\/$/, '') if (path[0] === '/') return path if (parent == null) return path diff --git a/test/unit/specs/create-map.spec.js b/test/unit/specs/create-map.spec.js index 67fba131a..a7d09daff 100644 --- a/test/unit/specs/create-map.spec.js +++ b/test/unit/specs/create-map.spec.js @@ -57,10 +57,18 @@ describe('Creating Route Map', function () { }) it('has a pathList which places wildcards at the end', () => { - expect(maps.pathList).toEqual(['', '/foo', '/bar/', '/bar', '/bar-redirect/', '/bar-redirect', '*']) + expect(maps.pathList).toEqual([ + '', + '/foo', + '/bar/', + '/bar', + '/bar-redirect/', + '/bar-redirect', + '*' + ]) }) - it('has a nameMap object for default subroute at \'bar.baz\'', function () { + it("has a nameMap object for default subroute at 'bar.baz'", function () { expect(maps.nameMap['bar.baz']).not.toBeUndefined() }) @@ -68,7 +76,9 @@ describe('Creating Route Map', function () { process.env.NODE_ENV = 'development' maps = createRouteMap(routes) expect(console.warn).toHaveBeenCalledTimes(1) - expect(console.warn.calls.argsFor(0)[0]).toMatch('vue-router] Named Route \'bar\'') + expect(console.warn.calls.argsFor(0)[0]).toMatch( + "vue-router] Named Route 'bar'" + ) }) it('in development, throws if path is missing', function () { @@ -87,22 +97,63 @@ describe('Creating Route Map', function () { process.env.NODE_ENV = 'development' maps = createRouteMap([ { - path: '/foo/:id', component: Foo, - children: [ - { path: 'bar/:id', component: Bar } - ] + path: '/foo/:id', + component: Foo, + children: [{ path: 'bar/:id', component: Bar }] + } + ]) + expect(console.warn).toHaveBeenCalled() + expect(console.warn.calls.argsFor(0)[0]).toMatch( + 'vue-router] Duplicate param keys in route with path: "/foo/:id/bar/:id"' + ) + }) + + it('in development, warns about alias and path having the same value', () => { + process.env.NODE_ENV = 'development' + maps = createRouteMap([ + { + path: '/foo-alias', + component: Foo, + alias: '/foo-alias' + } + ]) + expect(console.warn).toHaveBeenCalled() + expect(console.warn.calls.argsFor(0)[0]).toMatch( + 'vue-router] Found an alias with the same value as the path: "/foo-alias"' + ) + }) + + it('in development, warns about one alias (in an array) having the same value as the path', () => { + process.env.NODE_ENV = 'development' + maps = createRouteMap([ + { + path: '/foo-alias', + component: Foo, + alias: ['/bar', '/foo-alias'] } ]) expect(console.warn).toHaveBeenCalled() - expect(console.warn.calls.argsFor(0)[0]).toMatch('vue-router] Duplicate param keys in route with path: "/foo/:id/bar/:id"') + expect(console.warn.calls.argsFor(0)[0]).toMatch( + 'vue-router] Found an alias with the same value as the path: "/foo-alias"' + ) }) describe('path-to-regexp options', function () { const routes = [ { path: '/foo', name: 'foo', component: Foo }, { path: '/bar', name: 'bar', component: Bar, caseSensitive: false }, - { path: '/FooBar', name: 'FooBar', component: FooBar, caseSensitive: true }, - { path: '/foobar', name: 'foobar', component: Foobar, caseSensitive: true } + { + path: '/FooBar', + name: 'FooBar', + component: FooBar, + caseSensitive: true + }, + { + path: '/foobar', + name: 'foobar', + component: Foobar, + caseSensitive: true + } ] it('caseSensitive option in route', function () { From d8499b61f70a5297049644002f5ea335441da094 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Tue, 16 Jul 2019 11:27:56 +0200 Subject: [PATCH 11/30] chore: fix release tagging --- scripts/release.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/release.sh b/scripts/release.sh index fb0f8d639..a413e097d 100644 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -10,10 +10,10 @@ then npm test # commit - npm version $VERSION --message "chore(release): %s" VERSION=$VERSION npm run build git add dist - git commit --amend --no-edit # merge with previous commit + git commit -m "build: bundle $VERSION" + npm version $VERSION --message "chore(release): %s" echo "Please check the git history and press enter" read OKAY From b7715dcfbfa081cb81daa90f4063e93e5047b169 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Tue, 16 Jul 2019 19:39:49 +0200 Subject: [PATCH 12/30] fix(hash): correctly place query if placed before hash (#2851) Fixes #2125 Closes #2262 --- src/history/hash.js | 81 ++++++++++++++++++++++--------------- test/e2e/specs/hash-mode.js | 12 ++++++ 2 files changed, 61 insertions(+), 32 deletions(-) diff --git a/src/history/hash.js b/src/history/hash.js index 16c94db0e..210fae6a2 100644 --- a/src/history/hash.js +++ b/src/history/hash.js @@ -28,38 +28,49 @@ export class HashHistory extends History { setupScroll() } - window.addEventListener(supportsPushState ? 'popstate' : 'hashchange', () => { - const current = this.current - if (!ensureSlash()) { - return - } - this.transitionTo(getHash(), route => { - if (supportsScroll) { - handleScroll(this.router, route, current, true) - } - if (!supportsPushState) { - replaceHash(route.fullPath) + window.addEventListener( + supportsPushState ? 'popstate' : 'hashchange', + () => { + const current = this.current + if (!ensureSlash()) { + return } - }) - }) + this.transitionTo(getHash(), route => { + if (supportsScroll) { + handleScroll(this.router, route, current, true) + } + if (!supportsPushState) { + replaceHash(route.fullPath) + } + }) + } + ) } push (location: RawLocation, onComplete?: Function, onAbort?: Function) { const { current: fromRoute } = this - this.transitionTo(location, route => { - pushHash(route.fullPath) - handleScroll(this.router, route, fromRoute, false) - onComplete && onComplete(route) - }, onAbort) + this.transitionTo( + location, + route => { + pushHash(route.fullPath) + handleScroll(this.router, route, fromRoute, false) + onComplete && onComplete(route) + }, + onAbort + ) } replace (location: RawLocation, onComplete?: Function, onAbort?: Function) { const { current: fromRoute } = this - this.transitionTo(location, route => { - replaceHash(route.fullPath) - handleScroll(this.router, route, fromRoute, false) - onComplete && onComplete(route) - }, onAbort) + this.transitionTo( + location, + route => { + replaceHash(route.fullPath) + handleScroll(this.router, route, fromRoute, false) + onComplete && onComplete(route) + }, + onAbort + ) } go (n: number) { @@ -81,9 +92,7 @@ export class HashHistory extends History { function checkFallback (base) { const location = getLocation(base) if (!/^\/#/.test(location)) { - window.location.replace( - cleanPath(base + '/#' + location) - ) + window.location.replace(cleanPath(base + '/#' + location)) return true } } @@ -112,10 +121,13 @@ export function getHash (): string { const searchIndex = href.indexOf('?') if (searchIndex < 0) { const hashIndex = href.indexOf('#') - if (hashIndex > -1) href = decodeURI(href.slice(0, hashIndex)) + href.slice(hashIndex) - else href = decodeURI(href) + if (hashIndex > -1) { + href = decodeURI(href.slice(0, hashIndex)) + href.slice(hashIndex) + } else href = decodeURI(href) } else { - if (searchIndex > -1) href = decodeURI(href.slice(0, searchIndex)) + href.slice(searchIndex) + if (searchIndex > -1) { + href = decodeURI(href.slice(0, searchIndex)) + href.slice(searchIndex) + } } return href @@ -123,9 +135,14 @@ export function getHash (): string { function getUrl (path) { const href = window.location.href - const i = href.indexOf('#') - const base = i >= 0 ? href.slice(0, i) : href - return `${base}#${path}` + const hashPos = href.indexOf('#') + let base = hashPos > -1 ? href.slice(0, hashPos) : href + + const searchPos = base.indexOf('?') + const query = searchPos > -1 ? base.slice(searchPos) : '' + base = query ? base.slice(0, searchPos) : base + + return `${base}#${path + query}` } function pushHash (path) { diff --git a/test/e2e/specs/hash-mode.js b/test/e2e/specs/hash-mode.js index be5df7d14..6ca546214 100644 --- a/test/e2e/specs/hash-mode.js +++ b/test/e2e/specs/hash-mode.js @@ -57,6 +57,18 @@ module.exports = { .waitForElementVisible('#app', 1000) .assert.containsText('.view', 'unicode: ñ') .assert.containsText('#query-t', '%') + + // correctly placing query + // https://github.com/vuejs/vue-router/issues/2125 + .url('http://localhost:8080/hash-mode/?key=foo') + .waitForElementVisible('#app', 1000) + .assert.urlEquals('http://localhost:8080/hash-mode/#/?key=foo') + .url('http://localhost:8080/hash-mode?key=foo') + .waitForElementVisible('#app', 1000) + .assert.urlEquals('http://localhost:8080/hash-mode/#/?key=foo') + .url('http://localhost:8080/hash-mode?key=foo#other') + .waitForElementVisible('#app', 1000) + .assert.urlEquals('http://localhost:8080/hash-mode/#/other?key=foo') .end() } } From aeb09c392fb303c10c1a5414dab03e6d52ba3f25 Mon Sep 17 00:00:00 2001 From: Darryl Hein Date: Thu, 18 Jul 2019 00:47:43 -0600 Subject: [PATCH 13/30] docs: adding periods (#2855) --- docs/guide/essentials/named-views.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guide/essentials/named-views.md b/docs/guide/essentials/named-views.md index c848b08aa..d426ead04 100644 --- a/docs/guide/essentials/named-views.md +++ b/docs/guide/essentials/named-views.md @@ -48,7 +48,7 @@ It is possible to create complex layouts using named views with nested views. Wh - `UserSettings` is the view component - `UserEmailsSubscriptions`, `UserProfile`, `UserProfilePreview` are nested view components -**Note**: _Let's forget about how the HTML/CSS should look like to represent such layout and focus on the components used_ +**Note**: _Let's forget about how the HTML/CSS should look like to represent such layout and focus on the components used._ The `