diff --git a/docs/CNAME b/docs/CNAME new file mode 100644 index 00000000..5c153480 --- /dev/null +++ b/docs/CNAME @@ -0,0 +1 @@ +mithril.js.org diff --git a/docs/change-log.md b/docs/change-log.md index d0de73bc..5a9b75a3 100644 --- a/docs/change-log.md +++ b/docs/change-log.md @@ -1,7 +1,38 @@ # Change log +- [v1.0.2](#v101) +- [v1.0.1](#v101) - [Migrating from v0.2.x](#migrating-from-v02x) -- [Older docs](http://mithril.js.org/archive/v0.2.5/change-log.html) +- [Older docs](http://mithril.js.org/archive/v0.2.5/index.html) + +--- + +### v1.0.2 + +#### News + +- support for ES6 class components +- updated typescript definitions + +#### Bug fixes + +- fix IE11 input[type] error - [#1610](https://github.com/lhorie/mithril.js/issues/1610) +- apply [#1609](https://github.com/lhorie/mithril.js/issues/1609) to unkeyed children case +- fix abort detection [#1612](https://github.com/lhorie/mithril.js/issues/1612) +- fix input value focus issue when value is loosely equal to old value [#1593](https://github.com/lhorie/mithril.js/issues/1593) + +--- + +### v1.0.1 + +#### News + +- performance improvements in IE [#1598](https://github.com/lhorie/mithril.js/pull/1598) + +#### Bug fixes + +- prevent infinite loop in non-existent default route - [#1579](https://github.com/lhorie/mithril.js/issues/1579) +- call correct lifecycle methods on children of recycled keyed vnodes - [#1609](https://github.com/lhorie/mithril.js/issues/1609) --- @@ -28,6 +59,7 @@ If you are migrating, consider using the [mithril-codemods](https://www.npmjs.co - [`m.route` and anchor tags](#mroute-and-anchor-tags) - [Reading/writing the current route](#readingwriting-the-current-route) - [Accessing route params](#accessing-route-params) +- [Building/Parsing query strings](#buildingparsing-query-strings) - [Preventing unmounting](#preventing-unmounting) - [Run code on component removal](#run-code-on-component-removal) - [`m.request`](#mrequest) @@ -459,6 +491,28 @@ m.route(document.body, "/booga", { --- +## Building/Parsing query strings + +`v0.2.x` used methods hanging off of `m.route`, `m.route.buildQueryString()` and `m.route.parseQueryString()`. In `v1.x` these have been broken out and attached to the root `m`. + +### `v0.2.x` + +```javascript +var qs = m.route.buildQueryString({ a : 1 }); + +var obj = m.route.parseQueryString("a=1"); +``` + +### `v1.x` + +```javascript +var qs = m.buildQueryString({ a : 1 }); + +var obj = m.parseQueryString("a=1"); +``` + +--- + ## Preventing unmounting It is no longer possible to prevent unmounting via `onunload`'s `e.preventDefault()`. Instead you should explicitly call `m.route.set` when the expected conditions are met. @@ -588,11 +642,13 @@ greetAsync() ### `v1.x` ```javascript -var greetAsync = new Promise(function(resolve){ - setTimeout(function() { - resolve("hello") - }, 1000) -}) +var greetAsync = function() { + return new Promise(function(resolve){ + setTimeout(function() { + resolve("hello") + }, 1000) + }) +} greetAsync() .then(function(value) {return value + " world"}) diff --git a/docs/components.md b/docs/components.md index 6134ccc1..c67ea89b 100644 --- a/docs/components.md +++ b/docs/components.md @@ -3,6 +3,7 @@ - [Structure](#structure) - [Lifecycle methods](#lifecycle-methods) - [State](#state) +- [ES6 classes](#es6-classes) - [Avoid-anti-patterns](#avoid-anti-patterns) ### Structure @@ -108,7 +109,7 @@ The state of a component can be accessed three ways: as a blueprint at initializ #### At initialization -Any property attached to the component object is copied for every instance of the component. This allows simple state initialization. +The component object is the prototype of each component instance, so any property defined on the component object will be accessible as a property of `vnode.state`. This allows simple state initialization. In the example below, `data` is a property of the `ComponentWithInitialState` component's state object. @@ -170,6 +171,44 @@ Be aware that when using ES5 functions, the value of `this` in nested anonymous --- +### ES6 classes + +Components can also be written using ES6 class syntax: + +```javascript +class ES6ClassComponent { + view() { + return m("div", "Hello from an ES6 class") + } +} +``` + +They can be consumed in the same way regular components can. + +```javascript +// EXAMPLE: via m.render +m.render(document.body, m(ES6ClassComponent)) + +// EXAMPLE: via m.mount +m.mount(document.body, ES6ClassComponent) + +// EXAMPLE: via m.route +m.route(document.body, "/", { + "/": ES6ClassComponent +}) + +// EXAMPLE: component composition +class AnotherES6ClassComponent { + view() { + return m("main", [ + m(ES6ClassComponent) + ]) + } +} +``` + +--- + ### Avoid anti-patterns Although Mithril is flexible, some code patterns are discouraged: diff --git a/docs/credits.md b/docs/credits.md index 70ee277a..7fd2a048 100644 --- a/docs/credits.md +++ b/docs/credits.md @@ -17,10 +17,10 @@ Special thanks to: - Leon Sorokin, for writing a DOM instrumentation tool that helped improve performance in Mithril 1.0 - Jordan Walke, whose work on React was prior art to the implementation of keys in Mithril - Pierre-Yves Gérardy, who consistently makes high quality contributions +- Gyandeep Singh, who contributed significant IE performance improvements Other people who also deserve recognition: - Arthur Clemens - creator of [Polythene](https://github.com/ArthurClemens/Polythene) and the [HTML-to-Mithril converter](http://arthurclemens.github.io/mithril-template-converter/index.html) - Stephan Hoyer - creator of [mithril-node-render](https://github.com/StephanHoyer/mithril-node-render), [mithril-query](https://github.com/StephanHoyer/mithril-query) and [mithril-source-hint](https://github.com/StephanHoyer/mithril-source-hint) - the countless people who have reported and fixed bugs, participated in discussions, and helped promote Mithril - diff --git a/docs/fragment.md b/docs/fragment.md index b0d9ec43..d3bddc7a 100644 --- a/docs/fragment.md +++ b/docs/fragment.md @@ -35,11 +35,11 @@ Generates a fragment [vnode](vnodes.md) `vnode = m.fragment(attrs, children)` -Argument | Type | Required | Description ------------ | ------------------------------------ | -------- | --- -`attrs` | `Object` | Yes | A map of attributes -`children` | `Array|String|Number|Boolean` | Yes | A list of vnodes -**returns** | `Vnode` | | A fragment [vnode](vnodes.md) +Argument | Type | Required | Description +----------- | --------------------------------------------------- | -------- | --- +`attrs` | `Object` | Yes | A map of attributes +`children` | `Array` | Yes | A list of vnodes +**returns** | `Vnode` | | A fragment [vnode](vnodes.md) [How to read signatures](signatures.md) diff --git a/docs/framework-comparison.md b/docs/framework-comparison.md index 92573f40..4e4bd7f5 100644 --- a/docs/framework-comparison.md +++ b/docs/framework-comparison.md @@ -22,7 +22,7 @@ However, if you're starting something new, do consider giving Mithril a try, if ## Why use Mithril? -In one sentence: because **Mithril is pragmatic**. The 10 minutes [guide](index.md) is a good example: that's how long it takes to learn components, XHR and routing - and that's just about the right amount of knowledge needed to build useful applications. +In one sentence: because **Mithril is pragmatic**. This [10 minute guide](index.md) is a good example: that's how long it takes to learn components, XHR and routing - and that's just about the right amount of knowledge needed to build useful applications. Mithril is all about getting meaningful work done efficiently. Doing file uploads? [The docs show you how](request.md#file-uploads). Authentication? [Documented too](route.md#authentication). Exit animations? [You got it](animation.md). No extra libraries, no magic. diff --git a/docs/generate.js b/docs/generate.js index 9d694b87..438b8343 100644 --- a/docs/generate.js +++ b/docs/generate.js @@ -1,15 +1,17 @@ +"use strict" + var fs = require("fs") var path = require("path") var marked = require("marked") var layout = fs.readFileSync("./docs/layout.html", "utf-8") var version = JSON.parse(fs.readFileSync("./package.json", "utf-8")).version -try {fs.mkdirSync("../mithril")} catch (e) {} -try {fs.mkdirSync("../mithril/archive")} catch (e) {} -try {fs.mkdirSync("../mithril/archive/v" + version)} catch (e) {} -try {fs.mkdirSync("../mithril/archive/v" + version + "/lib")} catch (e) {} -try {fs.mkdirSync("../mithril/archive/v" + version + "/lib/prism")} catch (e) {} -try {fs.mkdirSync("../mithril/lib")} catch (e) {} -try {fs.mkdirSync("../mithril/lib/prism")} catch (e) {} +try {fs.mkdirSync("./dist")} catch (e) {/* ignore */} +try {fs.mkdirSync("./dist/archive")} catch (e) {/* ignore */} +try {fs.mkdirSync("./dist/archive/v" + version)} catch (e) {/* ignore */} +try {fs.mkdirSync("./dist/archive/v" + version + "/lib")} catch (e) {/* ignore */} +try {fs.mkdirSync("./dist/archive/v" + version + "/lib/prism")} catch (e) {/* ignore */} +try {fs.mkdirSync("./dist/lib")} catch (e) {/* ignore */} +try {fs.mkdirSync("./dist/lib/prism")} catch (e) {/* ignore */} var guides = fs.readFileSync("docs/guides.md", "utf-8") var methods = fs.readFileSync("docs/methods.md", "utf-8") @@ -25,7 +27,7 @@ function generate(pathname) { generate(pathname + "/" + filename) }) } - else if (!pathname.match(/tutorials|archive/)) { + else if (!pathname.match(/tutorials|archive|guides|methods/)) { if (pathname.match(/\.md$/)) { var outputFilename = pathname.replace(/\.md$/, ".html") var markdown = fs.readFileSync(pathname, "utf-8") @@ -33,7 +35,7 @@ function generate(pathname) { .replace(/`((?:\S| -> |, )+)(\|)(\S+)`/gim, function(match, a, b, c) { // fix pipes in code tags return "" + (a + b + c).replace(/\|/g, "|") + "" }) - .replace(/(^# .+?(?:\r?\n){2,}?)(?:(-(?:.|\r|\n)+?)((?:\r?\n){2,})|)/m, function(match, title, nav, space) { // inject menu + .replace(/(^# .+?(?:\r?\n){2,}?)(?:(-(?:.|\r|\n)+?)((?:\r?\n){2,})|)/m, function(match, title, nav) { // inject menu var file = path.basename(pathname) var link = new RegExp("([ \t]*)(- )(\\[.+?\\]\\(" + file + "\\))") var replace = function(match, space, li, link) { @@ -53,14 +55,14 @@ function generate(pathname) { .replace(/\[version\]/, version) // update version .replace(/\[body\]/, markedHtml) .replace(/(.+?)<\/h.>/gim, function(match, n, id, text) { // fix anchors - return "/g, "").replace(/.+?<\/a>/g, "").replace(/\.|\[|\]|"|\/|\(|\)/g, "").replace(/\s/g, "-") + "\">" + text + "" + return ".+?<\/a>/g, "").replace(/\.|\[|\]|"|\/|\(|\)/g, "").replace(/\s/g, "-") + '">' + text + "" }) - fs.writeFileSync("../mithril/archive/v" + version + "/" + outputFilename.replace(/^docs\//, ""), html, "utf-8") - fs.writeFileSync("../mithril/" + outputFilename.replace(/^docs\//, ""), html, "utf-8") + fs.writeFileSync("./dist/archive/v" + version + "/" + outputFilename.replace(/^docs\//, ""), html, "utf-8") + fs.writeFileSync("./dist/" + outputFilename.replace(/^docs\//, ""), html, "utf-8") } else if (!pathname.match(/lint|generate/)) { - fs.writeFileSync("../mithril/archive/v" + version + "/" + pathname.replace(/^docs\//, ""), fs.readFileSync(pathname, "utf-8"), "utf-8") - fs.writeFileSync("../mithril/" + pathname.replace(/^docs\//, ""), fs.readFileSync(pathname, "utf-8"), "utf-8") + fs.writeFileSync("./dist/archive/v" + version + "/" + pathname.replace(/^docs\//, ""), fs.readFileSync(pathname, "utf-8"), "utf-8") + fs.writeFileSync("./dist/" + pathname.replace(/^docs\//, ""), fs.readFileSync(pathname, "utf-8"), "utf-8") } } } diff --git a/docs/index.md b/docs/index.md index b95e83ff..1481b21e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -44,6 +44,8 @@ Mithril is used by companies like Vimeo and Nike, and open source platforms like If you are an experienced developer and want to know how Mithril compares to other frameworks, see the [framework comparison](framework-comparison.md) page. +Mithril supports browsers all the way back to IE9, no polyfills required. + --- ### Getting started @@ -54,7 +56,7 @@ Let's create an HTML file to follow along: ```markup - + +``` + +When loaded directly with a `