static nsEventStates GetStatesForPseudoClass(const nsAString& aStatePseudo) { // An array of the states that are relevant for various pseudoclasses. // XXXbz this duplicates code in nsCSSRuleProcessor static const nsEventStates sPseudoClassStates[] = { #define CSS_PSEUDO_CLASS(_name, _value) \ nsEventStates(), #define CSS_STATE_PSEUDO_CLASS(_name, _value, _states) \ _states, #include "nsCSSPseudoClassList.h" #undef CSS_STATE_PSEUDO_CLASS #undef CSS_PSEUDO_CLASS // Add more entries for our fake values to make sure we can't // index out of bounds into this array no matter what. nsEventStates(), nsEventStates() }; MOZ_STATIC_ASSERT(NS_ARRAY_LENGTH(sPseudoClassStates) == nsCSSPseudoClasses::ePseudoClass_NotPseudoClass + 1, "Length of PseudoClassStates array is incorrect"); nsCOMPtr<nsIAtom> atom = do_GetAtom(aStatePseudo); // Ignore :moz-any-link so we don't give the element simultaneous // visited and unvisited style state if (nsCSSPseudoClasses::GetPseudoType(atom) == nsCSSPseudoClasses::ePseudoClass_mozAnyLink) { return nsEventStates(); } // Our array above is long enough that indexing into it with // NotPseudoClass is ok. return sPseudoClassStates[nsCSSPseudoClasses::GetPseudoType(atom)]; }
nsEventStates nsNativeTheme::GetContentState(nsIFrame* aFrame, PRUint8 aWidgetType) { if (!aFrame) return nsEventStates(); PRBool isXULCheckboxRadio = (aWidgetType == NS_THEME_CHECKBOX || aWidgetType == NS_THEME_RADIO) && aFrame->GetContent()->IsXUL(); if (isXULCheckboxRadio) aFrame = aFrame->GetParent(); if (!aFrame->GetContent()) return nsEventStates(); nsIPresShell *shell = GetPresShell(aFrame); if (!shell) return nsEventStates(); nsIContent* frameContent = aFrame->GetContent(); nsEventStates flags; if (frameContent->IsElement()) { flags = frameContent->AsElement()->State(); } if (isXULCheckboxRadio && aWidgetType == NS_THEME_RADIO) { if (IsFocused(aFrame)) flags |= NS_EVENT_STATE_FOCUS; } // On Windows and Mac, only draw focus rings if they should be shown. This // means that focus rings are only shown once the keyboard has been used to // focus something in the window. #if defined(XP_MACOSX) // Mac always draws focus rings for textboxes and lists. if (aWidgetType == NS_THEME_TEXTFIELD || aWidgetType == NS_THEME_TEXTFIELD_MULTILINE || aWidgetType == NS_THEME_SEARCHFIELD || aWidgetType == NS_THEME_LISTBOX) { return flags; } #endif #if defined(XP_WIN) // On Windows, focused buttons are always drawn as such by the native theme. if (aWidgetType == NS_THEME_BUTTON) return flags; #endif #if defined(XP_MACOSX) || defined(XP_WIN) nsIDocument* doc = aFrame->GetContent()->GetOwnerDoc(); if (doc) { nsPIDOMWindow* window = doc->GetWindow(); if (window && !window->ShouldShowFocusRing()) flags &= ~NS_EVENT_STATE_FOCUS; } #endif return flags; }
nsEventStates Link::LinkState() const { // We are a constant method, but we are just lazily doing things and have to // track that state. Cast away that constness! Link *self = const_cast<Link *>(this); // If we are not in the document, default to not visited. Element *element = self->mElement; if (!element->IsInDoc()) { self->mLinkState = eLinkState_Unvisited; } // If we have not yet registered for notifications and are in an unknown // state, register now! if (!mRegistered && mLinkState == eLinkState_Unknown) { // First, make sure the href attribute has a valid link (bug 23209). nsCOMPtr<nsIURI> hrefURI(GetURI()); if (!hrefURI) { self->mLinkState = eLinkState_NotLink; return nsEventStates(); } // Assume that we are not visited until we are told otherwise. self->mLinkState = eLinkState_Unvisited; // We have a good href, so register with History. if (mHistory) { nsresult rv = mHistory->RegisterVisitedCallback(hrefURI, self); if (NS_SUCCEEDED(rv)) { self->mRegistered = true; // And make sure we are in the document's link map. nsIDocument *doc = element->GetCurrentDoc(); if (doc) { doc->AddStyleRelevantLink(self); } } } } // Otherwise, return our known state. if (mLinkState == eLinkState_Visited) { return NS_EVENT_STATE_VISITED; } if (mLinkState == eLinkState_Unvisited) { return NS_EVENT_STATE_UNVISITED; } return nsEventStates(); }
nsresult nsImageLoadingContent::ForceImageState(PRBool aForce, nsEventStates::InternalType aState) { NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); mIsImageStateForced = aForce; mForcedImageState = nsEventStates(aState); return NS_OK; }
void Link::ResetLinkState(bool aNotify, bool aHasHref) { nsLinkState defaultState; // The default state for links with an href is unvisited. if (aHasHref) { defaultState = eLinkState_Unvisited; } else { defaultState = eLinkState_NotLink; } // If !mNeedsRegstration, then either we've never registered, or we're // currently registered; in either case, we should remove ourself // from the doc and the history. if (!mNeedsRegistration && mLinkState != eLinkState_NotLink) { nsIDocument *doc = mElement->GetCurrentDoc(); if (doc && (mRegistered || mLinkState == eLinkState_Visited)) { // Tell the document to forget about this link if we've registered // with it before. doc->ForgetLink(this); } UnregisterFromHistory(); } // If we have an href, we should register with the history. mNeedsRegistration = aHasHref; // If we've cached the URI, reset always invalidates it. mCachedURI = nullptr; if (mSearchParams) { mSearchParams->Invalidate(); } // Update our state back to the default. mLinkState = defaultState; // We have to be very careful here: if aNotify is false we do NOT // want to call UpdateState, because that will call into LinkState() // and try to start off loads, etc. But ResetLinkState is called // with aNotify false when things are in inconsistent states, so // we'll get confused in that situation. Instead, just silently // update the link state on mElement. Since we might have set the // link state to unvisited, make sure to update with that state if // required. if (aNotify) { mElement->UpdateState(aNotify); } else { if (mLinkState == eLinkState_Unvisited) { mElement->UpdateLinkState(NS_EVENT_STATE_UNVISITED); } else { mElement->UpdateLinkState(nsEventStates()); } } }
static nsIFrame* GetClosest(nsIFrame* aRoot, const nsPoint& aPointRelativeToRootFrame, const nsRect& aTargetRect, const EventRadiusPrefs* aPrefs, nsIFrame* aRestrictToDescendants, nsTArray<nsIFrame*>& aCandidates) { nsIFrame* bestTarget = nullptr; // Lower is better; distance is in appunits float bestDistance = 1e6f; nsRegion exposedRegion(aTargetRect); for (uint32_t i = 0; i < aCandidates.Length(); ++i) { nsIFrame* f = aCandidates[i]; bool preservesAxisAlignedRectangles = false; nsRect borderBox = nsLayoutUtils::TransformFrameRectToAncestor(f, nsRect(nsPoint(0, 0), f->GetSize()), aRoot, &preservesAxisAlignedRectangles); nsRegion region; region.And(exposedRegion, borderBox); if (region.IsEmpty()) { continue; } if (preservesAxisAlignedRectangles) { // Subtract from the exposed region if we have a transform that won't make // the bounds include a bunch of area that we don't actually cover. SubtractFromExposedRegion(&exposedRegion, region); } if (!IsElementClickable(f)) { continue; } // If our current closest frame is a descendant of 'f', skip 'f' (prefer // the nested frame). if (bestTarget && nsLayoutUtils::IsProperAncestorFrameCrossDoc(f, bestTarget, aRoot)) { continue; } if (!nsLayoutUtils::IsAncestorFrameCrossDoc(aRestrictToDescendants, f, aRoot)) { continue; } // distance is in appunits float distance = ComputeDistanceFromRegion(aPointRelativeToRootFrame, region); nsIContent* content = f->GetContent(); if (content && content->IsElement() && content->AsElement()->State().HasState(nsEventStates(NS_EVENT_STATE_VISITED))) { distance *= aPrefs->mVisitedWeight / 100.0f; } if (distance < bestDistance) { bestDistance = distance; bestTarget = f; } } return bestTarget; }
NS_IMETHODIMP inDOMUtils::SetContentState(nsIDOMElement *aElement, nsEventStates::InternalType aState) { NS_ENSURE_ARG_POINTER(aElement); nsCOMPtr<nsIEventStateManager> esm = inLayoutUtils::GetEventStateManagerFor(aElement); if (esm) { nsCOMPtr<nsIContent> content; content = do_QueryInterface(aElement); return esm->SetContentState(content, nsEventStates(aState)); } return NS_ERROR_FAILURE; }
NS_IMETHODIMP inDOMUtils::SetContentState(nsIDOMElement *aElement, nsEventStates::InternalType aState) { NS_ENSURE_ARG_POINTER(aElement); nsRefPtr<nsEventStateManager> esm = inLayoutUtils::GetEventStateManagerFor(aElement); if (esm) { nsCOMPtr<nsIContent> content; content = do_QueryInterface(aElement); // XXX Invalid cast of bool to nsresult (bug 778108) return (nsresult)esm->SetContentState(content, nsEventStates(aState)); } return NS_ERROR_FAILURE; }
nsEventStates Link::LinkState() const { // We are a constant method, but we are just lazily doing things and have to // track that state. Cast away that constness! Link *self = const_cast<Link *>(this); Element *element = self->mElement; // If we have not yet registered for notifications and need to, // due to our href changing, register now! if (!mRegistered && mNeedsRegistration && element->IsInDoc()) { // Only try and register once. self->mNeedsRegistration = false; nsCOMPtr<nsIURI> hrefURI(GetURI()); // Assume that we are not visited until we are told otherwise. self->mLinkState = eLinkState_Unvisited; // Make sure the href attribute has a valid link (bug 23209). // If we have a good href, register with History if available. if (mHistory && hrefURI) { nsresult rv = mHistory->RegisterVisitedCallback(hrefURI, self); if (NS_SUCCEEDED(rv)) { self->mRegistered = true; // And make sure we are in the document's link map. element->GetCurrentDoc()->AddStyleRelevantLink(self); } } } // Otherwise, return our known state. if (mLinkState == eLinkState_Visited) { return NS_EVENT_STATE_VISITED; } if (mLinkState == eLinkState_Unvisited) { return NS_EVENT_STATE_UNVISITED; } return nsEventStates(); }
void Link::ResetLinkState(bool aNotify) { // If we are in our default state, bail early. if (mLinkState == defaultState) { return; } Element *element = mElement; // Tell the document to forget about this link if we were a link before. nsIDocument *doc = element->GetCurrentDoc(); if (doc && mLinkState != eLinkState_NotLink) { doc->ForgetLink(this); } UnregisterFromHistory(); // Update our state back to the default. mLinkState = defaultState; // Get rid of our cached URI. mCachedURI = nullptr; // We have to be very careful here: if aNotify is false we do NOT // want to call UpdateState, because that will call into LinkState() // and try to start off loads, etc. But ResetLinkState is called // with aNotify false when things are in inconsistent states, so // we'll get confused in that situation. Instead, just silently // update the link state on mElement. if (aNotify) { mElement->UpdateState(aNotify); } else { mElement->UpdateLinkState(nsEventStates()); } }
nsEventStates nsMathMLElement::IntrinsicState() const { return nsMathMLElementBase::IntrinsicState() | (mIncrementScriptLevel ? NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL : nsEventStates()); }