Bug 1954685 - Unship onafterscriptexecute and onbeforescriptexecute events on Nightly; r=dom-core,webidl,saschanaz,devtools-reviewers,ochameau,hsivonen,jandem
Differential Revision: https://phabricator.services.mozilla.com/D241940
This commit is contained in:
@@ -924,8 +924,7 @@ async function doEagerEvalDOMGetters(commands) {
|
||||
[`typeof document.lastModified`, "string"],
|
||||
[`typeof document.readyState`, "string"],
|
||||
[`typeof document.designMode`, "string"],
|
||||
[`typeof document.onbeforescriptexecute`, "object"],
|
||||
[`typeof document.onafterscriptexecute`, "object"],
|
||||
[`typeof document.onabort`, "object"],
|
||||
|
||||
// Element
|
||||
[`typeof document.documentElement.scrollTop`, "number"],
|
||||
|
||||
@@ -5137,12 +5137,13 @@ static already_AddRefed<Event> GetEventWithTarget(
|
||||
nsresult nsContentUtils::DispatchTrustedEvent(
|
||||
Document* aDoc, EventTarget* aTarget, const nsAString& aEventName,
|
||||
CanBubble aCanBubble, Cancelable aCancelable, Composed aComposed,
|
||||
bool* aDefaultAction) {
|
||||
bool* aDefaultAction, SystemGroupOnly aSystemGroupOnly) {
|
||||
MOZ_ASSERT(!aEventName.EqualsLiteral("input") &&
|
||||
!aEventName.EqualsLiteral("beforeinput"),
|
||||
"Use DispatchInputEvent() instead");
|
||||
return DispatchEvent(aDoc, aTarget, aEventName, aCanBubble, aCancelable,
|
||||
aComposed, Trusted::eYes, aDefaultAction);
|
||||
aComposed, Trusted::eYes, aDefaultAction,
|
||||
ChromeOnlyDispatch::eNo, aSystemGroupOnly);
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -5154,13 +5155,11 @@ nsresult nsContentUtils::DispatchUntrustedEvent(
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult nsContentUtils::DispatchEvent(Document* aDoc, EventTarget* aTarget,
|
||||
const nsAString& aEventName,
|
||||
CanBubble aCanBubble,
|
||||
Cancelable aCancelable,
|
||||
Composed aComposed, Trusted aTrusted,
|
||||
bool* aDefaultAction,
|
||||
ChromeOnlyDispatch aOnlyChromeDispatch) {
|
||||
nsresult nsContentUtils::DispatchEvent(
|
||||
Document* aDoc, EventTarget* aTarget, const nsAString& aEventName,
|
||||
CanBubble aCanBubble, Cancelable aCancelable, Composed aComposed,
|
||||
Trusted aTrusted, bool* aDefaultAction,
|
||||
ChromeOnlyDispatch aOnlyChromeDispatch, SystemGroupOnly aSystemGroupOnly) {
|
||||
if (!aDoc || !aTarget) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
@@ -5174,6 +5173,8 @@ nsresult nsContentUtils::DispatchEvent(Document* aDoc, EventTarget* aTarget,
|
||||
}
|
||||
event->WidgetEventPtr()->mFlags.mOnlyChromeDispatch =
|
||||
aOnlyChromeDispatch == ChromeOnlyDispatch::eYes;
|
||||
event->WidgetEventPtr()->mFlags.mOnlySystemGroupDispatch =
|
||||
aSystemGroupOnly == SystemGroupOnly::eYes;
|
||||
|
||||
bool doDefault = aTarget->DispatchEvent(*event, CallerType::System, err);
|
||||
if (aDefaultAction) {
|
||||
|
||||
@@ -266,6 +266,7 @@ class nsContentUtils {
|
||||
using Trusted = mozilla::Trusted;
|
||||
using JSONBehavior = mozilla::dom::JSONBehavior;
|
||||
using RFPTarget = mozilla::RFPTarget;
|
||||
using SystemGroupOnly = mozilla::SystemGroupOnly;
|
||||
|
||||
public:
|
||||
static nsresult Init();
|
||||
@@ -1556,24 +1557,22 @@ class nsContentUtils {
|
||||
*/
|
||||
// TODO: annotate with `MOZ_CAN_RUN_SCRIPT`
|
||||
// (https://bugzilla.mozilla.org/show_bug.cgi?id=1625902).
|
||||
static nsresult DispatchTrustedEvent(Document* aDoc,
|
||||
mozilla::dom::EventTarget* aTarget,
|
||||
const nsAString& aEventName, CanBubble,
|
||||
Cancelable,
|
||||
Composed aComposed = Composed::eDefault,
|
||||
bool* aDefaultAction = nullptr);
|
||||
static nsresult DispatchTrustedEvent(
|
||||
Document* aDoc, mozilla::dom::EventTarget* aTarget,
|
||||
const nsAString& aEventName, CanBubble, Cancelable,
|
||||
Composed aComposed = Composed::eDefault, bool* aDefaultAction = nullptr,
|
||||
SystemGroupOnly aSystemGroupOnly = SystemGroupOnly::eNo);
|
||||
|
||||
// TODO: annotate with `MOZ_CAN_RUN_SCRIPT`
|
||||
// (https://bugzilla.mozilla.org/show_bug.cgi?id=1625902).
|
||||
static nsresult DispatchTrustedEvent(Document* aDoc,
|
||||
mozilla::dom::EventTarget* aTarget,
|
||||
const nsAString& aEventName,
|
||||
CanBubble aCanBubble,
|
||||
Cancelable aCancelable,
|
||||
bool* aDefaultAction) {
|
||||
static nsresult DispatchTrustedEvent(
|
||||
Document* aDoc, mozilla::dom::EventTarget* aTarget,
|
||||
const nsAString& aEventName, CanBubble aCanBubble, Cancelable aCancelable,
|
||||
bool* aDefaultAction,
|
||||
SystemGroupOnly aSystemGroupOnly = SystemGroupOnly::eNo) {
|
||||
return DispatchTrustedEvent(aDoc, aTarget, aEventName, aCanBubble,
|
||||
aCancelable, Composed::eDefault,
|
||||
aDefaultAction);
|
||||
aCancelable, Composed::eDefault, aDefaultAction,
|
||||
aSystemGroupOnly);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3577,7 +3576,8 @@ class nsContentUtils {
|
||||
Document* aDoc, mozilla::dom::EventTarget* aTarget,
|
||||
const nsAString& aEventName, CanBubble, Cancelable, Composed, Trusted,
|
||||
bool* aDefaultAction = nullptr,
|
||||
ChromeOnlyDispatch = ChromeOnlyDispatch::eNo);
|
||||
ChromeOnlyDispatch = ChromeOnlyDispatch::eNo,
|
||||
SystemGroupOnly = SystemGroupOnly::eNo);
|
||||
|
||||
// TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY static nsresult DispatchEvent(
|
||||
|
||||
@@ -12,15 +12,24 @@ 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">
|
||||
|
||||
var { AppConstants } = SpecialPowers.ChromeUtils.importESModule(
|
||||
"resource://gre/modules/AppConstants.sys.mjs"
|
||||
);
|
||||
|
||||
/** 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, curr, "correct beforescript (" + n + ")");
|
||||
is(lastBeforeExecute, AppConstants.NIGHTLY_BUILD ? null : curr, "correct beforescript (" + n + ")");
|
||||
document.addEventListener("afterscriptexecute", function(event) {
|
||||
afterCount++;
|
||||
lastBeforeExecute = null;
|
||||
@@ -29,13 +38,26 @@ function verifyScript(n) {
|
||||
"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, 4, "correct number of afterscriptexecute");
|
||||
is(afterCount, AppConstants.NIGHTLY_BUILD ? 0 : 4, "correct number of afterscriptexecute");
|
||||
is(afterCountForSystemGroup, 4, "correct number of afterscriptexecute for system group");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
@@ -64,17 +86,17 @@ document.body.appendChild(s);
|
||||
<!-- Test cancel using beforescriptexecute -->
|
||||
<script onbeforescriptexecute="return false;"
|
||||
onafterescriptexecute="window.firedAfterScriptExecuteForCancel = true;">
|
||||
ok(false, "should have been canceled");
|
||||
ok(AppConstants.NIGHTLY_BUILD, "should have been canceled");
|
||||
</script>
|
||||
<script>
|
||||
isnot(window.firedAfterScriptExecuteForCancel, true, "onafterscriptexecute executed");
|
||||
</script>
|
||||
|
||||
<!-- Test cancel using beforescriptexecute for external -->
|
||||
<script onbeforescriptexecute="return false;"
|
||||
<script onbeforescriptexecute="window.extFiredBeforeScriptExecuteForCancel = true; return false;"
|
||||
onafterescriptexecute="window.extFiredAfterScriptExecuteForCancel = true;"
|
||||
onload="window.extFiredLoadForCancel = true;"
|
||||
src="data:text/plain,ok(false, 'should have been canceled');">
|
||||
src="data:text/plain,ok(!window.extFiredBeforeScriptExecuteForCancel, 'should have been canceled');">
|
||||
</script>
|
||||
<script>
|
||||
isnot(window.extFiredAfterScriptExecuteForCancel, true, "onafterscriptexecute executed");
|
||||
@@ -86,17 +108,17 @@ is(extFiredLoadForCancel, true, "onload executed");
|
||||
onafterscriptexecute="window.afterDidExecute = true;"
|
||||
onload="window.loadDidExecute = true"
|
||||
onerror="window.errorDidExecute = true"
|
||||
src="data:text/plain,
|
||||
is(window.beforeDidExecute, true, 'onbeforescriptexecute executed');
|
||||
isnot(window.afterDidExecute, true, 'onafterscriptexecute executed');
|
||||
isnot(window.loadDidExecute, true, 'onload executed');
|
||||
isnot(window.errorDidExecute, true, 'onerror executed');
|
||||
">
|
||||
src="data:text/plain,window.didExecute=true">
|
||||
is(window.beforeDidExecute, AppConstants.NIGHTLY_BUILD ? undefined : true, '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(afterDidExecute, true, "onafterscriptexecute executed");
|
||||
is(loadDidExecute, true, "onload executed");
|
||||
isnot(window.errorDidExecute, true, "onerror executed");
|
||||
is(window.afterDidExecute, AppConstants.NIGHTLY_BUILD ? undefined : true, "onafterscriptexecute executed");
|
||||
is(window.loadDidExecute, true, "onload executed");
|
||||
is(window.errorDidExecute, undefined, "onerror executed");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -2435,7 +2435,10 @@ nsresult ScriptLoader::ProcessRequest(ScriptLoadRequest* aRequest) {
|
||||
if (runScript) {
|
||||
nsContentUtils::DispatchTrustedEvent(
|
||||
scriptElem->OwnerDoc(), scriptElem, u"beforescriptexecute"_ns,
|
||||
CanBubble::eYes, Cancelable::eYes, &runScript);
|
||||
CanBubble::eYes, Cancelable::eYes, &runScript,
|
||||
StaticPrefs::dom_events_script_execute_enabled()
|
||||
? SystemGroupOnly::eNo
|
||||
: SystemGroupOnly::eYes);
|
||||
}
|
||||
|
||||
// Inner window could have gone away after firing beforescriptexecute
|
||||
@@ -2454,9 +2457,12 @@ nsresult ScriptLoader::ProcessRequest(ScriptLoadRequest* aRequest) {
|
||||
doc->DecrementIgnoreDestructiveWritesCounter();
|
||||
}
|
||||
|
||||
nsContentUtils::DispatchTrustedEvent(scriptElem->OwnerDoc(), scriptElem,
|
||||
u"afterscriptexecute"_ns,
|
||||
CanBubble::eYes, Cancelable::eNo);
|
||||
nsContentUtils::DispatchTrustedEvent(
|
||||
scriptElem->OwnerDoc(), scriptElem, u"afterscriptexecute"_ns,
|
||||
CanBubble::eYes, Cancelable::eNo, nullptr,
|
||||
StaticPrefs::dom_events_script_execute_enabled()
|
||||
? SystemGroupOnly::eNo
|
||||
: SystemGroupOnly::eYes);
|
||||
}
|
||||
|
||||
FireScriptEvaluated(rv, aRequest);
|
||||
|
||||
@@ -373,7 +373,9 @@ 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.
|
||||
|
||||
@@ -137,25 +137,16 @@
|
||||
// Temporarily install a new onerror handler to catch script errors.
|
||||
var hasUncaughtError = false;
|
||||
var uncaughtError;
|
||||
var eventOptions = {__proto__: null, once: true};
|
||||
ReflectApply(EventTargetPrototypeAddEventListener, script, [
|
||||
"beforescriptexecute", function() {
|
||||
setGlobalOnError(function(messageOrEvent, source, lineno, colno, error) {
|
||||
hasUncaughtError = true;
|
||||
uncaughtError = error;
|
||||
return true;
|
||||
});
|
||||
}, eventOptions
|
||||
]);
|
||||
ReflectApply(EventTargetPrototypeAddEventListener, script, [
|
||||
"afterscriptexecute", function() {
|
||||
restoreGlobalOnError();
|
||||
}, eventOptions
|
||||
]);
|
||||
|
||||
setGlobalOnError(function(messageOrEvent, source, lineno, colno, error) {
|
||||
hasUncaughtError = true;
|
||||
uncaughtError = error;
|
||||
return true;
|
||||
});
|
||||
ReflectApply(HTMLScriptElementTextSetter, script, [code]);
|
||||
AppendChild(documentDocumentElement, script);
|
||||
RemoveChild(documentDocumentElement, script);
|
||||
restoreGlobalOnError();
|
||||
|
||||
if (hasUncaughtError)
|
||||
throw uncaughtError;
|
||||
@@ -554,7 +545,7 @@
|
||||
let nextScriptIndex = i + 1;
|
||||
if (nextScriptIndex < scripts.length) {
|
||||
var callNextAppend = () => appendScript(nextScriptIndex);
|
||||
script.addEventListener("afterscriptexecute", callNextAppend, {once: true});
|
||||
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
|
||||
|
||||
@@ -2914,6 +2914,12 @@
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
# Whether to dispatch `beforescriptexecute` and `afterscriptexecute` event.
|
||||
- name: dom.events.script_execute.enabled
|
||||
type: bool
|
||||
value: @IS_NOT_NIGHTLY_BUILD@
|
||||
mirror: always
|
||||
|
||||
# Whether to expose test interfaces of various sorts
|
||||
- name: dom.expose_test_interfaces
|
||||
type: bool
|
||||
|
||||
@@ -2,13 +2,21 @@
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[onbeforescriptexecute content attribute should not be supported]
|
||||
expected: FAIL
|
||||
expected:
|
||||
if nightly_build: PASS
|
||||
FAIL
|
||||
|
||||
[onafterscriptexecute content attribute should not be supported]
|
||||
expected: FAIL
|
||||
expected:
|
||||
if nightly_build: PASS
|
||||
FAIL
|
||||
|
||||
[beforescriptexecute event should not be supported]
|
||||
expected: FAIL
|
||||
expected:
|
||||
if nightly_build: PASS
|
||||
FAIL
|
||||
|
||||
[afterscriptexecute event should not be supported]
|
||||
expected: FAIL
|
||||
expected:
|
||||
if nightly_build: PASS
|
||||
FAIL
|
||||
|
||||
@@ -48,6 +48,8 @@ enum class Trusted { eYes, eNo };
|
||||
|
||||
enum class Composed { eYes, eNo, eDefault };
|
||||
|
||||
enum class SystemGroupOnly { eYes, eNo };
|
||||
|
||||
/**
|
||||
* Event messages
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user