mirror of
https://github.com/penpot/penpot.git
synced 2026-08-01 19:06:18 +00:00
Merge pull request #7879 from penpot/elenatorro-12797-fix-update-spans
🐛 Fix paragraph with text spans with multiple styles
This commit is contained in:
commit
4e84deca44
@ -158,7 +158,7 @@
|
|||||||
(defn- store-font-id
|
(defn- store-font-id
|
||||||
[shape-id font-data asset-id emoji? fallback?]
|
[shape-id font-data asset-id emoji? fallback?]
|
||||||
(when asset-id
|
(when asset-id
|
||||||
(let [uri (font-id->ttf-url (:font-id font-data) asset-id (:font-variant-id font-data) (:weight font-data) (:style font-data))
|
(let [uri (font-id->ttf-url (:font-id font-data) asset-id (:font-variant-id font-data) (:weight font-data) (:style-name font-data))
|
||||||
id-buffer (uuid/get-u32 (:wasm-id font-data))
|
id-buffer (uuid/get-u32 (:wasm-id font-data))
|
||||||
font-data (assoc font-data :family-id-buffer id-buffer)
|
font-data (assoc font-data :family-id-buffer id-buffer)
|
||||||
font-stored? (not= 0 (h/call wasm/internal-module "_is_font_uploaded"
|
font-stored? (not= 0 (h/call wasm/internal-module "_is_font_uploaded"
|
||||||
@ -200,7 +200,7 @@
|
|||||||
font-style-fallback (or (:font-style span) (:font-style paragraph))
|
font-style-fallback (or (:font-style span) (:font-style paragraph))
|
||||||
font-data (font-db-data font-id font-variant-id font-weight-fallback font-style-fallback)]
|
font-data (font-db-data font-id font-variant-id font-weight-fallback font-style-fallback)]
|
||||||
(-> span
|
(-> span
|
||||||
(assoc :font-variant-id (or (:name font-data) (:id font-data) font-variant-id)
|
(assoc :font-variant-id (or (:id font-data) (:id font-data) font-variant-id)
|
||||||
:font-weight (or (:weight font-data) font-weight-fallback)
|
:font-weight (or (:weight font-data) font-weight-fallback)
|
||||||
:font-style (or (:style font-data) font-style-fallback)))))
|
:font-style (or (:style font-data) font-style-fallback)))))
|
||||||
|
|
||||||
@ -212,7 +212,7 @@
|
|||||||
font-style-fallback (:font-style paragraph)
|
font-style-fallback (:font-style paragraph)
|
||||||
font-data (font-db-data font-id font-variant-id font-weight-fallback font-style-fallback)]
|
font-data (font-db-data font-id font-variant-id font-weight-fallback font-style-fallback)]
|
||||||
(-> paragraph
|
(-> paragraph
|
||||||
(assoc :font-variant-id (or (:name font-data) (:id font-data) font-variant-id)
|
(assoc :font-variant-id (or (:id font-data) (:id font-data) font-variant-id)
|
||||||
:font-weight (or (:weight font-data) font-weight-fallback)
|
:font-weight (or (:weight font-data) font-weight-fallback)
|
||||||
:font-style (or (:style font-data) font-style-fallback)))))
|
:font-style (or (:style font-data) font-style-fallback)))))
|
||||||
|
|
||||||
@ -284,24 +284,29 @@
|
|||||||
[shape-id font]
|
[shape-id font]
|
||||||
(let [font-id (get font :font-id)
|
(let [font-id (get font :font-id)
|
||||||
font-variant-id (get font :font-variant-id)
|
font-variant-id (get font :font-variant-id)
|
||||||
|
normalized-variant-id (when font-variant-id
|
||||||
|
(-> font-variant-id
|
||||||
|
(str/lower)
|
||||||
|
(str/replace #"\s+" "")))
|
||||||
font-weight-fallback (or (get font :font-weight) 400)
|
font-weight-fallback (or (get font :font-weight) 400)
|
||||||
font-style-fallback (or (get font :font-style) "normal")
|
font-style-fallback (or (get font :font-style) "normal")
|
||||||
emoji? (get font :is-emoji false)
|
emoji? (get font :is-emoji false)
|
||||||
fallback? (get font :is-fallback false)
|
fallback? (get font :is-fallback false)
|
||||||
font-data (font-db-data font-id font-variant-id font-weight-fallback font-style-fallback)
|
font-data (font-db-data font-id normalized-variant-id font-weight-fallback font-style-fallback)
|
||||||
wasm-id (font-id->uuid font-id)
|
wasm-id (font-id->uuid font-id)
|
||||||
raw-weight (or (:weight font-data) font-weight-fallback)
|
raw-weight (or (:weight font-data) font-weight-fallback)
|
||||||
weight (serialize-font-weight raw-weight)
|
weight (serialize-font-weight raw-weight)
|
||||||
style (serialize-font-style (cond
|
style (cond
|
||||||
(str/includes? font-variant-id "italic") "italic"
|
(str/includes? (or normalized-variant-id "") "italic") "italic"
|
||||||
(str/includes? raw-weight "italic") "italic"
|
(str/includes? raw-weight "italic") "italic"
|
||||||
:else font-style-fallback))
|
:else font-style-fallback)
|
||||||
variant-id (or (:name font-data) font-variant-id)
|
variant-id (or (:id font-data) normalized-variant-id)
|
||||||
asset-id (font-id->asset-id font-id variant-id raw-weight style)
|
asset-id (font-id->asset-id font-id variant-id raw-weight style)
|
||||||
font-data {:wasm-id wasm-id
|
font-data {:wasm-id wasm-id
|
||||||
:font-id font-id
|
:font-id font-id
|
||||||
:font-variant-id variant-id
|
:font-variant-id variant-id
|
||||||
:style style
|
:style (serialize-font-style style)
|
||||||
|
:style-name style
|
||||||
:weight weight}]
|
:weight weight}]
|
||||||
(store-font-id shape-id font-data asset-id emoji? fallback?)))
|
(store-font-id shape-id font-data asset-id emoji? fallback?)))
|
||||||
|
|
||||||
@ -329,7 +334,7 @@
|
|||||||
font-style-fallback (or font-style (:font-style txt/default-typography) "normal")
|
font-style-fallback (or font-style (:font-style txt/default-typography) "normal")
|
||||||
font-data (font-db-data resolved-font-id resolved-variant-id font-weight-fallback font-style-fallback)
|
font-data (font-db-data resolved-font-id resolved-variant-id font-weight-fallback font-style-fallback)
|
||||||
font-ref {:font-id resolved-font-id
|
font-ref {:font-id resolved-font-id
|
||||||
:font-variant-id (or (:name font-data) (:id font-data) resolved-variant-id)
|
:font-variant-id (or (:id font-data) (:name font-data) resolved-variant-id)
|
||||||
:font-weight (or (:weight font-data) font-weight-fallback)
|
:font-weight (or (:weight font-data) font-weight-fallback)
|
||||||
:font-style (or (:style font-data) font-style-fallback)}]
|
:font-style (or (:style font-data) font-style-fallback)}]
|
||||||
(conj result font-ref)))
|
(conj result font-ref)))
|
||||||
|
|||||||
@ -339,13 +339,14 @@ export function setStylesFromObject(element, allowedStyles, styleObject) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let styleValue = styleObject[styleName];
|
let styleValue = styleObject[styleName];
|
||||||
|
if (!styleValue)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (styleName === "font-family") {
|
if (styleName === "font-family") {
|
||||||
styleValue = sanitizeFontFamily(styleValue);
|
styleValue = sanitizeFontFamily(styleValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (styleValue) {
|
setStyle(element, styleName, styleValue, styleUnit);
|
||||||
setStyle(element, styleName, styleValue, styleUnit);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -238,7 +238,11 @@ export class SelectionController extends EventTarget {
|
|||||||
#applyStylesFromElementToCurrentStyle(element) {
|
#applyStylesFromElementToCurrentStyle(element) {
|
||||||
for (let index = 0; index < element.style.length; index++) {
|
for (let index = 0; index < element.style.length; index++) {
|
||||||
const styleName = element.style.item(index);
|
const styleName = element.style.item(index);
|
||||||
|
if (styleName === "--fills") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let styleValue = element.style.getPropertyValue(styleName);
|
let styleValue = element.style.getPropertyValue(styleName);
|
||||||
|
|
||||||
if (styleName === "font-family") {
|
if (styleName === "font-family") {
|
||||||
styleValue = sanitizeFontFamily(styleValue);
|
styleValue = sanitizeFontFamily(styleValue);
|
||||||
}
|
}
|
||||||
@ -1939,11 +1943,21 @@ export class SelectionController extends EventTarget {
|
|||||||
const textSpan = this.startTextSpan;
|
const textSpan = this.startTextSpan;
|
||||||
const midText = startNode.splitText(startOffset);
|
const midText = startNode.splitText(startOffset);
|
||||||
const endText = midText.splitText(endOffset - startOffset);
|
const endText = midText.splitText(endOffset - startOffset);
|
||||||
const midTextSpan = createTextSpanFrom(textSpan, midText, newStyles);
|
|
||||||
textSpan.after(midTextSpan);
|
// Only create text span if midText is not empty
|
||||||
if (endText.length > 0) {
|
if (midText.nodeValue && midText.nodeValue.length > 0) {
|
||||||
const endTextSpan = createTextSpan(endText, textSpan.style);
|
const midTextSpan = createTextSpanFrom(textSpan, midText, newStyles);
|
||||||
midTextSpan.after(endTextSpan);
|
textSpan.after(midTextSpan);
|
||||||
|
if (endText.length > 0) {
|
||||||
|
const endTextSpan = createTextSpan(endText, textSpan.style);
|
||||||
|
midTextSpan.after(endTextSpan);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If midText is empty, just create endTextSpan if needed
|
||||||
|
if (endText.length > 0) {
|
||||||
|
const endTextSpan = createTextSpan(endText, textSpan.style);
|
||||||
|
textSpan.after(endTextSpan);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: This is necessary because sometimes
|
// NOTE: This is necessary because sometimes
|
||||||
@ -1960,7 +1974,7 @@ export class SelectionController extends EventTarget {
|
|||||||
// the styles are applied to the current caret
|
// the styles are applied to the current caret
|
||||||
else if (
|
else if (
|
||||||
this.startOffset === this.endOffset &&
|
this.startOffset === this.endOffset &&
|
||||||
this.endOffset === endNode.nodeValue.length
|
this.endOffset === endNode.nodeValue?.length
|
||||||
) {
|
) {
|
||||||
const newTextSpan = createVoidTextSpan(newStyles);
|
const newTextSpan = createVoidTextSpan(newStyles);
|
||||||
this.endTextSpan.after(newTextSpan);
|
this.endTextSpan.after(newTextSpan);
|
||||||
@ -1996,7 +2010,8 @@ export class SelectionController extends EventTarget {
|
|||||||
// new text span.
|
// new text span.
|
||||||
if (
|
if (
|
||||||
this.#textNodeIterator.currentNode === startNode &&
|
this.#textNodeIterator.currentNode === startNode &&
|
||||||
startOffset > 0
|
startOffset > 0 &&
|
||||||
|
startOffset < (startNode.nodeValue?.length || 0)
|
||||||
) {
|
) {
|
||||||
const newTextSpan = splitTextSpan(textSpan, startOffset);
|
const newTextSpan = splitTextSpan(textSpan, startOffset);
|
||||||
setTextSpanStyles(newTextSpan, newStyles);
|
setTextSpanStyles(newTextSpan, newStyles);
|
||||||
@ -2011,14 +2026,15 @@ export class SelectionController extends EventTarget {
|
|||||||
(this.#textNodeIterator.currentNode !== startNode &&
|
(this.#textNodeIterator.currentNode !== startNode &&
|
||||||
this.#textNodeIterator.currentNode !== endNode) ||
|
this.#textNodeIterator.currentNode !== endNode) ||
|
||||||
(this.#textNodeIterator.currentNode === endNode &&
|
(this.#textNodeIterator.currentNode === endNode &&
|
||||||
endOffset === endNode.nodeValue.length)
|
endOffset === endNode.nodeValue?.length)
|
||||||
) {
|
) {
|
||||||
setTextSpanStyles(textSpan, newStyles);
|
setTextSpanStyles(textSpan, newStyles);
|
||||||
|
|
||||||
// If we're at end node
|
// If we're at end node
|
||||||
} else if (
|
} else if (
|
||||||
this.#textNodeIterator.currentNode === endNode &&
|
this.#textNodeIterator.currentNode === endNode &&
|
||||||
endOffset < endNode.nodeValue.length
|
endOffset < endNode.nodeValue?.length &&
|
||||||
|
endOffset > 0
|
||||||
) {
|
) {
|
||||||
const newTextSpan = splitTextSpan(textSpan, endOffset);
|
const newTextSpan = splitTextSpan(textSpan, endOffset);
|
||||||
setTextSpanStyles(textSpan, newStyles);
|
setTextSpanStyles(textSpan, newStyles);
|
||||||
|
|||||||
@ -81,6 +81,8 @@ export class StyleDeclaration {
|
|||||||
return this.setProperty(name, value);
|
return this.setProperty(name, value);
|
||||||
} else if (currentValue === "" && ["initial", "none"].includes(value)) {
|
} else if (currentValue === "" && ["initial", "none"].includes(value)) {
|
||||||
return this.setProperty(name, value);
|
return this.setProperty(name, value);
|
||||||
|
} else if (currentValue !== value && name === "--fills") {
|
||||||
|
return this.setProperty(name, value);
|
||||||
} else if (currentValue !== value) {
|
} else if (currentValue !== value) {
|
||||||
return this.setProperty(name, "mixed");
|
return this.setProperty(name, "mixed");
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user