mirror of
https://github.com/penpot/penpot.git
synced 2025-02-12 18:18:24 -05:00
✨ Add write apis to the plugins
This commit is contained in:
parent
c85f76300a
commit
00de89197e
4 changed files with 160 additions and 29 deletions
|
@ -381,6 +381,53 @@
|
||||||
(-> (rec-style-text-map [] node {})
|
(-> (rec-style-text-map [] node {})
|
||||||
reverse)))
|
reverse)))
|
||||||
|
|
||||||
|
(defn content->text
|
||||||
|
"Given a root node of a text content extracts the texts with its associated styles"
|
||||||
|
[content]
|
||||||
|
(letfn [(add-node [acc node]
|
||||||
|
(cond
|
||||||
|
(is-paragraph-node? node)
|
||||||
|
(conj acc [])
|
||||||
|
|
||||||
|
(is-text-node? node)
|
||||||
|
(let [i (dec (count acc))]
|
||||||
|
(update acc i conj (:text node)))
|
||||||
|
|
||||||
|
:else
|
||||||
|
acc))]
|
||||||
|
(->> (node-seq content)
|
||||||
|
(reduce add-node [])
|
||||||
|
(map #(str/join "" %))
|
||||||
|
(str/join "\n"))))
|
||||||
|
|
||||||
|
(defn change-text
|
||||||
|
"Changes the content of the text shape to use the text as argument. Will use the styles of the
|
||||||
|
first paragraph and text that is present in the shape (and override the rest)"
|
||||||
|
[shape text]
|
||||||
|
(let [content (:content shape)
|
||||||
|
|
||||||
|
paragraph-style (select-keys (->> content (node-seq is-paragraph-node?) first) text-all-attrs)
|
||||||
|
text-style (select-keys (->> content (node-seq is-text-node?) first) text-all-attrs)
|
||||||
|
|
||||||
|
paragraph-texts (str/split text "\n")
|
||||||
|
|
||||||
|
paragraphs
|
||||||
|
(->> paragraph-texts
|
||||||
|
(mapv
|
||||||
|
(fn [pt]
|
||||||
|
(merge
|
||||||
|
paragraph-style
|
||||||
|
{:type "paragraph"
|
||||||
|
:children [(merge {:text pt} text-style)]}))))
|
||||||
|
|
||||||
|
new-content
|
||||||
|
{:type "root"
|
||||||
|
:children
|
||||||
|
[{:type "paragraph-set"
|
||||||
|
:children paragraphs}]}]
|
||||||
|
|
||||||
|
(assoc shape :content new-content)))
|
||||||
|
|
||||||
(defn index-content
|
(defn index-content
|
||||||
"Adds a property `$id` that identifies the current node inside"
|
"Adds a property `$id` that identifies the current node inside"
|
||||||
([content]
|
([content]
|
||||||
|
|
|
@ -8,8 +8,11 @@
|
||||||
"RPC for plugins runtime."
|
"RPC for plugins runtime."
|
||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.files.changes-builder :as cb]
|
||||||
[app.common.record :as cr]
|
[app.common.record :as cr]
|
||||||
|
[app.common.types.shape :as cts]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
|
[app.main.data.workspace.changes :as ch]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.plugins.events :as events]
|
[app.plugins.events :as events]
|
||||||
[app.plugins.file :as file]
|
[app.plugins.file :as file]
|
||||||
|
@ -37,8 +40,9 @@
|
||||||
|
|
||||||
(getPage
|
(getPage
|
||||||
[_]
|
[_]
|
||||||
(let [page-id (:current-page-id @st/state)]
|
(let [page-id (:current-page-id @st/state)
|
||||||
(page/data->page-proxy (dm/get-in @st/state [:workspace-data :pages-index page-id]))))
|
page (dm/get-in @st/state [:workspace-data :pages-index page-id])]
|
||||||
|
(page/data->page-proxy page)))
|
||||||
|
|
||||||
(getSelected
|
(getSelected
|
||||||
[_]
|
[_]
|
||||||
|
@ -64,11 +68,26 @@
|
||||||
(let [theme (get-in @st/state [:profile :theme])]
|
(let [theme (get-in @st/state [:profile :theme])]
|
||||||
(if (or (not theme) (= theme "default"))
|
(if (or (not theme) (= theme "default"))
|
||||||
"dark"
|
"dark"
|
||||||
(get-in @st/state [:profile :theme])))))
|
(get-in @st/state [:profile :theme]))))
|
||||||
|
|
||||||
|
(createRectangle
|
||||||
|
[_]
|
||||||
|
(let [page-id (:current-page-id @st/state)
|
||||||
|
page (dm/get-in @st/state [:workspace-data :pages-index page-id])
|
||||||
|
shape (cts/setup-shape {:type :rect
|
||||||
|
:x 0 :y 0 :width 100 :height 100})
|
||||||
|
changes
|
||||||
|
(-> (cb/empty-changes)
|
||||||
|
(cb/with-page page)
|
||||||
|
(cb/with-objects (:objects page))
|
||||||
|
(cb/add-object shape))]
|
||||||
|
(st/emit! (ch/commit-changes changes))
|
||||||
|
(shape/data->shape-proxy shape))))
|
||||||
|
|
||||||
(defn create-context
|
(defn create-context
|
||||||
[]
|
[]
|
||||||
(cr/add-properties!
|
(cr/add-properties!
|
||||||
(PenpotContext.)
|
(PenpotContext.)
|
||||||
{:name "root" :get #(.getRoot ^js %)}
|
{:name "root" :get #(.getRoot ^js %)}
|
||||||
{:name "currentPage" :get #(.getPage ^js %)}))
|
{:name "currentPage" :get #(.getPage ^js %)}
|
||||||
|
{:name "selection" :get #(.getSelectedShapes ^js %)}))
|
||||||
|
|
|
@ -53,12 +53,10 @@
|
||||||
"dark"
|
"dark"
|
||||||
new-theme))))
|
new-theme))))
|
||||||
|
|
||||||
|
|
||||||
(defmethod handle-state-change :default
|
(defmethod handle-state-change :default
|
||||||
[_ _ _]
|
[_ _ _]
|
||||||
::not-changed)
|
::not-changed)
|
||||||
|
|
||||||
|
|
||||||
(defn add-listener
|
(defn add-listener
|
||||||
[type callback]
|
[type callback]
|
||||||
(let [key (js/Symbol)
|
(let [key (js/Symbol)
|
||||||
|
|
|
@ -7,8 +7,12 @@
|
||||||
(ns app.plugins.shape
|
(ns app.plugins.shape
|
||||||
"RPC for plugins runtime."
|
"RPC for plugins runtime."
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.files.helpers :as cfh]
|
||||||
[app.common.record :as crc]
|
[app.common.record :as crc]
|
||||||
|
[app.common.text :as txt]
|
||||||
|
[app.main.data.workspace :as udw]
|
||||||
[app.main.data.workspace.changes :as dwc]
|
[app.main.data.workspace.changes :as dwc]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.plugins.utils :refer [get-data get-data-fn]]
|
[app.plugins.utils :refer [get-data get-data-fn]]
|
||||||
|
@ -18,24 +22,51 @@
|
||||||
|
|
||||||
(defn- make-fills
|
(defn- make-fills
|
||||||
[fills]
|
[fills]
|
||||||
;; TODO: Transform explicitly?
|
(.freeze
|
||||||
(apply array
|
js/Object
|
||||||
(->> fills
|
(apply array
|
||||||
(map #(clj->js % {:keyword-fn (fn [k] (str/camel (name k)))})))))
|
(->> fills
|
||||||
|
;; TODO: Transform explicitly instead of cljs->js?
|
||||||
|
(map #(clj->js % {:keyword-fn (fn [k] (str/camel (name k)))}))))))
|
||||||
|
|
||||||
|
(defn- make-strokes
|
||||||
|
[strokes]
|
||||||
|
(.freeze
|
||||||
|
js/Object
|
||||||
|
(apply array
|
||||||
|
(->> strokes
|
||||||
|
;; TODO: Transform explicitly instead of cljs->js?
|
||||||
|
(map #(clj->js % {:keyword-fn (fn [k] (str/camel (name k)))}))))))
|
||||||
|
|
||||||
(defn- locate-shape
|
(defn- locate-shape
|
||||||
[shape-id]
|
[shape-id]
|
||||||
(let [page-id (:current-page-id @st/state)]
|
(let [page-id (:current-page-id @st/state)]
|
||||||
(dm/get-in @st/state [:workspace-data :pages-index page-id :objects shape-id])))
|
(dm/get-in @st/state [:workspace-data :pages-index page-id :objects shape-id])))
|
||||||
|
|
||||||
(deftype ShapeProxy [#_:clj-kondo/ignore _data]
|
(defn- get-state
|
||||||
|
([self attr]
|
||||||
|
(let [id (get-data self :id)
|
||||||
|
page-id (d/nilv (get-data self :page-id) (:current-page-id @st/state))]
|
||||||
|
(dm/get-in @st/state [:workspace-data :pages-index page-id :objects id attr])))
|
||||||
|
([self attr mapfn]
|
||||||
|
(-> (get-state self attr)
|
||||||
|
(mapfn))))
|
||||||
|
|
||||||
|
(deftype ShapeProxy [^:mutable #_:clj-kondo/ignore _data]
|
||||||
Object
|
Object
|
||||||
(getChildren
|
(getChildren
|
||||||
[self]
|
[self]
|
||||||
(apply array (->> (get-data self :shapes)
|
(apply array (->> (get-state self :shapes)
|
||||||
(map locate-shape)
|
(map locate-shape)
|
||||||
(map data->shape-proxy))))
|
(map data->shape-proxy))))
|
||||||
|
|
||||||
|
(resize
|
||||||
|
[self width height]
|
||||||
|
|
||||||
|
(let [id (get-data self :id)]
|
||||||
|
(st/emit! (udw/update-dimensions [id] :width width)
|
||||||
|
(udw/update-dimensions [id] :height height))))
|
||||||
|
|
||||||
(clone [_] (.log js/console (clj->js _data)))
|
(clone [_] (.log js/console (clj->js _data)))
|
||||||
(delete [_] (.log js/console (clj->js _data)))
|
(delete [_] (.log js/console (clj->js _data)))
|
||||||
(appendChild [_] (.log js/console (clj->js _data))))
|
(appendChild [_] (.log js/console (clj->js _data))))
|
||||||
|
@ -48,25 +79,61 @@
|
||||||
(defn data->shape-proxy
|
(defn data->shape-proxy
|
||||||
[data]
|
[data]
|
||||||
|
|
||||||
(crc/add-properties!
|
(-> (ShapeProxy. data)
|
||||||
(ShapeProxy. data)
|
(crc/add-properties!
|
||||||
{:name "_data"
|
{:name "_data"
|
||||||
:enumerable false}
|
:enumerable false}
|
||||||
|
|
||||||
{:name "id"
|
{:name "id"
|
||||||
:get (get-data-fn :id str)}
|
:get (get-data-fn :id str)}
|
||||||
|
|
||||||
{:name "name"
|
{:name "type"
|
||||||
:get (get-data-fn :name)
|
:get (get-data-fn :type)}
|
||||||
:set (fn [self value]
|
|
||||||
(let [id (get-data self :id)]
|
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :name value)))))}
|
|
||||||
|
|
||||||
{:name "children"
|
{:name "x"
|
||||||
:get #(.getChildren ^js %)}
|
:get #(get-state % :x)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (get-data self :id)]
|
||||||
|
(st/emit! (udw/update-position id {:x value}))))}
|
||||||
|
|
||||||
{:name "fills"
|
{:name "y"
|
||||||
:get (get-data-fn :fills make-fills)
|
:get #(get-state % :y)
|
||||||
;;:set (fn [self value] (.log js/console self value))
|
:set
|
||||||
}))
|
(fn [self value]
|
||||||
|
(let [id (get-data self :id)]
|
||||||
|
(st/emit! (udw/update-position id {:y value}))))}
|
||||||
|
|
||||||
|
{:name "width"
|
||||||
|
:get #(get-state % :width)}
|
||||||
|
|
||||||
|
{:name "height"
|
||||||
|
:get #(get-state % :height)}
|
||||||
|
|
||||||
|
{:name "name"
|
||||||
|
:get #(get-state % :name)
|
||||||
|
:set (fn [self value]
|
||||||
|
(let [id (get-data self :id)]
|
||||||
|
(st/emit! (dwc/update-shapes [id] #(assoc % :name value)))))}
|
||||||
|
|
||||||
|
{:name "children"
|
||||||
|
:get #(.getChildren ^js %)}
|
||||||
|
|
||||||
|
{:name "fills"
|
||||||
|
:get #(get-state % :fills make-fills)
|
||||||
|
;;:set (fn [self value] (.log js/console self value))
|
||||||
|
}
|
||||||
|
|
||||||
|
{:name "strokes"
|
||||||
|
:get #(get-state % :strokes make-strokes)
|
||||||
|
;;:set (fn [self value] (.log js/console self value))
|
||||||
|
})
|
||||||
|
|
||||||
|
(cond-> (cfh/text-shape? data)
|
||||||
|
(crc/add-properties!
|
||||||
|
{:name "characters"
|
||||||
|
:get #(get-state % :content txt/content->text)
|
||||||
|
:set (fn [self value]
|
||||||
|
(let [id (get-data self :id)]
|
||||||
|
(st/emit! (dwc/update-shapes [id] #(txt/change-text % value)))))}))))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue