Skip to content

Instantly share code, notes, and snippets.

@aviks
Last active August 29, 2015 14:17
Show Gist options
  • Save aviks/16e883c1ac50662a5a02 to your computer and use it in GitHub Desktop.
Save aviks/16e883c1ac50662a5a02 to your computer and use it in GitHub Desktop.
Canvas.jl html output
<!doctype html>
<html>
<head><script>(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var VNode = require('vtree/vnode');
var svg = require('virtual-hyperscript/svg');
var VText = require('vtree/vtext');
var VPatch = require('vtree/vpatch');
var diff = require('virtual-dom/diff');
var patch = require('virtual-dom/patch');
var createElement = require('virtual-dom/create-element');
var nodeIndex = require('./node-index');
var patchVNode = require('./patch-vnode');
var isArray = require('x-is-array');
var isVPatch = require('./is-vpatch');
var P = Patchwork = {
nodes: {},
debug: false,
Node: function (id, jlNode, el) {
if (typeof(el) === "undefined") {
el = document.getElementById(id)
}
this.id = id
if (jlNode) {
// Note: makes this.root
var vnode = P.makeVNode(jlNode)
P.log("makeVNode: ", jlNode, "=>", vnode)
this.mount(vnode, el)
}
P.nodes[id] = this
},
NAMESPACES: {
"xhtml": null,
"svg": "http://www.w3.org/2000/svg",
null: null,
undefined: null
},
refDiff: function (a, b, p) {
var a = P.makeVNode(a)
b = P.makeVNode(b)
p = P.makeVPatches(a, p)
console.log(p, diff(a, b));
},
massageProps: function (props) {
if ("attributes" in props) {
// we can't send undefined over JSON, so we turn nulls into undefs
// so that VDom calls removeAttribute on the DOM node.
console.log("attributes ", props.attributes)
for (var attr in props.attributes) {
if (!props.attributes.hasOwnProperty(attr)) {
continue
}
if (props.attributes[attr] === null) {
console.log("remove ", attr, props.attributes[attr]);
props.attributes[attr] = undefined
}
}
}
return props;
},
makeVNode: function (jlNode) {
if ('txt' in jlNode) return new VText(jlNode.txt);
var children = [],
props = P.massageProps(jlNode.p || {})
if (jlNode.c) {
for (var i = 0, l = jlNode.c.length; i < l; i++) {
children[i] = P.makeVNode(jlNode.c[i])
}
}
if (jlNode.n === "svg") {
return svg(jlNode.t, props, children)
} else {
var key = null
if (props && props.key) {
key = props.key
delete props.key
}
return new VNode(jlNode.t,
props,
children,
key,
P.NAMESPACES[jlNode.n]);
}
},
makeVPatches: function (root, jlPatches) {
var indices = [];
var vpatches = {a: root}
for (var idx in jlPatches) {
indices.push(Number(idx))
}
nodes = nodeIndex(root, indices)
for (var idx in jlPatches) {
vpatches[idx] = P.makeVPatch(nodes[idx], jlPatches[idx]);
}
return vpatches
},
makeVPatch: function (vnode, jlPatch) {
if (isArray(jlPatch)) {
// multiple patches to the same VNode
var ps = [];
for (var i=0, l=jlPatch.length; i < l; i++) {
ps[i] = P.makeVPatch(vnode, jlPatch[i])
}
return ps
}
var type, patch;
for (var k in jlPatch) {
type = k;
patch = jlPatch[k];
break; // inorite?
}
function vpatch(p) { return new VPatch(type, vnode, p); }
switch (Number(type)) {
case VPatch.VTEXT:
return vpatch(new VText(patch));
case VPatch.VNODE:
return vpatch(P.makeVNode(patch));
case VPatch.PROPS:
patch = P.massageProps(patch)
if (vnode.namespace === P.NAMESPACES["svg"]) {
patch = svg('dummy', patch, []).properties
}
return vpatch(patch);
case VPatch.ORDER:
return vpatch(patch);
case VPatch.INSERT:
return vpatch(P.makeVNode(patch)); // What about vtext?
case VPatch.REMOVE:
return vpatch(null);
default:
return null;
}
},
log: function () {
if (console && P.debug) {
console.log.apply(console, arguments);
}
}
}
Patchwork.Node.prototype = {
mount: function (vnode, outer) {
var el = createElement(vnode);
P.log("createElement: ", vnode, "=>", el)
outer.appendChild(el)
this.element = el
this.root = vnode;
return el;
},
applyPatch: function (vpatches) {
// apply patch to DOM nodes
if (!isVPatch(vpatches)) {
vpatches = P.makeVPatches(this.root, vpatches)
}
this.element = patch(this.element, vpatches)
this.root = patchVNode(this.root, vpatches)
}
}
// IJulia setup
if (window.IPython && IPython && jQuery) {
$(document).ready(function () {
var commMgr = IPython.notebook.kernel.comm_manager;
commMgr.register_target("PatchStream", function (comm, msg) {
var nodeId = msg.content.data.pwid;
comm.on_msg(function (msg) {
var node = P.nodes[nodeId],
patches = msg.content.data
node.applyPatch(patches)
P.log("received patches", patches)
});
});
});
}
window.Patchwork = Patchwork;
},{"./is-vpatch":2,"./node-index":3,"./patch-vnode":52,"virtual-dom/create-element":5,"virtual-dom/diff":6,"virtual-dom/patch":14,"virtual-hyperscript/svg":38,"vtree/vnode":47,"vtree/vpatch":48,"vtree/vtext":49,"x-is-array":50}],2:[function(require,module,exports){
var version = require("vtree/version")
module.exports = isVirtualPatch
function isVirtualPatch(x) {
return x && x.type === "VirtualPatch" && x.version === version
}
},{"vtree/version":46}],3:[function(require,module,exports){
module.exports = nodeIndex
function nodeIndex(tree, indices, nodes) {
if (!indices || indices.length === 0) {
return {}
} else {
indices.sort(ascending)
return recurse(tree, indices, nodes, 0)
}
}
function recurse(tree, indices, nodes, rootIndex) {
nodes = nodes || {}
if (tree) {
if (indexInRange(indices, rootIndex, rootIndex)) {
nodes[rootIndex] = tree
}
var vChildren = tree.children
if (vChildren) {
for (var i = 0; i < vChildren.length; i++) {
rootIndex += 1
var vChild = vChildren[i]
var nextIndex = rootIndex + (vChild.count || 0)
// skip recursion down the tree if there are no nodes down here
if (indexInRange(indices, rootIndex, nextIndex)) {
recurse(vChild, indices, nodes, rootIndex)
}
rootIndex = nextIndex
}
}
} else {
rootIndex
}
return nodes
}
// Binary search for an index in the interval [left, right]
function indexInRange(indices, left, right) {
if (indices.length === 0) {
return false
}
var minIndex = 0
var maxIndex = indices.length - 1
var currentIndex
var currentItem
while (minIndex <= maxIndex) {
currentIndex = ((maxIndex + minIndex) / 2) >> 0
currentItem = indices[currentIndex]
if (minIndex === maxIndex) {
return currentItem >= left && currentItem <= right
} else if (currentItem < left) {
minIndex = currentIndex + 1
} else if (currentItem > right) {
maxIndex = currentIndex - 1
} else {
return true
}
}
return false;
}
function ascending(a, b) {
return a > b ? 1 : -1
}
},{}],4:[function(require,module,exports){
module.exports = isObject
function isObject(x) {
return typeof x === "object" && x !== null
}
},{}],5:[function(require,module,exports){
var createElement = require("vdom/create-element")
module.exports = createElement
},{"vdom/create-element":8}],6:[function(require,module,exports){
var diff = require("vtree/diff")
module.exports = diff
},{"vtree/diff":39}],7:[function(require,module,exports){
var isObject = require("is-object")
var isHook = require("vtree/is-vhook")
module.exports = applyProperties
function applyProperties(node, props, previous) {
for (var propName in props) {
var propValue = props[propName]
if (propValue === undefined) {
removeProperty(node, props, previous, propName);
} else if (isHook(propValue)) {
propValue.hook(node,
propName,
previous ? previous[propName] : undefined)
} else {
if (isObject(propValue)) {
patchObject(node, props, previous, propName, propValue);
} else if (propValue !== undefined) {
node[propName] = propValue
}
}
}
}
function removeProperty(node, props, previous, propName) {
if (previous) {
var previousValue = previous[propName]
if (!isHook(previousValue)) {
if (propName === "attributes") {
for (var attrName in previousValue) {
node.removeAttribute(attrName)
}
} else if (propName === "style") {
for (var i in previousValue) {
node.style[i] = ""
}
} else if (typeof previousValue === "string") {
node[propName] = ""
} else {
node[propName] = null
}
}
}
}
function patchObject(node, props, previous, propName, propValue) {
var previousValue = previous ? previous[propName] : undefined
// Set attributes
if (propName === "attributes") {
for (var attrName in propValue) {
var attrValue = propValue[attrName]
if (attrValue === undefined) {
node.removeAttribute(attrName)
} else {
node.setAttribute(attrName, attrValue)
}
}
return
}
if(previousValue && isObject(previousValue) &&
getPrototype(previousValue) !== getPrototype(propValue)) {
node[propName] = propValue
return
}
if (!isObject(node[propName])) {
node[propName] = {}
}
var replacer = propName === "style" ? "" : undefined
for (var k in propValue) {
var value = propValue[k]
node[propName][k] = (value === undefined) ? replacer : value
}
}
function getPrototype(value) {
if (Object.getPrototypeOf) {
return Object.getPrototypeOf(value)
} else if (value.__proto__) {
return value.__proto__
} else if (value.constructor) {
return value.constructor.prototype
}
}
},{"is-object":4,"vtree/is-vhook":42}],8:[function(require,module,exports){
var document = require("global/document")
var applyProperties = require("./apply-properties")
var isVNode = require("vtree/is-vnode")
var isVText = require("vtree/is-vtext")
var isWidget = require("vtree/is-widget")
var handleThunk = require("vtree/handle-thunk")
module.exports = createElement
function createElement(vnode, opts) {
var doc = opts ? opts.document || document : document
var warn = opts ? opts.warn : null
vnode = handleThunk(vnode).a
if (isWidget(vnode)) {
return vnode.init()
} else if (isVText(vnode)) {
return doc.createTextNode(vnode.text)
} else if (!isVNode(vnode)) {
if (warn) {
warn("Item is not a valid virtual dom node", vnode)
}
return null
}
var node = (vnode.namespace === null) ?
doc.createElement(vnode.tagName) :
doc.createElementNS(vnode.namespace, vnode.tagName)
var props = vnode.properties
applyProperties(node, props)
var children = vnode.children
for (var i = 0; i < children.length; i++) {
var childNode = createElement(children[i], opts)
if (childNode) {
node.appendChild(childNode)
}
}
return node
}
},{"./apply-properties":7,"global/document":10,"vtree/handle-thunk":40,"vtree/is-vnode":43,"vtree/is-vtext":44,"vtree/is-widget":45}],9:[function(require,module,exports){
// Maps a virtual DOM tree onto a real DOM tree in an efficient manner.
// We don't want to read all of the DOM nodes in the tree so we use
// the in-order tree indexing to eliminate recursion down certain branches.
// We only recurse into a DOM node if we know that it contains a child of
// interest.
var noChild = {}
module.exports = domIndex
function domIndex(rootNode, tree, indices, nodes) {
if (!indices || indices.length === 0) {
return {}
} else {
indices.sort(ascending)
return recurse(rootNode, tree, indices, nodes, 0)
}
}
function recurse(rootNode, tree, indices, nodes, rootIndex) {
nodes = nodes || {}
if (rootNode) {
if (indexInRange(indices, rootIndex, rootIndex)) {
nodes[rootIndex] = rootNode
}
var vChildren = tree.children
if (vChildren) {
var childNodes = rootNode.childNodes
for (var i = 0; i < tree.children.length; i++) {
rootIndex += 1
var vChild = vChildren[i] || noChild
var nextIndex = rootIndex + (vChild.count || 0)
// skip recursion down the tree if there are no nodes down here
if (indexInRange(indices, rootIndex, nextIndex)) {
recurse(childNodes[i], vChild, indices, nodes, rootIndex)
}
rootIndex = nextIndex
}
}
}
return nodes
}
// Binary search for an index in the interval [left, right]
function indexInRange(indices, left, right) {
if (indices.length === 0) {
return false
}
var minIndex = 0
var maxIndex = indices.length - 1
var currentIndex
var currentItem
while (minIndex <= maxIndex) {
currentIndex = ((maxIndex + minIndex) / 2) >> 0
currentItem = indices[currentIndex]
if (minIndex === maxIndex) {
return currentItem >= left && currentItem <= right
} else if (currentItem < left) {
minIndex = currentIndex + 1
} else if (currentItem > right) {
maxIndex = currentIndex - 1
} else {
return true
}
}
return false;
}
function ascending(a, b) {
return a > b ? 1 : -1
}
},{}],10:[function(require,module,exports){
(function (global){
var topLevel = typeof global !== 'undefined' ? global :
typeof window !== 'undefined' ? window : {}
var minDoc = require('min-document');
if (typeof document !== 'undefined') {
module.exports = document;
} else {
var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'];
if (!doccy) {
doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc;
}
module.exports = doccy;
}
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"min-document":54}],11:[function(require,module,exports){
var applyProperties = require("./apply-properties")
var isWidget = require("vtree/is-widget")
var VPatch = require("vtree/vpatch")
var render = require("./create-element")
var updateWidget = require("./update-widget")
module.exports = applyPatch
function applyPatch(vpatch, domNode, renderOptions) {
var type = vpatch.type
var vNode = vpatch.vNode
var patch = vpatch.patch
switch (type) {
case VPatch.REMOVE:
return removeNode(domNode, vNode)
case VPatch.INSERT:
return insertNode(domNode, patch, renderOptions)
case VPatch.VTEXT:
return stringPatch(domNode, vNode, patch, renderOptions)
case VPatch.WIDGET:
return widgetPatch(domNode, vNode, patch, renderOptions)
case VPatch.VNODE:
return vNodePatch(domNode, vNode, patch, renderOptions)
case VPatch.ORDER:
reorderChildren(domNode, patch)
return domNode
case VPatch.PROPS:
applyProperties(domNode, patch, vNode.properties)
return domNode
case VPatch.THUNK:
return replaceRoot(domNode,
renderOptions.patch(domNode, patch, renderOptions))
default:
return domNode
}
}
function removeNode(domNode, vNode) {
var parentNode = domNode.parentNode
if (parentNode) {
parentNode.removeChild(domNode)
}
destroyWidget(domNode, vNode);
return null
}
function insertNode(parentNode, vNode, renderOptions) {
var newNode = render(vNode, renderOptions)
if (parentNode) {
parentNode.appendChild(newNode)
}
return parentNode
}
function stringPatch(domNode, leftVNode, vText, renderOptions) {
var newNode
if (domNode.nodeType === 3) {
domNode.replaceData(0, domNode.length, vText.text)
newNode = domNode
} else {
var parentNode = domNode.parentNode
newNode = render(vText, renderOptions)
if (parentNode) {
parentNode.replaceChild(newNode, domNode)
}
}
destroyWidget(domNode, leftVNode)
return newNode
}
function widgetPatch(domNode, leftVNode, widget, renderOptions) {
if (updateWidget(leftVNode, widget)) {
return widget.update(leftVNode, domNode) || domNode
}
var parentNode = domNode.parentNode
var newWidget = render(widget, renderOptions)
if (parentNode) {
parentNode.replaceChild(newWidget, domNode)
}
destroyWidget(domNode, leftVNode)
return newWidget
}
function vNodePatch(domNode, leftVNode, vNode, renderOptions) {
var parentNode = domNode.parentNode
var newNode = render(vNode, renderOptions)
if (parentNode) {
parentNode.replaceChild(newNode, domNode)
}
destroyWidget(domNode, leftVNode)
return newNode
}
function destroyWidget(domNode, w) {
if (typeof w.destroy === "function" && isWidget(w)) {
w.destroy(domNode)
}
}
function reorderChildren(domNode, bIndex) {
var children = []
var childNodes = domNode.childNodes
var len = childNodes.length
var i
var reverseIndex = bIndex.reverse
for (i = 0; i < len; i++) {
children.push(domNode.childNodes[i])
}
var insertOffset = 0
var move
var node
var insertNode
for (i = 0; i < len; i++) {
move = bIndex[i]
if (move !== undefined && move !== i) {
// the element currently at this index will be moved later so increase the insert offset
if (reverseIndex[i] > i) {
insertOffset++
}
node = children[move]
insertNode = childNodes[i + insertOffset] || null
if (node !== insertNode) {
domNode.insertBefore(node, insertNode)
}
// the moved element came from the front of the array so reduce the insert offset
if (move < i) {
insertOffset--
}
}
// element at this index is scheduled to be removed so increase insert offset
if (i in bIndex.removes) {
insertOffset++
}
}
}
function replaceRoot(oldRoot, newRoot) {
if (oldRoot && newRoot && oldRoot !== newRoot && oldRoot.parentNode) {
console.log(oldRoot)
oldRoot.parentNode.replaceChild(newRoot, oldRoot)
}
return newRoot;
}
},{"./apply-properties":7,"./create-element":8,"./update-widget":13,"vtree/is-widget":45,"vtree/vpatch":48}],12:[function(require,module,exports){
var document = require("global/document")
var isArray = require("x-is-array")
var domIndex = require("./dom-index")
var patchOp = require("./patch-op")
module.exports = patch
function patch(rootNode, patches) {
return patchRecursive(rootNode, patches)
}
function patchRecursive(rootNode, patches, renderOptions) {
var indices = patchIndices(patches)
if (indices.length === 0) {
return rootNode
}
var index = domIndex(rootNode, patches.a, indices)
var ownerDocument = rootNode.ownerDocument
if (!renderOptions) {
renderOptions = { patch: patchRecursive }
if (ownerDocument !== document) {
renderOptions.document = ownerDocument
}
}
for (var i = 0; i < indices.length; i++) {
var nodeIndex = indices[i]
rootNode = applyPatch(rootNode,
index[nodeIndex],
patches[nodeIndex],
renderOptions)
}
return rootNode
}
function applyPatch(rootNode, domNode, patchList, renderOptions) {
if (!domNode) {
return rootNode
}
var newNode
if (isArray(patchList)) {
for (var i = 0; i < patchList.length; i++) {
newNode = patchOp(patchList[i], domNode, renderOptions)
if (domNode === rootNode) {
rootNode = newNode
}
}
} else {
newNode = patchOp(patchList, domNode, renderOptions)
if (domNode === rootNode) {
rootNode = newNode
}
}
return rootNode
}
function patchIndices(patches) {
var indices = []
for (var key in patches) {
if (key !== "a") {
indices.push(Number(key))
}
}
return indices
}
},{"./dom-index":9,"./patch-op":11,"global/document":10,"x-is-array":50}],13:[function(require,module,exports){
var isWidget = require("vtree/is-widget")
module.exports = updateWidget
function updateWidget(a, b) {
if (isWidget(a) && isWidget(b)) {
if ("name" in a && "name" in b) {
return a.id === b.id
} else {
return a.init === b.init
}
}
return false
}
},{"vtree/is-widget":45}],14:[function(require,module,exports){
var patch = require("vdom/patch")
module.exports = patch
},{"vdom/patch":12}],15:[function(require,module,exports){
module.exports = AttributeHook;
function AttributeHook(value) {
if (!(this instanceof AttributeHook)) {
return new AttributeHook(value);
}
this.value = value;
}
AttributeHook.prototype.hook = function (node, prop, prev) {
if (prev && prev.value === this.value) {
return;
}
node.setAttributeNS(null, prop, this.value)
}
},{}],16:[function(require,module,exports){
var DataSet = require("data-set")
module.exports = DataSetHook;
function DataSetHook(value) {
if (!(this instanceof DataSetHook)) {
return new DataSetHook(value);
}
this.value = value;
}
DataSetHook.prototype.hook = function (node, propertyName) {
var ds = DataSet(node)
var propName = propertyName.substr(5)
ds[propName] = this.value;
};
},{"data-set":21}],17:[function(require,module,exports){
var DataSet = require("data-set")
module.exports = DataSetHook;
function DataSetHook(value) {
if (!(this instanceof DataSetHook)) {
return new DataSetHook(value);
}
this.value = value;
}
DataSetHook.prototype.hook = function (node, propertyName) {
var ds = DataSet(node)
var propName = propertyName.substr(3)
ds[propName] = this.value;
};
},{"data-set":21}],18:[function(require,module,exports){
module.exports = SoftSetHook;
function SoftSetHook(value) {
if (!(this instanceof SoftSetHook)) {
return new SoftSetHook(value);
}
this.value = value;
}
SoftSetHook.prototype.hook = function (node, propertyName) {
if (node[propertyName] !== this.value) {
node[propertyName] = this.value;
}
};
},{}],19:[function(require,module,exports){
var VNode = require("vtree/vnode.js")
var VText = require("vtree/vtext.js")
var isVNode = require("vtree/is-vnode")
var isVText = require("vtree/is-vtext")
var isWidget = require("vtree/is-widget")
var isHook = require("vtree/is-vhook")
var isVThunk = require("vtree/is-thunk")
var TypedError = require("error/typed")
var parseTag = require("./parse-tag.js")
var softSetHook = require("./hooks/soft-set-hook.js")
var dataSetHook = require("./hooks/data-set-hook.js")
var evHook = require("./hooks/ev-hook.js")
var UnexpectedVirtualElement = TypedError({
type: "virtual-hyperscript.unexpected.virtual-element",
message: "Unexpected virtual child passed to h().\n" +
"Expected a VNode / Vthunk / VWidget / string but:\n" +
"got a {foreignObjectStr}.\n" +
"The parent vnode is {parentVnodeStr}.\n" +
"Suggested fix: change your `h(..., [ ... ])` callsite.",
foreignObjectStr: null,
parentVnodeStr: null,
foreignObject: null,
parentVnode: null
})
module.exports = h
function h(tagName, properties, children) {
var childNodes = []
var tag, props, key, namespace
if (!children && isChildren(properties)) {
children = properties
props = {}
}
props = props || properties || {}
tag = parseTag(tagName, props)
// support keys
if ("key" in props) {
key = props.key
props.key = undefined
}
// support namespace
if ("namespace" in props) {
namespace = props.namespace
props.namespace = undefined
}
// fix cursor bug
if (tag === "input" &&
"value" in props &&
props.value !== undefined &&
!isHook(props.value)
) {
props.value = softSetHook(props.value)
}
var keys = Object.keys(props)
var propName, value
for (var j = 0; j < keys.length; j++) {
propName = keys[j]
value = props[propName]
if (isHook(value)) {
continue
}
// add data-foo support
if (propName.substr(0, 5) === "data-") {
props[propName] = dataSetHook(value)
}
// add ev-foo support
if (propName.substr(0, 3) === "ev-") {
props[propName] = evHook(value)
}
}
if (children !== undefined && children !== null) {
addChild(children, childNodes, tag, props)
}
var node = new VNode(tag, props, childNodes, key, namespace)
return node
}
function addChild(c, childNodes, tag, props) {
if (typeof c === "string") {
childNodes.push(new VText(c))
} else if (isChild(c)) {
childNodes.push(c)
} else if (Array.isArray(c)) {
for (var i = 0; i < c.length; i++) {
addChild(c[i], childNodes, tag, props)
}
} else if (c === null || c === undefined) {
return
} else {
throw UnexpectedVirtualElement({
foreignObjectStr: JSON.stringify(c),
foreignObject: c,
parentVnodeStr: JSON.stringify({
tagName: tag,
properties: props
}),
parentVnode: {
tagName: tag,
properties: props
}
})
}
}
function isChild(x) {
return isVNode(x) || isVText(x) || isWidget(x) || isVThunk(x)
}
function isChildren(x) {
return typeof x === "string" || Array.isArray(x) || isChild(x)
}
},{"./hooks/data-set-hook.js":16,"./hooks/ev-hook.js":17,"./hooks/soft-set-hook.js":18,"./parse-tag.js":37,"error/typed":28,"vtree/is-thunk":29,"vtree/is-vhook":30,"vtree/is-vnode":31,"vtree/is-vtext":32,"vtree/is-widget":33,"vtree/vnode.js":35,"vtree/vtext.js":36}],20:[function(require,module,exports){
module.exports = createHash
function createHash(elem) {
var attributes = elem.attributes
var hash = {}
if (attributes === null || attributes === undefined) {
return hash
}
for (var i = 0; i < attributes.length; i++) {
var attr = attributes[i]
if (attr.name.substr(0,5) !== "data-") {
continue
}
hash[attr.name.substr(5)] = attr.value
}
return hash
}
},{}],21:[function(require,module,exports){
var createStore = require("weakmap-shim/create-store")
var Individual = require("individual")
var createHash = require("./create-hash.js")
var hashStore = Individual("__DATA_SET_WEAKMAP@3", createStore())
module.exports = DataSet
function DataSet(elem) {
var store = hashStore(elem)
if (!store.hash) {
store.hash = createHash(elem)
}
return store.hash
}
},{"./create-hash.js":20,"individual":22,"weakmap-shim/create-store":23}],22:[function(require,module,exports){
(function (global){
var root = typeof window !== 'undefined' ?
window : typeof global !== 'undefined' ?
global : {};
module.exports = Individual
function Individual(key, value) {
if (root[key]) {
return root[key]
}
Object.defineProperty(root, key, {
value: value
, configurable: true
})
return value
}
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],23:[function(require,module,exports){
var hiddenStore = require('./hidden-store.js');
module.exports = createStore;
function createStore() {
var key = {};
return function (obj) {
if (typeof obj !== 'object' || obj === null) {
throw new Error('Weakmap-shim: Key must be object')
}
var store = obj.valueOf(key);
return store && store.identity === key ?
store : hiddenStore(obj, key);
};
}
},{"./hidden-store.js":24}],24:[function(require,module,exports){
module.exports = hiddenStore;
function hiddenStore(obj, key) {
var store = { identity: key };
var valueOf = obj.valueOf;
Object.defineProperty(obj, "valueOf", {
value: function (value) {
return value !== key ?
valueOf.apply(this, arguments) : store;
},
writable: true
});
return store;
}
},{}],25:[function(require,module,exports){
module.exports = function(obj) {
if (typeof obj === 'string') return camelCase(obj);
return walk(obj);
};
function walk (obj) {
if (!obj || typeof obj !== 'object') return obj;
if (isDate(obj) || isRegex(obj)) return obj;
if (isArray(obj)) return map(obj, walk);
return reduce(objectKeys(obj), function (acc, key) {
var camel = camelCase(key);
acc[camel] = walk(obj[key]);
return acc;
}, {});
}
function camelCase(str) {
return str.replace(/[_.-](\w|$)/g, function (_,x) {
return x.toUpperCase();
});
}
var isArray = Array.isArray || function (obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
};
var isDate = function (obj) {
return Object.prototype.toString.call(obj) === '[object Date]';
};
var isRegex = function (obj) {
return Object.prototype.toString.call(obj) === '[object RegExp]';
};
var has = Object.prototype.hasOwnProperty;
var objectKeys = Object.keys || function (obj) {
var keys = [];
for (var key in obj) {
if (has.call(obj, key)) keys.push(key);
}
return keys;
};
function map (xs, f) {
if (xs.map) return xs.map(f);
var res = [];
for (var i = 0; i < xs.length; i++) {
res.push(f(xs[i], i));
}
return res;
}
function reduce (xs, f, acc) {
if (xs.reduce) return xs.reduce(f, acc);
for (var i = 0; i < xs.length; i++) {
acc = f(acc, xs[i], i);
}
return acc;
}
},{}],26:[function(require,module,exports){
var nargs = /\{([0-9a-zA-Z]+)\}/g
var slice = Array.prototype.slice
module.exports = template
function template(string) {
var args
if (arguments.length === 2 && typeof arguments[1] === "object") {
args = arguments[1]
} else {
args = slice.call(arguments, 1)
}
if (!args || !args.hasOwnProperty) {
args = {}
}
return string.replace(nargs, function replaceArg(match, i, index) {
var result
if (string[index - 1] === "{" &&
string[index + match.length] === "}") {
return i
} else {
result = args.hasOwnProperty(i) ? args[i] : null
if (result === null || result === undefined) {
return ""
}
return result
}
})
}
},{}],27:[function(require,module,exports){
module.exports = extend
function extend(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i]
for (var key in source) {
if (source.hasOwnProperty(key)) {
target[key] = source[key]
}
}
}
return target
}
},{}],28:[function(require,module,exports){
var camelize = require("camelize")
var template = require("string-template")
var extend = require("xtend/mutable")
module.exports = TypedError
function TypedError(args) {
if (!args) {
throw new Error("args is required");
}
if (!args.type) {
throw new Error("args.type is required");
}
if (!args.message) {
throw new Error("args.message is required");
}
var message = args.message
if (args.type && !args.name) {
var errorName = camelize(args.type) + "Error"
args.name = errorName[0].toUpperCase() + errorName.substr(1)
}
extend(createError, args);
createError._name = args.name;
return createError;
function createError(opts) {
var result = new Error()
Object.defineProperty(result, "type", {
value: result.type,
enumerable: true,
writable: true,
configurable: true
})
var options = extend({}, args, opts)
extend(result, options)
result.message = template(message, options)
return result
}
}
},{"camelize":25,"string-template":26,"xtend/mutable":27}],29:[function(require,module,exports){
module.exports = isThunk
function isThunk(t) {
return t && t.type === "Thunk"
}
},{}],30:[function(require,module,exports){
module.exports = isHook
function isHook(hook) {
return hook && typeof hook.hook === "function" &&
!hook.hasOwnProperty("hook")
}
},{}],31:[function(require,module,exports){
var version = require("./version")
module.exports = isVirtualNode
function isVirtualNode(x) {
return x && x.type === "VirtualNode" && x.version === version
}
},{"./version":34}],32:[function(require,module,exports){
var version = require("./version")
module.exports = isVirtualText
function isVirtualText(x) {
return x && x.type === "VirtualText" && x.version === version
}
},{"./version":34}],33:[function(require,module,exports){
module.exports = isWidget
function isWidget(w) {
return w && w.type === "Widget"
}
},{}],34:[function(require,module,exports){
module.exports = "1"
},{}],35:[function(require,module,exports){
var version = require("./version")
var isVNode = require("./is-vnode")
var isWidget = require("./is-widget")
var isVHook = require("./is-vhook")
module.exports = VirtualNode
var noProperties = {}
var noChildren = []
function VirtualNode(tagName, properties, children, key, namespace) {
this.tagName = tagName
this.properties = properties || noProperties
this.children = children || noChildren
this.key = key != null ? String(key) : undefined
this.namespace = (typeof namespace === "string") ? namespace : null
var count = (children && children.length) || 0
var descendants = 0
var hasWidgets = false
var descendantHooks = false
var hooks
for (var propName in properties) {
if (properties.hasOwnProperty(propName)) {
var property = properties[propName]
if (isVHook(property)) {
if (!hooks) {
hooks = {}
}
hooks[propName] = property
}
}
}
for (var i = 0; i < count; i++) {
var child = children[i]
if (isVNode(child)) {
descendants += child.count || 0
if (!hasWidgets && child.hasWidgets) {
hasWidgets = true
}
if (!descendantHooks && (child.hooks || child.descendantHooks)) {
descendantHooks = true
}
} else if (!hasWidgets && isWidget(child)) {
if (typeof child.destroy === "function") {
hasWidgets = true
}
}
}
this.count = count + descendants
this.hasWidgets = hasWidgets
this.hooks = hooks
this.descendantHooks = descendantHooks
}
VirtualNode.prototype.version = version
VirtualNode.prototype.type = "VirtualNode"
},{"./is-vhook":30,"./is-vnode":31,"./is-widget":33,"./version":34}],36:[function(require,module,exports){
var version = require("./version")
module.exports = VirtualText
function VirtualText(text) {
this.text = String(text)
}
VirtualText.prototype.version = version
VirtualText.prototype.type = "VirtualText"
},{"./version":34}],37:[function(require,module,exports){
var classIdSplit = /([\.#]?[a-zA-Z0-9_:-]+)/
var notClassId = /^\.|#/
module.exports = parseTag
function parseTag(tag, props) {
if (!tag) {
return "div"
}
var noId = !("id" in props)
var tagParts = tag.split(classIdSplit)
var tagName = null
if (notClassId.test(tagParts[1])) {
tagName = "div"
}
var classes, part, type, i
for (i = 0; i < tagParts.length; i++) {
part = tagParts[i]
if (!part) {
continue
}
type = part.charAt(0)
if (!tagName) {
tagName = part
} else if (type === ".") {
classes = classes || []
classes.push(part.substring(1, part.length))
} else if (type === "#" && noId) {
props.id = part.substring(1, part.length)
}
}
if (classes) {
if (props.className) {
classes.push(props.className)
}
props.className = classes.join(" ")
}
return tagName ? tagName.toLowerCase() : "div"
}
},{}],38:[function(require,module,exports){
var attributeHook = require("./hooks/attribute-hook.js")
var h = require("./index.js")
var BLACKLISTED_KEYS = {
"style": true,
"namespace": true,
"key": true
}
var SVG_NAMESPACE = "http://www.w3.org/2000/svg"
module.exports = svg
function svg(tagName, properties, children) {
if (!children && isChildren(properties)) {
children = properties
properties = {}
}
properties = properties || {}
// set namespace for svg
properties.namespace = SVG_NAMESPACE
// for each key, if attribute & string, bool or number then
// convert it into a setAttribute hook
for (var key in properties) {
if (!properties.hasOwnProperty(key)) {
continue
}
if (BLACKLISTED_KEYS[key]) {
continue
}
var value = properties[key]
if (typeof value !== "string" &&
typeof value !== "number" &&
typeof value !== "boolean"
) {
continue
}
properties[key] = attributeHook(value)
}
return h(tagName, properties, children)
}
function isChildren(x) {
return typeof x === "string" || Array.isArray(x)
}
},{"./hooks/attribute-hook.js":15,"./index.js":19}],39:[function(require,module,exports){
var isArray = require("x-is-array")
var isObject = require("is-object")
var VPatch = require("./vpatch")
var isVNode = require("./is-vnode")
var isVText = require("./is-vtext")
var isWidget = require("./is-widget")
var isThunk = require("./is-thunk")
var handleThunk = require("./handle-thunk")
module.exports = diff
function diff(a, b) {
var patch = { a: a }
walk(a, b, patch, 0)
return patch
}
function walk(a, b, patch, index) {
if (a === b) {
if (isThunk(a) || isThunk(b)) {
thunks(a, b, patch, index)
} else {
hooks(b, patch, index)
}
return
}
var apply = patch[index]
if (b == null) {
apply = appendPatch(apply, new VPatch(VPatch.REMOVE, a, b))
destroyWidgets(a, patch, index)
} else if (isThunk(a) || isThunk(b)) {
thunks(a, b, patch, index)
} else if (isVNode(b)) {
if (isVNode(a)) {
if (a.tagName === b.tagName &&
a.namespace === b.namespace &&
a.key === b.key) {
var propsPatch = diffProps(a.properties, b.properties, b.hooks)
if (propsPatch) {
apply = appendPatch(apply,
new VPatch(VPatch.PROPS, a, propsPatch))
}
apply = diffChildren(a, b, patch, apply, index)
} else {
apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b))
destroyWidgets(a, patch, index)
}
} else {
apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b))
destroyWidgets(a, patch, index)
}
} else if (isVText(b)) {
if (!isVText(a)) {
apply = appendPatch(apply, new VPatch(VPatch.VTEXT, a, b))
destroyWidgets(a, patch, index)
} else if (a.text !== b.text) {
apply = appendPatch(apply, new VPatch(VPatch.VTEXT, a, b))
}
} else if (isWidget(b)) {
apply = appendPatch(apply, new VPatch(VPatch.WIDGET, a, b))
if (!isWidget(a)) {
destroyWidgets(a, patch, index)
}
}
if (apply) {
patch[index] = apply
}
}
function diffProps(a, b, hooks) {
var diff
for (var aKey in a) {
if (!(aKey in b)) {
diff = diff || {}
diff[aKey] = undefined
}
var aValue = a[aKey]
var bValue = b[aKey]
if (hooks && aKey in hooks) {
diff = diff || {}
diff[aKey] = bValue
} else {
if (isObject(aValue) && isObject(bValue)) {
if (getPrototype(bValue) !== getPrototype(aValue)) {
diff = diff || {}
diff[aKey] = bValue
} else {
var objectDiff = diffProps(aValue, bValue)
if (objectDiff) {
diff = diff || {}
diff[aKey] = objectDiff
}
}
} else if (aValue !== bValue) {
diff = diff || {}
diff[aKey] = bValue
}
}
}
for (var bKey in b) {
if (!(bKey in a)) {
diff = diff || {}
diff[bKey] = b[bKey]
}
}
return diff
}
function getPrototype(value) {
if (Object.getPrototypeOf) {
return Object.getPrototypeOf(value)
} else if (value.__proto__) {
return value.__proto__
} else if (value.constructor) {
return value.constructor.prototype
}
}
function diffChildren(a, b, patch, apply, index) {
var aChildren = a.children
var bChildren = reorder(aChildren, b.children)
var aLen = aChildren.length
var bLen = bChildren.length
var len = aLen > bLen ? aLen : bLen
for (var i = 0; i < len; i++) {
var leftNode = aChildren[i]
var rightNode = bChildren[i]
index += 1
if (!leftNode) {
if (rightNode) {
// Excess nodes in b need to be added
apply = appendPatch(apply,
new VPatch(VPatch.INSERT, null, rightNode))
}
} else if (!rightNode) {
if (leftNode) {
// Excess nodes in a need to be removed
patch[index] = new VPatch(VPatch.REMOVE, leftNode, null)
destroyWidgets(leftNode, patch, index)
}
} else {
walk(leftNode, rightNode, patch, index)
}
if (isVNode(leftNode) && leftNode.count) {
index += leftNode.count
}
}
if (bChildren.moves) {
// Reorder nodes last
apply = appendPatch(apply, new VPatch(VPatch.ORDER, a, bChildren.moves))
}
return apply
}
// Patch records for all destroyed widgets must be added because we need
// a DOM node reference for the destroy function
function destroyWidgets(vNode, patch, index) {
if (isWidget(vNode)) {
if (typeof vNode.destroy === "function") {
patch[index] = new VPatch(VPatch.REMOVE, vNode, null)
}
} else if (isVNode(vNode) && vNode.hasWidgets) {
var children = vNode.children
var len = children.length
for (var i = 0; i < len; i++) {
var child = children[i]
index += 1
destroyWidgets(child, patch, index)
if (isVNode(child) && child.count) {
index += child.count
}
}
}
}
// Create a sub-patch for thunks
function thunks(a, b, patch, index) {
var nodes = handleThunk(a, b);
var thunkPatch = diff(nodes.a, nodes.b)
if (hasPatches(thunkPatch)) {
patch[index] = new VPatch(VPatch.THUNK, null, thunkPatch)
}
}
function hasPatches(patch) {
for (var index in patch) {
if (index !== "a") {
return true;
}
}
return false;
}
// Execute hooks when two nodes are identical
function hooks(vNode, patch, index) {
if (isVNode(vNode)) {
if (vNode.hooks) {
patch[index] = new VPatch(VPatch.PROPS, vNode.hooks, vNode.hooks)
}
if (vNode.descendantHooks) {
var children = vNode.children
var len = children.length
for (var i = 0; i < len; i++) {
var child = children[i]
index += 1
hooks(child, patch, index)
if (isVNode(child) && child.count) {
index += child.count
}
}
}
}
}
// List diff, naive left to right reordering
function reorder(aChildren, bChildren) {
var bKeys = keyIndex(bChildren)
if (!bKeys) {
return bChildren
}
var aKeys = keyIndex(aChildren)
if (!aKeys) {
return bChildren
}
var bMatch = {}, aMatch = {}
for (var key in bKeys) {
bMatch[bKeys[key]] = aKeys[key]
}
for (var key in aKeys) {
aMatch[aKeys[key]] = bKeys[key]
}
var aLen = aChildren.length
var bLen = bChildren.length
var len = aLen > bLen ? aLen : bLen
var shuffle = []
var freeIndex = 0
var i = 0
var moveIndex = 0
var moves = {}
var removes = moves.removes = {}
var reverse = moves.reverse = {}
var hasMoves = false
while (freeIndex < len) {
var move = aMatch[i]
if (move !== undefined) {
shuffle[i] = bChildren[move]
if (move !== moveIndex) {
moves[move] = moveIndex
reverse[moveIndex] = move
hasMoves = true
}
moveIndex++
} else if (i in aMatch) {
shuffle[i] = undefined
removes[i] = moveIndex++
hasMoves = true
} else {
while (bMatch[freeIndex] !== undefined) {
freeIndex++
}
if (freeIndex < len) {
var freeChild = bChildren[freeIndex]
if (freeChild) {
shuffle[i] = freeChild
if (freeIndex !== moveIndex) {
hasMoves = true
moves[freeIndex] = moveIndex
reverse[moveIndex] = freeIndex
}
moveIndex++
}
freeIndex++
}
}
i++
}
if (hasMoves) {
shuffle.moves = moves
}
return shuffle
}
function keyIndex(children) {
var i, keys
for (i = 0; i < children.length; i++) {
var child = children[i]
if (child.key !== undefined) {
keys = keys || {}
keys[child.key] = i
}
}
return keys
}
function appendPatch(apply, patch) {
if (apply) {
if (isArray(apply)) {
apply.push(patch)
} else {
apply = [apply, patch]
}
return apply
} else {
return patch
}
}
},{"./handle-thunk":40,"./is-thunk":41,"./is-vnode":43,"./is-vtext":44,"./is-widget":45,"./vpatch":48,"is-object":4,"x-is-array":50}],40:[function(require,module,exports){
var isVNode = require("./is-vnode")
var isVText = require("./is-vtext")
var isWidget = require("./is-widget")
var isThunk = require("./is-thunk")
module.exports = handleThunk
function handleThunk(a, b) {
var renderedA = a
var renderedB = b
if (isThunk(b)) {
renderedB = renderThunk(b, a)
}
if (isThunk(a)) {
renderedA = renderThunk(a, null)
}
return {
a: renderedA,
b: renderedB
}
}
function renderThunk(thunk, previous) {
var renderedThunk = thunk.vnode
if (!renderedThunk) {
renderedThunk = thunk.vnode = thunk.render(previous)
}
if (!(isVNode(renderedThunk) ||
isVText(renderedThunk) ||
isWidget(renderedThunk))) {
throw new Error("thunk did not return a valid node");
}
return renderedThunk
}
},{"./is-thunk":41,"./is-vnode":43,"./is-vtext":44,"./is-widget":45}],41:[function(require,module,exports){
arguments[4][29][0].apply(exports,arguments)
},{"dup":29}],42:[function(require,module,exports){
arguments[4][30][0].apply(exports,arguments)
},{"dup":30}],43:[function(require,module,exports){
arguments[4][31][0].apply(exports,arguments)
},{"./version":46,"dup":31}],44:[function(require,module,exports){
arguments[4][32][0].apply(exports,arguments)
},{"./version":46,"dup":32}],45:[function(require,module,exports){
arguments[4][33][0].apply(exports,arguments)
},{"dup":33}],46:[function(require,module,exports){
arguments[4][34][0].apply(exports,arguments)
},{"dup":34}],47:[function(require,module,exports){
arguments[4][35][0].apply(exports,arguments)
},{"./is-vhook":42,"./is-vnode":43,"./is-widget":45,"./version":46,"dup":35}],48:[function(require,module,exports){
var version = require("./version")
VirtualPatch.NONE = 0
VirtualPatch.VTEXT = 1
VirtualPatch.VNODE = 2
VirtualPatch.WIDGET = 3
VirtualPatch.PROPS = 4
VirtualPatch.ORDER = 5
VirtualPatch.INSERT = 6
VirtualPatch.REMOVE = 7
VirtualPatch.THUNK = 8
module.exports = VirtualPatch
function VirtualPatch(type, vNode, patch) {
this.type = Number(type)
this.vNode = vNode
this.patch = patch
}
VirtualPatch.prototype.version = version
VirtualPatch.prototype.type = "VirtualPatch"
},{"./version":46}],49:[function(require,module,exports){
arguments[4][36][0].apply(exports,arguments)
},{"./version":46,"dup":36}],50:[function(require,module,exports){
var nativeIsArray = Array.isArray
var toString = Object.prototype.toString
module.exports = nativeIsArray || isArray
function isArray(obj) {
return toString.call(obj) === "[object Array]"
}
},{}],51:[function(require,module,exports){
isObject = require('is-object')
module.exports = {reorder: reorder,
patchObject: patchObject}
function reorder(array, moves) {
if (!arr) { return }
var copy = array.slice(0)
for (var i=0, l=array.length; i < l; i++) {
var move = moves[i]
if (move !== undefined) {
array[move] = copy[i]
}
}
return array
}
function patchObject(obj, patch) {
for (var key in patch) {
if (isObject(patch[key]) && isObject(obj[key])) {
obj[key] = patchObject(obj[key], patch[key]);
} else {
obj[key] = patch[key]
}
}
}
},{"is-object":4}],52:[function(require,module,exports){
var mutateNode = require("./vnode-patch-op")
var isArray = require('x-is-array')
module.exports = patchVNode
function patchVNode(root, patches) {
linkParents(root)
for (var key in patches) {
if (key === "a") continue
patch = patches[key]
if (isArray(patch)) {
for (var i=0, l=patch.length; i < l; i++) {
mutateNode(patch[i].type, patch[i].vNode, patch[i].patch)
}
} else {
mutateNode(patch.type, patch.vNode, patch.patch)
}
}
return root
}
function linkParents(vNode) {
if (!vNode || !vNode.children) { return }
var children = vNode.children
for (var i=0, l=children.length; i < l; i++) {
children[i].up = vNode
linkParents(children[i])
}
}
},{"./vnode-patch-op":53,"x-is-array":50}],53:[function(require,module,exports){
var isWidget = require("vtree/is-widget")
var VPatch = require("vtree/vpatch")
var patchUtil = require("./patch-util.js")
module.exports = applyPatch
function applyPatch(type, vNode, patch) {
switch (type) {
case VPatch.REMOVE:
return removeNode(vNode)
case VPatch.INSERT:
return insertNode(vNode, patch)
case VPatch.VTEXT:
return stringPatch(vNode, patch)
case VPatch.VNODE:
return vNodePatch(vNode, patch)
case VPatch.ORDER:
patchUtil.reorder(vNode.children, patch)
return vNode
case VPatch.PROPS:
patchUtil.patchObject(vNode.properties, patch)
return vNode
default:
return vNode
}
}
function offsetCount(node, count) {
if (!node) { return }
if (node.count !== undefined) {
node.count = node.count + count
offsetCount(node.up, count)
} else {
node.count = count
}
}
function removeNode(node) {
if (!node) { return }
var count = node.count,
up = node.up
var idx = up.children.indexOf(node)
if (idx > -1) {
up.children.splice(idx, 1)
offsetCount(up, -node.count - 1)
}
delete node
return null
}
function insertNode(node, child) {
node.children.push(child)
offsetCount(node, child.count + 1)
child.up = node
return node
}
function stringPatch(node, patch) {
node.text = patch.text
return node
}
function vNodePatch(node, patch) {
var up = node.up,
idx = up.children.indexOf(node),
count = patch.count || 0
if (idx > -1) {
up.children[idx] = patch
if (node.count != count) {
offsetCount(up, count - node.count)
}
}
return node
}
},{"./patch-util.js":51,"vtree/is-widget":45,"vtree/vpatch":48}],54:[function(require,module,exports){
},{}]},{},[1]);
</script><link rel="import" href="/assets/basics.html"></head> <body unresolved><div id="root" class="canvasRoot"></div><script>new Canvasd("examples", "root");</script></body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment