mithril_rails 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/mithril.js +139 -116
- data/lib/mithril_rails/version.rb +1 -1
- metadata +10 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b6a280ee516de13bb19b02a57d8e81a379ff692
|
4
|
+
data.tar.gz: 3d3b67557ab7f491d273404f749b4429fe61d77c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b209e73c2b7385d1ead06e2f5f53706045b2b1b1864eeeb3a02af97516cb735fbedab792ddd4637399ec6aea70028dbec34348e18e49d1fdfd3ac6432b2c7285
|
7
|
+
data.tar.gz: 10cfd7659cff335878713bec7bbe4221685fbecac7b6ade88ae8d68e31f988d4d2857dc3b523929b7c72979567fba5cdf088f748635ce4d33d1718bf46def39c
|
@@ -33,17 +33,17 @@ var m = (function app(window, undefined) {
|
|
33
33
|
*/
|
34
34
|
function m() {
|
35
35
|
var args = [].slice.call(arguments);
|
36
|
-
var hasAttrs = args[1] != null && type.call(args[1])
|
36
|
+
var hasAttrs = args[1] != null && type.call(args[1]) === OBJECT && !("tag" in args[1]) && !("subtree" in args[1]);
|
37
37
|
var attrs = hasAttrs ? args[1] : {};
|
38
38
|
var classAttrName = "class" in attrs ? "class" : "className";
|
39
39
|
var cell = {tag: "div", attrs: {}};
|
40
40
|
var match, classes = [];
|
41
41
|
if (type.call(args[0]) != STRING) throw new Error("selector in m(selector, attrs, children) should be a string")
|
42
42
|
while (match = parser.exec(args[0])) {
|
43
|
-
if (match[1]
|
44
|
-
else if (match[1]
|
45
|
-
else if (match[1]
|
46
|
-
else if (match[3][0]
|
43
|
+
if (match[1] === "" && match[2]) cell.tag = match[2];
|
44
|
+
else if (match[1] === "#") cell.attrs.id = match[2];
|
45
|
+
else if (match[1] === ".") classes.push(match[2]);
|
46
|
+
else if (match[3][0] === "[") {
|
47
47
|
var pair = attrParser.exec(match[3]);
|
48
48
|
cell.attrs[pair[1]] = pair[3] || (pair[2] ? "" :true)
|
49
49
|
}
|
@@ -52,7 +52,7 @@ var m = (function app(window, undefined) {
|
|
52
52
|
|
53
53
|
|
54
54
|
var children = hasAttrs ? args[2] : args[1];
|
55
|
-
if (type.call(children)
|
55
|
+
if (type.call(children) === ARRAY) {
|
56
56
|
cell.children = children
|
57
57
|
}
|
58
58
|
else {
|
@@ -60,7 +60,7 @@ var m = (function app(window, undefined) {
|
|
60
60
|
}
|
61
61
|
|
62
62
|
for (var attrName in attrs) {
|
63
|
-
if (attrName
|
63
|
+
if (attrName === classAttrName) cell.attrs[attrName] = (cell.attrs[attrName] || "") + " " + attrs[attrName];
|
64
64
|
else cell.attrs[attrName] = attrs[attrName]
|
65
65
|
}
|
66
66
|
return cell
|
@@ -91,14 +91,15 @@ var m = (function app(window, undefined) {
|
|
91
91
|
//there's logic that relies on the assumption that null and undefined data are equivalent to empty strings
|
92
92
|
//- this prevents lifecycle surprises from procedural helpers that mix implicit and explicit return statements (e.g. function foo() {if (cond) return m("div")}
|
93
93
|
//- it simplifies diffing code
|
94
|
-
|
94
|
+
//data.toString() is null if data is the return value of Console.log in Firefox
|
95
|
+
if (data == null || data.toString() == null) data = "";
|
95
96
|
if (data.subtree === "retain") return cached;
|
96
97
|
var cachedType = type.call(cached), dataType = type.call(data);
|
97
|
-
if (cached == null || cachedType
|
98
|
+
if (cached == null || cachedType !== dataType) {
|
98
99
|
if (cached != null) {
|
99
100
|
if (parentCache && parentCache.nodes) {
|
100
101
|
var offset = index - parentIndex;
|
101
|
-
var end = offset + (dataType
|
102
|
+
var end = offset + (dataType === ARRAY ? data : cached.nodes).length;
|
102
103
|
clear(parentCache.nodes.slice(offset, end), parentCache.slice(offset, end))
|
103
104
|
}
|
104
105
|
else if (cached.nodes) clear(cached.nodes, cached)
|
@@ -108,10 +109,10 @@ var m = (function app(window, undefined) {
|
|
108
109
|
cached.nodes = []
|
109
110
|
}
|
110
111
|
|
111
|
-
if (dataType
|
112
|
+
if (dataType === ARRAY) {
|
112
113
|
//recursively flatten array
|
113
|
-
for (var i = 0
|
114
|
-
if (type.call(data[i])
|
114
|
+
for (var i = 0, len = data.length; i < len; i++) {
|
115
|
+
if (type.call(data[i]) === ARRAY) {
|
115
116
|
data = data.concat.apply([], data);
|
116
117
|
i-- //check current index again and flatten until there are no more nested arrays at that index
|
117
118
|
}
|
@@ -134,56 +135,70 @@ var m = (function app(window, undefined) {
|
|
134
135
|
}
|
135
136
|
}
|
136
137
|
if (shouldMaintainIdentities) {
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
from: existing[key].index,
|
146
|
-
element: parentElement.childNodes[existing[key].index] || $document.createElement("div")
|
147
|
-
}
|
148
|
-
}
|
149
|
-
else unkeyed.push({index: i, element: parentElement.childNodes[i] || $document.createElement("div")})
|
138
|
+
if (data.indexOf(null) > -1) data = data.filter(function(x) {return x != null})
|
139
|
+
|
140
|
+
var keysDiffer = false
|
141
|
+
if (data.length != cached.length) keysDiffer = true
|
142
|
+
else for (var i = 0, cachedCell, dataCell; cachedCell = cached[i], dataCell = data[i]; i++) {
|
143
|
+
if (cachedCell.attrs && dataCell.attrs && cachedCell.attrs.key != dataCell.attrs.key) {
|
144
|
+
keysDiffer = true
|
145
|
+
break
|
150
146
|
}
|
151
147
|
}
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
148
|
+
|
149
|
+
if (keysDiffer) {
|
150
|
+
for (var i = 0, len = data.length; i < len; i++) {
|
151
|
+
if (data[i] && data[i].attrs) {
|
152
|
+
if (data[i].attrs.key != null) {
|
153
|
+
var key = data[i].attrs.key;
|
154
|
+
if (!existing[key]) existing[key] = {action: INSERTION, index: i};
|
155
|
+
else existing[key] = {
|
156
|
+
action: MOVE,
|
157
|
+
index: i,
|
158
|
+
from: existing[key].index,
|
159
|
+
element: parentElement.childNodes[existing[key].index] || $document.createElement("div")
|
160
|
+
}
|
161
|
+
}
|
162
|
+
else unkeyed.push({index: i, element: parentElement.childNodes[i] || $document.createElement("div")})
|
163
|
+
}
|
166
164
|
}
|
165
|
+
var actions = []
|
166
|
+
for (var prop in existing) actions.push(existing[prop])
|
167
|
+
var changes = actions.sort(sortChanges);
|
168
|
+
var newCached = new Array(cached.length)
|
169
|
+
|
170
|
+
for (var i = 0, change; change = changes[i]; i++) {
|
171
|
+
if (change.action === DELETION) {
|
172
|
+
clear(cached[change.index].nodes, cached[change.index]);
|
173
|
+
newCached.splice(change.index, 1)
|
174
|
+
}
|
175
|
+
if (change.action === INSERTION) {
|
176
|
+
var dummy = $document.createElement("div");
|
177
|
+
dummy.key = data[change.index].attrs.key;
|
178
|
+
parentElement.insertBefore(dummy, parentElement.childNodes[change.index] || null);
|
179
|
+
newCached.splice(change.index, 0, {attrs: {key: data[change.index].attrs.key}, nodes: [dummy]})
|
180
|
+
}
|
167
181
|
|
168
|
-
|
169
|
-
|
170
|
-
|
182
|
+
if (change.action === MOVE) {
|
183
|
+
if (parentElement.childNodes[change.index] !== change.element && change.element !== null) {
|
184
|
+
parentElement.insertBefore(change.element, parentElement.childNodes[change.index] || null)
|
185
|
+
}
|
186
|
+
newCached[change.index] = cached[change.from]
|
171
187
|
}
|
172
|
-
newCached[change.index] = cached[change.from]
|
173
188
|
}
|
189
|
+
for (var i = 0, len = unkeyed.length; i < len; i++) {
|
190
|
+
var change = unkeyed[i];
|
191
|
+
parentElement.insertBefore(change.element, parentElement.childNodes[change.index] || null);
|
192
|
+
newCached[change.index] = cached[change.index]
|
193
|
+
}
|
194
|
+
cached = newCached;
|
195
|
+
cached.nodes = new Array(parentElement.childNodes.length);
|
196
|
+
for (var i = 0, child; child = parentElement.childNodes[i]; i++) cached.nodes[i] = child
|
174
197
|
}
|
175
|
-
for (var i = 0; i < unkeyed.length; i++) {
|
176
|
-
var change = unkeyed[i];
|
177
|
-
parentElement.insertBefore(change.element, parentElement.childNodes[change.index] || null);
|
178
|
-
newCached[change.index] = cached[change.index]
|
179
|
-
}
|
180
|
-
cached = newCached;
|
181
|
-
cached.nodes = [];
|
182
|
-
for (var i = 0, child; child = parentElement.childNodes[i]; i++) cached.nodes.push(child)
|
183
198
|
}
|
184
199
|
//end key algorithm
|
185
200
|
|
186
|
-
for (var i = 0, cacheCount = 0
|
201
|
+
for (var i = 0, cacheCount = 0, len = data.length; i < len; i++) {
|
187
202
|
//diff each item in the array
|
188
203
|
var item = build(parentElement, parentTag, cached, index, data[i], cached[cacheCount], shouldReattach, index + subArrayCount || subArrayCount, editable, namespace, configs);
|
189
204
|
if (item === undefined) continue;
|
@@ -194,14 +209,14 @@ var m = (function app(window, undefined) {
|
|
194
209
|
//the second clause (after the pipe) matches text nodes
|
195
210
|
subArrayCount += (item.match(/<[^\/]|\>\s*[^<]/g) || []).length
|
196
211
|
}
|
197
|
-
else subArrayCount += type.call(item)
|
212
|
+
else subArrayCount += type.call(item) === ARRAY ? item.length : 1;
|
198
213
|
cached[cacheCount++] = item
|
199
214
|
}
|
200
215
|
if (!intact) {
|
201
216
|
//diff the array itself
|
202
217
|
|
203
218
|
//update the list of DOM nodes by collecting the nodes from each item
|
204
|
-
for (var i = 0
|
219
|
+
for (var i = 0, len = data.length; i < len; i++) {
|
205
220
|
if (cached[i] != null) nodes.push.apply(nodes, cached[i].nodes)
|
206
221
|
}
|
207
222
|
//remove items from the end of the array if the new array is shorter than the old one
|
@@ -213,16 +228,16 @@ var m = (function app(window, undefined) {
|
|
213
228
|
cached.nodes = nodes
|
214
229
|
}
|
215
230
|
}
|
216
|
-
else if (data != null && dataType
|
231
|
+
else if (data != null && dataType === OBJECT) {
|
217
232
|
if (!data.attrs) data.attrs = {};
|
218
233
|
if (!cached.attrs) cached.attrs = {};
|
219
234
|
|
220
|
-
var dataAttrKeys = Object.keys(data.attrs)
|
235
|
+
var dataAttrKeys = Object.keys(data.attrs)
|
221
236
|
var hasKeys = dataAttrKeys.length > ("key" in data.attrs ? 1 : 0)
|
222
237
|
//if an element is different enough from the one in cache, recreate it
|
223
238
|
if (data.tag != cached.tag || dataAttrKeys.join() != Object.keys(cached.attrs).join() || data.attrs.id != cached.attrs.id) {
|
224
239
|
if (cached.nodes.length) clear(cached.nodes);
|
225
|
-
if (cached.configContext && typeof cached.configContext.onunload
|
240
|
+
if (cached.configContext && typeof cached.configContext.onunload === FUNCTION) cached.configContext.onunload()
|
226
241
|
}
|
227
242
|
if (type.call(data.tag) != STRING) return;
|
228
243
|
|
@@ -236,7 +251,7 @@ var m = (function app(window, undefined) {
|
|
236
251
|
cached = {
|
237
252
|
tag: data.tag,
|
238
253
|
//set attributes first, then create children
|
239
|
-
attrs:
|
254
|
+
attrs: hasKeys ? setAttributes(node, data.tag, data.attrs, {}, namespace) : data.attrs,
|
240
255
|
children: data.children != null && data.children.length > 0 ?
|
241
256
|
build(node, data.tag, undefined, undefined, data.children, cached.children, true, 0, data.attrs.contenteditable ? node : editable, namespace, configs) :
|
242
257
|
data.children,
|
@@ -244,18 +259,18 @@ var m = (function app(window, undefined) {
|
|
244
259
|
};
|
245
260
|
if (cached.children && !cached.children.nodes) cached.children.nodes = [];
|
246
261
|
//edge case: setting value on <select> doesn't work before children exist, so set it again after children have been created
|
247
|
-
if (data.tag
|
262
|
+
if (data.tag === "select" && data.attrs.value) setAttributes(node, data.tag, {value: data.attrs.value}, {}, namespace);
|
248
263
|
parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
249
264
|
}
|
250
265
|
else {
|
251
266
|
node = cached.nodes[0];
|
252
|
-
if (
|
267
|
+
if (hasKeys) setAttributes(node, data.tag, data.attrs, cached.attrs, namespace);
|
253
268
|
cached.children = build(node, data.tag, undefined, undefined, data.children, cached.children, false, 0, data.attrs.contenteditable ? node : editable, namespace, configs);
|
254
269
|
cached.nodes.intact = true;
|
255
270
|
if (shouldReattach === true && node != null) parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
256
271
|
}
|
257
272
|
//schedule configs to be called. They are called after `build` finishes running
|
258
|
-
if (typeof data.attrs["config"]
|
273
|
+
if (typeof data.attrs["config"] === FUNCTION) {
|
259
274
|
var context = cached.configContext = cached.configContext || {};
|
260
275
|
|
261
276
|
// bind
|
@@ -294,7 +309,7 @@ var m = (function app(window, undefined) {
|
|
294
309
|
if (parentTag === "textarea") parentElement.value = data;
|
295
310
|
else if (editable) editable.innerHTML = data;
|
296
311
|
else {
|
297
|
-
if (nodes[0].nodeType
|
312
|
+
if (nodes[0].nodeType === 1 || nodes.length > 1) { //was a trusted string
|
298
313
|
clear(cached.nodes, cached);
|
299
314
|
nodes = [$document.createTextNode(data)]
|
300
315
|
}
|
@@ -311,6 +326,7 @@ var m = (function app(window, undefined) {
|
|
311
326
|
|
312
327
|
return cached
|
313
328
|
}
|
329
|
+
function sortChanges(a, b) {return a.action - b.action || a.index - b.index}
|
314
330
|
function setAttributes(node, tag, dataAttrs, cachedAttrs, namespace) {
|
315
331
|
for (var attrName in dataAttrs) {
|
316
332
|
var dataAttr = dataAttrs[attrName];
|
@@ -319,14 +335,13 @@ var m = (function app(window, undefined) {
|
|
319
335
|
cachedAttrs[attrName] = dataAttr;
|
320
336
|
try {
|
321
337
|
//`config` isn't a real attributes, so ignore it
|
322
|
-
|
323
|
-
if (attrName === "config") continue;
|
338
|
+
if (attrName === "config" || attrName == "key") continue;
|
324
339
|
//hook event handlers to the auto-redrawing system
|
325
|
-
else if (typeof dataAttr
|
340
|
+
else if (typeof dataAttr === FUNCTION && attrName.indexOf("on") === 0) {
|
326
341
|
node[attrName] = autoredraw(dataAttr, node)
|
327
342
|
}
|
328
343
|
//handle `style: {...}`
|
329
|
-
else if (attrName === "style" && dataAttr != null && type.call(dataAttr)
|
344
|
+
else if (attrName === "style" && dataAttr != null && type.call(dataAttr) === OBJECT) {
|
330
345
|
for (var rule in dataAttr) {
|
331
346
|
if (cachedAttr == null || cachedAttr[rule] !== dataAttr[rule]) node.style[rule] = dataAttr[rule]
|
332
347
|
}
|
@@ -343,9 +358,9 @@ var m = (function app(window, undefined) {
|
|
343
358
|
//handle cases that are properties (but ignore cases where we should use setAttribute instead)
|
344
359
|
//- list and form are typically used as strings, but are DOM element references in js
|
345
360
|
//- when using CSS selectors (e.g. `m("[style='']")`), style is used as a string, but it's an object in js
|
346
|
-
else if (attrName in node && !(attrName
|
361
|
+
else if (attrName in node && !(attrName === "list" || attrName === "style" || attrName === "form" || attrName === "type")) {
|
347
362
|
//#348 don't set the value if not needed otherwise cursor placement breaks in Chrome
|
348
|
-
if (node[attrName]
|
363
|
+
if (tag !== "input" || node[attrName] !== dataAttr) node[attrName] = dataAttr
|
349
364
|
}
|
350
365
|
else node.setAttribute(attrName, dataAttr)
|
351
366
|
}
|
@@ -373,10 +388,10 @@ var m = (function app(window, undefined) {
|
|
373
388
|
if (nodes.length != 0) nodes.length = 0
|
374
389
|
}
|
375
390
|
function unload(cached) {
|
376
|
-
if (cached.configContext && typeof cached.configContext.onunload
|
391
|
+
if (cached.configContext && typeof cached.configContext.onunload === FUNCTION) cached.configContext.onunload();
|
377
392
|
if (cached.children) {
|
378
|
-
if (type.call(cached.children)
|
379
|
-
for (var i = 0;
|
393
|
+
if (type.call(cached.children) === ARRAY) {
|
394
|
+
for (var i = 0, child; child = cached.children[i]; i++) unload(child)
|
380
395
|
}
|
381
396
|
else if (cached.children.tag) unload(cached.children)
|
382
397
|
}
|
@@ -408,7 +423,7 @@ var m = (function app(window, undefined) {
|
|
408
423
|
m.startComputation();
|
409
424
|
try {return callback.call(object, e)}
|
410
425
|
finally {
|
411
|
-
|
426
|
+
endFirstComputation()
|
412
427
|
}
|
413
428
|
}
|
414
429
|
}
|
@@ -433,13 +448,13 @@ var m = (function app(window, undefined) {
|
|
433
448
|
var configs = [];
|
434
449
|
if (!root) throw new Error("Please ensure the DOM element exists before rendering a template into it.");
|
435
450
|
var id = getCellCacheKey(root);
|
436
|
-
var isDocumentRoot = root
|
437
|
-
var node = isDocumentRoot || root
|
451
|
+
var isDocumentRoot = root === $document;
|
452
|
+
var node = isDocumentRoot || root === $document.documentElement ? documentNode : root;
|
438
453
|
if (isDocumentRoot && cell.tag != "html") cell = {tag: "html", attrs: {}, children: cell};
|
439
454
|
if (cellCache[id] === undefined) clear(node.childNodes);
|
440
455
|
if (forceRecreation === true) reset(root);
|
441
456
|
cellCache[id] = build(node, null, undefined, undefined, cell, cellCache[id], false, 0, null, undefined, configs);
|
442
|
-
for (var i = 0
|
457
|
+
for (var i = 0, len = configs.length; i < len; i++) configs[i]()
|
443
458
|
};
|
444
459
|
function getCellCacheKey(element) {
|
445
460
|
var index = nodeCache.indexOf(element);
|
@@ -467,7 +482,7 @@ var m = (function app(window, undefined) {
|
|
467
482
|
|
468
483
|
m.prop = function (store) {
|
469
484
|
//note: using non-strict equality check here because we're checking if store is null OR undefined
|
470
|
-
if (((store != null && type.call(store)
|
485
|
+
if (((store != null && type.call(store) === OBJECT) || typeof store === FUNCTION) && typeof store.then === FUNCTION) {
|
471
486
|
return propify(store)
|
472
487
|
}
|
473
488
|
|
@@ -477,10 +492,11 @@ var m = (function app(window, undefined) {
|
|
477
492
|
var roots = [], modules = [], controllers = [], lastRedrawId = null, lastRedrawCallTime = 0, computePostRedrawHook = null, prevented = false, topModule;
|
478
493
|
var FRAME_BUDGET = 16; //60 frames per second = 1 call per 16 ms
|
479
494
|
m.module = function(root, module) {
|
495
|
+
if (!root) throw new Error("Please ensure the DOM element exists before rendering a template into it.");
|
480
496
|
var index = roots.indexOf(root);
|
481
497
|
if (index < 0) index = roots.length;
|
482
498
|
var isPrevented = false;
|
483
|
-
if (controllers[index] && typeof controllers[index].onunload
|
499
|
+
if (controllers[index] && typeof controllers[index].onunload === FUNCTION) {
|
484
500
|
var event = {
|
485
501
|
preventDefault: function() {isPrevented = true}
|
486
502
|
};
|
@@ -494,11 +510,11 @@ var m = (function app(window, undefined) {
|
|
494
510
|
var controller = new module.controller;
|
495
511
|
//controllers may call m.module recursively (via m.route redirects, for example)
|
496
512
|
//this conditional ensures only the last recursive m.module call is applied
|
497
|
-
if (currentModule
|
513
|
+
if (currentModule === topModule) {
|
498
514
|
controllers[index] = controller;
|
499
515
|
modules[index] = module
|
500
516
|
}
|
501
|
-
|
517
|
+
endFirstComputation();
|
502
518
|
return controllers[index]
|
503
519
|
}
|
504
520
|
};
|
@@ -508,7 +524,7 @@ var m = (function app(window, undefined) {
|
|
508
524
|
if (lastRedrawId && force !== true) {
|
509
525
|
//when setTimeout: only reschedule redraw if time between now and previous redraw is bigger than a frame, otherwise keep currently scheduled timeout
|
510
526
|
//when rAF: always reschedule redraw
|
511
|
-
if (new Date - lastRedrawCallTime > FRAME_BUDGET || $requestAnimationFrame
|
527
|
+
if (new Date - lastRedrawCallTime > FRAME_BUDGET || $requestAnimationFrame === window.requestAnimationFrame) {
|
512
528
|
if (lastRedrawId > 0) $cancelAnimationFrame(lastRedrawId);
|
513
529
|
lastRedrawId = $requestAnimationFrame(redraw, FRAME_BUDGET)
|
514
530
|
}
|
@@ -520,10 +536,10 @@ var m = (function app(window, undefined) {
|
|
520
536
|
};
|
521
537
|
m.redraw.strategy = m.prop();
|
522
538
|
function redraw() {
|
523
|
-
var
|
524
|
-
for (var i = 0;
|
525
|
-
if (controllers[i]
|
526
|
-
m.render(
|
539
|
+
var forceRedraw = m.redraw.strategy() === "all";
|
540
|
+
for (var i = 0, root; root = roots[i]; i++) {
|
541
|
+
if (controllers[i]) {
|
542
|
+
m.render(root, modules[i].view(controllers[i]), forceRedraw)
|
527
543
|
}
|
528
544
|
}
|
529
545
|
//after rendering within a routed context, we need to scroll back to the top, and fetch the document title for history.pushState
|
@@ -540,8 +556,15 @@ var m = (function app(window, undefined) {
|
|
540
556
|
m.startComputation = function() {pendingRequests++};
|
541
557
|
m.endComputation = function() {
|
542
558
|
pendingRequests = Math.max(pendingRequests - 1, 0);
|
543
|
-
if (pendingRequests
|
559
|
+
if (pendingRequests === 0) m.redraw()
|
544
560
|
};
|
561
|
+
var endFirstComputation = function() {
|
562
|
+
if (m.redraw.strategy() == "none") {
|
563
|
+
pendingRequests--
|
564
|
+
m.redraw.strategy("diff")
|
565
|
+
}
|
566
|
+
else m.endComputation();
|
567
|
+
}
|
545
568
|
|
546
569
|
m.withAttr = function(prop, withAttrCallback) {
|
547
570
|
return function(e) {
|
@@ -558,7 +581,7 @@ var m = (function app(window, undefined) {
|
|
558
581
|
//m.route()
|
559
582
|
if (arguments.length === 0) return currentRoute;
|
560
583
|
//m.route(el, defaultRoute, routes)
|
561
|
-
else if (arguments.length === 3 && type.call(arguments[1])
|
584
|
+
else if (arguments.length === 3 && type.call(arguments[1]) === STRING) {
|
562
585
|
var root = arguments[0], defaultRoute = arguments[1], router = arguments[2];
|
563
586
|
redirect = function(source) {
|
564
587
|
var path = currentRoute = normalizeRoute(source);
|
@@ -566,7 +589,7 @@ var m = (function app(window, undefined) {
|
|
566
589
|
m.route(defaultRoute, true)
|
567
590
|
}
|
568
591
|
};
|
569
|
-
var listener = m.route.mode
|
592
|
+
var listener = m.route.mode === "hash" ? "onhashchange" : "onpopstate";
|
570
593
|
window[listener] = function() {
|
571
594
|
if (currentRoute != normalizeRoute($location[m.route.mode])) {
|
572
595
|
redirect($location[m.route.mode])
|
@@ -585,7 +608,7 @@ var m = (function app(window, undefined) {
|
|
585
608
|
element.addEventListener("click", routeUnobtrusive)
|
586
609
|
}
|
587
610
|
//m.route(route, params)
|
588
|
-
else if (type.call(arguments[0])
|
611
|
+
else if (type.call(arguments[0]) === STRING) {
|
589
612
|
currentRoute = arguments[0];
|
590
613
|
var args = arguments[1] || {}
|
591
614
|
var queryIndex = currentRoute.indexOf("?")
|
@@ -595,7 +618,7 @@ var m = (function app(window, undefined) {
|
|
595
618
|
var currentPath = queryIndex > -1 ? currentRoute.slice(0, queryIndex) : currentRoute
|
596
619
|
if (querystring) currentRoute = currentPath + (currentPath.indexOf("?") === -1 ? "?" : "&") + querystring;
|
597
620
|
|
598
|
-
var shouldReplaceHistoryEntry = (arguments.length
|
621
|
+
var shouldReplaceHistoryEntry = (arguments.length === 3 ? arguments[2] : arguments[1]) === true;
|
599
622
|
|
600
623
|
if (window.history.pushState) {
|
601
624
|
computePostRedrawHook = function() {
|
@@ -623,7 +646,7 @@ var m = (function app(window, undefined) {
|
|
623
646
|
}
|
624
647
|
|
625
648
|
for (var route in router) {
|
626
|
-
if (route
|
649
|
+
if (route === path) {
|
627
650
|
m.module(root, router[route]);
|
628
651
|
return true
|
629
652
|
}
|
@@ -634,7 +657,7 @@ var m = (function app(window, undefined) {
|
|
634
657
|
path.replace(matcher, function() {
|
635
658
|
var keys = route.match(/:[^\/]+/g) || [];
|
636
659
|
var values = [].slice.call(arguments, 1, -2);
|
637
|
-
for (var i = 0
|
660
|
+
for (var i = 0, len = keys.length; i < len; i++) routeParams[keys[i].replace(/:|\./g, "")] = decodeURIComponent(values[i])
|
638
661
|
m.module(root, router[route])
|
639
662
|
});
|
640
663
|
return true
|
@@ -643,11 +666,11 @@ var m = (function app(window, undefined) {
|
|
643
666
|
}
|
644
667
|
function routeUnobtrusive(e) {
|
645
668
|
e = e || event;
|
646
|
-
if (e.ctrlKey || e.metaKey || e.which
|
669
|
+
if (e.ctrlKey || e.metaKey || e.which === 2) return;
|
647
670
|
if (e.preventDefault) e.preventDefault();
|
648
671
|
else e.returnValue = false;
|
649
672
|
var currentTarget = e.currentTarget || this;
|
650
|
-
var args = m.route.mode
|
673
|
+
var args = m.route.mode === "pathname" && currentTarget.search ? parseQueryString(currentTarget.search.slice(1)) : {};
|
651
674
|
m.route(currentTarget[m.route.mode].slice(modes[m.route.mode].length), args)
|
652
675
|
}
|
653
676
|
function setScroll() {
|
@@ -658,13 +681,13 @@ var m = (function app(window, undefined) {
|
|
658
681
|
var str = [];
|
659
682
|
for(var prop in object) {
|
660
683
|
var key = prefix ? prefix + "[" + prop + "]" : prop, value = object[prop];
|
661
|
-
str.push(value != null && type.call(value)
|
684
|
+
str.push(value != null && type.call(value) === OBJECT ? buildQueryString(value, key) : encodeURIComponent(key) + "=" + encodeURIComponent(value))
|
662
685
|
}
|
663
686
|
return str.join("&")
|
664
687
|
}
|
665
688
|
function parseQueryString(str) {
|
666
689
|
var pairs = str.split("&"), params = {};
|
667
|
-
for (var i = 0
|
690
|
+
for (var i = 0, len = pairs.length; i < len; i++) {
|
668
691
|
var pair = pairs[i].split("=");
|
669
692
|
params[decodeSpace(pair[0])] = pair[1] ? decodeSpace(pair[1]) : ""
|
670
693
|
}
|
@@ -724,10 +747,10 @@ var m = (function app(window, undefined) {
|
|
724
747
|
|
725
748
|
self.promise["then"] = function(successCallback, failureCallback) {
|
726
749
|
var deferred = new Deferred(successCallback, failureCallback);
|
727
|
-
if (state
|
750
|
+
if (state === RESOLVED) {
|
728
751
|
deferred.resolve(promiseValue)
|
729
752
|
}
|
730
|
-
else if (state
|
753
|
+
else if (state === REJECTED) {
|
731
754
|
deferred.reject(promiseValue)
|
732
755
|
}
|
733
756
|
else {
|
@@ -739,12 +762,12 @@ var m = (function app(window, undefined) {
|
|
739
762
|
function finish(type) {
|
740
763
|
state = type || REJECTED;
|
741
764
|
next.map(function(deferred) {
|
742
|
-
state
|
765
|
+
state === RESOLVED && deferred.resolve(promiseValue) || deferred.reject(promiseValue)
|
743
766
|
})
|
744
767
|
}
|
745
768
|
|
746
769
|
function thennable(then, successCallback, failureCallback, notThennableCallback) {
|
747
|
-
if (((promiseValue != null && type.call(promiseValue)
|
770
|
+
if (((promiseValue != null && type.call(promiseValue) === OBJECT) || typeof promiseValue === FUNCTION) && typeof then === FUNCTION) {
|
748
771
|
try {
|
749
772
|
// count protects against abuse calls from spec checker
|
750
773
|
var count = 0;
|
@@ -788,10 +811,10 @@ var m = (function app(window, undefined) {
|
|
788
811
|
fire()
|
789
812
|
}, function() {
|
790
813
|
try {
|
791
|
-
if (state
|
814
|
+
if (state === RESOLVING && typeof successCallback === FUNCTION) {
|
792
815
|
promiseValue = successCallback(promiseValue)
|
793
816
|
}
|
794
|
-
else if (state
|
817
|
+
else if (state === REJECTING && typeof failureCallback === "function") {
|
795
818
|
promiseValue = failureCallback(promiseValue);
|
796
819
|
state = RESOLVING
|
797
820
|
}
|
@@ -802,7 +825,7 @@ var m = (function app(window, undefined) {
|
|
802
825
|
return finish()
|
803
826
|
}
|
804
827
|
|
805
|
-
if (promiseValue
|
828
|
+
if (promiseValue === self) {
|
806
829
|
promiseValue = TypeError();
|
807
830
|
finish()
|
808
831
|
}
|
@@ -810,14 +833,14 @@ var m = (function app(window, undefined) {
|
|
810
833
|
thennable(then, function () {
|
811
834
|
finish(RESOLVED)
|
812
835
|
}, finish, function () {
|
813
|
-
finish(state
|
836
|
+
finish(state === RESOLVING && RESOLVED)
|
814
837
|
})
|
815
838
|
}
|
816
839
|
})
|
817
840
|
}
|
818
841
|
}
|
819
842
|
m.deferred.onerror = function(e) {
|
820
|
-
if (type.call(e)
|
843
|
+
if (type.call(e) === "[object Error]" && !e.constructor.toString().match(/ Error/)) throw e
|
821
844
|
};
|
822
845
|
|
823
846
|
m.sync = function(args) {
|
@@ -826,7 +849,7 @@ var m = (function app(window, undefined) {
|
|
826
849
|
return function(value) {
|
827
850
|
results[pos] = value;
|
828
851
|
if (!resolved) method = "reject";
|
829
|
-
if (--outstanding
|
852
|
+
if (--outstanding === 0) {
|
830
853
|
deferred.promise(results);
|
831
854
|
deferred[method](results)
|
832
855
|
}
|
@@ -899,18 +922,18 @@ var m = (function app(window, undefined) {
|
|
899
922
|
else options.onerror({type: "error", target: xhr})
|
900
923
|
}
|
901
924
|
};
|
902
|
-
if (options.serialize
|
925
|
+
if (options.serialize === JSON.stringify && options.data && options.method !== "GET") {
|
903
926
|
xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8")
|
904
927
|
}
|
905
|
-
if (options.deserialize
|
928
|
+
if (options.deserialize === JSON.parse) {
|
906
929
|
xhr.setRequestHeader("Accept", "application/json, text/*");
|
907
930
|
}
|
908
|
-
if (typeof options.config
|
931
|
+
if (typeof options.config === FUNCTION) {
|
909
932
|
var maybeXhr = options.config(xhr, options);
|
910
933
|
if (maybeXhr != null) xhr = maybeXhr
|
911
934
|
}
|
912
935
|
|
913
|
-
var data = options.method
|
936
|
+
var data = options.method === "GET" || !options.data ? "" : options.data
|
914
937
|
if (data && (type.call(data) != STRING && data.constructor != window.FormData)) {
|
915
938
|
throw "Request data should be either be a string or FormData. Check the `serialize` option in `m.request`";
|
916
939
|
}
|
@@ -919,7 +942,7 @@ var m = (function app(window, undefined) {
|
|
919
942
|
}
|
920
943
|
}
|
921
944
|
function bindData(xhrOptions, data, serialize) {
|
922
|
-
if (xhrOptions.method
|
945
|
+
if (xhrOptions.method === "GET" && xhrOptions.dataType != "jsonp") {
|
923
946
|
var prefix = xhrOptions.url.indexOf("?") < 0 ? "?" : "&";
|
924
947
|
var querystring = buildQueryString(data);
|
925
948
|
xhrOptions.url = xhrOptions.url + (querystring ? prefix + querystring : "")
|
@@ -953,15 +976,15 @@ var m = (function app(window, undefined) {
|
|
953
976
|
xhrOptions.onload = xhrOptions.onerror = function(e) {
|
954
977
|
try {
|
955
978
|
e = e || event;
|
956
|
-
var unwrap = (e.type
|
979
|
+
var unwrap = (e.type === "load" ? xhrOptions.unwrapSuccess : xhrOptions.unwrapError) || identity;
|
957
980
|
var response = unwrap(deserialize(extract(e.target, xhrOptions)));
|
958
|
-
if (e.type
|
959
|
-
if (type.call(response)
|
981
|
+
if (e.type === "load") {
|
982
|
+
if (type.call(response) === ARRAY && xhrOptions.type) {
|
960
983
|
for (var i = 0; i < response.length; i++) response[i] = new xhrOptions.type(response[i])
|
961
984
|
}
|
962
985
|
else if (xhrOptions.type) response = new xhrOptions.type(response)
|
963
986
|
}
|
964
|
-
deferred[e.type
|
987
|
+
deferred[e.type === "load" ? "resolve" : "reject"](response)
|
965
988
|
}
|
966
989
|
catch (e) {
|
967
990
|
m.deferred.onerror(e);
|
@@ -986,4 +1009,4 @@ var m = (function app(window, undefined) {
|
|
986
1009
|
})(typeof window != "undefined" ? window : {});
|
987
1010
|
|
988
1011
|
if (typeof module != "undefined" && module !== null && module.exports) module.exports = m;
|
989
|
-
else if (typeof define
|
1012
|
+
else if (typeof define === "function" && define.amd) define(function() {return m});
|
metadata
CHANGED
@@ -1,43 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mithril_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jordan Humphreys
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: execjs
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 2.2.2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 2.2.2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rails
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 3.2.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 3.2.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: sqlite3
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|