# HG changeset patch
# User Dragana Damjanovic
# Date 1524217620 -10800
# Node ID ccbbd0a711734c30808a2e934b5788d0907d405b
# Parent 06a30ad6e5a71c5ba28197cc381850e811ad9bd2
Bug 1441246 - Move preload code from nsStyleLinkElement to HTMLLinkElement. r=smaug
diff --git a/dom/base/Link.cpp b/dom/base/Link.cpp
--- a/dom/base/Link.cpp
+++ b/dom/base/Link.cpp
@@ -24,16 +24,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
@@ -156,18 +157,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,
@@ -241,18 +242,18 @@ Link::UpdatePreload(nsIAtom* aName, cons
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);
@@ -262,49 +263,49 @@ Link::UpdatePreload(nsIAtom* aName, cons
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)) {
diff --git a/dom/base/nsContentSink.cpp b/dom/base/nsContentSink.cpp
--- 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);
}
diff --git a/dom/base/nsStyleLinkElement.cpp b/dom/base/nsStyleLinkElement.cpp
--- a/dom/base/nsStyleLinkElement.cpp
+++ b/dom/base/nsStyleLinkElement.cpp
@@ -28,24 +28,16 @@
#include "nsIDOMStyleSheet.h"
#include "nsUnicharUtils.h"
#include "nsCRT.h"
#include "nsXPCOMCIDInternal.h"
#include "nsUnicharInputStream.h"
#include "nsContentUtils.h"
#include "nsStyleUtil.h"
#include "nsQueryObject.h"
-#include "nsIContentPolicyBase.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)
@@ -182,136 +174,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::Create(aDocument->GetStyleBackendType(),
- aMedia);
- nsIPresShell* shell = aDocument->GetShell();
- if (!shell) {
- return false;
- }
-
- nsPresContext* presContext = shell->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 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;
-}
-
Result
nsStyleLinkElement::UpdateStyleSheet(nsICSSLoaderObserver* aObserver,
ForceUpdate aForceUpdate)
{
if (aForceUpdate == ForceUpdate::Yes) {
// We remove this stylesheet from the cache to load a new version.
nsCOMPtr thisContent = do_QueryInterface(this);
nsCOMPtr doc = thisContent->IsInShadowTree() ?
diff --git a/dom/base/nsStyleLinkElement.h b/dom/base/nsStyleLinkElement.h
--- a/dom/base/nsStyleLinkElement.h
+++ b/dom/base/nsStyleLinkElement.h
@@ -17,16 +17,17 @@
#include "mozilla/CORSMode.h"
#include "mozilla/StyleSheetInlines.h"
#include "mozilla/Unused.h"
#include "mozilla/net/ReferrerPolicy.h"
#include "nsCOMPtr.h"
#include "nsIStyleSheetLinkingElement.h"
#include "nsTArray.h"
#include "nsAttrValue.h"
+#include "nsAttrValue.h"
class nsIDocument;
class nsIURI;
namespace mozilla {
class CSSStyleSheet;
namespace dom {
class ShadowRoot;
@@ -67,19 +68,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()
{
mozilla::Unused << UpdateStyleSheetInternal(nullptr, nullptr);
}
protected:
/**
* @param aOldDocument should be non-null only if we're updating because we
* removed the node from the document.
diff --git a/dom/html/HTMLLinkElement.cpp b/dom/html/HTMLLinkElement.cpp
--- a/dom/html/HTMLLinkElement.cpp
+++ b/dom/html/HTMLLinkElement.cpp
@@ -24,16 +24,24 @@
#include "nsINode.h"
#include "nsIStyleSheetLinkingElement.h"
#include "nsIURL.h"
#include "nsPIDOMWindow.h"
#include "nsReadableUtils.h"
#include "nsStyleConsts.h"
#include "nsStyleLinkElement.h"
#include "nsUnicharUtils.h"
+#include "nsIContentPolicyBase.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),
@@ -510,10 +518,131 @@ 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::Create(aDocument->GetStyleBackendType(),
+ aMedia);
+ nsIPresShell* shell = aDocument->GetShell();
+ if (!shell) {
+ return false;
+ }
+
+ nsPresContext* presContext = shell->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 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
diff --git a/dom/html/HTMLLinkElement.h b/dom/html/HTMLLinkElement.h
--- a/dom/html/HTMLLinkElement.h
+++ b/dom/html/HTMLLinkElement.h
@@ -200,16 +200,18 @@ public:
virtual CORSMode GetCORSMode() const override;
virtual void NodeInfoChanged(nsIDocument* aOldDoc) final override
{
ClearHasPendingLinkUpdate();
nsGenericHTMLElement::NodeInfoChanged(aOldDoc);
}
+ static bool CheckPreloadAttrs(const nsAttrValue& aAs, const nsAString& aType,
+ const nsAString& aMedia, nsIDocument* aDocument);
protected:
virtual ~HTMLLinkElement();
// nsStyleLinkElement
already_AddRefed
GetStyleSheetURL(bool* aIsInline, nsIPrincipal** aTriggeringPrincipal) final;
void GetStyleSheetInfo(nsAString& aTitle,