mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 16:41:07 +00:00
[dart:html] Move NullWindowException to implementation
Window.open may open a null window in more cases than expected. Users may not care that the window they get back is invalid if they never use it. Therefore, this CL moves the exception to the implementation of the returned window in order to reduce noise, but still give a way for users to recover if they wish to do so. CoreLibraryReviewExempt: Backend-specific library. Change-Id: I005cf80630cfb4db2f5ec2012cfcd0161ad10ff1 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/311460 Commit-Queue: Srujan Gaddam <srujzs@google.com> Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
parent
d2f5b3bfab
commit
14a3051552
|
@ -36,14 +36,6 @@
|
||||||
[#51486]: https://github.com/dart-lang/sdk/issues/51486
|
[#51486]: https://github.com/dart-lang/sdk/issues/51486
|
||||||
[#52027]: https://github.com/dart-lang/sdk/issues/52027
|
[#52027]: https://github.com/dart-lang/sdk/issues/52027
|
||||||
|
|
||||||
#### `dart:html`
|
|
||||||
|
|
||||||
- **Breaking change to Window.open**:
|
|
||||||
`Window.open` will now throw an exception that can be caught
|
|
||||||
(`NullWindowException`) if the opened window is null. Previously, this null
|
|
||||||
window would be wrapped, and there would be surprising runtime errors when any
|
|
||||||
member is used on the wrapper.
|
|
||||||
|
|
||||||
#### `dart:js_interop`
|
#### `dart:js_interop`
|
||||||
|
|
||||||
- **Object literal constructors**:
|
- **Object literal constructors**:
|
||||||
|
|
|
@ -32154,8 +32154,6 @@ class Window extends EventTarget
|
||||||
/**
|
/**
|
||||||
* Opens a new window.
|
* Opens a new window.
|
||||||
*
|
*
|
||||||
* Throws a NullWindowException if the opened window is null.
|
|
||||||
*
|
|
||||||
* ## Other resources
|
* ## Other resources
|
||||||
*
|
*
|
||||||
* * [Window.open](https://developer.mozilla.org/en-US/docs/Web/API/Window.open)
|
* * [Window.open](https://developer.mozilla.org/en-US/docs/Web/API/Window.open)
|
||||||
|
@ -32164,7 +32162,6 @@ class Window extends EventTarget
|
||||||
WindowBase open(String url, String name, [String? options]) {
|
WindowBase open(String url, String name, [String? options]) {
|
||||||
final win =
|
final win =
|
||||||
options == null ? _open2(url, name) : _open3(url, name, options);
|
options == null ? _open2(url, name) : _open3(url, name, options);
|
||||||
if (win == null) throw new NullWindowException();
|
|
||||||
return _DOMWindowCrossFrame._createSafe(win);
|
return _DOMWindowCrossFrame._createSafe(win);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33782,7 +33779,7 @@ class Window extends EventTarget
|
||||||
class NullWindowException implements Exception {
|
class NullWindowException implements Exception {
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'Attempted to call Window.open with a null window.';
|
return 'Attempting to use a null window opened in Window.open.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||||
|
@ -40124,7 +40121,12 @@ class _DOMWindowCrossFrame implements WindowBase {
|
||||||
// Private window. Note, this is a window in another frame, so it
|
// Private window. Note, this is a window in another frame, so it
|
||||||
// cannot be typed as "Window" as its prototype is not patched
|
// cannot be typed as "Window" as its prototype is not patched
|
||||||
// properly. Its fields and methods can only be accessed via JavaScript.
|
// properly. Its fields and methods can only be accessed via JavaScript.
|
||||||
final Object _window;
|
final Object? __window;
|
||||||
|
|
||||||
|
Object get _window {
|
||||||
|
if (__window == null) throw new NullWindowException();
|
||||||
|
return __window!;
|
||||||
|
}
|
||||||
|
|
||||||
// Fields.
|
// Fields.
|
||||||
HistoryBase get history =>
|
HistoryBase get history =>
|
||||||
|
@ -40161,7 +40163,7 @@ class _DOMWindowCrossFrame implements WindowBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implementation support.
|
// Implementation support.
|
||||||
_DOMWindowCrossFrame(this._window);
|
_DOMWindowCrossFrame(this.__window);
|
||||||
|
|
||||||
static WindowBase _createSafe(w) {
|
static WindowBase _createSafe(w) {
|
||||||
if (identical(w, window)) {
|
if (identical(w, window)) {
|
||||||
|
|
|
@ -12,12 +12,15 @@ main() {
|
||||||
expect(window.scrollY, 0);
|
expect(window.scrollY, 0);
|
||||||
});
|
});
|
||||||
test('open', () {
|
test('open', () {
|
||||||
window.open('', 'blank');
|
final valid = window.open('', 'blank');
|
||||||
try {
|
valid.closed;
|
||||||
// A blank page with no access to the original window (noopener) should
|
// A blank page with no access to the original window (noopener) should
|
||||||
// result in null.
|
// result in null.
|
||||||
window.open('', 'invalid', 'noopener=true');
|
final invalid = window.open('', 'invalid', 'noopener=true');
|
||||||
fail('Expected Window.open to throw.');
|
try {
|
||||||
|
// Should result in an exception since the underlying window is null.
|
||||||
|
invalid.closed;
|
||||||
|
fail('Expected invalid.closed to throw.');
|
||||||
} on NullWindowException {}
|
} on NullWindowException {}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,4 +13,16 @@ main() {
|
||||||
expect(window.scrollX, 0);
|
expect(window.scrollX, 0);
|
||||||
expect(window.scrollY, 0);
|
expect(window.scrollY, 0);
|
||||||
});
|
});
|
||||||
|
test('open', () {
|
||||||
|
final valid = window.open('', 'blank');
|
||||||
|
valid.closed;
|
||||||
|
// A blank page with no access to the original window (noopener) should
|
||||||
|
// result in null.
|
||||||
|
final invalid = window.open('', 'invalid', 'noopener=true');
|
||||||
|
try {
|
||||||
|
// Should result in an exception since the underlying window is null.
|
||||||
|
invalid.closed;
|
||||||
|
fail('Expected invalid.closed to throw.');
|
||||||
|
} on NullWindowException {}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,12 @@ class _DOMWindowCrossFrame implements WindowBase {
|
||||||
// Private window. Note, this is a window in another frame, so it
|
// Private window. Note, this is a window in another frame, so it
|
||||||
// cannot be typed as "Window" as its prototype is not patched
|
// cannot be typed as "Window" as its prototype is not patched
|
||||||
// properly. Its fields and methods can only be accessed via JavaScript.
|
// properly. Its fields and methods can only be accessed via JavaScript.
|
||||||
final Object _window;
|
final Object? __window;
|
||||||
|
|
||||||
|
Object get _window {
|
||||||
|
if (__window == null) throw new NullWindowException();
|
||||||
|
return __window!;
|
||||||
|
}
|
||||||
|
|
||||||
// Fields.
|
// Fields.
|
||||||
HistoryBase get history =>
|
HistoryBase get history =>
|
||||||
|
@ -46,7 +51,7 @@ class _DOMWindowCrossFrame implements WindowBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implementation support.
|
// Implementation support.
|
||||||
_DOMWindowCrossFrame(this._window);
|
_DOMWindowCrossFrame(this.__window);
|
||||||
|
|
||||||
static WindowBase _createSafe(w) {
|
static WindowBase _createSafe(w) {
|
||||||
if (identical(w, window)) {
|
if (identical(w, window)) {
|
||||||
|
|
|
@ -50,8 +50,6 @@ $(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
|
||||||
/**
|
/**
|
||||||
* Opens a new window.
|
* Opens a new window.
|
||||||
*
|
*
|
||||||
* Throws a NullWindowException if the opened window is null.
|
|
||||||
*
|
|
||||||
* ## Other resources
|
* ## Other resources
|
||||||
*
|
*
|
||||||
* * [Window.open](https://developer.mozilla.org/en-US/docs/Web/API/Window.open)
|
* * [Window.open](https://developer.mozilla.org/en-US/docs/Web/API/Window.open)
|
||||||
|
@ -60,7 +58,6 @@ $(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
|
||||||
WindowBase open(String url, String name, [String$NULLABLE options]) {
|
WindowBase open(String url, String name, [String$NULLABLE options]) {
|
||||||
final win =
|
final win =
|
||||||
options == null ? _open2(url, name) : _open3(url, name, options);
|
options == null ? _open2(url, name) : _open3(url, name, options);
|
||||||
if (win == null) throw new NullWindowException();
|
|
||||||
return _DOMWindowCrossFrame._createSafe(win);
|
return _DOMWindowCrossFrame._createSafe(win);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,6 +256,6 @@ $!MEMBERS
|
||||||
class NullWindowException implements Exception {
|
class NullWindowException implements Exception {
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'Attempted to call Window.open with a null window.';
|
return 'Attempting to use a null window opened in Window.open.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue