UNPKG

8.35 kBPlain TextView Raw
1/*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31import * as _ProtocolClient from '../../core/protocol_client/protocol_client.js'; // eslint-disable-line @typescript-eslint/no-unused-vars
32import * as SDK from '../../core/sdk/sdk.js';
33import * as UI from '../../ui/legacy/legacy.js';
34
35import * as ExtensionAPI from './ExtensionAPI.js';
36import type {ExtensionServer} from './ExtensionServer.js';
37import {ExtensionNotifierView, ExtensionView} from './ExtensionView.js';
38
39export 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
95export 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
124export 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 // This may only happen if setPage() was called while we were evaluating the expression.
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}