diff --git a/layout/reftests/forms/indeterminate-native-checked-notref.html b/layout/reftests/forms/indeterminate-native-checked-notref.html
new file mode 100644
index 00000000000..cf16667cbf0
--- /dev/null
+++ b/layout/reftests/forms/indeterminate-native-checked-notref.html
@@ -0,0 +1 @@
+
diff --git a/layout/reftests/forms/indeterminate-native-checked.html b/layout/reftests/forms/indeterminate-native-checked.html
new file mode 100644
index 00000000000..91097098ce1
--- /dev/null
+++ b/layout/reftests/forms/indeterminate-native-checked.html
@@ -0,0 +1 @@
+
diff --git a/layout/reftests/forms/indeterminate-native-unchecked-notref.html b/layout/reftests/forms/indeterminate-native-unchecked-notref.html
new file mode 100644
index 00000000000..74c06d2536e
--- /dev/null
+++ b/layout/reftests/forms/indeterminate-native-unchecked-notref.html
@@ -0,0 +1 @@
+
diff --git a/layout/reftests/forms/indeterminate-native-unchecked.html b/layout/reftests/forms/indeterminate-native-unchecked.html
new file mode 100644
index 00000000000..11832f47794
--- /dev/null
+++ b/layout/reftests/forms/indeterminate-native-unchecked.html
@@ -0,0 +1 @@
+
diff --git a/layout/reftests/forms/reftest.list b/layout/reftests/forms/reftest.list
index 15ef7400957..c262257eef6 100644
--- a/layout/reftests/forms/reftest.list
+++ b/layout/reftests/forms/reftest.list
@@ -7,3 +7,5 @@
== out-of-bounds-selectedindex.html out-of-bounds-selectedindex-ref.html # bug 471741
!= indeterminate-checked.html indeterminate-checked-notref.html
!= 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
diff --git a/widget/src/windows/nsNativeThemeWin.cpp b/widget/src/windows/nsNativeThemeWin.cpp
index b7b5283f776..8b0b4a142b4 100644
--- a/widget/src/windows/nsNativeThemeWin.cpp
+++ b/widget/src/windows/nsNativeThemeWin.cpp
@@ -417,45 +417,30 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
bool isCheckbox = (aWidgetType == NS_THEME_CHECKBOX);
aPart = isCheckbox ? BP_CHECKBOX : BP_RADIO;
- // XXXdwh This check will need to be more complicated, since HTML radio groups
- // use checked, but XUL radio groups use selected. There will need to be an
- // IsNodeOfType test for HTML vs. XUL here.
- nsIAtom* atom = isCheckbox ? nsWidgetAtoms::checked
- : nsWidgetAtoms::selected;
-
- PRBool isHTML = PR_FALSE;
- PRBool isHTMLChecked = PR_FALSE;
+ enum InputState {
+ UNCHECKED = 0, CHECKED, INDETERMINATE
+ };
+ InputState inputState = UNCHECKED;
PRBool isXULCheckboxRadio = PR_FALSE;
-
- if (!aFrame)
+
+ if (!aFrame) {
aState = TS_NORMAL;
- else {
- // For XUL checkboxes and radio buttons, the state of the parent
- // determines our state.
- nsIContent* content = aFrame->GetContent();
- PRBool isXULCheckboxRadio = content->IsNodeOfType(nsINode::eXUL);
- if (!isXULCheckboxRadio) {
- // Attempt a QI.
- nsCOMPtr inputElt(do_QueryInterface(content));
- if (inputElt) {
- inputElt->GetChecked(&isHTMLChecked);
- isHTML = PR_TRUE;
- }
+ } else {
+ if (GetCheckedOrSelected(aFrame, !isCheckbox)) {
+ inputState = CHECKED;
+ } if (isCheckbox && GetIndeterminate(aFrame)) {
+ inputState = INDETERMINATE;
}
- if (IsDisabled(isXULCheckboxRadio ? aFrame->GetParent(): aFrame))
+ if (IsDisabled(isXULCheckboxRadio ? aFrame->GetParent() : aFrame)) {
aState = TS_DISABLED;
- else {
+ } else {
aState = StandardGetState(aFrame, aWidgetType, PR_FALSE);
}
}
- if (isHTML) {
- if (isHTMLChecked)
- aState += 4;
- }
- else if (isCheckbox ? IsChecked(aFrame) : IsSelected(aFrame))
- aState += 4; // 4 unchecked states, 4 checked states.
+ // 4 unchecked states, 4 checked states, 4 indeterminate states.
+ aState += inputState * 4;
return NS_OK;
}
case NS_THEME_TEXTFIELD:
@@ -1994,44 +1979,43 @@ nsresult nsNativeThemeWin::ClassicGetThemePartAndState(nsIFrame* aFrame, PRUint8
}
case NS_THEME_CHECKBOX:
case NS_THEME_RADIO: {
- PRInt32 contentState ;
+ PRInt32 contentState;
aFocused = PR_FALSE;
aPart = DFC_BUTTON;
- aState = (aWidgetType == NS_THEME_CHECKBOX) ? DFCS_BUTTONCHECK : DFCS_BUTTONRADIO;
+ aState = 0;
nsIContent* content = aFrame->GetContent();
-
- if (content->IsNodeOfType(nsINode::eXUL)) {
- // XUL
- if (aWidgetType == NS_THEME_CHECKBOX) {
- if (IsChecked(aFrame))
- aState |= DFCS_CHECKED;
- }
- else
- if (IsSelected(aFrame))
- aState |= DFCS_CHECKED;
- contentState = GetContentState(aFrame, aWidgetType);
- }
- else {
- // HTML
+ PRBool isCheckbox = (aWidgetType == NS_THEME_CHECKBOX);
+ PRBool isChecked = GetCheckedOrSelected(aFrame, !isCheckbox);
+ PRBool isIndeterminate = isCheckbox && GetIndeterminate(aFrame);
- nsCOMPtr inputElt(do_QueryInterface(content));
- if (inputElt) {
- PRBool isChecked = PR_FALSE;
- inputElt->GetChecked(&isChecked);
- if (isChecked)
- aState |= DFCS_CHECKED;
+ if (isCheckbox) {
+ // indeterminate state takes precedence over checkedness.
+ if (isIndeterminate) {
+ aState = DFCS_BUTTON3STATE | DFCS_CHECKED;
+ } else {
+ aState = DFCS_BUTTONCHECK;
}
- contentState = GetContentState(aFrame, aWidgetType);
- if (contentState & NS_EVENT_STATE_FOCUS)
- aFocused = PR_TRUE;
+ } else {
+ aState = DFCS_BUTTONRADIO;
+ }
+ if (isChecked) {
+ aState |= DFCS_CHECKED;
}
- if (IsDisabled(aFrame))
+ contentState = GetContentState(aFrame, aWidgetType);
+ if (!content->IsNodeOfType(nsINode::eXUL) &&
+ (contentState & NS_EVENT_STATE_FOCUS)) {
+ aFocused = PR_TRUE;
+ }
+
+ if (IsDisabled(aFrame)) {
aState |= DFCS_INACTIVE;
- else if (contentState & NS_EVENT_STATE_ACTIVE && contentState & NS_EVENT_STATE_HOVER)
+ } else if (contentState & NS_EVENT_STATE_ACTIVE &&
+ contentState & NS_EVENT_STATE_HOVER) {
aState |= DFCS_PUSHED;
-
+ }
+
return NS_OK;
}
case NS_THEME_MENUITEM: