PDA

View Full Version : [OPEN-418][3.0.0] el.ownerDocument.createRange() error in IE8



thospfuller
23 Sep 2009, 5:36 AM
Folks,

I'm using IE8 and Ext.js version 3.0.0 and I'm getting the following complaint when I try to render my page:

range = el.ownerDocument.createRange();
(Object doesn't support this property or method.)

I've been looking through the forums and came across this thread, dating December 2007:

http://www.extjs.com/forum/showthread.php?t=77500

The proposed solution of adding an empty span just below the body works:

<body>
<span></span>

however when the page renders I'm getting an error, only in Internet Explorer
"Line: 7 Error: 'Ext' is undefined"

but the page does render correctly.

So I want to ask: is this considered a defect and has it been fixed in Ext.js version 3.1?

The span solution is simple, however it forces changes on other developers in my team that are going to be using the components I develop, so if there's a fix or better solution to this problem, I'd appreciate it if you could let me know.

Thanks,

Tom

Animal
23 Sep 2009, 5:45 AM
The simplest fix is something like



range = (el.nodeType == 1 ? el : el.parentNode).ownerDocument.createRange();

Animal
23 Sep 2009, 5:47 AM
That's in DomQuery's public interface, so the full context is



insertHtml : function(where, el, html){
var hash = {},
hashVal,
setStart,
range,
frag,
rangeEl,
rs;

where = where.toLowerCase();
// add these here because they are used in both branches of the condition.
hash[beforebegin] = ['BeforeBegin', 'previousSibling'];
hash[afterend] = ['AfterEnd', 'nextSibling'];

if (document.body.insertAdjacentHTML) {
if(tableRe.test(el.tagName) && (rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html))){
return rs;
}
// add these two to the hash.
hash[afterbegin] = ['AfterBegin', 'firstChild'];
hash[beforeend] = ['BeforeEnd', 'lastChild'];
if ((hashVal = hash[where])) {
el.insertAdjacentHTML(hashVal[0], html);
return el[hashVal[1]];
}
} else {
range = (el.nodeType == 1 ? el : el.parentNode).ownerDocument.createRange();
setStart = 'setStart' + (/end/i.test(where) ? 'After' : 'Before');
if (hash[where]) {
range[setStart](el);
frag = range.createContextualFragment(html);
el.parentNode.insertBefore(frag, where == beforebegin ? el : el.nextSibling);
return el[(where == beforebegin ? 'previous' : 'next') + 'Sibling'];
} else {
rangeEl = (where == afterbegin ? 'first' : 'last') + 'Child';
if (el.firstChild) {
range[setStart](el[rangeEl]);
frag = range.createContextualFragment(html);
if(where == afterbegin){
el.insertBefore(frag, el.firstChild);
}else{
el.appendChild(frag);
}
} else {
el.innerHTML = html;
}
return el[rangeEl];
}
}
throw 'Illegal insertion point -> "' + where + '"';
},

Animal
23 Sep 2009, 5:56 AM
That's no good.

It will have to temporarily wrap a text node in a span just for the duration...

thospfuller
23 Sep 2009, 5:58 AM
That's no good.

It will have to temporarily wrap a text node in a span just for the duration...

I was just about to say...:)

Animal
23 Sep 2009, 6:04 AM
Yeach! There has to be a better way than this:



