jspsych-vue
Version:
Vue3 component for JsPsych
145 lines (144 loc) • 5.36 kB
JavaScript
var L = Object.defineProperty;
var N = (t, n, s) => n in t ? L(t, n, { enumerable: !0, configurable: !0, writable: !0, value: s }) : t[n] = s;
var E = (t, n, s) => N(t, typeof n != "symbol" ? n + "" : n, s);
import { shallowRef as I, ref as _, provide as A, getCurrentInstance as S, h as p, nextTick as k } from "vue";
import { nanoid as H } from "nanoid";
const f = (t = void 0, n = "100%", s = void 0, r = void 0) => ({
name: "JsPsychContent",
props: {
trial: {
type: Object,
required: !1
},
on_load: {
type: Function,
required: !1
}
},
setup(a) {
return k(async () => {
var l;
let o = s == null ? void 0 : s(document.querySelector("#jspsych-content"), a.trial, a.on_load);
o instanceof Promise ? (o = await o, r == null || r(o)) : (l = a.on_load) == null || l.call(a);
}), () => {
let o;
return Array.isArray(t) ? o = t.map((l) => p(l)) : o = t && p(t, { key: H(), ...a }), p("div", {
class: "jspsych-content",
id: "jspsych-content",
tabIndex: "0",
style: `width: ${n};`
}, o);
};
}
}), $ = (t) => {
if (!t)
return document.body;
if (t instanceof Element)
return t;
if (typeof t == "string") {
const n = document.querySelector(t);
if (!n)
throw Error("The element with the specified selector does not exist.");
return n;
}
throw Error("Display element must be an HTML element or a string that specifies a query selector.");
}, G = {
name: "JsPsych",
props: {
options: {
type: Object,
default: () => ({})
},
module: {
type: Object,
required: !1
}
},
emits: ["init"],
setup(t, { slots: n }) {
const s = "jsPsychModule" in window ? window.jsPsychModule : t.module;
if (!s)
throw Error("JsPsych module is not found. You can either install it using npm, then passing it as module prop to JsPsychVue component or use CDN to load it.");
const { JsPsych: r, initJsPsych: a } = s, o = I(), l = _(), h = _();
r.prototype.prepareDom = function() {
let e = $(t.options.display_element);
this.displayContainerElement = e, this.DOM_container = this.displayContainerElement, this.contentElement = document.querySelector("#jspsych-content"), this.DOM_target = this.contentElement, this.displayElement = this.contentElement, this.data.createInteractionListeners(), window.addEventListener("beforeunload", t.options.on_close);
};
var T = r.prototype.run;
r.prototype.run = function(e) {
return T.call(this, u(e));
};
var P = r.prototype.addNodeToEndOfTimeline;
r.prototype.addNodeToEndOfTimeline = function(e) {
return P.call(this, u(e));
};
const w = n.finish && n.finish() || n.default && n.default(), g = t.options;
if (w) {
const e = t.options.on_finish;
g.on_finish = (...i) => {
e && e.call(this, ...i), o.value = f(w, d);
};
}
const c = a(t.options);
A("jsPsych", c), S().emit("init", c);
let d = (c.options || c.opts).experiment_width || "100%";
typeof d == "number" && (d = `${d}px`);
const C = n.start && n.start() || n.default && n.default();
o.value = f(C, d);
const b = (e) => {
if (e.type && e.component)
throw new Error("Cannot specify both type and component in a single timeline node.");
if (!e.type && !e.component)
throw new Error("Must specify either type or component in a timeline node.");
const i = e.type || Object, y = e.component ? e.component.info || {} : {};
class m extends i {
trial(U, O, x) {
return new Promise((q) => {
l.value = O, h.value = x;
const M = (...J) => {
var v;
return (v = super.trial) == null ? void 0 : v.call(this, ...J);
};
o.value = f(e.component, d, M, q);
});
}
}
E(m, "info", { ...i.info, ...y });
const { component: j, ...D } = e;
return {
...D,
type: m
};
}, u = (e) => {
if (!e)
throw Error("Try to convert an empty timeline. Do you forget add the plugin?");
if (e.type || e.component)
return b(e);
if (Array.isArray(e))
return e.map((i) => u(i));
if (!e.timeline)
throw Error("TimelineNode expected one of the following property that is not undifined: timeline, type, component.");
return {
...e,
timeline: u(e.timeline)
};
};
return c.data.displayData = (e) => {
var i = e.format || "json";
i = i.toLowerCase(), i != "json" && i != "csv" && (console.error("Invalid format declared for displayData function. Using json as default."), i = "json");
let y = c.data.allData ? c.data.allData : c.data.results;
const m = i === "json" ? y.json(!0) : y.csv();
var j = e.dom || document.querySelector("#jspsych-display-element");
j.innerHTML = '<pre id="jspsych-data-display"></pre>', document.getElementById("jspsych-data-display").textContent = m;
}, () => p("div", {
id: "jspsych-display-element",
class: "jspsych-display-element"
}, p("div", {
id: "jspsych-content-wrapper",
class: "jspsych-content-wrapper"
}, p(o.value, { trial: l.value, on_load: h.value })));
}
};
export {
G as default
};