Skip to content

Commit

Permalink
fix(script): add script tag to client widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
jourdain committed Sep 20, 2024
1 parent f2e762c commit 1e94bdf
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 1 deletion.
16 changes: 16 additions & 0 deletions examples/test/script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from trame.app import get_server
from trame.widgets import html, client
from trame.ui.html import DivLayout

server = get_server()

JS_CONTENT = (
"import confetti from 'https://esm.sh/canvas-confetti';"
"trame.utils.confetti = confetti;"
)

with DivLayout(server):
html.Button("Click Me", click="utils.confetti()")
client.Script(JS_CONTENT, module=True)

server.start()
33 changes: 33 additions & 0 deletions trame_client/widgets/trame.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
__all__ = [
"Loading",
"ServerTemplate",
"Script",
"Style",
"JSEval",
"Getter",
Expand Down Expand Up @@ -107,6 +108,38 @@ def var_name(self):
return self._key


# -----------------------------------------------------------------------------
# TrameScript
# -----------------------------------------------------------------------------
class Script(AbstractElement):
"""Provide means to inject a global script tag"""

def __init__(self, script_content=None, **kwargs):
super().__init__("trame-script", **kwargs)
self._key = f"trame__inline_script_{self._id}"
self._attributes["_script"] = f':script="{self._key}"'
self.server.state.setdefault(self._key, script_content)
self._attr_names += [
"module", # type="module" or "text/javascript"
"async",
"crossorigin",
"defer",
"integrity",
"nomodule",
"referrerpolicy",
"src",
]

def update(self, script_content):
"""Update style content"""
self.server.state[self._key] = script_content

@property
def var_name(self):
"""Name the the state variable used by this widget"""
return self._key


# -----------------------------------------------------------------------------
# TrameGetter
# -----------------------------------------------------------------------------
Expand Down
54 changes: 54 additions & 0 deletions vue2-app/src/components/TrameScript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
const { unref } = window.Vue;
let ID = 1;

function getNextId() {
return `trame_script_elem_${ID++}`;
}

export default {
props: {
script: {
type: String,
default: '',
},
module: {
type: Boolean,
default: false,
},
},
watch: {
script(scriptContent) {
this.updateContent(scriptContent);
},
},
created() {
this.elemId = getNextId();
this.updateContent(this.script);
},
beforeUnmount() {
this.removeScript();
},
methods: {
updateContent(scriptContent) {
scriptContent = unref(scriptContent);
let elem = document.querySelector(`#${this.elemId}`);
if (scriptContent) {
if (!elem) {
elem = document.createElement('script');
elem.id = this.elemId;
elem.type = this.module ? 'module' : 'text/javascript';
document.head.appendChild(elem);
}
elem.innerHTML = scriptContent;
} else {
this.removeScript();
}
},
removeScript() {
const elem = document.querySelector(`#${this.elemId}`);
if (elem) {
elem.parentNode.removeChild(elem);
}
},
},
};
2 changes: 2 additions & 0 deletions vue2-app/src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import TrameReconnect from './Reconnect';
import TrameTemplate from './ServerTemplate';
import TrameStateResolver from './StateResolver';
import TrameStyle from './Style';
import TrameScript from './TrameScript';
import TrameExec from './TrameExec';
import TrameGetter from './Getter';
import TrameClientStateChange from './ClientStateChange';
Expand All @@ -19,6 +20,7 @@ export default {
TrameReconnect,
TrameTemplate,
TrameStateResolver,
TrameScript,
TrameStyle,
TrameExec,
TrameGetter,
Expand Down
54 changes: 54 additions & 0 deletions vue3-app/src/components/TrameScript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
const { unref } = window.Vue;
let ID = 1;

function getNextId() {
return `trame_script_elem_${ID++}`;
}

export default {
props: {
script: {
type: String,
default: "",
},
module: {
type: Boolean,
default: false,
},
},
watch: {
script(scriptContent) {
this.updateContent(scriptContent);
},
},
created() {
this.elemId = getNextId();
this.updateContent(this.script);
},
beforeUnmount() {
this.removeScript();
},
methods: {
updateContent(scriptContent) {
scriptContent = unref(scriptContent);
let elem = document.querySelector(`#${this.elemId}`);
if (scriptContent) {
if (!elem) {
elem = document.createElement("script");
elem.id = this.elemId;
elem.type = this.module ? "module" : "text/javascript";
document.head.appendChild(elem);
}
elem.innerHTML = scriptContent;
} else {
this.removeScript();
}
},
removeScript() {
const elem = document.querySelector(`#${this.elemId}`);
if (elem) {
elem.parentNode.removeChild(elem);
}
},
},
};
1 change: 0 additions & 1 deletion vue3-app/src/components/TrameStyle.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,4 @@ export default {
}
},
},
template: `<div class="trame-style" />`,
};
2 changes: 2 additions & 0 deletions vue3-app/src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import TrameExec from "./TrameExec";
import TrameGetter from "./TrameGetter";
import TrameLoading from "./TrameLoading";
import TrameReconnect from "./TrameReconnect";
import TrameScript from "./TrameScript";
import TrameStyle from "./TrameStyle";
import TrameTemplate from "./TrameTemplate";
import TrameClientStateChange from "./TrameClientStateChange";
Expand All @@ -16,6 +17,7 @@ export default {
TrameGetter,
TrameLoading,
TrameReconnect,
TrameScript,
TrameStyle,
TrameTemplate,
TrameClientStateChange,
Expand Down

0 comments on commit 1e94bdf

Please sign in to comment.