In safari 3.1.1, when $element is not attached to the document the following calls:
Code:
var $range = $element.ownerDocument.createRange();
$range.setStartBefore($element);
$range.setStartAfter($element.lastChild);
fails with RangeException: "INVALID_NODE_TYPE_ERR: DOM Range Exception 2"
So for safari and not attached element I write the following fix:
Code:
/**
* Inserts an HTML fragment into the DOM.
* @param {String} where Where to insert the html in relation to el - beforeBegin, afterBegin, beforeEnd, afterEnd.
* @param {HTMLElement} el The context element
* @param {String} html The HTML fragmenet
* @return {HTMLElement} The new node
*/
Ext.DomHelper.insertHtml = (function() {
var insertHtmlOld = Ext.DomHelper.insertHtml;
function isAttached( $element ) {
var $body = $element.ownerDocument.body;
while ($element != null && $element != $body) {
$element = $element.parentNode;
}
return $element != null;
}
function isHackApplicable( $element, $exception ) {
if (!RangeException || !RangeException["INVALID_NODE_TYPE_ERR"]) {
return false;
}
if (!($exception instanceof RangeException)) {
return false;
}
if ($exception.code != RangeException["INVALID_NODE_TYPE_ERR"]) {
return false;
}
if (!Ext.isSafari) {
return false;
}
if (isAttached($element)) {
return false;
}
return true;
}
return function( $where, $element, $html ) {
var $exception;
try {
return insertHtmlOld.apply(Ext.DomHelper, arguments);
} catch ($e) {
$exception = $e;
}
/**
* In safari 3.1.1, when $element is not attached to the document the following calls:
* var $range = $element.ownerDocument.createRange();
* $range.setStartBefore($element);
* $range.setStartAfter($element.lastChild);
*
* always fails with RangeException:
* "INVALID_NODE_TYPE_ERR: DOM Range Exception 2"
*
* So for safari and not attached element the following fix was written
*/
if (isHackApplicable($element, $exception)) {
var $div = document.createElement("DIV");
$div.innerHTML = $html;
switch ($where.toLowerCase()) {
case "beforebegin":
while ($div.childNodes.length > 0) {
$element.parentNode.insertBefore($div.childNodes[0], $element);
}
return $element.previousSibling;
case "beforeend":
while ($div.childNodes.length > 0) {
$element.appendChild($div.childNodes[0]);
}
return $element.lastChild;
}
}
$html = $html.length > 60 ? $html.substr(0, 57) + "..." : $html;
Ext.console.error("insertHtml("
+ "\"" + $where + "\""
+ ", \"" + $element.nodeName.toLowerCase() + "\""
+ ", \"" + $html.replace(/(["\\])/g, "\\$1") + "\""
+ ") failed with exception:\n" + $exception);
/** If hack is not applicable - throw original exception */
throw $exception;
};
})();