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: If5823db63c504e3502513bd09e9a82c0cfa0d612 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2354238 Reviewed-by: Jack Franklin <jacktfranklin@chromium.org> Reviewed-by: Tony Ross <tross@microsoft.com> Commit-Queue: Patrick Brosset <patrick.brosset@microsoft.com>
This commit is contained in:
committed by
Commit Bot
parent
384827a10c
commit
78fa1f578a
@@ -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",
|
||||
"layout-pane_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"]';
|
||||
const MORE_TABS_SELECTOR = '[aria-label="More tabs"]';
|
||||
const LAYOUT_PANE_TAB_SELECTOR = '[aria-label="Layout"]';
|
||||
const INACTIVE_GRID_ADORNER_SELECTOR = '[aria-label="Enable grid mode"]';
|
||||
@@ -320,3 +323,56 @@ 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) => {
|
||||
await step(`Typing in new class names ${text}`, async () => {
|
||||
const clsInput = await waitFor(CLS_INPUT_SELECTOR);
|
||||
await clsInput.type(text, {delay: 50});
|
||||
});
|
||||
|
||||
if (commitWith) {
|
||||
await step(`Committing the changes with ${commitWith}`, async () => {
|
||||
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 it is not enough to wait for the selected node to change just once.
|
||||
await step('Waiting for the selected node to change', async () => {
|
||||
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