mirror of
https://github.com/penpot/penpot.git
synced 2025-01-22 14:39:45 -05:00
🐛 Improved behaviour on text options when not text is selected
This commit is contained in:
parent
1d575ece06
commit
4360c1fe4b
4 changed files with 117 additions and 34 deletions
|
@ -38,6 +38,7 @@
|
|||
- Fix problem when resizing texts inside groups [Taiga #2310](https://tree.taiga.io/project/penpot/issue/2310)
|
||||
- Fix problem with multiple exports [Taiga #2468](https://tree.taiga.io/project/penpot/issue/2468)
|
||||
- Allow import to continue from recoverable failures [#1412](https://github.com/penpot/penpot/issues/1412)
|
||||
- Improved behaviour on text options when not text is selected [Taiga #2390](https://tree.taiga.io/project/penpot/issue/2390)
|
||||
|
||||
### :arrow_up: Deps updates
|
||||
### :heart: Community contributions by (Thank you!)
|
||||
|
@ -81,8 +82,6 @@
|
|||
### :arrow_up: Deps updates
|
||||
|
||||
- Update log4j2 dependency.
|
||||
>>>>>>> main
|
||||
|
||||
|
||||
# 1.10.2-beta
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
(ns app.main.ui.workspace.shapes.text.editor
|
||||
(:require
|
||||
["draft-js" :as draft]
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.text :as txt]
|
||||
[app.main.data.workspace :as dw]
|
||||
|
@ -72,20 +71,18 @@
|
|||
(def empty-editor-state
|
||||
(ted/create-editor-state nil default-decorator))
|
||||
|
||||
(defn get-content-changes
|
||||
[old-state state]
|
||||
(let [old-blocks (js->clj (.toJS (.getBlockMap (.getCurrentContent ^js old-state)))
|
||||
:keywordize-keys false)
|
||||
new-blocks (js->clj (.toJS (.getBlockMap (.getCurrentContent ^js state)))
|
||||
(defn get-blocks-to-setup [block-changes]
|
||||
(->> block-changes
|
||||
(filter (fn [[_ v]]
|
||||
(nil? (:old v))))
|
||||
(mapv first)))
|
||||
|
||||
:keywordize-keys false)]
|
||||
(->> old-blocks
|
||||
(d/mapm
|
||||
(fn [bkey bstate]
|
||||
{:old (get bstate "text")
|
||||
:new (get-in new-blocks [bkey "text"])}))
|
||||
(filter #(contains? new-blocks (first %)))
|
||||
(into {}))))
|
||||
(defn get-blocks-to-add-styles
|
||||
[block-changes]
|
||||
(->> block-changes
|
||||
(filter (fn [[_ v]]
|
||||
(and (not= (:old v) (:new v)) (= (:old v) ""))))
|
||||
(mapv first)))
|
||||
|
||||
(mf/defc text-shape-edit-html
|
||||
{::mf/wrap [mf/memo]
|
||||
|
@ -143,25 +140,35 @@
|
|||
(fn [state]
|
||||
(let [old-state (mf/ref-val prev-value)]
|
||||
(if (and (some? state) (some? old-state))
|
||||
(let [block-states (get-content-changes old-state state)
|
||||
|
||||
block-to-add-styles
|
||||
(->> block-states
|
||||
(filter
|
||||
(fn [[_ v]]
|
||||
(and (not= (:old v) (:new v))
|
||||
(= (:old v) ""))))
|
||||
(mapv first))]
|
||||
(ted/apply-block-styles-to-content state block-to-add-styles))
|
||||
(let [block-changes (ted/get-content-changes old-state state)
|
||||
prev-data (ted/get-editor-current-inline-styles old-state)
|
||||
block-to-setup (get-blocks-to-setup block-changes)
|
||||
block-to-add-styles (get-blocks-to-add-styles block-changes)]
|
||||
(-> state
|
||||
(ted/setup-block-styles block-to-setup prev-data)
|
||||
(ted/apply-block-styles-to-content block-to-add-styles)))
|
||||
state))))
|
||||
|
||||
on-change
|
||||
(mf/use-callback
|
||||
(fn [val]
|
||||
(let [val (handle-change val)
|
||||
val (if (true? @blurred)
|
||||
(ted/add-editor-blur-selection val)
|
||||
(ted/remove-editor-blur-selection val))]
|
||||
(let [prev-val (mf/ref-val prev-value)
|
||||
styleOverride (ted/get-style-override prev-val)
|
||||
|
||||
;; If the content and the selection are the same we keep the style override
|
||||
keep-style? (and (some? styleOverride)
|
||||
(ted/content-equals prev-val val)
|
||||
(ted/selection-equals prev-val val))
|
||||
|
||||
val (cond-> (handle-change val)
|
||||
@blurred
|
||||
(ted/add-editor-blur-selection)
|
||||
|
||||
(not @blurred)
|
||||
(ted/remove-editor-blur-selection)
|
||||
|
||||
keep-style?
|
||||
(ted/set-style-override styleOverride))]
|
||||
(st/emit! (dwt/update-editor-state shape val)))))
|
||||
|
||||
on-editor
|
||||
|
|
|
@ -111,6 +111,16 @@
|
|||
[state]
|
||||
(impl/cursorToEnd state))
|
||||
|
||||
(defn setup-block-styles
|
||||
[state blocks attrs]
|
||||
(if (empty? blocks)
|
||||
state
|
||||
(->> blocks
|
||||
(reduce
|
||||
(fn [state block-key]
|
||||
(impl/updateBlockData state block-key (clj->js attrs)))
|
||||
state))))
|
||||
|
||||
(defn apply-block-styles-to-content
|
||||
[state blocks]
|
||||
(if (empty? blocks)
|
||||
|
@ -130,3 +140,37 @@
|
|||
(defn insert-text [state text attrs]
|
||||
(let [style (txt/attrs-to-styles attrs)]
|
||||
(impl/insertText state text (clj->js attrs) (clj->js style))))
|
||||
|
||||
(defn get-style-override [state]
|
||||
(.getInlineStyleOverride state))
|
||||
|
||||
(defn set-style-override [state inline-style]
|
||||
(impl/setInlineStyleOverride state inline-style))
|
||||
|
||||
(defn content-equals [state other]
|
||||
(.equals (.getCurrentContent state) (.getCurrentContent other)))
|
||||
|
||||
(defn selection-equals [state other]
|
||||
(impl/selectionEquals (.getSelection state) (.getSelection other)))
|
||||
|
||||
(defn get-content-changes
|
||||
[old-state state]
|
||||
(let [old-blocks (js->clj (.toJS (.getBlockMap (.getCurrentContent ^js old-state)))
|
||||
:keywordize-keys false)
|
||||
new-blocks (js->clj (.toJS (.getBlockMap (.getCurrentContent ^js state)))
|
||||
:keywordize-keys false)]
|
||||
(merge
|
||||
(into {}
|
||||
(comp (filter #(contains? new-blocks (first %)))
|
||||
(map (fn [[bkey bstate]]
|
||||
[bkey
|
||||
{:old (get bstate "text")
|
||||
:new (get-in new-blocks [bkey "text"])}])))
|
||||
old-blocks)
|
||||
(into {}
|
||||
(comp (filter #(not (contains? old-blocks (first %))))
|
||||
(map (fn [[bkey bstate]]
|
||||
[bkey
|
||||
{:old nil
|
||||
:new (get bstate "text")}])))
|
||||
new-blocks))))
|
||||
|
|
|
@ -121,15 +121,33 @@ export function updateCurrentBlockData(state, attrs) {
|
|||
return EditorState.push(state, content, "change-block-data");
|
||||
}
|
||||
|
||||
function addStylesToOverride(styles, other) {
|
||||
let result = styles;
|
||||
|
||||
for (let style of other) {
|
||||
const [p, k, v] = style.split("$$$");
|
||||
const prefix = [p, k, ""].join("$$$");
|
||||
|
||||
const curValue = result.find((it) => it.startsWith(prefix))
|
||||
if (curValue) {
|
||||
result = result.remove(curValue);
|
||||
}
|
||||
result = result.add(style);
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export function applyInlineStyle(state, styles) {
|
||||
const userSelection = state.getSelection();
|
||||
let selection = userSelection;
|
||||
let result = state;
|
||||
|
||||
if (selection.isCollapsed()) {
|
||||
selection = getSelectAllSelection(state);
|
||||
const currentOverride = state.getCurrentInlineStyle() || new OrderedSet();
|
||||
const styleOverride = addStylesToOverride(currentOverride, styles)
|
||||
return EditorState.setInlineStyleOverride(state, styleOverride);
|
||||
}
|
||||
|
||||
let result = state;
|
||||
let content = null;
|
||||
|
||||
for (let style of styles) {
|
||||
|
@ -300,6 +318,7 @@ export function getBlockData(state, blockKey) {
|
|||
|
||||
export function updateBlockData(state, blockKey, data) {
|
||||
const userSelection = state.getSelection();
|
||||
const inlineStyleOverride = state.getInlineStyleOverride();
|
||||
const content = state.getCurrentContent();
|
||||
const block = content.getBlockForKey(blockKey);
|
||||
const newBlock = mergeBlockData(block, data);
|
||||
|
@ -312,8 +331,10 @@ export function updateBlockData(state, blockKey, data) {
|
|||
blockData
|
||||
);
|
||||
|
||||
const result = EditorState.push(state, newContent, 'change-block-data');
|
||||
return EditorState.acceptSelection(result, userSelection);
|
||||
let result = EditorState.push(state, newContent, 'change-block-data');
|
||||
result = EditorState.acceptSelection(result, userSelection);
|
||||
result = EditorState.setInlineStyleOverride(result, inlineStyleOverride);
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getSelection(state) {
|
||||
|
@ -376,3 +397,15 @@ export function insertText(state, text, attrs, inlineStyles) {
|
|||
const resultSelection = SelectionState.createEmpty(selection.getStartKey());
|
||||
return EditorState.push(state, newContent, 'insert-fragment');
|
||||
}
|
||||
|
||||
export function setInlineStyleOverride(state, inlineStyles) {
|
||||
return EditorState.setInlineStyleOverride(state, inlineStyles);
|
||||
}
|
||||
|
||||
export function selectionEquals(selection, other) {
|
||||
return selection.getAnchorKey() === other.getAnchorKey() &&
|
||||
selection.getAnchorOffset() === other.getAnchorOffset() &&
|
||||
selection.getFocusKey() === other.getFocusKey() &&
|
||||
selection.getFocusOffset() === other.getFocusOffset() &&
|
||||
selection.getIsBackward() === other.getIsBackward();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue