Opera XPath issue

D

David Mark

I had heard that some strains Opera 9.x had some XPath quirks. I
thought one of my users had run into one of them and I'd have to
accelerate my schedule of beefing up the XPath fork's feature testing,
but it turned out he ran into the mother of all of them.

Simply put, a commented SCRIPT element in the HEAD of a valid HTML
document kills XPath completely. Can't find anything, not the body, not
the documentElement, nothing. (!) It could be any comment that does it.
I didn't bother investigating as I had wasted enough time up until I
removed the commented SCRIPT.

I'm definitely going to report that beauty to Opera. That will be easy
enough to feature test; but, for the moment, be forewarned.

I suppose I should have my head examined for putting an XPath fork in
the query module, but it's been a rock up until today. Watch that first
quirk, doc; it's a doozey! :)
 
D

David Mark

kangax said:
Strange. I'm not able to reproduce it.

Either I misunderstood something, or it's some other version of Opera
9.x (in between). I tested successfully on 9.0, 9.27, 9.50, and 9.64,
using this test case (all on Mac OS X):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>xpath opera test</title>
<!--
<script type="text/javascript">alert(1)</script>
-->

It was more like:-

<!--<script type="text/javascript" href="mylib-min.js"></script>-->

I'll post an example when I have a chance. It could be that only
certain structures cause the problem. Haven't put together my report
for Opera yet.
</head>
<body>
<script type="text/javascript">
if (!document.evaluate) {
document.write('document.evaluate is missing');
}
else {
document.write(
document.evaluate(
"//body",
document,
null,
XPathResult.ANY_TYPE,
null
).iterateNext());

That's more or less what was failing. Regardless, removing the
commented script made it work again. Putting it back in would make it
fail to find anytbing (body, html, whatever).
 
D

David Mark

David said:
Oops, src of course. :)

Or maybe like this:

<!--<script type="text/javascript" src="mylib-min.js">--><script
type="text/javascript" src="mylib.js"></script>

Figures, I can't reproduce it now. I do know it was an FF-saved ("full"
option) site, so the paths were very screwy (unlike above example) but I
also know I ran it through validation without issue (with the offending
comment in place). It was driving me nuts until I started eliminating
variables. First one I removed was the commented SCRIPT element and
bingo! Put it back in and back to futility. IIRC, it was every 9.x and
10.x Opera on my system (XP) that demonstrated the issue (couldn't find
anything at all with document.evaluate).

Maybe I won't report it after all (they will likely ignore it without a
test page). But, make no mistake, there is an inexplicable bug in their
XPath implementation, related to comments in the HEAD.
 
D

David Mark

David said:
Or maybe like this:

<!--<script type="text/javascript" src="mylib-min.js">--><script
type="text/javascript" src="mylib.js"></script>

Figures, I can't reproduce it now. I do know it was an FF-saved ("full"
option) site, so the paths were very screwy (unlike above example) but I
also know I ran it through validation without issue (with the offending
comment in place). It was driving me nuts until I started eliminating
variables. First one I removed was the commented SCRIPT element and
bingo! Put it back in and back to futility. IIRC, it was every 9.x and
10.x Opera on my system (XP) that demonstrated the issue (couldn't find
anything at all with document.evaluate).

Maybe I won't report it after all (they will likely ignore it without a
test page). But, make no mistake, there is an inexplicable bug in their
XPath implementation, related to comments in the HEAD.

And just ran into another one. This one was just missing:-

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

....and putting that in fixed it. You can see it in action here:-

http://code.eblackwelder.com/demos/MyWidgetsLibrary/MyTabs/index.html

....at least until I let the author know to add the missing META. Is
Opera ever picky when it comes to XPath. Of course, it isn't a good
idea to leave off that META (as the W3C validation service will tell you).

The author of the example didn't even (knowingly) use a query. My
getEBCN has the one freaking line of code in the entire library that
calls getEBCS (never the QSA version though as it is an external
adapter). I was always on the fence as to whether I wanted to do that
(call getEBCS internally). I didn't want to add a third fork for the
host-provided gEBCN at the time as it was too new. And I would rather
not have to duplicate the loop and check code that is already in the
query module. But then, it is sort of lame to make getEBCN available
only as part of the query module (something I could address on the
server side). Like XHTML support, I need to add a flag (and eventually
a build option) to disable (or exclude) the XPath forks.

The moral of this story is: validate your markup, especially when using
black box libraries (mine qualifies as that of course, but at least
there is _one_ person who understands what is going on inside it). The
other moral is: test in Opera (at least the latest version). It's a
very solid browser and normally not a problem, but it can expose issues
that may be covered up by the others (and apparently has some screwy
XPath problems).
 
D

David Mark

David said:
And just ran into another one. This one was just missing:-

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

...and putting that in fixed it. You can see it in action here:-

