Runtime-deprecate ospec, change change-log to changelog, fix a few assorted bugs (#2578)
This commit is contained in:
parent
1630b06106
commit
9f0dc2ab46
76 changed files with 484 additions and 410 deletions
3
.github/CODE_OF_CONDUCT.md
vendored
3
.github/CODE_OF_CONDUCT.md
vendored
|
|
@ -1,3 +0,0 @@
|
|||
# Code of Conduct
|
||||
|
||||
Please see https://mithril.js.org/code-of-conduct.html.
|
||||
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
|
|
@ -1 +0,0 @@
|
|||
open_collective: mithriljs
|
||||
11
.github/ISSUE_TEMPLATE/feature-or-enhancement.md
vendored
11
.github/ISSUE_TEMPLATE/feature-or-enhancement.md
vendored
|
|
@ -12,17 +12,18 @@ assignees: isiahmeadows
|
|||
Optional: Provide the exact version of Mithril you're experiencing issues with.
|
||||
This could matter, even if it's really old like version 0.1.0. Do note that bugs
|
||||
in older versions are commonly fixed in newer versions and that newer versions
|
||||
do end up with a lot more features than older versions, so it's unlikely we'll
|
||||
are much more actively maintained than older versions, so it's unlikely we'll
|
||||
add new features to older versions like 0.1.x.
|
||||
-->
|
||||
**Mithril version:**
|
||||
|
||||
<!--
|
||||
Optional: Provide the name and version of both the browser and operating system
|
||||
you're running Mithril on. If it's multiple, feel free to list multiple. This
|
||||
could matter, even if it's super ancient like IE 6 on Windows XP.
|
||||
Optional: Provide the name and version of both the platform (Chrome, Node, etc.)
|
||||
and operating system you're running Mithril on. If it's multiple, feel free to
|
||||
list multiple. This could matter, even if it's super ancient like IE 6 on
|
||||
Windows XP.
|
||||
-->
|
||||
**Browser and OS:**
|
||||
**Platform and OS:**
|
||||
|
||||
<!--
|
||||
Optional: Provide a link to your project, if it happens to be open source or if
|
||||
|
|
|
|||
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
|
@ -28,4 +28,4 @@
|
|||
- [ ] I have read the **CONTRIBUTING** document.
|
||||
- [ ] I have added tests to cover my changes.
|
||||
- [ ] All new and existing tests passed.
|
||||
- [ ] I have updated `docs/change-log.md`
|
||||
- [ ] I have updated `docs/changelog.md`
|
||||
|
|
|
|||
250
api/router.js
250
api/router.js
|
|
@ -13,11 +13,133 @@ var censor = require("../util/censor")
|
|||
var sentinel = {}
|
||||
|
||||
module.exports = function($window, mountRedraw) {
|
||||
var fireAsync
|
||||
var callAsync = $window == null
|
||||
// In case Mithril's loaded globally without the DOM, let's not break
|
||||
? null
|
||||
: typeof $window.setImmediate === "function" ? $window.setImmediate : $window.setTimeout
|
||||
var p = Promise.resolve()
|
||||
|
||||
var scheduled = false
|
||||
|
||||
// state === 0: init
|
||||
// state === 1: scheduled
|
||||
// state === 2: done
|
||||
var ready = false
|
||||
var state = 0
|
||||
|
||||
var compiled, fallbackRoute
|
||||
|
||||
var currentResolver = sentinel, component, attrs, currentPath, lastUpdate
|
||||
|
||||
var RouterRoot = {
|
||||
onbeforeupdate: function() {
|
||||
state = state ? 2 : 1
|
||||
return !(!state || sentinel === currentResolver)
|
||||
},
|
||||
onremove: function() {
|
||||
$window.removeEventListener("popstate", fireAsync, false)
|
||||
$window.removeEventListener("hashchange", resolveRoute, false)
|
||||
},
|
||||
view: function() {
|
||||
if (!state || sentinel === currentResolver) return
|
||||
// Wrap in a fragment to preserve existing key semantics
|
||||
var vnode = [Vnode(component, attrs.key, attrs)]
|
||||
if (currentResolver) vnode = currentResolver.render(vnode[0])
|
||||
return vnode
|
||||
},
|
||||
}
|
||||
|
||||
var SKIP = route.SKIP = {}
|
||||
|
||||
function resolveRoute() {
|
||||
scheduled = false
|
||||
// Consider the pathname holistically. The prefix might even be invalid,
|
||||
// but that's not our problem.
|
||||
var prefix = $window.location.hash
|
||||
if (route.prefix[0] !== "#") {
|
||||
prefix = $window.location.search + prefix
|
||||
if (route.prefix[0] !== "?") {
|
||||
prefix = $window.location.pathname + prefix
|
||||
if (prefix[0] !== "/") prefix = "/" + prefix
|
||||
}
|
||||
}
|
||||
// This seemingly useless `.concat()` speeds up the tests quite a bit,
|
||||
// since the representation is consistently a relatively poorly
|
||||
// optimized cons string.
|
||||
var path = prefix.concat()
|
||||
.replace(/(?:%[a-f89][a-f0-9])+/gim, decodeURIComponent)
|
||||
.slice(route.prefix.length)
|
||||
var data = parsePathname(path)
|
||||
|
||||
assign(data.params, $window.history.state)
|
||||
|
||||
function reject(e) {
|
||||
console.error(e)
|
||||
setPath(fallbackRoute, null, {replace: true})
|
||||
}
|
||||
|
||||
loop(0)
|
||||
function loop(i) {
|
||||
// state === 0: init
|
||||
// state === 1: scheduled
|
||||
// state === 2: done
|
||||
for (; i < compiled.length; i++) {
|
||||
if (compiled[i].check(data)) {
|
||||
var payload = compiled[i].component
|
||||
var matchedRoute = compiled[i].route
|
||||
var localComp = payload
|
||||
var update = lastUpdate = function(comp) {
|
||||
if (update !== lastUpdate) return
|
||||
if (comp === SKIP) return loop(i + 1)
|
||||
component = comp != null && (typeof comp.view === "function" || typeof comp === "function")? comp : "div"
|
||||
attrs = data.params, currentPath = path, lastUpdate = null
|
||||
currentResolver = payload.render ? payload : null
|
||||
if (state === 2) mountRedraw.redraw()
|
||||
else {
|
||||
state = 2
|
||||
mountRedraw.redraw.sync()
|
||||
}
|
||||
}
|
||||
// There's no understating how much I *wish* I could
|
||||
// use `async`/`await` here...
|
||||
if (payload.view || typeof payload === "function") {
|
||||
payload = {}
|
||||
update(localComp)
|
||||
}
|
||||
else if (payload.onmatch) {
|
||||
p.then(function () {
|
||||
return payload.onmatch(data.params, path, matchedRoute)
|
||||
}).then(update, path === fallbackRoute ? null : reject)
|
||||
}
|
||||
else update("div")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (path === fallbackRoute) {
|
||||
throw new Error("Could not resolve default route " + fallbackRoute + ".")
|
||||
}
|
||||
setPath(fallbackRoute, null, {replace: true})
|
||||
}
|
||||
}
|
||||
|
||||
// Set it unconditionally so `m.route.set` and `m.route.Link` both work,
|
||||
// even if neither `pushState` nor `hashchange` are supported. It's
|
||||
// cleared if `hashchange` is used, since that makes it automatically
|
||||
// async.
|
||||
function fireAsync() {
|
||||
if (!scheduled) {
|
||||
scheduled = true
|
||||
// TODO: just do `mountRedraw.redraw()` here and elide the timer
|
||||
// dependency. Note that this will muck with tests a *lot*, so it's
|
||||
// not as easy of a change as it sounds.
|
||||
callAsync(resolveRoute)
|
||||
}
|
||||
}
|
||||
|
||||
function setPath(path, data, options) {
|
||||
path = buildPathname(path, data)
|
||||
if (fireAsync != null) {
|
||||
if (ready) {
|
||||
fireAsync()
|
||||
var state = options ? options.state : null
|
||||
var title = options ? options.title : null
|
||||
|
|
@ -29,18 +151,10 @@ module.exports = function($window, mountRedraw) {
|
|||
}
|
||||
}
|
||||
|
||||
var currentResolver = sentinel, component, attrs, currentPath, lastUpdate
|
||||
|
||||
var SKIP = route.SKIP = {}
|
||||
|
||||
function route(root, defaultRoute, routes) {
|
||||
if (!root) throw new TypeError("DOM element being rendered to does not exist.")
|
||||
// 0 = start
|
||||
// 1 = init
|
||||
// 2 = ready
|
||||
var state = 0
|
||||
|
||||
var compiled = Object.keys(routes).map(function(route) {
|
||||
compiled = Object.keys(routes).map(function(route) {
|
||||
if (route[0] !== "/") throw new SyntaxError("Routes must start with a '/'.")
|
||||
if ((/:([^\/\.-]+)(\.{3})?:/).test(route)) {
|
||||
throw new SyntaxError("Route parameter names must be separated with either '/', '.', or '-'.")
|
||||
|
|
@ -51,13 +165,7 @@ module.exports = function($window, mountRedraw) {
|
|||
check: compileTemplate(route),
|
||||
}
|
||||
})
|
||||
var callAsync = typeof setImmediate === "function" ? setImmediate : setTimeout
|
||||
var p = Promise.resolve()
|
||||
var scheduled = false
|
||||
var onremove
|
||||
|
||||
fireAsync = null
|
||||
|
||||
fallbackRoute = defaultRoute
|
||||
if (defaultRoute != null) {
|
||||
var defaultData = parsePathname(defaultRoute)
|
||||
|
||||
|
|
@ -66,116 +174,14 @@ module.exports = function($window, mountRedraw) {
|
|||
}
|
||||
}
|
||||
|
||||
function resolveRoute() {
|
||||
scheduled = false
|
||||
// Consider the pathname holistically. The prefix might even be invalid,
|
||||
// but that's not our problem.
|
||||
var prefix = $window.location.hash
|
||||
if (route.prefix[0] !== "#") {
|
||||
prefix = $window.location.search + prefix
|
||||
if (route.prefix[0] !== "?") {
|
||||
prefix = $window.location.pathname + prefix
|
||||
if (prefix[0] !== "/") prefix = "/" + prefix
|
||||
}
|
||||
}
|
||||
// This seemingly useless `.concat()` speeds up the tests quite a bit,
|
||||
// since the representation is consistently a relatively poorly
|
||||
// optimized cons string.
|
||||
var path = prefix.concat()
|
||||
.replace(/(?:%[a-f89][a-f0-9])+/gim, decodeURIComponent)
|
||||
.slice(route.prefix.length)
|
||||
var data = parsePathname(path)
|
||||
|
||||
assign(data.params, $window.history.state)
|
||||
|
||||
function reject(e) {
|
||||
console.error(e)
|
||||
setPath(defaultRoute, null, {replace: true})
|
||||
}
|
||||
|
||||
loop(0)
|
||||
function loop(i) {
|
||||
// 0 = init
|
||||
// 1 = scheduled
|
||||
// 2 = done
|
||||
for (; i < compiled.length; i++) {
|
||||
if (compiled[i].check(data)) {
|
||||
var payload = compiled[i].component
|
||||
var matchedRoute = compiled[i].route
|
||||
var localComp = payload
|
||||
var update = lastUpdate = function(comp) {
|
||||
if (update !== lastUpdate) return
|
||||
if (comp === SKIP) return loop(i + 1)
|
||||
component = comp != null && (typeof comp.view === "function" || typeof comp === "function")? comp : "div"
|
||||
attrs = data.params, currentPath = path, lastUpdate = null
|
||||
currentResolver = payload.render ? payload : null
|
||||
if (state === 2) mountRedraw.redraw()
|
||||
else {
|
||||
state = 2
|
||||
mountRedraw.redraw.sync()
|
||||
}
|
||||
}
|
||||
// There's no understating how much I *wish* I could
|
||||
// use `async`/`await` here...
|
||||
if (payload.view || typeof payload === "function") {
|
||||
payload = {}
|
||||
update(localComp)
|
||||
}
|
||||
else if (payload.onmatch) {
|
||||
p.then(function () {
|
||||
return payload.onmatch(data.params, path, matchedRoute)
|
||||
}).then(update, path === defaultRoute ? null : reject)
|
||||
}
|
||||
else update("div")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (path === defaultRoute) {
|
||||
throw new Error("Could not resolve default route " + defaultRoute + ".")
|
||||
}
|
||||
setPath(defaultRoute, null, {replace: true})
|
||||
}
|
||||
}
|
||||
|
||||
// Set it unconditionally so `m.route.set` and `m.route.Link` both work,
|
||||
// even if neither `pushState` nor `hashchange` are supported. It's
|
||||
// cleared if `hashchange` is used, since that makes it automatically
|
||||
// async.
|
||||
fireAsync = function() {
|
||||
if (!scheduled) {
|
||||
scheduled = true
|
||||
callAsync(resolveRoute)
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof $window.history.pushState === "function") {
|
||||
onremove = function() {
|
||||
$window.removeEventListener("popstate", fireAsync, false)
|
||||
}
|
||||
$window.addEventListener("popstate", fireAsync, false)
|
||||
} else if (route.prefix[0] === "#") {
|
||||
fireAsync = null
|
||||
onremove = function() {
|
||||
$window.removeEventListener("hashchange", resolveRoute, false)
|
||||
}
|
||||
$window.addEventListener("hashchange", resolveRoute, false)
|
||||
}
|
||||
|
||||
mountRedraw.mount(root, {
|
||||
onbeforeupdate: function() {
|
||||
state = state ? 2 : 1
|
||||
return !(!state || sentinel === currentResolver)
|
||||
},
|
||||
onremove: onremove,
|
||||
view: function() {
|
||||
if (!state || sentinel === currentResolver) return
|
||||
// Wrap in a fragment to preserve existing key semantics
|
||||
var vnode = [Vnode(component, attrs.key, attrs)]
|
||||
if (currentResolver) vnode = currentResolver.render(vnode[0])
|
||||
return vnode
|
||||
},
|
||||
})
|
||||
ready = true
|
||||
mountRedraw.mount(root, RouterRoot)
|
||||
resolveRoute()
|
||||
}
|
||||
route.set = function(path, data, options) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"use strict"
|
||||
|
||||
// Low-priority TODO: remove the dependency on the renderer here.
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var components = require("../../test-utils/components")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var throttleMocker = require("../../test-utils/throttleMock")
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"use strict"
|
||||
|
||||
// Low-priority TODO: remove the dependency on the renderer here.
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var browserMock = require("../../test-utils/browserMock")
|
||||
var throttleMocker = require("../../test-utils/throttleMock")
|
||||
|
||||
|
|
@ -26,14 +26,13 @@ o.spec("route", function() {
|
|||
|
||||
// Use precisely what `m.route` uses, for consistency and to ensure timings
|
||||
// are aligned.
|
||||
var waitFunc = typeof setImmediate === "function" ? setImmediate : setTimeout
|
||||
function waitCycles(n) {
|
||||
n = Math.max(n, 1)
|
||||
return new Promise(function(resolve) {
|
||||
return loop()
|
||||
function loop() {
|
||||
if (n === 0) resolve()
|
||||
else { n--; waitFunc(loop) }
|
||||
else { n--; setTimeout(loop, 4) }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -75,6 +74,8 @@ o.spec("route", function() {
|
|||
o.beforeEach(function() {
|
||||
currentTest = nextID++
|
||||
$window = browserMock(env)
|
||||
$window.setTimeout = setTimeout
|
||||
// $window.setImmediate = setImmediate
|
||||
throttleMock = throttleMocker()
|
||||
|
||||
root = $window.document.body
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
"use strict"
|
||||
|
||||
// Low-priority TODO: remove the dependency on the renderer here.
|
||||
var o = require("../../ospec/ospec")
|
||||
var callAsync = require("../../test-utils/callAsync")
|
||||
var o = require("ospec")
|
||||
var browserMock = require("../../test-utils/browserMock")
|
||||
var throttleMocker = require("../../test-utils/throttleMock")
|
||||
|
||||
var callAsync = require("../../test-utils/callAsync")
|
||||
var apiMountRedraw = require("../../api/mount-redraw")
|
||||
var coreRenderer = require("../../render/render")
|
||||
var apiRouter = require("../../api/router")
|
||||
|
|
@ -20,6 +18,7 @@ o.spec("route.get/route.set", function() {
|
|||
o.beforeEach(function() {
|
||||
$window = browserMock(env)
|
||||
throttleMock = throttleMocker()
|
||||
$window.setTimeout = setTimeout
|
||||
|
||||
root = $window.document.body
|
||||
|
||||
|
|
@ -87,7 +86,7 @@ o.spec("route.get/route.set", function() {
|
|||
route.set("/b")
|
||||
o(spy1.callCount).equals(1)
|
||||
o(spy2.callCount).equals(0)
|
||||
callAsync(function() {
|
||||
setTimeout(function() {
|
||||
throttleMock.fire()
|
||||
|
||||
o(spy1.callCount).equals(1)
|
||||
|
|
@ -111,10 +110,10 @@ o.spec("route.get/route.set", function() {
|
|||
route.set("/c")
|
||||
o(spy1.callCount).equals(0)
|
||||
o(spy2.callCount).equals(1)
|
||||
callAsync(function() {
|
||||
setTimeout(function() {
|
||||
// Yep, before even the throttle mechanism takes hold.
|
||||
o(route.get()).equals("/b")
|
||||
callAsync(function() {
|
||||
setTimeout(function() {
|
||||
// Yep, before even the throttle mechanism takes hold.
|
||||
o(route.get()).equals("/a")
|
||||
throttleMock.fire()
|
||||
|
|
@ -134,7 +133,7 @@ o.spec("route.get/route.set", function() {
|
|||
})
|
||||
|
||||
route.set("/other/x/y/z?c=d#e=f")
|
||||
callAsync(function() {
|
||||
setTimeout(function() {
|
||||
// Yep, before even the throttle mechanism takes hold.
|
||||
o(route.get()).equals("/other/x/y/z?c=d#e=f")
|
||||
throttleMock.fire()
|
||||
|
|
@ -150,7 +149,7 @@ o.spec("route.get/route.set", function() {
|
|||
})
|
||||
|
||||
route.set(encodeURI("/ö?ö=ö#ö=ö"))
|
||||
callAsync(function() {
|
||||
setTimeout(function() {
|
||||
// Yep, before even the throttle mechanism takes hold.
|
||||
o(route.get()).equals("/ö?ö=ö#ö=ö")
|
||||
throttleMock.fire()
|
||||
|
|
@ -166,7 +165,7 @@ o.spec("route.get/route.set", function() {
|
|||
})
|
||||
|
||||
route.set("/ö?ö=ö#ö=ö")
|
||||
callAsync(function() {
|
||||
setTimeout(function() {
|
||||
// Yep, before even the throttle mechanism takes hold.
|
||||
o(route.get()).equals("/ö?ö=ö#ö=ö")
|
||||
throttleMock.fire()
|
||||
|
|
@ -182,7 +181,7 @@ o.spec("route.get/route.set", function() {
|
|||
})
|
||||
|
||||
route.set("/other/x/y/z?c=d#e=f")
|
||||
callAsync(function() {
|
||||
setTimeout(function() {
|
||||
// Yep, before even the throttle mechanism takes hold.
|
||||
o(route.get()).equals("/other/x/y/z?c=d#e=f")
|
||||
throttleMock.fire()
|
||||
|
|
@ -197,11 +196,11 @@ o.spec("route.get/route.set", function() {
|
|||
"/other/:a/:b...": {view: function() {}},
|
||||
})
|
||||
|
||||
callAsync(function() {
|
||||
setTimeout(function() {
|
||||
$window.history.pushState(null, null, prefix + "/other/x/y/z?c=d#e=f")
|
||||
$window.onpopstate()
|
||||
|
||||
callAsync(function() {
|
||||
setTimeout(function() {
|
||||
// Yep, before even the throttle mechanism takes hold.
|
||||
o(route.get()).equals("/other/x/y/z?c=d#e=f")
|
||||
throttleMock.fire()
|
||||
|
|
@ -219,7 +218,7 @@ o.spec("route.get/route.set", function() {
|
|||
})
|
||||
|
||||
route.set("/other/:a/:b", {a: "x", b: "y/z", c: "d", e: "f"})
|
||||
callAsync(function() {
|
||||
setTimeout(function() {
|
||||
// Yep, before even the throttle mechanism takes hold.
|
||||
o(route.get()).equals("/other/x/y%2Fz?c=d&e=f")
|
||||
throttleMock.fire()
|
||||
|
|
@ -236,7 +235,7 @@ o.spec("route.get/route.set", function() {
|
|||
|
||||
route.set("/other", null, {replace: true})
|
||||
|
||||
callAsync(function() {
|
||||
setTimeout(function() {
|
||||
throttleMock.fire()
|
||||
$window.history.back()
|
||||
o($window.location.href).equals(env.protocol + "//" + (env.hostname === "/" ? "" : env.hostname) + "/")
|
||||
|
|
@ -253,7 +252,7 @@ o.spec("route.get/route.set", function() {
|
|||
|
||||
route.set("/other", null, {replace: false})
|
||||
|
||||
callAsync(function() {
|
||||
setTimeout(function() {
|
||||
throttleMock.fire()
|
||||
$window.history.back()
|
||||
var slash = prefix[0] === "/" ? "" : "/"
|
||||
|
|
@ -270,7 +269,7 @@ o.spec("route.get/route.set", function() {
|
|||
})
|
||||
|
||||
route.set("/other", null, {state: {a: 1}})
|
||||
callAsync(function() {
|
||||
setTimeout(function() {
|
||||
throttleMock.fire()
|
||||
o($window.history.state).deepEquals({a: 1})
|
||||
done()
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
- [v1.x changelog](https://mithril.js.org/archive/v1.1.7/change-log.html)
|
||||
- [v1.x docs](https://mithril.js.org/archive/v1.1.7/index.html)
|
||||
- [v0.2 docs](https://mithril.js.org/archive/v0.2.5/index.html)
|
||||
- [`ospec` change log](https://github.com/MithrilJS/mithril.js/blob/master/ospec/change-log.md)
|
||||
- [`mithril/stream` change log](https://github.com/MithrilJS/mithril.js/blob/master/stream/change-log.md)
|
||||
- [`ospec` change log](https://github.com/MithrilJS/ospec/blob/master/changelog.md)
|
||||
- [`mithril-stream` change log](#mithril-stream-change-log)
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
*Note for later: release as semver-minor.*
|
||||
|
||||
PSA: changes to [`mithril/stream`](stream.md) are now specified in this changelog. I've also moved the old stream changelog into this file [here](#mithril-stream-change-log).
|
||||
|
||||
- Reduced package download size substantially by removing the archive of previous releases' documentation. ([#2561](https://github.com/MithrilJS/mithril.js/pull/2561) [@cztomsik](https://github.com/cztomsik))
|
||||
- Improved error messages in multiple places. ([#2536](https://github.com/MithrilJS/mithril.js/pull/2536) [@isiahmeadows](https://github.com/isiahmeadows))
|
||||
- The redraw reentrancy check was moved from `m.mount` to `m.render` and its error message was updated accordingly. ([#2536](https://github.com/MithrilJS/mithril.js/pull/2536) [@isiahmeadows](https://github.com/isiahmeadows))
|
||||
|
|
@ -31,6 +33,9 @@
|
|||
- Re-add stream bundles. ([#2539](https://github.com/MithrilJS/mithril.js/pull/2539) [@isiahmeadows](https://github.com/isiahmeadows))
|
||||
- Remove extra isLifecycleMethod call from removeAttr. ([#2594](https://github.com/MithrilJS/mithril.js/pull/2594) [@ZeikJT](https://github.com/zeikjt))
|
||||
- Fix issue where ending a stream in the middle of a stream callback would result in erroneous parent stream state for the rest of that emit. ([#2603](https://github.com/MithrilJS/mithril.js/pull/2603) [@isiahmeadows](https://github.com/isiahmeadows))
|
||||
- Fix issue where new redraw handlers weren't copied over on update. ([#2578](https://github.com/MithrilJS/mithril.js/pull/2578) [@isiahmeadows](https://github.com/isiahmeadows))
|
||||
- Make changes to file inputs gracefully handled, and don't break if the current value and old value mismatch (and the new value isn't empty), but instead just log an error. ([#2578](https://github.com/MithrilJS/mithril.js/pull/2578) [@isiahmeadows](https://github.com/isiahmeadows))
|
||||
- This mainly exists just to kick the can down the road - this is the only case I'm aware of where the DOM itself would be responsible for throwing an error. A proper fix to the greater issue of error handling is much more complex, and I'd rather not block users any longer over this one specific issue.
|
||||
|
||||
Important note: if you were using any of these undocumented tools, they are no longer available as of this release. This is not considered a breaking change as they were written for internal usage and as of v2 are all 100% unsupported in userland.
|
||||
|
||||
|
|
@ -181,3 +186,22 @@ _2019-07-24_
|
|||
- docs: clarify valid key usage ([#2452](https://github.com/MithrilJS/mithril.js/pull/2452) [@isiahmeadows](https://github.com/isiahmeadows))
|
||||
- route: don't pollute globals ([#2453](https://github.com/MithrilJS/mithril.js/pull/2453) [@isiahmeadows](https://github.com/isiahmeadows))
|
||||
- request: track xhr replacements correctly ([#2455](https://github.com/MithrilJS/mithril.js/pull/2455) [@isiahmeadows](https://github.com/isiahmeadows))
|
||||
|
||||
## `mithril-stream` change log
|
||||
|
||||
Formerly, `mithril/stream` was available standalone as the package `mithril-stream`, but this package has been deprecated and is no longer updated. The changelog for that package prior to being merged back into Mithril proper is below.
|
||||
|
||||
### 2.0.0
|
||||
_2019-02-07_
|
||||
|
||||
- when a stream conditionally returns HALT, dependant stream will also end ([#2200](https://github.com/MithrilJS/mithril.js/pull/2200), [#2369](https://github.com/MithrilJS/mithril.js/pull/2369))
|
||||
- Add `stream.lift` as a user-friendly alternative to `merge -> map` or `combine` ([#1944](https://github.com/MithrilJS/mithril.js/issues/1944))
|
||||
- renamed HALT to SKIP ([#2207](https://github.com/MithrilJS/mithril.js/pull/2207))
|
||||
- rewrote implementation ([#2207](https://github.com/MithrilJS/mithril.js/pull/2207))
|
||||
- Removed `valueOf` & `toString` methods ([#2150](https://github.com/MithrilJS/mithril.js/pull/2150))
|
||||
- fixed `stream.end` propagation ([#2369](https://github.com/MithrilJS/mithril.js/pull/2369))
|
||||
|
||||
### 1.1.0
|
||||
_2017-07-13_
|
||||
|
||||
- Move the "use strict" directive inside the IIFE [#1831](https://github.com/MithrilJS/mithril.js/issues/1831) ([#1893](https://github.com/MithrilJS/mithril.js/pull/1893))
|
||||
|
|
@ -25,6 +25,6 @@
|
|||
- [Code of Conduct](code-of-conduct.md)
|
||||
- Misc
|
||||
- [Framework comparison](framework-comparison.md)
|
||||
- [Change log/Migration](change-log.md)
|
||||
- [Change log/Migration](changelog.md)
|
||||
- [v1 Documentation](https://mithril.js.org/archive/v1.1.7/)
|
||||
- [v0.2 Documentation](https://mithril.js.org/archive/v0.2.5/)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
- [Releasing a new Mithril version](#releasing-a-new-mithril-version)
|
||||
- [Updating mithril.js.org](#updating-mithriljsorg)
|
||||
- [Releasing a new ospec version](#releasing-a-new-ospec-version)
|
||||
|
||||
## Releasing a new Mithril version
|
||||
|
||||
|
|
@ -18,7 +17,7 @@ $ git pull --rebase mithriljs next
|
|||
```
|
||||
|
||||
2. Determine patch level of the change
|
||||
3. Update information in `docs/change-log.md` to match reality of the new version being prepared for release.
|
||||
3. Update information in `docs/changelog.md` to match reality of the new version being prepared for release.
|
||||
- Don't forget to add today's date under the version heading!
|
||||
4. Replace all existing references to `mithril@next` to `mithril` if moving from a release candidate to stable.
|
||||
- Note: if making an initial release candidate, don't forget to move all the playground snippets to pull from `mithril@next`!
|
||||
|
|
@ -96,11 +95,11 @@ $ git push mithriljs next
|
|||
|
||||
### Update the GitHub release
|
||||
|
||||
16. The GitHub Release will require a manual description & title to be added. I suggest coming up with a fun title & then copying the `docs/change-log.md` entry for the build.
|
||||
16. The GitHub Release will require a manual description & title to be added. I suggest coming up with a fun title & then copying the `docs/changelog.md` entry for the build.
|
||||
|
||||
## Updating mithril.js.org
|
||||
|
||||
Fixes to documentation can land whenever, updates to the site are published via Travis.
|
||||
Fixes to documentation can land whenever, updates to the site are built and published via `scripts/update-docs.js`.
|
||||
|
||||
```bash
|
||||
# These steps assume that MithrilJS/mithril.js is a git remote named "mithriljs"
|
||||
|
|
@ -115,69 +114,9 @@ $ git checkout next -- ./docs
|
|||
|
||||
# Manually ensure that no new feature docs were added
|
||||
|
||||
$ git push mithriljs
|
||||
$ node scripts/update-docs
|
||||
```
|
||||
|
||||
After the Travis build completes the updated docs should appear on https://mithril.js.org in a few minutes.
|
||||
After the docs build completes, the updated docs should appear on https://mithril.js.org in a few minutes.
|
||||
|
||||
**Note:** When updating the stable version with a release candidate out, ***make sure to update the index + navigation to point to the new stable version!!!***
|
||||
|
||||
## Releasing a new ospec version
|
||||
|
||||
1. Ensure your local branch is up to date
|
||||
|
||||
```bash
|
||||
$ git checkout next
|
||||
$ git pull --rebase mithriljs next
|
||||
```
|
||||
|
||||
2. Determine patch level of the change
|
||||
3. Update `version` field in `ospec/package.json` to match new version being prepared for release.
|
||||
4. Update `ospec/change-log.md` to match new version being prepared for release.
|
||||
- Don't forget to add today's date under the version heading!
|
||||
5. Commit changes to `next`
|
||||
|
||||
```
|
||||
$ git add .
|
||||
$ git commit -m "chore(ospec): ospec@<version>"
|
||||
|
||||
# Push to your branch
|
||||
$ git push
|
||||
|
||||
# Push to MithrilJS/mithril.js
|
||||
$ git push mithriljs next
|
||||
```
|
||||
|
||||
### Merge from `next` to `master`
|
||||
|
||||
5. Switch to `master` and make sure it's up to date
|
||||
|
||||
```bash
|
||||
$ git checkout master
|
||||
$ git pull --rebase mithriljs master
|
||||
```
|
||||
|
||||
6. merge `next` on top of it
|
||||
|
||||
```bash
|
||||
$ git checkout next -- ./ospec
|
||||
$ git add .
|
||||
$ git commit -m "chore(ospec): ospec@<version>"
|
||||
```
|
||||
|
||||
7. Ensure the tests are passing!
|
||||
|
||||
### Publish the release
|
||||
|
||||
8. Push the changes to `MithrilJS/mithril.js`
|
||||
|
||||
```bash
|
||||
$ git push mithriljs master
|
||||
```
|
||||
|
||||
9. Publish the changes to npm **from the `/ospec` folder**. That bit is important to ensure you don't accidentally ship a new Mithril release!
|
||||
|
||||
```bash
|
||||
$ cd ./ospec
|
||||
$ npm publish
|
||||
```
|
||||
|
|
|
|||
|
|
@ -3,6 +3,12 @@
|
|||
if (typeof module !== "undefined") module["exports"] = m()
|
||||
else window.o = m()
|
||||
})(function init(name) {
|
||||
console.warn(
|
||||
"Please switch to the `ospec` package to remove this warning and see " +
|
||||
"the most recent features. Using the `ospec` bundled within Mithril " +
|
||||
"is deprecated, and it will be removed in the next major release."
|
||||
)
|
||||
|
||||
var spec = {}, subjects = [], results, only = [], ctx = spec, start, stack = 0, nextTickish, hasProcess = typeof process === "object", hasOwn = ({}).hasOwnProperty
|
||||
var ospecFileName = getStackName(ensureStackTrace(new Error), /[\/\\](.*?):\d+:\d+/), timeoutStackName
|
||||
var globalTimeout = noTimeoutRightNow
|
||||
|
|
|
|||
|
|
@ -6,7 +6,11 @@ var o, callAsync
|
|||
if (typeof require !== "undefined") {
|
||||
/* eslint-disable global-require */
|
||||
callAsync = require("../../test-utils/callAsync")
|
||||
var warn = console.warn
|
||||
// Let's drop the warning to leave the console a little less noisy.
|
||||
console.warn = function() {}
|
||||
o = require("../ospec")
|
||||
console.warn = warn
|
||||
/* eslint-enable global-require */
|
||||
} else {
|
||||
callAsync = typeof setImmediate === "function" ? setImmediate : setTimeout
|
||||
|
|
|
|||
31
package-lock.json
generated
31
package-lock.json
generated
|
|
@ -259,8 +259,7 @@
|
|||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"dev": true
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
|
||||
},
|
||||
"bcrypt-pbkdf": {
|
||||
"version": "1.0.2",
|
||||
|
|
@ -291,7 +290,6 @@
|
|||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
|
|
@ -523,8 +521,7 @@
|
|||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
|
|
@ -1152,8 +1149,7 @@
|
|||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||
},
|
||||
"fsevents": {
|
||||
"version": "2.1.0",
|
||||
|
|
@ -1229,7 +1225,6 @@
|
|||
"version": "7.1.4",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
|
||||
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
|
|
@ -1437,7 +1432,6 @@
|
|||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
|
|
@ -1446,8 +1440,7 @@
|
|||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"inquirer": {
|
||||
"version": "6.5.2",
|
||||
|
|
@ -2035,7 +2028,6 @@
|
|||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
|
|
@ -2226,7 +2218,6 @@
|
|||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
|
|
@ -2260,6 +2251,14 @@
|
|||
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
|
||||
"dev": true
|
||||
},
|
||||
"ospec": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ospec/-/ospec-4.1.1.tgz",
|
||||
"integrity": "sha512-fgWIk1eLDidfB+ixTo3PL3HuuO6iX2LhgWxdnWwqRu2rJdpTowgeAP0RHgt3DSUVyszs964fMuq1tB7Ov2C38A==",
|
||||
"requires": {
|
||||
"glob": "^7.1.3"
|
||||
}
|
||||
},
|
||||
"p-finally": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz",
|
||||
|
|
@ -2306,8 +2305,7 @@
|
|||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
|
||||
},
|
||||
"path-key": {
|
||||
"version": "2.0.1",
|
||||
|
|
@ -3137,8 +3135,7 @@
|
|||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"write": {
|
||||
"version": "1.0.3",
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Leo Horie",
|
||||
"license": "MIT",
|
||||
"unpkg": "mithril.min.js",
|
||||
"repository": "MithrilJS/mithril.js",
|
||||
"repository": "github:MithrilJS/mithril.js",
|
||||
"scripts": {
|
||||
"precommit": "lint-staged",
|
||||
"watch": "run-p watch:**",
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
"perf": "node performance/test-perf.js",
|
||||
"pretest": "npm run lint",
|
||||
"test": "run-s test:js",
|
||||
"test:js": "node ospec/bin/ospec",
|
||||
"test:js": "ospec",
|
||||
"cover": "istanbul cover --print both ospec/bin/ospec",
|
||||
"release": "npm version -m 'v%s'",
|
||||
"version": "npm run build && git add mithril.js mithril.min.js stream.js stream.min.js README.md"
|
||||
|
|
@ -45,6 +45,7 @@
|
|||
"marked": "^0.7.0",
|
||||
"minimist": "^1.2.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"ospec": "^4.0.1",
|
||||
"pinpoint": "^1.1.0",
|
||||
"request": "^2.88.0",
|
||||
"request-promise-native": "^1.0.7",
|
||||
|
|
@ -61,5 +62,7 @@
|
|||
"git add"
|
||||
]
|
||||
},
|
||||
"dependencies": {}
|
||||
"dependencies": {
|
||||
"ospec": "*"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var buildPathname = require("../../pathname/build")
|
||||
|
||||
o.spec("buildPathname", function() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var parsePathname = require("../../pathname/parse")
|
||||
var compileTemplate = require("../../pathname/compileTemplate")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var parsePathname = require("../../pathname/parse")
|
||||
|
||||
o.spec("parsePathname", function() {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ var o, callAsync, Promise
|
|||
if (typeof require !== "undefined") {
|
||||
/* eslint-disable global-require */
|
||||
callAsync = require("../../test-utils/callAsync")
|
||||
o = require("../../ospec/ospec")
|
||||
o = require("ospec")
|
||||
Promise = require("../../promise/polyfill")
|
||||
/* eslint-enable global-require */
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var buildQueryString = require("../../querystring/build")
|
||||
|
||||
o.spec("buildQueryString", function() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var parseQueryString = require("../../querystring/parse")
|
||||
|
||||
o.spec("parseQueryString", function() {
|
||||
|
|
|
|||
|
|
@ -726,12 +726,18 @@ module.exports = function($window) {
|
|||
|
||||
//attrs
|
||||
function setAttrs(vnode, attrs, ns) {
|
||||
// If you assign an input type that is not supported by IE 11 with an assignment expression, an error will occur.
|
||||
//
|
||||
// Also, the DOM does things to inputs based on the value, so it needs set first.
|
||||
// See: https://github.com/MithrilJS/mithril.js/issues/2622
|
||||
if (vnode.tag === "input" && attrs.type != null) vnode.dom.setAttribute("type", attrs.type)
|
||||
var isFileInput = attrs != null && vnode.tag === "input" && attrs.type === "file"
|
||||
for (var key in attrs) {
|
||||
setAttr(vnode, key, null, attrs[key], ns)
|
||||
setAttr(vnode, key, null, attrs[key], ns, isFileInput)
|
||||
}
|
||||
}
|
||||
function setAttr(vnode, key, old, value, ns) {
|
||||
if (key === "key" || key === "is" || value == null || isLifecycleMethod(key) || (old === value && !isFormAttribute(vnode, key)) && typeof value !== "object") return
|
||||
function setAttr(vnode, key, old, value, ns, isFileInput) {
|
||||
if (key === "key" || key === "is" || value == null || isLifecycleMethod(key) || (old === value && !isFormAttribute(vnode, key)) && typeof value !== "object" || key === "type" && vnode.tag === "input") return
|
||||
if (key[0] === "o" && key[1] === "n") return updateEvent(vnode, key, value)
|
||||
if (key.slice(0, 6) === "xlink:") vnode.dom.setAttributeNS("http://www.w3.org/1999/xlink", key.slice(6), value)
|
||||
else if (key === "style") updateStyle(vnode.dom, old, value)
|
||||
|
|
@ -740,16 +746,18 @@ module.exports = function($window) {
|
|||
// Only do the coercion if we're actually going to check the value.
|
||||
/* eslint-disable no-implicit-coercion */
|
||||
//setting input[value] to same value by typing on focused element moves cursor to end in Chrome
|
||||
if ((vnode.tag === "input" || vnode.tag === "textarea") && vnode.dom.value === "" + value && vnode.dom === activeElement()) return
|
||||
//setting input[type=file][value] to same value causes an error to be generated if it's non-empty
|
||||
if ((vnode.tag === "input" || vnode.tag === "textarea") && vnode.dom.value === "" + value && (isFileInput || vnode.dom === activeElement())) return
|
||||
//setting select[value] to same value while having select open blinks select dropdown in Chrome
|
||||
if (vnode.tag === "select" && old !== null && vnode.dom.value === "" + value) return
|
||||
//setting option[value] to same value while having select open blinks select dropdown in Chrome
|
||||
if (vnode.tag === "option" && old !== null && vnode.dom.value === "" + value) return
|
||||
//setting input[type=file][value] to different value is an error if it's non-empty
|
||||
// Not ideal, but it at least works around the most common source of uncaught exceptions for now.
|
||||
if (isFileInput && "" + value !== "") { console.error("`value` is read-only on file inputs!"); return }
|
||||
/* eslint-enable no-implicit-coercion */
|
||||
}
|
||||
// If you assign an input type that is not supported by IE 11 with an assignment expression, an error will occur.
|
||||
if (vnode.tag === "input" && key === "type") vnode.dom.setAttribute(key, value)
|
||||
else vnode.dom[key] = value
|
||||
vnode.dom[key] = value
|
||||
} else {
|
||||
if (typeof value === "boolean") {
|
||||
if (value) vnode.dom.setAttribute(key, "")
|
||||
|
|
@ -793,8 +801,14 @@ module.exports = function($window) {
|
|||
}
|
||||
function updateAttrs(vnode, old, attrs, ns) {
|
||||
if (attrs != null) {
|
||||
// If you assign an input type that is not supported by IE 11 with an assignment expression, an error will occur.
|
||||
//
|
||||
// Also, the DOM does things to inputs based on the value, so it needs set first.
|
||||
// See: https://github.com/MithrilJS/mithril.js/issues/2622
|
||||
if (vnode.tag === "input" && attrs.type != null) vnode.dom.setAttribute("type", attrs.type)
|
||||
var isFileInput = vnode.tag === "input" && attrs.type === "file"
|
||||
for (var key in attrs) {
|
||||
setAttr(vnode, key, old && old[key], attrs[key], ns)
|
||||
setAttr(vnode, key, old && old[key], attrs[key], ns, isFileInput)
|
||||
}
|
||||
}
|
||||
var val
|
||||
|
|
@ -897,6 +911,7 @@ module.exports = function($window) {
|
|||
//event
|
||||
function updateEvent(vnode, key, value) {
|
||||
if (vnode.events != null) {
|
||||
vnode.events._ = currentRedraw
|
||||
if (vnode.events[key] === value) return
|
||||
if (value != null && (typeof value === "function" || typeof value === "object")) {
|
||||
if (vnode.events[key] == null) vnode.dom.addEventListener(key.slice(2), vnode.events, false)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var components = require("../../test-utils/components")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
o.spec("event", function() {
|
||||
var $window, root, redraw, render
|
||||
var $window, root, redraw, render, reallyRender
|
||||
o.beforeEach(function() {
|
||||
$window = domMock()
|
||||
root = $window.document.body
|
||||
redraw = o.spy()
|
||||
var renderer = vdom($window)
|
||||
reallyRender = vdom($window)
|
||||
render = function(dom, vnode) {
|
||||
return renderer(dom, vnode, redraw)
|
||||
return reallyRender(dom, vnode, redraw)
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -355,4 +355,32 @@ o.spec("event", function() {
|
|||
o(redraw.this).equals(undefined)
|
||||
o(redraw.args.length).equals(0)
|
||||
})
|
||||
|
||||
o("handles changed spy", function() {
|
||||
var div1 = {tag: "div", attrs: {ontransitionend: function() {}}}
|
||||
|
||||
reallyRender(root, [div1], redraw)
|
||||
var e = $window.document.createEvent("HTMLEvents")
|
||||
e.initEvent("transitionend", true, true)
|
||||
div1.dom.dispatchEvent(e)
|
||||
|
||||
o(redraw.callCount).equals(1)
|
||||
o(redraw.this).equals(undefined)
|
||||
o(redraw.args.length).equals(0)
|
||||
|
||||
var replacementRedraw = o.spy()
|
||||
var div2 = {tag: "div", attrs: {ontransitionend: function() {}}}
|
||||
|
||||
reallyRender(root, [div2], replacementRedraw)
|
||||
var e = $window.document.createEvent("HTMLEvents")
|
||||
e.initEvent("transitionend", true, true)
|
||||
div2.dom.dispatchEvent(e)
|
||||
|
||||
o(redraw.callCount).equals(1)
|
||||
o(redraw.this).equals(undefined)
|
||||
o(redraw.args.length).equals(0)
|
||||
o(replacementRedraw.callCount).equals(1)
|
||||
o(replacementRedraw.this).equals(undefined)
|
||||
o(replacementRedraw.args.length).equals(0)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var fragment = require("../../render/fragment")
|
||||
var m = require("../../render/hyperscript")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var m = require("../../render/hyperscript")
|
||||
|
||||
o.spec("hyperscript", function() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
|
|
@ -86,6 +86,89 @@ o.spec("form inputs", function() {
|
|||
|
||||
o(updated.dom.checked).equals(true)
|
||||
})
|
||||
|
||||
o("syncs file input value attribute if DOM value differs from vdom value and is empty", function() {
|
||||
var input = {tag: "input", attrs: {type: "file", value: "", onclick: function() {}}}
|
||||
var updated = {tag: "input", attrs: {type: "file", value: "", onclick: function() {}}}
|
||||
var spy = o.spy()
|
||||
var error = console.error
|
||||
|
||||
render(root, [input])
|
||||
|
||||
input.dom.value = "test.png"
|
||||
|
||||
try {
|
||||
console.error = spy
|
||||
render(root, [updated])
|
||||
} finally {
|
||||
console.error = error
|
||||
}
|
||||
|
||||
o(updated.dom.value).equals("")
|
||||
o(spy.callCount).equals(0)
|
||||
})
|
||||
|
||||
o("warns and ignores file input value attribute if DOM value differs from vdom value and is non-empty", function() {
|
||||
var input = {tag: "input", attrs: {type: "file", value: "", onclick: function() {}}}
|
||||
var updated = {tag: "input", attrs: {type: "file", value: "other.png", onclick: function() {}}}
|
||||
var spy = o.spy()
|
||||
var error = console.error
|
||||
|
||||
render(root, [input])
|
||||
|
||||
input.dom.value = "test.png"
|
||||
|
||||
try {
|
||||
console.error = spy
|
||||
render(root, [updated])
|
||||
} finally {
|
||||
console.error = error
|
||||
}
|
||||
|
||||
o(updated.dom.value).equals("test.png")
|
||||
o(spy.callCount).equals(1)
|
||||
})
|
||||
|
||||
o("retains file input value attribute if DOM value is the same as vdom value and is non-empty", function() {
|
||||
var $window = domMock(o)
|
||||
var render = vdom($window)
|
||||
var root = $window.document.createElement("div")
|
||||
$window.document.body.appendChild(root)
|
||||
var input = {tag: "input", attrs: {type: "file", value: "", onclick: function() {}}}
|
||||
var updated1 = {tag: "input", attrs: {type: "file", value: "test.png", onclick: function() {}}}
|
||||
var updated2 = {tag: "input", attrs: {type: "file", value: "test.png", onclick: function() {}}}
|
||||
var spy = o.spy()
|
||||
var error = console.error
|
||||
|
||||
render(root, [input])
|
||||
|
||||
// Verify our assumptions about the outer element state
|
||||
o($window.__getSpies(input.dom).valueSetter.callCount).equals(0)
|
||||
input.dom.value = "test.png"
|
||||
o($window.__getSpies(input.dom).valueSetter.callCount).equals(1)
|
||||
|
||||
try {
|
||||
console.error = spy
|
||||
render(root, [updated1])
|
||||
} finally {
|
||||
console.error = error
|
||||
}
|
||||
|
||||
o(updated1.dom.value).equals("test.png")
|
||||
o(spy.callCount).equals(0)
|
||||
o($window.__getSpies(updated1.dom).valueSetter.callCount).equals(1)
|
||||
|
||||
try {
|
||||
console.error = spy
|
||||
render(root, [updated2])
|
||||
} finally {
|
||||
console.error = error
|
||||
}
|
||||
|
||||
o(updated2.dom.value).equals("test.png")
|
||||
o(spy.callCount).equals(0)
|
||||
o($window.__getSpies(updated2.dom).valueSetter.callCount).equals(1)
|
||||
})
|
||||
})
|
||||
|
||||
o.spec("select", function() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var Vnode = require("../../render/vnode")
|
||||
|
||||
o.spec("normalize", function() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var Vnode = require("../../render/vnode")
|
||||
|
||||
o.spec("normalizeChildren", function() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var m = require("../../render/hyperscript")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var callAsync = require("../../test-utils/callAsync")
|
||||
var components = require("../../test-utils/components")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var components = require("../../test-utils/components")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var components = require("../../test-utils/components")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var m = require("../../render/hyperscript")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var trust = require("../../render/trust")
|
||||
|
||||
o.spec("trust", function() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var components = require("../../test-utils/components")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
var vdom = require("../../render/render")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var xhrMock = require("../../test-utils/xhrMock")
|
||||
var Request = require("../../request/request")
|
||||
var PromisePolyfill = require("../../promise/promise")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var callAsync = require("../../test-utils/callAsync")
|
||||
var xhrMock = require("../../test-utils/xhrMock")
|
||||
var Request = require("../../request/request")
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ class Generator {
|
|||
let anchor = text.toLowerCase()
|
||||
.replace(/<(\/?)code>/g, "")
|
||||
.replace(/<a.*?>.+?<\/a>/g, "")
|
||||
.replace(/\.|\[|\]|"|\/|\(|\)/g, "")
|
||||
.replace(/[.`[\]\/()]|"/g, "")
|
||||
.replace(/\s/g, "-");
|
||||
|
||||
const anchorId = anchorIds.get(anchor)
|
||||
|
|
|
|||
|
|
@ -278,8 +278,8 @@ async function lintAll({useCache}) {
|
|||
await new Promise((resolve, reject) => {
|
||||
const glob = new Glob(path.resolve(__dirname, "../**/*.md"), {
|
||||
ignore: [
|
||||
"**/change-log.md",
|
||||
"**/migration-v02x.md",
|
||||
"**/changelog.md",
|
||||
"**/migration-*.md",
|
||||
"**/node_modules/**",
|
||||
],
|
||||
nodir: true,
|
||||
|
|
@ -304,10 +304,10 @@ if (require.main === module) {
|
|||
exec: lintAll,
|
||||
watch() {
|
||||
require("chokidar")
|
||||
.watch(path.resolve(__dirname, "../**/*.md"), {
|
||||
ignored: [
|
||||
"**/change-log.md",
|
||||
"**/migration-v02x.md",
|
||||
.watch(path.resolve(__dirname, "../docs/**/*.md"), {
|
||||
ignore: [
|
||||
"**/changelog.md",
|
||||
"**/migration-*.md",
|
||||
"**/node_modules/**",
|
||||
],
|
||||
})
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ async function release({increment, preid, publish}) {
|
|||
|
||||
console.error(`
|
||||
Copy the parts listed in "Upcoming" to a new section "### v${version}" in
|
||||
docs/change-log.md and clear that section out. Also, add today's date under the
|
||||
docs/changelog.md and clear that section out. Also, add today's date under the
|
||||
new section's heading to match the others and don't forget to update the table
|
||||
of contents accordingly.
|
||||
`)
|
||||
|
|
@ -138,7 +138,7 @@ of contents accordingly.
|
|||
// Verify the changelog was updated, and give a chance to retry if it's
|
||||
// prematurely continued.
|
||||
const changes = getChanges()
|
||||
const isChangelog = /^[ M][ M] docs\/change-log\.md$/
|
||||
const isChangelog = /^[ M][ M] docs\/changelog\.md$/
|
||||
const errors = []
|
||||
|
||||
console.log("changes", changes)
|
||||
|
|
|
|||
|
|
@ -2,22 +2,24 @@
|
|||
|
||||
const fs = require("fs")
|
||||
const util = require("util")
|
||||
const path = require("path")
|
||||
const access = util.promisify(fs.access)
|
||||
const writeFile = util.promisify(fs.writeFile)
|
||||
const unlink = util.promisify(fs.unlink)
|
||||
|
||||
const o = require("../../ospec/ospec")
|
||||
const o = require("ospec")
|
||||
const bundle = require("../_bundler-impl")
|
||||
|
||||
o.spec("bundler", async () => {
|
||||
let filesCreated
|
||||
const ns = "./"
|
||||
const root = path.resolve(__dirname, "../..")
|
||||
const p = (file) => path.join(root, file)
|
||||
|
||||
async function write(filepath, data) {
|
||||
try {
|
||||
await access(ns + filepath)
|
||||
await access(p(filepath))
|
||||
} catch (e) {
|
||||
return writeFile(ns + filepath, data, "utf8")
|
||||
return writeFile(p(filepath), data, "utf8")
|
||||
}
|
||||
throw new Error(`Don't call \`write('${filepath}')\`. Cannot overwrite file.`)
|
||||
}
|
||||
|
|
@ -28,7 +30,7 @@ o.spec("bundler", async () => {
|
|||
}
|
||||
|
||||
o.afterEach(() => Promise.all(
|
||||
filesCreated.map((filepath) => unlink(ns + filepath))
|
||||
filesCreated.map((filepath) => unlink(p(filepath)))
|
||||
))
|
||||
|
||||
o("relative imports works", async () => {
|
||||
|
|
@ -37,7 +39,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": "module.exports = 1",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nvar b = 1\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nvar b = 1\n}());")
|
||||
})
|
||||
o("relative imports works with semicolons", async () => {
|
||||
await setup({
|
||||
|
|
@ -45,7 +47,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": "module.exports = 1;",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nvar b = 1;\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nvar b = 1;\n}());")
|
||||
})
|
||||
o("relative imports works with let", async () => {
|
||||
await setup({
|
||||
|
|
@ -53,7 +55,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": "module.exports = 1",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nlet b = 1\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nlet b = 1\n}());")
|
||||
})
|
||||
o("relative imports works with const", async () => {
|
||||
await setup({
|
||||
|
|
@ -61,7 +63,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": "module.exports = 1",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nconst b = 1\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nconst b = 1\n}());")
|
||||
})
|
||||
o("relative imports works with assignment", async () => {
|
||||
await setup({
|
||||
|
|
@ -69,7 +71,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": "module.exports = 1",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nvar a = {}\na.b = 1\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nvar a = {}\na.b = 1\n}());")
|
||||
})
|
||||
o("relative imports works with reassignment", async () => {
|
||||
await setup({
|
||||
|
|
@ -77,7 +79,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": "module.exports = 1",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nvar b = {}\nb = 1\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nvar b = {}\nb = 1\n}());")
|
||||
})
|
||||
o("relative imports removes extra use strict", async () => {
|
||||
await setup({
|
||||
|
|
@ -85,7 +87,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": '"use strict"\nmodule.exports = 1',
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(';(function() {\n"use strict"\nvar b = 1\n}());')
|
||||
o(await bundle(p("a.js"))).equals(';(function() {\n"use strict"\nvar b = 1\n}());')
|
||||
})
|
||||
o("relative imports removes extra use strict using single quotes", async () => {
|
||||
await setup({
|
||||
|
|
@ -93,7 +95,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": "'use strict'\nmodule.exports = 1",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\n'use strict'\nvar b = 1\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\n'use strict'\nvar b = 1\n}());")
|
||||
})
|
||||
o("relative imports removes extra use strict using mixed quotes", async () => {
|
||||
await setup({
|
||||
|
|
@ -101,7 +103,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": "'use strict'\nmodule.exports = 1",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(';(function() {\n"use strict"\nvar b = 1\n}());')
|
||||
o(await bundle(p("a.js"))).equals(';(function() {\n"use strict"\nvar b = 1\n}());')
|
||||
})
|
||||
o("works w/ window", async () => {
|
||||
await setup({
|
||||
|
|
@ -109,7 +111,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": "module.exports = function() {return a}",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nwindow.a = 1\nvar b = function() {return a}\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nwindow.a = 1\nvar b = function() {return a}\n}());")
|
||||
})
|
||||
o("works without assignment", async () => {
|
||||
await setup({
|
||||
|
|
@ -117,7 +119,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": "1 + 1",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\n1 + 1\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\n1 + 1\n}());")
|
||||
})
|
||||
o("works if used fluently", async () => {
|
||||
await setup({
|
||||
|
|
@ -125,7 +127,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": "module.exports = []",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nvar _0 = []\nvar b = _0.toString()\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nvar _0 = []\nvar b = _0.toString()\n}());")
|
||||
})
|
||||
o("works if used fluently w/ multiline", async () => {
|
||||
await setup({
|
||||
|
|
@ -133,7 +135,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": "module.exports = []",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nvar _0 = []\nvar b = _0\n\t.toString()\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nvar _0 = []\nvar b = _0\n\t.toString()\n}());")
|
||||
})
|
||||
o("works if used w/ curry", async () => {
|
||||
await setup({
|
||||
|
|
@ -141,7 +143,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": "module.exports = function() {}",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nvar _0 = function() {}\nvar b = _0()\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nvar _0 = function() {}\nvar b = _0()\n}());")
|
||||
})
|
||||
o("works if used w/ curry w/ multiline", async () => {
|
||||
await setup({
|
||||
|
|
@ -149,7 +151,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": "module.exports = function() {}",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nvar _0 = function() {}\nvar b = _0\n()\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nvar _0 = function() {}\nvar b = _0\n()\n}());")
|
||||
})
|
||||
o("works if used fluently in one place and not in another", async () => {
|
||||
await setup({
|
||||
|
|
@ -158,7 +160,7 @@ o.spec("bundler", async () => {
|
|||
"c.js": 'var b = require("./b")\nmodule.exports = function() {return b}',
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nvar _0 = []\nvar b = _0.toString()\nvar b0 = _0\nvar c = function() {return b0}\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nvar _0 = []\nvar b = _0.toString()\nvar b0 = _0\nvar c = function() {return b0}\n}());")
|
||||
})
|
||||
o("works if used in sequence", async () => {
|
||||
await setup({
|
||||
|
|
@ -167,7 +169,7 @@ o.spec("bundler", async () => {
|
|||
"c.js": "var x\nmodule.exports = 2",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nvar b = 1\nvar x\nvar c = 2\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nvar b = 1\nvar x\nvar c = 2\n}());")
|
||||
})
|
||||
o("works if assigned to property", async () => {
|
||||
await setup({
|
||||
|
|
@ -176,7 +178,7 @@ o.spec("bundler", async () => {
|
|||
"c.js": "var cc = 2\nmodule.exports = cc",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nvar x = {}\nvar bb = 1\nx.b = bb\nvar cc = 2\nx.c = cc\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nvar x = {}\nvar bb = 1\nx.b = bb\nvar cc = 2\nx.c = cc\n}());")
|
||||
})
|
||||
o("works if assigned to property using bracket notation", async () => {
|
||||
await setup({
|
||||
|
|
@ -185,7 +187,7 @@ o.spec("bundler", async () => {
|
|||
"c.js": "var cc = 2\nmodule.exports = cc",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(';(function() {\nvar x = {}\nvar bb = 1\nx["b"] = bb\nvar cc = 2\nx["c"] = cc\n}());')
|
||||
o(await bundle(p("a.js"))).equals(';(function() {\nvar x = {}\nvar bb = 1\nx["b"] = bb\nvar cc = 2\nx["c"] = cc\n}());')
|
||||
})
|
||||
o("works if collision", async () => {
|
||||
await setup({
|
||||
|
|
@ -193,7 +195,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": "var b = 1\nmodule.exports = 2",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nvar b0 = 1\nvar b = 2\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nvar b0 = 1\nvar b = 2\n}());")
|
||||
})
|
||||
o("works if multiple aliases", async () => {
|
||||
await setup({
|
||||
|
|
@ -202,7 +204,7 @@ o.spec("bundler", async () => {
|
|||
"c.js": "var b = {}\nmodule.exports = b",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nvar b = {}\nb.x = 1\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nvar b = {}\nb.x = 1\n}());")
|
||||
})
|
||||
o("works if multiple collision", async () => {
|
||||
await setup({
|
||||
|
|
@ -212,7 +214,7 @@ o.spec("bundler", async () => {
|
|||
"d.js": "var a = 3\nmodule.exports = a",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nvar a = 1\nvar b = a\nvar a0 = 2\nvar c = a0\nvar a1 = 3\nvar d = a1\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nvar a = 1\nvar b = a\nvar a0 = 2\nvar c = a0\nvar a1 = 3\nvar d = a1\n}());")
|
||||
})
|
||||
o("works if included multiple times", async () => {
|
||||
await setup({
|
||||
|
|
@ -221,7 +223,7 @@ o.spec("bundler", async () => {
|
|||
"c.js": 'var a = require("./a").toString()\nvar b = require("./b")',
|
||||
})
|
||||
|
||||
o(await bundle(ns + "c.js")).equals(";(function() {\nvar _0 = 123\nvar a = _0.toString()\nvar a0 = _0.toString()\nvar b = a0\n}());")
|
||||
o(await bundle(p("c.js"))).equals(";(function() {\nvar _0 = 123\nvar a = _0.toString()\nvar a0 = _0.toString()\nvar b = a0\n}());")
|
||||
})
|
||||
o("works if included multiple times reverse", async () => {
|
||||
await setup({
|
||||
|
|
@ -230,7 +232,7 @@ o.spec("bundler", async () => {
|
|||
"c.js": 'var b = require("./b")\nvar a = require("./a").toString()',
|
||||
})
|
||||
|
||||
o(await bundle(ns + "c.js")).equals(";(function() {\nvar _0 = 123\nvar a0 = _0.toString()\nvar b = a0\nvar a = _0.toString()\n}());")
|
||||
o(await bundle(p("c.js"))).equals(";(function() {\nvar _0 = 123\nvar a0 = _0.toString()\nvar b = a0\nvar a = _0.toString()\n}());")
|
||||
})
|
||||
o("reuses binding if possible", async () => {
|
||||
await setup({
|
||||
|
|
@ -240,7 +242,7 @@ o.spec("bundler", async () => {
|
|||
"d.js": "module.exports = 1",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nvar d = 1\nvar b = function() {return d + 1}\nvar c = function() {return d + 2}\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nvar d = 1\nvar b = function() {return d + 1}\nvar c = function() {return d + 2}\n}());")
|
||||
})
|
||||
o("disambiguates conflicts if imported collides with itself", async () => {
|
||||
await setup({
|
||||
|
|
@ -248,7 +250,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": "var b = 1\nmodule.exports = function() {return b}",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nvar b0 = 1\nvar b = function() {return b0}\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nvar b0 = 1\nvar b = function() {return b0}\n}());")
|
||||
})
|
||||
o("disambiguates conflicts if imported collides with something else", async () => {
|
||||
await setup({
|
||||
|
|
@ -256,7 +258,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": "var a = 2\nmodule.exports = function() {return a}",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nvar a = 1\nvar a0 = 2\nvar b = function() {return a0}\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nvar a = 1\nvar a0 = 2\nvar b = function() {return a0}\n}());")
|
||||
})
|
||||
o("disambiguates conflicts if imported collides with function declaration", async () => {
|
||||
await setup({
|
||||
|
|
@ -264,7 +266,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": "var a = 2\nmodule.exports = function() {return a}",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nfunction a() {}\nvar a0 = 2\nvar b = function() {return a0}\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nfunction a() {}\nvar a0 = 2\nvar b = function() {return a0}\n}());")
|
||||
})
|
||||
o("disambiguates conflicts if imported collides with another module's private", async () => {
|
||||
await setup({
|
||||
|
|
@ -273,7 +275,7 @@ o.spec("bundler", async () => {
|
|||
"c.js": "var a = 2\nmodule.exports = function() {return a}",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nvar a = 1\nvar b = function() {return a}\nvar a0 = 2\nvar c = function() {return a0}\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nvar a = 1\nvar b = function() {return a}\nvar a0 = 2\nvar c = function() {return a0}\n}());")
|
||||
})
|
||||
o("does not mess up strings", async () => {
|
||||
await setup({
|
||||
|
|
@ -281,7 +283,7 @@ o.spec("bundler", async () => {
|
|||
"b.js": 'var b = "b b b \\" b"\nmodule.exports = function() {return b}',
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(';(function() {\nvar b0 = "b b b \\\" b"\nvar b = function() {return b0}\n}());')
|
||||
o(await bundle(p("a.js"))).equals(';(function() {\nvar b0 = "b b b \\\" b"\nvar b = function() {return b0}\n}());')
|
||||
})
|
||||
o("does not mess up properties", async () => {
|
||||
await setup({
|
||||
|
|
@ -289,6 +291,6 @@ o.spec("bundler", async () => {
|
|||
"b.js": "var b = {b: 1}\nmodule.exports = function() {return b.b}",
|
||||
})
|
||||
|
||||
o(await bundle(ns + "a.js")).equals(";(function() {\nvar b0 = {b: 1}\nvar b = function() {return b0.b}\n}());")
|
||||
o(await bundle(p("a.js"))).equals(";(function() {\nvar b0 = {b: 1}\nvar b = function() {return b0.b}\n}());")
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Leo Horie
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
mithril-stream [](https://www.npmjs.com/package/mithril-stream) [](https://www.npmjs.com/package/mithril-stream)
|
||||
==============
|
||||
|
||||
Mithril's `m.stream` as a standalone module.
|
||||
|
||||
See [mithril.js.org/stream.html](https://mithril.js.org/stream.html) for docs/usage.
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
# Change log for stream
|
||||
|
||||
- [Upcoming](#upcoming)
|
||||
- [v2.0.0](#v200)
|
||||
- [v1.1.0](#v110)
|
||||
|
||||
### Upcoming...
|
||||
|
||||
### 2.0.0
|
||||
_2019-02-07_
|
||||
|
||||
- when a stream conditionally returns HALT, dependant stream will also end ([#2200](https://github.com/MithrilJS/mithril.js/pull/2200), [#2369](https://github.com/MithrilJS/mithril.js/pull/2369))
|
||||
- Add `stream.lift` as a user-friendly alternative to `merge -> map` or `combine` ([#1944](https://github.com/MithrilJS/mithril.js/issues/1944))
|
||||
- renamed HALT to SKIP ([#2207](https://github.com/MithrilJS/mithril.js/pull/2207))
|
||||
- rewrote implementation ([#2207](https://github.com/MithrilJS/mithril.js/pull/2207))
|
||||
- Removed `valueOf` & `toString` methods ([#2150](https://github.com/MithrilJS/mithril.js/pull/2150))
|
||||
- fixed `stream.end` propagation ([#2369](https://github.com/MithrilJS/mithril.js/pull/2369))
|
||||
|
||||
### 1.1.0
|
||||
_2017-07-13_
|
||||
|
||||
- Move the "use strict" directive inside the IIFE [#1831](https://github.com/MithrilJS/mithril.js/issues/1831) ([#1893](https://github.com/MithrilJS/mithril.js/pull/1893))
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"name": "mithril-stream",
|
||||
"version": "2.0.0",
|
||||
"description": "Streaming data, mithril-style",
|
||||
"main": "stream.js",
|
||||
"directories": {
|
||||
"test": "tests"
|
||||
},
|
||||
"keywords": [ "stream", "reactive", "data" ],
|
||||
"author": "Leo Horie <lhorie@hotmail.com>",
|
||||
"license": "MIT",
|
||||
"repository": "MithrilJS/mithril.js"
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var stream = require("../stream")
|
||||
|
||||
o.spec("scan", function() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var stream = require("../stream")
|
||||
|
||||
o.spec("scanMerge", function() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var Stream = require("../stream")
|
||||
|
||||
o.spec("stream", function() {
|
||||
|
|
|
|||
|
|
@ -495,6 +495,37 @@ module.exports = function(options) {
|
|||
set: valueSetter,
|
||||
enumerable: true,
|
||||
})
|
||||
Object.defineProperty(element, "valueAsDate", {
|
||||
get: function() {
|
||||
if (this.getAttribute("type") !== "date") return null
|
||||
return new Date(value).getTime()
|
||||
},
|
||||
set: function(v) {
|
||||
if (this.getAttribute("type") !== "date") throw new Error("invalid state")
|
||||
var time = new Date(v).getTime()
|
||||
return valueSetter(isNaN(time) ? "" : new Date(time).toUTCString())
|
||||
},
|
||||
enumerable: true,
|
||||
})
|
||||
Object.defineProperty(element, "valueAsNumber", {
|
||||
get: function() {
|
||||
switch (this.getAttribute("type")) {
|
||||
case "date": return new Date(value).getTime()
|
||||
case "number": return new Date(value).getTime()
|
||||
default: return NaN
|
||||
}
|
||||
},
|
||||
set: function(v) {
|
||||
v = Number(v)
|
||||
if (!isNaN(v) && !isFinite(v)) throw new TypeError("infinite value")
|
||||
switch (this.getAttribute("type")) {
|
||||
case "date": return valueSetter(isNaN(v) ? "" : new Date(v).toUTCString())
|
||||
case "number": return valueSetter(String(value))
|
||||
default: throw new Error("invalid state")
|
||||
}
|
||||
},
|
||||
enumerable: true,
|
||||
})
|
||||
|
||||
// we currently emulate the non-ie behavior, but emulating ie may be more useful (throw when an invalid type is set)
|
||||
var typeSetter = spy(function(v) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var browserMock = require("../../test-utils/browserMock")
|
||||
var callAsync = require("../../test-utils/callAsync")
|
||||
o.spec("browserMock", function() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var callAsync = require("../../test-utils/callAsync")
|
||||
|
||||
o.spec("callAsync", function() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var components = require("../../test-utils/components")
|
||||
|
||||
o.spec("test-utils/components", function() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var domMock = require("../../test-utils/domMock")
|
||||
|
||||
o.spec("domMock", function() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var parseURL = require("../../test-utils/parseURL")
|
||||
|
||||
o.spec("parseURL", function() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var pushStateMock = require("../../test-utils/pushStateMock")
|
||||
var callAsync = require("../../test-utils/callAsync")
|
||||
o.spec("pushStateMock", function() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var throttleMocker = require("../../test-utils/throttleMock")
|
||||
|
||||
o.spec("throttleMock", function() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var xhrMock = require("../../test-utils/xhrMock")
|
||||
var parseQueryString = require("../../querystring/parse")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var browserMock = require("../test-utils/browserMock")
|
||||
var components = require("../test-utils/components")
|
||||
|
||||
o.spec("api", function() {
|
||||
var FRAME_BUDGET = Math.floor(1000 / 60)
|
||||
var mock = browserMock(), root
|
||||
mock.setTimeout = setTimeout
|
||||
if (typeof global !== "undefined") {
|
||||
global.window = mock
|
||||
global.requestAnimationFrame = mock.requestAnimationFrame
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict"
|
||||
|
||||
var o = require("../../ospec/ospec")
|
||||
var o = require("ospec")
|
||||
var censor = require("../../util/censor")
|
||||
|
||||
o.spec("censor", function() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue