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

Refactor of the plugins context

This commit is contained in:
alonso.torres 2024-04-02 09:58:21 +02:00 committed by Andrey Antukh
parent 5a34c25926
commit 127b481c38
12 changed files with 285 additions and 186 deletions

View file

@ -430,23 +430,31 @@
(defmacro define-properties!
[rsym & properties]
(let [rsym (with-meta rsym {:tag 'js})
self-sym (gensym "self-")
get-fn-sym (gensym "get-fn-")
set-fn-sym (gensym "set-fn-")
params-sym (gensym "params-")
args-sym (gensym "args-")]
(let [rsym (with-meta rsym {:tag 'js})]
`(do
~@(for [params properties
:let [pname (get params :name)
get-fn (get params :get)
set-fn (get params :set)]]
set-fn (get params :set)
enum-p (get params :enumerable)
conf-p (get params :configurable)
writ-p (get params :writable)]]
`(.defineProperty js/Object (.-prototype ~rsym) ~pname
(cljs.core/js-obj
"enumerable" true
"configurable" true
~@(concat
(if (some? enum-p)
["enumerable" enum-p]
["enumerable" true])
(if (some? conf-p)
["configurable" conf-p]
["configurable" true])
(when (some? writ-p)
["writable" writ-p])
(when get-fn
["get" get-fn])
(when set-fn
["set" set-fn]))))))))

View file

@ -1,16 +0,0 @@
export class PluginsElement extends HTMLElement {
connectedCallback() {
console.log('PluginsElement.connectedCallback');
}
}
customElements.define('penpot-plugins', PluginsElement);
// Alternative to message passing
export function initialize(api) {
console.log("PluginsRuntime:initialize", api)
api.addListener("foobar", "page", (page) => {
console.log("Page Changed:", page.name);
});
};

View file

@ -23,6 +23,7 @@
{{/isDebug}}
<link rel="icon" href="images/favicon.png" />
<script type="importmap">
{"imports": {"plugins-runtime": "http://localhost:4200/index.mjs"}}
</script>
@ -58,10 +59,7 @@
<script type="module">
import * as runtime from "plugins-runtime";
// console.log(globalThis.app.plugins);
runtime.initialize(globalThis.app.plugins);
runtime.initialize(globalThis.app.plugins.api);
</script>
</body>
</html>

View file

@ -18,7 +18,7 @@
{:entries []}
:main
{:entries [app.main app.plugins]
{:entries [app.main app.plugins.api]
:depends-on #{:shared}
:init-fn app.main/init}

View file

@ -25,7 +25,7 @@
[app.main.ui.modal :refer [modal]]
[app.main.ui.routes :as rt]
[app.main.worker :as worker]
[app.plugins]
[app.plugins.api]
[app.util.dom :as dom]
[app.util.i18n :as i18n]
[app.util.theme :as theme]

View file

@ -1,155 +0,0 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC
(ns app.plugins
"RPC for plugins runtime."
(:require
[app.common.data.macros :as dm]
[app.common.exceptions :as ex]
[app.common.record :as crc]
[app.main.refs :as refs]
[app.main.store :as st]
[goog.functions :as gf]
[app.util.array :as array]
[app.util.rxops :as rxops]
[app.util.timers :as tm]))
;; ---- TYPES
(deftype ShapeProxy [id name type _data])
(defn data->shape-proxy
[data]
(->ShapeProxy (str (:id data))
(:name data)
(name (:type data))
data))
(def ^:private
xf-map-shape-proxy
(comp
(map val)
(map data->shape-proxy)))
(deftype PageProxy [id name _data]
Object
(getShapes [_]
;; Returns a lazy (iterable) of all available shapes
(sequence xf-map-shape-proxy (:objects _data))))
(defn- data->page-proxy
[data]
(->PageProxy (str (:id data))
(:name data)
data))
(def ^:private
xf-map-page-proxy
(comp
(map val)
(map data->page-proxy)))
(deftype FileProxy [id name revn _data]
Object
(getPages [_]
;; Returns a lazy (iterable) of all available pages
(sequence xf-map-page-proxy (:pages-index _data))))
;; ---- PROPERTIES
(crc/define-properties!
FileProxy
{:name js/Symbol.toStringTag
:get (fn [] (str "FileProxy"))})
(crc/define-properties!
PageProxy
{:name js/Symbol.toStringTag
:get (fn [] (str "PageProxy"))})
(crc/define-properties!
ShapeProxy
{:name js/Symbol.toStringTag
:get (fn [] (str "ShapeProxy"))})
;; ---- PUBLIC API
(defn ^:export getCurrentFile
[]
(let [data (:workspace-data @st/state)]
(when (some? data)
(let [file (:workspace-file @st/state)]
(->FileProxy (str (:id file))
(:name file)
(:revn file)
data)))))
(defn ^:export getCurrentPage
[]
(when-let [page-id (:current-page-id @st/state)]
(when-let [data (get-in @st/state [:workspace-data :pages-index page-id])]
(data->page-proxy data))))
(defn ^:export getCurrentSelection
[]
(let [selection (get-in @st/state [:workspace-local :selected])]
(when (some? selection)
selection)))
(defn ^:export getCurrentTheme
[]
(get-in @st/state [:profile :theme]))
(defn ^:export getState
[]
@st/state)
;; (defonce listeners
;; (atom {}))
(defn ^:export addListener
[key type f]
(let [f (gf/debounce f 500)]
(case type
"file"
(add-watch st/state key
(fn [_ _ old-val new-val]
(let [old-file (:workspace-file old-val)
new-file (:workspace-file new-val)
old-data (:workspace-data old-val)
new-data (:workspace-data new-val)]
(when-not (and (identical? old-file new-file)
(identical? old-data new-data))
(f (->FileProxy (str (:id new-file))
(:name new-file)
(:revn new-file)
new-data))))))
"page"
(add-watch st/state key
(fn [_ _ old-val new-val]
(let [old-page-id (:current-page-id old-val)
new-page-id (:current-page-id new-val)
old-page (dm/get-in old-val [:workspace-data :pages-index old-page-id])
new-page (dm/get-in new-val [:workspace-data :pages-index new-page-id])]
(when-not (identical? old-page new-page)
(f (data->page-proxy new-page))))))
"selection"
(add-watch st/state key
(fn [_ _ old-val new-val]
(let [old-selection (get-in old-val [:workspace-local :selected])
new-selection (get-in new-val [:workspace-local :selected])]
(when-not (identical? old-selection new-selection)
(f (clj->js new-selection))))))
"theme"
(add-watch st/state key
(fn [_ _ old-val new-val]
(let [old-theme (get-in old-val [:profile :theme])
new-theme (get-in new-val [:profile :theme])]
(when-not (identical? old-theme new-theme)
(f new-theme)))))
)))

View file

@ -0,0 +1,57 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC
(ns app.plugins.api
"RPC for plugins runtime."
(:require
[app.common.data.macros :as dm]
[app.main.store :as st]
[app.plugins.events :as events]
[app.plugins.file :as file]
[app.plugins.page :as page]
[app.plugins.shape :as shape]))
;;
;; PLUGINS PUBLIC API - The plugins will able to access this functions
;;
(def ^:private
xf-map-shape-proxy
(comp
(map val)
(map shape/data->shape-proxy)))
(defn ^:export addListener
[type callback]
(events/add-listener type callback))
(defn ^:export 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]))))
(defn ^:export 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))))
(defn ^:export getTheme
[]
(let [theme (get-in @st/state [:profile :theme])]
(if (or (not theme) (= theme "default"))
"dark"
(get-in @st/state [:profile :theme]))))

