From 1abba1da6ef4545cc73f76e46c83e8fe6e3a0543 Mon Sep 17 00:00:00 2001 From: Stefan Penner Date: Wed, 27 May 2015 16:05:50 -0700 Subject: [PATCH] Ensure the form attribute is set using setAttribute for tags where it has no setter. --- packages/dom-helper/lib/prop.js | 28 ++++++++++++++++++--- packages/dom-helper/tests/prop-test.js | 35 ++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 packages/dom-helper/tests/prop-test.js diff --git a/packages/dom-helper/lib/prop.js b/packages/dom-helper/lib/prop.js index 8268cfad..adb76da1 100644 --- a/packages/dom-helper/lib/prop.js +++ b/packages/dom-helper/lib/prop.js @@ -2,22 +2,42 @@ export function isAttrRemovalValue(value) { return value === null || value === undefined; } +function UNDEFINED() {} // TODO should this be an o_create kind of thing? export var propertyCaches = {}; + +var FORM_REQUIRES_SET_ATTRIBUTE_BY_TAG = { + SELECT: true, + OPTION: true, + INPUT: true, + TEXTAREA: true, + BUTTON: true, + LABEL: true, + FIELDSET: true, + LEGEND: true, + OBJECT: true +}; + export function normalizeProperty(element, attrName) { var tagName = element.tagName; var key; var cache = propertyCaches[tagName]; - if (!cache) { + + if (cache === undefined) { // TODO should this be an o_create kind of thing? cache = {}; + for (key in element) { - cache[key.toLowerCase()] = key; + if (key === 'form' && FORM_REQUIRES_SET_ATTRIBUTE_BY_TAG[tagName]) { + cache[key] = UNDEFINED; + } else { + cache[key.toLowerCase()] = key; + } } propertyCaches[tagName] = cache; } - // presumes that the attrName has been lowercased. - return cache[attrName]; + var value = cache[attrName]; + return value === UNDEFINED ? undefined : value; } diff --git a/packages/dom-helper/tests/prop-test.js b/packages/dom-helper/tests/prop-test.js new file mode 100644 index 00000000..1a36229e --- /dev/null +++ b/packages/dom-helper/tests/prop-test.js @@ -0,0 +1,35 @@ +import { normalizeProperty } from 'dom-helper/prop'; + +QUnit.module('dom-helper prop'); + +function tag(tagName) { + return document.createElement(tagName); +} + +var scenario = [ + ['div', 'id', 'id'], + ['select', 'form', undefined], + ['div', 'form', undefined], + ['select', 'labels', 'labels'], + ['select', 'options', 'options'], + ['select', 'selectIndex', undefined], + ['select', 'selectedOptions', undefined], + ['select', 'type', 'type'], + ['select', 'validationMessage', undefined], + ['select', 'validity', 'validity'], + ['select', 'willValidate', undefined] +]; + +if (typeof document === 'object') { + test('it throws when instantiated without document', function(){ + scenario.forEach(function(test, index) { + var tagName = test[0]; + var propertyName = test[1]; + var expected = test[2]; + var element = tag(tagName); + var actual = normalizeProperty(element, propertyName); + + equal(actual, expected, '[scenario:' + index + '] expected: ' + tagName + '[' + propertyName+ '] to normalize to: ' + expected + ' but got: ' + actual); + }); + }); +}