UNPKG

chrome-devtools-frontend

Version:
248 lines (225 loc) • 9.17 kB
// Copyright 2019 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 * as Common from '../common/common.js'; // eslint-disable-line no-unused-vars import * as Host from '../host/host.js'; import * as i18n from '../i18n/i18n.js'; import * as SourceFrame from '../source_frame/source_frame.js'; import * as TextUtils from '../text_utils/text_utils.js'; // eslint-disable-line no-unused-vars import * as UI from '../ui/ui.js'; export const UIStrings = { /** *@description Text in Binary Resource View of the Network panel */ base: '`Base64`', /** * @description Text in Binary Resource View of the Network panel. Shown to the user as a status * message after the current text has been copied to the clipboard. Base64 is a format for encoding * data. */ copiedAsBase: 'Copied as `Base64`', /** *@description Text in Binary Resource View of the Network panel */ hexViewer: '`Hex` Viewer', /** * @description Text in Binary Resource View of the Network panel. Shown to the user as a status * message after the current text has been copied to the clipboard. Hex is short for hexadecimal, * and is a format for encoding data. */ copiedAsHex: 'Copied as `Hex`', /** *@description Text in Binary Resource View of the Network panel */ utf: '`UTF-8`', /** *@description Text in Binary Resource View of the Network panel. Shown to the user as a status * message after the current text has been copied to the clipboard. UTF-8 is a format for encoding data. */ copiedAsUtf: 'Copied as `UTF-8`', /** *@description Screen reader label for a select box that chooses how to display binary data in the Network panel */ binaryViewType: 'Binary view type', /** *@description Tooltip text that appears when hovering over the largeicon copy button in the Binary Resource View of the Network panel */ copyToClipboard: 'Copy to clipboard', /** *@description Text in Binary Resource View of the Network panel */ copyAsBase: 'Copy as `Base64`', /** *@description Text in Binary Resource View of the Network panel */ copyAsHex: 'Copy as `Hex`', /** *@description Text in Binary Resource View of the Network panel */ copyAsUtf: 'Copy as `UTF-8`', }; const str_ = i18n.i18n.registerUIStrings('network/BinaryResourceView.js', UIStrings); const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_); export class BinaryResourceView extends UI.Widget.VBox { /** * @param {string} base64content * @param {string} contentUrl * @param {!Common.ResourceType.ResourceType} resourceType */ constructor(base64content, contentUrl, resourceType) { super(); this.registerRequiredCSS('network/binaryResourceView.css', {enableLegacyPatching: false}); this._binaryResourceViewFactory = new SourceFrame.BinaryResourceViewFactory.BinaryResourceViewFactory(base64content, contentUrl, resourceType); this._toolbar = new UI.Toolbar.Toolbar('binary-view-toolbar', this.element); /** @type {!Array<!BinaryViewObject>} */ this._binaryViewObjects = [ new BinaryViewObject( 'base64', i18nString(UIStrings.base), i18nString(UIStrings.copiedAsBase), this._binaryResourceViewFactory.createBase64View.bind(this._binaryResourceViewFactory), this._binaryResourceViewFactory.base64.bind(this._binaryResourceViewFactory)), new BinaryViewObject( 'hex', i18nString(UIStrings.hexViewer), i18nString(UIStrings.copiedAsHex), this._binaryResourceViewFactory.createHexView.bind(this._binaryResourceViewFactory), this._binaryResourceViewFactory.hex.bind(this._binaryResourceViewFactory)), new BinaryViewObject( 'utf8', i18nString(UIStrings.utf), i18nString(UIStrings.copiedAsUtf), this._binaryResourceViewFactory.createUtf8View.bind(this._binaryResourceViewFactory), this._binaryResourceViewFactory.utf8.bind(this._binaryResourceViewFactory)), ]; this._binaryViewTypeSetting = Common.Settings.Settings.instance().createSetting('binaryViewType', 'hex'); this._binaryViewTypeCombobox = new UI.Toolbar.ToolbarComboBox(this._binaryViewTypeChanged.bind(this), i18nString(UIStrings.binaryViewType)); for (const viewObject of this._binaryViewObjects) { this._binaryViewTypeCombobox.addOption( this._binaryViewTypeCombobox.createOption(viewObject.label, viewObject.type)); } this._toolbar.appendToolbarItem(this._binaryViewTypeCombobox); const copyButton = new UI.Toolbar.ToolbarButton(i18nString(UIStrings.copyToClipboard), 'largeicon-copy'); copyButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, event => { this._copySelectedViewToClipboard(); }, this); this._toolbar.appendToolbarItem(copyButton); this._copiedText = new UI.Toolbar.ToolbarText(); this._copiedText.element.classList.add('binary-view-copied-text'); this._toolbar.element.appendChild(this._copiedText.element); /** @type {?number} */ this._addFadeoutSettimeoutId = null; /** @type {?UI.Widget.Widget} */ this._lastView = null; this._updateView(); } /** * @return {?BinaryViewObject} */ _getCurrentViewObject() { const filter = /** @param {!BinaryViewObject} obj */ obj => obj.type === this._binaryViewTypeSetting.get(); const binaryViewObject = this._binaryViewObjects.find(filter); console.assert( Boolean(binaryViewObject), `No binary view found for binary view type found in setting 'binaryViewType': ${ this._binaryViewTypeSetting.get()}`); return binaryViewObject || null; } async _copySelectedViewToClipboard() { const viewObject = this._getCurrentViewObject(); if (!viewObject) { return; } Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText((await viewObject.content()).content); this._copiedText.setText(viewObject.copiedMessage); this._copiedText.element.classList.remove('fadeout'); /** * @this {!BinaryResourceView} */ function addFadeoutClass() { this._copiedText.element.classList.add('fadeout'); } if (this._addFadeoutSettimeoutId) { clearTimeout(this._addFadeoutSettimeoutId); this._addFadeoutSettimeoutId = null; } this._addFadeoutSettimeoutId = window.setTimeout(addFadeoutClass.bind(this), 2000); } /** * @override */ wasShown() { this._updateView(); } _updateView() { const newViewObject = this._getCurrentViewObject(); if (!newViewObject) { return; } const newView = newViewObject.getView(); if (newView === this._lastView) { return; } if (this._lastView) { this._lastView.detach(); } this._lastView = newView; newView.show(this.element, this._toolbar.element); this._binaryViewTypeCombobox.selectElement().value = this._binaryViewTypeSetting.get(); } _binaryViewTypeChanged() { const selectedOption = /** @type {?HTMLOptionElement} */ (this._binaryViewTypeCombobox.selectedOption()); if (!selectedOption) { return; } const newViewType = selectedOption.value; if (this._binaryViewTypeSetting.get() === newViewType) { return; } this._binaryViewTypeSetting.set(newViewType); this._updateView(); } /** * @param {!UI.ContextMenu.ContextMenu} contextMenu * @param {string} submenuItemText */ addCopyToContextMenu(contextMenu, submenuItemText) { const copyMenu = contextMenu.clipboardSection().appendSubMenuItem(submenuItemText); const footerSection = copyMenu.footerSection(); footerSection.appendItem(i18nString(UIStrings.copyAsBase), async () => { const content = await this._binaryResourceViewFactory.base64(); Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(content.content); }); footerSection.appendItem(i18nString(UIStrings.copyAsHex), async () => { const content = await this._binaryResourceViewFactory.hex(); Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(content.content); }); footerSection.appendItem(i18nString(UIStrings.copyAsUtf), async () => { const content = await this._binaryResourceViewFactory.utf8(); Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(content.content); }); } } export class BinaryViewObject { /** * @param {string} type * @param {string} label * @param {string} copiedMessage * @param {function():!UI.Widget.Widget} createViewFn * @param {function():Promise<!TextUtils.ContentProvider.DeferredContent>} deferredContent */ constructor(type, label, copiedMessage, createViewFn, deferredContent) { this.type = type; this.label = label; this.copiedMessage = copiedMessage; this.content = deferredContent; this._createViewFn = createViewFn; /** @type {?UI.Widget.Widget} */ this._view = null; } /** * @return {!UI.Widget.Widget} */ getView() { if (!this._view) { this._view = this._createViewFn(); } return this._view; } }