From b39315b0e516225ac0c82c6e7039717ab4e8e07e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksander=20=C5=9Awitalski?= Date: Tue, 16 Jul 2019 11:22:52 +0200 Subject: [PATCH] Support derived attributes --- src/core/browser.js | 66 ++++++++++++++++++++++++++++++++++--- src/core/diff.js | 17 ++++++---- test/diff-calculate.spec.js | 6 ++-- test/server.js | 2 ++ 4 files changed, 77 insertions(+), 14 deletions(-) diff --git a/src/core/browser.js b/src/core/browser.js index 8a00ea0e..b94ff480 100644 --- a/src/core/browser.js +++ b/src/core/browser.js @@ -193,6 +193,9 @@ limitations under the License. 'select', 'textarea', ], + { + derived: true, + }, ], [ 'autoPlay', @@ -213,6 +216,9 @@ limitations under the License. [ 'input', ], + { + derived: true, + }, ], [ 'challenge', @@ -233,6 +239,9 @@ limitations under the License. 'command', 'input', ], + { + derived: true, + }, ], [ 'cite', @@ -348,6 +357,9 @@ limitations under the License. 'select', 'textarea', ], + { + derived: true, + }, ], [ 'download', @@ -463,6 +475,9 @@ limitations under the License. [ 'input', ], + { + derived: true, + }, ], [ 'inputMode', @@ -594,6 +609,9 @@ limitations under the License. 'input', 'select', ], + { + derived: true, + }, ], [ 'muted', @@ -601,6 +619,9 @@ limitations under the License. 'audio', 'video', ], + { + derived: true, + }, ], [ 'name', @@ -626,6 +647,9 @@ limitations under the License. [ 'form', ], + { + derived: true, + }, ], [ 'open', @@ -684,6 +708,9 @@ limitations under the License. 'input', 'textarea', ], + { + derived: true, + }, ], [ 'rel', @@ -700,6 +727,9 @@ limitations under the License. 'select', 'textarea', ], + { + derived: true, + }, ], [ 'reversed', @@ -746,6 +776,9 @@ limitations under the License. [ 'option', ], + { + derived: true, + }, ], [ 'shape', @@ -760,6 +793,9 @@ limitations under the License. 'input', 'select', ], + { + derived: true, + }, ], [ 'sizes', @@ -884,6 +920,10 @@ limitations under the License. 'progress', 'param', ], + { + derived: true, + normalize: false, + }, ], [ 'width', @@ -1050,8 +1090,16 @@ limitations under the License. ]; const supportedAttributes = new Map(); - for (const [key, whitelist] of SUPPORTED_ATTRIBUTES) { - supportedAttributes.set(key, whitelist || '*'); + const derivedAttributes = []; + for (const [key, whitelist, config] of SUPPORTED_ATTRIBUTES) { + const options = { + whitelist: whitelist || '*', + config: config || {}, + }; + supportedAttributes.set(key, options); + if (config && config.derived) { + derivedAttributes.push(key); + } } const Browser = { @@ -1060,14 +1108,22 @@ limitations under the License. return supportedAttributes.has(key); }, + isAttributeDerived(key) { + return derivedAttributes.includes(key); + }, + isAttributeValid(key, element) { - const whitelist = supportedAttributes.get(key); - if (whitelist) { - return whitelist === '*' || whitelist.includes(element); + const options = supportedAttributes.get(key); + if (options) { + return options.whitelist === '*' || options.whitelist.includes(element); } return false; }, + getDerivedAttributes() { + return derivedAttributes; + }, + getValidElementNamesFor(key) { return supportedAttributes.get(key); }, diff --git a/src/core/diff.js b/src/core/diff.js index 7ded0f9c..4d1dff0f 100644 --- a/src/core/diff.js +++ b/src/core/diff.js @@ -237,14 +237,19 @@ limitations under the License. const changed = attrs.filter( attr => nextAttrs.includes(attr) && current[attr] !== next[attr]); - for (let attr of added) { - this.addPatch(Patch.setAttribute(attr, next[attr], target, isCustom)); + for (let attr of added.concat(changed)) { + if (opr.Toolkit.Browser.isAttributeDerived(attr)) { + this.addPatch(Patch.setProperty(attr, next[attr], target)); + } else { + this.addPatch(Patch.setAttribute(attr, next[attr], target, isCustom)); + } } for (let attr of removed) { - this.addPatch(Patch.removeAttribute(attr, target, isCustom)); - } - for (let attr of changed) { - this.addPatch(Patch.setAttribute(attr, next[attr], target, isCustom)); + if (opr.Toolkit.Browser.isAttributeDerived(attr)) { + this.addPatch(Patch.deleteProperty(attr, target)); + } else { + this.addPatch(Patch.removeAttribute(attr, target, isCustom)); + } } } diff --git a/test/diff-calculate.spec.js b/test/diff-calculate.spec.js index 60a8c84d..a508f702 100644 --- a/test/diff-calculate.spec.js +++ b/test/diff-calculate.spec.js @@ -77,7 +77,7 @@ describe('Diff => calculate patches', () => { const nextTemplate = [ 'input', { - value: 'next', + title: 'foobar', }, ]; @@ -90,8 +90,8 @@ describe('Diff => calculate patches', () => { assert.equal(patches.length, 2); assert.equal(patches[0].type, Patch.Type.SET_ATTRIBUTE); assert(patches[0].target.isElement()); - assert.equal(patches[0].name, 'value'); - assert.equal(patches[0].value, 'next'); + assert.equal(patches[0].name, 'title'); + assert.equal(patches[0].value, 'foobar'); assertUpdatesNode(patches[1], element); }); diff --git a/test/server.js b/test/server.js index 478a5951..b96d4253 100644 --- a/test/server.js +++ b/test/server.js @@ -8,6 +8,8 @@ const PORT = 3033; app.set('port', PORT); app.use('/', express.static('test')); +app.use('/functional', express.static('test/functional')); +app.use('/introspector', express.static('test/web/introspector')); app.use('/config', express.static('test/config')); app.use('/src', express.static('src')); app.use('/core', express.static('src/core'));