diff --git a/content/base/public/nsIContent.h b/content/base/public/nsIContent.h index e58568d8563d..b52f8f069f8e 100644 --- a/content/base/public/nsIContent.h +++ b/content/base/public/nsIContent.h @@ -60,8 +60,8 @@ class nsIURI; // IID for the nsIContent interface #define NS_ICONTENT_IID \ -{ 0x10caf6a4, 0x8891, 0x46c9, \ - { 0x9b, 0x6c, 0x6d, 0xc8, 0xdf, 0x01, 0x2d, 0x29 } } +{ 0x3fecc374, 0x2839, 0x4db3, \ + { 0x8d, 0xe8, 0x6b, 0x76, 0xd1, 0xd8, 0xe6, 0xf6 } } /** * A node of content in a document's content model. This interface @@ -651,6 +651,20 @@ public: return PR_TRUE; } + /** + * Method to get the _intrinsic_ content state of this content node. This is + * the state that is independent of the node's presentation. To get the full + * content state, use nsIEventStateManager. Also see nsIEventStateManager + * for the possible bits that could be set here. + */ + // XXXbz this is PRInt32 because all the ESM content state APIs use + // PRInt32. We should really use PRUint32 instead. + virtual PRInt32 IntrinsicState() const + { + return 0; + } + + /* Methods for manipulating content node properties. For documentation on * properties, see nsPropertyTable.h. */ diff --git a/content/events/public/nsIEventStateManager.h b/content/events/public/nsIEventStateManager.h index 9fb2ef13571e..39a69fef8ce8 100644 --- a/content/events/public/nsIEventStateManager.h +++ b/content/events/public/nsIEventStateManager.h @@ -132,7 +132,6 @@ public: NS_IMETHOD ShiftFocus(PRBool aDirection, nsIContent* aStart)=0; }; -#define NS_EVENT_STATE_UNSPECIFIED 0x0000 #define NS_EVENT_STATE_ACTIVE 0x0001 // mouse is down on content #define NS_EVENT_STATE_FOCUS 0x0002 // content has focus #define NS_EVENT_STATE_HOVER 0x0004 // mouse is hovering over content diff --git a/content/events/src/nsEventStateManager.cpp b/content/events/src/nsEventStateManager.cpp index 36d44b6e3364..efbffea2b12e 100644 --- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -3625,7 +3625,7 @@ nsEventStateManager::GetEventRelatedContent(nsIContent** aContent) NS_IMETHODIMP nsEventStateManager::GetContentState(nsIContent *aContent, PRInt32& aState) { - aState = NS_EVENT_STATE_UNSPECIFIED; + aState = aContent->IntrinsicState(); // Hierchical active: Check the ancestor chain of mActiveContent to see // if we are on it. diff --git a/content/html/content/src/nsHTMLInputElement.cpp b/content/html/content/src/nsHTMLInputElement.cpp index 9e3ce555d91e..621b19b95b9d 100644 --- a/content/html/content/src/nsHTMLInputElement.cpp +++ b/content/html/content/src/nsHTMLInputElement.cpp @@ -225,6 +225,8 @@ public: virtual void DoneCreatingElement(); + virtual PRInt32 IntrinsicState() const; + // nsITextControlElement NS_IMETHOD TakeTextFrameValue(const nsAString& aValue); NS_IMETHOD SetValueChanged(PRBool aValueChanged); @@ -2461,6 +2463,18 @@ nsHTMLInputElement::DoneCreatingElement() SET_BOOLBIT(mBitField, BF_SHOULD_INIT_CHECKED, PR_FALSE); } +PRInt32 +nsHTMLInputElement::IntrinsicState() const +{ + PRInt32 state = nsGenericHTMLFormElement::IntrinsicState(); + if (GET_BOOLBIT(mBitField, BF_CHECKED) && + (mType == NS_FORM_INPUT_CHECKBOX || + mType == NS_FORM_INPUT_RADIO)) { + state |= NS_EVENT_STATE_CHECKED; + } + return state; +} + PRBool nsHTMLInputElement::RestoreState(nsPresState* aState) { diff --git a/content/html/content/src/nsHTMLOptionElement.cpp b/content/html/content/src/nsHTMLOptionElement.cpp index 71cb42e7fa41..40d9f7406d96 100644 --- a/content/html/content/src/nsHTMLOptionElement.cpp +++ b/content/html/content/src/nsHTMLOptionElement.cpp @@ -122,6 +122,7 @@ public: PRBool aNotify); virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify); virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify); + virtual PRInt32 IntrinsicState() const; protected: /** @@ -493,6 +494,20 @@ nsHTMLOptionElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify) return rv; } +PRInt32 +nsHTMLOptionElement::IntrinsicState() const +{ + PRInt32 state = nsGenericHTMLElement::IntrinsicState(); + // Nasty hack because we need to call an interface method, and one that + // toggles some of our hidden internal state at that! Would that we could + // use |mutable|. + PRBool selected; + NS_CONST_CAST(nsHTMLOptionElement*, this)->GetSelected(&selected); + if (selected) { + state |= NS_EVENT_STATE_CHECKED; + } + return state; +} // Options don't have frames - get the select content node // then call nsGenericHTMLElement::GetFormControlFrameFor() diff --git a/extensions/inspector/base/src/inDOMUtils.cpp b/extensions/inspector/base/src/inDOMUtils.cpp index 01b173daac0d..6108f9b866f3 100644 --- a/extensions/inspector/base/src/inDOMUtils.cpp +++ b/extensions/inspector/base/src/inDOMUtils.cpp @@ -233,7 +233,7 @@ inDOMUtils::SetContentState(nsIDOMElement *aElement, PRInt32 aState) NS_IMETHODIMP inDOMUtils::GetContentState(nsIDOMElement *aElement, PRInt32* aState) { - *aState = NS_EVENT_STATE_UNSPECIFIED; + *aState = 0; if (!aElement) return NS_ERROR_NULL_POINTER; diff --git a/layout/style/nsCSSStyleSheet.cpp b/layout/style/nsCSSStyleSheet.cpp index fbf4571152a7..45c94edb3615 100644 --- a/layout/style/nsCSSStyleSheet.cpp +++ b/layout/style/nsCSSStyleSheet.cpp @@ -2655,9 +2655,8 @@ RuleProcessorData::RuleProcessorData(nsPresContext* aPresContext, mIsHTMLContent = PR_FALSE; mIsHTMLLink = PR_FALSE; mIsSimpleXLink = PR_FALSE; - mIsChecked = PR_FALSE; mLinkState = eLinkState_Unknown; - mEventState = NS_EVENT_STATE_UNSPECIFIED; + mEventState = 0; mNameSpaceID = kNameSpaceID_Unknown; mPreviousSiblingData = nsnull; mParentData = nsnull; @@ -2721,18 +2720,6 @@ RuleProcessorData::RuleProcessorData(nsPresContext* aPresContext, nsStyleUtil::IsSimpleXlink(aContent, mPresContext, &mLinkState)) { mIsSimpleXLink = PR_TRUE; } - - if (mIsHTMLContent) { - PRBool isChecked = PR_FALSE; - if (mContentTag == nsHTMLAtoms::option) { - nsCOMPtr optEl = do_QueryInterface(mContent); - optEl->GetSelected(&isChecked); - } else if (mContentTag == nsHTMLAtoms::input) { - nsCOMPtr inputEl = do_QueryInterface(mContent); - inputEl->GetChecked(&isChecked); - } - mIsChecked = isChecked; - } } } @@ -2900,6 +2887,10 @@ static PRBool AttrMatchesValue(const nsAttrSelector* aAttrSelector, } } +#define STATE_CHECK(_state) \ + ((aStateMask & (_state)) || \ + (localTrue == (0 != (data.mEventState & (_state))))) + // NOTE: The |aStateMask| code isn't going to work correctly anymore if // we start batching style changes, because if multiple states change in // separate notifications then we might determine the style is not @@ -3095,24 +3086,19 @@ static PRBool SelectorMatches(RuleProcessorData &data, result = localFalse; } else { if (nsCSSPseudoClasses::active == pseudoClass->mAtom) { - result = (aStateMask & NS_EVENT_STATE_ACTIVE) || - (localTrue == (0 != (data.mEventState & NS_EVENT_STATE_ACTIVE))); + result = STATE_CHECK(NS_EVENT_STATE_ACTIVE); } else if (nsCSSPseudoClasses::focus == pseudoClass->mAtom) { - result = (aStateMask & NS_EVENT_STATE_FOCUS) || - (localTrue == (0 != (data.mEventState & NS_EVENT_STATE_FOCUS))); + result = STATE_CHECK(NS_EVENT_STATE_FOCUS); } else if (nsCSSPseudoClasses::hover == pseudoClass->mAtom) { - result = (aStateMask & NS_EVENT_STATE_HOVER) || - (localTrue == (0 != (data.mEventState & NS_EVENT_STATE_HOVER))); + result = STATE_CHECK(NS_EVENT_STATE_HOVER); } else if (nsCSSPseudoClasses::mozDragOver == pseudoClass->mAtom) { - result = (aStateMask & NS_EVENT_STATE_DRAGOVER) || - (localTrue == (0 != (data.mEventState & NS_EVENT_STATE_DRAGOVER))); + result = STATE_CHECK(NS_EVENT_STATE_DRAGOVER); } else if (nsCSSPseudoClasses::target == pseudoClass->mAtom) { - result = (aStateMask & NS_EVENT_STATE_URLTARGET) || - (localTrue == (0 != (data.mEventState & NS_EVENT_STATE_URLTARGET))); + result = STATE_CHECK(NS_EVENT_STATE_URLTARGET); } } } @@ -3137,8 +3123,7 @@ static PRBool SelectorMatches(RuleProcessorData &data, //