Skip to content

Commit 318c5aa

Browse files
elliettepull[bot]
authored andcommitted
Add new WidgetInspector service extension: getRootWidgetTree (flutter#150010)
The new service extension `getRootWidgetTree` can be used instead of the existing: * `getRootWidgetSummaryTree` --> use`getRootWidgetTree` with parameters `isSummaryTree=true` * `getRootWidgetSummaryTreeWithPreviews` --> use `getRootWidgetTree` with parameters `isSummaryTree=true` and `withPreviews=true` This new service extension will enable Flutter DevTools to combine the widget summary tree with the widget details tree by calling `getRootWidgetTree` with `isSummary=false` and `withPreviews=true`. Closes flutter/devtools#7894
1 parent 3c0fdcb commit 318c5aa

File tree

4 files changed

+376
-55
lines changed

4 files changed

+376
-55
lines changed

packages/flutter/lib/src/widgets/service_extensions.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,22 @@ enum WidgetInspectorServiceExtensions {
366366
/// extension is registered.
367367
getRootWidget,
368368

369+
/// Name of service extension that, when called, will return the
370+
/// [DiagnosticsNode] data for the root [Element] of the widget tree.
371+
///
372+
/// If the parameter `isSummaryTree` is true, the tree will only include
373+
/// [Element]s that were created by user code.
374+
///
375+
/// If the parameter `withPreviews` is true, text previews will be included
376+
/// for [Element]s with a corresponding [RenderObject] of type
377+
/// [RenderParagraph].
378+
///
379+
/// See also:
380+
///
381+
/// * [WidgetInspectorService.initServiceExtensions], where the service
382+
/// extension is registered.
383+
getRootWidgetTree,
384+
369385
/// Name of service extension that, when called, will return the
370386
/// [DiagnosticsNode] data for the root [Element] of the summary tree, which
371387
/// only includes [Element]s that were created by user code.

packages/flutter/lib/src/widgets/widget_inspector.dart

Lines changed: 79 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,11 @@ mixin WidgetInspectorService {
12551255
callback: _getRootWidgetSummaryTreeWithPreviews,
12561256
registerExtension: registerExtension,
12571257
);
1258+
registerServiceExtension(
1259+
name: WidgetInspectorServiceExtensions.getRootWidgetTree.name,
1260+
callback: _getRootWidgetTree,
1261+
registerExtension: registerExtension,
1262+
);
12581263
registerServiceExtension(
12591264
name: WidgetInspectorServiceExtensions.getDetailsSubtree.name,
12601265
callback: (Map<String, String> parameters) async {
@@ -1951,42 +1956,93 @@ mixin WidgetInspectorService {
19511956
String groupName, {
19521957
Map<String, Object>? Function(DiagnosticsNode, InspectorSerializationDelegate)? addAdditionalPropertiesCallback,
19531958
}) {
1954-
return _nodeToJson(
1955-
WidgetsBinding.instance.rootElement?.toDiagnosticsNode(),
1956-
InspectorSerializationDelegate(
1957-
groupName: groupName,
1958-
subtreeDepth: 1000000,
1959-
summaryTree: true,
1960-
service: this,
1961-
addAdditionalPropertiesCallback: addAdditionalPropertiesCallback,
1962-
),
1959+
return _getRootWidgetTreeImpl(
1960+
groupName: groupName,
1961+
isSummaryTree: true,
1962+
withPreviews: false,
1963+
addAdditionalPropertiesCallback: addAdditionalPropertiesCallback,
19631964
);
19641965
}
19651966

1966-
19671967
Future<Map<String, Object?>> _getRootWidgetSummaryTreeWithPreviews(
19681968
Map<String, String> parameters,
19691969
) {
19701970
final String groupName = parameters['groupName']!;
1971-
final Map<String, Object?>? result = _getRootWidgetSummaryTree(
1972-
groupName,
1973-
addAdditionalPropertiesCallback: (DiagnosticsNode node, InspectorSerializationDelegate? delegate) {
1974-
final Map<String, Object> additionalJson = <String, Object>{};
1975-
final Object? value = node.value;
1976-
if (value is Element) {
1977-
final RenderObject? renderObject = value.renderObject;
1978-
if (renderObject is RenderParagraph) {
1979-
additionalJson['textPreview'] = renderObject.text.toPlainText();
1980-
}
1981-
}
1982-
return additionalJson;
1983-
},
1971+
final Map<String, Object?>? result = _getRootWidgetTreeImpl(
1972+
groupName: groupName,
1973+
isSummaryTree: true,
1974+
withPreviews: true,
19841975
);
19851976
return Future<Map<String, dynamic>>.value(<String, dynamic>{
19861977
'result': result,
19871978
});
19881979
}
19891980

1981+
Future<Map<String, Object?>> _getRootWidgetTree(
1982+
Map<String, String> parameters,
1983+
) {
1984+
final String groupName = parameters['groupName']!;
1985+
final bool isSummaryTree = parameters['isSummaryTree'] == 'true';
1986+
final bool withPreviews = parameters['withPreviews'] == 'true';
1987+
1988+
final Map<String, Object?>? result = _getRootWidgetTreeImpl(
1989+
groupName: groupName,
1990+
isSummaryTree: isSummaryTree,
1991+
withPreviews: withPreviews,
1992+
);
1993+
1994+
return Future<Map<String, dynamic>>.value(<String, dynamic>{
1995+
'result': result,
1996+
});
1997+
}
1998+
1999+
Map<String, Object?>? _getRootWidgetTreeImpl({
2000+
required String groupName,
2001+
required bool isSummaryTree,
2002+
required bool withPreviews,
2003+
Map<String, Object>? Function(
2004+
DiagnosticsNode, InspectorSerializationDelegate)?
2005+
addAdditionalPropertiesCallback,
2006+
}) {
2007+
final bool shouldAddAdditionalProperties =
2008+
addAdditionalPropertiesCallback != null || withPreviews;
2009+
2010+
// Combine the given addAdditionalPropertiesCallback with logic to add text
2011+
// previews as well (if withPreviews is true):
2012+
Map<String, Object>? combinedAddAdditionalPropertiesCallback(
2013+
DiagnosticsNode node,
2014+
InspectorSerializationDelegate delegate,
2015+
) {
2016+
final Map<String, Object> additionalPropertiesJson =
2017+
addAdditionalPropertiesCallback?.call(node, delegate) ??
2018+
<String, Object>{};
2019+
if (!withPreviews) {
2020+
return additionalPropertiesJson;
2021+
}
2022+
final Object? value = node.value;
2023+
if (value is Element) {
2024+
final RenderObject? renderObject = value.renderObject;
2025+
if (renderObject is RenderParagraph) {
2026+
additionalPropertiesJson['textPreview'] =
2027+
renderObject.text.toPlainText();
2028+
}
2029+
}
2030+
return additionalPropertiesJson;
2031+
}
2032+
return _nodeToJson(
2033+
WidgetsBinding.instance.rootElement?.toDiagnosticsNode(),
2034+
InspectorSerializationDelegate(
2035+
groupName: groupName,
2036+
subtreeDepth: 1000000,
2037+
summaryTree: isSummaryTree,
2038+
service: this,
2039+
addAdditionalPropertiesCallback: shouldAddAdditionalProperties
2040+
? combinedAddAdditionalPropertiesCallback
2041+
: null,
2042+
),
2043+
);
2044+
}
2045+
19902046
/// Returns a JSON representation of the subtree rooted at the
19912047
/// [DiagnosticsNode] object that `diagnosticsNodeId` references providing
19922048
/// information needed for the details subtree view.

packages/flutter/test/foundation/service_extensions_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ void main() {
166166
tearDownAll(() async {
167167
// See widget_inspector_test.dart for tests of the ext.flutter.inspector
168168
// service extensions included in this count.
169-
int widgetInspectorExtensionCount = 28;
169+
int widgetInspectorExtensionCount = 29;
170170
if (WidgetInspectorService.instance.isWidgetCreationTracked()) {
171171
// Some inspector extensions are only exposed if widget creation locations
172172
// are tracked.

0 commit comments

Comments
 (0)