From ba2c26090b9143cf977b771111025dac9b809d3d Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Sun, 8 Mar 2009 18:16:02 -0500 Subject: [PATCH] Remove sniffing from `Element.update` branching in favor of feature detection. [#574 state:resolved] --- CHANGELOG | 2 ++ src/dom/dom.js | 97 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 67 insertions(+), 32 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index f9915da..d1ebe36 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +* Remove sniffing from `Element.update` branching in favor of feature detection. [#574 state:resolved] (kangax) + * Remove sniffing when branching `escapeHTML` and `unescapeHTML`. [#570 state:resolved] (kangax) * Redefine Element#down in IE 6-7 to avoid extending all descendants when no selector is given. [#452 state:resolved] (eno, Andrew Dupont) diff --git a/src/dom/dom.js b/src/dom/dom.js index 6bfa439..679ad7d 100644 --- a/src/dom/dom.js +++ b/src/dom/dom.js @@ -156,15 +156,71 @@ Element.Methods = { * If `newContent` is omitted, the element's content is blanked out (i.e., * replaced with an empty string). **/ - update: function(element, content) { - element = $(element); - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) return element.update().insert(content); - content = Object.toHTML(content); - element.innerHTML = content.stripScripts(); - content.evalScripts.bind(content).defer(); - return element; - }, + update: (function(){ + + // see: http://support.microsoft.com/kb/276228 + var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){ + var el = document.createElement("select"), + isBuggy = true; + el.innerHTML = ""; + if (el.options && el.options[0]) { + isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION"; + } + el = null; + return isBuggy; + })(); + + // see: http://msdn.microsoft.com/en-us/library/ms533897(VS.85).aspx + var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){ + try { + var el = document.createElement("table"); + if (el && el.tBodies) { + el.innerHTML = "test"; + var isBuggy = typeof el.tBodies[0] == "undefined"; + el = null; + return isBuggy; + } + } catch (e) { + return true; + } + })(); + + function update(element, content) { + element = $(element); + + if (content && content.toElement) + content = content.toElement(); + + if (Object.isElement(content)) + return element.update().insert(content); + + content = Object.toHTML(content); + + if (SELECT_ELEMENT_INNERHTML_BUGGY || TABLE_ELEMENT_INNERHTML_BUGGY) { + var tagName = element.tagName.toUpperCase(); + if (tagName in Element._insertionTranslations.tags) { + $A(element.childNodes).each(function(node) { + element.removeChild(node); + }); + Element._getContentFromAnonymousElement(tagName, content.stripScripts()) + .each(function(node) { + element.appendChild(node) + }); + } + else { + element.innerHTML = content.stripScripts(); + } + } + else { + element.innerHTML = content.stripScripts(); + } + + content.evalScripts.bind(content).defer(); + return element; + } + + return update; + })(), /** * Element#replace(@element[, newContent]) -> Element @@ -1392,29 +1448,6 @@ else if (Prototype.Browser.WebKit) { }; } -if (Prototype.Browser.IE || Prototype.Browser.Opera) { - // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements - Element.Methods.update = function(element, content) { - element = $(element); - - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) return element.update().insert(content); - - content = Object.toHTML(content); - var tagName = element.tagName.toUpperCase(); - - if (tagName in Element._insertionTranslations.tags) { - $A(element.childNodes).each(function(node) { element.removeChild(node) }); - Element._getContentFromAnonymousElement(tagName, content.stripScripts()) - .each(function(node) { element.appendChild(node) }); - } - else element.innerHTML = content.stripScripts(); - - content.evalScripts.bind(content).defer(); - return element; - }; -} - if ('outerHTML' in document.createElement('div')) { Element.Methods.replace = function(element, content) { element = $(element);