diff --git a/.deploy.enc b/.deploy.enc
index b22144e3..178d80b2 100644
Binary files a/.deploy.enc and b/.deploy.enc differ
diff --git a/.eslintignore b/.eslintignore
index 0711ad31..62117a94 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -3,8 +3,5 @@ coverage/
docs/lib/
examples/
/mithril.js
-/mithril.mjs
/mithril.min.js
-/mithril.min.mjs
-/stream/stream.mjs
node_modules/
diff --git a/.gitattributes b/.gitattributes
index 91f1f822..7296866f 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,7 +1,5 @@
* text=auto
/mithril.js binary
/mithril.min.js binary
-/mithril.mjs binary
-/mithril.min.mjs binary
/package-lock.json binary
/yarn.lock binary
diff --git a/.travis.yml b/.travis.yml
index dbfc11a5..97971661 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -21,8 +21,6 @@ before_script:
- npm run build-browser
# Pass -save so it'll update the readme as well
- npm run build-min -- -save
-# must run after build-min in order to generate min.mjs
-- npm run build-esm
# Run tests, lint, and then check for perf regressions
script:
@@ -34,8 +32,8 @@ after_success:
- |
# Set up SSH environment
$(npm bin)/set-up-ssh \
- --key "$encrypted_8b86e0359d64_key" \
- --iv "$encrypted_8b86e0359d64_iv" \
+ --key "$encrypted_016049456622_key" \
+ --iv "$encrypted_016049456622_iv" \
--path-encrypted-key "./.deploy.enc"
# Commit bundle changes generated in before_script step
@@ -75,20 +73,18 @@ after_success:
env:
global:
# Set up GH_USER_EMAIL & GH_USER_NAME env variables used by travis-scripts package
- - secure: Xvqvm3+PvJu/rs3jl/NNn0RWLkkLkIoPHiL0GCfVRaywgjCYVN02g54NVvIDaOfybqPmu9E6PJFVs92vhF34NMFQHf4EWskynusIGV271R2BV0i+OJBfLMuLgiwm6zRn7/Zw4JvWIUGEwcnlz0qxbqdHsS0SOR3fIkFzePickW0=
- - secure: Rf/ldEO9d4vItJhe6EmqWpFAyCARzoCb422nHnjr1hYJknnwIXpgyZ1C/7On/9o7rWPPf+8WcHC/rgjK2rthKCldzdG5I60LfWSNzap9lk3Aa4TpSCoDBuEp7JVvDr5tc3rKnBXVT71hOay7RSx1StWzXiJs9mjaeVMJzYzRT78=
+ - secure: UdSk2uKTL56iOHkIZP9Tpj/OI8w26DRTs6INRq+peZKkHq8NVC0TmbtbpRoc5kxErovN2hyqsAnoMtXSQHKK+H9mpMx0v4ck/I+o2oEny/1hwi5YQ/Q0nAebVhZkgA3eVhJY1brK0bOlr8uI07m9mcPs3Qz0ramZutJQG7FdnZs=
# Deploy to npm and github pages on tagged commits that successfully build
deploy:
- provider: releases
api_key:
- secure: PauFuz+pn7oRpHn2JTl4k3+iWjOofyBYBvavPQVNdXgKws9mGj0i2n5k2oIDU09VD7NeyEkwP6tdLCUFNaR8uwTJH/TBXMZE95oxUEaliFreA0nOiI3WkG4NCW0GwUoIIn1yL14y6+9oEBinWUia8DIn9kZNS11DNDgQpIPnoQQ=
+ secure: BBlVwr3CRWS6Zmc8nsYMMN59P95g/lg9OzNCsP7uiFyu7mnC6VdOIgwmmJXBviUiEymbcdepgRqEdjHIoemg2YhM5IOnhMoYFrfMBoWUpMihpejFY8EVm3NrTh0prXgCHbp/3OktoKdOn/Zhc2z7cKDMeToHzaDStLtQPR8u9jU=
file:
- "mithril.js"
- "mithril.min.js"
- - "mithril.mjs"
- - "mithril.min.mjs"
skip_cleanup: true
+ draft: true
on:
tags: true
repo: MithrilJS/mithril.js
diff --git a/README.md b/README.md
index 1cc98724..5088ce20 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ mithril.js [](https://ww
## What is Mithril?
-A modern client-side Javascript framework for building Single Page Applications. It's small (8.88 KB gzipped), fast and provides routing and XHR utilities out of the box.
+A modern client-side Javascript framework for building Single Page Applications. It's small (9.31 KB gzipped), fast and provides routing and XHR utilities out of the box.
Mithril is used by companies like Vimeo and Nike, and open source platforms like Lichess ๐.
@@ -29,9 +29,9 @@ Mithril supports IE11, Firefox ESR, and the last two versions of Firefox, Edge,
### CDN
```html
-
+
-
+
```
### npm
diff --git a/api/router.js b/api/router.js
index 4d893acc..a053bac2 100644
--- a/api/router.js
+++ b/api/router.js
@@ -23,7 +23,7 @@ module.exports = function($window, redrawService) {
if (path !== defaultRoute) routeService.setPath(defaultRoute, null, {replace: true})
else throw new Error("Could not resolve default route " + defaultRoute)
}
- routeService.defineRoutes(routes, function(payload, params, path) {
+ routeService.defineRoutes(routes, function(payload, params, path, route) {
var update = lastUpdate = function(routeResolver, comp) {
if (update !== lastUpdate) return
component = comp != null && (typeof comp.view === "function" || typeof comp === "function")? comp : "div"
@@ -34,13 +34,13 @@ module.exports = function($window, redrawService) {
if (payload.view || typeof payload === "function") update({}, payload)
else {
if (payload.onmatch) {
- Promise.resolve(payload.onmatch(params, path)).then(function(resolved) {
+ Promise.resolve(payload.onmatch(params, path, route)).then(function(resolved) {
update(payload, resolved)
- }, bail)
+ }, function () { bail(path) })
}
else update(payload, "div")
}
- }, bail)
+ }, bail, defaultRoute)
}
route.set = function(path, data, options) {
if (lastUpdate != null) {
diff --git a/api/tests/test-router.js b/api/tests/test-router.js
index f5336625..cf99e4c6 100644
--- a/api/tests/test-router.js
+++ b/api/tests/test-router.js
@@ -321,11 +321,12 @@ o.spec("route", function() {
}
var resolver = {
- onmatch: function(args, requestedPath) {
+ onmatch: function(args, requestedPath, route) {
matchCount++
o(args.id).equals("abc")
o(requestedPath).equals("/abc")
+ o(route).equals("/:id")
o(this).equals(resolver)
return Component
},
@@ -362,11 +363,12 @@ o.spec("route", function() {
}
var resolver = {
- onmatch: function(args, requestedPath) {
+ onmatch: function(args, requestedPath, route) {
matchCount++
o(args.id).equals("abc")
o(requestedPath).equals("/abc")
+ o(route).equals("/:id")
o(this).equals(resolver)
return Promise.resolve(Component)
},
@@ -398,11 +400,12 @@ o.spec("route", function() {
var renderCount = 0
var resolver = {
- onmatch: function(args, requestedPath) {
+ onmatch: function(args, requestedPath, route) {
matchCount++
o(args.id).equals("abc")
o(requestedPath).equals("/abc")
+ o(route).equals("/:id")
o(this).equals(resolver)
return Promise.resolve()
},
@@ -434,11 +437,12 @@ o.spec("route", function() {
var renderCount = 0
var resolver = {
- onmatch: function(args, requestedPath) {
+ onmatch: function(args, requestedPath, route) {
matchCount++
o(args.id).equals("abc")
o(requestedPath).equals("/abc")
+ o(route).equals("/:id")
o(this).equals(resolver)
return Promise.resolve([])
},
@@ -508,11 +512,12 @@ o.spec("route", function() {
$window.location.href = prefix + "/abc"
route(root, "/abc", {
"/:id" : {
- onmatch: function(args, requestedPath) {
+ onmatch: function(args, requestedPath, route) {
matchCount++
o(args.id).equals("abc")
o(requestedPath).equals("/abc")
+ o(route).equals("/:id")
return Component
},
@@ -985,7 +990,8 @@ o.spec("route", function() {
$window.location.href = prefix + "/a"
route(root, "/", {
"/a": {view: view},
- "/b": {onmatch: onmatch}
+ "/b": {onmatch: onmatch},
+ "/": {view: function() {}}
})
o(view.callCount).equals(1)
diff --git a/docs/animation.md b/docs/animation.md
index 95dd4c0c..1f7b0b92 100644
--- a/docs/animation.md
+++ b/docs/animation.md
@@ -9,7 +9,7 @@
### Technology choices
-Animations are often used to make applications come alive. Nowadays, browsers have good support for CSS animations, and there are [various](https://greensock.com/gsap) [libraries](http://velocityjs.org/) that provide fast Javascript-based animations. There's also an upcoming [Web API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API/Using_the_Web_Animations_API) and a [polyfill](https://github.com/web-animations/web-animations-js) if you like living on the bleeding edge.
+Animations are often used to make applications come alive. Nowadays, browsers have good support for CSS animations, and there are [various](https://greensock.com/gsap) [libraries](http://velocityjs.org/) that provide fast JavaScript-based animations. There's also an upcoming [Web API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API/Using_the_Web_Animations_API) and a [polyfill](https://github.com/web-animations/web-animations-js) if you like living on the bleeding edge.
Mithril does not provide any animation APIs per se, since these other options are more than sufficient to achieve rich, complex animations. Mithril does, however, offer hooks to make life easier in some specific cases where it's traditionally difficult to make animations work.
diff --git a/docs/buildPathname.md b/docs/buildPathname.md
new file mode 100644
index 00000000..35049a4c
--- /dev/null
+++ b/docs/buildPathname.md
@@ -0,0 +1,41 @@
+# buildPathname(object)
+
+- [Description](#description)
+- [Signature](#signature)
+- [How it works](#how-it-works)
+
+---
+
+### Description
+
+Turns a [path template](paths.md) and a parameters object into a string of form `/path/user?a=1&b=2`
+
+```javascript
+var querystring = m.buildPathname("/path/:id", {id: "user", a: "1", b: "2"})
+// "/path/user?a=1&b=2"
+```
+
+---
+
+### Signature
+
+`querystring = m.buildPathname(object)`
+
+Argument | Type | Required | Description
+------------ | ------------------------------------------ | -------- | ---
+`object` | `Object` | Yes | A key-value map to be converted into a string
+**returns** | `String` | | A string representing the input object
+
+[How to read signatures](signatures.md)
+
+---
+
+### How it works
+
+The `m.buildPathname` creates a [path name](paths.md) from a path template and a parameters object. It's useful for building URLs, and it's what [`m.route`](route.md), [`m.request`](request.md), and [`m.jsonp`](jsonp.md) all use internally to interpolate paths. It uses [`m.buildQueryString`](buildQueryString.md) to generate the query parameters to append to the path name.
+
+```javascript
+var querystring = m.buildPathname("/path/:id", {id: "user", a: 1, b: 2})
+
+// querystring is "/path/user?a=1&b=2"
+```
diff --git a/docs/change-log.md b/docs/change-log.md
index 380fd761..c0bb1199 100644
--- a/docs/change-log.md
+++ b/docs/change-log.md
@@ -10,11 +10,15 @@
- [v1.1.0](#v110)
- [v1.0.1](#v101)
- [Migrating from v0.2.x](#migrating-from-v02x)
-- [Older docs](http://mithril.js.org/archive/v0.2.5/index.html)
-- [ospec change-log](../ospec/change-log.md)
+- [v1.x docs](http://mithril.js.org/archive/v1.1.6/index.html)
+- [v0.2 docs](http://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)
---
+### Upcoming...
+
### v2.0.0-rc
#### Breaking changes
@@ -27,13 +31,15 @@
- hyperscript: when attributes have a `null` or `undefined` value, they are treated as if they were absent. [#1773](https://github.com/MithrilJS/mithril.js/issues/1773) ([#2174](https://github.com/MithrilJS/mithril.js/pull/2174))
- API: `m.request` errors no longer copy response fields to the error, but instead assign the parsed JSON response to `error.response` and the HTTP status code `error.code`.
- hyperscript: when an attribute is defined on both the first and second argument (as a CSS selector and an `attrs` field, respectively), the latter takes precedence, except for `class` attributes that are still added together. [#2172](https://github.com/MithrilJS/mithril.js/issues/2172) ([#2174](https://github.com/MithrilJS/mithril.js/pull/2174))
-- stream: when a stream conditionally returns HALT, dependant stream will also end ([#2200](https://github.com/MithrilJS/mithril.js/pull/2200))
-- render: remove some redundancy within the component initialization code ([#2213](https://github.com/MithrilJS/mithril.js/pull/2213))
- render: Align custom elements to work like normal elements, minus all the HTML-specific magic. ([#2221](https://github.com/MithrilJS/mithril.js/pull/2221))
-- render: simplify component removal ([#2214](https://github.com/MithrilJS/mithril.js/pull/2214))
- cast className using toString ([#2309](https://github.com/MithrilJS/mithril.js/pull/2309))
- render: call attrs' hooks first, with express exception of `onbeforeupdate` to allow attrs to block components from even diffing ([#2297](https://github.com/MithrilJS/mithril.js/pull/2297))
- API: `m.withAttr` removed. ([#2317](https://github.com/MithrilJS/mithril.js/pull/2317))
+- request: `data` has now been split to `params` and `body` and `useBody` has been removed in favor of just using `body`. ([#2361](https://github.com/MithrilJS/mithril.js/pull/2361))
+- route, request: Interpolated arguments are URL-escaped (and for declared routes, URL-unescaped) automatically. If you want to use a raw route parameter, use a variadic parameter like in `/asset/:path.../view`. This was previously only available in `m.route` route definitions, but it's now usable in both that and where paths are accepted. ([#2361](https://github.com/MithrilJS/mithril.js/pull/2361))
+- route, request: Interpolated arguments are *not* appended to the query string. This means `m.request({url: "/api/user/:id/get", params: {id: user.id}})` would result in a request like `GET /api/user/1/get`, not one like `GET /api/user/1/get?id=1`. If you really need it in both places, pass the same value via two separate parameters with the non-query-string parameter renamed, like in `m.request({url: "/api/user/:urlID/get", params: {id: user.id, urlID: user.id}})`. ([#2361](https://github.com/MithrilJS/mithril.js/pull/2361))
+- route, request: `m.route.set`, `m.request`, and `m.jsonp` all use the same path template syntax now, and vary only in how they receive their parameters. Furthermore, declared routes in `m.route` shares the same syntax and semantics, but acts in reverse as if via pattern matching. ([#2361](https://github.com/MithrilJS/mithril.js/pull/2361))
+- request: `options.responseType` now defaults to `"json"` if `extract` is absent, and `deserialize` receives the parsed response, not the raw string. If you want the old behavior, [use `responseType: "text"`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType). ([#2335](https://github.com/MithrilJS/mithril.js/pull/2335))
#### News
@@ -49,12 +55,15 @@
- render/core: remove the DOM nodes recycling pool ([#2122](https://github.com/MithrilJS/mithril.js/pull/2122))
- render/core: revamp the core diff engine, and introduce a longest-increasing-subsequence-based logic to minimize DOM operations when re-ordering keyed nodes.
- docs: Emphasize Closure Components for stateful components, use them for all stateful component examples.
-- stream: Add `stream.lift` as a user-friendly alternative to `merge -> map` or `combine` [#1944](https://github.com/MithrilJS/mithril.js/issues/1944)
- API: ES module bundles are now available for `mithril` and `mithril/stream` ([#2194](https://github.com/MithrilJS/mithril.js/pull/2194) [@porsager](https://github.com/porsager)).
- All of the `m.*` properties from `mithril` are re-exported as named exports in addition to being attached to `m`.
- `m()` itself from `mithril` is exported as the default export.
- `mithril/stream`'s primary export is exported as the default export.
- fragments: allow same attrs/children overloading logic as hyperscript ([#2328](https://github.com/MithrilJS/mithril.js/pull/2328))
+- route: Declared routes may check against path names with query strings. ([#2361](https://github.com/MithrilJS/mithril.js/pull/2361))
+- route: Declared routes in `m.route` now support `-` and `.` as delimiters for path segments. This means you can have a route like `"/edit/:file.:ext"`. ([#2361](https://github.com/MithrilJS/mithril.js/pull/2361))
+ - Previously, this was possible to do in `m.route.set`, `m.request`, and `m.jsonp`, but it was wholly untested for and also undocumented.
+- API: `m.buildPathname` and `m.parsePathname` added. ([#2361](https://github.com/MithrilJS/mithril.js/pull/2361))
#### Bug fixes
@@ -75,6 +84,12 @@
- render/core: Vnodes stored in the dom node supplied to `m.render()` are now normalized [#2266](https://github.com/MithrilJS/mithril.js/pull/2266)
- render/core: CSS vars can now be specified in `{style}` attributes ([#2192](https://github.com/MithrilJS/mithril.js/pull/2192) [@barneycarroll](https://github.com/barneycarroll)), ([#2311](https://github.com/MithrilJS/mithril.js/pull/2311) [@porsager](https://github.com/porsager)), ([#2312](https://github.com/MithrilJS/mithril.js/pull/2312) [@isiahmeadows](https://github.com/isiahmeadows))
- request: don't modify params, call `extract`/`serialize`/`deserialize` with correct `this` value ([#2288](https://github.com/MithrilJS/mithril.js/pull/2288))
+- render: simplify component removal ([#2214](https://github.com/MithrilJS/mithril.js/pull/2214))
+- render: remove some redundancy within the component initialization code ([#2213](https://github.com/MithrilJS/mithril.js/pull/2213))
+- API: `mithril` loads `mithril/index.js`, not the bundle, so users of `mithril/hyperscript`, `mithril/render`, and similar see the same Mithril instance as those just using `mithril` itself.
+ - `https://unpkg.com/mithril` is configured to receive the *minified* bundle, not the development bundle.
+ - The raw bundle itself remains accessible at `mithril.js`, and is *not* browser-wrapped.
+ - Note: this *will* increase overhead with bundlers like Webpack, Rollup, and Browserify.
---
diff --git a/docs/components.md b/docs/components.md
index 3dccc5c1..eea61ae7 100644
--- a/docs/components.md
+++ b/docs/components.md
@@ -14,7 +14,7 @@
Components are a mechanism to encapsulate parts of a view to make code easier to organize and/or reuse.
-Any Javascript object that has a `view` method is a Mithril component. Components can be consumed via the [`m()`](hyperscript.md) utility:
+Any JavaScript object that has a `view` method is a Mithril component. Components can be consumed via the [`m()`](hyperscript.md) utility:
```javascript
// define your component
@@ -117,7 +117,7 @@ If a state change occurs that is not as a result of any of the above conditions
#### Closure Component State
-In the above examples, each component is defined as a POJO (Plain Old Javascript Object), which is used by Mithril internally as the prototype for that component's instances. It's possible to use component state with a POJO (as we'll discuss below), but it's not the cleanest or simplest approach. For that we'll use a **_closure component_**, which is simply a wrapper function which _returns_ a POJO component instance, which in turn carries its own, closed-over scope.
+In the above examples, each component is defined as a POJO (Plain Old JavaScript Object), which is used by Mithril internally as the prototype for that component's instances. It's possible to use component state with a POJO (as we'll discuss below), but it's not the cleanest or simplest approach. For that we'll use a **_closure component_**, which is simply a wrapper function which _returns_ a POJO component instance, which in turn carries its own, closed-over scope.
With a closure component, state can simply be maintained by variables that are declared within the outer function:
@@ -247,7 +247,7 @@ m(ComponentUsingThis, {text: "Hello"})
//
Hello
```
-Be aware that when using ES5 functions, the value of `this` in nested anonymous functions is not the component instance. There are two recommended ways to get around this Javascript limitation, use ES6 arrow functions, or if ES6 is not available, use `vnode.state`.
+Be aware that when using ES5 functions, the value of `this` in nested anonymous functions is not the component instance. There are two recommended ways to get around this JavaScript limitation, use ES6 arrow functions, or if ES6 is not available, use `vnode.state`.
---
diff --git a/docs/contributing.md b/docs/contributing.md
index 8489707f..e656984f 100644
--- a/docs/contributing.md
+++ b/docs/contributing.md
@@ -114,9 +114,9 @@ Type checks are generally already irreducible expressions and having micro-modul
## What should I know in advance when attempting a performance related contribution?
-You should be trying to reduce the number of DOM operations or reduce algorithmic complexity in a hot spot. Anything else is likely a waste of time. Specifically, micro-optimizations like caching array lengths, caching object property values and inlining functions won't have any positive impact in modern javascript engines.
+You should be trying to reduce the number of DOM operations or reduce algorithmic complexity in a hot spot. Anything else is likely a waste of time. Specifically, micro-optimizations like caching array lengths, caching object property values and inlining functions won't have any positive impact in modern JavaScript engines.
-Keep object properties consistent (i.e. ensure the data objects always have the same properties and that properties are always in the same order) to allow the engine to keep using JIT'ed structs instead of hashmaps. Always place null checks first in compound type checking expressions to allow the Javascript engine to optimize to type-specific code paths. Prefer for loops over Array methods and try to pull conditionals out of loops if possible.
+Keep object properties consistent (i.e. ensure the data objects always have the same properties and that properties are always in the same order) to allow the engine to keep using JIT'ed structs instead of hashmaps. Always place null checks first in compound type checking expressions to allow the JavaScript engine to optimize to type-specific code paths. Prefer for loops over Array methods and try to pull conditionals out of loops if possible.
diff --git a/docs/es6.md b/docs/es6.md
index 0192a6ca..75b9fdf7 100644
--- a/docs/es6.md
+++ b/docs/es6.md
@@ -5,7 +5,7 @@
---
-Mithril is written in ES5, and is fully compatible with ES6 as well. ES6 is a recent update to Javascript that introduces new syntax sugar for various common cases. It's not yet fully supported by all major browsers and it's not a requirement for writing an application, but it may be pleasing to use depending on your team's preferences.
+Mithril is written in ES5, and is fully compatible with ES6 as well. ES6 is a recent update to JavaScript that introduces new syntax sugar for various common cases. It's not yet fully supported by all major browsers and it's not a requirement for writing an application, but it may be pleasing to use depending on your team's preferences.
In some limited environments, it's possible to use a significant subset of ES6 directly without extra tooling (for example, in internal applications that do not support IE). However, for the vast majority of use cases, a compiler toolchain like [Babel](https://babeljs.io) is required to compile ES6 features down to ES5.
diff --git a/docs/fragment.md b/docs/fragment.md
index 5a914165..f6269d07 100644
--- a/docs/fragment.md
+++ b/docs/fragment.md
@@ -67,6 +67,6 @@ m("ul",
)
```
-However, Javascript arrays cannot be keyed or hold lifecycle methods. One option would be to create a wrapper element to host the key or lifecycle method, but sometimes it is not desirable to have an extra element (for example in complex table structures). In those cases, a fragment vnode can be used instead.
+However, JavaScript arrays cannot be keyed or hold lifecycle methods. One option would be to create a wrapper element to host the key or lifecycle method, but sometimes it is not desirable to have an extra element (for example in complex table structures). In those cases, a fragment vnode can be used instead.
There are a few benefits that come from using `m.fragment` instead of handwriting a vnode object structure: m.fragment creates [monomorphic objects](vnodes.md#monomorphic-class), which have better performance characteristics than creating objects dynamically. In addition, using `m.fragment` makes your intentions clear to other developers, and it makes it less likely that you'll mistakenly set attributes on the vnode object itself rather than on its `attrs` map.
diff --git a/docs/framework-comparison.md b/docs/framework-comparison.md
index 0969b2c9..73bd96b0 100644
--- a/docs/framework-comparison.md
+++ b/docs/framework-comparison.md
@@ -38,7 +38,7 @@ React and Mithril share a lot of similarities. If you already learned React, you
- They both use virtual DOM, lifecycle methods and key-based reconciliation
- They both organize views via components
-- They both use Javascript as a flow control mechanism within views
+- They both use JavaScript as a flow control mechanism within views
The most obvious difference between React and Mithril is in their scope. React is a view library, so a typical React-based application relies on third-party libraries for routing, XHR and state management. Using a library oriented approach allows developers to customize their stack to precisely match their needs. The not-so-nice way of saying that is that React-based architectures can vary wildly from project to project, and that those projects are that much more likely to cross the 1MB size line.
@@ -50,7 +50,7 @@ Both React and Mithril care strongly about rendering performance, but go about i
Mithril follows the less-is-more school of thought. It has a substantially smaller, aggressively optimized codebase. The rationale is that a small codebase is easier to audit and optimize, and ultimately results in less code being run.
-Here's a comparison of library load times, i.e. the time it takes to parse and run the Javascript code for each framework, by adding a `console.time()` call on the first line and a `console.timeEnd()` call on the last of a script that is composed solely of framework code. For your reading convenience, here are best-of-20 results with logging code manually added to bundled scripts, running from the filesystem, in Chrome on a modest 2010 PC desktop:
+Here's a comparison of library load times, i.e. the time it takes to parse and run the JavaScript code for each framework, by adding a `console.time()` call on the first line and a `console.timeEnd()` call on the last of a script that is composed solely of framework code. For your reading convenience, here are best-of-20 results with logging code manually added to bundled scripts, running from the filesystem, in Chrome on a modest 2010 PC desktop:
React | Mithril
------- | -------
@@ -74,7 +74,7 @@ What these numbers show is that not only does Mithril initializes significantly
Update performance can be even more important than first-render performance, since updates can happen many times while a Single Page Application is running.
-A useful tool to benchmark update performance is a tool developed by the Ember team called DbMonster. It updates a table as fast as it can and measures frames per second (FPS) and Javascript times (min, max and mean). The FPS count can be difficult to evaluate since it also includes browser repaint times and `setTimeout` clamping delay, so the most meaningful number to look at is the mean render time. You can compare a [React implementation](http://cdn.rawgit.com/MithrilJS/mithril.js/master/examples/dbmonster/react/index.html) and a [Mithril implementation](http://cdn.rawgit.com/MithrilJS/mithril.js/master/examples/dbmonster/mithril/index.html). Sample results are shown below:
+A useful tool to benchmark update performance is a tool developed by the Ember team called DbMonster. It updates a table as fast as it can and measures frames per second (FPS) and JavaScript times (min, max and mean). The FPS count can be difficult to evaluate since it also includes browser repaint times and `setTimeout` clamping delay, so the most meaningful number to look at is the mean render time. You can compare a [React implementation](http://cdn.rawgit.com/MithrilJS/mithril.js/master/examples/dbmonster/react/index.html) and a [Mithril implementation](http://cdn.rawgit.com/MithrilJS/mithril.js/master/examples/dbmonster/mithril/index.html). Sample results are shown below:
React | Mithril
------- | -------
@@ -125,7 +125,7 @@ Angular and Mithril are fairly different, but they share a few similarities:
- Both support componentization
- Both have an array of tools for various aspects of web applications (e.g. routing, XHR)
-The most obvious difference between Angular and Mithril is in their complexity. This can be seen most easily in how views are implemented. Mithril views are plain Javascript, and flow control is done with Javascript built-in mechanisms such as ternary operators or `Array.prototype.map`. Angular, on the other hand, implements a directive system to extend HTML views so that it's possible to evaluate Javascript-like expressions within HTML attributes and interpolations. Angular actually ships with a parser and a compiler written in Javascript to achieve that. If that doesn't seem complex enough, there's actually two compilation modes (a default mode that generates Javascript functions dynamically for performance, and [a slower mode](https://docs.angularjs.org/api/ng/directive/ngCsp) for dealing with Content Security Policy restrictions).
+The most obvious difference between Angular and Mithril is in their complexity. This can be seen most easily in how views are implemented. Mithril views are plain JavaScript, and flow control is done with JavaScript built-in mechanisms such as ternary operators or `Array.prototype.map`. Angular, on the other hand, implements a directive system to extend HTML views so that it's possible to evaluate JavaScript-like expressions within HTML attributes and interpolations. Angular actually ships with a parser and a compiler written in JavaScript to achieve that. If that doesn't seem complex enough, there's actually two compilation modes (a default mode that generates JavaScript functions dynamically for performance, and [a slower mode](https://docs.angularjs.org/api/ng/directive/ngCsp) for dealing with Content Security Policy restrictions).
#### Performance
@@ -139,7 +139,7 @@ Also, remember that frameworks like Angular and Mithril are designed for non-tri
##### Update performance
-A useful tool to benchmark update performance is a tool developed by the Ember team called DbMonster. It updates a table as fast as it can and measures frames per second (FPS) and Javascript times (min, max and mean). The FPS count can be difficult to evaluate since it also includes browser repaint times and `setTimeout` clamping delay, so the most meaningful number to look at is the mean render time. You can compare an [Angular implementation](http://cdn.rawgit.com/MithrilJS/mithril.js/master/examples/dbmonster/angular/index.html) and a [Mithril implementation](http://cdn.rawgit.com/MithrilJS/mithril.js/master/examples/dbmonster/mithril/index.html). Both implementations are naive (i.e. no optimizations). Sample results are shown below:
+A useful tool to benchmark update performance is a tool developed by the Ember team called DbMonster. It updates a table as fast as it can and measures frames per second (FPS) and JavaScript times (min, max and mean). The FPS count can be difficult to evaluate since it also includes browser repaint times and `setTimeout` clamping delay, so the most meaningful number to look at is the mean render time. You can compare an [Angular implementation](http://cdn.rawgit.com/MithrilJS/mithril.js/master/examples/dbmonster/angular/index.html) and a [Mithril implementation](http://cdn.rawgit.com/MithrilJS/mithril.js/master/examples/dbmonster/mithril/index.html). Both implementations are naive (i.e. no optimizations). Sample results are shown below:
Angular | Mithril
------- | -------
@@ -155,7 +155,7 @@ Angular 2 has a lot more concepts to understand: on the language level, Typescri
If we compare apples to apples, Angular 2 and Mithril have similar learning curves: in both, components are a central aspect of architecture, and both have reasonable routing and XHR tools.
-With that being said, Angular has a lot more concepts to learn than Mithril. It offers Angular-specific APIs for many things that often can be trivially implemented (e.g. pluralization is essentially a switch statement, "required" validation is simply an equality check, etc). Angular templates also have several layers of abstractions to emulate what Javascript does natively in Mithril - Angular's `ng-if`/`ngIf` is a *directive*, which uses a custom *parser* and *compiler* to evaluate an expression string and emulate lexical scoping... and so on. Mithril tends to be a lot more transparent, and therefore easier to reason about.
+With that being said, Angular has a lot more concepts to learn than Mithril. It offers Angular-specific APIs for many things that often can be trivially implemented (e.g. pluralization is essentially a switch statement, "required" validation is simply an equality check, etc). Angular templates also have several layers of abstractions to emulate what JavaScript does natively in Mithril - Angular's `ng-if`/`ngIf` is a *directive*, which uses a custom *parser* and *compiler* to evaluate an expression string and emulate lexical scoping... and so on. Mithril tends to be a lot more transparent, and therefore easier to reason about.
#### Documentation
@@ -183,7 +183,7 @@ Vue is significantly smaller than Angular when comparing apples to apples, but n
#### Performance
-Here's a comparison of library load times, i.e. the time it takes to parse and run the Javascript code for each framework, by adding a `console.time()` call on the first line and a `console.timeEnd()` call on the last of a script that is composed solely of framework code. For your reading convenience, here are best-of-20 results with logging code manually added to bundled scripts, running from the filesystem, in Chrome on a modest 2010 PC desktop:
+Here's a comparison of library load times, i.e. the time it takes to parse and run the JavaScript code for each framework, by adding a `console.time()` call on the first line and a `console.timeEnd()` call on the last of a script that is composed solely of framework code. For your reading convenience, here are best-of-20 results with logging code manually added to bundled scripts, running from the filesystem, in Chrome on a modest 2010 PC desktop:
Vue | Mithril
------- | -------
@@ -193,7 +193,7 @@ Library load times matter in applications that don't stay open for long periods
##### Update performance
-A useful tool to benchmark update performance is a tool developed by the Ember team called DbMonster. It updates a table as fast as it can and measures frames per second (FPS) and Javascript times (min, max and mean). The FPS count can be difficult to evaluate since it also includes browser repaint times and `setTimeout` clamping delay, so the most meaningful number to look at is the mean render time. You can compare a [Vue implementation](http://cdn.rawgit.com/MithrilJS/mithril.js/master/examples/dbmonster/vue/index.html) and a [Mithril implementation](http://cdn.rawgit.com/MithrilJS/mithril.js/master/examples/dbmonster/mithril/index.html). Both implementations are naive (i.e. no optimizations). Sample results are shown below:
+A useful tool to benchmark update performance is a tool developed by the Ember team called DbMonster. It updates a table as fast as it can and measures frames per second (FPS) and JavaScript times (min, max and mean). The FPS count can be difficult to evaluate since it also includes browser repaint times and `setTimeout` clamping delay, so the most meaningful number to look at is the mean render time. You can compare a [Vue implementation](http://cdn.rawgit.com/MithrilJS/mithril.js/master/examples/dbmonster/vue/index.html) and a [Mithril implementation](http://cdn.rawgit.com/MithrilJS/mithril.js/master/examples/dbmonster/mithril/index.html). Both implementations are naive (i.e. no optimizations). Sample results are shown below:
Vue | Mithril
------ | -------
@@ -203,7 +203,7 @@ Vue | Mithril
Vue is heavily inspired by Angular and has many things that Angular does (e.g. directives, filters, bi-directional bindings, `v-cloak`), but also has things inspired by React (e.g. components). As of Vue 2.0, it's also possible to write templates using hyperscript/JSX syntax (in addition to single-file components and the various webpack-based language transpilation plugins). Vue provides both bi-directional data binding and an optional Redux-like state management library, but unlike Angular, it provides no style guide. The many-ways-of-doing-one-thing approach can cause architectural fragmentation in long-lived projects.
-Mithril has far less concepts and typically organizes applications in terms of components and a data layer. All component creation styles in Mithril output the same vnode structure using native Javascript features only. The direct consequence of leaning on the language is less tooling and a simpler project setup.
+Mithril has far less concepts and typically organizes applications in terms of components and a data layer. All component creation styles in Mithril output the same vnode structure using native JavaScript features only. The direct consequence of leaning on the language is less tooling and a simpler project setup.
#### Documentation
diff --git a/docs/hyperscript.md b/docs/hyperscript.md
index 4adb8516..bd718b1c 100644
--- a/docs/hyperscript.md
+++ b/docs/hyperscript.md
@@ -55,7 +55,7 @@ Argument | Type | Required | Descripti
### How it works
-Mithril provides a hyperscript function `m()`, which allows expressing any HTML structure using javascript syntax. It accepts a `selector` string (required), an `attrs` object (optional) and a `children` array (optional).
+Mithril provides a hyperscript function `m()`, which allows expressing any HTML structure using JavaScript syntax. It accepts a `selector` string (required), an `attrs` object (optional) and a `children` array (optional).
```javascript
m("div", {id: "box"}, "hello")
@@ -64,7 +64,7 @@ m("div", {id: "box"}, "hello")
// hello
```
-The `m()` function does not actually return a DOM element. Instead it returns a [virtual DOM node](vnodes.md), or *vnode*, which is a javascript object that represents the DOM element to be created.
+The `m()` function does not actually return a DOM element. Instead it returns a [virtual DOM node](vnodes.md), or *vnode*, which is a JavaScript object that represents the DOM element to be created.
```javascript
// a vnode
@@ -167,9 +167,9 @@ If another attribute is present in both the first and the second argument, the s
### DOM attributes
-Mithril uses both the Javascript API and the DOM API (`setAttribute`) to resolve attributes. This means you can use both syntaxes to refer to attributes.
+Mithril uses both the JavaScript API and the DOM API (`setAttribute`) to resolve attributes. This means you can use both syntaxes to refer to attributes.
-For example, in the Javascript API, the `readonly` attribute is called `element.readOnly` (notice the uppercase). In Mithril, all of the following are supported:
+For example, in the JavaScript API, the `readonly` attribute is called `element.readOnly` (notice the uppercase). In Mithril, all of the following are supported:
```javascript
m("input", {readonly: true}) // lowercase
@@ -322,7 +322,7 @@ m("select", {selectedIndex: 0}, [
[Components](components.md) allow you to encapsulate logic into a unit and use it as if it was an element. They are the base for making large, scalable applications.
-A component is any Javascript object that contains a `view` method. To consume a component, pass the component as the first argument to `m()` instead of passing a CSS selector string. You can pass arguments to the component by defining attributes and children, as shown in the example below.
+A component is any JavaScript object that contains a `view` method. To consume a component, pass the component as the first argument to `m()` instead of passing a CSS selector string. You can pass arguments to the component by defining attributes and children, as shown in the example below.
```javascript
// define a component
@@ -413,7 +413,7 @@ MathML is also fully supported.
### Making templates dynamic
-Since nested vnodes are just plain Javascript expressions, you can simply use Javascript facilities to manipulate them
+Since nested vnodes are just plain JavaScript expressions, you can simply use JavaScript facilities to manipulate them
#### Dynamic text
@@ -454,7 +454,7 @@ var isError = false
m("div", isError ? "An error occurred" : "Saved") // Saved
```
-You cannot use Javascript statements such as `if` or `for` within Javascript expressions. It's preferable to avoid using those statements altogether and instead, use the constructs above exclusively in order to keep the structure of the templates linear and declarative, and to avoid deoptimizations.
+You cannot use JavaScript statements such as `if` or `for` within JavaScript expressions. It's preferable to avoid using those statements altogether and instead, use the constructs above exclusively in order to keep the structure of the templates linear and declarative, and to avoid deoptimizations.
---
@@ -520,7 +520,7 @@ var BetterLabeledComponent = {
#### Avoid statements in view methods
-Javascript statements often require changing the naturally nested structure of an HTML tree, making the code more verbose and harder to understand. Constructing an virtual DOM tree procedurally can also potentially trigger expensive deoptimizations (such as an entire template being recreated from scratch)
+JavaScript statements often require changing the naturally nested structure of an HTML tree, making the code more verbose and harder to understand. Constructing an virtual DOM tree procedurally can also potentially trigger expensive deoptimizations (such as an entire template being recreated from scratch)
```javascript
// AVOID
@@ -536,7 +536,7 @@ var BadListComponent = {
}
```
-Instead, prefer using Javascript expressions such as the ternary operator and Array methods.
+Instead, prefer using JavaScript expressions such as the ternary operator and Array methods.
```javascript
// PREFER
diff --git a/docs/index.md b/docs/index.md
index 2df235d4..d2ea949e 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -12,7 +12,7 @@
### What is Mithril?
-Mithril is a modern client-side Javascript framework for building Single Page Applications.
+Mithril is a modern client-side JavaScript framework for building Single Page Applications.
It's small (< 8kb gzip), fast and provides routing and XHR utilities out of the box.
@@ -58,7 +58,7 @@ Let's create an HTML file to follow along:
```markup
-
+
+
```
---
@@ -71,7 +71,7 @@ $ npm start
For production-level projects, the recommended way of installing Mithril is to use NPM.
-NPM (Node package manager) is the default package manager that is bundled w/ Node.js. It is widely used as the package manager for both client-side and server-side libraries in the Javascript ecosystem. Download and install [Node.js](https://nodejs.org); NPM will be automatically installed as well.
+NPM (Node package manager) is the default package manager that is bundled w/ Node.js. It is widely used as the package manager for both client-side and server-side libraries in the JavaScript ecosystem. Download and install [Node.js](https://nodejs.org); NPM will be automatically installed as well.
To use Mithril via NPM, go to your project folder, and run `npm init --yes` from the command line. This will create a file called `package.json`.
@@ -99,9 +99,9 @@ m.render(document.body, "hello world")
Modularization is the practice of separating the code into files. Doing so makes it easier to find code, understand what code relies on what code, and test.
-CommonJS is a de-facto standard for modularizing Javascript code, and it's used by Node.js, as well as tools like [Browserify](http://browserify.org/) and [Webpack](https://webpack.js.org/). It's a robust, battle-tested precursor to ES6 modules. Although the syntax for ES6 modules is specified in Ecmascript 6, the actual module loading mechanism is not. If you wish to use ES6 modules despite the non-standardized status of module loading, you can use tools like [Rollup](http://rollupjs.org/), [Babel](https://babeljs.io/) or [Traceur](https://github.com/google/traceur-compiler).
+CommonJS is a de-facto standard for modularizing JavaScript code, and it's used by Node.js, as well as tools like [Browserify](http://browserify.org/) and [Webpack](https://webpack.js.org/). It's a robust, battle-tested precursor to ES6 modules. Although the syntax for ES6 modules is specified in Ecmascript 6, the actual module loading mechanism is not. If you wish to use ES6 modules despite the non-standardized status of module loading, you can use tools like [Rollup](http://rollupjs.org/), [Babel](https://babeljs.io/) or [Traceur](https://github.com/google/traceur-compiler).
-Most browser today do not natively support modularization systems (CommonJS or ES6), so modularized code must be bundled into a single Javascript file before running in a client-side application.
+Most browser today do not natively support modularization systems (CommonJS or ES6), so modularized code must be bundled into a single JavaScript file before running in a client-side application.
A popular way for creating a bundle is to setup an NPM script for [Webpack](https://webpack.js.org/). To install Webpack, run this from the command line:
@@ -247,7 +247,7 @@ If you don't have the ability to run a bundler script due to company security po
Hello world
-
+