diff --git a/frontend/text-editor/src/editor/content/dom/Style.js b/frontend/text-editor/src/editor/content/dom/Style.js index d194a13363..1875bef926 100644 --- a/frontend/text-editor/src/editor/content/dom/Style.js +++ b/frontend/text-editor/src/editor/content/dom/Style.js @@ -21,7 +21,7 @@ const DEFAULT_LINE_HEIGHT = "1.2"; export function mergeStyleDeclarations(target, source) { // This is better but it doesn't work in JSDOM // for (const styleName of source) { - for (let index = 0; index < source.length; index++) { + for (let index = 0; index < source.length; ++index) { const styleName = source.item(index); const styleValue = source.getPropertyValue(styleName); target.setProperty(styleName, styleValue); @@ -36,7 +36,7 @@ export function mergeStyleDeclarations(target, source) { * @returns {CSSStyleDeclaration} */ function resetStyleDeclaration(styleDeclaration) { - for (let index = 0; index < styleDeclaration.length; index++) { + for (let index = 0; index < styleDeclaration.length; ++index) { const styleName = styleDeclaration.item(index); styleDeclaration.removeProperty(styleName); } @@ -121,6 +121,19 @@ export function getComputedStyle(element) { return inertElement.style; } +/** + * Returns a property value + * + * @param {CSSStyleDeclaration} styleDeclaration + * @param {string} propertyName + * @returns {string|undefined} + */ +function getPropertyValue(styleDeclaration, propertyName) { + if (Array.from(styleDeclaration).includes(propertyName)) { + return styleDeclaration.getPropertyValue(propertyName) + } +} + /** * Normalizes style declaration. * @@ -140,34 +153,39 @@ export function normalizeStyles(node, styleDefaults = getStyleDefaultsDeclaratio // If there's a color property, we should convert it to // a --fills CSS variable property. - const fills = styleDeclaration.getPropertyValue("--fills"); - const color = styleDeclaration.getPropertyValue("color"); + const fills = getPropertyValue(styleDeclaration, "--fills"); + const color = getPropertyValue(styleDeclaration, "color"); if (color && !fills) { styleDeclaration.removeProperty("color"); styleDeclaration.setProperty("--fills", getFills(color)); - } else { + } else if (fills) { styleDeclaration.setProperty("--fills", fills); + } else { + styleDeclaration.setProperty( + "--fills", + JSON.stringify([["^ ","~:fill-color","#000000","~:fill-opacity",1]]), + ); } // If there's a font-family property and not a --font-id, then // we remove the font-family because it will not work. - const fontFamily = styleDeclaration.getPropertyValue("font-family"); - const fontId = styleDeclaration.getPropertyValue("--font-id"); + const fontFamily = getPropertyValue(styleDeclaration, "font-family"); + const fontId = getPropertyValue(styleDeclaration, "--font-id"); if (fontFamily && !fontId) { styleDeclaration.removeProperty("font-family"); } - const fontSize = styleDeclaration.getPropertyValue("font-size"); + const fontSize = getPropertyValue(styleDeclaration, "font-size"); if (!fontSize || fontSize === "0px") { styleDeclaration.setProperty("font-size", DEFAULT_FONT_SIZE); } - const lineHeight = styleDeclaration.getPropertyValue("line-height"); + const lineHeight = getPropertyValue(styleDeclaration, "line-height"); if (!lineHeight || lineHeight === "" || !lineHeight.endsWith("px")) { // TODO: PodrĂ­amos convertir unidades en decimales. styleDeclaration.setProperty("line-height", DEFAULT_LINE_HEIGHT); } else if (lineHeight.endsWith("px")) { - const fontSize = styleDeclaration.getPropertyValue("font-size"); + const fontSize = getPropertyValue(styleDeclaration, "font-size"); styleDeclaration.setProperty( "line-height", parseFloat(lineHeight) / parseFloat(fontSize), diff --git a/frontend/text-editor/src/editor/controllers/SelectionController.js b/frontend/text-editor/src/editor/controllers/SelectionController.js index dd01048552..0aefcdde7d 100644 --- a/frontend/text-editor/src/editor/controllers/SelectionController.js +++ b/frontend/text-editor/src/editor/controllers/SelectionController.js @@ -46,6 +46,7 @@ import CommandMutations from "../commands/CommandMutations.js"; import { isRoot, setRootStyles } from "../content/dom/Root.js"; import { SelectionDirection } from "./SelectionDirection.js"; import SafeGuard from "./SafeGuard.js"; +import { mergeStyleDeclarations } from '../content/dom/Style.js'; /** * Supported options for the SelectionController. @@ -56,39 +57,7 @@ import SafeGuard from "./SafeGuard.js"; /** * SelectionController uses the same concepts used by the Selection API but extending it to support - * our own internal model based on paragraphs (in drafconst textEditorMock = TextEditorMock.createTextEditorMockWithParagraphs([ - createParagraph([createInline(new Text("Hello, "))]), - createEmptyParagraph(), - createParagraph([createInline(new Text("World!"))]), - ]); - const root = textEditorMock.root; - const selection = document.getSelection(); - const selectionController = new SelectionController( - textEditorMock, - selection - ); - focus( - selection, - textEditorMock, - root.childNodes.item(2).firstChild.firstChild, - 0 - ); - selectionController.mergeBackwardParagraph(); - expect(textEditorMock.root).toBeInstanceOf(HTMLDivElement); - expect(textEditorMock.root.children.length).toBe(2); - expect(textEditorMock.root.dataset.itype).toBe("root"); - expect(textEditorMock.root.firstChild).toBeInstanceOf(HTMLDivElement); - expect(textEditorMock.root.firstChild.dataset.itype).toBe("paragraph"); - expect(textEditorMock.root.firstChild.firstChild).toBeInstanceOf( - HTMLSpanElement - ); - expect(textEditorMock.root.firstChild.firstChild.dataset.itype).toBe( - "inline" - ); - expect(textEditorMock.root.textContent).toBe("Hello, World!"); - expect(textEditorMock.root.firstChild.textContent).toBe("Hello, "); - expect(textEditorMock.root.lastChild.textContent).toBe("World!"); - t.js they were called blocks) and inlines. + * our own internal model based on paragraphs (in draft.js they were called blocks) and inlines. */ export class SelectionController extends EventTarget { /** @@ -253,11 +222,7 @@ export class SelectionController extends EventTarget { * @param {HTMLElement} element */ #applyStylesToCurrentStyle(element) { - for (let index = 0; index < element.style.length; index++) { - const styleName = element.style.item(index); - const styleValue = element.style.getPropertyValue(styleName); - this.#currentStyle.setProperty(styleName, styleValue); - } + mergeStyleDeclarations(this.#currentStyle, element.style); } /**