Пример #1
0
nsresult
HTMLImageElement::LoadSelectedImage(bool aForce, bool aNotify)
{
  nsresult rv = NS_ERROR_FAILURE;

  if (aForce) {
    // In responsive mode we generally want to re-run the full
    // selection algorithm whenever starting a new load, per
    // spec. This also causes us to re-resolve the URI as appropriate.
    UpdateResponsiveSource();
  }

  if (mResponsiveSelector) {
    nsCOMPtr<nsIURI> url = mResponsiveSelector->GetSelectedImageURL();
    rv = LoadImage(url, aForce, aNotify, eImageLoadType_Imageset);
  } else {
    nsAutoString src;
    if (!GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
      CancelImageRequests(aNotify);
      rv = NS_OK;
    } else {
      // If we have a srcset attribute or are in a <picture> element,
      // we always use the Imageset load type, even if we parsed no
      // valid responsive sources from either, per spec.
      rv = LoadImage(src, aForce, aNotify,
                     HaveSrcsetOrInPicture() ? eImageLoadType_Imageset
                                             : eImageLoadType_Normal);
    }
  }

  if (NS_FAILED(rv)) {
    CancelImageRequests(aNotify);
  }
  return rv;
}
Пример #2
0
nsresult
HTMLImageElement::LoadSelectedImage(bool aForce, bool aNotify)
{
  nsresult rv = NS_ERROR_FAILURE;

  if (mResponsiveSelector) {
    nsCOMPtr<nsIURI> url = mResponsiveSelector->GetSelectedImageURL();
    if (url) {
      rv = LoadImage(url, aForce, aNotify);
    } else {
      CancelImageRequests(aNotify);
      rv = NS_OK;
    }
  } else {
    nsAutoString src;
    if (!GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
      CancelImageRequests(aNotify);
      rv = NS_OK;
    } else {
      rv = LoadImage(src, aForce, aNotify);
      if (NS_FAILED(rv)) {
        CancelImageRequests(aNotify);
      }
    }
  }

  return rv;
}
Пример #3
0
void
nsSVGImageElement::MaybeLoadSVGImage()
{
  if (HasAttr(kNameSpaceID_XLink, nsGkAtoms::href) &&
      (NS_FAILED(LoadSVGImage(PR_FALSE, PR_TRUE)) ||
       !LoadingEnabled())) {
    CancelImageRequests(PR_TRUE);
  }
}
nsresult
HTMLImageElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
                            bool aNotify)
{
  if (aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::src) {
    CancelImageRequests(aNotify);
  }

  return nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
}
void
HTMLImageElement::MaybeLoadImage()
{
  // Our base URI may have changed; claim that our URI changed, and the
  // nsImageLoadingContent will decide whether a new image load is warranted.
  // Note, check LoadingEnabled() after LoadImage call.
  nsAutoString uri;
  if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, uri) &&
      (NS_FAILED(LoadImage(uri, false, true)) ||
       !LoadingEnabled())) {
    CancelImageRequests(true);
  }
}
Пример #6
0
nsresult
HTMLImageElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                               const nsAttrValue* aValue, bool aNotify)
{
  if (aNameSpaceID == kNameSpaceID_None && mForm &&
      (aName == nsGkAtoms::name || aName == nsGkAtoms::id) &&
      aValue && !aValue->IsEmptyString()) {
    // add the image to the hashtable as needed
    NS_ABORT_IF_FALSE(aValue->Type() == nsAttrValue::eAtom,
      "Expected atom value for name/id");
    mForm->AddImageElementToTable(this,
      nsDependentAtomString(aValue->GetAtomValue()));
  }

  // Handle src/srcset/crossorigin updates. If aNotify is false, we are coming
  // from the parser or some such place; we'll get bound after all the
  // attributes have been set, so we'll do the image load from BindToTree.
  if (aName == nsGkAtoms::src &&
      aNameSpaceID == kNameSpaceID_None) {
    // SetAttr handles setting src in the non-responsive case, so only handle it
    // for responsive mode or unsetting
    if (!aValue) {
      CancelImageRequests(aNotify);
    } else if (mResponsiveSelector) {
      mResponsiveSelector->SetDefaultSource(aValue ? aValue->GetStringValue()
                                                   : EmptyString());
      LoadSelectedImage(false, aNotify);
    }
  } else if (aName == nsGkAtoms::srcset &&
             aNameSpaceID == kNameSpaceID_None &&
             aNotify &&
             AsContent()->IsInDoc() &&
             IsSrcsetEnabled()) {
    // We currently don't handle responsive mode until BindToTree
    UpdateSourceSet(aValue->GetStringValue());
    LoadSelectedImage(false, aNotify);
  } else if (aName == nsGkAtoms::crossorigin &&
             aNameSpaceID == kNameSpaceID_None &&
             aNotify) {
    // We want aForce == true in this LoadImage call, because we want to force
    // a new load of the image with the new cross origin policy.
    nsCOMPtr<nsIURI> currentURI;
    if (NS_SUCCEEDED(GetCurrentURI(getter_AddRefs(currentURI))) && currentURI) {
      LoadImage(currentURI, true, aNotify);
    }
  }

  return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName,
                                            aValue, aNotify);
}
Пример #7
0
void
HTMLImageElement::MaybeLoadImage()
{
  // Our base URI may have changed, or we may have had responsive parameters
  // change while not bound to the tree. Re-parse src/srcset and call LoadImage,
  // which is a no-op if it resolves to the same effective URI without aForce.

  // Note, check LoadingEnabled() after LoadImage call.

  LoadSelectedImage(false, true, false);

  if (!LoadingEnabled()) {
    CancelImageRequests(true);
  }
}
Пример #8
0
nsresult
nsSVGImageElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
                                const nsAString* aValue, PRBool aNotify)
{
  if (aNamespaceID == kNameSpaceID_XLink && aName == nsGkAtoms::href) {
    // If caller is not chrome and dom.disable_image_src_set is true,
    // prevent setting image.src by exiting early
    if (nsContentUtils::GetBoolPref("dom.disable_image_src_set") &&
        !nsContentUtils::IsCallerChrome()) {
      return NS_OK;
    }

    if (aValue) {
      LoadSVGImage(PR_TRUE, aNotify);
    } else {
      CancelImageRequests(aNotify);
    }
  }
  return nsSVGImageElementBase::AfterSetAttr(aNamespaceID, aName,
                                             aValue, aNotify);
}
nsresult
nsImageLoadingContent::LoadImage(const nsAString& aNewURI,
                                 PRBool aForce,
                                 PRBool aNotify)
{
  // First, get a document (needed for security checks and the like)
  nsIDocument* doc = GetOurDocument();
  if (!doc) {
    // No reason to bother, I think...
    return NS_OK;
  }

  nsCOMPtr<nsIURI> imageURI;
  nsresult rv = StringToURI(aNewURI, doc, getter_AddRefs(imageURI));
  NS_ENSURE_SUCCESS(rv, rv);
  // XXXbiesi fire onerror if that failed?

  PRBool equal;

  if (aNewURI.IsEmpty() &&
      doc->GetDocumentURI() &&
      NS_SUCCEEDED(doc->GetDocumentURI()->Equals(imageURI, &equal)) && 
      equal)  {

    // Loading an embedded img from the same URI as the document URI will not work
    // as a resource cannot recursively embed itself. Attempting to do so generally
    // results in having to pre-emptively close down an in-flight HTTP transaction 
    // and then incurring the significant cost of establishing a new TCP channel.
    // This is generally triggered from <img src=""> 
    // In light of that, just skip loading it..
    // Do make sure to drop our existing image, if any
    CancelImageRequests(aNotify);
    return NS_OK;
  }

  NS_TryToSetImmutable(imageURI);

  return LoadImage(imageURI, aForce, aNotify, doc);
}
Пример #10
0
nsresult
HTMLImageElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                               const nsAttrValue* aValue, bool aNotify)
{
  if (aNameSpaceID == kNameSpaceID_None && mForm &&
      (aName == nsGkAtoms::name || aName == nsGkAtoms::id) &&
      aValue && !aValue->IsEmptyString()) {
    // add the image to the hashtable as needed
    MOZ_ASSERT(aValue->Type() == nsAttrValue::eAtom,
               "Expected atom value for name/id");
    mForm->AddImageElementToTable(this,
      nsDependentAtomString(aValue->GetAtomValue()));
  }

  // Handle src/srcset/crossorigin updates. If aNotify is false, we are coming
  // from the parser or some such place; we'll get bound after all the
  // attributes have been set, so we'll do the image load from BindToTree.

  nsAttrValueOrString attrVal(aValue);

  if (aName == nsGkAtoms::src &&
      aNameSpaceID == kNameSpaceID_None &&
      !aValue) {
    // SetAttr handles setting src since it needs to catch img.src =
    // img.src, so we only need to handle the unset case
    if (InResponsiveMode()) {
      if (mResponsiveSelector &&
          mResponsiveSelector->Content() == this) {
        mResponsiveSelector->SetDefaultSource(NullString());
      }
      QueueImageLoadTask(true);
    } else {
      // Bug 1076583 - We still behave synchronously in the non-responsive case
      CancelImageRequests(aNotify);
    }
  } else if (aName == nsGkAtoms::srcset &&
             aNameSpaceID == kNameSpaceID_None &&
             IsSrcsetEnabled()) {
    PictureSourceSrcsetChanged(this, attrVal.String(), aNotify);
  } else if (aName == nsGkAtoms::sizes &&
             aNameSpaceID == kNameSpaceID_None &&
             HTMLPictureElement::IsPictureEnabled()) {
    PictureSourceSizesChanged(this, attrVal.String(), aNotify);
  } else if (aName == nsGkAtoms::crossorigin &&
             aNameSpaceID == kNameSpaceID_None &&
             aNotify) {
    // Force a new load of the image with the new cross origin policy.
    if (InResponsiveMode()) {
      // per spec, full selection runs when this changes, even though
      // it doesn't directly affect the source selection
      QueueImageLoadTask(true);
    } else {
      // Bug 1076583 - We still use the older synchronous algorithm in
      // non-responsive mode.  Force a new load of the image with the
      // new cross origin policy.
      ForceReload(aNotify);
    }
  }

  return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName,
                                            aValue, aNotify);
}