Skip to content

Commit

Permalink
Backed out changeset 0054de12b39c (bug 1425310) while the issue is be…
Browse files Browse the repository at this point in the history
…ing investigated(Bug 1832361) CLOSED TREE
  • Loading branch information
Cristian Tuns committed May 10, 2023
1 parent 1ce9c6c commit 44fa46d
Show file tree
Hide file tree
Showing 18 changed files with 107 additions and 352 deletions.
95 changes: 29 additions & 66 deletions dom/html/HTMLLinkElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,30 +311,36 @@ void HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
aNameSpaceID, aName, aValue, aOldValue, aSubjectPrincipal, aNotify);
}

// Keep this and the arrays below in sync with ToLinkMask in LinkStyle.cpp.
#define SUPPORTED_REL_VALUES_BASE \
"prefetch", "dns-prefetch", "stylesheet", "next", "alternate", "preconnect", \
"icon", "search", nullptr

static const DOMTokenListSupportedToken sSupportedRelValueCombinations[][12] = {
{SUPPORTED_REL_VALUES_BASE},
{"manifest", SUPPORTED_REL_VALUES_BASE},
{"preload", SUPPORTED_REL_VALUES_BASE},
{"preload", "manifest", SUPPORTED_REL_VALUES_BASE},
{"modulepreload", SUPPORTED_REL_VALUES_BASE},
{"modulepreload", "manifest", SUPPORTED_REL_VALUES_BASE},
{"modulepreload", "preload", SUPPORTED_REL_VALUES_BASE},
{"modulepreload", "preload", "manifest", SUPPORTED_REL_VALUES_BASE}};
#undef SUPPORTED_REL_VALUES_BASE
static const DOMTokenListSupportedToken sSupportedRelValues[] = {
// Keep this and the one below in sync with ToLinkMask in
// LinkStyle.cpp.
// "preload" must come first because it can be disabled.
"preload", "prefetch", "dns-prefetch", "stylesheet",
"next", "alternate", "preconnect", "icon",
"search", "modulepreload", nullptr};

static const DOMTokenListSupportedToken sSupportedRelValuesWithManifest[] = {
// Keep this in sync with ToLinkMask in LinkStyle.cpp.
// "preload" and "manifest" must come first because they can be disabled.
"preload", "manifest", "prefetch", "dns-prefetch", "stylesheet", "next",
"alternate", "preconnect", "icon", "search", nullptr};

nsDOMTokenList* HTMLLinkElement::RelList() {
if (!mRelList) {
int index = (StaticPrefs::dom_manifest_enabled() ? 1 : 0) |
(StaticPrefs::network_preload() ? 2 : 0) |
(StaticPrefs::network_modulepreload() ? 4 : 0);

mRelList = new nsDOMTokenList(this, nsGkAtoms::rel,
sSupportedRelValueCombinations[index]);
auto preload = StaticPrefs::network_preload();
auto manifest = StaticPrefs::dom_manifest_enabled();
if (manifest && preload) {
mRelList = new nsDOMTokenList(this, nsGkAtoms::rel,
sSupportedRelValuesWithManifest);
} else if (manifest && !preload) {
mRelList = new nsDOMTokenList(this, nsGkAtoms::rel,
&sSupportedRelValuesWithManifest[1]);
} else if (!manifest && preload) {
mRelList = new nsDOMTokenList(this, nsGkAtoms::rel, sSupportedRelValues);
} else { // both false...drop preload
mRelList =
new nsDOMTokenList(this, nsGkAtoms::rel, &sSupportedRelValues[1]);
}
}
return mRelList;
}
Expand Down Expand Up @@ -484,10 +490,7 @@ void HTMLLinkElement::
}

