static void configureRequest(FetchRequest& request, ImageLoader::BypassMainWorldBehavior bypassBehavior, Element& element, const ClientHintsPreferences& clientHintsPreferences)
{
    if (bypassBehavior == ImageLoader::BypassMainWorldCSP)
        request.setContentSecurityCheck(DoNotCheckContentSecurityPolicy);

    AtomicString crossOriginMode = element.fastGetAttribute(HTMLNames::crossoriginAttr);
    if (!crossOriginMode.isNull())
        request.setCrossOriginAccessControl(element.document().securityOrigin(), crossOriginMode);

    if (clientHintsPreferences.shouldSendResourceWidth() && isHTMLImageElement(element))
        request.setResourceWidth(toHTMLImageElement(element).resourceWidth());
}
void LinkStyle::process()
{
    ASSERT(m_owner->shouldProcessStyle());
    String type = m_owner->typeValue().lower();
    LinkRequestBuilder builder(m_owner);

    if (m_owner->relAttribute().iconType() != InvalidIcon && builder.url().isValid() && !builder.url().isEmpty()) {
        if (!m_owner->shouldLoadLink())
            return;
        if (!document().securityOrigin()->canDisplay(builder.url()))
            return;
        if (!document().contentSecurityPolicy()->allowImageFromSource(builder.url()))
            return;
        if (document().frame() && document().frame()->loader().client())
            document().frame()->loader().client()->dispatchDidChangeIcons(m_owner->relAttribute().iconType());
    }

    if (!m_owner->loadLink(type, builder.url()))
        return;

    if ((m_disabledState != Disabled) && m_owner->relAttribute().isStyleSheet()
        && shouldLoadResource() && builder.url().isValid()) {

        if (resource()) {
            removePendingSheet();
            clearResource();
        }

        if (!m_owner->shouldLoadLink())
            return;

        m_loading = true;

        bool mediaQueryMatches = true;
        if (!m_owner->media().isEmpty()) {
            LocalFrame* frame = loadingFrame();
            if (Document* document = loadingFrame()->document()) {
                RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(*document);
                RefPtrWillBeRawPtr<MediaQuerySet> media = MediaQuerySet::create(m_owner->media());
                MediaQueryEvaluator evaluator(frame->view()->mediaType(), frame, documentStyle.get());
                mediaQueryMatches = evaluator.eval(media.get());
            }
        }

        // Don't hold up render tree construction and script execution on stylesheets
        // that are not needed for the rendering at the moment.
        bool blocking = mediaQueryMatches && !m_owner->isAlternate();
        addPendingSheet(blocking ? Blocking : NonBlocking);

        // Load stylesheets that are not needed for the rendering immediately with low priority.
        FetchRequest request = builder.build(blocking);
        AtomicString crossOriginMode = m_owner->fastGetAttribute(HTMLNames::crossoriginAttr);
        if (!crossOriginMode.isNull())
            request.setCrossOriginAccessControl(document().securityOrigin(), crossOriginMode);
        setResource(document().fetcher()->fetchCSSStyleSheet(request));

        if (!resource()) {
            // The request may have been denied if (for example) the stylesheet is local and the document is remote.
            m_loading = false;
            removePendingSheet();
        }
    } else if (m_sheet) {
        // we no longer contain a stylesheet, e.g. perhaps rel or type was changed
        RefPtrWillBeRawPtr<StyleSheet> removedSheet = m_sheet.get();
        clearSheet();
        document().removedStyleSheet(removedSheet.get());
    }
}
Exemple #3
0
void LinkStyle::process() {
  DCHECK(m_owner->shouldProcessStyle());
  String type = m_owner->typeValue().lower();
  String as = m_owner->asValue().lower();
  String media = m_owner->media().lower();
  LinkRequestBuilder builder(m_owner);

  if (m_owner->relAttribute().getIconType() != InvalidIcon &&
      builder.url().isValid() && !builder.url().isEmpty()) {
    if (!m_owner->shouldLoadLink())
      return;
    if (!document().getSecurityOrigin()->canDisplay(builder.url()))
      return;
    if (!document().contentSecurityPolicy()->allowImageFromSource(
            builder.url()))
      return;
    if (document().frame() && document().frame()->loader().client()) {
      document().frame()->loader().client()->dispatchDidChangeIcons(
          m_owner->relAttribute().getIconType());
    }
  }

  if (!m_owner->loadLink(type, as, media, builder.url()))
    return;

  if (m_disabledState != Disabled && m_owner->relAttribute().isStyleSheet() &&
      styleSheetTypeIsSupported(type) && shouldLoadResource() &&
      builder.url().isValid()) {
    if (resource()) {
      removePendingSheet();
      clearResource();
      clearFetchFollowingCORS();
    }

    if (!m_owner->shouldLoadLink())
      return;

    m_loading = true;

    String title = m_owner->title();
    if (!title.isEmpty() && !m_owner->isAlternate() &&
        m_disabledState != EnabledViaScript && m_owner->isInDocumentTree()) {
      document().styleEngine().setPreferredStylesheetSetNameIfNotSet(
          title, StyleEngine::DontUpdateActiveSheets);
    }

    bool mediaQueryMatches = true;
    LocalFrame* frame = loadingFrame();
    if (!m_owner->media().isEmpty() && frame) {
      MediaQuerySet* media = MediaQuerySet::create(m_owner->media());
      MediaQueryEvaluator evaluator(frame);
      mediaQueryMatches = evaluator.eval(media);
    }

    // Don't hold up layout tree construction and script execution on
    // stylesheets that are not needed for the layout at the moment.
    bool blocking = mediaQueryMatches && !m_owner->isAlternate() &&
                    m_owner->isCreatedByParser();
    addPendingSheet(blocking ? Blocking : NonBlocking);

    // Load stylesheets that are not needed for the layout immediately with low
    // priority.  When the link element is created by scripts, load the
    // stylesheets asynchronously but in high priority.
    bool lowPriority = !mediaQueryMatches || m_owner->isAlternate();
    FetchRequest request = builder.build(lowPriority);
    CrossOriginAttributeValue crossOrigin = crossOriginAttributeValue(
        m_owner->fastGetAttribute(HTMLNames::crossoriginAttr));
    if (crossOrigin != CrossOriginAttributeNotSet) {
      request.setCrossOriginAccessControl(document().getSecurityOrigin(),
                                          crossOrigin);
      setFetchFollowingCORS();
    }

    String integrityAttr = m_owner->fastGetAttribute(HTMLNames::integrityAttr);
    if (!integrityAttr.isEmpty()) {
      IntegrityMetadataSet metadataSet;
      SubresourceIntegrity::parseIntegrityAttribute(integrityAttr, metadataSet);
      request.setIntegrityMetadata(metadataSet);
    }
    setResource(CSSStyleSheetResource::fetch(request, document().fetcher()));

    if (m_loading && !resource()) {
      // The request may have been denied if (for example) the stylesheet is
      // local and the document is remote, or if there was a Content Security
      // Policy Failure.  setCSSStyleSheet() can be called synchronuosly in
      // setResource() and thus resource() is null and |m_loading| is false in
      // such cases even if the request succeeds.
      m_loading = false;
      removePendingSheet();
      notifyLoadedSheetAndAllCriticalSubresources(
          Node::ErrorOccurredLoadingSubresource);
    }
  } else if (m_sheet) {
    // we no longer contain a stylesheet, e.g. perhaps rel or type was changed
    StyleSheet* removedSheet = m_sheet.get();
    clearSheet();
    document().styleEngine().setNeedsActiveStyleUpdate(removedSheet,
                                                       FullStyleUpdate);
  }
}