View file

@ -0,0 +1,72 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC
(ns app.plugins.events
(:require
[app.common.data.macros :as dm]
[app.main.store :as st]
[app.plugins.file :as file]
[app.plugins.page :as page]
[goog.functions :as gf]))
(defmulti handle-state-change (fn [type _] type))
(defmethod handle-state-change "filechange"
[_ old-val new-val]
(let [old-file (:workspace-file old-val)
new-file (:workspace-file new-val)
old-data (:workspace-data old-val)
new-data (:workspace-data new-val)]
(if (and (identical? old-file new-file)
(identical? old-data new-data))
::not-changed
(file/data->file-proxy new-file new-data))))
(defmethod handle-state-change "pagechange"
[_ old-val new-val]
(let [old-page-id (:current-page-id old-val)
new-page-id (:current-page-id new-val)
old-page (dm/get-in old-val [:workspace-data :pages-index old-page-id])
new-page (dm/get-in new-val [:workspace-data :pages-index new-page-id])]
(if (identical? old-page new-page)
::not-changed
(page/data->page-proxy new-page))))
(defmethod handle-state-change "selectionchange"
[_ old-val new-val]
(let [old-selection (get-in old-val [:workspace-local :selected])
new-selection (get-in new-val [:workspace-local :selected])]
(if (identical? old-selection new-selection)
::not-changed
(apply array (map str new-selection)))))
(defmethod handle-state-change "themechange"
[_ old-val new-val]
(let [old-theme (get-in old-val [:profile :theme])
new-theme (get-in new-val [:profile :theme])]
(if (identical? old-theme new-theme)
::not-changed
new-theme)))
(defmethod handle-state-change :default
[_ _ _]
::not-changed)
(defn add-listener
[type callback]
(let [key (js/Symbol)
callback (gf/debounce callback 10)]
(add-watch
st/state key
(fn [_ _ old-val new-val]
(let [result (handle-state-change type old-val new-val)]
(when (not= ::not-changed result)
(callback result)))))
;; return the generated key
key))

