Skip to content
This repository was archived by the owner on Jun 7, 2023. It is now read-only.

Commit d49236f

Browse files
committed
Attach logging to pretext events
1 parent 395a01f commit d49236f

3 files changed

Lines changed: 72 additions & 28 deletions

File tree

runestone/common/js/bookfuncs.js

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,9 @@ function addReadingList() {
5858
name: "link",
5959
class: "btn btn-lg ' + 'buttonConfirmCompletion'",
6060
href: nxt_link,
61-
text: `Continue to page ${position + 2
62-
} of ${num_readings} in the reading assignment.`,
61+
text: `Continue to page ${
62+
position + 2
63+
} of ${num_readings} in the reading assignment.`,
6364
});
6465
} else {
6566
l = $("<div />", {
@@ -153,7 +154,7 @@ class PageProgressBar {
153154
if (
154155
val == 100.0 &&
155156
$("#completionButton").text().toLowerCase() ===
156-
"mark as completed"
157+
"mark as completed"
157158
) {
158159
$("#completionButton").click();
159160
}
@@ -171,11 +172,14 @@ async function handlePageSetup() {
171172
Accept: "application/json",
172173
});
173174
let data = { timezoneoffset: new Date().getTimezoneOffset() / 60 };
174-
let request = new Request(`${eBookConfig.new_server_prefix}/logger/set_tz_offset`, {
175-
method: "POST",
176-
body: JSON.stringify(data),
177-
headers: headers,
178-
});
175+
let request = new Request(
176+
`${eBookConfig.new_server_prefix}/logger/set_tz_offset`,
177+
{
178+
method: "POST",
179+
body: JSON.stringify(data),
180+
headers: headers,
181+
}
182+
);
179183
try {
180184
let response = await fetch(request);
181185
if (!response.ok) {
@@ -195,8 +199,10 @@ async function handlePageSetup() {
195199
$(document).trigger("runestone:login");
196200
addReadingList();
197201
// Avoid the timedRefresh on the grading page.
198-
if ((window.location.pathname.indexOf("/admin/grading") == -1)
199-
&& (window.location.pathname.indexOf("/peer/") == -1)) {
202+
if (
203+
window.location.pathname.indexOf("/admin/grading") == -1 &&
204+
window.location.pathname.indexOf("/peer/") == -1
205+
) {
200206
timedRefresh();
201207
}
202208
} else {

runestone/common/js/pretext.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
Support functions for PreTeXt books running on Runestone
3+
4+
*/
5+
6+
import RunestoneBase from "./runestonebase.js";
7+
8+
function setupPTXEvents() {
9+
let rb = new RunestoneBase();
10+
// log an event when a knowl is opened.
11+
$("[data-knowl").on("click", function () {
12+
let div_id = $(this).data("refid");
13+
rb.logBookEvent({ event: "knowl", act: "click", div_id: div_id });
14+
});
15+
// log an event when a sage cell is evaluated
16+
$(".sagecell_evalButton").on("click", function () {
17+
// find parents
18+
let container = $(this).closest(".sagecell-sage");
19+
let code = $(container[0]).find(".sagecell_input")[0].textContent;
20+
rb.logBookEvent({ event: "sage", act: "run", div_id: container[0].id });
21+
});
22+
}
23+
24+
window.addEventListener("load", function () {
25+
console.log("setting up pretext");
26+
setupPTXEvents();
27+
});

webpack.index.js

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
"use strict";
1414

15-
1615
// Static imports
1716
// ==============
1817
// These imports are (we assume) needed by all pages. However, it would be much better to load these in the modules that actually use them.
@@ -40,6 +39,7 @@ import "./runestone/common/css/runestone-custom-sphinx-bootstrap.css";
4039
// Misc
4140
import "./runestone/common/js/bookfuncs.js";
4241
import "./runestone/common/js/user-highlights.js";
42+
import "./runestone/common/js/pretext.js";
4343

4444
// These belong in dynamic imports for the obvious component; however, these components don't include a ``data-component`` attribute.
4545
import "./runestone/matrixeq/css/matrixeq.css";
@@ -50,7 +50,6 @@ import { getSwitch, switchTheme } from "./runestone/common/js/theme.js";
5050
import "./runestone/common/js/presenter_mode.js";
5151
import "./runestone/common/css/presenter_mode.css";
5252

53-
5453
// Dynamically loaded components
5554
// =============================
5655
// This provides a list of modules that components can dynamically import. Webpack will create a list of imports for each based on its analysis.
@@ -61,7 +60,8 @@ const module_map = {
6160
activecode: () => import("./runestone/activecode/js/acfactory.js"),
6261
ble: () => import("./runestone/cellbotics/js/ble.js"),
6362
// Always import the timed version of a component if available, since the timed components also define the component's factory and include the component as well. Note that ``acfactory`` imports the timed components of ActiveCode, so it follows this pattern.
64-
clickablearea: () => import("./runestone/clickableArea/js/timedclickable.js"),
63+
clickablearea: () =>
64+
import("./runestone/clickableArea/js/timedclickable.js"),
6565
codelens: () => import("./runestone/codelens/js/codelens.js"),
6666
datafile: () => import("./runestone/datafile/js/datafile.js"),
6767
dragndrop: () => import("./runestone/dragndrop/js/timeddnd.js"),
@@ -75,7 +75,8 @@ const module_map = {
7575
quizly: () => import("./runestone/quizly/js/quizly.js"),
7676
reveal: () => import("./runestone/reveal/js/reveal.js"),
7777
selectquestion: () => import("./runestone/selectquestion/js/selectone.js"),
78-
shortanswer: () => import("./runestone/shortanswer/js/timed_shortanswer.js"),
78+
shortanswer: () =>
79+
import("./runestone/shortanswer/js/timed_shortanswer.js"),
7980
showeval: () => import("./runestone/showeval/js/showEval.js"),
8081
simple_sensor: () => import("./runestone/cellbotics/js/simple_sensor.js"),
8182
spreadsheet: () => import("./runestone/spreadsheet/js/spreadsheet.js"),
@@ -85,35 +86,41 @@ const module_map = {
8586
// TODO: since this isn't in a ``data-component``, need to trigger an import of this code manually.
8687
webwork: () => import("./runestone/webwork/js/webwork.js"),
8788
youtube: () => import("./runestone/video/js/runestonevideo.js"),
88-
}
89+
};
8990

9091
// .. _dynamic import machinery:
9192
//
9293
// Dynamic import machinery
9394
// ========================
9495
// Fulfill a promise when the Runestone pre-login complete event occurs.
95-
let pre_login_complete_promise = new Promise(resolve => $(document).bind("runestone:pre-login-complete", resolve));
96+
let pre_login_complete_promise = new Promise((resolve) =>
97+
$(document).bind("runestone:pre-login-complete", resolve)
98+
);
9699
let loadedComponents;
97100
// Provide a simple function to import the JS for all components on the page.
98101
export function runestone_auto_import() {
99102
// Create a set of ``data-component`` values, to avoid duplication.
100103
const s = new Set(
101104
// All Runestone components have a ``data-component`` attribute.
102-
$("[data-component]").map(
103-
// Extract the value of the data-component attribute.
104-
(index, element) => $(element).attr("data-component")
105-
// Switch from a jQuery object back to an array, passing that to the Set constructor.
106-
).get()
105+
$("[data-component]")
106+
.map(
107+
// Extract the value of the data-component attribute.
108+
(index, element) => $(element).attr("data-component")
109+
// Switch from a jQuery object back to an array, passing that to the Set constructor.
110+
)
111+
.get()
107112
);
108113

109114
// Load JS for each of the components found.
110-
const a = [...s].map(value =>
115+
const a = [...s].map((value) =>
111116
// If there's no JS for this component, return an empty Promise.
112117
(module_map[value] || (() => Promise.resolve()))()
113118
);
114119

115120
// Send the Runestone login complete event when all JS is loaded and the pre-login is also complete.
116-
Promise.all([pre_login_complete_promise, ...a]).then(() => $(document).trigger("runestone:login-complete"));
121+
Promise.all([pre_login_complete_promise, ...a]).then(() =>
122+
$(document).trigger("runestone:login-complete")
123+
);
117124
}
118125

119126
// Load component JS when the document is ready.
@@ -133,9 +140,11 @@ async function popupScratchAC() {
133140
// activecode. If its not defined then we need to get it ready to toggle
134141
if (!eBookConfig.scratchDiv) {
135142
window.ACFactory.createScratchActivecode();
136-
let divid = eBookConfig.scratchDiv
137-
window.edList[divid] = ACFactory.createActiveCode($(`#${divid}`)[0],
138-
eBookConfig.acDefaultLanguage);
143+
let divid = eBookConfig.scratchDiv;
144+
window.edList[divid] = ACFactory.createActiveCode(
145+
$(`#${divid}`)[0],
146+
eBookConfig.acDefaultLanguage
147+
);
139148
if (eBookConfig.isLoggedIn) {
140149
window.edList[divid].enableSaveLoad();
141150
}
@@ -145,8 +154,10 @@ async function popupScratchAC() {
145154

146155
// Set the directory containing this script as the `path <https://webpack.js.org/guides/public-path/#on-the-fly>`_ for all webpacked scripts.
147156
const script_src = document.currentScript.src;
148-
__webpack_public_path__ = script_src.substring(0, script_src.lastIndexOf('/') + 1);
149-
157+
__webpack_public_path__ = script_src.substring(
158+
0,
159+
script_src.lastIndexOf("/") + 1
160+
);
150161

151162
// Manual exports
152163
// ==============

0 commit comments

Comments
 (0)