зеркало из https://github.com/mozilla/pjs.git
Add an nsIContent api for getting the intrinsic state of the content; this can
be used to implement more pseudo-classes (eg CSS3 UI ones for XForms). Bug 296309, r+sr=dbaron, a=chofmann
This commit is contained in:
Родитель
c65178a702
Коммит
8fc3ac9a30
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<nsIDOMHTMLOptionElement> optEl = do_QueryInterface(mContent);
|
||||
optEl->GetSelected(&isChecked);
|
||||
} else if (mContentTag == nsHTMLAtoms::input) {
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> 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,
|
|||
// <option>
|
||||
// <input type=checkbox>
|
||||
// <input type=radio>
|
||||
if (!(aStateMask & NS_EVENT_STATE_CHECKED))
|
||||
result = data.mIsChecked ? localTrue : localFalse;
|
||||
result = STATE_CHECK(NS_EVENT_STATE_CHECKED);
|
||||
}
|
||||
else {
|
||||
NS_ERROR("CSS parser parsed a pseudo-class that we do not handle");
|
||||
|
@ -3295,6 +3280,8 @@ static PRBool SelectorMatches(RuleProcessorData &data,
|
|||
return result;
|
||||
}
|
||||
|
||||
#undef STATE_CHECK
|
||||
|
||||
// Right now, there are four operators:
|
||||
// PRUnichar(0), the descendent combinator, is greedy
|
||||
// '~', the indirect adjacent sibling combinator, is greedy
|
||||
|
|
|
@ -90,7 +90,6 @@ struct RuleProcessorData {
|
|||
PRPackedBool mIsSimpleXLink; // if content, calls nsStyleUtil::IsSimpleXLink
|
||||
nsCompatibility mCompatMode; // Possibly remove use of this in SelectorMatches?
|
||||
PRPackedBool mHasAttributes; // if content, content->GetAttrCount() > 0
|
||||
PRPackedBool mIsChecked; // checked/selected attribute for option and select elements
|
||||
nsLinkState mLinkState; // if a link, this is the state, otherwise unknown
|
||||
PRInt32 mEventState; // if content, eventStateMgr->GetContentState()
|
||||
PRInt32 mNameSpaceID; // if content, content->GetNameSapce()
|
||||
|
|
Загрузка…
Ссылка в новой задаче