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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cae7853c501aeb7070d48dc192630be72b063cf9
4
- data.tar.gz: ca7ee6eb9b78c601c45775f5d7c17fdb267f9a62
3
+ metadata.gz: 7b6a280ee516de13bb19b02a57d8e81a379ff692
4
+ data.tar.gz: 3d3b67557ab7f491d273404f749b4429fe61d77c
5
5
  SHA512:
6
- metadata.gz: 94e3c47c7b7355c4a793c29aa8cc5c873765f0eb461eeb146142079b72dca67682ab1a17866c8a0a1a5c8999e7fd70693a856e3f0e6d37e4ac1c6e0e27184f82
7
- data.tar.gz: 9dd014f34fb3627e69bef90a3d5cccb3a742da8ba02ec5694402fadcab50015ffa2034fe1e208c6252e761b232809485493188ffc91401ff5083b3d905a8da2c
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]) == OBJECT && !("tag" in args[1]) && !("subtree" in 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] == "" && 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] == "[") {
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) == ARRAY) {
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 == classAttrName) cell.attrs[attrName] = (cell.attrs[attrName] || "") + " " + attrs[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
- if (data == null) data = "";
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 != dataType) {
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 == ARRAY ? data : cached.nodes).length;
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 == ARRAY) {
112
+ if (dataType === ARRAY) {
112
113
  //recursively flatten array
113
- for (var i = 0; i < data.length; i++) {
114
- if (type.call(data[i]) == ARRAY) {
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
- for (var i = 0; i < data.length; i++) {
138
- if (data[i] && data[i].attrs) {
139
- if (data[i].attrs.key != null) {
140
- var key = data[i].attrs.key;
141
- if (!existing[key]) existing[key] = {action: INSERTION, index: i};
142
- else existing[key] = {
143
- action: MOVE,
144
- index: i,
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
- var actions = Object.keys(existing).map(function(key) {return existing[key]});
153
- var changes = actions.sort(function(a, b) {return a.action - b.action || a.index - b.index});
154
- var newCached = cached.slice();
155
-
156
- for (var i = 0, change; change = changes[i]; i++) {
157
- if (change.action == DELETION) {
158
- clear(cached[change.index].nodes, cached[change.index]);
159
- newCached.splice(change.index, 1)
160
- }
161
- if (change.action == INSERTION) {
162
- var dummy = $document.createElement("div");
163
- dummy.key = data[change.index].attrs.key;
164
- parentElement.insertBefore(dummy, parentElement.childNodes[change.index] || null);
165
- newCached.splice(change.index, 0, {attrs: {key: data[change.index].attrs.key}, nodes: [dummy]})
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
- if (change.action == MOVE) {
169
- if (parentElement.childNodes[change.index] !== change.element && change.element !== null) {
170
- parentElement.insertBefore(change.element, parentElement.childNodes[change.index] || null)
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; i < data.length; i++) {
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) == ARRAY ? item.length : 1;
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; i < data.length; i++) {
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 == OBJECT) {
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 == FUNCTION) 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: dataAttrKeys.length ? setAttributes(node, data.tag, data.attrs, {}, namespace) : {},
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 == "select" && data.attrs.value) setAttributes(node, data.tag, {value: data.attrs.value}, {}, namespace);
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 (dataAttrKeys.length) setAttributes(node, data.tag, data.attrs, cached.attrs, namespace);
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"] == FUNCTION) {
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 == 1 || nodes.length > 1) { //was a trusted string
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
- //we don't ignore `key` because it must be unique and having it on the DOM helps debugging
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 == FUNCTION && attrName.indexOf("on") == 0) {
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) == OBJECT) {
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 == "list" || attrName == "style" || attrName == "form" || attrName == "type")) {
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] != dataAttr) node[attrName] = dataAttr
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 == FUNCTION) 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) == ARRAY) {
379
- for (var i = 0; i < cached.children.length; i++) unload(cached.children[i])
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
- m.endComputation()
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 == $document;
437
- var node = isDocumentRoot || root == $document.documentElement ? documentNode : 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; i < configs.length; i++) configs[i]()
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) == OBJECT) || typeof store == FUNCTION) && typeof store.then == FUNCTION) {
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 == FUNCTION) {
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 == topModule) {
513
+ if (currentModule === topModule) {
498
514
  controllers[index] = controller;
499
515
  modules[index] = module
500
516
  }
501
- m.endComputation();
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 == window.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 mode = m.redraw.strategy();
524
- for (var i = 0; i < roots.length; i++) {
525
- if (controllers[i] && mode != "none") {
526
- m.render(roots[i], modules[i].view(controllers[i]), mode == "all")
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 == 0) m.redraw()
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]) == STRING) {
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 == "hash" ? "onhashchange" : "onpopstate";
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]) == STRING) {
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 == 3 ? arguments[2] : arguments[1]) === true;
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 == path) {
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; i < keys.length; i++) routeParams[keys[i].replace(/:|\./g, "")] = decodeURIComponent(values[i])
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 == 2) return;
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 == "pathname" && currentTarget.search ? parseQueryString(currentTarget.search.slice(1)) : {};
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) == OBJECT ? buildQueryString(value, key) : encodeURIComponent(key) + "=" + encodeURIComponent(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; i < pairs.length; i++) {
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 == RESOLVED) {
750
+ if (state === RESOLVED) {
728
751
  deferred.resolve(promiseValue)
729
752
  }
730
- else if (state == REJECTED) {
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 == RESOLVED && deferred.resolve(promiseValue) || deferred.reject(promiseValue)
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) == OBJECT) || typeof promiseValue == FUNCTION) && typeof then == FUNCTION) {
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 == RESOLVING && typeof successCallback == FUNCTION) {
814
+ if (state === RESOLVING && typeof successCallback === FUNCTION) {
792
815
  promiseValue = successCallback(promiseValue)
793
816
  }
794
- else if (state == REJECTING && typeof failureCallback == "function") {
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 == self) {
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 == RESOLVING && RESOLVED)
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) == "[object Error]" && !e.constructor.toString().match(/ Error/)) throw 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 == 0) {
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 == JSON.stringify && options.data && options.method != "GET") {
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 == JSON.parse) {
928
+ if (options.deserialize === JSON.parse) {
906
929
  xhr.setRequestHeader("Accept", "application/json, text/*");
907
930
  }
908
- if (typeof options.config == FUNCTION) {
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 == "GET" || !options.data ? "" : options.data
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 == "GET" && xhrOptions.dataType != "jsonp") {
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 == "load" ? xhrOptions.unwrapSuccess : xhrOptions.unwrapError) || identity;
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 == "load") {
959
- if (type.call(response) == ARRAY && xhrOptions.type) {
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 == "load" ? "resolve" : "reject"](response)
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 == "function" && define.amd) define(function() {return m});
1012
+ else if (typeof define === "function" && define.amd) define(function() {return m});
@@ -1,3 +1,3 @@
1
1
  module MithrilRails
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
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
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: 2014-12-05 00:00:00.000000000 Z
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: '0'
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: '0'
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: 4.1.0
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: 4.1.0
40
+ version: 3.2.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: sqlite3
43
43
  requirement: !ruby/object:Gem::Requirement