diff --git a/examples/editor-bundle/index.html b/examples/editor-bundle/index.html
new file mode 100644
index 00000000..d988274e
--- /dev/null
+++ b/examples/editor-bundle/index.html
@@ -0,0 +1,34 @@
+
+
+
+ Markdown Editor
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/editor/index.html b/examples/editor/index.html
new file mode 100644
index 00000000..c9178f18
--- /dev/null
+++ b/examples/editor/index.html
@@ -0,0 +1,43 @@
+
+
+
+ Markdown Editor
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/threaditjs/app.js b/examples/threaditjs/app.js
index d8cb5b00..05085fe6 100644
--- a/examples/threaditjs/app.js
+++ b/examples/threaditjs/app.js
@@ -3,8 +3,8 @@ T.time("Setup");
var request = require("../../request/request")(window, Promise).ajax
var m = require("../../render/hyperscript")
var trust = require("../../render/trust")
-var render = require("../../render/render")(window, run).render
-var router = require("../../router/router")(window, "#")
+var renderer = require("../../render/render")(window)
+var router = require("../../router/router")(window)
//API calls
var api = {
@@ -178,16 +178,18 @@ var Reply = {
}
//router
+renderer.setEventCallback(run)
function run() {
replayRoute()
}
var root = document.getElementById("app")
+router.setPrefix("#")
var replayRoute = router.defineRoutes({
"/thread/:id" : Thread,
"/" : Home
}, function(view, args) {
- render(root, [m(view, args)])
+ renderer.render(root, [m(view, args)])
}, function() {
router.setPath("/")
})
diff --git a/examples/todomvc/todomvc.js b/examples/todomvc/todomvc.js
index 58136282..0aa2d5d5 100644
--- a/examples/todomvc/todomvc.js
+++ b/examples/todomvc/todomvc.js
@@ -1,6 +1,6 @@
var m = require("../../render/hyperscript")
-var render = require("../../render/render")(window, run).render
-var router = require("../../router/router")(window, "#")
+var renderer = require("../../render/render")(window)
+var router = require("../../router/router")(window)
//model
var todos = loadData()
@@ -124,14 +124,16 @@ function view() {
var root = document.getElementById("todoapp")
var raf
+renderer.setEventCallback(run)
function run() {
cancelAnimationFrame(raf)
raf = requestAnimationFrame(function() {
saveData()
- render(root, view())
+ renderer.render(root, view())
})
}
+router.setPrefix("#")
router.defineRoutes({
"/": "all",
"/active": "active",
diff --git a/mithril.js b/mithril.js
index dd2c1d20..c920b2d5 100644
--- a/mithril.js
+++ b/mithril.js
@@ -78,6 +78,7 @@ function hyperscript(selector) {
}
if (typeof selector === "string") return selectorCache[selector](attrs || {}, Node.normalizeChildren(children))
+
return Node(selector, attrs && attrs.key, attrs || {}, Node.normalizeChildren(children), undefined, undefined)
}
@@ -113,10 +114,7 @@ var createRenderer = function($window) {
}
function createNode(vnode, hooks) {
var tag = vnode.tag
- if (vnode.attrs) {
- if (vnode.attrs.oninit) vnode.attrs.oninit.call(vnode, vnode)
- if (vnode.attrs.oncreate) hooks.push(vnode.attrs.oncreate.bind(vnode, vnode))
- }
+ if (vnode.attrs != null) initLifecycle(vnode.attrs, vnode, hooks)
if (typeof tag === "string") {
switch (tag) {
case "#": return createText(vnode)
@@ -184,8 +182,10 @@ var createRenderer = function($window) {
return element
}
function createComponent(vnode, hooks) {
+ vnode.state = copy(vnode.tag)
+
initLifecycle(vnode.tag, vnode, hooks)
- vnode.instance = Node.normalize(vnode.tag.view.call(vnode, vnode))
+ vnode.instance = Node.normalize(vnode.tag.view.call(vnode.state, vnode))
var element = createNode(vnode.instance, hooks)
vnode.dom = vnode.instance.dom
vnode.domSize = vnode.instance.domSize
@@ -324,7 +324,7 @@ var createRenderer = function($window) {
}
}
function updateComponent(parent, old, vnode, hooks, nextSibling, recycling) {
- vnode.instance = Node.normalize(vnode.tag.view.call(vnode, vnode))
+ vnode.instance = Node.normalize(vnode.tag.view.call(vnode.state, vnode))
updateLifecycle(vnode.tag, vnode, hooks, recycling)
updateNode(parent, old.instance, vnode.instance, hooks, nextSibling, recycling)
vnode.dom = vnode.instance.dom
@@ -545,6 +545,20 @@ var createRenderer = function($window) {
}
return false
}
+
+ function copy(data) {
+ if (data instanceof Array) {
+ var output = []
+ for (var i = 0; i < data.length; i++) output[i] = copy(data[i])
+ return output
+ }
+ else if (typeof data === "object") {
+ var output = {}
+ for (var i in data) output[i] = copy(data[i])
+ return output
+ }
+ return data
+ }
function render(dom, vnodes) {
var hooks = []
@@ -564,13 +578,15 @@ var createRenderer = function($window) {
var createMounter = function($window, redraw) {
return function(root, component) {
- var render = createRenderer($window, draw).render
+ var renderer = createRenderer($window)
+ renderer.setEventCallback(draw)
function draw() {
- render(root, component)
+ renderer.render(root, {tag: component})
}
- redraw.run = redraw
+ redraw.run = draw
+ draw()
}
}
diff --git a/mount.js b/mount.js
index d6a0665b..3a389ba0 100644
--- a/mount.js
+++ b/mount.js
@@ -2,12 +2,14 @@ var createRenderer = require("./render/render")
module.exports = function($window, redraw) {
return function(root, component) {
- var render = createRenderer($window, draw).render
+ var renderer = createRenderer($window)
+ renderer.setEventCallback(draw)
function draw() {
- render(root, component)
+ renderer.render(root, {tag: component})
}
- redraw.run = redraw
+ redraw.run = draw
+ draw()
}
}
\ No newline at end of file
diff --git a/render/hyperscript.js b/render/hyperscript.js
index 58f8f3d5..8b407075 100644
--- a/render/hyperscript.js
+++ b/render/hyperscript.js
@@ -63,6 +63,7 @@ function hyperscript(selector) {
}
if (typeof selector === "string") return selectorCache[selector](attrs || {}, Node.normalizeChildren(children))
+
return Node(selector, attrs && attrs.key, attrs || {}, Node.normalizeChildren(children), undefined, undefined)
}
diff --git a/render/render.js b/render/render.js
index 2c0eb925..0c54d084 100644
--- a/render/render.js
+++ b/render/render.js
@@ -87,8 +87,10 @@ module.exports = function($window) {
return element
}
function createComponent(vnode, hooks) {
+ vnode.state = copy(vnode.tag)
+
initLifecycle(vnode.tag, vnode, hooks)
- vnode.instance = Node.normalize(vnode.tag.view.call(vnode, vnode))
+ vnode.instance = Node.normalize(vnode.tag.view.call(vnode.state, vnode))
var element = createNode(vnode.instance, hooks)
vnode.dom = vnode.instance.dom
vnode.domSize = vnode.instance.domSize
@@ -227,7 +229,7 @@ module.exports = function($window) {
}
}
function updateComponent(parent, old, vnode, hooks, nextSibling, recycling) {
- vnode.instance = Node.normalize(vnode.tag.view.call(vnode, vnode))
+ vnode.instance = Node.normalize(vnode.tag.view.call(vnode.state, vnode))
updateLifecycle(vnode.tag, vnode, hooks, recycling)
updateNode(parent, old.instance, vnode.instance, hooks, nextSibling, recycling)
vnode.dom = vnode.instance.dom
@@ -448,6 +450,20 @@ module.exports = function($window) {
}
return false
}
+
+ function copy(data) {
+ if (data instanceof Array) {
+ var output = []
+ for (var i = 0; i < data.length; i++) output[i] = copy(data[i])
+ return output
+ }
+ else if (typeof data === "object") {
+ var output = {}
+ for (var i in data) output[i] = copy(data[i])
+ return output
+ }
+ return data
+ }
function render(dom, vnodes) {
var hooks = []
diff --git a/render/tests/test-input.js b/render/tests/test-input.js
index 401895d8..ebff4147 100644
--- a/render/tests/test-input.js
+++ b/render/tests/test-input.js
@@ -14,6 +14,7 @@ o.spec("form inputs", function() {
})
o.afterEach(function() {
while (root.firstChild) root.removeChild(root.firstChild)
+ root.vnodes = null
})
o.spec("input", function() {