From 16eb8e6bba4aa840a7fff7a5c89180b2bcbdc084 Mon Sep 17 00:00:00 2001 From: Carl Mungazi Date: Mon, 16 Jan 2017 10:02:19 +0000 Subject: [PATCH 1/5] Update animation.md Fixed typo --- docs/animation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/animation.md b/docs/animation.md index 28c99be1..0d45614f 100644 --- a/docs/animation.md +++ b/docs/animation.md @@ -94,7 +94,7 @@ We can verify that both the enter and exit animations work by mounting the `Togg m.mount(document.body, Toggler) ``` -Note that the `onbeforeremove` hook only fires on the element that loses its `parentNode` when an elements gets detached from the DOM. This behavior is by design and exists to prevent a potential jarring user experience where every conceivable exit animation on the page would run on a route change. If your exit animation is not running, make sure to attach the `onbeforeremove` handler as high up the tree as it makes sense to ensure that your animation code is called. +Note that the `onbeforeremove` hook only fires on the element that loses its `parentNode` when an element gets detached from the DOM. This behavior is by design and exists to prevent a potential jarring user experience where every conceivable exit animation on the page would run on a route change. If your exit animation is not running, make sure to attach the `onbeforeremove` handler as high up the tree as it makes sense to ensure that your animation code is called. --- @@ -102,4 +102,4 @@ Note that the `onbeforeremove` hook only fires on the element that loses its `pa When creating animations, it's recommended that you only use the `opacity` and `transform` CSS rules, since these can be hardware-accelerated by modern browsers and yield better performance than animating `top`, `left`, `width`, and `height`. -It's also recommended that you avoid the `box-shadow` rule and selectors like `:nth-child`, since these are also resource intensive options. Other things that can be expensive include large or dynamically scaled images and overlapping elements with different `position` values (e.g. an absolute postioned element over a fixed element). \ No newline at end of file +It's also recommended that you avoid the `box-shadow` rule and selectors like `:nth-child`, since these are also resource intensive options. Other things that can be expensive include large or dynamically scaled images and overlapping elements with different `position` values (e.g. an absolute postioned element over a fixed element). From 839f9a75835d7379b8c488262c26270bbe239d98 Mon Sep 17 00:00:00 2001 From: Alexander Travov Date: Mon, 16 Jan 2017 15:56:04 +0300 Subject: [PATCH 2/5] Fix typo. --- docs/simple-application.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/simple-application.md b/docs/simple-application.md index 190991c6..bec3d9a8 100644 --- a/docs/simple-application.md +++ b/docs/simple-application.md @@ -99,7 +99,7 @@ module.exports = User The `method` option is an [HTTP method](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods). To retrieve data from the server without causing side-effects on the server, we need to use the `GET` method. The `url` is the address for the API endpoint. The `withCredentials: true` line indicates that we're using cookies (which is a requirement for the REM API). -The `m.request` call returns a Promise that resolves to the data from the endpoint. By default, Mithril assumes a HTTP response body are in JSON format and automatically parses it into a Javascript object or array. The `.then` callback runs when the XHR request completes. In this case, the callback assigns the `reesult.data` array to `User.list`. +The `m.request` call returns a Promise that resolves to the data from the endpoint. By default, Mithril assumes a HTTP response body are in JSON format and automatically parses it into a Javascript object or array. The `.then` callback runs when the XHR request completes. In this case, the callback assigns the `result.data` array to `User.list`. Notice we also have a `return` statement in `loadList`. This is a general good practice when working with Promises, which allows us to register more callbacks to run after the completion of the XHR request. From 70f8655f528cd8618a9ec866bc5f9ff935c11ed4 Mon Sep 17 00:00:00 2001 From: Alexander Travov Date: Mon, 16 Jan 2017 15:57:17 +0300 Subject: [PATCH 3/5] Make file paths consistent across tutorial and installation instruction. --- docs/simple-application.md | 64 +++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/docs/simple-application.md b/docs/simple-application.md index bec3d9a8..e715d0f8 100644 --- a/docs/simple-application.md +++ b/docs/simple-application.md @@ -13,14 +13,14 @@ First let's create an entry point for the application. Create a file `index.html My Application - + ``` The `` line indicates this is an HTML 5 document. The first `charset` meta tag indicates the encoding of the document and the `viewport` meta tag dictates how mobile browsers should scale the page. The `title` tag contains the text to be displayed on the browser tab for this application, and the `script` tag indicates what is the path to the Javascript file that controls the application. -We could create the entire application in a single Javascript file, but doing so would make it difficult to navigate the codebase later on. Instead, let's split the code into *modules*, and assemble these modules into a *bundle* `app.js`. +We could create the entire application in a single Javascript file, but doing so would make it difficult to navigate the codebase later on. Instead, let's split the code into *modules*, and assemble these modules into a *bundle* `bin/app.js`. There are many ways to setup a bundler tool, but most are distributed via NPM. In fact, most modern Javascript libraries and tools are distributed that way, including Mithril. NPM stands for Node.js Package Manager. To download NPM, [install Node.js](https://nodejs.org/en/); NPM is installed automatically with it. Once you have Node.js and NPM installed, open the command line and run this command: @@ -61,7 +61,7 @@ module.exports = User Next we create a function that will trigger an XHR call. Let's call it `loadList` ```javascript -// models/User.js +// src/models/User.js var m = require("mithril") var User = { @@ -77,7 +77,7 @@ module.exports = User Then we can add an `m.request` call to make an XHR request. For this tutorial, we'll make XHR calls to the [REM](http://rem-rest-api.herokuapp.com/) API, a mock REST API designed for rapid prototyping. This API returns a list of users from the `GET http://rem-rest-api.herokuapp.com/api/users` endpoint. Let's use `m.request` to make an XHR request and populate our data with the response of that endpoint. ```javascript -// models/User.js +// src/models/User.js var m = require("mithril") var User = { @@ -112,15 +112,17 @@ Now, let's create a view module so that we can display data from our User model Create a file called `src/views/UserList.js`. First, let's include Mithril and our model, since we'll need to use both: ```javascript +// src/views/UserList.js var m = require("mithril") -var User = require("../model/User") +var User = require("../models/User") ``` Next, let's create a Mithril component. A component is simply an object that has a `view` method: ```javascript +// src/views/UserList.js var m = require("mithril") -var User = require("../model/User") +var User = require("../models/User") module.exports = { view: function() { @@ -135,7 +137,7 @@ Let's use Mithril hyperscript to create a list of items. Hyperscript is the most ```javascript var m = require("mithril") -var User = require("../model/User") +var User = require("../models/User") module.exports = { view: function() { @@ -149,8 +151,9 @@ The `".user-list"` string is a CSS selector, and as you would expect, `.user-lis Now, let's reference the list of users from the model we created earlier (`User.list`) to dynamically loop through data: ```javascript +// src/views/UserList.js var m = require("mithril") -var User = require("../model/User") +var User = require("../models/User") module.exports = { view: function() { @@ -168,8 +171,9 @@ Since `User.list` is a Javascript array, and since hyperscript views are just Ja The problem, of course, is that we never called the `User.loadList` function. Therefore, `User.list` is still an empty array, and thus this view would render a blank page. Since we want `User.loadList` to be called when we render this component, we can take advantage of component [lifecycle methods](lifecycle-methods.md): ```javascript +// src/views/UserList.js var m = require("mithril") -var User = require("../model/User") +var User = require("../models/User") module.exports = { oninit: User.loadList, @@ -189,12 +193,13 @@ Also notice we **didn't** do `oninit: User.loadList()` (with parentheses at the --- -Let's render the view from the entry point file `index.js` we created earlier: +Let's render the view from the entry point file `src/index.js` we created earlier: ```javascript +// src/index.js var m = require("mithril") -var UserList = require("./view/UserList") +var UserList = require("./views/UserList") m.mount(document.body, UserList) ``` @@ -221,7 +226,7 @@ To add styles, let's first create a file called `styles.css` and include it in t - + ``` @@ -249,9 +254,10 @@ Routing means binding a screen to a unique URL, to create the ability to go from We can add routing by changing the `m.mount` call to a `m.route` call: ```javascript +// src/index.js var m = require("mithril") -var UserList = require("./view/UserList") +var UserList = require("./views/UserList") m.route(document.body, "/list", { "/list": UserList @@ -278,14 +284,14 @@ module.exports = { } ``` -Then we can `require` this new module from `index.js` +Then we can `require` this new module from `src/index.js` ```javascript -// index.js +// src/index.js var m = require("mithril") -var UserList = require("./view/UserList") -var UserForm = require("./view/UserForm") +var UserList = require("./views/UserList") +var UserForm = require("./views/UserForm") m.route(document.body, "/list", { "/list": UserList @@ -295,11 +301,11 @@ m.route(document.body, "/list", { And finally, we can create a route that references it: ```javascript -// index.js +// src/index.js var m = require("mithril") -var UserList = require("./view/UserList") -var UserForm = require("./view/UserForm") +var UserList = require("./views/UserList") +var UserForm = require("./views/UserForm") m.route(document.body, "/list", { "/list": UserList, @@ -344,7 +350,7 @@ body,.input,.button {font:normal 16px Verdana;margin:0;} .button:hover {background:#e8e8e8;} ``` -Right now, this component does nothing to respond to user events. Let's add some code to our `User` model in `src/model/User.js`. This is how the code is right now: +Right now, this component does nothing to respond to user events. Let's add some code to our `User` model in `src/models/User.js`. This is how the code is right now: ```javascript // src/models/User.js @@ -408,7 +414,7 @@ Notice we added a `User.current` property, and a `User.load(id)` method which po ```javascript // src/views/UserForm.js var m = require("mithril") -var User = require("./model/User") +var User = require("./models/User") module.exports = { oninit: function(vnode) {User.load(vnode.attrs.id)}, @@ -431,7 +437,7 @@ Now, let's modify the `UserList` view so that we can navigate from there to a `U ```javascript // src/views/UserList.js var m = require("mithril") -var User = require("../model/User") +var User = require("../models/User") module.exports = { oninit: User.loadList, @@ -456,7 +462,7 @@ The form itself still doesn't save when you press "Save". Let's make this form w ```javascript // src/views/UserForm.js var m = require("mithril") -var User = require("../model/User") +var User = require("../models/User") module.exports = { oninit: function(vnode) {User.load(vnode.attrs.id)}, @@ -573,15 +579,15 @@ body,.input,.button {font:normal 16px Verdana;margin:0;} .button:hover {background:#e8e8e8;} ``` -Let's change the router in `index.js` to add our layout into the mix: +Let's change the router in `src/index.js` to add our layout into the mix: ```javascript -// index.js +// src/index.js var m = require("mithril") -var UserList = require("./view/UserList") -var UserForm = require("./view/UserForm") -var Layout = require("./view/Layout") +var UserList = require("./views/UserList") +var UserForm = require("./views/UserForm") +var Layout = require("./views/Layout") m.route(document.body, "/list", { "/list": { From 15cfaa9655babecc9df7cc97256271a0bc9c8087 Mon Sep 17 00:00:00 2001 From: Alexander Travov Date: Mon, 16 Jan 2017 16:06:37 +0300 Subject: [PATCH 4/5] Get rid of unnecessary nested array. --- docs/simple-application.md | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/docs/simple-application.md b/docs/simple-application.md index e715d0f8..d41ea2ae 100644 --- a/docs/simple-application.md +++ b/docs/simple-application.md @@ -157,11 +157,9 @@ var User = require("../models/User") module.exports = { view: function() { - return m(".user-list", [ - User.list.map(function(user) { - return m(".user-list-item", user.firstName + " " + user.lastName) - }) - ]) + return m(".user-list", User.list.map(function(user) { + return m(".user-list-item", user.firstName + " " + user.lastName) + })) } } ``` @@ -178,11 +176,9 @@ var User = require("../models/User") module.exports = { oninit: User.loadList, view: function() { - return m(".user-list", [ - User.list.map(function(user) { - return m(".user-list-item", user.firstName + " " + user.lastName) - }) - ]) + return m(".user-list", User.list.map(function(user) { + return m(".user-list-item", user.firstName + " " + user.lastName) + })) } } ``` @@ -442,11 +438,9 @@ var User = require("../models/User") module.exports = { oninit: User.loadList, view: function() { - return m(".user-list", [ - User.list.map(function(user) { - return m("a.user-list-item", {href: "/edit/" + user.id, oncreate: m.route.link}, user.firstName + " " + user.lastName) - }) - ]) + return m(".user-list", User.list.map(function(user) { + return m("a.user-list-item", {href: "/edit/" + user.id, oncreate: m.route.link}, user.firstName + " " + user.lastName) + })) } } ``` From 9122d00d036427b5f63ff70167f51a6124532226 Mon Sep 17 00:00:00 2001 From: Alexander Travov Date: Mon, 16 Jan 2017 16:22:56 +0300 Subject: [PATCH 5/5] Fix model import. --- docs/simple-application.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/simple-application.md b/docs/simple-application.md index d41ea2ae..91bf0a8e 100644 --- a/docs/simple-application.md +++ b/docs/simple-application.md @@ -410,7 +410,7 @@ Notice we added a `User.current` property, and a `User.load(id)` method which po ```javascript // src/views/UserForm.js var m = require("mithril") -var User = require("./models/User") +var User = require("../models/User") module.exports = { oninit: function(vnode) {User.load(vnode.attrs.id)},