Bug 1441246 - Move preload cod from nsStyleLinkElement to HTMLLinkElement. r=smaug
authorDragana Damjanovic <dd.mozilla@gmail.com>
Fri, 20 Apr 2018 12:47:00 +0300
changeset 415308 ccbbd0a711734c30808a2e934b5788d0907d405b
parent 415307 de7eb5f97eced4c71a8dc6a9077db34b82e7f7c3
child 415309 badbb1751a16a03e4bd89d0af7159508addae9eb
push id102542
push userebalazs@mozilla.com
push dateTue, 24 Apr 2018 15:15:54 +0000
treeherdermozilla-inbound@62388dd742c7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1441246
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1441246 - Move preload cod from nsStyleLinkElement to HTMLLinkElement. r=smaug
dom/base/Link.cpp
dom/base/nsContentSink.cpp
dom/base/nsStyleLinkElement.cpp
dom/base/nsStyleLinkElement.h
dom/html/HTMLLinkElement.cpp
dom/html/HTMLLinkElement.h
--- a/dom/base/Link.cpp
+++ b/dom/base/Link.cpp
@@ -25,16 +25,17 @@
 #include "nsEscape.h"
 #include "nsGkAtoms.h"
 #include "nsHTMLDNSPrefetch.h"
 #include "nsString.h"
 #include "mozAutoDocUpdate.h"
 
 #include "mozilla/Services.h"
 #include "nsAttrValueInlines.h"