if (linkTypes & eMODULE_PRELOAD) {
ScriptLoader* scriptLoader = OwnerDoc()->ScriptLoader();
ModuleLoader* moduleLoader = scriptLoader->GetModuleLoader();

if (!moduleLoader) {
if (!OwnerDoc()->ScriptLoader()->GetModuleLoader()) {
// For the print preview documents, at this moment it doesn't have module
// loader yet, as the (print preview) document is not attached to the
// nsIContentViewer yet, so it doesn't have the GlobalObject.
Expand All @@ -497,49 +500,9 @@ void HTMLLinkElement::
return;
}

if (!StaticPrefs::network_modulepreload()) {
// Keep behavior from https://phabricator.services.mozilla.com/D149371,
// prior to main implementation of modulepreload
moduleLoader->DisallowImportMaps();
return;
}

// https://html.spec.whatwg.org/multipage/semantics.html#processing-the-media-attribute
// TODO: apply this check for all linkTypes
nsAutoString media;
if (GetAttr(nsGkAtoms::media, media)) {
RefPtr<mozilla::dom::MediaList> mediaList =
mozilla::dom::MediaList::Create(NS_ConvertUTF16toUTF8(media));
if (!mediaList->Matches(*OwnerDoc())) {
return;
}
}

// TODO: per spec, apply this check for ePREFETCH as well
if (!HasNonEmptyAttr(nsGkAtoms::href)) {
return;
}

nsAutoString as;
GetAttr(nsGkAtoms::as, as);

if (!net::IsScriptLikeOrInvalid(as)) {
RefPtr<AsyncEventDispatcher> asyncDispatcher = new AsyncEventDispatcher(
this, u"error"_ns, CanBubble::eNo, ChromeOnlyDispatch::eNo);
asyncDispatcher->PostDOMEvent();
return;
}

nsCOMPtr<nsIURI> uri = GetURI();
if (!uri) {
return;
}

// https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-modulepreload-module-script-graph
// Step 1. Disallow further import maps given settings object.
moduleLoader->DisallowImportMaps();

StartPreload(nsIContentPolicy::TYPE_SCRIPT);
OwnerDoc()->ScriptLoader()->GetModuleLoader()->DisallowImportMaps();
return;
}

Expand Down
7 changes: 3 additions & 4 deletions dom/script/ScriptLoadContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,9 @@ class Element;
* the script does not need to be fetched first.
* * mIsXSLT
* Set if we are in an XSLT request.
* * mIsPreload
* * TODO: mIsPreload (will be moved from ScriptFetchOptions)
* Set for scripts that are preloaded in a
* <link rel="preload" as="script"> or <link rel="modulepreload">
* element.
* <link rel="preload" as="script"> element.
*
* In addition to describing how the ScriptLoadRequest will be loaded by the
* DOM ScriptLoader, the ScriptLoadContext contains fields that facilitate
Expand Down Expand Up @@ -114,7 +113,7 @@ class ScriptLoadContext : public JS::loader::LoadContextBase,
eDeferred,
eAsync,
eLinkPreload // this is a load initiated by <link rel="preload"
// as="script"> or <link rel="modulepreload"> tag
// as="script"> tag
};

void SetScriptMode(bool aDeferAttr, bool aAsyncAttr, bool aLinkPreload);
Expand Down
15 changes: 7 additions & 8 deletions dom/script/ScriptLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -675,12 +675,12 @@ nsresult ScriptLoader::StartLoadInternal(
aRequest->GetScriptLoadContext()->IsTracking()));

if (aRequest->GetScriptLoadContext()->IsLinkPreloadScript()) {
// This is <link rel="preload" as="script"> or <link rel="modulepreload">
// initiated speculative load, put it to the group that is not blocked by
// leaders and doesn't block follower at the same time. Giving it a much
// higher priority will make this request be processed ahead of other
// Unblocked requests, but with the same weight as Leaders. This will make
// us behave similar way for both http2 and http1.
// This is <link rel="preload" as="script"> initiated speculative load,
// put it to the group that is not blocked by leaders and doesn't block
// follower at the same time. Giving it a much higher priority will make
// this request be processed ahead of other Unblocked requests, but with
// the same weight as Leaders. This will make us behave similar way for
// both http2 and http1.
ScriptLoadContext::PrioritizeAsPreload(channel);
ScriptLoadContext::AddLoadBackgroundFlag(channel);
} else if (nsCOMPtr<nsIClassOfService> cos = do_QueryInterface(channel)) {
Expand Down Expand Up @@ -786,8 +786,7 @@ nsresult ScriptLoader::StartLoadInternal(
aRequest->mURI, aRequest->CORSMode(), aRequest->mKind);
aRequest->GetScriptLoadContext()->NotifyOpen(
key, channel, mDocument,
aRequest->GetScriptLoadContext()->IsLinkPreloadScript(),
aRequest->IsModuleRequest());
aRequest->GetScriptLoadContext()->IsLinkPreloadScript());

