From 30c1935cdb6f3a8d850dab8b07a37918740233fb Mon Sep 17 00:00:00 2001 From: Juriy Zaytsev Date: Fri, 20 Mar 2009 17:33:56 -0400 Subject: [PATCH] Fix `writeAttribute` and `readAttribute` failures in IE8. Use proper feature testing when taking care of getAttribute/setAttribute glitches. --- CHANGELOG | 2 + src/dom/dom.js | 105 ++++++++++++++++++++++++++++++++++--------------- 2 files changed, 75 insertions(+), 32 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 83e4ce0..d6373bb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +* Fix `Element#writeAttribute` and `Element#readAttribute` failures in IE8 due to lack of proper feature testing. (kangax) + * Remove sniffing from one of the DOM tests, which produced failures in IE8. (kangax) * Fix `Form.reset` test where `respondsTo` wouldn't detect a method due to typeof returning "object" (rather than "function") in IE (kangax) diff --git a/src/dom/dom.js b/src/dom/dom.js index 1d58343..6ba0765 100644 --- a/src/dom/dom.js +++ b/src/dom/dom.js @@ -1306,42 +1306,83 @@ else if (Prototype.Browser.IE) { return element; }; - Element._attributeTranslations = { - read: { - names: { - 'class': 'className', - 'for': 'htmlFor' - }, - values: { - _getAttr: function(element, attribute) { - return element.getAttribute(attribute, 2); + Element._attributeTranslations = (function(){ + + var classProp = 'className'; + var el = document.createElement('div'); + + // try "className" first (IE <8) + el.setAttribute(classProp, 'x'); + + if (el.className !== 'x') { + + // try "class" (IE 8) + el.setAttribute('class', 'x'); + if (el.className === 'x') { + classProp = 'class'; + } + } + el = null; + + return { + read: { + names: { + 'class': classProp, + 'className': classProp, + 'for': 'htmlFor' }, - _getAttrNode: function(element, attribute) { - var node = element.getAttributeNode(attribute); - return node ? node.value : ""; - }, - _getEv: function(element, attribute) { - attribute = element.getAttribute(attribute); - - // TODO: Need something less ugly here. - if (!attribute) return null; - attribute = attribute.toString(); - attribute = attribute.split('{')[1]; - attribute = attribute.split('}')[0]; - return attribute.strip(); - }, - _flag: function(element, attribute) { - return $(element).hasAttribute(attribute) ? attribute : null; - }, - style: function(element) { - return element.style.cssText.toLowerCase(); - }, - title: function(element) { - return element.title; + values: { + _getAttr: function(element, attribute) { + return element.getAttribute(attribute, 2); + }, + _getAttrNode: function(element, attribute) { + var node = element.getAttributeNode(attribute); + return node ? node.value : ""; + }, + _getEv: (function(){ + + var el = document.createElement('div'); + el.onclick = Prototype.emptyFunction; + var value = el.getAttribute('onclick'); + var f; + + // IE<8 + if (String(value).indexOf('{') > -1) { + // intrinsic event attributes are serialized as `function { ... }` + f = function(element, attribute) { + attribute = element.getAttribute(attribute); + if (!attribute) return null; + attribute = attribute.toString(); + attribute = attribute.split('{')[1]; + attribute = attribute.split('}')[0]; + return attribute.strip(); + } + } + // IE8 + else if (value === '') { + // only function body is serialized + f = function(element, attribute) { + attribute = element.getAttribute(attribute); + if (!attribute) return null; + return attribute.strip(); + } + } + el = null; + return f; + })(), + _flag: function(element, attribute) { + return $(element).hasAttribute(attribute) ? attribute : null; + }, + style: function(element) { + return element.style.cssText.toLowerCase(); + }, + title: function(element) { + return element.title; + } } } } - }; + })(); Element._attributeTranslations.write = { names: Object.extend({