forked from mirrors/gecko-dev
Backed out changeset be054669251a (bug 1425310) for causing browser-chrome leaks on nsStringBuffer.
This commit is contained in:
parent
23b02093ca
commit
e95c76d3bf
13 changed files with 101 additions and 245 deletions
|
|
@ -9,7 +9,6 @@
|
||||||
#include "mozilla/AsyncEventDispatcher.h"
|
#include "mozilla/AsyncEventDispatcher.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/Components.h"
|
#include "mozilla/Components.h"
|
||||||
#include "mozilla/ConsoleReportCollector.h"
|
|
||||||
#include "mozilla/EventDispatcher.h"
|
#include "mozilla/EventDispatcher.h"
|
||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
|
|
@ -43,7 +42,6 @@
|
||||||
#include "DecoderTraits.h"
|
#include "DecoderTraits.h"
|
||||||
#include "MediaList.h"
|
#include "MediaList.h"
|
||||||
#include "nsAttrValueInlines.h"
|
#include "nsAttrValueInlines.h"
|
||||||
#include "js/loader/ModuleLoadRequest.h"
|
|
||||||
|
|
||||||
NS_IMPL_NS_NEW_HTML_ELEMENT(Link)
|
NS_IMPL_NS_NEW_HTML_ELEMENT(Link)
|
||||||
|
|
||||||
|
|
@ -314,30 +312,36 @@ nsresult HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
|
||||||
aNameSpaceID, aName, aValue, aOldValue, aSubjectPrincipal, aNotify);
|
aNameSpaceID, aName, aValue, aOldValue, aSubjectPrincipal, aNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep this and the arrays below in sync with ToLinkMask in LinkStyle.cpp.
|
static const DOMTokenListSupportedToken sSupportedRelValues[] = {
|
||||||
#define SUPPORTED_REL_VALUES_BASE \
|
// Keep this and the one below in sync with ToLinkMask in
|
||||||
"prefetch", "dns-prefetch", "stylesheet", "next", "alternate", "preconnect", \
|
// LinkStyle.cpp.
|
||||||
"icon", "search", nullptr
|
// "preload" must come first because it can be disabled.
|
||||||
|
"preload", "prefetch", "dns-prefetch", "stylesheet",
|
||||||
|
"next", "alternate", "preconnect", "icon",
|
||||||
|
"search", "modulepreload", nullptr};
|
||||||
|
|
||||||
static const DOMTokenListSupportedToken sSupportedRelValueCombinations[][12] = {
|
static const DOMTokenListSupportedToken sSupportedRelValuesWithManifest[] = {
|
||||||
{SUPPORTED_REL_VALUES_BASE},
|
// Keep this in sync with ToLinkMask in LinkStyle.cpp.
|
||||||
{"manifest", SUPPORTED_REL_VALUES_BASE},
|
// "preload" and "manifest" must come first because they can be disabled.
|
||||||
{"preload", SUPPORTED_REL_VALUES_BASE},
|
"preload", "manifest", "prefetch", "dns-prefetch", "stylesheet", "next",
|
||||||
{"preload", "manifest", SUPPORTED_REL_VALUES_BASE},
|
"alternate", "preconnect", "icon", "search", nullptr};
|
||||||
{"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
|
|
||||||
|
|
||||||
nsDOMTokenList* HTMLLinkElement::RelList() {
|
nsDOMTokenList* HTMLLinkElement::RelList() {
|
||||||
if (!mRelList) {
|
if (!mRelList) {
|
||||||
int index = (StaticPrefs::dom_manifest_enabled() ? 1 : 0) |
|
auto preload = StaticPrefs::network_preload();
|
||||||
(StaticPrefs::network_preload() ? 2 : 0) |
|
auto manifest = StaticPrefs::dom_manifest_enabled();
|
||||||
(StaticPrefs::network_modulepreload() ? 4 : 0);
|
if (manifest && preload) {
|
||||||
|
mRelList = new nsDOMTokenList(this, nsGkAtoms::rel,
|
||||||
mRelList = new nsDOMTokenList(this, nsGkAtoms::rel,
|
sSupportedRelValuesWithManifest);
|
||||||
sSupportedRelValueCombinations[index]);
|
} 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;
|
return mRelList;
|
||||||
}
|
}
|
||||||
|
|
@ -487,10 +491,7 @@ void HTMLLinkElement::
|
||||||
}
|
}
|
||||||
|
|
||||||
if (linkTypes & eMODULE_PRELOAD) {
|
if (linkTypes & eMODULE_PRELOAD) {
|
||||||
ScriptLoader* scriptLoader = OwnerDoc()->ScriptLoader();
|
if (!OwnerDoc()->ScriptLoader()->GetModuleLoader()) {
|
||||||
ModuleLoader* moduleLoader = scriptLoader->GetModuleLoader();
|
|
||||||
|
|
||||||
if (!moduleLoader) {
|
|
||||||
// For the print preview documents, at this moment it doesn't have module
|
// 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
|
// loader yet, as the (print preview) document is not attached to the
|
||||||
// nsIContentViewer yet, so it doesn't have the GlobalObject.
|
// nsIContentViewer yet, so it doesn't have the GlobalObject.
|
||||||
|
|
@ -500,54 +501,9 @@ void HTMLLinkElement::
|
||||||
return;
|
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(kNameSpaceID_None, 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 destination;
|
|
||||||
GetAs(destination);
|
|
||||||
if (!(destination.IsEmpty() ||
|
|
||||||
destination.LowerCaseEqualsLiteral("audioworklet") ||
|
|
||||||
destination.LowerCaseEqualsLiteral("paintworklet") ||
|
|
||||||
destination.LowerCaseEqualsLiteral("script") ||
|
|
||||||
destination.LowerCaseEqualsLiteral("serviceworker") ||
|
|
||||||
destination.LowerCaseEqualsLiteral("sharedworker") ||
|
|
||||||
destination.LowerCaseEqualsLiteral("worker"))) {
|
|
||||||
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
|
// https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-modulepreload-module-script-graph
|
||||||
// Step 1. Disallow further import maps given settings object.
|
// Step 1. Disallow further import maps given settings object.
|
||||||
moduleLoader->DisallowImportMaps();
|
OwnerDoc()->ScriptLoader()->GetModuleLoader()->DisallowImportMaps();
|
||||||
|
|
||||||
StartPreload(nsIContentPolicy::TYPE_SCRIPT);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,10 +62,9 @@ class Element;
|
||||||
* the script does not need to be fetched first.
|
* the script does not need to be fetched first.
|
||||||
* * mIsXSLT
|
* * mIsXSLT
|
||||||
* Set if we are in an XSLT request.
|
* Set if we are in an XSLT request.
|
||||||
* * mIsPreload
|
* * TODO: mIsPreload (will be moved from ScriptFetchOptions)
|
||||||
* Set for scripts that are preloaded in a
|
* Set for scripts that are preloaded in a
|
||||||
* <link rel="preload" as="script"> or <link rel="modulepreload">
|
* <link rel="preload" as="script"> element.
|
||||||
* element.
|
|
||||||
*
|
*
|
||||||
* In addition to describing how the ScriptLoadRequest will be loaded by the
|
* In addition to describing how the ScriptLoadRequest will be loaded by the
|
||||||
* DOM ScriptLoader, the ScriptLoadContext contains fields that facilitate
|
* DOM ScriptLoader, the ScriptLoadContext contains fields that facilitate
|
||||||
|
|
@ -114,7 +113,7 @@ class ScriptLoadContext : public JS::loader::LoadContextBase,
|
||||||
eDeferred,
|
eDeferred,
|
||||||
eAsync,
|
eAsync,
|
||||||
eLinkPreload // this is a load initiated by <link rel="preload"
|
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);
|
void SetScriptMode(bool aDeferAttr, bool aAsyncAttr, bool aLinkPreload);
|
||||||
|
|
|
||||||
|
|
@ -675,12 +675,12 @@ nsresult ScriptLoader::StartLoadInternal(
|
||||||
aRequest->GetScriptLoadContext()->IsTracking()));
|
aRequest->GetScriptLoadContext()->IsTracking()));
|
||||||
|
|
||||||
if (aRequest->GetScriptLoadContext()->IsLinkPreloadScript()) {
|
if (aRequest->GetScriptLoadContext()->IsLinkPreloadScript()) {
|
||||||
// This is <link rel="preload" as="script"> or <link rel="modulepreload">
|
// This is <link rel="preload" as="script"> initiated speculative load,
|
||||||
// initiated speculative load, put it to the group that is not blocked by
|
// put it to the group that is not blocked by leaders and doesn't block
|
||||||
// leaders and doesn't block follower at the same time. Giving it a much
|
// follower at the same time. Giving it a much higher priority will make
|
||||||
// higher priority will make this request be processed ahead of other
|
// this request be processed ahead of other Unblocked requests, but with
|
||||||
// Unblocked requests, but with the same weight as Leaders. This will make
|
// the same weight as Leaders. This will make us behave similar way for
|
||||||
// us behave similar way for both http2 and http1.
|
// both http2 and http1.
|
||||||
ScriptLoadContext::PrioritizeAsPreload(channel);
|
ScriptLoadContext::PrioritizeAsPreload(channel);
|
||||||
ScriptLoadContext::AddLoadBackgroundFlag(channel);
|
ScriptLoadContext::AddLoadBackgroundFlag(channel);
|
||||||
} else if (nsCOMPtr<nsIClassOfService> cos = do_QueryInterface(channel)) {
|
} else if (nsCOMPtr<nsIClassOfService> cos = do_QueryInterface(channel)) {
|
||||||
|
|
@ -786,8 +786,7 @@ nsresult ScriptLoader::StartLoadInternal(
|
||||||
aRequest->mURI, aRequest->CORSMode(), aRequest->mKind);
|
aRequest->mURI, aRequest->CORSMode(), aRequest->mKind);
|
||||||
aRequest->GetScriptLoadContext()->NotifyOpen(
|
aRequest->GetScriptLoadContext()->NotifyOpen(
|
||||||
key, channel, mDocument,
|
key, channel, mDocument,
|
||||||
aRequest->GetScriptLoadContext()->IsLinkPreloadScript(),
|
aRequest->GetScriptLoadContext()->IsLinkPreloadScript());
|
||||||
aRequest->IsModuleRequest());
|
|
||||||
|
|
||||||
if (aEarlyHintPreloaderId) {
|
if (aEarlyHintPreloaderId) {
|
||||||
nsCOMPtr<nsIHttpChannelInternal> channelInternal =
|
nsCOMPtr<nsIHttpChannelInternal> channelInternal =
|
||||||
|
|
|
||||||
|
|
@ -11616,21 +11616,12 @@
|
||||||
value: false
|
value: false
|
||||||
mirror: always
|
mirror: always
|
||||||
|
|
||||||
# Enables `<link rel="preload">` tag and `Link: rel=preload` response header
|
# Enables `<link rel="preload">` tag and `Link: rel=preload` response header handling.
|
||||||
# handling.
|
|
||||||
- name: network.preload
|
- name: network.preload
|
||||||
type: RelaxedAtomicBool
|
type: RelaxedAtomicBool
|
||||||
value: true
|
value: true
|
||||||
mirror: always
|
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)
|
# Enable 103 Early Hint status code (RFC 8297)
|
||||||
- name: network.early-hints.enabled
|
- name: network.early-hints.enabled
|
||||||
type: RelaxedAtomicBool
|
type: RelaxedAtomicBool
|
||||||
|
|
|
||||||
|
|
@ -336,27 +336,6 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement(
|
||||||
}
|
}
|
||||||
// Other "as" values will be supported later.
|
// 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 charset =
|
|
||||||
aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
|
|
||||||
nsHtml5String type = nsHtml5String::FromLiteral("module");
|
|
||||||
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) {
|
} else if (nsGkAtoms::video == aName) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
[avoid-delaying-onload-link-modulepreload-exec.html]
|
||||||
|
expected: ERROR
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
[avoid-delaying-onload-link-modulepreload.html]
|
||||||
|
expected: ERROR
|
||||||
47
testing/web-platform/meta/preload/modulepreload.html.ini
Normal file
47
testing/web-platform/meta/preload/modulepreload.html.ini
Normal file
|
|
@ -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
|
||||||
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<meta charset=utf-8>
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<link rel="modulepreload" href="resources/module1.js" integrity="sha384-invalid">
|
|
||||||
<script type="module" src="resources/module1.js" id="myscript"></script>
|
|
||||||
<body>
|
|
||||||
<script>
|
|
||||||
promise_test(() => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let myscript = document.querySelector('#myscript');
|
|
||||||
myscript.onerror = resolve;
|
|
||||||
myscript.onload = reject;
|
|
||||||
});
|
|
||||||
}, "Script should not be loaded if modulepreload's integrity is invalid");
|
|
||||||
</script>
|
|
||||||
|
|
@ -33,15 +33,6 @@ function attachAndWaitForError(element) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function attachAndWaitForTimeout(element, t) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
element.onload = reject;
|
|
||||||
element.onerror = reject;
|
|
||||||
t.step_timeout(resolve, 1000);
|
|
||||||
document.body.appendChild(element);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
promise_test(function(t) {
|
promise_test(function(t) {
|
||||||
var link = document.createElement('link');
|
var link = document.createElement('link');
|
||||||
link.rel = 'modulepreload';
|
link.rel = 'modulepreload';
|
||||||
|
|
@ -229,7 +220,7 @@ promise_test(function(t) {
|
||||||
var link = document.createElement('link');
|
var link = document.createElement('link');
|
||||||
link.rel = 'modulepreload';
|
link.rel = 'modulepreload';
|
||||||
link.href = 'resources/module1.js?integrity-match';
|
link.href = 'resources/module1.js?integrity-match';
|
||||||
link.integrity = 'sha256-+Ks3iNIiTq2ujlWhvB056cmXobrCFpU9hd60xZ1WCaA='
|
link.integrity = 'sha256-dOxReWMnMSPfUvxEbBqIrjNh8ZN8n05j7h3JmhF8gQc=%'
|
||||||
return attachAndWaitForLoad(link);
|
return attachAndWaitForLoad(link);
|
||||||
}, 'link rel=modulepreload with integrity match');
|
}, 'link rel=modulepreload with integrity match');
|
||||||
|
|
||||||
|
|
@ -237,7 +228,7 @@ promise_test(function(t) {
|
||||||
var link = document.createElement('link');
|
var link = document.createElement('link');
|
||||||
link.rel = 'modulepreload';
|
link.rel = 'modulepreload';
|
||||||
link.href = 'resources/module1.mjs?integrity-match';
|
link.href = 'resources/module1.mjs?integrity-match';
|
||||||
link.integrity = 'sha256-+Ks3iNIiTq2ujlWhvB056cmXobrCFpU9hd60xZ1WCaA='
|
link.integrity = 'sha256-dOxReWMnMSPfUvxEbBqIrjNh8ZN8n05j7h3JmhF8gQc=%'
|
||||||
return attachAndWaitForLoad(link);
|
return attachAndWaitForLoad(link);
|
||||||
}, 'link rel=modulepreload with integrity match2');
|
}, 'link rel=modulepreload with integrity match2');
|
||||||
|
|
||||||
|
|
@ -249,88 +240,5 @@ promise_test(function(t) {
|
||||||
return attachAndWaitForError(link);
|
return attachAndWaitForError(link);
|
||||||
}, 'link rel=modulepreload with integrity mismatch');
|
}, 'link rel=modulepreload with integrity mismatch');
|
||||||
|
|
||||||
promise_test(function(t) {
|
|
||||||
var link = document.createElement('link');
|
|
||||||
link.rel = 'modulepreload';
|
|
||||||
link.href = 'resources/module1.mjs?integrity-doesnotmatch';
|
|
||||||
link.integrity = 'sha256-dOxReWMnMSPfUvxEbBqIrjNh8ZN8n05j7h3JmhF8gQc='
|
|
||||||
return attachAndWaitForError(link);
|
|
||||||
}, 'link rel=modulepreload with integrity mismatch2');
|
|
||||||
|
|
||||||
promise_test(function(t) {
|
|
||||||
var link = document.createElement('link');
|
|
||||||
link.rel = 'modulepreload';
|
|
||||||
link.href = 'resources/module1.mjs?integrity-invalid';
|
|
||||||
link.integrity = 'sha256-dOxReWMnMSPfUvxEbBqIrjNh8ZN8n05j7h3JmhF8gQc=%'
|
|
||||||
return attachAndWaitForError(link);
|
|
||||||
}, 'link rel=modulepreload with integrity mismatch3');
|
|
||||||
|
|
||||||
promise_test(function(t) {
|
|
||||||
var link1 = document.createElement('link');
|
|
||||||
var link2 = document.createElement('link');
|
|
||||||
link1.rel = 'modulepreload';
|
|
||||||
link2.rel = 'modulepreload';
|
|
||||||
link1.href = 'resources/module1.js?same-url';
|
|
||||||
link2.href = 'resources/module1.js?same-url';
|
|
||||||
return Promise.all([
|
|
||||||
attachAndWaitForLoad(link1),
|
|
||||||
attachAndWaitForLoad(link2),
|
|
||||||
]);
|
|
||||||
}, 'multiple link rel=modulepreload with same href');
|
|
||||||
|
|
||||||
promise_test(function(t) {
|
|
||||||
var link1 = document.createElement('link');
|
|
||||||
var link2 = document.createElement('link');
|
|
||||||
link1.rel = 'modulepreload';
|
|
||||||
link2.rel = 'modulepreload';
|
|
||||||
link1.href = 'resources/module2.js?child-before';
|
|
||||||
link2.href = 'resources/module1.js?child-before';
|
|
||||||
return attachAndWaitForLoad(link1)
|
|
||||||
.then(() => attachAndWaitForLoad(link2))
|
|
||||||
.then(() => new Promise(r => t.step_timeout(r, 1000)))
|
|
||||||
.then(() => {
|
|
||||||
verifyNumberOfDownloads('resources/module2.js?child-before', 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
}, 'multiple link rel=modulepreload with child module before parent');
|
|
||||||
|
|
||||||
promise_test(function(t) {
|
|
||||||
var link = document.createElement('link');
|
|
||||||
link.rel = 'modulepreload';
|
|
||||||
link.href = 'resources/module1.mjs?matching-media';
|
|
||||||
link.media = 'all';
|
|
||||||
return attachAndWaitForLoad(link);
|
|
||||||
}, 'link rel=modulepreload with matching media');
|
|
||||||
|
|
||||||
promise_test(function(t) {
|
|
||||||
var link = document.createElement('link');
|
|
||||||
link.rel = 'modulepreload';
|
|
||||||
link.href = 'resources/module1.mjs?non-matching-media';
|
|
||||||
link.media = 'not all';
|
|
||||||
return attachAndWaitForTimeout(link, t);
|
|
||||||
}, 'link rel=modulepreload with non-matching media');
|
|
||||||
|
|
||||||
promise_test(function(t) {
|
|
||||||
var link = document.createElement('link');
|
|
||||||
link.rel = 'modulepreload';
|
|
||||||
link.href = 'resources/module1.mjs?empty-media';
|
|
||||||
link.media = '';
|
|
||||||
return attachAndWaitForLoad(link);
|
|
||||||
}, 'link rel=modulepreload with empty media');
|
|
||||||
|
|
||||||
promise_test(function(t) {
|
|
||||||
var link = document.createElement('link');
|
|
||||||
link.rel = 'modulepreload';
|
|
||||||
link.href = '';
|
|
||||||
return attachAndWaitForTimeout(link, t);
|
|
||||||
}, 'link rel=modulepreload with empty href');
|
|
||||||
|
|
||||||
promise_test(function(t) {
|
|
||||||
var link = document.createElement('link');
|
|
||||||
link.rel = 'modulepreload';
|
|
||||||
link.href = '';
|
|
||||||
link.as = 'fetch';
|
|
||||||
return attachAndWaitForTimeout(link, t);
|
|
||||||
}, 'link rel=modulepreload with empty href and invalid as= value');
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
|
|
@ -72,10 +72,11 @@ already_AddRefed<PreloaderBase> PreloadService::PreloadLinkElement(
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsAutoString as, charset, crossOrigin, integrity, referrerPolicy, rel, srcset,
|
nsAutoString as, charset, crossOrigin, integrity, referrerPolicy, srcset,
|
||||||
sizes, type, url;
|
sizes, type, url;
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> uri = aLinkElement->GetURI();
|
nsCOMPtr<nsIURI> uri = aLinkElement->GetURI();
|
||||||
|
aLinkElement->GetAs(as);
|
||||||
aLinkElement->GetCharset(charset);
|
aLinkElement->GetCharset(charset);
|
||||||
aLinkElement->GetImageSrcset(srcset);
|
aLinkElement->GetImageSrcset(srcset);
|
||||||
aLinkElement->GetImageSizes(sizes);
|
aLinkElement->GetImageSizes(sizes);
|
||||||
|
|
@ -83,15 +84,7 @@ already_AddRefed<PreloaderBase> PreloadService::PreloadLinkElement(
|
||||||
aLinkElement->GetCrossOrigin(crossOrigin);
|
aLinkElement->GetCrossOrigin(crossOrigin);
|
||||||
aLinkElement->GetIntegrity(integrity);
|
aLinkElement->GetIntegrity(integrity);
|
||||||
aLinkElement->GetReferrerPolicy(referrerPolicy);
|
aLinkElement->GetReferrerPolicy(referrerPolicy);
|
||||||
aLinkElement->GetRel(rel);
|
aLinkElement->GetType(type);
|
||||||
|
|
||||||
if (rel.LowerCaseEqualsASCII("modulepreload")) {
|
|
||||||
as = u"script"_ns;
|
|
||||||
type = u"module"_ns;
|
|
||||||
} else {
|
|
||||||
aLinkElement->GetAs(as);
|
|
||||||
aLinkElement->GetType(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto result = PreloadOrCoalesce(uri, url, aPolicyType, as, type, charset,
|
auto result = PreloadOrCoalesce(uri, url, aPolicyType, as, type, charset,
|
||||||
srcset, sizes, integrity, crossOrigin,
|
srcset, sizes, integrity, crossOrigin,
|
||||||
|
|
|
||||||
|
|
@ -124,8 +124,7 @@ void PreloaderBase::AddLoadBackgroundFlag(nsIChannel* aChannel) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreloaderBase::NotifyOpen(const PreloadHashKey& aKey,
|
void PreloaderBase::NotifyOpen(const PreloadHashKey& aKey,
|
||||||
dom::Document* aDocument, bool aIsPreload,
|
dom::Document* aDocument, bool aIsPreload) {
|
||||||
bool aIsModule) {
|
|
||||||
if (aDocument) {
|
if (aDocument) {
|
||||||
DebugOnly<bool> alreadyRegistered =
|
DebugOnly<bool> alreadyRegistered =
|
||||||
aDocument->Preloads().RegisterPreload(aKey, this);
|
aDocument->Preloads().RegisterPreload(aKey, this);
|
||||||
|
|
@ -138,8 +137,7 @@ void PreloaderBase::NotifyOpen(const PreloadHashKey& aKey,
|
||||||
mKey = aKey;
|
mKey = aKey;
|
||||||
mIsUsed = !aIsPreload;
|
mIsUsed = !aIsPreload;
|
||||||
|
|
||||||
// Start usage timer for rel="preload" but not for rel="modulepreload"
|
if (!mIsUsed && !mUsageTimer) {
|
||||||
if (!aIsModule && !mIsUsed && !mUsageTimer) {
|
|
||||||
auto callback = MakeRefPtr<UsageTimer>(this, aDocument);
|
auto callback = MakeRefPtr<UsageTimer>(this, aDocument);
|
||||||
NS_NewTimerWithCallback(getter_AddRefs(mUsageTimer), callback, 10000,
|
NS_NewTimerWithCallback(getter_AddRefs(mUsageTimer), callback, 10000,
|
||||||
nsITimer::TYPE_ONE_SHOT);
|
nsITimer::TYPE_ONE_SHOT);
|
||||||
|
|
@ -149,9 +147,8 @@ void PreloaderBase::NotifyOpen(const PreloadHashKey& aKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreloaderBase::NotifyOpen(const PreloadHashKey& aKey, nsIChannel* aChannel,
|
void PreloaderBase::NotifyOpen(const PreloadHashKey& aKey, nsIChannel* aChannel,
|
||||||
dom::Document* aDocument, bool aIsPreload,
|
dom::Document* aDocument, bool aIsPreload) {
|
||||||
bool aIsModule) {
|
NotifyOpen(aKey, aDocument, aIsPreload);
|
||||||
NotifyOpen(aKey, aDocument, aIsPreload, aIsModule);
|
|
||||||
mChannel = aChannel;
|
mChannel = aChannel;
|
||||||
|
|
||||||
nsCOMPtr<nsIInterfaceRequestor> callbacks;
|
nsCOMPtr<nsIInterfaceRequestor> callbacks;
|
||||||
|
|
|
||||||
|
|
@ -45,10 +45,9 @@ class PreloaderBase : public SupportsWeakPtr, public nsISupports {
|
||||||
// preload service to provide coalescing, and access to the preload when it
|
// preload service to provide coalescing, and access to the preload when it
|
||||||
// should be used for an actual load.
|
// should be used for an actual load.
|
||||||
void NotifyOpen(const PreloadHashKey& aKey, dom::Document* aDocument,
|
void NotifyOpen(const PreloadHashKey& aKey, dom::Document* aDocument,
|
||||||
bool aIsPreload, bool aIsModule = false);
|
bool aIsPreload);
|
||||||
void NotifyOpen(const PreloadHashKey& aKey, nsIChannel* aChannel,
|
void NotifyOpen(const PreloadHashKey& aKey, nsIChannel* aChannel,
|
||||||
dom::Document* aDocument, bool aIsPreload,
|
dom::Document* aDocument, bool aIsPreload);
|
||||||
bool aIsModule = false);
|
|
||||||
|
|
||||||
// Called when the load is about to be started all over again and thus this
|
// Called when the load is about to be started all over again and thus this
|
||||||
// PreloaderBase will be registered again with the same key. This method
|
// PreloaderBase will be registered again with the same key. This method
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue