Skip to content

Commit 1a36ec8

Browse files
authored
Send debug info from injected client to the debug extension (#1772)
1 parent 069b870 commit 1a36ec8

18 files changed

+848
-168
lines changed

dwds/CHANGELOG.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
1+
## 16.0.2-dev
2+
3+
- Include debug information in the event sent from the injected client to the
4+
Dart Debug Extension notifying that the Dart app is ready.
5+
- Include an optional param to `Dwds.start` to indicate whether it is running
6+
internally or externally.
7+
18
## 16.0.1
29

310
- Allow the following API to return `null` and add error handling:
411
- `LoadStrategy.serverPathForModule`
512
- `LoadStrategy.sourceMapPathForModule`
613
- Expression evaluation performance improvement:
7-
- Batch `ChromeProxyService.evaluate()` requests that are close in time
8-
and are executed in the same library and scope.
9-
- Update `package:file` version to `6.13` or greater to handle https://github.com/dart-lang/sdk/issues/49647.
14+
- Batch `ChromeProxyService.evaluate()` requests that are close in time and
15+
are executed in the same library and scope.
16+
- Update `package:file` version to `6.13` or greater to handle
17+
https://github.com/dart-lang/sdk/issues/49647.
1018

1119
## 16.0.0
1220

dwds/debug_extension_mv3/pubspec.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,9 @@ dev_dependencies:
1515
build: ^2.0.0
1616
build_web_compilers: ^3.0.0
1717
build_runner: ^2.0.6
18+
dwds: ^16.0.0
19+
20+
dependency_overrides:
21+
dwds:
22+
path: ..
23+

dwds/debug_extension_mv3/web/background.dart

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55
@JS()
66
library background;
77

8+
import 'dart:html';
9+
10+
import 'package:dwds/data/debug_info.dart';
811
import 'package:js/js.dart';
912

1013
import 'chrome_api.dart';
1114
import 'messaging.dart';
15+
import 'web_api.dart';
1216

1317
void main() {
1418
_registerListeners();
@@ -22,13 +26,27 @@ void _handleRuntimeMessages(
2226
dynamic jsRequest, MessageSender sender, Function sendResponse) async {
2327
if (jsRequest is! String) return;
2428

25-
interceptMessage(
29+
interceptMessage<DebugInfo>(
2630
message: jsRequest,
31+
expectedType: MessageType.debugInfo,
2732
expectedSender: Script.detector,
2833
expectedRecipient: Script.background,
29-
expectedType: MessageType.dartAppReady,
30-
messageHandler: (_) {
34+
messageHandler: (DebugInfo debugInfo) async {
35+
final currentTab = await _getTab();
36+
final currentUrl = currentTab?.url ?? '';
37+
final appUrl = debugInfo.appUrl ?? '';
38+
if (currentUrl.isEmpty || appUrl.isEmpty || currentUrl != appUrl) {
39+
console.warn(
40+
'Dart app detected at $appUrl but current tab is $currentUrl.');
41+
return;
42+
}
3143
// Update the icon to show that a Dart app has been detected:
3244
chrome.action.setIcon(IconInfo(path: 'dart.png'), /*callback*/ null);
3345
});
3446
}
47+
48+
Future<Tab?> _getTab() async {
49+
final query = QueryInfo(active: true, currentWindow: true);
50+
final tabs = List<Tab>.from(await promiseToFuture(chrome.tabs.query(query)));
51+
return tabs.isNotEmpty ? tabs.first : null;
52+
}

dwds/debug_extension_mv3/web/chrome_api.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ external Chrome get chrome;
1212
class Chrome {
1313
external Action get action;
1414
external Runtime get runtime;
15+
external Tabs get tabs;
1516
}
1617

1718
/// chrome.action APIs
@@ -66,6 +67,24 @@ class MessageSender {
6667
external factory MessageSender({String? id, String? url, Tab? tab});
6768
}
6869

70+
/// chrome.tabs APIs
71+
/// https://developer.chrome.com/docs/extensions/reference/tabs
72+
73+
@JS()
74+
@anonymous
75+
class Tabs {
76+
external Object query(QueryInfo queryInfo);
77+
}
78+
79+
@JS()
80+
@anonymous
81+
class QueryInfo {
82+
external bool get active;
83+
external bool get currentWindow;
84+
external String get url;
85+
external factory QueryInfo({bool? active, bool? currentWindow, String? url});
86+
}
87+
6988
@JS()
7089
@anonymous
7190
class Tab {

dwds/debug_extension_mv3/web/detector.dart

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
library detector;
77

88
import 'dart:html';
9+
import 'dart:js_util';
910
import 'package:js/js.dart';
1011

1112
import 'chrome_api.dart';
1213
import 'messaging.dart';
14+
import 'web_api.dart';
1315

1416
void main() {
1517
_registerListeners();
@@ -20,9 +22,14 @@ void _registerListeners() {
2022
}
2123

2224
void _onDartAppReadyEvent(Event event) {
25+
final debugInfo = getProperty(event, 'detail') as String?;
26+
if (debugInfo == null) {
27+
console.warn('Can\'t debug Dart app without debug info.');
28+
return;
29+
}
2330
_sendMessageToBackgroundScript(
24-
type: MessageType.dartAppReady,
25-
body: 'Dart app ready!',
31+
type: MessageType.debugInfo,
32+
body: debugInfo,
2633
);
2734
}
2835

dwds/debug_extension_mv3/web/messaging.dart

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ library messaging;
77

88
import 'dart:convert';
99

10+
import 'package:dwds/data/serializers.dart';
1011
import 'package:js/js.dart';
1112

1213
import 'web_api.dart';
@@ -21,7 +22,7 @@ enum Script {
2122
}
2223

2324
enum MessageType {
24-
dartAppReady;
25+
debugInfo;
2526

2627
factory MessageType.fromString(String value) {
2728
return MessageType.values.byName(value);
@@ -57,34 +58,34 @@ class Message {
5758

5859
String toJSON() {
5960
return jsonEncode({
60-
'type': type.name,
6161
'to': to.name,
6262
'from': from.name,
63-
'encodedBody': body,
63+
'type': type.name,
64+
'body': body,
6465
if (error != null) 'error': error,
6566
});
6667
}
6768
}
6869

69-
void interceptMessage({
70+
void interceptMessage<T>({
7071
required String? message,
7172
required MessageType expectedType,
7273
required Script expectedSender,
7374
required Script expectedRecipient,
74-
required void Function(String message) messageHandler,
75+
required void Function(T message) messageHandler,
7576
}) {
77+
if (message == null) return;
7678
try {
77-
if (message == null) return;
7879
final decodedMessage = Message.fromJSON(message);
7980
if (decodedMessage.type != expectedType ||
8081
decodedMessage.to != expectedRecipient ||
8182
decodedMessage.from != expectedSender) {
8283
return;
8384
}
84-
messageHandler(decodedMessage.body);
85+
messageHandler(
86+
serializers.deserialize(jsonDecode(decodedMessage.body)) as T);
8587
} catch (error) {
8688
console.warn(
87-
'Error intercepting $expectedType message from $expectedSender to $expectedRecipient: $error');
88-
return;
89+
'Error intercepting $expectedType from $expectedSender to $expectedRecipient: $error');
8990
}
9091
}

dwds/lib/dart_web_debug_service.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class Dwds {
8686
bool launchDevToolsInNewWindow = true,
8787
SdkConfigurationProvider? sdkConfigurationProvider,
8888
bool emitDebugEvents = true,
89+
bool isInternalBuild = false,
8990
}) async {
9091
globalLoadStrategy = loadStrategy;
9192
sdkConfigurationProvider ??= DefaultSdkConfigurationProvider();

dwds/lib/data/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# How to generate data files:
2+
3+
## Creating a new data file:
4+
5+
1. Create a new file for your data type in the `/data` directory with the
6+
`.dart` extension
7+
1. Create an abstract class for your data type (see existing files for examples)
8+
1. Add the new data type to `/data/serializers.dart` 4 Run:
9+
`dart run build_runner build` from DWDS root (this will generate the
10+
`.g.dart` file)
11+
12+
## To update an existing data file:
13+
14+
1. Make your changes
15+
1. Run: `dart run build_runner clean` from DWDS root
16+
1. Run: `dart run build_runner build` from DWDS root

dwds/lib/data/debug_info.dart

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:built_value/built_value.dart';
6+
import 'package:built_value/serializer.dart';
7+
8+
part 'debug_info.g.dart';
9+
10+
abstract class DebugInfo implements Built<DebugInfo, DebugInfoBuilder> {
11+
static Serializer<DebugInfo> get serializer => _$debugInfoSerializer;
12+
13+
factory DebugInfo([Function(DebugInfoBuilder) updates]) = _$DebugInfo;
14+
15+
DebugInfo._();
16+
17+
String? get appEntrypointPath;
18+
String? get appId;
19+
String? get appInstanceId;
20+
String? get appOrigin;
21+
String? get appUrl;
22+
String? get dwdsVersion;
23+
String? get extensionUrl;
24+
bool? get isInternalBuild;
25+
}

0 commit comments

Comments
 (0)