mirror of
https://github.com/penpot/penpot.git
synced 2026-08-31 17:19:11 +00:00
🐛 Fix font change regression and activate font preview by default (#11341)
* ✨ Materialize font-preview flag to make it permanent * 🐛 Fix font change regression when WebGL is disabled * 📎 Add fixes for e2e tests * 🐛 Fix font change from legacy render --------- Co-authored-by: Luis de Dios <luis.dedios@kaleidos.net>
This commit is contained in:
parent
6bedd5ac76
commit
43bbf756b0
@ -569,7 +569,7 @@ test.describe("Tokens - creation", () => {
|
|||||||
});
|
});
|
||||||
await selectDropdown.click();
|
await selectDropdown.click();
|
||||||
|
|
||||||
const fontOption = tokensUpdateCreateModal.getByText("ABeeZee");
|
const fontOption = tokensUpdateCreateModal.getByRole('img', { name: 'ABeeZee' })
|
||||||
await expect(fontOption).toBeVisible();
|
await expect(fontOption).toBeVisible();
|
||||||
|
|
||||||
await fontOption.click();
|
await fontOption.click();
|
||||||
@ -583,7 +583,7 @@ test.describe("Tokens - creation", () => {
|
|||||||
name: "Search font",
|
name: "Search font",
|
||||||
});
|
});
|
||||||
await searchField.fill("alme");
|
await searchField.fill("alme");
|
||||||
const fontOption2 = tokensUpdateCreateModal.getByText("Almendra Display");
|
const fontOption2 = tokensUpdateCreateModal.getByRole('img', {name: "Almendra Display"});
|
||||||
await expect(fontOption2).toBeVisible();
|
await expect(fontOption2).toBeVisible();
|
||||||
await fontOption2.click();
|
await fontOption2.click();
|
||||||
|
|
||||||
@ -1521,7 +1521,7 @@ test.describe("Tokens - creation", () => {
|
|||||||
});
|
});
|
||||||
await selectDropdown.click();
|
await selectDropdown.click();
|
||||||
|
|
||||||
const fontOption = tokensUpdateCreateModal.getByText("ABeeZee");
|
const fontOption = tokensUpdateCreateModal.getByRole("img", {name: "ABeeZee"});
|
||||||
await expect(fontOption).toBeVisible();
|
await expect(fontOption).toBeVisible();
|
||||||
|
|
||||||
await fontOption.click();
|
await fontOption.click();
|
||||||
@ -1536,7 +1536,7 @@ test.describe("Tokens - creation", () => {
|
|||||||
name: "Search font",
|
name: "Search font",
|
||||||
});
|
});
|
||||||
await searchField.fill("alme");
|
await searchField.fill("alme");
|
||||||
const fontOption2 = tokensUpdateCreateModal.getByText("Almendra Display");
|
const fontOption2 = tokensUpdateCreateModal.getByRole("img", {name: "Almendra Display"});
|
||||||
await expect(fontOption2).toBeVisible();
|
await expect(fontOption2).toBeVisible();
|
||||||
await fontOption2.click();
|
await fontOption2.click();
|
||||||
await expect(
|
await expect(
|
||||||
|
|||||||
@ -174,7 +174,12 @@
|
|||||||
(rx/mapcat (fn [_]
|
(rx/mapcat (fn [_]
|
||||||
(rx/from (fonts/ensure-loaded! font-id font-variant-id))))
|
(rx/from (fonts/ensure-loaded! font-id font-variant-id))))
|
||||||
(rx/take-until (text-work-stopper stream))
|
(rx/take-until (text-work-stopper stream))
|
||||||
(rx/ignore)
|
(rx/mapcat (fn [_]
|
||||||
|
(st/emit! (dwsh/update-shapes
|
||||||
|
ids
|
||||||
|
#(dissoc % :position-data)
|
||||||
|
{:save-undo? false}))
|
||||||
|
(rx/empty)))
|
||||||
(wrf/with-pending :font ids))))
|
(wrf/with-pending :font ids))))
|
||||||
|
|
||||||
;; -- Content helpers
|
;; -- Content helpers
|
||||||
@ -850,16 +855,16 @@
|
|||||||
::resize-text-debounce-event)))))
|
::resize-text-debounce-event)))))
|
||||||
(rx/empty))))))
|
(rx/empty))))))
|
||||||
|
|
||||||
(defn save-font
|
(defn save-default-font
|
||||||
[data]
|
[data]
|
||||||
(ptk/reify ::save-font
|
(ptk/reify ::save-default-font
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [multiple? (->> data vals (d/seek #(= % :multiple)))]
|
(let [multiple? (->> data vals (d/seek #(= % :multiple)))
|
||||||
|
font (dissoc data :typography-ref-id :typography-ref-file)]
|
||||||
(cond-> state
|
(cond-> state
|
||||||
(not multiple?)
|
(not multiple?)
|
||||||
(assoc-in [:workspace-global :default-font]
|
(update :workspace-global assoc :default-font font))))))
|
||||||
(dissoc data :typography-ref-id :typography-ref-file)))))))
|
|
||||||
|
|
||||||
(defn apply-text-modifier
|
(defn apply-text-modifier
|
||||||
[shape text-modifier]
|
[shape text-modifier]
|
||||||
|
|||||||
@ -242,7 +242,7 @@
|
|||||||
(when (zero? (:refs new-state))
|
(when (zero? (:refs new-state))
|
||||||
(dom/remove! node))))
|
(dom/remove! node))))
|
||||||
|
|
||||||
(defn- add-font-css!
|
(defn- add-font-css
|
||||||
"Creates a style element and attaches it to the dom."
|
"Creates a style element and attaches it to the dom."
|
||||||
[id css]
|
[id css]
|
||||||
(let [node (dom/create-element "style")]
|
(let [node (dom/create-element "style")]
|
||||||
@ -306,7 +306,7 @@
|
|||||||
(->> (request-gfont-css url)
|
(->> (request-gfont-css url)
|
||||||
(rx/map process-gfont-css)
|
(rx/map process-gfont-css)
|
||||||
(rx/tap #(on-loaded id))
|
(rx/tap #(on-loaded id))
|
||||||
(rx/subs! (partial add-font-css! id)
|
(rx/subs! (partial add-font-css id)
|
||||||
#(when (fn? on-failed) (on-failed %))))
|
#(when (fn? on-failed) (on-failed %))))
|
||||||
nil)))
|
nil)))
|
||||||
|
|
||||||
@ -346,7 +346,7 @@
|
|||||||
(when (globals/browser?)
|
(when (globals/browser?)
|
||||||
(log/dbg :hint "load-font" :font-id id :backend "custom")
|
(log/dbg :hint "load-font" :font-id id :backend "custom")
|
||||||
(let [css (generate-custom-font-css font)]
|
(let [css (generate-custom-font-css font)]
|
||||||
(add-font-css! id css)
|
(add-font-css id css)
|
||||||
(when (fn? on-loaded)
|
(when (fn? on-loaded)
|
||||||
(on-loaded)))))
|
(on-loaded)))))
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,6 @@
|
|||||||
(:require-macros [app.main.style :as stl])
|
(:require-macros [app.main.style :as stl])
|
||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.config :as cf]
|
|
||||||
[app.main.data.common :as dcm]
|
[app.main.data.common :as dcm]
|
||||||
[app.main.data.helpers :as dsh]
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.persistence :as dps]
|
[app.main.data.persistence :as dps]
|
||||||
@ -229,12 +228,8 @@
|
|||||||
(st/emit! (dps/initialize-persistence)
|
(st/emit! (dps/initialize-persistence)
|
||||||
(dpl/update-plugins-permissions-peek)))
|
(dpl/update-plugins-permissions-peek)))
|
||||||
|
|
||||||
;; FLAG :font-preview — prefetch the preview sprite markup on workspace mount
|
|
||||||
;; (kept in memory, not the DOM) so the typography selector renders previews on
|
|
||||||
;; open with no network wait. Remove the flag check to drop the feature.
|
|
||||||
(mf/with-effect []
|
(mf/with-effect []
|
||||||
(when (contains? cf/flags :font-preview)
|
(fonts/prefetch-preview-sprite!))
|
||||||
(fonts/prefetch-preview-sprite!)))
|
|
||||||
|
|
||||||
;; Setting the layout preset by its name
|
;; Setting the layout preset by its name
|
||||||
(mf/with-effect [layout-name]
|
(mf/with-effect [layout-name]
|
||||||
@ -302,4 +297,3 @@
|
|||||||
|
|
||||||
(when (uuid? file-id)
|
(when (uuid? file-id)
|
||||||
[:> workspace* props])))
|
[:> workspace* props])))
|
||||||
|
|
||||||
|
|||||||
@ -30,18 +30,24 @@
|
|||||||
|
|
||||||
;; --- Text Editor Rendering
|
;; --- Text Editor Rendering
|
||||||
|
|
||||||
(mf/defc block-component*
|
(mf/defc block-component
|
||||||
[{:keys [block-props] :as props}]
|
{::mf/wrap-props false}
|
||||||
(let [data (.-data ^js block-props)
|
[props]
|
||||||
style (sts/generate-paragraph-styles (.-shape ^js block-props) data)
|
(let [bprops (obj/get props "blockProps")
|
||||||
dir (:text-direction data "auto")]
|
data (obj/get bprops "data")
|
||||||
|
style (sts/generate-paragraph-styles (obj/get bprops "shape")
|
||||||
|
(obj/get bprops "data"))
|
||||||
|
dir (:text-direction data "auto")]
|
||||||
|
|
||||||
|
|
||||||
[:div {:style style :dir dir}
|
[:div {:style style :dir dir}
|
||||||
[:> draft/EditorBlock props]]))
|
[:> draft/EditorBlock props]]))
|
||||||
|
|
||||||
(mf/defc selection-component*
|
(mf/defc selection-component
|
||||||
[{:keys [children]}]
|
{::mf/wrap-props false}
|
||||||
[:span {:style {:background "#ccc" :display "inline-block"}} children])
|
[props]
|
||||||
|
(let [children (obj/get props "children")]
|
||||||
|
[:span {:style {:background "#ccc" :display "inline-block"}} children]))
|
||||||
|
|
||||||
(defn- render-block
|
(defn- render-block
|
||||||
[block shape]
|
[block shape]
|
||||||
@ -49,7 +55,7 @@
|
|||||||
(case type
|
(case type
|
||||||
"unstyled"
|
"unstyled"
|
||||||
#js {:editable true
|
#js {:editable true
|
||||||
:component block-component*
|
:component block-component
|
||||||
:props #js {:data (ted/get-editor-block-data block)
|
:props #js {:data (ted/get-editor-block-data block)
|
||||||
:shape shape}}
|
:shape shape}}
|
||||||
nil)))
|
nil)))
|
||||||
@ -63,7 +69,7 @@
|
|||||||
(sts/generate-text-styles shape data {:show-text? false})))
|
(sts/generate-text-styles shape data {:show-text? false})))
|
||||||
|
|
||||||
(def default-decorator
|
(def default-decorator
|
||||||
(ted/create-decorator "PENPOT_SELECTION" selection-component*))
|
(ted/create-decorator "PENPOT_SELECTION" selection-component))
|
||||||
|
|
||||||
(def empty-editor-state
|
(def empty-editor-state
|
||||||
(ted/create-editor-state nil default-decorator))
|
(ted/create-editor-state nil default-decorator))
|
||||||
@ -89,11 +95,12 @@
|
|||||||
"bottom" "flex-end"
|
"bottom" "flex-end"
|
||||||
nil))
|
nil))
|
||||||
|
|
||||||
(mf/defc text-shape-edit-html*
|
(mf/defc text-shape-edit-html
|
||||||
{::mf/wrap [mf/memo]
|
{::mf/wrap [mf/memo]
|
||||||
|
::mf/wrap-props false
|
||||||
::mf/forward-ref true}
|
::mf/forward-ref true}
|
||||||
[{:keys [shape]} _]
|
[props _]
|
||||||
(let [{:keys [id content]} shape
|
(let [{:keys [id content] :as shape} (obj/get props "shape")
|
||||||
|
|
||||||
state-map (mf/deref refs/workspace-editor-state)
|
state-map (mf/deref refs/workspace-editor-state)
|
||||||
state (get state-map id empty-editor-state)
|
state (get state-map id empty-editor-state)
|
||||||
@ -268,7 +275,8 @@
|
|||||||
(-> (gpt/subtract pt box)
|
(-> (gpt/subtract pt box)
|
||||||
(gpt/multiply zoom)))))
|
(gpt/multiply zoom)))))
|
||||||
|
|
||||||
(mf/defc text-editor-svg*
|
(mf/defc text-editor-svg
|
||||||
|
{::mf/wrap-props false}
|
||||||
[{:keys [shape modifiers]}]
|
[{:keys [shape modifiers]}]
|
||||||
(let [shape-id (dm/get-prop shape :id)
|
(let [shape-id (dm/get-prop shape :id)
|
||||||
modifiers (dm/get-in modifiers [shape-id :modifiers])
|
modifiers (dm/get-in modifiers [shape-id :modifiers])
|
||||||
@ -341,6 +349,6 @@
|
|||||||
|
|
||||||
[:foreignObject {:x x :y y :width width :height height}
|
[:foreignObject {:x x :y y :width width :height height}
|
||||||
[:div {:style style}
|
[:div {:style style}
|
||||||
[:> text-shape-edit-html*
|
[:& text-shape-edit-html
|
||||||
{:shape shape
|
{:shape shape
|
||||||
:key (dm/str shape-id)}]]]]))
|
:key (dm/str shape-id)}]]]]))
|
||||||
|
|||||||
@ -412,7 +412,7 @@
|
|||||||
(select-keys txt/text-node-attrs))]
|
(select-keys txt/text-node-attrs))]
|
||||||
(when (features/active-feature? @st/state "text-editor-wasm/v1")
|
(when (features/active-feature? @st/state "text-editor-wasm/v1")
|
||||||
(st/emit! (dwt-v3/v3-update-text-editor-styles (first ids) attrs)))
|
(st/emit! (dwt-v3/v3-update-text-editor-styles (first ids) attrs)))
|
||||||
(st/emit! (dwt/save-font updated-attrs)
|
(st/emit! (dwt/save-default-font updated-attrs)
|
||||||
(dwt/update-all-attrs ids attrs)))))
|
(dwt/update-all-attrs ids attrs)))))
|
||||||
|
|
||||||
on-change
|
on-change
|
||||||
|
|||||||
@ -12,7 +12,6 @@
|
|||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.exceptions :as ex]
|
[app.common.exceptions :as ex]
|
||||||
[app.common.types.text :as txt]
|
[app.common.types.text :as txt]
|
||||||
[app.config :as cf]
|
|
||||||
[app.main.constants :refer [max-input-length]]
|
[app.main.constants :refer [max-input-length]]
|
||||||
[app.main.data.common :as dcm]
|
[app.main.data.common :as dcm]
|
||||||
[app.main.data.fonts :as fts]
|
[app.main.data.fonts :as fts]
|
||||||
@ -91,19 +90,13 @@
|
|||||||
(constantly nil)))))
|
(constantly nil)))))
|
||||||
@loaded?))
|
@loaded?))
|
||||||
|
|
||||||
;; --- FEATURE: font preview (flag :font-preview) ------------------------------
|
|
||||||
;; font-item-preview* and use-font-lazy-load are the whole feature. They are only
|
|
||||||
;; rendered/called behind the `:font-preview` flag check in font-item* below, so
|
|
||||||
;; their hooks never run when the flag is off. To remove the flag, inline
|
|
||||||
;; font-item-preview* into font-item* and drop the plain-name branch.
|
|
||||||
|
|
||||||
(mf/defc font-item-preview*
|
(mf/defc font-item-preview*
|
||||||
"Row content with previews: a vector preview from the shared sprite for catalog
|
"Row content with previews: a vector preview from the shared sprite for catalog
|
||||||
fonts, or the font's own name lazily loaded for custom fonts the sprite doesn't
|
fonts, or the font's own name lazily loaded for custom fonts the sprite doesn't
|
||||||
cover."
|
cover."
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
[{:keys [font]}]
|
[{:keys [font]}]
|
||||||
(let [font-id (:id font)
|
(let [font-id (get font :id)
|
||||||
sprite (mf/deref fonts/preview-sprite)
|
sprite (mf/deref fonts/preview-sprite)
|
||||||
|
|
||||||
;; The sprite is only referenceable once it's been attached to the DOM,
|
;; The sprite is only referenceable once it's been attached to the DOM,
|
||||||
@ -133,29 +126,20 @@
|
|||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
[{:keys [font is-current on-click style]}]
|
[{:keys [font is-current on-click style]}]
|
||||||
(let [item-ref (mf/use-ref)
|
(let [item-ref (mf/use-ref)
|
||||||
on-click (mf/use-fn (mf/deps font) #(on-click font))
|
on-click (mf/use-fn (mf/deps font) #(on-click font))]
|
||||||
;; FLAG :font-preview — gates the feature markup AND its row styling
|
|
||||||
;; (.font-item-preview-on in the scss). Remove this and its two uses below.
|
|
||||||
preview? (contains? cf/flags :font-preview)]
|
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/with-effect [is-current]
|
||||||
(mf/deps is-current)
|
(when is-current
|
||||||
(fn []
|
(let [element (mf/ref-val item-ref)]
|
||||||
(when is-current
|
(when-not (dom/is-in-viewport? element)
|
||||||
(let [element (mf/ref-val item-ref)]
|
(dom/scroll-into-view! element)))))
|
||||||
(when-not (dom/is-in-viewport? element)
|
|
||||||
(dom/scroll-into-view! element))))))
|
|
||||||
|
|
||||||
[:div {:class (stl/css :font-wrapper)
|
[:div {:class (stl/css :font-wrapper)
|
||||||
:style style
|
:style style
|
||||||
:ref item-ref
|
:ref item-ref
|
||||||
:on-click on-click}
|
:on-click on-click}
|
||||||
[:div {:class (stl/css-case :font-item true
|
[:div {:class (stl/css-case :font-item true :selected is-current)}
|
||||||
:font-item-preview-on preview?
|
[:> font-item-preview* {:font font}]
|
||||||
:selected is-current)}
|
|
||||||
(if preview?
|
|
||||||
[:> font-item-preview* {:font font}]
|
|
||||||
[:span {:class (stl/css :font-item-label)} (:name font)])
|
|
||||||
(when is-current
|
(when is-current
|
||||||
[:> icon* {:icon-id i/tick
|
[:> icon* {:icon-id i/tick
|
||||||
:size "s"}])]]))
|
:size "s"}])]]))
|
||||||
@ -260,14 +244,13 @@
|
|||||||
(let [key (events/listen js/document "keydown" on-key-down)]
|
(let [key (events/listen js/document "keydown" on-key-down)]
|
||||||
#(events/unlistenByKey key)))
|
#(events/unlistenByKey key)))
|
||||||
|
|
||||||
;; FLAG :font-preview — materialize the preview sprite into the DOM only while
|
;; Materialize the preview sprite into the DOM only while the picker is open
|
||||||
;; the picker is open (markup is prefetched on workspace load), removing it on
|
;; (markup is prefetched on workspace load), removing it on close so its
|
||||||
;; close so its ~2000 nodes aren't kept around idle. The attachment is deferred
|
;; ~2000 nodes aren't kept around idle. The attachment is deferred so the
|
||||||
;; so the dropdown can paint first with plain names, then the sprite swaps in
|
;; dropdown can paint first with plain names, then the sprite swaps in on the
|
||||||
;; on the next tick. Remove the flag clause to drop the feature.
|
;; next tick.
|
||||||
(mf/with-effect [sprite-status]
|
(mf/with-effect [sprite-status]
|
||||||
(when (and (contains? cf/flags :font-preview)
|
(when (= :ready sprite-status)
|
||||||
(= :ready sprite-status))
|
|
||||||
(let [node* (volatile! nil)
|
(let [node* (volatile! nil)
|
||||||
task (tm/schedule
|
task (tm/schedule
|
||||||
(fn []
|
(fn []
|
||||||
@ -278,9 +261,11 @@
|
|||||||
(fonts/detach-preview-sprite! n))))))
|
(fonts/detach-preview-sprite! n))))))
|
||||||
|
|
||||||
(mf/with-effect [@selected]
|
(mf/with-effect [@selected]
|
||||||
(when-let [inst (mf/ref-val flist)]
|
(let [node (mf/ref-val flist)
|
||||||
(when-let [index (:index @selected)]
|
index (:index @selected)]
|
||||||
(.scrollToRow ^js inst index))))
|
;; This is nil safe operation, do nothing if node or index are
|
||||||
|
;; invalid.
|
||||||
|
(dom/scroll-to-row node index)))
|
||||||
|
|
||||||
(mf/with-effect [@selected]
|
(mf/with-effect [@selected]
|
||||||
(on-select @selected))
|
(on-select @selected))
|
||||||
@ -291,11 +276,12 @@
|
|||||||
(st/emit! (dsc/pop-shortcuts :typography))))
|
(st/emit! (dsc/pop-shortcuts :typography))))
|
||||||
|
|
||||||
(mf/with-effect []
|
(mf/with-effect []
|
||||||
(let [index (d/index-of-pred fonts #(= (:id %) (:id current-font)))
|
(let [index (d/index-of-pred fonts #(= (:id %) (:id current-font)))
|
||||||
inst (mf/ref-val flist)]
|
node (mf/ref-val flist)]
|
||||||
(tm/schedule
|
(tm/schedule
|
||||||
#(let [offset (.getOffsetForRow ^js inst #js {:alignment "center" :index index})]
|
#(let [offset (.getOffsetForRow ^js node #js {:alignment "center" :index index})]
|
||||||
(.scrollToPosition ^js inst offset)))))
|
;; Safe operaton, do nothing if node or offset has invalid values
|
||||||
|
(dom/scroll-to-position node offset)))))
|
||||||
|
|
||||||
[:div {:class [(stl/css-case :font-selector true
|
[:div {:class [(stl/css-case :font-selector true
|
||||||
:fonts-on-modal (not full-size?))]}
|
:fonts-on-modal (not full-size?))]}
|
||||||
|
|||||||
@ -388,20 +388,7 @@ $font-preview-box-height: 28px;
|
|||||||
&.selected {
|
&.selected {
|
||||||
color: var(--color-foreground-primary);
|
color: var(--color-foreground-primary);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.font-item-label {
|
|
||||||
@include t.use-typography("body-small");
|
|
||||||
@include text-ellipsis;
|
|
||||||
|
|
||||||
flex-grow: 1;
|
|
||||||
min-inline-size: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- FLAG :font-preview row styling. Only applied when font-item* adds the
|
|
||||||
// .font-item-preview-on modifier; remove this whole block with the flag so rows
|
|
||||||
// render exactly as before.
|
|
||||||
.font-item-preview-on {
|
|
||||||
// Center & clip so a previewed font's own metrics never grow/overflow the row.
|
// Center & clip so a previewed font's own metrics never grow/overflow the row.
|
||||||
align-items: center;
|
align-items: center;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -414,6 +401,14 @@ $font-preview-box-height: 28px;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.font-item-label {
|
||||||
|
@include t.use-typography("body-small");
|
||||||
|
@include text-ellipsis;
|
||||||
|
|
||||||
|
flex-grow: 1;
|
||||||
|
min-inline-size: 0;
|
||||||
|
}
|
||||||
|
|
||||||
// `currentColor` makes the glyph fill follow the row text color (theme + selected).
|
// `currentColor` makes the glyph fill follow the row text color (theme + selected).
|
||||||
.font-item-preview {
|
.font-item-preview {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
|||||||
@ -455,8 +455,8 @@
|
|||||||
[:& editor-v2/text-editor {:shape editing-shape
|
[:& editor-v2/text-editor {:shape editing-shape
|
||||||
:canvas-ref canvas-ref
|
:canvas-ref canvas-ref
|
||||||
:modifiers modifiers}]
|
:modifiers modifiers}]
|
||||||
[:> editor-v1/text-editor-svg* {:shape editing-shape
|
[:& editor-v1/text-editor-svg {:shape editing-shape
|
||||||
:modifiers modifiers}]))
|
:modifiers modifiers}]))
|
||||||
|
|
||||||
(when show-frame-outline?
|
(when show-frame-outline?
|
||||||
(let [outlined-frame-id
|
(let [outlined-frame-id
|
||||||
|
|||||||
@ -747,8 +747,8 @@
|
|||||||
:canvas-ref canvas-ref
|
:canvas-ref canvas-ref
|
||||||
:ref text-editor-ref}]
|
:ref text-editor-ref}]
|
||||||
|
|
||||||
:else [:> editor-v1/text-editor-svg* {:shape editing-shape
|
:else [:& editor-v1/text-editor-svg {:shape editing-shape
|
||||||
:ref text-editor-ref}]))
|
:ref text-editor-ref}]))
|
||||||
|
|
||||||
(when show-frame-outline?
|
(when show-frame-outline?
|
||||||
(let [outlined-frame-id (->> @hover-ids
|
(let [outlined-frame-id (->> @hover-ids
|
||||||
|
|||||||
@ -244,6 +244,16 @@
|
|||||||
height (.-clientHeight scroll-node)]
|
height (.-clientHeight scroll-node)]
|
||||||
(/ distance height)))
|
(/ distance height)))
|
||||||
|
|
||||||
|
(defn scroll-to-row
|
||||||
|
[node index]
|
||||||
|
(when (and (some? node) (number? index))
|
||||||
|
(.scrollToRow ^js node index)))
|
||||||
|
|
||||||
|
(defn scroll-to-position
|
||||||
|
[node offset]
|
||||||
|
(when (and (some? node) (number? offset))
|
||||||
|
(.scrollToPosition ^js node offset)))
|
||||||
|
|
||||||
(def get-target-val (comp get-value get-target))
|
(def get-target-val (comp get-value get-target))
|
||||||
|
|
||||||
(def get-target-scroll (comp get-scroll-position get-target))
|
(def get-target-scroll (comp get-scroll-position get-target))
|
||||||
|
|||||||
@ -379,14 +379,14 @@
|
|||||||
"float letter-spacing is normalised to 2-decimal string")))))))
|
"float letter-spacing is normalised to 2-decimal string")))))))
|
||||||
|
|
||||||
;; ---------------------------------------------------------------------------
|
;; ---------------------------------------------------------------------------
|
||||||
;; Tests: save-font must not persist typography refs into the global default font
|
;; Tests: save-default-font must not persist typography refs into the global default font
|
||||||
;;
|
;;
|
||||||
;; Root cause of #10925: typography assets are file-specific references, but
|
;; Root cause of #10925: typography assets are file-specific references, but
|
||||||
;; save-font used to write :typography-ref-id / :typography-ref-file into the
|
;; save-default-font used to write :typography-ref-id / :typography-ref-file into the
|
||||||
;; session-global [:workspace-global :default-font]. That state survives a file
|
;; session-global [:workspace-global :default-font]. That state survives a file
|
||||||
;; switch, and v2-default-text-content bakes it into brand-new text shapes in
|
;; switch, and v2-default-text-content bakes it into brand-new text shapes in
|
||||||
;; the other file, so they got a non-existent typography asset instead of the
|
;; the other file, so they got a non-existent typography asset instead of the
|
||||||
;; default Penpot font. save-font now strips those two keys.
|
;; default Penpot font. save-default-font now strips those two keys.
|
||||||
;; ---------------------------------------------------------------------------
|
;; ---------------------------------------------------------------------------
|
||||||
|
|
||||||
(t/deftest save-font-strips-typography-refs-from-default-font
|
(t/deftest save-font-strips-typography-refs-from-default-font
|
||||||
@ -405,7 +405,7 @@
|
|||||||
:typography-ref-id (uuid/next)
|
:typography-ref-id (uuid/next)
|
||||||
:typography-ref-file (:id file)}]
|
:typography-ref-file (:id file)}]
|
||||||
(ths/run-store
|
(ths/run-store
|
||||||
store done [(dwt/save-font attrs)]
|
store done [(dwt/save-default-font attrs)]
|
||||||
(fn [new-state]
|
(fn [new-state]
|
||||||
(let [default-font (get-in new-state [:workspace-global :default-font])]
|
(let [default-font (get-in new-state [:workspace-global :default-font])]
|
||||||
(t/is (some? default-font))
|
(t/is (some? default-font))
|
||||||
@ -425,7 +425,7 @@
|
|||||||
:letter-spacing "0"
|
:letter-spacing "0"
|
||||||
:typography-ref-id (uuid/next)
|
:typography-ref-id (uuid/next)
|
||||||
:typography-ref-file (uuid/next)}]
|
:typography-ref-file (uuid/next)}]
|
||||||
(ths/run-store store done [(dwt/save-font attrs)]
|
(ths/run-store store done [(dwt/save-default-font attrs)]
|
||||||
(fn [new-state]
|
(fn [new-state]
|
||||||
(let [default-font (get-in new-state [:workspace-global :default-font])]
|
(let [default-font (get-in new-state [:workspace-global :default-font])]
|
||||||
(t/is (= "Open Sans" (:font-family default-font)))
|
(t/is (= "Open Sans" (:font-family default-font)))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user