Skip to content

Commit

Permalink
Allows to customize the patch & rendering function.
Browse files Browse the repository at this point in the history
  • Loading branch information
jails committed Apr 6, 2015
1 parent 1dda0f6 commit 519fd8d
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 12 deletions.
9 changes: 4 additions & 5 deletions vdom/patch-op.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ var applyProperties = require("./apply-properties")
var isWidget = require("../vnode/is-widget.js")
var VPatch = require("../vnode/vpatch.js")

var render = require("./create-element")
var updateWidget = require("./update-widget")

module.exports = applyPatch
Expand Down Expand Up @@ -51,7 +50,7 @@ function removeNode(domNode, vNode) {
}

function insertNode(parentNode, vNode, renderOptions) {
var newNode = render(vNode, renderOptions)
var newNode = renderOptions.render(vNode, renderOptions)

if (parentNode) {
parentNode.appendChild(newNode)
Expand All @@ -68,7 +67,7 @@ function stringPatch(domNode, leftVNode, vText, renderOptions) {
newNode = domNode
} else {
var parentNode = domNode.parentNode
newNode = render(vText, renderOptions)
newNode = renderOptions.render(vText, renderOptions)

if (parentNode && newNode !== domNode) {
parentNode.replaceChild(newNode, domNode)
Expand All @@ -85,7 +84,7 @@ function widgetPatch(domNode, leftVNode, widget, renderOptions) {
if (updating) {
newNode = widget.update(leftVNode, domNode) || domNode
} else {
newNode = render(widget, renderOptions)
newNode = renderOptions.render(widget, renderOptions)
}

var parentNode = domNode.parentNode
Expand All @@ -103,7 +102,7 @@ function widgetPatch(domNode, leftVNode, widget, renderOptions) {

function vNodePatch(domNode, leftVNode, vNode, renderOptions) {
var parentNode = domNode.parentNode
var newNode = render(vNode, renderOptions)
var newNode = renderOptions.render(vNode, renderOptions)

if (parentNode && newNode !== domNode) {
parentNode.replaceChild(newNode, domNode)
Expand Down
16 changes: 9 additions & 7 deletions vdom/patch.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
var document = require("global/document")
var isArray = require("x-is-array")

var render = require("./create-element")
var domIndex = require("./dom-index")
var patchOp = require("./patch-op")
module.exports = patch

function patch(rootNode, patches) {
return patchRecursive(rootNode, patches)
function patch(rootNode, patches, renderOptions) {
renderOptions = renderOptions || {}
renderOptions.patch = renderOptions.patch || patchRecursive
renderOptions.render = renderOptions.render || render

return renderOptions.patch(rootNode, patches, renderOptions)
}

function patchRecursive(rootNode, patches, renderOptions) {
Expand All @@ -19,11 +24,8 @@ function patchRecursive(rootNode, patches, renderOptions) {
var index = domIndex(rootNode, patches.a, indices)
var ownerDocument = rootNode.ownerDocument

if (!renderOptions) {
renderOptions = { patch: patchRecursive }
if (ownerDocument !== document) {
renderOptions.document = ownerDocument
}
if (!renderOptions.document && ownerDocument !== document) {
renderOptions.document = ownerDocument
}

for (var i = 0; i < indices.length; i++) {
Expand Down
2 changes: 2 additions & 0 deletions vdom/test/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
require("./dom-index")
require("./patch-index")
require("./patch-op-index")
29 changes: 29 additions & 0 deletions vdom/test/patch-index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
var test = require("tape")
var VNode = require("../../vnode/vnode")
var VText = require("../../vnode/vtext")
var diff = require("../../vtree/diff")

var createElement = require("../create-element")
var patch = require("../patch")

test("overrided patch function is correctly used and received correct options", function (assert) {

function patchCustom(rootNode, patches, renderOptions) {
return {
rootNode: rootNode,
patches: patches,
renderOptions: renderOptions
}
}
function createElementCustom(vnode) {}

var rootNode = new VNode("div")
var patches = {}
var renderOptions = { patch: patchCustom, render: createElementCustom }

var result = patch(rootNode, patches, renderOptions)
assert.equal(result.rootNode, rootNode)
assert.equal(result.patches, patches)
assert.equal(result.renderOptions, renderOptions)
assert.end()
})
56 changes: 56 additions & 0 deletions vdom/test/patch-op-index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
var test = require("tape")
var VNode = require("../../vnode/vnode")
var VText = require("../../vnode/vtext")
var diff = require("../../vtree/diff")
var document = require("global/document")

var createElement = require("../create-element")
var patch = require("../patch")

var createElementCustom = function(vnode) {
var created = createElement(vnode)
created.customCreation = true
return created
}

function assertPachedNodeIsMarked(leftNode, rightNode, assert) {
var root = createElementCustom(leftNode)
var patches = diff(leftNode, rightNode)
var newRoot = patch(root, patches, { render: createElementCustom })
assert.equal(newRoot.childNodes[0].customCreation, true)
assert.end()
}

test("overrided createElement is used on node insertion", function (assert) {
var leftNode = new VNode("div")
var rightNode = new VNode("div", {}, [new VNode("div")])

assertPachedNodeIsMarked(leftNode, rightNode, assert)
})

test("overrided createElement is used for patching vnodes", function (assert) {
var leftNode = new VNode("div", {}, [new VNode("div")])
var rightNode = new VNode("div", {}, [new VNode("span")])

assertPachedNodeIsMarked(leftNode, rightNode, assert)
})

test("overrided createElement is used for patching text nodes", function (assert) {
var leftNode = new VNode("div", {}, [new VNode("div")])
var rightNode = new VNode("div", {}, [new VText("hello")])

assertPachedNodeIsMarked(leftNode, rightNode, assert)
})

test("overrided createElement is used for patching widget nodes", function (assert) {
var Widget = function (){}
Widget.prototype.type = "Widget"
Widget.prototype.init = function(){ return document.createElement("div") }
Widget.prototype.update = function(previous, domNode){ return null }
Widget.prototype.destroy = function(domNode){}

var leftNode = new VNode("div", {}, [new VNode("div")])
var rightNode = new VNode("div", {}, [new Widget()])

assertPachedNodeIsMarked(leftNode, rightNode, assert)
})

0 comments on commit 519fd8d

Please sign in to comment.