Skip to content

Commit

Permalink
Use es5 native methods
Browse files Browse the repository at this point in the history
  • Loading branch information
KidkArolis committed Aug 31, 2015
1 parent 2a9794f commit 02141db
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 58 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Make params, query and route array immutable between transitions, i.e. modifying those directly on the transition only affects that transition
* Replace `paramNames` with `params` in the route descriptor
* Drop the `ancestors` attribute from the route descriptor
* Drop support for es3 environments (IE8), to use Cherrytree - es5 polyfills for native `map`, `reduce` and `forEach` needs to be used now

### v2.0.0-alpha.12

Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ In an AMD environment, require the standalone UMD build - this version has all o

require('cherrytree/standalone')

# Environment

Cherrytree requires es5 environment and es6 promises. If you have to support older browsers, you will have to use polyfills, e.g.:

* https://github.com/es-shims/es5-shim
* https://github.com/jakearchibald/es6-promise

# Size

The size excluding all deps is ~10.96 kB gzipped and the standalone build with all deps is ~12.82 kB gzipped.
Expand Down
53 changes: 19 additions & 34 deletions lib/dash.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,28 @@
// helpers
let toString = Object.prototype.toString
let keys = Object.keys
let apply = (fn, args) => fn.apply(null, args)
let identity = x => x
let append = (item, list) => { list.push(item); return list }
let assoc = (obj, attr, val) => { obj[attr] = val; return obj }
let isArray = obj => toString.call(obj) === '[object Array]'

// exports
export let reduce = (list = [], iterator = identity, ...rest) => {
let i = rest.length ? 0 : 1
let acc = rest.length ? rest[0] : list[0]
let keyList = keys(list)
for (let len = keyList.length; i < len; i++) {
let key = keyList[i]
acc = apply(iterator, [acc, list[key], key, list])
}
return acc
}

export let map = (list, iterator) =>
reduce(list, (acc, value, i) =>
append(apply(iterator, [value, i]), acc), [])

export let each = (...args) => { apply(map, args) }

export let pluck = (list, attr) => map(list, item => item[attr])

export let toArray = args => Array.prototype.slice.call(args)

export let isArray = obj => Object.prototype.toString.call(obj) === '[object Array]'

export let clone = obj => isArray(obj) ? obj.slice(0) : extend({}, obj)
export let clone = obj =>
isArray(obj)
? obj.slice(0)
: extend({}, obj)

