bool HTMLLinkAccessible::IsLinked() const { EventStates state = mContent->AsElement()->State(); return state.HasAtLeastOneOfStates(NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED); }
/* virtual */ void nsHTMLStyleSheet::RulesMatching(ElementRuleProcessorData* aData) { nsRuleWalker *ruleWalker = aData->mRuleWalker; if (aData->mElement->IsHTML() && !ruleWalker->AuthorStyleDisabled()) { nsIAtom* tag = aData->mElement->Tag(); // if we have anchor colors, check if this is an anchor with an href if (tag == nsGkAtoms::a) { if (mLinkRule || mVisitedRule || mActiveRule) { EventStates state = nsCSSRuleProcessor::GetContentStateForVisitedHandling( aData->mElement, aData->mTreeMatchContext, aData->mTreeMatchContext.VisitedHandling(), // If the node being matched is a link, // it's the relevant link. nsCSSRuleProcessor::IsLink(aData->mElement)); if (mLinkRule && state.HasState(NS_EVENT_STATE_UNVISITED)) { ruleWalker->Forward(mLinkRule); aData->mTreeMatchContext.SetHaveRelevantLink(); } else if (mVisitedRule && state.HasState(NS_EVENT_STATE_VISITED)) { ruleWalker->Forward(mVisitedRule); aData->mTreeMatchContext.SetHaveRelevantLink(); } // No need to add to the active rule if it's not a link if (mActiveRule && nsCSSRuleProcessor::IsLink(aData->mElement) && state.HasState(NS_EVENT_STATE_ACTIVE)) { ruleWalker->Forward(mActiveRule); } } // end link/visited/active rules } // end A tag // add the rule to handle text-align for a <th> else if (tag == nsGkAtoms::th) { ruleWalker->Forward(mTableTHRule); } else if (tag == nsGkAtoms::table) { if (aData->mTreeMatchContext.mCompatMode == eCompatibility_NavQuirks) { ruleWalker->Forward(mTableQuirkColorRule); } } } // end html element // just get the style rules from the content. For SVG we do this even if // author style is disabled, because SVG presentational hints aren't // considered style. if (!ruleWalker->AuthorStyleDisabled() || aData->mElement->IsSVG()) { aData->mElement->WalkContentStyleRules(ruleWalker); } // http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#language // says that the xml:lang attribute overrides HTML's lang attribute, // so we need to do this after WalkContentStyleRules. nsString lang; if (aData->mElement->GetAttr(kNameSpaceID_XML, nsGkAtoms::lang, lang)) { ruleWalker->Forward(LangRuleFor(lang)); } }
uint64_t HTMLButtonAccessible::NativeState() const { uint64_t state = HyperTextAccessibleWrap::NativeState(); EventStates elmState = mContent->AsElement()->State(); if (elmState.HasState(NS_EVENT_STATE_DEFAULT)) state |= states::DEFAULT; return state; }
bool nsNativeTheme::IsPressedButton(nsIFrame* aFrame) { EventStates eventState = GetContentState(aFrame, NS_THEME_TOOLBAR_BUTTON); if (IsDisabled(aFrame, eventState)) return false; return IsOpenButton(aFrame) || eventState.HasAllStates(NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_HOVER); }
bool HTMLLinkAccessible::IsLinked() { if (IsDefunct()) return false; EventStates state = mContent->AsElement()->State(); return state.HasAtLeastOneOfStates(NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED); }
void nsRangeFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (IsThemed()) { DisplayBorderBackgroundOutline(aBuilder, aLists); // Only create items for the thumb. Specifically, we do not want // the track to paint, since *our* background is used to paint // the track, and we don't want the unthemed track painting over // the top of the themed track. // This logic is copied from // nsContainerFrame::BuildDisplayListForNonBlockChildren as // called by BuildDisplayListForInline. nsIFrame* thumb = mThumbDiv->GetPrimaryFrame(); if (thumb) { nsDisplayListSet set(aLists, aLists.Content()); BuildDisplayListForChild(aBuilder, thumb, aDirtyRect, set, DISPLAY_CHILD_INLINE); } } else { BuildDisplayListForInline(aBuilder, aDirtyRect, aLists); } // Draw a focus outline if appropriate: if (!aBuilder->IsForPainting() || !IsVisibleForPainting(aBuilder)) { // we don't want the focus ring item for hit-testing or if the item isn't // in the area being [re]painted return; } EventStates eventStates = mContent->AsElement()->State(); if (eventStates.HasState(NS_EVENT_STATE_DISABLED) || !eventStates.HasState(NS_EVENT_STATE_FOCUSRING)) { return; // can't have focus or doesn't match :-moz-focusring } if (!mOuterFocusStyle || !mOuterFocusStyle->StyleBorder()->HasBorder()) { // no ::-moz-focus-outer specified border (how style specifies a focus ring // for range) return; } const nsStyleDisplay *disp = StyleDisplay(); if (IsThemed(disp) && PresContext()->GetTheme()->ThemeDrawsFocusForWidget(disp->mAppearance)) { return; // the native theme displays its own visual indication of focus } aLists.Content()->AppendNewToTop( new (aBuilder) nsDisplayRangeFocusRing(aBuilder, this)); }
void nsNumberControlFrame::SyncDisabledState() { EventStates eventStates = mContent->AsElement()->State(); if (eventStates.HasState(NS_EVENT_STATE_DISABLED)) { mTextField->SetAttr(kNameSpaceID_None, nsGkAtoms::disabled, EmptyString(), true); } else { mTextField->UnsetAttr(kNameSpaceID_None, nsGkAtoms::disabled, true); } }
EventStates HTMLTextAreaElement::IntrinsicState() const { EventStates state = nsGenericHTMLFormElementWithState::IntrinsicState(); if (HasAttr(kNameSpaceID_None, nsGkAtoms::required)) { state |= NS_EVENT_STATE_REQUIRED; } else { state |= NS_EVENT_STATE_OPTIONAL; } if (IsCandidateForConstraintValidation()) { if (IsValid()) { state |= NS_EVENT_STATE_VALID; } else { state |= NS_EVENT_STATE_INVALID; // :-moz-ui-invalid always apply if the element suffers from a custom // error and never applies if novalidate is set on the form owner. if ((!mForm || !mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) && (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR) || (mCanShowInvalidUI && ShouldShowValidityUI()))) { state |= NS_EVENT_STATE_MOZ_UI_INVALID; } } // :-moz-ui-valid applies if all the following are true: // 1. The element is not focused, or had either :-moz-ui-valid or // :-moz-ui-invalid applying before it was focused ; // 2. The element is either valid or isn't allowed to have // :-moz-ui-invalid applying ; // 3. The element has no form owner or its form owner doesn't have the // novalidate attribute set ; // 4. The element has already been modified or the user tried to submit the // form owner while invalid. if ((!mForm || !mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) && (mCanShowValidUI && ShouldShowValidityUI() && (IsValid() || (state.HasState(NS_EVENT_STATE_MOZ_UI_INVALID) && !mCanShowInvalidUI)))) { state |= NS_EVENT_STATE_MOZ_UI_VALID; } } if (HasAttr(kNameSpaceID_None, nsGkAtoms::placeholder) && IsValueEmpty()) { state |= NS_EVENT_STATE_PLACEHOLDERSHOWN; } return state; }
void nsButtonBoxFrame::Blurred() { NS_ASSERTION(mContent->IsElement(), "How do we have a non-element?"); EventStates buttonState = mContent->AsElement()->State(); if (mIsHandlingKeyEvent && buttonState.HasAllStates(NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_HOVER)) { // return to normal state EventStateManager* esm = PresContext()->EventStateManager(); esm->SetContentState(nullptr, NS_EVENT_STATE_ACTIVE); esm->SetContentState(nullptr, NS_EVENT_STATE_HOVER); } mIsHandlingKeyEvent = false; }
uint64_t HTMLLinkAccessible::NativeLinkState() const { EventStates eventState = mContent->AsElement()->State(); if (eventState.HasState(NS_EVENT_STATE_UNVISITED)) return states::LINKED; if (eventState.HasState(NS_EVENT_STATE_VISITED)) return states::LINKED | states::TRAVERSED; // This is a either named anchor (a link with also a name attribute) or // it doesn't have any attributes. Check if 'click' event handler is // registered, otherwise bail out. return nsCoreUtils::HasClickListener(mContent) ? states::LINKED : 0; }
void nsNumberControlFrame::ContentStatesChanged(EventStates aStates) { if (aStates.HasState(NS_EVENT_STATE_DISABLED)) { nsContentUtils::AddScriptRunner(new SyncDisabledStateEvent(this)); } }
// progressbar: bool nsNativeTheme::IsIndeterminateProgress(nsIFrame* aFrame, EventStates aEventStates) { if (!aFrame || !aFrame->GetContent()) return false; if (aFrame->GetContent()->IsHTML(nsGkAtoms::progress)) { return aEventStates.HasState(NS_EVENT_STATE_INDETERMINATE); } return aFrame->GetContent()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::mode, NS_LITERAL_STRING("undetermined"), eCaseMatters); }
bool nsNativeTheme::IsDisabled(nsIFrame* aFrame, EventStates aEventStates) { if (!aFrame) { return false; } nsIContent* content = aFrame->GetContent(); if (!content) { return false; } if (content->IsHTML()) { return aEventStates.HasState(NS_EVENT_STATE_DISABLED); } // For XML/XUL elements, an attribute must be equal to the literal // string "true" to be counted as true. An empty string should _not_ // be counted as true. return content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled, NS_LITERAL_STRING("true"), eCaseMatters); }
nsresult nsButtonBoxFrame::HandleEvent(nsPresContext* aPresContext, WidgetGUIEvent* aEvent, nsEventStatus* aEventStatus) { NS_ENSURE_ARG_POINTER(aEventStatus); if (nsEventStatus_eConsumeNoDefault == *aEventStatus) { return NS_OK; } switch (aEvent->message) { case NS_KEY_DOWN: { WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent(); if (!keyEvent) { break; } if (NS_VK_SPACE == keyEvent->keyCode) { EventStateManager* esm = aPresContext->EventStateManager(); // :hover:active state esm->SetContentState(mContent, NS_EVENT_STATE_HOVER); esm->SetContentState(mContent, NS_EVENT_STATE_ACTIVE); mIsHandlingKeyEvent = true; } break; } // On mac, Return fires the default button, not the focused one. #ifndef XP_MACOSX case NS_KEY_PRESS: { WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent(); if (!keyEvent) { break; } if (NS_VK_RETURN == keyEvent->keyCode) { nsCOMPtr<nsIDOMXULButtonElement> buttonEl(do_QueryInterface(mContent)); if (buttonEl) { MouseClicked(aPresContext, aEvent); *aEventStatus = nsEventStatus_eConsumeNoDefault; } } break; } #endif case NS_KEY_UP: { WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent(); if (!keyEvent) { break; } if (NS_VK_SPACE == keyEvent->keyCode) { mIsHandlingKeyEvent = false; // only activate on keyup if we're already in the :hover:active state NS_ASSERTION(mContent->IsElement(), "How do we have a non-element?"); EventStates buttonState = mContent->AsElement()->State(); if (buttonState.HasAllStates(NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_HOVER)) { // return to normal state EventStateManager* esm = aPresContext->EventStateManager(); esm->SetContentState(nullptr, NS_EVENT_STATE_ACTIVE); esm->SetContentState(nullptr, NS_EVENT_STATE_HOVER); MouseClicked(aPresContext, aEvent); } } break; } case NS_MOUSE_CLICK: { WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent(); if (mouseEvent->IsLeftClickEvent()) { MouseClicked(aPresContext, mouseEvent); } break; } } return nsBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus); }
/** * Calculates the change hint and the restyle hint for a given content state * change. * * This is called from both Restyle managers. */ void RestyleManagerBase::ContentStateChangedInternal(Element* aElement, EventStates aStateMask, nsChangeHint* aOutChangeHint, nsRestyleHint* aOutRestyleHint) { MOZ_ASSERT(aOutChangeHint); MOZ_ASSERT(aOutRestyleHint); StyleSetHandle styleSet = PresContext()->StyleSet(); NS_ASSERTION(styleSet, "couldn't get style set"); *aOutChangeHint = nsChangeHint(0); // Any change to a content state that affects which frames we construct // must lead to a frame reconstruct here if we already have a frame. // Note that we never decide through non-CSS means to not create frames // based on content states, so if we already don't have a frame we don't // need to force a reframe -- if it's needed, the HasStateDependentStyle // call will handle things. nsIFrame* primaryFrame = aElement->GetPrimaryFrame(); CSSPseudoElementType pseudoType = CSSPseudoElementType::NotPseudo; if (primaryFrame) { // If it's generated content, ignore LOADING/etc state changes on it. if (!primaryFrame->IsGeneratedContentFrame() && aStateMask.HasAtLeastOneOfStates(NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_USERDISABLED | NS_EVENT_STATE_SUPPRESSED | NS_EVENT_STATE_LOADING)) { *aOutChangeHint = nsChangeHint_ReconstructFrame; } else { uint8_t app = primaryFrame->StyleDisplay()->mAppearance; if (app) { nsITheme* theme = PresContext()->GetTheme(); if (theme && theme->ThemeSupportsWidget(PresContext(), primaryFrame, app)) { bool repaint = false; theme->WidgetStateChanged(primaryFrame, app, nullptr, &repaint, nullptr); if (repaint) { *aOutChangeHint |= nsChangeHint_RepaintFrame; } } } } pseudoType = primaryFrame->StyleContext()->GetPseudoType(); primaryFrame->ContentStatesChanged(aStateMask); } if (pseudoType >= CSSPseudoElementType::Count) { *aOutRestyleHint = styleSet->HasStateDependentStyle(aElement, aStateMask); } else if (nsCSSPseudoElements::PseudoElementSupportsUserActionState( pseudoType)) { // If aElement is a pseudo-element, we want to check to see whether there // are any state-dependent rules applying to that pseudo. Element* ancestor = ElementForStyleContext(nullptr, primaryFrame, pseudoType); *aOutRestyleHint = styleSet->HasStateDependentStyle(ancestor, pseudoType, aElement, aStateMask); } else { *aOutRestyleHint = nsRestyleHint(0); } if (aStateMask.HasState(NS_EVENT_STATE_HOVER) && *aOutRestyleHint != 0) { IncrementHoverGeneration(); } if (aStateMask.HasState(NS_EVENT_STATE_VISITED)) { // Exposing information to the page about whether the link is // visited or not isn't really something we can worry about here. // FIXME: We could probably do this a bit better. *aOutChangeHint |= nsChangeHint_RepaintFrame; } }