http://code.eblackwelder.com/demos/MyWidgetsLibrary/MyTabs/index.html

...at least until I let the author know to add the missing META. Is
Opera ever picky when it comes to XPath. Of course, it isn't a good
idea to leave off that META (as the W3C validation service will tell you).

The author of the example didn't even (knowingly) use a query. My
getEBCN has the one freaking line of code in the entire library that
calls getEBCS (never the QSA version though as it is an external
adapter). I was always on the fence as to whether I wanted to do that
(call getEBCS internally). I didn't want to add a third fork for the
host-provided gEBCN at the time as it was too new. And I would rather
not have to duplicate the loop and check code that is already in the
query module. But then, it is sort of lame to make getEBCN available
only as part of the query module (something I could address on the
server side). Like XHTML support, I need to add a flag (and eventually
a build option) to disable (or exclude) the XPath forks.

That coming to mind was no coincidence. The docs (on my site) explain
what is going with both issues. It's that $%# isXmlParseMode method,
which is thoroughly unforgiving and lacking any real robustness (it
should really be attempting to create a namespaced element rather than
just looking at the createElementNS method and noting whether the user
included an appropriate META or not). Still, that contract is
documented (should probably have a big red star next to it or
something). The first cited failure was because the META was included
at the end of the HEAD (not above the TITLE where it belongs). The
unforgiving part is good (both users will now know to always when and
where to include this META). The lack of robustness is very bad.

And I don't know what the hell the commented script had to do with it.
Somehow it was getting between the script and the META. Just another
reason to do a controlled ditching of the XHTML nonsense.

And the latter cited example has been fixed, though it turns out it was
nothing to see. The former still has the problem:-

http://www.souagil.com.br/gabriel/myimagegallery/

Though because queries are not involved at this point, it doesn't appear
that it is having any problems. The reason queries are a problem is
because the XPath code tacks on the html namespace when XHTML is
"detected". D'oh! Honestly, I'm not even sure if that is necessary for
the default namespace. I'll find out soon enough as I am getting ready
to pit up XHTML versions of SlickSpeed, as well as unit tests for XML
queries (e.g. XHR results, created XML documents, etc.)

So do as I say, not as I did. :) In other words, I know having XHTML
support in there is largely useless (today) and have been bit by trying
to automatically detect it a few times. It's a remnant. The docs
indicate how to disable it and the builder will optionally filter that
crap when I get back to it. Like deferAudio, the default is backwards.
I'll deal with those issues before I call it a release.
 
D

David Mark

kangax said:
David said:
David Mark wrote: [...]
And just ran into another one. This one was just missing:-

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

...and putting that in fixed it. You can see it in action here:-

http://code.eblackwelder.com/demos/MyWidgetsLibrary/MyTabs/index.html

...at least until I let the author know to add the missing META. Is
Opera ever picky when it comes to XPath. Of course, it isn't a good
idea to leave off that META (as the W3C validation service will tell
you).

The author of the example didn't even (knowingly) use a query. My
getEBCN has the one freaking line of code in the entire library that
calls getEBCS (never the QSA version though as it is an external
adapter). I was always on the fence as to whether I wanted to do that
(call getEBCS internally). I didn't want to add a third fork for the
host-provided gEBCN at the time as it was too new. And I would rather
not have to duplicate the loop and check code that is already in the
query module. But then, it is sort of lame to make getEBCN available
only as part of the query module (something I could address on the
server side). Like XHTML support, I need to add a flag (and eventually
a build option) to disable (or exclude) the XPath forks.

That coming to mind was no coincidence. The docs (on my site) explain
what is going with both issues. It's that $%# isXmlParseMode method,
which is thoroughly unforgiving and lacking any real robustness (it
should really be attempting to create a namespaced element rather than
just looking at the createElementNS method and noting whether the user
included an appropriate META or not). Still, that contract is
documented (should probably have a big red star next to it or
something). The first cited failure was because the META was included
at the end of the HEAD (not above the TITLE where it belongs). The
unforgiving part is good (both users will now know to always when and
where to include this META). The lack of robustness is very bad.

So does `document.evaluate` failure have to do with position of
content-type/charset META in regards to TITLE, or is it some encoding
issue related to content-type sniffing and META positioned low in the
HEAD? Or was META missing completely?

Not a thing. :)

http://www.cinsoft.net/mylib-doc.asp#isxmlparsemode

I misdiagnosed it because I was sure that the commented script was the
issue. No excuse, but I was pretty harried with IM's at the time. It's
been freaking _crazy_ around here since about two or three weeks ago.
I've actually taken to paying part time workers just to deal with My
Library questions. It appears the tipping point has arrived (and I
clearly wasn't quite ready for it).
I'm not completely following.

Likely due to my bad lead. :)
I can imagine XHTML being useful in closed environments, when dealing
with SVG or MathML. As you know, it's all about context.

