[DOC] doc: miscellaneous formatting updates

This commit is contained in:
Géry Debongnie
2019-06-14 15:24:04 +02:00
parent 1f0457f69b
commit b9fae87273
10 changed files with 153 additions and 155 deletions
+3 -3
View File
@@ -10,7 +10,7 @@ other Odoo related projects. OWL's main feature is a _declarative component syst
**Try it online!** An online playground is available at [https://odoo.github.io/owl/playground](https://odoo.github.io/owl/playground) to let you experiment with the OWL framework. **Try it online!** An online playground is available at [https://odoo.github.io/owl/playground](https://odoo.github.io/owl/playground) to let you experiment with the OWL framework.
## OWL's design principles ## OWL's Design Principles
OWL is designed to be used in highly dynamic applications where changing OWL is designed to be used in highly dynamic applications where changing
requirements are common, code needs to be maintained by large teams. requirements are common, code needs to be maintained by large teams.
@@ -30,7 +30,7 @@ Owl is not designed to be fast or small (even though it is quite good on those
two topics). If you are interested in a comparison with React or Vue, you will two topics). If you are interested in a comparison with React or Vue, you will
find some more information [here](doc/comparison.md). find some more information [here](doc/comparison.md).
# Example ## Example
Here is a short example to illustrate interactive widgets: Here is a short example to illustrate interactive widgets:
@@ -65,7 +65,7 @@ If you want to use a simple `<script>` tag, the last release can be downloaded h
Some npm scripts are available: Some npm scripts are available:
| Command | Description | | Command | Description |
| ---------------------- | ------------------------------------------------------------------------------- | | --------------------- | ---------------------------------------------------------------------------- |
| `npm install` | install every dependency required for this project | | `npm install` | install every dependency required for this project |
| `npm run build` | build a bundle of _owl_ in the _/dist/_ folder | | `npm run build` | build a bundle of _owl_ in the _/dist/_ folder |
| `npm run minify` | minify the prebuilt owl.js file | | `npm run minify` | minify the prebuilt owl.js file |
+7 -5
View File
@@ -7,6 +7,8 @@ In this page, we try to highlight some of these differences. Obviously, some
effort was done to be fair. However, if you disagree with some of the points effort was done to be fair. However, if you disagree with some of the points
discussed, feel free to open an issue/submit a PR to correct this text. discussed, feel free to open an issue/submit a PR to correct this text.
## Content
- [Size](#size) - [Size](#size)
- [Tooling/Build Step](#toolingbuild-step) - [Tooling/Build Step](#toolingbuild-step)
- [Templating](#templating) - [Templating](#templating)
@@ -14,7 +16,7 @@ discussed, feel free to open an issue/submit a PR to correct this text.
- [Reactiveness](#reactiveness) - [Reactiveness](#reactiveness)
- [State Management](#state-management) - [State Management](#state-management)
### Size ## Size
OWL is intended to be small and to work at a slightly lower level of abstraction OWL is intended to be small and to work at a slightly lower level of abstraction
than React and Vue. Also, jQuery is not the same kind of framework, but it is interesting to compare. than React and Vue. Also, jQuery is not the same kind of framework, but it is interesting to compare.
@@ -26,7 +28,7 @@ than React and Vue. Also, jQuery is not the same kind of framework, but it is in
| React + ReactDOM + Redux | | 40kb | | React + ReactDOM + Redux | | 40kb |
| jQuery | 86kb | 30kb | | jQuery | 86kb | 30kb |
### Tooling/Build step ## Tooling/Build step
OWL is designed to be easy to use in a standalone way. For various reasons, OWL is designed to be easy to use in a standalone way. For various reasons,
Odoo does not want to rely on standard web tools (such as webpack), and OWL can Odoo does not want to rely on standard web tools (such as webpack), and OWL can
@@ -84,7 +86,7 @@ This has the advantage of having the full power of Javascript, but is less
structured than a template language. Note that the tooling is quite impressive: structured than a template language. Note that the tooling is quite impressive:
there is a syntax highlighter for jsx here on github! there is a syntax highlighter for jsx here on github!
### Asynchronous rendering ## Asynchronous Rendering
This is actually a big difference between OWL and React/Vue: components in OWL This is actually a big difference between OWL and React/Vue: components in OWL
are totally asynchronous. They have two asynchronous hooks in their lifecycle: are totally asynchronous. They have two asynchronous hooks in their lifecycle:
@@ -115,7 +117,7 @@ extremely powerful as well, as demonstrated by the Odoo Web Client.
Lazy loading static libraries can obviously be done with React/Vue, but it is Lazy loading static libraries can obviously be done with React/Vue, but it is
more convoluted. more convoluted.
### Reactiveness ## Reactiveness
React has a simple model: whenever the state changes, it is React has a simple model: whenever the state changes, it is
replaced with a new state (via the setState method). Then, the DOM is patched. replaced with a new state (via the setState method). Then, the DOM is patched.
@@ -129,7 +131,7 @@ Owl is closer to vue: it also tracks magically the state properties, but it does
only increment a counter whenever it changes (and a _deep_ counter for each of only increment a counter whenever it changes (and a _deep_ counter for each of
its parents). This assumes that the state is actually a tree. its parents). This assumes that the state is actually a tree.
### State Management ## State Management
Managing the state of an application is a tricky issue. Many solutions have Managing the state of an application is a tricky issue. Many solutions have
been proposed these last few years. It also depends on the kind of application we been proposed these last few years. It also depends on the kind of application we
+11 -11
View File
@@ -10,16 +10,16 @@
- [Methods](#methods) - [Methods](#methods)
- [Lifecycle](#lifecycle) - [Lifecycle](#lifecycle)
- [Composition](#composition) - [Composition](#composition)
- [Asynchronous rendering](#asynchronous-rendering) - [Asynchronous Rendering](#asynchronous-rendering)
- [Event Handling](#event-handling) - [Event Handling](#event-handling)
- [`t-key` directive](#t-key-directive) - [`t-key` Directive](#t-key-directive)
- [`t-mounted` directive](#t-mounted-directive) - [`t-mounted` Directive](#t-mounted-directive)
- [Semantics](#semantics) - [Semantics](#semantics)
- [Props Validation](#props-validation) - [Props Validation](#props-validation)
- [Keeping References](#keeping-references) - [References](#references)
- [Slots](#slots) - [Slots](#slots)
- [Form input bindings](#form-input-bindings) - [Form Input Bindings](#form-input-bindings)
- [Asynchronous rendering](#asynchronous-rendering) - [Asynchronous Rendering](#asynchronous-rendering)
## Overview ## Overview
@@ -410,7 +410,7 @@ with a class object:
<t t-widget="MyWidget" t-att-class="{a: state.flagA, b: state.flagB}" /> <t t-widget="MyWidget" t-att-class="{a: state.flagA, b: state.flagB}" />
``` ```
### Event handling ### Event Handling
In a component's template, it is useful to be able to register handlers on some In a component's template, it is useful to be able to register handlers on some
elements to some specific events. This is what makes a template _alive_. There elements to some specific events. This is what makes a template _alive_. There
@@ -496,7 +496,7 @@ The `t-on` directive also allows to prebind some arguments. For example,
Here, `expr` is a valid Owl expression, so it could be `true` or some variable Here, `expr` is a valid Owl expression, so it could be `true` or some variable
from the rendering context. from the rendering context.
### `t-key` directive ### `t-key` Directive
Even though Owl tries to be as declarative as possible, some DOM state is still Even though Owl tries to be as declarative as possible, some DOM state is still
locked inside the DOM: for example, the scrolling state, the current user selection, locked inside the DOM: for example, the scrolling state, the current user selection,
@@ -520,7 +520,7 @@ There are three main use cases:
- _animations_: give a different identity to a component. Ex: thread id with - _animations_: give a different identity to a component. Ex: thread id with
animations on add/remove message. animations on add/remove message.
### `t-mounted` directive ### `t-mounted` Directive
The `t-mounted` directive allows to register a callback to execute whenever the node The `t-mounted` directive allows to register a callback to execute whenever the node
is inserted into the DOM. is inserted into the DOM.
@@ -712,7 +712,7 @@ Examples:
}; };
``` ```
### Keeping references ### References
The `t-ref` directive helps a component keep reference to some inside part of it. The `t-ref` directive helps a component keep reference to some inside part of it.
Like the `t-on` directive, it can work either on a DOM node, or on a component: Like the `t-on` directive, it can work either on a DOM node, or on a component:
@@ -904,7 +904,7 @@ update a number whenever the change is done.
Note: the online playground has an example to show how it works. Note: the online playground has an example to show how it works.
### Asynchronous rendering ### Asynchronous Rendering
Working with asynchronous code always adds a lot of complexity to a system. Whenever Working with asynchronous code always adds a lot of complexity to a system. Whenever
different parts of a system are active at the same time, one needs to think different parts of a system are active at the same time, one needs to think
+1 -1
View File
@@ -1,6 +1,6 @@
# 🦉 Quick Start 🦉 # 🦉 Quick Start 🦉
## Static server ## Static Server
Let us assume that we have a static server running somewhere. We could then Let us assume that we have a static server running somewhere. We could then
simply add an html page with a few extra files. simply add an html page with a few extra files.
+12 -12
View File
@@ -6,14 +6,14 @@
- [Directives](#directives) - [Directives](#directives)
- [QWeb Engine](#qweb-engine) - [QWeb Engine](#qweb-engine)
- [Reference](#reference) - [Reference](#reference)
- [White spaces](#white-spaces) - [White Spaces](#white-spaces)
- [Root nodes](#root-nodes) - [Root Nodes](#root-nodes)
- [Expression evaluation](#expression-evaluation) - [Expression Evaluation](#expression-evaluation)
- [Static html nodes](#static-html-nodes) - [Static html Nodes](#static-html-nodes)
- [Outputting data](#outputting-data) - [Outputting Data](#outputting-data)
- [Setting Variables](#setting-variables) - [Setting Variables](#setting-variables)
- [Conditionals](#conditionals) - [Conditionals](#conditionals)
- [Dynamic attributes](#dynamic-attributes) - [Dynamic Attributes](#dynamic-attributes)
- [Loops](#loops) - [Loops](#loops)
- [Rendering Sub Templates](#rendering-sub-templates) - [Rendering Sub Templates](#rendering-sub-templates)
- [Debugging](#debugging) - [Debugging](#debugging)
@@ -66,9 +66,9 @@ The component system in Owl requires additional directives, to express various
needs. Here is a list of all Owl specific directives: needs. Here is a list of all Owl specific directives:
| Name | Description | | Name | Description |
| ------------------------------------ | --------------------------------------------------------------------------------------- | | ------------------------------------ | ----------------------------------------------------------------------------------- |
| `t-widget`, `t-keepalive`, `t-async` | [Defining a sub component](component.md#composition) | | `t-widget`, `t-keepalive`, `t-async` | [Defining a sub component](component.md#composition) |
| `t-ref` | [Setting a reference to a dom node or a sub component](component.md#keeping-references) | | `t-ref` | [Setting a reference to a dom node or a sub component](component.md#references) |
| `t-key` | [Defining a key (to help virtual dom reconciliation)](component.md#t-key-directive) | | `t-key` | [Defining a key (to help virtual dom reconciliation)](component.md#t-key-directive) |
| `t-on-*` | [Event handling](component.md#event-handling) | | `t-on-*` | [Event handling](component.md#event-handling) |
| `t-transition` | [Defining an animation](animations.md#css-transitions) | | `t-transition` | [Defining an animation](animations.md#css-transitions) |
@@ -141,7 +141,7 @@ We define in this section the specification of how `QWeb` templates should be
rendered. Note that we only document here the standard QWeb specification. Owl rendered. Note that we only document here the standard QWeb specification. Owl
specific extensions are documented in various other parts of the documentation. specific extensions are documented in various other parts of the documentation.
### White spaces ### White Spaces
White spaces in a templates are handled in a special way: White spaces in a templates are handled in a special way:
@@ -149,7 +149,7 @@ White spaces in a templates are handled in a special way:
- if a whitespace-only text node contains a linebreak, it is ignored - if a whitespace-only text node contains a linebreak, it is ignored
- the previous rules do not apply if we are in a `<pre>` tag - the previous rules do not apply if we are in a `<pre>` tag
### Root nodes ### Root Nodes
For many reasons, Owl QWeb templates should have a single root node. More For many reasons, Owl QWeb templates should have a single root node. More
precisely, the result of a template rendering should have a single root node: precisely, the result of a template rendering should have a single root node:
@@ -175,7 +175,7 @@ Note: this does not apply to subtemplates (see the `t-call` directive). In that
case, they will be inlined in the main template, and can actually have many case, they will be inlined in the main template, and can actually have many
root nodes. root nodes.
### Expression evaluation ### Expression Evaluation
QWeb expressions are strings that will be processed at compile time. Each variable in QWeb expressions are strings that will be processed at compile time. Each variable in
the javascript expression will be replaced by a lookup in the context (so, the the javascript expression will be replaced by a lookup in the context (so, the
@@ -345,7 +345,7 @@ Extra conditional branching directives `t-elif` and `t-else` are also available:
</div> </div>
``` ```
### Dynamic attributes ### Dynamic Attributes
One can use the `t-att-` directive to add dynamic attributes. Its main use is to One can use the `t-att-` directive to add dynamic attributes. Its main use is to
evaluate an expression (at rendering time) and bind an attribute to its result: evaluate an expression (at rendering time) and bind an attribute to its result:
+1 -2
View File
@@ -1,6 +1,5 @@
# 🦉 OWL Documentation 🦉 # 🦉 OWL Documentation 🦉
## Reference ## Reference
- [Animations](animations.md) - [Animations](animations.md)
@@ -12,7 +11,7 @@
- [Utils](utils.md) - [Utils](utils.md)
- [Virtual DOM](vdom.md) - [Virtual DOM](vdom.md)
## Learning resources ## Learning Resources
- [Quick Start](quick_start.md) - [Quick Start](quick_start.md)
+19 -19
View File
@@ -9,7 +9,7 @@
- [Mutations](#mutations) - [Mutations](#mutations)
- [Actions](#actions) - [Actions](#actions)
- [Getters](#getters) - [Getters](#getters)
- [Connecting a component](#connecting-a-component) - [Connecting a Component](#connecting-a-component)
## Overview ## Overview
@@ -33,7 +33,7 @@ Here is what a simple store looks like:
```js ```js
const actions = { const actions = {
addTodo({ commit }, message) { addTodo({ commit }, message) {
commit('addTodo', message); commit("addTodo", message);
} }
}; };
@@ -42,25 +42,24 @@ const mutations = {
const todo = { const todo = {
id: state.nextId++, id: state.nextId++,
message, message,
isCompleted: false, isCompleted: false
}; };
state.todos.push(todo); state.todos.push(todo);
}, }
}; };
const state = { const state = {
todos: [], todos: [],
nextId: 1, nextId: 1
}; };
const store = new owl.Store({ state, actions, mutations }); const store = new owl.Store({ state, actions, mutations });
store.on('update', () => console.log(store.state)); store.on("update", () => console.log(store.state));
// updating the state // updating the state
store.dispatch('addTodo', 'fix all bugs'); store.dispatch("addTodo", "fix all bugs");
``` ```
## Reference ## Reference
The store is a simple [`owl.EventBus`](event_bus.md) that triggers `update` events whenever its The store is a simple [`owl.EventBus`](event_bus.md) that triggers `update` events whenever its
@@ -94,12 +93,12 @@ in an action.
```js ```js
const actions = { const actions = {
async login({ commit }) { async login({ commit }) {
commit('setLoginState', 'pending'); commit("setLoginState", "pending");
try { try {
const loginInfo = await doSomeRPC('/login/', 'someinfo'); const loginInfo = await doSomeRPC("/login/", "someinfo");
commit('setLoginState', loginInfo); commit("setLoginState", loginInfo);
} catch { } catch {
commit('setLoginState', 'error'); commit("setLoginState", "error");
} }
} }
}; };
@@ -130,21 +129,20 @@ transform the data contained in the store.
const getters = { const getters = {
getPost({ state }, id) { getPost({ state }, id) {
const post = state.posts.find(p => p.id === id); const post = state.posts.find(p => p.id === id);
const author = state.authors.find(a => a.id = post.id); const author = state.authors.find(a => (a.id = post.id));
return { return {
id, id,
author, author,
content: post.content content: post.content
}; };
}, }
}; };
// somewhere else // somewhere else
const post = store.getters.getPost(id); const post = store.getters.getPost(id);
``` ```
### Connecting a component ### Connecting a Component
By default, an Owl `Component` is not connected to any store. The `connect` By default, an Owl `Component` is not connected to any store. The `connect`
function is there to create sub Components that are connected versions of function is there to create sub Components that are connected versions of
@@ -153,7 +151,7 @@ Components.
```javascript ```javascript
const actions = { const actions = {
increment({ commit }) { increment({ commit }) {
commit('increment', 1); commit("increment", 1);
} }
}; };
const mutations = { const mutations = {
@@ -162,13 +160,13 @@ const mutations = {
} }
}; };
const state = { const state = {
counter: 0, counter: 0
}; };
const store = new owl.Store({ state, actions, mutations }); const store = new owl.Store({ state, actions, mutations });
class Counter extends owl.Component { class Counter extends owl.Component {
increment() { increment() {
this.env.store.dispatch('increment'); this.env.store.dispatch("increment");
} }
} }
function mapStoreToProps(state) { function mapStoreToProps(state) {
@@ -180,6 +178,7 @@ const ConnectedCounter = owl.connect(Counter, mapStoreToProps);
const counter = new ConnectedCounter({ store, qweb }); const counter = new ConnectedCounter({ store, qweb });
``` ```
```xml ```xml
<button t-name="Counter" t-on-click="increment"> <button t-name="Counter" t-on-click="increment">
Click Me! [<t t-esc="props.value"/>] Click Me! [<t t-esc="props.value"/>]
@@ -187,6 +186,7 @@ const counter = new ConnectedCounter({ store, qweb });
``` ```
The arguments of `connect` are: The arguments of `connect` are:
- `Counter`: an owl `Component` to connect - `Counter`: an owl `Component` to connect
- `mapStoreToProps`: a function that extracts the `props` of the Component - `mapStoreToProps`: a function that extracts the `props` of the Component
from the `state` of the `Store` and returns them as a dict from the `state` of the `Store` and returns them as a dict
+5 -5
View File
@@ -18,7 +18,9 @@ not ready yet, resolved directly otherwise). If called with a callback as
argument, it executes it as soon as the DOM ready (or directly). argument, it executes it as soon as the DOM ready (or directly).
```js ```js
Promise.all([loadTemplates(), owl.utils.whenReady()]).then(function ([templates]) { Promise.all([loadTemplates(), owl.utils.whenReady()]).then(function([
templates
]) {
const qweb = new owl.QWeb(templates); const qweb = new owl.QWeb(templates);
const app = new App({ qweb }); const app = new App({ qweb });
app.mount(document.body); app.mount(document.body);
@@ -33,7 +35,6 @@ owl.utils.whenReady(function() {
}); });
``` ```
## `loadJS` ## `loadJS`
`loadJS` takes a url (string) for a javascript resource, and loads it. It returns `loadJS` takes a url (string) for a javascript resource, and loads it. It returns
@@ -44,7 +45,7 @@ prevent doing twice the work.
```js ```js
class MyComponent extends owl.Component { class MyComponent extends owl.Component {
willStart() { willStart() {
return owl.utils.loadJS('/static/libs/someLib.js'); return owl.utils.loadJS("/static/libs/someLib.js");
} }
} }
``` ```
@@ -53,7 +54,7 @@ class MyComponent extends owl.Component {
```js ```js
async function makeEnv() { async function makeEnv() {
const templates = await owl.utils.loadTemplates('templates.xml'); const templates = await owl.utils.loadTemplates("templates.xml");
const qweb = new owl.QWeb(templates); const qweb = new owl.QWeb(templates);
return { qweb }; return { qweb };
} }
@@ -61,5 +62,4 @@ async function makeEnv() {
## `escape` ## `escape`
## `debounce` ## `debounce`
-3
View File
@@ -5,7 +5,6 @@ tree, and Owl will translate that to a list of imperative operations. This
translation is done by a virtual dom. This is the low level layer of Owl, most translation is done by a virtual dom. This is the low level layer of Owl, most
developer will not need to call directly the virtual dom functions. developer will not need to call directly the virtual dom functions.
The main idea behind a virtual dom is to keep a in-memory representation of the The main idea behind a virtual dom is to keep a in-memory representation of the
DOM (called a virtual node), and whenever some change is needed, to regenerate DOM (called a virtual node), and whenever some change is needed, to regenerate
a new representation, compute the difference between the old and the new, then a new representation, compute the difference between the old and the new, then
@@ -17,5 +16,3 @@ apply the changes.
- `patch`: compare two virtual nodes, and apply the difference. - `patch`: compare two virtual nodes, and apply the difference.
Note: Owl's virtual dom is a fork of [snabbdom](https://github.com/snabbdom/snabbdom). Note: Owl's virtual dom is a fork of [snabbdom](https://github.com/snabbdom/snabbdom).