preact-router
Advanced tools
Comparing version 1.4.0 to 2.0.0-beta1
@@ -9,2 +9,40 @@ (function (global, factory) { | ||
babelHelpers.classCallCheck = function (instance, Constructor) { | ||
if (!(instance instanceof Constructor)) { | ||
throw new TypeError("Cannot call a class as a function"); | ||
} | ||
}; | ||
babelHelpers.createClass = function () { | ||
function defineProperties(target, props) { | ||
for (var i = 0; i < props.length; i++) { | ||
var descriptor = props[i]; | ||
descriptor.enumerable = descriptor.enumerable || false; | ||
descriptor.configurable = true; | ||
if ("value" in descriptor) descriptor.writable = true; | ||
Object.defineProperty(target, descriptor.key, descriptor); | ||
} | ||
} | ||
return function (Constructor, protoProps, staticProps) { | ||
if (protoProps) defineProperties(Constructor.prototype, protoProps); | ||
if (staticProps) defineProperties(Constructor, staticProps); | ||
return Constructor; | ||
}; | ||
}(); | ||
babelHelpers.extends = Object.assign || function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
}; | ||
babelHelpers.inherits = function (subClass, superClass) { | ||
@@ -38,21 +76,12 @@ if (typeof superClass !== "function" && superClass !== null) { | ||
babelHelpers._extends = Object.assign || function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
babelHelpers.possibleConstructorReturn = function (self, call) { | ||
if (!self) { | ||
throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); | ||
} | ||
return target; | ||
return call && (typeof call === "object" || typeof call === "function") ? call : self; | ||
}; | ||
babelHelpers.classCallCheck = function (instance, Constructor) { | ||
if (!(instance instanceof Constructor)) { | ||
throw new TypeError("Cannot call a class as a function"); | ||
} | ||
}; | ||
babelHelpers; | ||
var EMPTY$1 = {}; | ||
@@ -66,3 +95,3 @@ | ||
matches = {}, | ||
ret = undefined; | ||
ret = void 0; | ||
if (c && c[1]) { | ||
@@ -78,9 +107,9 @@ var p = c[1].split('&'); | ||
var max = Math.max(url.length, route.length); | ||
for (var i = 0; i < max; i++) { | ||
if (route[i] && route[i].charAt(0) === ':') { | ||
var param = route[i].replace(/(^\:|[+*?]+$)/g, ''), | ||
flags = (route[i].match(/[+*?]+$/) || EMPTY$1)[0] || '', | ||
for (var _i = 0; _i < max; _i++) { | ||
if (route[_i] && route[_i].charAt(0) === ':') { | ||
var param = route[_i].replace(/(^\:|[+*?]+$)/g, ''), | ||
flags = (route[_i].match(/[+*?]+$/) || EMPTY$1)[0] || '', | ||
plus = ~flags.indexOf('+'), | ||
star = ~flags.indexOf('*'), | ||
val = url[i] || ''; | ||
val = url[_i] || ''; | ||
if (!val && !star && (flags.indexOf('?') < 0 || plus)) { | ||
@@ -92,13 +121,11 @@ ret = false; | ||
if (plus || star) { | ||
matches[param] = url.slice(i).map(decodeURIComponent).join('/'); | ||
matches[param] = url.slice(_i).map(decodeURIComponent).join('/'); | ||
break; | ||
} | ||
} else { | ||
if (route[i] !== url[i]) { | ||
ret = false; | ||
break; | ||
} | ||
} else if (route[_i] !== url[_i]) { | ||
ret = false; | ||
break; | ||
} | ||
} | ||
if (opts['default'] !== true && ret === false) return false; | ||
if (opts.default !== true && ret === false) return false; | ||
return matches; | ||
@@ -110,4 +137,4 @@ } | ||
bAttr = b.attributes || EMPTY$1; | ||
if (aAttr['default']) return 1; | ||
if (bAttr['default']) return -1; | ||
if (aAttr.default) return 1; | ||
if (bAttr.default) return -1; | ||
var diff = rank(aAttr.path) - rank(bAttr.path); | ||
@@ -129,6 +156,8 @@ return diff || aAttr.path.length - bAttr.path.length; | ||
var routers = []; | ||
var ROUTERS = []; | ||
var EMPTY = {}; | ||
var DOM = typeof document !== 'undefined'; | ||
function route(url) { | ||
@@ -141,3 +170,3 @@ var replace = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; | ||
} | ||
if (history) { | ||
if (DOM && typeof history !== 'undefined') { | ||
if (replace === true) { | ||
@@ -149,9 +178,13 @@ history.replaceState(null, null, url); | ||
} | ||
routeTo(url); | ||
return routeTo(url); | ||
} | ||
function routeTo(url) { | ||
routers.forEach(function (router) { | ||
return router.routeTo(url); | ||
var didRoute = false; | ||
ROUTERS.forEach(function (router) { | ||
if (router.routeTo(url) === true) { | ||
didRoute = true; | ||
} | ||
}); | ||
return didRoute; | ||
} | ||
@@ -164,22 +197,36 @@ | ||
if (typeof addEventListener === 'function') { | ||
function handleLinkClick(e, target) { | ||
target = target || e && (e.currentTarget || e.target) || this; | ||
if (!target) return; | ||
if (route(target.getAttribute('href')) === true) { | ||
if (e.stopImmediatePropagation) e.stopImmediatePropagation(); | ||
e.stopPropagation(); | ||
e.preventDefault(); | ||
return false; | ||
} | ||
} | ||
function linkHandler(e) { | ||
var t = e.target; | ||
do { | ||
var href = String(t.nodeName).toUpperCase() === 'A' && t.getAttribute('href'); | ||
if (href && href.match(/^\//g)) { | ||
return handleLinkClick(e, t); | ||
} | ||
} while (t = t.parentNode); | ||
} | ||
if (DOM) { | ||
addEventListener('popstate', function () { | ||
return routeTo(getCurrentUrl()); | ||
}); | ||
document.body.addEventListener('click', linkHandler); | ||
} | ||
function handleLinkClick(e) { | ||
route(this.getAttribute('href')); | ||
if (e.stopImmediatePropagation) e.stopImmediatePropagation(); | ||
e.stopPropagation(); | ||
e.preventDefault(); | ||
return false; | ||
} | ||
var Link = function Link(_ref) { | ||
var children = _ref.children; | ||
var props = babelHelpers.objectWithoutProperties(_ref, ['children']); | ||
return preact.h( | ||
return React.createElement( | ||
'a', | ||
babelHelpers._extends({}, props, { onClick: handleLinkClick }), | ||
babelHelpers.extends({}, props, { onClick: handleLinkClick }), | ||
children | ||
@@ -189,66 +236,86 @@ ); | ||
var Router = (function (_Component) { | ||
var Router = function (_Component) { | ||
babelHelpers.inherits(Router, _Component); | ||
function Router(props) { | ||
babelHelpers.classCallCheck(this, Router); | ||
function Router() { | ||
var _Object$getPrototypeO; | ||
_Component.call(this); | ||
this.state = { | ||
url: props.url || getCurrentUrl() | ||
}; | ||
} | ||
var _temp, _this, _ret; | ||
Router.prototype.routeTo = function routeTo(url) { | ||
this.setState({ url: url }); | ||
}; | ||
babelHelpers.classCallCheck(this, Router); | ||
Router.prototype.componentWillMount = function componentWillMount() { | ||
routers.push(this); | ||
}; | ||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
Router.prototype.componentWillUnmount = function componentWillUnmount() { | ||
routers.splice(routers.indexOf(this), 1); | ||
}; | ||
return _ret = (_temp = (_this = babelHelpers.possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(Router)).call.apply(_Object$getPrototypeO, [this].concat(args))), _this), _this.state = { | ||
url: _this.props.url || getCurrentUrl() | ||
}, _temp), babelHelpers.possibleConstructorReturn(_this, _ret); | ||
} | ||
Router.prototype.render = function render(_ref2, _ref3) { | ||
var children = _ref2.children; | ||
var onChange = _ref2.onChange; | ||
var url = _ref3.url; | ||
babelHelpers.createClass(Router, [{ | ||
key: 'routeTo', | ||
value: function routeTo(url) { | ||
this._didRoute = false; | ||
this.setState({ url: url }); | ||
this.forceUpdate(); | ||
return this._didRoute; | ||
} | ||
}, { | ||
key: 'componentWillMount', | ||
value: function componentWillMount() { | ||
ROUTERS.push(this); | ||
} | ||
}, { | ||
key: 'componentWillUnmount', | ||
value: function componentWillUnmount() { | ||
ROUTERS.splice(ROUTERS.indexOf(this), 1); | ||
} | ||
}, { | ||
key: 'render', | ||
value: function render(_ref2, _ref3) { | ||
var children = _ref2.children; | ||
var onChange = _ref2.onChange; | ||
var url = _ref3.url; | ||
var active = children.slice().sort(pathRankSort).filter(function (_ref4) { | ||
var attributes = _ref4.attributes; | ||
var active = children.slice().sort(pathRankSort).filter(function (_ref4) { | ||
var attributes = _ref4.attributes; | ||
var path = attributes.path, | ||
matches = exec(url, path, attributes); | ||
if (matches) { | ||
attributes.url = url; | ||
attributes.matches = matches; | ||
// copy matches onto props | ||
for (var i in matches) { | ||
if (matches.hasOwnProperty(i)) { | ||
attributes[i] = matches[i]; | ||
var path = attributes.path, | ||
matches = exec(url, path, attributes); | ||
if (matches) { | ||
attributes.url = url; | ||
attributes.matches = matches; | ||
// copy matches onto props | ||
for (var i in matches) { | ||
if (matches.hasOwnProperty(i)) { | ||
attributes[i] = matches[i]; | ||
} | ||
} | ||
return true; | ||
} | ||
return true; | ||
}); | ||
var current = active[0] || null; | ||
this._didRoute = !!current; | ||
var previous = this.previousUrl; | ||
if (url !== previous) { | ||
this.previousUrl = url; | ||
if (typeof onChange === 'function') { | ||
onChange({ | ||
router: this, | ||
url: url, | ||
previous: previous, | ||
active: active, | ||
current: current | ||
}); | ||
} | ||
} | ||
}); | ||
var previous = this.previousUrl; | ||
if (url !== previous) { | ||
this.previousUrl = url; | ||
if (typeof onChange === 'function') { | ||
onChange({ | ||
router: this, | ||
url: url, | ||
previous: previous, | ||
active: active, | ||
current: active[0] | ||
}); | ||
} | ||
return current; | ||
} | ||
return active[0] || null; | ||
}; | ||
}]); | ||
return Router; | ||
})(preact.Component); | ||
}(preact.Component); | ||
@@ -259,3 +326,3 @@ var Route = function Route(_ref5) { | ||
var matches = _ref5.matches; | ||
return preact.h(RoutedComponent, { url: url, matches: matches }); | ||
return React.createElement(RoutedComponent, { url: url, matches: matches }); | ||
}; | ||
@@ -262,0 +329,0 @@ |
@@ -1,2 +0,2 @@ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("preact")):"function"==typeof define&&define.amd?define(["preact"],e):t.preactRouter=e(t.preact)}(this,function(t){"use strict";function e(t,e){var n=arguments.length<=2||void 0===arguments[2]?l:arguments[2],o=/(?:\?([^#]*))?(#.*)?$/,i=t.match(o),u={},a=void 0;if(i&&i[1])for(var c=i[1].split("&"),p=0;p<c.length;p++){var f=c[p].split("=");u[decodeURIComponent(f[0])]=decodeURIComponent(f.slice(1).join("="))}t=r(t.replace(o,"")),e=r(e||"");for(var s=Math.max(t.length,e.length),p=0;s>p;p++)if(e[p]&&":"===e[p].charAt(0)){var h=e[p].replace(/(^\:|[+*?]+$)/g,""),d=(e[p].match(/[+*?]+$/)||l)[0]||"",m=~d.indexOf("+"),v=~d.indexOf("*"),g=t[p]||"";if(!g&&!v&&(d.indexOf("?")<0||m)){a=!1;break}if(u[h]=decodeURIComponent(g),m||v){u[h]=t.slice(p).map(decodeURIComponent).join("/");break}}else if(e[p]!==t[p]){a=!1;break}return n["default"]!==!0&&a===!1?!1:u}function n(t,e){var n=t.attributes||l,r=e.attributes||l;if(n["default"])return 1;if(r["default"])return-1;var i=o(n.path)-o(r.path);return i||n.path.length-r.path.length}function r(t){return i(t).split("/")}function o(t){return(i(t).match(/\/+/g)||"").length}function i(t){return t.replace(/(^\/+|\/+$)/g,"")}function u(t){var e=arguments.length<=1||void 0===arguments[1]?!1:arguments[1];"string"!=typeof t&&t.url&&(e=t.replace,t=t.url),history&&(e===!0?history.replaceState(null,null,t):history.pushState(null,null,t)),a(t)}function a(t){s.forEach(function(e){return e.routeTo(t)})}function c(){var t="undefined"!=typeof location?location:h;return""+(t.pathname||"")+(t.search||"")}function p(t){return u(this.getAttribute("href")),t.stopImmediatePropagation&&t.stopImmediatePropagation(),t.stopPropagation(),t.preventDefault(),!1}var f={};f.inherits=function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)},f.objectWithoutProperties=function(t,e){var n={};for(var r in t)e.indexOf(r)>=0||Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n},f._extends=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(t[r]=n[r])}return t},f.a=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")};var l={},s=[],h={};"function"==typeof addEventListener&&addEventListener("popstate",function(){return a(c())});var d=function(e){var n=e.children,r=f.objectWithoutProperties(e,["children"]);return t.h("a",f._extends({},r,{onClick:p}),n)},m=function(t){function r(e){f.a(this,r),t.call(this),this.state={url:e.url||c()}}return f.inherits(r,t),r.prototype.routeTo=function(t){this.setState({url:t})},r.prototype.componentWillMount=function(){s.push(this)},r.prototype.componentWillUnmount=function(){s.splice(s.indexOf(this),1)},r.prototype.render=function(t,r){var o=t.children,i=t.onChange,u=r.url,a=o.slice().sort(n).filter(function(t){var n=t.attributes,r=n.path,o=e(u,r,n);if(o){n.url=u,n.matches=o;for(var i in o)o.hasOwnProperty(i)&&(n[i]=o[i]);return!0}}),c=this.previousUrl;return u!==c&&(this.previousUrl=u,"function"==typeof i&&i({router:this,url:u,previous:c,active:a,current:a[0]})),a[0]||null},r}(t.Component),v=function(e){var n=e.component,r=e.url,o=e.matches;return t.h(n,{url:r,matches:o})};return m.route=u,m.Router=m,m.Route=v,m.Link=d,m}); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("preact")):"function"==typeof define&&define.amd?define(["preact"],t):e.preactRouter=t(e.preact)}(this,function(e){"use strict";function t(e,t){var r=arguments.length<=2||void 0===arguments[2]?p:arguments[2],o=/(?:\?([^#]*))?(#.*)?$/,i=e.match(o),a={},u=void 0;if(i&&i[1])for(var c=i[1].split("&"),l=0;l<c.length;l++){var f=c[l].split("=");a[decodeURIComponent(f[0])]=decodeURIComponent(f.slice(1).join("="))}e=n(e.replace(o,"")),t=n(t||"");for(var s=Math.max(e.length,t.length),h=0;s>h;h++)if(t[h]&&":"===t[h].charAt(0)){var d=t[h].replace(/(^\:|[+*?]+$)/g,""),v=(t[h].match(/[+*?]+$/)||p)[0]||"",y=~v.indexOf("+"),m=~v.indexOf("*"),b=e[h]||"";if(!b&&!m&&(v.indexOf("?")<0||y)){u=!1;break}if(a[d]=decodeURIComponent(b),y||m){a[d]=e.slice(h).map(decodeURIComponent).join("/");break}}else if(t[h]!==e[h]){u=!1;break}return r["default"]!==!0&&u===!1?!1:a}function r(e,t){var r=e.attributes||p,n=t.attributes||p;if(r["default"])return 1;if(n["default"])return-1;var i=o(r.path)-o(n.path);return i||r.path.length-n.path.length}function n(e){return i(e).split("/")}function o(e){return(i(e).match(/\/+/g)||"").length}function i(e){return e.replace(/(^\/+|\/+$)/g,"")}function a(e){var t=arguments.length<=1||void 0===arguments[1]?!1:arguments[1];return"string"!=typeof e&&e.url&&(t=e.replace,e=e.url),v&&"undefined"!=typeof history&&(t===!0?history.replaceState(null,null,e):history.pushState(null,null,e)),u(e)}function u(e){var t=!1;return h.forEach(function(r){r.routeTo(e)===!0&&(t=!0)}),t}function c(){var e="undefined"!=typeof location?location:d;return""+(e.pathname||"")+(e.search||"")}function l(e,t){return(t=t||e&&(e.currentTarget||e.target)||this)&&a(t.getAttribute("href"))===!0?(e.stopImmediatePropagation&&e.stopImmediatePropagation(),e.stopPropagation(),e.preventDefault(),!1):void 0}function f(e){var t=e.target;do{var r="A"===String(t.nodeName).toUpperCase()&&t.getAttribute("href");if(r&&r.match(/^\//g))return l(e,t)}while(t=t.parentNode)}var s={};s.a=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},s.createClass=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),s["extends"]=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},s.inherits=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)},s.objectWithoutProperties=function(e,t){var r={};for(var n in e)t.indexOf(n)>=0||Object.prototype.hasOwnProperty.call(e,n)&&(r[n]=e[n]);return r},s.possibleConstructorReturn=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t};var p={},h=[],d={},v="undefined"!=typeof document;v&&(addEventListener("popstate",function(){return u(c())}),document.body.addEventListener("click",f));var y=function(e){var t=e.children,r=s.objectWithoutProperties(e,["children"]);return React.createElement("a",s["extends"]({},r,{onClick:l}),t)},m=function(e){function n(){var e,t,r,o;s.a(this,n);for(var i=arguments.length,a=Array(i),u=0;i>u;u++)a[u]=arguments[u];return t=r=s.possibleConstructorReturn(this,(e=Object.getPrototypeOf(n)).call.apply(e,[this].concat(a))),r.state={url:r.props.url||c()},o=t,s.possibleConstructorReturn(r,o)}return s.inherits(n,e),s.createClass(n,[{key:"routeTo",value:function(e){return this._didRoute=!1,this.setState({url:e}),this.forceUpdate(),this._didRoute}},{key:"componentWillMount",value:function(){h.push(this)}},{key:"componentWillUnmount",value:function(){h.splice(h.indexOf(this),1)}},{key:"render",value:function(e,n){var o=e.children,i=e.onChange,a=n.url,u=o.slice().sort(r).filter(function(e){var r=e.attributes,n=r.path,o=t(a,n,r);if(o){r.url=a,r.matches=o;for(var i in o)o.hasOwnProperty(i)&&(r[i]=o[i]);return!0}}),c=u[0]||null;this._didRoute=!!c;var l=this.previousUrl;return a!==l&&(this.previousUrl=a,"function"==typeof i&&i({router:this,url:a,previous:l,active:u,current:c})),c}}]),n}(e.Component),b=function(e){var t=e.component,r=e.url,n=e.matches;return React.createElement(t,{url:r,matches:n})};return m.route=a,m.Router=m,m.Route=b,m.Link=y,m}); | ||
//# sourceMappingURL=preact-router.min.js.map |
{ | ||
"name": "preact-router", | ||
"amdName": "preactRouter", | ||
"version": "1.4.0", | ||
"version": "2.0.0-beta1", | ||
"description": "Connect your components up to that address bar.", | ||
@@ -15,3 +15,3 @@ "main": "dist/preact-router.js", | ||
"size": "size=$(gzip-size $npm_package_minified_main) && echo \"gzip size: $size / $(pretty-bytes $size)\"", | ||
"test": "eslint {src,test} && mocha --compilers js:babel/register test/**/*.js", | ||
"test": "eslint {src,test} && mocha --compilers js:babel-register test/**/*.js", | ||
"prepublish": "npm run build", | ||
@@ -38,16 +38,23 @@ "release": "npm run build && git commit -am $npm_package_version && git tag $npm_package_version && git push && git push --tags && npm publish" | ||
"devDependencies": { | ||
"babel": "^5.8.23", | ||
"babel-eslint": "^6.0.0", | ||
"babel-cli": "^6.9.0", | ||
"babel-eslint": "^6.0.4", | ||
"babel-preset-es2015": "^6.9.0", | ||
"babel-preset-es2015-rollup": "^1.1.1", | ||
"babel-preset-react": "^6.5.0", | ||
"babel-preset-stage-0": "^6.5.0", | ||
"babel-register": "^6.9.0", | ||
"chai": "^3.5.0", | ||
"eslint": "^2.2.0", | ||
"eslint": "^2.11.1", | ||
"eslint-plugin-react": "^5.1.1", | ||
"gzip-size-cli": "^1.0.0", | ||
"mkdirp": "^0.5.1", | ||
"mocha": "^2.4.5", | ||
"npm-run-all": "^1.5.1", | ||
"preact": "^4.1.1", | ||
"mocha": "^2.5.0", | ||
"npm-run-all": "^2.0.0", | ||
"preact": "^4.8.0", | ||
"pretty-bytes-cli": "^1.0.0", | ||
"rimraf": "^2.5.1", | ||
"rollup": "^0.25.2", | ||
"rollup-plugin-babel": "^1.0.0", | ||
"sinon": "^1.17.3", | ||
"rollup": "^0.26.0", | ||
"rollup-plugin-babel": "^2.4.0", | ||
"rollup-plugin-memory": "^1.0.0", | ||
"sinon": "^1.17.4", | ||
"sinon-chai": "^2.8.0", | ||
@@ -54,0 +61,0 @@ "uglify-js": "^2.6.1" |
import babel from 'rollup-plugin-babel'; | ||
import memory from 'rollup-plugin-memory'; | ||
export default { | ||
exports: 'default', | ||
plugins: [ | ||
memory({ | ||
path: 'src/index', | ||
contents: "export { default } from './index';" | ||
}), | ||
babel({ | ||
sourceMap: true, | ||
babelrc: false, | ||
presets: ['es2015-rollup', 'stage-0', 'react'], | ||
exclude: 'node_modules/**' | ||
@@ -8,0 +15,0 @@ }) |
import { h, Component } from 'preact'; | ||
import { exec, pathRankSort } from './util'; | ||
const routers = []; | ||
const ROUTERS = []; | ||
const EMPTY = {}; | ||
const DOM = typeof document!=='undefined'; | ||
function route(url, replace=false) { | ||
@@ -13,3 +16,3 @@ if (typeof url!=='string' && url.url) { | ||
} | ||
if (history) { | ||
if (DOM && typeof history!=='undefined') { | ||
if (replace===true) { | ||
@@ -22,9 +25,17 @@ history.replaceState(null, null, url); | ||
} | ||
routeTo(url); | ||
return routeTo(url); | ||
} | ||
function routeTo(url) { | ||
routers.forEach( router => router.routeTo(url) ); | ||
let didRoute = false; | ||
ROUTERS.forEach( router => { | ||
if (router.routeTo(url)===true) { | ||
didRoute = true; | ||
} | ||
}); | ||
return didRoute; | ||
} | ||
function getCurrentUrl() { | ||
@@ -35,18 +46,34 @@ let url = typeof location!=='undefined' ? location : EMPTY; | ||
if (typeof addEventListener==='function') { | ||
addEventListener('popstate', () => routeTo(getCurrentUrl())); | ||
function handleLinkClick(e, target) { | ||
target = target || (e && (e.currentTarget || e.target)) || this; | ||
if (!target) return; | ||
if (route(target.getAttribute('href'))===true) { | ||
if (e.stopImmediatePropagation) e.stopImmediatePropagation(); | ||
e.stopPropagation(); | ||
e.preventDefault(); | ||
return false; | ||
} | ||
} | ||
function handleLinkClick(e) { | ||
route(this.getAttribute('href')); | ||
if (e.stopImmediatePropagation) e.stopImmediatePropagation(); | ||
e.stopPropagation(); | ||
e.preventDefault(); | ||
return false; | ||
function linkHandler(e) { | ||
let t = e.target; | ||
do { | ||
let href = String(t.nodeName).toUpperCase()==='A' && t.getAttribute('href'); | ||
if (href && href.match(/^\//g)) { | ||
return handleLinkClick(e, t); | ||
} | ||
} while ((t=t.parentNode)); | ||
} | ||
if (DOM) { | ||
addEventListener('popstate', () => routeTo(getCurrentUrl())); | ||
document.body.addEventListener('click', linkHandler); | ||
} | ||
const Link = ({ children, ...props }) => ( | ||
<a {...props} onClick={ handleLinkClick }>{ children }</a> | ||
<a {...props} onClick={handleLinkClick}>{ children }</a> | ||
); | ||
@@ -56,19 +83,19 @@ | ||
class Router extends Component { | ||
constructor(props) { | ||
super(); | ||
this.state = { | ||
url: props.url || getCurrentUrl() | ||
}; | ||
} | ||
state = { | ||
url: this.props.url || getCurrentUrl() | ||
}; | ||
routeTo(url) { | ||
this._didRoute = false; | ||
this.setState({ url }); | ||
this.forceUpdate(); | ||
return this._didRoute; | ||
} | ||
componentWillMount() { | ||
routers.push(this); | ||
ROUTERS.push(this); | ||
} | ||
componentWillUnmount() { | ||
routers.splice(routers.indexOf(this), 1); | ||
ROUTERS.splice(ROUTERS.indexOf(this), 1); | ||
} | ||
@@ -92,2 +119,6 @@ | ||
}); | ||
let current = active[0] || null; | ||
this._didRoute = !!current; | ||
let previous = this.previousUrl; | ||
@@ -102,7 +133,8 @@ if (url!==previous) { | ||
active, | ||
current: active[0] | ||
current | ||
}); | ||
} | ||
} | ||
return active[0] || null; | ||
return current; | ||
} | ||
@@ -122,2 +154,3 @@ } | ||
export { route, Router, Route, Link }; | ||
export default Router; |
@@ -36,7 +36,5 @@ | ||
} | ||
else { | ||
if (route[i]!==url[i]) { | ||
ret = false; | ||
break; | ||
} | ||
else if (route[i]!==url[i]) { | ||
ret = false; | ||
break; | ||
} | ||
@@ -43,0 +41,0 @@ } |
@@ -1,4 +0,5 @@ | ||
import { Router, Link, route } from '../'; | ||
import { h, Component } from 'preact'; | ||
import { h } from 'preact'; | ||
import { expect } from 'chai'; | ||
const router = require('../'); // eslint-disable-line | ||
const { Router, Link, route } = router; | ||
/** @jsx h */ | ||
@@ -11,2 +12,3 @@ | ||
expect(route).to.be.a('function'); | ||
expect(router).to.equal(Router); | ||
}); | ||
@@ -16,3 +18,3 @@ | ||
it('should be instantiable', () => { | ||
let router = new Router(); | ||
let router = new Router({}); | ||
let children = [ | ||
@@ -19,0 +21,0 @@ <foo path="/" />, |
import { Router, Link, route } from '../src'; | ||
import { h, Component } from 'preact'; | ||
import { expect, use } from 'chai'; | ||
import { spy, match } from 'sinon'; | ||
import { h } from 'preact'; | ||
import chai, { expect } from 'chai'; | ||
import { spy } from 'sinon'; | ||
import sinonChai from 'sinon-chai'; | ||
use(sinonChai); | ||
chai.use(sinonChai); | ||
/** @jsx h */ | ||
@@ -96,2 +96,60 @@ | ||
}); | ||
describe('route()', () => { | ||
let router; | ||
before( () => { | ||
router = new Router({ | ||
url: '/foo', | ||
children: [ | ||
<foo path="/" />, | ||
<foo path="/foo" /> | ||
] | ||
}, {}); | ||
spy(router, 'routeTo'); | ||
router.componentWillMount(); | ||
}); | ||
after( () => { | ||
router.componentWillUnmount(); | ||
}); | ||
it('should return true for existing route', () => { | ||
router.routeTo.reset(); | ||
expect(route('/')).to.equal(true); | ||
expect(router.routeTo) | ||
.to.have.been.calledOnce | ||
.and.calledWithExactly('/'); | ||
router.routeTo.reset(); | ||
expect(route('/foo')).to.equal(true); | ||
expect(router.routeTo) | ||
.to.have.been.calledOnce | ||
.and.calledWithExactly('/foo'); | ||
}); | ||
it('should return false for missing route', () => { | ||
router.routeTo.reset(); | ||
expect(route('/asdf')).to.equal(false); | ||
expect(router.routeTo) | ||
.to.have.been.calledOnce | ||
.and.calledWithExactly('/asdf'); | ||
}); | ||
it('should return true for fallback route', () => { | ||
let oldChildren = router.props.children; | ||
router.props.children = [ | ||
<foo default />, | ||
...oldChildren | ||
]; | ||
router.routeTo.reset(); | ||
expect(route('/asdf')).to.equal(true); | ||
expect(router.routeTo) | ||
.to.have.been.calledOnce | ||
.and.calledWithExactly('/asdf'); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
738
47265
23
2