diff --git a/docs/integration.md b/docs/integration.md
index b166d35a..b990ed3b 100644
--- a/docs/integration.md
+++ b/docs/integration.md
@@ -1,8 +1,8 @@
## Integrating with Other Libraries
-Integration with third party libraries can be achieved via the `config` attribute of virtual elements.
+Integration with third party libraries or vanilla javascript code can be achieved via the [`config` attribute of virtual elements](mithril.md#accessing-the-real-dom).
-It's recommended that you encapsulate integration code in a component.
+It's recommended that you encapsulate integration code in a component or a helper function.
The example below shows a simple component that integrates with the [select2 library](http://ivaynberg.github.io/select2/).
diff --git a/docs/mithril.computation.md b/docs/mithril.computation.md
index 07162679..5e835b6b 100644
--- a/docs/mithril.computation.md
+++ b/docs/mithril.computation.md
@@ -1,6 +1,15 @@
## m.startComputation / m.endComputation
-Typically, `m.startComputation` / `m.endComputation` don't need to be called from application space. These methods are only intended to be used by people who are writing libraries that do things asynchronously.
+---
+
+[How auto-redrawing-works](#how-auto-redrawing-works)
+[Integrating multiple execution threads](#integrating-multiple-execution-threads)
+[Integrating to legacy code](#integrating-to-legacy-code)
+[Signature](#signature)
+
+---
+
+Typically, `m.startComputation` / `m.endComputation` don't need to be called from application space. These methods are only intended to be used by people who are writing libraries that do things asynchronously, or when calling vanilla javascript asynchronous functions from template [`config`](mithril.md#accessing-the-real-dom) functions.
If you need to do custom asynchronous calls without using Mithril's API, and find that your views are not redrawing, or that you're being forced to call [`m.redraw`](mithril.redraw.md) manually, you should consider using `m.startComputation` / `m.endComputation` so that Mithril can intelligently auto-redraw once your custom code finishes running.
@@ -53,6 +62,20 @@ window.onfocus = function() {
---
+### How auto-redrawing works
+
+The auto-redrawing system in Mithril is not affected by changes in values of `m.prop` getter-setters. Instead, Mithril relies on `m.startComputation` and `m.endComputation` calls to figure out when to redraw.
+
+Mithril has an internal counter, which is incremented every time `m.startComputation` is called, and decremented every time `m.endComputation` is called. Once the counter reaches zero, Mithril redraws. Mithril internally calls this pair of functions when you call [`m.module`](mithril.module.md), [`m.route`](mithril.route.md), [`m.request`](mithril.request.md), and whenever an event defined with [`m()`](mithril.md) is triggered.
+
+So calling `m.request` multiple times from a controller context increments the internal counter. Once each request completes, the counter is decremented. The end result is that Mithril waits for all requests to complete before attempting to redraw. This also applies for asynchronous functions called from 3rd party libraries or from vanilla javascript, if they call this pair of functions.
+
+The reason Mithril waits for all asynchronous services to complete before redrawing is to avoid wasteful browser repaints, and to minimize the need for null reference checks in templates.
+
+It's possible to opt out of the redrawing schedule by using the `background` option for `m.request`, or by simply not calling `m.startComputation` / `m.endComputation` when calling non-Mithril asynchronous functions.
+
+---
+
### Integrating multiple execution threads
When [integrating with third party libraries](integration.md), you might find that you need to call asynchronous methods from outside of Mithril's API.
@@ -126,7 +149,7 @@ var doSomething = function(callback) {
---
-## Integrating to legacy code
+### Integrating to legacy code
If you need to add separate widgets to different places on a same page, you can simply initialize each widget as you would a regular Mithril application (i.e. use `m.render`, `m.module` or `m.route`).
diff --git a/docs/mithril.deferred.md b/docs/mithril.deferred.md
index f97f7f71..902de6af 100644
--- a/docs/mithril.deferred.md
+++ b/docs/mithril.deferred.md
@@ -1,5 +1,15 @@
## m.deferred
+---
+
+[Usage](#usage)
+[Retrieving a value via the getter-setter API](#retrieving-a-value-via-the-getter-setter-api)
+[Integrating to the Mithril redrawing system](#integrating-to-the-mithril-redrawing-system)
+[Differences from Promises/A+](#differences-from-promises-a-)
+[Signature](#signature)
+
+---
+
This is a low-level method in Mithril. It's a modified version of the Thenable API.
A deferred is an asynchrony monad. It exposes a `promise` property which can *bind* callbacks to build a computation tree.
@@ -37,6 +47,8 @@ greetAsync()
#### Retrieving a value via the getter-setter API
+The promise object is actually a getter-setter function that gets populated when the promise is fulfilled.
+
```javascript
//asynchronous service
var greetAsync = function() {
@@ -64,21 +76,45 @@ setTimeout(function() {
#### Integrating to the Mithril redrawing system
+By default, promises are not integrated to the Mithril auto-redrawing system. When dealing with asynchronous functions, you must call [`m.startComputation` / `m.endComputation`] if you want the asynchronous payload to affect the view.
+
```javascript
//asynchronous service
var greetAsync = function() {
+ //tell Mithril to wait for this service to complete before redrawing
m.startComputation();
var deferred = m.deferred();
setTimeout(function() {
deferred.resolve("hello");
+ //the service is done, tell Mithril that it may redraw
m.endComputation();
}, 1000);
return deferred.promise;
};
```
+Some cases may not require a redraw upon completion of the asynchronous callbacks. In such cases, simply omit the m.startComputation/m.endComputation calls.
+
+Some asynchronous operations might need to affect redrawing both before and after their completion. In those cases, you can call [`m.redraw`](mithril.redraw.md) instead of using m.startComputation/m.endComputation.
+
+```javascript
+//asynchronous service
+var greetAsync = function() {
+ //don't wait for this service; redraw right away
+
+ var deferred = m.deferred();
+ setTimeout(function() {
+ deferred.resolve("hello");
+
+ //redraw again
+ m.redraw()
+ }, 1000);
+ return deferred.promise;
+};
+```
+
---
### Differences from Promises/A+
diff --git a/docs/mithril.md b/docs/mithril.md
index bf4b3cfe..fcb2eb20 100644
--- a/docs/mithril.md
+++ b/docs/mithril.md
@@ -1,5 +1,18 @@
## m
+---
+
+[Usage](#usage)
+[Using HTML entities](#using-html-entities)
+[Accessing the real DOM element](#accessing-the-real-dom-element)
+[Persisting config data](#persisting-config-data)
+[Destructors](#destructors)
+[SVG](#svg)
+[Dealing with focus](#dealing-with-focus)
+[Signature](#signature)
+
+---
+
This is a convenience method to compose virtual elements that can be rendered via [`m.render()`](mithril.render.md).
You are encouraged to use CSS selectors to define virtual elements. See "Signature" section for details.
@@ -157,6 +170,22 @@ One caveat of using the CSS syntax is that it clobbers the `style` attribute in
---
+### Using HTML entities
+
+By default, Mithril escapes HTML strings in order to help prevent XSS attacks.
+
+```javascript
+m("div", "×") //becomes
×
+```
+
+You can unescape trusted HTML strings by using [`m.trust`](mithril.trust.md)
+
+```javascript
+m("div", m.trust("×"() //becomes ×
+```
+
+---
+
#### Accessing the real DOM element
You can define a non-HTML-standard attribute called `config`. This special parameter allows you to call methods on the DOM element after it gets created.
diff --git a/docs/mithril.module.md b/docs/mithril.module.md
index d76f76a0..ae9c18eb 100644
--- a/docs/mithril.module.md
+++ b/docs/mithril.module.md
@@ -1,5 +1,13 @@
## m.module
+---
+
+[Usage](#usage)
+[Unloading modules](#unloading-modules)
+[Signature](#signature)
+
+---
+
A module is an Object with two keys: `controller` and `view`. Each of those should point to a Javascript function.
When using `m.module`, Mithril instantiates controllers as if they were class constructors. However, controllers may return objects if you want to use that Javascript feature to have more fine-grained control over a controller's lifecycle.
diff --git a/docs/mithril.prop.md b/docs/mithril.prop.md
index 3d3df755..235abf22 100644
--- a/docs/mithril.prop.md
+++ b/docs/mithril.prop.md
@@ -1,7 +1,18 @@
## m.prop
+---
+
+[Usage](#usage)
+[Third-party promise library support](#third-party-promise-library-support)
+[Serializing getter-setters](#serializing-getter-setters)
+[Signature](#signature)
+
+---
+
This is a getter-setter factory utility. It returns a function that stores information.
+Note that modifying the values of `m.prop` getter-setters does not trigger redrawing. Instead, Mithril's redrawing system relies on [`m.startComputation` and `m.endComputation`](mithril.computation.md). These functions are internally called by Mithril when you initialize a module via [`m.module`](mithril.module.md) or [`m.route`](mithril.route.md), and when you trigger event handlers that were created within templates with [`m()`](mithril.md).
+
---
### Usage
diff --git a/docs/mithril.redraw.md b/docs/mithril.redraw.md
index 443a41da..bf10a4e9 100644
--- a/docs/mithril.redraw.md
+++ b/docs/mithril.redraw.md
@@ -1,5 +1,14 @@
## m.redraw
+---
+
+[Changing redraw strategy](#changing-redraw-strategy)
+[Preventing redraws on events](#preventing-redraws-on-events)
+[Forcing redraw](#forcing-redraw)
+[Signature](#signature)
+
+---
+
Redraws the view for the currently active module. Use [`m.module()`](mithril.module.md) to activate a module.
This method is called internally by Mithril's auto-redrawing system. Usually you don't need to call it manually unless you are doing recurring asynchronous operations (i.e. using `setInterval`) or if you want to decouple slow running background requests from the rendering context (see the `background` option in [`m.request`](mithril.request.md).
@@ -37,11 +46,19 @@ module1.config = function(el, isInit, ctx) {
}
```
+Common reasons why one might need to change redraw strategy are:
+
+- in order to avoid the full-page recreation when changing routes, for the sake of performance of global 3rd party components
+- in order to prevent redraw when dealing with `keypress` events where the event's keyCode is not of interest
+
+Note that the redraw strategy is a global setting that affects the entire template trees of all modules on the page. In order to prevent redraws in *some parts* of an application, but not others, see [subtree directives](mithril.render.md#subtree-directives)
+
---
### Preventing redraws on events
-Similarly, it's possible to skip redrawing altogether by calling `m.redraw.strategy("none")`
+Sometimes you only care about a particular condition in an event and want to ignore it if this condition is not met.
+For example, you might only be interested in running a redraw if a user presses the space bar, and you might not want to waste a redraw if the user presses any other key. In that case, it's possible to skip redrawing altogether by calling `m.redraw.strategy("none")`
```javascript
m("input", {onkeydown: function(e) {
@@ -54,12 +71,14 @@ m("input", {onkeydown: function(e) {
### Forcing redraw
-If you find yourself needing to redraw before the browsers normal redraw cycle, you can force it.
+If you find yourself needing to redraw before the browsers normal redraw cycle, you can force a synchronous redraw by passing a boolean `true` as a parameter to `m.redraw`.
```javascript
m.redraw(true) // force
```
+Normally, you should only do this if you need to synchronously read a value from the DOM that requires a browser repaint (e.g. `offsetTop` or a CSS rule). If you need to read DOM values, try to read them all at once, because alternating reading and writing to the DOM causes multiple browser repaints, and repaints are expensive.
+
---
### Signature
diff --git a/docs/mithril.render.md b/docs/mithril.render.md
index 91a59429..bec3ecbe 100644
--- a/docs/mithril.render.md
+++ b/docs/mithril.render.md
@@ -1,10 +1,18 @@
## m.render
+---
+
+[Usage](#usage)
+[Subtree directives](#subtree directives)
+[Signature](#signature)
+
+---
+
This method generates a DOM tree inside of a given HTML element.
If the method is run more than once with the same root element, it diffs the new tree against the existing one and intelligently modifies only the portions that have changed.
-Note that, unlike many templating engines, this "smart diff" feature does not affect things like cursor placement in inputs and focus, and is therefore safe to call during user interactions.
+Note that, unlike many templating engines, this "smart diff" feature does not affect things like cursor placement in inputs and focus, and is therefore safe to call during user interactions. There are, however, some limitations to the diff algorithm that require you to add [key attributes](mithril.md#dealing-with-focus) in some edge cases.
---
diff --git a/docs/mithril.request.md b/docs/mithril.request.md
index c1232418..5106a92b 100644
--- a/docs/mithril.request.md
+++ b/docs/mithril.request.md
@@ -1,5 +1,23 @@
## m.request
+---
+
+[Basic usage](#basic-usage)
+[Processing-web-service-data](#processing-web-service-data)
+[Bind redirection code](#bind-redirection-code)
+[Binding errors](#binding-errors)
+[Queuing operations](#queuing-operations)
+[Casting the Response Data to a Class](#casting-the-response-data-to-a-class)
+[Unwrapping Response Data](#unwrapping-response-data)
+[Using Different Data Transfer Formats](#using-different-data-transfer-formats)
+[Using variable data formats](#using-variable-data-formats)
+[Extracting Metadata from the Response](#extracting-metadata-from-the-response)
+[Configuring the underlying XMLHttpRequest](#configuring-the-underlying-xmlhttprequest)
+[Aborting a request](#aborting-a-request)
+[Signature](#signature)
+
+---
+
This is a high-level utility for working with web services, which allows writing asynchronous code relatively procedurally.
By default, it assumes server responses are in JSON format and optionally instantiates a class with the response data.
diff --git a/docs/mithril.route.md b/docs/mithril.route.md
index 7c5c39ba..9d1d046f 100644
--- a/docs/mithril.route.md
+++ b/docs/mithril.route.md
@@ -1,5 +1,17 @@
## m.route
+---
+
+[Defining routes](#defining-routes)
+[Variadic routes](#variadic-routes)
+[Routes with querystrings](#routes-with-querystrings)
+[Running clean up code on route change](#running-clean-up-code-on-route-change)
+[Redirecting](#redirecting)
+[Reading the currently active route](#reading-the-currently-active-route)
+[Mode abstraction](#mode abstraction)
+
+---
+
Routing is a system that allows creating Single-Page-Applications (SPA), i.e. applications that can go from a page to another without causing a full browser refresh.
It enables seamless navigability while preserving the ability to bookmark each page individually, and the ability to navigate the application via the browser's history mechanism.
@@ -18,8 +30,6 @@ Routing is single-page-application (SPA) friendly, and can be implemented using
---
-
-
### Defining routes
#### Usage