bool HTMLImageElement::Draggable() const { // images may be dragged unless the draggable attribute is false return !AttrValueIs(kNameSpaceID_None, nsGkAtoms::draggable, nsGkAtoms::_false, eIgnoreCase); }
nsresult XULTooltipElement::PostHandleEvent(EventChainPostVisitor& aVisitor) { if (aVisitor.mEvent->mMessage == eXULPopupShowing && aVisitor.mEvent->IsTrusted() && !aVisitor.mEvent->DefaultPrevented() && AttrValueIs(kNameSpaceID_None, nsGkAtoms::page, nsGkAtoms::_true, eCaseMatters)) { // When the tooltip node has the "page" attribute set to "true" the // tooltip text provider is used to find the tooltip text from page where // mouse is hovering over. nsCOMPtr<nsITooltipTextProvider> textProvider = do_GetService(NS_DEFAULTTOOLTIPTEXTPROVIDER_CONTRACTID); nsString text; nsString direction; bool shouldChange = false; if (textProvider) { textProvider->GetNodeText(GetTriggerNode(), getter_Copies(text), getter_Copies(direction), &shouldChange); } if (shouldChange) { SetAttr(kNameSpaceID_None, nsGkAtoms::label, text, true); SetAttr(kNameSpaceID_None, nsGkAtoms::direction, direction, true); } else { aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault; aVisitor.mEvent->PreventDefault(); } } return NS_OK; }
void CheckCaption(TidyDocImpl* doc, Node *node) { AttVal *attval; TY_(CheckAttributes)(doc, node); attval = TY_(AttrGetById)(node, TidyAttr_ALIGN); if (!AttrHasValue(attval)) return; if (AttrValueIs(attval, "left") || AttrValueIs(attval, "right")) TY_(ConstrainVersion)(doc, VERS_HTML40_LOOSE); else if (AttrValueIs(attval, "top") || AttrValueIs(attval, "bottom")) TY_(ConstrainVersion)(doc, ~(VERS_HTML20|VERS_HTML32)); else TY_(ReportAttrError)(doc, node, attval, BAD_ATTRIBUTE_VALUE); }
nsIContent * nsSVGSwitchElement::FindActiveChild() const { PRBool allowReorder = AttrValueIs(kNameSpaceID_None, nsGkAtoms::allowReorder, nsGkAtoms::yes, eCaseMatters); const nsAdoptingString& acceptLangs = nsContentUtils::GetLocalizedStringPref("intl.accept_languages"); PRUint32 count = GetChildCount(); if (allowReorder && !acceptLangs.IsEmpty()) { PRInt32 bestLanguagePreferenceRank = -1; nsIContent *bestChild = nsnull; for (PRUint32 i = 0; i < count; i++) { nsIContent *child = GetChildAt(i); if (nsSVGFeatures::PassesConditionalProcessingTests( child, nsSVGFeatures::kIgnoreSystemLanguage)) { nsAutoString value; if (child->GetAttr(kNameSpaceID_None, nsGkAtoms::systemLanguage, value)) { PRInt32 languagePreferenceRank = nsSVGFeatures::GetBestLanguagePreferenceRank(value, acceptLangs); switch (languagePreferenceRank) { case 0: // best possible match return child; case -1: // not found break; default: if (bestLanguagePreferenceRank == -1 || languagePreferenceRank < bestLanguagePreferenceRank) { bestLanguagePreferenceRank = languagePreferenceRank; bestChild = child; } break; } } else if (!bestChild) { bestChild = child; } } } return bestChild; } for (PRUint32 i = 0; i < count; i++) { nsIContent *child = GetChildAt(i); if (nsSVGFeatures::PassesConditionalProcessingTests(child, &acceptLangs)) { return child; } } return nsnull; }
bool HTMLAnchorElement::Draggable() const { // links can be dragged as long as there is an href and the // draggable attribute isn't false if (!HasAttr(kNameSpaceID_None, nsGkAtoms::href)) { // no href, so just use the same behavior as other elements return nsGenericHTMLElement::Draggable(); } return !AttrValueIs(kNameSpaceID_None, nsGkAtoms::draggable, nsGkAtoms::_false, eIgnoreCase); }
PRBool nsXMLElement::IsLink(nsIURI** aURI) const { NS_PRECONDITION(aURI, "Must provide aURI out param"); // To be an XLink for styling and interaction purposes, we require: // // xlink:href - must be set // xlink:type - must be set to "simple" // xlink:_moz_target - must be set, OR // xlink:show - must be unset or set to "", "new" or "replace" // xlink:actuate - must be unset or set to "" or "onRequest" // // For any other values, we're either not a *clickable* XLink, or the end // result is poorly specified. Either way, we return PR_FALSE. static nsIContent::AttrValuesArray sShowVals[] = { &nsGkAtoms::_empty, &nsGkAtoms::_new, &nsGkAtoms::replace, nsnull }; static nsIContent::AttrValuesArray sActuateVals[] = { &nsGkAtoms::_empty, &nsGkAtoms::onRequest, nsnull }; // Optimization: check for href first for early return const nsAttrValue* href = mAttrsAndChildren.GetAttr(nsGkAtoms::href, kNameSpaceID_XLink); if (href && AttrValueIs(kNameSpaceID_XLink, nsGkAtoms::type, nsGkAtoms::simple, eCaseMatters) && (HasAttr(kNameSpaceID_XLink, nsGkAtoms::_moz_target) || FindAttrValueIn(kNameSpaceID_XLink, nsGkAtoms::show, sShowVals, eCaseMatters) != nsIContent::ATTR_VALUE_NO_MATCH) && FindAttrValueIn(kNameSpaceID_XLink, nsGkAtoms::actuate, sActuateVals, eCaseMatters) != nsIContent::ATTR_VALUE_NO_MATCH) { // Get absolute URI nsCOMPtr<nsIURI> baseURI = GetBaseURI(); nsContentUtils::NewURIWithDocumentCharset(aURI, href->GetStringValue(), GetOwnerDoc(), baseURI); return !!*aURI; // must promise out param is non-null if we return true } *aURI = nsnull; return PR_FALSE; }
/* add missing type attribute when appropriate */ void CheckLINK( TidyDocImpl* doc, Node *node ) { AttVal *rel = TY_(AttrGetById)(node, TidyAttr_REL); TY_(CheckAttributes)( doc, node ); /* todo: <link rel="alternate stylesheet"> */ if (AttrValueIs(rel, "stylesheet")) { AttVal *type = TY_(AttrGetById)(node, TidyAttr_TYPE); if (!type) { TY_(AddAttribute)( doc, node, "type", "text/css" ); type = TY_(AttrGetById)(node, TidyAttr_TYPE); TY_(ReportAttrError)( doc, node, type, INSERTING_ATTRIBUTE ); } } }
nsresult HTMLMetaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent, nsIContent* aBindingParent, bool aCompileEventHandlers) { nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent, aBindingParent, aCompileEventHandlers); NS_ENSURE_SUCCESS(rv, rv); if (aDocument && AttrValueIs(kNameSpaceID_None, nsGkAtoms::name, nsGkAtoms::viewport, eIgnoreCase)) { nsAutoString content; rv = GetContent(content); NS_ENSURE_SUCCESS(rv, rv); nsContentUtils::ProcessViewportInfo(aDocument, content); } CreateAndDispatchEvent(aDocument, NS_LITERAL_STRING("DOMMetaAdded")); return rv; }
nsIContent * SVGSwitchElement::FindActiveChild() const { bool allowReorder = AttrValueIs(kNameSpaceID_None, nsGkAtoms::allowReorder, nsGkAtoms::yes, eCaseMatters); const nsAdoptingString& acceptLangs = Preferences::GetLocalizedString("intl.accept_languages"); if (allowReorder && !acceptLangs.IsEmpty()) { int32_t bestLanguagePreferenceRank = -1; nsIContent *bestChild = nullptr; for (nsIContent* child = nsINode::GetFirstChild(); child; child = child->GetNextSibling()) { if (!child->IsElement()) { continue; } nsCOMPtr<DOMSVGTests> tests(do_QueryInterface(child)); if (tests) { if (tests->PassesConditionalProcessingTests( DOMSVGTests::kIgnoreSystemLanguage)) { int32_t languagePreferenceRank = tests->GetBestLanguagePreferenceRank(acceptLangs); switch (languagePreferenceRank) { case 0: // best possible match return child; case -1: // not found break; default: if (bestLanguagePreferenceRank == -1 || languagePreferenceRank < bestLanguagePreferenceRank) { bestLanguagePreferenceRank = languagePreferenceRank; bestChild = child; } break; } } } else if (!bestChild) { bestChild = child; } } return bestChild; } for (nsIContent* child = nsINode::GetFirstChild(); child; child = child->GetNextSibling()) { if (!child->IsElement()) { continue; } nsCOMPtr<DOMSVGTests> tests(do_QueryInterface(child)); if (!tests || tests->PassesConditionalProcessingTests(&acceptLangs)) { return child; } } return nullptr; }
nsresult HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName, const nsAttrValue* aValue, const nsAttrValue* aOldValue, nsIPrincipal* aSubjectPrincipal, bool aNotify) { // It's safe to call ResetLinkState here because our new attr value has // already been set or unset. ResetLinkState needs the updated attribute // value because notifying the document that content states have changed will // call IntrinsicState, which will try to get updated information about the // visitedness from Link. if (aName == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID) { bool hasHref = aValue; Link::ResetLinkState(!!aNotify, hasHref); if (IsInUncomposedDoc()) { CreateAndDispatchEvent(OwnerDoc(), NS_LITERAL_STRING("DOMLinkChanged")); } } if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::href) { mTriggeringPrincipal = nsContentUtils::GetAttrTriggeringPrincipal( this, aValue ? aValue->GetStringValue() : EmptyString(), aSubjectPrincipal); } // If a link's `rel` attribute was changed from or to `localization`, // update the list of localization links. if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::rel) { Document* doc = GetComposedDoc(); if (doc) { if ((aValue && aValue->Equals(nsGkAtoms::localization, eIgnoreCase)) && (!aOldValue || !aOldValue->Equals(nsGkAtoms::localization, eIgnoreCase))) { doc->LocalizationLinkAdded(this); } else if ((aOldValue && aOldValue->Equals(nsGkAtoms::localization, eIgnoreCase)) && (!aValue || !aValue->Equals(nsGkAtoms::localization, eIgnoreCase))) { doc->LocalizationLinkRemoved(this); } } } // If the link has `rel=localization` and its `href` attribute is changed, // update the list of localization links. if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::href && AttrValueIs(kNameSpaceID_None, nsGkAtoms::rel, nsGkAtoms::localization, eIgnoreCase)) { Document* doc = GetComposedDoc(); if (doc) { if (aOldValue) { doc->LocalizationLinkRemoved(this); } if (aValue) { doc->LocalizationLinkAdded(this); } } } if (aValue) { if (aNameSpaceID == kNameSpaceID_None && (aName == nsGkAtoms::href || aName == nsGkAtoms::rel || aName == nsGkAtoms::title || aName == nsGkAtoms::media || aName == nsGkAtoms::type || aName == nsGkAtoms::as || aName == nsGkAtoms::crossorigin)) { bool dropSheet = false; if (aName == nsGkAtoms::rel) { nsAutoString value; aValue->ToString(value); uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(value); if (GetSheet()) { dropSheet = !(linkTypes & nsStyleLinkElement::eSTYLESHEET); } } if ((aName == nsGkAtoms::rel || aName == nsGkAtoms::href) && IsInComposedDoc()) { TryDNSPrefetchOrPreconnectOrPrefetchOrPreloadOrPrerender(); } if ((aName == nsGkAtoms::as || aName == nsGkAtoms::type || aName == nsGkAtoms::crossorigin || aName == nsGkAtoms::media) && IsInComposedDoc()) { UpdatePreload(aName, aValue, aOldValue); } const bool forceUpdate = dropSheet || aName == nsGkAtoms::title || aName == nsGkAtoms::media || aName == nsGkAtoms::type; Unused << UpdateStyleSheetInternal( nullptr, nullptr, forceUpdate ? ForceUpdate::Yes : ForceUpdate::No); } } else { // Since removing href or rel makes us no longer link to a // stylesheet, force updates for those too. if (aNameSpaceID == kNameSpaceID_None) { if (aName == nsGkAtoms::href || aName == nsGkAtoms::rel || aName == nsGkAtoms::title || aName == nsGkAtoms::media || aName == nsGkAtoms::type) { Unused << UpdateStyleSheetInternal(nullptr, nullptr, ForceUpdate::Yes); } if ((aName == nsGkAtoms::as || aName == nsGkAtoms::type || aName == nsGkAtoms::crossorigin || aName == nsGkAtoms::media) && IsInComposedDoc()) { UpdatePreload(aName, aValue, aOldValue); } } } return nsGenericHTMLElement::AfterSetAttr( aNameSpaceID, aName, aValue, aOldValue, aSubjectPrincipal, aNotify); }
nsresult nsXMLElement::MaybeTriggerAutoLink(nsIDocShell *aShell) { NS_ENSURE_ARG_POINTER(aShell); // We require an xlink:href, xlink:type="simple" and xlink:actuate="onLoad" // XXX: as of XLink 1.1, elements will be links even without xlink:type set if (!HasAttr(kNameSpaceID_XLink, nsGkAtoms::href) || !AttrValueIs(kNameSpaceID_XLink, nsGkAtoms::type, nsGkAtoms::simple, eCaseMatters) || !AttrValueIs(kNameSpaceID_XLink, nsGkAtoms::actuate, nsGkAtoms::onLoad, eCaseMatters)) { return NS_OK; } // Disable in Mail/News for now. We may want a pref to control // this at some point. nsCOMPtr<nsIDocShellTreeItem> docShellItem = do_QueryInterface(aShell); if (docShellItem) { nsCOMPtr<nsIDocShellTreeItem> rootItem; docShellItem->GetRootTreeItem(getter_AddRefs(rootItem)); nsCOMPtr<nsIDocShell> docshell = do_QueryInterface(rootItem); if (docshell) { PRUint32 appType; if (NS_SUCCEEDED(docshell->GetAppType(&appType)) && appType == nsIDocShell::APP_TYPE_MAIL) { return NS_OK; } } } // Get absolute URI nsCOMPtr<nsIURI> absURI; nsAutoString href; GetAttr(kNameSpaceID_XLink, nsGkAtoms::href, href); nsCOMPtr<nsIURI> baseURI = GetBaseURI(); nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(absURI), href, GetOwnerDoc(), baseURI); if (!absURI) { return NS_OK; } // Check that the link's URI isn't the same as its document's URI, or else // we'll recursively load the document forever (possibly in new windows!) PRBool isDocURI; absURI->Equals(GetOwnerDoc()->GetDocumentURI(), &isDocURI); if (isDocURI) { return NS_OK; } // Get target nsAutoString target; nsresult special_rv = GetLinkTargetAndAutoType(target); // Ignore this link if xlink:show has a value we don't implement if (NS_FAILED(special_rv)) return NS_OK; // Attempt to load the URI nsCOMPtr<nsPresContext> pc; nsresult rv = DocShellToPresContext(aShell, getter_AddRefs(pc)); NS_ENSURE_SUCCESS(rv, rv); if (pc) { nsContentUtils::TriggerLink(this, pc, absURI, target, PR_TRUE, PR_FALSE); } return special_rv; // return GetLinkTargetAndAutoType's special rv! }