mirror of
https://github.com/penpot/penpot.git
synced 2025-05-23 21:26:13 +02:00
✨ Refactor of the plugins context
This commit is contained in:
parent
5a34c25926
commit
127b481c38
12 changed files with 285 additions and 186 deletions
|
@ -430,23 +430,31 @@
|
||||||
|
|
||||||
(defmacro define-properties!
|
(defmacro define-properties!
|
||||||
[rsym & properties]
|
[rsym & properties]
|
||||||
(let [rsym (with-meta rsym {:tag 'js})
|
(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-")]
|
|
||||||
`(do
|
`(do
|
||||||
~@(for [params properties
|
~@(for [params properties
|
||||||
:let [pname (get params :name)
|
:let [pname (get params :name)
|
||||||
get-fn (get params :get)
|
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
|
`(.defineProperty js/Object (.-prototype ~rsym) ~pname
|
||||||
(cljs.core/js-obj
|
(cljs.core/js-obj
|
||||||
"enumerable" true
|
|
||||||
"configurable" true
|
|
||||||
~@(concat
|
~@(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
|
(when get-fn
|
||||||
["get" get-fn])
|
["get" get-fn])
|
||||||
|
|
||||||
(when set-fn
|
(when set-fn
|
||||||
["set" set-fn]))))))))
|
["set" set-fn]))))))))
|
||||||
|
|
|
@ -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);
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -23,6 +23,7 @@
|
||||||
{{/isDebug}}
|
{{/isDebug}}
|
||||||
|
|
||||||
<link rel="icon" href="images/favicon.png" />
|
<link rel="icon" href="images/favicon.png" />
|
||||||
|
|
||||||
<script type="importmap">
|
<script type="importmap">
|
||||||
{"imports": {"plugins-runtime": "http://localhost:4200/index.mjs"}}
|
{"imports": {"plugins-runtime": "http://localhost:4200/index.mjs"}}
|
||||||
</script>
|
</script>
|
||||||
|
@ -58,10 +59,7 @@
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import * as runtime from "plugins-runtime";
|
import * as runtime from "plugins-runtime";
|
||||||
|
runtime.initialize(globalThis.app.plugins.api);
|
||||||
// console.log(globalThis.app.plugins);
|
|
||||||
runtime.initialize(globalThis.app.plugins);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
{:entries []}
|
{:entries []}
|
||||||
|
|
||||||
:main
|
:main
|
||||||
{:entries [app.main app.plugins]
|
{:entries [app.main app.plugins.api]
|
||||||
:depends-on #{:shared}
|
:depends-on #{:shared}
|
||||||
:init-fn app.main/init}
|
:init-fn app.main/init}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
[app.main.ui.modal :refer [modal]]
|
[app.main.ui.modal :refer [modal]]
|
||||||
[app.main.ui.routes :as rt]
|
[app.main.ui.routes :as rt]
|
||||||
[app.main.worker :as worker]
|
[app.main.worker :as worker]
|
||||||
[app.plugins]
|
[app.plugins.api]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.i18n :as i18n]
|
[app.util.i18n :as i18n]
|
||||||
[app.util.theme :as theme]
|
[app.util.theme :as theme]
|
||||||
|
|
|
@ -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)))))
|
|
||||||
)))
|
|
||||||
|
|
57
frontend/src/app/plugins/api.cljs
Normal file
57
frontend/src/app/plugins/api.cljs
Normal 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]))))
|
72
frontend/src/app/plugins/events.cljs
Normal file
72
frontend/src/app/plugins/events.cljs
Normal 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))
|
||||||
|
|
42
frontend/src/app/plugins/file.cljs
Normal file
42
frontend/src/app/plugins/file.cljs
Normal 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)))
|
||||||
|
|
||||||
|
|
38
frontend/src/app/plugins/page.cljs
Normal file
38
frontend/src/app/plugins/page.cljs
Normal 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)))
|
43
frontend/src/app/plugins/shape.cljs
Normal file
43
frontend/src/app/plugins/shape.cljs
Normal 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)))
|
||||||
|
|
12
frontend/src/app/plugins/utils.cljs
Normal file
12
frontend/src/app/plugins/utils.cljs
Normal 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}))
|
Loading…
Add table
Add a link
Reference in a new issue