Files
react-native-devtools-frontend/front_end/elements/ColorSwatchPopoverIcon.js
T
Jesus David Garcia Gomez 206ff7c5a9 Normalize BezierPopoverIcon behavior
This CL will normalize the behavior of the Bezier picker and the color
picker in the styles sections.

For more info, you can see the issue related with the color picker:
https://crbug.com/1116327

Bug: 1126495
Change-Id: I13d17c6a8a3d46902b8017fc0a2fd75ac4d11bf5
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2412433
Commit-Queue: Jesus David Garcia Gomez <jegarc@microsoft.com>
Reviewed-by: Jose Leal <joselea@microsoft.com>
Reviewed-by: Alex Rudenko <alexrudenko@chromium.org>
2020-09-16 18:04:57 +00:00

361 lines
12 KiB
JavaScript

// Copyright (c) 2015 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.
// @ts-nocheck
// TODO(crbug.com/1011811): Enable TypeScript compiler checks
import * as Bindings from '../bindings/bindings.js';
import * as ColorPicker from '../color_picker/color_picker.js';
import * as Common from '../common/common.js';
import * as InlineEditor from '../inline_editor/inline_editor.js';
import * as UI from '../ui/ui.js';
import {StylePropertyTreeElement} from './StylePropertyTreeElement.js'; // eslint-disable-line no-unused-vars
/**
* @unrestricted
*/
export class BezierPopoverIcon {
/**
* @param {!StylePropertyTreeElement} treeElement
* @param {!InlineEditor.SwatchPopoverHelper.SwatchPopoverHelper} swatchPopoverHelper
* @param {!InlineEditor.ColorSwatch.BezierSwatch} swatch
*/
constructor(treeElement, swatchPopoverHelper, swatch) {
this._treeElement = treeElement;
this._swatchPopoverHelper = swatchPopoverHelper;
this._swatch = swatch;
this._swatch.iconElement().title = Common.UIString.UIString('Open cubic bezier editor.');
this._swatch.iconElement().addEventListener('click', this._iconClick.bind(this), false);
this._swatch.iconElement().addEventListener('mousedown', event => event.consume(), false);
this._boundBezierChanged = this._bezierChanged.bind(this);
this._boundOnScroll = this._onScroll.bind(this);
}
/**
* @param {!Event} event
*/
_iconClick(event) {
event.consume(true);
if (this._swatchPopoverHelper.isShowing()) {
this._swatchPopoverHelper.hide(true);
return;
}
this._bezierEditor = new InlineEditor.BezierEditor.BezierEditor();
let cubicBezier = UI.Geometry.CubicBezier.parse(this._swatch.bezierText());
if (!cubicBezier) {
cubicBezier =
/** @type {!UI.Geometry.CubicBezier} */ (UI.Geometry.CubicBezier.parse('linear'));
}
this._bezierEditor.setBezier(cubicBezier);
this._bezierEditor.addEventListener(InlineEditor.BezierEditor.Events.BezierChanged, this._boundBezierChanged);
this._swatchPopoverHelper.show(this._bezierEditor, this._swatch.iconElement(), this._onPopoverHidden.bind(this));
this._scrollerElement = this._swatch.enclosingNodeOrSelfWithClass('style-panes-wrapper');
if (this._scrollerElement) {
this._scrollerElement.addEventListener('scroll', this._boundOnScroll, false);
}
this._originalPropertyText = this._treeElement.property.propertyText;
this._treeElement.parentPane().setEditingStyle(true);
const uiLocation = Bindings.CSSWorkspaceBinding.CSSWorkspaceBinding.instance().propertyUILocation(
this._treeElement.property, false /* forName */);
if (uiLocation) {
Common.Revealer.reveal(uiLocation, true /* omitFocus */);
}
}
/**
* @param {!Common.EventTarget.EventTargetEvent} event
*/
_bezierChanged(event) {
this._swatch.setBezierText(/** @type {string} */ (event.data));
this._treeElement.applyStyleText(this._treeElement.renderedPropertyText(), false);
}
/**
* @param {!Event} event
*/
_onScroll(event) {
this._swatchPopoverHelper.hide(true);
}
/**
* @param {boolean} commitEdit
*/
_onPopoverHidden(commitEdit) {
if (this._scrollerElement) {
this._scrollerElement.removeEventListener('scroll', this._boundOnScroll, false);
}
this._bezierEditor.removeEventListener(InlineEditor.BezierEditor.Events.BezierChanged, this._boundBezierChanged);
delete this._bezierEditor;
const propertyText = commitEdit ? this._treeElement.renderedPropertyText() : this._originalPropertyText;
this._treeElement.applyStyleText(propertyText, true);
this._treeElement.parentPane().setEditingStyle(false);
delete this._originalPropertyText;
}
}
/**
* @unrestricted
*/
export class ColorSwatchPopoverIcon {
/**
* @param {!StylePropertyTreeElement} treeElement
* @param {!InlineEditor.SwatchPopoverHelper.SwatchPopoverHelper} swatchPopoverHelper
* @param {!InlineEditor.ColorSwatch.ColorSwatch} swatch
*/
constructor(treeElement, swatchPopoverHelper, swatch) {
this._treeElement = treeElement;
this._treeElement[ColorSwatchPopoverIcon._treeElementSymbol] = this;
this._swatchPopoverHelper = swatchPopoverHelper;
this._swatch = swatch;
const shiftClickMessage = Common.UIString.UIString('Shift + Click to change color format.');
this._swatch.iconElement().title = Common.UIString.UIString('Open color picker. %s', shiftClickMessage);
this._swatch.iconElement().addEventListener('click', this._iconClick.bind(this));
this._swatch.iconElement().addEventListener('mousedown', event => event.consume(), false);
this._contrastInfo = null;
this._boundSpectrumChanged = this._spectrumChanged.bind(this);
this._boundOnScroll = this._onScroll.bind(this);
}
/**
* @return {!ColorPicker.Spectrum.Palette}
*/
_generateCSSVariablesPalette() {
const matchedStyles = this._treeElement.matchedStyles();
const style = this._treeElement.property.ownerStyle;
const cssVariables = matchedStyles.availableCSSVariables(style);
const colors = [];
const colorNames = [];
for (const cssVariable of cssVariables) {
if (cssVariable === this._treeElement.property.name) {
continue;
}
const value = matchedStyles.computeCSSVariable(style, cssVariable);
if (!value) {
continue;
}
const color = Common.Color.Color.parse(value);
if (!color) {
continue;
}
colors.push(value);
colorNames.push(cssVariable);
}
return {title: 'CSS Variables', mutable: false, matchUserFormat: true, colors: colors, colorNames: colorNames};
}
/**
* @param {!StylePropertyTreeElement} treeElement
* @return {?ColorSwatchPopoverIcon}
*/
static forTreeElement(treeElement) {
return treeElement[ColorSwatchPopoverIcon._treeElementSymbol] || null;
}
/**
* @param {!ColorPicker.ContrastInfo.ContrastInfo} contrastInfo
*/
setContrastInfo(contrastInfo) {
this._contrastInfo = contrastInfo;
}
/**
* @param {!Event} event
*/
_iconClick(event) {
event.consume(true);
this.showPopover();
}
showPopover() {
if (this._swatchPopoverHelper.isShowing()) {
this._swatchPopoverHelper.hide(true);
return;
}
const color = this._swatch.color();
let format = this._swatch.format();
if (format === Common.Color.Format.Original) {
format = color.format();
}
this._spectrum = new ColorPicker.Spectrum.Spectrum(this._contrastInfo);
this._spectrum.setColor(color, format);
this._spectrum.addPalette(this._generateCSSVariablesPalette());
this._spectrum.addEventListener(ColorPicker.Spectrum.Events.SizeChanged, this._spectrumResized, this);
this._spectrum.addEventListener(ColorPicker.Spectrum.Events.ColorChanged, this._boundSpectrumChanged);
this._swatchPopoverHelper.show(this._spectrum, this._swatch.iconElement(), this._onPopoverHidden.bind(this));
this._scrollerElement = this._swatch.enclosingNodeOrSelfWithClass('style-panes-wrapper');
if (this._scrollerElement) {
this._scrollerElement.addEventListener('scroll', this._boundOnScroll, false);
}
this._originalPropertyText = this._treeElement.property.propertyText;
this._treeElement.parentPane().setEditingStyle(true);
const uiLocation = Bindings.CSSWorkspaceBinding.CSSWorkspaceBinding.instance().propertyUILocation(
this._treeElement.property, false /* forName */);
if (uiLocation) {
Common.Revealer.reveal(uiLocation, true /* omitFocus */);
}
}
/**
* @param {!Common.EventTarget.EventTargetEvent} event
*/
_spectrumResized(event) {
this._swatchPopoverHelper.reposition();
}
/**
* @param {!Common.EventTarget.EventTargetEvent} event
*/
_spectrumChanged(event) {
const color = Common.Color.Color.parse(/** @type {string} */ (event.data));
if (!color) {
return;
}
this._swatch.setColor(color);
const colorName = this._spectrum.colorName();
if (colorName && colorName.startsWith('--')) {
this._swatch.setText(`var(${colorName})`);
}
this._treeElement.applyStyleText(this._treeElement.renderedPropertyText(), false);
}
/**
* @param {!Event} event
*/
_onScroll(event) {
this._swatchPopoverHelper.hide(true);
}
/**
* @param {boolean} commitEdit
*/
_onPopoverHidden(commitEdit) {
if (this._scrollerElement) {
this._scrollerElement.removeEventListener('scroll', this._boundOnScroll, false);
}
this._spectrum.removeEventListener(ColorPicker.Spectrum.Events.ColorChanged, this._boundSpectrumChanged);
delete this._spectrum;
const propertyText = commitEdit ? this._treeElement.renderedPropertyText() : this._originalPropertyText;
this._treeElement.applyStyleText(propertyText, true);
this._treeElement.parentPane().setEditingStyle(false);
delete this._originalPropertyText;
}
}
ColorSwatchPopoverIcon._treeElementSymbol = Symbol('ColorSwatchPopoverIcon._treeElementSymbol');
/**
* @unrestricted
*/
export class ShadowSwatchPopoverHelper {
/**
* @param {!StylePropertyTreeElement} treeElement
* @param {!InlineEditor.SwatchPopoverHelper.SwatchPopoverHelper} swatchPopoverHelper
* @param {!InlineEditor.ColorSwatch.CSSShadowSwatch} shadowSwatch
*/
constructor(treeElement, swatchPopoverHelper, shadowSwatch) {
this._treeElement = treeElement;
this._treeElement[ShadowSwatchPopoverHelper._treeElementSymbol] = this;
this._swatchPopoverHelper = swatchPopoverHelper;
this._shadowSwatch = shadowSwatch;
this._iconElement = shadowSwatch.iconElement();
this._iconElement.title = Common.UIString.UIString('Open shadow editor.');
this._iconElement.addEventListener('click', this._iconClick.bind(this), false);
this._iconElement.addEventListener('mousedown', event => event.consume(), false);
this._boundShadowChanged = this._shadowChanged.bind(this);
this._boundOnScroll = this._onScroll.bind(this);
}
/**
* @param {!StylePropertyTreeElement} treeElement
* @return {?ShadowSwatchPopoverHelper}
*/
static forTreeElement(treeElement) {
return treeElement[ShadowSwatchPopoverHelper._treeElementSymbol] || null;
}
/**
* @param {!Event} event
*/
_iconClick(event) {
event.consume(true);
this.showPopover();
}
showPopover() {
if (this._swatchPopoverHelper.isShowing()) {
this._swatchPopoverHelper.hide(true);
return;
}
this._cssShadowEditor = new InlineEditor.CSSShadowEditor.CSSShadowEditor();
this._cssShadowEditor.setModel(this._shadowSwatch.model());
this._cssShadowEditor.addEventListener(InlineEditor.CSSShadowEditor.Events.ShadowChanged, this._boundShadowChanged);
this._swatchPopoverHelper.show(this._cssShadowEditor, this._iconElement, this._onPopoverHidden.bind(this));
this._scrollerElement = this._iconElement.enclosingNodeOrSelfWithClass('style-panes-wrapper');
if (this._scrollerElement) {
this._scrollerElement.addEventListener('scroll', this._boundOnScroll, false);
}
this._originalPropertyText = this._treeElement.property.propertyText;
this._treeElement.parentPane().setEditingStyle(true);
const uiLocation = Bindings.CSSWorkspaceBinding.CSSWorkspaceBinding.instance().propertyUILocation(
this._treeElement.property, false /* forName */);
if (uiLocation) {
Common.Revealer.reveal(uiLocation, true /* omitFocus */);
}
}
/**
* @param {!Common.EventTarget.EventTargetEvent} event
*/
_shadowChanged(event) {
this._shadowSwatch.setCSSShadow(/** @type {!InlineEditor.CSSShadowModel.CSSShadowModel} */ (event.data));
this._treeElement.applyStyleText(this._treeElement.renderedPropertyText(), false);
}
/**
* @param {!Event} event
*/
_onScroll(event) {
this._swatchPopoverHelper.hide(true);
}
/**
* @param {boolean} commitEdit
*/
_onPopoverHidden(commitEdit) {
if (this._scrollerElement) {
this._scrollerElement.removeEventListener('scroll', this._boundOnScroll, false);
}
this._cssShadowEditor.removeEventListener(
InlineEditor.CSSShadowEditor.Events.ShadowChanged, this._boundShadowChanged);
delete this._cssShadowEditor;
const propertyText = commitEdit ? this._treeElement.renderedPropertyText() : this._originalPropertyText;
this._treeElement.applyStyleText(propertyText, true);
this._treeElement.parentPane().setEditingStyle(false);
delete this._originalPropertyText;
}
}
ShadowSwatchPopoverHelper._treeElementSymbol = Symbol('ShadowSwatchPopoverHelper._treeElementSymbol');