зеркало из https://github.com/mozilla/pjs.git
Fix up and enable hierarchical :hover and remove the hacks that made :hover work for anchors without it. Pass mask rather than pseudo-class to ContentStatesChanged notifications. Optimize event state changes in the style system by passing state mask to HasStateDependentStyle and using it in HasStateDependentStyle implementations. b=5693 r=bryner, joki sr=hyatt
This commit is contained in:
Родитель
ee356815ee
Коммит
324f543007
|
@ -319,7 +319,7 @@ public:
|
|||
// either may be nsnull, but not both
|
||||
NS_IMETHOD ContentStatesChanged(nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass) = 0;
|
||||
PRInt32 aStateMask) = 0;
|
||||
NS_IMETHOD AttributeWillChange(nsIContent* aChild,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute) = 0;
|
||||
|
|
|
@ -139,7 +139,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass) = 0;
|
||||
PRInt32 aStateMask) = 0;
|
||||
|
||||
/**
|
||||
* Notification that the content model has changed. This method is called
|
||||
|
|
|
@ -131,11 +131,15 @@ struct PseudoRuleProcessorData : public RuleProcessorData {
|
|||
|
||||
struct StateRuleProcessorData : public RuleProcessorData {
|
||||
StateRuleProcessorData(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent)
|
||||
: RuleProcessorData(aPresContext, aContent, nsnull)
|
||||
nsIContent* aContent,
|
||||
PRInt32 aStateMask)
|
||||
: RuleProcessorData(aPresContext, aContent, nsnull),
|
||||
mStateMask(aStateMask)
|
||||
{
|
||||
NS_PRECONDITION(aContent, "null pointer");
|
||||
}
|
||||
const PRInt32 mStateMask; // |HasStateDependentStyle| for which state(s)?
|
||||
// Constants defined in nsIEventStateManager.h .
|
||||
};
|
||||
|
||||
|
||||
|
@ -162,8 +166,9 @@ public:
|
|||
nsIAtom* aMedium) = 0;
|
||||
|
||||
// Test if style is dependent on content state
|
||||
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||
nsIAtom* aMedium) = 0;
|
||||
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||
nsIAtom* aMedium,
|
||||
PRBool* aResult) = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize) = 0;
|
||||
|
|
|
@ -139,7 +139,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass) { return NS_OK; }
|
||||
PRInt32 aStateMask) { return NS_OK; }
|
||||
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
|
|
@ -1857,14 +1857,14 @@ nsDocument::ContentChanged(nsIContent* aContent,
|
|||
NS_IMETHODIMP
|
||||
nsDocument::ContentStatesChanged(nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass)
|
||||
PRInt32 aStateMask)
|
||||
{
|
||||
PRInt32 i;
|
||||
// Get new value of count for every iteration in case
|
||||
// observers remove themselves during the loop.
|
||||
for (i = 0; i < mObservers.Count(); i++) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->ContentStatesChanged(this, aContent1, aContent2, aChangedPseudoClass);
|
||||
observer->ContentStatesChanged(this, aContent1, aContent2, aStateMask);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (i < mObservers.Count() &&
|
||||
|
|
|
@ -163,7 +163,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass) { return NS_OK; }
|
||||
PRInt32 aStateMask) { return NS_OK; }
|
||||
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
@ -454,7 +454,7 @@ public:
|
|||
nsISupports* aSubContent);
|
||||
NS_IMETHOD ContentStatesChanged(nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass);
|
||||
PRInt32 aStateMask);
|
||||
|
||||
NS_IMETHOD AttributeWillChange(nsIContent* aChild,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
|
|
@ -205,8 +205,10 @@ public:
|
|||
nsIStyleContext* aNewParentContext,
|
||||
nsIStyleContext** aNewStyleContext);
|
||||
|
||||
NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent);
|
||||
NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aStateMask,
|
||||
PRBool* aResult);
|
||||
|
||||
NS_IMETHOD ConstructRootFrame(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
|
@ -235,7 +237,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass);
|
||||
PRInt32 aStateMask);
|
||||
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
@ -1432,8 +1434,9 @@ StyleSetImpl::ReParentStyleContext(nsIPresContext* aPresContext,
|
|||
}
|
||||
|
||||
struct StatefulData : public StateRuleProcessorData {
|
||||
StatefulData(nsIPresContext* aPresContext, nsIAtom* aMedium, nsIContent* aContent)
|
||||
: StateRuleProcessorData(aPresContext, aContent),
|
||||
StatefulData(nsIPresContext* aPresContext, nsIAtom* aMedium,
|
||||
nsIContent* aContent, PRInt32 aStateMask)
|
||||
: StateRuleProcessorData(aPresContext, aContent, aStateMask),
|
||||
mMedium(aMedium),
|
||||
mStateful(PR_FALSE)
|
||||
{}
|
||||
|
@ -1445,17 +1448,18 @@ static PRBool SheetHasStatefulStyle(nsISupports* aProcessor, void *aData)
|
|||
{
|
||||
nsIStyleRuleProcessor* processor = (nsIStyleRuleProcessor*)aProcessor;
|
||||
StatefulData* data = (StatefulData*)aData;
|
||||
if (NS_OK == processor->HasStateDependentStyle(data, data->mMedium)) {
|
||||
data->mStateful = PR_TRUE;
|
||||
processor->HasStateDependentStyle(data, data->mMedium, &data->mStateful);
|
||||
if (data->mStateful)
|
||||
return PR_FALSE; // stop iteration
|
||||
}
|
||||
return PR_TRUE; // continue
|
||||
}
|
||||
|
||||
// Test if style is dependent on content state
|
||||
NS_IMETHODIMP
|
||||
StyleSetImpl::HasStateDependentStyle(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent)
|
||||
nsIContent* aContent,
|
||||
PRInt32 aStateMask,
|
||||
PRBool* aResult)
|
||||
{
|
||||
GatherRuleProcessors();
|
||||
|
||||
|
@ -1466,12 +1470,15 @@ StyleSetImpl::HasStateDependentStyle(nsIPresContext* aPresContext,
|
|||
mOverrideRuleProcessors)) {
|
||||
nsIAtom* medium = nsnull;
|
||||
aPresContext->GetMedium(&medium);
|
||||
StatefulData data(aPresContext, medium, aContent);
|
||||
StatefulData data(aPresContext, medium, aContent, aStateMask);
|
||||
WalkRuleProcessors(SheetHasStatefulStyle, &data);
|
||||
NS_IF_RELEASE(medium);
|
||||
return ((data.mStateful) ? NS_OK : NS_COMFALSE);
|
||||
*aResult = data.mStateful;
|
||||
} else {
|
||||
*aResult = PR_FALSE;
|
||||
}
|
||||
return NS_COMFALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1541,10 +1548,10 @@ NS_IMETHODIMP
|
|||
StyleSetImpl::ContentStatesChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass)
|
||||
PRInt32 aStateMask)
|
||||
{
|
||||
return mFrameConstructor->ContentStatesChanged(aPresContext, aContent1, aContent2,
|
||||
aChangedPseudoClass);
|
||||
return mFrameConstructor->ContentStatesChanged(aPresContext, aContent1,
|
||||
aContent2, aStateMask);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -126,6 +126,8 @@ public:
|
|||
#define NS_EVENT_STATE_FOCUS 0x0002 // content has focus
|
||||
#define NS_EVENT_STATE_HOVER 0x0004 // mouse is hovering over content
|
||||
#define NS_EVENT_STATE_DRAGOVER 0x0008 // drag is hovering over content
|
||||
// The following states are used only for ContentStatesChanged
|
||||
#define NS_EVENT_STATE_CHECKED 0x0010
|
||||
|
||||
enum EFocusedWithType {
|
||||
eEventFocusedByUnknown, // focus gained via unknown method
|
||||
|
|
|
@ -183,7 +183,6 @@ nsEventStateManager::nsEventStateManager()
|
|||
mFirstFocusEvent = nsnull;
|
||||
mAccessKeys = nsnull;
|
||||
mBrowseWithCaret = PR_FALSE;
|
||||
hHover = PR_FALSE;
|
||||
mLeftClickOnly = PR_TRUE;
|
||||
mNormalLMouseEventInProcess = PR_FALSE;
|
||||
|
||||
|
@ -210,7 +209,6 @@ nsEventStateManager::Init()
|
|||
rv = getPrefService();
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mPrefService->GetBoolPref("nglayout.events.showHierarchicalHover", &hHover);
|
||||
mPrefService->GetBoolPref("nglayout.events.dispatchLeftClickOnly", &mLeftClickOnly);
|
||||
}
|
||||
|
||||
|
@ -2278,8 +2276,9 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIE
|
|||
targetContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
if ( status != nsEventStatus_eConsumeNoDefault )
|
||||
SetContentState(targetContent, NS_EVENT_STATE_HOVER);
|
||||
// :hover is a state that is more basic than a "default
|
||||
// action", so we don't check |status|. See bug 38380.
|
||||
SetContentState(targetContent, NS_EVENT_STATE_HOVER);
|
||||
|
||||
//Now dispatch to the frame
|
||||
if (mCurrentTarget) {
|
||||
|
@ -2330,8 +2329,9 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIE
|
|||
if (mLastMouseOverContent) {
|
||||
mLastMouseOverContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
|
||||
if ( status != nsEventStatus_eConsumeNoDefault )
|
||||
SetContentState(nsnull, NS_EVENT_STATE_HOVER);
|
||||
// :hover is a state that is more basic than a "default
|
||||
// action", so we don't check |status|. See bug 38380.
|
||||
SetContentState(nsnull, NS_EVENT_STATE_HOVER);
|
||||
}
|
||||
|
||||
//Now dispatch to the frame
|
||||
|
@ -3392,24 +3392,17 @@ nsEventStateManager::GetContentState(nsIContent *aContent, PRInt32& aState)
|
|||
if (aContent == mActiveContent) {
|
||||
aState |= NS_EVENT_STATE_ACTIVE;
|
||||
}
|
||||
if (hHover) {
|
||||
//If using hierchical hover check the ancestor chain of mHoverContent
|
||||
//to see if we are on it.
|
||||
nsCOMPtr<nsIContent> parent = mHoverContent;
|
||||
nsIContent* child;
|
||||
while (parent) {
|
||||
if (aContent == parent.get()) {
|
||||
aState |= NS_EVENT_STATE_HOVER;
|
||||
break;
|
||||
}
|
||||
child = parent;
|
||||
child->GetParent(*getter_AddRefs(parent));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (aContent == mHoverContent) {
|
||||
// Hierchical hover: Check the ancestor chain of mHoverContent to see
|
||||
// if we are on it.
|
||||
nsCOMPtr<nsIContent> hoverContent = mHoverContent;
|
||||
while (hoverContent) {
|
||||
if (aContent == hoverContent) {
|
||||
aState |= NS_EVENT_STATE_HOVER;
|
||||
break;
|
||||
}
|
||||
nsIContent *parent;
|
||||
hoverContent->GetParent(parent);
|
||||
hoverContent = dont_AddRef(parent);
|
||||
}
|
||||
|
||||
if (aContent == mCurrentFocus) {
|
||||
|
@ -3428,6 +3421,7 @@ nsEventStateManager::SetContentState(nsIContent *aContent, PRInt32 aState)
|
|||
nsIContent *notifyContent[maxNotify] = {nsnull, nsnull, nsnull, nsnull, nsnull};
|
||||
|
||||
// check to see that this state is allowed by style. Check dragover too?
|
||||
// XXX This doesn't consider that |aState| is a bitfield.
|
||||
if (mCurrentTarget && (aState == NS_EVENT_STATE_ACTIVE || aState == NS_EVENT_STATE_HOVER))
|
||||
{
|
||||
const nsStyleUserInterface* ui;
|
||||
|
@ -3450,66 +3444,61 @@ nsEventStateManager::SetContentState(nsIContent *aContent, PRInt32 aState)
|
|||
NS_IF_ADDREF(mActiveContent);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> newHover = nsnull;
|
||||
nsCOMPtr<nsIContent> oldHover = nsnull;
|
||||
nsCOMPtr<nsIContent> commonHoverParent = nsnull;
|
||||
nsCOMPtr<nsIContent> commonHoverAncestor, oldHover, newHover;
|
||||
if ((aState & NS_EVENT_STATE_HOVER) && (aContent != mHoverContent)) {
|
||||
if (hHover) {
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
if (aContent && NS_SUCCEEDED(aContent->GetDocument(*getter_AddRefs(doc))) && doc) {
|
||||
newHover = aContent;
|
||||
oldHover = mHoverContent;
|
||||
newHover = aContent;
|
||||
// Find closest common ancestor (commonHoverAncestor)
|
||||
if (mHoverContent && aContent) {
|
||||
// Find the nearest common ancestor by counting the distance to the
|
||||
// root and then walking up again, in pairs.
|
||||
PRInt32 offset = 0;
|
||||
nsCOMPtr<nsIContent> oldAncestor = mHoverContent;
|
||||
for (;;) {
|
||||
++offset;
|
||||
nsIContent *parent;
|
||||
oldAncestor->GetParent(parent);
|
||||
if (!parent)
|
||||
break;
|
||||
oldAncestor = dont_AddRef(parent);
|
||||
}
|
||||
if (mHoverContent && NS_SUCCEEDED(mHoverContent->GetDocument(*getter_AddRefs(doc))) && doc) {
|
||||
oldHover = mHoverContent;
|
||||
nsCOMPtr<nsIContent> newAncestor = aContent;
|
||||
for (;;) {
|
||||
--offset;
|
||||
nsIContent *parent;
|
||||
newAncestor->GetParent(parent);
|
||||
if (!parent)
|
||||
break;
|
||||
newAncestor = dont_AddRef(parent);
|
||||
}
|
||||
NS_ASSERTION(oldAncestor == newAncestor, "different documents");
|
||||
if (oldAncestor == newAncestor) {
|
||||
oldAncestor = mHoverContent;
|
||||
newAncestor = aContent;
|
||||
while (offset > 0) {
|
||||
nsIContent *parent;
|
||||
oldAncestor->GetParent(parent);
|
||||
oldAncestor = dont_AddRef(parent);
|
||||
--offset;
|
||||
}
|
||||
while (offset < 0) {
|
||||
nsIContent *parent;
|
||||
newAncestor->GetParent(parent);
|
||||
newAncestor = dont_AddRef(parent);
|
||||
++offset;
|
||||
}
|
||||
while (oldAncestor != newAncestor) {
|
||||
nsIContent *parent;
|
||||
oldAncestor->GetParent(parent);
|
||||
oldAncestor = dont_AddRef(parent);
|
||||
newAncestor->GetParent(parent);
|
||||
newAncestor = dont_AddRef(parent);
|
||||
}
|
||||
commonHoverAncestor = oldAncestor;
|
||||
}
|
||||
}
|
||||
|
||||
//Find closest common parent
|
||||
nsCOMPtr<nsIContent> parent1 = mHoverContent;
|
||||
nsCOMPtr<nsIContent> parent2;
|
||||
if (mHoverContent && aContent) {
|
||||
while (parent1) {
|
||||
parent2 = aContent;
|
||||
while (parent2) {
|
||||
if (parent1 == parent2) {
|
||||
commonHoverParent = parent1;
|
||||
break;
|
||||
}
|
||||
nsIContent* child2 = parent2;
|
||||
child2->GetParent(*getter_AddRefs(parent2));
|
||||
}
|
||||
if (commonHoverParent) {
|
||||
break;
|
||||
}
|
||||
nsIContent* child1 = parent1;
|
||||
child1->GetParent(*getter_AddRefs(parent1));
|
||||
}
|
||||
}
|
||||
//If new hover content is null we get the top parent of mHoverContent
|
||||
else if (mHoverContent) {
|
||||
nsCOMPtr<nsIContent> parent = mHoverContent;
|
||||
nsIContent* child = nsnull;
|
||||
while (parent) {
|
||||
child = parent;
|
||||
child->GetParent(*getter_AddRefs(parent));
|
||||
}
|
||||
commonHoverParent = child;
|
||||
}
|
||||
//Else if old hover content is null we get the top parent of aContent
|
||||
else {
|
||||
nsCOMPtr<nsIContent> parent = aContent;
|
||||
nsIContent* child = nsnull;
|
||||
while (parent) {
|
||||
child = parent;
|
||||
child->GetParent(*getter_AddRefs(parent));
|
||||
}
|
||||
commonHoverParent = child;
|
||||
}
|
||||
NS_IF_RELEASE(mHoverContent);
|
||||
}
|
||||
else {
|
||||
//transferring ref to notifyContent from mHoverContent
|
||||
notifyContent[1] = mHoverContent; // notify hover first, since more common case
|
||||
}
|
||||
NS_IF_RELEASE(mHoverContent);
|
||||
mHoverContent = aContent;
|
||||
NS_IF_ADDREF(mHoverContent);
|
||||
}
|
||||
|
@ -3533,7 +3522,7 @@ nsEventStateManager::SetContentState(nsIContent *aContent, PRInt32 aState)
|
|||
}
|
||||
}
|
||||
|
||||
if (aContent) { // notify about new content too
|
||||
if (aContent && aContent != newHover) { // notify about new content too
|
||||
notifyContent[0] = aContent;
|
||||
NS_ADDREF(aContent); // everything in notify array has a ref
|
||||
}
|
||||
|
@ -3603,71 +3592,53 @@ nsEventStateManager::SetContentState(nsIContent *aContent, PRInt32 aState)
|
|||
newHover->GetDocument(*getter_AddRefs(doc1));
|
||||
}
|
||||
else {
|
||||
oldHover->GetDocument(*getter_AddRefs(doc2));
|
||||
oldHover->GetDocument(*getter_AddRefs(doc1));
|
||||
}
|
||||
if (doc1) {
|
||||
doc1->BeginUpdate();
|
||||
|
||||
//Notify all content from newHover to the commonHoverParent
|
||||
if (newHover) {
|
||||
nsCOMPtr<nsIContent> parent;
|
||||
newHover->GetParent(*getter_AddRefs(parent));
|
||||
doc1->ContentStatesChanged(newHover, parent, nsCSSAtoms::hoverPseudo);
|
||||
while (parent && parent != commonHoverParent) {
|
||||
parent->GetParent(*getter_AddRefs(newHover));
|
||||
if (newHover && newHover != commonHoverParent) {
|
||||
newHover->GetParent(*getter_AddRefs(parent));
|
||||
if (parent == commonHoverParent) {
|
||||
doc1->ContentStatesChanged(newHover, nsnull, nsCSSAtoms::hoverPseudo);
|
||||
}
|
||||
else {
|
||||
doc1->ContentStatesChanged(newHover, parent, nsCSSAtoms::hoverPseudo);
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Notify all content from newHover to the commonHoverAncestor
|
||||
while (newHover && newHover != commonHoverAncestor) {
|
||||
doc1->ContentStatesChanged(newHover, nsnull, NS_EVENT_STATE_HOVER);
|
||||
nsIContent *parent;
|
||||
newHover->GetParent(parent);
|
||||
newHover = dont_AddRef(parent);
|
||||
}
|
||||
//Notify all content from oldHover to the commonHoverParent
|
||||
if (oldHover) {
|
||||
nsCOMPtr<nsIContent> parent;
|
||||
oldHover->GetParent(*getter_AddRefs(parent));
|
||||
doc1->ContentStatesChanged(oldHover, parent, nsCSSAtoms::hoverPseudo);
|
||||
while (parent && parent != commonHoverParent) {
|
||||
parent->GetParent(*getter_AddRefs(oldHover));
|
||||
if (oldHover && oldHover != commonHoverParent) {
|
||||
oldHover->GetParent(*getter_AddRefs(parent));
|
||||
if (parent == commonHoverParent) {
|
||||
doc1->ContentStatesChanged(oldHover, nsnull, nsCSSAtoms::hoverPseudo);
|
||||
}
|
||||
else {
|
||||
doc1->ContentStatesChanged(oldHover, parent, nsCSSAtoms::hoverPseudo);
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Notify all content from oldHover to the commonHoverAncestor
|
||||
while (oldHover && oldHover != commonHoverAncestor) {
|
||||
doc1->ContentStatesChanged(oldHover, nsnull, NS_EVENT_STATE_HOVER);
|
||||
nsIContent *parent;
|
||||
oldHover->GetParent(parent);
|
||||
oldHover = dont_AddRef(parent);
|
||||
}
|
||||
|
||||
doc1->ContentStatesChanged(notifyContent[0], notifyContent[1], nsnull);
|
||||
if (notifyContent[2]) { // more that two notifications are needed (should be rare)
|
||||
// XXX a further optimization here would be to group the notification pairs
|
||||
// together by parent/child, only needed if more than two content changed
|
||||
// (ie: if [0] and [2] are parent/child, then notify (0,2) (1,3))
|
||||
doc1->ContentStatesChanged(notifyContent[2], notifyContent[3], nsnull);
|
||||
if (notifyContent[4]) { // more that two notifications are needed (should be rare)
|
||||
doc1->ContentStatesChanged(notifyContent[4], nsnull, nsnull);
|
||||
if (notifyContent[0]) {
|
||||
doc1->ContentStatesChanged(notifyContent[0], notifyContent[1],
|
||||
aState & ~NS_EVENT_STATE_HOVER);
|
||||
if (notifyContent[2]) {
|
||||
// more that two notifications are needed (should be rare)
|
||||
// XXX a further optimization here would be to group the
|
||||
// notification pairs together by parent/child, only needed if
|
||||
// more than two content changed (ie: if [0] and [2] are
|
||||
// parent/child, then notify (0,2) (1,3))
|
||||
doc1->ContentStatesChanged(notifyContent[2], notifyContent[3],
|
||||
aState & ~NS_EVENT_STATE_HOVER);
|
||||
if (notifyContent[4]) {
|
||||
// more that four notifications are needed (should be rare)
|
||||
doc1->ContentStatesChanged(notifyContent[4], nsnull,
|
||||
aState & ~NS_EVENT_STATE_HOVER);
|
||||
}
|
||||
}
|
||||
}
|
||||
doc1->EndUpdate();
|
||||
|
||||
if (doc2) {
|
||||
doc2->BeginUpdate();
|
||||
doc2->ContentStatesChanged(notifyContent[1], notifyContent[2], nsnull);
|
||||
doc2->ContentStatesChanged(notifyContent[1], notifyContent[2],
|
||||
aState & ~NS_EVENT_STATE_HOVER);
|
||||
if (notifyContent[3]) {
|
||||
doc1->ContentStatesChanged(notifyContent[3], notifyContent[4], nsnull);
|
||||
doc1->ContentStatesChanged(notifyContent[3], notifyContent[4],
|
||||
aState & ~NS_EVENT_STATE_HOVER);
|
||||
}
|
||||
doc2->EndUpdate();
|
||||
}
|
||||
|
@ -4282,7 +4253,8 @@ void nsEventStateManager::FocusElementButNotDocument(nsIContent *aContent)
|
|||
mDocument->BeginUpdate();
|
||||
if (!lastFocusInThisDoc)
|
||||
lastFocusInThisDoc = mCurrentFocus;
|
||||
mDocument->ContentStatesChanged(lastFocusInThisDoc, mCurrentFocus, nsnull);
|
||||
mDocument->ContentStatesChanged(lastFocusInThisDoc, mCurrentFocus,
|
||||
NS_EVENT_STATE_FOCUS);
|
||||
mDocument->EndUpdate();
|
||||
FlushPendingEvents(mPresContext);
|
||||
|
||||
|
|
|
@ -260,9 +260,6 @@ protected:
|
|||
nsCOMPtr<nsIPref> mPrefService;
|
||||
PRBool m_haveShutdown;
|
||||
|
||||
//Pref for using hierarchical hover (possibly expensive) or not
|
||||
PRBool hHover;
|
||||
|
||||
// So we don't have to keep checking accessibility.browsewithcaret pref
|
||||
PRBool mBrowseWithCaret;
|
||||
|
||||
|
|
|
@ -1390,8 +1390,9 @@ nsGenericHTMLElement::HandleDOMEventForAnchors(nsIContent* aOuter,
|
|||
return ret;
|
||||
|
||||
if ((*aEventStatus == nsEventStatus_eIgnore ||
|
||||
aEvent->message == NS_MOUSE_ENTER_SYNTH ||
|
||||
aEvent->message == NS_MOUSE_EXIT_SYNTH) &&
|
||||
(*aEventStatus != nsEventStatus_eConsumeNoDefault &&
|
||||
(aEvent->message == NS_MOUSE_ENTER_SYNTH ||
|
||||
aEvent->message == NS_MOUSE_EXIT_SYNTH))) &&
|
||||
!(aFlags & NS_EVENT_FLAG_CAPTURE)) {
|
||||
|
||||
// If we're here, then aOuter should be an nsILink. We'll use the
|
||||
|
@ -1483,20 +1484,9 @@ nsGenericHTMLElement::HandleDOMEventForAnchors(nsIContent* aOuter,
|
|||
}
|
||||
break;
|
||||
|
||||
case NS_MOUSE_ENTER_SYNTH:
|
||||
{
|
||||
nsCOMPtr<nsIEventStateManager> stateManager;
|
||||
aPresContext->GetEventStateManager(getter_AddRefs(stateManager));
|
||||
if (stateManager)
|
||||
stateManager->SetContentState(this, NS_EVENT_STATE_HOVER);
|
||||
|
||||
// don't set status for onmouseover="...; return true;"
|
||||
if (*aEventStatus == nsEventStatus_eConsumeNoDefault)
|
||||
break;
|
||||
|
||||
*aEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
// Set the status bar the same for focus and mouseover
|
||||
case NS_MOUSE_ENTER_SYNTH:
|
||||
*aEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
case NS_FOCUS_CONTENT:
|
||||
{
|
||||
nsAutoString target;
|
||||
|
@ -1513,15 +1503,6 @@ nsGenericHTMLElement::HandleDOMEventForAnchors(nsIContent* aOuter,
|
|||
|
||||
case NS_MOUSE_EXIT_SYNTH:
|
||||
{
|
||||
nsCOMPtr<nsIEventStateManager> stateManager;
|
||||
aPresContext->GetEventStateManager(getter_AddRefs(stateManager));
|
||||
if (stateManager)
|
||||
stateManager->SetContentState(nsnull, NS_EVENT_STATE_HOVER);
|
||||
|
||||
// don't set status for onmouseover="...; return true;"
|
||||
if (*aEventStatus == nsEventStatus_eConsumeNoDefault)
|
||||
break;
|
||||
|
||||
*aEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
|
||||
nsAutoString empty;
|
||||
|
|
|
@ -905,7 +905,7 @@ nsHTMLInputElement::SetCheckedInternal(PRBool aChecked)
|
|||
// Probably ContentStatesChanged() needs to be told not to worry if there is
|
||||
// no frame in some cases. Bug 134560.
|
||||
if (mDocument && frame) {
|
||||
mDocument->ContentStatesChanged(this, nsnull, nsCSSAtoms::checkedPseudo);
|
||||
mDocument->ContentStatesChanged(this, nsnull, NS_EVENT_STATE_CHECKED);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
#include "nsNodeInfoManager.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsCSSAtoms.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
|
||||
class nsHTMLOptionElement : public nsGenericHTMLContainerElement,
|
||||
public nsIDOMHTMLOptionElement,
|
||||
|
@ -269,7 +269,7 @@ nsHTMLOptionElement::SetSelectedInternal(PRBool aValue, PRBool aNotify)
|
|||
mIsSelected = aValue;
|
||||
|
||||
if (aNotify && mDocument)
|
||||
mDocument->ContentStatesChanged(this, nsnull, nsCSSAtoms::checkedPseudo);
|
||||
mDocument->ContentStatesChanged(this, nsnull, NS_EVENT_STATE_CHECKED);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -294,7 +294,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass) { return NS_OK; }
|
||||
PRInt32 aStateMask) { return NS_OK; }
|
||||
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
|
|
@ -735,7 +735,8 @@ public:
|
|||
nsIAtom* aMedium);
|
||||
|
||||
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||
nsIAtom* aMedium);
|
||||
nsIAtom* aMedium,
|
||||
PRBool* aResult);
|
||||
|
||||
#ifdef DEBUG
|
||||
virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize);
|
||||
|
@ -3456,9 +3457,14 @@ static PRBool IsSignificantChild(nsIContent* aChild, PRBool aAcceptNonWhitespace
|
|||
}
|
||||
|
||||
|
||||
// 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
|
||||
// state-dependent when it really is (e.g., determining that a
|
||||
// :hover:active rule no longer matches when both states are unset).
|
||||
static PRBool SelectorMatches(RuleProcessorData &data,
|
||||
nsCSSSelector* aSelector,
|
||||
PRBool aTestState,
|
||||
PRInt32 aStateMask, // states NOT to test
|
||||
PRInt8 aNegationIndex)
|
||||
|
||||
{
|
||||
|
@ -3587,24 +3593,28 @@ static PRBool SelectorMatches(RuleProcessorData &data,
|
|||
if ((data.mIsHTMLContent) &&
|
||||
(!IsEventSensitive(pseudoClass->mAtom, data.mContentTag, isSelectorGlobal))){
|
||||
result = localFalse;
|
||||
} else if (aTestState) {
|
||||
} else {
|
||||
if (nsCSSAtoms::activePseudo == pseudoClass->mAtom) {
|
||||
result = PRBool(localTrue == (0 != (data.mEventState & NS_EVENT_STATE_ACTIVE)));
|
||||
result = (aStateMask & NS_EVENT_STATE_ACTIVE) ||
|
||||
(localTrue == (0 != (data.mEventState & NS_EVENT_STATE_ACTIVE)));
|
||||
}
|
||||
else if (nsCSSAtoms::focusPseudo == pseudoClass->mAtom) {
|
||||
result = PRBool(localTrue == (0 != (data.mEventState & NS_EVENT_STATE_FOCUS)));
|
||||
result = (aStateMask & NS_EVENT_STATE_FOCUS) ||
|
||||
(localTrue == (0 != (data.mEventState & NS_EVENT_STATE_FOCUS)));
|
||||
}
|
||||
else if (nsCSSAtoms::hoverPseudo == pseudoClass->mAtom) {
|
||||
result = PRBool(localTrue == (0 != (data.mEventState & NS_EVENT_STATE_HOVER)));
|
||||
result = (aStateMask & NS_EVENT_STATE_HOVER) ||
|
||||
(localTrue == (0 != (data.mEventState & NS_EVENT_STATE_HOVER)));
|
||||
}
|
||||
else if (nsCSSAtoms::dragOverPseudo == pseudoClass->mAtom) {
|
||||
result = PRBool(localTrue == (0 != (data.mEventState & NS_EVENT_STATE_DRAGOVER)));
|
||||
result = (aStateMask & NS_EVENT_STATE_DRAGOVER) ||
|
||||
(localTrue == (0 != (data.mEventState & NS_EVENT_STATE_DRAGOVER)));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (IsLinkPseudo(pseudoClass->mAtom)) {
|
||||
if (data.mIsHTMLLink || data.mIsSimpleXLink) {
|
||||
if (result && aTestState) {
|
||||
if (result) {
|
||||
if (nsCSSAtoms::anyLinkPseudo == pseudoClass->mAtom) {
|
||||
result = localTrue;
|
||||
}
|
||||
|
@ -3625,7 +3635,7 @@ static PRBool SelectorMatches(RuleProcessorData &data,
|
|||
// <option>
|
||||
// <input type=checkbox>
|
||||
// <input type=radio>
|
||||
if (aTestState)
|
||||
if (!(aStateMask & NS_EVENT_STATE_CHECKED))
|
||||
result = data.mIsChecked ? localTrue : localFalse;
|
||||
}
|
||||
else {
|
||||
|
@ -3778,7 +3788,8 @@ static PRBool SelectorMatches(RuleProcessorData &data,
|
|||
|
||||
// apply SelectorMatches to the negated selectors in the chain
|
||||
if (result && (nsnull != aSelector->mNegations)) {
|
||||
result = SelectorMatches(data, aSelector->mNegations, aTestState, aNegationIndex+1);
|
||||
result = SelectorMatches(data, aSelector->mNegations, aStateMask,
|
||||
aNegationIndex+1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -3853,7 +3864,7 @@ static PRBool SelectorMatchesTree(RuleProcessorData &data,
|
|||
NS_ASSERTION(!content, "content must be null");
|
||||
break;
|
||||
}
|
||||
if (SelectorMatches(*newdata, selector, PR_TRUE, 0)) {
|
||||
if (SelectorMatches(*newdata, selector, 0, 0)) {
|
||||
// to avoid greedy matching, we need to recurse if this is a
|
||||
// descendant combinator and the next combinator is not
|
||||
if ((NS_IS_GREEDY_OPERATOR(selector->mOperator)) &&
|
||||
|
@ -3897,7 +3908,7 @@ static void ContentEnumFunc(nsICSSStyleRule* aRule, void* aData)
|
|||
ElementRuleProcessorData* data = (ElementRuleProcessorData*)aData;
|
||||
|
||||
nsCSSSelector* selector = aRule->FirstSelector();
|
||||
if (SelectorMatches(*data, selector, PR_TRUE, 0)) {
|
||||
if (SelectorMatches(*data, selector, 0, 0)) {
|
||||
selector = selector->mNext;
|
||||
if (SelectorMatchesTree(*data, selector)) {
|
||||
// for performance, require that every implementation of
|
||||
|
@ -3976,7 +3987,7 @@ static void PseudoEnumFunc(nsICSSStyleRule* aRule, void* aData)
|
|||
if (PRUnichar('+') == selector->mOperator) {
|
||||
return; // not valid here, can't match
|
||||
}
|
||||
if (SelectorMatches(*data, selector, PR_TRUE, 0)) {
|
||||
if (SelectorMatches(*data, selector, 0, 0)) {
|
||||
selector = selector->mNext;
|
||||
}
|
||||
else {
|
||||
|
@ -4049,7 +4060,7 @@ PRBool PR_CALLBACK StateEnumFunc(void* aSelector, void* aData)
|
|||
StateRuleProcessorData* data = (StateRuleProcessorData*)aData;
|
||||
|
||||
nsCSSSelector* selector = (nsCSSSelector*)aSelector;
|
||||
if (SelectorMatches(*data, selector, PR_FALSE, 0)) {
|
||||
if (SelectorMatches(*data, selector, data->mStateMask, 0)) {
|
||||
selector = selector->mNext;
|
||||
if (SelectorMatchesTree(*data, selector)) {
|
||||
return PR_FALSE;
|
||||
|
@ -4060,21 +4071,19 @@ PRBool PR_CALLBACK StateEnumFunc(void* aSelector, void* aData)
|
|||
|
||||
NS_IMETHODIMP
|
||||
CSSRuleProcessor::HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||
nsIAtom* aMedium)
|
||||
nsIAtom* aMedium,
|
||||
PRBool* aResult)
|
||||
{
|
||||
NS_PRECONDITION(aData->mContent->IsContentOfType(nsIContent::eELEMENT),
|
||||
"content must be element");
|
||||
|
||||
PRBool isStateful = PR_FALSE;
|
||||
|
||||
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext, aMedium);
|
||||
|
||||
if (cascade) {
|
||||
// look up content in state rule list
|
||||
isStateful = ! cascade->mStateSelectors.EnumerateForwards(StateEnumFunc, aData); // if stopped, have state
|
||||
}
|
||||
// Look up content in state rule list. If enumeration stopped, have state.
|
||||
*aResult = cascade &&
|
||||
!cascade->mStateSelectors.EnumerateForwards(StateEnumFunc, aData);
|
||||
|
||||
return ((isStateful) ? NS_OK : NS_COMFALSE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -251,7 +251,8 @@ public:
|
|||
nsIAtom* aMedium);
|
||||
|
||||
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||
nsIAtom* aMedium);
|
||||
nsIAtom* aMedium,
|
||||
PRBool* aResult);
|
||||
|
||||
// XXX style rule enumerations
|
||||
|
||||
|
@ -422,9 +423,11 @@ HTMLCSSStyleSheetImpl::Init(nsIURI* aURL, nsIDocument* aDocument)
|
|||
// Test if style is dependent on content state
|
||||
NS_IMETHODIMP
|
||||
HTMLCSSStyleSheetImpl::HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||
nsIAtom* aMedium)
|
||||
nsIAtom* aMedium,
|
||||
PRBool* aResult)
|
||||
{
|
||||
return NS_COMFALSE;
|
||||
*aResult = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -840,7 +840,8 @@ public:
|
|||
nsIAtom* aMedium);
|
||||
|
||||
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||
nsIAtom* aMedium);
|
||||
nsIAtom* aMedium,
|
||||
PRBool* aResult);
|
||||
|
||||
// nsIHTMLStyleSheet api
|
||||
NS_IMETHOD Init(nsIURI* aURL, nsIDocument* aDocument);
|
||||
|
@ -1149,26 +1150,21 @@ HTMLStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData,
|
|||
// Test if style is dependent on content state
|
||||
NS_IMETHODIMP
|
||||
HTMLStyleSheetImpl::HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||
nsIAtom* aMedium)
|
||||
nsIAtom* aMedium,
|
||||
PRBool* aResult)
|
||||
{
|
||||
nsresult result = NS_COMFALSE;
|
||||
*aResult = mActiveRule &&
|
||||
(aData->mStateMask & NS_EVENT_STATE_ACTIVE) &&
|
||||
aData->mStyledContent &&
|
||||
aData->mIsHTMLContent &&
|
||||
aData->mContentTag == nsHTMLAtoms::a &&
|
||||
aData->mStyledContent->HasAttr(kNameSpaceID_None,
|
||||
nsHTMLAtoms::href);
|
||||
|
||||
if ((mActiveRule || mLinkRule || mVisitedRule) &&
|
||||
aData->mStyledContent &&
|
||||
aData->mIsHTMLContent &&
|
||||
aData->mContentTag == nsHTMLAtoms::a) {
|
||||
PRBool hasHrefAttr =
|
||||
aData->mStyledContent->HasAttr(kNameSpaceID_None,
|
||||
nsHTMLAtoms::href);
|
||||
if (hasHrefAttr)
|
||||
result = NS_OK; // yes, style will depend on link state
|
||||
}
|
||||
|
||||
return result;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLStyleSheetImpl::RulesMatching(PseudoRuleProcessorData* aData,
|
||||
nsIAtom* aMedium)
|
||||
|
|
|
@ -305,7 +305,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass) { return NS_OK; }
|
||||
PRInt32 aStateMask) { return NS_OK; }
|
||||
NS_IMETHOD AttributeChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
|
|
@ -1926,11 +1926,11 @@ nsXULDocument::ContentChanged(nsIContent* aContent,
|
|||
NS_IMETHODIMP
|
||||
nsXULDocument::ContentStatesChanged(nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass)
|
||||
PRInt32 aStateMask)
|
||||
{
|
||||
for (PRInt32 i = mObservers.Count() - 1; i >= 0; --i) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->ContentStatesChanged(this, aContent1, aContent2, aChangedPseudoClass);
|
||||
observer->ContentStatesChanged(this, aContent1, aContent2, aStateMask);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -280,7 +280,7 @@ public:
|
|||
|
||||
NS_IMETHOD ContentStatesChanged(nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass);
|
||||
PRInt32 aStateMask);
|
||||
|
||||
NS_IMETHOD AttributeChanged(nsIContent* aChild,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
|
|
@ -338,7 +338,7 @@ NS_IMETHODIMP
|
|||
nsXULTemplateBuilder::ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass)
|
||||
PRInt32 aStateMask)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass);
|
||||
PRInt32 aStateMask);
|
||||
|
||||
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent,
|
||||
|
|
|
@ -92,7 +92,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass) { return NS_OK; }
|
||||
PRInt32 aStateMask) { return NS_OK; }
|
||||
NS_IMETHOD BeginUpdate(nsIDocument *aDocument) { return NS_OK; }
|
||||
NS_IMETHOD EndUpdate(nsIDocument *aDocument) { return NS_OK; }
|
||||
NS_IMETHOD BeginLoad(nsIDocument *aDocument) { return NS_OK; }
|
||||
|
|
|
@ -253,7 +253,7 @@ NS_IMETHODIMP
|
|||
nsXPathResult::ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass)
|
||||
PRInt32 aStateMask)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -93,7 +93,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass);
|
||||
PRInt32 aStateMask);
|
||||
NS_IMETHOD AttributeChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
|
|
@ -10037,7 +10037,7 @@ NS_IMETHODIMP
|
|||
nsCSSFrameConstructor::ContentStatesChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass)
|
||||
PRInt32 aStateMask)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
|
||||
|
@ -10063,9 +10063,14 @@ nsCSSFrameConstructor::ContentStatesChanged(nsIPresContext* aPresContext,
|
|||
app1 = disp->mAppearance;
|
||||
}
|
||||
|
||||
if (!app1 && (NS_OK != styleSet->HasStateDependentStyle(aPresContext, aContent1))) {
|
||||
primaryFrame1 = nsnull;
|
||||
aContent1 = nsnull;
|
||||
if (!app1) {
|
||||
PRBool depends = PR_FALSE;
|
||||
styleSet->HasStateDependentStyle(aPresContext, aContent1,
|
||||
aStateMask, &depends);
|
||||
if (!depends) {
|
||||
primaryFrame1 = nsnull;
|
||||
aContent1 = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
if (aContent2 == aContent1)
|
||||
|
@ -10078,9 +10083,14 @@ nsCSSFrameConstructor::ContentStatesChanged(nsIPresContext* aPresContext,
|
|||
app2 = disp2->mAppearance;
|
||||
}
|
||||
|
||||
if (!app2 && (NS_OK != styleSet->HasStateDependentStyle(aPresContext, aContent2))) {
|
||||
primaryFrame2 = nsnull;
|
||||
aContent2 = nsnull;
|
||||
if (!app2) {
|
||||
PRBool depends = PR_FALSE;
|
||||
styleSet->HasStateDependentStyle(aPresContext, aContent2,
|
||||
aStateMask, &depends);
|
||||
if (!depends) {
|
||||
primaryFrame2 = nsnull;
|
||||
aContent2 = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass);
|
||||
PRInt32 aStateMask);
|
||||
|
||||
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
|
|
|
@ -1029,7 +1029,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass);
|
||||
PRInt32 aStateMask);
|
||||
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
@ -5111,11 +5111,11 @@ NS_IMETHODIMP
|
|||
PresShell::ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass)
|
||||
PRInt32 aStateMask)
|
||||
{
|
||||
WillCauseReflow();
|
||||
nsresult rv = mStyleSet->ContentStatesChanged(mPresContext, aContent1, aContent2,
|
||||
aChangedPseudoClass);
|
||||
nsresult rv = mStyleSet->ContentStatesChanged(mPresContext, aContent1,
|
||||
aContent2, aStateMask);
|
||||
VERIFY_STYLE_TREE;
|
||||
DidCauseReflow();
|
||||
|
||||
|
|
|
@ -203,7 +203,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass) = 0;
|
||||
PRInt32 aStateMask) = 0;
|
||||
|
||||
/**
|
||||
* Notification that an attribute was changed for a content node
|
||||
|
|
|
@ -195,7 +195,9 @@ public:
|
|||
|
||||
// Test if style is dependent on content state
|
||||
NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent) = 0;
|
||||
nsIContent* aContent,
|
||||
PRInt32 aStateMask,
|
||||
PRBool* aResult) = 0;
|
||||
|
||||
// Create frames for the root content element and its child content
|
||||
NS_IMETHOD ConstructRootFrame(nsIPresContext* aPresContext,
|
||||
|
@ -231,7 +233,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass) = 0;
|
||||
PRInt32 aStateMask) = 0;
|
||||
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
|
|
@ -105,7 +105,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass) { return NS_OK; }
|
||||
PRInt32 aStateMask) { return NS_OK; }
|
||||
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
|
|
@ -1117,7 +1117,7 @@ NS_IMETHODIMP
|
|||
nsImageMap::ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass)
|
||||
PRInt32 aStateMask)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass);
|
||||
PRInt32 aStateMask);
|
||||
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
|
|
@ -105,7 +105,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass) { return NS_OK; }
|
||||
PRInt32 aStateMask) { return NS_OK; }
|
||||
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
|
|
@ -1117,7 +1117,7 @@ NS_IMETHODIMP
|
|||
nsImageMap::ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass)
|
||||
PRInt32 aStateMask)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass);
|
||||
PRInt32 aStateMask);
|
||||
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
|
|
@ -1029,7 +1029,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass);
|
||||
PRInt32 aStateMask);
|
||||
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
@ -5111,11 +5111,11 @@ NS_IMETHODIMP
|
|||
PresShell::ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass)
|
||||
PRInt32 aStateMask)
|
||||
{
|
||||
WillCauseReflow();
|
||||
nsresult rv = mStyleSet->ContentStatesChanged(mPresContext, aContent1, aContent2,
|
||||
aChangedPseudoClass);
|
||||
nsresult rv = mStyleSet->ContentStatesChanged(mPresContext, aContent1,
|
||||
aContent2, aStateMask);
|
||||
VERIFY_STYLE_TREE;
|
||||
DidCauseReflow();
|
||||
|
||||
|
|
|
@ -10037,7 +10037,7 @@ NS_IMETHODIMP
|
|||
nsCSSFrameConstructor::ContentStatesChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass)
|
||||
PRInt32 aStateMask)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
|
||||
|
@ -10063,9 +10063,14 @@ nsCSSFrameConstructor::ContentStatesChanged(nsIPresContext* aPresContext,
|
|||
app1 = disp->mAppearance;
|
||||
}
|
||||
|
||||
if (!app1 && (NS_OK != styleSet->HasStateDependentStyle(aPresContext, aContent1))) {
|
||||
primaryFrame1 = nsnull;
|
||||
aContent1 = nsnull;
|
||||
if (!app1) {
|
||||
PRBool depends = PR_FALSE;
|
||||
styleSet->HasStateDependentStyle(aPresContext, aContent1,
|
||||
aStateMask, &depends);
|
||||
if (!depends) {
|
||||
primaryFrame1 = nsnull;
|
||||
aContent1 = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
if (aContent2 == aContent1)
|
||||
|
@ -10078,9 +10083,14 @@ nsCSSFrameConstructor::ContentStatesChanged(nsIPresContext* aPresContext,
|
|||
app2 = disp2->mAppearance;
|
||||
}
|
||||
|
||||
if (!app2 && (NS_OK != styleSet->HasStateDependentStyle(aPresContext, aContent2))) {
|
||||
primaryFrame2 = nsnull;
|
||||
aContent2 = nsnull;
|
||||
if (!app2) {
|
||||
PRBool depends = PR_FALSE;
|
||||
styleSet->HasStateDependentStyle(aPresContext, aContent2,
|
||||
aStateMask, &depends);
|
||||
if (!depends) {
|
||||
primaryFrame2 = nsnull;
|
||||
aContent2 = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass);
|
||||
PRInt32 aStateMask);
|
||||
|
||||
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
|
|
|
@ -735,7 +735,8 @@ public:
|
|||
nsIAtom* aMedium);
|
||||
|
||||
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||
nsIAtom* aMedium);
|
||||
nsIAtom* aMedium,
|
||||
PRBool* aResult);
|
||||
|
||||
#ifdef DEBUG
|
||||
virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize);
|
||||
|
@ -3456,9 +3457,14 @@ static PRBool IsSignificantChild(nsIContent* aChild, PRBool aAcceptNonWhitespace
|
|||
}
|
||||
|
||||
|
||||
// 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
|
||||
// state-dependent when it really is (e.g., determining that a
|
||||
// :hover:active rule no longer matches when both states are unset).
|
||||
static PRBool SelectorMatches(RuleProcessorData &data,
|
||||
nsCSSSelector* aSelector,
|
||||
PRBool aTestState,
|
||||
PRInt32 aStateMask, // states NOT to test
|
||||
PRInt8 aNegationIndex)
|
||||
|
||||
{
|
||||
|
@ -3587,24 +3593,28 @@ static PRBool SelectorMatches(RuleProcessorData &data,
|
|||
if ((data.mIsHTMLContent) &&
|
||||
(!IsEventSensitive(pseudoClass->mAtom, data.mContentTag, isSelectorGlobal))){
|
||||
result = localFalse;
|
||||
} else if (aTestState) {
|
||||
} else {
|
||||
if (nsCSSAtoms::activePseudo == pseudoClass->mAtom) {
|
||||
result = PRBool(localTrue == (0 != (data.mEventState & NS_EVENT_STATE_ACTIVE)));
|
||||
result = (aStateMask & NS_EVENT_STATE_ACTIVE) ||
|
||||
(localTrue == (0 != (data.mEventState & NS_EVENT_STATE_ACTIVE)));
|
||||
}
|
||||
else if (nsCSSAtoms::focusPseudo == pseudoClass->mAtom) {
|
||||
result = PRBool(localTrue == (0 != (data.mEventState & NS_EVENT_STATE_FOCUS)));
|
||||
result = (aStateMask & NS_EVENT_STATE_FOCUS) ||
|
||||
(localTrue == (0 != (data.mEventState & NS_EVENT_STATE_FOCUS)));
|
||||
}
|
||||
else if (nsCSSAtoms::hoverPseudo == pseudoClass->mAtom) {
|
||||
result = PRBool(localTrue == (0 != (data.mEventState & NS_EVENT_STATE_HOVER)));
|
||||
result = (aStateMask & NS_EVENT_STATE_HOVER) ||
|
||||
(localTrue == (0 != (data.mEventState & NS_EVENT_STATE_HOVER)));
|
||||
}
|
||||
else if (nsCSSAtoms::dragOverPseudo == pseudoClass->mAtom) {
|
||||
result = PRBool(localTrue == (0 != (data.mEventState & NS_EVENT_STATE_DRAGOVER)));
|
||||
result = (aStateMask & NS_EVENT_STATE_DRAGOVER) ||
|
||||
(localTrue == (0 != (data.mEventState & NS_EVENT_STATE_DRAGOVER)));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (IsLinkPseudo(pseudoClass->mAtom)) {
|
||||
if (data.mIsHTMLLink || data.mIsSimpleXLink) {
|
||||
if (result && aTestState) {
|
||||
if (result) {
|
||||
if (nsCSSAtoms::anyLinkPseudo == pseudoClass->mAtom) {
|
||||
result = localTrue;
|
||||
}
|
||||
|
@ -3625,7 +3635,7 @@ static PRBool SelectorMatches(RuleProcessorData &data,
|
|||
// <option>
|
||||
// <input type=checkbox>
|
||||
// <input type=radio>
|
||||
if (aTestState)
|
||||
if (!(aStateMask & NS_EVENT_STATE_CHECKED))
|
||||
result = data.mIsChecked ? localTrue : localFalse;
|
||||
}
|
||||
else {
|
||||
|
@ -3778,7 +3788,8 @@ static PRBool SelectorMatches(RuleProcessorData &data,
|
|||
|
||||
// apply SelectorMatches to the negated selectors in the chain
|
||||
if (result && (nsnull != aSelector->mNegations)) {
|
||||
result = SelectorMatches(data, aSelector->mNegations, aTestState, aNegationIndex+1);
|
||||
result = SelectorMatches(data, aSelector->mNegations, aStateMask,
|
||||
aNegationIndex+1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -3853,7 +3864,7 @@ static PRBool SelectorMatchesTree(RuleProcessorData &data,
|
|||
NS_ASSERTION(!content, "content must be null");
|
||||
break;
|
||||
}
|
||||
if (SelectorMatches(*newdata, selector, PR_TRUE, 0)) {
|
||||
if (SelectorMatches(*newdata, selector, 0, 0)) {
|
||||
// to avoid greedy matching, we need to recurse if this is a
|
||||
// descendant combinator and the next combinator is not
|
||||
if ((NS_IS_GREEDY_OPERATOR(selector->mOperator)) &&
|
||||
|
@ -3897,7 +3908,7 @@ static void ContentEnumFunc(nsICSSStyleRule* aRule, void* aData)
|
|||
ElementRuleProcessorData* data = (ElementRuleProcessorData*)aData;
|
||||
|
||||
nsCSSSelector* selector = aRule->FirstSelector();
|
||||
if (SelectorMatches(*data, selector, PR_TRUE, 0)) {
|
||||
if (SelectorMatches(*data, selector, 0, 0)) {
|
||||
selector = selector->mNext;
|
||||
if (SelectorMatchesTree(*data, selector)) {
|
||||
// for performance, require that every implementation of
|
||||
|
@ -3976,7 +3987,7 @@ static void PseudoEnumFunc(nsICSSStyleRule* aRule, void* aData)
|
|||
if (PRUnichar('+') == selector->mOperator) {
|
||||
return; // not valid here, can't match
|
||||
}
|
||||
if (SelectorMatches(*data, selector, PR_TRUE, 0)) {
|
||||
if (SelectorMatches(*data, selector, 0, 0)) {
|
||||
selector = selector->mNext;
|
||||
}
|
||||
else {
|
||||
|
@ -4049,7 +4060,7 @@ PRBool PR_CALLBACK StateEnumFunc(void* aSelector, void* aData)
|
|||
StateRuleProcessorData* data = (StateRuleProcessorData*)aData;
|
||||
|
||||
nsCSSSelector* selector = (nsCSSSelector*)aSelector;
|
||||
if (SelectorMatches(*data, selector, PR_FALSE, 0)) {
|
||||
if (SelectorMatches(*data, selector, data->mStateMask, 0)) {
|
||||
selector = selector->mNext;
|
||||
if (SelectorMatchesTree(*data, selector)) {
|
||||
return PR_FALSE;
|
||||
|
@ -4060,21 +4071,19 @@ PRBool PR_CALLBACK StateEnumFunc(void* aSelector, void* aData)
|
|||
|
||||
NS_IMETHODIMP
|
||||
CSSRuleProcessor::HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||
nsIAtom* aMedium)
|
||||
nsIAtom* aMedium,
|
||||
PRBool* aResult)
|
||||
{
|
||||
NS_PRECONDITION(aData->mContent->IsContentOfType(nsIContent::eELEMENT),
|
||||
"content must be element");
|
||||
|
||||
PRBool isStateful = PR_FALSE;
|
||||
|
||||
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext, aMedium);
|
||||
|
||||
if (cascade) {
|
||||
// look up content in state rule list
|
||||
isStateful = ! cascade->mStateSelectors.EnumerateForwards(StateEnumFunc, aData); // if stopped, have state
|
||||
}
|
||||
// Look up content in state rule list. If enumeration stopped, have state.
|
||||
*aResult = cascade &&
|
||||
!cascade->mStateSelectors.EnumerateForwards(StateEnumFunc, aData);
|
||||
|
||||
return ((isStateful) ? NS_OK : NS_COMFALSE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -251,7 +251,8 @@ public:
|
|||
nsIAtom* aMedium);
|
||||
|
||||
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||
nsIAtom* aMedium);
|
||||
nsIAtom* aMedium,
|
||||
PRBool* aResult);
|
||||
|
||||
// XXX style rule enumerations
|
||||
|
||||
|
@ -422,9 +423,11 @@ HTMLCSSStyleSheetImpl::Init(nsIURI* aURL, nsIDocument* aDocument)
|
|||
// Test if style is dependent on content state
|
||||
NS_IMETHODIMP
|
||||
HTMLCSSStyleSheetImpl::HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||
nsIAtom* aMedium)
|
||||
nsIAtom* aMedium,
|
||||
PRBool* aResult)
|
||||
{
|
||||
return NS_COMFALSE;
|
||||
*aResult = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -840,7 +840,8 @@ public:
|
|||
nsIAtom* aMedium);
|
||||
|
||||
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||
nsIAtom* aMedium);
|
||||
nsIAtom* aMedium,
|
||||
PRBool* aResult);
|
||||
|
||||
// nsIHTMLStyleSheet api
|
||||
NS_IMETHOD Init(nsIURI* aURL, nsIDocument* aDocument);
|
||||
|
@ -1149,26 +1150,21 @@ HTMLStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData,
|
|||
// Test if style is dependent on content state
|
||||
NS_IMETHODIMP
|
||||
HTMLStyleSheetImpl::HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||
nsIAtom* aMedium)
|
||||
nsIAtom* aMedium,
|
||||
PRBool* aResult)
|
||||
{
|
||||
nsresult result = NS_COMFALSE;
|
||||
*aResult = mActiveRule &&
|
||||
(aData->mStateMask & NS_EVENT_STATE_ACTIVE) &&
|
||||
aData->mStyledContent &&
|
||||
aData->mIsHTMLContent &&
|
||||
aData->mContentTag == nsHTMLAtoms::a &&
|
||||
aData->mStyledContent->HasAttr(kNameSpaceID_None,
|
||||
nsHTMLAtoms::href);
|
||||
|
||||
if ((mActiveRule || mLinkRule || mVisitedRule) &&
|
||||
aData->mStyledContent &&
|
||||
aData->mIsHTMLContent &&
|
||||
aData->mContentTag == nsHTMLAtoms::a) {
|
||||
PRBool hasHrefAttr =
|
||||
aData->mStyledContent->HasAttr(kNameSpaceID_None,
|
||||
nsHTMLAtoms::href);
|
||||
if (hasHrefAttr)
|
||||
result = NS_OK; // yes, style will depend on link state
|
||||
}
|
||||
|
||||
return result;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLStyleSheetImpl::RulesMatching(PseudoRuleProcessorData* aData,
|
||||
nsIAtom* aMedium)
|
||||
|
|
|
@ -131,11 +131,15 @@ struct PseudoRuleProcessorData : public RuleProcessorData {
|
|||
|
||||
struct StateRuleProcessorData : public RuleProcessorData {
|
||||
StateRuleProcessorData(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent)
|
||||
: RuleProcessorData(aPresContext, aContent, nsnull)
|
||||
nsIContent* aContent,
|
||||
PRInt32 aStateMask)
|
||||
: RuleProcessorData(aPresContext, aContent, nsnull),
|
||||
mStateMask(aStateMask)
|
||||
{
|
||||
NS_PRECONDITION(aContent, "null pointer");
|
||||
}
|
||||
const PRInt32 mStateMask; // |HasStateDependentStyle| for which state(s)?
|
||||
// Constants defined in nsIEventStateManager.h .
|
||||
};
|
||||
|
||||
|
||||
|
@ -162,8 +166,9 @@ public:
|
|||
nsIAtom* aMedium) = 0;
|
||||
|
||||
// Test if style is dependent on content state
|
||||
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||
nsIAtom* aMedium) = 0;
|
||||
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||
nsIAtom* aMedium,
|
||||
PRBool* aResult) = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize) = 0;
|
||||
|
|
|
@ -205,8 +205,10 @@ public:
|
|||
nsIStyleContext* aNewParentContext,
|
||||
nsIStyleContext** aNewStyleContext);
|
||||
|
||||
NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent);
|
||||
NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aStateMask,
|
||||
PRBool* aResult);
|
||||
|
||||
NS_IMETHOD ConstructRootFrame(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
|
@ -235,7 +237,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass);
|
||||
PRInt32 aStateMask);
|
||||
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
@ -1432,8 +1434,9 @@ StyleSetImpl::ReParentStyleContext(nsIPresContext* aPresContext,
|
|||
}
|
||||
|
||||
struct StatefulData : public StateRuleProcessorData {
|
||||
StatefulData(nsIPresContext* aPresContext, nsIAtom* aMedium, nsIContent* aContent)
|
||||
: StateRuleProcessorData(aPresContext, aContent),
|
||||
StatefulData(nsIPresContext* aPresContext, nsIAtom* aMedium,
|
||||
nsIContent* aContent, PRInt32 aStateMask)
|
||||
: StateRuleProcessorData(aPresContext, aContent, aStateMask),
|
||||
mMedium(aMedium),
|
||||
mStateful(PR_FALSE)
|
||||
{}
|
||||
|
@ -1445,17 +1448,18 @@ static PRBool SheetHasStatefulStyle(nsISupports* aProcessor, void *aData)
|
|||
{
|
||||
nsIStyleRuleProcessor* processor = (nsIStyleRuleProcessor*)aProcessor;
|
||||
StatefulData* data = (StatefulData*)aData;
|
||||
if (NS_OK == processor->HasStateDependentStyle(data, data->mMedium)) {
|
||||
data->mStateful = PR_TRUE;
|
||||
processor->HasStateDependentStyle(data, data->mMedium, &data->mStateful);
|
||||
if (data->mStateful)
|
||||
return PR_FALSE; // stop iteration
|
||||
}
|
||||
return PR_TRUE; // continue
|
||||
}
|
||||
|
||||
// Test if style is dependent on content state
|
||||
NS_IMETHODIMP
|
||||
StyleSetImpl::HasStateDependentStyle(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent)
|
||||
nsIContent* aContent,
|
||||
PRInt32 aStateMask,
|
||||
PRBool* aResult)
|
||||
{
|
||||
GatherRuleProcessors();
|
||||
|
||||
|
@ -1466,12 +1470,15 @@ StyleSetImpl::HasStateDependentStyle(nsIPresContext* aPresContext,
|
|||
mOverrideRuleProcessors)) {
|
||||
nsIAtom* medium = nsnull;
|
||||
aPresContext->GetMedium(&medium);
|
||||
StatefulData data(aPresContext, medium, aContent);
|
||||
StatefulData data(aPresContext, medium, aContent, aStateMask);
|
||||
WalkRuleProcessors(SheetHasStatefulStyle, &data);
|
||||
NS_IF_RELEASE(medium);
|
||||
return ((data.mStateful) ? NS_OK : NS_COMFALSE);
|
||||
*aResult = data.mStateful;
|
||||
} else {
|
||||
*aResult = PR_FALSE;
|
||||
}
|
||||
return NS_COMFALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1541,10 +1548,10 @@ NS_IMETHODIMP
|
|||
StyleSetImpl::ContentStatesChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass)
|
||||
PRInt32 aStateMask)
|
||||
{
|
||||
return mFrameConstructor->ContentStatesChanged(aPresContext, aContent1, aContent2,
|
||||
aChangedPseudoClass);
|
||||
return mFrameConstructor->ContentStatesChanged(aPresContext, aContent1,
|
||||
aContent2, aStateMask);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "nsChildIterator.h"
|
||||
#include "nsIDOMHTMLOptionElement.h"
|
||||
#include "nsIDOMClassInfo.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
|
||||
|
||||
// A content model view implementation for the tree.
|
||||
|
@ -730,10 +731,11 @@ NS_IMETHODIMP
|
|||
nsTreeContentView::ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass)
|
||||
PRInt32 aStateMask)
|
||||
{
|
||||
if (!aContent1 || !mSelection || !aContent1->IsContentOfType(nsIContent::eHTML) ||
|
||||
aChangedPseudoClass != nsCSSAtoms::checkedPseudo)
|
||||
if (!aContent1 || !mSelection ||
|
||||
!aContent1->IsContentOfType(nsIContent::eHTML) ||
|
||||
!(aStateMask & NS_EVENT_STATE_CHECKED))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIAtom> contentTag;
|
||||
|
|
|
@ -92,7 +92,7 @@ class nsTreeContentView : public nsITreeView,
|
|||
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudo);
|
||||
PRInt32 aStateMask);
|
||||
|
||||
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent,
|
||||
|
|
|
@ -771,7 +771,7 @@ nsMenuBarX::ContentChanged( nsIDocument * aDocument, nsIContent * aContent, nsIS
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsMenuBarX::ContentStatesChanged( nsIDocument * aDocument, nsIContent * aContent1,
|
||||
nsIContent * aContent2, nsIAtom * aChangedPseudoClass)
|
||||
nsIContent * aContent2, PRInt32 aStateMask)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass);
|
||||
PRInt32 aStateMask);
|
||||
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
|
|
@ -665,7 +665,7 @@ nsMenuBar::ContentChanged( nsIDocument * aDocument, nsIContent * aContent, nsISu
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsMenuBar::ContentStatesChanged( nsIDocument * aDocument, nsIContent * aContent1,
|
||||
nsIContent * aContent2, nsIAtom * aChangedPseudoClass)
|
||||
nsIContent * aContent2, PRInt32 aStateMask)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass);
|
||||
PRInt32 aStateMask);
|
||||
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
|
|
@ -761,7 +761,7 @@ nsMenuBarX::ContentChanged( nsIDocument * aDocument, nsIContent * aContent, nsIS
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsMenuBarX::ContentStatesChanged( nsIDocument * aDocument, nsIContent * aContent1,
|
||||
nsIContent * aContent2, nsIAtom * aChangedPseudoClass)
|
||||
nsIContent * aContent2, PRInt32 aStateMask)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass);
|
||||
PRInt32 aStateMask);
|
||||
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
|
|
@ -1551,7 +1551,7 @@ NS_IMETHODIMP
|
|||
nsWebShellWindow::ContentStatesChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass)
|
||||
PRInt32 aStateMask)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ public:
|
|||
NS_IMETHOD ContentStatesChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
nsIAtom* aChangedPseudoClass);
|
||||
PRInt32 aStateMask);
|
||||
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
|
Загрузка…
Ссылка в новой задаче