bool HTMLImageElement::SourceElementMatches(nsIContent* aSourceNode) { MOZ_ASSERT(aSourceNode->IsHTMLElement(nsGkAtoms::source)); DebugOnly<Element *> parent(nsINode::GetParentElement()); MOZ_ASSERT(parent && parent->IsHTMLElement(nsGkAtoms::picture)); MOZ_ASSERT(IsPreviousSibling(aSourceNode, this)); MOZ_ASSERT(HTMLPictureElement::IsPictureEnabled()); // Check media and type HTMLSourceElement *src = static_cast<HTMLSourceElement*>(aSourceNode); if (!src->MatchesCurrentMedia()) { return false; } nsAutoString type; if (aSourceNode->GetAttr(kNameSpaceID_None, nsGkAtoms::type, type) && !SupportedPictureSourceType(type)) { return false; } return true; }
/* static */ bool HTMLImageElement::SelectSourceForTagWithAttrs(nsIDocument *aDocument, bool aIsSourceTag, const nsAString& aSrcAttr, const nsAString& aSrcsetAttr, const nsAString& aSizesAttr, const nsAString& aTypeAttr, const nsAString& aMediaAttr, nsAString& aResult) { MOZ_ASSERT(aIsSourceTag || (aTypeAttr.IsEmpty() && aMediaAttr.IsEmpty()), "Passing type or media attrs makes no sense without aIsSourceTag"); MOZ_ASSERT(!aIsSourceTag || aSrcAttr.IsEmpty(), "Passing aSrcAttr makes no sense with aIsSourceTag set"); bool pictureEnabled = HTMLPictureElement::IsPictureEnabled(); if (aIsSourceTag && !pictureEnabled) { return false; } if (!IsSrcsetEnabled() || aSrcsetAttr.IsEmpty()) { if (!aIsSourceTag) { // For an <img> with no srcset, we would always select the src attr. aResult.Assign(aSrcAttr); return true; } // Otherwise, a <source> without srcset is never selected return false; } // Would not consider source tags with unsupported media or type if (aIsSourceTag && ((!aMediaAttr.IsVoid() && !HTMLSourceElement::WouldMatchMediaForDocument(aMediaAttr, aDocument)) || (!aTypeAttr.IsVoid() && !SupportedPictureSourceType(aTypeAttr)))) { return false; } // Using srcset or picture <source>, build a responsive selector for this tag. RefPtr<ResponsiveImageSelector> sel = new ResponsiveImageSelector(aDocument); sel->SetCandidatesFromSourceSet(aSrcsetAttr); if (pictureEnabled && !aSizesAttr.IsEmpty()) { sel->SetSizesFromDescriptor(aSizesAttr); } if (!aIsSourceTag) { sel->SetDefaultSource(aSrcAttr); } if (sel->GetSelectedImageURLSpec(aResult)) { return true; } if (!aIsSourceTag) { // <img> tag with no match would definitively load nothing. aResult.Truncate(); return true; } // <source> tags with no match would leave source yet-undetermined. return false; }
bool HTMLImageElement::TryCreateResponsiveSelector(nsIContent *aSourceNode, const nsAString *aSrcset, const nsAString *aSizes) { if (!IsSrcsetEnabled()) { return false; } bool pictureEnabled = HTMLPictureElement::IsPictureEnabled(); // Skip if this is not a <source> with matching media query bool isSourceTag = aSourceNode->IsHTMLElement(nsGkAtoms::source); if (isSourceTag) { DebugOnly<Element *> parent(nsINode::GetParentElement()); MOZ_ASSERT(parent && parent->IsHTMLElement(nsGkAtoms::picture)); MOZ_ASSERT(IsPreviousSibling(aSourceNode, this)); MOZ_ASSERT(pictureEnabled); // Check media and type HTMLSourceElement *src = static_cast<HTMLSourceElement*>(aSourceNode); if (!src->MatchesCurrentMedia()) { return false; } nsAutoString type; if (aSourceNode->GetAttr(kNameSpaceID_None, nsGkAtoms::type, type) && !SupportedPictureSourceType(type)) { return false; } } else if (aSourceNode->IsHTMLElement(nsGkAtoms::img)) { // Otherwise this is the <img> tag itself MOZ_ASSERT(aSourceNode == this); } // Skip if has no srcset or an empty srcset nsString srcset; if (aSrcset) { srcset = *aSrcset; } else if (!aSourceNode->GetAttr(kNameSpaceID_None, nsGkAtoms::srcset, srcset)) { return false; } if (srcset.IsEmpty()) { return false; } // Try to parse nsRefPtr<ResponsiveImageSelector> sel = new ResponsiveImageSelector(aSourceNode); if (!sel->SetCandidatesFromSourceSet(srcset)) { // No possible candidates, don't need to bother parsing sizes return false; } if (pictureEnabled && aSizes) { sel->SetSizesFromDescriptor(*aSizes); } else if (pictureEnabled) { nsAutoString sizes; aSourceNode->GetAttr(kNameSpaceID_None, nsGkAtoms::sizes, sizes); sel->SetSizesFromDescriptor(sizes); } // If this is the <img> tag, also pull in src as the default source if (!isSourceTag) { MOZ_ASSERT(aSourceNode == this); nsAutoString src; if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src) && !src.IsEmpty()) { sel->SetDefaultSource(src); } } mResponsiveSelector = sel; return true; }