It can be useful. But automatically "detecting" it is problematic at
best. I had considered doing something like what you did on your test
page, but ISTM that some browsers might throw an exception (and
try-catch is not allowed in the lower levels of the core). The obvious
solution is to make it a build time decision. I made the necessary
changes a couple of months ago, but haven't updated the back end since then.
 
D

David Mark

David said:
kangax said:
David Mark wrote:
David Mark wrote: [...]
And just ran into another one. This one was just missing:-

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

...and putting that in fixed it. You can see it in action here:-

http://code.eblackwelder.com/demos/MyWidgetsLibrary/MyTabs/index.html

...at least until I let the author know to add the missing META. Is
Opera ever picky when it comes to XPath. Of course, it isn't a good
idea to leave off that META (as the W3C validation service will tell
you).

The author of the example didn't even (knowingly) use a query. My
getEBCN has the one freaking line of code in the entire library that
calls getEBCS (never the QSA version though as it is an external
adapter). I was always on the fence as to whether I wanted to do that
(call getEBCS internally). I didn't want to add a third fork for the
host-provided gEBCN at the time as it was too new. And I would rather
not have to duplicate the loop and check code that is already in the
query module. But then, it is sort of lame to make getEBCN available
only as part of the query module (something I could address on the
server side). Like XHTML support, I need to add a flag (and eventually
a build option) to disable (or exclude) the XPath forks.

That coming to mind was no coincidence. The docs (on my site) explain
what is going with both issues. It's that $%# isXmlParseMode method,
which is thoroughly unforgiving and lacking any real robustness (it
should really be attempting to create a namespaced element rather than
just looking at the createElementNS method and noting whether the user
included an appropriate META or not). Still, that contract is
documented (should probably have a big red star next to it or
something). The first cited failure was because the META was included
at the end of the HEAD (not above the TITLE where it belongs). The
unforgiving part is good (both users will now know to always when and
where to include this META). The lack of robustness is very bad.
So does `document.evaluate` failure have to do with position of
content-type/charset META in regards to TITLE, or is it some encoding
issue related to content-type sniffing and META positioned low in the
HEAD? Or was META missing completely?

Not a thing. :)

Referring to your "what does it have to do with" query. As for the
latter two queries, both happened. One user left it out of their
example and the other had it after the script. Imagine my chagrin to
see their otherwise fine efforts failing in Opera. D'oh!
 
D

David Mark

David said:
David said:
kangax said:
On 3/27/10 6:51 PM, David Mark wrote:
David Mark wrote:
David Mark wrote:
[...]
And just ran into another one. This one was just missing:-

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

...and putting that in fixed it. You can see it in action here:-

http://code.eblackwelder.com/demos/MyWidgetsLibrary/MyTabs/index.html

...at least until I let the author know to add the missing META. Is
Opera ever picky when it comes to XPath. Of course, it isn't a good
idea to leave off that META (as the W3C validation service will tell
you).

The author of the example didn't even (knowingly) use a query. My
getEBCN has the one freaking line of code in the entire library that
calls getEBCS (never the QSA version though as it is an external
adapter). I was always on the fence as to whether I wanted to do that
(call getEBCS internally). I didn't want to add a third fork for the
host-provided gEBCN at the time as it was too new. And I would rather
not have to duplicate the loop and check code that is already in the
query module. But then, it is sort of lame to make getEBCN available
only as part of the query module (something I could address on the
server side). Like XHTML support, I need to add a flag (and eventually
a build option) to disable (or exclude) the XPath forks.

That coming to mind was no coincidence. The docs (on my site) explain
what is going with both issues. It's that $%# isXmlParseMode method,
which is thoroughly unforgiving and lacking any real robustness (it
should really be attempting to create a namespaced element rather than
just looking at the createElementNS method and noting whether the user
included an appropriate META or not). Still, that contract is
documented (should probably have a big red star next to it or
something). The first cited failure was because the META was included
at the end of the HEAD (not above the TITLE where it belongs). The
unforgiving part is good (both users will now know to always when and
where to include this META). The lack of robustness is very bad.
So does `document.evaluate` failure have to do with position of
content-type/charset META in regards to TITLE, or is it some encoding
issue related to content-type sniffing and META positioned low in the
HEAD? Or was META missing completely?
Not a thing. :)

Referring to your "what does it have to do with" query. As for the
latter two queries, both happened. One user left it out of their
example and the other had it after the script. Imagine my chagrin to
see their otherwise fine efforts failing in Opera. D'oh!

And sorry for the confusion about the TITLE. The SCRIPT is what matters
(i.e. it must come after the appropriate META). In my mind, the SCRIPT
follows the TITLE, but that is irrelevant to the issue.
 
D

David Mark

