UNPKG

chrome-devtools-frontend

Version:
400 lines (357 loc) • 15.2 kB
// 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 {renderElementIntoDOM} from '../../../../testing/DOMHelpers.js'; import * as InlineEditor from './inline_editor.js'; const assertPopoverOpen = (root: ShadowRoot) => { const popover = root.querySelector('.popover'); assert.exists(popover); }; const assertPopoverClosed = (root: ShadowRoot) => { const popover = root.querySelector('.popover'); assert.notExists(popover); }; const assertAndGetSwatch = (root: ShadowRoot) => { const swatch = root.querySelector<HTMLElement>('devtools-css-angle-swatch'); if (!swatch) { assert.fail('swatch was not rendered'); return; } return swatch; }; const togglePopover = (root: ShadowRoot) => { const swatch = assertAndGetSwatch(root); swatch?.click(); }; const assertNewAngleFromEvent = (angle: InlineEditor.CSSAngleUtils.Angle, event: KeyboardEvent|MouseEvent, approximateNewValue: number) => { const newAngle = InlineEditor.CSSAngleUtils.getNewAngleFromEvent(angle, event); if (!newAngle) { assert.fail('should create a new angle'); return; } assert.strictEqual(newAngle.unit, angle.unit); assert.approximately(newAngle.value, approximateNewValue, 0.1); }; const initialData: InlineEditor.CSSAngle.CSSAngleData = { angleText: '45deg', containingPane: document.createElement('div'), }; describe('CSSAngle', () => { it('can open and close a popover', () => { const component = new InlineEditor.CSSAngle.CSSAngle(); renderElementIntoDOM(component); component.data = initialData; assert.isNotNull(component.shadowRoot); assertPopoverClosed(component.shadowRoot); togglePopover(component.shadowRoot); assertPopoverOpen(component.shadowRoot); togglePopover(component.shadowRoot); assertPopoverClosed(component.shadowRoot); }); it('can fire events when toggling the popover', () => { const component = new InlineEditor.CSSAngle.CSSAngle(); renderElementIntoDOM(component); let isPopoverOpen = false; component.data = initialData; component.addEventListener('popovertoggled', (event: Event) => { const popoverToggledEvent = event as InlineEditor.CSSAngle.PopoverToggledEvent; isPopoverOpen = popoverToggledEvent.data.open; }); assert.isNotNull(component.shadowRoot); assertPopoverClosed(component.shadowRoot); togglePopover(component.shadowRoot); assertPopoverOpen(component.shadowRoot); assert.isTrue(isPopoverOpen, 'external isPopoverOpen flag not synced'); togglePopover(component.shadowRoot); assertPopoverClosed(component.shadowRoot); assert.isFalse(isPopoverOpen, 'external isPopoverOpen flag not synced'); }); it('can change unit when the swatch is shift-clicked upon', () => { const component = new InlineEditor.CSSAngle.CSSAngle(); renderElementIntoDOM(component); component.data = initialData; assert.isNotNull(component.shadowRoot); let cssAngleText = initialData.angleText; component.addEventListener('unitchanged', (event: Event) => { const {data} = event as InlineEditor.CSSAngle.UnitChangedEvent; cssAngleText = data.value; }); const swatch = assertAndGetSwatch(component.shadowRoot); if (!swatch) { return; } const shiftClick = new MouseEvent('click', {shiftKey: true}); swatch.dispatchEvent(shiftClick); assert.strictEqual(cssAngleText, '50grad', 'angle unit should change to Grad from Deg'); }); it('can +/- angle values when pressing UP or DOWN keys', () => { const component = new InlineEditor.CSSAngle.CSSAngle(); renderElementIntoDOM(component); component.data = initialData; assert.isNotNull(component.shadowRoot); let cssAngleText = initialData.angleText; component.addEventListener('valuechanged', (event: Event) => { const {data} = event as InlineEditor.InlineEditorUtils.ValueChangedEvent; cssAngleText = data.value; }); togglePopover(component.shadowRoot); const angleContainer = component.shadowRoot.querySelector('.css-angle'); if (!angleContainer) { assert.fail('angle container was not rendered'); return; } const arrowUp = new KeyboardEvent('keydown', {key: 'ArrowUp'}); angleContainer.dispatchEvent(arrowUp); assert.strictEqual(cssAngleText, '46deg', 'angle value should increase by 1 when ArrowUp is pressed'); const arrowDownShift = new KeyboardEvent('keydown', {key: 'ArrowDown', shiftKey: true}); angleContainer.dispatchEvent(arrowDownShift); assert.strictEqual(cssAngleText, '36deg', 'angle value should increase by 1 when ArrowUp is pressed'); }); describe('#CSSAngleUtils', () => { it('can fire InlineEditor.CSSAngle.PopoverToggledEvent when toggling the popover', () => { const component = new InlineEditor.CSSAngle.CSSAngle(); renderElementIntoDOM(component); let shouldPopoverEventBeOpen = false; component.data = initialData; component.addEventListener('popovertoggled', (event: Event) => { const popoverEvent = event as InlineEditor.CSSAngle.PopoverToggledEvent; assert.strictEqual(popoverEvent.data.open, shouldPopoverEventBeOpen); }); assert.isNotNull(component.shadowRoot); assertPopoverClosed(component.shadowRoot); shouldPopoverEventBeOpen = true; togglePopover(component.shadowRoot); shouldPopoverEventBeOpen = false; togglePopover(component.shadowRoot); }); it('parses CSS properties with angles correctly', () => { assert.deepEqual( InlineEditor.CSSAngleUtils.parseText('rotate(45deg)'), {value: 45, unit: InlineEditor.CSSAngleUtils.AngleUnit.DEG}); assert.deepEqual( InlineEditor.CSSAngleUtils.parseText('rotate(calc(45deg))'), {value: 45, unit: InlineEditor.CSSAngleUtils.AngleUnit.DEG}); assert.deepEqual( InlineEditor.CSSAngleUtils.parseText('skew(20deg)'), {value: 20, unit: InlineEditor.CSSAngleUtils.AngleUnit.DEG}); assert.deepEqual( InlineEditor.CSSAngleUtils.parseText('rotateX(20deg)'), {value: 20, unit: InlineEditor.CSSAngleUtils.AngleUnit.DEG}); assert.deepEqual( InlineEditor.CSSAngleUtils.parseText('rotateY(20deg)'), {value: 20, unit: InlineEditor.CSSAngleUtils.AngleUnit.DEG}); assert.deepEqual( InlineEditor.CSSAngleUtils.parseText('rotateZ(20deg)'), {value: 20, unit: InlineEditor.CSSAngleUtils.AngleUnit.DEG}); assert.deepEqual( InlineEditor.CSSAngleUtils.parseText('rotate3d(1, 1, 1, 20deg)'), {value: 20, unit: InlineEditor.CSSAngleUtils.AngleUnit.DEG}); assert.deepEqual( InlineEditor.CSSAngleUtils.parseText('linear-gradient(10.5grad, black, white)'), {value: 10.5, unit: InlineEditor.CSSAngleUtils.AngleUnit.GRAD}); assert.deepEqual( InlineEditor.CSSAngleUtils.parseText( 'conic-gradient(black 25%, white 10deg 50%, black 20deg 75%, white 30deg)'), {value: 10, unit: InlineEditor.CSSAngleUtils.AngleUnit.DEG}); assert.deepEqual( InlineEditor.CSSAngleUtils.parseText('rotate3d(2, -1, -1, -0.2rad);'), {value: -0.2, unit: InlineEditor.CSSAngleUtils.AngleUnit.RAD}); assert.deepEqual( InlineEditor.CSSAngleUtils.parseText('hue-rotate(1.5turn)'), {value: 1.5, unit: InlineEditor.CSSAngleUtils.AngleUnit.TURN}); assert.deepEqual( InlineEditor.CSSAngleUtils.parseText('oblique 25deg'), {value: 25, unit: InlineEditor.CSSAngleUtils.AngleUnit.DEG}); assert.deepEqual( InlineEditor.CSSAngleUtils.parseText('ray(20.8deg closest-side)'), {value: 20.8, unit: InlineEditor.CSSAngleUtils.AngleUnit.DEG}); assert.isNull(InlineEditor.CSSAngleUtils.parseText('rotate(12345)')); assert.isNull(InlineEditor.CSSAngleUtils.parseText('')); // TODO(changhaohan): crbug.com/1138628 handle unitless 0 case assert.isNull(InlineEditor.CSSAngleUtils.parseText('rotate(0)')); }); it('converts angles in degree to other units correctly', () => { assert.deepEqual( InlineEditor.CSSAngleUtils.getAngleFromRadians(Math.PI / 4, InlineEditor.CSSAngleUtils.AngleUnit.GRAD), { value: 50, unit: InlineEditor.CSSAngleUtils.AngleUnit.GRAD, }); assert.deepEqual( InlineEditor.CSSAngleUtils.getAngleFromRadians(Math.PI / 4, InlineEditor.CSSAngleUtils.AngleUnit.RAD), { value: Math.PI / 4, unit: InlineEditor.CSSAngleUtils.AngleUnit.RAD, }); assert.deepEqual( InlineEditor.CSSAngleUtils.getAngleFromRadians(Math.PI / 4, InlineEditor.CSSAngleUtils.AngleUnit.TURN), { value: 0.125, unit: InlineEditor.CSSAngleUtils.AngleUnit.TURN, }); assert.deepEqual( InlineEditor.CSSAngleUtils.getAngleFromRadians(Math.PI / 4, InlineEditor.CSSAngleUtils.AngleUnit.DEG), { value: 45, unit: InlineEditor.CSSAngleUtils.AngleUnit.DEG, }); }); it('converts angles in other units to radians correctly', () => { assert.strictEqual( InlineEditor.CSSAngleUtils.getRadiansFromAngle({ value: 50, unit: InlineEditor.CSSAngleUtils.AngleUnit.GRAD, }), 0.7853981633974483); assert.strictEqual( InlineEditor.CSSAngleUtils.getRadiansFromAngle({ value: 45, unit: InlineEditor.CSSAngleUtils.AngleUnit.DEG, }), 0.7853981633974483); assert.strictEqual( InlineEditor.CSSAngleUtils.getRadiansFromAngle({ value: 0.125, unit: InlineEditor.CSSAngleUtils.AngleUnit.TURN, }), 0.7853981633974483); assert.strictEqual( InlineEditor.CSSAngleUtils.getRadiansFromAngle({ value: 1, unit: InlineEditor.CSSAngleUtils.AngleUnit.RAD, }), 1); }); it('gets 2D translations for angles correctly', () => { assert.deepEqual( InlineEditor.CSSAngleUtils.get2DTranslationsForAngle( { value: 45, unit: InlineEditor.CSSAngleUtils.AngleUnit.DEG, }, 1), { translateX: 0.7071067811865475, translateY: -0.7071067811865476, }); }); it('rounds angles by units correctly', () => { assert.deepEqual( InlineEditor.CSSAngleUtils.roundAngleByUnit({ value: 45.723, unit: InlineEditor.CSSAngleUtils.AngleUnit.DEG, }), { value: 46, unit: InlineEditor.CSSAngleUtils.AngleUnit.DEG, }); assert.deepEqual( InlineEditor.CSSAngleUtils.roundAngleByUnit({ value: 45.723, unit: InlineEditor.CSSAngleUtils.AngleUnit.GRAD, }), { value: 46, unit: InlineEditor.CSSAngleUtils.AngleUnit.GRAD, }); assert.deepEqual( InlineEditor.CSSAngleUtils.roundAngleByUnit({ value: 45.723, unit: InlineEditor.CSSAngleUtils.AngleUnit.RAD, }), { value: 45.723, unit: InlineEditor.CSSAngleUtils.AngleUnit.RAD, }); assert.deepEqual( InlineEditor.CSSAngleUtils.roundAngleByUnit({ value: 45.723275, unit: InlineEditor.CSSAngleUtils.AngleUnit.RAD, }), { value: 45.7233, unit: InlineEditor.CSSAngleUtils.AngleUnit.RAD, }); assert.deepEqual( InlineEditor.CSSAngleUtils.roundAngleByUnit({ value: 45.723275, unit: InlineEditor.CSSAngleUtils.AngleUnit.TURN, }), { value: 45.72, unit: InlineEditor.CSSAngleUtils.AngleUnit.TURN, }); assert.deepEqual( InlineEditor.CSSAngleUtils.roundAngleByUnit({ value: 45.8, unit: InlineEditor.CSSAngleUtils.AngleUnit.TURN, }), { value: 45.8, unit: InlineEditor.CSSAngleUtils.AngleUnit.TURN, }); }); it('cycles angle units correctly', () => { assert.strictEqual( InlineEditor.CSSAngleUtils.getNextUnit(InlineEditor.CSSAngleUtils.AngleUnit.DEG), InlineEditor.CSSAngleUtils.AngleUnit.GRAD); assert.strictEqual( InlineEditor.CSSAngleUtils.getNextUnit(InlineEditor.CSSAngleUtils.AngleUnit.GRAD), InlineEditor.CSSAngleUtils.AngleUnit.RAD); assert.strictEqual( InlineEditor.CSSAngleUtils.getNextUnit(InlineEditor.CSSAngleUtils.AngleUnit.RAD), InlineEditor.CSSAngleUtils.AngleUnit.TURN); assert.strictEqual( InlineEditor.CSSAngleUtils.getNextUnit(InlineEditor.CSSAngleUtils.AngleUnit.TURN), InlineEditor.CSSAngleUtils.AngleUnit.DEG); }); it('converts angle units correctly', () => { assert.deepEqual( InlineEditor.CSSAngleUtils.convertAngleUnit( { value: 45, unit: InlineEditor.CSSAngleUtils.AngleUnit.DEG, }, InlineEditor.CSSAngleUtils.AngleUnit.GRAD), { value: 50, unit: InlineEditor.CSSAngleUtils.AngleUnit.GRAD, }); assert.deepEqual( InlineEditor.CSSAngleUtils.convertAngleUnit( { value: Math.PI / 180, unit: InlineEditor.CSSAngleUtils.AngleUnit.RAD, }, InlineEditor.CSSAngleUtils.AngleUnit.DEG), { value: 1, unit: InlineEditor.CSSAngleUtils.AngleUnit.DEG, }); assert.deepEqual( InlineEditor.CSSAngleUtils.convertAngleUnit( { value: 1, unit: InlineEditor.CSSAngleUtils.AngleUnit.TURN, }, InlineEditor.CSSAngleUtils.AngleUnit.DEG), { value: 360, unit: InlineEditor.CSSAngleUtils.AngleUnit.DEG, }); }); it('gets new angles from events correctly', () => { const originalAngle = { value: 45, unit: InlineEditor.CSSAngleUtils.AngleUnit.DEG, }; const arrowDown = new KeyboardEvent('keydown', {key: 'ArrowDown'}); const arrowUpShift = new KeyboardEvent('keydown', {key: 'ArrowUp', shiftKey: true}); const wheelUp = new WheelEvent('wheel', {deltaY: 1}); const wheelDownShift = new WheelEvent('wheel', {deltaX: -1, shiftKey: true}); assertNewAngleFromEvent(originalAngle, arrowDown, 44); assertNewAngleFromEvent(originalAngle, arrowUpShift, 55); assertNewAngleFromEvent(originalAngle, wheelUp, 44); assertNewAngleFromEvent(originalAngle, wheelDownShift, 55); const otherEvent = new MouseEvent('mousedown'); assert.notExists(InlineEditor.CSSAngleUtils.getNewAngleFromEvent(originalAngle, otherEvent)); }); }); });