insertHtml : function(where, el, html){
var hash = {},
hashVal,
setStart,
range,
frag,
rangeEl,
rs,
result,
needsWrapping = el.nodeType != 1,
wrapSpan,
unwrap = Ext.emptyFn;

if (needsWrapping) {
wrapSpan = el.parentNode.insertBefore(document.createElement('span'), el);
wrapSpan.appendChild(el);
el = wrapSpan;
unwrap = function() {
wrapSpan.parentNode.insertBefore(wrapSpan.firstChild, wrapSpan);
wrapSpan.parentNode.removeChild(wrapSpan);
}
}

where = where.toLowerCase();
// add these here because they are used in both branches of the condition.
hash[beforebegin] = ['BeforeBegin', 'previousSibling'];
hash[afterend] = ['AfterEnd', 'nextSibling'];

if (el.insertAdjacentHTML) {
if(tableRe.test(el.tagName) && (rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html))){
return rs;
}
// add these two to the hash.
hash[afterbegin] = ['AfterBegin', 'firstChild'];
hash[beforeend] = ['BeforeEnd', 'lastChild'];
if ((hashVal = hash[where])) {
el.insertAdjacentHTML(hashVal[0], html);
result = el[hashVal[1]];
unwrap();
return result;
}
} else {
range = (el.nodeType == 1 ? el : el.parentNode).ownerDocument.createRange();
setStart = 'setStart' + (/end/i.test(where) ? 'After' : 'Before');
if (hash[where]) {
range[setStart](el);
frag = range.createContextualFragment(html);
el.parentNode.insertBefore(frag, where == beforebegin ? el : el.nextSibling);
result = el[(where == beforebegin ? 'previous' : 'next') + 'Sibling'];
unwrap();
return result;
} else {
rangeEl = (where == afterbegin ? 'first' : 'last') + 'Child';
if (el.firstChild) {
range[setStart](el[rangeEl]);
frag = range.createContextualFragment(html);
if(where == afterbegin){
el.insertBefore(frag, el.firstChild);
}else{
el.appendChild(frag);
}
} else {
el.innerHTML = html;
}
result = el[rangeEl];
unwrap();
return result;
}
}
throw 'Illegal insertion point -> "' + where + '"';
},

thospfuller
23 Sep 2009, 6:07 AM
Yeach!

You're not kidding mate!

Tom

thospfuller
25 Sep 2009, 6:06 AM
range = el.ownerDocument.createRange(); (Object doesn't support this property or method.)

The problem I had was that I included both of the following files in an html page, when only one is required:

<script type="text/javascript" src="./js/ext/ext-all.js"></script>
<script type="text/javascript" src="./js/ext/ext-all-debug.js"></script>

I removed ext-all.js and the problem went away.

Tom

hashira
5 Oct 2009, 7:03 PM
Animal, thanks for that fix.

It works except that insertChild is not a DOM method. Using appendChild() instead worked fine though.

I wonder if this will be fixed in a future version of ExtJS....

jerrybrown5
12 Jan 2010, 11:04 AM
Animal, thanks for that fix.

It works except that insertChild is not a DOM method. Using appendChild() instead worked fine though.

I wonder if this will be fixed in a future version of ExtJS....

I came across this as well and Nigel's bug fix worked with that one appendChild update. +1 for getting this fixed from Ext.

Animal
12 Jan 2010, 11:17 AM
Animal, thanks for that fix.

It works except that insertChild is not a DOM method.



No but insertBefore is which was probably what I meant.

http://www.w3.org/TR/DOM-Level-3-Core/ecma-script-binding.html

jerrybrown5
12 Jan 2010, 2:59 PM
No but insertBefore is which was probably what I meant.

http://www.w3.org/TR/DOM-Level-3-Core/ecma-script-binding.html


I'll have to rebuild my js files to retest with insertBefore but I can confirm that your update with appendChild passed all of our production tests. Thanks again for the fix! You are the equalizer to that hopeless browser. :)

realjax
20 Jan 2010, 12:03 AM
Problem is STILL there in 3.1.. :-?

dolittle
29 Jan 2010, 4:08 PM
bump

aconran
2 Feb 2010, 1:12 PM
Could some of the people which are encountering this problem post a testcase for our testing?

jerrybrown5
2 Feb 2010, 2:35 PM
Could some of the people which are encountering this problem post a testcase for our testing?

Aaron,

I haven't narrowed it down to a test case format but you if you don't have anything better you can use this production site that has the fix applied. You'll just need to remove the fix and run it with pretty much any version of IE. It will error out before Render is complete.

http://mountainres.parkcitymountain.com/

Regards,
Jerry

dolittle
5 Apr 2010, 5:32 AM
It happens to me with FF, not sure about IE.
I can't reproduce it yet because I have a very big app and in some point tons of errors starts firing.
It didn't happen in previous 3.x versions.
Will Animal code fix it?