#include "config.h"
#include "core/html/HTMLLinkElement.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
-#include "bindings/v8/ScriptEventListener.h"
+#include "bindings/core/v8/ScriptEventListener.h"
+#include "bindings/core/v8/V8DOMActivityLogger.h"
+#include "core/HTMLNames.h"
#include "core/css/MediaList.h"
#include "core/css/MediaQueryEvaluator.h"
#include "core/css/StyleSheetContents.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
+#include "core/dom/StyleEngine.h"
#include "core/events/Event.h"
#include "core/events/EventSender.h"
-#include "core/dom/StyleEngine.h"
#include "core/fetch/CSSStyleSheetResource.h"
#include "core/fetch/FetchRequest.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/frame/FrameView.h"
#include "core/frame/LocalFrame.h"
+#include "core/frame/SubresourceIntegrity.h"
#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/LinkManifest.h"
#include "core/html/imports/LinkImport.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
+#include "core/rendering/style/StyleInheritedData.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "wtf/StdLibExtras.h"
-namespace WebCore {
+namespace blink {
using namespace HTMLNames;
, m_createdByParser(createdByParser)
, m_isInShadowTree(false)
{
- ScriptWrappable::init(this);
}
PassRefPtrWillBeRawPtr<HTMLLinkElement> HTMLLinkElement::create(Document& document, bool createdByParser)
{
- return adoptRefWillBeRefCountedGarbageCollected(new HTMLLinkElement(document, createdByParser));
+ return adoptRefWillBeNoop(new HTMLLinkElement(document, createdByParser));
}
HTMLLinkElement::~HTMLLinkElement()
parseSizesAttribute(value, m_iconSizes);
process();
} else if (name == mediaAttr) {
- m_media = value.string().lower();
+ m_media = value.lower();
process();
} else if (name == disabledAttr) {
if (LinkStyle* link = linkStyle())
bool visible = inDocument() && !m_isInShadowTree;
if (!visible) {
ASSERT(!linkStyle() || !linkStyle()->hasSheet());
- return 0;
+ return nullptr;
}
if (!m_link) {
- if (m_relAttribute.isImport() && RuntimeEnabledFeatures::htmlImportsEnabled()) {
+ if (m_relAttribute.isImport()) {
m_link = LinkImport::create(this);
- } else if (m_relAttribute.isManifest() && RuntimeEnabledFeatures::manifestEnabled()) {
+ } else if (m_relAttribute.isManifest()) {
m_link = LinkManifest::create(this);
} else {
OwnPtrWillBeRawPtr<LinkStyle> link = LinkStyle::create(this);
- if (fastHasAttribute(disabledAttr))
+ if (fastHasAttribute(disabledAttr) || m_relAttribute.isTransitionExitingStylesheet())
link->setDisabledState(true);
m_link = link.release();
}
LinkStyle* HTMLLinkElement::linkStyle() const
{
if (!m_link || m_link->type() != LinkResource::Style)
- return 0;
+ return nullptr;
return static_cast<LinkStyle*>(m_link.get());
}
LinkImport* HTMLLinkElement::linkImport() const
{
if (!m_link || m_link->type() != LinkResource::Import)
- return 0;
+ return nullptr;
return static_cast<LinkImport*>(m_link.get());
}
{
if (LinkImport* link = linkImport())
return link->importedDocument();
- return 0;
+ return nullptr;
}
void HTMLLinkElement::process()
link->process();
}
+void HTMLLinkElement::enableIfExitTransitionStyle()
+{
+ if (m_relAttribute.isTransitionExitingStylesheet()) {
+ if (LinkStyle* link = linkStyle())
+ link->setDisabledState(false);
+ }
+}
+
Node::InsertionNotificationRequest HTMLLinkElement::insertedInto(ContainerNode* insertionPoint)
{
+ if (insertionPoint->inDocument()) {
+ V8DOMActivityLogger* activityLogger = V8DOMActivityLogger::currentActivityLoggerIfIsolatedWorld();
+ if (activityLogger) {
+ Vector<String> argv;
+ argv.append("link");
+ argv.append(fastGetAttribute(relAttr));
+ argv.append(fastGetAttribute(hrefAttr));
+ activityLogger->logEvent("blinkAddElement", argv.size(), argv.data());
+ }
+ }
HTMLElement::insertedInto(insertionPoint);
if (!insertionPoint->inDocument())
return InsertionDone;
m_isInShadowTree = isInShadowTree();
- if (m_isInShadowTree)
+ if (m_isInShadowTree) {
+ String message = "HTML element <link> is ignored in shadow tree.";
+ document().addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message));
return InsertionDone;
+ }
document().styleEngine()->addStyleSheetCandidateNode(this, m_createdByParser);
process();
+
+ if (m_link)
+ m_link->ownerInserted();
+
return InsertionDone;
}
HTMLElement::trace(visitor);
}
+void HTMLLinkElement::attributeWillChange(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
+{
+ if (name == hrefAttr && inDocument()) {
+ V8DOMActivityLogger* activityLogger = V8DOMActivityLogger::currentActivityLoggerIfIsolatedWorld();
+ if (activityLogger) {
+ Vector<String> argv;
+ argv.append("link");
+ argv.append(hrefAttr.toString());
+ argv.append(oldValue);
+ argv.append(newValue);
+ activityLogger->logEvent("blinkSetAttribute", argv.size(), argv.data());
+ }
+ }
+ HTMLElement::attributeWillChange(name, oldValue, newValue);
+}
+
PassOwnPtrWillBeRawPtr<LinkStyle> LinkStyle::create(HTMLLinkElement* owner)
{
return adoptPtrWillBeNoop(new LinkStyle(owner));
if (!m_owner->inDocument()) {
ASSERT(!m_sheet);
return;
+ }
+ if (!SubresourceIntegrity::CheckSubresourceIntegrity(*m_owner, cachedStyleSheet->sheetText(), KURL(KURL(), href))) {
+ m_loading = false;
+ removePendingSheet();
+ return;
}
+
// Completing the sheet load may cause scripts to execute.
- RefPtrWillBeRawPtr<Node> protector(m_owner);
+ RefPtrWillBeRawPtr<Node> protector(m_owner.get());
CSSParserContext parserContext(m_owner->document(), 0, baseURL, charset);
if (m_sheet)
clearSheet();
+
m_sheet = CSSStyleSheet::create(styleSheet, m_owner);
m_sheet->setMediaQueries(MediaQuerySet::create(m_owner->media()));
m_sheet->setTitle(m_owner->title());
m_owner->document().styleEngine()->addPendingSheet();
}
-void LinkStyle::removePendingSheet(RemovePendingSheetNotificationType notification)
+void LinkStyle::removePendingSheet()
{
PendingSheetType type = m_pendingSheetType;
m_pendingSheetType = None;
// Document::removePendingSheet() triggers the style selector recalc for blocking sheets.
// FIXME: We don't have enough knowledge at this point to know if we're adding or removing a sheet
// so we can't call addedStyleSheet() or removedStyleSheet().
- m_owner->document().styleResolverChanged(RecalcStyleDeferred);
+ m_owner->document().styleResolverChanged();
return;
}
- m_owner->document().styleEngine()->removePendingSheet(m_owner,
- notification == RemovePendingSheetNotifyImmediately
- ? StyleEngine::RemovePendingSheetNotifyImmediately
- : StyleEngine::RemovePendingSheetNotifyLater);
+ m_owner->document().styleEngine()->removePendingSheet(m_owner);
}
void LinkStyle::setDisabledState(bool disabled)
process();
} else {
// FIXME: We don't have enough knowledge here to know if we should call addedStyleSheet() or removedStyleSheet().
- m_owner->document().styleResolverChanged(RecalcStyleDeferred);
+ m_owner->document().styleResolverChanged();
}
}
}
if (!m_owner->loadLink(type, builder.url()))
return;
- if ((m_disabledState != Disabled) && m_owner->relAttribute().isStyleSheet()
+ if ((m_disabledState != Disabled) && (m_owner->relAttribute().isStyleSheet() || m_owner->relAttribute().isTransitionExitingStylesheet())
&& shouldLoadResource() && builder.url().isValid()) {
if (resource()) {
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);
- mediaQueryMatches = evaluator.eval(media.get());
- }
+ LocalFrame* frame = loadingFrame();
+ if (!m_owner->media().isEmpty() && frame && frame->document()) {
+ RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(*frame->document());
+ RefPtrWillBeRawPtr<MediaQuerySet> media = MediaQuerySet::create(m_owner->media());
+ MediaQueryEvaluator evaluator(frame);
+ mediaQueryMatches = evaluator.eval(media.get());
}
// Don't hold up render tree construction and script execution on stylesheets
clearSheet();
if (styleSheetIsLoading())
- removePendingSheet(RemovePendingSheetNotifyLater);
+ removePendingSheet();
}
void LinkStyle::trace(Visitor* visitor)
LinkResource::trace(visitor);
}
-} // namespace WebCore
+} // namespace blink