From 6e1e69bcce4eec3311a0a3d85e51ed735cd1cec0 Mon Sep 17 00:00:00 2001 From: Viktar Donich Date: Mon, 22 Jan 2018 14:08:21 -0800 Subject: [PATCH] Update endpoint params on registered elements Whenever endpoint-provided value changes, update corresponding attribute on the plugin provided element. With this change, plugins can receive updates to the parameters if that's needed. To take advantage of this change, plugin has few options: - use a Polymer observers or computed properties - use `plugin.attributeHelper(element).bind(propertyName, callback)` Bug: Issue 8162 Change-Id: Ie95f30dd8d840be62cb3370bf39de96672638fd7 --- Documentation/pg-plugin-dev.txt | 8 +++- .../gr-attribute-helper.js | 12 ++++++ .../gr-endpoint-decorator.js | 12 ++++-- .../gr-endpoint-decorator_test.html | 18 +++++++++ .../app/samples/bind-parameters.html | 37 +++++++++++++++++++ 5 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 polygerrit-ui/app/samples/bind-parameters.html diff --git a/Documentation/pg-plugin-dev.txt b/Documentation/pg-plugin-dev.txt index fc704a1b21..ff32309a06 100644 --- a/Documentation/pg-plugin-dev.txt +++ b/Documentation/pg-plugin-dev.txt @@ -150,7 +150,13 @@ The low-level DOM API methods are the base of all UI customization. === attributeHelper `plugin.attributeHelper(element)` -Note: TODO +Alternative for +link:https://www.polymer-project.org/1.0/docs/devguide/data-binding[Polymer data +binding] for plugins that don't use Polymer. Can be used to bind element +attribute changes to callbacks. + +See `samples/bind-parameters.html` for examples on both Polymer data bindings +and `attibuteHelper` usage. === eventHelper `plugin.eventHelper(element)` diff --git a/polygerrit-ui/app/elements/plugins/gr-attribute-helper/gr-attribute-helper.js b/polygerrit-ui/app/elements/plugins/gr-attribute-helper/gr-attribute-helper.js index 301c12e48a..8db59b5f6d 100644 --- a/polygerrit-ui/app/elements/plugins/gr-attribute-helper/gr-attribute-helper.js +++ b/polygerrit-ui/app/elements/plugins/gr-attribute-helper/gr-attribute-helper.js @@ -83,5 +83,17 @@ return this._promises[name]; }; + /** + * Sets value and dispatches event to force notify. + * + * @param {string} name Property name. + * @param {?} value + */ + GrAttributeHelper.prototype.set = function(name, value) { + this.element[name] = value; + this.element.dispatchEvent( + new CustomEvent(this._getChangedEventName(name), {detail: {value}})); + }; + window.GrAttributeHelper = GrAttributeHelper; })(window); diff --git a/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator.js b/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator.js index 5e558ec3ae..16dd8c4ce2 100644 --- a/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator.js +++ b/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator.js @@ -72,10 +72,14 @@ if (opt_content) { el.content = opt_content; } - const expectProperties = this._getEndpointParams().map( - paramEl => plugin.attributeHelper(paramEl).get('value') - .then(value => el[paramEl.getAttribute('name')] = value) - ); + const expectProperties = this._getEndpointParams().map(paramEl => { + const helper = plugin.attributeHelper(paramEl); + const paramName = paramEl.getAttribute('name'); + return helper.get('value').then( + value => helper.bind('value', + value => plugin.attributeHelper(el).set(paramName, value)) + ); + }); let timeoutId; const timeout = new Promise( resolve => timeoutId = setTimeout(() => { diff --git a/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator_test.html b/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator_test.html index cfebc95209..ae6c4b8da2 100644 --- a/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator_test.html +++ b/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator_test.html @@ -148,5 +148,23 @@ limitations under the License. }); }); }); + + test('param is bound', done => { + const element = + container.querySelector('gr-endpoint-decorator[name="banana"]'); + const param = Polymer.dom(element).querySelector('gr-endpoint-param'); + const value1 = {abc: 'def'}; + const value2 = {def: 'abc'}; + param.value = value1; + plugin.registerCustomComponent('banana', 'noob-noob'); + flush(() => { + const module = Polymer.dom(element.root).children.find( + element => element.nodeName === 'NOOB-NOOB'); + assert.strictEqual(module['someParam'], value1); + param.value = value2; + assert.strictEqual(module['someParam'], value2); + done(); + }); + }); }); diff --git a/polygerrit-ui/app/samples/bind-parameters.html b/polygerrit-ui/app/samples/bind-parameters.html new file mode 100644 index 0000000000..dc7a87a984 --- /dev/null +++ b/polygerrit-ui/app/samples/bind-parameters.html @@ -0,0 +1,37 @@ + + + + + + + +