fix opening in new tab for routed links

This commit is contained in:
Leo Horie 2014-05-01 21:31:56 -04:00
parent 91a32af76c
commit 913b8a5579
11 changed files with 90 additions and 56 deletions

View file

@ -68,6 +68,10 @@
<li>Added <code>m.route()</code> overload to allow reading of current route <a href="https://github.com/lhorie/mithril.js/issues/61">#61</a></li>
<li>Added <code>background</code> option to <code>m.request</code> to allow requests that don&#39;t affect rendering <a href="https://github.com/lhorie/mithril.js/issues/62">#62</a></li>
</ul>
<h3 id="bug-fixes-">Bug Fixes:</h3>
<ul>
<li>Links using <code>config: m.route</code> can now be opened in new tab correctly <a href="https://github.com/lhorie/mithril.js/issues/64">#64</a></li>
</ul>
<hr>
<p><a href="/mithril/archive/v0.1.10">v0.1.10</a> - maintenance</p>
<h3 id="news-">News:</h3>

View file

@ -211,7 +211,7 @@ Mithril = m = new function app(window) {
return value
}
var roots = [], modules = [], controllers = [], now = 0, lastRedraw = 0, lastRedrawId = 0
var roots = [], modules = [], controllers = [], now = 0, lastRedraw = 0, lastRedrawId = 0, computePostRedrawHook = null
m.module = function(root, module) {
m.startComputation()
var index = roots.indexOf(root)
@ -235,20 +235,18 @@ Mithril = m = new function app(window) {
for (var i = 0; i < roots.length; i++) {
m.render(roots[i], modules[i].view(controllers[i]))
}
if (computePostRedrawHook) {
computePostRedrawHook()
computePostRedrawHook = null
}
lastRedraw = now
}
var pendingRequests = 0, computePostRedrawHook = null
var pendingRequests = 0
m.startComputation = function() {pendingRequests++}
m.endComputation = function() {
pendingRequests = Math.max(pendingRequests - 1, 0)
if (pendingRequests == 0) {
m.redraw()
if (computePostRedrawHook) {
computePostRedrawHook()
computePostRedrawHook = null
}
}
if (pendingRequests == 0) m.redraw()
}
m.withAttr = function(prop, withAttrCallback) {
@ -279,6 +277,7 @@ Mithril = m = new function app(window) {
else if (arguments[0].addEventListener) {
var element = arguments[0]
var isInitialized = arguments[1]
element.href = modes[m.route.mode] + element.pathname
if (!isInitialized) {
element.removeEventListener("click", routeUnobtrusive)
element.addEventListener("click", routeUnobtrusive)
@ -316,8 +315,9 @@ Mithril = m = new function app(window) {
}
}
function routeUnobtrusive(e) {
if (e.ctrlKey || e.metaKey || e.which == 2) return
e.preventDefault()
m.route(e.currentTarget.getAttribute("href"))
m.route(e.currentTarget[m.route.mode].slice(modes[m.route.mode].length))
}
function scrollToHash() {
if (m.route.mode != "hash" && window.location.hash) window.location.hash = window.location.hash
@ -934,7 +934,7 @@ function testMithril(mock) {
//m.redraw
test(function() {
mock.performance.$elapse(50)
mock.performance.$elapse(50) //setup
var controller
var root = mock.document.createElement("div")
m.module(root, {
@ -946,11 +946,11 @@ function testMithril(mock) {
var lengthBefore = root.childNodes.length
mock.performance.$elapse(50)
m.redraw()
mock.performance.$elapse(50)
mock.performance.$elapse(50) //teardown
return lengthBefore === 0 && root.childNodes[0].nodeValue === "foo"
})
test(function() {
mock.performance.$elapse(50)
mock.performance.$elapse(50) //setup
var count = 0
var root = mock.document.createElement("div")
m.module(root, {
@ -964,13 +964,13 @@ function testMithril(mock) {
m.redraw()
mock.performance.$elapse(50)
m.redraw()
mock.performance.$elapse(50)
mock.performance.$elapse(50) //teardown
return count === 2
})
//m.route
test(function() {
mock.performance.$elapse(50)
mock.performance.$elapse(50) //setup
mock.location.search = "?"
var root = mock.document.createElement("div")
@ -978,10 +978,11 @@ function testMithril(mock) {
m.route(root, "/test1", {
"/test1": {controller: function() {}, view: function() {return "foo"}}
})
mock.performance.$elapse(50) //teardown
return mock.location.search == "?/test1" && root.childNodes[0].nodeValue === "foo"
})
test(function() {
mock.performance.$elapse(50)
mock.performance.$elapse(50) //setup
mock.location.pathname = "/"
var root = mock.document.createElement("div")
@ -989,10 +990,11 @@ function testMithril(mock) {
m.route(root, "/test2", {
"/test2": {controller: function() {}, view: function() {return "foo"}}
})
mock.performance.$elapse(50) //teardown
return mock.location.pathname == "/test2" && root.childNodes[0].nodeValue === "foo"
})
test(function() {
mock.performance.$elapse(50)
mock.performance.$elapse(50) //setup
mock.location.hash = "#"
var root = mock.document.createElement("div")
@ -1000,10 +1002,11 @@ function testMithril(mock) {
m.route(root, "/test3", {
"/test3": {controller: function() {}, view: function() {return "foo"}}
})
mock.performance.$elapse(50) //teardown
return mock.location.hash == "#/test3" && root.childNodes[0].nodeValue === "foo"
})
test(function() {
mock.performance.$elapse(50)
mock.performance.$elapse(50) //setup
mock.location.search = "?"
var root = mock.document.createElement("div")
@ -1011,10 +1014,11 @@ function testMithril(mock) {
m.route(root, "/test4/foo", {
"/test4/:test": {controller: function() {}, view: function() {return m.route.param("test")}}
})
mock.performance.$elapse(50) //teardown
return mock.location.search == "?/test4/foo" && root.childNodes[0].nodeValue === "foo"
})
test(function() {
mock.performance.$elapse(50)
mock.performance.$elapse(50) //setup
mock.location.search = "?"
var module = {controller: function() {}, view: function() {return m.route.param("test")}}
@ -1026,13 +1030,14 @@ function testMithril(mock) {
"/test5/:test": module
})
var paramValueBefore = m.route.param("test")
mock.performance.$elapse(50)
m.route("/")
var paramValueAfter = m.route.param("test")
mock.performance.$elapse(50) //teardown
return mock.location.search == "?/" && paramValueBefore === "foo" && paramValueAfter === undefined
})
test(function() {
mock.performance.$elapse(50)
mock.performance.$elapse(50) //setup
mock.location.search = "?"
var module = {controller: function() {}, view: function() {return m.route.param("a1")}}
@ -1044,13 +1049,15 @@ function testMithril(mock) {
"/test6/:a1": module
})
var paramValueBefore = m.route.param("a1")
mock.performance.$elapse(50)
m.route("/")
var paramValueAfter = m.route.param("a1")
mock.performance.$elapse(50) //teardown
return mock.location.search == "?/" && paramValueBefore === "foo" && paramValueAfter === undefined
})
test(function() {
//https://github.com/lhorie/mithril.js/issues/61
mock.performance.$elapse(50)
mock.performance.$elapse(50) //setup
mock.location.search = "?"
var module = {controller: function() {}, view: function() {return m.route.param("a1")}}
@ -1062,8 +1069,10 @@ function testMithril(mock) {
"/test7/:a1": module
})
var routeValueBefore = m.route()
mock.performance.$elapse(50)
m.route("/")
var routeValueAfter = m.route()
mock.performance.$elapse(50) //teardown
return routeValueBefore === "/test7/foo" && routeValueAfter === "/"
})

View file

@ -147,6 +147,8 @@ m(&quot;button&quot;, {onclick: alert}); //yields &lt;button&gt;&lt;/button&gt;,
<p>You can set inline styles like this:</p>
<pre><code class="lang-javascript">m(&quot;div&quot;, {style: {border: &quot;1px solid red&quot;}}); //yields &lt;div style=&quot;border:1px solid red;&quot;&gt;&lt;/div&gt;</code></pre>
<p>Note that in order to keep the framework lean, Mithril does not auto-append units like <code>px</code> or <code>%</code> to any values. Typically, you should not even be using inline styles to begin with (unless you are dynamically changing them).</p>
<p>Mithril also does not auto-camel-case CSS properties on inline style attributes, so you should use the Javascript syntax when setting them:</p>
<pre><code class="lang-javascript">m(&quot;div&quot;, {style: {textAlign: &quot;center&quot;}}); //yields &lt;div style=&quot;text-align:1px solid red;&quot;&gt;&lt;/div&gt;</code></pre>
<hr>
<p>You can define a non-HTML-standard attribute called <code>config</code>. This special parameter allows you to call methods on the DOM element after it gets created.</p>
<p>This is useful, for example, if you declare a <code>canvas</code> element and want to use the Javascript API to draw:</p>

View file

@ -211,7 +211,7 @@ Mithril = m = new function app(window) {
return value
}
var roots = [], modules = [], controllers = [], now = 0, lastRedraw = 0, lastRedrawId = 0
var roots = [], modules = [], controllers = [], now = 0, lastRedraw = 0, lastRedrawId = 0, computePostRedrawHook = null
m.module = function(root, module) {
m.startComputation()
var index = roots.indexOf(root)
@ -235,20 +235,18 @@ Mithril = m = new function app(window) {
for (var i = 0; i < roots.length; i++) {
m.render(roots[i], modules[i].view(controllers[i]))
}
if (computePostRedrawHook) {
computePostRedrawHook()
computePostRedrawHook = null
}
lastRedraw = now
}
var pendingRequests = 0, computePostRedrawHook = null
var pendingRequests = 0
m.startComputation = function() {pendingRequests++}
m.endComputation = function() {
pendingRequests = Math.max(pendingRequests - 1, 0)
if (pendingRequests == 0) {
m.redraw()
if (computePostRedrawHook) {
computePostRedrawHook()
computePostRedrawHook = null
}
}
if (pendingRequests == 0) m.redraw()
}
m.withAttr = function(prop, withAttrCallback) {
@ -279,6 +277,7 @@ Mithril = m = new function app(window) {
else if (arguments[0].addEventListener) {
var element = arguments[0]
var isInitialized = arguments[1]
element.href = modes[m.route.mode] + element.pathname
if (!isInitialized) {
element.removeEventListener("click", routeUnobtrusive)
element.addEventListener("click", routeUnobtrusive)
@ -316,8 +315,9 @@ Mithril = m = new function app(window) {
}
}
function routeUnobtrusive(e) {
if (e.ctrlKey || e.metaKey || e.which == 2) return
e.preventDefault()
m.route(e.currentTarget.getAttribute("href"))
m.route(e.currentTarget[m.route.mode].slice(modes[m.route.mode].length))
}
function scrollToHash() {
if (m.route.mode != "hash" && window.location.hash) window.location.hash = window.location.hash

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

View file

@ -7,6 +7,10 @@
- Added `m.route()` overload to allow reading of current route [#61](https://github.com/lhorie/mithril.js/issues/61)
- Added `background` option to `m.request` to allow requests that don't affect rendering [#62](https://github.com/lhorie/mithril.js/issues/62)
### Bug Fixes:
- Links using `config: m.route` can now be opened in new tab correctly [#64](https://github.com/lhorie/mithril.js/issues/64)
---
[v0.1.10](/mithril/archive/v0.1.10) - maintenance

View file

@ -138,6 +138,12 @@ m("div", {style: {border: "1px solid red"}}); //yields <div style="border:1px so
Note that in order to keep the framework lean, Mithril does not auto-append units like `px` or `%` to any values. Typically, you should not even be using inline styles to begin with (unless you are dynamically changing them).
Mithril also does not auto-camel-case CSS properties on inline style attributes, so you should use the Javascript syntax when setting them:
```javascript
m("div", {style: {textAlign: "center"}}); //yields <div style="text-align:1px solid red;"></div>
```
---
You can define a non-HTML-standard attribute called `config`. This special parameter allows you to call methods on the DOM element after it gets created.

View file

@ -211,7 +211,7 @@ Mithril = m = new function app(window) {
return value
}
var roots = [], modules = [], controllers = [], now = 0, lastRedraw = 0, lastRedrawId = 0
var roots = [], modules = [], controllers = [], now = 0, lastRedraw = 0, lastRedrawId = 0, computePostRedrawHook = null
m.module = function(root, module) {
m.startComputation()
var index = roots.indexOf(root)
@ -235,20 +235,18 @@ Mithril = m = new function app(window) {
for (var i = 0; i < roots.length; i++) {
m.render(roots[i], modules[i].view(controllers[i]))
}
if (computePostRedrawHook) {
computePostRedrawHook()
computePostRedrawHook = null
}
lastRedraw = now
}
var pendingRequests = 0, computePostRedrawHook = null
var pendingRequests = 0
m.startComputation = function() {pendingRequests++}
m.endComputation = function() {
pendingRequests = Math.max(pendingRequests - 1, 0)
if (pendingRequests == 0) {
m.redraw()
if (computePostRedrawHook) {
computePostRedrawHook()
computePostRedrawHook = null
}
}
if (pendingRequests == 0) m.redraw()
}
m.withAttr = function(prop, withAttrCallback) {
@ -279,6 +277,7 @@ Mithril = m = new function app(window) {
else if (arguments[0].addEventListener) {
var element = arguments[0]
var isInitialized = arguments[1]
element.href = modes[m.route.mode] + element.pathname
if (!isInitialized) {
element.removeEventListener("click", routeUnobtrusive)
element.addEventListener("click", routeUnobtrusive)
@ -316,8 +315,9 @@ Mithril = m = new function app(window) {
}
}
function routeUnobtrusive(e) {
if (e.ctrlKey || e.metaKey || e.which == 2) return
e.preventDefault()
m.route(e.currentTarget.getAttribute("href"))
m.route(e.currentTarget[m.route.mode].slice(modes[m.route.mode].length))
}
function scrollToHash() {
if (m.route.mode != "hash" && window.location.hash) window.location.hash = window.location.hash

View file

@ -330,7 +330,7 @@ function testMithril(mock) {
//m.redraw
test(function() {
mock.performance.$elapse(50)
mock.performance.$elapse(50) //setup
var controller
var root = mock.document.createElement("div")
m.module(root, {
@ -342,11 +342,11 @@ function testMithril(mock) {
var lengthBefore = root.childNodes.length
mock.performance.$elapse(50)
m.redraw()
mock.performance.$elapse(50)
mock.performance.$elapse(50) //teardown
return lengthBefore === 0 && root.childNodes[0].nodeValue === "foo"
})
test(function() {
mock.performance.$elapse(50)
mock.performance.$elapse(50) //setup
var count = 0
var root = mock.document.createElement("div")
m.module(root, {
@ -360,13 +360,13 @@ function testMithril(mock) {
m.redraw()
mock.performance.$elapse(50)
m.redraw()
mock.performance.$elapse(50)
mock.performance.$elapse(50) //teardown
return count === 2
})
//m.route
test(function() {
mock.performance.$elapse(50)
mock.performance.$elapse(50) //setup
mock.location.search = "?"
var root = mock.document.createElement("div")
@ -374,10 +374,11 @@ function testMithril(mock) {
m.route(root, "/test1", {
"/test1": {controller: function() {}, view: function() {return "foo"}}
})
mock.performance.$elapse(50) //teardown
return mock.location.search == "?/test1" && root.childNodes[0].nodeValue === "foo"
})
test(function() {
mock.performance.$elapse(50)
mock.performance.$elapse(50) //setup
mock.location.pathname = "/"
var root = mock.document.createElement("div")
@ -385,10 +386,11 @@ function testMithril(mock) {
m.route(root, "/test2", {
"/test2": {controller: function() {}, view: function() {return "foo"}}
})
mock.performance.$elapse(50) //teardown
return mock.location.pathname == "/test2" && root.childNodes[0].nodeValue === "foo"
})
test(function() {
mock.performance.$elapse(50)
mock.performance.$elapse(50) //setup
mock.location.hash = "#"
var root = mock.document.createElement("div")
@ -396,10 +398,11 @@ function testMithril(mock) {
m.route(root, "/test3", {
"/test3": {controller: function() {}, view: function() {return "foo"}}
})
mock.performance.$elapse(50) //teardown
return mock.location.hash == "#/test3" && root.childNodes[0].nodeValue === "foo"
})
test(function() {
mock.performance.$elapse(50)
mock.performance.$elapse(50) //setup
mock.location.search = "?"
var root = mock.document.createElement("div")
@ -407,10 +410,11 @@ function testMithril(mock) {
m.route(root, "/test4/foo", {
"/test4/:test": {controller: function() {}, view: function() {return m.route.param("test")}}
})
mock.performance.$elapse(50) //teardown
return mock.location.search == "?/test4/foo" && root.childNodes[0].nodeValue === "foo"
})
test(function() {
mock.performance.$elapse(50)
mock.performance.$elapse(50) //setup
mock.location.search = "?"
var module = {controller: function() {}, view: function() {return m.route.param("test")}}
@ -422,13 +426,14 @@ function testMithril(mock) {
"/test5/:test": module
})
var paramValueBefore = m.route.param("test")
mock.performance.$elapse(50)
m.route("/")
var paramValueAfter = m.route.param("test")
mock.performance.$elapse(50) //teardown
return mock.location.search == "?/" && paramValueBefore === "foo" && paramValueAfter === undefined
})
test(function() {
mock.performance.$elapse(50)
mock.performance.$elapse(50) //setup
mock.location.search = "?"
var module = {controller: function() {}, view: function() {return m.route.param("a1")}}
@ -440,13 +445,15 @@ function testMithril(mock) {
"/test6/:a1": module
})
var paramValueBefore = m.route.param("a1")
mock.performance.$elapse(50)
m.route("/")
var paramValueAfter = m.route.param("a1")
mock.performance.$elapse(50) //teardown
return mock.location.search == "?/" && paramValueBefore === "foo" && paramValueAfter === undefined
})
test(function() {
//https://github.com/lhorie/mithril.js/issues/61
mock.performance.$elapse(50)
mock.performance.$elapse(50) //setup
mock.location.search = "?"
var module = {controller: function() {}, view: function() {return m.route.param("a1")}}
@ -458,8 +465,10 @@ function testMithril(mock) {
"/test7/:a1": module
})
var routeValueBefore = m.route()
mock.performance.$elapse(50)
m.route("/")
var routeValueAfter = m.route()
mock.performance.$elapse(50) //teardown
return routeValueBefore === "/test7/foo" && routeValueAfter === "/"
})