cherrytree
Advanced tools
Comparing version 2.3.2 to 2.4.0
@@ -0,1 +1,5 @@ | ||
### v2.4.0 | ||
* Make it possible to `transitionTo('anAbstractRoute')` and `generate('anAbstractRoute')` in cases where the abstract route has a corresponding index route. This can be more intuitive in some cases. | ||
### v2.3.2 | ||
@@ -2,0 +6,0 @@ |
101
lib/dash.js
@@ -1,80 +0,39 @@ | ||
'use strict'; | ||
let toString = Object.prototype.toString | ||
let keys = Object.keys | ||
let assoc = (obj, attr, val) => { obj[attr] = val; return obj } | ||
let isArray = obj => toString.call(obj) === '[object Array]' | ||
Object.defineProperty(exports, '__esModule', { | ||
value: true | ||
}); | ||
var toString = Object.prototype.toString; | ||
var keys = Object.keys; | ||
var assoc = function assoc(obj, attr, val) { | ||
obj[attr] = val;return obj; | ||
}; | ||
var isArray = function isArray(obj) { | ||
return toString.call(obj) === '[object Array]'; | ||
}; | ||
export let clone = obj => | ||
obj | ||
? isArray(obj) | ||
? obj.slice(0) | ||
: extend({}, obj) | ||
: obj | ||
var clone = function clone(obj) { | ||
return obj ? isArray(obj) ? obj.slice(0) : extend({}, obj) : obj; | ||
}; | ||
export let pick = (obj, attrs) => | ||
attrs.reduce((acc, attr) => | ||
obj[attr] === undefined | ||
? acc | ||
: assoc(acc, attr, obj[attr]), {}) | ||
exports.clone = clone; | ||
var pick = function pick(obj, attrs) { | ||
return attrs.reduce(function (acc, attr) { | ||
return obj[attr] === undefined ? acc : assoc(acc, attr, obj[attr]); | ||
}, {}); | ||
}; | ||
export let isEqual = (obj1, obj2) => | ||
keys(obj1).length === keys(obj2).length && | ||
keys(obj1).reduce((acc, key) => acc && obj2[key] === obj1[key], true) | ||
exports.pick = pick; | ||
var isEqual = function isEqual(obj1, obj2) { | ||
return keys(obj1).length === keys(obj2).length && keys(obj1).reduce(function (acc, key) { | ||
return acc && obj2[key] === obj1[key]; | ||
}, true); | ||
}; | ||
exports.isEqual = isEqual; | ||
var extend = function extend(obj) { | ||
for (var _len = arguments.length, rest = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
rest[_key - 1] = arguments[_key]; | ||
} | ||
rest.forEach(function (source) { | ||
export let extend = (obj, ...rest) => { | ||
rest.forEach(source => { | ||
if (source) { | ||
for (var prop in source) { | ||
obj[prop] = source[prop]; | ||
for (let prop in source) { | ||
obj[prop] = source[prop] | ||
} | ||
} | ||
}); | ||
return obj; | ||
}; | ||
}) | ||
return obj | ||
} | ||
exports.extend = extend; | ||
var find = function find(list, pred) { | ||
var _iteratorNormalCompletion = true; | ||
var _didIteratorError = false; | ||
var _iteratorError = undefined; | ||
export let find = (list, pred) => { | ||
for (let x of list) if (pred(x)) return x | ||
} | ||
try { | ||
for (var _iterator = list[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
var x = _step.value; | ||
if (pred(x)) return x; | ||
} | ||
} catch (err) { | ||
_didIteratorError = true; | ||
_iteratorError = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion && _iterator['return']) { | ||
_iterator['return'](); | ||
} | ||
} finally { | ||
if (_didIteratorError) { | ||
throw _iteratorError; | ||
} | ||
} | ||
} | ||
}; | ||
exports.find = find; | ||
var isString = function isString(obj) { | ||
return Object.prototype.toString.call(obj) === '[object String]'; | ||
}; | ||
exports.isString = isString; | ||
export let isString = obj => | ||
Object.prototype.toString.call(obj) === '[object String]' |
@@ -1,40 +0,28 @@ | ||
'use strict'; | ||
import { clone } from './dash' | ||
import invariant from './invariant' | ||
Object.defineProperty(exports, '__esModule', { | ||
value: true | ||
}); | ||
exports['default'] = dsl; | ||
export default function dsl (callback) { | ||
let ancestors = [] | ||
let matches = {} | ||
let names = {} | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
callback(function route (name, options, callback) { | ||
let routes | ||
var _dash = require('./dash'); | ||
invariant(!names[name], 'Route names must be unique, but route "%s" is declared multiple times', name) | ||
var _invariant = require('./invariant'); | ||
names[name] = true | ||
var _invariant2 = _interopRequireDefault(_invariant); | ||
function dsl(callback) { | ||
var ancestors = []; | ||
var matches = {}; | ||
var names = {}; | ||
callback(function route(name, options, callback) { | ||
var routes = undefined; | ||
(0, _invariant2['default'])(!names[name], 'Route names must be unique, but route "%s" is declared multiple times', name); | ||
names[name] = true; | ||
if (arguments.length === 1) { | ||
options = {}; | ||
options = {} | ||
} | ||
if (arguments.length === 2 && typeof options === 'function') { | ||
callback = options; | ||
options = {}; | ||
callback = options | ||
options = {} | ||
} | ||
if (typeof options.path !== 'string') { | ||
var parts = name.split('.'); | ||
options.path = parts[parts.length - 1]; | ||
let parts = name.split('.') | ||
options.path = parts[parts.length - 1] | ||
} | ||
@@ -44,6 +32,6 @@ | ||
if (callback) { | ||
ancestors = ancestors.concat(name); | ||
callback(); | ||
routes = pop(); | ||
ancestors.splice(-1); | ||
ancestors = ancestors.concat(name) | ||
callback() | ||
routes = pop() | ||
ancestors.splice(-1) | ||
} | ||
@@ -57,22 +45,20 @@ | ||
options: options, | ||
ancestors: (0, _dash.clone)(ancestors) | ||
}); | ||
}); | ||
ancestors: clone(ancestors) | ||
}) | ||
}) | ||
function pop() { | ||
return matches[currentLevel()] || []; | ||
function pop () { | ||
return matches[currentLevel()] || [] | ||
} | ||
function push(route) { | ||
matches[currentLevel()] = matches[currentLevel()] || []; | ||
matches[currentLevel()].push(route); | ||
function push (route) { | ||
matches[currentLevel()] = matches[currentLevel()] || [] | ||
matches[currentLevel()].push(route) | ||
} | ||
function currentLevel() { | ||
return ancestors.join('.'); | ||
function currentLevel () { | ||
return ancestors.join('.') | ||
} | ||
return pop(); | ||
return pop() | ||
} | ||
module.exports = exports['default']; |
@@ -1,15 +0,10 @@ | ||
'use strict'; | ||
let events = createEvents() | ||
Object.defineProperty(exports, '__esModule', { | ||
value: true | ||
}); | ||
var events = createEvents(); | ||
export default events | ||
exports['default'] = events; | ||
function createEvents () { | ||
let exp = {} | ||
function createEvents() { | ||
var exp = {}; | ||
if (typeof window === 'undefined') { | ||
return exp; | ||
return exp | ||
} | ||
@@ -21,5 +16,5 @@ | ||
var bind = window.addEventListener ? 'addEventListener' : 'attachEvent'; | ||
var unbind = window.removeEventListener ? 'removeEventListener' : 'detachEvent'; | ||
var prefix = bind !== 'addEventListener' ? 'on' : ''; | ||
let bind = window.addEventListener ? 'addEventListener' : 'attachEvent' | ||
let unbind = window.removeEventListener ? 'removeEventListener' : 'detachEvent' | ||
let prefix = bind !== 'addEventListener' ? 'on' : '' | ||
@@ -38,5 +33,5 @@ /** | ||
exp.bind = function (el, type, fn, capture) { | ||
el[bind](prefix + type, fn, capture || false); | ||
return fn; | ||
}; | ||
el[bind](prefix + type, fn, capture || false) | ||
return fn | ||
} | ||
@@ -55,8 +50,7 @@ /** | ||
exp.unbind = function (el, type, fn, capture) { | ||
el[unbind](prefix + type, fn, capture || false); | ||
return fn; | ||
}; | ||
el[unbind](prefix + type, fn, capture || false) | ||
return fn | ||
} | ||
return exp; | ||
return exp | ||
} | ||
module.exports = exports['default']; |
@@ -1,22 +0,12 @@ | ||
'use strict'; | ||
Object.defineProperty(exports, '__esModule', { | ||
value: true | ||
}); | ||
exports['default'] = invariant; | ||
function invariant(condition, format, a, b, c, d, e, f) { | ||
export default function invariant (condition, format, a, b, c, d, e, f) { | ||
if (!condition) { | ||
(function () { | ||
var args = [a, b, c, d, e, f]; | ||
var argIndex = 0; | ||
var error = new Error('Invariant Violation: ' + format.replace(/%s/g, function () { | ||
return args[argIndex++]; | ||
})); | ||
error.framesToPop = 1; // we don't care about invariant's own frame | ||
throw error; | ||
})(); | ||
let args = [a, b, c, d, e, f] | ||
let argIndex = 0 | ||
let error = new Error( | ||
'Invariant Violation: ' + | ||
format.replace(/%s/g, () => args[argIndex++]) | ||
) | ||
error.framesToPop = 1 // we don't care about invariant's own frame | ||
throw error | ||
} | ||
} | ||
module.exports = exports['default']; |
@@ -1,14 +0,3 @@ | ||
'use strict'; | ||
import events from './events' | ||
Object.defineProperty(exports, '__esModule', { | ||
value: true | ||
}); | ||
exports.intercept = intercept; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
var _events = require('./events'); | ||
var _events2 = _interopRequireDefault(_events); | ||
/** | ||
@@ -23,22 +12,22 @@ * Handle link delegation on `el` or the document, | ||
function intercept(el, fn) { | ||
export function intercept (el, fn) { | ||
// default to document | ||
if (typeof el === 'function') { | ||
fn = el; | ||
el = document; | ||
fn = el | ||
el = document | ||
} | ||
var cb = delegate(el, 'click', function (e, el) { | ||
if (clickable(e, el)) fn(e, el); | ||
}); | ||
let cb = delegate(el, 'click', function (e, el) { | ||
if (clickable(e, el)) fn(e, el) | ||
}) | ||
return function dispose() { | ||
undelegate(el, 'click', cb); | ||
}; | ||
return function dispose () { | ||
undelegate(el, 'click', cb) | ||
} | ||
} | ||
function link(element) { | ||
element = { parentNode: element }; | ||
function link (element) { | ||
element = {parentNode: element} | ||
var root = document; | ||
let root = document | ||
@@ -49,3 +38,3 @@ // Make sure `element !== document` and `element != null` | ||
if (element.tagName.toLowerCase() === 'a') { | ||
return element; | ||
return element | ||
} | ||
@@ -56,3 +45,3 @@ // After `matches` on the edge case that | ||
if (element === root) { | ||
return; | ||
return | ||
} | ||
@@ -76,10 +65,10 @@ } | ||
function delegate(el, type, fn) { | ||
return _events2['default'].bind(el, type, function (e) { | ||
var target = e.target || e.srcElement; | ||
var el = link(target); | ||
function delegate (el, type, fn) { | ||
return events.bind(el, type, function (e) { | ||
let target = e.target || e.srcElement | ||
let el = link(target) | ||
if (el) { | ||
fn(e, el); | ||
fn(e, el) | ||
} | ||
}); | ||
}) | ||
} | ||
@@ -97,4 +86,4 @@ | ||
function undelegate(el, type, fn) { | ||
_events2['default'].unbind(el, type, fn); | ||
function undelegate (el, type, fn) { | ||
events.unbind(el, type, fn) | ||
} | ||
@@ -106,28 +95,28 @@ | ||
function clickable(e, el) { | ||
if (which(e) !== 1) return; | ||
if (e.metaKey || e.ctrlKey || e.shiftKey) return; | ||
if (e.defaultPrevented) return; | ||
function clickable (e, el) { | ||
if (which(e) !== 1) return | ||
if (e.metaKey || e.ctrlKey || e.shiftKey) return | ||
if (e.defaultPrevented) return | ||
// check target | ||
if (el.target) return; | ||
if (el.target) return | ||
// check for data-bypass attribute | ||
if (el.getAttribute('data-bypass') !== null) return; | ||
if (el.getAttribute('data-bypass') !== null) return | ||
// inspect the href | ||
var href = el.getAttribute('href'); | ||
if (!href || href.length === 0) return; | ||
let href = el.getAttribute('href') | ||
if (!href || href.length === 0) return | ||
// don't handle hash links | ||
if (href[0] === '#') return; | ||
if (href[0] === '#') return | ||
// external/absolute links | ||
if (href.indexOf('http://') === 0 || href.indexOf('https://') === 0) return; | ||
if (href.indexOf('http://') === 0 || href.indexOf('https://') === 0) return | ||
// email links | ||
if (href.indexOf('mailto:') === 0) return; | ||
if (href.indexOf('mailto:') === 0) return | ||
// don't intercept javascript links | ||
/* eslint-disable no-script-url */ | ||
if (href.indexOf('javascript:') === 0) return; | ||
if (href.indexOf('javascript:') === 0) return | ||
/* eslint-enable no-script-url */ | ||
return true; | ||
return true | ||
} | ||
@@ -139,5 +128,5 @@ | ||
function which(e) { | ||
e = e || window.event; | ||
return e.which === null ? e.button : e.which; | ||
} | ||
function which (e) { | ||
e = e || window.event | ||
return e.which === null ? e.button : e.which | ||
} |
@@ -1,34 +0,23 @@ | ||
'use strict'; | ||
import { extend } from '../dash' | ||
import LocationBar from 'location-bar' | ||
Object.defineProperty(exports, '__esModule', { | ||
value: true | ||
}); | ||
export default BrowserLocation | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
function BrowserLocation (options) { | ||
this.path = options.path || '' | ||
var _dash = require('../dash'); | ||
var _locationBar = require('location-bar'); | ||
var _locationBar2 = _interopRequireDefault(_locationBar); | ||
exports['default'] = BrowserLocation; | ||
function BrowserLocation(options) { | ||
this.path = options.path || ''; | ||
this.options = (0, _dash.extend)({ | ||
this.options = extend({ | ||
pushState: false, | ||
root: '/' | ||
}, options); | ||
}, options) | ||
// we're using the location-bar module for actual | ||
// URL management | ||
var self = this; | ||
this.locationBar = new _locationBar2['default'](); | ||
let self = this | ||
this.locationBar = new LocationBar() | ||
this.locationBar.onChange(function (path) { | ||
self.handleURL('/' + (path || '')); | ||
}); | ||
self.handleURL('/' + (path || '')) | ||
}) | ||
this.locationBar.start((0, _dash.extend)({}, options)); | ||
this.locationBar.start(extend({}, options)) | ||
} | ||
@@ -44,4 +33,4 @@ | ||
BrowserLocation.prototype.usesPushState = function () { | ||
return this.options.pushState && this.locationBar.hasPushState(); | ||
}; | ||
return this.options.pushState && this.locationBar.hasPushState() | ||
} | ||
@@ -53,4 +42,4 @@ /** | ||
BrowserLocation.prototype.getURL = function () { | ||
return this.path; | ||
}; | ||
return this.path | ||
} | ||
@@ -64,6 +53,6 @@ /** | ||
if (this.path !== path) { | ||
this.path = path; | ||
this.locationBar.update(path, (0, _dash.extend)({ trigger: true }, options)); | ||
this.path = path | ||
this.locationBar.update(path, extend({trigger: true}, options)) | ||
} | ||
}; | ||
} | ||
@@ -77,6 +66,6 @@ /** | ||
if (this.path !== path) { | ||
this.path = path; | ||
this.locationBar.update(path, (0, _dash.extend)({ trigger: true, replace: true }, options)); | ||
this.path = path | ||
this.locationBar.update(path, extend({trigger: true, replace: true}, options)) | ||
} | ||
}; | ||
} | ||
@@ -88,4 +77,4 @@ /** | ||
BrowserLocation.prototype.onChange = function (callback) { | ||
this.changeCallback = callback; | ||
}; | ||
this.changeCallback = callback | ||
} | ||
@@ -98,14 +87,14 @@ /** | ||
if (this.locationBar.hasPushState()) { | ||
var rootURL = this.options.root; | ||
let rootURL = this.options.root | ||
if (path !== '') { | ||
rootURL = rootURL.replace(/\/$/, ''); | ||
rootURL = rootURL.replace(/\/$/, '') | ||
} | ||
return rootURL + path; | ||
return rootURL + path | ||
} else { | ||
if (path[0] === '/') { | ||
path = path.substr(1); | ||
path = path.substr(1) | ||
} | ||
return '#' + path; | ||
return '#' + path | ||
} | ||
}; | ||
} | ||
@@ -122,7 +111,7 @@ /** | ||
if (this.options.pushState && this.options.root && this.options.root !== '/') { | ||
return url.replace(this.options.root, ''); | ||
return url.replace(this.options.root, '') | ||
} else { | ||
return url; | ||
return url | ||
} | ||
}; | ||
} | ||
@@ -133,4 +122,4 @@ /** | ||
BrowserLocation.prototype.destroy = function () { | ||
this.locationBar.stop(); | ||
}; | ||
this.locationBar.stop() | ||
} | ||
@@ -147,7 +136,6 @@ /** | ||
BrowserLocation.prototype.handleURL = function (url) { | ||
this.path = url; | ||
this.path = url | ||
if (this.changeCallback) { | ||
this.changeCallback(url); | ||
this.changeCallback(url) | ||
} | ||
}; | ||
module.exports = exports['default']; | ||
} |
@@ -1,55 +0,48 @@ | ||
'use strict'; | ||
import { extend } from '../dash' | ||
Object.defineProperty(exports, '__esModule', { | ||
value: true | ||
}); | ||
export default MemoryLocation | ||
var _dash = require('../dash'); | ||
exports['default'] = MemoryLocation; | ||
function MemoryLocation(options) { | ||
this.path = options.path || ''; | ||
function MemoryLocation (options) { | ||
this.path = options.path || '' | ||
} | ||
MemoryLocation.prototype.getURL = function () { | ||
return this.path; | ||
}; | ||
return this.path | ||
} | ||
MemoryLocation.prototype.setURL = function (path, options) { | ||
if (this.path !== path) { | ||
this.path = path; | ||
this.handleURL(this.getURL(), options); | ||
this.path = path | ||
this.handleURL(this.getURL(), options) | ||
} | ||
}; | ||
} | ||
MemoryLocation.prototype.replaceURL = function (path, options) { | ||
if (this.path !== path) { | ||
this.setURL(path, options); | ||
this.setURL(path, options) | ||
} | ||
}; | ||
} | ||
MemoryLocation.prototype.onChange = function (callback) { | ||
this.changeCallback = callback; | ||
}; | ||
this.changeCallback = callback | ||
} | ||
MemoryLocation.prototype.handleURL = function (url, options) { | ||
this.path = url; | ||
options = (0, _dash.extend)({ trigger: true }, options); | ||
this.path = url | ||
options = extend({trigger: true}, options) | ||
if (this.changeCallback && options.trigger) { | ||
this.changeCallback(url); | ||
this.changeCallback(url) | ||
} | ||
}; | ||
} | ||
MemoryLocation.prototype.usesPushState = function () { | ||
return false; | ||
}; | ||
return false | ||
} | ||
MemoryLocation.prototype.removeRoot = function (url) { | ||
return url; | ||
}; | ||
return url | ||
} | ||
MemoryLocation.prototype.formatURL = function (url) { | ||
return url; | ||
}; | ||
module.exports = exports['default']; | ||
return url | ||
} |
@@ -1,21 +0,12 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports["default"] = createLogger; | ||
function createLogger(log, options) { | ||
options = options || {}; | ||
export default function createLogger (log, options) { | ||
options = options || {} | ||
// falsy means no logging | ||
if (!log) return function () {}; | ||
if (!log) return () => {} | ||
// custom logging function | ||
if (log !== true) return log; | ||
if (log !== true) return log | ||
// true means use the default logger - console | ||
var fn = options.error ? console.error : console.info; | ||
let fn = options.error ? console.error : console.info | ||
return function () { | ||
fn.apply(console, arguments); | ||
}; | ||
fn.apply(console, arguments) | ||
} | ||
} | ||
module.exports = exports["default"]; |
120
lib/path.js
@@ -1,45 +0,30 @@ | ||
'use strict'; | ||
import invariant from './invariant' | ||
import pathToRegexp from 'path-to-regexp' | ||
Object.defineProperty(exports, '__esModule', { | ||
value: true | ||
}); | ||
let paramInjectMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$?]*[?+*]?)/g | ||
let specialParamChars = /[+*?]$/g | ||
let queryMatcher = /\?(.+)/ | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
let _compiledPatterns = {} | ||
var _invariant = require('./invariant'); | ||
var _invariant2 = _interopRequireDefault(_invariant); | ||
var _pathToRegexp = require('path-to-regexp'); | ||
var _pathToRegexp2 = _interopRequireDefault(_pathToRegexp); | ||
var paramInjectMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$?]*[?+*]?)/g; | ||
var specialParamChars = /[+*?]$/g; | ||
var queryMatcher = /\?(.+)/; | ||
var _compiledPatterns = {}; | ||
function compilePattern(pattern) { | ||
function compilePattern (pattern) { | ||
if (!(pattern in _compiledPatterns)) { | ||
var paramNames = []; | ||
var re = (0, _pathToRegexp2['default'])(pattern, paramNames); | ||
let paramNames = [] | ||
let re = pathToRegexp(pattern, paramNames) | ||
_compiledPatterns[pattern] = { | ||
matcher: re, | ||
paramNames: paramNames.map(function (p) { | ||
return p.name; | ||
}) | ||
}; | ||
paramNames: paramNames.map(p => p.name) | ||
} | ||
} | ||
return _compiledPatterns[pattern]; | ||
return _compiledPatterns[pattern] | ||
} | ||
var Path = { | ||
let Path = { | ||
/** | ||
* Returns true if the given path is absolute. | ||
*/ | ||
isAbsolute: function isAbsolute(path) { | ||
return path.charAt(0) === '/'; | ||
isAbsolute: function (path) { | ||
return path.charAt(0) === '/' | ||
}, | ||
@@ -50,4 +35,4 @@ | ||
*/ | ||
join: function join(a, b) { | ||
return a.replace(/\/*$/, '/') + b; | ||
join: function (a, b) { | ||
return a.replace(/\/*$/, '/') + b | ||
}, | ||
@@ -58,4 +43,4 @@ | ||
*/ | ||
extractParamNames: function extractParamNames(pattern) { | ||
return compilePattern(pattern).paramNames; | ||
extractParamNames: function (pattern) { | ||
return compilePattern(pattern).paramNames | ||
}, | ||
@@ -68,19 +53,19 @@ | ||
*/ | ||
extractParams: function extractParams(pattern, path) { | ||
var cp = compilePattern(pattern); | ||
var matcher = cp.matcher; | ||
var paramNames = cp.paramNames; | ||
var match = path.match(matcher); | ||
extractParams: function (pattern, path) { | ||
let cp = compilePattern(pattern) | ||
let matcher = cp.matcher | ||
let paramNames = cp.paramNames | ||
let match = path.match(matcher) | ||
if (!match) { | ||
return null; | ||
return null | ||
} | ||
var params = {}; | ||
let params = {} | ||
paramNames.forEach(function (paramName, index) { | ||
params[paramName] = match[index + 1] && decodeURIComponent(match[index + 1]); | ||
}); | ||
params[paramName] = match[index + 1] && decodeURIComponent(match[index + 1]) | ||
}) | ||
return params; | ||
return params | ||
}, | ||
@@ -92,8 +77,8 @@ | ||
*/ | ||
injectParams: function injectParams(pattern, params) { | ||
params = params || {}; | ||
injectParams: function (pattern, params) { | ||
params = params || {} | ||
return pattern.replace(paramInjectMatcher, function (match, param) { | ||
var paramName = param.replace(specialParamChars, ''); | ||
var lastChar = param.slice(-1); | ||
let paramName = param.replace(specialParamChars, '') | ||
let lastChar = param.slice(-1) | ||
@@ -103,15 +88,19 @@ // If param is optional don't check for existence | ||
if (params[paramName] == null) { | ||
return ''; | ||
return '' | ||
} | ||
} else { | ||
(0, _invariant2['default'])(params[paramName] != null, "Missing '%s' parameter for path '%s'", paramName, pattern); | ||
invariant( | ||
params[paramName] != null, | ||
"Missing '%s' parameter for path '%s'", | ||
paramName, pattern | ||
) | ||
} | ||
var paramValue = encodeURIComponent(params[paramName]); | ||
let paramValue = encodeURIComponent(params[paramName]) | ||
if (lastChar === '*' || lastChar === '+') { | ||
// restore / for splats | ||
paramValue = paramValue.replace('%2F', '/'); | ||
paramValue = paramValue.replace('%2F', '/') | ||
} | ||
return paramValue; | ||
}); | ||
return paramValue | ||
}) | ||
}, | ||
@@ -123,5 +112,5 @@ | ||
*/ | ||
extractQuery: function extractQuery(qs, path) { | ||
var match = path.match(queryMatcher); | ||
return match && qs.parse(match[1]); | ||
extractQuery: function (qs, path) { | ||
let match = path.match(queryMatcher) | ||
return match && qs.parse(match[1]) | ||
}, | ||
@@ -133,10 +122,10 @@ | ||
*/ | ||
withQuery: function withQuery(qs, path, query) { | ||
var queryString = qs.stringify(query, { indices: false }); | ||
withQuery: function (qs, path, query) { | ||
let queryString = qs.stringify(query, { indices: false }) | ||
if (queryString) { | ||
return Path.withoutQuery(path) + '?' + queryString; | ||
return Path.withoutQuery(path) + '?' + queryString | ||
} | ||
return path; | ||
return path | ||
}, | ||
@@ -147,8 +136,7 @@ | ||
*/ | ||
withoutQuery: function withoutQuery(path) { | ||
return path.replace(queryMatcher, ''); | ||
withoutQuery: function (path) { | ||
return path.replace(queryMatcher, '') | ||
} | ||
}; | ||
} | ||
exports['default'] = Path; | ||
module.exports = exports['default']; | ||
export default Path |
@@ -1,24 +0,18 @@ | ||
'use strict'; | ||
Object.defineProperty(exports, '__esModule', { | ||
value: true | ||
}); | ||
exports['default'] = { | ||
parse: function parse(querystring) { | ||
return querystring.split('&').reduce(function (acc, pair) { | ||
var parts = pair.split('='); | ||
acc[parts[0]] = decodeURIComponent(parts[1]); | ||
return acc; | ||
}, {}); | ||
export default { | ||
parse (querystring) { | ||
return querystring.split('&').reduce((acc, pair) => { | ||
let parts = pair.split('=') | ||
acc[parts[0]] = decodeURIComponent(parts[1]) | ||
return acc | ||
}, {}) | ||
}, | ||
stringify: function stringify(params) { | ||
return Object.keys(params).reduce(function (acc, key) { | ||
stringify (params) { | ||
return Object.keys(params).reduce((acc, key) => { | ||
if (params[key] !== undefined) { | ||
acc.push(key + '=' + encodeURIComponent(params[key])); | ||
acc.push(key + '=' + encodeURIComponent(params[key])) | ||
} | ||
return acc; | ||
}, []).join('&'); | ||
return acc | ||
}, []).join('&') | ||
} | ||
}; | ||
module.exports = exports['default']; | ||
} |
@@ -1,48 +0,14 @@ | ||
'use strict'; | ||
import { pick, clone, extend, isEqual, isString, find } from './dash' | ||
import dsl from './dsl' | ||
import Path from './path' | ||
import invariant from './invariant' | ||
import BrowserLocation from './locations/browser' | ||
import MemoryLocation from './locations/memory' | ||
import transition from './transition' | ||
import { intercept } from './links' | ||
import createLogger from './logger' | ||
import qs from './qs' | ||
Object.defineProperty(exports, '__esModule', { | ||
value: true | ||
}); | ||
exports['default'] = cherrytree; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
var _dash = require('./dash'); | ||
var _dsl = require('./dsl'); | ||
var _dsl2 = _interopRequireDefault(_dsl); | ||
var _path = require('./path'); | ||
var _path2 = _interopRequireDefault(_path); | ||
var _invariant = require('./invariant'); | ||
var _invariant2 = _interopRequireDefault(_invariant); | ||
var _locationsBrowser = require('./locations/browser'); | ||
var _locationsBrowser2 = _interopRequireDefault(_locationsBrowser); | ||
var _locationsMemory = require('./locations/memory'); | ||
var _locationsMemory2 = _interopRequireDefault(_locationsMemory); | ||
var _transition = require('./transition'); | ||
var _transition2 = _interopRequireDefault(_transition); | ||
var _links = require('./links'); | ||
var _logger = require('./logger'); | ||
var _logger2 = _interopRequireDefault(_logger); | ||
var _qs = require('./qs'); | ||
var _qs2 = _interopRequireDefault(_qs); | ||
function Cherrytree() { | ||
this.initialize.apply(this, arguments); | ||
function Cherrytree () { | ||
this.initialize.apply(this, arguments) | ||
} | ||
@@ -55,6 +21,6 @@ | ||
Cherrytree.prototype.initialize = function (options) { | ||
this.nextId = 1; | ||
this.state = {}; | ||
this.middleware = []; | ||
this.options = (0, _dash.extend)({ | ||
this.nextId = 1 | ||
this.state = {} | ||
this.middleware = [] | ||
this.options = extend({ | ||
location: 'browser', | ||
@@ -64,9 +30,11 @@ interceptLinks: true, | ||
Promise: Promise, | ||
qs: _qs2['default'] | ||
}, options); | ||
this.log = (0, _logger2['default'])(this.options.log); | ||
this.logError = (0, _logger2['default'])(this.options.logError, { error: true }); | ||
qs: qs | ||
}, options) | ||
this.log = createLogger(this.options.log) | ||
this.logError = createLogger(this.options.logError, { error: true }) | ||
(0, _invariant2['default'])(typeof this.options.Promise === 'function', 'Cherrytree requires an ES6 Promise implementation, ' + 'either as an explicit option or a global Promise'); | ||
}; | ||
invariant(typeof this.options.Promise === 'function', | ||
'Cherrytree requires an ES6 Promise implementation, ' + | ||
'either as an explicit option or a global Promise') | ||
} | ||
@@ -80,5 +48,5 @@ /** | ||
Cherrytree.prototype.use = function (middleware) { | ||
this.middleware.push(middleware); | ||
return this; | ||
}; | ||
this.middleware.push(middleware) | ||
return this | ||
} | ||
@@ -93,55 +61,79 @@ /** | ||
// create the route tree | ||
this.routes = (0, _dsl2['default'])(routes); | ||
this.routes = dsl(routes) | ||
// create the matcher list, which is like a flattened | ||
// list of routes = a list of all branches of the route tree | ||
var matchers = this.matchers = []; | ||
let matchers = this.matchers = [] | ||
// keep track of whether duplicate paths have been created, | ||
// in which case we'll warn the dev | ||
var dupes = {}; | ||
let dupes = {} | ||
// keep track of abstract routes to build index route forwarding | ||
let abstracts = {} | ||
eachBranch({ routes: this.routes }, [], function (routes) { | ||
eachBranch({routes: this.routes}, [], function (routes) { | ||
// concatenate the paths of the list of routes | ||
var path = routes.reduce(function (memo, r) { | ||
let path = routes.reduce(function (memo, r) { | ||
// reset if there's a leading slash, otherwise concat | ||
// and keep resetting the trailing slash | ||
return (r.path[0] === '/' ? r.path : memo + '/' + r.path).replace(/\/$/, ''); | ||
}, ''); | ||
return (r.path[0] === '/' ? r.path : memo + '/' + r.path).replace(/\/$/, '') | ||
}, '') | ||
// ensure we have a leading slash | ||
if (path === '') { | ||
path = '/'; | ||
path = '/' | ||
} | ||
let lastRoute = routes[routes.length - 1] | ||
if (lastRoute.options.abstract) { | ||
abstracts[path] = lastRoute.name | ||
return | ||
} | ||
// register routes | ||
matchers.push({ | ||
routes: routes, | ||
name: routes[routes.length - 1].name, | ||
name: lastRoute.name, | ||
path: path | ||
}); | ||
}) | ||
// dupe detection | ||
var lastRoute = routes[routes.length - 1]; | ||
if (dupes[path]) { | ||
throw new Error('Routes ' + dupes[path] + ' and ' + lastRoute.name + ' have the same url path \'' + path + '\''); | ||
throw new Error('Routes ' + dupes[path] + ' and ' + lastRoute.name + | ||
' have the same url path \'' + path + '\'') | ||
} | ||
dupes[path] = lastRoute.name; | ||
}); | ||
dupes[path] = lastRoute.name | ||
}) | ||
function eachBranch(node, memo, fn) { | ||
// check if there is an index route for each abstract route | ||
Object.keys(abstracts).forEach(function (path) { | ||
let matcher | ||
if (!dupes[path]) return | ||
matchers.some(function (m) { | ||
if (m.path === path) { | ||
matcher = m | ||
return true | ||
} | ||
}) | ||
matchers.push({ | ||
routes: matcher.routes, | ||
name: abstracts[path], | ||
path: path | ||
}) | ||
}) | ||
function eachBranch (node, memo, fn) { | ||
node.routes.forEach(function (route) { | ||
if (!abstract(route)) { | ||
fn(memo.concat(route)); | ||
fn(memo.concat(route)) | ||
if (route.routes.length) { | ||
eachBranch(route, memo.concat(route), fn) | ||
} | ||
if (route.routes && route.routes.length > 0) { | ||
eachBranch(route, memo.concat(route), fn); | ||
} | ||
}); | ||
}) | ||
} | ||
function abstract(route) { | ||
return route.options && route.options.abstract; | ||
} | ||
return this | ||
} | ||
return this; | ||
}; | ||
/** | ||
@@ -155,16 +147,12 @@ * Starts listening to the location changes. | ||
Cherrytree.prototype.listen = function (path) { | ||
var _this = this; | ||
var location = this.location = this.createLocation(path || ''); | ||
let location = this.location = this.createLocation(path || '') | ||
// setup the location onChange handler | ||
location.onChange(function (url) { | ||
return _this.dispatch(url); | ||
}); | ||
location.onChange((url) => this.dispatch(url)) | ||
// start intercepting links | ||
if (this.options.interceptLinks && location.usesPushState()) { | ||
this.interceptLinks(); | ||
this.interceptLinks() | ||
} | ||
// and also kick off the initial transition | ||
return this.dispatch(location.getURL()); | ||
}; | ||
return this.dispatch(location.getURL()) | ||
} | ||
@@ -180,12 +168,8 @@ /** | ||
*/ | ||
Cherrytree.prototype.transitionTo = function () { | ||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
Cherrytree.prototype.transitionTo = function (...args) { | ||
if (this.state.activeTransition) { | ||
return this.replaceWith.apply(this, args); | ||
return this.replaceWith.apply(this, args) | ||
} | ||
return this.doTransition('setURL', args); | ||
}; | ||
return this.doTransition('setURL', args) | ||
} | ||
@@ -202,10 +186,6 @@ /** | ||
*/ | ||
Cherrytree.prototype.replaceWith = function () { | ||
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
args[_key2] = arguments[_key2]; | ||
} | ||
Cherrytree.prototype.replaceWith = function (...args) { | ||
return this.doTransition('replaceURL', args) | ||
} | ||
return this.doTransition('replaceURL', args); | ||
}; | ||
/** | ||
@@ -221,16 +201,16 @@ * Create an href | ||
Cherrytree.prototype.generate = function (name, params, query) { | ||
(0, _invariant2['default'])(this.location, 'call .listen() before using .generate()'); | ||
var matcher = undefined; | ||
invariant(this.location, 'call .listen() before using .generate()') | ||
let matcher | ||
params = params || {}; | ||
query = query || {}; | ||
params = params || {} | ||
query = query || {} | ||
this.matchers.forEach(function (m) { | ||
if (m.name === name) { | ||
matcher = m; | ||
matcher = m | ||
} | ||
}); | ||
}) | ||
if (!matcher) { | ||
throw new Error('No route is named ' + name); | ||
throw new Error('No route is named ' + name) | ||
} | ||
@@ -243,11 +223,11 @@ | ||
// reaching out to the router.state if that's what they want. | ||
var currentParams = (0, _dash.clone)(this.state.params || {}); | ||
let currentParams = clone(this.state.params || {}) | ||
if (this.state.activeTransition) { | ||
currentParams = (0, _dash.clone)(this.state.activeTransition.params || {}); | ||
currentParams = clone(this.state.activeTransition.params || {}) | ||
} | ||
params = (0, _dash.extend)(currentParams, params); | ||
params = extend(currentParams, params) | ||
var url = _path2['default'].withQuery(this.options.qs, _path2['default'].injectParams(matcher.path, params), query); | ||
return this.location.formatURL(url); | ||
}; | ||
let url = Path.withQuery(this.options.qs, Path.injectParams(matcher.path, params), query) | ||
return this.location.formatURL(url) | ||
} | ||
@@ -259,13 +239,13 @@ /** | ||
Cherrytree.prototype.destroy = function () { | ||
if (this.location && this.location.destroy && this.location.destroy) { | ||
this.location.destroy(); | ||
if (this.location && this.location.destroy) { | ||
this.location.destroy() | ||
} | ||
if (this.disposeIntercept) { | ||
this.disposeIntercept(); | ||
this.disposeIntercept() | ||
} | ||
if (this.state.activeTransition) { | ||
this.state.activeTransition.cancel(); | ||
this.state.activeTransition.cancel() | ||
} | ||
this.state = {}; | ||
}; | ||
this.state = {} | ||
} | ||
@@ -282,21 +262,15 @@ /** | ||
Cherrytree.prototype.isActive = function (name, params, query) { | ||
params = params || {}; | ||
query = query || {}; | ||
params = params || {} | ||
query = query || {} | ||
var activeRoutes = this.state.routes || []; | ||
var activeParams = this.state.params || {}; | ||
var activeQuery = this.state.query || []; | ||
let activeRoutes = this.state.routes || [] | ||
let activeParams = this.state.params || {} | ||
let activeQuery = this.state.query || {} | ||
var isNameActive = !!(0, _dash.find)(activeRoutes, function (route) { | ||
return route.name === name; | ||
}); | ||
var areParamsActive = !!Object.keys(params).every(function (key) { | ||
return activeParams[key] === params[key]; | ||
}); | ||
var isQueryActive = !!Object.keys(query).every(function (key) { | ||
return activeQuery[key] === query[key]; | ||
}); | ||
let isActive = !!find(activeRoutes, route => route.name === name) | ||
isActive = isActive && !!Object.keys(params).every(key => activeParams[key] === params[key]) | ||
isActive = isActive && !!Object.keys(query).every(key => activeQuery[key] === query[key]) | ||
return isNameActive && areParamsActive && isQueryActive; | ||
}; | ||
return isActive | ||
} | ||
@@ -307,30 +281,28 @@ /** | ||
Cherrytree.prototype.doTransition = function (method, params) { | ||
var _this2 = this; | ||
let previousUrl = this.location.getURL() | ||
var previousUrl = this.location.getURL(); | ||
var url = params[0]; | ||
let url = params[0] | ||
if (url[0] !== '/') { | ||
url = this.generate.apply(this, params); | ||
url = url.replace(/^#/, '/'); | ||
url = this.generate.apply(this, params) | ||
url = url.replace(/^#/, '/') | ||
} | ||
if (this.options.pushState) { | ||
url = this.location.removeRoot(url); | ||
url = this.location.removeRoot(url) | ||
} | ||
var transition = this.dispatch(url); | ||
let transition = this.dispatch(url) | ||
transition['catch'](function (err) { | ||
transition.catch((err) => { | ||
if (err && err.type === 'TransitionCancelled') { | ||
// reset the URL in case the transition has been cancelled | ||
_this2.location.replaceURL(previousUrl, { trigger: false }); | ||
this.location.replaceURL(previousUrl, {trigger: false}) | ||
} | ||
return err; | ||
}); | ||
return err | ||
}) | ||
this.location[method](url, { trigger: false }); | ||
this.location[method](url, {trigger: false}) | ||
return transition; | ||
}; | ||
return transition | ||
} | ||
@@ -345,22 +317,20 @@ /** | ||
Cherrytree.prototype.match = function (path) { | ||
path = (path || '').replace(/\/$/, '') || '/'; | ||
var found = false; | ||
var params = undefined; | ||
var routes = []; | ||
var pathWithoutQuery = _path2['default'].withoutQuery(path); | ||
var qs = this.options.qs; | ||
this.matchers.forEach(function (matcher) { | ||
if (!found) { | ||
params = _path2['default'].extractParams(matcher.path, pathWithoutQuery); | ||
if (params) { | ||
found = true; | ||
routes = matcher.routes; | ||
} | ||
path = (path || '').replace(/\/$/, '') || '/' | ||
let params | ||
let routes = [] | ||
let pathWithoutQuery = Path.withoutQuery(path) | ||
let qs = this.options.qs | ||
this.matchers.some(function (matcher) { | ||
params = Path.extractParams(matcher.path, pathWithoutQuery) | ||
if (params) { | ||
routes = matcher.routes | ||
return true | ||
} | ||
}); | ||
}) | ||
return { | ||
routes: routes.map(descriptor), | ||
params: params || {}, | ||
query: _path2['default'].extractQuery(qs, path) || {} | ||
}; | ||
pathname: pathWithoutQuery, | ||
query: Path.extractQuery(qs, path) || {} | ||
} | ||
@@ -373,23 +343,25 @@ // clone the data (only a shallow clone of options) | ||
// will get to use pristine data. | ||
function descriptor(route) { | ||
function descriptor (route) { | ||
return { | ||
name: route.name, | ||
path: route.path, | ||
params: (0, _dash.pick)(params, _path2['default'].extractParamNames(route.path)), | ||
options: (0, _dash.clone)(route.options) | ||
}; | ||
params: pick(params, Path.extractParamNames(route.path)), | ||
options: clone(route.options) | ||
} | ||
} | ||
}; | ||
} | ||
Cherrytree.prototype.dispatch = function (path) { | ||
var match = this.match(path); | ||
var query = match.query; | ||
var pathname = _path2['default'].withoutQuery(path); | ||
let match = this.match(path) | ||
let query = match.query | ||
let pathname = match.pathname | ||
var activeTransition = this.state.activeTransition; | ||
let activeTransition = this.state.activeTransition | ||
// if we already have an active transition with all the same | ||
// params - return that and don't do anything else | ||
if (activeTransition && activeTransition.pathname === pathname && (0, _dash.isEqual)(activeTransition.query, query)) { | ||
return activeTransition; | ||
if (activeTransition && | ||
activeTransition.pathname === pathname && | ||
isEqual(activeTransition.query, query)) { | ||
return activeTransition | ||
} | ||
@@ -400,6 +372,6 @@ | ||
if (activeTransition) { | ||
var err = new Error('TransitionRedirected'); | ||
err.type = 'TransitionRedirected'; | ||
err.nextPath = path; | ||
activeTransition.cancel(err); | ||
let err = new Error('TransitionRedirected') | ||
err.type = 'TransitionRedirected' | ||
err.nextPath = path | ||
activeTransition.cancel(err) | ||
} | ||
@@ -412,4 +384,5 @@ | ||
if (!activeTransition) { | ||
if (this.state.pathname === pathname && (0, _dash.isEqual)(this.state.query, query)) { | ||
return (0, _transition2['default'])({ | ||
if (this.state.pathname === pathname && | ||
isEqual(this.state.query, query)) { | ||
return transition({ | ||
id: this.nextId++, | ||
@@ -420,7 +393,7 @@ path: path, | ||
router: this | ||
}, this.options.Promise); | ||
}, this.options.Promise) | ||
} | ||
} | ||
var t = (0, _transition2['default'])({ | ||
let t = transition({ | ||
id: this.nextId++, | ||
@@ -430,8 +403,8 @@ path: path, | ||
router: this | ||
}, this.options.Promise); | ||
}, this.options.Promise) | ||
this.state.activeTransition = t; | ||
this.state.activeTransition = t | ||
return t; | ||
}; | ||
return t | ||
} | ||
@@ -447,14 +420,14 @@ /** | ||
Cherrytree.prototype.createLocation = function (path) { | ||
var location = this.options.location; | ||
if (!(0, _dash.isString)(location)) { | ||
return location; | ||
let location = this.options.location | ||
if (!isString(location)) { | ||
return location | ||
} | ||
if (location === 'browser') { | ||
return new _locationsBrowser2['default']((0, _dash.pick)(this.options, ['pushState', 'root'])); | ||
return new BrowserLocation(pick(this.options, ['pushState', 'root'])) | ||
} else if (location === 'memory') { | ||
return new _locationsMemory2['default']({ path: path }); | ||
return new MemoryLocation({path}) | ||
} else { | ||
throw new Error('Location can be `browser`, `memory` or a custom implementation'); | ||
throw new Error('Location can be `browser`, `memory` or a custom implementation') | ||
} | ||
}; | ||
} | ||
@@ -467,21 +440,18 @@ /** | ||
Cherrytree.prototype.interceptLinks = function () { | ||
var _this3 = this; | ||
let clickHandler = typeof this.options.interceptLinks === 'function' | ||
? this.options.interceptLinks | ||
: defaultClickHandler | ||
this.disposeIntercept = intercept((event, link) => clickHandler(event, link, this)) | ||
var clickHandler = typeof this.options.interceptLinks === 'function' ? this.options.interceptLinks : defaultClickHandler; | ||
this.disposeIntercept = (0, _links.intercept)(function (event, link) { | ||
return clickHandler(event, link, _this3); | ||
}); | ||
function defaultClickHandler(event, link, router) { | ||
event.preventDefault(); | ||
router.transitionTo(router.location.removeRoot(link.getAttribute('href'))); | ||
function defaultClickHandler (event, link, router) { | ||
event.preventDefault() | ||
router.transitionTo(router.location.removeRoot(link.getAttribute('href'))) | ||
} | ||
}; | ||
} | ||
function cherrytree(options) { | ||
return new Cherrytree(options); | ||
export default function cherrytree (options) { | ||
return new Cherrytree(options) | ||
} | ||
cherrytree.BrowserLocation = _locationsBrowser2['default']; | ||
cherrytree.MemoryLocation = _locationsMemory2['default']; | ||
module.exports = exports['default']; | ||
cherrytree.BrowserLocation = BrowserLocation | ||
cherrytree.MemoryLocation = MemoryLocation |
@@ -1,50 +0,32 @@ | ||
'use strict'; | ||
import { clone } from './dash' | ||
import invariant from './invariant' | ||
Object.defineProperty(exports, '__esModule', { | ||
value: true | ||
}); | ||
exports['default'] = transition; | ||
export default function transition (options, Promise) { | ||
options = options || {} | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
let router = options.router | ||
let log = router.log | ||
let logError = router.logError | ||
var _dash = require('./dash'); | ||
let path = options.path | ||
let match = options.match | ||
let routes = match.routes | ||
let params = match.params | ||
let pathname = match.pathname | ||
let query = match.query | ||
var _invariant = require('./invariant'); | ||
let id = options.id | ||
let startTime = Date.now() | ||
log('---') | ||
log('Transition #' + id, 'to', path) | ||
log('Transition #' + id, 'routes:', routes.map(r => r.name)) | ||
log('Transition #' + id, 'params:', params) | ||
log('Transition #' + id, 'query:', query) | ||
var _invariant2 = _interopRequireDefault(_invariant); | ||
var _path = require('./path'); | ||
var _path2 = _interopRequireDefault(_path); | ||
function transition(options, Promise) { | ||
options = options || {}; | ||
var router = options.router; | ||
var log = router.log; | ||
var logError = router.logError; | ||
var path = options.path; | ||
var match = options.match; | ||
var routes = match.routes; | ||
var params = match.params; | ||
var query = match.query; | ||
var id = options.id; | ||
var startTime = Date.now(); | ||
log('---'); | ||
log('Transition #' + id, 'to', path); | ||
log('Transition #' + id, 'routes:', routes.map(function (r) { | ||
return r.name; | ||
})); | ||
log('Transition #' + id, 'params:', params); | ||
log('Transition #' + id, 'query:', query); | ||
// create the transition promise | ||
var resolve = undefined, | ||
reject = undefined; | ||
var promise = new Promise(function (res, rej) { | ||
resolve = res; | ||
reject = rej; | ||
}); | ||
let resolve, reject | ||
let promise = new Promise(function (res, rej) { | ||
resolve = res | ||
reject = rej | ||
}) | ||
@@ -56,97 +38,99 @@ // 1. make transition errors loud | ||
promise.then(function () { | ||
log('Transition #' + id, 'completed in', Date.now() - startTime + 'ms'); | ||
})['catch'](function (err) { | ||
log('Transition #' + id, 'completed in', (Date.now() - startTime) + 'ms') | ||
}).catch(function (err) { | ||
if (err.type !== 'TransitionRedirected' && err.type !== 'TransitionCancelled') { | ||
log('Transition #' + id, 'FAILED'); | ||
logError(err.stack); | ||
log('Transition #' + id, 'FAILED') | ||
logError(err.stack) | ||
} | ||
}); | ||
}) | ||
var cancelled = false; | ||
let cancelled = false | ||
var transition = { | ||
let transition = { | ||
id: id, | ||
prev: { | ||
routes: (0, _dash.clone)(router.state.routes) || [], | ||
routes: clone(router.state.routes) || [], | ||
path: router.state.path || '', | ||
pathname: router.state.pathname || '', | ||
params: (0, _dash.clone)(router.state.params) || {}, | ||
query: (0, _dash.clone)(router.state.query) || {} | ||
params: clone(router.state.params) || {}, | ||
query: clone(router.state.query) || {} | ||
}, | ||
routes: (0, _dash.clone)(routes), | ||
routes: clone(routes), | ||
path: path, | ||
pathname: _path2['default'].withoutQuery(path), | ||
params: (0, _dash.clone)(params), | ||
query: (0, _dash.clone)(query), | ||
redirectTo: function redirectTo() { | ||
return router.transitionTo.apply(router, arguments); | ||
pathname: pathname, | ||
params: clone(params), | ||
query: clone(query), | ||
redirectTo: function () { | ||
return router.transitionTo.apply(router, arguments) | ||
}, | ||
retry: function retry() { | ||
return router.transitionTo(path); | ||
retry: function () { | ||
return router.transitionTo(path) | ||
}, | ||
cancel: function cancel(err) { | ||
cancel: function (err) { | ||
if (router.state.activeTransition !== transition) { | ||
return; | ||
return | ||
} | ||
if (transition.isCancelled) { | ||
return; | ||
return | ||
} | ||
router.state.activeTransition = null; | ||
transition.isCancelled = true; | ||
cancelled = true; | ||
router.state.activeTransition = null | ||
transition.isCancelled = true | ||
cancelled = true | ||
if (!err) { | ||
err = new Error('TransitionCancelled'); | ||
err.type = 'TransitionCancelled'; | ||
err = new Error('TransitionCancelled') | ||
err.type = 'TransitionCancelled' | ||
} | ||
if (err.type === 'TransitionCancelled') { | ||
log('Transition #' + id, 'cancelled'); | ||
log('Transition #' + id, 'cancelled') | ||
} | ||
if (err.type === 'TransitionRedirected') { | ||
log('Transition #' + id, 'redirected'); | ||
log('Transition #' + id, 'redirected') | ||
} | ||
reject(err); | ||
reject(err) | ||
}, | ||
followRedirects: function followRedirects() { | ||
followRedirects: function () { | ||
return promise['catch'](function (reason) { | ||
if (router.state.activeTransition) { | ||
return router.state.activeTransition.followRedirects(); | ||
return router.state.activeTransition.followRedirects() | ||
} | ||
return Promise.reject(reason); | ||
}); | ||
return Promise.reject(reason) | ||
}) | ||
}, | ||
then: promise.then.bind(promise), | ||
'catch': promise['catch'].bind(promise) | ||
}; | ||
catch: promise.catch.bind(promise) | ||
} | ||
// here we handle calls to all of the middlewares | ||
function callNext(i, prevResult) { | ||
var middlewareName = undefined; | ||
function callNext (i, prevResult) { | ||
let middlewareName | ||
// if transition has been cancelled - nothing left to do | ||
if (cancelled) { | ||
return; | ||
return | ||
} | ||
// done | ||
if (i < router.middleware.length) { | ||
middlewareName = router.middleware[i].name || 'anonymous'; | ||
log('Transition #' + id, 'resolving middleware:', middlewareName); | ||
var middlewarePromise = undefined; | ||
middlewareName = router.middleware[i].name || 'anonymous' | ||
log('Transition #' + id, 'resolving middleware:', middlewareName) | ||
let middlewarePromise | ||
try { | ||
middlewarePromise = router.middleware[i](transition, prevResult); | ||
(0, _invariant2['default'])(transition !== middlewarePromise, 'Middleware %s returned a transition which resulted in a deadlock', middlewareName); | ||
middlewarePromise = router.middleware[i](transition, prevResult) | ||
invariant(transition !== middlewarePromise, 'Middleware %s returned a transition which resulted in a deadlock', middlewareName) | ||
} catch (err) { | ||
router.state.activeTransition = null; | ||
return reject(err); | ||
router.state.activeTransition = null | ||
return reject(err) | ||
} | ||
Promise.resolve(middlewarePromise).then(function (result) { | ||
callNext(i + 1, result); | ||
})['catch'](function (err) { | ||
log('Transition #' + id, 'resolving middleware:', middlewareName, 'FAILED'); | ||
router.state.activeTransition = null; | ||
reject(err); | ||
}); | ||
Promise.resolve(middlewarePromise) | ||
.then(function (result) { | ||
callNext(i + 1, result) | ||
}) | ||
.catch(function (err) { | ||
log('Transition #' + id, 'resolving middleware:', middlewareName, 'FAILED') | ||
router.state.activeTransition = null | ||
reject(err) | ||
}) | ||
} else { | ||
@@ -157,7 +141,7 @@ router.state = { | ||
path: path, | ||
pathname: _path2['default'].withoutQuery(path), | ||
pathname: pathname, | ||
params: params, | ||
query: query | ||
}; | ||
resolve(); | ||
} | ||
resolve() | ||
} | ||
@@ -167,16 +151,12 @@ } | ||
if (!options.noop) { | ||
Promise.resolve().then(function () { | ||
return callNext(0); | ||
}); | ||
Promise.resolve().then(() => callNext(0)) | ||
} else { | ||
resolve(); | ||
resolve() | ||
} | ||
if (options.noop) { | ||
transition.noop = true; | ||
transition.noop = true | ||
} | ||
return transition; | ||
return transition | ||
} | ||
module.exports = exports['default']; |
{ | ||
"name": "cherrytree", | ||
"version": "2.3.2", | ||
"version": "2.4.0", | ||
"description": "Cherrytree - a flexible hierarchical client side router", | ||
@@ -5,0 +5,0 @@ "main": "index", |
@@ -126,3 +126,3 @@ # <img src="https://cloud.githubusercontent.com/assets/324440/11302251/2c573b4a-8f94-11e5-9df6-889b19c2ad48.png" width="320" /> | ||
[![Build Status](https://travis-ci.org/QubitProducts/cherrytree.svg?branch=master)](https://travis-ci.org/QubitProducts/cherrytree) | ||
[![build status](https://www.codeship.io/projects/aa5e37b0-aeb1-0131-dd5f-06fd12e6a611/status?branch=master)](https://codeship.com/projects/19734) | ||
[![build status](https://codeship.com/projects/aa5e37b0-aeb1-0131-dd5f-06fd12e6a611/status?branch=master)](https://codeship.com/projects/19734) | ||
@@ -129,0 +129,0 @@ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 4 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
1077371
129
8064
1
6
1