From bab881ee75921fb7a5afdeb9510e967cb0132904 Mon Sep 17 00:00:00 2001 From: Daniel Compton Date: Fri, 20 Oct 2017 14:02:32 +1300 Subject: [PATCH] Switch re-frame-trace to render into Shadow DOM I tried to render re-frame-trace into a Shadow DOM which worked, but I ran out of time to get click handlers to work. This is the working point that I got up to. Relates to https://github.com/Day8/re-frame-trace/issues/44 --- src/day8/re_frame/trace.cljs | 63 +++++++++++++++++----------- test/day8/re_frame/trace/shadow.html | 34 +++++++++++++++ 2 files changed, 73 insertions(+), 24 deletions(-) create mode 100644 test/day8/re_frame/trace/shadow.html diff --git a/src/day8/re_frame/trace.cljs b/src/day8/re_frame/trace.cljs index cb9ad0f..5206e80 100644 --- a/src/day8/re_frame/trace.cljs +++ b/src/day8/re_frame/trace.cljs @@ -393,34 +393,49 @@ :subvis [subvis/render-subvis traces [:div.panel-content-scrollable]])]]]))}))) -(defn panel-div [] - (let [id "--re-frame-trace--" - panel (.getElementById js/document id)] - (if panel - panel - (let [new-panel (.createElement js/document "div")] - (.setAttribute new-panel "id" id) - (.appendChild (.-body js/document) new-panel) - (js/window.focus new-panel) - new-panel)))) +(defn panel-shadow + "Attaches the panel to the dom and returns the shadow root for rendering. -(defn inject-styles [] - (let [id "--re-frame-trace-styles--" - styles-el (.getElementById js/document id) + Creates a re-frame-trace div on the body of the document + and attaches a shadow root, returning the root. + Returns an existing shadow root if one exists." + [] + (let [id "--re-frame-trace--root"] + (if-let [panel (.getElementById js/document id)] + (.-shadowRoot panel) + (let [new-panel (.createElement js/document "div") + _ (.setAttribute new-panel "id" id) + _ (.appendChild (.-body js/document) new-panel) + shadow (.attachShadow new-panel (clj->js {:mode "open"}))] + (js/window.focus new-panel) + shadow)))) + +(defn tracing-div + "Returns a div inside the shadow-root that can be used for rendering into with React/Reagent. + Creates it if it does not exist." + [shadow-root] + (let [id "--re-frame-trace--"] + (if-let [div (.querySelector shadow-root (str "#" id))] + div + (let [new-div (.createElement js/document "div")] + (.setAttribute new-div "id" id) + (.appendChild shadow-root new-div) + new-div)))) + +(defn inject-styles [shadow-root] + (let [id "--re-frame-trace-styles--" + styles-el (.querySelector shadow-root (str "#" id)) new-styles-el (.createElement js/document "style") new-styles styles/panel-styles] (.setAttribute new-styles-el "id" id) - (-> new-styles-el - (.-innerHTML) - (set! new-styles)) + (set! (.-innerHTML new-styles-el) new-styles) (if styles-el - (-> styles-el - (.-parentNode) - (.replaceChild new-styles-el styles-el)) - (let [] - (.appendChild (.-head js/document) new-styles-el) - new-styles-el)))) + (.replaceChild (.-parentNode styles-el) new-styles-el styles-el) + (.appendChild shadow-root new-styles-el)) + styles-el)) (defn inject-devtools! [] - (inject-styles) - (r/render [devtools] (panel-div))) + (let [shadow-root (panel-shadow) + div (tracing-div shadow-root)] + (inject-styles shadow-root) + (r/render [devtools] div))) diff --git a/test/day8/re_frame/trace/shadow.html b/test/day8/re_frame/trace/shadow.html new file mode 100644 index 0000000..4678644 --- /dev/null +++ b/test/day8/re_frame/trace/shadow.html @@ -0,0 +1,34 @@ + + + + + + + + +