@pimaonline/pimaonline-themepack 2.4.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +30 -0
- package/README.md +69 -111
- package/dist/css/main.css +1 -1
- package/dist/css/themes/ecn/styles.css +1 -0
- package/dist/css/themes/eng/styles.css +1 -0
- package/dist/css/themes/fsc/styles.css +1 -0
- package/dist/css/themes/lang/styles.css +1 -1
- package/dist/css/themes/ss/styles.css +1 -0
- package/dist/img/theme-images/ecn/arrow-2.svg +4 -0
- package/dist/img/theme-images/ecn/arrow.svg +4 -0
- package/dist/img/theme-images/ecn/point.svg +3 -0
- package/dist/img/theme-images/eng/button-bkg.svg +178 -0
- package/dist/img/theme-images/eng/halftone-banner.svg +1 -0
- package/dist/img/theme-images/eng/halftone.svg +177 -0
- package/dist/img/theme-images/eng/long-button-bkg.svg +353 -0
- package/dist/img/theme-images/fsc/bottomwave-pinkred.svg +17 -0
- package/dist/img/theme-images/fsc/bottomwave-redorange.svg +17 -0
- package/dist/img/theme-images/fsc/bottomwave-yellow.svg +17 -0
- package/dist/img/theme-images/fsc/bottomwave-yelloworange.svg +17 -0
- package/dist/img/theme-images/fsc/fire-icon.png +0 -0
- package/dist/img/theme-images/fsc/mainwave-pinkred.svg +17 -0
- package/dist/img/theme-images/fsc/mainwave-redorange.svg +17 -0
- package/dist/img/theme-images/fsc/mainwave-yellow.svg +17 -0
- package/dist/img/theme-images/fsc/mainwave-yelloworange.svg +17 -0
- package/dist/img/theme-images/lang/country-flags/argentina_flag.png +0 -0
- package/dist/img/theme-images/lang/country-flags/bolivia_flag.png +0 -0
- package/dist/img/theme-images/lang/country-flags/chile_flag.png +0 -0
- package/dist/img/theme-images/lang/country-flags/colombia_flag.png +0 -0
- package/dist/img/theme-images/lang/country-flags/costa-rica_flag.png +0 -0
- package/dist/img/theme-images/lang/country-flags/cuba_flag.png +0 -0
- package/dist/img/theme-images/lang/country-flags/dominican-republic_flag.png +0 -0
- package/dist/img/theme-images/lang/country-flags/ecuador_flag.png +0 -0
- package/dist/img/theme-images/lang/country-flags/el-salvador_flag.png +0 -0
- package/dist/img/theme-images/lang/country-flags/guatemala_flag.png +0 -0
- package/dist/img/theme-images/lang/country-flags/honduras_flag.png +0 -0
- package/dist/img/theme-images/lang/country-flags/mexico_flag.png +0 -0
- package/dist/img/theme-images/lang/country-flags/nicaragua_flag.png +0 -0
- package/dist/img/theme-images/lang/country-flags/panama_flag.png +0 -0
- package/dist/img/theme-images/lang/country-flags/paraguay_flag.png +0 -0
- package/dist/img/theme-images/lang/country-flags/peru_flag.png +0 -0
- package/dist/img/theme-images/lang/country-flags/puerto-rice_flag.png +0 -0
- package/dist/img/theme-images/lang/country-flags/spain_flag.png +0 -0
- package/dist/img/theme-images/lang/country-flags/uruguay_flag.png +0 -0
- package/dist/img/theme-images/lang/country-flags/venezuela_flag.png +0 -0
- package/dist/img/theme-images/music/half_note.svg +5 -5
- package/dist/img/theme-images/resort/flourish-left.svg +32 -32
- package/dist/img/theme-images/resort/flourish-main.svg +37 -37
- package/dist/img/theme-images/resort/flourish-right.svg +31 -31
- package/dist/img/theme-images/resort/separator.svg +15 -15
- package/dist/img/theme-images/ss/blockquote.svg +3 -0
- package/dist/img/theme-images/ss/list-style.svg +3 -0
- package/dist/img/theme-images/ss/main-large-blob.svg +3 -0
- package/dist/img/theme-images/ss/main-small-blob.svg +3 -0
- package/dist/img/theme-images/ss/small-blob.svg +3 -0
- package/dist/img/theme-images/ss/tall-blob.svg +3 -0
- package/dist/img/theme-images/widgets/separator.svg +17 -17
- package/dist/js/jumpTo.js +3 -3
- package/dist/js/scripts.js +326 -326
- package/dist/js/scripts2.js +541 -361
- package/dist/plugins/fancybox/fancybox-example.html +51 -51
- package/dist/plugins/fancybox/fancybox.css +72 -72
- package/dist/plugins/fancybox/helpers/jquery.fancybox-buttons.css +97 -97
- package/dist/plugins/fancybox/helpers/jquery.fancybox-buttons.js +122 -122
- package/dist/plugins/fancybox/helpers/jquery.fancybox-media.js +201 -201
- package/dist/plugins/fancybox/helpers/jquery.fancybox-thumbs.css +54 -54
- package/dist/plugins/fancybox/helpers/jquery.fancybox-thumbs.js +165 -165
- package/dist/plugins/fancybox/jquery.fancybox.css +274 -274
- package/dist/plugins/fancybox/jquery.fancybox.js +2018 -2018
- package/dist/plugins/fancybox/jquery.fancybox.pack.js +46 -46
- package/dist/plugins/flashcards/README.md +135 -135
- package/dist/plugins/flashcards/config.rb +24 -24
- package/dist/plugins/flashcards/css/style.css +215 -215
- package/dist/plugins/flashcards/flashcards-example.html +65 -65
- package/dist/plugins/flashcards/index.html +90 -90
- package/dist/plugins/flashcards/js/flash_cards.min.js +11 -11
- package/dist/plugins/flashcards/js/plugins/flash_cards.js +62 -62
- package/dist/plugins/flashcards/js/plugins/jquery.cycle.js +1147 -1147
- package/dist/plugins/flashcards/js/vendor/jquery-1.7.2.js +9404 -9404
- package/dist/plugins/flashcards/js/vendor/jquery-1.7.2.min.js +3 -3
- package/dist/plugins/flashcards/js/vendor/modernizr-2.5.3.min.js +3 -3
- package/dist/plugins/flashcards/resources/fonts/flash_cards/flash_cards.svg +20 -20
- package/dist/plugins/floating-particles/floating-particles.js +67 -67
- package/dist/plugins/font-awesome-icons/webfonts/fa-brands-400.svg +3570 -3570
- package/dist/plugins/font-awesome-icons/webfonts/fa-regular-400.svg +803 -803
- package/dist/plugins/font-awesome-icons/webfonts/fa-solid-900.svg +4700 -4700
- package/dist/plugins/global-homepage-overrides/global-homepage-overrides.css +539 -539
- package/dist/plugins/global-homepage-overrides/global-homepage-overrides.html +18 -18
- package/dist/plugins/global-homepage-overrides/global-homepage-overrides.js +52 -52
- package/dist/plugins/preview-banner/preview-banner.css +125 -125
- package/dist/plugins/preview-banner/preview-banner.html +17 -17
- package/dist/plugins/preview-banner/preview-banner.js +56 -56
- package/package.json +39 -40
package/dist/js/scripts2.js
CHANGED
@@ -1,361 +1,541 @@
|
|
1
|
-
/// @description Main JS file for PimaOnline Themepack
|
2
|
-
/// @dependencies jQuery 3.3.1 or later
|
3
|
-
|
4
|
-
const courseBody = document.querySelector("body");
|
5
|
-
const contentWrapper = document.querySelector("#content-wrapper");
|
6
|
-
const secondColumn = document.querySelector("#second-column");
|
7
|
-
const thirdColumn = document.querySelector("#third-column");
|
8
|
-
const columnWidget = document.querySelector("#column-widget");
|
9
|
-
const videoWrapper = document.querySelector("#video-wrapper");
|
10
|
-
const rolePres = document.querySelectorAll('[role="presentation"]');
|
11
|
-
const imageGallery = document.querySelector(".image-gallery");
|
12
|
-
const vocabListWidget = document.querySelector("dl.vocab-list");
|
13
|
-
const vocabTerms = document.querySelectorAll("dl.vocab-list dt");
|
14
|
-
const vocabDefs = document.querySelectorAll("dl.vocab-list dd");
|
15
|
-
const vocabCloseBtns = document.querySelectorAll("dl.vocab-list button");
|
16
|
-
const vocabLists = document.querySelectorAll("dl[class^='vocab-list']");
|
17
|
-
const mediaContainers = document.querySelectorAll(".media-container");
|
18
|
-
const tabsWidgets = document.querySelectorAll(".tabs");
|
19
|
-
const h5pIframes = document.querySelectorAll("iframe");
|
20
|
-
const docHead = document.querySelector("head");
|
21
|
-
const h5pResizerExists = docHead.querySelector("script[src='https://pima.h5p.com/js/h5p-resizer.js']");
|
22
|
-
const h5pResizer = document.createElement("script");
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
}
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
secondColumn.setAttribute("
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
thirdColumn.setAttribute("
|
50
|
-
|
51
|
-
}
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
tableElems.
|
67
|
-
|
68
|
-
|
69
|
-
};
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
}
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
//
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
const
|
103
|
-
fontAwesomeCdn.
|
104
|
-
fontAwesomeCdn.setAttribute("
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
<
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
imgBoxes[imgBox].
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
}
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
}
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
let
|
219
|
-
let
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
}
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
let
|
239
|
-
|
240
|
-
let
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
tabInputs[tabIndex].
|
254
|
-
tabInputs[tabIndex].setAttribute("
|
255
|
-
tabInputs[tabIndex].setAttribute("
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
tabDivs[tabIndex].
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
}
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
}
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
h5pResizer.setAttribute("
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
1
|
+
/// @description Main JS file for PimaOnline Themepack
|
2
|
+
/// @dependencies jQuery 3.3.1 or later
|
3
|
+
|
4
|
+
const courseBody = document.querySelector("body");
|
5
|
+
const contentWrapper = document.querySelector("#content-wrapper");
|
6
|
+
const secondColumn = document.querySelector("#second-column");
|
7
|
+
const thirdColumn = document.querySelector("#third-column");
|
8
|
+
const columnWidget = document.querySelector("#column-widget");
|
9
|
+
const videoWrapper = document.querySelector("#video-wrapper");
|
10
|
+
const rolePres = document.querySelectorAll('[role="presentation"]');
|
11
|
+
const imageGallery = document.querySelector(".image-gallery");
|
12
|
+
const vocabListWidget = document.querySelector("dl.vocab-list");
|
13
|
+
const vocabTerms = document.querySelectorAll("dl.vocab-list dt");
|
14
|
+
const vocabDefs = document.querySelectorAll("dl.vocab-list dd");
|
15
|
+
const vocabCloseBtns = document.querySelectorAll("dl.vocab-list button");
|
16
|
+
const vocabLists = document.querySelectorAll("dl[class^='vocab-list']");
|
17
|
+
const mediaContainers = document.querySelectorAll(".media-container");
|
18
|
+
const tabsWidgets = document.querySelectorAll(".tabs");
|
19
|
+
const h5pIframes = document.querySelectorAll("iframe");
|
20
|
+
const docHead = document.querySelector("head");
|
21
|
+
const h5pResizerExists = docHead.querySelector("script[src='https://pima.h5p.com/js/h5p-resizer.js']");
|
22
|
+
const h5pResizer = document.createElement("script");
|
23
|
+
const focusReaderTooltipText = "Highlight text as you scroll";
|
24
|
+
|
25
|
+
// Grid
|
26
|
+
const addGrid = () => {
|
27
|
+
if (secondColumn && thirdColumn) {
|
28
|
+
courseBody.id = "three-column";
|
29
|
+
} else if (secondColumn && !columnWidget) {
|
30
|
+
courseBody.id = "two-column";
|
31
|
+
} else if (columnWidget) {
|
32
|
+
courseBody.id = "two-col-widget";
|
33
|
+
} else if (videoWrapper) {
|
34
|
+
courseBody.id = "video-grid";
|
35
|
+
} else {
|
36
|
+
courseBody.id = "one-column";
|
37
|
+
}
|
38
|
+
};
|
39
|
+
addGrid();
|
40
|
+
|
41
|
+
// JS to add role and aria-label to content-wrapper, second-column, and third-column
|
42
|
+
const addAria = () => {
|
43
|
+
contentWrapper.setAttribute("role", "main");
|
44
|
+
if (secondColumn) {
|
45
|
+
secondColumn.setAttribute("role", "region");
|
46
|
+
secondColumn.setAttribute("aria-label", "Second column");
|
47
|
+
}
|
48
|
+
if (thirdColumn) {
|
49
|
+
thirdColumn.setAttribute("role", "region");
|
50
|
+
thirdColumn.setAttribute("aria-label", "Third column");
|
51
|
+
}
|
52
|
+
};
|
53
|
+
addAria();
|
54
|
+
|
55
|
+
// Clean up HTML
|
56
|
+
const cleanMarkup = () => {
|
57
|
+
// Remove role="presentation" attr from any element that has it
|
58
|
+
if (rolePres) {
|
59
|
+
rolePres.forEach((roleElem) => roleElem.removeAttribute("role"));
|
60
|
+
}
|
61
|
+
// Set functino to remove atrributes from elements
|
62
|
+
const discardAttributes = (element, ...attributes) => {
|
63
|
+
attributes.forEach((attribute) => element.removeAttribute(attribute));
|
64
|
+
}
|
65
|
+
// Remove attributes from tables
|
66
|
+
const tableElems = document.querySelectorAll("table, thead, tbody, tr, th, td");
|
67
|
+
tableElems.forEach((elem) => {
|
68
|
+
discardAttributes(elem, "cellspacing", "cellpadding", "width", "style");
|
69
|
+
});
|
70
|
+
};
|
71
|
+
cleanMarkup();
|
72
|
+
|
73
|
+
// Helper JS for Responsive Tables
|
74
|
+
const initResponsiveTables = () => {
|
75
|
+
const tables = document.querySelectorAll(".display, .display-lg")
|
76
|
+
for (let table = 0; table < tables.length; table++) {
|
77
|
+
let headertext = [],
|
78
|
+
headers = tables[table].querySelectorAll(".display table th, table.display th, .display-lg table th, table.display-lg th"),
|
79
|
+
tablebody = tables[table].querySelector(".display table tbody, table.display tbody, .display-lg table tbody, table.display-lg tbody");
|
80
|
+
for (let header = 0; header < headers.length; header++) {
|
81
|
+
let current = headers[header];
|
82
|
+
headertext.push(current.textContent.replace(/\r?\n|\r/, ""));
|
83
|
+
}
|
84
|
+
for (let y = 0, row; row = tablebody.rows[y]; y++) {
|
85
|
+
for (let j = 0, col; col = row.cells[j]; j++) {
|
86
|
+
col.setAttribute("data-th", headertext[j]);
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
initResponsiveTables();
|
92
|
+
|
93
|
+
// This is called by anchor links via onlick="" in the HTML
|
94
|
+
// Added because default anchor links don't work on all browsers using D2L
|
95
|
+
const jumpTo = (anchor) => {
|
96
|
+
document.getElementById(anchor).scrollIntoView();
|
97
|
+
}
|
98
|
+
|
99
|
+
// Image gallery
|
100
|
+
const callImageGallery = () => {
|
101
|
+
// Create link element with font-awesome cdn and append it to the <head>
|
102
|
+
const docHead = document.querySelector("head");
|
103
|
+
const fontAwesomeCdn = document.createElement("link");
|
104
|
+
fontAwesomeCdn.setAttribute("rel", "stylesheet");
|
105
|
+
fontAwesomeCdn.setAttribute("href", "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css");
|
106
|
+
docHead.appendChild(fontAwesomeCdn);
|
107
|
+
// Begin image gallery
|
108
|
+
const imgGalleries = document.querySelectorAll(".image-gallery"),
|
109
|
+
imgBoxes = document.querySelectorAll(".image-box"),
|
110
|
+
modalBoxContent = `<div class="modal-box invisible">
|
111
|
+
<div class="gallery-overlay"></div>
|
112
|
+
<figure class="modal-box--image"><i class="fa-solid fa-x close-img"></i> <img src="#" alt="image here" /><figcaption class="img-caption"></figcaption></figure>
|
113
|
+
</div>
|
114
|
+
<button class="hide-gallery">Hide</button>`;
|
115
|
+
|
116
|
+
// createModalBox.innerHTML = modalBoxContent;
|
117
|
+
for (let imgGallery = 0; imgGallery < imgGalleries.length; imgGallery++) {
|
118
|
+
imgGalleries[imgGallery].insertAdjacentHTML("afterbegin", modalBoxContent);
|
119
|
+
}
|
120
|
+
|
121
|
+
if (document.querySelector(".modal-box")) {
|
122
|
+
const overlay = document.querySelector(".gallery-overlay"),
|
123
|
+
modalBox = document.querySelector(".modal-box"),
|
124
|
+
modalImg = document.querySelector(".modal-box--image img"),
|
125
|
+
modalCaption = document.querySelector(".img-caption"),
|
126
|
+
closeImg = document.querySelector(".close-img");
|
127
|
+
|
128
|
+
for (let imgBox = 0; imgBox < imgBoxes.length; imgBox++) {
|
129
|
+
imgBoxes[imgBox].onclick = function () {
|
130
|
+
modalBox.classList.remove("invisible");
|
131
|
+
let imgSrc = this.querySelector("img").src;
|
132
|
+
modalImg.src = imgSrc;
|
133
|
+
let imgCaption = this.querySelector("img").alt;
|
134
|
+
modalCaption.innerHTML = imgCaption;
|
135
|
+
}
|
136
|
+
|
137
|
+
// Make images tab-able
|
138
|
+
imgBoxes[imgBox].setAttribute("tabindex", "0");
|
139
|
+
imgBoxes[imgBox].addEventListener("keydown", function (enter) {
|
140
|
+
if (enter.key === "Enter") {
|
141
|
+
modalBox.classList.remove("invisible");
|
142
|
+
let imgSrc = this.querySelector("img").src;
|
143
|
+
modalImg.src = imgSrc;
|
144
|
+
let imgCaption = this.querySelector("img").alt;
|
145
|
+
modalCaption.innerHTML = imgCaption;
|
146
|
+
}
|
147
|
+
})
|
148
|
+
}
|
149
|
+
overlay.onclick = () => {
|
150
|
+
modalBox.classList.add("invisible");
|
151
|
+
}
|
152
|
+
window.onkeydown = (esc) => {
|
153
|
+
if (esc.keyCode === 27) {
|
154
|
+
modalBox.classList.add("invisible");
|
155
|
+
}
|
156
|
+
}
|
157
|
+
|
158
|
+
closeImg.onclick = () => {
|
159
|
+
modalBox.classList.add("invisible");
|
160
|
+
}
|
161
|
+
const hideGalleries = document.querySelectorAll(".hide-gallery");
|
162
|
+
for (let hideGallery = 0; hideGallery < hideGalleries.length; hideGallery++) {
|
163
|
+
hideGalleries[hideGallery].addEventListener("click", () => {
|
164
|
+
hideGalleries[hideGallery].nextElementSibling.classList.toggle("invisible");
|
165
|
+
if (hideGalleries[hideGallery].innerHTML === "Hide") {
|
166
|
+
hideGalleries[hideGallery].innerHTML = "Show";
|
167
|
+
} else {
|
168
|
+
hideGalleries[hideGallery].innerHTML = "Hide";
|
169
|
+
}
|
170
|
+
});
|
171
|
+
}
|
172
|
+
};
|
173
|
+
}
|
174
|
+
if (imageGallery) {
|
175
|
+
callImageGallery();
|
176
|
+
}
|
177
|
+
|
178
|
+
// Vocab list widget
|
179
|
+
const callVocabList = () => {
|
180
|
+
if (vocabCloseBtns) {
|
181
|
+
for (let btn = 0; btn < vocabCloseBtns.length; btn++) {
|
182
|
+
vocabCloseBtns[btn].addEventListener("click", () => {
|
183
|
+
for (let node = 0; node < vocabLists[btn].children.length; node++) {
|
184
|
+
if (vocabLists[btn].children[node].tagName == "DD") {
|
185
|
+
vocabLists[btn].children[node].removeAttribute("style");
|
186
|
+
}
|
187
|
+
if (vocabLists[btn].children[node].tagName == "DT") {
|
188
|
+
vocabLists[btn].children[node].removeAttribute("class");
|
189
|
+
}
|
190
|
+
}
|
191
|
+
});
|
192
|
+
}
|
193
|
+
}
|
194
|
+
for (let activeTerm = 0; activeTerm < vocabTerms.length; activeTerm++) {
|
195
|
+
vocabTerms[activeTerm].addEventListener("click", function () {
|
196
|
+
this.classList.toggle("active");
|
197
|
+
let termPanel = this.nextElementSibling;
|
198
|
+
if (termPanel.style.display === "block") { termPanel.removeAttribute("style"); }
|
199
|
+
else { termPanel.style.display = "block"; }
|
200
|
+
});
|
201
|
+
|
202
|
+
vocabTerms[activeTerm].addEventListener("keydown", function (e) {
|
203
|
+
if (e.key === "Enter") {
|
204
|
+
this.classList.toggle("active");
|
205
|
+
let termPanel = this.nextElementSibling;
|
206
|
+
if (termPanel.style.display === "block") { termPanel.removeAttribute("style"); }
|
207
|
+
else { termPanel.style.display = "block"; }
|
208
|
+
}
|
209
|
+
});
|
210
|
+
}
|
211
|
+
}
|
212
|
+
if (vocabListWidget) { callVocabList(); }
|
213
|
+
|
214
|
+
// Media Container
|
215
|
+
const addMediaContainersAria = () => {
|
216
|
+
mediaContainers.forEach((eachContainer, index) => {
|
217
|
+
// loopID: find the current index value, convert it to its letter equivalent, then convert to lowercase
|
218
|
+
let loopId = String.fromCharCode(index + 65).toLowerCase();
|
219
|
+
let mediaObject = eachContainer.querySelector(".media-object");
|
220
|
+
let iframe = mediaObject.firstElementChild;
|
221
|
+
let mediaInfo = mediaObject.nextElementSibling;
|
222
|
+
|
223
|
+
// If element DOES NOT have "aria-describedby" && it DOES have a sibling element.
|
224
|
+
if (!iframe.hasAttribute("aria-describedby") && mediaInfo != null) {
|
225
|
+
iframe.setAttribute("aria-describedby", `${loopId}`);
|
226
|
+
mediaInfo.id = `${[loopId]}`;
|
227
|
+
}
|
228
|
+
});
|
229
|
+
}
|
230
|
+
if (mediaContainers) { addMediaContainersAria(); }
|
231
|
+
|
232
|
+
//Tabs Widget
|
233
|
+
const callTabsWidget = () => {
|
234
|
+
|
235
|
+
let tabsWidgetsNum = 0;
|
236
|
+
|
237
|
+
tabsWidgets.forEach((tab, index) => {
|
238
|
+
let tabInputs = tab.querySelectorAll("input")
|
239
|
+
let tabLabels = tab.querySelectorAll("label")
|
240
|
+
let tabDivs = tab.querySelectorAll("div")
|
241
|
+
|
242
|
+
let groupNum = index + 1;
|
243
|
+
|
244
|
+
//Add region and aria-label to parent div
|
245
|
+
tab.setAttribute("role", "region");
|
246
|
+
tab.setAttribute("aria-label", `tab group ${groupNum}`)
|
247
|
+
|
248
|
+
for (tabIndex = 0; tabIndex < tabInputs.length; tabIndex++) {
|
249
|
+
|
250
|
+
let tabNum = tabsWidgetsNum + 1;
|
251
|
+
|
252
|
+
//Add class, id, name, and aria-described by for inputs
|
253
|
+
tabInputs[tabIndex].classList.add("tab-input");
|
254
|
+
tabInputs[tabIndex].setAttribute("type", "radio")
|
255
|
+
tabInputs[tabIndex].setAttribute("id", `tab${tabNum}`);
|
256
|
+
tabInputs[tabIndex].setAttribute("name", `hint-group-${groupNum}`)
|
257
|
+
tabInputs[tabIndex].setAttribute("aria-describedby", `tabHeading${tabNum}`)
|
258
|
+
//Add class and for for labels
|
259
|
+
tabLabels[tabIndex].classList.add("tab-header");
|
260
|
+
tabLabels[tabIndex].setAttribute("for", `tab${tabNum}`)
|
261
|
+
//Add class, tabindex, and id for divs
|
262
|
+
tabDivs[tabIndex].classList.add("tab-panel")
|
263
|
+
tabDivs[tabIndex].setAttribute("tabindex", 0)
|
264
|
+
tabDivs[tabIndex].setAttribute("id", `tabHeading${tabNum}`)
|
265
|
+
//Add attributes for hide tab
|
266
|
+
if (tabIndex + 1 == tabInputs.length) {
|
267
|
+
tabLabels[tabIndex].classList.add("hide-tab")
|
268
|
+
tabInputs[tabIndex].checked = true;
|
269
|
+
tabDivs[tabIndex].classList.add("hide-panel")
|
270
|
+
}
|
271
|
+
tabsWidgetsNum++;
|
272
|
+
}
|
273
|
+
})
|
274
|
+
}
|
275
|
+
if (tabsWidgets) { callTabsWidget(); }
|
276
|
+
|
277
|
+
// Toggle footnotes
|
278
|
+
const toggleBtns = document.querySelectorAll(".toggle-btn, .toggle-footnotes");
|
279
|
+
|
280
|
+
if (document.querySelector(".toggle-btn") || document.querySelector(".toggle-footnotes")) {
|
281
|
+
for (let toggleBtn = 0; toggleBtn < toggleBtns.length; toggleBtn++) {
|
282
|
+
// Add tabindex
|
283
|
+
toggleBtns[toggleBtn].setAttribute("tabindex", "0");
|
284
|
+
|
285
|
+
// Show/hide on click
|
286
|
+
toggleBtns[toggleBtn].addEventListener("click", () => {
|
287
|
+
toggleBtns[toggleBtn].nextElementSibling.classList.toggle("show");
|
288
|
+
})
|
289
|
+
|
290
|
+
// Show/hide on enter for users who use tab
|
291
|
+
toggleBtns[toggleBtn].addEventListener("keydown", (enter) => {
|
292
|
+
if (enter.keyCode === 13) {
|
293
|
+
toggleBtns[toggleBtn].nextElementSibling.classList.toggle("show");
|
294
|
+
}
|
295
|
+
})
|
296
|
+
}
|
297
|
+
}
|
298
|
+
|
299
|
+
// Change footnotes from 'show' to 'hide'
|
300
|
+
const footnotes = document.querySelector(".toggle-footnotes");
|
301
|
+
|
302
|
+
if (footnotes) {
|
303
|
+
footnotes.addEventListener("click", () => {
|
304
|
+
footnotes.innerHTML = (footnotes.innerHTML === "[Show Footnotes]") ? "[Hide Footnotes]" : "[Show Footnotes]";
|
305
|
+
})
|
306
|
+
}
|
307
|
+
|
308
|
+
// Animated border for HRS theme
|
309
|
+
const hrsBorders = document.querySelectorAll(".hrs-border");
|
310
|
+
|
311
|
+
if (hrsBorders) {
|
312
|
+
for (let hrsBorder = 0; hrsBorder < hrsBorders.length; hrsBorder++) {
|
313
|
+
const callAnimateBorder = new IntersectionObserver(entries => {
|
314
|
+
// Loop over the entries
|
315
|
+
entries.forEach(entry => {
|
316
|
+
// If the element is visible
|
317
|
+
if (entry.isIntersecting) {
|
318
|
+
// Add the animation class
|
319
|
+
entry.target.classList.add('animate-border');
|
320
|
+
}
|
321
|
+
});
|
322
|
+
});
|
323
|
+
callAnimateBorder.observe(hrsBorders[hrsBorder]);
|
324
|
+
}
|
325
|
+
};
|
326
|
+
|
327
|
+
// Add h5p resizer dynamically
|
328
|
+
h5pResizer.setAttribute("src", "https://pima.h5p.com/js/h5p-resizer.js");
|
329
|
+
h5pResizer.setAttribute("charset", "UTF-8");
|
330
|
+
h5pResizer.setAttribute("defer", "");
|
331
|
+
|
332
|
+
h5pIframes.forEach(function (h5pIframe) {
|
333
|
+
const src = h5pIframe.getAttribute("src");
|
334
|
+
if (src.includes("/d2l/common/dialogs/quickLink") || src.includes("https://pima.h5p.com/content") && !h5pResizerExists) {
|
335
|
+
docHead.appendChild(h5pResizer);
|
336
|
+
}
|
337
|
+
});
|
338
|
+
|
339
|
+
if (document.querySelector("body[focus-reader]")) {
|
340
|
+
|
341
|
+
// Initializations
|
342
|
+
let focusOn = false;
|
343
|
+
|
344
|
+
const fr_contentWrapper = document.querySelector("#content-wrapper");
|
345
|
+
const fr_thisBody = document.querySelector("body[focus-reader]");
|
346
|
+
|
347
|
+
// Add fontAwesome to header
|
348
|
+
const fr_pageHead = document.querySelector("head");
|
349
|
+
const fontAweLink = document.createElement("link");
|
350
|
+
fontAweLink.rel = "stylesheet";
|
351
|
+
fontAweLink.href = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css";
|
352
|
+
fr_pageHead.append(fontAweLink);
|
353
|
+
|
354
|
+
// add intersection observer to head tag
|
355
|
+
const observerScript = document.createElement("script");
|
356
|
+
observerScript.setAttribute("src", "https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver");
|
357
|
+
fr_pageHead.append(observerScript);
|
358
|
+
|
359
|
+
// Create Switches container
|
360
|
+
const fr_switchesContainer = document.createElement("div");
|
361
|
+
fr_switchesContainer.className = "focus-reader-switches";
|
362
|
+
fr_thisBody.append(fr_switchesContainer);
|
363
|
+
|
364
|
+
// Focus-text container
|
365
|
+
const fr_focusTextContainer = document.createElement("div");
|
366
|
+
fr_switchesContainer.append(fr_focusTextContainer);
|
367
|
+
|
368
|
+
// Focus-text Icon
|
369
|
+
const fr_focusTextIcon = document.createElement("p");
|
370
|
+
fr_focusTextIcon.innerHTML = "Focus Text"
|
371
|
+
fr_focusTextContainer.append(fr_focusTextIcon);
|
372
|
+
|
373
|
+
// info icon
|
374
|
+
const fr_infoIcon = document.createElement("i");
|
375
|
+
fr_infoIcon.classList.add("fa-solid");
|
376
|
+
fr_infoIcon.classList.add("fa-circle-info");
|
377
|
+
fr_focusTextContainer.append(fr_infoIcon);
|
378
|
+
|
379
|
+
// info tooltip
|
380
|
+
const fr_infoTooltip = document.createElement("span");
|
381
|
+
const focusReaderTooltipText = "Highlight text as you scroll";
|
382
|
+
fr_infoTooltip.classList.add("info-tooltip");
|
383
|
+
fr_infoTooltip.innerHTML = focusReaderTooltipText;
|
384
|
+
fr_infoIcon.append(fr_infoTooltip);
|
385
|
+
|
386
|
+
// Focus-text switch button
|
387
|
+
const fr_focusTextSwitch = document.createElement("button");
|
388
|
+
fr_focusTextSwitch.id = "focus-text";
|
389
|
+
fr_focusTextSwitch.innerHTML = (focusOn) ? `<i class="fas fa-toggle-on"></i>` : `<i class="fas fa-toggle-off"></i>`;
|
390
|
+
fr_focusTextContainer.append(fr_focusTextSwitch);
|
391
|
+
|
392
|
+
// Focus-text logic
|
393
|
+
fr_focusTextSwitch.addEventListener("click", () => {
|
394
|
+
if (focusOn) {
|
395
|
+
focusOn = !focusOn;
|
396
|
+
fr_contentWrapper.removeAttribute("on");
|
397
|
+
fr_focusTextSwitch.innerHTML = (focusOn) ? `<i class="fas fa-toggle-on"></i>` : `<i class="fas fa-toggle-off"></i>`;
|
398
|
+
removeSpans(fr_contentWrapper);
|
399
|
+
} else {
|
400
|
+
focusOn = !focusOn;
|
401
|
+
fr_contentWrapper.setAttribute("on", "");
|
402
|
+
fr_focusTextSwitch.innerHTML = (focusOn) ? `<i class="fas fa-toggle-on"></i>` : `<i class="fas fa-toggle-off"></i>`;
|
403
|
+
const elements = document.querySelectorAll("#content-wrapper .content-body :is(p, li, dd, dt, blockquote)");
|
404
|
+
elements.forEach(element => {
|
405
|
+
traverseAndWrapTextInSpans(element, focusText);
|
406
|
+
});
|
407
|
+
}
|
408
|
+
});
|
409
|
+
|
410
|
+
const options = {
|
411
|
+
root: null,
|
412
|
+
rootMargin: '-48.9% 0px',
|
413
|
+
threshold: 0.00
|
414
|
+
};
|
415
|
+
|
416
|
+
const focusText = new IntersectionObserver(entries => {
|
417
|
+
entries.forEach(entry => {
|
418
|
+
if (entry.isIntersecting) {
|
419
|
+
entry.target.closest("span").classList.add("focus-text");
|
420
|
+
} else {
|
421
|
+
entry.target.closest("span").classList.remove("focus-text");
|
422
|
+
}
|
423
|
+
});
|
424
|
+
}, options);
|
425
|
+
|
426
|
+
|
427
|
+
}
|
428
|
+
|
429
|
+
function traverseAndWrapTextInSpans(node, focusText) {
|
430
|
+
if (node.nodeType === Node.TEXT_NODE && node.textContent.trim() !== '') {
|
431
|
+
// Split the text into words
|
432
|
+
const words = node.textContent.split(' ');
|
433
|
+
|
434
|
+
// Wrap each word in a span
|
435
|
+
words.forEach(word => {
|
436
|
+
if (word !== '') {
|
437
|
+
const span = document.createElement("span");
|
438
|
+
span.textContent = word + ' '; // Add a space after the word to preserve spacing
|
439
|
+
|
440
|
+
// Observe the span
|
441
|
+
focusText.observe(span);
|
442
|
+
|
443
|
+
// Insert the span before the text node
|
444
|
+
node.parentNode.insertBefore(span, node);
|
445
|
+
}
|
446
|
+
});
|
447
|
+
|
448
|
+
// Remove the original text node
|
449
|
+
node.parentNode.removeChild(node);
|
450
|
+
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
451
|
+
// Recursively process child nodes
|
452
|
+
Array.from(node.childNodes).forEach(childNode => {
|
453
|
+
traverseAndWrapTextInSpans(childNode, focusText);
|
454
|
+
});
|
455
|
+
}
|
456
|
+
}
|
457
|
+
|
458
|
+
function removeSpans(node) {
|
459
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
460
|
+
// If the node is a span with the class 'focus-text', an empty class attribute, is empty, or has no attributes, replace it with a text node
|
461
|
+
if (node.tagName === 'SPAN' && (node.className === 'focus-text' || node.className === '' || node.textContent.trim() === '' || node.attributes.length === 0)) {
|
462
|
+
const textNode = document.createTextNode(node.textContent);
|
463
|
+
node.parentNode.insertBefore(textNode, node);
|
464
|
+
node.parentNode.removeChild(node);
|
465
|
+
} else {
|
466
|
+
// Recursively process child nodes
|
467
|
+
Array.from(node.childNodes).forEach(childNode => {
|
468
|
+
removeSpans(childNode);
|
469
|
+
});
|
470
|
+
}
|
471
|
+
}
|
472
|
+
}
|
473
|
+
|
474
|
+
// Reset margin-top and padding-top for content bodies that don't have headings as the first child element
|
475
|
+
const ecnStylesheet = document.querySelector("[href*='themes/ecn/styles.css']");
|
476
|
+
const ecnContentBodies = document.querySelectorAll(".content-body");
|
477
|
+
|
478
|
+
if (ecnStylesheet) {
|
479
|
+
ecnContentBodies.forEach((contentBody) => {
|
480
|
+
const firstChildHeading = contentBody.querySelector(":first-child");
|
481
|
+
if (firstChildHeading && firstChildHeading.tagName !== "H2" && firstChildHeading.tagName !== "H3") {
|
482
|
+
contentBody.style.marginTop = "unset";
|
483
|
+
contentBody.style.paddingTop = "15px";
|
484
|
+
}
|
485
|
+
})
|
486
|
+
}
|
487
|
+
|
488
|
+
|
489
|
+
// Call function with jQuery scripts
|
490
|
+
const callJquery = () => {
|
491
|
+
// Toggle Button's Arrow Right Points Down on Click
|
492
|
+
$('.arrow-right').on('click', function () {
|
493
|
+
$(this).toggleClass('arrow-down');
|
494
|
+
});
|
495
|
+
// TOOLTIP
|
496
|
+
// Allows Screen readers to toggle a tooltip on click and to say if the tooltip is collapsed or expanded.
|
497
|
+
$(".tooltip").click(function () {
|
498
|
+
$(this).children(".tip-hover").toggle();
|
499
|
+
if ($(this).children(".tip-hover").is(':visible')) {
|
500
|
+
$(this).attr('aria-expanded', 'true');
|
501
|
+
$(this).removeClass('hidden');
|
502
|
+
} else {
|
503
|
+
$(this).attr('aria-expanded', 'false');
|
504
|
+
$(this).addClass('hidden');
|
505
|
+
}
|
506
|
+
});
|
507
|
+
let start = 999;
|
508
|
+
$('.tooltip').each(function (i) {
|
509
|
+
$(this).css('z-index', start--);
|
510
|
+
});
|
511
|
+
$(".tooltip .video-container").parent().css("width", "450px");
|
512
|
+
}
|
513
|
+
callJquery();
|
514
|
+
|
515
|
+
// Array for all themes that require theme specific js
|
516
|
+
const customJsThemes = ["ss"];
|
517
|
+
|
518
|
+
//Search links for theme styles
|
519
|
+
const themeJsCheck = () => {
|
520
|
+
|
521
|
+
const links = document.querySelectorAll("link");
|
522
|
+
|
523
|
+
links.forEach((link) => {
|
524
|
+
const href = link.getAttribute("href");
|
525
|
+
customJsThemes.forEach((theme) => {
|
526
|
+
// If theme requires custom js, run addThemeScript()
|
527
|
+
if (href && href.includes(`/${theme}/styles.css`)) {
|
528
|
+
addThemeScript(theme);
|
529
|
+
}
|
530
|
+
});
|
531
|
+
});
|
532
|
+
|
533
|
+
// Adds a script to the head for that particular theme
|
534
|
+
function addThemeScript(theme) {
|
535
|
+
let themeScript = document.createElement("script");
|
536
|
+
themeScript.src = `../js/themes/${theme}.js`;
|
537
|
+
document.head.appendChild(themeScript);
|
538
|
+
}
|
539
|
+
}
|
540
|
+
|
541
|
+
themeJsCheck()
|