UNPKG

chrome-devtools-frontend

Version:
169 lines (149 loc) 7.21 kB
// Copyright (c) 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import '../../ui/legacy/legacy.js'; import type * as Common from '../../core/common/common.js'; import * as i18n from '../../core/i18n/i18n.js'; import * as Platform from '../../core/platform/platform.js'; import * as SDK from '../../core/sdk/sdk.js'; import * as UI from '../../ui/legacy/legacy.js'; import * as VisualLogging from '../../ui/visual_logging/visual_logging.js'; import {DeveloperResourcesListView} from './DeveloperResourcesListView.js'; import developerResourcesViewStyles from './developerResourcesView.css.js'; const UIStrings = { /** *@description Placeholder for a search field in a toolbar */ filterByText: 'Filter by URL and error', /** * @description Tooltip for a checkbox in the toolbar of the developer resources view. The * inspected target is the webpage that DevTools is debugging/inspecting/attached to. */ loadHttpsDeveloperResources: 'Load `HTTP(S)` developer resources through the website you inspect, not through DevTools', /** * @description Text for a checkbox in the toolbar of the developer resources view. The target is * the webpage that DevTools is debugging/inspecting/attached to. This setting makes it so * developer resources are requested from the webpage itself, and not from the DevTools * application. */ enableLoadingThroughTarget: 'Load through website', /** *@description Text for resources load status *@example {1} PH1 *@example {1} PH2 */ resourcesCurrentlyLoading: '{PH1} resources, {PH2} currently loading', /** * @description Status text that appears to tell the developer how many resources were loaded in * total. Resources are files related to the webpage. */ resources: '{n, plural, =1 {# resource} other {# resources}}', /** * @description Nnumber of resource(s) match */ numberOfResourceMatch: '{n, plural, =1 {# resource matches} other {# resources match}}', /** * @description No resource matches */ noResourceMatches: 'No resource matches', }; const str_ = i18n.i18n.registerUIStrings('panels/developer_resources/DeveloperResourcesView.ts', UIStrings); const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_); export class DeveloperResourcesRevealer implements Common.Revealer.Revealer<SDK.PageResourceLoader.ResourceKey> { async reveal(resourceInitiatorKey: SDK.PageResourceLoader.ResourceKey): Promise<void> { const loader = SDK.PageResourceLoader.PageResourceLoader.instance(); const resource = loader.getResourcesLoaded().get(resourceInitiatorKey.key); if (resource) { await UI.ViewManager.ViewManager.instance().showView('developer-resources'); const developerResourcesView = await UI.ViewManager.ViewManager.instance().view('developer-resources').widget() as DeveloperResourcesView; return developerResourcesView.select(resource); } } } export class DeveloperResourcesView extends UI.ThrottledWidget.ThrottledWidget { private textFilterRegExp: RegExp|null; private readonly filterInput: UI.Toolbar.ToolbarInput; private readonly coverageResultsElement: HTMLElement; private listView: DeveloperResourcesListView; private readonly statusToolbarElement: HTMLElement; private statusMessageElement: HTMLElement; private readonly loader: SDK.PageResourceLoader.PageResourceLoader; constructor() { super(true); this.registerRequiredCSS(developerResourcesViewStyles); this.element.setAttribute('jslog', `${VisualLogging.panel('developer-resources').track({resize: true})}`); const toolbarContainer = this.contentElement.createChild('div', 'developer-resource-view-toolbar-container'); toolbarContainer.setAttribute('jslog', `${VisualLogging.toolbar()}`); toolbarContainer.role = 'toolbar'; const toolbar = toolbarContainer.createChild('devtools-toolbar', 'developer-resource-view-toolbar'); toolbar.role = 'presentation'; this.textFilterRegExp = null; this.filterInput = new UI.Toolbar.ToolbarFilter(i18nString(UIStrings.filterByText), 1); this.filterInput.addEventListener(UI.Toolbar.ToolbarInput.Event.TEXT_CHANGED, this.onFilterChanged, this); toolbar.appendToolbarItem(this.filterInput); const loadThroughTarget = SDK.PageResourceLoader.getLoadThroughTargetSetting(); const loadThroughTargetCheckbox = new UI.Toolbar.ToolbarSettingCheckbox( loadThroughTarget, i18nString(UIStrings.loadHttpsDeveloperResources), i18nString(UIStrings.enableLoadingThroughTarget)); toolbar.appendToolbarItem(loadThroughTargetCheckbox); this.coverageResultsElement = this.contentElement.createChild('div', 'developer-resource-view-results'); this.listView = new DeveloperResourcesListView(); this.listView.show(this.coverageResultsElement); this.statusToolbarElement = this.contentElement.createChild('div', 'developer-resource-view-toolbar-summary'); this.statusMessageElement = this.statusToolbarElement.createChild('div', 'developer-resource-view-message'); this.loader = SDK.PageResourceLoader.PageResourceLoader.instance(); this.loader.addEventListener(SDK.PageResourceLoader.Events.UPDATE, this.update, this); this.update(); } override async doUpdate(): Promise<void> { const selectedItem = this.listView.selectedItem(); this.listView.reset(); this.listView.items = this.loader.getScopedResourcesLoaded().values(); if (selectedItem) { this.listView.select(selectedItem); } this.updateStats(); } async select(resource: SDK.PageResourceLoader.PageResource): Promise<void> { await this.lastUpdatePromise; this.listView.select(resource); } async selectedItem(): Promise<SDK.PageResourceLoader.PageResource|null> { await this.lastUpdatePromise; return this.listView.selectedItem(); } private updateStats(): void { const {loading, resources} = this.loader.getScopedNumberOfResources(); if (loading > 0) { this.statusMessageElement.textContent = i18nString(UIStrings.resourcesCurrentlyLoading, {PH1: resources, PH2: loading}); } else { this.statusMessageElement.textContent = i18nString(UIStrings.resources, {n: resources}); } } private onFilterChanged(): void { if (!this.listView) { return; } const text = this.filterInput.value(); this.textFilterRegExp = text ? Platform.StringUtilities.createPlainTextSearchRegex(text, 'i') : null; if (this.textFilterRegExp) { this.listView.updateFilterAndHighlight([ {key: 'url,error-message', regex: this.textFilterRegExp, negative: false}, ]); } else { this.listView.updateFilterAndHighlight([]); } this.updateStats(); const numberOfResourceMatch = this.listView.getNumberOfVisibleItems(); let resourceMatch = ''; if (numberOfResourceMatch === 0) { resourceMatch = i18nString(UIStrings.noResourceMatches); } else { resourceMatch = i18nString(UIStrings.numberOfResourceMatch, {n: numberOfResourceMatch}); } UI.ARIAUtils.alert(resourceMatch); } }