+#include "HTMLLinkElement.h"
 
 namespace mozilla {
 namespace dom {
 
 #ifndef ANDROID
 using places::History;
 #endif
 
@@ -157,18 +158,18 @@ Link::TryDNSPrefetchOrPreconnectOrPrefet
           nsAutoString media;
           GetContentPolicyMimeTypeMedia(asAttr, policyType, mimeType, media);
 
           if (policyType == nsIContentPolicy::TYPE_INVALID) {
             // Ignore preload with a wrong or empty as attribute.
             return;
           }
 
-          if (!nsStyleLinkElement::CheckPreloadAttrs(asAttr, mimeType, media,
-                                                     mElement->OwnerDoc())) {
+          if (!HTMLLinkElement::CheckPreloadAttrs(asAttr, mimeType, media,
+                                                  mElement->OwnerDoc())) {
             policyType = nsIContentPolicy::TYPE_INVALID;
           }
 
           prefetchService->PreloadURI(uri,
                                       mElement->OwnerDoc()->GetDocumentURI(),
                                       domNode, policyType);
         } else {
           prefetchService->PrefetchURI(uri,
@@ -242,18 +243,18 @@ Link::UpdatePreload(nsAtom* aName, const
   if (asPolicyType == nsIContentPolicy::TYPE_INVALID) {
     // Ignore preload with a wrong or empty as attribute, but be sure to cancel
     // the old one.
     prefetchService->CancelPrefetchPreloadURI(uri, domNode);
     return;
   }
 
   nsContentPolicyType policyType = asPolicyType;
-  if (!nsStyleLinkElement::CheckPreloadAttrs(asAttr, mimeType, media,
-                                             mElement->OwnerDoc())) {
+  if (!HTMLLinkElement::CheckPreloadAttrs(asAttr, mimeType, media,
+                                          mElement->OwnerDoc())) {
     policyType = nsIContentPolicy::TYPE_INVALID;
   }
 
   if (aName == nsGkAtoms::crossorigin) {
     CORSMode corsMode = Element::AttrValueToCORSMode(aValue);
     CORSMode oldCorsMode = Element::AttrValueToCORSMode(aOldValue);
     if (corsMode != oldCorsMode) {
       prefetchService->CancelPrefetchPreloadURI(uri, domNode);
@@ -263,49 +264,49 @@ Link::UpdatePreload(nsAtom* aName, const
     return;
   }
 
   nsContentPolicyType oldPolicyType;
 
   if (aName == nsGkAtoms::as) {
     if (aOldValue) {
       oldPolicyType = AsValueToContentPolicy(*aOldValue);
-      if (!nsStyleLinkElement::CheckPreloadAttrs(*aOldValue, mimeType, media,
-                                                 mElement->OwnerDoc())) {
+      if (!HTMLLinkElement::CheckPreloadAttrs(*aOldValue, mimeType, media,
+                                              mElement->OwnerDoc())) {
         oldPolicyType = nsIContentPolicy::TYPE_INVALID;
       }
     } else {
       oldPolicyType = nsIContentPolicy::TYPE_INVALID;
     }    
   } else if (aName == nsGkAtoms::type) {
     nsAutoString oldType;
     nsAutoString notUsed;
     if (aOldValue) {
       aOldValue->ToString(oldType);
     } else {
       oldType = EmptyString();
     }
     nsAutoString oldMimeType;
     nsContentUtils::SplitMimeType(oldType, oldMimeType, notUsed);
-    if (nsStyleLinkElement::CheckPreloadAttrs(asAttr, oldMimeType, media,
-                                              mElement->OwnerDoc())) {
+    if (HTMLLinkElement::CheckPreloadAttrs(asAttr, oldMimeType, media,
+                                           mElement->OwnerDoc())) {
       oldPolicyType = asPolicyType;
     } else {
       oldPolicyType = nsIContentPolicy::TYPE_INVALID;
     }
   } else {
     MOZ_ASSERT(aName == nsGkAtoms::media);
     nsAutoString oldMedia;
     if (aOldValue) {
       aOldValue->ToString(oldMedia);
     } else {
       oldMedia = EmptyString();
     }
-    if (nsStyleLinkElement::CheckPreloadAttrs(asAttr, mimeType, oldMedia,
-                                              mElement->OwnerDoc())) {
+    if (HTMLLinkElement::CheckPreloadAttrs(asAttr, mimeType, oldMedia,
+                                           mElement->OwnerDoc())) {
       oldPolicyType = asPolicyType;
     } else {
       oldPolicyType = nsIContentPolicy::TYPE_INVALID;
     }
   }
 
   if ((policyType != oldPolicyType) &&
       (oldPolicyType != nsIContentPolicy::TYPE_INVALID)) {
--- a/dom/base/nsContentSink.cpp
+++ b/dom/base/nsContentSink.cpp
@@ -48,16 +48,17 @@
 #include "nsHTMLDNSPrefetch.h"
 #include "nsIObserverService.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/ServiceWorkerDescriptor.h"
 #include "mozilla/dom/ScriptLoader.h"
 #include "nsParserConstants.h"
 #include "nsSandboxFlags.h"
 #include "Link.h"
+#include "HTMLLinkElement.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 LazyLogModule gContentSinkLogModuleInfo("nscontentsink");
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsContentSink)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsContentSink)
@@ -881,18 +882,18 @@ nsContentSink::PrefetchPreloadHref(const
         if (policyType == nsIContentPolicy::TYPE_INVALID) {
           // Ignore preload with a wrong or empty as attribute.
           return;
         }
 
         nsAutoString mimeType;
         nsAutoString notUsed;
         nsContentUtils::SplitMimeType(aType, mimeType, notUsed);
-        if (!nsStyleLinkElement::CheckPreloadAttrs(asAttr, mimeType,
-                                                   aMedia,mDocument)) {
+        if (!HTMLLinkElement::CheckPreloadAttrs(asAttr, mimeType,
+                                                aMedia,mDocument)) {
           policyType = nsIContentPolicy::TYPE_INVALID;
         }
 
         prefetchService->PreloadURI(uri, mDocumentURI, domNode, policyType);
       } else {
         prefetchService->PrefetchURI(uri, mDocumentURI, domNode,
                                      aLinkTypes & nsStyleLinkElement::ePREFETCH);
       }
--- a/dom/base/nsStyleLinkElement.cpp
+++ b/dom/base/nsStyleLinkElement.cpp
@@ -26,24 +26,16 @@
 #include "nsIDOMNode.h"
 #include "nsUnicharUtils.h"
 #include "nsCRT.h"
 #include "nsXPCOMCIDInternal.h"
 #include "nsUnicharInputStream.h"
 #include "nsContentUtils.h"
 #include "nsStyleUtil.h"
 #include "nsQueryObject.h"
-#include "nsIContentPolicy.h"
-#include "nsMimeTypes.h"
-#include "imgLoader.h"
-#include "MediaContainerType.h"
-#include "DecoderDoctorDiagnostics.h"
-#include "DecoderTraits.h"
-#include "MediaList.h"
-#include "nsAttrValueInlines.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 nsStyleLinkElement::nsStyleLinkElement()
   : mDontLoadStyle(false)
   , mUpdatesEnabled(true)
   , mLineNumber(1)
@@ -179,130 +171,16 @@ uint32_t nsStyleLinkElement::ParseLinkTy
   }
   if (inString) {
     nsContentUtils::ASCIIToLower(Substring(start, current), subString);
     linkMask |= ToLinkMask(subString);
   }
   return linkMask;
 }
 
-// We will use official mime-types from:
-// https://www.iana.org/assignments/media-types/media-types.xhtml#font
-// We do not support old deprecated mime-types for preload feature.
-// (We currectly do not support font/collection)
-static uint32_t StyleLinkElementFontMimeTypesNum = 5;
-static const char* StyleLinkElementFontMimeTypes[] = {
-  "font/otf",
-  "font/sfnt",
-  "font/ttf",
-  "font/woff",
-  "font/woff2"
-};
-
-bool
-IsFontMimeType(const nsAString& aType)
-{
-  if (aType.IsEmpty()) {
-    return true;
-  }
-  for (uint32_t i = 0; i < StyleLinkElementFontMimeTypesNum; i++) {
-    if (aType.EqualsASCII(StyleLinkElementFontMimeTypes[i])) {
-      return true;
-    }
-  }
-  return false;
-}
-
-bool
-nsStyleLinkElement::CheckPreloadAttrs(const nsAttrValue& aAs,
-                                      const nsAString& aType,
-                                      const nsAString& aMedia,
-                                      nsIDocument* aDocument)
-{
-  nsContentPolicyType policyType = Link::AsValueToContentPolicy(aAs);
-  if (policyType == nsIContentPolicy::TYPE_INVALID) {
-    return false;
-  }
-
-  // Check if media attribute is valid.
-  if (!aMedia.IsEmpty()) {
-    RefPtr<MediaList> mediaList = MediaList::Create(aMedia);
-    nsPresContext* presContext = aDocument->GetPresContext();
-    if (!presContext) {
-      return false;
-    }
-    if (!mediaList->Matches(presContext)) {
-      return false;
-    }
-  }
-
-  if (aType.IsEmpty()) {
-    return true;
-  }
-
-  nsString type = nsString(aType);
-  ToLowerCase(type);
-
-  if (policyType == nsIContentPolicy::TYPE_OTHER) {
-    return true;
-
-  } else if (policyType == nsIContentPolicy::TYPE_MEDIA) {
-    if (aAs.GetEnumValue() == DESTINATION_TRACK) {
-      if (type.EqualsASCII("text/vtt")) {
-        return true;
-      } else {
-        return false;
-      }
-    }
-    Maybe<MediaContainerType> mimeType = MakeMediaContainerType(aType);
-    if (!mimeType) {
-      return false;
-    }
-    DecoderDoctorDiagnostics diagnostics;
-    CanPlayStatus status = DecoderTraits::CanHandleContainerType(*mimeType,
-                                                                 &diagnostics);
-    // Preload if this return CANPLAY_YES and CANPLAY_MAYBE.
-    if (status == CANPLAY_NO) {
-      return false;
-    } else {
-      return true;
-    }
-
-  } else if (policyType == nsIContentPolicy::TYPE_FONT) {
-    if (IsFontMimeType(type)) {
-      return true;
-    } else {
-      return false;
-    }
-
-  } else if (policyType == nsIContentPolicy::TYPE_IMAGE) {
-    if (imgLoader::SupportImageWithMimeType(NS_ConvertUTF16toUTF8(type).get(),
-                                            AcceptedMimeTypes::IMAGES_AND_DOCUMENTS)) {
-      return true;
-    } else {
-      return false;
-    }
-
-  } else if (policyType == nsIContentPolicy::TYPE_SCRIPT) {
-    if (nsContentUtils::IsJavascriptMIMEType(type)) {
-      return true;
-    } else {
-      return false;
-    }
-
-  } else if (policyType == nsIContentPolicy::TYPE_STYLESHEET) {
-    if (type.EqualsASCII("text/css")) {
-      return true;
-    } else {
-      return false;
-    }
-  }
-  return false;
-}
-
 nsresult
 nsStyleLinkElement::UpdateStyleSheet(nsICSSLoaderObserver* aObserver,
                                      bool* aWillNotify,
                                      bool* aIsAlternate,
                                      bool aForceReload)
 {
   if (aForceReload) {
     // We remove this stylesheet from the cache to load a new version.
--- a/dom/base/nsStyleLinkElement.h
+++ b/dom/base/nsStyleLinkElement.h
@@ -15,17 +15,16 @@
 
 #include "mozilla/Attributes.h"
 #include "mozilla/CORSMode.h"
 #include "mozilla/StyleSheetInlines.h"
 #include "mozilla/net/ReferrerPolicy.h"
 #include "nsCOMPtr.h"
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsTArray.h"
-#include "nsAttrValue.h"
 
 class nsIDocument;
 class nsIURI;
 
 namespace mozilla {
 class CSSStyleSheet;
 namespace dom {
 class ShadowRoot;
@@ -66,19 +65,16 @@ public:
     ePRECONNECT =   0x00000020,
     // NOTE: 0x40 is unused
     ePRELOAD =      0x00000080
   };
 
   // The return value is a bitwise or of 0 or more RelValues.
   static uint32_t ParseLinkTypes(const nsAString& aTypes);
 
-  static bool CheckPreloadAttrs(const nsAttrValue& aAs, const nsAString& aType,
-                                const nsAString& aMedia, nsIDocument* aDocument);
-
   void UpdateStyleSheetInternal()
   {
     UpdateStyleSheetInternal(nullptr, nullptr);
   }
 protected:
   /**
    * @param aOldDocument should be non-null only if we're updating because we
    *                     removed the node from the document.
--- a/dom/html/HTMLLinkElement.cpp
+++ b/dom/html/HTMLLinkElement.cpp
@@ -23,16 +23,24 @@
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsIURL.h"
 #include "nsPIDOMWindow.h"
 #include "nsReadableUtils.h"
 #include "nsStyleConsts.h"
 #include "nsStyleLinkElement.h"
 #include "nsUnicharUtils.h"
 #include "nsWindowSizes.h"
+#include "nsIContentPolicy.h"
+#include "nsMimeTypes.h"
+#include "imgLoader.h"
+#include "MediaContainerType.h"
+#include "DecoderDoctorDiagnostics.h"
+#include "DecoderTraits.h"
+#include "MediaList.h"
+#include "nsAttrValueInlines.h"
 
 #define LINK_ELEMENT_FLAG_BIT(n_) \
   NODE_FLAG_BIT(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET + (n_))
 
 // Link element specific bits
 enum {
   // Indicates that a DNS Prefetch has been requested from this Link element.
   HTML_LINK_DNS_PREFETCH_REQUESTED = LINK_ELEMENT_FLAG_BIT(0),
@@ -507,10 +515,124 @@ HTMLLinkElement::WrapNode(JSContext* aCx
 }
 
 void
 HTMLLinkElement::GetAs(nsAString& aResult)
 {
   GetEnumAttr(nsGkAtoms::as, EmptyCString().get(), aResult);
 }
 
+// We will use official mime-types from:
+// https://www.iana.org/assignments/media-types/media-types.xhtml#font
+// We do not support old deprecated mime-types for preload feature.
+// (We currectly do not support font/collection)
+static uint32_t StyleLinkElementFontMimeTypesNum = 5;
+static const char* StyleLinkElementFontMimeTypes[] = {
+  "font/otf",
+  "font/sfnt",
+  "font/ttf",
+  "font/woff",
+  "font/woff2"
+};
+
+bool
+IsFontMimeType(const nsAString& aType)
+{
+  if (aType.IsEmpty()) {
+    return true;
+  }
+  for (uint32_t i = 0; i < StyleLinkElementFontMimeTypesNum; i++) {
+    if (aType.EqualsASCII(StyleLinkElementFontMimeTypes[i])) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool
+HTMLLinkElement::CheckPreloadAttrs(const nsAttrValue& aAs,
+                                   const nsAString& aType,
+                                   const nsAString& aMedia,
+                                   nsIDocument* aDocument)
+{
+  nsContentPolicyType policyType = Link::AsValueToContentPolicy(aAs);
+  if (policyType == nsIContentPolicy::TYPE_INVALID) {
+    return false;
+  }
+
+  // Check if media attribute is valid.
+  if (!aMedia.IsEmpty()) {
+    RefPtr<MediaList> mediaList = MediaList::Create(aMedia);
+    nsPresContext* presContext = aDocument->GetPresContext();
+    if (!presContext) {
+      return false;
+    }
+    if (!mediaList->Matches(presContext)) {
+      return false;
+    }
+  }
+
+  if (aType.IsEmpty()) {
+    return true;
+  }
+
+  nsString type = nsString(aType);
+  ToLowerCase(type);
+
+  if (policyType == nsIContentPolicy::TYPE_OTHER) {
+    return true;
+
+  } else if (policyType == nsIContentPolicy::TYPE_MEDIA) {
+    if (aAs.GetEnumValue() == DESTINATION_TRACK) {
+      if (type.EqualsASCII("text/vtt")) {
+        return true;
+      } else {
+        return false;
+      }
+    }
+    Maybe<MediaContainerType> mimeType = MakeMediaContainerType(aType);
+    if (!mimeType) {
+      return false;
+    }
+    DecoderDoctorDiagnostics diagnostics;
+    CanPlayStatus status = DecoderTraits::CanHandleContainerType(*mimeType,
+                                                                 &diagnostics);
+    // Preload if this return CANPLAY_YES and CANPLAY_MAYBE.
+    if (status == CANPLAY_NO) {
+      return false;
+    } else {
+      return true;
+    }
+
+  } else if (policyType == nsIContentPolicy::TYPE_FONT) {
+    if (IsFontMimeType(type)) {
+      return true;
+    } else {
+      return false;
+    }
+
+  } else if (policyType == nsIContentPolicy::TYPE_IMAGE) {
+    if (imgLoader::SupportImageWithMimeType(NS_ConvertUTF16toUTF8(type).get(),
+                                            AcceptedMimeTypes::IMAGES_AND_DOCUMENTS)) {
+      return true;
+    } else {
+      return false;
+    }
+
+  } else if (policyType == nsIContentPolicy::TYPE_SCRIPT) {
+    if (nsContentUtils::IsJavascriptMIMEType(type)) {
+      return true;
+    } else {
+      return false;
+    }
+
+  } else if (policyType == nsIContentPolicy::TYPE_STYLESHEET) {
+    if (type.EqualsASCII("text/css")) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+  return false;
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLLinkElement.h
+++ b/dom/html/HTMLLinkElement.h
@@ -197,16 +197,18 @@ public:
   virtual CORSMode GetCORSMode() const override;
 
   void NodeInfoChanged(nsIDocument* aOldDoc) final
   {
     ClearHasPendingLinkUpdate();
     nsGenericHTMLElement::NodeInfoChanged(aOldDoc);
   }
 
+  static bool CheckPreloadAttrs(const nsAttrValue& aAs, const nsAString& aType,
+                                const nsAString& aMedia, nsIDocument* aDocument);
 protected:
   virtual ~HTMLLinkElement();
 
   // nsStyleLinkElement
   already_AddRefed<nsIURI>
     GetStyleSheetURL(bool* aIsInline, nsIPrincipal** aTriggeringPrincipal) final;
 
   void GetStyleSheetInfo(nsAString& aTitle,