Bug 1111633 - Unresolved pseudo class. r=bz

This commit is contained in:
Gabor Krizsanits 2015-01-13 19:58:06 +01:00
parent 0ba1d70246
commit 380412f166
11 changed files with 122 additions and 54 deletions

View File

@ -55,6 +55,7 @@ class nsFocusManager;
class nsGlobalWindow; class nsGlobalWindow;
class nsICSSDeclaration; class nsICSSDeclaration;
class nsISMILAttr; class nsISMILAttr;
class nsDocument;
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
@ -398,6 +399,7 @@ private:
friend class mozilla::EventStateManager; friend class mozilla::EventStateManager;
friend class ::nsGlobalWindow; friend class ::nsGlobalWindow;
friend class ::nsFocusManager; friend class ::nsFocusManager;
friend class ::nsDocument;
// Also need to allow Link to call UpdateLinkState. // Also need to allow Link to call UpdateLinkState.
friend class Link; friend class Link;

View File

@ -5844,6 +5844,7 @@ nsDocument::RegisterUnresolvedElement(Element* aElement, nsIAtom* aTypeName)
nsRefPtr<Element>* elem = unresolved->AppendElement(); nsRefPtr<Element>* elem = unresolved->AppendElement();
*elem = aElement; *elem = aElement;
aElement->AddStates(NS_EVENT_STATE_UNRESOLVED);
return NS_OK; return NS_OK;
} }
@ -6274,11 +6275,17 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
for (size_t i = 0; i < candidates->Length(); ++i) { for (size_t i = 0; i < candidates->Length(); ++i) {
Element *elem = candidates->ElementAt(i); Element *elem = candidates->ElementAt(i);
elem->RemoveStates(NS_EVENT_STATE_UNRESOLVED);
// Make sure that the element name matches the name in the definition. // Make sure that the element name matches the name in the definition.
// (e.g. a definition for x-button extending button should match // (e.g. a definition for x-button extending button should match
// <button is="x-button"> but not <x-button>. // <button is="x-button"> but not <x-button>.
if (elem->NodeInfo()->NameAtom() != nameAtom) { // Note: we also check the tag name, because if it's not the above
// Skip over this element because definition does not apply. // mentioned case, it can be that only the |is| property has been
// changed, which we should ignore by the spec.
if (elem->NodeInfo()->NameAtom() != nameAtom &&
elem->Tag() == nameAtom) {
//Skip over this element because definition does not apply.
continue; continue;
} }

View File

@ -265,6 +265,8 @@ private:
#define NS_EVENT_STATE_TYPE_PLAY_PREVIEW NS_DEFINE_EVENT_STATE_MACRO(44) #define NS_EVENT_STATE_TYPE_PLAY_PREVIEW NS_DEFINE_EVENT_STATE_MACRO(44)
// Element is highlighted (devtools inspector) // Element is highlighted (devtools inspector)
#define NS_EVENT_STATE_DEVTOOLS_HIGHLIGHTED NS_DEFINE_EVENT_STATE_MACRO(45) #define NS_EVENT_STATE_DEVTOOLS_HIGHLIGHTED NS_DEFINE_EVENT_STATE_MACRO(45)
// Element is an unresolved custom element candidate
#define NS_EVENT_STATE_UNRESOLVED NS_DEFINE_EVENT_STATE_MACRO(46)
// Event state that is used for values that need to be parsed but do nothing. // Event state that is used for values that need to be parsed but do nothing.
#define NS_EVENT_STATE_IGNORE NS_DEFINE_EVENT_STATE_MACRO(63) #define NS_EVENT_STATE_IGNORE NS_DEFINE_EVENT_STATE_MACRO(63)
@ -278,7 +280,8 @@ private:
#define ESM_MANAGED_STATES (NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS | \ #define ESM_MANAGED_STATES (NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS | \
NS_EVENT_STATE_HOVER | NS_EVENT_STATE_DRAGOVER | \ NS_EVENT_STATE_HOVER | NS_EVENT_STATE_DRAGOVER | \
NS_EVENT_STATE_URLTARGET | NS_EVENT_STATE_FOCUSRING | \ NS_EVENT_STATE_URLTARGET | NS_EVENT_STATE_FOCUSRING | \
NS_EVENT_STATE_FULL_SCREEN | NS_EVENT_STATE_FULL_SCREEN_ANCESTOR) NS_EVENT_STATE_FULL_SCREEN | NS_EVENT_STATE_FULL_SCREEN_ANCESTOR | \
NS_EVENT_STATE_UNRESOLVED)
#define INTRINSIC_STATES (~ESM_MANAGED_STATES) #define INTRINSIC_STATES (~ESM_MANAGED_STATES)

