From 426daec51f83f319a87ccf1a9e48a71718a1fd07 Mon Sep 17 00:00:00 2001 From: Federico Ruggi <1081051+ruggi@users.noreply.github.com> Date: Thu, 28 Sep 2023 18:41:44 +0200 Subject: [PATCH 1/9] delete existing empty spans --- .../text-editor/text-editor.spec.browser2.tsx | 17 ++--------------- .../src/components/text-editor/text-editor.tsx | 2 +- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/editor/src/components/text-editor/text-editor.spec.browser2.tsx b/editor/src/components/text-editor/text-editor.spec.browser2.tsx index b1378b65fd2c..83b1f7f38aae 100644 --- a/editor/src/components/text-editor/text-editor.spec.browser2.tsx +++ b/editor/src/components/text-editor/text-editor.spec.browser2.tsx @@ -357,7 +357,7 @@ describe('Use the text editor', () => { }) describe('blur', () => { describe('when the element is empty', () => { - it('keeps existing elements', async () => { + it('deletes existing elements', async () => { const editor = await renderTestEditorWithCode(projectWithText, 'await-first-dom-report') await enterTextEditMode(editor) @@ -375,20 +375,7 @@ describe('Use the text editor', () => { export var storyboard = ( - -
- + )`), ) }) diff --git a/editor/src/components/text-editor/text-editor.tsx b/editor/src/components/text-editor/text-editor.tsx index 1c15a6935aaa..751130785c18 100644 --- a/editor/src/components/text-editor/text-editor.tsx +++ b/editor/src/components/text-editor/text-editor.tsx @@ -342,7 +342,7 @@ const TextEditor = React.memo((props: TextEditorProps) => { return () => { const content = currentElement.textContent if (content != null) { - if (elementState === 'new' && content.replace(/\n/g, '') === '') { + if (content.replace(/\n/g, '') === '') { requestAnimationFrame(() => dispatch([deleteView(elementPath)])) } else { if (elementState != null && savedContentRef.current !== content) { From 2c67e18b0c8abe4719cb9e28bd93a8789be3a013 Mon Sep 17 00:00:00 2001 From: Federico Ruggi <1081051+ruggi@users.noreply.github.com> Date: Fri, 29 Sep 2023 09:49:17 +0200 Subject: [PATCH 2/9] only remove spans --- editor/src/components/text-editor/text-editor.tsx | 15 +++++++++++++-- editor/src/core/model/element-metadata-utils.ts | 3 +++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/editor/src/components/text-editor/text-editor.tsx b/editor/src/components/text-editor/text-editor.tsx index 751130785c18..03e7924a2d7b 100644 --- a/editor/src/components/text-editor/text-editor.tsx +++ b/editor/src/components/text-editor/text-editor.tsx @@ -342,7 +342,7 @@ const TextEditor = React.memo((props: TextEditorProps) => { return () => { const content = currentElement.textContent if (content != null) { - if (content.replace(/\n/g, '') === '') { + if (elementState === 'new' && content.replace(/\n/g, '') === '') { requestAnimationFrame(() => dispatch([deleteView(elementPath)])) } else { if (elementState != null && savedContentRef.current !== content) { @@ -437,7 +437,18 @@ const TextEditor = React.memo((props: TextEditorProps) => { } else { dispatch([updateEditorMode(EditorModes.selectMode(null, false, 'none'))]) } - }, [dispatch, elementPath, elementState, textProp]) + + // remove dangling empty spans + if ( + content != null && + content.replace(/^\n/, '').length === 0 && + MetadataUtils.isMaybeSpan( + MetadataUtils.findElementByElementPath(metadataRef.current, elementPath), + ) + ) { + requestAnimationFrame(() => dispatch([deleteView(elementPath)])) + } + }, [dispatch, elementPath, elementState, textProp, metadataRef]) const editorProps: React.DetailedHTMLProps< React.HTMLAttributes, diff --git a/editor/src/core/model/element-metadata-utils.ts b/editor/src/core/model/element-metadata-utils.ts index c20816f137ce..78bbc25b403e 100644 --- a/editor/src/core/model/element-metadata-utils.ts +++ b/editor/src/core/model/element-metadata-utils.ts @@ -903,6 +903,9 @@ export const MetadataUtils = { isSpan(instance: ElementInstanceMetadata): boolean { return this.isElementOfType(instance, 'span') }, + isMaybeSpan(instance: ElementInstanceMetadata | null): boolean { + return instance != null && this.isElementOfType(instance, 'span') + }, targetIsScene(metadata: ElementInstanceMetadataMap, path: ElementPath): boolean { const elementMetadata = MetadataUtils.findElementByElementPath(metadata, path) return elementMetadata != null && isSceneFromMetadata(elementMetadata) From ebb4b12a58bb4aa3f86905f008723b7324253998 Mon Sep 17 00:00:00 2001 From: Federico Ruggi <1081051+ruggi@users.noreply.github.com> Date: Fri, 29 Sep 2023 09:52:39 +0200 Subject: [PATCH 3/9] helper --- editor/src/components/text-editor/text-editor.tsx | 15 ++++++++++++--- editor/src/core/model/element-metadata-utils.ts | 3 --- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/editor/src/components/text-editor/text-editor.tsx b/editor/src/components/text-editor/text-editor.tsx index 03e7924a2d7b..338d553069e3 100644 --- a/editor/src/components/text-editor/text-editor.tsx +++ b/editor/src/components/text-editor/text-editor.tsx @@ -442,9 +442,7 @@ const TextEditor = React.memo((props: TextEditorProps) => { if ( content != null && content.replace(/^\n/, '').length === 0 && - MetadataUtils.isMaybeSpan( - MetadataUtils.findElementByElementPath(metadataRef.current, elementPath), - ) + canDeleteWhenEmpty(metadataRef.current, elementPath) ) { requestAnimationFrame(() => dispatch([deleteView(elementPath)])) } @@ -604,3 +602,14 @@ function getSaveAction( ): EditorAction { return updateText(elementPath, escapeHTML(content, textProp), textProp) } + +function canDeleteWhenEmpty(jsxMetadata: ElementInstanceMetadataMap, path: ElementPath): boolean { + const element = MetadataUtils.findElementByElementPath(jsxMetadata, path) + if (element == null) { + return false + } + if (!MetadataUtils.isSpan(element)) { + return false + } + return true +} diff --git a/editor/src/core/model/element-metadata-utils.ts b/editor/src/core/model/element-metadata-utils.ts index 78bbc25b403e..c20816f137ce 100644 --- a/editor/src/core/model/element-metadata-utils.ts +++ b/editor/src/core/model/element-metadata-utils.ts @@ -903,9 +903,6 @@ export const MetadataUtils = { isSpan(instance: ElementInstanceMetadata): boolean { return this.isElementOfType(instance, 'span') }, - isMaybeSpan(instance: ElementInstanceMetadata | null): boolean { - return instance != null && this.isElementOfType(instance, 'span') - }, targetIsScene(metadata: ElementInstanceMetadataMap, path: ElementPath): boolean { const elementMetadata = MetadataUtils.findElementByElementPath(metadata, path) return elementMetadata != null && isSceneFromMetadata(elementMetadata) From 29b573f9226ca7ffbfef54177ee0f670bfbd553c Mon Sep 17 00:00:00 2001 From: Federico Ruggi <1081051+ruggi@users.noreply.github.com> Date: Fri, 29 Sep 2023 10:08:40 +0200 Subject: [PATCH 4/9] delete if not styled and has no event handlers --- .../components/text-editor/text-editor.tsx | 49 +++++++++++++++++-- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/editor/src/components/text-editor/text-editor.tsx b/editor/src/components/text-editor/text-editor.tsx index 338d553069e3..27ed7e893bbb 100644 --- a/editor/src/components/text-editor/text-editor.tsx +++ b/editor/src/components/text-editor/text-editor.tsx @@ -31,7 +31,7 @@ import { EditorModes } from '../editor/editor-modes' import { useDispatch } from '../editor/store/dispatch-context' import { MainEditorStoreProvider } from '../editor/store/store-context-providers' import { Substores, useEditorState, useRefEditorState } from '../editor/store/store-hook' -import { printCSSNumber } from '../inspector/common/css-utils' +import { DOMEventHandlerNames, printCSSNumber } from '../inspector/common/css-utils' import { toggleTextBold, toggleTextItalic, @@ -43,6 +43,8 @@ import { mapArrayToDictionary } from '../../core/shared/array-utils' import { TextRelatedProperties } from '../../core/properties/css-properties' import { assertNever } from '../../core/shared/utils' import { notice } from '../common/notice' +import type { AllElementProps } from '../editor/store/editor-state' +import { toString } from '../../core/shared/element-path' export const TextEditorSpanId = 'text-editor' @@ -305,6 +307,7 @@ const TextEditor = React.memo((props: TextEditorProps) => { ) const metadataRef = useRefEditorState((store) => store.editor.jsxMetadata) + const allElementPropsRef = useRefEditorState((store) => store.editor.allElementProps) const savedContentRef = React.useRef(null) @@ -442,11 +445,11 @@ const TextEditor = React.memo((props: TextEditorProps) => { if ( content != null && content.replace(/^\n/, '').length === 0 && - canDeleteWhenEmpty(metadataRef.current, elementPath) + canDeleteWhenEmpty(metadataRef.current, elementPath, allElementPropsRef.current) ) { requestAnimationFrame(() => dispatch([deleteView(elementPath)])) } - }, [dispatch, elementPath, elementState, textProp, metadataRef]) + }, [dispatch, elementPath, elementState, textProp, metadataRef, allElementPropsRef]) const editorProps: React.DetailedHTMLProps< React.HTMLAttributes, @@ -603,7 +606,26 @@ function getSaveAction( return updateText(elementPath, escapeHTML(content, textProp), textProp) } -function canDeleteWhenEmpty(jsxMetadata: ElementInstanceMetadataMap, path: ElementPath): boolean { +const allowedStyleKeysForDeletion: string[] = [ + 'position', + 'top', + 'left', + 'bottom', + 'right', + 'width', + 'height', + 'wordBreak', + 'fontSize', + 'fontWeight', + 'fontFamily', + 'font', +] + +function canDeleteWhenEmpty( + jsxMetadata: ElementInstanceMetadataMap, + path: ElementPath, + allElementProps: AllElementProps, +): boolean { const element = MetadataUtils.findElementByElementPath(jsxMetadata, path) if (element == null) { return false @@ -611,5 +633,24 @@ function canDeleteWhenEmpty(jsxMetadata: ElementInstanceMetadataMap, path: Eleme if (!MetadataUtils.isSpan(element)) { return false } + + const elementProps = allElementProps[toString(path)] + if (elementProps == null) { + return false + } + + // it must not have defined styling + if ( + elementProps.style != null && + Object.keys(elementProps.style).some((key) => !allowedStyleKeysForDeletion.includes(key)) + ) { + return false + } + + // it must not have defined event handlers + if (Object.keys(elementProps).some((prop) => DOMEventHandlerNames.includes(prop as any))) { + return false + } + return true } From 2e637dd080c15aa1a27351ca07799152d24825b6 Mon Sep 17 00:00:00 2001 From: Federico Ruggi <1081051+ruggi@users.noreply.github.com> Date: Fri, 29 Sep 2023 10:32:27 +0200 Subject: [PATCH 5/9] style/handlers constraints --- .../text-editor/text-editor.spec.browser2.tsx | 265 +++++++++++++++++- .../components/text-editor/text-editor.tsx | 26 +- 2 files changed, 270 insertions(+), 21 deletions(-) diff --git a/editor/src/components/text-editor/text-editor.spec.browser2.tsx b/editor/src/components/text-editor/text-editor.spec.browser2.tsx index 83b1f7f38aae..cdf888261ca5 100644 --- a/editor/src/components/text-editor/text-editor.spec.browser2.tsx +++ b/editor/src/components/text-editor/text-editor.spec.browser2.tsx @@ -357,7 +357,7 @@ describe('Use the text editor', () => { }) describe('blur', () => { describe('when the element is empty', () => { - it('deletes existing elements', async () => { + it('keeps existing elements', async () => { const editor = await renderTestEditorWithCode(projectWithText, 'await-first-dom-report') await enterTextEditMode(editor) @@ -375,7 +375,20 @@ describe('Use the text editor', () => { export var storyboard = ( - + +
+ )`), ) }) @@ -407,6 +420,177 @@ describe('Use the text editor', () => { )`), ) }) + it('deletes existing span elements', async () => { + const editor = await renderTestEditorWithCode( + formatTestProjectCode(` + import * as React from 'react' + import { Storyboard } from 'utopia-api' + + export var storyboard = ( + + + Hello + + + ) + `), + 'await-first-dom-report', + ) + + await enterTextEditMode(editor, 'span') + + deleteTypedText() + + await closeTextEditor() + await editor.getDispatchFollowUpActionsFinished() + + expect(editor.getEditorState().editor.mode.type).toEqual('select') + expect(getPrintedUiJsCode(editor.getEditorState())).toEqual( + formatTestProjectCode(` + import * as React from 'react' + import { Storyboard } from 'utopia-api' + + export var storyboard = ( + + ) + `), + ) + }) + it('does not delete span elements with styling', async () => { + const editor = await renderTestEditorWithCode( + formatTestProjectCode(` + import * as React from 'react' + import { Storyboard } from 'utopia-api' + + export var storyboard = ( + + + Hello + + + ) + `), + 'await-first-dom-report', + ) + + await enterTextEditMode(editor, 'span') + + deleteTypedText() + + await closeTextEditor() + await editor.getDispatchFollowUpActionsFinished() + + expect(editor.getEditorState().editor.mode.type).toEqual('select') + expect(getPrintedUiJsCode(editor.getEditorState())).toEqual( + formatTestProjectCode(` + import * as React from 'react' + import { Storyboard } from 'utopia-api' + + export var storyboard = ( + + + + ) + `), + ) + }) + it('does not delete span elements with event handlers', async () => { + const editor = await renderTestEditorWithCode( + formatTestProjectCode(` + import * as React from 'react' + import { Storyboard } from 'utopia-api' + + export var storyboard = ( + + console.log('click')} + > + Hello + + + ) + `), + 'await-first-dom-report', + ) + + await enterTextEditMode(editor, 'span') + + deleteTypedText() + + await closeTextEditor() + await editor.getDispatchFollowUpActionsFinished() + + expect(editor.getEditorState().editor.mode.type).toEqual('select') + expect(getPrintedUiJsCode(editor.getEditorState())).toEqual( + formatTestProjectCode(` + import * as React from 'react' + import { Storyboard } from 'utopia-api' + + export var storyboard = ( + + console.log('click')} + /> + + ) + `), + ) + }) }) describe('collapses runs of text', () => { it('only when the elements involved are eligible', async () => { @@ -1784,20 +1968,23 @@ async function testModifierExpectingWayTooManySavesTheFirstTime( return { before, after } } -async function enterTextEditMode(editor: EditorRenderResult): Promise { +async function enterTextEditMode( + editor: EditorRenderResult, + testId: string = 'div', +): Promise { const canvasControlsLayer = editor.renderedDOM.getByTestId(CanvasControlsContainerID) - const div = editor.renderedDOM.getByTestId('div') - const divBounds = div.getBoundingClientRect() - const divCorner = { - x: divBounds.x + 50, - y: divBounds.y + 40, + const element = editor.renderedDOM.getByTestId(testId) + const bounds = element.getBoundingClientRect() + const corner = { + x: bounds.x + 1, + y: bounds.y + 1, } FOR_TESTS_setNextGeneratedUid('text-span') await pressKey('t') await editor.getDispatchFollowUpActionsFinished() - await mouseClickAtPoint(canvasControlsLayer, divCorner) + await mouseClickAtPoint(canvasControlsLayer, corner) await editor.getDispatchFollowUpActionsFinished() } @@ -1910,6 +2097,66 @@ function projectWithoutTextWithExtraStyle(extraStyleProps: { [prop: string]: str `) } +const projectWithTextSpan = formatTestProjectCode(` +import * as React from 'react' +import { Storyboard } from 'utopia-api' + + +export var storyboard = ( + + + Hello + + +) +`) + +function projectWithoutTextSpanWithExtraStyle(extraStyleProps: { [prop: string]: string }) { + const styleProps = { + backgroundColor: '#0091FFAA', + position: 'absolute', + left: 0, + top: 0, + width: 288, + height: 362, + ...extraStyleProps, + } + + return formatTestProjectCode(` + import * as React from 'react' + import { Storyboard } from 'utopia-api' + + + export var storyboard = ( + + + Hello + + + ) + `) +} + const emptyProject = formatTestProjectCode(`import * as React from 'react' import { Storyboard } from 'utopia-api' diff --git a/editor/src/components/text-editor/text-editor.tsx b/editor/src/components/text-editor/text-editor.tsx index 27ed7e893bbb..7cfb9f75bd06 100644 --- a/editor/src/components/text-editor/text-editor.tsx +++ b/editor/src/components/text-editor/text-editor.tsx @@ -342,6 +342,12 @@ const TextEditor = React.memo((props: TextEditorProps) => { currentElement.style.minWidth = '0.5px' } + const canDeleteWhenEmpty = canDeleteElementWhenEmpty( + metadataRef.current, + elementPath, + allElementPropsRef.current, + ) + return () => { const content = currentElement.textContent if (content != null) { @@ -352,10 +358,15 @@ const TextEditor = React.memo((props: TextEditorProps) => { savedContentRef.current = content requestAnimationFrame(() => dispatch([getSaveAction(elementPath, content, textProp)])) } + + // remove dangling empty spans + if (content != null && content.replace(/^\n/, '').length === 0 && canDeleteWhenEmpty) { + requestAnimationFrame(() => dispatch([deleteView(elementPath)])) + } } } } - }, [dispatch, elementPath, elementState, metadataRef, textProp]) + }, [dispatch, elementPath, elementState, textProp, metadataRef, allElementPropsRef]) React.useLayoutEffect(() => { if (myElement.current == null) { @@ -440,16 +451,7 @@ const TextEditor = React.memo((props: TextEditorProps) => { } else { dispatch([updateEditorMode(EditorModes.selectMode(null, false, 'none'))]) } - - // remove dangling empty spans - if ( - content != null && - content.replace(/^\n/, '').length === 0 && - canDeleteWhenEmpty(metadataRef.current, elementPath, allElementPropsRef.current) - ) { - requestAnimationFrame(() => dispatch([deleteView(elementPath)])) - } - }, [dispatch, elementPath, elementState, textProp, metadataRef, allElementPropsRef]) + }, [dispatch, elementPath, elementState, textProp]) const editorProps: React.DetailedHTMLProps< React.HTMLAttributes, @@ -621,7 +623,7 @@ const allowedStyleKeysForDeletion: string[] = [ 'font', ] -function canDeleteWhenEmpty( +function canDeleteElementWhenEmpty( jsxMetadata: ElementInstanceMetadataMap, path: ElementPath, allElementProps: AllElementProps, From c467d454708e339315e18840919f26e738cd26f1 Mon Sep 17 00:00:00 2001 From: Federico Ruggi <1081051+ruggi@users.noreply.github.com> Date: Fri, 29 Sep 2023 11:12:44 +0200 Subject: [PATCH 6/9] update helper --- .../text-editor/text-editor.spec.browser2.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/editor/src/components/text-editor/text-editor.spec.browser2.tsx b/editor/src/components/text-editor/text-editor.spec.browser2.tsx index cdf888261ca5..1131b23d876a 100644 --- a/editor/src/components/text-editor/text-editor.spec.browser2.tsx +++ b/editor/src/components/text-editor/text-editor.spec.browser2.tsx @@ -448,7 +448,7 @@ describe('Use the text editor', () => { 'await-first-dom-report', ) - await enterTextEditMode(editor, 'span') + await enterTextEditMode(editor, 'start', 'span') deleteTypedText() @@ -496,7 +496,7 @@ describe('Use the text editor', () => { 'await-first-dom-report', ) - await enterTextEditMode(editor, 'span') + await enterTextEditMode(editor, 'start', 'span') deleteTypedText() @@ -558,7 +558,7 @@ describe('Use the text editor', () => { 'await-first-dom-report', ) - await enterTextEditMode(editor, 'span') + await enterTextEditMode(editor, 'start', 'span') deleteTypedText() @@ -1970,14 +1970,15 @@ async function testModifierExpectingWayTooManySavesTheFirstTime( async function enterTextEditMode( editor: EditorRenderResult, + where: 'start' | 'end' = 'end', testId: string = 'div', ): Promise { const canvasControlsLayer = editor.renderedDOM.getByTestId(CanvasControlsContainerID) const element = editor.renderedDOM.getByTestId(testId) const bounds = element.getBoundingClientRect() const corner = { - x: bounds.x + 1, - y: bounds.y + 1, + x: bounds.x + (where === 'start' ? 1 : 50), + y: bounds.y + (where === 'start' ? 1 : 40), } FOR_TESTS_setNextGeneratedUid('text-span') @@ -1987,7 +1988,6 @@ async function enterTextEditMode( await mouseClickAtPoint(canvasControlsLayer, corner) await editor.getDispatchFollowUpActionsFinished() } - function typeText(text: string) { document.execCommand('insertText', false, text) } From 5d69256eeace177c96c15a619338693cd88c1ad5 Mon Sep 17 00:00:00 2001 From: Federico Ruggi <1081051+ruggi@users.noreply.github.com> Date: Fri, 29 Sep 2023 12:30:54 +0200 Subject: [PATCH 7/9] when content changes --- editor/src/components/text-editor/text-editor.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/editor/src/components/text-editor/text-editor.tsx b/editor/src/components/text-editor/text-editor.tsx index 7cfb9f75bd06..2cf12ce9406a 100644 --- a/editor/src/components/text-editor/text-editor.tsx +++ b/editor/src/components/text-editor/text-editor.tsx @@ -357,11 +357,11 @@ const TextEditor = React.memo((props: TextEditorProps) => { if (elementState != null && savedContentRef.current !== content) { savedContentRef.current = content requestAnimationFrame(() => dispatch([getSaveAction(elementPath, content, textProp)])) - } - // remove dangling empty spans - if (content != null && content.replace(/^\n/, '').length === 0 && canDeleteWhenEmpty) { - requestAnimationFrame(() => dispatch([deleteView(elementPath)])) + // remove dangling empty spans + if (content != null && content.replace(/^\n/, '').length === 0 && canDeleteWhenEmpty) { + requestAnimationFrame(() => dispatch([deleteView(elementPath)])) + } } } } From 4730c30b337aa6ba7f6102ece840cf8f6d6ca79d Mon Sep 17 00:00:00 2001 From: Federico Ruggi <1081051+ruggi@users.noreply.github.com> Date: Fri, 29 Sep 2023 16:13:28 +0200 Subject: [PATCH 8/9] drop style constraint --- .../components/text-editor/text-editor.tsx | 38 +++++-------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/editor/src/components/text-editor/text-editor.tsx b/editor/src/components/text-editor/text-editor.tsx index 2cf12ce9406a..91139ea6e20c 100644 --- a/editor/src/components/text-editor/text-editor.tsx +++ b/editor/src/components/text-editor/text-editor.tsx @@ -333,6 +333,7 @@ const TextEditor = React.memo((props: TextEditorProps) => { currentElement.focus() savedContentRef.current = currentElement.textContent + const initialText = currentElement.textContent const elementCanvasFrame = MetadataUtils.getFrameOrZeroRectInCanvasCoords( elementPath, @@ -357,11 +358,15 @@ const TextEditor = React.memo((props: TextEditorProps) => { if (elementState != null && savedContentRef.current !== content) { savedContentRef.current = content requestAnimationFrame(() => dispatch([getSaveAction(elementPath, content, textProp)])) - - // remove dangling empty spans - if (content != null && content.replace(/^\n/, '').length === 0 && canDeleteWhenEmpty) { - requestAnimationFrame(() => dispatch([deleteView(elementPath)])) - } + } + // remove dangling empty spans + if ( + content != null && + initialText !== content && + content.replace(/^\n/, '').length === 0 && + canDeleteWhenEmpty + ) { + requestAnimationFrame(() => dispatch([deleteView(elementPath)])) } } } @@ -608,21 +613,6 @@ function getSaveAction( return updateText(elementPath, escapeHTML(content, textProp), textProp) } -const allowedStyleKeysForDeletion: string[] = [ - 'position', - 'top', - 'left', - 'bottom', - 'right', - 'width', - 'height', - 'wordBreak', - 'fontSize', - 'fontWeight', - 'fontFamily', - 'font', -] - function canDeleteElementWhenEmpty( jsxMetadata: ElementInstanceMetadataMap, path: ElementPath, @@ -641,14 +631,6 @@ function canDeleteElementWhenEmpty( return false } - // it must not have defined styling - if ( - elementProps.style != null && - Object.keys(elementProps.style).some((key) => !allowedStyleKeysForDeletion.includes(key)) - ) { - return false - } - // it must not have defined event handlers if (Object.keys(elementProps).some((prop) => DOMEventHandlerNames.includes(prop as any))) { return false From d6cba5c35546364f13f0b17e393a7aa99fb2349d Mon Sep 17 00:00:00 2001 From: Federico Ruggi <1081051+ruggi@users.noreply.github.com> Date: Fri, 29 Sep 2023 16:47:19 +0200 Subject: [PATCH 9/9] drop outdated test --- .../text-editor/text-editor.spec.browser2.tsx | 62 ------------------- 1 file changed, 62 deletions(-) diff --git a/editor/src/components/text-editor/text-editor.spec.browser2.tsx b/editor/src/components/text-editor/text-editor.spec.browser2.tsx index 1131b23d876a..99da66b44416 100644 --- a/editor/src/components/text-editor/text-editor.spec.browser2.tsx +++ b/editor/src/components/text-editor/text-editor.spec.browser2.tsx @@ -467,68 +467,6 @@ describe('Use the text editor', () => { `), ) }) - it('does not delete span elements with styling', async () => { - const editor = await renderTestEditorWithCode( - formatTestProjectCode(` - import * as React from 'react' - import { Storyboard } from 'utopia-api' - - export var storyboard = ( - - - Hello - - - ) - `), - 'await-first-dom-report', - ) - - await enterTextEditMode(editor, 'start', 'span') - - deleteTypedText() - - await closeTextEditor() - await editor.getDispatchFollowUpActionsFinished() - - expect(editor.getEditorState().editor.mode.type).toEqual('select') - expect(getPrintedUiJsCode(editor.getEditorState())).toEqual( - formatTestProjectCode(` - import * as React from 'react' - import { Storyboard } from 'utopia-api' - - export var storyboard = ( - - - - ) - `), - ) - }) it('does not delete span elements with event handlers', async () => { const editor = await renderTestEditorWithCode( formatTestProjectCode(`