UNPKG

chrome-devtools-frontend

Version:
146 lines (133 loc) 5.3 kB
// Copyright 2020 The Chromium Authors // 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 * as i18n from '../../core/i18n/i18n.js'; import type * as SDK from '../../core/sdk/sdk.js'; import type * as UI from '../../ui/legacy/legacy.js'; import {html, nothing, render} from '../../ui/lit/lit.js'; import * as VisualLogging from '../../ui/visual_logging/visual_logging.js'; import {AccessibilitySubPane} from './AccessibilitySubPane.js'; const UIStrings = { /** * @description Name of a tool which allows the developer to view the contents of the page in the * 'source order' (the order in which the HTML elements show up in the source code). In the * Accessibility panel. */ sourceOrderViewer: 'Source Order Viewer', /** * @description Text in Source Order Viewer of the Accessibility panel shown when the selected node has no child elements */ noSourceOrderInformation: 'No source order information available', /** * @description Text in Source Order Viewer of the Accessibility panel shown when the selected node has many child elements */ thereMayBeADelayInDisplaying: 'There may be a delay in displaying source order for elements with many children', /** * @description Checkbox label in Source Order Viewer of the Accessibility panel. Source order * means the order in which the HTML elements show up in the source code. */ showSourceOrder: 'Show source order', } as const; const str_ = i18n.i18n.registerUIStrings('panels/accessibility/SourceOrderView.ts', UIStrings); const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_); const MAX_CHILD_ELEMENTS_THRESHOLD = 300; interface ViewInput { childCount: number; showSourceOrder: boolean|undefined; onShowSourceOrderChanged: (showSourceOrder: boolean) => void; } type View = (input: ViewInput, output: unknown, target: HTMLElement) => void; const DEFAULT_VIEW: View = (input, _output, target) => { function onShowSourceOrderChanged(event: Event): void { const checkbox = event.currentTarget as UI.UIUtils.CheckboxLabel; input.onShowSourceOrderChanged(checkbox.checked); event.consume(); } // clang-format off render(html` ${input.showSourceOrder === undefined ? html` <div class="gray-info-message info-message-overflow"> ${i18nString(UIStrings.noSourceOrderInformation)} </div> ` : html` ${input.childCount >= MAX_CHILD_ELEMENTS_THRESHOLD ? html` <div class="gray-info-message info-message-overflow" id="source-order-warning"> ${i18nString(UIStrings.thereMayBeADelayInDisplaying)} </div> ` : nothing } <devtools-checkbox class="source-order-checkbox" jslog=${VisualLogging.toggle().track({click: true})} ?checked=${input.showSourceOrder} @change=${onShowSourceOrderChanged}> ${i18nString(UIStrings.showSourceOrder)} </devtools-checkbox> ` } `, target); // clang-format on }; export class SourceOrderPane extends AccessibilitySubPane { #childCount = 0; #showSourceOrder: boolean|undefined = undefined; readonly #view: View; constructor(view: View = DEFAULT_VIEW) { super({ title: i18nString(UIStrings.sourceOrderViewer), viewId: 'source-order-viewer', jslog: `${VisualLogging.section('source-order-viewer')}`, }); this.#view = view; } async setNodeAsync(node: SDK.DOMModel.DOMNode|null): Promise<void> { if (this.nodeInternal && this.#showSourceOrder) { this.nodeInternal.domModel().overlayModel().hideSourceOrderInOverlay(); } super.setNode(node); this.#childCount = this.nodeInternal?.childNodeCount() ?? 0; if (!this.nodeInternal || !this.#childCount) { this.#showSourceOrder = undefined; } else { if (!this.nodeInternal.children()) { await this.nodeInternal.getSubtree(1, false); } const children = this.nodeInternal.children() as SDK.DOMModel.DOMNode[]; if (!children.some(child => child.nodeType() === Node.ELEMENT_NODE)) { this.#showSourceOrder = undefined; } else if (this.#showSourceOrder === undefined) { this.#showSourceOrder = false; } if (this.#showSourceOrder) { this.nodeInternal.domModel().overlayModel().highlightSourceOrderInOverlay(this.nodeInternal); } } this.requestUpdate(); } override async performUpdate(): Promise<void> { const onShowSourceOrderChanged = (showSourceOrder: boolean): void => { if (!this.nodeInternal) { this.#showSourceOrder = undefined; return; } if (showSourceOrder) { this.nodeInternal.domModel().overlayModel().highlightSourceOrderInOverlay(this.nodeInternal); } else { this.nodeInternal.domModel().overlayModel().hideSourceOrderInOverlay(); } this.#showSourceOrder = showSourceOrder; }; const input = { childCount: this.#childCount, showSourceOrder: this.#showSourceOrder, onShowSourceOrderChanged, }; const output = undefined; this.#view(input, output, this.contentElement); } }