0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-28 15:41:25 -05:00

Refactor to the context api

This commit is contained in:
alonso.torres 2024-04-18 16:42:09 +02:00 committed by Andrey Antukh
parent 7b508f2803
commit 0ffd82299f
7 changed files with 187 additions and 82 deletions

View file

@ -429,8 +429,9 @@
`(update ~ssym ~ksym ~f ~@params)))
(defmacro define-properties!
"Define properties in the prototype with `.defineProperty`"
[rsym & properties]
(let [rsym (with-meta rsym {:tag 'js})]
(let [rsym (with-meta rsym {:tag 'js})]
`(do
~@(for [params properties
:let [pname (get params :name)
@ -458,3 +459,50 @@
(when set-fn
["set" set-fn]))))))))
(defmacro add-properties!
"Adds properties to an object using `.defineProperty`"
[rsym & properties]
(let [rsym (with-meta rsym {:tag 'js})
getf-sym (with-meta (gensym "get-fn") {:tag 'js})
setf-sym (with-meta (gensym "set-fn") {:tag 'js})
this-sym (with-meta (gensym "this") {:tag 'js})
target-sym (with-meta (gensym "target") {:tag 'js})]
`(let [~target-sym ~rsym]
;; Creates the `.defineProperty` per property
~@(for [params properties
:let [pname (get params :name)
get-fn (get params :get)
set-fn (get params :set)
enum-p (get params :enumerable)
conf-p (get params :configurable)
writ-p (get params :writable)]]
`(let [~getf-sym ~get-fn
~setf-sym ~set-fn]
(.defineProperty
js/Object
~target-sym
~pname
(cljs.core/js-obj
~@(concat
(if (some? enum-p)
["enumerable" enum-p]
;; Default in JS is false. We default to true
["enumerable" true])
(when (some? conf-p)
["configurable" conf-p])
(when (some? writ-p)
["writable" writ-p])
(when get-fn
["get" `(fn []
(cljs.core/this-as ~this-sym
(~getf-sym ~this-sym)))])
(when set-fn
["set" `(fn [value#]
(cljs.core/this-as ~this-sym
(~setf-sym ~this-sym value#)))]))))))
;; Returns the object
~target-sym)))

View file

@ -18,6 +18,4 @@
(when (features/active-feature? @st/state "plugins/runtime")
(when-let [init-runtime (obj/get global "initPluginsRuntime")]
(let [context (api/create-context)]
(when *assert*
(js/console.log "Plugins context" context))
(init-runtime context)))))

View file

@ -8,6 +8,8 @@
"RPC for plugins runtime."
(:require
[app.common.data.macros :as dm]
[app.common.record :as cr]
[app.common.uuid :as uuid]
[app.main.store :as st]
[app.plugins.events :as events]
[app.plugins.file :as file]
@ -23,35 +25,50 @@
(map val)
(map shape/data->shape-proxy)))
(defn ^:export addListener
[type callback]
(events/add-listener type callback))
(deftype PenpotContext []
Object
(addListener
[_ type callback]
(events/add-listener type callback))
(defn ^:export getFile
[]
(file/data->file-proxy (:workspace-file @st/state) (:workspace-data @st/state)))
(getFile
[_]
(file/data->file-proxy (:workspace-file @st/state) (:workspace-data @st/state)))
(defn ^:export getPage
[]
(let [page-id (:current-page-id @st/state)]
(page/data->page-proxy (dm/get-in @st/state [:workspace-data :pages-index page-id]))))
(getPage
[_]
(let [page-id (:current-page-id @st/state)]
(page/data->page-proxy (dm/get-in @st/state [:workspace-data :pages-index page-id]))))
(defn ^:export getSelected
[]
(let [selection (get-in @st/state [:workspace-local :selected])]
(apply array (map str selection))))
(getSelected
[_]
(let [selection (get-in @st/state [:workspace-local :selected])]
(apply array (map str selection))))
(defn ^:export getSelectedShapes
[]
(let [page-id (:current-page-id @st/state)
selection (get-in @st/state [:workspace-local :selected])
objects (dm/get-in @st/state [:workspace-data :pages-index page-id :objects])
shapes (select-keys objects selection)]
(apply array (sequence xf-map-shape-proxy shapes))))
(getSelectedShapes
[_]
(let [page-id (:current-page-id @st/state)
selection (get-in @st/state [:workspace-local :selected])
objects (dm/get-in @st/state [:workspace-data :pages-index page-id :objects])
shapes (select-keys objects selection)]
(apply array (sequence xf-map-shape-proxy shapes))))
(defn ^:export getTheme
(getRoot
[_]
(let [page-id (:current-page-id @st/state)
root (dm/get-in @st/state [:workspace-data :pages-index page-id :objects uuid/zero])]
(shape/data->shape-proxy root)))
(getTheme
[_]
(let [theme (get-in @st/state [:profile :theme])]
(if (or (not theme) (= theme "default"))
"dark"
(get-in @st/state [:profile :theme])))))
(defn create-context
[]
(let [theme (get-in @st/state [:profile :theme])]
(if (or (not theme) (= theme "default"))
"dark"
(get-in @st/state [:profile :theme]))))
(cr/add-properties!
(PenpotContext.)
{:name "root" :get #(.getRoot ^js %)}
{:name "currentPage" :get #(.getPage ^js %)}))

View file

@ -9,7 +9,7 @@
(:require
[app.common.record :as crc]
[app.plugins.page :as page]
[app.plugins.utils :as utils]))
[app.plugins.utils :refer [get-data-fn]]))
(def ^:private
xf-map-page-proxy
@ -17,8 +17,7 @@
(map val)
(map page/data->page-proxy)))
(deftype FileProxy [id name revn
#_:clj-kondo/ignore _data]
(deftype FileProxy [#_:clj-kondo/ignore _data]
Object
(getPages [_]
;; Returns a lazy (iterable) of all available pages
@ -27,16 +26,21 @@
(crc/define-properties!
FileProxy
{:name js/Symbol.toStringTag
:get (fn [] (str "FileProxy"))}
{:name "pages"
:get (fn [] (this-as this (.getPages ^js this)))})
:get (fn [] (str "FileProxy"))})
(defn data->file-proxy
[file data]
(utils/hide-data!
(->FileProxy (str (:id file))
(:name file)
(:revn file)
data)))
(crc/add-properties!
(FileProxy. (merge file data))
{:name "_data" :enumerable false}
{:name "id"
:get (get-data-fn :id str)}
{:name "name"
:get (get-data-fn :name)}
{:name "pages"
:get #(.getPages ^js %)}))

View file

@ -8,8 +8,9 @@
"RPC for plugins runtime."
(:require
[app.common.record :as crc]
[app.common.uuid :as uuid]
[app.plugins.shape :as shape]
[app.plugins.utils :as utils]))
[app.plugins.utils :refer [get-data-fn]]))
(def ^:private
xf-map-shape-proxy
@ -17,9 +18,14 @@
(map val)
(map shape/data->shape-proxy)))
(deftype PageProxy [id name
#_:clj-kondo/ignore _data]
(deftype PageProxy [#_:clj-kondo/ignore _data]
Object
(getShapeById [_ id]
(shape/data->shape-proxy (get (:objects _data) (uuid/uuid id))))
(getRoot [_]
(shape/data->shape-proxy (get (:objects _data) uuid/zero)))
(findShapes [_]
;; Returns a lazy (iterable) of all available shapes
(apply array (sequence xf-map-shape-proxy (:objects _data)))))
@ -31,8 +37,16 @@
(defn data->page-proxy
[data]
(utils/hide-data!
(->PageProxy
(str (:id data))
(:name data)
data)))
(crc/add-properties!
(PageProxy. data)
{:name "_data" :enumerable false}
{:name "id"
:get (get-data-fn :id str)}
{:name "name"
:get (get-data-fn :name)}
{:name "root"
:get #(.getRoot ^js %)}))

View file

@ -7,12 +7,15 @@
(ns app.plugins.shape
"RPC for plugins runtime."
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.record :as crc]
[app.plugins.utils :as utils]
[app.util.object :as obj]
[app.main.data.workspace.changes :as dwc]
[app.main.store :as st]
[app.plugins.utils :refer [get-data get-data-fn]]
[cuerdas.core :as str]))
(declare data->shape-proxy)
(defn- make-fills
[fills]
;; TODO: Transform explicitly?
@ -20,8 +23,19 @@
(->> fills
(map #(clj->js % {:keyword-fn (fn [k] (str/camel (name k)))})))))
(deftype ShapeProxy [_data]
(defn- locate-shape
[shape-id]
(let [page-id (:current-page-id @st/state)]
(dm/get-in @st/state [:workspace-data :pages-index page-id :objects shape-id])))
(deftype ShapeProxy [#_:clj-kondo/ignore _data]
Object
(getChildren
[self]
(apply array (->> (get-data self :shapes)
(map locate-shape)
(map data->shape-proxy))))
(clone [_] (.log js/console (clj->js _data)))
(delete [_] (.log js/console (clj->js _data)))
(appendChild [_] (.log js/console (clj->js _data))))
@ -31,36 +45,28 @@
{:name js/Symbol.toStringTag
:get (fn [] (str "ShapeProxy"))})
(defn get-data
([this attr]
(-> this
(obj/get "_data")
(get attr)))
([this attr transform-fn]
(-> this
(get-data attr)
(transform-fn))))
(defn data->shape-proxy
[data]
(-> (->ShapeProxy data)
(js/Object.defineProperties
#js {"_data" #js {:enumerable false}
(crc/add-properties!
(ShapeProxy. data)
{:name "_data"
:enumerable false}
:id
#js {:get #(get-data (js* "this") :id str)
:enumerable true}
{:name "id"
:get (get-data-fn :id str)}
:name
#js {:get #(get-data (js* "this") :name)
;;:set (fn [] (prn "SET NAME"))
:enumerable true}
{:name "name"
:get (get-data-fn :name)
:set (fn [self value]
(let [id (get-data self :id)]
(st/emit! (dwc/update-shapes [id] #(assoc % :name value)))))}
:fills
#js {:get #(get-data (js* "this") :fills make-fills)
;;:set (fn [] (prn "SET FILLS"))
:enumerable true}}
)))
{:name "children"
:get #(.getChildren ^js %)}
{:name "fills"
:get (get-data-fn :fills make-fills)
;;:set (fn [self value] (.log js/console self value))
}))

View file

@ -5,8 +5,26 @@
;; Copyright (c) KALEIDOS INC
(ns app.plugins.utils
"RPC for plugins runtime.")
"RPC for plugins runtime."
(:require
[app.util.object :as obj]))
(defn get-data
([self attr]
(-> (obj/get self "_data")
(get attr)))
([self attr transform-fn]
(-> (get-data self attr)
(transform-fn))))
(defn get-data-fn
([attr]
(fn [self]
(get-data self attr)))
([attr transform-fn]
(fn [self]
(get-data self attr transform-fn))))
(defn hide-data!
[proxy]
(.defineProperty js/Object proxy "_data" #js {:enumerable false}))