View file

@ -0,0 +1,42 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC
(ns app.plugins.file
"RPC for plugins runtime."
(:require
[app.common.record :as crc]
[app.plugins.page :as page]
[app.plugins.utils :as utils]))
(def ^:private
xf-map-page-proxy
(comp
(map val)
(map page/data->page-proxy)))
(deftype FileProxy [id name revn
#_:clj-kondo/ignore _data]
Object
(getPages [_]
;; Returns a lazy (iterable) of all available pages
(apply array (sequence xf-map-page-proxy (:pages-index _data)))))
(crc/define-properties!
FileProxy
{:name js/Symbol.toStringTag
:get (fn [] (str "FileProxy"))}
{:name "pages"
:get (fn [] (this-as this (.getPages ^js this)))})
(defn data->file-proxy
[file data]
(utils/hide-data!
(->FileProxy (str (:id file))
(:name file)
(:revn file)
data)))

View file

@ -0,0 +1,38 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC
(ns app.plugins.page
"RPC for plugins runtime."
(:require
[app.common.record :as crc]
[app.plugins.shape :as shape]
[app.plugins.utils :as utils]))
(def ^:private
xf-map-shape-proxy
(comp
(map val)
(map shape/data->shape-proxy)))
(deftype PageProxy [id name
#_:clj-kondo/ignore _data]
Object
(findShapes [_]
;; Returns a lazy (iterable) of all available shapes
(apply array (sequence xf-map-shape-proxy (:objects _data)))))
(crc/define-properties!
PageProxy
{:name js/Symbol.toStringTag
:get (fn [] (str "PageProxy"))})
(defn data->page-proxy
[data]
(utils/hide-data!
(->PageProxy
(str (:id data))
(:name data)
data)))

View file

@ -0,0 +1,43 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC
(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]
[cuerdas.core :as str]))
(defn- fills
[shape]
;; TODO: Transform explicitly?
(apply array
(->> (:fills shape)
(map #(clj->js % {:keyword-fn (fn [k] (str/camel (name k)))})))))
(deftype ShapeProxy
[id
name
type
fills
_data])
(crc/define-properties!
ShapeProxy
{:name js/Symbol.toStringTag
:get (fn [] (str "ShapeProxy"))})
(defn data->shape-proxy
[data]
(utils/hide-data!
(->ShapeProxy (dm/str (:id data))
(:name data)
(d/name (:type data))
(fills data)
data)))

View file

@ -0,0 +1,12 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC
(ns app.plugins.utils
"RPC for plugins runtime.")
(defn hide-data!
[proxy]
(.defineProperty js/Object proxy "_data" #js {:enumerable false}))