mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-30 20:37:31 +09:00
Merge remote-tracking branch 'origin/tracking' into custom
This commit is contained in:
commit
0db181d2b7
21 changed files with 1554 additions and 998 deletions
|
|
@ -675,7 +675,6 @@ BrowserConsole.prototype = extend(WebConsole.prototype, {
|
||||||
// instance.
|
// instance.
|
||||||
let onClose = () => {
|
let onClose = () => {
|
||||||
window.removeEventListener("unload", onClose);
|
window.removeEventListener("unload", onClose);
|
||||||
window.removeEventListener("focus", onFocus);
|
|
||||||
this.destroy();
|
this.destroy();
|
||||||
};
|
};
|
||||||
window.addEventListener("unload", onClose);
|
window.addEventListener("unload", onClose);
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
#include "nsCPrefetchService.h"
|
#include "nsCPrefetchService.h"
|
||||||
#include "nsStyleLinkElement.h"
|
#include "nsStyleLinkElement.h"
|
||||||
|
|
||||||
|
#include "nsAttrValueInlines.h"
|
||||||
#include "nsEscape.h"
|
#include "nsEscape.h"
|
||||||
#include "nsGkAtoms.h"
|
#include "nsGkAtoms.h"
|
||||||
#include "nsHTMLDNSPrefetch.h"
|
#include "nsHTMLDNSPrefetch.h"
|
||||||
|
|
@ -23,9 +24,57 @@
|
||||||
|
|
||||||
#include "mozilla/Services.h"
|
#include "mozilla/Services.h"
|
||||||
|
|
||||||
|
#include "nsIContentPolicy.h"
|
||||||
|
#include "nsCSSParser.h"
|
||||||
|
#include "nsMimeTypes.h"
|
||||||
|
#include "nsIMediaList.h"
|
||||||
|
#include "DecoderTraits.h"
|
||||||
|
#include "imgLoader.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
enum Destination : uint8_t
|
||||||
|
{
|
||||||
|
DESTINATION_INVALID,
|
||||||
|
DESTINATION_AUDIO,
|
||||||
|
DESTINATION_AUDIOWORKLET,
|
||||||
|
DESTINATION_DOCUMENT,
|
||||||
|
DESTINATION_EMBED,
|
||||||
|
DESTINATION_FONT,
|
||||||
|
DESTINATION_FRAME,
|
||||||
|
DESTINATION_IFRAME,
|
||||||
|
DESTINATION_IMAGE,
|
||||||
|
DESTINATION_JSON,
|
||||||
|
DESTINATION_MANIFEST,
|
||||||
|
DESTINATION_OBJECT,
|
||||||
|
DESTINATION_REPORT,
|
||||||
|
DESTINATION_SCRIPT,
|
||||||
|
DESTINATION_SERVICEWORKER,
|
||||||
|
DESTINATION_SHAREDWORKER,
|
||||||
|
DESTINATION_STYLE,
|
||||||
|
DESTINATION_TRACK,
|
||||||
|
DESTINATION_VIDEO,
|
||||||
|
DESTINATION_WEBIDENTITY,
|
||||||
|
DESTINATION_WORKER,
|
||||||
|
DESTINATION_XSLT,
|
||||||
|
DESTINATION_FETCH
|
||||||
|
};
|
||||||
|
|
||||||
|
static const nsAttrValue::EnumTable kDestinationAttributeTable[] = {
|
||||||
|
{ "", DESTINATION_INVALID },
|
||||||
|
{ "audio", DESTINATION_AUDIO },
|
||||||
|
{ "font", DESTINATION_FONT },
|
||||||
|
{ "image", DESTINATION_IMAGE },
|
||||||
|
{ "script", DESTINATION_SCRIPT },
|
||||||
|
{ "style", DESTINATION_STYLE },
|
||||||
|
{ "track", DESTINATION_TRACK },
|
||||||
|
{ "video", DESTINATION_VIDEO },
|
||||||
|
{ "fetch", DESTINATION_FETCH },
|
||||||
|
{ "json", DESTINATION_JSON },
|
||||||
|
{ nullptr, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
Link::Link(Element *aElement)
|
Link::Link(Element *aElement)
|
||||||
: mElement(aElement)
|
: mElement(aElement)
|
||||||
, mHistory(services::GetHistoryService())
|
, mHistory(services::GetHistoryService())
|
||||||
|
|
@ -75,7 +124,7 @@ Link::CancelDNSPrefetch(nsWrapperCache::FlagsType aDeferredFlag,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Link::TryDNSPrefetchPreconnectOrPrefetch()
|
Link::TrySpeculativeLoadFeature()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mElement->IsInComposedDoc());
|
MOZ_ASSERT(mElement->IsInComposedDoc());
|
||||||
if (!ElementHasHref()) {
|
if (!ElementHasHref()) {
|
||||||
|
|
@ -95,15 +144,28 @@ Link::TryDNSPrefetchPreconnectOrPrefetch()
|
||||||
mElement->NodePrincipal());
|
mElement->NodePrincipal());
|
||||||
|
|
||||||
if ((linkTypes & nsStyleLinkElement::ePREFETCH) ||
|
if ((linkTypes & nsStyleLinkElement::ePREFETCH) ||
|
||||||
(linkTypes & nsStyleLinkElement::eNEXT)){
|
(linkTypes & nsStyleLinkElement::eNEXT) ||
|
||||||
|
(linkTypes & nsStyleLinkElement::ePRELOAD)) {
|
||||||
nsCOMPtr<nsIPrefetchService> prefetchService(do_GetService(NS_PREFETCHSERVICE_CONTRACTID));
|
nsCOMPtr<nsIPrefetchService> prefetchService(do_GetService(NS_PREFETCHSERVICE_CONTRACTID));
|
||||||
if (prefetchService) {
|
if (prefetchService) {
|
||||||
nsCOMPtr<nsIURI> uri(GetURI());
|
nsCOMPtr<nsIURI> uri(GetURI());
|
||||||
if (uri) {
|
if (uri) {
|
||||||
nsCOMPtr<nsIDOMNode> domNode = GetAsDOMNode(mElement);
|
nsCOMPtr<nsIDOMNode> domNode = GetAsDOMNode(mElement);
|
||||||
|
if (linkTypes & nsStyleLinkElement::ePRELOAD) {
|
||||||
|
nsContentPolicyType policyType;
|
||||||
|
bool isPreloadValid = CheckPreloadAttrs(policyType, mElement);
|
||||||
|
if (!isPreloadValid) {
|
||||||
|
// XXX: WPTs expect that we timeout on invalid preloads including
|
||||||
|
// those with valid destinations instead of firing an error event.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nsContentUtils::DispatchEventForPreloadURI(domNode, policyType);
|
||||||
|
} else {
|
||||||
prefetchService->PrefetchURI(uri,
|
prefetchService->PrefetchURI(uri,
|
||||||
mElement->OwnerDoc()->GetDocumentURI(),
|
mElement->OwnerDoc()->GetDocumentURI(),
|
||||||
domNode, linkTypes & nsStyleLinkElement::ePREFETCH);
|
domNode,
|
||||||
|
linkTypes & nsStyleLinkElement::ePREFETCH);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -125,6 +187,95 @@ Link::TryDNSPrefetchPreconnectOrPrefetch()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Link::UpdatePreload(nsIAtom* aName,
|
||||||
|
const nsAttrValue* aValue,
|
||||||
|
const nsAttrValue* aOldValue)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mElement->IsInComposedDoc());
|
||||||
|
|
||||||
|
if (!ElementHasHref()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoString rel;
|
||||||
|
if (!mElement->GetAttr(kNameSpaceID_None, nsGkAtoms::rel, rel)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nsContentUtils::PrefetchEnabled(mElement->OwnerDoc()->GetDocShell()) ||
|
||||||
|
!nsContentUtils::IsPreloadEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(rel,
|
||||||
|
mElement->NodePrincipal());
|
||||||
|
|
||||||
|
if (!(linkTypes & nsStyleLinkElement::ePRELOAD)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIURI> uri(GetURI());
|
||||||
|
if (!uri) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMNode> domNode = GetAsDOMNode(mElement);
|
||||||
|
|
||||||
|
nsContentPolicyType policyType;
|
||||||
|
bool isPreloadValid = CheckPreloadAttrs(policyType, mElement);
|
||||||
|
if (!isPreloadValid) {
|
||||||
|
// XXX: WPTs expect that we timeout on invalid preloads including
|
||||||
|
// those with valid destinations instead of firing an error event.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aName == nsGkAtoms::crossorigin) {
|
||||||
|
CORSMode corsMode = Element::AttrValueToCORSMode(aValue);
|
||||||
|
CORSMode oldCorsMode = Element::AttrValueToCORSMode(aOldValue);
|
||||||
|
if (corsMode != oldCorsMode) {
|
||||||
|
nsContentUtils::DispatchEventForPreloadURI(domNode, policyType);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoString oldValue;
|
||||||
|
if (aOldValue) {
|
||||||
|
aOldValue->ToString(oldValue);
|
||||||
|
} else {
|
||||||
|
oldValue = EmptyString();
|
||||||
|
}
|
||||||
|
nsContentPolicyType oldPolicyType = nsIContentPolicy::TYPE_INVALID;
|
||||||
|
|
||||||
|
if (aName == nsGkAtoms::as) {
|
||||||
|
if (aOldValue) {
|
||||||
|
CheckPreloadAttrs(oldPolicyType, aName, oldValue, mElement);
|
||||||
|
}
|
||||||
|
} else if (aName == nsGkAtoms::type) {
|
||||||
|
if (CheckPreloadAttrs(oldPolicyType, aName, oldValue, mElement)) {
|
||||||
|
oldPolicyType = policyType;
|
||||||
|
} else {
|
||||||
|
oldPolicyType = nsIContentPolicy::TYPE_INVALID;
|
||||||
|
}
|
||||||
|
} else if (aName == nsGkAtoms::media) {
|
||||||
|
if (CheckPreloadAttrs(oldPolicyType, aName, oldValue, mElement)) {
|
||||||
|
oldPolicyType = policyType;
|
||||||
|
} else {
|
||||||
|
oldPolicyType = nsIContentPolicy::TYPE_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return early for invalid preloads since we shouldn't trigger a new fetch.
|
||||||
|
if (policyType == nsIContentPolicy::TYPE_INVALID) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fire the associated event if the policy type has changed.
|
||||||
|
if (policyType != oldPolicyType) {
|
||||||
|
nsContentUtils::DispatchEventForPreloadURI(domNode, policyType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Link::CancelPrefetch()
|
Link::CancelPrefetch()
|
||||||
{
|
{
|
||||||
|
|
@ -635,6 +786,156 @@ Link::SetHrefAttribute(nsIURI *aURI)
|
||||||
NS_ConvertUTF8toUTF16(href), true);
|
NS_ConvertUTF8toUTF16(href), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Link::CheckPreloadAttrs(nsContentPolicyType& aPolicyType,
|
||||||
|
const nsAString& aDestination,
|
||||||
|
const nsAString& aType,
|
||||||
|
const nsAString& aMedia,
|
||||||
|
nsIDocument* aDocument)
|
||||||
|
{
|
||||||
|
nsString mimeType;
|
||||||
|
nsString params;
|
||||||
|
nsContentUtils::SplitMimeType(aType, mimeType, params);
|
||||||
|
ToLowerCase(mimeType);
|
||||||
|
|
||||||
|
nsAttrValue destinationAttr;
|
||||||
|
ParseDestinationValue(aDestination, destinationAttr);
|
||||||
|
|
||||||
|
aPolicyType = DestinationToContentPolicy(destinationAttr);
|
||||||
|
if (aPolicyType == nsIContentPolicy::TYPE_INVALID) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if media attribute is valid.
|
||||||
|
if (!aMedia.IsEmpty()) {
|
||||||
|
nsCSSParser cssParser;
|
||||||
|
RefPtr<nsMediaList> mediaList = new nsMediaList();
|
||||||
|
cssParser.ParseMediaList(aMedia, nullptr, 0, mediaList, false);
|
||||||
|
|
||||||
|
nsIPresShell* shell = aDocument->GetShell();
|
||||||
|
if (!shell) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsPresContext* presContext = shell->GetPresContext();
|
||||||
|
if (!presContext) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!mediaList->Matches(presContext, nullptr)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mimeType.IsEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (aPolicyType) {
|
||||||
|
case nsIContentPolicy::TYPE_OTHER:
|
||||||
|
if (destinationAttr.GetEnumValue() == DESTINATION_JSON) {
|
||||||
|
return nsContentUtils::IsJSONMIMEType(mimeType);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
case nsIContentPolicy::TYPE_MEDIA:
|
||||||
|
if (destinationAttr.GetEnumValue() == DESTINATION_TRACK) {
|
||||||
|
return mimeType.EqualsASCII(TEXT_VTT);
|
||||||
|
}
|
||||||
|
return DecoderTraits::IsSupportedInVideoDocument(NS_ConvertUTF16toUTF8(mimeType));
|
||||||
|
case nsIContentPolicy::TYPE_FONT:
|
||||||
|
return nsContentUtils::IsFontMIMEType(mimeType);
|
||||||
|
case nsIContentPolicy::TYPE_IMAGE:
|
||||||
|
return imgLoader::SupportImageWithMimeType(NS_ConvertUTF16toUTF8(mimeType).get(),
|
||||||
|
AcceptedMimeTypes::IMAGES_AND_DOCUMENTS);
|
||||||
|
case nsIContentPolicy::TYPE_SCRIPT:
|
||||||
|
return nsContentUtils::IsJavascriptMIMEType(mimeType);
|
||||||
|
case nsIContentPolicy::TYPE_STYLESHEET:
|
||||||
|
return mimeType.EqualsASCII(TEXT_CSS);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Link::CheckPreloadAttrs(nsContentPolicyType& aPolicyType,
|
||||||
|
nsIAtom* aName,
|
||||||
|
const nsAString& aValue,
|
||||||
|
Element* aElement)
|
||||||
|
{
|
||||||
|
nsAutoString destination;
|
||||||
|
if (aName == nsGkAtoms::as) {
|
||||||
|
destination = aValue;
|
||||||
|
} else {
|
||||||
|
aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::as, destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoString type;
|
||||||
|
if (aName == nsGkAtoms::type) {
|
||||||
|
type = aValue;
|
||||||
|
} else {
|
||||||
|
aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::type, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoString media;
|
||||||
|
if (aName == nsGkAtoms::media) {
|
||||||
|
media = aValue;
|
||||||
|
} else {
|
||||||
|
aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::media, media);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CheckPreloadAttrs(aPolicyType,
|
||||||
|
destination,
|
||||||
|
type,
|
||||||
|
media,
|
||||||
|
aElement->OwnerDoc());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Link::CheckPreloadAttrs(nsContentPolicyType& aPolicyType,
|
||||||
|
Element* aElement)
|
||||||
|
{
|
||||||
|
nsAutoString unused;
|
||||||
|
return CheckPreloadAttrs(aPolicyType,
|
||||||
|
nullptr,
|
||||||
|
unused,
|
||||||
|
aElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ void
|
||||||
|
Link::ParseDestinationValue(const nsAString& aValue,
|
||||||
|
nsAttrValue& aResult)
|
||||||
|
{
|
||||||
|
// Invalid values are treated as an empty string.
|
||||||
|
aResult.ParseEnumValue(aValue,
|
||||||
|
kDestinationAttributeTable,
|
||||||
|
false,
|
||||||
|
&kDestinationAttributeTable[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ nsContentPolicyType
|
||||||
|
Link::DestinationToContentPolicy(const nsAttrValue& aValue)
|
||||||
|
{
|
||||||
|
switch (aValue.GetEnumValue()) {
|
||||||
|
case DESTINATION_AUDIO:
|
||||||
|
case DESTINATION_TRACK:
|
||||||
|
case DESTINATION_VIDEO:
|
||||||
|
return nsIContentPolicy::TYPE_MEDIA;
|
||||||
|
case DESTINATION_FONT:
|
||||||
|
return nsIContentPolicy::TYPE_FONT;
|
||||||
|
case DESTINATION_IMAGE:
|
||||||
|
return nsIContentPolicy::TYPE_IMAGE;
|
||||||
|
case DESTINATION_SCRIPT:
|
||||||
|
return nsIContentPolicy::TYPE_SCRIPT;
|
||||||
|
case DESTINATION_STYLE:
|
||||||
|
return nsIContentPolicy::TYPE_STYLESHEET;
|
||||||
|
case DESTINATION_JSON:
|
||||||
|
case DESTINATION_FETCH:
|
||||||
|
return nsIContentPolicy::TYPE_OTHER;
|
||||||
|
case DESTINATION_INVALID:
|
||||||
|
default:
|
||||||
|
return nsIContentPolicy::TYPE_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
Link::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
Link::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -116,9 +116,26 @@ public:
|
||||||
nsWrapperCache::FlagsType aRequestedFlag);
|
nsWrapperCache::FlagsType aRequestedFlag);
|
||||||
|
|
||||||
// This is called by HTMLLinkElement.
|
// This is called by HTMLLinkElement.
|
||||||
void TryDNSPrefetchPreconnectOrPrefetch();
|
void TrySpeculativeLoadFeature();
|
||||||
|
void UpdatePreload(nsIAtom* aName,
|
||||||
|
const nsAttrValue* aValue,
|
||||||
|
const nsAttrValue* aOldValue);
|
||||||
void CancelPrefetch();
|
void CancelPrefetch();
|
||||||
|
|
||||||
|
static void ParseDestinationValue(const nsAString& aValue, nsAttrValue& aResult);
|
||||||
|
static bool CheckPreloadAttrs(nsContentPolicyType& aPolicyType,
|
||||||
|
Element* aElement);
|
||||||
|
static bool CheckPreloadAttrs(nsContentPolicyType& aPolicyType,
|
||||||
|
nsIAtom* aName,
|
||||||
|
const nsAString& aValue,
|
||||||
|
Element* aElement);
|
||||||
|
static bool CheckPreloadAttrs(nsContentPolicyType& aPolicyType,
|
||||||
|
const nsAString& aAs,
|
||||||
|
const nsAString& aType,
|
||||||
|
const nsAString& aMedia,
|
||||||
|
nsIDocument* aDocument);
|
||||||
|
static nsContentPolicyType DestinationToContentPolicy(const nsAttrValue& aValue);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~Link();
|
virtual ~Link();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/dom/ScriptLoader.h"
|
#include "mozilla/dom/ScriptLoader.h"
|
||||||
|
#include "mozilla/dom/Link.h"
|
||||||
#include "nsParserConstants.h"
|
#include "nsParserConstants.h"
|
||||||
#include "nsSandboxFlags.h"
|
#include "nsSandboxFlags.h"
|
||||||
|
|
||||||
|
|
@ -471,6 +472,7 @@ nsContentSink::ProcessLinkHeader(const nsAString& aLinkData)
|
||||||
nsAutoString media;
|
nsAutoString media;
|
||||||
nsAutoString anchor;
|
nsAutoString anchor;
|
||||||
nsAutoString crossOrigin;
|
nsAutoString crossOrigin;
|
||||||
|
nsAutoString destination;
|
||||||
|
|
||||||
crossOrigin.SetIsVoid(true);
|
crossOrigin.SetIsVoid(true);
|
||||||
|
|
||||||
|
|
@ -653,6 +655,11 @@ nsContentSink::ProcessLinkHeader(const nsAString& aLinkData)
|
||||||
crossOrigin = value;
|
crossOrigin = value;
|
||||||
crossOrigin.StripWhitespace();
|
crossOrigin.StripWhitespace();
|
||||||
}
|
}
|
||||||
|
} else if (attr.LowerCaseEqualsLiteral("as")) {
|
||||||
|
if (destination.IsEmpty()) {
|
||||||
|
destination = value;
|
||||||
|
destination.StripWhitespace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -666,7 +673,7 @@ nsContentSink::ProcessLinkHeader(const nsAString& aLinkData)
|
||||||
rv = ProcessLink(anchor, href, rel,
|
rv = ProcessLink(anchor, href, rel,
|
||||||
// prefer RFC 5987 variant over non-I18zed version
|
// prefer RFC 5987 variant over non-I18zed version
|
||||||
titleStar.IsEmpty() ? title : titleStar,
|
titleStar.IsEmpty() ? title : titleStar,
|
||||||
type, media, crossOrigin);
|
type, media, crossOrigin, destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
href.Truncate();
|
href.Truncate();
|
||||||
|
|
@ -676,6 +683,7 @@ nsContentSink::ProcessLinkHeader(const nsAString& aLinkData)
|
||||||
media.Truncate();
|
media.Truncate();
|
||||||
anchor.Truncate();
|
anchor.Truncate();
|
||||||
crossOrigin.SetIsVoid(true);
|
crossOrigin.SetIsVoid(true);
|
||||||
|
destination.Truncate();
|
||||||
|
|
||||||
seenParameters = false;
|
seenParameters = false;
|
||||||
}
|
}
|
||||||
|
|
@ -688,7 +696,7 @@ nsContentSink::ProcessLinkHeader(const nsAString& aLinkData)
|
||||||
rv = ProcessLink(anchor, href, rel,
|
rv = ProcessLink(anchor, href, rel,
|
||||||
// prefer RFC 5987 variant over non-I18zed version
|
// prefer RFC 5987 variant over non-I18zed version
|
||||||
titleStar.IsEmpty() ? title : titleStar,
|
titleStar.IsEmpty() ? title : titleStar,
|
||||||
type, media, crossOrigin);
|
type, media, crossOrigin, destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
|
@ -699,7 +707,8 @@ nsresult
|
||||||
nsContentSink::ProcessLink(const nsSubstring& aAnchor, const nsSubstring& aHref,
|
nsContentSink::ProcessLink(const nsSubstring& aAnchor, const nsSubstring& aHref,
|
||||||
const nsSubstring& aRel, const nsSubstring& aTitle,
|
const nsSubstring& aRel, const nsSubstring& aTitle,
|
||||||
const nsSubstring& aType, const nsSubstring& aMedia,
|
const nsSubstring& aType, const nsSubstring& aMedia,
|
||||||
const nsSubstring& aCrossOrigin)
|
const nsSubstring& aCrossOrigin,
|
||||||
|
const nsSubstring& aDestination)
|
||||||
{
|
{
|
||||||
uint32_t linkTypes =
|
uint32_t linkTypes =
|
||||||
nsStyleLinkElement::ParseLinkTypes(aRel, mDocument->NodePrincipal());
|
nsStyleLinkElement::ParseLinkTypes(aRel, mDocument->NodePrincipal());
|
||||||
|
|
@ -716,19 +725,22 @@ nsContentSink::ProcessLink(const nsSubstring& aAnchor, const nsSubstring& aHref,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasPrefetch = linkTypes & nsStyleLinkElement::ePREFETCH;
|
|
||||||
// prefetch href if relation is "next" or "prefetch"
|
// prefetch href if relation is "next" or "prefetch"
|
||||||
if (hasPrefetch || (linkTypes & nsStyleLinkElement::eNEXT)) {
|
if ((linkTypes & nsStyleLinkElement::eNEXT) ||
|
||||||
PrefetchHref(aHref, mDocument, hasPrefetch);
|
(linkTypes & nsStyleLinkElement::ePREFETCH) ||
|
||||||
|
(linkTypes & nsStyleLinkElement::ePRELOAD)) {
|
||||||
|
PrefetchOrPreloadHref(aHref, mDocument, linkTypes, aDestination, aType, aMedia);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aHref.IsEmpty() && (linkTypes & nsStyleLinkElement::eDNS_PREFETCH)) {
|
if (!aHref.IsEmpty()) {
|
||||||
|
if (linkTypes & nsStyleLinkElement::eDNS_PREFETCH) {
|
||||||
PrefetchDNS(aHref);
|
PrefetchDNS(aHref);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aHref.IsEmpty() && (linkTypes & nsStyleLinkElement::ePRECONNECT)) {
|
if (linkTypes & nsStyleLinkElement::ePRECONNECT) {
|
||||||
Preconnect(aHref, aCrossOrigin);
|
Preconnect(aHref, aCrossOrigin);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// is it a stylesheet link?
|
// is it a stylesheet link?
|
||||||
if (!(linkTypes & nsStyleLinkElement::eSTYLESHEET)) {
|
if (!(linkTypes & nsStyleLinkElement::eSTYLESHEET)) {
|
||||||
|
|
@ -847,9 +859,12 @@ nsContentSink::ProcessMETATag(nsIContent* aContent)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsContentSink::PrefetchHref(const nsAString &aHref,
|
nsContentSink::PrefetchOrPreloadHref(const nsAString &aHref,
|
||||||
nsINode *aSource,
|
nsINode *aSource,
|
||||||
bool aExplicit)
|
uint32_t aLinkTypes,
|
||||||
|
const nsAString& aDestination,
|
||||||
|
const nsAString& aType,
|
||||||
|
const nsAString& aMedia)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIPrefetchService> prefetchService(do_GetService(NS_PREFETCHSERVICE_CONTRACTID));
|
nsCOMPtr<nsIPrefetchService> prefetchService(do_GetService(NS_PREFETCHSERVICE_CONTRACTID));
|
||||||
if (prefetchService) {
|
if (prefetchService) {
|
||||||
|
|
@ -861,7 +876,25 @@ nsContentSink::PrefetchHref(const nsAString &aHref,
|
||||||
mDocument->GetDocBaseURI());
|
mDocument->GetDocBaseURI());
|
||||||
if (uri) {
|
if (uri) {
|
||||||
nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(aSource);
|
nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(aSource);
|
||||||
prefetchService->PrefetchURI(uri, mDocumentURI, domNode, aExplicit);
|
if (aLinkTypes & nsStyleLinkElement::ePRELOAD) {
|
||||||
|
nsContentPolicyType policyType;
|
||||||
|
bool isPreloadValid = Link::CheckPreloadAttrs(policyType,
|
||||||
|
aDestination,
|
||||||
|
aType,
|
||||||
|
aMedia,
|
||||||
|
mDocument);
|
||||||
|
if (!isPreloadValid) {
|
||||||
|
// XXX: WPTs expect that we timeout on invalid preloads including
|
||||||
|
// those with valid destinations instead of firing an error event.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nsContentUtils::DispatchEventForPreloadURI(domNode, policyType);
|
||||||
|
} else {
|
||||||
|
prefetchService->PrefetchURI(uri,
|
||||||
|
mDocumentURI,
|
||||||
|
domNode,
|
||||||
|
aLinkTypes & nsStyleLinkElement::ePREFETCH);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,8 @@ protected:
|
||||||
nsresult ProcessLink(const nsSubstring& aAnchor,
|
nsresult ProcessLink(const nsSubstring& aAnchor,
|
||||||
const nsSubstring& aHref, const nsSubstring& aRel,
|
const nsSubstring& aHref, const nsSubstring& aRel,
|
||||||
const nsSubstring& aTitle, const nsSubstring& aType,
|
const nsSubstring& aTitle, const nsSubstring& aType,
|
||||||
const nsSubstring& aMedia, const nsSubstring& aCrossOrigin);
|
const nsSubstring& aMedia, const nsSubstring& aCrossOrigin,
|
||||||
|
const nsSubstring& aDestination);
|
||||||
|
|
||||||
virtual nsresult ProcessStyleLink(nsIContent* aElement,
|
virtual nsresult ProcessStyleLink(nsIContent* aElement,
|
||||||
const nsSubstring& aHref,
|
const nsSubstring& aHref,
|
||||||
|
|
@ -162,8 +163,12 @@ protected:
|
||||||
const nsSubstring& aType,
|
const nsSubstring& aType,
|
||||||
const nsSubstring& aMedia);
|
const nsSubstring& aMedia);
|
||||||
|
|
||||||
void PrefetchHref(const nsAString &aHref, nsINode *aSource,
|
void PrefetchOrPreloadHref(const nsAString &aHref,
|
||||||
bool aExplicit);
|
nsINode *aSource,
|
||||||
|
uint32_t aLinkTypes,
|
||||||
|
const nsAString& aDestination,
|
||||||
|
const nsAString& aType,
|
||||||
|
const nsAString& aMedia);
|
||||||
|
|
||||||
// For PrefetchDNS() aHref can either be the usual
|
// For PrefetchDNS() aHref can either be the usual
|
||||||
// URI format or of the form "//www.hostname.com" without a scheme.
|
// URI format or of the form "//www.hostname.com" without a scheme.
|
||||||
|
|
|
||||||
|
|
@ -216,6 +216,7 @@
|
||||||
#include "TabChild.h"
|
#include "TabChild.h"
|
||||||
#include "mozilla/dom/DocGroup.h"
|
#include "mozilla/dom/DocGroup.h"
|
||||||
#include "mozilla/dom/TabGroup.h"
|
#include "mozilla/dom/TabGroup.h"
|
||||||
|
#include "mozilla/AsyncEventDispatcher.h"
|
||||||
|
|
||||||
#include "nsIBidiKeyboard.h"
|
#include "nsIBidiKeyboard.h"
|
||||||
|
|
||||||
|
|
@ -294,6 +295,7 @@ bool nsContentUtils::sGettersDecodeURLHash = false;
|
||||||
bool nsContentUtils::sPrivacyResistFingerprinting = false;
|
bool nsContentUtils::sPrivacyResistFingerprinting = false;
|
||||||
bool nsContentUtils::sSendPerformanceTimingNotifications = false;
|
bool nsContentUtils::sSendPerformanceTimingNotifications = false;
|
||||||
bool nsContentUtils::sUseActivityCursor = false;
|
bool nsContentUtils::sUseActivityCursor = false;
|
||||||
|
bool nsContentUtils::sPreloadEnabled = true;
|
||||||
|
|
||||||
uint32_t nsContentUtils::sHandlingInputTimeout = 1000;
|
uint32_t nsContentUtils::sHandlingInputTimeout = 1000;
|
||||||
|
|
||||||
|
|
@ -632,6 +634,9 @@ nsContentUtils::Init()
|
||||||
Preferences::AddBoolVarCache(&sUseActivityCursor,
|
Preferences::AddBoolVarCache(&sUseActivityCursor,
|
||||||
"ui.use_activity_cursor", false);
|
"ui.use_activity_cursor", false);
|
||||||
|
|
||||||
|
Preferences::AddBoolVarCache(&sPreloadEnabled,
|
||||||
|
"network.preload", true);
|
||||||
|
|
||||||
Element::InitCCCallbacks();
|
Element::InitCCCallbacks();
|
||||||
|
|
||||||
nsCOMPtr<nsIUUIDGenerator> uuidGenerator =
|
nsCOMPtr<nsIUUIDGenerator> uuidGenerator =
|
||||||
|
|
@ -4120,6 +4125,28 @@ nsresult GetEventAndTarget(nsIDocument* aDoc, nsISupports* aTarget,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsContentUtils::DispatchEventForPreloadURI(nsIDOMNode* aNode,
|
||||||
|
nsContentPolicyType& aPolicyType)
|
||||||
|
{
|
||||||
|
if (!IsPreloadEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsINode> domNode = do_QueryInterface(aNode);
|
||||||
|
if (domNode && domNode->IsInComposedDoc()) {
|
||||||
|
bool success = aPolicyType != nsIContentPolicy::TYPE_INVALID;
|
||||||
|
RefPtr<AsyncEventDispatcher> asyncDispatcher =
|
||||||
|
new AsyncEventDispatcher(domNode,
|
||||||
|
success ?
|
||||||
|
NS_LITERAL_STRING("load") :
|
||||||
|
NS_LITERAL_STRING("error"),
|
||||||
|
/* aCanBubble = */ false,
|
||||||
|
/* aCancelable = */ false);
|
||||||
|
asyncDispatcher->RunDOMEventWhenSafe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
nsresult
|
nsresult
|
||||||
nsContentUtils::DispatchTrustedEvent(nsIDocument* aDoc, nsISupports* aTarget,
|
nsContentUtils::DispatchTrustedEvent(nsIDocument* aDoc, nsISupports* aTarget,
|
||||||
|
|
@ -7377,6 +7404,12 @@ nsContentUtils::GPCEnabled()
|
||||||
return nsContentUtils::sGPCEnabled;
|
return nsContentUtils::sGPCEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsContentUtils::IsPreloadEnabled()
|
||||||
|
{
|
||||||
|
return nsContentUtils::sPreloadEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
mozilla::LogModule*
|
mozilla::LogModule*
|
||||||
nsContentUtils::DOMDumpLog()
|
nsContentUtils::DOMDumpLog()
|
||||||
{
|
{
|
||||||
|
|
@ -7441,6 +7474,48 @@ nsContentUtils::IsJavascriptMIMEType(const nsAString& aMIMEType)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsContentUtils::IsJSONMIMEType(const nsAString& aMIMEType)
|
||||||
|
{
|
||||||
|
static const char* jsonTypes[] = {
|
||||||
|
"text/json",
|
||||||
|
"application/json",
|
||||||
|
"application/geo+json",
|
||||||
|
nullptr
|
||||||
|
};
|
||||||
|
|
||||||
|
for (uint32_t i = 0; jsonTypes[i]; ++i) {
|
||||||
|
if (aMIMEType.LowerCaseEqualsASCII(jsonTypes[i])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsContentUtils::IsFontMIMEType(const nsAString& aMIMEType)
|
||||||
|
{
|
||||||
|
// The following list was taken from IANA and excludes deprecated mime-types:
|
||||||
|
// https://www.iana.org/assignments/media-types/media-types.xhtml#font
|
||||||
|
static const char* fontTypes[] = {
|
||||||
|
"font/otf",
|
||||||
|
"font/sfnt",
|
||||||
|
"font/ttf",
|
||||||
|
"font/woff",
|
||||||
|
"font/woff2",
|
||||||
|
nullptr
|
||||||
|
};
|
||||||
|
|
||||||
|
for (uint32_t i = 0; fontTypes[i]; ++i) {
|
||||||
|
if (aMIMEType.LowerCaseEqualsASCII(fontTypes[i])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsContentUtils::GenerateUUIDInPlace(nsID& aUUID)
|
nsContentUtils::GenerateUUIDInPlace(nsID& aUUID)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1178,6 +1178,16 @@ public:
|
||||||
static void MaybeFireNodeRemoved(nsINode* aChild, nsINode* aParent,
|
static void MaybeFireNodeRemoved(nsINode* aChild, nsINode* aParent,
|
||||||
nsIDocument* aOwnerDoc);
|
nsIDocument* aOwnerDoc);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method creates and dispatches either a "load" or "error" event
|
||||||
|
* to the provided node (a preload link).
|
||||||
|
* @param aNode The node to fire the event at.
|
||||||
|
* @param aPolicyType The resulting content policy from the preload.
|
||||||
|
*/
|
||||||
|
static void DispatchEventForPreloadURI(nsIDOMNode* aNode,
|
||||||
|
nsContentPolicyType& aPolicyType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method creates and dispatches a trusted event.
|
* This method creates and dispatches a trusted event.
|
||||||
* Works only with events which can be created by calling
|
* Works only with events which can be created by calling
|
||||||
|
|
@ -2139,6 +2149,11 @@ public:
|
||||||
return sUseActivityCursor;
|
return sUseActivityCursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the preload service is enabled.
|
||||||
|
*/
|
||||||
|
static bool IsPreloadEnabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if this doc is controlled by a ServiceWorker.
|
* Return true if this doc is controlled by a ServiceWorker.
|
||||||
*/
|
*/
|
||||||
|
|
@ -2383,6 +2398,10 @@ public:
|
||||||
|
|
||||||
static bool IsJavascriptMIMEType(const nsAString& aMIMEType);
|
static bool IsJavascriptMIMEType(const nsAString& aMIMEType);
|
||||||
|
|
||||||
|
static bool IsJSONMIMEType(const nsAString& aMIMEType);
|
||||||
|
|
||||||
|
static bool IsFontMIMEType(const nsAString& aMIMEType);
|
||||||
|
|
||||||
static void SplitMimeType(const nsAString& aValue, nsString& aType,
|
static void SplitMimeType(const nsAString& aValue, nsString& aType,
|
||||||
nsString& aParams);
|
nsString& aParams);
|
||||||
|
|
||||||
|
|
@ -2955,6 +2974,7 @@ private:
|
||||||
static bool sPrivacyResistFingerprinting;
|
static bool sPrivacyResistFingerprinting;
|
||||||
static bool sSendPerformanceTimingNotifications;
|
static bool sSendPerformanceTimingNotifications;
|
||||||
static bool sUseActivityCursor;
|
static bool sUseActivityCursor;
|
||||||
|
static bool sPreloadEnabled;
|
||||||
static uint32_t sCookiesLifetimePolicy;
|
static uint32_t sCookiesLifetimePolicy;
|
||||||
static uint32_t sCookiesBehavior;
|
static uint32_t sCookiesBehavior;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,7 @@ GK_ATOM(archive, "archive")
|
||||||
GK_ATOM(area, "area")
|
GK_ATOM(area, "area")
|
||||||
GK_ATOM(arrow, "arrow")
|
GK_ATOM(arrow, "arrow")
|
||||||
GK_ATOM(article, "article")
|
GK_ATOM(article, "article")
|
||||||
|
GK_ATOM(as, "as")
|
||||||
GK_ATOM(ascending, "ascending")
|
GK_ATOM(ascending, "ascending")
|
||||||
GK_ATOM(aside, "aside")
|
GK_ATOM(aside, "aside")
|
||||||
GK_ATOM(aspectRatio, "aspect-ratio")
|
GK_ATOM(aspectRatio, "aspect-ratio")
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,8 @@ static uint32_t ToLinkMask(const nsAString& aLink, nsIPrincipal* aPrincipal)
|
||||||
return nsStyleLinkElement::eHTMLIMPORT;
|
return nsStyleLinkElement::eHTMLIMPORT;
|
||||||
else if (aLink.EqualsLiteral("preconnect"))
|
else if (aLink.EqualsLiteral("preconnect"))
|
||||||
return nsStyleLinkElement::ePRECONNECT;
|
return nsStyleLinkElement::ePRECONNECT;
|
||||||
|
else if (aLink.EqualsLiteral("preload"))
|
||||||
|
return nsStyleLinkElement::ePRELOAD;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,8 @@ public:
|
||||||
eNEXT = 0x00000008,
|
eNEXT = 0x00000008,
|
||||||
eALTERNATE = 0x00000010,
|
eALTERNATE = 0x00000010,
|
||||||
eHTMLIMPORT = 0x00000020,
|
eHTMLIMPORT = 0x00000020,
|
||||||
ePRECONNECT = 0x00000040
|
ePRECONNECT = 0x00000040,
|
||||||
|
ePRELOAD = 0x00000080
|
||||||
};
|
};
|
||||||
|
|
||||||
// The return value is a bitwise or of 0 or more RelValues.
|
// The return value is a bitwise or of 0 or more RelValues.
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,7 @@ nsIAtom** const kAttributesHTML[] = {
|
||||||
&nsGkAtoms::accesskey,
|
&nsGkAtoms::accesskey,
|
||||||
&nsGkAtoms::action,
|
&nsGkAtoms::action,
|
||||||
&nsGkAtoms::alt,
|
&nsGkAtoms::alt,
|
||||||
|
&nsGkAtoms::as,
|
||||||
&nsGkAtoms::autocomplete,
|
&nsGkAtoms::autocomplete,
|
||||||
&nsGkAtoms::autofocus,
|
&nsGkAtoms::autofocus,
|
||||||
&nsGkAtoms::autoplay,
|
&nsGkAtoms::autoplay,
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,7 @@ HTMLLinkElement::BindToTree(nsIDocument* aDocument,
|
||||||
|
|
||||||
if (nsIDocument* doc = GetComposedDoc()) {
|
if (nsIDocument* doc = GetComposedDoc()) {
|
||||||
doc->RegisterPendingLinkUpdate(this);
|
doc->RegisterPendingLinkUpdate(this);
|
||||||
TryDNSPrefetchPreconnectOrPrefetch();
|
TrySpeculativeLoadFeature();
|
||||||
}
|
}
|
||||||
|
|
||||||
void (HTMLLinkElement::*update)() = &HTMLLinkElement::UpdateStyleSheetInternal;
|
void (HTMLLinkElement::*update)() = &HTMLLinkElement::UpdateStyleSheetInternal;
|
||||||
|
|
@ -242,6 +242,11 @@ HTMLLinkElement::ParseAttribute(int32_t aNamespaceID,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aAttribute == nsGkAtoms::as) {
|
||||||
|
ParseDestinationValue(aValue, aResult);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (aAttribute == nsGkAtoms::sizes) {
|
if (aAttribute == nsGkAtoms::sizes) {
|
||||||
aResult.ParseAtomArray(aValue);
|
aResult.ParseAtomArray(aValue);
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -374,6 +379,8 @@ HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
aName == nsGkAtoms::title ||
|
aName == nsGkAtoms::title ||
|
||||||
aName == nsGkAtoms::media ||
|
aName == nsGkAtoms::media ||
|
||||||
aName == nsGkAtoms::type ||
|
aName == nsGkAtoms::type ||
|
||||||
|
aName == nsGkAtoms::as ||
|
||||||
|
aName == nsGkAtoms::crossorigin ||
|
||||||
(LINK_DISABLED && aName == nsGkAtoms::disabled))) {
|
(LINK_DISABLED && aName == nsGkAtoms::disabled))) {
|
||||||
bool dropSheet = false;
|
bool dropSheet = false;
|
||||||
if (aName == nsGkAtoms::rel) {
|
if (aName == nsGkAtoms::rel) {
|
||||||
|
|
@ -392,9 +399,17 @@ HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
UpdateImport();
|
UpdateImport();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((aName == nsGkAtoms::rel || aName == nsGkAtoms::href) &&
|
if (IsInComposedDoc()) {
|
||||||
IsInComposedDoc()) {
|
if (aName == nsGkAtoms::rel || aName == nsGkAtoms::href) {
|
||||||
TryDNSPrefetchPreconnectOrPrefetch();
|
TrySpeculativeLoadFeature();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aName == nsGkAtoms::as ||
|
||||||
|
aName == nsGkAtoms::type ||
|
||||||
|
aName == nsGkAtoms::crossorigin ||
|
||||||
|
aName == nsGkAtoms::media) {
|
||||||
|
UpdatePreload(aName, aValue, aOldValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateStyleSheetInternal(nullptr, nullptr,
|
UpdateStyleSheetInternal(nullptr, nullptr,
|
||||||
|
|
@ -421,6 +436,13 @@ HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
(LINK_DISABLED && aName == nsGkAtoms::disabled)) {
|
(LINK_DISABLED && aName == nsGkAtoms::disabled)) {
|
||||||
UpdateStyleSheetInternal(nullptr, nullptr, true);
|
UpdateStyleSheetInternal(nullptr, nullptr, true);
|
||||||
}
|
}
|
||||||
|
if ((aName == nsGkAtoms::as ||
|
||||||
|
aName == nsGkAtoms::type ||
|
||||||
|
aName == nsGkAtoms::crossorigin ||
|
||||||
|
aName == nsGkAtoms::media) &&
|
||||||
|
IsInComposedDoc()) {
|
||||||
|
UpdatePreload(aName, aValue, aOldValue);
|
||||||
|
}
|
||||||
if (aName == nsGkAtoms::href ||
|
if (aName == nsGkAtoms::href ||
|
||||||
aName == nsGkAtoms::rel) {
|
aName == nsGkAtoms::rel) {
|
||||||
UpdateImport();
|
UpdateImport();
|
||||||
|
|
@ -471,6 +493,7 @@ static const DOMTokenListSupportedToken sSupportedRelValues[] = {
|
||||||
"preconnect",
|
"preconnect",
|
||||||
"icon",
|
"icon",
|
||||||
"search",
|
"search",
|
||||||
|
"preload",
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -523,7 +546,8 @@ HTMLLinkElement::GetStyleSheetInfo(nsAString& aTitle,
|
||||||
|
|
||||||
nsAutoString rel;
|
nsAutoString rel;
|
||||||
GetAttr(kNameSpaceID_None, nsGkAtoms::rel, rel);
|
GetAttr(kNameSpaceID_None, nsGkAtoms::rel, rel);
|
||||||
uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(rel, NodePrincipal());
|
uint32_t linkTypes =
|
||||||
|
nsStyleLinkElement::ParseLinkTypes(rel, NodePrincipal());
|
||||||
// Is it a stylesheet link?
|
// Is it a stylesheet link?
|
||||||
if (!(linkTypes & nsStyleLinkElement::eSTYLESHEET)) {
|
if (!(linkTypes & nsStyleLinkElement::eSTYLESHEET)) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -602,6 +626,12 @@ HTMLLinkElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||||
return HTMLLinkElementBinding::Wrap(aCx, this, aGivenProto);
|
return HTMLLinkElementBinding::Wrap(aCx, this, aGivenProto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HTMLLinkElement::GetAs(nsAString& aResult)
|
||||||
|
{
|
||||||
|
GetEnumAttr(nsGkAtoms::as, EmptyCString().get(), aResult);
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<nsIDocument>
|
already_AddRefed<nsIDocument>
|
||||||
HTMLLinkElement::GetImport()
|
HTMLLinkElement::GetImport()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,11 @@ public:
|
||||||
{
|
{
|
||||||
SetHTMLAttr(nsGkAtoms::hreflang, aHreflang, aRv);
|
SetHTMLAttr(nsGkAtoms::hreflang, aHreflang, aRv);
|
||||||
}
|
}
|
||||||
|
void GetAs(nsAString& aResult);
|
||||||
|
void SetAs(const nsAString& aAs, ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
SetAttr(nsGkAtoms::as, aAs, aRv);
|
||||||
|
}
|
||||||
nsDOMTokenList* Sizes()
|
nsDOMTokenList* Sizes()
|
||||||
{
|
{
|
||||||
return GetTokenList(nsGkAtoms::sizes);
|
return GetTokenList(nsGkAtoms::sizes);
|
||||||
|
|
|
||||||
|
|
@ -59,3 +59,9 @@ partial interface HTMLLinkElement {
|
||||||
[CEReactions, SetterThrows]
|
[CEReactions, SetterThrows]
|
||||||
attribute DOMString integrity;
|
attribute DOMString integrity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//https://w3c.github.io/preload/
|
||||||
|
partial interface HTMLLinkElement {
|
||||||
|
[SetterThrows, Pure]
|
||||||
|
attribute DOMString as;
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ function ModuleGetExportedNames(exportStarSet = [])
|
||||||
for (let i = 0; i < starExportEntries.length; i++) {
|
for (let i = 0; i < starExportEntries.length; i++) {
|
||||||
let e = starExportEntries[i];
|
let e = starExportEntries[i];
|
||||||
let requestedModule = CallModuleResolveHook(module, e.moduleRequest,
|
let requestedModule = CallModuleResolveHook(module, e.moduleRequest,
|
||||||
MODULE_STATE_INSTANTIATED);
|
MODULE_STATUS_INSTANTIATED);
|
||||||
let starNames = callFunction(requestedModule.getExportedNames, requestedModule,
|
let starNames = callFunction(requestedModule.getExportedNames, requestedModule,
|
||||||
exportStarSet);
|
exportStarSet);
|
||||||
for (let j = 0; j < starNames.length; j++) {
|
for (let j = 0; j < starNames.length; j++) {
|
||||||
|
|
|
||||||
|
|
@ -1908,6 +1908,9 @@ pref("network.ftp.idleConnectionTimeout", 300);
|
||||||
// all other values are treated like 2
|
// all other values are treated like 2
|
||||||
pref("network.dir.format", 2);
|
pref("network.dir.format", 2);
|
||||||
|
|
||||||
|
// enables the preload service (i.e., preloading of <link rel="preload"> URLs).
|
||||||
|
pref("network.preload", true);
|
||||||
|
|
||||||
// enables the prefetch service (i.e., prefetching of <link rel="next"> URLs).
|
// enables the prefetch service (i.e., prefetching of <link rel="next"> URLs).
|
||||||
pref("network.prefetch-next", true);
|
pref("network.prefetch-next", true);
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -544,6 +544,7 @@ HTML5_ATOM(ondragleave, "ondragleave")
|
||||||
HTML5_ATOM(startoffset, "startoffset")
|
HTML5_ATOM(startoffset, "startoffset")
|
||||||
HTML5_ATOM(startOffset, "startOffset")
|
HTML5_ATOM(startOffset, "startOffset")
|
||||||
HTML5_ATOM(start, "start")
|
HTML5_ATOM(start, "start")
|
||||||
|
HTML5_ATOM(as, "as")
|
||||||
HTML5_ATOM(axis, "axis")
|
HTML5_ATOM(axis, "axis")
|
||||||
HTML5_ATOM(bias, "bias")
|
HTML5_ATOM(bias, "bias")
|
||||||
HTML5_ATOM(colspan, "colspan")
|
HTML5_ATOM(colspan, "colspan")
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -655,6 +655,7 @@ class nsHtml5AttributeName
|
||||||
static nsHtml5AttributeName* ATTR_ONDRAGLEAVE;
|
static nsHtml5AttributeName* ATTR_ONDRAGLEAVE;
|
||||||
static nsHtml5AttributeName* ATTR_STARTOFFSET;
|
static nsHtml5AttributeName* ATTR_STARTOFFSET;
|
||||||
static nsHtml5AttributeName* ATTR_START;
|
static nsHtml5AttributeName* ATTR_START;
|
||||||
|
static nsHtml5AttributeName* ATTR_AS;
|
||||||
static nsHtml5AttributeName* ATTR_AXIS;
|
static nsHtml5AttributeName* ATTR_AXIS;
|
||||||
static nsHtml5AttributeName* ATTR_BIAS;
|
static nsHtml5AttributeName* ATTR_BIAS;
|
||||||
static nsHtml5AttributeName* ATTR_COLSPAN;
|
static nsHtml5AttributeName* ATTR_COLSPAN;
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,54 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace,
|
||||||
mSpeculativeLoadQueue.AppendElement()->InitPreconnect(
|
mSpeculativeLoadQueue.AppendElement()->InitPreconnect(
|
||||||
url, crossOrigin);
|
url, crossOrigin);
|
||||||
}
|
}
|
||||||
|
} else if (rel.LowerCaseEqualsASCII("preload") && nsContentUtils::IsPreloadEnabled()) {
|
||||||
|
nsHtml5String url =
|
||||||
|
aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
|
||||||
|
if (url) {
|
||||||
|
nsHtml5String preloadAs =
|
||||||
|
aAttributes->getValue(nsHtml5AttributeName::ATTR_AS);
|
||||||
|
if (preloadAs.LowerCaseEqualsASCII("script")) {
|
||||||
|
nsHtml5String charset =
|
||||||
|
aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
|
||||||
|
nsHtml5String type =
|
||||||
|
aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
|
||||||
|
nsHtml5String crossOrigin =
|
||||||
|
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
|
||||||
|
nsHtml5String integrity =
|
||||||
|
aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
|
||||||
|
mSpeculativeLoadQueue.AppendElement()->InitScript(
|
||||||
|
url,
|
||||||
|
charset,
|
||||||
|
type,
|
||||||
|
crossOrigin,
|
||||||
|
integrity,
|
||||||
|
mode == nsHtml5TreeBuilder::IN_HEAD,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false);
|
||||||
|
mCurrentHtmlScriptIsAsyncOrDefer = false;
|
||||||
|
} else if (preloadAs.LowerCaseEqualsASCII("style")) {
|
||||||
|
nsHtml5String charset =
|
||||||
|
aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
|
||||||
|
nsHtml5String crossOrigin =
|
||||||
|
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
|
||||||
|
nsHtml5String integrity =
|
||||||
|
aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
|
||||||
|
mSpeculativeLoadQueue.AppendElement()->InitStyle(
|
||||||
|
url, charset, crossOrigin, integrity);
|
||||||
|
} else if (preloadAs.LowerCaseEqualsASCII("image")) {
|
||||||
|
nsHtml5String srcset =
|
||||||
|
aAttributes->getValue(nsHtml5AttributeName::ATTR_SRCSET);
|
||||||
|
nsHtml5String crossOrigin =
|
||||||
|
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
|
||||||
|
nsHtml5String referrerPolicy =
|
||||||
|
aAttributes->getValue(nsHtml5AttributeName::ATTR_REFERRERPOLICY);
|
||||||
|
nsHtml5String sizes =
|
||||||
|
aAttributes->getValue(nsHtml5AttributeName::ATTR_SIZES);
|
||||||
|
mSpeculativeLoadQueue.AppendElement()->InitImage(
|
||||||
|
url, crossOrigin, referrerPolicy, srcset, sizes);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (nsHtml5Atoms::video == aName) {
|
} else if (nsHtml5Atoms::video == aName) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue