0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-06 14:50:20 -05:00

Merge pull request #5383 from penpot/azazeln28-fix-text-editor-more-issues

🐛 Fix text editor issues
This commit is contained in:
Andrey Antukh 2024-11-29 10:17:43 +01:00 committed by GitHub
commit 5e2b847202
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 30 additions and 13 deletions

View file

@ -150,6 +150,7 @@ export function normalizeStyles(node, styleDefaults) {
}
return styleDeclaration
}
/**
* Sets a single style property value of an element.
*
@ -210,6 +211,8 @@ export function getStyleFromDeclaration(style, styleName, styleUnit) {
const styleValueAsNumber = parseFloat(styleValue);
if (styleName === "font-size") {
return getStyleFontSize(styleValueAsNumber, styleValue);
} else if (styleName === "line-height") {
return styleValue
}
if (Number.isNaN(styleValueAsNumber)) {
return styleValue;

View file

@ -479,6 +479,9 @@ export class SelectionController extends EventTarget {
* Selects all content.
*/
selectAll() {
if (this.#textEditor.isEmpty) {
return this
}
this.#selection.selectAllChildren(this.#textEditor.root);
return this;
}
@ -1466,8 +1469,8 @@ export class SelectionController extends EventTarget {
let previousNode = null;
let nextNode = null;
// This is the simplest case, when the startNode and the endNode
// are the same and they're a textNode.
// This is the simplest case, when the startNode and
// the endNode are the same and they're textNodes.
if (startNode === endNode) {
this.#textNodeIterator.currentNode = startNode;
previousNode = this.#textNodeIterator.previousNode();
@ -1510,15 +1513,17 @@ export class SelectionController extends EventTarget {
do {
SafeGuard.update();
const currentNode = this.#textNodeIterator.currentNode;
const { currentNode } = this.#textNodeIterator;
// We retrieve the inline and paragraph of the
// current node.
const inline = getInline(this.#textNodeIterator.currentNode);
const paragraph = getParagraph(this.#textNodeIterator.currentNode);
const inline = getInline(currentNode);
const paragraph = getParagraph(currentNode);
affectedInlines.add(inline);
affectedParagraphs.add(paragraph);
let shouldRemoveNodeCompletely = false;
if (this.#textNodeIterator.currentNode === startNode) {
if (currentNode === startNode) {
if (startOffset === 0) {
// We should remove this node completely.
shouldRemoveNodeCompletely = true;
@ -1526,7 +1531,7 @@ export class SelectionController extends EventTarget {
// We should remove this node partially.
currentNode.nodeValue = currentNode.nodeValue.slice(0, startOffset);
}
} else if (this.#textNodeIterator.currentNode === endNode) {
} else if (currentNode === endNode) {
if (isLineBreak(endNode)
|| (isTextNode(endNode)
&& endOffset === endNode.nodeValue.length)) {
@ -1549,13 +1554,11 @@ export class SelectionController extends EventTarget {
if (currentNode === startNode) {
continue;
}
if (currentNode === endNode) {
break;
}
if (inline.childNodes.length === 0) {
inline.remove();
}
if (paragraph !== startParagraph && paragraph.children.length === 0) {
paragraph.remove();
}
@ -1576,13 +1579,16 @@ export class SelectionController extends EventTarget {
}
}
if (startInline.childNodes.length === 0 && endInline.childNodes.length > 0) {
if (startInline.childNodes.length === 0
&& endInline.childNodes.length > 0) {
startInline.remove();
return this.collapse(endNode, 0);
} else if (startInline.childNodes.length > 0 && endInline.childNodes.length === 0) {
} else if (startInline.childNodes.length > 0
&& endInline.childNodes.length === 0) {
endInline.remove();
return this.collapse(startNode, startOffset);
} else if (startInline.childNodes.length === 0 && endInline.childNodes.length === 0) {
} else if (startInline.childNodes.length === 0
&& endInline.childNodes.length === 0) {
const previousInline = startInline.previousElementSibling;
const nextInline = endInline.nextElementSibling;
startInline.remove();
@ -1641,6 +1647,14 @@ export class SelectionController extends EventTarget {
midInline.after(endInline);
}
// NOTE: This is necessary because sometimes
// inlines are splitted from the beginning
// to a mid offset and then the starting node
// remains empty.
if (inline.firstChild.nodeValue === "") {
inline.remove();
}
// FIXME: This can change focus <-> anchor order.
this.setSelection(midText, 0, midText, midText.nodeValue.length);