made with requirebin
Last active
August 18, 2022 21:45
-
-
Save Raynos/1156430c25a28cd8cfe1 to your computer and use it in GitHub Desktop.
requirebin sketch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var mercury = require("mercury") | |
var h = mercury.h | |
var clicks = mercury.input() | |
var clickCount = mercury.value(0) | |
clicks(function () { | |
clickCount.set(clickCount() + 1) | |
}) | |
function render(clickCount) { | |
return h("div.counter", [ | |
"The state ", h("code", "clickCount"), | |
" has value: " + clickCount + ".", h("input.button", { | |
type: "button", | |
value: "Click me!", | |
"ev-click": mercury.event(clicks) | |
}) | |
]) | |
} | |
mercury.app(document.body, clickCount, render) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// mercury @ 5.0.2 | |
!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.mercury=e()}}(function(){var define,module,exports;return (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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.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(_dereq_,module,exports){ | |
var SingleEvent = _dereq_("geval/single") | |
var MultipleEvent = _dereq_("geval/multiple") | |
/* | |
Pro tip: Don't require `mercury` itself. | |
require and depend on all these modules directly! | |
*/ | |
var mercury = module.exports = { | |
// Entry | |
main: _dereq_("main-loop"), | |
app: app, | |
// Input | |
Delegator: _dereq_("dom-delegator"), | |
input: input, | |
event: _dereq_("value-event/event"), | |
valueEvent: _dereq_("value-event/value"), | |
submitEvent: _dereq_("value-event/submit"), | |
changeEvent: _dereq_("value-event/change"), | |
keyEvent: _dereq_("value-event/key"), | |
// State | |
array: _dereq_("observ-array"), | |
struct: _dereq_("observ-struct"), | |
// alias struct as hash for back compat | |
hash: _dereq_("observ-struct"), | |
varhash: _dereq_("observ-varhash"), | |
value: _dereq_("observ"), | |
// Render | |
diff: _dereq_("virtual-dom/diff"), | |
patch: _dereq_("virtual-dom/patch"), | |
partial: _dereq_("vdom-thunk"), | |
create: _dereq_("virtual-dom/create-element"), | |
h: _dereq_("virtual-hyperscript"), | |
svg: _dereq_("virtual-hyperscript/svg"), | |
// Utilities | |
computed: _dereq_("observ/computed"), | |
watch: _dereq_("observ/watch") | |
} | |
function input(names) { | |
if (!names) { | |
return SingleEvent() | |
} | |
return MultipleEvent(names) | |
} | |
function app(elem, observ, render, opts) { | |
mercury.Delegator(opts); | |
var loop = mercury.main(observ(), render, opts) | |
observ(loop.update) | |
elem.appendChild(loop.target) | |
} | |
},{"dom-delegator":6,"geval/multiple":16,"geval/single":17,"main-loop":19,"observ":36,"observ-array":22,"observ-struct":25,"observ-varhash":27,"observ/computed":35,"observ/watch":37,"value-event/change":39,"value-event/event":40,"value-event/key":41,"value-event/submit":47,"value-event/value":48,"vdom-thunk":49,"virtual-dom/create-element":50,"virtual-dom/diff":51,"virtual-dom/patch":55,"virtual-hyperscript":75,"virtual-hyperscript/svg":82}],2:[function(_dereq_,module,exports){ | |
},{}],3:[function(_dereq_,module,exports){ | |
/** | |
* cuid.js | |
* Collision-resistant UID generator for browsers and node. | |
* Sequential for fast db lookups and recency sorting. | |
* Safe for element IDs and server-side lookups. | |
* | |
* Extracted from CLCTR | |
* | |
* Copyright (c) Eric Elliott 2012 | |
* MIT License | |
*/ | |
/*global window, navigator, document, require, process, module */ | |
(function (app) { | |
'use strict'; | |
var namespace = 'cuid', | |
c = 0, | |
blockSize = 4, | |
base = 36, | |
discreteValues = Math.pow(base, blockSize), | |
pad = function pad(num, size) { | |
var s = "000000000" + num; | |
return s.substr(s.length-size); | |
}, | |
randomBlock = function randomBlock() { | |
return pad((Math.random() * | |
discreteValues << 0) | |
.toString(base), blockSize); | |
}, | |
safeCounter = function () { | |
c = (c < discreteValues) ? c : 0; | |
c++; // this is not subliminal | |
return c - 1; | |
}, | |
api = function cuid() { | |
// Starting with a lowercase letter makes | |
// it HTML element ID friendly. | |
var letter = 'c', // hard-coded allows for sequential access | |
// timestamp | |
// warning: this exposes the exact date and time | |
// that the uid was created. | |
timestamp = (new Date().getTime()).toString(base), | |
// Prevent same-machine collisions. | |
counter, | |
// A few chars to generate distinct ids for different | |
// clients (so different computers are far less | |
// likely to generate the same id) | |
fingerprint = api.fingerprint(), | |
// Grab some more chars from Math.random() | |
random = randomBlock() + randomBlock(); | |
counter = pad(safeCounter().toString(base), blockSize); | |
return (letter + timestamp + counter + fingerprint + random); | |
}; | |
api.slug = function slug() { | |
var date = new Date().getTime().toString(36), | |
counter, | |
print = api.fingerprint().slice(0,1) + | |
api.fingerprint().slice(-1), | |
random = randomBlock().slice(-2); | |
counter = safeCounter().toString(36).slice(-4); | |
return date.slice(-2) + | |
counter + print + random; | |
}; | |
api.globalCount = function globalCount() { | |
// We want to cache the results of this | |
var cache = (function calc() { | |
var i, | |
count = 0; | |
for (i in window) { | |
count++; | |
} | |
return count; | |
}()); | |
api.globalCount = function () { return cache; }; | |
return cache; | |
}; | |
api.fingerprint = function browserPrint() { | |
return pad((navigator.mimeTypes.length + | |
navigator.userAgent.length).toString(36) + | |
api.globalCount().toString(36), 4); | |
}; | |
// don't change anything from here down. | |
if (app.register) { | |
app.register(namespace, api); | |
} else if (typeof module !== 'undefined') { | |
module.exports = api; | |
} else { | |
app[namespace] = api; | |
} | |
}(this.applitude || this)); | |
},{}],4:[function(_dereq_,module,exports){ | |
var DataSet = _dereq_("data-set") | |
module.exports = addEvent | |
function addEvent(target, type, handler) { | |
var ds = DataSet(target) | |
var events = ds[type] | |
if (!events) { | |
ds[type] = handler | |
} else if (Array.isArray(events)) { | |
if (events.indexOf(handler) === -1) { | |
events.push(handler) | |
} | |
} else if (events !== handler) { | |
ds[type] = [events, handler] | |
} | |
} | |
},{"data-set":8}],5:[function(_dereq_,module,exports){ | |
var globalDocument = _dereq_("global/document") | |
var DataSet = _dereq_("data-set") | |
var addEvent = _dereq_("./add-event.js") | |
var removeEvent = _dereq_("./remove-event.js") | |
var ProxyEvent = _dereq_("./proxy-event.js") | |
module.exports = DOMDelegator | |
function DOMDelegator(document) { | |
document = document || globalDocument | |
this.target = document.documentElement | |
this.events = {} | |
this.rawEventListeners = {} | |
this.globalListeners = {} | |
} | |
DOMDelegator.prototype.addEventListener = addEvent | |
DOMDelegator.prototype.removeEventListener = removeEvent | |
DOMDelegator.prototype.addGlobalEventListener = | |
function addGlobalEventListener(eventName, fn) { | |
var listeners = this.globalListeners[eventName] | |
if (!listeners) { | |
listeners = this.globalListeners[eventName] = [] | |
} | |
if (listeners.indexOf(fn) === -1) { | |
listeners.push(fn) | |
} | |
} | |
DOMDelegator.prototype.removeGlobalEventListener = | |
function removeGlobalEventListener(eventName, fn) { | |
var listeners = this.globalListeners[eventName] | |
if (!listeners) { | |
return | |
} | |
var index = listeners.indexOf(fn) | |
if (index !== -1) { | |
listeners.splice(index, 1) | |
} | |
} | |
DOMDelegator.prototype.listenTo = function listenTo(eventName) { | |
if (this.events[eventName]) { | |
return | |
} | |
this.events[eventName] = true | |
listen(this, eventName) | |
} | |
DOMDelegator.prototype.unlistenTo = function unlistenTo(eventName) { | |
if (!this.events[eventName]) { | |
return | |
} | |
this.events[eventName] = false | |
unlisten(this, eventName) | |
} | |
function listen(delegator, eventName) { | |
var listener = delegator.rawEventListeners[eventName] | |
if (!listener) { | |
listener = delegator.rawEventListeners[eventName] = | |
createHandler(eventName, delegator.globalListeners) | |
} | |
delegator.target.addEventListener(eventName, listener, true) | |
} | |
function unlisten(delegator, eventName) { | |
var listener = delegator.rawEventListeners[eventName] | |
if (!listener) { | |
throw new Error("dom-delegator#unlistenTo: cannot " + | |
"unlisten to " + eventName) | |
} | |
delegator.target.removeEventListener(eventName, listener, true) | |
} | |
function createHandler(eventName, globalListeners) { | |
return handler | |
function handler(ev) { | |
var globalHandlers = globalListeners[eventName] || [] | |
var listener = getListener(ev.target, eventName) | |
var handlers = globalHandlers | |
.concat(listener ? listener.handlers : []) | |
if (handlers.length === 0) { | |
return | |
} | |
var arg = new ProxyEvent(ev, listener) | |
handlers.forEach(function (handler) { | |
typeof handler === "function" ? | |
handler(arg) : handler.handleEvent(arg) | |
}) | |
} | |
} | |
function getListener(target, type) { | |
// terminate recursion if parent is `null` | |
if (target === null) { | |
return null | |
} | |
var ds = DataSet(target) | |
// fetch list of handler fns for this event | |
var handler = ds[type] | |
var allHandler = ds.event | |
if (!handler && !allHandler) { | |
return getListener(target.parentNode, type) | |
} | |
var handlers = [].concat(handler || [], allHandler || []) | |
return new Listener(target, handlers) | |
} | |
function Listener(target, handlers) { | |
this.currentTarget = target | |
this.handlers = handlers | |
} | |
},{"./add-event.js":4,"./proxy-event.js":13,"./remove-event.js":14,"data-set":8,"global/document":18}],6:[function(_dereq_,module,exports){ | |
var Individual = _dereq_("individual") | |
var cuid = _dereq_("cuid") | |
var DOMDelegator = _dereq_("./dom-delegator.js") | |
var delegatorCache = Individual("__DOM_DELEGATOR_CACHE@8", { | |
delegators: {} | |
}) | |
var commonEvents = [ | |
"blur", "change", "click", "contextmenu", "dblclick", | |
"error","focus", "focusin", "focusout", "input", "keydown", | |
"keypress", "keyup", "load", "mousedown", "mouseup", | |
"resize", "scroll", "select", "submit", "unload" | |
] | |
/* Delegator is a thin wrapper around a singleton `DOMDelegator` | |
instance. | |
Only one DOMDelegator should exist because we do not want | |
duplicate event listeners bound to the DOM. | |
`Delegator` will also `listenTo()` all events unless | |
every caller opts out of it | |
*/ | |
module.exports = Delegator | |
function Delegator(opts) { | |
opts = opts || {} | |
var document = opts.document | |
var cacheKey = document ? | |
document["__DOM_DELEGATOR_CACHE_TOKEN@8"] : "global" | |
if (!cacheKey) { | |
cacheKey = | |
document["__DOM_DELEGATOR_CACHE_TOKEN@8"] = cuid() | |
} | |
var delegator = delegatorCache.delegators[cacheKey] | |
if (!delegator) { | |
delegator = delegatorCache.delegators[cacheKey] = | |
new DOMDelegator(document) | |
} | |
if (opts.defaultEvents !== false) { | |
for (var i = 0; i < commonEvents.length; i++) { | |
delegator.listenTo(commonEvents[i]) | |
} | |
} | |
return delegator | |
} | |
},{"./dom-delegator.js":5,"cuid":3,"individual":11}],7:[function(_dereq_,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 | |
} | |
},{}],8:[function(_dereq_,module,exports){ | |
var createStore = _dereq_("weakmap-shim/create-store") | |
var Individual = _dereq_("individual") | |
var createHash = _dereq_("./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":7,"individual":11,"weakmap-shim/create-store":9}],9:[function(_dereq_,module,exports){ | |
var hiddenStore = _dereq_('./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":10}],10:[function(_dereq_,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; | |
} | |
},{}],11:[function(_dereq_,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 self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) | |
},{}],12:[function(_dereq_,module,exports){ | |
if (typeof Object.create === 'function') { | |
// implementation from standard node.js 'util' module | |
module.exports = function inherits(ctor, superCtor) { | |
ctor.super_ = superCtor | |
ctor.prototype = Object.create(superCtor.prototype, { | |
constructor: { | |
value: ctor, | |
enumerable: false, | |
writable: true, | |
configurable: true | |
} | |
}); | |
}; | |
} else { | |
// old school shim for old browsers | |
module.exports = function inherits(ctor, superCtor) { | |
ctor.super_ = superCtor | |
var TempCtor = function () {} | |
TempCtor.prototype = superCtor.prototype | |
ctor.prototype = new TempCtor() | |
ctor.prototype.constructor = ctor | |
} | |
} | |
},{}],13:[function(_dereq_,module,exports){ | |
var inherits = _dereq_("inherits") | |
var ALL_PROPS = [ | |
"altKey", "bubbles", "cancelable", "ctrlKey", | |
"eventPhase", "metaKey", "relatedTarget", "shiftKey", | |
"target", "timeStamp", "type", "view", "which" | |
] | |
var KEY_PROPS = ["char", "charCode", "key", "keyCode"] | |
var MOUSE_PROPS = [ | |
"button", "buttons", "clientX", "clientY", "layerX", | |
"layerY", "offsetX", "offsetY", "pageX", "pageY", | |
"screenX", "screenY", "toElement" | |
] | |
var rkeyEvent = /^key|input/ | |
var rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/ | |
module.exports = ProxyEvent | |
function ProxyEvent(ev, listener) { | |
if (!(this instanceof ProxyEvent)) { | |
return new ProxyEvent(ev, listener) | |
} | |
if (rkeyEvent.test(ev.type)) { | |
return new KeyEvent(ev, listener) | |
} else if (rmouseEvent.test(ev.type)) { | |
return new MouseEvent(ev, listener) | |
} | |
for (var i = 0; i < ALL_PROPS.length; i++) { | |
var propKey = ALL_PROPS[i] | |
this[propKey] = ev[propKey] | |
} | |
this._rawEvent = ev | |
this.currentTarget = listener ? listener.currentTarget : null | |
} | |
ProxyEvent.prototype.preventDefault = function () { | |
this._rawEvent.preventDefault() | |
} | |
function MouseEvent(ev, listener) { | |
for (var i = 0; i < ALL_PROPS.length; i++) { | |
var propKey = ALL_PROPS[i] | |
this[propKey] = ev[propKey] | |
} | |
for (var j = 0; j < MOUSE_PROPS.length; j++) { | |
var mousePropKey = MOUSE_PROPS[j] | |
this[mousePropKey] = ev[mousePropKey] | |
} | |
this._rawEvent = ev | |
this.currentTarget = listener ? listener.currentTarget : null | |
} | |
inherits(MouseEvent, ProxyEvent) | |
function KeyEvent(ev, listener) { | |
for (var i = 0; i < ALL_PROPS.length; i++) { | |
var propKey = ALL_PROPS[i] | |
this[propKey] = ev[propKey] | |
} | |
for (var j = 0; j < KEY_PROPS.length; j++) { | |
var keyPropKey = KEY_PROPS[j] | |
this[keyPropKey] = ev[keyPropKey] | |
} | |
this._rawEvent = ev | |
this.currentTarget = listener ? listener.currentTarget : null | |
} | |
inherits(KeyEvent, ProxyEvent) | |
},{"inherits":12}],14:[function(_dereq_,module,exports){ | |
var DataSet = _dereq_("data-set") | |
module.exports = removeEvent | |
function removeEvent(target, type, handler) { | |
var ds = DataSet(target) | |
var events = ds[type] | |
if (!events) { | |
return | |
} else if (Array.isArray(events)) { | |
var index = events.indexOf(handler) | |
if (index !== -1) { | |
events.splice(index, 1) | |
} | |
} else if (events === handler) { | |
ds[type] = null | |
} | |
} | |
},{"data-set":8}],15:[function(_dereq_,module,exports){ | |
module.exports = Event | |
function Event() { | |
var listeners = [] | |
return { broadcast: broadcast, listen: event } | |
function broadcast(value) { | |
for (var i = 0; i < listeners.length; i++) { | |
listeners[i](value) | |
} | |
} | |
function event(listener) { | |
listeners.push(listener) | |
return removeListener | |
function removeListener() { | |
var index = listeners.indexOf(listener) | |
if (index !== -1) { | |
listeners.splice(index, 1) | |
} | |
} | |
} | |
} | |
},{}],16:[function(_dereq_,module,exports){ | |
var event = _dereq_("./single.js") | |
module.exports = multiple | |
function multiple(names) { | |
return names.reduce(function (acc, name) { | |
acc[name] = event() | |
return acc | |
}, {}) | |
} | |
},{"./single.js":17}],17:[function(_dereq_,module,exports){ | |
var Event = _dereq_('./event.js') | |
module.exports = Single | |
function Single() { | |
var tuple = Event() | |
return function event(value) { | |
if (typeof value === "function") { | |
return tuple.listen(value) | |
} else { | |
return tuple.broadcast(value) | |
} | |
} | |
} | |
},{"./event.js":15}],18:[function(_dereq_,module,exports){ | |
(function (global){ | |
var topLevel = typeof global !== 'undefined' ? global : | |
typeof window !== 'undefined' ? window : {} | |
var minDoc = _dereq_('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 self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) | |
},{"min-document":2}],19:[function(_dereq_,module,exports){ | |
var raf = _dereq_("raf/polyfill") | |
var vdomCreate = _dereq_("virtual-dom/create-element") | |
var vdomDiff = _dereq_("virtual-dom/diff") | |
var vdomPatch = _dereq_("virtual-dom/patch") | |
module.exports = main | |
function main(initialState, view, opts) { | |
opts = opts || {} | |
var currentState = initialState | |
var create = opts.create || vdomCreate | |
var diff = opts.diff || vdomDiff | |
var patch = opts.patch || vdomPatch | |
var redrawScheduled = false | |
var tree = view(currentState) | |
var target = create(tree, opts) | |
currentState = null | |
return { | |
target: target, | |
update: update | |
} | |
function update(state) { | |
if (currentState === null && !redrawScheduled) { | |
redrawScheduled = true | |
raf(redraw) | |
} | |
currentState = state | |
} | |
function redraw() { | |
redrawScheduled = false; | |
if (currentState === null) { | |
return | |
} | |
var newTree = view(currentState) | |
if (opts.createOnly) { | |
create(newTree, opts) | |
} else { | |
var patches = diff(tree, newTree, opts) | |
patch(target, patches, opts) | |
} | |
tree = newTree | |
currentState = null | |
} | |
} | |
},{"raf/polyfill":38,"virtual-dom/create-element":50,"virtual-dom/diff":51,"virtual-dom/patch":55}],20:[function(_dereq_,module,exports){ | |
module.exports = addListener | |
function addListener(observArray, observ) { | |
var list = observArray._list | |
return observ(function (value) { | |
var valueList = observArray().slice() | |
var index = list.indexOf(observ) | |
// This code path should never hit. If this happens | |
// there's a bug in the cleanup code | |
if (index === -1) { | |
var message = "observ-array: Unremoved observ listener" | |
var err = new Error(message) | |
err.list = list | |
err.index = index | |
err.observ = observ | |
throw err | |
} | |
valueList.splice(index, 1, value) | |
valueList._diff = [index, 1, value] | |
observArray.set(valueList) | |
}) | |
} | |
},{}],21:[function(_dereq_,module,exports){ | |
var ObservArray = _dereq_("./index.js") | |
var slice = Array.prototype.slice | |
var ARRAY_METHODS = [ | |
"concat", "slice", "every", "filter", "forEach", "indexOf", | |
"join", "lastIndexOf", "map", "reduce", "reduceRight", | |
"some", "toString", "toLocaleString" | |
] | |
var methods = ARRAY_METHODS.map(function (name) { | |
return [name, function () { | |
var res = this._list[name].apply(this._list, arguments) | |
if (res && Array.isArray(res)) { | |
res = ObservArray(res) | |
} | |
return res | |
}] | |
}) | |
module.exports = ArrayMethods | |
function ArrayMethods(obs) { | |
obs.push = observArrayPush | |
obs.pop = observArrayPop | |
obs.shift = observArrayShift | |
obs.unshift = observArrayUnshift | |
obs.reverse = notImplemented | |
obs.sort = notImplemented | |
methods.forEach(function (tuple) { | |
obs[tuple[0]] = tuple[1] | |
}) | |
return obs | |
} | |
function observArrayPush() { | |
var args = slice.call(arguments) | |
args.unshift(this._list.length, 0) | |
this.splice.apply(this, args) | |
return this._list.length | |
} | |
function observArrayPop() { | |
return this.splice(this._list.length - 1, 1)[0] | |
} | |
function observArrayShift() { | |
return this.splice(0, 1)[0] | |
} | |
function observArrayUnshift() { | |
var args = slice.call(arguments) | |
args.unshift(0, 0) | |
this.splice.apply(this, args) | |
return this._list.length | |
} | |
function notImplemented() { | |
throw new Error("Pull request welcome") | |
} | |
},{"./index.js":22}],22:[function(_dereq_,module,exports){ | |
var Observ = _dereq_("observ") | |
// circular dep between ArrayMethods & this file | |
module.exports = ObservArray | |
var splice = _dereq_("./splice.js") | |
var ArrayMethods = _dereq_("./array-methods.js") | |
var addListener = _dereq_("./add-listener.js") | |
/* ObservArray := (Array<T>) => Observ< | |
Array<T> & { _diff: Array } | |
> & { | |
splice: (index: Number, amount: Number, rest...: T) => | |
Array<T>, | |
push: (values...: T) => Number, | |
filter: (lambda: Function, thisValue: Any) => Array<T>, | |
indexOf: (item: T, fromIndex: Number) => Number | |
} | |
Fix to make it more like ObservHash. | |
I.e. you write observables into it. | |
reading methods take plain JS objects to read | |
and the value of the array is always an array of plain | |
objsect. | |
The observ array instance itself would have indexed | |
properties that are the observables | |
*/ | |
function ObservArray(initialList) { | |
// list is the internal mutable list observ instances that | |
// all methods on `obs` dispatch to. | |
var list = initialList | |
var initialState = [] | |
// copy state out of initialList into initialState | |
list.forEach(function (observ, index) { | |
initialState[index] = typeof observ === "function" ? | |
observ() : observ | |
}) | |
var obs = Observ(initialState) | |
obs.splice = splice | |
obs.get = get | |
obs.getLength = getLength | |
obs.put = put | |
// you better not mutate this list directly | |
// this is the list of observs instances | |
obs._list = list | |
var removeListeners = list.map(function (observ) { | |
return typeof observ === "function" ? | |
addListener(obs, observ) : | |
null | |
}); | |
// this is a list of removal functions that must be called | |
// when observ instances are removed from `obs.list` | |
// not calling this means we do not GC our observ change | |
// listeners. Which causes rage bugs | |
obs._removeListeners = removeListeners | |
return ArrayMethods(obs, list) | |
} | |
function get(index) { | |
return this._list[index] | |
} | |
function put(index, value) { | |
this.splice(index, 1, value) | |
} | |
function getLength() { | |
return this._list.length | |
} | |
},{"./add-listener.js":20,"./array-methods.js":21,"./splice.js":24,"observ":23}],23:[function(_dereq_,module,exports){ | |
module.exports = Observable | |
function Observable(value) { | |
var listeners = [] | |
value = value === undefined ? null : value | |
observable.set = function (v) { | |
value = v | |
listeners.forEach(function (f) { | |
f(v) | |
}) | |
} | |
return observable | |
function observable(listener) { | |
if (!listener) { | |
return value | |
} | |
listeners.push(listener) | |
return function remove() { | |
listeners.splice(listeners.indexOf(listener), 1) | |
} | |
} | |
} | |
},{}],24:[function(_dereq_,module,exports){ | |
var slice = Array.prototype.slice | |
var addListener = _dereq_("./add-listener.js") | |
module.exports = splice | |
// `obs.splice` is a mutable implementation of `splice()` | |
// that mutates both `list` and the internal `valueList` that | |
// is the current value of `obs` itself | |
function splice(index, amount) { | |
var obs = this | |
var args = slice.call(arguments, 0) | |
var valueList = obs().slice() | |
// generate a list of args to mutate the internal | |
// list of only obs | |
var valueArgs = args.map(function (value, index) { | |
if (index === 0 || index === 1) { | |
return value | |
} | |
// must unpack observables that we are adding | |
return typeof value === "function" ? value() : value | |
}) | |
valueList.splice.apply(valueList, valueArgs) | |
// we remove the observs that we remove | |
var removed = obs._list.splice.apply(obs._list, args) | |
var extraRemoveListeners = args.slice(2).map(function (observ) { | |
return typeof observ === "function" ? | |
addListener(obs, observ) : | |
null | |
}) | |
extraRemoveListeners.unshift(args[0], args[1]) | |
var removedListeners = obs._removeListeners.splice | |
.apply(obs._removeListeners, extraRemoveListeners) | |
removedListeners.forEach(function (removeObservListener) { | |
if (removeObservListener) { | |
removeObservListener() | |
} | |
}) | |
valueList._diff = valueArgs | |
obs.set(valueList) | |
return removed | |
} | |
},{"./add-listener.js":20}],25:[function(_dereq_,module,exports){ | |
var Observ = _dereq_("observ") | |
var extend = _dereq_("xtend") | |
/* ObservStruct := (Object<String, Observ<T>>) => | |
Object<String, Observ<T>> & | |
Observ<Object<String, T> & { | |
_diff: Object<String, Any> | |
}> | |
*/ | |
module.exports = ObservStruct | |
function ObservStruct(struct) { | |
var keys = Object.keys(struct) | |
var initialState = {} | |
keys.forEach(function (key) { | |
if (key === "name") { | |
throw new Error("cannot create an observ-struct " + | |
"with a key named 'name'. Clashes with " + | |
"`Function.prototype.name`."); | |
} | |
var observ = struct[key] | |
initialState[key] = typeof observ === "function" ? | |
observ() : observ | |
}) | |
var obs = Observ(initialState) | |
keys.forEach(function (key) { | |
var observ = struct[key] | |
obs[key] = observ | |
if (typeof observ === "function") { | |
observ(function (value) { | |
var state = extend(obs()) | |
state[key] = value | |
var diff = {} | |
diff[key] = value && value._diff ? | |
value._diff : value | |
state._diff = diff | |
obs.set(state) | |
}) | |
} | |
}) | |
return obs | |
} | |
},{"observ":26,"xtend":83}],26:[function(_dereq_,module,exports){ | |
module.exports=_dereq_(23) | |
},{}],27:[function(_dereq_,module,exports){ | |
var Observ = _dereq_('observ') | |
var extend = _dereq_('xtend') | |
var TOMBSTONE = ObservVarhash.Tombstone = new Tombstone() | |
module.exports = ObservVarhash | |
function ObservVarhash(hash, createFn) { | |
createFn = createFn || function (obj) { return obj } | |
var keys = Object.keys(hash) | |
var initialState = {} | |
keys.forEach(function (key) { | |
if (key === 'name') { | |
throw new Error('cannot create an observ-varhash with a key named' + | |
'"name". Clashes with `Function.prototype.name`.') | |
} | |
var observ = hash[key] | |
initialState[key] = typeof observ === 'function' ? observ() : observ | |
}) | |
var obs = Observ(initialState) | |
obs.get = get | |
obs.delete = del | |
obs.put = put(createFn) | |
obs._removeListeners = {} | |
keys.forEach(function (key) { | |
var observ = hash[key] | |
obs[key] = createFn(observ, key) | |
if (typeof observ === 'function') { | |
obs._removeListeners[key] = observ(watch(obs, key)) | |
} | |
}) | |
return obs | |
} | |
// api | |
function get (key) { return this[key] } | |
function put (createFn) { | |
return function (key, val) { | |
var obs = this | |
var observ = createFn(val, key) | |
var state = prepareChange(obs, key) | |
var value = typeof observ === 'function' ? observ() : observ | |
state[key] = value | |
if (typeof observ === 'function') { | |
obs._removeListeners[key] = observ(watch(obs, key)) | |
} | |
state._diff = diff(key, value) | |
obs.set(state) | |
obs[key] = observ | |
return obs | |
} | |
} | |
function del (key) { | |
var state = prepareChange(this, key) | |
delete state[key] | |
state._diff = diff(key, TOMBSTONE) | |
this.set(state) | |
return this | |
} | |
// helpers | |
function watch (obs, key, state) { | |
return function (value) { | |
var state = extend(obs()) | |
state[key] = value | |
state._diff = diff(key, value) | |
obs.set(state) | |
} | |
} | |
function prepareChange (obs, key) { | |
var state = extend(obs()) | |
if (obs._removeListeners[key]) { | |
obs._removeListeners[key]() | |
delete obs._removeListeners[key] | |
} | |
return state | |
} | |
function diff (key, value) { | |
var obj = {} | |
obj[key] = value && value._diff ? value._diff : value | |
return obj | |
} | |
function Tombstone () { | |
this.toString = function () { return '[object Tombstone]' } | |
this.toJSON = function () { return '[object Tombstone]' } | |
} | |
},{"observ":28,"xtend":30}],28:[function(_dereq_,module,exports){ | |
module.exports=_dereq_(23) | |
},{}],29:[function(_dereq_,module,exports){ | |
module.exports = hasKeys | |
function hasKeys(source) { | |
return source !== null && | |
(typeof source === "object" || | |
typeof source === "function") | |
} | |
},{}],30:[function(_dereq_,module,exports){ | |
var Keys = _dereq_("object-keys") | |
var hasKeys = _dereq_("./has-keys") | |
module.exports = extend | |
function extend() { | |
var target = {} | |
for (var i = 0; i < arguments.length; i++) { | |
var source = arguments[i] | |
if (!hasKeys(source)) { | |
continue | |
} | |
var keys = Keys(source) | |
for (var j = 0; j < keys.length; j++) { | |
var name = keys[j] | |
target[name] = source[name] | |
} | |
} | |
return target | |
} | |
},{"./has-keys":29,"object-keys":32}],31:[function(_dereq_,module,exports){ | |
var hasOwn = Object.prototype.hasOwnProperty; | |
var toString = Object.prototype.toString; | |
var isFunction = function (fn) { | |
var isFunc = (typeof fn === 'function' && !(fn instanceof RegExp)) || toString.call(fn) === '[object Function]'; | |
if (!isFunc && typeof window !== 'undefined') { | |
isFunc = fn === window.setTimeout || fn === window.alert || fn === window.confirm || fn === window.prompt; | |
} | |
return isFunc; | |
}; | |
module.exports = function forEach(obj, fn) { | |
if (!isFunction(fn)) { | |
throw new TypeError('iterator must be a function'); | |
} | |
var i, k, | |
isString = typeof obj === 'string', | |
l = obj.length, | |
context = arguments.length > 2 ? arguments[2] : null; | |
if (l === +l) { | |
for (i = 0; i < l; i++) { | |
if (context === null) { | |
fn(isString ? obj.charAt(i) : obj[i], i, obj); | |
} else { | |
fn.call(context, isString ? obj.charAt(i) : obj[i], i, obj); | |
} | |
} | |
} else { | |
for (k in obj) { | |
if (hasOwn.call(obj, k)) { | |
if (context === null) { | |
fn(obj[k], k, obj); | |
} else { | |
fn.call(context, obj[k], k, obj); | |
} | |
} | |
} | |
} | |
}; | |
},{}],32:[function(_dereq_,module,exports){ | |
module.exports = Object.keys || _dereq_('./shim'); | |
},{"./shim":34}],33:[function(_dereq_,module,exports){ | |
var toString = Object.prototype.toString; | |
module.exports = function isArguments(value) { | |
var str = toString.call(value); | |
var isArguments = str === '[object Arguments]'; | |
if (!isArguments) { | |
isArguments = str !== '[object Array]' | |
&& value !== null | |
&& typeof value === 'object' | |
&& typeof value.length === 'number' | |
&& value.length >= 0 | |
&& toString.call(value.callee) === '[object Function]'; | |
} | |
return isArguments; | |
}; | |
},{}],34:[function(_dereq_,module,exports){ | |
(function () { | |
"use strict"; | |
// modified from https://github.com/kriskowal/es5-shim | |
var has = Object.prototype.hasOwnProperty, | |
toString = Object.prototype.toString, | |
forEach = _dereq_('./foreach'), | |
isArgs = _dereq_('./isArguments'), | |
hasDontEnumBug = !({'toString': null}).propertyIsEnumerable('toString'), | |
hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'), | |
dontEnums = [ | |
"toString", | |
"toLocaleString", | |
"valueOf", | |
"hasOwnProperty", | |
"isPrototypeOf", | |
"propertyIsEnumerable", | |
"constructor" | |
], | |
keysShim; | |
keysShim = function keys(object) { | |
var isObject = object !== null && typeof object === 'object', | |
isFunction = toString.call(object) === '[object Function]', | |
isArguments = isArgs(object), | |
theKeys = []; | |
if (!isObject && !isFunction && !isArguments) { | |
throw new TypeError("Object.keys called on a non-object"); | |
} | |
if (isArguments) { | |
forEach(object, function (value) { | |
theKeys.push(value); | |
}); | |
} else { | |
var name, | |
skipProto = hasProtoEnumBug && isFunction; | |
for (name in object) { | |
if (!(skipProto && name === 'prototype') && has.call(object, name)) { | |
theKeys.push(name); | |
} | |
} | |
} | |
if (hasDontEnumBug) { | |
var ctor = object.constructor, | |
skipConstructor = ctor && ctor.prototype === object; | |
forEach(dontEnums, function (dontEnum) { | |
if (!(skipConstructor && dontEnum === 'constructor') && has.call(object, dontEnum)) { | |
theKeys.push(dontEnum); | |
} | |
}); | |
} | |
return theKeys; | |
}; | |
module.exports = keysShim; | |
}()); | |
},{"./foreach":31,"./isArguments":33}],35:[function(_dereq_,module,exports){ | |
var Observable = _dereq_("./index.js") | |
module.exports = computed | |
function computed(observables, lambda) { | |
var values = observables.map(function (o) { | |
return o() | |
}) | |
var result = Observable(lambda.apply(null, values)) | |
observables.forEach(function (o, index) { | |
o(function (newValue) { | |
values[index] = newValue | |
result.set(lambda.apply(null, values)) | |
}) | |
}) | |
return result | |
} | |
},{"./index.js":36}],36:[function(_dereq_,module,exports){ | |
module.exports=_dereq_(23) | |
},{}],37:[function(_dereq_,module,exports){ | |
module.exports = watch | |
function watch(observable, listener) { | |
var remove = observable(listener) | |
listener(observable()) | |
return remove | |
} | |
},{}],38:[function(_dereq_,module,exports){ | |
var global = typeof window === 'undefined' ? this : window | |
var _raf = | |
global.requestAnimationFrame || | |
global.webkitRequestAnimationFrame || | |
global.mozRequestAnimationFrame || | |
global.msRequestAnimationFrame || | |
global.oRequestAnimationFrame || | |
(global.setImmediate ? function(fn, el) { | |
setImmediate(fn) | |
} : | |
function(fn, el) { | |
setTimeout(fn, 0) | |
}) | |
module.exports = _raf | |
},{}],39:[function(_dereq_,module,exports){ | |
var extend = _dereq_('xtend') | |
var getFormData = _dereq_('form-data-set/element') | |
module.exports = ChangeSinkHandler | |
function ChangeSinkHandler(sink, data) { | |
if (!(this instanceof ChangeSinkHandler)) { | |
return new ChangeSinkHandler(sink, data) | |
} | |
this.sink = sink | |
this.data = data | |
this.type = 'change' | |
this.id = sink.id | |
} | |
ChangeSinkHandler.prototype.handleEvent = handleEvent | |
function handleEvent(ev) { | |
var target = ev.target | |
var isValid = | |
(ev.type === 'change' && target.type === 'checkbox') || | |
(ev.type === 'input' && target.type === 'text') || | |
(ev.type === 'change' && target.type === 'range') | |
if (!isValid) { | |
return | |
} | |
var value = getFormData(ev.currentTarget) | |
var data = extend(value, this.data) | |
if (typeof this.sink === 'function') { | |
this.sink(data) | |
} else { | |
this.sink.write(data) | |
} | |
} | |
},{"form-data-set/element":43,"xtend":46}],40:[function(_dereq_,module,exports){ | |
module.exports = SinkEventHandler | |
function SinkEventHandler(sink, data) { | |
if (!(this instanceof SinkEventHandler)) { | |
return new SinkEventHandler(sink, data) | |
} | |
this.sink = sink | |
this.id = sink.id | |
this.data = data | |
} | |
SinkEventHandler.prototype.handleEvent = handleEvent | |
function handleEvent(ev) { | |
if (typeof this.sink === 'function') { | |
this.sink(this.data) | |
} else { | |
this.sink.write(this.data) | |
} | |
} | |
},{}],41:[function(_dereq_,module,exports){ | |
module.exports = KeyEventHandler | |
function KeyEventHandler(fn, key, data) { | |
if (!(this instanceof KeyEventHandler)) { | |
return new KeyEventHandler(fn, key, data) | |
} | |
this.fn = fn | |
this.data = data | |
this.key = key | |
} | |
KeyEventHandler.prototype.handleEvent = handleEvent | |
function handleEvent(ev) { | |
if (ev.keyCode === this.key) { | |
this.fn(this.data) | |
} | |
} | |
},{}],42:[function(_dereq_,module,exports){ | |
var slice = Array.prototype.slice | |
module.exports = iterativelyWalk | |
function iterativelyWalk(nodes, cb) { | |
if (!('length' in nodes)) { | |
nodes = [nodes] | |
} | |
nodes = slice.call(nodes) | |
while(nodes.length) { | |
var node = nodes.shift(), | |
ret = cb(node) | |
if (ret) { | |
return ret | |
} | |
if (node.childNodes.length) { | |
nodes = slice.call(node.childNodes).concat(nodes) | |
} | |
} | |
} | |
},{}],43:[function(_dereq_,module,exports){ | |
var walk = _dereq_('dom-walk') | |
var FormData = _dereq_('./index.js') | |
module.exports = getFormData | |
function buildElems(rootElem) { | |
var hash = {} | |
walk(rootElem, function (child) { | |
if (child.name) { | |
hash[child.name] = child | |
} | |
}) | |
return hash | |
} | |
function getFormData(rootElem) { | |
var elements = buildElems(rootElem) | |
return FormData(elements) | |
} | |
},{"./index.js":44,"dom-walk":42}],44:[function(_dereq_,module,exports){ | |
/*jshint maxcomplexity: 10*/ | |
module.exports = FormData | |
//TODO: Massive spec: http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#constructing-form-data-set | |
function FormData(elements) { | |
return Object.keys(elements).reduce(function (acc, key) { | |
var elem = elements[key] | |
acc[key] = valueOfElement(elem) | |
return acc | |
}, {}) | |
} | |
function valueOfElement(elem) { | |
if (typeof elem === "function") { | |
return elem() | |
} else if (containsRadio(elem)) { | |
var elems = toList(elem) | |
var checked = elems.filter(function (elem) { | |
return elem.checked | |
})[0] || null | |
return checked ? checked.value : null | |
} else if (Array.isArray(elem)) { | |
return elem.map(valueOfElement).filter(filterNull) | |
} else if (elem.tagName === undefined && elem.nodeType === undefined) { | |
return FormData(elem) | |
} else if (elem.tagName === "INPUT" && isChecked(elem)) { | |
if (elem.hasAttribute("value")) { | |
return elem.checked ? elem.value : null | |
} else { | |
return elem.checked | |
} | |
} else if (elem.tagName === "INPUT") { | |
return elem.value | |
} else if (elem.tagName === "TEXTAREA") { | |
return elem.value | |
} else if (elem.tagName === "SELECT") { | |
return elem.value | |
} | |
} | |
function isChecked(elem) { | |
return elem.type === "checkbox" || elem.type === "radio" | |
} | |
function containsRadio(value) { | |
if (value.tagName || value.nodeType) { | |
return false | |
} | |
var elems = toList(value) | |
return elems.some(function (elem) { | |
return elem.tagName === "INPUT" && elem.type === "radio" | |
}) | |
} | |
function toList(value) { | |
if (Array.isArray(value)) { | |
return value | |
} | |
return Object.keys(value).map(prop, value) | |
} | |
function prop(x) { | |
return this[x] | |
} | |
function filterNull(val) { | |
return val !== null | |
} | |
},{}],45:[function(_dereq_,module,exports){ | |
module.exports=_dereq_(29) | |
},{}],46:[function(_dereq_,module,exports){ | |
var hasKeys = _dereq_("./has-keys") | |
module.exports = extend | |
function extend() { | |
var target = {} | |
for (var i = 0; i < arguments.length; i++) { | |
var source = arguments[i] | |
if (!hasKeys(source)) { | |
continue | |
} | |
for (var key in source) { | |
if (source.hasOwnProperty(key)) { | |
target[key] = source[key] | |
} | |
} | |
} | |
return target | |
} | |
},{"./has-keys":45}],47:[function(_dereq_,module,exports){ | |
var extend = _dereq_('xtend') | |
var getFormData = _dereq_('form-data-set/element') | |
var ENTER = 13 | |
module.exports = SubmitSinkHandler | |
function SubmitSinkHandler(sink, data) { | |
if (!(this instanceof SubmitSinkHandler)) { | |
return new SubmitSinkHandler(sink, data) | |
} | |
this.sink = sink | |
this.data = data | |
this.id = sink.id | |
this.type = 'submit' | |
} | |
SubmitSinkHandler.prototype.handleEvent = handleEvent | |
function handleEvent(ev) { | |
var target = ev.target | |
var isValid = | |
(ev.type === 'click' && target.tagName === 'BUTTON') || | |
( | |
(target.type === 'text' || target.tagName === 'TEXTAREA') && | |
(ev.keyCode === ENTER && !ev.shiftKey && ev.type === 'keydown') | |
) | |
if (!isValid) { | |
return | |
} | |
var value = getFormData(ev.currentTarget) | |
var data = extend(value, this.data) | |
if (typeof this.sink === 'function') { | |
this.sink(data) | |
} else { | |
this.sink.write(data) | |
} | |
} | |
},{"form-data-set/element":43,"xtend":46}],48:[function(_dereq_,module,exports){ | |
var extend = _dereq_('xtend') | |
var getFormData = _dereq_('form-data-set/element') | |
module.exports = ValueEventHandler | |
function ValueEventHandler(sink, data) { | |
if (!(this instanceof ValueEventHandler)) { | |
return new ValueEventHandler(sink, data) | |
} | |
this.sink = sink | |
this.data = data | |
this.id = sink.id | |
} | |
ValueEventHandler.prototype.handleEvent = handleEvent | |
function handleEvent(ev) { | |
var value = getFormData(ev.currentTarget) | |
var data = extend(value, this.data) | |
if (typeof this.sink === 'function') { | |
this.sink(data) | |
} else { | |
this.sink.write(data) | |
} | |
} | |
},{"form-data-set/element":43,"xtend":46}],49:[function(_dereq_,module,exports){ | |
var createElement = _dereq_("virtual-dom/create-element") | |
var diff = _dereq_("virtual-dom/diff") | |
var patch = _dereq_("virtual-dom/patch") | |
var MESSAGE = "partial() cannot cache on values. " + | |
"You must specify object arguments. partial(" | |
function copyOver(list, offset) { | |
var newList = [] | |
for (var i = offset; i < list.length; i++) { | |
newList[i - offset] = list[i] | |
} | |
return newList | |
} | |
module.exports = partial | |
function partial(fn) { | |
var args = copyOver(arguments, 1) | |
var firstArg = args[0] | |
var hasObjects = args.length === 0 | |
var key | |
if (typeof firstArg === "object" && firstArg !== null) { | |
hasObjects = true | |
if ("key" in firstArg) { | |
key = firstArg.key | |
} else if ("id" in firstArg) { | |
key = firstArg.id | |
} | |
} | |
for (var i = 1; !hasObjects && i < args.length; i++) { | |
var arg = args[i]; | |
if (typeof arg === "object" && arg !== null) { | |
hasObjects = true | |
} | |
} | |
if (!hasObjects) { | |
throw new Error(MESSAGE + args + ")") | |
} | |
return new Thunk(fn, args, key) | |
} | |
function Thunk(fn, args, key) { | |
this.fn = fn | |
this.args = args | |
this.vnode = null | |
this.key = key | |
} | |
Thunk.prototype.type = "immutable-thunk" | |
Thunk.prototype.update = update | |
Thunk.prototype.init = init | |
function shouldUpdate(current, previous) { | |
if (current.fn !== previous.fn) { | |
return true | |
} | |
var cargs = current.args | |
var pargs = previous.args | |
// fast case for args is zero case. | |
if (cargs.length === 0 && pargs.length === 0) { | |
return false | |
} | |
if (cargs.length !== pargs.length) { | |
return true | |
} | |
var max = cargs.length > pargs.length ? cargs.length : pargs.length | |
for (var i = 0; i < max; i++) { | |
if (cargs[i] !== pargs[i]) { | |
return true | |
} | |
} | |
return false | |
} | |
function update(previous, domNode) { | |
if (!shouldUpdate(this, previous)) { | |
this.vnode = previous.vnode | |
return | |
} | |
if (!this.vnode) { | |
this.vnode = this.fn.apply(null, this.args) | |
} | |
var patches = diff(previous.vnode, this.vnode) | |
patch(domNode, patches) | |
} | |
function init() { | |
this.vnode = this.fn.apply(null, this.args) | |
return createElement(this.vnode) | |
} | |
},{"virtual-dom/create-element":50,"virtual-dom/diff":51,"virtual-dom/patch":55}],50:[function(_dereq_,module,exports){ | |
var createElement = _dereq_("./vdom/create-element") | |
module.exports = createElement | |
},{"./vdom/create-element":57}],51:[function(_dereq_,module,exports){ | |
var diff = _dereq_("./vtree/diff") | |
module.exports = diff | |
},{"./vtree/diff":62}],52:[function(_dereq_,module,exports){ | |
if (typeof document !== "undefined") { | |
module.exports = document; | |
} else { | |
module.exports = _dereq_("min-document"); | |
} | |
},{"min-document":2}],53:[function(_dereq_,module,exports){ | |
module.exports = isObject | |
function isObject(x) { | |
return typeof x === "object" && x !== null | |
} | |
},{}],54:[function(_dereq_,module,exports){ | |
var nativeIsArray = Array.isArray | |
var toString = Object.prototype.toString | |
module.exports = nativeIsArray || isArray | |
function isArray(obj) { | |
return toString.call(obj) === "[object Array]" | |
} | |
},{}],55:[function(_dereq_,module,exports){ | |
var patch = _dereq_("./vdom/patch") | |
module.exports = patch | |
},{"./vdom/patch":60}],56:[function(_dereq_,module,exports){ | |
var isObject = _dereq_("is-object") | |
var isHook = _dereq_("../vtree/is-vhook") | |
module.exports = applyProperties | |
function applyProperties(node, props, previous) { | |
for (var propName in props) { | |
var propValue = props[propName] | |
if (isHook(propValue)) { | |
propValue.hook(node, | |
propName, | |
previous ? previous[propName] : undefined) | |
} else { | |
if (isObject(propValue)) { | |
if (!isObject(node[propName])) { | |
node[propName] = {} | |
} | |
for (var k in propValue) { | |
node[propName][k] = propValue[k] | |
} | |
} else if (propValue !== undefined) { | |
node[propName] = propValue | |
} | |
} | |
} | |
} | |
},{"../vtree/is-vhook":63,"is-object":53}],57:[function(_dereq_,module,exports){ | |
var document = _dereq_("global/document") | |
var applyProperties = _dereq_("./apply-properties") | |
var isVNode = _dereq_("../vtree/is-vnode") | |
var isVText = _dereq_("../vtree/is-vtext") | |
var isWidget = _dereq_("../vtree/is-widget") | |
module.exports = createElement | |
function createElement(vnode, opts) { | |
var doc = opts ? opts.document || document : document | |
var warn = opts ? opts.warn : null | |
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 | |
} | |
},{"../vtree/is-vnode":64,"../vtree/is-vtext":65,"../vtree/is-widget":66,"./apply-properties":56,"global/document":52}],58:[function(_dereq_,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 | |
} | |
},{}],59:[function(_dereq_,module,exports){ | |
var applyProperties = _dereq_("./apply-properties") | |
var isWidget = _dereq_("../vtree/is-widget") | |
var VPatch = _dereq_("../vtree/vpatch") | |
var render = _dereq_("./create-element") | |
var updateWidget = _dereq_("./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.propeties) | |
return domNode | |
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 | |
for (i = 0; i < len; i++) { | |
children.push(domNode.childNodes[i]) | |
} | |
for (i = 0; i < len; i++) { | |
var move = bIndex[i] | |
if (move !== undefined) { | |
var node = children[move] | |
domNode.removeChild(node) | |
domNode.insertBefore(node, childNodes[i]) | |
} | |
} | |
} | |
},{"../vtree/is-widget":66,"../vtree/vpatch":69,"./apply-properties":56,"./create-element":57,"./update-widget":61}],60:[function(_dereq_,module,exports){ | |
var document = _dereq_("global/document") | |
var isArray = _dereq_("x-is-array") | |
var domIndex = _dereq_("./dom-index") | |
var patchOp = _dereq_("./patch-op") | |
module.exports = patch | |
function patch(rootNode, patches) { | |
var indices = patchIndices(patches) | |
if (indices.length === 0) { | |
return rootNode | |
} | |
var index = domIndex(rootNode, patches.a, indices) | |
var ownerDocument = rootNode.ownerDocument | |
var renderOptions | |
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":58,"./patch-op":59,"global/document":52,"x-is-array":54}],61:[function(_dereq_,module,exports){ | |
var isWidget = _dereq_("../vtree/is-widget") | |
module.exports = updateWidget | |
function updateWidget(a, b) { | |
if (isWidget(a) && isWidget(b)) { | |
if ("type" in a && "type" in b) { | |
return a.type === b.type | |
} else { | |
return a.init === b.init | |
} | |
} | |
return false | |
} | |
},{"../vtree/is-widget":66}],62:[function(_dereq_,module,exports){ | |
var isArray = _dereq_("x-is-array") | |
var isObject = _dereq_("is-object") | |
var VPatch = _dereq_("./vpatch") | |
var isVNode = _dereq_("./is-vnode") | |
var isVText = _dereq_("./is-vtext") | |
var isWidget = _dereq_("./is-widget") | |
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) { | |
hooks(b, patch, index) | |
return | |
} | |
var apply = patch[index] | |
if (isWidget(b)) { | |
apply = appendPatch(apply, new VPatch(VPatch.WIDGET, a, b)) | |
if (!isWidget(a)) { | |
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 (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)) | |
} | |
} else { | |
apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b)) | |
destroyWidgets(a, patch, index) | |
} | |
apply = diffChildren(a, b, patch, apply, index) | |
} else { | |
apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b)) | |
destroyWidgets(a, patch, index) | |
} | |
} else if (b == null) { | |
apply = appendPatch(apply, new VPatch(VPatch.REMOVE, a, b)) | |
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)) { | |
continue | |
} | |
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 && bValue !== undefined) { | |
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 | |
} | |
} | |
} | |
} | |
// 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 = shuffle.moves = {} | |
while (freeIndex < len) { | |
var move = aMatch[i] | |
if (move !== undefined) { | |
shuffle[i] = bChildren[move] | |
moves[move] = moveIndex++ | |
} else if (i in aMatch) { | |
shuffle[i] = undefined | |
} else { | |
while (bMatch[freeIndex] !== undefined) { | |
freeIndex++ | |
} | |
if (freeIndex < len) { | |
moves[freeIndex] = moveIndex++ | |
shuffle[i] = bChildren[freeIndex] | |
freeIndex++ | |
} | |
} | |
i++ | |
} | |
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 | |
} | |
} | |
},{"./is-vnode":64,"./is-vtext":65,"./is-widget":66,"./vpatch":69,"is-object":53,"x-is-array":54}],63:[function(_dereq_,module,exports){ | |
module.exports = isHook | |
function isHook(hook) { | |
return hook && typeof hook.hook === "function" && | |
!hook.hasOwnProperty("hook") | |
} | |
},{}],64:[function(_dereq_,module,exports){ | |
var version = _dereq_("./version") | |
module.exports = isVirtualNode | |
function isVirtualNode(x) { | |
if (!x) { | |
return false; | |
} | |
return x.type === "VirtualNode" && x.version === version | |
} | |
},{"./version":67}],65:[function(_dereq_,module,exports){ | |
var version = _dereq_("./version") | |
module.exports = isVirtualText | |
function isVirtualText(x) { | |
if (!x) { | |
return false; | |
} | |
return x.type === "VirtualText" && x.version === version | |
} | |
},{"./version":67}],66:[function(_dereq_,module,exports){ | |
module.exports = isWidget | |
function isWidget(w) { | |
return w && typeof w.init === "function" && typeof w.update === "function" | |
} | |
},{}],67:[function(_dereq_,module,exports){ | |
module.exports = "1" | |
},{}],68:[function(_dereq_,module,exports){ | |
var version = _dereq_("./version") | |
var isVNode = _dereq_("./is-vnode") | |
var isWidget = _dereq_("./is-widget") | |
var isVHook = _dereq_("./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":63,"./is-vnode":64,"./is-widget":66,"./version":67}],69:[function(_dereq_,module,exports){ | |
var version = _dereq_("./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 | |
module.exports = VirtualPatch | |
function VirtualPatch(type, vNode, patch) { | |
this.type = Number(type) | |
this.vNode = vNode | |
this.patch = patch | |
} | |
VirtualPatch.prototype.version = version.split(".") | |
VirtualPatch.prototype.type = "VirtualPatch" | |
},{"./version":67}],70:[function(_dereq_,module,exports){ | |
var version = _dereq_("./version") | |
module.exports = VirtualText | |
function VirtualText(text) { | |
this.text = String(text) | |
} | |
VirtualText.prototype.version = version | |
VirtualText.prototype.type = "VirtualText" | |
},{"./version":67}],71:[function(_dereq_,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) | |
} | |
},{}],72:[function(_dereq_,module,exports){ | |
var DataSet = _dereq_("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":77}],73:[function(_dereq_,module,exports){ | |
var DataSet = _dereq_("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":77}],74:[function(_dereq_,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; | |
} | |
}; | |
},{}],75:[function(_dereq_,module,exports){ | |
var VNode = _dereq_("virtual-dom/vtree/vnode.js") | |
var VText = _dereq_("virtual-dom/vtree/vtext.js") | |
var isVNode = _dereq_("virtual-dom/vtree/is-vnode") | |
var isVText = _dereq_("virtual-dom/vtree/is-vtext") | |
var isWidget = _dereq_("virtual-dom/vtree/is-widget") | |
var isHook = _dereq_("virtual-dom/vtree/is-vhook") | |
var parseTag = _dereq_("./parse-tag.js") | |
var softSetHook = _dereq_("./hooks/soft-set-hook.js") | |
var dataSetHook = _dereq_("./hooks/data-set-hook.js") | |
var evHook = _dereq_("./hooks/ev-hook.js") | |
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) | |
if (children) { | |
addChild(children, childNodes) | |
} | |
// 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) | |
} | |
} | |
return new VNode(tag, props, childNodes, key, namespace) | |
} | |
function addChild(c, childNodes) { | |
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) | |
} | |
} | |
} | |
function isChild(x) { | |
return isVNode(x) || isVText(x) || isWidget(x) | |
} | |
function isChildren(x) { | |
return typeof x === "string" || Array.isArray(x) || isChild(x) | |
} | |
},{"./hooks/data-set-hook.js":72,"./hooks/ev-hook.js":73,"./hooks/soft-set-hook.js":74,"./parse-tag.js":81,"virtual-dom/vtree/is-vhook":63,"virtual-dom/vtree/is-vnode":64,"virtual-dom/vtree/is-vtext":65,"virtual-dom/vtree/is-widget":66,"virtual-dom/vtree/vnode.js":68,"virtual-dom/vtree/vtext.js":70}],76:[function(_dereq_,module,exports){ | |
module.exports=_dereq_(7) | |
},{}],77:[function(_dereq_,module,exports){ | |
module.exports=_dereq_(8) | |
},{"./create-hash.js":76,"individual":78,"weakmap-shim/create-store":79}],78:[function(_dereq_,module,exports){ | |
module.exports=_dereq_(11) | |
},{}],79:[function(_dereq_,module,exports){ | |
module.exports=_dereq_(9) | |
},{"./hidden-store.js":80}],80:[function(_dereq_,module,exports){ | |
module.exports=_dereq_(10) | |
},{}],81:[function(_dereq_,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" | |
} | |
},{}],82:[function(_dereq_,module,exports){ | |
var attributeHook = _dereq_("./hooks/attribute-hook.js") | |
var h = _dereq_("./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":71,"./index.js":75}],83:[function(_dereq_,module,exports){ | |
module.exports = extend | |
function extend() { | |
var target = {} | |
for (var i = 0; i < arguments.length; i++) { | |
var source = arguments[i] | |
for (var key in source) { | |
if (source.hasOwnProperty(key)) { | |
target[key] = source[key] | |
} | |
} | |
} | |
return target | |
} | |
},{}]},{},[1]) | |
(1) | |
}); | |
var h=mercury.h;var clicks=mercury.input();var clickCount=mercury.value(0);clicks(function(){clickCount.set(clickCount()+1)});function render(clickCount){return h("div.counter",["The state ",h("code","clickCount")," has value: "+clickCount+".",h("input.button",{type:"button",value:"Click me!","ev-click":mercury.event(clicks)})])}mercury.app(document.body,clickCount,render); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "requirebin-sketch", | |
"version": "1.0.0", | |
"dependencies": { | |
"mercury": "3.2.2" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<style type='text/css'>html, body { margin: 0; padding: 0; border: 0; } | |
body, html { height: 100%; width: 100%; }</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment