mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[IMP] owl: update to v0.10.0
This commit is contained in:
@@ -6,7 +6,8 @@
|
|||||||
* - emit events
|
* - emit events
|
||||||
* - add/remove listeners.
|
* - add/remove listeners.
|
||||||
*
|
*
|
||||||
* This is a useful pattern of communication in some cases.
|
* This is a useful pattern of communication in many cases. For OWL, each
|
||||||
|
* components and stores are event buses.
|
||||||
*/
|
*/
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// EventBus
|
// EventBus
|
||||||
@@ -64,9 +65,27 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Owl Observer
|
||||||
|
*
|
||||||
|
* This code contains the logic that allows Owl to observe and react to state
|
||||||
|
* changes.
|
||||||
|
*
|
||||||
|
* This is a Observer class that can observe any JS values. The way it works
|
||||||
|
* can be summarized thusly:
|
||||||
|
* - primitive values are not observed at all
|
||||||
|
* - Objects are observed by replacing all their keys with getters/setters
|
||||||
|
* (recursively)
|
||||||
|
* - Arrays are observed by replacing their prototype with a customized version,
|
||||||
|
* which wrap some methods to allow the tracking of each state change.
|
||||||
|
*
|
||||||
|
* Note that this code is inspired by Vue.
|
||||||
|
*/
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Observer
|
// Modified Array prototype
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
// we define here a new modified Array prototype, which basically override all
|
||||||
|
// Array methods that change some state to be able to track their changes
|
||||||
const methodsToPatch = [
|
const methodsToPatch = [
|
||||||
"push",
|
"push",
|
||||||
"pop",
|
"pop",
|
||||||
@@ -108,6 +127,9 @@
|
|||||||
return initialMethod.call(this, ...args);
|
return initialMethod.call(this, ...args);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Observer
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
class Observer {
|
class Observer {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.rev = 1;
|
this.rev = 1;
|
||||||
@@ -194,6 +216,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Owl VDOM
|
||||||
|
*
|
||||||
|
* This file contains an implementation of a virtual DOM, which is a system that
|
||||||
|
* can generate in-memory representations of a DOM tree, compare them, and
|
||||||
|
* eventually change a concrete DOM tree to match its representation, in an
|
||||||
|
* hopefully efficient way.
|
||||||
|
*
|
||||||
|
* Note that this code is a fork of Snabbdom, slightly tweaked/optimized for our
|
||||||
|
* needs (see https://github.com/snabbdom/snabbdom).
|
||||||
|
*
|
||||||
|
* The main exported values are:
|
||||||
|
* - interface VNode
|
||||||
|
* - h function (a helper function to generate a vnode)
|
||||||
|
* - patch function (to apply a vnode to an actual DOM node)
|
||||||
|
*/
|
||||||
function vnode(sel, data, children, text, elm) {
|
function vnode(sel, data, children, text, elm) {
|
||||||
let key = data === undefined ? undefined : data.key;
|
let key = data === undefined ? undefined : data.key;
|
||||||
return {
|
return {
|
||||||
@@ -1009,28 +1047,29 @@
|
|||||||
if (!this.__owl__.isMounted) {
|
if (!this.__owl__.isMounted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const shouldCallPatchHooks = !patchQueue;
|
const shouldPatch = !patchQueue;
|
||||||
if (shouldCallPatchHooks) {
|
if (shouldPatch) {
|
||||||
patchQueue = [];
|
patchQueue = [];
|
||||||
}
|
}
|
||||||
const renderVDom = this._render(force, patchQueue);
|
const renderVDom = this._render(force, patchQueue);
|
||||||
const renderId = this.__owl__.renderId;
|
const renderId = this.__owl__.renderId;
|
||||||
const vnode = await renderVDom;
|
await renderVDom;
|
||||||
if (this.__owl__.isMounted && renderId === this.__owl__.renderId) {
|
if (shouldPatch &&
|
||||||
|
this.__owl__.isMounted &&
|
||||||
|
renderId === this.__owl__.renderId) {
|
||||||
// we only update the vnode and the actual DOM if no other rendering
|
// we only update the vnode and the actual DOM if no other rendering
|
||||||
// occurred between now and when the render method was initially called.
|
// occurred between now and when the render method was initially called.
|
||||||
if (shouldCallPatchHooks) {
|
for (let i = 0; i < patchQueue.length; i++) {
|
||||||
for (let i = 0; i < patchQueue.length; i++) {
|
const patch = patchQueue[i];
|
||||||
const c = patchQueue[i];
|
patch.push(patch[0].willPatch());
|
||||||
c.__owl__.willPatchVal = c.willPatch();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this._patch(vnode);
|
for (let i = 0; i < patchQueue.length; i++) {
|
||||||
if (shouldCallPatchHooks) {
|
const patch = patchQueue[i];
|
||||||
for (let i = patchQueue.length - 1; i >= 0; i--) {
|
patch[0]._patch(patch[1]);
|
||||||
const c = patchQueue[i];
|
}
|
||||||
c.patched(c.__owl__.willPatchVal);
|
for (let i = patchQueue.length - 1; i >= 0; i--) {
|
||||||
}
|
const patch = patchQueue[i];
|
||||||
|
patch[0].patched(patch[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1094,17 +1133,13 @@
|
|||||||
if (shouldUpdate) {
|
if (shouldUpdate) {
|
||||||
await this.willUpdateProps(nextProps);
|
await this.willUpdateProps(nextProps);
|
||||||
this.props = nextProps;
|
this.props = nextProps;
|
||||||
await this.render(false, patchQueue);
|
await this.render(forceUpdate, patchQueue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_patch(vnode) {
|
_patch(vnode) {
|
||||||
this.__owl__.renderPromise = null;
|
this.__owl__.renderPromise = null;
|
||||||
if (this.__owl__.vnode) {
|
const target = this.__owl__.vnode || document.createElement(vnode.sel);
|
||||||
this.__owl__.vnode = patch(this.__owl__.vnode, vnode);
|
this.__owl__.vnode = patch(target, vnode);
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.__owl__.vnode = patch(document.createElement(vnode.sel), vnode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_prepare() {
|
_prepare() {
|
||||||
this.__owl__.renderProps = this.props;
|
this.__owl__.renderProps = this.props;
|
||||||
@@ -1125,11 +1160,12 @@
|
|||||||
return this._render();
|
return this._render();
|
||||||
}
|
}
|
||||||
async _render(force = false, patchQueue = []) {
|
async _render(force = false, patchQueue = []) {
|
||||||
if (this.__owl__.isMounted) {
|
|
||||||
patchQueue.push(this);
|
|
||||||
}
|
|
||||||
this.__owl__.renderId++;
|
this.__owl__.renderId++;
|
||||||
const promises = [];
|
const promises = [];
|
||||||
|
const patch = [this];
|
||||||
|
if (this.__owl__.isMounted) {
|
||||||
|
patchQueue.push(patch);
|
||||||
|
}
|
||||||
if (this.__owl__.observer) {
|
if (this.__owl__.observer) {
|
||||||
this.__owl__.observer.allowMutations = false;
|
this.__owl__.observer.allowMutations = false;
|
||||||
}
|
}
|
||||||
@@ -1139,6 +1175,7 @@
|
|||||||
forceUpdate: force,
|
forceUpdate: force,
|
||||||
patchQueue
|
patchQueue
|
||||||
});
|
});
|
||||||
|
patch.push(vnode);
|
||||||
if (this.__owl__.observer) {
|
if (this.__owl__.observer) {
|
||||||
this.__owl__.observer.allowMutations = true;
|
this.__owl__.observer.allowMutations = true;
|
||||||
}
|
}
|
||||||
@@ -1179,6 +1216,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Owl Utils
|
||||||
|
*
|
||||||
|
* We have here a small collection of utility functions:
|
||||||
|
*
|
||||||
|
* - escape
|
||||||
|
* - memoize
|
||||||
|
* - debounce
|
||||||
|
* - patch
|
||||||
|
* - unpatch
|
||||||
|
* - loadTemplates
|
||||||
|
* - loadJS
|
||||||
|
* - whenReady
|
||||||
|
* - parseXML
|
||||||
|
*/
|
||||||
function escape(str) {
|
function escape(str) {
|
||||||
if (str === undefined) {
|
if (str === undefined) {
|
||||||
return "";
|
return "";
|
||||||
@@ -1888,6 +1940,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Owl QWeb Directives
|
||||||
|
*
|
||||||
|
* This file contains the implementation of most standard QWeb directives:
|
||||||
|
* - t-esc
|
||||||
|
* - t-raw
|
||||||
|
* - t-set/t-value
|
||||||
|
* - t-if/t-elif/t-else
|
||||||
|
* - t-call
|
||||||
|
* - t-foreach/t-as
|
||||||
|
* - t-debug
|
||||||
|
* - t-log
|
||||||
|
*/
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// t-esc and t-raw
|
// t-esc and t-raw
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -2152,6 +2217,17 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Owl QWeb Extensions
|
||||||
|
*
|
||||||
|
* This file contains the implementation of non standard QWeb directives, added
|
||||||
|
* by Owl and that will only work on Owl projects:
|
||||||
|
*
|
||||||
|
* - t-on
|
||||||
|
* - t-ref
|
||||||
|
* - t-transition
|
||||||
|
* - t-widget/t-props/t-keepalive
|
||||||
|
*/
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// t-on
|
// t-on
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -2259,9 +2335,9 @@
|
|||||||
QWeb.addDirective({
|
QWeb.addDirective({
|
||||||
name: "transition",
|
name: "transition",
|
||||||
priority: 96,
|
priority: 96,
|
||||||
atNodeCreation({ ctx, value }) {
|
atNodeCreation({ ctx, value, nodeID }) {
|
||||||
let name = value;
|
let name = value;
|
||||||
ctx.addLine(`p${ctx.parentNode}.hook = {
|
ctx.addLine(`p${nodeID}.hook = {
|
||||||
create: (_, n) => {
|
create: (_, n) => {
|
||||||
this.utils.transitionCreate(n.elm, '${name}');
|
this.utils.transitionCreate(n.elm, '${name}');
|
||||||
},
|
},
|
||||||
@@ -2324,8 +2400,7 @@
|
|||||||
ctx.addLine(`let isNew${widgetID} = !w${widgetID};`);
|
ctx.addLine(`let isNew${widgetID} = !w${widgetID};`);
|
||||||
// check if we can reuse current rendering promise
|
// check if we can reuse current rendering promise
|
||||||
ctx.addIf(`w${widgetID} && w${widgetID}.__owl__.renderPromise`);
|
ctx.addIf(`w${widgetID} && w${widgetID}.__owl__.renderPromise`);
|
||||||
ctx.addIf(`w${widgetID}.__owl__.vnode`);
|
ctx.addIf(`w${widgetID}.__owl__.isStarted`);
|
||||||
// ctx.addIf(`w${widgetID}.__owl__.isStarted`);
|
|
||||||
ctx.addLine(`def${defID} = w${widgetID}._updateProps(props${widgetID}, extra.forceUpdate, extra.patchQueue);`);
|
ctx.addLine(`def${defID} = w${widgetID}._updateProps(props${widgetID}, extra.forceUpdate, extra.patchQueue);`);
|
||||||
ctx.addElse();
|
ctx.addElse();
|
||||||
ctx.addLine(`isNew${widgetID} = true`);
|
ctx.addLine(`isNew${widgetID} = true`);
|
||||||
@@ -2422,10 +2497,18 @@
|
|||||||
this.observer.notifyCB = this.trigger.bind(this, "update");
|
this.observer.notifyCB = this.trigger.bind(this, "update");
|
||||||
this.observer.allowMutations = false;
|
this.observer.allowMutations = false;
|
||||||
this.observer.observe(this.state);
|
this.observer.observe(this.state);
|
||||||
|
this.getters = {};
|
||||||
if (this.debug) {
|
if (this.debug) {
|
||||||
this.history.push({ state: this.state });
|
this.history.push({ state: this.state });
|
||||||
}
|
}
|
||||||
this.set = this.observer.set.bind(this.observer);
|
this.set = this.observer.set.bind(this.observer);
|
||||||
|
for (let entry of Object.entries(config.getters || {})) {
|
||||||
|
const name = entry[0];
|
||||||
|
const func = entry[1];
|
||||||
|
this.getters[name] = payload => {
|
||||||
|
return func({ state: this.state, getters: this.getters }, payload);
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dispatch(action, payload) {
|
dispatch(action, payload) {
|
||||||
if (!this.actions[action]) {
|
if (!this.actions[action]) {
|
||||||
@@ -2435,7 +2518,8 @@
|
|||||||
commit: this.commit.bind(this),
|
commit: this.commit.bind(this),
|
||||||
dispatch: this.dispatch.bind(this),
|
dispatch: this.dispatch.bind(this),
|
||||||
env: this.env,
|
env: this.env,
|
||||||
state: this.state
|
state: this.state,
|
||||||
|
getters: this.getters
|
||||||
}, payload);
|
}, payload);
|
||||||
if (result instanceof Promise) {
|
if (result instanceof Promise) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@@ -2453,7 +2537,8 @@
|
|||||||
const res = this.mutations[type].call(null, {
|
const res = this.mutations[type].call(null, {
|
||||||
commit: this.commit.bind(this),
|
commit: this.commit.bind(this),
|
||||||
state: this.state,
|
state: this.state,
|
||||||
set: this.set
|
set: this.set,
|
||||||
|
getters: this.getters
|
||||||
}, payload);
|
}, payload);
|
||||||
if (this._commitLevel === 1) {
|
if (this._commitLevel === 1) {
|
||||||
this.observer.allowMutations = false;
|
this.observer.allowMutations = false;
|
||||||
@@ -2515,7 +2600,7 @@
|
|||||||
constructor(parent, props) {
|
constructor(parent, props) {
|
||||||
const env = parent instanceof Component ? parent.env : parent;
|
const env = parent instanceof Component ? parent.env : parent;
|
||||||
const ownProps = Object.assign({}, props || {});
|
const ownProps = Object.assign({}, props || {});
|
||||||
const storeProps = mapStateToProps(env.store.state, ownProps);
|
const storeProps = mapStateToProps(env.store.state, ownProps, env.store.getters);
|
||||||
const mergedProps = Object.assign({}, props || {}, storeProps);
|
const mergedProps = Object.assign({}, props || {}, storeProps);
|
||||||
super(parent, mergedProps);
|
super(parent, mergedProps);
|
||||||
this.__owl__.ownProps = ownProps;
|
this.__owl__.ownProps = ownProps;
|
||||||
@@ -2544,7 +2629,7 @@
|
|||||||
}
|
}
|
||||||
_checkUpdate() {
|
_checkUpdate() {
|
||||||
const ownProps = this.__owl__.ownProps;
|
const ownProps = this.__owl__.ownProps;
|
||||||
const storeProps = mapStateToProps(this.env.store.state, ownProps);
|
const storeProps = mapStateToProps(this.env.store.state, ownProps, this.env.store.getters);
|
||||||
const options = {
|
const options = {
|
||||||
currentStoreProps: this.__owl__.currentStoreProps
|
currentStoreProps: this.__owl__.currentStoreProps
|
||||||
};
|
};
|
||||||
@@ -2566,7 +2651,7 @@
|
|||||||
}
|
}
|
||||||
_updateProps(nextProps, forceUpdate, patchQueue) {
|
_updateProps(nextProps, forceUpdate, patchQueue) {
|
||||||
if (this.__owl__.ownProps !== nextProps) {
|
if (this.__owl__.ownProps !== nextProps) {
|
||||||
this.__owl__.currentStoreProps = mapStateToProps(this.env.store.state, nextProps);
|
this.__owl__.currentStoreProps = mapStateToProps(this.env.store.state, nextProps, this.env.store.getters);
|
||||||
}
|
}
|
||||||
this.__owl__.ownProps = nextProps;
|
this.__owl__.ownProps = nextProps;
|
||||||
const mergedProps = Object.assign({}, nextProps, this.__owl__.currentStoreProps);
|
const mergedProps = Object.assign({}, nextProps, this.__owl__.currentStoreProps);
|
||||||
@@ -2576,6 +2661,12 @@
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file is the main file packaged by rollup (see rollup.config.js). From
|
||||||
|
* this file, we export all public owl elements.
|
||||||
|
*
|
||||||
|
* Note that dynamic values, such as a date or a commit hash are added by rollup
|
||||||
|
*/
|
||||||
const utils = _utils;
|
const utils = _utils;
|
||||||
|
|
||||||
exports.utils = utils;
|
exports.utils = utils;
|
||||||
@@ -2586,9 +2677,9 @@
|
|||||||
exports.connect = connect;
|
exports.connect = connect;
|
||||||
exports.Store = Store;
|
exports.Store = Store;
|
||||||
|
|
||||||
exports._version = '0.9.0';
|
exports._version = '0.10.0';
|
||||||
exports._date = '2019-05-07T18:51:30.761Z';
|
exports._date = '2019-05-10T10:19:55.109Z';
|
||||||
exports._hash = 'edc7d2b';
|
exports._hash = 'e04c5b1';
|
||||||
exports._url = 'https://github.com/odoo/owl';
|
exports._url = 'https://github.com/odoo/owl';
|
||||||
|
|
||||||
}(this.owl = this.owl || {}));
|
}(this.owl = this.owl || {}));
|
||||||
|
|||||||
Reference in New Issue
Block a user