diff --git a/dist/example/example.js b/dist/example/example.js index 3e43172..fc58c5a 100644 --- a/dist/example/example.js +++ b/dist/example/example.js @@ -95,7 +95,6 @@ /** * a very simple router for the **demo** of [weui](https://github.com/weui/weui) */ - var Router = function () { /** @@ -105,7 +104,6 @@ // array of route config - function Router(options) { _classCallCheck(this, Router); @@ -147,7 +145,10 @@ // why not `history.pushState`? see https://github.com/weui/weui/issues/26, Router in wechat webview window.addEventListener('hashchange', function (event) { + var old_hash = util.getHash(event.oldURL); var hash = util.getHash(event.newURL); + // fix '/' repeat see https://github.com/progrape/router/issues/21 + if (old_hash === hash) return; var state = history.state || {}; _this.go(hash, state._index <= _this._index); @@ -175,6 +176,14 @@ }, { key: 'push', value: function push(route) { + + var exist = this._routes.filter(function (r) { + return r.url === route.url; + })[0]; + if (exist) { + throw new Error('route ' + route.url + ' is existed'); + } + route = _extends({}, { url: '*', className: '', @@ -414,7 +423,7 @@ // "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?", undefined] // "/route(\\d+)" => [undefined, undefined, undefined, "\d+", undefined, undefined] // "/*" => ["/", undefined, undefined, undefined, undefined, "*"] - '([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^()])+)\\))?|\\(((?:\\\\.|[^()])+)\\))([+*?])?|(\\*))' + '([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))' ].join('|'), 'g') /** @@ -451,18 +460,13 @@ var modifier = res[6] var asterisk = res[7] - // Only use the prefix when followed by another path segment. - if (prefix != null && next != null && next !== prefix) { - path += prefix - prefix = null - } - // Push the current path onto the tokens. if (path) { tokens.push(path) path = '' } + var partial = prefix != null && next != null && next !== prefix var repeat = modifier === '+' || modifier === '*' var optional = modifier === '?' || modifier === '*' var delimiter = res[2] || '/' @@ -474,6 +478,8 @@ delimiter: delimiter, optional: optional, repeat: repeat, + partial: partial, + asterisk: !!asterisk, pattern: escapeGroup(pattern) }) } @@ -502,13 +508,25 @@ } /** - * Encode characters for segment that could cause trouble for parsing. + * Prettier encoding of URI path segments. * * @param {string} * @return {string} */ function encodeURIComponentPretty (str) { - return encodeURI(str).replace(/[/?#'"]/g, function (c) { + return encodeURI(str).replace(/[\/?#]/g, function (c) { + return '%' + c.charCodeAt(0).toString(16).toUpperCase() + }) + } + + /** + * Encode the asterisk parameter. Similar to `pretty`, but allows slashes. + * + * @param {string} + * @return {string} + */ + function encodeAsterisk (str) { + return encodeURI(str).replace(/[?#]/g, function (c) { return '%' + c.charCodeAt(0).toString(16).toUpperCase() }) } @@ -523,7 +541,7 @@ // Compile all the patterns before compilation. for (var i = 0; i < tokens.length; i++) { if (typeof tokens[i] === 'object') { - matches[i] = new RegExp('^' + tokens[i].pattern + '$') + matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$') } } @@ -547,6 +565,11 @@ if (value == null) { if (token.optional) { + // Prepend partial segment prefixes. + if (token.partial) { + path += token.prefix + } + continue } else { throw new TypeError('Expected "' + token.name + '" to be defined') @@ -555,7 +578,7 @@ if (isarray(value)) { if (!token.repeat) { - throw new TypeError('Expected "' + token.name + '" to not repeat, but received "' + value + '"') + throw new TypeError('Expected "' + token.name + '" to not repeat, but received `' + JSON.stringify(value) + '`') } if (value.length === 0) { @@ -570,7 +593,7 @@ segment = encode(value[j]) if (!matches[i].test(segment)) { - throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"') + throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received `' + JSON.stringify(segment) + '`') } path += (j === 0 ? token.prefix : token.delimiter) + segment @@ -579,7 +602,7 @@ continue } - segment = encode(value) + segment = token.asterisk ? encodeAsterisk(value) : encode(value) if (!matches[i].test(segment)) { throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"') @@ -599,7 +622,7 @@ * @return {string} */ function escapeString (str) { - return str.replace(/([.+*?=^!:${}()[\]|\/])/g, '\\$1') + return str.replace(/([.+*?=^!:${}()[\]|\/\\])/g, '\\$1') } /** @@ -653,6 +676,8 @@ delimiter: null, optional: false, repeat: false, + partial: false, + asterisk: false, pattern: null }) } @@ -727,17 +752,17 @@ route += escapeString(token) } else { var prefix = escapeString(token.prefix) - var capture = token.pattern + var capture = '(?:' + token.pattern + ')' if (token.repeat) { capture += '(?:' + prefix + capture + ')*' } if (token.optional) { - if (prefix) { + if (!token.partial) { capture = '(?:' + prefix + '(' + capture + '))?' } else { - capture = '(' + capture + ')?' + capture = prefix + '(' + capture + ')?' } } else { capture = prefix + '(' + capture + ')' @@ -853,308 +878,308 @@ /* 7 */ /***/ function(module, exports) { - /* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra - */ - // css base code, injected by the css-loader - module.exports = function() { - var list = []; - - // return the list of modules as css string - list.toString = function toString() { - var result = []; - for(var i = 0; i < this.length; i++) { - var item = this[i]; - if(item[2]) { - result.push("@media " + item[2] + "{" + item[1] + "}"); - } else { - result.push(item[1]); - } - } - return result.join(""); - }; - - // import a list of modules into the list - list.i = function(modules, mediaQuery) { - if(typeof modules === "string") - modules = [[null, modules, ""]]; - var alreadyImportedModules = {}; - for(var i = 0; i < this.length; i++) { - var id = this[i][0]; - if(typeof id === "number") - alreadyImportedModules[id] = true; - } - for(i = 0; i < modules.length; i++) { - var item = modules[i]; - // skip already imported module - // this implementation is not 100% perfect for weird media query combinations - // when a module is imported multiple times with different media queries. - // I hope this will never occur (Hey this way we have smaller bundles) - if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) { - if(mediaQuery && !item[2]) { - item[2] = mediaQuery; - } else if(mediaQuery) { - item[2] = "(" + item[2] + ") and (" + mediaQuery + ")"; - } - list.push(item); - } - } - }; - return list; - }; + /* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra + */ + // css base code, injected by the css-loader + module.exports = function() { + var list = []; + + // return the list of modules as css string + list.toString = function toString() { + var result = []; + for(var i = 0; i < this.length; i++) { + var item = this[i]; + if(item[2]) { + result.push("@media " + item[2] + "{" + item[1] + "}"); + } else { + result.push(item[1]); + } + } + return result.join(""); + }; + + // import a list of modules into the list + list.i = function(modules, mediaQuery) { + if(typeof modules === "string") + modules = [[null, modules, ""]]; + var alreadyImportedModules = {}; + for(var i = 0; i < this.length; i++) { + var id = this[i][0]; + if(typeof id === "number") + alreadyImportedModules[id] = true; + } + for(i = 0; i < modules.length; i++) { + var item = modules[i]; + // skip already imported module + // this implementation is not 100% perfect for weird media query combinations + // when a module is imported multiple times with different media queries. + // I hope this will never occur (Hey this way we have smaller bundles) + if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) { + if(mediaQuery && !item[2]) { + item[2] = mediaQuery; + } else if(mediaQuery) { + item[2] = "(" + item[2] + ") and (" + mediaQuery + ")"; + } + list.push(item); + } + } + }; + return list; + }; /***/ }, /* 8 */ /***/ function(module, exports, __webpack_require__) { - /* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra - */ - var stylesInDom = {}, - memoize = function(fn) { - var memo; - return function () { - if (typeof memo === "undefined") memo = fn.apply(this, arguments); - return memo; - }; - }, - isOldIE = memoize(function() { - return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase()); - }), - getHeadElement = memoize(function () { - return document.head || document.getElementsByTagName("head")[0]; - }), - singletonElement = null, - singletonCounter = 0, - styleElementsInsertedAtTop = []; - - module.exports = function(list, options) { - if(false) { - if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment"); - } - - options = options || {}; - // Force single-tag solution on IE6-9, which has a hard limit on the # of