mirror of
https://github.com/penpot/penpot.git
synced 2025-12-11 22:14:05 +01:00
WIP
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user