mirror of
https://github.com/penpot/penpot.git
synced 2025-01-21 06:02:32 -05:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
5bfd448483
18 changed files with 175 additions and 62 deletions
|
@ -195,13 +195,16 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [share-id (-> state :viewer-local :share-id)]
|
||||
(->> (rp/cmd! :update-comment-thread {:id id :is-resolved is-resolved :share-id share-id})
|
||||
(rx/catch (fn [{:keys [type code] :as cause}]
|
||||
(if (and (= type :restriction)
|
||||
(= code :max-quote-reached))
|
||||
(rx/throw cause)
|
||||
(rx/throw {:type :comment-error}))))
|
||||
(rx/ignore))))))
|
||||
(rx/concat
|
||||
(when is-resolved (rx/of
|
||||
(ptk/event ::ev/event {::ev/name "resolve-comment-thread" :thread-id id})))
|
||||
(->> (rp/cmd! :update-comment-thread {:id id :is-resolved is-resolved :share-id share-id})
|
||||
(rx/catch (fn [{:keys [type code] :as cause}]
|
||||
(if (and (= type :restriction)
|
||||
(= code :max-quote-reached))
|
||||
(rx/throw cause)
|
||||
(rx/throw {:type :comment-error}))))
|
||||
(rx/ignore)))))))
|
||||
|
||||
(defn add-comment
|
||||
[thread content]
|
||||
|
|
|
@ -2016,6 +2016,8 @@
|
|||
(map :id)
|
||||
(pcb/resize-parents changes))
|
||||
|
||||
orig-shapes (map (d/getf all-objects) selected)
|
||||
|
||||
selected (into (d/ordered-set)
|
||||
(comp
|
||||
(filter add-obj?)
|
||||
|
@ -2028,13 +2030,22 @@
|
|||
(some? drop-cell)
|
||||
(pcb/update-shapes [parent-id]
|
||||
#(ctl/add-children-to-cell % selected all-objects drop-cell)))
|
||||
|
||||
undo-id (js/Symbol)]
|
||||
|
||||
(rx/of (dwu/start-undo-transaction undo-id)
|
||||
(dch/commit-changes changes)
|
||||
(dws/select-shapes selected)
|
||||
(ptk/data-event :layout/update {:ids [frame-id]})
|
||||
(dwu/commit-undo-transaction undo-id)))))))
|
||||
(rx/concat
|
||||
(->> (filter ctk/instance-head? orig-shapes)
|
||||
(map (fn [{:keys [component-file]}]
|
||||
(ptk/event ::ev/event
|
||||
{::ev/name "use-library-component"
|
||||
::ev/origin "paste"
|
||||
:external-library (not= file-id component-file)})))
|
||||
(rx/from))
|
||||
(rx/of (dwu/start-undo-transaction undo-id)
|
||||
(dch/commit-changes changes)
|
||||
(dws/select-shapes selected)
|
||||
(ptk/data-event :layout/update {:ids [frame-id]})
|
||||
(dwu/commit-undo-transaction undo-id))))))))
|
||||
|
||||
(defn as-content [text]
|
||||
(let [paragraphs (->> (str/lines text)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
[app.common.types.shape.interactions :as ctsi]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.changes :as dch]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.data.workspace.shapes :as dwsh]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
|
@ -168,6 +169,7 @@
|
|||
objects (get page :objects)
|
||||
frame (cfh/get-root-frame objects (:id shape))
|
||||
|
||||
first? (not-any? #(seq (:interactions %)) (vals objects))
|
||||
flows (get page :flows)
|
||||
flow (ctp/get-frame-flow flows (:id frame))]
|
||||
(rx/concat
|
||||
|
@ -184,7 +186,10 @@
|
|||
|
||||
(when (and (not (connected-frame? objects (:id frame)))
|
||||
(nil? flow))
|
||||
(rx/of (add-flow (:id frame))))))))))
|
||||
(rx/of (add-flow (:id frame))))
|
||||
(when first?
|
||||
;; When the first interaction of the page is created we emit the event "create-prototype"
|
||||
(rx/of (ptk/event ::ev/event {::ev/name "create-prototype"})))))))))
|
||||
|
||||
(defn remove-interaction
|
||||
([shape index]
|
||||
|
|
|
@ -586,7 +586,7 @@
|
|||
in the given file library. Then selects the newly created instance."
|
||||
([file-id component-id position]
|
||||
(instantiate-component file-id component-id position nil))
|
||||
([file-id component-id position {:keys [start-move? initial-point id-ref]}]
|
||||
([file-id component-id position {:keys [start-move? initial-point id-ref origin]}]
|
||||
(dm/assert! (uuid? file-id))
|
||||
(dm/assert! (uuid? component-id))
|
||||
(dm/assert! (gpt/point? position))
|
||||
|
@ -600,6 +600,8 @@
|
|||
changes (-> (pcb/empty-changes it (:id page))
|
||||
(pcb/with-objects objects))
|
||||
|
||||
current-file-id (:current-file-id state)
|
||||
|
||||
[new-shape changes]
|
||||
(cll/generate-instantiate-component changes
|
||||
objects
|
||||
|
@ -608,12 +610,18 @@
|
|||
position
|
||||
page
|
||||
libraries)
|
||||
|
||||
undo-id (js/Symbol)]
|
||||
|
||||
(when id-ref
|
||||
(reset! id-ref (:id new-shape)))
|
||||
|
||||
(rx/of (dwu/start-undo-transaction undo-id)
|
||||
(rx/of (ptk/event
|
||||
::ev/event
|
||||
{::ev/name "use-library-component"
|
||||
::ev/origin origin
|
||||
:external-library (not= file-id current-file-id)})
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
(dch/commit-changes changes)
|
||||
(ptk/data-event :layout/update {:ids [(:id new-shape)]})
|
||||
(dws/select-shapes (d/ordered-set (:id new-shape)))
|
||||
|
|
|
@ -456,22 +456,30 @@
|
|||
|
||||
id-duplicated (first new-ids)
|
||||
|
||||
frames (into #{}
|
||||
(map #(get-in objects [% :frame-id]))
|
||||
ids)
|
||||
undo-id (js/Symbol)]
|
||||
|
||||
frames (into #{}
|
||||
(map #(get-in objects [% :frame-id]))
|
||||
ids)
|
||||
undo-id (js/Symbol)]
|
||||
(rx/concat
|
||||
(->> (map (d/getf objects) ids)
|
||||
(filter ctk/instance-head?)
|
||||
(map (fn [{:keys [component-file]}]
|
||||
(ptk/event ::ev/event
|
||||
{::ev/name "use-library-component"
|
||||
::ev/origin "duplicate"
|
||||
:external-library (not= file-id component-file)})))
|
||||
(rx/from))
|
||||
;; Warning: This order is important for the focus mode.
|
||||
(->> (rx/of
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
(dch/commit-changes changes)
|
||||
(when change-selection?
|
||||
(select-shapes new-ids))
|
||||
(ptk/data-event :layout/update {:ids frames})
|
||||
(memorize-duplicated id-original id-duplicated)
|
||||
(dwu/commit-undo-transaction undo-id))
|
||||
(rx/tap #(when (some? return-ref)
|
||||
(reset! return-ref id-duplicated))))))))))
|
||||
(->> (rx/of
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
(dch/commit-changes changes)
|
||||
(when change-selection?
|
||||
(select-shapes new-ids))
|
||||
(ptk/data-event :layout/update {:ids frames})
|
||||
(memorize-duplicated id-original id-duplicated)
|
||||
(dwu/commit-undo-transaction undo-id))
|
||||
(rx/tap #(when (some? return-ref)
|
||||
(reset! return-ref id-duplicated)))))))))))
|
||||
|
||||
(defn duplicate-selected
|
||||
([move-delta?]
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.shape-icon :as sir]
|
||||
[app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]]
|
||||
[app.main.ui.icons :as i]
|
||||
|
@ -18,6 +20,7 @@
|
|||
[app.main.ui.viewer.inspect.selection-feedback :refer [resolve-shapes]]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[potok.v2.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(defn- get-libraries
|
||||
|
@ -63,7 +66,9 @@
|
|||
(fn [new-section]
|
||||
(reset! section (keyword new-section))
|
||||
(when on-change-section
|
||||
(on-change-section (keyword new-section)))))
|
||||
(on-change-section (keyword new-section))
|
||||
(st/emit!
|
||||
(ptk/event ::ev/event {::ev/name "change-inspect-tab" :tab new-section})))))
|
||||
|
||||
handle-expand
|
||||
(mf/use-fn
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.data.workspace.colors :as mdc]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.refs :as refs]
|
||||
|
@ -20,15 +21,22 @@
|
|||
[app.util.i18n :refer [tr]]
|
||||
[app.util.keyboard :as kbd]
|
||||
[app.util.object :as obj]
|
||||
[potok.v2.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc palette-item
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [color size]}]
|
||||
[{:keys [color size selected]}]
|
||||
(letfn [(select-color [event]
|
||||
(st/emit!
|
||||
(dwl/add-recent-color color)
|
||||
(mdc/apply-color-from-palette color (kbd/alt? event))))]
|
||||
(mdc/apply-color-from-palette color (kbd/alt? event))
|
||||
(when (not= selected :recent)
|
||||
(ptk/event
|
||||
::ev/event
|
||||
{::ev/name "use-library-color"
|
||||
::ev/origin "color-palette"
|
||||
:external-library (not= selected :file)}))))]
|
||||
[:div {:class (stl/css-case :color-cell true
|
||||
:is-not-library-color (nil? (:id color))
|
||||
:no-text (<= size 64))
|
||||
|
@ -39,7 +47,7 @@
|
|||
|
||||
|
||||
(mf/defc palette
|
||||
[{:keys [current-colors size width]}]
|
||||
[{:keys [current-colors size width selected]}]
|
||||
(let [;; We had to do this due to a bug that leave some bugged colors
|
||||
current-colors (h/use-equal-memo (filter #(or (:gradient %) (:color %) (:image %)) current-colors))
|
||||
state (mf/use-state {:show-menu false})
|
||||
|
@ -132,7 +140,7 @@
|
|||
:max-width (str width "px")
|
||||
:right (str (* offset-step offset) "px")}}
|
||||
(for [[idx item] (map-indexed vector current-colors)]
|
||||
[:& palette-item {:color item :key idx :size size}])])]
|
||||
[:& palette-item {:color item :key idx :size size :selected selected}])])]
|
||||
(when show-arrows?
|
||||
[:button {:class (stl/css :right-arrow)
|
||||
:disabled (= offset max-offset)
|
||||
|
@ -170,4 +178,5 @@
|
|||
|
||||
[:& palette {:current-colors @colors
|
||||
:size size
|
||||
:width width}]))
|
||||
:width width
|
||||
:selected selected}]))
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[potok.v2.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc libraries
|
||||
|
@ -76,8 +77,14 @@
|
|||
|
||||
on-color-click
|
||||
(mf/use-fn
|
||||
(mf/deps state)
|
||||
(mf/deps state @selected)
|
||||
(fn [event]
|
||||
(when-not (= :recent @selected)
|
||||
(st/emit! (ptk/event
|
||||
::ev/event
|
||||
{::ev/name "use-library-color"
|
||||
::ev/origin "colorpicker"
|
||||
:external-library (not= :file @selected)})))
|
||||
(on-select-color state event)))]
|
||||
|
||||
;; Load library colors when the select is changed
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
[app.util.i18n :refer [tr] :as i18n]
|
||||
[app.util.timers :as timers]
|
||||
[okulary.core :as l]
|
||||
[potok.v2.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def menu-ref
|
||||
|
@ -532,7 +533,9 @@
|
|||
:title (tr "modals.delete-page.title")
|
||||
:message (tr "modals.delete-page.body")
|
||||
:on-accept delete-fn}))
|
||||
do-duplicate #(st/emit! (dw/duplicate-page id))
|
||||
do-duplicate #(st/emit!
|
||||
(dw/duplicate-page id)
|
||||
(ptk/event ::ev/event {::ev/name "duplicate-page"}))
|
||||
do-rename #(st/emit! (dw/start-rename-page-item id))]
|
||||
|
||||
[:*
|
||||
|
|
|
@ -70,7 +70,12 @@
|
|||
(fn [event]
|
||||
(st/emit!
|
||||
(dwl/add-recent-color color)
|
||||
(dc/apply-color-from-palette color (kbd/alt? event)))))
|
||||
(dc/apply-color-from-palette color (kbd/alt? event))
|
||||
(ptk/event
|
||||
::ev/event
|
||||
{::ev/name "use-library-color"
|
||||
::ev/origin "sidebar"
|
||||
:external-library (not local?)}))))
|
||||
|
||||
rename-color
|
||||
(mf/use-fn
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
|
@ -29,6 +30,7 @@
|
|||
[app.util.router :as rt]
|
||||
[cuerdas.core :as str]
|
||||
[okulary.core :as l]
|
||||
[potok.v2.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def lens:open-status
|
||||
|
@ -50,7 +52,15 @@
|
|||
(mf/use-fn
|
||||
(mf/deps file-id open?)
|
||||
(fn []
|
||||
(st/emit! (dw/set-assets-section-open file-id :library (not open?)))))]
|
||||
(st/emit! (dw/set-assets-section-open file-id :library (not open?)))))
|
||||
|
||||
on-click
|
||||
(mf/use-fn
|
||||
(fn [ev]
|
||||
(dom/stop-propagation ev)
|
||||
(st/emit!
|
||||
(ptk/event ::ev/event {::ev/name "navigate-to-library-file"}))))]
|
||||
|
||||
[:div {:class (stl/css-case :library-title true
|
||||
:open open?)}
|
||||
[:& title-bar {:collapsable true
|
||||
|
@ -65,11 +75,11 @@
|
|||
(mf/html [:div {:class (stl/css :special-title)}
|
||||
file-name]))}
|
||||
(when-not local?
|
||||
[:span {:title "Open library file"}
|
||||
[:span {:title (tr "workspace.assets.open-library")}
|
||||
[:a {:class (stl/css :file-link)
|
||||
:href (str "#" url)
|
||||
:target "_blank"
|
||||
:on-click dom/stop-propagation}
|
||||
:on-click on-click}
|
||||
i/open-link]])]]))
|
||||
|
||||
(mf/defc file-library-content
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
|
@ -26,6 +27,7 @@
|
|||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[cuerdas.core :as str]
|
||||
[okulary.core :as l]
|
||||
[potok.v2.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def lens:typography-section-state
|
||||
|
@ -97,7 +99,18 @@
|
|||
on-asset-click
|
||||
(mf/use-fn
|
||||
(mf/deps typography apply-typography on-asset-click)
|
||||
(partial on-asset-click typography-id apply-typography))]
|
||||
(partial on-asset-click typography-id apply-typography))
|
||||
|
||||
on-click
|
||||
(mf/use-fn
|
||||
(mf/deps typography apply-typography on-asset-click)
|
||||
(fn [ev]
|
||||
(st/emit! (ptk/event
|
||||
::ev/event
|
||||
{::ev/name "use-library-typography"
|
||||
::ev/origin "sidebar"
|
||||
:external-library (not local?)}))
|
||||
(on-asset-click ev)))]
|
||||
|
||||
[:div {:class (stl/css :typography-item)
|
||||
:ref item-ref
|
||||
|
@ -113,7 +126,7 @@
|
|||
:typography typography
|
||||
:local? local?
|
||||
:selected? (contains? selected typography-id)
|
||||
:on-click on-asset-click
|
||||
:on-click on-click
|
||||
:on-change handle-change
|
||||
:on-context-menu on-context-menu
|
||||
:editing? editing?
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
[app.main.fonts :as f]
|
||||
[app.main.refs :as refs]
|
||||
|
@ -18,23 +19,30 @@
|
|||
[app.util.i18n :refer [tr]]
|
||||
[app.util.object :as obj]
|
||||
[cuerdas.core :as str]
|
||||
[potok.v2.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc typography-item
|
||||
[{:keys [file-id selected-ids typography name-only? size]}]
|
||||
[{:keys [file-id selected-ids typography name-only? size current-file-id]}]
|
||||
(let [font-data (f/get-font-data (:font-id typography))
|
||||
font-variant-id (:font-variant-id typography)
|
||||
variant-data (->> font-data :variants (d/seek #(= (:id %) font-variant-id)))
|
||||
|
||||
|
||||
handle-click
|
||||
(mf/use-callback
|
||||
(mf/deps typography selected-ids)
|
||||
(mf/deps typography selected-ids file-id current-file-id)
|
||||
(fn []
|
||||
(let [attrs (merge
|
||||
{:typography-ref-file file-id
|
||||
:typography-ref-id (:id typography)}
|
||||
(dissoc typography :id :name))]
|
||||
|
||||
(st/emit! (ptk/event
|
||||
::ev/event
|
||||
{::ev/name "use-library-typography"
|
||||
::ev/origin "text-palette"
|
||||
:external-library (not= file-id current-file-id)}))
|
||||
(run! #(st/emit!
|
||||
(dwt/update-text-attrs
|
||||
{:id %
|
||||
|
@ -160,6 +168,7 @@
|
|||
[:& typography-item
|
||||
{:key idx
|
||||
:file-id file-id
|
||||
:current-file-id current-file-id
|
||||
:selected-ids selected-ids
|
||||
:typography item
|
||||
:size size}])])]
|
||||
|
|
|
@ -422,7 +422,7 @@
|
|||
file-id
|
||||
(:id component)
|
||||
(gpt/point final-x final-y)
|
||||
{:start-move? true :initial-point viewport-coord})))))
|
||||
{:start-move? true :initial-point viewport-coord :origin "sidebar"})))))
|
||||
(when (or (dnd/has-type? e "penpot/shape")
|
||||
(dnd/has-type? e "penpot/component")
|
||||
(dnd/has-type? e "Files")
|
||||
|
|
|
@ -676,7 +676,7 @@
|
|||
|
||||
:else
|
||||
(let [id-ref (atom nil)]
|
||||
(st/emit! (dwl/instantiate-component file-id id (gpt/point 0 0) {:id-ref id-ref}))
|
||||
(st/emit! (dwl/instantiate-component file-id id (gpt/point 0 0) {:id-ref id-ref :origin "plugin"}))
|
||||
(shape/shape-proxy plugin-id @id-ref))))
|
||||
|
||||
:getPluginData
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -4069,7 +4069,7 @@ msgstr "local library"
|
|||
msgid "workspace.assets.not-found"
|
||||
msgstr "No assets found"
|
||||
|
||||
#, unused
|
||||
#: src/app/main/ui/workspace/sidebar/assets/file_library.cljs:68
|
||||
msgid "workspace.assets.open-library"
|
||||
msgstr "Open library file"
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue