This commit is contained in:
Robert Sayre 2010-04-26 16:30:52 -04:00
Родитель 7633163736 14e71ac217
Коммит dc740985af
9 изменённых файлов: 542 добавлений и 493 удалений

Просмотреть файл

@ -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;
}