UNPKG

31.1 kBHTMLView Raw
1<!doctype html>
2<head>
3 <style>
4 body {
5 font-family: sans-serif;
6 color: #333333;
7 }
8
9 .demo, .noedit {
10 font-family: monospace;
11 font-size : 14px;
12 padding : 2px;
13 margin : 0px;
14 border: 1px solid #ccc;
15 display : inline-block;
16 border-radius: 3px;
17 }
18
19 .demoInput {
20 background-color: rgb(255, 255, 244);
21 }
22 .demoOutput {
23 background-color: rgb(172, 243, 172);
24 }
25 .demoError {
26 background-color: rgb(248, 151, 151);
27 }
28 .demoNull {
29 background-color: rgb(224, 203, 149);
30 }
31 .demoIO, .noedit {
32 border: 1px solid #ccc;
33 border-radius: 3px;
34 display: inline-block;
35 padding: 5px;
36 background-color: #f8f8f8;
37 }
38 .noedit {
39 display: block;
40 }
41
42 .markdown {
43 display: inline-block;
44 background: #fff;
45 border-radius: 3px;
46 padding: 3px;
47 font-size: 14px;
48 line-height: 1.6;
49 font: 13px Helvetica, arial, freesans, clean, sans-serif;
50 border: 1px solid #CACACA;
51 margin: 0px auto auto;
52 padding: 0px 30px 0px 30px;
53 text-align: left;
54 }
55
56 .markdown p {
57 max-width: 600px;
58 }
59
60 #centerer {
61 text-align: center;
62 padding: 0px;
63 margin: 0px;
64 }
65
66 .markdown>h2, .markdown>h3,
67 .markdown>h4, .markdown>h5, .markdown>h6 {
68 border-bottom: 1px solid #ccc;
69 }
70
71 .container {
72 padding: 3px;
73 background: #EEE;
74 border-radius: 3px;
75 margin: 0px;
76 display: inline-block;
77 margin-bottom: 200px;
78 }
79
80 #footer {
81 font-size: 10px;
82 text-align: center;
83 }
84
85 </style>
86 <script>var require = function (file, cwd) {
87 var resolved = require.resolve(file, cwd || '/');
88 var mod = require.modules[resolved];
89 if (!mod) throw new Error(
90 'Failed to resolve module ' + file + ', tried ' + resolved
91 );
92 var cached = require.cache[resolved];
93 var res = cached? cached.exports : mod();
94 return res;
95};
96
97require.paths = [];
98require.modules = {};
99require.cache = {};
100require.extensions = [".js",".coffee",".json"];
101
102require._core = {
103 'assert': true,
104 'events': true,
105 'fs': true,
106 'path': true,
107 'vm': true
108};
109
110require.resolve = (function () {
111 return function (x, cwd) {
112 if (!cwd) cwd = '/';
113
114 if (require._core[x]) return x;
115 var path = require.modules.path();
116 cwd = path.resolve('/', cwd);
117 var y = cwd || '/';
118
119 if (x.match(/^(?:\.\.?\/|\/)/)) {
120 var m = loadAsFileSync(path.resolve(y, x))
121 || loadAsDirectorySync(path.resolve(y, x));
122 if (m) return m;
123 }
124
125 var n = loadNodeModulesSync(x, y);
126 if (n) return n;
127
128 throw new Error("Cannot find module '" + x + "'");
129
130 function loadAsFileSync (x) {
131 x = path.normalize(x);
132 if (require.modules[x]) {
133 return x;
134 }
135
136 for (var i = 0; i < require.extensions.length; i++) {
137 var ext = require.extensions[i];
138 if (require.modules[x + ext]) return x + ext;
139 }
140 }
141
142 function loadAsDirectorySync (x) {
143 x = x.replace(/\/+$/, '');
144 var pkgfile = path.normalize(x + '/package.json');
145 if (require.modules[pkgfile]) {
146 var pkg = require.modules[pkgfile]();
147 var b = pkg.browserify;
148 if (typeof b === 'object' && b.main) {
149 var m = loadAsFileSync(path.resolve(x, b.main));
150 if (m) return m;
151 }
152 else if (typeof b === 'string') {
153 var m = loadAsFileSync(path.resolve(x, b));
154 if (m) return m;
155 }
156 else if (pkg.main) {
157 var m = loadAsFileSync(path.resolve(x, pkg.main));
158 if (m) return m;
159 }
160 }
161
162 return loadAsFileSync(x + '/index');
163 }
164
165 function loadNodeModulesSync (x, start) {
166 var dirs = nodeModulesPathsSync(start);
167 for (var i = 0; i < dirs.length; i++) {
168 var dir = dirs[i];
169 var m = loadAsFileSync(dir + '/' + x);
170 if (m) return m;
171 var n = loadAsDirectorySync(dir + '/' + x);
172 if (n) return n;
173 }
174
175 var m = loadAsFileSync(x);
176 if (m) return m;
177 }
178
179 function nodeModulesPathsSync (start) {
180 var parts;
181 if (start === '/') parts = [ '' ];
182 else parts = path.normalize(start).split('/');
183
184 var dirs = [];
185 for (var i = parts.length - 1; i >= 0; i--) {
186 if (parts[i] === 'node_modules') continue;
187 var dir = parts.slice(0, i + 1).join('/') + '/node_modules';
188 dirs.push(dir);
189 }
190
191 return dirs;
192 }
193 };
194})();
195
196require.alias = function (from, to) {
197 var path = require.modules.path();
198 var res = null;
199 try {
200 res = require.resolve(from + '/package.json', '/');
201 }
202 catch (err) {
203 res = require.resolve(from, '/');
204 }
205 var basedir = path.dirname(res);
206
207 var keys = (Object.keys || function (obj) {
208 var res = [];
209 for (var key in obj) res.push(key);
210 return res;
211 })(require.modules);
212
213 for (var i = 0; i < keys.length; i++) {
214 var key = keys[i];
215 if (key.slice(0, basedir.length + 1) === basedir + '/') {
216 var f = key.slice(basedir.length);
217 require.modules[to + f] = require.modules[basedir + f];
218 }
219 else if (key === basedir) {
220 require.modules[to] = require.modules[basedir];
221 }
222 }
223};
224
225(function () {
226 var process = {};
227 var global = typeof window !== 'undefined' ? window : {};
228 var definedProcess = false;
229
230 require.define = function (filename, fn) {
231 if (!definedProcess && require.modules.__browserify_process) {
232 process = require.modules.__browserify_process();
233 definedProcess = true;
234 }
235
236 var dirname = require._core[filename]
237 ? ''
238 : require.modules.path().dirname(filename)
239 ;
240
241 var require_ = function (file) {
242 var requiredModule = require(file, dirname);
243 var cached = require.cache[require.resolve(file, dirname)];
244
245 if (cached && cached.parent === null) {
246 cached.parent = module_;
247 }
248
249 return requiredModule;
250 };
251 require_.resolve = function (name) {
252 return require.resolve(name, dirname);
253 };
254 require_.modules = require.modules;
255 require_.define = require.define;
256 require_.cache = require.cache;
257 var module_ = {
258 id : filename,
259 filename: filename,
260 exports : {},
261 loaded : false,
262 parent: null
263 };
264
265 require.modules[filename] = function () {
266 require.cache[filename] = module_;
267 fn.call(
268 module_.exports,
269 require_,
270 module_,
271 module_.exports,
272 dirname,
273 filename,
274 process,
275 global
276 );
277 module_.loaded = true;
278 return module_.exports;
279 };
280 };
281})();
282
283
284require.define("path",Function(['require','module','exports','__dirname','__filename','process','global'],"function filter (xs, fn) {\n var res = [];\n for (var i = 0; i < xs.length; i++) {\n if (fn(xs[i], i, xs)) res.push(xs[i]);\n }\n return res;\n}\n\n// resolves . and .. elements in a path array with directory names there\n// must be no slashes, empty elements, or device names (c:\\) in the array\n// (so also no leading and trailing slashes - it does not distinguish\n// relative and absolute paths)\nfunction normalizeArray(parts, allowAboveRoot) {\n // if the path tries to go above the root, `up` ends up > 0\n var up = 0;\n for (var i = parts.length; i >= 0; i--) {\n var last = parts[i];\n if (last == '.') {\n parts.splice(i, 1);\n } else if (last === '..') {\n parts.splice(i, 1);\n up++;\n } else if (up) {\n parts.splice(i, 1);\n up--;\n }\n }\n\n // if the path is allowed to go above the root, restore leading ..s\n if (allowAboveRoot) {\n for (; up--; up) {\n parts.unshift('..');\n }\n }\n\n return parts;\n}\n\n// Regex to split a filename into [*, dir, basename, ext]\n// posix version\nvar splitPathRe = /^(.+\\/(?!$)|\\/)?((?:.+?)?(\\.[^.]*)?)$/;\n\n// path.resolve([from ...], to)\n// posix version\nexports.resolve = function() {\nvar resolvedPath = '',\n resolvedAbsolute = false;\n\nfor (var i = arguments.length; i >= -1 && !resolvedAbsolute; i--) {\n var path = (i >= 0)\n ? arguments[i]\n : process.cwd();\n\n // Skip empty and invalid entries\n if (typeof path !== 'string' || !path) {\n continue;\n }\n\n resolvedPath = path + '/' + resolvedPath;\n resolvedAbsolute = path.charAt(0) === '/';\n}\n\n// At this point the path should be resolved to a full absolute path, but\n// handle relative paths to be safe (might happen when process.cwd() fails)\n\n// Normalize the path\nresolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {\n return !!p;\n }), !resolvedAbsolute).join('/');\n\n return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';\n};\n\n// path.normalize(path)\n// posix version\nexports.normalize = function(path) {\nvar isAbsolute = path.charAt(0) === '/',\n trailingSlash = path.slice(-1) === '/';\n\n// Normalize the path\npath = normalizeArray(filter(path.split('/'), function(p) {\n return !!p;\n }), !isAbsolute).join('/');\n\n if (!path && !isAbsolute) {\n path = '.';\n }\n if (path && trailingSlash) {\n path += '/';\n }\n \n return (isAbsolute ? '/' : '') + path;\n};\n\n\n// posix version\nexports.join = function() {\n var paths = Array.prototype.slice.call(arguments, 0);\n return exports.normalize(filter(paths, function(p, index) {\n return p && typeof p === 'string';\n }).join('/'));\n};\n\n\nexports.dirname = function(path) {\n var dir = splitPathRe.exec(path)[1] || '';\n var isWindows = false;\n if (!dir) {\n // No dirname\n return '.';\n } else if (dir.length === 1 ||\n (isWindows && dir.length <= 3 && dir.charAt(1) === ':')) {\n // It is just a slash or a drive letter with a slash\n return dir;\n } else {\n // It is a full dirname, strip trailing slash\n return dir.substring(0, dir.length - 1);\n }\n};\n\n\nexports.basename = function(path, ext) {\n var f = splitPathRe.exec(path)[2] || '';\n // TODO: make this comparison case-insensitive on windows?\n if (ext && f.substr(-1 * ext.length) === ext) {\n f = f.substr(0, f.length - ext.length);\n }\n return f;\n};\n\n\nexports.extname = function(path) {\n return splitPathRe.exec(path)[3] || '';\n};\n\nexports.relative = function(from, to) {\n from = exports.resolve(from).substr(1);\n to = exports.resolve(to).substr(1);\n\n function trim(arr) {\n var start = 0;\n for (; start < arr.length; start++) {\n if (arr[start] !== '') break;\n }\n\n var end = arr.length - 1;\n for (; end >= 0; end--) {\n if (arr[end] !== '') break;\n }\n\n if (start > end) return [];\n return arr.slice(start, end - start + 1);\n }\n\n var fromParts = trim(from.split('/'));\n var toParts = trim(to.split('/'));\n\n var length = Math.min(fromParts.length, toParts.length);\n var samePartsLength = length;\n for (var i = 0; i < length; i++) {\n if (fromParts[i] !== toParts[i]) {\n samePartsLength = i;\n break;\n }\n }\n\n var outputParts = [];\n for (var i = samePartsLength; i < fromParts.length; i++) {\n outputParts.push('..');\n }\n\n outputParts = outputParts.concat(toParts.slice(samePartsLength));\n\n return outputParts.join('/');\n};\n\n//@ sourceURL=path"
285));
286
287require.define("__browserify_process",Function(['require','module','exports','__dirname','__filename','process','global'],"var process = module.exports = {};\n\nprocess.nextTick = (function () {\n var canSetImmediate = typeof window !== 'undefined'\n && window.setImmediate;\n var canPost = typeof window !== 'undefined'\n && window.postMessage && window.addEventListener\n ;\n\n if (canSetImmediate) {\n return function (f) { return window.setImmediate(f) };\n }\n\n if (canPost) {\n var queue = [];\n window.addEventListener('message', function (ev) {\n if (ev.source === window && ev.data === 'browserify-tick') {\n ev.stopPropagation();\n if (queue.length > 0) {\n var fn = queue.shift();\n fn();\n }\n }\n }, true);\n\n return function nextTick(fn) {\n queue.push(fn);\n window.postMessage('browserify-tick', '*');\n };\n }\n\n return function nextTick(fn) {\n setTimeout(fn, 0);\n };\n})();\n\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\n\nprocess.binding = function (name) {\n if (name === 'evals') return (require)('vm')\n else throw new Error('No such module. (Possibly not yet loaded)')\n};\n\n(function () {\n var cwd = '/';\n var path;\n process.cwd = function () { return cwd };\n process.chdir = function (dir) {\n if (!path) path = require('path');\n cwd = path.resolve(dir, cwd);\n };\n})();\n\n//@ sourceURL=__browserify_process"
288));
289
290require.define("/node_modules/hyperscript/node_modules/hyperscript/package.json",Function(['require','module','exports','__dirname','__filename','process','global'],"module.exports = {}\n//@ sourceURL=/node_modules/hyperscript/node_modules/hyperscript/package.json"
291));
292
293require.define("/node_modules/hyperscript/index.js",Function(['require','module','exports','__dirname','__filename','process','global'],";(function () {\n\nvar ClassList = require(\"class-list\")\n\nfunction h() {\n var args = [].slice.call(arguments), e = null\n function item (l) {\n var r\n function parseClass (string) {\n var m = string.split(/([\\.#]?[a-zA-Z0-9_-]+)/)\n m.forEach(function (v) {\n var s = v.substring(1,v.length)\n if(!v) return\n if(!e)\n e = document.createElement(v)\n else if (v[0] === '.')\n ClassList(e).add(s)\n else if (v[0] === '#')\n e.setAttribute('id', s)\n })\n }\n\n if(l == null)\n ;\n else if('string' === typeof l) {\n if(!e)\n parseClass(l)\n else\n e.appendChild(r = document.createTextNode(l))\n }\n else if('number' === typeof l\n || 'boolean' === typeof l\n || l instanceof Date\n || l instanceof RegExp ) {\n e.appendChild(r = document.createTextNode(l.toString()))\n }\n //there might be a better way to handle this...\n else if (Array.isArray(l))\n l.forEach(item)\n else if(l instanceof Node)\n e.appendChild(r = l)\n else if(l instanceof Text)\n e.appendChild(r = l)\n else if ('object' === typeof l) {\n for (var k in l) {\n if('function' === typeof l[k]) {\n if(/^on\\w+/.test(k)) {\n e.addEventListener(k.substring(2), l[k])\n } else {\n e[k] = l[k]()\n l[k](function (v) {\n e[k] = v\n })\n }\n }\n else if(k === 'style') {\n for (var s in l[k]) (function(s, v) {\n if('function' === typeof v) {\n e.style.setProperty(s, v())\n v(function (val) {\n e.style.setProperty(s, val)\n })\n } else\n e.style.setProperty(s, l[k][s])\n })(s, l[k][s])\n } else\n e[k] = l[k]\n }\n } else if ('function' === typeof l) {\n //assume it's an observable!\n var v = l()\n e.appendChild(r = v instanceof Node ? v : document.createTextNode(v))\n\n l(function (v) {\n if(v instanceof Node && r.parentElement)\n r.parentElement.replaceChild(v, r), r = v\n else\n r.textContent = v\n })\n\n }\n\n return r\n }\n while(args.length)\n item(args.shift())\n\n return e\n}\n\nif(typeof module === 'object')\n module.exports = h\nelse\n this.hyperscript = h\n})()\n\n//@ sourceURL=/node_modules/hyperscript/index.js"
294));
295
296require.define("/node_modules/hyperscript/node_modules/class-list/package.json",Function(['require','module','exports','__dirname','__filename','process','global'],"module.exports = {\"main\":\"index\"}\n//@ sourceURL=/node_modules/hyperscript/node_modules/class-list/package.json"
297));
298
299require.define("/node_modules/hyperscript/node_modules/class-list/index.js",Function(['require','module','exports','__dirname','__filename','process','global'],"// contains, add, remove, toggle\n\nmodule.exports = ClassList\n\nfunction ClassList(elem) {\n var cl = elem.classList\n\n if (cl) {\n return cl\n }\n\n var classList = {\n add: add\n , remove: remove\n , contains: contains\n , toggle: toggle\n , toString: $toString\n , length: 0\n , item: item\n }\n\n return classList\n\n function add(token) {\n var list = getTokens()\n if (list.indexOf(token) > -1) {\n return\n }\n list.push(token)\n setTokens(list)\n }\n\n function remove(token) {\n var list = getTokens()\n , index = list.indexOf(token)\n\n if (index === -1) {\n return\n }\n\n list.splice(index, 1)\n setTokens(list)\n }\n\n function contains(token) {\n return getTokens().indexOf(token) > -1\n }\n\n function toggle(token) {\n if (contains(token)) {\n remove(token)\n return false\n } else {\n add(token)\n return true\n }\n }\n\n function $toString() {\n return elem.className\n }\n\n function item(index) {\n var tokens = getTokens()\n return tokens[index] || null\n }\n\n function getTokens() {\n var className = elem.className\n\n return className.split(\" \").filter(isTruthy)\n }\n\n function setTokens(list) {\n var length = list.length\n\n elem.className = list.join(\" \")\n classList.length = length\n\n for (var i = 0; i < list.length; i++) {\n classList[i] = list[i]\n }\n\n delete list[length]\n }\n}\n\nfunction isTruthy(value) {\n return !!value\n}\n//@ sourceURL=/node_modules/hyperscript/node_modules/class-list/index.js"
300));
301
302require.define("/tmp.js",Function(['require','module','exports','__dirname','__filename','process','global'],"var funx = [\nfunction () {\nvar h = require('hyperscript')\nh('div#page',\n h('div#header',\n h('h1.classy', 'h', { style: {'background-color': '#22f'} })),\n h('div#menu', { style: {'background-color': '#2f2'} },\n h('ul',\n h('li', 'one'),\n h('li', 'two'),\n h('li', 'three'))),\n h('h2', 'content title', { style: {'background-color': '#f22'} }),\n h('p', \n \"so it's just like a templating engine,\\n\",\n \"but easy to use inline with javascript\\n\"),\n h('p', \n \"the intension is for this to be used to create\\n\",\n \"reusable, interactive html widgets. \"))\n},\nfunction () {\nvar h = require('hyperscript')\nh('a', {href: 'https://npm.im/hyperscript'}, 'hyperscript')\n},\nfunction () {\nvar h = require('hyperscript')\nh('a', {href: '#', \n onclick: function (e) {\n alert('you are 1,000,000th visitor!')\n e.preventDefault()\n }\n}, 'click here to win a prize')\n},\nfunction () {\nvar h = require('hyperscript')\nh('h1.fun', {style: {'font-family': 'Comic Sans MS'}}, 'Happy Birthday!')\n},\nfunction () {\nvar h = require('hyperscript')\nvar obj = {\n a: 'Apple',\n b: 'Banana',\n c: 'Cherry',\n d: 'Durian',\n e: 'Elder Berry'\n}\nh('table',\n h('tr', h('th', 'letter'), h('th', 'fruit')),\n Object.keys(obj).map(function (k) {\n return h('tr', \n h('th', k),\n h('td', obj[k])\n )\n })\n)\n}\n];\n\n//@ sourceURL=/tmp.js"
303));
304require("/tmp.js");
305
306</script>
307</head>
308<body>
309 <div id=centerer>
310 <div class=container><div class=markdown>
311 <h1>HyperScript</h1>
312<p>Create HyperText with JavaScript.</p>
313<p><a href="http://dominictarr.github.com/hyperscript">Interactive Demo</a></p>
314<h2>Example</h2>
315<pre><code class="lang-js">var h = require(&#39;hyperscript&#39;)
316h(&#39;div#page&#39;,
317 h(&#39;div#header&#39;,
318 h(&#39;h1.classy&#39;, &#39;h&#39;, { style: {&#39;background-color&#39;: &#39;#22f&#39;} })),
319 h(&#39;div#menu&#39;, { style: {&#39;background-color&#39;: &#39;#2f2&#39;} },
320 h(&#39;ul&#39;,
321 h(&#39;li&#39;, &#39;one&#39;),
322 h(&#39;li&#39;, &#39;two&#39;),
323 h(&#39;li&#39;, &#39;three&#39;))),
324 h(&#39;h2&#39;, &#39;content title&#39;, { style: {&#39;background-color&#39;: &#39;#f22&#39;} }),
325 h(&#39;p&#39;,
326 &quot;so it&#39;s just like a templating engine,\n&quot;,
327 &quot;but easy to use inline with javascript\n&quot;),
328 h(&#39;p&#39;,
329 &quot;the intension is for this to be used to create\n&quot;,
330 &quot;reusable, interactive html widgets. &quot;))</code></pre>
331<h2>h (tag, attrs, [text?, Elements?,...])</h2>
332<p>Create an <code>HTMLElement</code>. first argument must be the tag name.</p>
333<h3>classes &amp; id</h3>
334<p>If the tag name is of form <code>name.class1.class2#id</code> that is a short cut
335for setting the class and id.</p>
336<h3>Attributes</h3>
337<p>If an <code>{}</code> object is passed in, it&#39;s values will be used to set attributes.</p>
338<pre><code class="lang-js">var h = require(&#39;hyperscript&#39;)
339h(&#39;a&#39;, {href: &#39;https://npm.im/hyperscript&#39;}, &#39;hyperscript&#39;)</code></pre>
340<h3>events</h3>
341<p>If an attribute is a function, then it will be registered as an event listener.</p>
342<pre><code class="lang-js">var h = require(&#39;hyperscript&#39;)
343h(&#39;a&#39;, {href: &#39;#&#39;,
344 onclick: function (e) {
345 alert(&#39;you are 1,000,000th visitor!&#39;)
346 e.preventDefault()
347 }
348}, &#39;click here to win a prize&#39;)</code></pre>
349<h3>styles</h3>
350<p>If an attribute has a style property, then that will be handled specially.</p>
351<pre><code class="lang-js">var h = require(&#39;hyperscript&#39;)
352h(&#39;h1.fun&#39;, {style: {&#39;font-family&#39;: &#39;Comic Sans MS&#39;}}, &#39;Happy Birthday!&#39;)</code></pre>
353<p>You may pass in attributes in multiple positions, it&#39;s no problem!</p>
354<h3>children - string</h3>
355<p>If an argument is a string, a TextNode is created in that position.</p>
356<h3>children - HTMLElement</h3>
357<p>If a argument is a <code>Node</code> (or <code>HTMLElement</code>), for example, the return value of a call to <code>h</code>
358thats cool too.</p>
359<h3>children - null.</h3>
360<p>This is just ignored.</p>
361<h3>children - Array</h3>
362<p>Each item in the array is treated like a ordinary child. (string or HTMLElement)
363this is uesful when you want to iterate over an object:</p>
364<pre><code>var h = require(&#39;hyperscript&#39;)
365var obj = {
366 a: &#39;Apple&#39;,
367 b: &#39;Banana&#39;,
368 c: &#39;Cherry&#39;,
369 d: &#39;Durian&#39;,
370 e: &#39;Elder Berry&#39;
371}
372h(&#39;table&#39;,
373 h(&#39;tr&#39;, h(&#39;th&#39;, &#39;letter&#39;), h(&#39;th&#39;, &#39;fruit&#39;)),
374 Object.keys(obj).map(function (k) {
375 return h(&#39;tr&#39;,
376 h(&#39;th&#39;, k),
377 h(&#39;td&#39;, obj[k])
378 )
379 })
380)</code></pre>
381<h2>License</h2>
382<p>MIT</p>
383
384 </div></div>
385 </div>
386<div id=footer>
387created with <a href=https://github.com/dominictarr/demonstrate>demonstrate</a>
388</div>
389 <script>;(function () {
390;(function () {
391
392function h() {
393 var args = [].slice.call(arguments), e = null
394 function item (l) {
395 var r
396 function parseClass (string) {
397 var m = string.split(/([\.#]?[a-zA-Z0-9_-]+)/)
398 m.forEach(function (v) {
399 var s = v.substring(1,v.length)
400 if(!v) return
401 if(!e)
402 e = document.createElement(v)
403 else if (v[0] === '.')
404 e.classList.add(s)
405 else if (v[0] === '#')
406 e.setAttribute('id', s)
407 })
408 }
409
410 if(l == null)
411 ;
412 else if('string' === typeof l) {
413 if(!e)
414 parseClass(l)
415 else
416 e.appendChild(r = document.createTextNode(l))
417 }
418 else if('number' === typeof l
419 || 'boolean' === typeof l
420 || l instanceof Date
421 || l instanceof RegExp ) {
422 e.appendChild(r = document.createTextNode(l.toString()))
423 }
424 //there might be a better way to handle this...
425 else if (Array.isArray(l))
426 l.forEach(item)
427 else if(l instanceof Node)
428 e.appendChild(r = l)
429 else if(l instanceof Text)
430 e.appendChild(r = l)
431 else if ('object' === typeof l) {
432 for (var k in l) {
433 if('function' === typeof l[k]) {
434 if(/^on\w+/.test(k)) {
435 e.addEventListener(k, l[k])
436 } else {
437 e[k] = l[k]()
438 l[k](function (v) {
439 e[k] = v
440 })
441 }
442 }
443 else if(k === 'style') {
444 for (var s in l[k]) (function(s, v) {
445 if('function' === typeof v) {
446 e.style.setProperty(s, v())
447 v(function (val) {
448 e.style.setProperty(s, val)
449 })
450 } else
451 e.style.setProperty(s, l[k][s])
452 })(s, l[k][s])
453 } else
454 e[k] = l[k]
455 }
456 } else if ('function' === typeof l) {
457 //assume it's an observable!
458 var v = l()
459 e.appendChild(r = v instanceof Node ? v : document.createTextNode(v))
460
461 l(function (v) {
462 if(v instanceof Node && r.parentElement)
463 r.parentElement.replaceChild(v, r), r = v
464 else
465 r.textContent = v
466 })
467
468 }
469
470 return r
471 }
472 while(args.length)
473 item(args.shift())
474
475 return e
476}
477
478if(typeof module === 'object')
479 module.exports = h
480else
481 this.hyperscript = h
482})()
483;(function () {
484
485//---util-funtions------
486
487function all(ary, val) {
488 for(var k in ary)
489 ary[k](val)
490}
491
492function remove(ary, item) {
493 delete ary[ary.indexOf(item)]
494}
495
496/*
497##value
498An observable that stores a value.
499*/
500
501function value () {
502 var _val, listeners = []
503 return function (val) {
504 return (
505 get(val) ? _val
506 : set(val) ? all(listeners, _val = val)
507 : (listeners.push(val), function () {
508 remove(listeners, val)
509 })
510 )}}
511
512/*
513##property
514observe a property of an object, works with scuttlebutt.
515could change this to work with backbone Model - but it would become ugly.
516*/
517
518function get(val) {
519 //void(0) is a trick to get a true undefined value, even if user has overwrit
520 return undefined === val
521}
522
523/*
524### set(val) _(private)_
525return true if this call is a set (a non function is supplied)
526set(val) assumes you have already checked get(val)
527if the call is neither a get or a set, a function is passed, it's a listen.
528*/
529
530function set(val) {
531 return 'function' !== typeof val
532}
533
534/*
535now, lets rewrite our first example
536*/
537
538function property (model, key) {
539 return function (val) {
540 return (
541 get(val) ? model.get(key) :
542 set(val) ? model.set(key, val) :
543 (model.on('change:'+key, val), function () {
544 model.removeListener('change:'+key, val)
545 })
546 )}}
547 //^ if written in this style, always ends )}}
548
549/*
550note the use of the elvis operator `?:` in chained else-if formation,
551and also the comma operator `,` which evaluates each part and then
552returns the last value.
553
554only 8 lines! that isn't much for what this baby can do!
555*/
556
557function transform (observable, down, up) {
558 return function (val) {
559 return (
560 get(val) ? down(observable())
561 : set(val) ? observable((up || down)(val))
562 : observable(function (_val) { val(down(_val)) })
563 )}}
564
565function not(observable) {
566 return transform(observable, function (v) { return !v })
567}
568
569function listen (element, event, attr, listener) {
570 function onEvent () {
571 listener(element[attr])
572 }
573 element.addEventListener(event, onEvent, false)
574 return function () {
575 element.removeEventListener(event, onEvent, false)
576 }
577}
578
579function attribute(element, attr, event) {
580 attr = attr || 'value'; event = event || 'input'
581 return function (val) {
582 return (
583 get(val) ? element[attr]
584 : set(val) ? element[attr] = val
585 : listen(element, event, attr, val)
586 )}}
587
588
589function html (element) {
590 return attribute(element, 'innerHTML', false) //read only
591}
592
593function error (message) {
594 throw new Error(message)
595}
596
597function compute (observables, compute) {
598 function getAll() {
599 return compute.apply(null, observables.map(function (e) {return e()}))
600 }
601 return function (val) {
602 return (
603 get(val) ? getAll()
604 : set(val) ? error('read-only')
605 : observables.forEach(function (obs) {
606 obs(function () { val(getAll()) })
607 })
608 )}}
609
610function boolean (observable, truthy, falsey) {
611 return transform(observable, function (val) {
612 return val ? truthy : falsey
613 }, function (val) {
614 return val == truthy ? true : false
615 })
616 }
617
618var exports = value
619
620exports.value = value
621exports.not = not
622exports.input =
623exports.attribute = attribute
624exports.html = html
625exports.compute = compute
626exports.transform = transform
627exports.boolean = boolean
628
629if('object' === typeof module) module.exports = exports
630else this.observable = exports
631})()
632var h = hyperscript
633var o = observable
634var a = [].slice.call(document.body.getElementsByTagName('pre'))
635
636a.filter(function (e) {
637 return !~[].slice.call(e.classList).indexOf('noedit')
638}).forEach(function (e) {
639
640 var textarea
641 var demo =
642 h('div.demoIO',
643 textarea = h('textarea.demo.demoInput',
644 {cols: 80, rows: e.innerText.split('\n').length + 1},
645 e.innerText),
646 h('div', o.transform(o.input(textarea), function (code) {
647 try {
648 var r = eval(code)
649 if(r instanceof Node)
650 return r
651 if(r == null)
652 return h('pre.demo.demoNull', r === null ? 'null' : 'undefined')
653
654 return h('pre.demo.demoOutput', r)
655 }
656 catch (err) { return h('pre.demo.demoError', err.toString()) }
657 })
658 )
659 )
660
661 //no scrolling!
662 //It's much nicer to just resize the textarea to fit
663
664 o.input(textarea)(function (v) {
665 textarea.rows = v.split('\n').length + 1
666 })
667
668 e.parentElement.replaceChild(demo, e)
669
670
671})
672
673;})();
674</script>
675</body>
676</html>
677