From 29726e8fd000cb09075f9b6b2a6a8d2ddaf4ef58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Fri, 23 Aug 2019 13:19:24 +0000 Subject: [ADD] web: add owl 1.0.0-beta1 to odoo With this commit, we properly introduce the Owl library into our beloved codebase. More information on the Owl library can be found in the project repository: https://github.com/odoo/owl/ Co-authored-by: Aaron Bohy Co-authored-by: Julien Mougenot Co-authored-by: Mathieu Duckerts-Antoine --- addons/web/static/src/js/core/utils.js | 75 ++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) (limited to 'addons/web/static/src/js/core/utils.js') diff --git a/addons/web/static/src/js/core/utils.js b/addons/web/static/src/js/core/utils.js index 29c2ff04c40..4fe1740d6eb 100644 --- a/addons/web/static/src/js/core/utils.js +++ b/addons/web/static/src/js/core/utils.js @@ -203,7 +203,10 @@ var diacriticsMap = { '\u0225': 'z','\u0240': 'z','\u2C6C': 'z','\uA763': 'z', }; +const patchMap = new WeakMap(); + var utils = { + /** * Throws an error if the given condition is not true * @@ -510,6 +513,51 @@ var utils = { str = "" + str; return new Array(size - str.length + 1).join('0') + str; }, + /** + * Patch a class and return a function that remove the patch + * when called. + * + * @param {Class} C Class to patch + * @param {string} patchName + * @param {Object} patch + * @returns {Function} + */ + patch: function(C, patchName, patch) { + let metadata = patchMap.get(C.prototype); + if (!metadata) { + metadata = { + origMethods: {}, + patches: {}, + current: [] + }; + patchMap.set(C.prototype, metadata); + } + const proto = C.prototype; + if (metadata.patches[patchName]) { + throw new Error(`Patch [${patchName}] already exists`); + } + metadata.patches[patchName] = patch; + applyPatch(proto, patch); + metadata.current.push(patchName); + + function applyPatch(proto, patch) { + Object.keys(patch).forEach(function (methodName) { + const method = patch[methodName]; + if (typeof method === "function") { + const original = proto[methodName]; + if (!(methodName in metadata.origMethods)) { + metadata.origMethods[methodName] = original; + } + proto[methodName] = function (...args) { + this._super = original; + return method.call(this, ...args); + }; + } + }); + } + + return this.unpatch.bind(null, C, patchName); + }, /** * performs a half up rounding with a fixed amount of decimals, correcting for float loss of precision * See the corresponding float_round() in server/tools/float_utils.py for more info @@ -661,6 +709,33 @@ var utils = { }); return casesensetive ? str : str.toLowerCase(); }, + /** + * We define here an unpatch function. This is mostly useful if we want to + * remove a patch. For example, for testing purposes + * + * @param {Class} C + * @param {string} patchName + */ + unpatch: function(C, patchName) { + const proto = C.prototype; + let metadata = patchMap.get(proto); + if (!metdata) { + return; + } + patchMap.delete(proto); + + // reset to original + for (let k in metadata.origMethods) { + proto[k] = metadata.origMethods[k]; + } + + // apply other patches + for (let name of metadata.current) { + if (name !== patchName) { + this.patch(C, name, metadata.patches[name]); + } + } + }, /** * @param {any} node * @param {any} strip_whitespace -- cgit v1.2.3