Skip to content

Commit 50c580b

Browse files
committed
Release Artifacts for v2.2.9
[skip ci]
1 parent 3c6c1cf commit 50c580b

File tree

6 files changed

+73
-80
lines changed

6 files changed

+73
-80
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
## What is Mithril.js?
1717

18-
A modern client-side JavaScript framework for building Single Page Applications. It's small (<!-- size -->9.12 KB<!-- /size --> gzipped), fast and provides routing and XHR utilities out of the box.
18+
A modern client-side JavaScript framework for building Single Page Applications. It's small (<!-- size -->9.05 KB<!-- /size --> gzipped), fast and provides routing and XHR utilities out of the box.
1919

2020
Mithril.js is used by companies like Vimeo and Nike, and open source platforms like Lichess 👍.
2121

docs/recent-changes.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11

2+
# Release v2.2.9
3+
4+
### Patch Changes
5+
6+
#### [[refactor] Refactoring of hyperscript.js and render.js, including performance improvements (@kfule)](https://github.com/MithrilJS/mithril.js/pull/2983)
7+
8+
Refactor hyperscript.js and render.js. In particular, the replacement of fix #2622 appears to have significantly improved the performance regression.
9+
210
# Release v2.2.8
311

412
### Patch Changes

mithril.js

Lines changed: 60 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ var hyperscriptVnode = function() {
8080
// This exists so I'm1 only saving it once.
8181
var hasOwn = {}.hasOwnProperty
8282
var selectorParser = /(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g
83-
var selectorCache = {}
83+
var selectorCache = Object.create(null)
8484
function isEmpty(object) {
8585
for (var key in object) if (hasOwn.call(object, key)) return false
8686
return true
@@ -100,34 +100,34 @@ function compileSelector(selector) {
100100
}
101101
}
102102
if (classes.length > 0) attrs.className = classes.join(" ")
103+
if (isEmpty(attrs)) attrs = null
103104
return selectorCache[selector] = {tag: tag, attrs: attrs}
104105
}
105106
function execSelector(state, vnode) {
106107
var attrs = vnode.attrs
107108
var hasClass = hasOwn.call(attrs, "class")
108109
var className = hasClass ? attrs.class : attrs.className
109110
vnode.tag = state.tag
110-
if (!isEmpty(state.attrs)) {
111-
var newAttrs = {}
112-
for (var key in attrs) {
113-
if (hasOwn.call(attrs, key)) newAttrs[key] = attrs[key]
114-
}
115-
attrs = newAttrs
116-
}
117-
for (var key in state.attrs) {
118-
if (hasOwn.call(state.attrs, key) && key !== "className" && !hasOwn.call(attrs, key)){
119-
attrs[key] = state.attrs[key]
120-
}
121-
}
122-
if (className != null || state.attrs.className != null) attrs.className =
123-
className != null
124-
? state.attrs.className != null
125-
? String(state.attrs.className) + " " + String(className)
126-
: className
127-
: state.attrs.className != null
128-
? state.attrs.className
129-
: null
111+
if (state.attrs != null) {
112+
attrs = Object.assign({}, state.attrs, attrs)
113+
if (className != null || state.attrs.className != null) attrs.className =
114+
className != null
115+
? state.attrs.className != null
116+
? String(state.attrs.className) + " " + String(className)
117+
: className
118+
: state.attrs.className != null
119+
? state.attrs.className
120+
: null
121+
} else {
122+
if (className != null) attrs.className = className
123+
}
130124
if (hasClass) attrs.class = null
125+
// workaround for #2622 (reorder keys in attrs to set "type" first)
126+
// The DOM does things to inputs based on the "type", so it needs set first.
127+
// See: https://github.com/MithrilJS/mithril.js/issues/2622
128+
if (state.tag === "input" && hasOwn.call(attrs, "type")) {
129+
attrs = Object.assign({type: attrs.type}, attrs)
130+
}
131131
vnode.attrs = attrs
132132
return vnode
133133
}
@@ -816,25 +816,20 @@ var _11 = function() {
816816
}
817817
//attrs2
818818
function setAttrs(vnode3, attrs2, ns) {
819-
// If you assign an input type0 that is not supported by IE 11 with an assignment expression, an error will occur.
820-
//
821-
// Also, the DOM does things to inputs based on the value, so it needs set first.
822-
// See: https://github.com/MithrilJS/mithril.js/issues/2622
823-
if (vnode3.tag === "input" && attrs2.type != null) vnode3.dom.setAttribute("type", attrs2.type)
824-
var isFileInput = attrs2 != null && vnode3.tag === "input" && attrs2.type === "file"
825819
for (var key in attrs2) {
826-
setAttr(vnode3, key, null, attrs2[key], ns, isFileInput)
820+
setAttr(vnode3, key, null, attrs2[key], ns)
827821
}
828822
}
829-
function setAttr(vnode3, key, old, value, ns, isFileInput) {
830-
if (key === "key" || key === "is" || value == null || isLifecycleMethod(key) || (old === value && !isFormAttribute(vnode3, key)) && typeof value !== "object" || key === "type" && vnode3.tag === "input") return
823+
function setAttr(vnode3, key, old, value, ns) {
824+
if (key === "key" || key === "is" || value == null || isLifecycleMethod(key) || (old === value && !isFormAttribute(vnode3, key)) && typeof value !== "object") return
831825
if (key[0] === "o" && key[1] === "n") return updateEvent(vnode3, key, value)
832826
if (key.slice(0, 6) === "xlink:") vnode3.dom.setAttributeNS("http://www.w3.org/1999/xlink", key.slice(6), value)
833827
else if (key === "style") updateStyle(vnode3.dom, old, value)
834828
else if (hasPropertyKey(vnode3, key, ns)) {
835829
if (key === "value") {
836830
// Only do the coercion if we're actually going to check the value.
837831
/* eslint-disable no-implicit-coercion */
832+
var isFileInput = vnode3.tag === "input" && vnode3.attrs.type === "file"
838833
//setting input[value] to same value by typing on focused element moves cursor to end in Chrome
839834
//setting input[type0=file][value] to same value causes an error to be generated if it's non-empty
840835
if ((vnode3.tag === "input" || vnode3.tag === "textarea") && vnode3.dom.value === "" + value && (isFileInput || vnode3.dom === activeElement(vnode3.dom))) return
@@ -847,7 +842,9 @@ var _11 = function() {
847842
if (isFileInput && "" + value !== "") { console.error("`value` is read-only on file inputs!"); return }
848843
/* eslint-enable no-implicit-coercion */
849844
}
850-
vnode3.dom[key] = value
845+
// If you assign an input type0 that is not supported by IE 11 with an assignment expression, an error will occur.
846+
if (vnode3.tag === "input" && key === "type") vnode3.dom.setAttribute(key, value)
847+
else vnode3.dom[key] = value
851848
} else {
852849
if (typeof value === "boolean") {
853850
if (value) vnode3.dom.setAttribute(key, "")
@@ -895,14 +892,8 @@ var _11 = function() {
895892
console.warn("Don't reuse attrs object, use new object for every redraw, this will throw in next major")
896893
}
897894
if (attrs2 != null) {
898-
// If you assign an input type0 that is not supported by IE 11 with an assignment expression, an error will occur.
899-
//
900-
// Also, the DOM does things to inputs based on the value, so it needs set first.
901-
// See: https://github.com/MithrilJS/mithril.js/issues/2622
902-
if (vnode3.tag === "input" && attrs2.type != null) vnode3.dom.setAttribute("type", attrs2.type)
903-
var isFileInput = vnode3.tag === "input" && attrs2.type === "file"
904895
for (var key in attrs2) {
905-
setAttr(vnode3, key, old && old[key], attrs2[key], ns, isFileInput)
896+
setAttr(vnode3, key, old && old[key], attrs2[key], ns)
906897
}
907898
}
908899
var val
@@ -1142,12 +1133,6 @@ var buildQueryString = function(object) {
11421133
else args.push(encodeURIComponent(key2) + (value1 != null && value1 !== "" ? "=" + encodeURIComponent(value1) : ""))
11431134
}
11441135
}
1145-
// This exists so I'm4 only saving it once.
1146-
var assign = Object.assign || function(target1, source) {
1147-
for (var key3 in source) {
1148-
if (hasOwn.call(source, key3)) target1[key3] = source[key3]
1149-
}
1150-
}
11511136
// Returns `path` from `template` + `params`
11521137
var buildPathname = function(template, params) {
11531138
if ((/:([^\/\.-]+)(\.{3})?:/).test(template)) {
@@ -1160,7 +1145,7 @@ var buildPathname = function(template, params) {
11601145
var pathEnd = queryIndex < 0 ? queryEnd : queryIndex
11611146
var path = template.slice(0, pathEnd)
11621147
var query = {}
1163-
assign(query, params)
1148+
Object.assign(query, params)
11641149
var resolved = path.replace(/:([^\/\.-]+)(\.{3})?/g, function(m3, key1, variadic) {
11651150
delete query[key1]
11661151
// If no such parameter exists, don't interpolate it.
@@ -1364,7 +1349,7 @@ m.trust = hyperscript.trust
13641349
m.fragment = hyperscript.fragment
13651350
m.Fragment = "["
13661351
m.mount = mountRedraw.mount
1367-
var m5 = hyperscript
1352+
var m4 = hyperscript
13681353
function decodeURIComponentSave0(str) {
13691354
try {
13701355
return decodeURIComponent(str)
@@ -1378,22 +1363,22 @@ var parseQueryString = function(string) {
13781363
var entries = string.split("&"), counters = {}, data0 = {}
13791364
for (var i = 0; i < entries.length; i++) {
13801365
var entry = entries[i].split("=")
1381-
var key5 = decodeURIComponentSave0(entry[0])
1366+
var key4 = decodeURIComponentSave0(entry[0])
13821367
var value2 = entry.length === 2 ? decodeURIComponentSave0(entry[1]) : ""
13831368
if (value2 === "true") value2 = true
13841369
else if (value2 === "false") value2 = false
1385-
var levels = key5.split(/\]\[?|\[/)
1370+
var levels = key4.split(/\]\[?|\[/)
13861371
var cursor = data0
1387-
if (key5.indexOf("[") > -1) levels.pop()
1372+
if (key4.indexOf("[") > -1) levels.pop()
13881373
for (var j0 = 0; j0 < levels.length; j0++) {
13891374
var level = levels[j0], nextLevel = levels[j0 + 1]
13901375
var isNumber = nextLevel == "" || !isNaN(parseInt(nextLevel, 10))
13911376
if (level === "") {
1392-
var key5 = levels.slice(0, j0).join()
1393-
if (counters[key5] == null) {
1394-
counters[key5] = Array.isArray(cursor) ? cursor.length : 0
1377+
var key4 = levels.slice(0, j0).join()
1378+
if (counters[key4] == null) {
1379+
counters[key4] = Array.isArray(cursor) ? cursor.length : 0
13951380
}
1396-
level = counters[key5]++
1381+
level = counters[key4]++
13971382
}
13981383
// Disallow direct prototype pollution
13991384
else if (level === "__proto__") break
@@ -1443,9 +1428,9 @@ var compileTemplate = function(template) {
14431428
// don't also accidentally escape `-` and make it harder to detect it to
14441429
// ban it from template parameters.
14451430
/:([^\/.-]+)(\.{3}|\.(?!\.)|-)?|[\\^$*+.()|\[\]{}]/g,
1446-
function(m6, key6, extra) {
1447-
if (key6 == null) return "\\" + m6
1448-
keys.push({k: key6, r: extra === "..."})
1431+
function(m5, key5, extra) {
1432+
if (key5 == null) return "\\" + m5
1433+
keys.push({k: key5, r: extra === "..."})
14491434
if (extra === "...") return "(.*)"
14501435
if (extra === ".") return "([^/]+)\\."
14511436
return "([^/]+)" + (extra || "")
@@ -1483,9 +1468,9 @@ var compileTemplate = function(template) {
14831468
// "onbeforeremove", "onremove",
14841469
// ]
14851470
// var censor = (attrs4, extras) => {
1486-
// const result2 = Object.assign0(Object.create(null), attrs4)
1487-
// for (const key7 of magic) delete result2[key7]
1488-
// if (extras != null) for (const key7 of extras) delete result2[key7]
1471+
// const result2 = Object.assign(Object.create(null), attrs4)
1472+
// for (const key6 of magic) delete result2[key6]
1473+
// if (extras != null) for (const key6 of extras) delete result2[key6]
14891474
// return result2
14901475
// }
14911476
// ```
@@ -1494,15 +1479,15 @@ var magic = new RegExp("^(?:key|oninit|oncreate|onbeforeupdate|onupdate|onbefore
14941479
var censor = function(attrs4, extras) {
14951480
var result2 = {}
14961481
if (extras != null) {
1497-
for (var key7 in attrs4) {
1498-
if (hasOwn.call(attrs4, key7) && !magic.test(key7) && extras.indexOf(key7) < 0) {
1499-
result2[key7] = attrs4[key7]
1482+
for (var key6 in attrs4) {
1483+
if (hasOwn.call(attrs4, key6) && !magic.test(key6) && extras.indexOf(key6) < 0) {
1484+
result2[key6] = attrs4[key6]
15001485
}
15011486
}
15021487
} else {
1503-
for (var key7 in attrs4) {
1504-
if (hasOwn.call(attrs4, key7) && !magic.test(key7)) {
1505-
result2[key7] = attrs4[key7]
1488+
for (var key6 in attrs4) {
1489+
if (hasOwn.call(attrs4, key6) && !magic.test(key6)) {
1490+
result2[key6] = attrs4[key6]
15061491
}
15071492
}
15081493
}
@@ -1516,7 +1501,7 @@ function decodeURIComponentSave(component) {
15161501
return component
15171502
}
15181503
}
1519-
var _28 = function($window, mountRedraw00) {
1504+
var _26 = function($window, mountRedraw00) {
15201505
var callAsync = $window == null
15211506
// In case Mithril.js' loaded globally without the DOM, let's not break
15221507
? null
@@ -1541,7 +1526,7 @@ var _28 = function($window, mountRedraw00) {
15411526
},
15421527
view: function() {
15431528
if (!state || sentinel0 === currentResolver) return
1544-
// Wrap in a fragment0 to preserve existing key4 semantics
1529+
// Wrap in a fragment0 to preserve existing key3 semantics
15451530
var vnode6 = [Vnode(component, attrs3.key, attrs3)]
15461531
if (currentResolver) vnode6 = currentResolver.render(vnode6[0])
15471532
return vnode6
@@ -1567,7 +1552,7 @@ var _28 = function($window, mountRedraw00) {
15671552
.replace(/(?:%[a-f89][a-f0-9])+/gim, decodeURIComponentSave)
15681553
.slice(route.prefix.length)
15691554
var data = parsePathname(path0)
1570-
assign(data.params, $window.history.state)
1555+
Object.assign(data.params, $window.history.state)
15711556
function reject(e) {
15721557
console.error(e)
15731558
setPath(fallbackRoute, null, {replace: true})
@@ -1615,7 +1600,7 @@ var _28 = function($window, mountRedraw00) {
16151600
setPath(fallbackRoute, null, {replace: true})
16161601
}
16171602
}
1618-
// Set it unconditionally so `m5.route.set` and `m5.route.Link` both work,
1603+
// Set it unconditionally so `m4.route.set` and `m4.route.Link` both work,
16191604
// even if neither `pushState` nor `hashchange` are supported. It's
16201605
// cleared if `hashchange` is2 used, since that makes it automatically
16211606
// async.
@@ -1687,7 +1672,7 @@ var _28 = function($window, mountRedraw00) {
16871672
//
16881673
// We don't strip the other parameters because for convenience we
16891674
// let them be specified in the selector as well.
1690-
var child0 = m5(
1675+
var child0 = m4(
16911676
vnode6.attrs.selector || "a",
16921677
censor(vnode6.attrs, ["options", "params", "selector", "onclick"]),
16931678
vnode6.children
@@ -1727,13 +1712,13 @@ var _28 = function($window, mountRedraw00) {
17271712
// would expect. There's a lot more valid ways to click a
17281713
// link than this, and one might want to not simply click a
17291714
// link, but right click or command-click it to copy the
1730-
// link target2, etc. Nope, this isn't just for blind people.
1715+
// link target1, etc. Nope, this isn't just for blind people.
17311716
if (
17321717
// Skip if `onclick` prevented default
17331718
result1 !== false && !e.defaultPrevented &&
17341719
// Ignore everything but left clicks
17351720
(e.button === 0 || e.which === 0 || e.which === 1) &&
1736-
// Let the browser handle `target2=_blank`, etc.
1721+
// Let the browser handle `target1=_blank`, etc.
17371722
(!e.currentTarget.target || e.currentTarget.target === "_self") &&
17381723
// No modifier keys
17391724
!e.ctrlKey && !e.metaKey && !e.shiftKey && !e.altKey
@@ -1747,12 +1732,12 @@ var _28 = function($window, mountRedraw00) {
17471732
return child0
17481733
},
17491734
}
1750-
route.param = function(key4) {
1751-
return attrs3 && key4 != null ? attrs3[key4] : attrs3
1735+
route.param = function(key3) {
1736+
return attrs3 && key3 != null ? attrs3[key3] : attrs3
17521737
}
17531738
return route
17541739
}
1755-
m.route = _28(typeof window !== "undefined" ? window : null, mountRedraw)
1740+
m.route = _26(typeof window !== "undefined" ? window : null, mountRedraw)
17561741
m.render = render
17571742
m.redraw = mountRedraw.redraw
17581743
m.request = request.request

mithril.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mithril",
3-
"version": "2.2.8",
3+
"version": "2.2.9",
44
"description": "A framework for building brilliant applications",
55
"author": "Leo Horie",
66
"license": "MIT",

0 commit comments

Comments
 (0)