commit f212adc98da1cccad93acc367a0fe57a870a72be
parent 4b2c560c91239356425452245e6a61604cb0863a
Author: Mathew Hodson <mathew.hodson@gmail.com>
Date: Thu, 16 Oct 2025 14:44:48 +0000
Bug 1286822 - Remove beforescriptexecute/afterscriptexecute events r=webidl,emilio
Differential Revision: https://phabricator.services.mozilla.com/D264718
Diffstat:
17 files changed, 30 insertions(+), 223 deletions(-)
diff --git a/dom/base/nsDeprecatedOperationList.h b/dom/base/nsDeprecatedOperationList.h
@@ -54,6 +54,4 @@ DEPRECATED_OPERATION(DocumentReleaseCapture)
DEPRECATED_OPERATION(OffscreenCanvasToBlob)
DEPRECATED_OPERATION(SVGDeselectAll)
DEPRECATED_OPERATION(IDBObjectStoreCreateIndexLocale)
-DEPRECATED_OPERATION(BeforeScriptExecuteEvent)
-DEPRECATED_OPERATION(AfterScriptExecuteEvent)
DEPRECATED_OPERATION(FullscreenAttribute)
diff --git a/dom/base/nsDocumentWarningList.h b/dom/base/nsDocumentWarningList.h
@@ -16,5 +16,3 @@ DOCUMENT_WARNING(SVGRefLoop)
DOCUMENT_WARNING(SVGRefChainLengthExceeded)
DOCUMENT_WARNING(NotificationsRequireUserGestureDeprecation)
DOCUMENT_WARNING(DocumentSetDomainIgnored)
-DOCUMENT_WARNING(AfterScriptExecuteEventNotSupported)
-DOCUMENT_WARNING(BeforeScriptExecuteEventNotSupported)
diff --git a/dom/base/test/test_bug587931.html b/dom/base/test/test_bug587931.html
@@ -12,50 +12,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=587931
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=587931">Mozilla Bug 587931</a>
<pre id="test">
<script type="application/javascript">
-
-const gScriptExecuteEventEnabled = SpecialPowers.getBoolPref("dom.events.script_execute.enabled");
-
/** Test for Bug 587931 **/
SimpleTest.waitForExplicitFinish();
-var afterCount = 0;
-var lastBeforeExecute = null;
-var afterCountForSystemGroup = 0;
-// For system group
-var afterCountForSystemGroup = 0;
-var lastBeforeExecuteForSystemGroup = null;
-var expectedCurrentScriptInAfterScriptExecute = null;
function verifyScript(n) {
var curr = document.currentScript;
is(curr, document.getElementById(n), "correct script (" + n + ")");
- is(lastBeforeExecute, gScriptExecuteEventEnabled ? curr : null, "correct beforescript (" + n + ")");
- document.addEventListener("afterscriptexecute", function(event) {
- afterCount++;
- lastBeforeExecute = null;
- is(event.target, curr, "correct afterscript (" + n + ")");
- is(document.currentScript, expectedCurrentScriptInAfterScriptExecute,
- "document.currentScript in afterscriptexecute(" + n + ")");
- document.removeEventListener("afterscriptexecute", arguments.callee);
- });
- // Test system group
- SpecialPowers.wrap(document).addEventListener("afterscriptexecute", function(event) {
- afterCountForSystemGroup++;
- lastBeforeExecuteForSystemGroup = null;
- is(event.target, curr, "correct afterscript (" + n + ") for system group");
- is(document.currentScript, expectedCurrentScriptInAfterScriptExecute,
- "document.currentScript in afterscriptexecute(" + n + ") for system group");
- }, { mozSystemGroup: true, once: true });
}
-document.onbeforescriptexecute = function(event) {
- lastBeforeExecute = event.target;
-};
-// Test system group
-SpecialPowers.wrap(document).addEventListener("beforescriptexecute", function(event) {
- lastBeforeExecuteForSystemGroup = event.target;
-}, { mozSystemGroup: true });
window.addEventListener("load", function() {
- is(afterCount, gScriptExecuteEventEnabled ? 4 : 0, "correct number of afterscriptexecute");
- is(afterCountForSystemGroup, 4, "correct number of afterscriptexecute for system group");
SimpleTest.finish();
});
</script>
@@ -71,52 +35,12 @@ verifyScript("parse-inline");
var s = document.createElement("script");
s.textContent = "verifyScript('dom-inline');";
s.id = "dom-inline";
-expectedCurrentScriptInAfterScriptExecute = document.currentScript;
document.body.appendChild(s);
-expectedCurrentScriptInAfterScriptExecute = null;
s = document.createElement("script");
s.src = "data:text/plain,verifyScript('dom-ext');";
s.id = "dom-ext";
document.body.appendChild(s);
</script>
-
-<!-- Test cancel using beforescriptexecute -->
-<script onbeforescriptexecute="return false;"
- onafterescriptexecute="window.firedAfterScriptExecuteForCancel = true;">
-ok(!gScriptExecuteEventEnabled, "should have been canceled");
-</script>
-<script>
-isnot(window.firedAfterScriptExecuteForCancel, true, "onafterscriptexecute executed");
-</script>
-
-<!-- Test cancel using beforescriptexecute for external -->
-<script onbeforescriptexecute="window.extFiredBeforeScriptExecuteForCancel = true; return false;"
- onafterescriptexecute="window.extFiredAfterScriptExecuteForCancel = true;"
- onload="window.extFiredLoadForCancel = true;"
- src="data:text/plain,ok(!window.extFiredBeforeScriptExecuteForCancel, 'should have been canceled');">
-</script>
-<script>
-isnot(window.extFiredAfterScriptExecuteForCancel, true, "onafterscriptexecute executed");
-is(extFiredLoadForCancel, true, "onload executed");
-</script>
-
-<!-- Test that all events fire -->
-<script onbeforescriptexecute="window.beforeDidExecute = true;"
- onafterscriptexecute="window.afterDidExecute = true;"
- onload="window.loadDidExecute = true"
- onerror="window.errorDidExecute = true"
- src="data:text/plain,window.didExecute=true">
-is(window.beforeDidExecute, gScriptExecuteEventEnabled ? true : undefined, 'onbeforescriptexecute executed');
-is(window.afterDidExecute, undefined, 'onafterscriptexecute executed');
-is(window.didExecute, true, 'script executed');
-is(window.loadDidExecute, undefined, 'onload executed');
-is(window.errorDidExecute, undefined, 'onerror executed');
-</script>
-<script>
-is(window.afterDidExecute, gScriptExecuteEventEnabled ? true : undefined, "onafterscriptexecute executed");
-is(window.loadDidExecute, true, "onload executed");
-is(window.errorDidExecute, undefined, "onerror executed");
-</script>
</body>
</html>
diff --git a/dom/events/EventListenerManager.cpp b/dom/events/EventListenerManager.cpp
@@ -464,34 +464,6 @@ void EventListenerManager::AddEventListenerInternal(
case eFormRadioStateChange:
nsContentUtils::SetMayHaveFormRadioStateChangeListeners();
break;
- case eAfterScriptExecute:
- if (nsPIDOMWindowInner* window = GetInnerWindowForTarget()) {
- if (Document* doc = window->GetExtantDoc()) {
- doc->SetUseCounter(eUseCounter_AfterScriptExecuteEvent);
- if (StaticPrefs::dom_events_script_execute_enabled()) {
- doc->WarnOnceAbout(
- DeprecatedOperations::eAfterScriptExecuteEvent);
- } else {
- doc->WarnOnceAbout(
- Document::eAfterScriptExecuteEventNotSupported);
- }
- }
- }
- break;
- case eBeforeScriptExecute:
- if (nsPIDOMWindowInner* window = GetInnerWindowForTarget()) {
- if (Document* doc = window->GetExtantDoc()) {
- doc->SetUseCounter(eUseCounter_BeforeScriptExecuteEvent);
- if (StaticPrefs::dom_events_script_execute_enabled()) {
- doc->WarnOnceAbout(
- DeprecatedOperations::eBeforeScriptExecuteEvent);
- } else {
- doc->WarnOnceAbout(
- Document::eBeforeScriptExecuteEventNotSupported);
- }
- }
- }
- break;
default:
// XXX Use NS_ASSERTION here to print resolvedEventMessage since
// MOZ_ASSERT can take only string literal, not pointer to
diff --git a/dom/events/EventNameList.h b/dom/events/EventNameList.h
@@ -268,11 +268,6 @@ EVENT(cut, eCut, EventNameType_HTMLXUL | EventNameType_SVGGraphic,
eClipboardEventClass)
EVENT(paste, ePaste, EventNameType_HTMLXUL | EventNameType_SVGGraphic,
eClipboardEventClass)
-// Gecko-specific extensions that apply to elements
-EVENT(beforescriptexecute, eBeforeScriptExecute, EventNameType_HTMLXUL,
- eBasicEventClass)
-EVENT(afterscriptexecute, eAfterScriptExecute, EventNameType_HTMLXUL,
- eBasicEventClass)
FORWARDED_EVENT(blur, eBlur, EventNameType_HTMLXUL, eFocusEventClass)
ERROR_EVENT(error, eLoadError, EventNameType_All, eBasicEventClass)
diff --git a/dom/locales/en-US/chrome/dom/dom.properties b/dom/locales/en-US/chrome/dom/dom.properties
@@ -465,15 +465,6 @@ InvalidNamedFormControlUnfocusable=The invalid form control with name=‘%S’ i
# LOCALIZATION NOTE: %1$S is the granularity string received as argument by Selection.modify().
SelectionModifyGranualirtyUnsupported=Granularity “%1$S” is not supported yet for Selection.modify()
-# LOCALIZATION NOTE: Do not translate "afterscriptexecute".
-AfterScriptExecuteEventWarning=Adding a listener for afterscriptexecute events is deprecated and will be removed soon.
-# LOCALIZATION NOTE: Do not translate "beforescriptexecute".
-BeforeScriptExecuteEventWarning=Adding a listener for beforescriptexecute events is deprecated and will be removed soon.
-# LOCALIZATION NOTE: Do not translate "afterscriptexecute".
-AfterScriptExecuteEventNotSupportedWarning=Adding a listener for afterscriptexecute events is no longer supported.
-# LOCALIZATION NOTE: Do not translate "beforescriptexecute".
-BeforeScriptExecuteEventNotSupportedWarning=Adding a listener for beforescriptexecute events is no longer supported.
-
# LOCALIZATION NOTE: Do not translate "intercept()". %1$S is the overridden option, %2$S is the new value and %3$S is the old value.
PreviousInterceptCallOptionOverriddenWarning=The ’%1$S’ option for a previous call to intercept() was overridden by ’%2$S’, and the previous value ’%3$S’ will be ignored.
diff --git a/dom/script/ScriptLoadContext.h b/dom/script/ScriptLoadContext.h
@@ -209,12 +209,6 @@ class ScriptLoadContext : public JS::loader::LoadContextBase,
return mScriptElement;
}
- // Event target for beforescriptexecute/afterscriptexecute events.
- inline nsIScriptElement* GetScriptElementForExecuteEvents() const {
- MOZ_ASSERT(mScriptElement);
- return mScriptElement;
- }
-
// For ScriptLoader::mCurrentParserInsertedScript.
inline nsIScriptElement* GetScriptElementForCurrentParserInsertedScript()
const {
diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp
@@ -2457,15 +2457,6 @@ nsresult ScriptLoader::ProcessRequest(ScriptLoadRequest* aRequest) {
}
}
- nsCOMPtr<nsINode> scriptElem = do_QueryInterface(
- aRequest->GetScriptLoadContext()->GetScriptElementForExecuteEvents());
-
- nsCOMPtr<Document> doc;
- if (!aRequest->GetScriptLoadContext()->mIsInline ||
- aRequest->IsModuleRequest()) {
- doc = scriptElem->OwnerDoc();
- }
-
nsCOMPtr<nsIScriptElement> oldParserInsertedScript;
uint32_t parserCreated = aRequest->GetScriptLoadContext()->GetParserCreated();
if (parserCreated) {
@@ -2479,48 +2470,12 @@ nsresult ScriptLoader::ProcessRequest(ScriptLoadRequest* aRequest) {
FireScriptAvailable(NS_OK, aRequest);
- // The window may have gone away by this point, in which case there's no point
- // in trying to run the script.
-
{
// Try to perform a microtask checkpoint
nsAutoMicroTask mt;
}
- nsPIDOMWindowInner* pwin = mDocument->GetInnerWindow();
- bool runScript = !!pwin;
- if (runScript) {
- nsContentUtils::DispatchTrustedEvent(
- scriptElem->OwnerDoc(), scriptElem, u"beforescriptexecute"_ns,
- CanBubble::eYes, Cancelable::eYes, &runScript,
- StaticPrefs::dom_events_script_execute_enabled()
- ? SystemGroupOnly::eNo
- : SystemGroupOnly::eYes);
- }
-
- // Inner window could have gone away after firing beforescriptexecute
- pwin = mDocument->GetInnerWindow();
- if (!pwin) {
- runScript = false;
- }
-
- nsresult rv = NS_OK;
- if (runScript) {
- if (doc) {
- doc->IncrementIgnoreDestructiveWritesCounter();
- }
- rv = EvaluateScriptElement(aRequest);
- if (doc) {
- doc->DecrementIgnoreDestructiveWritesCounter();
- }
-
- nsContentUtils::DispatchTrustedEvent(
- scriptElem->OwnerDoc(), scriptElem, u"afterscriptexecute"_ns,
- CanBubble::eYes, Cancelable::eNo, nullptr,
- StaticPrefs::dom_events_script_execute_enabled()
- ? SystemGroupOnly::eNo
- : SystemGroupOnly::eYes);
- }
+ nsresult rv = EvaluateScriptElement(aRequest);
FireScriptEvaluated(rv, aRequest);
@@ -2902,19 +2857,21 @@ static void ExecuteCompiledScript(JSContext* aCx, ClassicScript* aLoaderScript,
}
}
+// https://html.spec.whatwg.org/#execute-the-script-element
nsresult ScriptLoader::EvaluateScriptElement(ScriptLoadRequest* aRequest) {
MOZ_ASSERT(aRequest->IsFinished());
+ MOZ_ASSERT(mDocument);
- // We need a document to evaluate scripts.
- if (!mDocument) {
- return NS_ERROR_FAILURE;
+ // The window may have gone away by this point, in which case there's no point
+ // in trying to run the script.
+ if (!mDocument->GetInnerWindow()) {
+ return NS_OK;
}
+ // 2. If el's preparation-time document is not equal to document, then return.
Document* ownerDoc =
aRequest->GetScriptLoadContext()->GetScriptOwnerDocument();
if (ownerDoc != mDocument) {
- // https://html.spec.whatwg.org/#prepare-the-script-element step 16
- // as of 2025-01-15
return NS_ERROR_FAILURE;
}
@@ -2942,13 +2899,22 @@ nsresult ScriptLoader::EvaluateScriptElement(ScriptLoadRequest* aRequest) {
globalObject = scriptGlobal;
}
- // This mechanism is currently only used when the parser returns
- // early due to this script loader having a current script. However,
- // now that we have this, we could migrate continuing after a
- // parser-blocking script to this same mechanism. Not doing it right
- // away to reduce risk of introducing bugs.
- auto maybeContinueParser = MakeScopeExit([&] {
+ // 5. If el's from an external file is true, or el's type is "module", then
+ // increment document's ignore-destructive-writes counter.
+ const bool ignoreDestructiveWrites =
+ !aRequest->GetScriptLoadContext()->mIsInline ||
+ aRequest->IsModuleRequest();
+ if (ignoreDestructiveWrites) {
+ ownerDoc->IncrementIgnoreDestructiveWritesCounter();
+ }
+
+ auto afterScript = MakeScopeExit([&] {
if (mContinueParsingDocumentAfterCurrentScript) {
+ // This mechanism is currently only used when the parser returns
+ // early due to this script loader having a current script. However,
+ // now that we have this, we could migrate continuing after a
+ // parser-blocking script to this same mechanism. Not doing it right
+ // away to reduce risk of introducing bugs.
mContinueParsingDocumentAfterCurrentScript = false;
if (mDocument) {
nsCOMPtr<nsIParser> parser = mDocument->CreatorParserOrNull();
@@ -2957,6 +2923,11 @@ nsresult ScriptLoader::EvaluateScriptElement(ScriptLoadRequest* aRequest) {
}
}
}
+ // 7. Decrement the ignore-destructive-writes counter of document, if it was
+ // incremented in the earlier step.
+ if (ignoreDestructiveWrites) {
+ ownerDoc->DecrementIgnoreDestructiveWritesCounter();
+ }
});
// Update our current script.
diff --git a/dom/svg/crashtests/1507961-1.html b/dom/svg/crashtests/1507961-1.html
@@ -2255,7 +2255,6 @@ try { var00127.setProperty("float", "-webkit-positioned"); } catch(e) { }
try { htmlvar00004.setAttribute("onautocompleteerror", "eventhandler3()"); } catch(e) { }
try { svgvar00012.setAttribute("direction", "rtl"); } catch(e) { }
try { var00013.scrollLeft = 0.909759935717; } catch(e) { }
-try { htmlvar00011.setAttribute("onbeforescriptexecute", "eventhandler2()"); } catch(e) { }
try { var00127.setProperty("counter-increment", "c"); } catch(e) { }
try { var00084.onwebkitanimationiteration = var00133; } catch(e) { }
try { var00057.setAttribute("hanging", "1"); } catch(e) { }
@@ -3932,7 +3931,6 @@ try { /* newvar{var00162:DOMRectReadOnly} */ var var00162 = var00163; } catch(e)
try { if (!var00162) { var00162 = GetVariable(fuzzervars, 'DOMRectReadOnly'); } else { SetVariable(var00162, 'DOMRectReadOnly'); } } catch(e) { }
try { /* newvar{var00161:double} */ var var00161 = var00162.top; } catch(e) { }
try { var00089.setAttribute("aria-relevant", "removals"); } catch(e) { }
-try { htmlvar00017.setAttribute("onbeforescriptexecute", "eventhandler1()"); } catch(e) { }
try { var00132.stopImmediatePropagation(); } catch(e) { }
try { /* newvar{var00164:EventHandler} */ var var00164 = htmlvar00023.onmouseenter; } catch(e) { }
try { if (!var00164) { var00164 = GetVariable(fuzzervars, 'EventHandler'); } else { SetVariable(var00164, 'EventHandler'); } } catch(e) { }
diff --git a/dom/webidl/Document.webidl b/dom/webidl/Document.webidl
@@ -372,12 +372,6 @@ partial interface Document {
// Mozilla extensions of various sorts
partial interface Document {
- // @deprecated We are going to remove these (bug 1584269).
- [Pref="dom.events.script_execute.enabled"]
- attribute EventHandler onbeforescriptexecute;
- [Pref="dom.events.script_execute.enabled"]
- attribute EventHandler onafterscriptexecute;
-
// Creates a new XUL element regardless of the document's default type.
[ChromeOnly, CEReactions, NewObject, Throws]
Element createXULElement(DOMString localName, optional (ElementCreationOptions or DOMString) options = {});
diff --git a/gfx/layers/apz/test/mochitest/helper_wide_crossorigin_iframe_child.html b/gfx/layers/apz/test/mochitest/helper_wide_crossorigin_iframe_child.html
@@ -62,8 +62,6 @@ html {
window.onload = onloaded;
window.onDOMContentLoaded = sendDpToParent;
document.onreadystatechange = sendDpToParent;
- document.onafterscriptexecute = sendDpToParent;
- document.onbeforescriptexecute = sendDpToParent;
document.onvisibilitychange = sendDpToParent;
function onloaded() {
numMoreTimesToSend = 10;
diff --git a/js/src/tests/browser.js b/js/src/tests/browser.js
@@ -545,14 +545,8 @@
let nextScriptIndex = i + 1;
if (nextScriptIndex < scripts.length) {
var callNextAppend = () => appendScript(nextScriptIndex);
- SpecialPowers.wrap(script).addEventListener("afterscriptexecute", callNextAppend, {mozSystemGroup: true, once: true});
-
- // Module scripts don't fire the "afterscriptexecute" event when there
- // was an error, instead the "error" event is emitted. So listen for
- // both events when creating module scripts.
- if (spec.module) {
- script.addEventListener("error", callNextAppend, {once: true});
- }
+ script.addEventListener("load", callNextAppend, {once: true});
+ script.addEventListener("error", callNextAppend, {once: true});
}
scriptElements[i] = script;
diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml
@@ -3022,12 +3022,6 @@
value: true
mirror: always
-# Whether to dispatch `beforescriptexecute` and `afterscriptexecute` event.
-- name: dom.events.script_execute.enabled
- type: bool
- value: false
- mirror: always
-
# Whether to expose test interfaces of various sorts
- name: dom.expose_test_interfaces
type: bool
diff --git a/tools/@types/generated/lib.gecko.dom.d.ts b/tools/@types/generated/lib.gecko.dom.d.ts
@@ -7778,8 +7778,6 @@ declare var Directory: {
};
interface DocumentEventMap extends GlobalEventHandlersEventMap, OnErrorEventHandlerForNodesEventMap, TouchEventHandlersEventMap {
- "afterscriptexecute": Event;
- "beforescriptexecute": Event;
"fullscreenchange": Event;
"fullscreenerror": Event;
"pointerlockchange": Event;
@@ -7851,8 +7849,6 @@ interface Document extends Node, DocumentOrShadowRoot, FontFaceSource, GeometryU
readonly mozFullScreen: boolean;
readonly mozFullScreenEnabled: boolean;
readonly mozSyntheticDocument: boolean;
- onafterscriptexecute: ((this: Document, ev: Event) => any) | null;
- onbeforescriptexecute: ((this: Document, ev: Event) => any) | null;
onfullscreenchange: ((this: Document, ev: Event) => any) | null;
onfullscreenerror: ((this: Document, ev: Event) => any) | null;
onpointerlockchange: ((this: Document, ev: Event) => any) | null;
diff --git a/tools/@types/generated/lib.gecko.glean.d.ts b/tools/@types/generated/lib.gecko.glean.d.ts
@@ -3105,10 +3105,8 @@ interface GleanImpl {
}
useCounterDeprecatedOpsDoc: {
- afterScriptExecuteEvent: GleanCounter;
ambientLightEvent: GleanCounter;
appCache: GleanCounter;
- beforeScriptExecuteEvent: GleanCounter;
components: GleanCounter;
createImageBitmapCanvasRenderingContext2D: GleanCounter;
deprecatedTestingAttribute: GleanCounter;
@@ -3154,10 +3152,8 @@ interface GleanImpl {
}
useCounterDeprecatedOpsPage: {
- afterScriptExecuteEvent: GleanCounter;
ambientLightEvent: GleanCounter;
appCache: GleanCounter;
- beforeScriptExecuteEvent: GleanCounter;
components: GleanCounter;
createImageBitmapCanvasRenderingContext2D: GleanCounter;
deprecatedTestingAttribute: GleanCounter;
diff --git a/widget/EventMessageList.h b/widget/EventMessageList.h
@@ -395,10 +395,6 @@ NS_EVENT_MESSAGE(eSMILRepeatEvent)
NS_EVENT_MESSAGE(eAudioProcess)
NS_EVENT_MESSAGE(eAudioComplete)
-// script notification events
-NS_EVENT_MESSAGE(eBeforeScriptExecute)
-NS_EVENT_MESSAGE(eAfterScriptExecute)
-
NS_EVENT_MESSAGE(eBeforePrint)
NS_EVENT_MESSAGE(eAfterPrint)
diff --git a/xpcom/ds/StaticAtoms.py b/xpcom/ds/StaticAtoms.py
@@ -767,7 +767,6 @@ STATIC_ATOMS = [
Atom("onmozaccesskeynotfound", "onmozaccesskeynotfound"),
Atom("onactivate", "onactivate"),
Atom("onafterprint", "onafterprint"),
- Atom("onafterscriptexecute", "onafterscriptexecute"),
Atom("onanimationcancel", "onanimationcancel"),
Atom("onanimationend", "onanimationend"),
Atom("onanimationiteration", "onanimationiteration"),
@@ -781,7 +780,6 @@ STATIC_ATOMS = [
Atom("onbeforematch", "onbeforematch"),
Atom("onbeforepaste", "onbeforepaste"),
Atom("onbeforeprint", "onbeforeprint"),
- Atom("onbeforescriptexecute", "onbeforescriptexecute"),
Atom("onbeforeunload", "onbeforeunload"),
Atom("onblocked", "onblocked"),
Atom("onblur", "onblur"),