-
Notifications
You must be signed in to change notification settings - Fork 6k
[web] De-singletonize MouseCursor for multi-view #45295
Changes from 8 commits
231aedd
f4b93f7
6348d51
567299e
b803c12
c109a91
b29c5f6
1b949ec
48c2216
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,8 @@ import 'package:ui/ui_web/src/ui_web.dart' as ui_web; | |
| import '../engine.dart' show DimensionsProvider, registerHotRestartListener, renderer; | ||
| import 'display.dart'; | ||
| import 'dom.dart'; | ||
| import 'embedder.dart'; | ||
| import 'mouse/cursor.dart'; | ||
| import 'navigation/history.dart'; | ||
| import 'platform_dispatcher.dart'; | ||
| import 'services.dart'; | ||
|
|
@@ -29,8 +31,17 @@ const bool debugPrintPlatformMessages = false; | |
| /// The view ID for the implicit flutter view provided by the platform. | ||
| const int kImplicitViewId = 0; | ||
|
|
||
| /// Represents all views in the Flutter Web Engine. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that the class that represents all views in the Flutter Web Engine is
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here's a follow up PR to rename this class to make it clear that it's a singleton: #45981 |
||
| /// | ||
| /// In addition to everything defined in [ui.FlutterView], this class adds | ||
| /// a few web-specific properties. | ||
| abstract interface class EngineFlutterView extends ui.FlutterView { | ||
| MouseCursor get mouseCursor; | ||
| DomElement get rootElement; | ||
| } | ||
|
|
||
| /// The Web implementation of [ui.SingletonFlutterWindow]. | ||
| class EngineFlutterWindow extends ui.SingletonFlutterWindow { | ||
| class EngineFlutterWindow extends ui.SingletonFlutterWindow implements EngineFlutterView { | ||
| EngineFlutterWindow(this.viewId, this.platformDispatcher) { | ||
| platformDispatcher.viewData[viewId] = this; | ||
| platformDispatcher.windowConfigurations[viewId] = const ViewConfiguration(); | ||
|
|
@@ -53,6 +64,12 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow { | |
| @override | ||
| final EnginePlatformDispatcher platformDispatcher; | ||
|
|
||
| @override | ||
| late final MouseCursor mouseCursor = MouseCursor(rootElement); | ||
|
|
||
| @override | ||
| DomElement get rootElement => flutterViewEmbedder.flutterViewElement; | ||
|
|
||
| /// Handles the browser history integration to allow users to use the back | ||
| /// button, etc. | ||
| BrowserHistory get browserHistory { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| // Copyright 2013 The Flutter Authors. All rights reserved. | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| import 'package:test/bootstrap/browser.dart'; | ||
| import 'package:test/test.dart'; | ||
| import 'package:ui/src/engine.dart'; | ||
|
|
||
| void main() { | ||
| internalBootstrapBrowserTest(() => testMain); | ||
| } | ||
|
|
||
| void testMain() { | ||
| group('$MouseCursor', () { | ||
| test('sets correct `cursor` style on root element', () { | ||
| final DomElement rootViewElement = createDomElement('div'); | ||
| final MouseCursor mouseCursor = MouseCursor(rootViewElement); | ||
|
|
||
| mouseCursor.activateSystemCursor('alias'); | ||
| expect(rootViewElement.style.cursor, 'alias'); | ||
|
|
||
| mouseCursor.activateSystemCursor('move'); | ||
| expect(rootViewElement.style.cursor, 'move'); | ||
|
|
||
| mouseCursor.activateSystemCursor('precise'); | ||
| expect(rootViewElement.style.cursor, 'crosshair'); | ||
|
|
||
| mouseCursor.activateSystemCursor('resizeDownRight'); | ||
| expect(rootViewElement.style.cursor, 'se-resize'); | ||
| }); | ||
|
|
||
| test('handles unknown cursor type', () { | ||
| final DomElement rootViewElement = createDomElement('div'); | ||
| final MouseCursor mouseCursor = MouseCursor(rootViewElement); | ||
|
|
||
| mouseCursor.activateSystemCursor('unknown'); | ||
| expect(rootViewElement.style.cursor, 'default'); | ||
| }); | ||
| }); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only problem I can imagine with this is that if the
elementgets detached/deleted from the DOM, and then a system cursor event message comes, this might attempt to operate on a null instance. Since this is speculation and not a bug that we've seen so far, I say we don't worry about it for now.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's not a problem at all! The element is non-nullable and cannot become null. Yes, it can be detached/removed from the DOM tree, but it is still a valid element. In fact, in
cursor_test.dart, we are using detached elements to testMouseCursor.