From 53a1e6026ad0e2e83360e7325fee361ff7ec0f07 Mon Sep 17 00:00:00 2001 From: Yoshua Wuyts Date: Thu, 12 May 2016 14:45:20 +0700 Subject: [PATCH] choo: add href / history handling --- examples/http/client.js | 7 ++-- examples/http/models/sent.js | 15 ++++++++ examples/http/views/main.js | 3 +- index.js | 70 ++++++++++++++++++++---------------- 4 files changed, 61 insertions(+), 34 deletions(-) diff --git a/examples/http/client.js b/examples/http/client.js index 32c32cf..2bdb663 100644 --- a/examples/http/client.js +++ b/examples/http/client.js @@ -5,7 +5,7 @@ sf('css-wipe/dest/bundle') sf('tachyons') const mainView = require('./views/main') -const navElement = require('./elements/nav') +const nav = require('./elements/nav') const app = choo() @@ -14,7 +14,10 @@ app.model('spam', require('./models/spam')) app.model('sent', require('./models/sent')) app.router((route) => [ - route('/', mainView(navElement)) + route('/', mainView(nav)), + route('/:mailbox', mainView(nav), [ + route('/:message_id', mainView(nav)) + ]) ]) const tree = app.start() diff --git a/examples/http/models/sent.js b/examples/http/models/sent.js index e69de29..75b7bb7 100644 --- a/examples/http/models/sent.js +++ b/examples/http/models/sent.js @@ -0,0 +1,15 @@ +module.exports = { + state: { + messages: [ + { + id: 4, + subject: 'Should I use Ember', + from: 'user@example.com', + to: 'tomster@emberjs.com', + date: new Date(), + body: 'Ember looks pretty good, should I use it?' + } + ] + }, + reducers: { } +} diff --git a/examples/http/views/main.js b/examples/http/views/main.js index 7335529..c0bea4f 100644 --- a/examples/http/views/main.js +++ b/examples/http/views/main.js @@ -3,9 +3,10 @@ const choo = require('../../../') module.exports = function (nav) { return function (params, state, send) { + console.log(state) return choo.view`
- URL: ${pathname(state.location) || '/'} + URL: ${'/' + pathname(state.location)} ${nav(params, state, send)}
diff --git a/index.js b/index.js index add9550..755c4a7 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,8 @@ -// const history = require('sheet-router/history') +const history = require('sheet-router/history') const sheetRouter = require('sheet-router') const document = require('global/document') -// const href = require('sheet-router/href') +const href = require('sheet-router/href') const sendAction = require('send-action') -const mutate = require('xtend/mutable') const xtend = require('xtend') const yo = require('yo-yo') @@ -12,7 +11,9 @@ module.exports = choo // A framework for creating sturdy web applications // null -> fn -function choo () { +function choo (opts) { + opts = opts || {} + const name = opts.name || 'choo' var _router = null var _models = [ appInit() ] @@ -27,20 +28,33 @@ function choo () { function start () { const events = bootstrap(_models) const send = sendAction({ - onaction: events.middleware, + onaction: events.modifyState, onchange: onchange, state: events.state }) + if (opts.href !== false) { + href(function (href) { + send('location', { location: href }) + }) + } + + if (opts.history !== false) { + history(function (href) { + send('location', { location: href }) + }) + } + + const rootId = name + '-root' const tree = _router(send.state().location, send.state(), send) - tree.setAttribute('id', 'choo-root') + tree.setAttribute('id', rootId) return tree // update on every change function onchange (action, state) { - const oldTree = document.querySelector('#choo-root') + const oldTree = document.querySelector('#' + rootId) const newTree = _router(state.location, state, send) - newTree.setAttribute('id', 'choo-root') + newTree.setAttribute('id', rootId) yo.update(oldTree, newTree) } } @@ -60,6 +74,8 @@ function choo () { } } +// initial application state model +// null -> obj function appInit () { return { state: { @@ -78,35 +94,18 @@ function appInit () { } function bootstrap (events) { - const initialState = { } + const initialState = {} const reducers = {} const effects = {} - events.forEach(function (event) { - const name = event.name - if (event.state) mutate(initialState, event.state) - if (event.reducers) { - Object.keys(event.reducers).forEach(function (key) { - if (name) { - reducers[name + ':' + key] = event.reducers[key] - } else { - reducers[key] = event.reducers[key] - } - }) - } - if (event.effects) { - Object.keys(event.effects).forEach(function (key) { - if (name) { - effects[name + ':' + key] = event.effects[key] - } else { - effects[key] = event.effects[key] - } - }) - } + events.forEach(function (model) { + if (model.state) apply(model.name, model.state, initialState) + if (model.reducers) apply(model.name, model.reducers, reducers) + if (model.effects) apply(model.name, model.effects, effects) }) return { - middleware: modifyState, + modifyState: modifyState, state: initialState } @@ -133,3 +132,12 @@ function bootstrap (events) { return newState } } + +// compose an object conditionally +// (str, obj, obj) -> null +function apply (name, source, target) { + Object.keys(source).forEach(function (key) { + if (name) target[name + ':' + key] = source[key] + else target[key] = source[key] + }) +}