View File

@ -36,3 +36,4 @@ support-files =
[test_shadowroot_style_order.html] [test_shadowroot_style_order.html]
[test_shadowroot_youngershadowroot.html] [test_shadowroot_youngershadowroot.html]
[test_style_fallback_content.html] [test_style_fallback_content.html]
[test_unresolved_pseudo_class.html]

View File

@ -0,0 +1,99 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1111633
-->
<head>
<title>Test template element in stale document.</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<style>
:unresolved {
color: rgb(0, 0, 255);
background-color: rgb(0, 0, 255);
}
x-foo { color: rgb(255, 0, 0); }
[is="x-del"]:not(:unresolved) { color: rgb(255, 0, 0); }
[is="x-bar"]:not(:unresolved) { color: rgb(255, 0, 0); }
[is="x-bar"]:unresolved { background-color: rgb(255, 0, 0); }
x-baz:not(:unresolved) {
color: rgb(255, 0, 0);
background-color: rgb(255, 0, 0);
}
span { color: rgb(0,255,0); }
x-foo:unresolved + span { color: rgb(255,0,0); }
</style>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1111633">Bug 1111633</a>
<div id="container"></div>
<x-foo id="foo"></x-foo>
<span id="span1">This text should be green</span>
<span id="bar" is="x-bar"></span>
<x-baz id="baz"></x-baz>
<span id="del" is="x-del"></span>
<script>
// Before registerElement
var foo = document.querySelector('#foo');
is(getComputedStyle(foo).color, "rgb(0, 0, 255)", "foo - color");
is(getComputedStyle(foo).backgroundColor, "rgb(0, 0, 255)", "foo - backgroundColor");
var bar = document.querySelector('#bar');
is(getComputedStyle(bar).color, "rgb(0, 0, 255)", "bar - color");
is(getComputedStyle(bar).backgroundColor, "rgb(255, 0, 0)", "bar - backgroundColor");
var baz = document.querySelector('#baz');
is(getComputedStyle(baz).color, "rgb(0, 0, 255)", "baz - color");
is(getComputedStyle(baz).backgroundColor, "rgb(0, 0, 255)", "baz - backgroundColor");
var span1 = document.querySelector('#span1');
is(getComputedStyle(span1).color, "rgb(255, 0, 0)", "span1 - color");
var Foo = document.registerElement('x-foo', { prototype: Object.create(HTMLElement.prototype) });
var Bar = document.registerElement('x-bar', { extends: 'span', prototype: Object.create(HTMLSpanElement.prototype) });
var Baz = document.registerElement('x-baz', { prototype: Object.create(HTMLElement.prototype) });
// After registerElement
is(getComputedStyle(foo).color, "rgb(255, 0, 0)",
"foo - color (after registerElement)");
is(getComputedStyle(bar).color,
"rgb(255, 0, 0)", "bar - color (after registerElement)");
is(getComputedStyle(baz).color,
"rgb(255, 0, 0)", "baz - color (after registerElement)");
is(getComputedStyle(baz).backgroundColor,
"rgb(255, 0, 0)", "baz - backgroundColor (after registerElement)");
is(getComputedStyle(span1).color, "rgb(0, 255, 0)", "span1 - color (after registerElement)");
// After tree removal
var del = document.querySelector('#del');
is(getComputedStyle(del).color, "rgb(0, 0, 255)", "del - color");
var par = del.parentNode;
par.removeChild(del);
// Changing is attribute after creation should not change the type
// of a custom element, even if the element was removed and re-append to the tree.
del.setAttribute("is", "foobar");
par.appendChild(del);
is(getComputedStyle(del).color, "rgb(0, 0, 255)", "del - color (after reappend)");
var Del = document.registerElement('x-del', { prototype: Object.create(HTMLSpanElement.prototype) });
// [is="x-del"] will not match any longer so the rule of span will apply
is(getComputedStyle(del).color, "rgb(0, 255, 0)", "del - color (after registerElement)");
// but the element should have been upgraded:
ok(del instanceof Del, "element was upgraded correctly after changing |is|");
</script>
</body>
</html>

View File

