Skip to content

Commit b8d5882

Browse files
arturovtalxhub
authored andcommitted
fix(zone.js): allow enabling default beforeunload handling (#55875)
Prior to this commit, when zone.js was included, it wasn't possible to handle `beforeunload` events correctly if event handlers returned strings to prompt the user. With this change, we introduce a global configuration flag, `__zone_symbol__enable_beforeunload`, to allow consumers to enable the default `beforeunload` handling behavior. This flag is necessary to prevent any breaking changes resulting from this modification. The previous attempt to fix it caused a large number of failures in G3. Hence, we're hiding that fix behind the configuration flag. Closes #47579 PR Close #55875
1 parent b400e2e commit b8d5882

2 files changed

Lines changed: 30 additions & 1 deletion

File tree

packages/zone.js/lib/common/utils.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ export const isMix: boolean =
131131

132132
const zoneSymbolEventNames: {[eventName: string]: string} = {};
133133

134+
const enableBeforeunloadSymbol = zoneSymbol('enable_beforeunload');
135+
134136
const wrapFn = function (this: unknown, event: Event) {
135137
// https://github.com/angular/zone.js/issues/911, in IE, sometimes
136138
// event will be undefined, so we need to use window.event
@@ -165,7 +167,25 @@ const wrapFn = function (this: unknown, event: Event) {
165167
}
166168
} else {
167169
result = listener && listener.apply(this, arguments);
168-
if (result != undefined && !result) {
170+
if (
171+
// https://github.com/angular/angular/issues/47579
172+
// https://www.w3.org/TR/2011/WD-html5-20110525/history.html#beforeunloadevent
173+
// This is the only specific case we should check for. The spec defines that the
174+
// `returnValue` attribute represents the message to show the user. When the event
175+
// is created, this attribute must be set to the empty string.
176+
event.type === 'beforeunload' &&
177+
// To prevent any breaking changes resulting from this change, given that
178+
// it was already causing a significant number of failures in G3, we have hidden
179+
// that behavior behind a global configuration flag. Consumers can enable this
180+
// flag explicitly if they want the `beforeunload` event to be handled as defined
181+
// in the specification.
182+
_global[enableBeforeunloadSymbol] &&
183+
// The IDL event definition is `attribute DOMString returnValue`, so we check whether
184+
// `typeof result` is a string.
185+
typeof result === 'string'
186+
) {
187+
(event as BeforeUnloadEvent).returnValue = result;
188+
} else if (result != undefined && !result) {
169189
event.preventDefault();
170190
}
171191
}

packages/zone.js/lib/zone.configurations.api.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,15 @@ declare global {
636636
* trace.
637637
*/
638638
__zone_symbol__DISABLE_WRAPPING_UNCAUGHT_PROMISE_REJECTION?: boolean;
639+
640+
/**
641+
* https://github.com/angular/angular/issues/47579
642+
*
643+
* Enables the default `beforeunload` handling behavior, allowing the result of the event
644+
* handling invocation to be set on the event's `returnValue`. The browser may then prompt
645+
* the user with a string returned from the event handler.
646+
*/
647+
__zone_symbol__enable_beforeunload?: boolean;
639648
}
640649

641650
/**

0 commit comments

Comments
 (0)