UNPKG

debug-server-next

Version:

Dev server for hippy-core.

101 lines (100 loc) 4.21 kB
// Copyright (c) 2020 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 i18n from '../../../../core/i18n/i18n.js'; import * as ComponentHelpers from '../../../components/helpers/helpers.js'; import * as LitHtml from '../../../lit-html/lit-html.js'; import cssVarSwatchStyles from './cssVarSwatch.css.js'; const UIStrings = { /** *@description Text displayed in a tooltip shown when hovering over a var() CSS function in the Styles pane when the custom property in this function does not exist. The parameter is the name of the property. *@example {--my-custom-property-name} PH1 */ sIsNotDefined: '{PH1} is not defined', }; const str_ = i18n.i18n.registerUIStrings('ui/legacy/components/inline_editor/CSSVarSwatch.ts', UIStrings); const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_); const { render, html, Directives } = LitHtml; const VARIABLE_FUNCTION_REGEX = /(var\()(\s*--[^,)]+)(.*)/; export class CSSVarSwatch extends HTMLElement { static litTagName = LitHtml.literal `devtools-css-var-swatch`; shadow = this.attachShadow({ mode: 'open' }); text = ''; computedValue = null; fromFallback = false; onLinkActivate = () => undefined; constructor() { super(); this.tabIndex = -1; this.addEventListener('focus', () => { const link = this.shadow.querySelector('[role="link"]'); if (link) { link.focus(); } }); } connectedCallback() { this.shadow.adoptedStyleSheets = [cssVarSwatchStyles]; } set data(data) { this.text = data.text; this.computedValue = data.computedValue; this.fromFallback = data.fromFallback; this.onLinkActivate = (variableName, event) => { if (event instanceof MouseEvent && event.button !== 0) { return; } if (event instanceof KeyboardEvent && !isEnterOrSpaceKey(event)) { return; } data.onLinkActivate(variableName); event.consume(true); }; this.render(); } parseVariableFunctionParts() { // When the value of CSS var() is greater than two spaces, only one is // always displayed, and the actual number of spaces is displayed when // editing is clicked. const result = this.text.replace(/\s{2,}/g, ' ').match(VARIABLE_FUNCTION_REGEX); if (!result) { return null; } return { pre: result[1], name: result[2], post: result[3], }; } get variableName() { const match = this.text.match(/--[^,)]+/); if (match) { return match[0]; } return ''; } renderLink(variableName) { const isDefined = this.computedValue && !this.fromFallback; const classes = Directives.classMap({ 'css-var-link': true, 'undefined': !isDefined, }); const title = isDefined ? this.computedValue : i18nString(UIStrings.sIsNotDefined, { PH1: variableName }); // The this.variableName's space must be removed, otherwise it cannot be triggered when clicked. const onActivate = isDefined ? this.onLinkActivate.bind(this, this.variableName.trim()) : null; return html `<span class="${classes}" title="${title}" @mousedown=${onActivate} @keydown=${onActivate} role="link" tabindex="-1">${variableName}</span>`; } render() { const functionParts = this.parseVariableFunctionParts(); if (!functionParts) { render('', this.shadow, { host: this }); return; } const link = this.renderLink(functionParts.name); // Disabled until https://crbug.com/1079231 is fixed. // clang-format off render(html `<span title="${this.computedValue || ''}">${functionParts.pre}${link}${functionParts.post}</span>`, this.shadow, { host: this }); // clang-format on } } ComponentHelpers.CustomElements.defineComponent('devtools-css-var-swatch', CSSVarSwatch);