1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 | import * as _ProtocolClient from '../../core/protocol_client/protocol_client.js';
|
32 | import * as SDK from '../../core/sdk/sdk.js';
|
33 | import * as UI from '../../ui/legacy/legacy.js';
|
34 |
|
35 | import * as ExtensionAPI from './ExtensionAPI.js';
|
36 | import type {ExtensionServer} from './ExtensionServer.js';
|
37 | import {ExtensionNotifierView, ExtensionView} from './ExtensionView.js';
|
38 |
|
39 | export class ExtensionPanel extends UI.Panel.Panel implements UI.SearchableView.Searchable {
|
40 | private readonly server: ExtensionServer;
|
41 | private readonly id: string;
|
42 | private readonly panelToolbar: UI.Toolbar.Toolbar;
|
43 | private readonly searchableViewInternal: UI.SearchableView.SearchableView;
|
44 |
|
45 | constructor(server: ExtensionServer, panelName: string, id: string, pageURL: string) {
|
46 | super(panelName);
|
47 | this.server = server;
|
48 | this.id = id;
|
49 | this.setHideOnDetach();
|
50 | this.panelToolbar = new UI.Toolbar.Toolbar('hidden', this.element);
|
51 |
|
52 | this.searchableViewInternal = new UI.SearchableView.SearchableView(this, null);
|
53 | this.searchableViewInternal.show(this.element);
|
54 |
|
55 | const extensionView = new ExtensionView(server, this.id, pageURL, 'extension');
|
56 | extensionView.show(this.searchableViewInternal.element);
|
57 | }
|
58 |
|
59 | addToolbarItem(item: UI.Toolbar.ToolbarItem): void {
|
60 | this.panelToolbar.element.classList.remove('hidden');
|
61 | this.panelToolbar.appendToolbarItem(item);
|
62 | }
|
63 |
|
64 | searchCanceled(): void {
|
65 | this.server.notifySearchAction(this.id, ExtensionAPI.PrivateAPI.Panels.SearchAction.CancelSearch);
|
66 | this.searchableViewInternal.updateSearchMatchesCount(0);
|
67 | }
|
68 |
|
69 | searchableView(): UI.SearchableView.SearchableView {
|
70 | return this.searchableViewInternal;
|
71 | }
|
72 |
|
73 | performSearch(searchConfig: UI.SearchableView.SearchConfig, _shouldJump: boolean, _jumpBackwards?: boolean): void {
|
74 | const query = searchConfig.query;
|
75 | this.server.notifySearchAction(this.id, ExtensionAPI.PrivateAPI.Panels.SearchAction.PerformSearch, query);
|
76 | }
|
77 |
|
78 | jumpToNextSearchResult(): void {
|
79 | this.server.notifySearchAction(this.id, ExtensionAPI.PrivateAPI.Panels.SearchAction.NextSearchResult);
|
80 | }
|
81 |
|
82 | jumpToPreviousSearchResult(): void {
|
83 | this.server.notifySearchAction(this.id, ExtensionAPI.PrivateAPI.Panels.SearchAction.PreviousSearchResult);
|
84 | }
|
85 |
|
86 | supportsCaseSensitiveSearch(): boolean {
|
87 | return false;
|
88 | }
|
89 |
|
90 | supportsRegexSearch(): boolean {
|
91 | return false;
|
92 | }
|
93 | }
|
94 |
|
95 | export class ExtensionButton {
|
96 | private readonly id: string;
|
97 | private readonly toolbarButtonInternal: UI.Toolbar.ToolbarButton;
|
98 | constructor(server: ExtensionServer, id: string, iconURL: string, tooltip?: string, disabled?: boolean) {
|
99 | this.id = id;
|
100 |
|
101 | this.toolbarButtonInternal = new UI.Toolbar.ToolbarButton('', '');
|
102 | this.toolbarButtonInternal.addEventListener(
|
103 | UI.Toolbar.ToolbarButton.Events.Click, server.notifyButtonClicked.bind(server, this.id));
|
104 | this.update(iconURL, tooltip, disabled);
|
105 | }
|
106 |
|
107 | update(iconURL?: string, tooltip?: string, disabled?: boolean): void {
|
108 | if (typeof iconURL === 'string') {
|
109 | this.toolbarButtonInternal.setBackgroundImage(iconURL);
|
110 | }
|
111 | if (typeof tooltip === 'string') {
|
112 | this.toolbarButtonInternal.setTitle(tooltip);
|
113 | }
|
114 | if (typeof disabled === 'boolean') {
|
115 | this.toolbarButtonInternal.setEnabled(!disabled);
|
116 | }
|
117 | }
|
118 |
|
119 | toolbarButton(): UI.Toolbar.ToolbarButton {
|
120 | return this.toolbarButtonInternal;
|
121 | }
|
122 | }
|
123 |
|
124 | export class ExtensionSidebarPane extends UI.View.SimpleView {
|
125 | private readonly panelNameInternal: string;
|
126 | private server: ExtensionServer;
|
127 | private idInternal: string;
|
128 | private extensionView?: ExtensionView;
|
129 | private objectPropertiesView?: ExtensionNotifierView;
|
130 | constructor(server: ExtensionServer, panelName: string, title: string, id: string) {
|
131 | super(title);
|
132 | this.element.classList.add('fill');
|
133 | this.panelNameInternal = panelName;
|
134 | this.server = server;
|
135 | this.idInternal = id;
|
136 | }
|
137 |
|
138 | id(): string {
|
139 | return this.idInternal;
|
140 | }
|
141 |
|
142 | panelName(): string {
|
143 | return this.panelNameInternal;
|
144 | }
|
145 |
|
146 | setObject(object: Object, title: string|undefined, callback: (arg0?: (string|null)|undefined) => void): void {
|
147 | this.createObjectPropertiesView();
|
148 | this.setObjectInternal(SDK.RemoteObject.RemoteObject.fromLocalObject(object), title, callback);
|
149 | }
|
150 |
|
151 | setExpression(
|
152 | expression: string, title: string|undefined, evaluateOptions: Object|undefined, securityOrigin: string,
|
153 | callback: (arg0?: (string|null)|undefined) => void): void {
|
154 | this.createObjectPropertiesView();
|
155 | this.server.evaluate(
|
156 | expression, true, false, evaluateOptions, securityOrigin, this.onEvaluate.bind(this, title, callback));
|
157 | }
|
158 |
|
159 | setPage(url: string): void {
|
160 | if (this.objectPropertiesView) {
|
161 | this.objectPropertiesView.detach();
|
162 | delete this.objectPropertiesView;
|
163 | }
|
164 | if (this.extensionView) {
|
165 | this.extensionView.detach(true);
|
166 | }
|
167 |
|
168 | this.extensionView = new ExtensionView(this.server, this.idInternal, url, 'extension fill');
|
169 | this.extensionView.show(this.element);
|
170 |
|
171 | if (!this.element.style.height) {
|
172 | this.setHeight('150px');
|
173 | }
|
174 | }
|
175 |
|
176 | setHeight(height: string): void {
|
177 | this.element.style.height = height;
|
178 | }
|
179 |
|
180 | private onEvaluate(
|
181 | title: string|undefined, callback: (arg0?: (string|null)|undefined) => void, error: string|null,
|
182 | result: SDK.RemoteObject.RemoteObject|null, _wasThrown?: boolean): void {
|
183 | if (error) {
|
184 | callback(error.toString());
|
185 | } else if (!result) {
|
186 | callback();
|
187 | } else {
|
188 | this.setObjectInternal(result, title, callback);
|
189 | }
|
190 | }
|
191 |
|
192 | private createObjectPropertiesView(): void {
|
193 | if (this.objectPropertiesView) {
|
194 | return;
|
195 | }
|
196 | if (this.extensionView) {
|
197 | this.extensionView.detach(true);
|
198 | delete this.extensionView;
|
199 | }
|
200 | this.objectPropertiesView = new ExtensionNotifierView(this.server, this.idInternal);
|
201 | this.objectPropertiesView.show(this.element);
|
202 | }
|
203 |
|
204 | private setObjectInternal(
|
205 | object: SDK.RemoteObject.RemoteObject, title: string|undefined,
|
206 | callback: (arg0?: (string|null)|undefined) => void): void {
|
207 | const objectPropertiesView = this.objectPropertiesView;
|
208 |
|
209 | if (!objectPropertiesView) {
|
210 | callback('operation cancelled');
|
211 | return;
|
212 | }
|
213 | objectPropertiesView.element.removeChildren();
|
214 | UI.UIUtils.Renderer.render(object, {title, editable: false}).then(result => {
|
215 | if (!result) {
|
216 | callback();
|
217 | return;
|
218 | }
|
219 | const firstChild = result.tree && result.tree.firstChild();
|
220 | if (firstChild) {
|
221 | firstChild.expand();
|
222 | }
|
223 | objectPropertiesView.element.appendChild(result.node);
|
224 | callback();
|
225 | });
|
226 | }
|
227 | }
|