diff --git a/addons/web_editor/static/src/js/editor/snippets.options.js b/addons/web_editor/static/src/js/editor/snippets.options.js index 19e69958884..75eae90896d 100644 --- a/addons/web_editor/static/src/js/editor/snippets.options.js +++ b/addons/web_editor/static/src/js/editor/snippets.options.js @@ -76,6 +76,31 @@ function _buildRowElement(title, options) { return groupEl; } +/** + * Creates a proxy for an object where one property is replaced by a different + * value. This value is captured in the closure and can be read and written to. + * + * @param {Object} obj - the object for which to create a proxy + * @param {string} propertyName - the name/key of the property to replace + * @param {*} value - the initial value to give to the property's copy + * @returns {Proxy} a proxy of the object with the property replaced + */ +function createPropertyProxy(obj, propertyName, value) { + return new Proxy(obj, { + get: function (obj, prop) { + if (prop === propertyName) { + return value; + } + return obj[prop]; + }, + set: function (obj, prop, val) { + if (prop === propertyName) { + return (value = val); + } + return Reflect.set(...arguments); + }, + }); +} //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: @@ -1330,7 +1355,18 @@ const SnippetOptionWidget = Widget.extend({ const methodsNames = widget.getMethodsNames(); const proms = methodsNames.map(async methodName => { - const value = await this._computeWidgetState(methodName, widget.getMethodsParams(methodName)); + const params = widget.getMethodsParams(methodName); + + let obj = this; + if (params.applyTo) { + const $firstSubTarget = this.$(params.applyTo).eq(0); + if (!$firstSubTarget.length) { + return; + } + obj = createPropertyProxy(this, '$target', $firstSubTarget); + } + + const value = await this._computeWidgetState.call(obj, methodName, params); if (value === undefined) { return; } @@ -1575,7 +1611,18 @@ const SnippetOptionWidget = Widget.extend({ } widget.getMethodsNames().forEach(methodName => { - this[methodName](previewMode, widget.getValue(methodName), widget.getMethodsParams(methodName)); + const widgetValue = widget.getValue(methodName); + const params = widget.getMethodsParams(methodName); + + if (params.applyTo) { + const $subTargets = this.$(params.applyTo); + _.each($subTargets, subTargetEl => { + const proxy = createPropertyProxy(this, '$target', $(subTargetEl)); + this[methodName].call(proxy, previewMode, widgetValue, params); + }); + } else { + this[methodName](previewMode, widgetValue, params); + } }); if (!previewMode) {