David said:
David said:
David said:
kangax wrote:
On 3/27/10 6:51 PM, David Mark wrote:
David Mark wrote:
David Mark wrote:
[...]
And just ran into another one. This one was just missing:-

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

...and putting that in fixed it. You can see it in action here:-

http://code.eblackwelder.com/demos/MyWidgetsLibrary/MyTabs/index.html

...at least until I let the author know to add the missing META. Is
Opera ever picky when it comes to XPath. Of course, it isn't a good
idea to leave off that META (as the W3C validation service will tell
you).

The author of the example didn't even (knowingly) use a query. My
getEBCN has the one freaking line of code in the entire library that
calls getEBCS (never the QSA version though as it is an external
adapter). I was always on the fence as to whether I wanted to do that
(call getEBCS internally). I didn't want to add a third fork for the
host-provided gEBCN at the time as it was too new. And I would rather
not have to duplicate the loop and check code that is already in the
query module. But then, it is sort of lame to make getEBCN available
only as part of the query module (something I could address on the
server side). Like XHTML support, I need to add a flag (and eventually
a build option) to disable (or exclude) the XPath forks.

That coming to mind was no coincidence. The docs (on my site) explain
what is going with both issues. It's that $%# isXmlParseMode method,
which is thoroughly unforgiving and lacking any real robustness (it
should really be attempting to create a namespaced element rather than
just looking at the createElementNS method and noting whether the user
included an appropriate META or not). Still, that contract is
documented (should probably have a big red star next to it or
something). The first cited failure was because the META was included
at the end of the HEAD (not above the TITLE where it belongs). The
unforgiving part is good (both users will now know to always when and
where to include this META). The lack of robustness is very bad.
So does `document.evaluate` failure have to do with position of
content-type/charset META in regards to TITLE, or is it some encoding
issue related to content-type sniffing and META positioned low in the
HEAD? Or was META missing completely?
Not a thing. :)
Referring to your "what does it have to do with" query. As for the
latter two queries, both happened. One user left it out of their
example and the other had it after the script. Imagine my chagrin to
see their otherwise fine efforts failing in Opera. D'oh!

And sorry for the confusion about the TITLE. The SCRIPT is what matters
(i.e. it must come after the appropriate META). In my mind, the SCRIPT
follows the TITLE, but that is irrelevant to the issue.

The builder is updated. XHTML support can now be filtered at build
time. That is what I should have done in the first place, but the
original My Library (server and client side) was more of a furious
stream-of-consciousness than an actual design. Thanks to my
indifference to marketing it over the years, the user base is still
small enough for me to mold it into something better (getting there).

The button that launches the XHTML test page is disabled when this
support is filtered; but, of course, that can be "fooled" by disabling
scripting or using a browser that doesn't disable buttons dynamically
(e.g. Opera 6, NN4). If you fool it, the XHTML test page issues a
warning at the top that you are trying to test XHTML, but the build is
lacking XHTML support. But, for the most part, it doesn't seem to make
any difference (i.e. the test page still works). The notable exception
(as discussed in this thread) is the query module in XPath-capable
browsers. This can be demonstrated by fooling the test page and running
the unit tests in an XPath-capable browser (most modern standards-based
browsers have it). All but the query tests pass. This confirms that
the XPath query fork was correct to add the html namespace to its
expressions (as failing to do so results in failure in at least some
XHTML DOM's). I thought I had a reason to do that, but couldn't
remember as it has been too long since I wrote it and my commenting on
the original code was fairly non-existent (something else I am
addressing now). The problem that arose was that XML parse mode was
being falsely identified due to page authors breaking the documented
contract related to the Content-Type META (is the last resort fallback
for the isXmlParseMode test). With this new build option, authors can
ignore that contract without being bitten by false positives.

If you are wondering how the XHTML test page can (mostly) work without
XHTML support, it is because My Library only deals with the (default)
HTML namespace. However, the next update to the query module, which
adds support for XML DOM's (e.g. XHR results) will add support for other
namespaces. Of course, the XML DOM support is unrelated to XHTML support.

For those who wish to forget all of these details, follow the
recommendation on the new builder and *exclude* XHTML support. If you
don't follow the preceding discussion, you definitely don't need such
support. If you use the full build from the Downloads page, you can
disable XHTML support by setting an API property:-

var API = { disableXmlParseMode:true };

See:-

http://www.cinsoft.net/mylib-doc.asp#isxmlparsemode

On a slightly related note, users of the full build are advised to set
the deferAudio property in the same way. I will change the default for
that one (needs to be true) in the near future.

var API = { disableXmlParseMode:true, deferAudio:true };

This keeps audio plug-ins from being initialized on load (definitely
something to avoid in most cases). Should definitely be used for those
who seek to run query unit tests as well as the initialization adds two
OBJECT's to the DOM.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top