PDA

View Full Version : [FIXED] SYNTAX_ERR: DOM Exception 12



skirtle
29 Oct 2011, 5:14 AM
I'm getting the following error (in Chrome):


Uncaught Error: SYNTAX_ERR: DOM Exception 12 ext-all-debug.js:9876
Ext.define.Ext.getElementById ext-all-debug.js:9876
garbageCollect ext-all-debug.js:12984

I see it after a couple of minutes clicking around in my UI. Everything is fine using 4.0.6.

I've done some limited investigation and it seems the problem is on this line:


el = detachedBodyEl.dom.querySelector('#' + id);

A bit of digging shows that the id in this case is a number. It seems that trying to use querySelector using a numeric id doesn't work. These ids are being injected automatically by the framework, not by me.

I haven't got a concrete test case yet and it looks like it's going to be a real pain to extract one. I will do it if required but I'd like to get confirmation that this is not a known issue before I spend any more time on it. It seems to have something do with destroying trigger fields but it's probably much more subtle than that because as far as I can tell the elements that have numeric ids are part of my surrounding HTML, not part of the field itself.

skirtle
23 Dec 2011, 3:52 PM
I've explained this one, mistake in my app's code. Not sure why it wasn't failing in previous versions though.

dongryphon
23 Dec 2011, 9:18 PM
I've explained this one, mistake in my app's code. Not sure why it wasn't failing in previous versions though.

That is odd because we were using this to support Ext.getDetachedBody in 4.1 PR1 I believe. This use of DomQuery is relatively new though and it does not like id's that don't conform. Technically you are correct that they are invalid id's in the DOM (e.g., CSS cannot select on them either), but getElelemtById is able to handle them. I will take a peek because we don't want JS errors even with bad id's in play.

Thanks for digging in so quickly!

skirtle
24 Dec 2011, 8:57 AM
In case anyone comes across this thread in future and wonders what my mistake was, it looks like this:


var ids = Ext.Array.map(elements, Ext.id, Ext);

I was trying to grab an array of the ids of the elements. Figuring out why this results in some elements having all-numeric ids I'll leave as an exercise to the reader... I thought it was kinda fun.

tvanzoelen
27 Dec 2011, 1:49 AM
Ext 4.1 beta. Getting this error too. But I don't use skirtles Ext.map thing.

If you have any hint where to start searching, don't mind telling me.

It's in this function


Ext.fly = function() {
return AbstractElement.fly.apply(AbstractElement, arguments);
};
(function (proto) {
proto.destroy = proto.remove;
if (document.querySelector) {
proto.getById = function (id, asDom) {
var dom = document.getElementById(id) ||
(validIdRe.test(id) ? this.dom.querySelector('#'+id) : null);
return asDom ? dom : (dom ? Ext.get(dom) : null);
};
} else {
proto.getById = function (id, asDom) {
var dom = document.getElementById(id);
return asDom ? dom : (dom ? Ext.get(dom) : null);
};
}
})(this.prototype);
});


Firebug says: An invalid or illegal string was specified
http://localhost/ASLASIL/ASLASLIB/extjs/ext-all-dev.js?version=3.1.2
Line 10683

So probably that id is something else than a string.

skirtle
27 Dec 2011, 2:12 AM
What's the id that causes the explosion? If you can't find a better way to find it, just hack some extra logging into that function.

My invalid ids looked like this:

18123
28124
38125
...

Once I realized what the pattern was I then put in a conditional breakpoint in Ext.id to break when the prefix was a number... quick check up the stack and I had the culprit.

dongryphon
27 Dec 2011, 3:40 AM
We have a regex to validate the id, but apparently it needs to be a bit stricter. It might also work to enable "break on uncaught exceptions" or "break on all exceptions" and see where you are when the exception occurs.

dongryphon
27 Dec 2011, 3:42 AM
This is issue EXTJSIV-4882 and should be fixed for the next build. Fixed in this case means no exception, but the invalid ID will return a null element.

tvanzoelen
27 Dec 2011, 5:50 AM
The id where it breaks on

0_aslas_statusbar-overflowPadderEl

Prefix is a number. Isn't that allowed?

skirtle
27 Dec 2011, 6:00 AM
Quick test. Type this into the console:


document.body.querySelector('hello');

Returns null (unless you happen to have an element with the id hello).

Now type this:


document.body.querySelector('0hello');

Throws an error.

Seems browsers don't support ids that start with numbers for this method.

