Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / html / HTMLLinkElement.cpp
index 3ee6600..6095285 100644 (file)
 #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;
 
@@ -138,12 +141,11 @@ inline HTMLLinkElement::HTMLLinkElement(Document& document, bool createdByParser
     , 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()
@@ -173,7 +175,7 @@ void HTMLLinkElement::parseAttribute(const QualifiedName& name, const AtomicStri
         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())
@@ -203,17 +205,17 @@ LinkResource* HTMLLinkElement::linkResourceToProcess()
     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();
         }
@@ -225,14 +227,14 @@ LinkResource* HTMLLinkElement::linkResourceToProcess()
 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());
 }
 
@@ -240,7 +242,7 @@ Document* HTMLLinkElement::import() const
 {
     if (LinkImport* link = linkImport())
         return link->importedDocument();
-    return 0;
+    return nullptr;
 }
 
 void HTMLLinkElement::process()
@@ -249,19 +251,44 @@ 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;
 }
 
@@ -429,6 +456,22 @@ void HTMLLinkElement::trace(Visitor* visitor)
     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));
@@ -462,10 +505,16 @@ void LinkStyle::setCSSStyleSheet(const String& href, const KURL& baseURL, const
     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);
 
@@ -488,6 +537,7 @@ void LinkStyle::setCSSStyleSheet(const String& href, const KURL& baseURL, const
 
     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());
@@ -555,7 +605,7 @@ void LinkStyle::addPendingSheet(PendingSheetType type)
     m_owner->document().styleEngine()->addPendingSheet();
 }
 
-void LinkStyle::removePendingSheet(RemovePendingSheetNotificationType notification)
+void LinkStyle::removePendingSheet()
 {
     PendingSheetType type = m_pendingSheetType;
     m_pendingSheetType = None;
@@ -568,14 +618,11 @@ void LinkStyle::removePendingSheet(RemovePendingSheetNotificationType notificati
         // 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)
@@ -615,7 +662,7 @@ 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();
         }
     }
 }
@@ -640,7 +687,7 @@ void LinkStyle::process()
     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()) {
@@ -654,14 +701,12 @@ void LinkStyle::process()
         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
@@ -701,7 +746,7 @@ void LinkStyle::ownerRemoved()
         clearSheet();
 
     if (styleSheetIsLoading())
-        removePendingSheet(RemovePendingSheetNotifyLater);
+        removePendingSheet();
 }
 
 void LinkStyle::trace(Visitor* visitor)
@@ -710,4 +755,4 @@ void LinkStyle::trace(Visitor* visitor)
     LinkResource::trace(visitor);
 }
 
-} // namespace WebCore
+} // namespace blink