export let pick = (obj, attrs) =>
reduce(attrs, (acc, attr) =>
attrs.reduce((acc, attr) =>
assoc(acc, attr, obj[attr]), {})

export let extend = (obj1, obj2) =>
reduce(obj2 || {}, (__, value, key) => assoc(obj1, key, value), obj1 || {})

export let isEqual = (obj1, obj2) =>
keys(obj1).length === keys(obj2).length &&
reduce(obj1, (acc, value, key) => acc && obj2[key] === value, true)
keys(obj1).reduce((acc, key) => acc && obj2[key] === obj1[key], true)

export let extend = (obj, ...rest) => {
rest.forEach(source => {
if (source) {
for (var prop in source) {
obj[prop] = source[prop]
}
}
})
return obj
}
3 changes: 1 addition & 2 deletions lib/path.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
var _ = require('./dash')
var invariant = require('./invariant')
var merge = require('qs/lib/utils').merge
var qs = require('qs')
Expand All @@ -17,7 +16,7 @@ function compilePattern (pattern) {

_compiledPatterns[pattern] = {
matcher: re,
paramNames: _.pluck(paramNames, 'name')
paramNames: paramNames.map(p => p.name)
}
}

Expand Down
20 changes: 10 additions & 10 deletions lib/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Cherrytree.prototype.map = function (routes) {

eachBranch({routes: this.routes}, [], function (routes) {
// concatenate the paths of the list of routes
var path = _.reduce(routes, function (memo, r) {
var 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(/\/$/, '')
Expand All @@ -92,7 +92,7 @@ Cherrytree.prototype.map = function (routes) {
})

function eachBranch (node, memo, fn) {
_.each(node.routes, function (route) {
node.routes.forEach(function (route) {
if (!route.routes || route.routes.length === 0) {
fn.call(null, memo.concat(route))
} else {
Expand Down Expand Up @@ -132,11 +132,11 @@ Cherrytree.prototype.listen = function (location) {
*
* @api public
*/
Cherrytree.prototype.transitionTo = function () {
Cherrytree.prototype.transitionTo = function (...args) {
if (this.state.activeTransition) {
return this.replaceWith.apply(this, arguments)
return this.replaceWith.apply(this, args)
}
return this.doTransition('setURL', _.toArray(arguments))
return this.doTransition('setURL', args)
}

/**
Expand All @@ -149,8 +149,8 @@ Cherrytree.prototype.transitionTo = function () {
*
* @api public
*/
Cherrytree.prototype.replaceWith = function () {
return this.doTransition('replaceURL', _.toArray(arguments))
Cherrytree.prototype.replaceWith = function (...args) {
return this.doTransition('replaceURL', args)
}

/**
Expand All @@ -169,7 +169,7 @@ Cherrytree.prototype.generate = function (name, params, query) {
params = params || {}
query = query || {}

_.each(this.matchers, function (m) {
this.matchers.forEach(function (m) {
if (m.name === name) {
matcher = m
}
Expand Down Expand Up @@ -264,7 +264,7 @@ Cherrytree.prototype.match = function (path) {
var query
var routes = []
var pathWithoutQuery = Path.withoutQuery(path)
_.each(this.matchers, function (matcher) {
this.matchers.forEach(function (matcher) {
if (!found) {
params = Path.extractParams(matcher.path, pathWithoutQuery)
if (params) {
Expand All @@ -275,7 +275,7 @@ Cherrytree.prototype.match = function (path) {
}
})
return {
routes: _.map(routes, descriptor),
routes: routes.map(descriptor),
params: params || {},
query: query || {}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/transition.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module.exports = function transition (options, Promise) {
let startTime = Date.now()
log('---')
log('Transition #' + id, 'to', path)
log('Transition #' + id, 'routes:', _.pluck(routes, 'name'))
log('Transition #' + id, 'routes:', routes.map(r => r.name))
log('Transition #' + id, 'params:', params)
log('Transition #' + id, 'query:', query)

Expand Down
46 changes: 35 additions & 11 deletions tests/unit/dashTest.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,46 @@
let {assert} = require('referee')
let {assert, refute} = require('referee')
let {suite, test} = window
let _ = require('../../lib/dash')
let {clone, pick, isEqual, extend} = require('../../lib/dash')

suite('_')
suite('dash')

test('map', () => {
assert.equals(_.map([1, 2, 3], i => i * 2), [2, 4, 6])
test('clone arrays', () => {
let a = [1, 2, 3]
let b = clone(a)
b.push(4)
assert.equals(a, [1, 2, 3])
assert.equals(b, [1, 2, 3, 4])
})

test('clone objects', () => {
let a = {a: 1, b: 2}
let b = clone(a)
b.c = 3
assert.equals(a, {a: 1, b: 2})
assert.equals(b, {a: 1, b: 2, c: 3})
})

test('pick', () => {
assert.equals(_.pick({a: 1, b: 2, c: 3}, ['a', 'c']), {a: 1, c: 3})
assert.equals(pick({a: 1, b: 2, c: 3}, ['a', 'c']), {a: 1, c: 3})
})

test('pluck', () => {
assert.equals(_.pluck([{a: 1, b: 2}, {a: 3, b: 4}], 'a'), [1, 3])
test('isEqual', () => {
let arr = []
assert(isEqual({a: 1, b: 2}, {a: 1, b: 2}))
assert(isEqual({a: 1, b: arr}, {a: 1, b: arr}))
refute(isEqual({a: 1, b: 2}, {a: 1, b: '2'}))
refute(isEqual({a: 1, b: 2}, {a: 1}))
refute(isEqual({a: 1, b: {c: 3}}, {a: 1, b: {c: 3}}))
})

test('isArray', () => {
assert.equals(_.isArray([]), true)
assert.equals(_.isArray({}), false)
test('extend', () => {
assert.equals(extend({}, {a: 1, b: 2}, null, {c: 3}), {a: 1, b: 2, c: 3})

let obj = {d: 4}
let target = {}
extend(target, obj)
target.a = 1
obj.b = 2
assert.equals(obj, {b: 2, d: 4})
assert.equals(target, {a: 1, d: 4})
})

0 comments on commit 02141db

Please sign in to comment.