Fix issue where Opera 9.x returns incorrect results on certain Selector queries with descendant combinators. [#395 state:resolved] (Arpan, fearphage, kangax, Andrew Dupont)

This commit is contained in:
Andrew Dupont 2009-02-28 04:41:55 -06:00
parent ee56c93f16
commit 26eaa4300b
3 changed files with 53 additions and 16 deletions

View File

@ -1,6 +1,8 @@
* Fix issue where Opera 9.x returns incorrect results on certain Selector queries with descendant combinators. [#395 state:resolved] (Arpan, fearphage, kangax, Andrew Dupont)
* Null out references to elements in cache on page unload. Need this in addition to the Event#stopObserving calls to clean up memory leaks. [#425 state:resolved] (ykphuah, mr_justin, Andrew Dupont)
* Ensure `toString` and `valueOf` properties are copied to a subclass only when necessary in IE6. [@382 state:resolved] (Samuel Lebeau)
* Ensure `toString` and `valueOf` properties are copied to a subclass only when necessary in IE6. [#382 state:resolved] (Samuel Lebeau)
* Make sure `getAttribute` is used without flag when accessing the "type" attribute of an iframe (IE throws error otherwise). [#118 state:resolved] (Zekid, kangax)

View File

@ -18,23 +18,50 @@ var Selector = Class.create({
},
shouldUseXPath: function() {
if (!Prototype.BrowserFeatures.XPath) return false;
shouldUseXPath: (function() {
var e = this.expression;
// Safari 3 chokes on :*-of-type and :empty
if (Prototype.Browser.WebKit &&
(e.include("-of-type") || e.include(":empty")))
return false;
// Some versions of Opera 9.x produce incorrect results when using XPath
// with descendant combinators.
// see: http://opera.remcol.ath.cx/bugs/index.php?action=bug&id=652
var IS_DESCENDANT_SELECTOR_BUGGY = (function(){
var isBuggy = false;
if (document.evaluate && window.XPathResult) {
var el = document.createElement('div');
el.innerHTML = '<ul><li></li></ul><div><ul><li></li></ul></div>';
var xpath = ".//*[local-name()='ul' or local-name()='UL']" +
"//*[local-name()='li' or local-name()='LI']";
var result = document.evaluate(xpath, el, null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
isBuggy = (result.snapshotLength !== 2);
el = null;
}
return isBuggy;
})();
// XPath can't do namespaced attributes, nor can it read
// the "checked" property from DOM nodes
if ((/(\[[\w-]*?:|:checked)/).test(e))
return false;
return function() {
if (!Prototype.BrowserFeatures.XPath) return false;
return true;
},
var e = this.expression;
// Safari 3 chokes on :*-of-type and :empty
if (Prototype.Browser.WebKit &&
(e.include("-of-type") || e.include(":empty")))
return false;
// XPath can't do namespaced attributes, nor can it read
// the "checked" property from DOM nodes
if ((/(\[[\w-]*?:|:checked)/).test(e))
return false;
if (IS_DESCENDANT_SELECTOR_BUGGY) return false;
return true;
}
})(),
shouldUseSelectorsAPI: function() {
if (!Prototype.BrowserFeatures.SelectorsAPI) return false;

View File

@ -88,7 +88,7 @@ new Test.Unit.Runner({
},
testSelectorWithAttributeContainingDash: function() {
this.assertEnumEqual([$('attr_with_dash')], $$('[foo-bar]'));
this.assertEnumEqual([$('attr_with_dash')], $$('[foo-bar]'), "attribute with hyphen");
},
testSelectorWithUniversalAndHyphenTokenizedAttributeValue: function() {
@ -392,5 +392,13 @@ new Test.Unit.Runner({
var b = $('dupContainer').down('#dupL4');
this.assertEqual(a, b);
},
testDescendantSelectorBuggy: function() {
var el = document.createElement('div');
el.innerHTML = '<ul><li></li></ul><div><ul><li></li></ul></div>';
document.body.appendChild(el);
this.assertEqual(2, $(el).select('ul li').length);
document.body.removeChild(el);
}
});