if (aEarlyHintPreloaderId) {
nsCOMPtr<nsIHttpChannelInternal> channelInternal =
Expand Down
11 changes: 1 addition & 10 deletions modules/libpref/init/StaticPrefList.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11691,21 +11691,12 @@
value: false
mirror: always

# Enables `<link rel="preload">` tag and `Link: rel=preload` response header
# handling.
# Enables `<link rel="preload">` tag and `Link: rel=preload` response header handling.
- name: network.preload
type: RelaxedAtomicBool
value: true
mirror: always

# Enables `<link rel="modulepreload">` tag and `Link: rel=modulepreload`
# response header handling. The latter is not yet implemented, see:
# https://bugzilla.mozilla.org/show_bug.cgi?id=1773056.
- name: network.modulepreload
type: RelaxedAtomicBool
value: true
mirror: always

# Enable 103 Early Hint status code (RFC 8297)
- name: network.early-hints.enabled
type: RelaxedAtomicBool
Expand Down
18 changes: 0 additions & 18 deletions netwerk/base/nsNetUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3756,24 +3756,6 @@ nsContentPolicyType AsValueToContentPolicy(const nsAttrValue& aValue) {
return nsIContentPolicy::TYPE_INVALID;
}

// TODO: implement this using nsAttrValue's destination enums when support for
// the new destinations is added; see this diff for a possible start:
// https://phabricator.services.mozilla.com/D172368?vs=705114&id=708720
bool IsScriptLikeOrInvalid(const nsAString& aAs) {
return !(
aAs.LowerCaseEqualsASCII("fetch") || aAs.LowerCaseEqualsASCII("audio") ||
aAs.LowerCaseEqualsASCII("document") ||
aAs.LowerCaseEqualsASCII("embed") || aAs.LowerCaseEqualsASCII("font") ||
aAs.LowerCaseEqualsASCII("frame") || aAs.LowerCaseEqualsASCII("iframe") ||
aAs.LowerCaseEqualsASCII("image") ||
aAs.LowerCaseEqualsASCII("manifest") ||
aAs.LowerCaseEqualsASCII("object") ||
aAs.LowerCaseEqualsASCII("report") || aAs.LowerCaseEqualsASCII("style") ||
aAs.LowerCaseEqualsASCII("track") || aAs.LowerCaseEqualsASCII("video") ||
aAs.LowerCaseEqualsASCII("webidentity") ||
aAs.LowerCaseEqualsASCII("xslt"));
}

bool CheckPreloadAttrs(const nsAttrValue& aAs, const nsAString& aType,
const nsAString& aMedia,
mozilla::dom::Document* aDocument) {
Expand Down
1 change: 0 additions & 1 deletion netwerk/base/nsNetUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -1039,7 +1039,6 @@ enum ASDestination : uint8_t {

void ParseAsValue(const nsAString& aValue, nsAttrValue& aResult);
nsContentPolicyType AsValueToContentPolicy(const nsAttrValue& aValue);
bool IsScriptLikeOrInvalid(const nsAString& aAs);

bool CheckPreloadAttrs(const nsAttrValue& aAs, const nsAString& aType,
const nsAString& aMedia,
Expand Down
8 changes: 4 additions & 4 deletions parser/html/nsHtml5SpeculativeLoad.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,8 +334,8 @@ class nsHtml5SpeculativeLoad {

/**
* True if and only if this is a speculative load initiated by <link
* rel="preload"> or <link rel="modulepreload"> tag encounter. Passed to the
* handling loader as an indication to raise the priority.
* rel="preload"> tag encounter. Passed to the handling loader as an
* indication to raise the priority.
*/
bool mIsLinkPreload;

Expand Down Expand Up @@ -387,8 +387,8 @@ class nsHtml5SpeculativeLoad {
* value of the "sizes" attribute. If the attribute is not set, this will
* be a void string. If mOpCode is eSpeculativeLoadStyle, this
* is the value of the "integrity" attribute. If the attribute is not set,
* this will be a void string. Otherwise, it is empty or the value of the type
* attribute.
* this will be a void string. Otherwise it is empty or the value of the
* referrer policy. Otherwise, it is empty or the value of the type attribute.
*/
nsString mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity;
/**
Expand Down
30 changes: 0 additions & 30 deletions parser/html/nsHtml5TreeBuilderCppSupplement.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

#include "ErrorList.h"
#include "nsError.h"
#include "nsNetUtil.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/Likely.h"
#include "mozilla/StaticPrefs_dom.h"
Expand Down Expand Up @@ -337,35 +336,6 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement(
}
// Other "as" values will be supported later.
}
} else if (mozilla::StaticPrefs::network_modulepreload() &&
rel.LowerCaseEqualsASCII("modulepreload")) {
nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
if (url && url.Length() != 0) {
nsHtml5String as =
aAttributes->getValue(nsHtml5AttributeName::ATTR_AS);
nsAutoString asString;
as.ToString(asString);
if (mozilla::net::IsScriptLikeOrInvalid(asString)) {
nsHtml5String charset =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
RefPtr<nsAtom> moduleType = nsGkAtoms::_module;
nsHtml5String type =
nsHtml5String::FromAtom(moduleType.forget());
nsHtml5String crossOrigin = aAttributes->getValue(
nsHtml5AttributeName::ATTR_CROSSORIGIN);
nsHtml5String media =
aAttributes->getValue(nsHtml5AttributeName::ATTR_MEDIA);
nsHtml5String integrity = aAttributes->getValue(
nsHtml5AttributeName::ATTR_INTEGRITY);
nsHtml5String referrerPolicy = aAttributes->getValue(
nsHtml5AttributeName::ATTR_REFERRERPOLICY);
mSpeculativeLoadQueue.AppendElement()->InitScript(
url, charset, type, crossOrigin, media, integrity,
referrerPolicy, mode == nsHtml5TreeBuilder::IN_HEAD,
false, false, false, true);
}
}
}
}
} else if (nsGkAtoms::video == aName) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[avoid-delaying-onload-link-modulepreload-exec.html]
expected: ERROR
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[avoid-delaying-onload-link-modulepreload.html]
expected: ERROR
47 changes: 47 additions & 0 deletions testing/web-platform/meta/preload/modulepreload.html.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
[modulepreload.html]
expected: TIMEOUT
[link rel=modulepreload]
expected: TIMEOUT

[link rel=modulepreload with submodules]
expected: NOTRUN

[link rel=modulepreload for a module with syntax error]
expected: NOTRUN

[link rel=modulepreload for a module with network error]
expected: NOTRUN

[link rel=modulepreload with bad href attribute]
expected: NOTRUN

[link rel=modulepreload as=script]
expected: NOTRUN

[link rel=modulepreload with invalid as= value]
expected: NOTRUN

[link rel=modulepreload with integrity match]
expected: NOTRUN

[link rel=modulepreload with integrity mismatch]
expected: NOTRUN

[cross-origin link rel=modulepreload]
expected: NOTRUN

[cross-origin link rel=modulepreload crossorigin=anonymous]
expected: NOTRUN

[same-origin link rel=modulepreload crossorigin=anonymous]
expected: NOTRUN

[same-origin link rel=modulepreload crossorigin=use-credentials]
expected: NOTRUN

[cross-origin link rel=modulepreload crossorigin=use-credentials]
expected: NOTRUN

[link rel=modulepreload with integrity match2]
expected: NOTRUN

Loading

0 comments on commit 44fa46d

Please sign in to comment.