asciidoctor-revealjs 4.1.0 → 5.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +7 -2
  3. data/README.adoc +12 -1351
  4. data/asciidoctor-revealjs.gemspec +2 -3
  5. data/examples/auto-animate-code.adoc +47 -0
  6. data/examples/auto-animate.adoc +351 -0
  7. data/examples/favicon.adoc +13 -0
  8. data/examples/images/sample.svg +27 -0
  9. data/examples/mathjax-cdn.adoc +1 -1
  10. data/examples/mathjax.adoc +1 -1
  11. data/examples/revealjs-custom-theme.adoc +1 -1
  12. data/examples/revealjs-plugin-activation.adoc +3 -2
  13. data/examples/revealjs-plugins/chalkboard/README.md +94 -61
  14. data/examples/revealjs-plugins/chalkboard/img/boardmarker-black.png +0 -0
  15. data/examples/revealjs-plugins/chalkboard/img/boardmarker-blue.png +0 -0
  16. data/examples/revealjs-plugins/chalkboard/img/boardmarker-green.png +0 -0
  17. data/examples/revealjs-plugins/chalkboard/img/boardmarker-orange.png +0 -0
  18. data/examples/revealjs-plugins/chalkboard/img/boardmarker-purple.png +0 -0
  19. data/examples/revealjs-plugins/chalkboard/img/boardmarker-red.png +0 -0
  20. data/examples/revealjs-plugins/chalkboard/img/boardmarker-yellow.png +0 -0
  21. data/examples/revealjs-plugins/chalkboard/img/chalk-blue.png +0 -0
  22. data/examples/revealjs-plugins/chalkboard/img/chalk-green.png +0 -0
  23. data/examples/revealjs-plugins/chalkboard/img/chalk-orange.png +0 -0
  24. data/examples/revealjs-plugins/chalkboard/img/chalk-purple.png +0 -0
  25. data/examples/revealjs-plugins/chalkboard/img/chalk-red.png +0 -0
  26. data/examples/revealjs-plugins/chalkboard/img/chalk-yellow.png +0 -0
  27. data/examples/revealjs-plugins/chalkboard/plugin.js +1836 -0
  28. data/examples/revealjs-plugins/chalkboard/style.css +38 -0
  29. data/examples/revealjs-plugins/{reveal.js-menu → menu}/LICENSE +1 -1
  30. data/examples/revealjs-plugins/menu/README.md +368 -0
  31. data/examples/revealjs-plugins/{reveal.js-menu → menu}/menu.css +116 -115
  32. data/examples/revealjs-plugins/menu/menu.esm.js +1 -0
  33. data/examples/revealjs-plugins/menu/menu.js +1 -0
  34. data/examples/revealjs-plugins/menu/plugin.js +1252 -0
  35. data/examples/revealjs-plugins-docinfo-footer.html +20 -0
  36. data/examples/revealjs-plugins.adoc +2 -3
  37. data/examples/search-plugin.adoc +26 -0
  38. data/examples/source-rouge.adoc +1 -1
  39. data/examples/svg-images-docinfo-revealjs.html +15 -0
  40. data/examples/svg-images.adoc +41 -0
  41. data/examples/text-formatting.adoc +34 -0
  42. data/lib/asciidoctor-revealjs/converter.rb +819 -686
  43. data/lib/asciidoctor-revealjs/highlightjs.rb +155 -14
  44. data/lib/asciidoctor-revealjs/version.rb +1 -1
  45. data/templates/asciidoctor-compatibility.css +26 -1
  46. data/templates/document.html.slim +28 -44
  47. data/templates/helpers.rb +188 -10
  48. data/templates/image.html.slim +1 -16
  49. data/templates/inline_image.html.slim +1 -20
  50. data/templates/inline_quoted.html.slim +2 -2
  51. data/templates/listing.html.slim +2 -1
  52. data/templates/section.html.slim +7 -1
  53. data/templates/title_slide.html.slim +1 -2
  54. metadata +58 -81
  55. data/examples/revealjs-plugins/chalkboard/chalkboard.js +0 -1288
  56. data/examples/revealjs-plugins/chalkboard/img/boardmarker.png +0 -0
  57. data/examples/revealjs-plugins/reveal.js-menu/CONTRIBUTING.md +0 -9
  58. data/examples/revealjs-plugins/reveal.js-menu/README.md +0 -334
  59. data/examples/revealjs-plugins/reveal.js-menu/bower.json +0 -21
  60. data/examples/revealjs-plugins/reveal.js-menu/menu.js +0 -949
  61. data/examples/revealjs-plugins/reveal.js-menu/package.json +0 -22
  62. data/examples/revealjs-plugins-conf.js +0 -10
  63. data/examples/revealjs-plugins.js +0 -2
  64. /data/examples/revealjs-plugins/chalkboard/img/{chalk.png → chalk-white.png} +0 -0
  65. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/LICENSE.txt +0 -0
  66. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/all.css +0 -0
  67. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/brands.css +0 -0
  68. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/fontawesome.css +0 -0
  69. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/regular.css +0 -0
  70. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/solid.css +0 -0
  71. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/svg-with-js.css +0 -0
  72. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/v4-shims.css +0 -0
  73. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/v4-shims.min.css +0 -0
  74. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-brands-400.eot +0 -0
  75. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-brands-400.svg +0 -0
  76. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-brands-400.ttf +0 -0
  77. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-brands-400.woff +0 -0
  78. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-brands-400.woff2 +0 -0
  79. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-regular-400.eot +0 -0
  80. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-regular-400.svg +0 -0
  81. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-regular-400.ttf +0 -0
  82. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-regular-400.woff +0 -0
  83. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-regular-400.woff2 +0 -0
  84. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-solid-900.eot +0 -0
  85. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-solid-900.svg +0 -0
  86. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-solid-900.ttf +0 -0
  87. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-solid-900.woff +0 -0
  88. /data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-solid-900.woff2 +0 -0
