Bug 477531. Support CSS3 :indeterminate pseudo-class. r+sr=dbaron,r=bzbarsky

--HG--
extra : rebase_source : 03d1be9b5742e8d17114aaeb0b5de20d61926d51
This commit is contained in:
Michael Ventnor 2009-02-11 14:19:37 +13:00
Родитель 1e63ca7445
Коммит 8ddfeb2aa2
9 изменённых файлов: 122 добавлений и 8 удалений

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

@ -225,4 +225,6 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIEventStateManager, NS_IEVENTSTATEMANAGER_IID)
#define NS_EVENT_STATE_HANDLER_DISABLED \
0x02000000
#define NS_EVENT_STATE_INDETERMINATE 0x04000000 // CSS3-Selectors
#endif // nsIEventStateManager_h__

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

@ -322,6 +322,9 @@ protected:
nsITextControlFrame* aFrame,
PRBool aUserInput);
nsresult SetIndeterminateInternal(PRBool aValue,
PRBool aShouldInvalidate);
nsresult GetSelectionRange(PRInt32* aSelectionStart, PRInt32* aSelectionEnd);
/**
@ -686,6 +689,7 @@ nsHTMLInputElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
NS_EVENT_STATE_USERDISABLED |
NS_EVENT_STATE_SUPPRESSED |
NS_EVENT_STATE_LOADING |
NS_EVENT_STATE_INDETERMINATE |
NS_EVENT_STATE_MOZ_READONLY |
NS_EVENT_STATE_MOZ_READWRITE);
}
@ -763,19 +767,35 @@ nsHTMLInputElement::GetIndeterminate(PRBool* aValue)
return NS_OK;
}
NS_IMETHODIMP
nsHTMLInputElement::SetIndeterminate(PRBool aValue)
nsresult
nsHTMLInputElement::SetIndeterminateInternal(PRBool aValue,
PRBool aShouldInvalidate)
{
SET_BOOLBIT(mBitField, BF_INDETERMINATE, aValue);
// Repaint the frame
nsIFrame* frame = GetPrimaryFrame();
if (frame)
frame->InvalidateOverflowRect();
if (aShouldInvalidate) {
// Repaint the frame
nsIFrame* frame = GetPrimaryFrame();
if (frame)
frame->InvalidateOverflowRect();
}
// Notify the document so it can update :indeterminate pseudoclass rules
nsIDocument* document = GetCurrentDoc();
if (document) {
mozAutoDocUpdate upd(document, UPDATE_CONTENT_STATE, PR_TRUE);
document->ContentStatesChanged(this, nsnull, NS_EVENT_STATE_INDETERMINATE);
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLInputElement::SetIndeterminate(PRBool aValue)
{
return SetIndeterminateInternal(aValue, PR_TRUE);
}
NS_IMETHODIMP
nsHTMLInputElement::GetSize(PRUint32* aValue)
{
@ -1539,7 +1559,7 @@ nsHTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
{
if (GET_BOOLBIT(mBitField, BF_INDETERMINATE)) {
// indeterminate is always set to FALSE when the checkbox is toggled
SET_BOOLBIT(mBitField, BF_INDETERMINATE, PR_FALSE);
SetIndeterminateInternal(PR_FALSE, PR_FALSE);
aVisitor.mItemFlags |= NS_ORIGINAL_INDETERMINATE_VALUE;
}
@ -1695,7 +1715,7 @@ nsHTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
} else if (oldType == NS_FORM_INPUT_CHECKBOX) {
PRBool originalIndeterminateValue =
!!(aVisitor.mItemFlags & NS_ORIGINAL_INDETERMINATE_VALUE);
SET_BOOLBIT(mBitField, BF_INDETERMINATE, originalIndeterminateValue);
SetIndeterminateInternal(originalIndeterminateValue, PR_FALSE);
DoSetChecked(originalCheckedValue);
}
} else {
@ -2729,6 +2749,11 @@ nsHTMLInputElement::IntrinsicState() const
state |= NS_EVENT_STATE_CHECKED;
}
// Check current indeterminate state (:indeterminate)
if (mType == NS_FORM_INPUT_CHECKBOX && GET_BOOLBIT(mBitField, BF_INDETERMINATE)) {
state |= NS_EVENT_STATE_INDETERMINATE;
}
// Check whether we are the default checked element (:default)
// The call is to an interface function, which makes it non-const, so we
// use a nasty hack :(

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

@ -50,6 +50,7 @@ _TEST_FILES = test_bug345267.html \
test_bug411236.html \
test_bug446663.html \
test_bug476308.html \
test_bug477531.html \
$(NULL)
libs:: $(_TEST_FILES)

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

@ -0,0 +1,66 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=477531
-->
<head>
<title>Test for Bug 477531</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<style type="text/css">
#s {
margin-left: 10px;
}
#s:indeterminate {
margin-left: 30px;
}
</style>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=477531">Mozilla Bug 477531</a>
<p id="display"></p>
<div id="content">
<input type="checkbox" id="s" />
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 477531 **/
is(document.defaultView.getComputedStyle($("s"), null).getPropertyValue("margin-left"),
"10px",
"Non-indeterminate checkbox should have a margin of 10px");
$("s").indeterminate = true;
is(document.defaultView.getComputedStyle($("s"), null).getPropertyValue("margin-left"),
"30px",
"Indeterminate checkbox should have a margin of 30px");
$("s").setAttribute("type", "radio");
is(document.defaultView.getComputedStyle($("s"), null).getPropertyValue("margin-left"),
"10px",
"Only checkboxes should have indeterminate styles applied to them");
$("s").setAttribute("type", "checkbox");
is(document.defaultView.getComputedStyle($("s"), null).getPropertyValue("margin-left"),
"30px",
"Setting an indeterminate element to type checkbox should give it indeterminate styles");
$("s").indeterminate = false;
is(document.defaultView.getComputedStyle($("s"), null).getPropertyValue("margin-left"),
"10px",
"Newly non-indeterminate checkbox should have a margin of 10px");
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,7 @@
<style>
#s {
margin: 50px;
}
</style>
<input type="checkbox" id="s"><script>document.getElementById("s").indeterminate = true;</script>

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

