mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-02 18:11:04 +08:00
Remove the previewed class when pressing Escape in the .cls pane
When typing new classes in the .cls pane, they get applied to the selected element as you type, in order to be previewed live. However, if you press Escape, the classes go away from the .cls pane but they stay on the element itself. They should not. This change fixes that by making sure we re-apply the active classes when this happens. It also adds a new e2e test for the .cls panel. Gif of the fix: https://imgur.com/BjDiEQY.gif Bug: 1114726 Change-Id: I393243b469b416b7fd001a096cda08aa10e8bce2 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2346775 Commit-Queue: Patrick Brosset <patrick.brosset@microsoft.com> Reviewed-by: Jack Franklin <jacktfranklin@chromium.org> Reviewed-by: Tony Ross <tross@microsoft.com>
This commit is contained in:
committed by
Commit Bot
parent
fc2bd21796
commit
2b36c8eb3e
@@ -87,6 +87,7 @@ export class ClassesPaneWidget extends UI.Widget.Widget {
|
||||
|
||||
const classNames = this._splitTextIntoClasses(text);
|
||||
if (!classNames.length) {
|
||||
this._installNodeClasses(node);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import("../../../third_party/typescript/typescript.gni")
|
||||
node_ts_library("elements") {
|
||||
sources = [
|
||||
"adornment_test.ts",
|
||||
"classes-pane_test.ts",
|
||||
"computed-pane-properties_test.ts",
|
||||
"element-breadcrumbs_test.ts",
|
||||
"pseudo-states_test.ts",
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright 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 {beforeEach, describe, it} from 'mocha';
|
||||
|
||||
import {goToResource} from '../../shared/helper.js';
|
||||
import {assertSelectedNodeClasses, toggleClassesPane, toggleClassesPaneCheckbox, typeInClassesPaneInput} from '../helpers/elements-helpers.js';
|
||||
|
||||
describe('The Classes pane', async () => {
|
||||
beforeEach(async function() {
|
||||
await goToResource('elements/simple-styled-page.html');
|
||||
await toggleClassesPane();
|
||||
});
|
||||
|
||||
it('can add a class to the element', async () => {
|
||||
await typeInClassesPaneInput('foo');
|
||||
await assertSelectedNodeClasses(['foo']);
|
||||
});
|
||||
|
||||
it('can add multiple classes at once', async () => {
|
||||
await typeInClassesPaneInput('foo bar baz');
|
||||
await assertSelectedNodeClasses(['foo', 'bar', 'baz']);
|
||||
});
|
||||
|
||||
it('can toggle classes', async () => {
|
||||
await typeInClassesPaneInput('on off');
|
||||
await assertSelectedNodeClasses(['on', 'off']);
|
||||
|
||||
await toggleClassesPaneCheckbox('off');
|
||||
await assertSelectedNodeClasses(['on']);
|
||||
|
||||
await toggleClassesPaneCheckbox('off');
|
||||
await toggleClassesPaneCheckbox('on');
|
||||
await assertSelectedNodeClasses(['off']);
|
||||
});
|
||||
|
||||
it('removes the previewed classes on ESC', async () => {
|
||||
await typeInClassesPaneInput('foo');
|
||||
await typeInClassesPaneInput('bar', 'Escape', false);
|
||||
await typeInClassesPaneInput('baz');
|
||||
|
||||
await assertSelectedNodeClasses(['foo', 'baz']);
|
||||
});
|
||||
});
|
||||
@@ -16,6 +16,9 @@ const COMPUTED_STYLES_PANEL_SELECTOR = '[aria-label="Computed panel"]';
|
||||
const COMPUTED_STYLES_SHOW_ALL_SELECTOR = '[aria-label="Show all"]';
|
||||
const ELEMENTS_PANEL_SELECTOR = '.panel[aria-label="elements"]';
|
||||
const SECTION_SUBTITLE_SELECTOR = '.styles-section-subtitle';
|
||||
const CLS_PANE_SELECTOR = '.styles-sidebar-toolbar-pane';
|
||||
const CLS_BUTTON_SELECTOR = '[aria-label="Element Classes"]';
|
||||
const CLS_INPUT_SELECTOR = '[aria-placeholder="Add new class"]';
|
||||
|
||||
export const assertContentOfSelectedElementsNode = async (expectedTextContent: string) => {
|
||||
const selectedNode = await waitFor(SELECTED_TREE_ELEMENT_SELECTOR);
|
||||
@@ -276,3 +279,50 @@ export const clickOnFirstLinkInStylesPanel = async () => {
|
||||
const stylesPane = await waitFor('div.styles-pane');
|
||||
await click('div.styles-section-subtitle span.devtools-link', {root: stylesPane});
|
||||
};
|
||||
|
||||
export const toggleClassesPane = async () => {
|
||||
await click(CLS_BUTTON_SELECTOR);
|
||||
};
|
||||
|
||||
export const typeInClassesPaneInput =
|
||||
async (text: string, commitWith: string = 'Enter', waitForNodeChange: Boolean = true) => {
|
||||
const clsInput = await waitFor(CLS_INPUT_SELECTOR);
|
||||
await clsInput.type(text);
|
||||
|
||||
if (commitWith) {
|
||||
const {frontend} = getBrowserAndPages();
|
||||
await frontend.keyboard.press(commitWith);
|
||||
}
|
||||
|
||||
if (waitForNodeChange) {
|
||||
// Make sure the classes provided in text can be found in the selected element's content. This is important as the
|
||||
// cls pane applies classes as you type, so we need to wait until all of them are applied.
|
||||
await waitForFunction(async () => {
|
||||
const nodeContent = await getContentOfSelectedNode();
|
||||
return text.split(' ').every(cls => nodeContent.includes(cls));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const toggleClassesPaneCheckbox = async (checkboxLabel: string) => {
|
||||
const initialValue = await getContentOfSelectedNode();
|
||||
|
||||
const classesPane = await waitFor(CLS_PANE_SELECTOR);
|
||||
await click(`input[aria-label="${checkboxLabel}"]`, {root: classesPane});
|
||||
|
||||
await waitForSelectedNodeChange(initialValue);
|
||||
};
|
||||
|
||||
export const assertSelectedNodeClasses = async (expectedClasses: string[]) => {
|
||||
const nodeText = await getContentOfSelectedNode();
|
||||
const match = nodeText.match(/class=\u200B"([^"]*)/);
|
||||
const classText = match ? match[1] : '';
|
||||
const classes = classText.split(/[\s]/).map(className => className.trim()).filter(className => className.length);
|
||||
|
||||
assert.strictEqual(
|
||||
classes.length, expectedClasses.length, 'Did not find the expected number of classes on the element');
|
||||
|
||||
for (const expectedClass of expectedClasses) {
|
||||
assert.include(classes, expectedClass, `Could not find class ${expectedClass} on the element`);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user