Skip to content

Commit

Permalink
[BUGFIX] Adds the ability to blacklist props that should use setAttri…
Browse files Browse the repository at this point in the history
…bute because of browser compliance issues, fixes emberjs/ember.js#11112
  • Loading branch information
jayphelps committed May 29, 2015
1 parent 325de7c commit ef08002
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 2 deletions.
32 changes: 30 additions & 2 deletions packages/dom-helper/lib/prop.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ export function isAttrRemovalValue(value) {
return value === null || value === undefined;
}

function UNDEFINED() {}

// TODO should this be an o_create kind of thing?
export var propertyCaches = {};

Expand All @@ -13,11 +15,37 @@ export function normalizeProperty(element, attrName) {
// TODO should this be an o_create kind of thing?
cache = {};
for (key in element) {
cache[key.toLowerCase()] = key;
key = key.toLowerCase();
if (isSettable(element, key)) {
cache[key] = key;
} else {
cache[key] = UNDEFINED;
}
}
propertyCaches[tagName] = cache;
}

// presumes that the attrName has been lowercased.
return cache[attrName];
var value = cache[attrName];
return value === UNDEFINED ? undefined : value;
}

// elements with a property that does not conform to the spec in certain
// browsers. In these cases, we'll end up using setAttribute instead
var badPairs = [{
// phantomjs < 2.0 lets you set it as a prop but won't reflect it
// back to the attribute. button.getAttribute('type') === null
tagName: 'BUTTON',
propName: 'type'
}];

function isSettable(element, attrName) {
for (let i = 0, l = badPairs.length; i < l; i++) {
let pair = badPairs[i];
if (pair.tagName === element.tagName && pair.propName === attrName) {
return false;
}
}

return true;
}
24 changes: 24 additions & 0 deletions packages/dom-helper/tests/prop-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { normalizeProperty } from 'dom-helper/prop';

QUnit.module('dom-helper prop');

test('returns `undefined` for special element properties that are non-compliant in certain browsers', function() {
expect(1);

var badPairs = [{ tagName: 'BUTTON', key: 'type' }];

badPairs.forEach(function (pair) {
var element = {
tagName: pair.tagName
};

Object.defineProperty(element, pair.key, {
set: function () {
throw new Error('I am a bad browser!');
}
});

var actual = normalizeProperty(element, pair.key);
equal(actual, undefined);
});
});

0 comments on commit ef08002

Please sign in to comment.