@ -0,0 +1,7 @@
<style>
#s:indeterminate {
margin: 50px;
}
</style>
<input type="checkbox" id="s"><script>document.getElementById("s").indeterminate = true;</script>

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

@ -9,3 +9,4 @@
!= indeterminate-unchecked.html indeterminate-unchecked-notref.html
!= indeterminate-native-checked.html indeterminate-native-checked-notref.html
!= indeterminate-native-unchecked.html indeterminate-native-unchecked-notref.html
== indeterminate-selector.html indeterminate-selector-ref.html

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

@ -72,6 +72,7 @@ CSS_PSEUDO_CLASS(focus, ":focus")
CSS_PSEUDO_CLASS(hover, ":hover")
CSS_PSEUDO_CLASS(mozDragOver, ":-moz-drag-over")
CSS_PSEUDO_CLASS(target, ":target")
CSS_PSEUDO_CLASS(indeterminate, ":indeterminate")
CSS_PSEUDO_CLASS(firstChild, ":first-child")
CSS_PSEUDO_CLASS(firstNode, ":-moz-first-node")

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

@ -1573,6 +1573,9 @@ static PRBool SelectorMatches(RuleProcessorData &data,
else if (nsCSSPseudoClasses::mozReadWrite == pseudoClass->mAtom) {
stateToCheck = NS_EVENT_STATE_MOZ_READWRITE;
}
else if (nsCSSPseudoClasses::indeterminate == pseudoClass->mAtom) {
stateToCheck = NS_EVENT_STATE_INDETERMINATE;
}
else if (nsCSSPseudoClasses::mozIsHTML == pseudoClass->mAtom) {
result = data.mIsHTMLContent &&
data.mContent->GetNameSpaceID() == kNameSpaceID_None;
@ -2209,6 +2212,7 @@ PRBool IsStateSelector(nsCSSSelector& aSelector)
(pseudoClass->mAtom == nsCSSPseudoClasses::outOfRange) ||
(pseudoClass->mAtom == nsCSSPseudoClasses::mozReadOnly) ||
(pseudoClass->mAtom == nsCSSPseudoClasses::mozReadWrite) ||
(pseudoClass->mAtom == nsCSSPseudoClasses::indeterminate) ||
#ifdef MOZ_MATHML
(pseudoClass->mAtom == nsCSSPseudoClasses::mozMathIncrementScriptLevel) ||
#endif