@ -90,6 +90,9 @@ CSS_PSEUDO_CLASS(nthLastOfType, ":nth-last-of-type", 0, "")
// Match nodes that are HTML but not XHTML // Match nodes that are HTML but not XHTML
CSS_PSEUDO_CLASS(mozIsHTML, ":-moz-is-html", 0, "") CSS_PSEUDO_CLASS(mozIsHTML, ":-moz-is-html", 0, "")
// Match all custom elements whose created callback has not yet been invoked
CSS_STATE_PSEUDO_CLASS(unresolved, ":unresolved", 0, "", NS_EVENT_STATE_UNRESOLVED)
// Matches nodes that are in a native-anonymous subtree (i.e., nodes in // Matches nodes that are in a native-anonymous subtree (i.e., nodes in
// a subtree of C++ anonymous content constructed by Gecko for its own // a subtree of C++ anonymous content constructed by Gecko for its own
// purposes). // purposes).

View File

@ -9,3 +9,6 @@
[Test custom element type after changing IS attribute value. Element is HTML5 element with IS attribute referring to custom element type] [Test custom element type after changing IS attribute value. Element is HTML5 element with IS attribute referring to custom element type]
expected: FAIL expected: FAIL
[Custom element type must be taken from the local name of the element even if IS attribute provided. There's no definition for the value of IS attribute at first]
expected: FAIL

View File

@ -1,5 +0,0 @@
[unresolved-element-pseudoclass-css-test-custom-tag.html]
type: reftest
reftype: ==
refurl: /custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-custom-tag-ref.html
expected: FAIL

View File

@ -1,5 +0,0 @@
[unresolved-element-pseudoclass-css-test-type-extension.html]
type: reftest
reftype: ==
refurl: /custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-type-extension-ref.html
expected: FAIL

View File

@ -1,26 +1,7 @@
[unresolved-element-pseudoclass-matching-query-selector-all.html] [unresolved-element-pseudoclass-matching-query-selector-all.html]
type: testharness type: testharness
[Test that single unresolved custom element is accessible by Document.querySelectorAll(\':unresolved\')] [Custom element type must be taken from the local name of the element even if IS attribute provided. There's no definition for the value of IS attribute at first]
expected: FAIL
[Test that single registered custom element is not accessible by :unresolved]
expected: FAIL
[If there are more than one unresolved custom element then all of them accessible by Document.querySelectorAll(\':unresolved\')]
expected: FAIL
[Unresolved custom element, created via Document.createElement(), should be accessible by Document.querySelectorAll(\':unresolved\')]
expected: FAIL
[All unresolved custom element including nested ones are accessible by Document.querySelectorAll(\':unresolved\')]
expected: FAIL
[Unresolved custom element should be accessible by Document.querySelectorAll(\':unresolved\') in a loaded document]
expected: FAIL expected: FAIL
[Test that Document.querySelectorAll(\':unresolved\') returns unresolved custom elements, extending HTML elements by IS attribute] [Test that Document.querySelectorAll(\':unresolved\') returns unresolved custom elements, extending HTML elements by IS attribute]
expected: FAIL expected: FAIL
[Test Document.querySelectorAll(\':unresolved\') returns mix of custom elements of different types]
expected: FAIL

View File

@ -1,26 +1,5 @@
[unresolved-element-pseudoclass-matching-query-selector.html] [unresolved-element-pseudoclass-matching-query-selector.html]
type: testharness type: testharness
[Test that unresolved custom element is accessible by Document.querySelector(\':unresolved\')]
expected: FAIL
[Test that registered custom element are not accessible by :unresolved]
expected: FAIL
[If there are more than one unresolved custom element, all of them should be accessible by :unresolved pseudoclass]
expected: FAIL
[Unresolved custom element, created via Document.createElement(), should be accessible by Document.querySelector(\':unresolved\')]
expected: FAIL
[Unresolved custom element inside div element should be accessible by :unresolved pseudoclass]
expected: FAIL
[All unresolved custom element including nested ones should be accessible by Document.querySelector(\':unresolved\')]
expected: FAIL
[Document.querySelector(): Unresolved custom element should be accessible by :unresolved in loaded document]
expected: FAIL
[Test that Document.querySelector(\':unresolved\') returns custom element, extending HTML elements by IS attribute] [Test that Document.querySelector(\':unresolved\') returns custom element, extending HTML elements by IS attribute]
expected: FAIL expected: FAIL