void StyleElement::removedFrom(Element* element, ContainerNode* insertionPoint)
{
    if (!insertionPoint->inShadowIncludingDocument())
        return;

    ShadowRoot* shadowRoot = element->containingShadowRoot();
    if (!shadowRoot)
        shadowRoot = insertionPoint->containingShadowRoot();

    if (shadowRoot)
        shadowRoot->unregisterScopedHTMLStyleChild();

    Document& document = element->document();
    if (m_registeredAsCandidate) {
        document.styleEngine().removeStyleSheetCandidateNode(element, shadowRoot ? *toTreeScope(shadowRoot) : toTreeScope(document));
        m_registeredAsCandidate = false;
    }

    StyleSheet* removedSheet = m_sheet.get();

    if (m_sheet)
        clearSheet(element);
    if (removedSheet)
        document.styleEngine().setNeedsActiveStyleUpdate(removedSheet, AnalyzedStyleUpdate);
}
Example #2
0
void StyleElement::createSheet(Element* e, const String& text)
{
    ASSERT(e);
    ASSERT(e->inDocument());
    Document& document = e->document();
    if (m_sheet)
        clearSheet(e);

    // If type is empty or CSS, this is a CSS style sheet.
    const AtomicString& type = this->type();
    if (isCSS(e, type)) {
        RefPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(media());

        MediaQueryEvaluator screenEval("screen", true);
        MediaQueryEvaluator printEval("print", true);
        if (screenEval.eval(mediaQueries.get()) || printEval.eval(mediaQueries.get())) {
            m_loading = true;
            TextPosition startPosition = m_startPosition == TextPosition::belowRangePosition() ? TextPosition::minimumPosition() : m_startPosition;
            m_sheet = document.styleEngine()->createSheet(e, text, startPosition, m_createdByParser);
            m_sheet->setMediaQueries(mediaQueries.release());
            m_loading = false;
        }
    }


    document.styleResolverMayHaveChanged();
}
Example #3
0
StyleElement::~StyleElement()
{
#if !ENABLE(OILPAN)
    if (m_sheet)
        clearSheet();
#endif
}
Example #4
0
void ProcessingInstruction::removedFrom(ContainerNode* insertionPoint)
{
    CharacterData::removedFrom(insertionPoint);
    if (!insertionPoint->inDocument())
        return;

    // No need to remove XSLStyleSheet from StyleEngine.
    if (m_isCSS)
        document().styleEngine()->removeStyleSheetCandidateNode(this);
    else if (m_isXSL)
        document().styleEngine()->removeXSLStyleSheet(this);

    RefPtrWillBeRawPtr<StyleSheet> removedSheet = m_sheet;
    if (m_sheet) {
        ASSERT(m_sheet->ownerNode() == this);
        clearSheet();
    }

    // No need to remove pending sheets.
    clearResource();

    // If we're in document teardown, then we don't need to do any notification of our sheet's removal.
    if (document().isActive())
        document().removedStyleSheet(removedSheet.get());
}
Example #5
0
void ProcessingInstruction::removedFrom(ContainerNode* insertionPoint) {
  CharacterData::removedFrom(insertionPoint);
  if (!insertionPoint->isConnected())
    return;

  // No need to remove XSLStyleSheet from StyleEngine.
  if (!DocumentXSLT::processingInstructionRemovedFromDocument(document(),
                                                              this)) {
    document().styleEngine().removeStyleSheetCandidateNode(*this,
                                                           *insertionPoint);
  }

  if (m_sheet) {
    DCHECK_EQ(m_sheet->ownerNode(), this);
    clearSheet();
  }

  // No need to remove pending sheets.
  clearResource();

  // TODO([email protected]): resolverChanged() can be removed once stylesheet
  // updates are async. https://crbug.com/567021
  // If we're in document teardown, then we don't need to do any notification of
  // our sheet's removal.
  if (document().isActive())
    document().styleEngine().resolverChanged(FullStyleUpdate);
}
Example #6
0
void ProcessingInstruction::didAttributeChanged() {
  if (m_sheet)
    clearSheet();

  String href;
  String charset;
  if (!checkStyleSheet(href, charset))
    return;
  process(href, charset);
}
Example #7
0
void InlineStyleSheetOwner::removedFromDocument(Document& document, Element& element)
{
    authorStyleSheetsForElement(element).removeStyleSheetCandidateNode(element);

    if (m_sheet)
        clearSheet();

    // If we're in document teardown, then we don't need to do any notification of our sheet's removal.
    if (document.hasLivingRenderTree())
        document.styleResolverChanged(DeferRecalcStyle);
}
Example #8
0
void StyleElement::removedFromDocument(Document* document, Element* element)
{
    ASSERT(document);
    ASSERT(element);
    document->removeStyleSheetCandidateNode(element);

    if (m_sheet)
        clearSheet();

    // If we're in document teardown, then we don't need to do any notification of our sheet's removal.
    if (document->renderer())
        document->styleResolverChanged(DeferRecalcStyle);
}
void StyleElement::removedFromDocument(Document& document, Element* element, ContainerNode* scopingNode)
{
    ASSERT(element);
    document.styleEngine()->removeStyleSheetCandidateNode(element, scopingNode);

    RefPtr<StyleSheet> removedSheet = m_sheet;

    if (m_sheet)
        clearSheet();

    // If we're in document teardown, then we don't need to do any notification of our sheet's removal.
    if (document.isActive())
        document.removedStyleSheet(removedSheet.get(), RecalcStyleDeferred, AnalyzedStyleUpdate);
}
ProcessingInstruction::~ProcessingInstruction()
{
#if !ENABLE(OILPAN)
    if (m_sheet)
        clearSheet();

    // FIXME: ProcessingInstruction should not be in document here.
    // However, if we add ASSERT(!inDocument()), fast/xsl/xslt-entity.xml
    // crashes. We need to investigate ProcessingInstruction lifetime.
    if (inDocument() && m_isCSS)
        document().styleEngine().removeStyleSheetCandidateNode(this);
    clearEventListenerForXSLT();
#endif
}
Example #11
0
void StyleElement::removedFromDocument(Document& document, Element* element, ContainerNode* scopingNode, TreeScope& treeScope)
{
    ASSERT(element);

    if (m_registeredAsCandidate) {
        document.styleEngine()->removeStyleSheetCandidateNode(element, scopingNode, treeScope);
        m_registeredAsCandidate = false;
    }

    RefPtr<StyleSheet> removedSheet = m_sheet.get();

    if (m_sheet)
        clearSheet(element);
    if (removedSheet)
        document.removedStyleSheet(removedSheet.get(), AnalyzedStyleUpdate);
}
Example #12
0
StyleElement::ProcessingResult StyleElement::createSheet(Element& element,
                                                         const String& text) {
  DCHECK(element.isConnected());
  Document& document = element.document();

  const ContentSecurityPolicy* csp = document.contentSecurityPolicy();
  bool passesContentSecurityPolicyChecks =
      shouldBypassMainWorldCSP(element) ||
      csp->allowStyleWithHash(text, ContentSecurityPolicy::InlineType::Block) ||
      csp->allowInlineStyle(&element, document.url(),
                            element.fastGetAttribute(HTMLNames::nonceAttr),
                            m_startPosition.m_line, text);

  // Clearing the current sheet may remove the cache entry so create the new
  // sheet first
  CSSStyleSheet* newSheet = nullptr;

  // If type is empty or CSS, this is a CSS style sheet.
  const AtomicString& type = this->type();
  if (isCSS(element, type) && passesContentSecurityPolicyChecks) {
    MediaQuerySet* mediaQueries = MediaQuerySet::create(media());

    MediaQueryEvaluator screenEval("screen");
    MediaQueryEvaluator printEval("print");
    if (screenEval.eval(mediaQueries) || printEval.eval(mediaQueries)) {
      m_loading = true;
      TextPosition startPosition =
          m_startPosition == TextPosition::belowRangePosition()
              ? TextPosition::minimumPosition()
              : m_startPosition;
      newSheet = document.styleEngine().createSheet(
          element, text, startPosition, m_styleEngineContext);
      newSheet->setMediaQueries(mediaQueries);
      m_loading = false;
    }
  }

  if (m_sheet)
    clearSheet(element);

  m_sheet = newSheet;
  if (m_sheet)
    m_sheet->contents()->checkLoaded();

  return passesContentSecurityPolicyChecks ? ProcessingSuccessful
                                           : ProcessingFatalError;
}
Example #13
0
void InlineStyleSheetOwner::createSheet(Element& element, const String& text)
{
    ASSERT(element.inDocument());
    Document& document = element.document();
    if (m_sheet) {
        if (m_sheet->isLoading())
            document.authorStyleSheets().removePendingSheet();
        clearSheet();
    }

    if (!isValidCSSContentType(element, m_contentType))
        return;

    ASSERT(document.contentSecurityPolicy());
    const ContentSecurityPolicy& contentSecurityPolicy = *document.contentSecurityPolicy();
    bool hasKnownNonce = contentSecurityPolicy.allowStyleWithNonce(element.fastGetAttribute(HTMLNames::nonceAttr), element.isInUserAgentShadowTree());
    if (!contentSecurityPolicy.allowInlineStyle(document.url(), m_startTextPosition.m_line, text, hasKnownNonce))
        return;

    RefPtr<MediaQuerySet> mediaQueries;
    if (element.isHTMLElement())
        mediaQueries = MediaQuerySet::createAllowingDescriptionSyntax(m_media);
    else
        mediaQueries = MediaQuerySet::create(m_media);

    MediaQueryEvaluator screenEval(ASCIILiteral("screen"), true);
    MediaQueryEvaluator printEval(ASCIILiteral("print"), true);
    if (!screenEval.evaluate(*mediaQueries) && !printEval.evaluate(*mediaQueries))
        return;

    authorStyleSheetsForElement(element).addPendingSheet();

    m_loading = true;

    m_sheet = CSSStyleSheet::createInline(element, URL(), m_startTextPosition, document.encoding());
    m_sheet->setMediaQueries(mediaQueries.releaseNonNull());
    m_sheet->setTitle(element.title());
    m_sheet->contents().parseStringAtPosition(text, m_startTextPosition, m_isParsingChildren);

    m_loading = false;

    if (m_sheet)
        m_sheet->contents().checkLoaded();
}
void HTMLLinkElement::removedFromDocument()
{
    HTMLElement::removedFromDocument();

    if (m_isInShadowTree) {
        ASSERT(!m_sheet);
        return;
    }
    document()->removeStyleSheetCandidateNode(this);

    if (m_sheet)
        clearSheet();

    if (styleSheetIsLoading())
        removePendingSheet();

    if (document()->renderer())
        document()->styleSelectorChanged(DeferRecalcStyle);
}
Example #15
0
void InlineStyleSheetOwner::createSheet(Element* element, const String& text)
{
    ASSERT(element);
    ASSERT(element->inDocument());
    Document& document = element->document();
    if (m_sheet) {
        if (m_sheet->isLoading())
            document.styleSheetCollection()->removePendingSheet();
        clearSheet();
    }

    if (!isValidCSSContentType(element, m_contentType))
        return;
    if (!document.contentSecurityPolicy()->allowInlineStyle(document.url(), m_startLineNumber))
        return;

    RefPtr<MediaQuerySet> mediaQueries;
    if (element->isHTMLElement())
        mediaQueries = MediaQuerySet::createAllowingDescriptionSyntax(m_media);
    else
        mediaQueries = MediaQuerySet::create(m_media);

    MediaQueryEvaluator screenEval(ASCIILiteral("screen"), true);
    MediaQueryEvaluator printEval(ASCIILiteral("print"), true);
    if (!screenEval.eval(mediaQueries.get()) && !printEval.eval(mediaQueries.get()))
        return;

    document.styleSheetCollection()->addPendingSheet();

    m_loading = true;

    m_sheet = CSSStyleSheet::createInline(element, KURL(), document.inputEncoding());
    m_sheet->setMediaQueries(mediaQueries.release());
    m_sheet->setTitle(element->title());
    m_sheet->contents()->parseStringAtLine(text, m_startLineNumber.zeroBasedInt(), m_isParsingChildren);

    m_loading = false;

    if (m_sheet)
        m_sheet->contents()->checkLoaded();
}
Example #16
0
void StyleElement::removedFrom(Element& element,
                               ContainerNode* insertionPoint) {
  if (!insertionPoint->isConnected())
    return;

  Document& document = element.document();
  if (m_registeredAsCandidate) {
    document.styleEngine().removeStyleSheetCandidateNode(element,
                                                         *insertionPoint);
    m_registeredAsCandidate = false;
  }

  if (m_sheet) {
    clearSheet(element);
    if (element.isConnected()) {
      // TODO([email protected]): resolverChanged() can be removed once stylesheet
      // updates are async. https://crbug.com/567021
      document.styleEngine().resolverChanged(AnalyzedStyleUpdate);
    }
  }
}
Example #17
0
void StyleElement::createSheet(Element* e, int startLineNumber, const String& text)
{
    ASSERT(e);
    ASSERT(e->inDocument());
    Document* document = e->document();
    if (m_sheet) {
        if (m_sheet->isLoading())
            document->removePendingSheet();
        clearSheet();
    }

    // If type is empty or CSS, this is a CSS style sheet.
    const AtomicString& type = this->type();
    if (document->contentSecurityPolicy()->allowInlineStyle() && isCSS(e, type)) {
        RefPtr<MediaQuerySet> mediaQueries;
        if (e->isHTMLElement())
            mediaQueries = MediaQuerySet::createAllowingDescriptionSyntax(media());
        else
            mediaQueries = MediaQuerySet::create(media());

        MediaQueryEvaluator screenEval("screen", true);
        MediaQueryEvaluator printEval("print", true);
        if (screenEval.eval(mediaQueries.get()) || printEval.eval(mediaQueries.get())) {
            document->addPendingSheet();
            m_loading = true;

            m_sheet = CSSStyleSheet::createInline(e, KURL(), document->inputEncoding());
            m_sheet->setMediaQueries(mediaQueries.release());
            m_sheet->setTitle(e->title());
    
            m_sheet->internal()->parseStringAtLine(text, startLineNumber);

            m_loading = false;
        }
    }

    if (m_sheet)
        m_sheet->internal()->checkLoaded();
}
Example #18
0
void ProcessingInstruction::removedFrom(ContainerNode* insertionPoint) {
  CharacterData::removedFrom(insertionPoint);
  if (!insertionPoint->isConnected())
    return;

  // No need to remove XSLStyleSheet from StyleEngine.
  if (!DocumentXSLT::processingInstructionRemovedFromDocument(document(), this))
    document().styleEngine().removeStyleSheetCandidateNode(*this);

  StyleSheet* removedSheet = m_sheet;
  if (m_sheet) {
    DCHECK_EQ(m_sheet->ownerNode(), this);
    clearSheet();
  }

  // No need to remove pending sheets.
  clearResource();

  // If we're in document teardown, then we don't need to do any notification of
  // our sheet's removal.
  if (document().isActive())
    document().styleEngine().setNeedsActiveStyleUpdate(removedSheet,
                                                       FullStyleUpdate);
}
void StyleElement::createSheet(Element* e, const String& text)
{
    ASSERT(e);
    ASSERT(e->inDocument());
    Document& document = e->document();
    if (m_sheet) {
        if (m_sheet->isLoading())
            document.styleEngine()->removePendingSheet(e);
        clearSheet();
    }

    // If type is empty or CSS, this is a CSS style sheet.
    const AtomicString& type = this->type();
    bool passesContentSecurityPolicyChecks = document.contentSecurityPolicy()->allowStyleNonce(e->fastGetAttribute(HTMLNames::nonceAttr)) || document.contentSecurityPolicy()->allowInlineStyle(e->document().url(), m_startPosition.m_line);
    if (isCSS(e, type) && passesContentSecurityPolicyChecks) {
        RefPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(media());

        MediaQueryEvaluator screenEval("screen", true);
        MediaQueryEvaluator printEval("print", true);
        if (screenEval.eval(mediaQueries.get()) || printEval.eval(mediaQueries.get())) {
            document.styleEngine()->addPendingSheet();
            m_loading = true;

            TextPosition startPosition = m_startPosition == TextPosition::belowRangePosition() ? TextPosition::minimumPosition() : m_startPosition;
            m_sheet = CSSStyleSheet::createInline(e, KURL(), startPosition, document.inputEncoding());
            m_sheet->setMediaQueries(mediaQueries.release());
            m_sheet->setTitle(e->title());
            m_sheet->contents()->parseStringAtPosition(text, startPosition, m_createdByParser);

            m_loading = false;
        }
    }

    if (m_sheet)
        m_sheet->contents()->checkLoaded();
}
void HTMLLinkElement::process()
{
    if (!inDocument() || m_isInShadowTree) {
        ASSERT(!m_sheet);
        return;
    }

    String type = m_type.lower();

    if (!m_linkLoader.loadLink(m_relAttribute, type, m_sizes->toString(), m_url, document()))
        return;

    bool acceptIfTypeContainsTextCSS = document()->page() && document()->page()->settings() && document()->page()->settings()->treatsAnyTextCSSLinkAsStylesheet();

    if (m_disabledState != Disabled && (m_relAttribute.m_isStyleSheet || (acceptIfTypeContainsTextCSS && type.contains("text/css")))
        && document()->frame() && m_url.isValid()) {
        
        String charset = getAttribute(charsetAttr);
        if (charset.isEmpty() && document()->frame())
            charset = document()->charset();
        
        if (m_cachedSheet) {
            removePendingSheet();
            m_cachedSheet->removeClient(this);
            m_cachedSheet = 0;
        }

        if (!shouldLoadLink())
            return;

        m_loading = true;

        bool mediaQueryMatches = true;
        if (!m_media.isEmpty()) {
            RefPtr<RenderStyle> documentStyle = CSSStyleSelector::styleForDocument(document());
            RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(m_media);
            MediaQueryEvaluator evaluator(document()->frame()->view()->mediaType(), document()->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 && !isAlternate();
        addPendingSheet(blocking ? Blocking : NonBlocking);

        // Load stylesheets that are not needed for the rendering immediately with low priority.
        ResourceLoadPriority priority = blocking ? ResourceLoadPriorityUnresolved : ResourceLoadPriorityVeryLow;
        ResourceRequest request(document()->completeURL(m_url));
        m_cachedSheet = document()->cachedResourceLoader()->requestCSSStyleSheet(request, charset, priority);
        
        if (m_cachedSheet)
            m_cachedSheet->addClient(this);
        else {
            // 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
        clearSheet();
        document()->styleSelectorChanged(DeferRecalcStyle);
    }
}
StyleElement::~StyleElement()
{
    if (m_sheet)
        clearSheet();
}