tvanzoelen
27 Dec 2011, 6:05 AM
Yes I see it throws an error. Ok this one solved. Unfortunatly I already have the next error. :((

dongryphon
27 Dec 2011, 10:57 AM
Yes, DOM Query is more restrictive on ID syntax.

FYI, this use of DOM query is part of a new mechanism (getDetachedBody) that we use to speed up rendering of hidden items.

It is interesting that you are hitting this because we fallback to DOM query when we are looking for an element given it's ID but that element is not in the document (we try getElementById first which supports any ID value).

Did you remove a component from the page to get this error?

The fix for this (returning null instead of the error) is probably correct because items do not typically move off document to the getDetachedBody - they are completely removed.

tvanzoelen
27 Dec 2011, 11:14 AM
I recently changed all my ids into itemIds. Unfortunatly I had one statusbar component with an id with number prefix. No big problem for me to change that. But this is interesting to know. Probably other users will also run into this problem. Today I started to try 4.1 beta, it was the first error I ran into.

Luckily (for me) skirtle catched it first. That saved me a lot of time.

But dongryphon, this one is really a show-stopper: http://www.sencha.com/forum/showthread.php?167152-Resizers

and

http://www.sencha.com/forum/showthread.php?167183-Resizers-on-TextFields-do-not-work-in-4.1-Beta

There is another related bug on that.

http://www.sencha.com/forum/showthread.php?164913

dongryphon
27 Dec 2011, 11:52 AM
I replied to the textarea + resizer thread, and I agree, it is a critical issue. Do you think there are two issues on that (there are two threads)? They look like the same thing.

tvanzoelen
28 Dec 2011, 12:13 AM
michellsimoens thought that this one http://www.sencha.com/forum/showthread.php?164913 is related to the resizer problem. But problably that opinion is re-evaluated, my bugreport is put back to open.

dongryphon
28 Dec 2011, 2:24 AM
michellsimoens thought that this one http://www.sencha.com/forum/showthread.php?164913 is related to the resizer problem. But problably that opinion is re-evaluated, my bugreport is put back to open.

Yes, there is a bug with resizers on fields and a bug with adding components to a checkboxgroup dynamically I believe. Both are field issues, but I am pretty sure they are different.

dongryphon
28 Dec 2011, 2:24 AM
michellsimoens thought that this one http://www.sencha.com/forum/showthread.php?164913 is related to the resizer problem. But problably that opinion is re-evaluated, my bugreport is put back to open.

Yes, there is a bug with resizers on fields and a bug with adding components to a checkboxgroup dynamically I believe. Both are field issues, but I am pretty sure they are different.

paipai
6 Jan 2012, 2:39 AM
Since I use ExtJS 4.1.b1 my PC freeze or is very slow, I should reboot several time each day.
I found it comes when I leave my app(for example after a F5 to reload my app). After 5 or 10 reload, my browser is out.
When I leave my app, I launch destroy method on all my component. In Ext 4.0.7 it was just fine (no memory leak or so). But since 4.1.b.1 I got this error too:
INVALID_CHARACTER_ERR: DOM Exception 5
When I execute destroy method on my components (a simple component extends from panel).

paipai
6 Jan 2012, 5:04 AM
I found the line where there is an error in my case.



removeCls: function(className) {
var me = this,
dom = me.dom,
len,
elClasses;


if (typeof(className) == 'string') {
// split string on spaces to make an array of className
className = className.replace(trimRe, '').split(spacesRe);
}


if (dom && dom.className && className && !!(len = className.length)) {
if (len == 1 && hasClassList) {
if (className[0]) {
dom.classList.remove(className[0]); // one DOM write


When the error is raised, className[0] equals : x-box-item x-accordion-item

Nobody tried to destroy a panel with an accordion inside ?

paipai
6 Jan 2012, 6:22 AM
I got it.
In my case removeCls is called with an array parameter ["
x-box-item x-accordion-item"]
In the removeCls function the split is done if typeof == string
No split -> DOM Error

Temporary fix, in Layout.js:


afterRemove : function(item) {
var me = this,
el = item.el,
owner = me.owner,
removeClasses = [];


if (item.rendered) {
if (me.itemCls) {
//removeClasses.push(me.itemCls);
el.removeCls(removeClasses);
}
if (owner.itemCls) {
removeClasses.push(owner.itemCls);
}
if (removeClasses.length) {
el.removeCls(removeClasses);
}
}


delete item.ownerLayout;
},



Could you confirm this bug will be fixed in next release ?

jmcolyer
24 Jan 2012, 12:49 PM
I have a similar problem, which appears to be the same root cause. When I have multple classes on a card layout I have the same issue. Ex:
itemCls: 'x-class-1 x-class2'

Now in addCls an object is passed in that looks like this:

["x-class-1 x-class2", "x-class-1 x-class2"] instead of ["x-class-1", "x-class-2"]

Is anyone else seeing this?

jmcolyer
24 Jan 2012, 1:12 PM
I fixed this in my case by explicitly passing in an array.

change itemCls : 'x-class-1 x-class-2' to itemCls: ['x-class-1', 'x-class-2']