@@ -0,0 +1,1252 @@
1
+ /*
2
+ * Reveal.js menu plugin
3
+ * MIT licensed
4
+ * (c) Greg Denehy 2020
5
+ */
6
+
7
+ const Plugin = () => {
8
+ const ieVersion = (function () {
9
+ let browser = /(msie) ([\w.]+)/.exec(
10
+ window.navigator.userAgent.toLowerCase()
11
+ );
12
+ if (browser && browser[1] === 'msie') {
13
+ return parseFloat(browser[2]);
14
+ }
15
+ return null;
16
+ })();
17
+
18
+ var deck;
19
+ var config;
20
+ var options;
21
+ var initialised = false;
22
+
23
+ function scriptPath() {
24
+ // obtain plugin path from the script element
25
+ var path;
26
+
27
+ const script = document.querySelector('script[src$="menu.js"]');
28
+ if (script) {
29
+ var sel = document.querySelector('script[src$="menu.js"]');
30
+ if (sel) {
31
+ path = sel.src.slice(0, -7);
32
+ }
33
+ } else {
34
+ path = import.meta.url.slice(0, import.meta.url.lastIndexOf('/') + 1);
35
+ }
36
+
37
+ return path;
38
+ }
39
+
40
+ function initOptions(config) {
41
+ options = config.menu || {};
42
+ options.path = options.path || scriptPath() || 'plugin/menu/';
43
+ if (!options.path.endsWith('/')) {
44
+ options.path += '/';
45
+ }
46
+
47
+ // Set defaults
48
+ if (options.side === undefined) options.side = 'left';
49
+
50
+ if (options.numbers === undefined) options.numbers = false;
51
+
52
+ if (typeof options.titleSelector !== 'string')
53
+ options.titleSelector = 'h1, h2, h3, h4, h5';
54
+
55
+ if (options.hideMissingTitles === undefined)
56
+ options.hideMissingTitles = false;
57
+
58
+ if (options.useTextContentForMissingTitles === undefined)
59
+ options.useTextContentForMissingTitles = false;
60
+
61
+ if (options.markers === undefined) options.markers = true;
62
+
63
+ if (typeof options.themesPath !== 'string')
64
+ options.themesPath = 'dist/theme/';
65
+ if (!options.themesPath.endsWith('/')) options.themesPath += '/';
66
+
67
+ if (!select('link#theme')) options.themes = false;
68
+ if (options.themes === true) {
69
+ options.themes = [
70
+ { name: 'Black', theme: options.themesPath + 'black.css' },
71
+ { name: 'White', theme: options.themesPath + 'white.css' },
72
+ { name: 'League', theme: options.themesPath + 'league.css' },
73
+ { name: 'Sky', theme: options.themesPath + 'sky.css' },
74
+ { name: 'Beige', theme: options.themesPath + 'beige.css' },
75
+ { name: 'Simple', theme: options.themesPath + 'simple.css' },
76
+ { name: 'Serif', theme: options.themesPath + 'serif.css' },
77
+ { name: 'Blood', theme: options.themesPath + 'blood.css' },
78
+ { name: 'Night', theme: options.themesPath + 'night.css' },
79
+ { name: 'Moon', theme: options.themesPath + 'moon.css' },
80
+ { name: 'Solarized', theme: options.themesPath + 'solarized.css' }
81
+ ];
82
+ } else if (!Array.isArray(options.themes)) {
83
+ options.themes = false;
84
+ }
85
+
86
+ if (options.transitions === undefined) options.transitions = false;
87
+ if (options.transitions === true) {
88
+ options.transitions = [
89
+ 'None',
90
+ 'Fade',
91
+ 'Slide',
92
+ 'Convex',
93
+ 'Concave',
94
+ 'Zoom'
95
+ ];
96
+ } else if (
97
+ options.transitions !== false &&
98
+ (!Array.isArray(options.transitions) ||
99
+ !options.transitions.every(function (e) {
100
+ return typeof e === 'string';
101
+ }))
102
+ ) {
103
+ console.error(
104
+ "reveal.js-menu error: transitions config value must be 'true' or an array of strings, eg ['None', 'Fade', 'Slide')"
105
+ );
106
+ options.transitions = false;
107
+ }
108
+ if (ieVersion && ieVersion <= 9) {
109
+ // transitions aren't support in IE9 anyway, so no point in showing them
110
+ options.transitions = false;
111
+ }
112
+
113
+ if (typeof options.openButton === 'undefined') options.openButton = true;
114
+
115
+ if (typeof options.openSlideNumber === 'undefined')
116
+ options.openSlideNumber = false;
117
+
118
+ if (typeof options.keyboard === 'undefined') options.keyboard = true;
119
+
120
+ if (typeof options.sticky === 'undefined') options.sticky = false;
121
+
122
+ if (typeof options.autoOpen === 'undefined') options.autoOpen = true;
123
+
124
+ if (typeof options.delayInit === 'undefined') options.delayInit = false;
125
+
126
+ if (typeof options.openOnInit === 'undefined') options.openOnInit = false;
127
+ }
128
+
129
+ var mouseSelectionEnabled = true;
130
+ function disableMouseSelection() {
131
+ mouseSelectionEnabled = false;
132
+ }
133
+
134
+ function reenableMouseSelection() {
135
+ // wait until the mouse has moved before re-enabling mouse selection
136
+ // to avoid selections on scroll
137
+ select('nav.slide-menu').addEventListener('mousemove', function fn(e) {
138
+ select('nav.slide-menu').removeEventListener('mousemove', fn);
139
+ //XXX this should select the item under the mouse
140
+ mouseSelectionEnabled = true;
141
+ });
142
+ }
143
+
144
+ //
145
+ // Keyboard handling
146
+ //
147
+ function getOffset(el) {
148
+ var _x = 0;
149
+ var _y = 0;
150
+ while (el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) {
151
+ _x += el.offsetLeft - el.scrollLeft;
152
+ _y += el.offsetTop - el.scrollTop;
153
+ el = el.offsetParent;
154
+ }
155
+ return { top: _y, left: _x };
156
+ }
157
+
158
+ function visibleOffset(el) {
159
+ var offsetFromTop = getOffset(el).top - el.offsetParent.offsetTop;
160
+ if (offsetFromTop < 0) return -offsetFromTop;
161
+ var offsetFromBottom =
162
+ el.offsetParent.offsetHeight -
163
+ (el.offsetTop - el.offsetParent.scrollTop + el.offsetHeight);
164
+ if (offsetFromBottom < 0) return offsetFromBottom;
165
+ return 0;
166
+ }
167
+
168
+ function keepVisible(el) {
169
+ var offset = visibleOffset(el);
170
+ if (offset) {
171
+ disableMouseSelection();
172
+ el.scrollIntoView(offset > 0);
173
+ reenableMouseSelection();
174
+ }
175
+ }
176
+
177
+ function scrollItemToTop(el) {
178
+ disableMouseSelection();
179
+ el.offsetParent.scrollTop = el.offsetTop;
180
+ reenableMouseSelection();
181
+ }
182
+
183
+ function scrollItemToBottom(el) {
184
+ disableMouseSelection();
185
+ el.offsetParent.scrollTop =
186
+ el.offsetTop - el.offsetParent.offsetHeight + el.offsetHeight;
187
+ reenableMouseSelection();
188
+ }
189
+
190
+ function selectItem(el) {
191
+ el.classList.add('selected');
192
+ keepVisible(el);
193
+ if (options.sticky && options.autoOpen) openItem(el);
194
+ }
195
+
196
+ function onDocumentKeyDown(event) {
197
+ // opening menu is handled by registering key binding with Reveal below
198
+ if (isOpen()) {
199
+ event.stopImmediatePropagation();
200
+ switch (event.keyCode) {
201
+ // case 77:
202
+ // closeMenu();
203
+ // break;
204
+ // h, left - change panel
205
+ case 72:
206
+ case 37:
207
+ prevPanel();
208
+ break;
209
+ // l, right - change panel
210
+ case 76:
211
+ case 39:
212
+ nextPanel();
213
+ break;
214
+ // k, up
215
+ case 75:
216
+ case 38:
217
+ var currItem =
218
+ select('.active-menu-panel .slide-menu-items li.selected') ||
219
+ select('.active-menu-panel .slide-menu-items li.active');
220
+ if (currItem) {
221
+ selectAll('.active-menu-panel .slide-menu-items li').forEach(
222
+ function (item) {
223
+ item.classList.remove('selected');
224
+ }
225
+ );
226
+ var nextItem =
227
+ select(
228
+ '.active-menu-panel .slide-menu-items li[data-item="' +
229
+ (parseInt(currItem.getAttribute('data-item')) - 1) +
230
+ '"]'
231
+ ) || currItem;
232
+ selectItem(nextItem);
233
+ } else {
234
+ var item = select(
235
+ '.active-menu-panel .slide-menu-items li.slide-menu-item'
236
+ );
237
+ if (item) selectItem(item);
238
+ }
239
+ break;
240
+ // j, down
241
+ case 74:
242
+ case 40:
243
+ var currItem =
244
+ select('.active-menu-panel .slide-menu-items li.selected') ||
245
+ select('.active-menu-panel .slide-menu-items li.active');
246
+ if (currItem) {
247
+ selectAll('.active-menu-panel .slide-menu-items li').forEach(
248
+ function (item) {
249
+ item.classList.remove('selected');
250
+ }
251
+ );
252
+ var nextItem =
253
+ select(
254
+ '.active-menu-panel .slide-menu-items li[data-item="' +
255
+ (parseInt(currItem.getAttribute('data-item')) + 1) +
256
+ '"]'
257
+ ) || currItem;
258
+ selectItem(nextItem);
259
+ } else {
260
+ var item = select(
261
+ '.active-menu-panel .slide-menu-items li.slide-menu-item'
262
+ );
263
+ if (item) selectItem(item);
264
+ }
265
+ break;
266
+ // pageup, u
267
+ case 33:
268
+ case 85:
269
+ var itemsAbove = selectAll(
270
+ '.active-menu-panel .slide-menu-items li'
271
+ ).filter(function (item) {
272
+ return visibleOffset(item) > 0;
273
+ });
274
+ var visibleItems = selectAll(
275
+ '.active-menu-panel .slide-menu-items li'
276
+ ).filter(function (item) {
277
+ return visibleOffset(item) == 0;
278
+ });
279
+
280
+ var firstVisible =
281
+ itemsAbove.length > 0 &&
282
+ Math.abs(visibleOffset(itemsAbove[itemsAbove.length - 1])) <
283
+ itemsAbove[itemsAbove.length - 1].clientHeight
284
+ ? itemsAbove[itemsAbove.length - 1]
285
+ : visibleItems[0];
286
+ if (firstVisible) {
287
+ if (
288
+ firstVisible.classList.contains('selected') &&
289
+ itemsAbove.length > 0
290
+ ) {
291
+ // at top of viewport already, page scroll (if not at start)
292
+ // ...move selected item to bottom, and change selection to last fully visible item at top
293
+ scrollItemToBottom(firstVisible);
294
+ visibleItems = selectAll(
295
+ '.active-menu-panel .slide-menu-items li'
296
+ ).filter(function (item) {
297
+ return visibleOffset(item) == 0;
298
+ });
299
+ if (visibleItems[0] == firstVisible) {
300
+ // prev item is still beyond the viewport (for custom panels)
301
+ firstVisible = itemsAbove[itemsAbove.length - 1];
302
+ } else {
303
+ firstVisible = visibleItems[0];
304
+ }
305
+ }
306
+ selectAll('.active-menu-panel .slide-menu-items li').forEach(
307
+ function (item) {
308
+ item.classList.remove('selected');
309
+ }
310
+ );
311
+ selectItem(firstVisible);
312
+ // ensure selected item is positioned at the top of the viewport
313
+ scrollItemToTop(firstVisible);
314
+ }
315
+ break;
316
+ // pagedown, d
317
+ case 34:
318
+ case 68:
319
+ var visibleItems = selectAll(
320
+ '.active-menu-panel .slide-menu-items li'
321
+ ).filter(function (item) {
322
+ return visibleOffset(item) == 0;
323
+ });
324
+ var itemsBelow = selectAll(
325
+ '.active-menu-panel .slide-menu-items li'
326
+ ).filter(function (item) {
327
+ return visibleOffset(item) < 0;
328
+ });
329
+
330
+ var lastVisible =
331
+ itemsBelow.length > 0 &&
332
+ Math.abs(visibleOffset(itemsBelow[0])) < itemsBelow[0].clientHeight
333
+ ? itemsBelow[0]
334
+ : visibleItems[visibleItems.length - 1];
335
+ if (lastVisible) {
336
+ if (
337
+ lastVisible.classList.contains('selected') &&
338
+ itemsBelow.length > 0
339
+ ) {
340
+ // at bottom of viewport already, page scroll (if not at end)
341
+ // ...move selected item to top, and change selection to last fully visible item at bottom
342
+ scrollItemToTop(lastVisible);
343
+ visibleItems = selectAll(
344
+ '.active-menu-panel .slide-menu-items li'
345
+ ).filter(function (item) {
346
+ return visibleOffset(item) == 0;
347
+ });
348
+ if (visibleItems[visibleItems.length - 1] == lastVisible) {
349
+ // next item is still beyond the viewport (for custom panels)
350
+ lastVisible = itemsBelow[0];
351
+ } else {
352
+ lastVisible = visibleItems[visibleItems.length - 1];
353
+ }
354
+ }
355
+ selectAll('.active-menu-panel .slide-menu-items li').forEach(
356
+ function (item) {
357
+ item.classList.remove('selected');
358
+ }
359
+ );
360
+ selectItem(lastVisible);
361
+ // ensure selected item is positioned at the bottom of the viewport
362
+ scrollItemToBottom(lastVisible);
363
+ }
364
+ break;
365
+ // home
366
+ case 36:
367
+ selectAll('.active-menu-panel .slide-menu-items li').forEach(
368
+ function (item) {
369
+ item.classList.remove('selected');
370
+ }
371
+ );
372
+ var item = select(
373
+ '.active-menu-panel .slide-menu-items li:first-of-type'
374
+ );
375
+ if (item) {
376
+ item.classList.add('selected');
377
+ keepVisible(item);
378
+ }
379
+ break;
380
+ // end
381
+ case 35:
382
+ selectAll('.active-menu-panel .slide-menu-items li').forEach(
383
+ function (item) {
384
+ item.classList.remove('selected');
385
+ }
386
+ );
387
+ var item = select(
388
+ '.active-menu-panel .slide-menu-items:last-of-type li:last-of-type'
389
+ );
390
+ if (item) {
391
+ item.classList.add('selected');
392
+ keepVisible(item);
393
+ }
394
+ break;
395
+ // space, return
396
+ case 32:
397
+ case 13:
398
+ var currItem = select(
399
+ '.active-menu-panel .slide-menu-items li.selected'
400
+ );
401
+ if (currItem) {
402
+ openItem(currItem, true);
403
+ }
404
+ break;
405
+ // esc
406
+ case 27:
407
+ closeMenu(null, true);
408
+ break;
409
+ }
410
+ }
411
+ }
412
+
413
+ //
414
+ // Utilty functions
415
+ //
416
+
417
+ function openMenu(event) {
418
+ if (event) event.preventDefault();
419
+ if (!isOpen()) {
420
+ select('body').classList.add('slide-menu-active');
421
+ select('.reveal').classList.add(
422
+ 'has-' + options.effect + '-' + options.side
423
+ );
424
+ select('.slide-menu').classList.add('active');
425
+ select('.slide-menu-overlay').classList.add('active');
426
+
427
+ // identify active theme
428
+ if (options.themes) {
429
+ selectAll('div[data-panel="Themes"] li').forEach(function (i) {
430
+ i.classList.remove('active');
431
+ });
432
+ selectAll(
433
+ 'li[data-theme="' + select('link#theme').getAttribute('href') + '"]'
434
+ ).forEach(function (i) {
435
+ i.classList.add('active');
436
+ });
437
+ }
438
+
439
+ // identify active transition
440
+ if (options.transitions) {
441
+ selectAll('div[data-panel="Transitions"] li').forEach(function (i) {
442
+ i.classList.remove('active');
443
+ });
444
+ selectAll('li[data-transition="' + config.transition + '"]').forEach(
445
+ function (i) {
446
+ i.classList.add('active');
447
+ }
448
+ );
449
+ }
450
+
451
+ // set item selections to match active items
452
+ var items = selectAll('.slide-menu-panel li.active');
453
+ items.forEach(function (i) {
454
+ i.classList.add('selected');
455
+ keepVisible(i);
456
+ });
457
+ }
458
+ }
459
+
460
+ function closeMenu(event, force) {
461
+ if (event) event.preventDefault();
462
+ if (!options.sticky || force) {
463
+ select('body').classList.remove('slide-menu-active');
464
+ select('.reveal').classList.remove(
465
+ 'has-' + options.effect + '-' + options.side
466
+ );
467
+ select('.slide-menu').classList.remove('active');
468
+ select('.slide-menu-overlay').classList.remove('active');
469
+ selectAll('.slide-menu-panel li.selected').forEach(function (i) {
470
+ i.classList.remove('selected');
471
+ });
472
+ }
473
+ }
474
+
475
+ function toggleMenu(event) {
476
+ if (isOpen()) {
477
+ closeMenu(event, true);
478
+ } else {
479
+ openMenu(event);
480
+ }
481
+ }
482
+
483
+ function isOpen() {
484
+ return select('body').classList.contains('slide-menu-active');
485
+ }
486
+
487
+ function openPanel(event, ref) {
488
+ openMenu(event);
489
+ var panel = ref;
490
+ if (typeof ref !== 'string') {
491
+ panel = event.currentTarget.getAttribute('data-panel');
492
+ }
493
+ select('.slide-menu-toolbar > li.active-toolbar-button').classList.remove(
494
+ 'active-toolbar-button'
495
+ );
496
+ select('li[data-panel="' + panel + '"]').classList.add(
497
+ 'active-toolbar-button'
498
+ );
499
+ select('.slide-menu-panel.active-menu-panel').classList.remove(
500
+ 'active-menu-panel'
501
+ );
502
+ select('div[data-panel="' + panel + '"]').classList.add(
503
+ 'active-menu-panel'
504
+ );
505
+ }
506
+
507
+ function nextPanel() {
508
+ var next =
509
+ (parseInt(select('.active-toolbar-button').getAttribute('data-button')) +
510
+ 1) %
511
+ buttons;
512
+ openPanel(
513
+ null,
514
+ select('.toolbar-panel-button[data-button="' + next + '"]').getAttribute(
515
+ 'data-panel'
516
+ )
517
+ );
518
+ }
519
+
520
+ function prevPanel() {
521
+ var next =
522
+ parseInt(select('.active-toolbar-button').getAttribute('data-button')) -
523
+ 1;
524
+ if (next < 0) {
525
+ next = buttons - 1;
526
+ }
527
+ openPanel(
528
+ null,
529
+ select('.toolbar-panel-button[data-button="' + next + '"]').getAttribute(
530
+ 'data-panel'
531
+ )
532
+ );
533
+ }
534
+
535
+ function openItem(item, force) {
536
+ var h = parseInt(item.getAttribute('data-slide-h'));
537
+ var v = parseInt(item.getAttribute('data-slide-v'));
538
+ var theme = item.getAttribute('data-theme');
539
+ var highlightTheme = item.getAttribute('data-highlight-theme');
540
+ var transition = item.getAttribute('data-transition');
541
+
542
+ if (!isNaN(h) && !isNaN(v)) {
543
+ deck.slide(h, v);
544
+ }
545
+
546
+ if (theme) {
547
+ changeStylesheet('theme', theme);
548
+ }
549
+
550
+ if (highlightTheme) {
551
+ changeStylesheet('highlight-theme', highlightTheme);
552
+ }
553
+
554
+ if (transition) {
555
+ deck.configure({ transition: transition });
556
+ }
557
+
558
+ var link = select('a', item);
559
+ if (link) {
560
+ if (
561
+ force ||
562
+ !options.sticky ||
563
+ (options.autoOpen && link.href.startsWith('#')) ||
564
+ link.href.startsWith(
565
+ window.location.origin + window.location.pathname + '#'
566
+ )
567
+ ) {
568
+ link.click();
569
+ }
570
+ }
571
+
572
+ closeMenu();
573
+ }
574
+
575
+ function clicked(event) {
576
+ if (event.target.nodeName !== 'A') {
577
+ event.preventDefault();
578
+ }
579
+ openItem(event.currentTarget);
580
+ }
581
+
582
+ function highlightCurrentSlide() {
583
+ var state = deck.getState();
584
+ selectAll('li.slide-menu-item, li.slide-menu-item-vertical').forEach(
585
+ function (item) {
586
+ item.classList.remove('past');
587
+ item.classList.remove('active');
588
+ item.classList.remove('future');
589
+
590
+ var h = parseInt(item.getAttribute('data-slide-h'));
591
+ var v = parseInt(item.getAttribute('data-slide-v'));
592
+ if (h < state.indexh || (h === state.indexh && v < state.indexv)) {
593
+ item.classList.add('past');
594
+ } else if (h === state.indexh && v === state.indexv) {
595
+ item.classList.add('active');
596
+ } else {
597
+ item.classList.add('future');
598
+ }
599
+ }
600
+ );
601
+ }
602
+
603
+ function matchRevealStyle() {
604
+ var revealStyle = window.getComputedStyle(select('.reveal'));
605
+ var element = select('.slide-menu');
606
+ element.style.fontFamily = revealStyle.fontFamily;
607
+ //XXX could adjust the complete menu style to match the theme, ie colors, etc
608
+ }
609
+
610
+ var buttons = 0;
611
+ function initMenu() {
612
+ if (!initialised) {
613
+ var parent = select('.reveal').parentElement;
614
+ var top = create('div', { class: 'slide-menu-wrapper' });
615
+ parent.appendChild(top);
616
+ var panels = create('nav', {
617
+ class: 'slide-menu slide-menu--' + options.side
618
+ });
619
+ if (typeof options.width === 'string') {
620
+ if (
621
+ ['normal', 'wide', 'third', 'half', 'full'].indexOf(options.width) !=
622
+ -1
623
+ ) {
624
+ panels.classList.add('slide-menu--' + options.width);
625
+ } else {
626
+ panels.classList.add('slide-menu--custom');
627
+ panels.style.width = options.width;
628
+ }
629
+ }
630
+ top.appendChild(panels);
631
+ matchRevealStyle();
632
+ var overlay = create('div', { class: 'slide-menu-overlay' });
633
+ top.appendChild(overlay);
634
+ overlay.onclick = function () {
635
+ closeMenu(null, true);
636
+ };
637
+
638
+ var toolbar = create('ol', { class: 'slide-menu-toolbar' });
639
+ select('.slide-menu').appendChild(toolbar);
640
+
641
+ function addToolbarButton(title, ref, icon, style, fn, active) {
642
+ var attrs = {
643
+ 'data-button': '' + buttons++,
644
+ class:
645
+ 'toolbar-panel-button' + (active ? ' active-toolbar-button' : '')
646
+ };
647
+ if (ref) {
648
+ attrs['data-panel'] = ref;
649
+ }
650
+ var button = create('li', attrs);
651
+
652
+ if (icon.startsWith('fa-')) {
653
+ button.appendChild(create('i', { class: style + ' ' + icon }));
654
+ } else {
655
+ button.innerHTML = icon + '</i>';
656
+ }
657
+ button.appendChild(create('br'), select('i', button));
658
+ button.appendChild(
659
+ create('span', { class: 'slide-menu-toolbar-label' }, title),
660
+ select('i', button)
661
+ );
662
+ button.onclick = fn;
663
+ toolbar.appendChild(button);
664
+ return button;
665
+ }
666
+
667
+ addToolbarButton('Slides', 'Slides', 'fa-images', 'fas', openPanel, true);
668
+
669
+ if (options.custom) {
670
+ options.custom.forEach(function (element, index, array) {
671
+ addToolbarButton(
672
+ element.title,
673
+ 'Custom' + index,
674
+ element.icon,
675
+ null,
676
+ openPanel
677
+ );
678
+ });
679
+ }
680
+
681
+ if (options.themes) {
682
+ addToolbarButton('Themes', 'Themes', 'fa-adjust', 'fas', openPanel);
683
+ }
684
+ if (options.transitions) {
685
+ addToolbarButton(
686
+ 'Transitions',
687
+ 'Transitions',
688
+ 'fa-sticky-note',
689
+ 'fas',
690
+ openPanel
691
+ );
692
+ }
693
+ var button = create('li', {
694
+ id: 'close',
695
+ class: 'toolbar-panel-button'
696
+ });
697
+ button.appendChild(create('i', { class: 'fas fa-times' }));
698
+ button.appendChild(create('br'));
699
+ button.appendChild(
700
+ create('span', { class: 'slide-menu-toolbar-label' }, 'Close')
701
+ );
702
+ button.onclick = function () {
703
+ closeMenu(null, true);
704
+ };
705
+ toolbar.appendChild(button);
706
+
707
+ //
708
+ // Slide links
709
+ //
710
+ function generateItem(type, section, i, h, v) {
711
+ var link = '/#/' + h;
712
+ if (typeof v === 'number' && !isNaN(v)) link += '/' + v;
713
+
714
+ function text(selector, parent) {
715
+ if (selector === '') return null;
716
+ var el = parent ? select(selector, section) : select(selector);
717
+ if (el) return el.textContent;
718
+ return null;
719
+ }
720
+ var title =
721
+ section.getAttribute('data-menu-title') ||
722
+ text('.menu-title', section) ||
723
+ text(options.titleSelector, section);
724
+
725
+ if (!title && options.useTextContentForMissingTitles) {
726
+ // attempt to figure out a title based on the text in the slide
727
+ title = section.textContent.trim();
728
+ if (title) {
729
+ title =
730
+ title
731
+ .split('\n')
732
+ .map(function (t) {
733
+ return t.trim();
734
+ })
735
+ .join(' ')
736
+ .trim()
737
+ .replace(/^(.{16}[^\s]*).*/, '$1') // limit to 16 chars plus any consecutive non-whitespace chars (to avoid breaking words)
738
+ .replace(/&/g, '&amp;')
739
+ .replace(/</g, '&lt;')
740
+ .replace(/>/g, '&gt;')
741
+ .replace(/"/g, '&quot;')
742
+ .replace(/'/g, '&#039;') + '...';
743
+ }
744
+ }
745
+
746
+ if (!title) {
747
+ if (options.hideMissingTitles) return '';
748
+ type += ' no-title';
749
+ title = 'Slide ' + (i + 1);
750
+ }
751
+
752
+ var item = create('li', {
753
+ class: type,
754
+ 'data-item': i,
755
+ 'data-slide-h': h,
756
+ 'data-slide-v': v === undefined ? 0 : v
757
+ });
758
+
759
+ if (options.markers) {
760
+ item.appendChild(
761
+ create('i', { class: 'fas fa-check-circle fa-fw past' })
762
+ );
763
+ item.appendChild(
764
+ create('i', {
765
+ class: 'fas fa-arrow-alt-circle-right fa-fw active'
766
+ })
767
+ );
768
+ item.appendChild(
769
+ create('i', { class: 'far fa-circle fa-fw future' })
770
+ );
771
+ }
772
+
773
+ if (options.numbers) {
774
+ // Number formatting taken from reveal.js
775
+ var value = [];
776
+ var format = 'h.v';
777
+
778
+ // Check if a custom number format is available
779
+ if (typeof options.numbers === 'string') {
780
+ format = options.numbers;
781
+ } else if (typeof config.slideNumber === 'string') {
782
+ // Take user defined number format for slides
783
+ format = config.slideNumber;
784
+ }
785
+
786
+ switch (format) {
787
+ case 'c':
788
+ value.push(i + 1);
789
+ break;
790
+ case 'c/t':
791
+ value.push(i + 1, '/', deck.getTotalSlides());
792
+ break;
793
+ case 'h/v':
794
+ value.push(h + 1);
795
+ if (typeof v === 'number' && !isNaN(v)) value.push('/', v + 1);
796
+ break;
797
+ default:
798
+ value.push(h + 1);
799
+ if (typeof v === 'number' && !isNaN(v)) value.push('.', v + 1);
800
+ }
801
+
802
+ item.appendChild(
803
+ create(
804
+ 'span',
805
+ { class: 'slide-menu-item-number' },
806
+ value.join('') + '. '
807
+ )
808
+ );
809
+ }
810
+
811
+ item.appendChild(
812
+ create('span', { class: 'slide-menu-item-title' }, title)
813
+ );
814
+
815
+ return item;
816
+ }
817
+
818
+ function createSlideMenu() {
819
+ if (
820
+ !document.querySelector(
821
+ 'section[data-markdown]:not([data-markdown-parsed])'
822
+ )
823
+ ) {
824
+ var panel = create('div', {
825
+ 'data-panel': 'Slides',
826
+ class: 'slide-menu-panel active-menu-panel'
827
+ });
828
+ panel.appendChild(create('ul', { class: 'slide-menu-items' }));
829
+ panels.appendChild(panel);
830
+ var items = select(
831
+ '.slide-menu-panel[data-panel="Slides"] > .slide-menu-items'
832
+ );
833
+ var slideCount = 0;
834
+ selectAll('.slides > section').forEach(function (section, h) {
835
+ var subsections = selectAll('section', section);
836
+ if (subsections.length > 0) {
837
+ subsections.forEach(function (subsection, v) {
838
+ var type =
839
+ v === 0 ? 'slide-menu-item' : 'slide-menu-item-vertical';
840
+ var item = generateItem(type, subsection, slideCount, h, v);
841
+ if (item) {
842
+ items.appendChild(item);
843
+ }
844
+ slideCount++;
845
+ });
846
+ } else {
847
+ var item = generateItem(
848
+ 'slide-menu-item',
849
+ section,
850
+ slideCount,
851
+ h
852
+ );
853
+ if (item) {
854
+ items.appendChild(item);
855
+ }
856
+ slideCount++;
857
+ }
858
+ });
859
+ selectAll('.slide-menu-item, .slide-menu-item-vertical').forEach(
860
+ function (i) {
861
+ i.onclick = clicked;
862
+ }
863
+ );
864
+ highlightCurrentSlide();
865
+ } else {
866
+ // wait for markdown to be loaded and parsed
867
+ setTimeout(createSlideMenu, 100);
868
+ }
869
+ }
870
+
871
+ createSlideMenu();
872
+ deck.addEventListener('slidechanged', highlightCurrentSlide);
873
+
874
+ //
875
+ // Custom menu panels
876
+ //
877
+ if (options.custom) {
878
+ function xhrSuccess() {
879
+ if (this.status >= 200 && this.status < 300) {
880
+ this.panel.innerHTML = this.responseText;
881
+ enableCustomLinks(this.panel);
882
+ } else {
883
+ showErrorMsg(this);
884
+ }
885
+ }
886
+ function xhrError() {
887
+ showErrorMsg(this);
888
+ }
889
+ function loadCustomPanelContent(panel, sURL) {
890
+ var oReq = new XMLHttpRequest();
891
+ oReq.panel = panel;
892
+ oReq.arguments = Array.prototype.slice.call(arguments, 2);
893
+ oReq.onload = xhrSuccess;
894
+ oReq.onerror = xhrError;
895
+ oReq.open('get', sURL, true);
896
+ oReq.send(null);
897
+ }
898
+ function enableCustomLinks(panel) {
899
+ selectAll('ul.slide-menu-items li.slide-menu-item', panel).forEach(
900
+ function (item, i) {
901
+ item.setAttribute('data-item', i + 1);
902
+ item.onclick = clicked;
903
+ item.addEventListener('mouseenter', handleMouseHighlight);
904
+ }
905
+ );
906
+ }
907
+
908
+ function showErrorMsg(response) {
909
+ var msg =
910
+ '<p>ERROR: The attempt to fetch ' +
911
+ response.responseURL +
912
+ ' failed with HTTP status ' +
913
+ response.status +
914
+ ' (' +
915
+ response.statusText +
916
+ ').</p>' +
917
+ '<p>Remember that you need to serve the presentation HTML from a HTTP server.</p>';
918
+ response.panel.innerHTML = msg;
919
+ }
920
+
921
+ options.custom.forEach(function (element, index, array) {
922
+ var panel = create('div', {
923
+ 'data-panel': 'Custom' + index,
924
+ class: 'slide-menu-panel slide-menu-custom-panel'
925
+ });
926
+ if (element.content) {
927
+ panel.innerHTML = element.content;
928
+ enableCustomLinks(panel);
929
+ } else if (element.src) {
930
+ loadCustomPanelContent(panel, element.src);
931
+ }
932
+ panels.appendChild(panel);
933
+ });
934
+ }
935
+
936
+ //
937
+ // Themes
938
+ //
939
+ if (options.themes) {
940
+ var panel = create('div', {
941
+ class: 'slide-menu-panel',
942
+ 'data-panel': 'Themes'
943
+ });
944
+ panels.appendChild(panel);
945
+ var menu = create('ul', { class: 'slide-menu-items' });
946
+ panel.appendChild(menu);
947
+ options.themes.forEach(function (t, i) {
948
+ var attrs = {
949
+ class: 'slide-menu-item',
950
+ 'data-item': '' + (i + 1)
951
+ };
952
+ if (t.theme) {
953
+ attrs['data-theme'] = t.theme;
954
+ }
955
+ if (t.highlightTheme) {
956
+ attrs['data-highlight-theme'] = t.highlightTheme;
957
+ }
958
+ var item = create('li', attrs, t.name);
959
+ menu.appendChild(item);
960
+ item.onclick = clicked;
961
+ });
962
+ }
963
+
964
+ //
965
+ // Transitions
966
+ //
967
+ if (options.transitions) {
968
+ var panel = create('div', {
969
+ class: 'slide-menu-panel',
970
+ 'data-panel': 'Transitions'
971
+ });
972
+ panels.appendChild(panel);
973
+ var menu = create('ul', { class: 'slide-menu-items' });
974
+ panel.appendChild(menu);
975
+ options.transitions.forEach(function (name, i) {
976
+ var item = create(
977
+ 'li',
978
+ {
979
+ class: 'slide-menu-item',
980
+ 'data-transition': name.toLowerCase(),
981
+ 'data-item': '' + (i + 1)
982
+ },
983
+ name
984
+ );
985
+ menu.appendChild(item);
986
+ item.onclick = clicked;
987
+ });
988
+ }
989
+
990
+ //
991
+ // Open menu options
992
+ //
993
+ if (options.openButton) {
994
+ // add menu button
995
+ var div = create('div', { class: 'slide-menu-button' });
996
+ var link = create('a', { href: '#' });
997
+ link.appendChild(create('i', { class: 'fas fa-bars' }));
998
+ div.appendChild(link);
999
+ select('.reveal').appendChild(div);
1000
+ div.onclick = openMenu;
1001
+ }
1002
+
1003
+ if (options.openSlideNumber) {
1004
+ var slideNumber = select('div.slide-number');
1005
+ slideNumber.onclick = openMenu;
1006
+ }
1007
+
1008
+ //
1009
+ // Handle mouse overs
1010
+ //
1011
+ selectAll('.slide-menu-panel .slide-menu-items li').forEach(function (
1012
+ item
1013
+ ) {
1014
+ item.addEventListener('mouseenter', handleMouseHighlight);
1015
+ });
1016
+
1017
+ function handleMouseHighlight(event) {
1018
+ if (mouseSelectionEnabled) {
1019
+ selectAll('.active-menu-panel .slide-menu-items li.selected').forEach(
1020
+ function (i) {
1021
+ i.classList.remove('selected');
1022
+ }
1023
+ );
1024
+ event.currentTarget.classList.add('selected');
1025
+ }
1026
+ }
1027
+ }
1028
+
1029
+ if (options.keyboard) {
1030
+ //XXX add keyboard option for custom key codes, etc.
1031
+
1032
+ document.addEventListener('keydown', onDocumentKeyDown, false);
1033
+
1034
+ // handle key presses within speaker notes
1035
+ window.addEventListener('message', function (event) {
1036
+ var data;
1037
+ try {
1038
+ data = JSON.parse(event.data);
1039
+ } catch (e) {}
1040
+ if (data && data.method === 'triggerKey') {
1041
+ onDocumentKeyDown({
1042
+ keyCode: data.args[0],
1043
+ stopImmediatePropagation: function () {}
1044
+ });
1045
+ }
1046
+ });
1047
+
1048
+ // Prevent reveal from processing keyboard events when the menu is open
1049
+ if (
1050
+ config.keyboardCondition &&
1051
+ typeof config.keyboardCondition === 'function'
1052
+ ) {
1053
+ // combine user defined keyboard condition with the menu's own condition
1054
+ var userCondition = config.keyboardCondition;
1055
+ config.keyboardCondition = function (event) {
1056
+ return userCondition(event) && (!isOpen() || event.keyCode == 77);
1057
+ };
1058
+ } else {
1059
+ config.keyboardCondition = function (event) {
1060
+ return !isOpen() || event.keyCode == 77;
1061
+ };
1062
+ }
1063
+
1064
+ deck.addKeyBinding(
1065
+ { keyCode: 77, key: 'M', description: 'Toggle menu' },
1066
+ toggleMenu
1067
+ );
1068
+ }
1069
+
1070
+ if (options.openOnInit) {
1071
+ openMenu();
1072
+ }
1073
+
1074
+ initialised = true;
1075
+ }
1076
+
1077
+ /**
1078
+ * Extend object a with the properties of object b.
1079
+ * If there's a conflict, object b takes precedence.
1080
+ */
1081
+ function extend(a, b) {
1082
+ for (var i in b) {
1083
+ a[i] = b[i];
1084
+ }
1085
+ }
1086
+
1087
+ /**
1088
+ * Dispatches an event of the specified type from the
1089
+ * reveal DOM element.
1090
+ */
1091
+ function dispatchEvent(type, args) {
1092
+ var event = document.createEvent('HTMLEvents', 1, 2);
1093
+ event.initEvent(type, true, true);
1094
+ extend(event, args);
1095
+ document.querySelector('.reveal').dispatchEvent(event);
1096
+
1097
+ // If we're in an iframe, post each reveal.js event to the
1098
+ // parent window. Used by the notes plugin
1099
+ if (config.postMessageEvents && window.parent !== window.self) {
1100
+ window.parent.postMessage(
1101
+ JSON.stringify({
1102
+ namespace: 'reveal',
1103
+ eventName: type,
1104
+ state: deck.getState()
1105
+ }),
1106
+ '*'
1107
+ );
1108
+ }
1109
+ }
1110
+
1111
+ function select(selector, el) {
1112
+ if (!el) {
1113
+ el = document;
1114
+ }
1115
+ return el.querySelector(selector);
1116
+ }
1117
+
1118
+ function selectAll(selector, el) {
1119
+ if (!el) {
1120
+ el = document;
1121
+ }
1122
+ return Array.prototype.slice.call(el.querySelectorAll(selector));
1123
+ }
1124
+
1125
+ function create(tagName, attrs, content) {
1126
+ var el = document.createElement(tagName);
1127
+ if (attrs) {
1128
+ Object.getOwnPropertyNames(attrs).forEach(function (n) {
1129
+ el.setAttribute(n, attrs[n]);
1130
+ });
1131
+ }
1132
+ if (content) el.innerHTML = content;
1133
+ return el;
1134
+ }
1135
+
1136
+ function changeStylesheet(id, href) {
1137
+ // take note of the previous theme and remove it, then create a new stylesheet reference and insert it
1138
+ // this is required to force a load event so we can change the menu style to match the new style
1139
+ var stylesheet = select('link#' + id);
1140
+ var parent = stylesheet.parentElement;
1141
+ var sibling = stylesheet.nextElementSibling;
1142
+ stylesheet.remove();
1143
+
1144
+ var newStylesheet = stylesheet.cloneNode();
1145
+ newStylesheet.setAttribute('href', href);
1146
+ newStylesheet.onload = function () {
1147
+ matchRevealStyle();
1148
+ };
1149
+ parent.insertBefore(newStylesheet, sibling);
1150
+ }
1151
+
1152
+ // modified from math plugin
1153
+ function loadResource(url, type, callback) {
1154
+ var head = document.querySelector('head');
1155
+ var resource;
1156
+
1157
+ if (type === 'script') {
1158
+ resource = document.createElement('script');
1159
+ resource.type = 'text/javascript';
1160
+ resource.src = url;
1161
+ } else if (type === 'stylesheet') {
1162
+ resource = document.createElement('link');
1163
+ resource.rel = 'stylesheet';
1164
+ resource.href = url;
1165
+ }
1166
+
1167
+ // Wrapper for callback to make sure it only fires once
1168
+ var finish = function () {
1169
+ if (typeof callback === 'function') {
1170
+ callback.call();
1171
+ callback = null;
1172
+ }
1173
+ };
1174
+
1175
+ resource.onload = finish;
1176
+
1177
+ // IE
1178
+ resource.onreadystatechange = function () {
1179
+ if (this.readyState === 'loaded') {
1180
+ finish();
1181
+ }
1182
+ };
1183
+
1184
+ // Normal browsers
1185
+ head.appendChild(resource);
1186
+ }
1187
+
1188
+ function loadPlugin() {
1189
+ // does not support IE8 or below
1190
+ var supported = !ieVersion || ieVersion >= 9;
1191
+
1192
+ // do not load the menu in the upcoming slide panel in the speaker notes
1193
+ if (
1194
+ deck.isSpeakerNotes() &&
1195
+ window.location.search.endsWith('controls=false')
1196
+ ) {
1197
+ supported = false;
1198
+ }
1199
+
1200
+ if (supported) {
1201
+ if (!options.delayInit) initMenu();
1202
+ dispatchEvent('menu-ready');
1203
+ }
1204
+ }
1205
+
1206
+ return {
1207
+ id: 'menu',
1208
+ init: reveal => {
1209
+ deck = reveal;
1210
+ config = deck.getConfig();
1211
+ initOptions(config);
1212
+ loadResource(options.path + 'menu.css', 'stylesheet', function () {
1213
+ if (options.loadIcons === undefined || options.loadIcons) {
1214
+ loadResource(
1215
+ options.path + 'font-awesome/css/all.css',
1216
+ 'stylesheet',
1217
+ loadPlugin
1218
+ );
1219
+ } else {
1220
+ loadPlugin();
1221
+ }
1222
+ });
1223
+ },
1224
+
1225
+ toggle: toggleMenu,
1226
+ openMenu: openMenu,
1227
+ closeMenu: closeMenu,
1228
+ openPanel: openPanel,
1229
+ isOpen: isOpen,
1230
+ initialiseMenu: initMenu,
1231
+ isMenuInitialised: function () {
1232
+ return initialised;
1233
+ }
1234
+ };
1235
+ };
1236
+
1237
+ // polyfill
1238
+ if (!String.prototype.startsWith) {
1239
+ String.prototype.startsWith = function (searchString, position) {
1240
+ return this.substr(position || 0, searchString.length) === searchString;
1241
+ };
1242
+ }
1243
+ if (!String.prototype.endsWith) {
1244
+ String.prototype.endsWith = function (search, this_len) {
1245
+ if (this_len === undefined || this_len > this.length) {
1246
+ this_len = this.length;
1247
+ }
1248
+ return this.substring(this_len - search.length, this_len) === search;
1249
+ };
1250
+ }
1251
+
1252
+ export default Plugin;