-
Notifications
You must be signed in to change notification settings - Fork 313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use a HtmlElementView
for the debugger page
#1255
Conversation
I needed to override how we querySelectors for the debug page to run properly. I've cleaned up the way I do that and explained how it's used. Please review and ask questions. |
I am currently seeing this exception when loading the plugin I've created. ══╡ EXCEPTION CAUGHT BY SERVICES LIBRARY ╞══════════════════════════════════════════════════════════
The following StateError was thrown during a platform message response callback:
Bad state: Future already completed
When the exception was thrown, this was the stack:
dart:sdk_internal 37842:62 complete
package:flutter/src/services/binding.dart 177:18 <fn>
dart:sdk_internal 134370:31 push
package:flutter_web_plugins/src/plugin_registry.dart 84:27 handlePlatformMessage
dart:sdk_internal 42389:7 _async
package:flutter_web_plugins/src/plugin_registry.dart 76:37 handlePlatformMessage
dart:sdk_internal 159840:17 sendPlatformMessage
package:flutter/src/services/binding.dart 175:15 [_sendPlatformMessage]
package:flutter/src/services/binding.dart 221:12 send
package:flutter/src/services/platform_channel.dart 314:51 invokeMethod
dart:sdk_internal 42389:7 _async
package:flutter/src/services/platform_channel.dart 312:28 invokeMethod
package:flutter/src/services/platform_channel.dart 446:3 [invokeMethod]
package:flutter/src/services/platform_channel.dart 429:36 invokeMethod$
dart:sdk_internal 42389:7 _async
package:flutter/src/services/platform_channel.dart 427:28 invokeMethod
package:flutter/src/services/system_sound.dart 23:35 play
dart:sdk_internal 42389:7 _async
package:flutter/src/services/system_sound.dart 22:27 play
package:flutter/src/material/feedback.dart 98:28 forTap
dart:sdk_internal 42389:7 _async
package:flutter/src/material/feedback.dart 93:29 forTap
package:flutter/src/material/ink_well.dart 700:33 [_handleTap]
package:flutter/src/material/ink_well.dart 783:36 <fn>
package:flutter/src/gestures/recognizer.dart 182:24 invokeCallback
package:flutter/src/gestures/tap.dart 486:47 handleTapUp
package:flutter/src/gestures/tap.dart 264:5 [_checkUp]
package:flutter/src/gestures/tap.dart 199:7 handlePrimaryPointer
package:flutter/src/gestures/recognizer.dart 467:9 handleEvent
package:flutter/src/gestures/pointer_router.dart 75:12 [_dispatch]
package:flutter/src/gestures/pointer_router.dart 102:34 route
package:flutter/src/gestures/binding.dart 218:19 handleEvent
package:flutter/src/gestures/binding.dart 198:14 dispatchEvent
package:flutter/src/gestures/binding.dart 156:7 [_handlePointerEvent]
package:flutter/src/gestures/binding.dart 102:7 [_flushPointerEventQueue]
package:flutter/src/gestures/binding.dart 86:32 [_handlePointerDataPacket]
dart:sdk_internal 145346:11 <fn>
════════════════════════════════════════════════════════════════════════════════════════════════════
Another exception was thrown: Bad state: Future already completed |
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.
Can we make a Framework interface implemented by the dart:html and the Flutter versions of the app?
It should be pretty easy to make the couple of use cases covered by the debugger page work with the interface and then this page of the inspector can display toast and warning messages in a consistent way to the rest of the flutter things instead of doing odd and probably broken things when it needs to display warning messages, etc.
|
||
// We actually use dart:html here, no shim. | ||
// This code may only be compiled into the web app. | ||
import 'dart:ui' as web_ui; |
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.
dart:ui
should be aliased as ui
or dart_ui
not web_ui
.
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.
My goal here is to be very specific: Right now this code will only work in the Flutter web implementation of dart:ui.
Happy to consider alternatives, but it's important to get that across to readers of this code.
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.
how about
dart_ui_web
web_ui
made me think dart:html
but it might be just me.
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
// We actually use dart:html here, no shim. |
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.
remove the
// we actually use dart:html here, no shim.
All uses of html_shim are really using dart:html and throwing exceptions on other platforms.
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.
My goal here is to point out that this code and its transitive dependencies are intended to only run as web code, in spite of being part of the flutter app.
When we turn down the html app, we want to switch from html shim to regular dart:html.
import 'package:html_shim/html.dart' as html; | ||
|
||
import 'src/debugger/html_debugger_screen.dart'; | ||
import 'src/framework/html_framework.dart'; |
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.
including all of html_framework.dart worries me a bit as there is going to be a bunch of intentional overlap with the flutter framework.
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.
We need to quantify exactly which functionality needs to get tied in with Flutter. We can discuss this in detail in #1259
return _viewRoot; | ||
} | ||
_viewRoot = html.Element.tag('html'); | ||
html.HttpRequest.getString('debugger_screen.html').then((response) { |
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.
add an async helper method so you can use async await rather than then here.
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.
A then
is necessary here. This method is getting passed as a PlatformViewFactory, which is synchronous.
print('Built framework, building screen.'); | ||
_screen = HtmlDebuggerScreen(); | ||
_framework.addScreen(_screen); | ||
final observer = html.MutationObserver((mutations, observer) { |
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.
why are we using mutation observers here? Add a comment. It isn't clear whether you are hacking around something in the html framework or if this is something to do with Flutter plugins.
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.
This is waiting for content to attach to the page. I've updated the comments.
<link href="packages/octicons_css/octicons_4.4.0.css" rel="stylesheet"> | ||
<link href="packages/polymer_css/flex.css" rel="stylesheet"> | ||
<link href="packages/devtools_app/src/debugger/debugger.css" rel="stylesheet"> | ||
<link href="packages/devtools_app/src/inspector/inspector.css" rel="stylesheet"> |
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.
remove the inspector, logging, performance, profiler, info, and timeline
css files.
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.
Done.
<link href="packages/codemirror/codemirror.css" rel="stylesheet"> | ||
<script src="packages/codemirror/codemirror.js"></script> | ||
|
||
<script src="packages/devtools_app/src/ui/plotly.js"></script> |
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.
remove plotly.
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.
Done.
} | ||
</style> | ||
|
||
<script src="packages/ansi_up/ansi_up.js"></script> |
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.
add TODO to remove ansi_up.js
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.
What is ansi_up used for in the debugger view?
A flutter-specific implementation of ansi will probably end up different from the web implementation and we may not be able to use it.
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.
I believe ansi_up is used for debugger console output
<nav class="masthead-nav" id="main-nav"> | ||
<!-- add the known pages --> | ||
<a disabled> | ||
<span class="octicon octicon-device-mobile"></span> |
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.
why is all this content still here? it doesn't make sense if this is just the debugger screen.
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 framework crashes if it can't find this content. I've marked it as hidden to get it to work.
Ideally, we strip down Framework and only take the steps necessary to show the debugger screen.
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.
better yet. rewrite the debugger page so the only dart:html dependency is the codemirror portion rather than the full page :)
<div id="messages-container" class="container legacy-dart"></div> | ||
|
||
<form id="ga-dialog" class="container legacy-dart"></form> | ||
<form id="connect-dialog" class="container legacy-dart"></form> |
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.
remove this as well. Basically strip this file way down to just what is needed for the debugger page.
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.
See previous comment.
final instance = DebuggerHtmlPlugin(); | ||
// ignore:undefined_prefixed_name | ||
web_ui.platformViewRegistry | ||
.registerViewFactory('DebuggerFlutterPlugin', instance.build); |
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.
nit: trailing comma
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.
Done.
<!DOCTYPE html> | ||
|
||
<!-- | ||
Copyright 2018 The Chromium Authors. All rights reserved. |
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.
2019?
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.
Good catch.
|
||
<form id="ga-dialog" class="container legacy-dart"></form> | ||
<form id="connect-dialog" class="container legacy-dart"></form> | ||
<form id="snapshot-message" class="container legacy-dart"></form> |
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.
remove snapshot message
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.
See my discussion about the html framework above.
@@ -0,0 +1,152 @@ | |||
<!DOCTYPE html> |
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.
For the code shared between this page and index.html, maybe add a comment to both that updating shared code in one file requires updating the other.
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.
Good idea, done.
.copyWith(color: theme.accentColor); | ||
return Center( | ||
child: Text( | ||
'The debugger screen is only available on web.', |
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.
Add a second line explaining why to avoid any confusion that we thought we were debugging a non web app.
For example:
"Because we have yet to port the debugger to Flutter"
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.
Done.
// Don't build this in const because compile time const evaluation | ||
// will fail on non-web apps. | ||
// TODO(djshuckerow): Follow up on this: if this code won't compile | ||
// on desktop as a const, then the constructor shouldn't be const. | ||
// ignore:prefer_const_constructors |
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.
Use conditional imports instead of hacking around the const limitations.
On the web you would have this Screen widget.
On regular flutter you would have the kIsWeb fallback empty widget.
You can trigger which import is executed based on whether dart:html is available.
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.
We should treat this as a bug in Flutter. Android and iOS native view widgets do not have this issue when building.
I want to make sure that future Flutter for web users don't need to be a special case.
flutter/flutter#43532
For showing platform views, we should be able to get a pattern like
switch(platform) {
case Platform.android:
return AndroidView(name);
case Platform.web:
return HtmlElementView(name);
case Platform.macos:
return MacosView(name);
// etc.
}
@@ -39,7 +39,9 @@ | |||
</head> | |||
|
|||
<body layout vertical style="width: 100%; height: 100%; background-color: transparent;"> |
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.
There might be quite a flash of oddly styled content when this screen is displayed. As we can't remove the content until 1259 is landed in a separate cl, at least make all the unstyled content be hidden by 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.
Everything except for the content div is already set to hidden.
The styles will be loaded before any of the other html content of this page, so I'm not sure what would come up as oddly styled.
I can set the entire body to be hidden until the framework loads the debugger screen, but I don't notice any difference between that and making no change.
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 is all I was looking for
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.
lgtm with some nits.
If the generated_plugin_constants gets generated before package package:tuneup checks the code, the inspection fails. We need to be able to tell tuneup or the analyzer to ignore lints in generated files. |
The only failure in the tests is caused by #1267, which this change doesn't affect. I'm merging this. |
Caveats:
Fixes #1182
For cross-referencing, this is the list of issues I've generated in Flutter out of this PR: