preact-router
Advanced tools
Comparing version 2.4.5 to 2.5.0
export function route(url: string, replace?: boolean): boolean; | ||
export interface RouterProps extends JSX.HTMLAttributes { | ||
path: string; | ||
export interface CustomHistory { | ||
getCurrentLocation?: () => string; | ||
location?: string; | ||
listen(callback: (url: string) => void): () => void; | ||
push?: (url: string) => void; | ||
replace?: (url: string) => void; | ||
} | ||
export class Router extends preact.Component<{}, {}> { | ||
export interface RouterProps extends JSX.HTMLAttributes, preact.ComponentProps { | ||
history?: CustomHistory; | ||
path?: string; | ||
static?: boolean; | ||
url?: string; | ||
} | ||
export class Router extends preact.Component<RouterProps, {}> { | ||
canRoute(url: string): boolean; | ||
getMatchingChildren(children: preact.VNode[], url: string, invoke: boolean): preact.VNode[]; | ||
routeTo(url: string): boolean; | ||
render(props: RouterProps & preact.ComponentProps, {}): preact.VNode; | ||
render(props: RouterProps, {}): preact.VNode; | ||
} | ||
@@ -16,4 +27,5 @@ | ||
component: preact.Component<PropsType, StateType>; | ||
matches: boolean; | ||
url: string; | ||
path: string; | ||
matches?: boolean; | ||
url?: string; | ||
} | ||
@@ -20,0 +32,0 @@ |
@@ -5,12 +5,12 @@ import { Component, cloneElement, h } from 'preact'; | ||
function exec(url, route) { | ||
var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : EMPTY$1; | ||
function exec(url, route, opts) { | ||
if ( opts === void 0 ) opts=EMPTY$1; | ||
var reg = /(?:\?([^#]*))?(#.*)?$/, | ||
c = url.match(reg), | ||
matches = {}, | ||
ret = void 0; | ||
c = url.match(reg), | ||
matches = {}, | ||
ret; | ||
if (c && c[1]) { | ||
var p = c[1].split('&'); | ||
for (var i = 0; i < p.length; i++) { | ||
for (var i=0; i<p.length; i++) { | ||
var r = p[i].split('='); | ||
@@ -23,10 +23,10 @@ matches[decodeURIComponent(r[0])] = decodeURIComponent(r.slice(1).join('=')); | ||
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] || '', | ||
plus = ~flags.indexOf('+'), | ||
star = ~flags.indexOf('*'), | ||
val = url[_i] || ''; | ||
if (!val && !star && (flags.indexOf('?') < 0 || plus)) { | ||
for (var i$1=0; i$1<max; i$1++) { | ||
if (route[i$1] && route[i$1].charAt(0)===':') { | ||
var param = route[i$1].replace(/(^\:|[+*?]+$)/g, ''), | ||
flags = (route[i$1].match(/[+*?]+$/) || EMPTY$1)[0] || '', | ||
plus = ~flags.indexOf('+'), | ||
star = ~flags.indexOf('*'), | ||
val = url[i$1] || ''; | ||
if (!val && !star && (flags.indexOf('?')<0 || plus)) { | ||
ret = false; | ||
@@ -37,6 +37,7 @@ break; | ||
if (plus || star) { | ||
matches[param] = url.slice(_i).map(decodeURIComponent).join('/'); | ||
matches[param] = url.slice(i$1).map(decodeURIComponent).join('/'); | ||
break; | ||
} | ||
} else if (route[_i] !== url[_i]) { | ||
} | ||
else if (route[i$1]!==url[i$1]) { | ||
ret = false; | ||
@@ -46,3 +47,3 @@ break; | ||
} | ||
if (opts.default !== true && ret === false) return false; | ||
if (opts.default!==true && ret===false) { return false; } | ||
return matches; | ||
@@ -53,7 +54,7 @@ } | ||
var aAttr = a.attributes || EMPTY$1, | ||
bAttr = b.attributes || EMPTY$1; | ||
if (aAttr.default) return 1; | ||
if (bAttr.default) return -1; | ||
bAttr = b.attributes || EMPTY$1; | ||
if (aAttr.default) { return 1; } | ||
if (bAttr.default) { return -1; } | ||
var diff = rank(aAttr.path) - rank(bAttr.path); | ||
return diff || aAttr.path.length - bAttr.path.length; | ||
return diff || (aAttr.path.length - bAttr.path.length); | ||
} | ||
@@ -73,10 +74,2 @@ | ||
var _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; }; | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | ||
var customHistory = null; | ||
@@ -86,34 +79,42 @@ | ||
var subscribers = []; | ||
var EMPTY = {}; | ||
function isPreactElement(node) { | ||
return node.__preactattr_ != null || typeof Symbol !== 'undefined' && node[Symbol.for('preactattr')] != null; | ||
return node.__preactattr_!=null || typeof Symbol!=='undefined' && node[Symbol.for('preactattr')]!=null; | ||
} | ||
function setUrl(url) { | ||
var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'push'; | ||
function setUrl(url, type) { | ||
if ( type === void 0 ) type='push'; | ||
if (customHistory && customHistory[type]) { | ||
customHistory[type](url); | ||
} else if (typeof history !== 'undefined' && history[type + 'State']) { | ||
history[type + 'State'](null, null, url); | ||
} | ||
else if (typeof history!=='undefined' && history[type+'State']) { | ||
history[type+'State'](null, null, url); | ||
} | ||
} | ||
function getCurrentUrl() { | ||
var url = void 0; | ||
var url; | ||
if (customHistory && customHistory.location) { | ||
url = customHistory.location; | ||
} else if (customHistory && customHistory.getCurrentLocation) { | ||
} | ||
else if (customHistory && customHistory.getCurrentLocation) { | ||
url = customHistory.getCurrentLocation(); | ||
} else { | ||
url = typeof location !== 'undefined' ? location : EMPTY; | ||
} | ||
return '' + (url.pathname || '') + (url.search || ''); | ||
else { | ||
url = typeof location!=='undefined' ? location : EMPTY; | ||
} | ||
return ("" + (url.pathname || '') + (url.search || '')); | ||
} | ||
function route(url) { | ||
var replace = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; | ||
if (typeof url !== 'string' && url.url) { | ||
function route(url, replace) { | ||
if ( replace === void 0 ) replace=false; | ||
if (typeof url!=='string' && url.url) { | ||
replace = url.replace; | ||
@@ -131,6 +132,7 @@ url = url.url; | ||
/** Check if the given URL can be handled by any router instances. */ | ||
function canRoute(url) { | ||
for (var i = ROUTERS.length; i--;) { | ||
if (ROUTERS[i].canRoute(url)) return true; | ||
for (var i=ROUTERS.length; i--; ) { | ||
if (ROUTERS[i].canRoute(url)) { return true; } | ||
} | ||
@@ -140,22 +142,27 @@ return false; | ||
/** Tell all router instances to handle the given URL. */ | ||
function routeTo(url) { | ||
var didRoute = false; | ||
for (var i = 0; i < ROUTERS.length; i++) { | ||
if (ROUTERS[i].routeTo(url) === true) { | ||
for (var i=0; i<ROUTERS.length; i++) { | ||
if (ROUTERS[i].routeTo(url)===true) { | ||
didRoute = true; | ||
} | ||
} | ||
for (var i$1=subscribers.length; i$1--; ) { | ||
subscribers[i$1](url); | ||
} | ||
return didRoute; | ||
} | ||
function routeFromLink(node) { | ||
// only valid elements | ||
if (!node || !node.getAttribute) return; | ||
if (!node || !node.getAttribute) { return; } | ||
var href = node.getAttribute('href'), | ||
target = node.getAttribute('target'); | ||
target = node.getAttribute('target'); | ||
// ignore links with targets and non-path URLs | ||
if (!href || !href.match(/^\//g) || target && !target.match(/^_?self$/i)) return; | ||
if (!href || !href.match(/^\//g) || (target && !target.match(/^_?self$/i))) { return; } | ||
@@ -166,4 +173,5 @@ // attempt to route, if no match simply cede control to browser | ||
function handleLinkClick(e) { | ||
if (e.button !== 0) return; | ||
if (e.button !== 0) { return; } | ||
routeFromLink(e.currentTarget || e.target || this); | ||
@@ -173,6 +181,7 @@ return prevent(e); | ||
function prevent(e) { | ||
if (e) { | ||
if (e.stopImmediatePropagation) e.stopImmediatePropagation(); | ||
if (e.stopPropagation) e.stopPropagation(); | ||
if (e.stopImmediatePropagation) { e.stopImmediatePropagation(); } | ||
if (e.stopPropagation) { e.stopPropagation(); } | ||
e.preventDefault(); | ||
@@ -183,10 +192,11 @@ } | ||
function delegateLinkHandler(e) { | ||
// ignore events the browser takes care of already: | ||
if (e.ctrlKey || e.metaKey || e.altKey || e.shiftKey || e.button !== 0) return; | ||
if (e.ctrlKey || e.metaKey || e.altKey || e.shiftKey || e.button!==0) { return; } | ||
var t = e.target; | ||
do { | ||
if (String(t.nodeName).toUpperCase() === 'A' && t.getAttribute('href') && isPreactElement(t)) { | ||
if (t.hasAttribute('native')) return; | ||
if (String(t.nodeName).toUpperCase()==='A' && t.getAttribute('href') && isPreactElement(t)) { | ||
if (t.hasAttribute('native')) { return; } | ||
// if link is handled by the router, prevent browser defaults | ||
@@ -197,17 +207,16 @@ if (routeFromLink(t)) { | ||
} | ||
} while (t = t.parentNode); | ||
} while ((t=t.parentNode)); | ||
} | ||
var eventListenersInitialized = false; | ||
function initEventListeners() { | ||
if (eventListenersInitialized) { | ||
if (eventListenersInitialized){ | ||
return; | ||
} | ||
if (typeof addEventListener === 'function') { | ||
if (typeof addEventListener==='function') { | ||
if (!customHistory) { | ||
addEventListener('popstate', function () { | ||
return routeTo(getCurrentUrl()); | ||
}); | ||
addEventListener('popstate', function () { return routeTo(getCurrentUrl()); }); | ||
} | ||
@@ -219,14 +228,6 @@ addEventListener('click', delegateLinkHandler); | ||
var Link = function Link(props) { | ||
return h('a', _extends({}, props, { onClick: handleLinkClick })); | ||
}; | ||
var Router = function (_Component) { | ||
_inherits(Router, _Component); | ||
var Router = (function (Component$$1) { | ||
function Router(props) { | ||
_classCallCheck(this, Router); | ||
var _this = _possibleConstructorReturn(this, _Component.call(this, props)); | ||
Component$$1.call(this, props); | ||
if (props.history) { | ||
@@ -236,19 +237,20 @@ customHistory = props.history; | ||
_this.state = { | ||
url: _this.props.url || getCurrentUrl() | ||
this.state = { | ||
url: this.props.url || getCurrentUrl() | ||
}; | ||
initEventListeners(); | ||
return _this; | ||
} | ||
Router.prototype.shouldComponentUpdate = function shouldComponentUpdate(props) { | ||
if (props.static !== true) return true; | ||
return props.url !== this.props.url || props.onChange !== this.props.onChange; | ||
if ( Component$$1 ) Router.__proto__ = Component$$1; | ||
Router.prototype = Object.create( Component$$1 && Component$$1.prototype ); | ||
Router.prototype.constructor = Router; | ||
Router.prototype.shouldComponentUpdate = function shouldComponentUpdate (props) { | ||
if (props.static!==true) { return true; } | ||
return props.url!==this.props.url || props.onChange!==this.props.onChange; | ||
}; | ||
/** Check if the given URL can be matched against any children */ | ||
Router.prototype.canRoute = function canRoute(url) { | ||
Router.prototype.canRoute = function canRoute (url) { | ||
return this.getMatchingChildren(this.props.children, url, false).length > 0; | ||
@@ -258,5 +260,3 @@ }; | ||
/** Re-render children with a new URL to match against. */ | ||
Router.prototype.routeTo = function routeTo(url) { | ||
Router.prototype.routeTo = function routeTo (url) { | ||
this._didRoute = false; | ||
@@ -266,3 +266,3 @@ this.setState({ url: url }); | ||
// if we're in the middle of an update, don't synchronously re-route. | ||
if (this.updating) return this.canRoute(url); | ||
if (this.updating) { return this.canRoute(url); } | ||
@@ -273,3 +273,3 @@ this.forceUpdate(); | ||
Router.prototype.componentWillMount = function componentWillMount() { | ||
Router.prototype.componentWillMount = function componentWillMount () { | ||
ROUTERS.push(this); | ||
@@ -279,8 +279,8 @@ this.updating = true; | ||
Router.prototype.componentDidMount = function componentDidMount() { | ||
var _this2 = this; | ||
Router.prototype.componentDidMount = function componentDidMount () { | ||
var this$1 = this; | ||
if (customHistory) { | ||
this.unlisten = customHistory.listen(function (location) { | ||
_this2.routeTo('' + (location.pathname || '') + (location.search || '')); | ||
this$1.routeTo(("" + (location.pathname || '') + (location.search || ''))); | ||
}); | ||
@@ -291,21 +291,22 @@ } | ||
Router.prototype.componentWillUnmount = function componentWillUnmount() { | ||
if (typeof this.unlisten === 'function') this.unlisten(); | ||
Router.prototype.componentWillUnmount = function componentWillUnmount () { | ||
if (typeof this.unlisten==='function') { this.unlisten(); } | ||
ROUTERS.splice(ROUTERS.indexOf(this), 1); | ||
}; | ||
Router.prototype.componentWillUpdate = function componentWillUpdate() { | ||
Router.prototype.componentWillUpdate = function componentWillUpdate () { | ||
this.updating = true; | ||
}; | ||
Router.prototype.componentDidUpdate = function componentDidUpdate() { | ||
Router.prototype.componentDidUpdate = function componentDidUpdate () { | ||
this.updating = false; | ||
}; | ||
Router.prototype.getMatchingChildren = function getMatchingChildren(children, url, invoke) { | ||
return children.slice().sort(pathRankSort).map(function (vnode) { | ||
var path = vnode.attributes.path, | ||
matches = exec(url, path, vnode.attributes); | ||
Router.prototype.getMatchingChildren = function getMatchingChildren (children, url, invoke) { | ||
return children.slice().sort(pathRankSort).map( function (vnode) { | ||
var attrs = vnode.attributes || {}, | ||
path = attrs.path, | ||
matches = exec(url, path, attrs); | ||
if (matches) { | ||
if (invoke !== false) { | ||
if (invoke!==false) { | ||
var newProps = { url: url, matches: matches }; | ||
@@ -326,6 +327,6 @@ // copy matches onto props | ||
Router.prototype.render = function render(_ref, _ref2) { | ||
var children = _ref.children, | ||
onChange = _ref.onChange; | ||
var url = _ref2.url; | ||
Router.prototype.render = function render (ref, ref$1) { | ||
var children = ref.children; | ||
var onChange = ref.onChange; | ||
var url = ref$1.url; | ||
@@ -338,5 +339,5 @@ var active = this.getMatchingChildren(children, url, true); | ||
var previous = this.previousUrl; | ||
if (url !== previous) { | ||
if (url!==previous) { | ||
this.previousUrl = url; | ||
if (typeof onChange === 'function') { | ||
if (typeof onChange==='function') { | ||
onChange({ | ||
@@ -356,8 +357,12 @@ router: this, | ||
return Router; | ||
}(Component); | ||
}(Component)); | ||
var Route = function Route(props) { | ||
return h(props.component, props); | ||
}; | ||
var Link = function (props) { return ( | ||
h('a', Object.assign({}, props, { onClick: handleLinkClick })) | ||
); }; | ||
var Route = function (props) { return h(props.component, props); }; | ||
Router.subscribers = subscribers; | ||
Router.getCurrentUrl = getCurrentUrl; | ||
Router.route = route; | ||
@@ -368,3 +373,3 @@ Router.Router = Router; | ||
export { route, Router, Route, Link };export default Router; | ||
export { subscribers, getCurrentUrl, route, Router, Route, Link };export default Router; | ||
//# sourceMappingURL=preact-router.es.js.map |
@@ -1,352 +0,2 @@ | ||
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('preact')) : | ||
typeof define === 'function' && define.amd ? define(['preact'], factory) : | ||
(global.preactRouter = factory(global.preact)); | ||
}(this, (function (preact) { 'use strict'; | ||
var EMPTY$1 = {}; | ||
function exec(url, route) { | ||
var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : EMPTY$1; | ||
var reg = /(?:\?([^#]*))?(#.*)?$/, | ||
c = url.match(reg), | ||
matches = {}, | ||
ret = void 0; | ||
if (c && c[1]) { | ||
var p = c[1].split('&'); | ||
for (var i = 0; i < p.length; i++) { | ||
var r = p[i].split('='); | ||
matches[decodeURIComponent(r[0])] = decodeURIComponent(r.slice(1).join('=')); | ||
} | ||
} | ||
url = segmentize(url.replace(reg, '')); | ||
route = segmentize(route || ''); | ||
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] || '', | ||
plus = ~flags.indexOf('+'), | ||
star = ~flags.indexOf('*'), | ||
val = url[_i] || ''; | ||
if (!val && !star && (flags.indexOf('?') < 0 || plus)) { | ||
ret = false; | ||
break; | ||
} | ||
matches[param] = decodeURIComponent(val); | ||
if (plus || star) { | ||
matches[param] = url.slice(_i).map(decodeURIComponent).join('/'); | ||
break; | ||
} | ||
} else if (route[_i] !== url[_i]) { | ||
ret = false; | ||
break; | ||
} | ||
} | ||
if (opts.default !== true && ret === false) return false; | ||
return matches; | ||
} | ||
function pathRankSort(a, b) { | ||
var aAttr = a.attributes || EMPTY$1, | ||
bAttr = b.attributes || EMPTY$1; | ||
if (aAttr.default) return 1; | ||
if (bAttr.default) return -1; | ||
var diff = rank(aAttr.path) - rank(bAttr.path); | ||
return diff || aAttr.path.length - bAttr.path.length; | ||
} | ||
function segmentize(url) { | ||
return strip(url).split('/'); | ||
} | ||
function rank(url) { | ||
return (strip(url).match(/\/+/g) || '').length; | ||
} | ||
function strip(url) { | ||
return url.replace(/(^\/+|\/+$)/g, ''); | ||
} | ||
var _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; }; | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | ||
var customHistory = null; | ||
var ROUTERS = []; | ||
var EMPTY = {}; | ||
function isPreactElement(node) { | ||
return node.__preactattr_ != null || typeof Symbol !== 'undefined' && node[Symbol.for('preactattr')] != null; | ||
} | ||
function setUrl(url) { | ||
var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'push'; | ||
if (customHistory && customHistory[type]) { | ||
customHistory[type](url); | ||
} else if (typeof history !== 'undefined' && history[type + 'State']) { | ||
history[type + 'State'](null, null, url); | ||
} | ||
} | ||
function getCurrentUrl() { | ||
var url = void 0; | ||
if (customHistory && customHistory.location) { | ||
url = customHistory.location; | ||
} else if (customHistory && customHistory.getCurrentLocation) { | ||
url = customHistory.getCurrentLocation(); | ||
} else { | ||
url = typeof location !== 'undefined' ? location : EMPTY; | ||
} | ||
return '' + (url.pathname || '') + (url.search || ''); | ||
} | ||
function route(url) { | ||
var replace = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; | ||
if (typeof url !== 'string' && url.url) { | ||
replace = url.replace; | ||
url = url.url; | ||
} | ||
// only push URL into history if we can handle it | ||
if (canRoute(url)) { | ||
setUrl(url, replace ? 'replace' : 'push'); | ||
} | ||
return routeTo(url); | ||
} | ||
/** Check if the given URL can be handled by any router instances. */ | ||
function canRoute(url) { | ||
for (var i = ROUTERS.length; i--;) { | ||
if (ROUTERS[i].canRoute(url)) return true; | ||
} | ||
return false; | ||
} | ||
/** Tell all router instances to handle the given URL. */ | ||
function routeTo(url) { | ||
var didRoute = false; | ||
for (var i = 0; i < ROUTERS.length; i++) { | ||
if (ROUTERS[i].routeTo(url) === true) { | ||
didRoute = true; | ||
} | ||
} | ||
return didRoute; | ||
} | ||
function routeFromLink(node) { | ||
// only valid elements | ||
if (!node || !node.getAttribute) return; | ||
var href = node.getAttribute('href'), | ||
target = node.getAttribute('target'); | ||
// ignore links with targets and non-path URLs | ||
if (!href || !href.match(/^\//g) || target && !target.match(/^_?self$/i)) return; | ||
// attempt to route, if no match simply cede control to browser | ||
return route(href); | ||
} | ||
function handleLinkClick(e) { | ||
if (e.button !== 0) return; | ||
routeFromLink(e.currentTarget || e.target || this); | ||
return prevent(e); | ||
} | ||
function prevent(e) { | ||
if (e) { | ||
if (e.stopImmediatePropagation) e.stopImmediatePropagation(); | ||
if (e.stopPropagation) e.stopPropagation(); | ||
e.preventDefault(); | ||
} | ||
return false; | ||
} | ||
function delegateLinkHandler(e) { | ||
// ignore events the browser takes care of already: | ||
if (e.ctrlKey || e.metaKey || e.altKey || e.shiftKey || e.button !== 0) return; | ||
var t = e.target; | ||
do { | ||
if (String(t.nodeName).toUpperCase() === 'A' && t.getAttribute('href') && isPreactElement(t)) { | ||
if (t.hasAttribute('native')) return; | ||
// if link is handled by the router, prevent browser defaults | ||
if (routeFromLink(t)) { | ||
return prevent(e); | ||
} | ||
} | ||
} while (t = t.parentNode); | ||
} | ||
var eventListenersInitialized = false; | ||
function initEventListeners() { | ||
if (eventListenersInitialized) { | ||
return; | ||
} | ||
if (typeof addEventListener === 'function') { | ||
if (!customHistory) { | ||
addEventListener('popstate', function () { | ||
return routeTo(getCurrentUrl()); | ||
}); | ||
} | ||
addEventListener('click', delegateLinkHandler); | ||
} | ||
eventListenersInitialized = true; | ||
} | ||
var Link = function Link(props) { | ||
return preact.h('a', _extends({}, props, { onClick: handleLinkClick })); | ||
}; | ||
var Router = function (_Component) { | ||
_inherits(Router, _Component); | ||
function Router(props) { | ||
_classCallCheck(this, Router); | ||
var _this = _possibleConstructorReturn(this, _Component.call(this, props)); | ||
if (props.history) { | ||
customHistory = props.history; | ||
} | ||
_this.state = { | ||
url: _this.props.url || getCurrentUrl() | ||
}; | ||
initEventListeners(); | ||
return _this; | ||
} | ||
Router.prototype.shouldComponentUpdate = function shouldComponentUpdate(props) { | ||
if (props.static !== true) return true; | ||
return props.url !== this.props.url || props.onChange !== this.props.onChange; | ||
}; | ||
/** Check if the given URL can be matched against any children */ | ||
Router.prototype.canRoute = function canRoute(url) { | ||
return this.getMatchingChildren(this.props.children, url, false).length > 0; | ||
}; | ||
/** Re-render children with a new URL to match against. */ | ||
Router.prototype.routeTo = function routeTo(url) { | ||
this._didRoute = false; | ||
this.setState({ url: url }); | ||
// if we're in the middle of an update, don't synchronously re-route. | ||
if (this.updating) return this.canRoute(url); | ||
this.forceUpdate(); | ||
return this._didRoute; | ||
}; | ||
Router.prototype.componentWillMount = function componentWillMount() { | ||
ROUTERS.push(this); | ||
this.updating = true; | ||
}; | ||
Router.prototype.componentDidMount = function componentDidMount() { | ||
var _this2 = this; | ||
if (customHistory) { | ||
this.unlisten = customHistory.listen(function (location) { | ||
_this2.routeTo('' + (location.pathname || '') + (location.search || '')); | ||
}); | ||
} | ||
this.updating = false; | ||
}; | ||
Router.prototype.componentWillUnmount = function componentWillUnmount() { | ||
if (typeof this.unlisten === 'function') this.unlisten(); | ||
ROUTERS.splice(ROUTERS.indexOf(this), 1); | ||
}; | ||
Router.prototype.componentWillUpdate = function componentWillUpdate() { | ||
this.updating = true; | ||
}; | ||
Router.prototype.componentDidUpdate = function componentDidUpdate() { | ||
this.updating = false; | ||
}; | ||
Router.prototype.getMatchingChildren = function getMatchingChildren(children, url, invoke) { | ||
return children.slice().sort(pathRankSort).map(function (vnode) { | ||
var path = vnode.attributes.path, | ||
matches = exec(url, path, vnode.attributes); | ||
if (matches) { | ||
if (invoke !== false) { | ||
var newProps = { url: url, matches: matches }; | ||
// copy matches onto props | ||
for (var i in matches) { | ||
if (matches.hasOwnProperty(i)) { | ||
newProps[i] = matches[i]; | ||
} | ||
} | ||
return preact.cloneElement(vnode, newProps); | ||
} | ||
return vnode; | ||
} | ||
return false; | ||
}).filter(Boolean); | ||
}; | ||
Router.prototype.render = function render(_ref, _ref2) { | ||
var children = _ref.children, | ||
onChange = _ref.onChange; | ||
var url = _ref2.url; | ||
var active = this.getMatchingChildren(children, url, 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 | ||
}); | ||
} | ||
} | ||
return current; | ||
}; | ||
return Router; | ||
}(preact.Component); | ||
var Route = function Route(props) { | ||
return preact.h(props.component, props); | ||
}; | ||
Router.route = route; | ||
Router.Router = Router; | ||
Router.Route = Route; | ||
Router.Link = Link; | ||
return Router; | ||
}))); | ||
!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){function e(t,e,n){void 0===n&&(n=y);var o,i=/(?:\?([^#]*))?(#.*)?$/,u=t.match(i),a={};if(u&&u[1])for(var p=u[1].split("&"),c=0;c<p.length;c++){var f=p[c].split("=");a[decodeURIComponent(f[0])]=decodeURIComponent(f.slice(1).join("="))}t=r(t.replace(i,"")),e=r(e||"");for(var s=Math.max(t.length,e.length),l=0;l<s;l++)if(e[l]&&":"===e[l].charAt(0)){var h=e[l].replace(/(^\:|[+*?]+$)/g,""),d=(e[l].match(/[+*?]+$/)||y)[0]||"",g=~d.indexOf("+"),m=~d.indexOf("*"),v=t[l]||"";if(!v&&!m&&(d.indexOf("?")<0||g)){o=!1;break}if(a[h]=decodeURIComponent(v),g||m){a[h]=t.slice(l).map(decodeURIComponent).join("/");break}}else if(e[l]!==t[l]){o=!1;break}return(!0===n.default||!1!==o)&&a}function n(t,e){var n=t.attributes||y,r=e.attributes||y;return n.default?1:r.default?-1:o(n.path)-o(r.path)||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){return null!=t.__preactattr_||"undefined"!=typeof Symbol&&null!=t[Symbol.for("preactattr")]}function a(t,e){void 0===e&&(e="push"),v&&v[e]?v[e](t):"undefined"!=typeof history&&history[e+"State"]&&history[e+"State"](null,null,t)}function p(){var t;return t=v&&v.location?v.location:v&&v.getCurrentLocation?v.getCurrentLocation():"undefined"!=typeof location?location:R,""+(t.pathname||"")+(t.search||"")}function c(t,e){return void 0===e&&(e=!1),"string"!=typeof t&&t.url&&(e=t.replace,t=t.url),f(t)&&a(t,e?"replace":"push"),s(t)}function f(t){for(var e=b.length;e--;)if(b[e].canRoute(t))return!0;return!1}function s(t){for(var e=!1,n=0;n<b.length;n++)!0===b[n].routeTo(t)&&(e=!0);for(var r=C.length;r--;)C[r](t);return e}function l(t){if(t&&t.getAttribute){var e=t.getAttribute("href"),n=t.getAttribute("target");if(e&&e.match(/^\//g)&&(!n||n.match(/^_?self$/i)))return c(e)}}function h(t){if(0===t.button)return l(t.currentTarget||t.target||this),d(t)}function d(t){return t&&(t.stopImmediatePropagation&&t.stopImmediatePropagation(),t.stopPropagation&&t.stopPropagation(),t.preventDefault()),!1}function g(t){if(!(t.ctrlKey||t.metaKey||t.altKey||t.shiftKey||0!==t.button)){var e=t.target;do{if("A"===(e.nodeName+"").toUpperCase()&&e.getAttribute("href")&&u(e)){if(e.hasAttribute("native"))return;if(l(e))return d(t)}}while(e=e.parentNode)}}function m(){U||("function"==typeof addEventListener&&(v||addEventListener("popstate",function(){return s(p())}),addEventListener("click",g)),U=!0)}var y={},v=null,b=[],C=[],R={},U=!1,_=function(r){function o(t){r.call(this,t),t.history&&(v=t.history),this.state={url:this.props.url||p()},m()}return r&&(o.__proto__=r),o.prototype=Object.create(r&&r.prototype),o.prototype.constructor=o,o.prototype.shouldComponentUpdate=function(t){return!0!==t.static||(t.url!==this.props.url||t.onChange!==this.props.onChange)},o.prototype.canRoute=function(t){return this.getMatchingChildren(this.props.children,t,!1).length>0},o.prototype.routeTo=function(t){return this._didRoute=!1,this.setState({url:t}),this.updating?this.canRoute(t):(this.forceUpdate(),this._didRoute)},o.prototype.componentWillMount=function(){b.push(this),this.updating=!0},o.prototype.componentDidMount=function(){var t=this;v&&(this.unlisten=v.listen(function(e){t.routeTo(""+(e.pathname||"")+(e.search||""))})),this.updating=!1},o.prototype.componentWillUnmount=function(){"function"==typeof this.unlisten&&this.unlisten(),b.splice(b.indexOf(this),1)},o.prototype.componentWillUpdate=function(){this.updating=!0},o.prototype.componentDidUpdate=function(){this.updating=!1},o.prototype.getMatchingChildren=function(r,o,i){return r.slice().sort(n).map(function(n){var r=n.attributes||{},u=r.path,a=e(o,u,r);if(a){if(!1!==i){var p={url:o,matches:a};for(var c in a)a.hasOwnProperty(c)&&(p[c]=a[c]);return t.cloneElement(n,p)}return n}return!1}).filter(Boolean)},o.prototype.render=function(t,e){var n=t.children,r=t.onChange,o=e.url,i=this.getMatchingChildren(n,o,!0),u=i[0]||null;this._didRoute=!!u;var a=this.previousUrl;return o!==a&&(this.previousUrl=o,"function"==typeof r&&r({router:this,url:o,previous:a,active:i,current:u})),u},o}(t.Component),x=function(e){return t.h("a",Object.assign({},e,{onClick:h}))},A=function(e){return t.h(e.component,e)};return _.subscribers=C,_.getCurrentUrl=p,_.route=c,_.Router=_,_.Route=A,_.Link=x,_}); | ||
//# sourceMappingURL=preact-router.js.map |
{ | ||
"name": "preact-router", | ||
"amdName": "preactRouter", | ||
"version": "2.4.5", | ||
"version": "2.5.0", | ||
"description": "Connect your components up to that address bar.", | ||
"main": "dist/preact-router.js", | ||
"jsnext:main": "dist/preact-router.es.js", | ||
"minified:main": "dist/preact-router.min.js", | ||
"module": "dist/preact-router.es.js", | ||
@@ -13,6 +12,6 @@ "scripts": { | ||
"copy-typescript-definition": "copyfiles -f src/index.d.ts dist", | ||
"build": "npm-run-all --silent clean transpile copy-typescript-definition minify size", | ||
"build": "npm-run-all --silent clean transpile transpile:match copy-typescript-definition size", | ||
"transpile": "rollup -c --environment FORMAT:umd && rollup -c --environment FORMAT:es", | ||
"minify": "uglifyjs $npm_package_main -cm -o $npm_package_minified_main -p relative --in-source-map ${npm_package_main}.map --source-map ${npm_package_minified_main}.map", | ||
"size": "size=$(gzip-size $npm_package_minified_main) && echo \"gzip size: $size / $(pretty-bytes $size)\"", | ||
"transpile:match": "babel src/match.js -o match.js -f umd", | ||
"size": "size=$(gzip-size $npm_package_main) && echo \"gzip size: $size / $(pretty-bytes $size)\"", | ||
"test": "npm-run-all lint build test:karma", | ||
@@ -80,9 +79,11 @@ "lint": "eslint {src,test,test_helpers}", | ||
"rollup": "^0.41.6", | ||
"rollup-plugin-babel": "^2.4.0", | ||
"rollup-plugin-buble": "^0.15.0", | ||
"rollup-plugin-es3": "^1.0.3", | ||
"rollup-plugin-memory": "^2.0.0", | ||
"rollup-plugin-post-replace": "^1.0.0", | ||
"rollup-plugin-uglify": "^1.0.1", | ||
"sinon": "^1.17.4", | ||
"sinon-chai": "^2.8.0", | ||
"uglify-js": "^2.6.1", | ||
"webpack": "^1.13.1" | ||
} | ||
} |
export function route(url: string, replace?: boolean): boolean; | ||
export interface RouterProps extends JSX.HTMLAttributes { | ||
path: string; | ||
export interface CustomHistory { | ||
getCurrentLocation?: () => string; | ||
location?: string; | ||
listen(callback: (url: string) => void): () => void; | ||
push?: (url: string) => void; | ||
replace?: (url: string) => void; | ||
} | ||
export class Router extends preact.Component<{}, {}> { | ||
export interface RouterProps extends JSX.HTMLAttributes, preact.ComponentProps { | ||
history?: CustomHistory; | ||
path?: string; | ||
static?: boolean; | ||
url?: string; | ||
} | ||
export class Router extends preact.Component<RouterProps, {}> { | ||
canRoute(url: string): boolean; | ||
getMatchingChildren(children: preact.VNode[], url: string, invoke: boolean): preact.VNode[]; | ||
routeTo(url: string): boolean; | ||
render(props: RouterProps & preact.ComponentProps, {}): preact.VNode; | ||
render(props: RouterProps, {}): preact.VNode; | ||
} | ||
@@ -16,4 +27,5 @@ | ||
component: preact.Component<PropsType, StateType>; | ||
matches: boolean; | ||
url: string; | ||
path: string; | ||
matches?: boolean; | ||
url?: string; | ||
} | ||
@@ -20,0 +32,0 @@ |
@@ -8,2 +8,4 @@ import { cloneElement, h, Component } from 'preact'; | ||
const subscribers = []; | ||
const EMPTY = {}; | ||
@@ -40,2 +42,3 @@ | ||
function route(url, replace=false) { | ||
@@ -73,2 +76,5 @@ if (typeof url!=='string' && url.url) { | ||
} | ||
for (let i=subscribers.length; i--; ) { | ||
subscribers[i](url); | ||
} | ||
return didRoute; | ||
@@ -144,7 +150,2 @@ } | ||
const Link = (props) => { | ||
return h('a', Object.assign({}, props, { onClick: handleLinkClick })); | ||
}; | ||
class Router extends Component { | ||
@@ -215,4 +216,5 @@ constructor(props) { | ||
return children.slice().sort(pathRankSort).map( vnode => { | ||
let path = vnode.attributes.path, | ||
matches = exec(url, path, vnode.attributes); | ||
let attrs = vnode.attributes || {}, | ||
path = attrs.path, | ||
matches = exec(url, path, attrs); | ||
if (matches) { | ||
@@ -259,4 +261,10 @@ if (invoke!==false) { | ||
const Link = (props) => ( | ||
h('a', Object.assign({}, props, { onClick: handleLinkClick })) | ||
); | ||
const Route = props => h(props.component, props); | ||
Router.subscribers = subscribers; | ||
Router.getCurrentUrl = getCurrentUrl; | ||
Router.route = route; | ||
@@ -267,3 +275,3 @@ Router.Router = Router; | ||
export { route, Router, Route, Link }; | ||
export { subscribers, getCurrentUrl, route, Router, Route, Link }; | ||
export default Router; |
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
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
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
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
31112
40
16951
12
674