зеркало из https://github.com/mozilla/gecko-dev.git
Merge.
This commit is contained in:
Коммит
dc740985af
|
@ -158,6 +158,7 @@ _TEST_FILES = test_bug589.html \
|
|||
test_bug536891.html \
|
||||
test_bug536895.html \
|
||||
test_bug458037.xhtml \
|
||||
test_bug559284.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=559284
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 559284</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=559284">Mozilla Bug 559284</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<section id="section"></section>
|
||||
<nav id="nav"></nav>
|
||||
<article id="article"></article>
|
||||
<aside id="aside"></aside>
|
||||
<hgroup id="hgroup"></hgroup>
|
||||
<header id="header"></header>
|
||||
<footer id="footer"></footer>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 559284 **/
|
||||
todo_is($("section").constructor, "[object HTMLElement]",
|
||||
"Constructor should be section");
|
||||
todo_is($("section").toString().substring(0, 19), "[object HTMLElement",
|
||||
"Section should be HTMLElement");
|
||||
is($("section") instanceof HTMLElement, true,
|
||||
"Section should be instance of HTMLElement");
|
||||
todo_is($("nav").constructor, "[object HTMLElement]",
|
||||
"Constructor should be nav");
|
||||
todo_is($("nav").toString().substring(0, 19), "[object HTMLElement",
|
||||
"Nav should be HTMLElement");
|
||||
is($("nav") instanceof HTMLElement, true,
|
||||
"Nav should be instance of HTMLElement");
|
||||
todo_is($("article").constructor, "[object HTMLElement]",
|
||||
"Constructor should be article");
|
||||
todo_is($("article").toString().substring(0, 19), "[object HTMLElement",
|
||||
"Article should be HTMLElement");
|
||||
is($("article") instanceof HTMLElement, true,
|
||||
"Article should be instance of HTMLElement");
|
||||
todo_is($("aside").constructor, "[object HTMLElement]",
|
||||
"Constructor should be aside");
|
||||
todo_is($("aside").toString().substring(0, 19), "[object HTMLElement",
|
||||
"Aside should be HTMLElement");
|
||||
is($("aside") instanceof HTMLElement, true,
|
||||
"Aside should be instance of HTMLElement");
|
||||
todo_is($("hgroup").constructor, "[object HTMLElement]",
|
||||
"Constructor should be hgroup");
|
||||
todo_is($("hgroup").toString().substring(0, 19), "[object HTMLElement",
|
||||
"Hgroup should be HTMLElement");
|
||||
is($("hgroup") instanceof HTMLElement, true,
|
||||
"Hgroup should be instance of HTMLElement");
|
||||
todo_is($("header").constructor, "[object HTMLElement]",
|
||||
"Constructor should be header");
|
||||
todo_is($("header").toString().substring(0, 19), "[object HTMLElement",
|
||||
"Header should be HTMLElement");
|
||||
is($("header") instanceof HTMLElement, true,
|
||||
"Header should be instance of HTMLElement");
|
||||
todo_is($("footer").constructor, "[object HTMLElement]",
|
||||
"Constructor should be footer");
|
||||
todo_is($("footer").toString().substring(0, 19), "[object HTMLElement",
|
||||
"Footer should be HTMLElement");
|
||||
is($("footer") instanceof HTMLElement, true,
|
||||
"Footer should be instance of HTMLElement");
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<body>
|
||||
-<div>section</div>
|
||||
-<div>nav</div>
|
||||
-<div>article</div>
|
||||
-<div>aside</div>
|
||||
-<div>hgroup</div>
|
||||
-<div>header</div>
|
||||
-<div>footer</div>
|
||||
-
|
||||
</body>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<body>
|
||||
-<section>section</section>
|
||||
-<nav>nav</nav>
|
||||
-<article>article</article>
|
||||
-<aside>aside</aside>
|
||||
-<hgroup>hgroup</hgroup>
|
||||
-<header>header</header>
|
||||
-<footer>footer</footer>
|
||||
-
|
||||
</body>
|
|
@ -1425,3 +1425,4 @@ random-if(!haveTestPlugin) == 546071-1.html 546071-1-ref.html
|
|||
== 552334-1.html 552334-1-ref.html
|
||||
== 556661-1.html 556661-1-ref.html
|
||||
== 557736-1.html 557736-1-ref.html
|
||||
== 559284-1.html 559284-1-ref.html
|
||||
|
|
|
@ -60,17 +60,74 @@ bdo[dir] {
|
|||
* formatting obtained by explicitly adding a dir attribute (assigned the
|
||||
* inherited value) to the transformed element." */
|
||||
|
||||
address, blockquote, body, caption, center, col, colgroup, dd, dir, div, dl, dt,
|
||||
fieldset, form, h1, h2, h3, h4, h5, h6, hr, html, isindex, li, listing, map,
|
||||
marquee, menu, noframes, ol, p, plaintext, pre, table, tbody, td, tfoot, th,
|
||||
thead, tr, ul, xmp {
|
||||
address,
|
||||
article,
|
||||
aside,
|
||||
blockquote,
|
||||
body,
|
||||
caption,
|
||||
center,
|
||||
col,
|
||||
colgroup,
|
||||
dd,
|
||||
dir,
|
||||
div,
|
||||
dl,
|
||||
dt,
|
||||
fieldset,
|
||||
footer,
|
||||
form,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
header,
|
||||
hgroup,
|
||||
hr,
|
||||
html,
|
||||
isindex,
|
||||
li,
|
||||
listing,
|
||||
map,
|
||||
marquee,
|
||||
menu,
|
||||
nav,
|
||||
noframes,
|
||||
ol,
|
||||
p,
|
||||
plaintext,
|
||||
pre,
|
||||
section,
|
||||
table,
|
||||
tbody,
|
||||
td,
|
||||
tfoot,
|
||||
th,
|
||||
thead,
|
||||
tr,
|
||||
ul,
|
||||
xmp {
|
||||
unicode-bidi: embed;
|
||||
}
|
||||
|
||||
|
||||
/* blocks */
|
||||
|
||||
html, div, map, dt, isindex, form {
|
||||
article,
|
||||
aside,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
html,
|
||||
div,
|
||||
map,
|
||||
dt,
|
||||
isindex,
|
||||
form,
|
||||
nav,
|
||||
section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,35 +66,18 @@
|
|||
#define DEFINED_CSS_STATE_PSEUDO_CLASS
|
||||
#endif
|
||||
|
||||
// The CSS_PSEUDO_CLASS entries should all come before the
|
||||
// CSS_STATE_PSEUDO_CLASS entries. The CSS_PSEUDO_CLASS entry order
|
||||
// must be the same as the order of cases in SelectorMatches.
|
||||
|
||||
CSS_PSEUDO_CLASS(empty, ":empty")
|
||||
CSS_PSEUDO_CLASS(mozOnlyWhitespace, ":-moz-only-whitespace")
|
||||
CSS_PSEUDO_CLASS(mozEmptyExceptChildrenWithLocalname, ":-moz-empty-except-children-with-localname")
|
||||
CSS_PSEUDO_CLASS(lang, ":lang")
|
||||
CSS_PSEUDO_CLASS(notPseudo, ":not")
|
||||
CSS_PSEUDO_CLASS(mozBoundElement, ":-moz-bound-element")
|
||||
CSS_PSEUDO_CLASS(root, ":root")
|
||||
CSS_PSEUDO_CLASS(any, ":-moz-any")
|
||||
|
||||
CSS_STATE_PSEUDO_CLASS(link, ":link", NS_EVENT_STATE_UNVISITED)
|
||||
// what matches :link or :visited
|
||||
CSS_STATE_PSEUDO_CLASS(mozAnyLink, ":-moz-any-link",
|
||||
NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED)
|
||||
CSS_STATE_PSEUDO_CLASS(visited, ":visited", NS_EVENT_STATE_VISITED)
|
||||
|
||||
CSS_STATE_PSEUDO_CLASS(active, ":active", NS_EVENT_STATE_ACTIVE)
|
||||
CSS_STATE_PSEUDO_CLASS(checked, ":checked", NS_EVENT_STATE_CHECKED)
|
||||
CSS_STATE_PSEUDO_CLASS(disabled, ":disabled", NS_EVENT_STATE_DISABLED)
|
||||
CSS_STATE_PSEUDO_CLASS(enabled, ":enabled", NS_EVENT_STATE_ENABLED)
|
||||
CSS_STATE_PSEUDO_CLASS(focus, ":focus", NS_EVENT_STATE_FOCUS)
|
||||
CSS_STATE_PSEUDO_CLASS(hover, ":hover", NS_EVENT_STATE_HOVER)
|
||||
CSS_STATE_PSEUDO_CLASS(mozDragOver, ":-moz-drag-over", NS_EVENT_STATE_DRAGOVER)
|
||||
CSS_STATE_PSEUDO_CLASS(target, ":target", NS_EVENT_STATE_URLTARGET)
|
||||
CSS_STATE_PSEUDO_CLASS(indeterminate, ":indeterminate",
|
||||
NS_EVENT_STATE_INDETERMINATE)
|
||||
|
||||
// Matches if the element is focused and should show a focus ring
|
||||
CSS_STATE_PSEUDO_CLASS(mozFocusRing, ":-moz-focusring", NS_EVENT_STATE_FOCUSRING)
|
||||
|
||||
CSS_PSEUDO_CLASS(firstChild, ":first-child")
|
||||
CSS_PSEUDO_CLASS(firstNode, ":-moz-first-node")
|
||||
CSS_PSEUDO_CLASS(lastChild, ":last-child")
|
||||
|
@ -108,22 +91,6 @@ CSS_PSEUDO_CLASS(nthLastChild, ":nth-last-child")
|
|||
CSS_PSEUDO_CLASS(nthOfType, ":nth-of-type")
|
||||
CSS_PSEUDO_CLASS(nthLastOfType, ":nth-last-of-type")
|
||||
|
||||
// Image, object, etc state pseudo-classes
|
||||
CSS_STATE_PSEUDO_CLASS(mozBroken, ":-moz-broken", NS_EVENT_STATE_BROKEN)
|
||||
CSS_STATE_PSEUDO_CLASS(mozUserDisabled, ":-moz-user-disabled",
|
||||
NS_EVENT_STATE_USERDISABLED)
|
||||
CSS_STATE_PSEUDO_CLASS(mozSuppressed, ":-moz-suppressed",
|
||||
NS_EVENT_STATE_SUPPRESSED)
|
||||
CSS_STATE_PSEUDO_CLASS(mozLoading, ":-moz-loading", NS_EVENT_STATE_LOADING)
|
||||
CSS_STATE_PSEUDO_CLASS(mozTypeUnsupported, ":-moz-type-unsupported",
|
||||
NS_EVENT_STATE_TYPE_UNSUPPORTED)
|
||||
CSS_STATE_PSEUDO_CLASS(mozHandlerDisabled, ":-moz-handler-disabled",
|
||||
NS_EVENT_STATE_HANDLER_DISABLED)
|
||||
CSS_STATE_PSEUDO_CLASS(mozHandlerBlocked, ":-moz-handler-blocked",
|
||||
NS_EVENT_STATE_HANDLER_BLOCKED)
|
||||
CSS_STATE_PSEUDO_CLASS(mozHandlerCrashed, ":-moz-handler-crashed",
|
||||
NS_EVENT_STATE_HANDLER_CRASHED)
|
||||
|
||||
CSS_PSEUDO_CLASS(mozHasHandlerRef, ":-moz-has-handlerref")
|
||||
|
||||
// Match nodes that are HTML but not XHTML
|
||||
|
@ -148,6 +115,46 @@ CSS_PSEUDO_CLASS(mozLWThemeDarkText, ":-moz-lwtheme-darktext")
|
|||
// Matches anything when the containing window is inactive
|
||||
CSS_PSEUDO_CLASS(mozWindowInactive, ":-moz-window-inactive")
|
||||
|
||||
// :not needs to come at the end of the non-bit pseudo-class list, since
|
||||
// it doesn't actually get directly matched on in SelectorMatches.
|
||||
CSS_PSEUDO_CLASS(notPseudo, ":not")
|
||||
|
||||
CSS_STATE_PSEUDO_CLASS(link, ":link", NS_EVENT_STATE_UNVISITED)
|
||||
// what matches :link or :visited
|
||||
CSS_STATE_PSEUDO_CLASS(mozAnyLink, ":-moz-any-link",
|
||||
NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED)
|
||||
CSS_STATE_PSEUDO_CLASS(visited, ":visited", NS_EVENT_STATE_VISITED)
|
||||
|
||||
CSS_STATE_PSEUDO_CLASS(active, ":active", NS_EVENT_STATE_ACTIVE)
|
||||
CSS_STATE_PSEUDO_CLASS(checked, ":checked", NS_EVENT_STATE_CHECKED)
|
||||
CSS_STATE_PSEUDO_CLASS(disabled, ":disabled", NS_EVENT_STATE_DISABLED)
|
||||
CSS_STATE_PSEUDO_CLASS(enabled, ":enabled", NS_EVENT_STATE_ENABLED)
|
||||
CSS_STATE_PSEUDO_CLASS(focus, ":focus", NS_EVENT_STATE_FOCUS)
|
||||
CSS_STATE_PSEUDO_CLASS(hover, ":hover", NS_EVENT_STATE_HOVER)
|
||||
CSS_STATE_PSEUDO_CLASS(mozDragOver, ":-moz-drag-over", NS_EVENT_STATE_DRAGOVER)
|
||||
CSS_STATE_PSEUDO_CLASS(target, ":target", NS_EVENT_STATE_URLTARGET)
|
||||
CSS_STATE_PSEUDO_CLASS(indeterminate, ":indeterminate",
|
||||
NS_EVENT_STATE_INDETERMINATE)
|
||||
|
||||
// Matches if the element is focused and should show a focus ring
|
||||
CSS_STATE_PSEUDO_CLASS(mozFocusRing, ":-moz-focusring", NS_EVENT_STATE_FOCUSRING)
|
||||
|
||||
// Image, object, etc state pseudo-classes
|
||||
CSS_STATE_PSEUDO_CLASS(mozBroken, ":-moz-broken", NS_EVENT_STATE_BROKEN)
|
||||
CSS_STATE_PSEUDO_CLASS(mozUserDisabled, ":-moz-user-disabled",
|
||||
NS_EVENT_STATE_USERDISABLED)
|
||||
CSS_STATE_PSEUDO_CLASS(mozSuppressed, ":-moz-suppressed",
|
||||
NS_EVENT_STATE_SUPPRESSED)
|
||||
CSS_STATE_PSEUDO_CLASS(mozLoading, ":-moz-loading", NS_EVENT_STATE_LOADING)
|
||||
CSS_STATE_PSEUDO_CLASS(mozTypeUnsupported, ":-moz-type-unsupported",
|
||||
NS_EVENT_STATE_TYPE_UNSUPPORTED)
|
||||
CSS_STATE_PSEUDO_CLASS(mozHandlerDisabled, ":-moz-handler-disabled",
|
||||
NS_EVENT_STATE_HANDLER_DISABLED)
|
||||
CSS_STATE_PSEUDO_CLASS(mozHandlerBlocked, ":-moz-handler-blocked",
|
||||
NS_EVENT_STATE_HANDLER_BLOCKED)
|
||||
CSS_STATE_PSEUDO_CLASS(mozHandlerCrashed, ":-moz-handler-crashed",
|
||||
NS_EVENT_STATE_HANDLER_CRASHED)
|
||||
|
||||
#ifdef MOZ_MATHML
|
||||
CSS_STATE_PSEUDO_CLASS(mozMathIncrementScriptLevel,
|
||||
":-moz-math-increment-script-level",
|
||||
|
|
|
@ -1410,74 +1410,6 @@ static PRBool AttrMatchesValue(const nsAttrSelector* aAttrSelector,
|
|||
}
|
||||
}
|
||||
|
||||
static PRBool SelectorMatches(RuleProcessorData &data,
|
||||
nsCSSSelector* aSelector,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
TreeMatchContext& aTreeMatchContext,
|
||||
PRBool* const aDependence = nsnull);
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
anyMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext, nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::any,
|
||||
"Unexpected atom");
|
||||
for (nsCSSSelectorList *l = pseudoClass->u.mSelectors; l; l = l->mNext) {
|
||||
nsCSSSelector *s = l->mSelectors;
|
||||
NS_ABORT_IF_FALSE(!s->mNext && !s->IsPseudoElement(), "parser failed");
|
||||
if (SelectorMatches(data, s, aNodeMatchContext, aTreeMatchContext)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
firstNodeMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::firstNode,
|
||||
"Unexpected atom");
|
||||
nsIContent *firstNode = nsnull;
|
||||
nsIContent *parent = data.mParentContent;
|
||||
if (parent) {
|
||||
if (aTreeMatchContext.mForStyling)
|
||||
parent->SetFlags(NODE_HAS_EDGE_CHILD_SELECTOR);
|
||||
|
||||
PRInt32 index = -1;
|
||||
do {
|
||||
firstNode = parent->GetChildAt(++index);
|
||||
// stop at first non-comment and non-whitespace node
|
||||
} while (firstNode &&
|
||||
!IsSignificantChild(firstNode, PR_TRUE, PR_FALSE));
|
||||
}
|
||||
return (data.mContent == firstNode);
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
lastNodeMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::lastNode,
|
||||
"Unexpected atom");
|
||||
nsIContent *lastNode = nsnull;
|
||||
nsIContent *parent = data.mParentContent;
|
||||
if (parent) {
|
||||
if (aTreeMatchContext.mForStyling)
|
||||
parent->SetFlags(NODE_HAS_EDGE_CHILD_SELECTOR);
|
||||
|
||||
PRUint32 index = parent->GetChildCount();
|
||||
do {
|
||||
lastNode = parent->GetChildAt(--index);
|
||||
// stop at first non-comment and non-whitespace node
|
||||
} while (lastNode &&
|
||||
!IsSignificantChild(lastNode, PR_TRUE, PR_FALSE));
|
||||
}
|
||||
return (data.mContent == lastNode);
|
||||
}
|
||||
|
||||
static inline PRBool
|
||||
edgeChildMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
||||
PRBool checkFirst, PRBool checkLast)
|
||||
|
@ -1496,36 +1428,6 @@ edgeChildMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
|||
data.GetNthIndex(PR_FALSE, PR_TRUE, PR_TRUE) == 1);
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
firstChildMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::firstChild,
|
||||
"Unexpected atom");
|
||||
return edgeChildMatches(data, aTreeMatchContext, PR_TRUE, PR_FALSE);
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
lastChildMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::lastChild,
|
||||
"Unexpected atom");
|
||||
return edgeChildMatches(data, aTreeMatchContext, PR_FALSE, PR_TRUE);
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
onlyChildMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::onlyChild,
|
||||
"Unexpected atom");
|
||||
return edgeChildMatches(data, aTreeMatchContext, PR_TRUE, PR_TRUE);
|
||||
}
|
||||
|
||||
static inline PRBool
|
||||
nthChildGenericMatches(RuleProcessorData& data,
|
||||
TreeMatchContext& aTreeMatchContext,
|
||||
|
@ -1565,52 +1467,6 @@ nthChildGenericMatches(RuleProcessorData& data,
|
|||
return n >= 0 && (a * n == index - b);
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
nthChildMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::nthChild,
|
||||
"Unexpected atom");
|
||||
return nthChildGenericMatches(data, aTreeMatchContext, pseudoClass,
|
||||
PR_FALSE, PR_FALSE);
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
nthLastChildMatches(RuleProcessorData& data,
|
||||
TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::nthLastChild,
|
||||
"Unexpected atom");
|
||||
return nthChildGenericMatches(data, aTreeMatchContext, pseudoClass,
|
||||
PR_FALSE, PR_TRUE);
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
nthOfTypeMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::nthOfType,
|
||||
"Unexpected atom");
|
||||
return nthChildGenericMatches(data, aTreeMatchContext, pseudoClass,
|
||||
PR_TRUE, PR_FALSE);
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
nthLastOfTypeMatches(RuleProcessorData& data,
|
||||
TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::nthLastOfType,
|
||||
"Unexpected atom");
|
||||
return nthChildGenericMatches(data, aTreeMatchContext, pseudoClass,
|
||||
PR_TRUE, PR_TRUE);
|
||||
}
|
||||
|
||||
static inline PRBool
|
||||
edgeOfTypeMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
||||
PRBool checkFirst, PRBool checkLast)
|
||||
|
@ -1633,36 +1489,6 @@ edgeOfTypeMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
|||
data.GetNthIndex(PR_TRUE, PR_TRUE, PR_TRUE) == 1);
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
firstOfTypeMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::firstOfType,
|
||||
"Unexpected atom");
|
||||
return edgeOfTypeMatches(data, aTreeMatchContext, PR_TRUE, PR_FALSE);
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
lastOfTypeMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::lastOfType,
|
||||
"Unexpected atom");
|
||||
return edgeOfTypeMatches(data, aTreeMatchContext, PR_FALSE, PR_TRUE);
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
onlyOfTypeMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::onlyOfType,
|
||||
"Unexpected atom");
|
||||
return edgeOfTypeMatches(data, aTreeMatchContext, PR_TRUE, PR_TRUE);
|
||||
}
|
||||
|
||||
static inline PRBool
|
||||
checkGenericEmptyMatches(RuleProcessorData& data,
|
||||
TreeMatchContext& aTreeMatchContext,
|
||||
|
@ -1683,282 +1509,22 @@ checkGenericEmptyMatches(RuleProcessorData& data,
|
|||
return (child == nsnull);
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
emptyMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::empty,
|
||||
"Unexpected atom");
|
||||
return checkGenericEmptyMatches(data, aTreeMatchContext, PR_TRUE);
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
mozOnlyWhitespaceMatches(RuleProcessorData& data,
|
||||
TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozOnlyWhitespace,
|
||||
"Unexpected atom");
|
||||
return checkGenericEmptyMatches(data, aTreeMatchContext, PR_FALSE);
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
mozEmptyExceptChildrenWithLocalnameMatches(RuleProcessorData& data,
|
||||
TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom ==
|
||||
nsCSSPseudoClasses::mozEmptyExceptChildrenWithLocalname,
|
||||
"Unexpected atom");
|
||||
NS_ASSERTION(pseudoClass->u.mString, "Must have string!");
|
||||
nsIContent *child = nsnull;
|
||||
nsIContent *element = data.mContent;
|
||||
PRInt32 index = -1;
|
||||
|
||||
if (aTreeMatchContext.mForStyling)
|
||||
element->SetFlags(NODE_HAS_SLOW_SELECTOR);
|
||||
|
||||
do {
|
||||
child = element->GetChildAt(++index);
|
||||
} while (child &&
|
||||
(!IsSignificantChild(child, PR_TRUE, PR_FALSE) ||
|
||||
(child->GetNameSpaceID() == element->GetNameSpaceID() &&
|
||||
child->Tag()->Equals(nsDependentString(pseudoClass->u.mString)))));
|
||||
return (child == nsnull);
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
mozSystemMetricMatches(RuleProcessorData& data,
|
||||
TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozSystemMetric,
|
||||
"Unexpected atom");
|
||||
NS_ASSERTION(pseudoClass->u.mString, "Must have string!");
|
||||
nsCOMPtr<nsIAtom> metric = do_GetAtom(pseudoClass->u.mString);
|
||||
return nsCSSRuleProcessor::HasSystemMetric(metric);
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
mozHasHandlerRefMatches(RuleProcessorData& data,
|
||||
TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozHasHandlerRef,
|
||||
"Unexpected atom");
|
||||
nsIContent *child = nsnull;
|
||||
nsIContent *element = data.mContent;
|
||||
PRInt32 index = -1;
|
||||
|
||||
do {
|
||||
child = element->GetChildAt(++index);
|
||||
if (child && child->IsHTML() &&
|
||||
child->Tag() == nsGkAtoms::param &&
|
||||
child->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
|
||||
NS_LITERAL_STRING("pluginurl"), eIgnoreCase)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
} while (child);
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
rootMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext, nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::root,
|
||||
"Unexpected atom");
|
||||
return (data.mParentContent == nsnull &&
|
||||
data.mContent == data.mContent->GetOwnerDoc()->GetRootContent());
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
mozBoundElementMatches(RuleProcessorData& data,
|
||||
TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozBoundElement,
|
||||
"Unexpected atom");
|
||||
// XXXldb How do we know where the selector came from? And what
|
||||
// if there are multiple bindings, and we should be matching the
|
||||
// outer one?
|
||||
return (data.mScopedRoot == data.mContent);
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
langMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext, nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::lang,
|
||||
"Unexpected atom");
|
||||
NS_ASSERTION(nsnull != pseudoClass->u.mString, "null lang parameter");
|
||||
if (!pseudoClass->u.mString || !*pseudoClass->u.mString) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// We have to determine the language of the current element. Since
|
||||
// this is currently no property and since the language is inherited
|
||||
// from the parent we have to be prepared to look at all parent
|
||||
// nodes. The language itself is encoded in the LANG attribute.
|
||||
const nsString* lang = data.GetLang();
|
||||
if (lang && !lang->IsEmpty()) { // null check for out-of-memory
|
||||
return
|
||||
nsStyleUtil::DashMatchCompare(*lang,
|
||||
nsDependentString(pseudoClass->u.mString),
|
||||
nsCaseInsensitiveStringComparator());
|
||||
}
|
||||
|
||||
nsIDocument* doc = data.mContent->GetDocument();
|
||||
if (doc) {
|
||||
// Try to get the language from the HTTP header or if this
|
||||
// is missing as well from the preferences.
|
||||
// The content language can be a comma-separated list of
|
||||
// language codes.
|
||||
nsAutoString language;
|
||||
doc->GetContentLanguage(language);
|
||||
|
||||
nsDependentString langString(pseudoClass->u.mString);
|
||||
language.StripWhitespace();
|
||||
PRInt32 begin = 0;
|
||||
PRInt32 len = language.Length();
|
||||
while (begin < len) {
|
||||
PRInt32 end = language.FindChar(PRUnichar(','), begin);
|
||||
if (end == kNotFound) {
|
||||
end = len;
|
||||
}
|
||||
if (nsStyleUtil::DashMatchCompare(Substring(language, begin, end-begin),
|
||||
langString,
|
||||
nsCaseInsensitiveStringComparator())) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
begin = end + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
mozIsHTMLMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozIsHTML,
|
||||
"Unexpected atom");
|
||||
return data.mIsHTML;
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
mozLocaleDirMatches(RuleProcessorData& data,
|
||||
TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozLocaleDir,
|
||||
"Unexpected atom");
|
||||
|
||||
PRBool docIsRTL = (data.DocumentState() & NS_DOCUMENT_STATE_RTL_LOCALE) != 0;
|
||||
|
||||
nsDependentString dirString(pseudoClass->u.mString);
|
||||
NS_ASSERTION(dirString.EqualsLiteral("ltr") || dirString.EqualsLiteral("rtl"),
|
||||
"invalid value for -moz-locale-dir");
|
||||
|
||||
return dirString.EqualsLiteral("rtl") == docIsRTL;
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
mozLWThemeMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozLWTheme,
|
||||
"Unexpected atom");
|
||||
nsIDocument* doc = data.mContent->GetOwnerDoc();
|
||||
return doc && doc->GetDocumentLWTheme() > nsIDocument::Doc_Theme_None;
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
mozLWThemeBrightTextMatches(RuleProcessorData& data,
|
||||
TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom ==
|
||||
nsCSSPseudoClasses::mozLWThemeBrightText,
|
||||
"Unexpected atom");
|
||||
nsIDocument* doc = data.mContent->GetOwnerDoc();
|
||||
return doc && doc->GetDocumentLWTheme() == nsIDocument::Doc_Theme_Bright;
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
mozLWThemeDarkTextMatches(RuleProcessorData& data,
|
||||
TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom ==
|
||||
nsCSSPseudoClasses::mozLWThemeDarkText,
|
||||
"Unexpected atom");
|
||||
nsIDocument* doc = data.mContent->GetOwnerDoc();
|
||||
return doc && doc->GetDocumentLWTheme() == nsIDocument::Doc_Theme_Dark;
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
mozWindowInactiveMatches(RuleProcessorData& data,
|
||||
TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_PRECONDITION(pseudoClass->mAtom ==
|
||||
nsCSSPseudoClasses::mozWindowInactive,
|
||||
"Unexpected atom");
|
||||
return (data.DocumentState() & NS_DOCUMENT_STATE_WINDOW_INACTIVE) != 0;
|
||||
}
|
||||
|
||||
static PRBool NS_FASTCALL
|
||||
notPseudoMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass)
|
||||
{
|
||||
NS_NOTREACHED("Why did this get called?");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
typedef PRBool
|
||||
(NS_FASTCALL * PseudoClassMatcher)(RuleProcessorData&,
|
||||
TreeMatchContext& aTreeMatchContext,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
nsPseudoClassList* pseudoClass);
|
||||
// Only one of mFunc or mBits will be set; the other will be null or 0
|
||||
// respectively. We could use a union, but then we'd still need to
|
||||
// differentiate somehow, eiher with another member in the struct or
|
||||
// with a boolean coming from _sowewhere_.
|
||||
struct PseudoClassInfo {
|
||||
PseudoClassMatcher mFunc;
|
||||
PRInt32 mBits;
|
||||
};
|
||||
|
||||
static const PseudoClassInfo sPseudoClassInfo[] = {
|
||||
// An array of the bits that are relevant for various pseudoclasses.
|
||||
static const PRUint32 sPseudoClassBits[] = {
|
||||
#define CSS_PSEUDO_CLASS(_name, _value) \
|
||||
{ &_name##Matches, 0 },
|
||||
0,
|
||||
#define CSS_STATE_PSEUDO_CLASS(_name, _value, _bit) \
|
||||
{ nsnull, _bit },
|
||||
_bit,
|
||||
#include "nsCSSPseudoClassList.h"
|
||||
#undef CSS_STATE_PSEUDO_CLASS
|
||||
#undef CSS_PSEUDO_CLASS
|
||||
// Add more entries for our fake values to make sure we can't
|
||||
// index out of bounds into this array no matter what.
|
||||
{ nsnull, 0 },
|
||||
{ nsnull, 0 }
|
||||
0,
|
||||
0
|
||||
};
|
||||
PR_STATIC_ASSERT(NS_ARRAY_LENGTH(sPseudoClassInfo) >
|
||||
nsCSSPseudoClasses::ePseudoClass_NotPseudoClass);
|
||||
PR_STATIC_ASSERT(NS_ARRAY_LENGTH(sPseudoClassBits) ==
|
||||
nsCSSPseudoClasses::ePseudoClass_NotPseudoClass + 1);
|
||||
|
||||
// |aDependence| has two functions:
|
||||
// * when non-null, it indicates that we're processing a negation,
|
||||
|
@ -1969,7 +1535,7 @@ static PRBool SelectorMatches(RuleProcessorData &data,
|
|||
nsCSSSelector* aSelector,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
TreeMatchContext& aTreeMatchContext,
|
||||
PRBool* const aDependence /* = nsnull */)
|
||||
PRBool* const aDependence = nsnull)
|
||||
|
||||
{
|
||||
NS_PRECONDITION(!aSelector->IsPseudoElement(),
|
||||
|
@ -2062,15 +1628,332 @@ static PRBool SelectorMatches(RuleProcessorData &data,
|
|||
// test for pseudo class match
|
||||
for (nsPseudoClassList* pseudoClass = aSelector->mPseudoClassList;
|
||||
pseudoClass; pseudoClass = pseudoClass->mNext) {
|
||||
const PseudoClassInfo& info = sPseudoClassInfo[pseudoClass->mType];
|
||||
if (info.mFunc) {
|
||||
if (!(*info.mFunc)(data, aTreeMatchContext, aNodeMatchContext,
|
||||
pseudoClass)) {
|
||||
PRInt32 statesToCheck = sPseudoClassBits[pseudoClass->mType];
|
||||
if (!statesToCheck) {
|
||||
// keep the cases here in the same order as the list in
|
||||
// nsCSSPseudoClassList.h
|
||||
switch (pseudoClass->mType) {
|
||||
case nsCSSPseudoClasses::ePseudoClass_empty:
|
||||
if (!checkGenericEmptyMatches(data, aTreeMatchContext, PR_TRUE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_mozOnlyWhitespace:
|
||||
if (!checkGenericEmptyMatches(data, aTreeMatchContext, PR_FALSE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_mozEmptyExceptChildrenWithLocalname:
|
||||
{
|
||||
NS_ASSERTION(pseudoClass->u.mString, "Must have string!");
|
||||
nsIContent *child = nsnull;
|
||||
nsIContent *element = data.mContent;
|
||||
PRInt32 index = -1;
|
||||
|
||||
if (aTreeMatchContext.mForStyling)
|
||||
element->SetFlags(NODE_HAS_SLOW_SELECTOR);
|
||||
do {
|
||||
child = element->GetChildAt(++index);
|
||||
} while (child &&
|
||||
(!IsSignificantChild(child, PR_TRUE, PR_FALSE) ||
|
||||
(child->GetNameSpaceID() == element->GetNameSpaceID() &&
|
||||
child->Tag()->Equals(nsDependentString(pseudoClass->u.mString)))));
|
||||
if (child != nsnull) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_lang:
|
||||
{
|
||||
NS_ASSERTION(nsnull != pseudoClass->u.mString, "null lang parameter");
|
||||
if (!pseudoClass->u.mString || !*pseudoClass->u.mString) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// We have to determine the language of the current element. Since
|
||||
// this is currently no property and since the language is inherited
|
||||
// from the parent we have to be prepared to look at all parent
|
||||
// nodes. The language itself is encoded in the LANG attribute.
|
||||
const nsString* lang = data.GetLang();
|
||||
if (lang && !lang->IsEmpty()) { // null check for out-of-memory
|
||||
if (!nsStyleUtil::DashMatchCompare(*lang,
|
||||
nsDependentString(pseudoClass->u.mString),
|
||||
nsCaseInsensitiveStringComparator())) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
// This pseudo-class matched; move on to the next thing
|
||||
break;
|
||||
}
|
||||
|
||||
nsIDocument* doc = data.mContent->GetDocument();
|
||||
if (doc) {
|
||||
// Try to get the language from the HTTP header or if this
|
||||
// is missing as well from the preferences.
|
||||
// The content language can be a comma-separated list of
|
||||
// language codes.
|
||||
nsAutoString language;
|
||||
doc->GetContentLanguage(language);
|
||||
|
||||
nsDependentString langString(pseudoClass->u.mString);
|
||||
language.StripWhitespace();
|
||||
PRInt32 begin = 0;
|
||||
PRInt32 len = language.Length();
|
||||
while (begin < len) {
|
||||
PRInt32 end = language.FindChar(PRUnichar(','), begin);
|
||||
if (end == kNotFound) {
|
||||
end = len;
|
||||
}
|
||||
if (nsStyleUtil::DashMatchCompare(Substring(language, begin,
|
||||
end-begin),
|
||||
langString,
|
||||
nsCaseInsensitiveStringComparator())) {
|
||||
break;
|
||||
}
|
||||
begin = end + 1;
|
||||
}
|
||||
if (begin < len) {
|
||||
// This pseudo-class matched
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_mozBoundElement:
|
||||
if (data.mScopedRoot != data.mContent) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_root:
|
||||
if (data.mParentContent != nsnull ||
|
||||
data.mContent != data.mContent->GetOwnerDoc()->GetRootContent()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_any:
|
||||
{
|
||||
nsCSSSelectorList *l;
|
||||
for (l = pseudoClass->u.mSelectors; l; l = l->mNext) {
|
||||
nsCSSSelector *s = l->mSelectors;
|
||||
NS_ABORT_IF_FALSE(!s->mNext && !s->IsPseudoElement(),
|
||||
"parser failed");
|
||||
if (SelectorMatches(data, s, aNodeMatchContext, aTreeMatchContext)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!l) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_firstChild:
|
||||
if (!edgeChildMatches(data, aTreeMatchContext, PR_TRUE, PR_FALSE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_firstNode:
|
||||
{
|
||||
nsIContent *firstNode = nsnull;
|
||||
nsIContent *parent = data.mParentContent;
|
||||
if (parent) {
|
||||
if (aTreeMatchContext.mForStyling)
|
||||
parent->SetFlags(NODE_HAS_EDGE_CHILD_SELECTOR);
|
||||
|
||||
PRInt32 index = -1;
|
||||
do {
|
||||
firstNode = parent->GetChildAt(++index);
|
||||
// stop at first non-comment and non-whitespace node
|
||||
} while (firstNode &&
|
||||
!IsSignificantChild(firstNode, PR_TRUE, PR_FALSE));
|
||||
}
|
||||
if (data.mContent != firstNode) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_lastChild:
|
||||
if (!edgeChildMatches(data, aTreeMatchContext, PR_FALSE, PR_TRUE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_lastNode:
|
||||
{
|
||||
nsIContent *lastNode = nsnull;
|
||||
nsIContent *parent = data.mParentContent;
|
||||
if (parent) {
|
||||
if (aTreeMatchContext.mForStyling)
|
||||
parent->SetFlags(NODE_HAS_EDGE_CHILD_SELECTOR);
|
||||
|
||||
PRUint32 index = parent->GetChildCount();
|
||||
do {
|
||||
lastNode = parent->GetChildAt(--index);
|
||||
// stop at first non-comment and non-whitespace node
|
||||
} while (lastNode &&
|
||||
!IsSignificantChild(lastNode, PR_TRUE, PR_FALSE));
|
||||
}
|
||||
if (data.mContent != lastNode) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_onlyChild:
|
||||
if (!edgeChildMatches(data, aTreeMatchContext, PR_TRUE, PR_TRUE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_firstOfType:
|
||||
if (!edgeOfTypeMatches(data, aTreeMatchContext, PR_TRUE, PR_FALSE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_lastOfType:
|
||||
if (!edgeOfTypeMatches(data, aTreeMatchContext, PR_FALSE, PR_TRUE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_onlyOfType:
|
||||
if (!edgeOfTypeMatches(data, aTreeMatchContext, PR_TRUE, PR_TRUE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_nthChild:
|
||||
if (!nthChildGenericMatches(data, aTreeMatchContext, pseudoClass,
|
||||
PR_FALSE, PR_FALSE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_nthLastChild:
|
||||
if (!nthChildGenericMatches(data, aTreeMatchContext, pseudoClass,
|
||||
PR_FALSE, PR_TRUE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_nthOfType:
|
||||
if (!nthChildGenericMatches(data, aTreeMatchContext, pseudoClass,
|
||||
PR_TRUE, PR_FALSE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_nthLastOfType:
|
||||
if (!nthChildGenericMatches(data, aTreeMatchContext, pseudoClass,
|
||||
PR_TRUE, PR_TRUE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_mozHasHandlerRef:
|
||||
{
|
||||
nsIContent *child = nsnull;
|
||||
nsIContent *element = data.mContent;
|
||||
PRInt32 index = -1;
|
||||
|
||||
do {
|
||||
child = element->GetChildAt(++index);
|
||||
if (child && child->IsHTML() &&
|
||||
child->Tag() == nsGkAtoms::param &&
|
||||
child->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
|
||||
NS_LITERAL_STRING("pluginurl"),
|
||||
eIgnoreCase)) {
|
||||
break;
|
||||
}
|
||||
} while (child);
|
||||
if (!child) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_mozIsHTML:
|
||||
if (!data.mIsHTML) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_mozSystemMetric:
|
||||
{
|
||||
nsCOMPtr<nsIAtom> metric = do_GetAtom(pseudoClass->u.mString);
|
||||
if (!nsCSSRuleProcessor::HasSystemMetric(metric)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_mozLocaleDir:
|
||||
{
|
||||
PRBool docIsRTL =
|
||||
(data.DocumentState() & NS_DOCUMENT_STATE_RTL_LOCALE) != 0;
|
||||
|
||||
nsDependentString dirString(pseudoClass->u.mString);
|
||||
NS_ASSERTION(dirString.EqualsLiteral("ltr") ||
|
||||
dirString.EqualsLiteral("rtl"),
|
||||
"invalid value for -moz-locale-dir");
|
||||
|
||||
if (dirString.EqualsLiteral("rtl") != docIsRTL) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_mozLWTheme:
|
||||
{
|
||||
nsIDocument* doc = data.mContent->GetOwnerDoc();
|
||||
if (!doc ||
|
||||
doc->GetDocumentLWTheme() <= nsIDocument::Doc_Theme_None) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_mozLWThemeBrightText:
|
||||
{
|
||||
nsIDocument* doc = data.mContent->GetOwnerDoc();
|
||||
if (!doc ||
|
||||
doc->GetDocumentLWTheme() != nsIDocument::Doc_Theme_Bright) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_mozLWThemeDarkText:
|
||||
{
|
||||
nsIDocument* doc = data.mContent->GetOwnerDoc();
|
||||
if (!doc ||
|
||||
doc->GetDocumentLWTheme() != nsIDocument::Doc_Theme_Dark) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_mozWindowInactive:
|
||||
if ((data.DocumentState() & NS_DOCUMENT_STATE_WINDOW_INACTIVE) == 0) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_ABORT_IF_FALSE(PR_FALSE, "How did that happen?");
|
||||
}
|
||||
} else {
|
||||
PRInt32 statesToCheck = info.mBits;
|
||||
NS_ABORT_IF_FALSE(statesToCheck != 0, "How did that happen?");
|
||||
// Bit-based pseudo-classes
|
||||
if ((statesToCheck & (NS_EVENT_STATE_HOVER | NS_EVENT_STATE_ACTIVE)) &&
|
||||
data.mCompatMode == eCompatibility_NavQuirks &&
|
||||
// global selector (but don't check .class):
|
||||
|
@ -2668,7 +2551,7 @@ PRBool IsStateSelector(nsCSSSelector& aSelector)
|
|||
if (pseudoClass->mType >= nsCSSPseudoClasses::ePseudoClass_Count) {
|
||||
continue;
|
||||
}
|
||||
if (sPseudoClassInfo[pseudoClass->mType].mBits) {
|
||||
if (sPseudoClassBits[pseudoClass->mType]) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -534,7 +534,10 @@ nsHttpResponseHead::GetMaxAgeValue(PRUint32 *result)
|
|||
if (!p)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
*result = (PRUint32) atoi(p + 8);
|
||||
int maxAgeValue = atoi(p + 8);
|
||||
if (maxAgeValue < 0)
|
||||
maxAgeValue = 0;
|
||||
*result = PRUint32(maxAgeValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче