asciidoctor-revealjs 4.1.0 → 5.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +11 -1350
  3. data/asciidoctor-revealjs.gemspec +0 -2
  4. data/examples/auto-animate-code.adoc +47 -0
  5. data/examples/auto-animate.adoc +351 -0
  6. data/examples/favicon.adoc +13 -0
  7. data/examples/mathjax-cdn.adoc +1 -1
  8. data/examples/mathjax.adoc +1 -1
  9. data/examples/revealjs-custom-theme.adoc +1 -1
  10. data/examples/revealjs-plugin-activation.adoc +3 -2
  11. data/examples/revealjs-plugins/chalkboard/README.md +94 -61
  12. data/examples/revealjs-plugins/chalkboard/img/boardmarker-black.png +0 -0
  13. data/examples/revealjs-plugins/chalkboard/img/boardmarker-blue.png +0 -0
  14. data/examples/revealjs-plugins/chalkboard/img/boardmarker-green.png +0 -0
  15. data/examples/revealjs-plugins/chalkboard/img/boardmarker-orange.png +0 -0
  16. data/examples/revealjs-plugins/chalkboard/img/boardmarker-purple.png +0 -0
  17. data/examples/revealjs-plugins/chalkboard/img/boardmarker-red.png +0 -0
  18. data/examples/revealjs-plugins/chalkboard/img/boardmarker-yellow.png +0 -0
  19. data/examples/revealjs-plugins/chalkboard/img/chalk-blue.png +0 -0
  20. data/examples/revealjs-plugins/chalkboard/img/chalk-green.png +0 -0
  21. data/examples/revealjs-plugins/chalkboard/img/chalk-orange.png +0 -0
  22. data/examples/revealjs-plugins/chalkboard/img/chalk-purple.png +0 -0
  23. data/examples/revealjs-plugins/chalkboard/img/chalk-red.png +0 -0
  24. data/examples/revealjs-plugins/chalkboard/img/{chalk.png → chalk-white.png} +0 -0
  25. data/examples/revealjs-plugins/chalkboard/img/chalk-yellow.png +0 -0
  26. data/examples/revealjs-plugins/chalkboard/plugin.js +1836 -0
  27. data/examples/revealjs-plugins/chalkboard/style.css +38 -0
  28. data/examples/revealjs-plugins/{reveal.js-menu → menu}/LICENSE +1 -1
  29. data/examples/revealjs-plugins/menu/README.md +368 -0
  30. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/LICENSE.txt +0 -0
  31. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/all.css +0 -0
  32. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/brands.css +0 -0
  33. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/fontawesome.css +0 -0
  34. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/regular.css +0 -0
  35. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/solid.css +0 -0
  36. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/svg-with-js.css +0 -0
  37. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/v4-shims.css +0 -0
  38. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/v4-shims.min.css +0 -0
  39. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-brands-400.eot +0 -0
  40. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-brands-400.svg +0 -0
  41. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-brands-400.ttf +0 -0
  42. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-brands-400.woff +0 -0
  43. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-brands-400.woff2 +0 -0
  44. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-regular-400.eot +0 -0
  45. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-regular-400.svg +0 -0
  46. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-regular-400.ttf +0 -0
  47. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-regular-400.woff +0 -0
  48. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-regular-400.woff2 +0 -0
  49. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-solid-900.eot +0 -0
  50. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-solid-900.svg +0 -0
  51. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-solid-900.ttf +0 -0
  52. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-solid-900.woff +0 -0
  53. data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-solid-900.woff2 +0 -0
  54. data/examples/revealjs-plugins/{reveal.js-menu → menu}/menu.css +116 -115
  55. data/examples/revealjs-plugins/menu/menu.esm.js +1 -0
  56. data/examples/revealjs-plugins/menu/menu.js +1 -0
  57. data/examples/revealjs-plugins/menu/plugin.js +1252 -0
  58. data/examples/revealjs-plugins-docinfo-footer.html +20 -0
  59. data/examples/revealjs-plugins.adoc +2 -3
  60. data/examples/search-plugin.adoc +26 -0
  61. data/examples/source-rouge.adoc +1 -1
  62. data/examples/text-formatting.adoc +34 -0
  63. data/lib/asciidoctor-revealjs/converter.rb +1029 -966
  64. data/lib/asciidoctor-revealjs/highlightjs.rb +155 -14
  65. data/lib/asciidoctor-revealjs/version.rb +1 -1
  66. data/templates/asciidoctor-compatibility.css +26 -1
  67. data/templates/document.html.slim +28 -44
  68. data/templates/helpers.rb +83 -9
  69. data/templates/inline_quoted.html.slim +2 -2
  70. data/templates/listing.html.slim +2 -1
  71. data/templates/section.html.slim +7 -1
  72. data/templates/title_slide.html.slim +1 -2
  73. metadata +57 -69
  74. data/examples/revealjs-plugins/chalkboard/chalkboard.js +0 -1288
  75. data/examples/revealjs-plugins/chalkboard/img/boardmarker.png +0 -0
  76. data/examples/revealjs-plugins/reveal.js-menu/CONTRIBUTING.md +0 -9
  77. data/examples/revealjs-plugins/reveal.js-menu/README.md +0 -334
  78. data/examples/revealjs-plugins/reveal.js-menu/bower.json +0 -21
  79. data/examples/revealjs-plugins/reveal.js-menu/menu.js +0 -949
  80. data/examples/revealjs-plugins/reveal.js-menu/package.json +0 -22
  81. data/examples/revealjs-plugins-conf.js +0 -10
  82. data/examples/revealjs-plugins.js +0 -2
@@ -1,9 +0,0 @@
1
- ## Contributing
2
-
3
- ### Bug Reports
4
- When reporting a bug make sure to include information about which browser and operating system you are on as well as the necessary steps to reproduce the issue. If possible please include a link to a sample presentation where the bug can be tested.
5
-
6
- ### Pull Requests
7
- - Should follow the coding style of the file you work in
8
- - Should be made towards the **dev branch**
9
- - Should be submitted from a feature/topic branch (not your master)
@@ -1,334 +0,0 @@
1
- # reveal.js-menu
2
-
3
- A slideout menu plugin for [Reveal.js](https://github.com/hakimel/reveal.js) to quickly jump to any slide by title. Also optionally change the theme and set the default transition. [Check out the live demo](https://denehyg.github.io/reveal.js-menu)
4
-
5
- ## Installation
6
-
7
- ### Bower
8
-
9
- Download and install the package in your project:
10
-
11
- ```bower install reveal.js-menu```
12
-
13
- Add the plugin to the dependencies in your presentation, as below.
14
-
15
- ```javascript
16
- Reveal.initialize({
17
- // ...
18
-
19
- dependencies: [
20
- // ...
21
-
22
- { src: 'bower_components/reveal.js-menu/menu.js' }
23
- ]
24
- });
25
- ```
26
-
27
- ### npm
28
-
29
- Download and install the package in your project:
30
-
31
- ```npm install --save reveal.js-menu```
32
-
33
- Add the plugin to the dependencies in your presentation, as below.
34
-
35
- ```javascript
36
- Reveal.initialize({
37
- // ...
38
-
39
- dependencies: [
40
- // ...
41
-
42
- { src: 'node_modules/reveal.js-menu/menu.js' }
43
- ]
44
- });
45
- ```
46
-
47
- ### Manual
48
-
49
- Copy this repository into the plugins folder of your reveal.js presentation, ie ```plugins/menu```.
50
-
51
- Add the plugin to the dependencies in your presentation, as below.
52
-
53
- ```javascript
54
- Reveal.initialize({
55
- // ...
56
-
57
- dependencies: [
58
- // ...
59
-
60
- { src: 'plugin/menu/menu.js' }
61
- ]
62
- });
63
- ```
64
-
65
- ## Configuration
66
-
67
- You can configure the menu for your presentation by providing a ```menu``` option in the reveal.js initialization options. Note that all config values are optional and will default as specified below.
68
-
69
- ```javascript
70
- Reveal.initialize({
71
- // ...
72
-
73
- menu: {
74
- // Specifies which side of the presentation the menu will
75
- // be shown. Use 'left' or 'right'.
76
- side: 'left',
77
-
78
- // Specifies the width of the menu.
79
- // Can be one of the following:
80
- // 'normal', 'wide', 'third', 'half', 'full', or
81
- // any valid css length value
82
- width: 'normal',
83
-
84
- // Add slide numbers to the titles in the slide list.
85
- // Use 'true' or format string (same as reveal.js slide numbers)
86
- numbers: false,
87
-
88
- // Specifies which slide elements will be used for generating
89
- // the slide titles in the menu. The default selects the first
90
- // heading element found in the slide, but you can specify any
91
- // valid css selector and the text from the first matching
92
- // element will be used.
93
- // Note: that a section data-menu-title attribute or an element
94
- // with a menu-title class will take precedence over this option
95
- titleSelector: 'h1, h2, h3, h4, h5, h6',
96
-
97
- // If slides do not have a matching title, attempt to use the
98
- // start of the text content as the title instead
99
- useTextContentForMissingTitles: false,
100
-
101
- // Hide slides from the menu that do not have a title.
102
- // Set to 'true' to only list slides with titles.
103
- hideMissingTitles: false,
104
-
105
- // Adds markers to the slide titles to indicate the
106
- // progress through the presentation. Set to 'false'
107
- // to hide the markers.
108
- markers: true,
109
-
110
- // Specify custom panels to be included in the menu, by
111
- // providing an array of objects with 'title', 'icon'
112
- // properties, and either a 'src' or 'content' property.
113
- custom: false,
114
-
115
- // Specifies the themes that will be available in the themes
116
- // menu panel. Set to 'true' to show the themes menu panel
117
- // with the default themes list. Alternatively, provide an
118
- // array to specify the themes to make available in the
119
- // themes menu panel, for example...
120
- // [
121
- // { name: 'Black', theme: 'css/theme/black.css' },
122
- // { name: 'White', theme: 'css/theme/white.css' },
123
- // { name: 'League', theme: 'css/theme/league.css' }
124
- // ]
125
- themes: false,
126
-
127
- // Specifies the path to the default theme files. If your
128
- // presentation uses a different path to the standard reveal
129
- // layout then you need to provide this option, but only
130
- // when 'themes' is set to 'true'. If you provide your own
131
- // list of themes or 'themes' is set to 'false' the
132
- // 'themesPath' option is ignored.
133
- themesPath: 'css/theme/',
134
-
135
- // Specifies if the transitions menu panel will be shown.
136
- // Set to 'true' to show the transitions menu panel with
137
- // the default transitions list. Alternatively, provide an
138
- // array to specify the transitions to make available in
139
- // the transitions panel, for example...
140
- // ['None', 'Fade', 'Slide']
141
- transitions: false,
142
-
143
- // Adds a menu button to the slides to open the menu panel.
144
- // Set to 'false' to hide the button.
145
- openButton: true,
146
-
147
- // If 'true' allows the slide number in the presentation to
148
- // open the menu panel. The reveal.js slideNumber option must
149
- // be displayed for this to take effect
150
- openSlideNumber: false,
151
-
152
- // If true allows the user to open and navigate the menu using
153
- // the keyboard. Standard keyboard interaction with reveal
154
- // will be disabled while the menu is open.
155
- keyboard: true,
156
-
157
- // Normally the menu will close on user actions such as
158
- // selecting a menu item, or clicking the presentation area.
159
- // If 'true', the sticky option will leave the menu open
160
- // until it is explicitly closed, that is, using the close
161
- // button or pressing the ESC or m key (when the keyboard
162
- // interaction option is enabled).
163
- sticky: false,
164
-
165
- // If 'true' standard menu items will be automatically opened
166
- // when navigating using the keyboard. Note: this only takes
167
- // effect when both the 'keyboard' and 'sticky' options are enabled.
168
- autoOpen: true,
169
-
170
- // If 'true' the menu will not be created until it is explicitly
171
- // requested by calling RevealMenu.init(). Note this will delay
172
- // the creation of all menu panels, including custom panels, and
173
- // the menu button.
174
- delayInit: false,
175
-
176
- // If 'true' the menu will be shown when the menu is initialised.
177
- openOnInit: false,
178
-
179
- // By default the menu will load it's own font-awesome library
180
- // icons. If your presentation needs to load a different
181
- // font-awesome library the 'loadIcons' option can be set to false
182
- // and the menu will not attempt to load the font-awesome library.
183
- loadIcons: true
184
- },
185
-
186
- });
187
- ```
188
-
189
- ### Themes Stylesheet
190
-
191
- If you are using the themes panel you need to ensure the theme stylesheet in the presentation uses the ```id="theme"``` attribute. For example...
192
- ```html
193
- <link rel="stylesheet" href="css/theme/black.css" id="theme">
194
- ```
195
-
196
- ## Slide Titles
197
-
198
- The slide titles used in the menu can be supplied explicitly or are taken directly from the presentation, using the following rules...
199
-
200
- ###### 1. The section's ```data-menu-title``` attribute.
201
- If the slide's section element contains a ```data-menu-title``` attribute this will be used for the slide title in the menu. For example...
202
-
203
- ```html
204
- <section data-menu-title="Custom Menu Title">
205
- <h1>Title</h1>
206
- <p>...</p>
207
- </section>
208
- ```
209
-
210
- ###### 2. Any element with the class ```menu-title```.
211
- If the slide's section contains an element with the class ```menu-title``` then the element's text will be used for the title. The first such element found will be used if there are more than one. Note the element need not be displayed to be used. For example...
212
-
213
- ```html
214
- <section>
215
- <h1>Title</h1>
216
- <span class="menu-title" style="display: none">Custom Menu Title</span>
217
- <p>...</p>
218
- </section>
219
- ```
220
-
221
- ###### 3. The first heading found or a custom element selector
222
- The ```titleSelector``` option can be used to customise the elements that will be used to generate the slide titles in the menu. The default option selects the first heading element found in the slide. For example...
223
-
224
- ```html
225
- <section>
226
- <h3>This will be the slide title in the menu</h3>
227
- <h1>Title</h1>
228
- <p>...</p>
229
- </section>
230
- ```
231
-
232
- Any valid CSS selector should work but note the selector will only be applied to elements contained within the slide section. You could use the ```'h1'``` selector to only use level 1 headings or ```'p'``` to use the first paragraph element. For example, ```titleSelector: 'p.lead'``` would be used like this...
233
-
234
- ```html
235
- <section>
236
- <h1>Title</h1>
237
- <p class="lead">This will be the slide title in the menu</p>
238
- <p>...</p>
239
- </section>
240
- ```
241
-
242
- Using ```titleSelector: ''``` will ignore all elements and no title will be provided, unless the slide section contains a ```data-menu-title``` attribute or an element with the ```menu-title``` class.
243
-
244
- ###### 4. No title is provided
245
- If no title can be found using the above methods, a default title incorporating the slide number will be used. For example, the following would result in a slide title in the format of 'Slide 12'...
246
-
247
- ```html
248
- <section>
249
- <p>...</p>
250
- </section>
251
- ```
252
-
253
- If the ```hideMissingTitles``` option is set to ```true```, however, the slide will not be listed in the menu.
254
-
255
-
256
- ## Custom Menu Panels
257
-
258
- Additional custom panels can be added the menu using the ```custom``` option.
259
-
260
- ```javascript
261
- Reveal.initialize({
262
- // ...
263
-
264
- menu: {
265
- // ...
266
-
267
- custom: [
268
- { title: 'Links', icon: '<i class="fa fa-external-link">', src: 'links.html' },
269
- { title: 'About', icon: '<i class="fa fa-info">', content: '<p>This slidedeck is created with reveal.js</p>' }
270
- ]
271
- }
272
- });
273
- ```
274
-
275
- ```title``` and ```icon``` are used for the toolbar buttons at the top of the menu. There are two approaches you can use to provide content for the panels...
276
-
277
- * You can provide a URL in ```src``` to load html from another file.
278
- * Alternatively, you can provide html in ```content``` and this will be added to the custom panel.
279
-
280
- ###### Custom slide menu items
281
-
282
- You can provide menu items in your custom panels using the following format. This allows you to define your own navigation links for your presentation.
283
-
284
- ```html
285
- <h1>Links</h1>
286
- <ul class="slide-menu-items">
287
- <li class="slide-menu-item"><a href="#/transitions">Transitions</a></li>
288
- <li class="slide-menu-item"><a href="#/13">Code highlighting</a></li>
289
- </ul>
290
- ```
291
-
292
- You are not limited to linking to presentation slides. You can provide any link you wish.
293
-
294
- ```html
295
- <h1>External Links</h1>
296
- <ul class="slide-menu-items">
297
- <li class="slide-menu-item"><a href="https://github.com/denehyg/reveal.js-menu">Reveal.js-menu</a></li>
298
- <li class="slide-menu-item"><a href="https://github.com/hakimel/reveal.js">Reveal.js</a></li>
299
- </ul>
300
- ```
301
-
302
- Using menu items enables keyboard navigation of your links as with the other panels. However, you don't have to use menu items for your links. You can simply provide standard links and unordered lists in your html. Notice you can provide your custom menu items mixed with other html if you wish.
303
-
304
-
305
- ## Ready Event
306
-
307
- A 'menu-ready' event is fired when reveal.js-menu has loaded all non-async dependencies and is ready to start navigating.
308
-
309
- ```javascript
310
- Reveal.addEventListener( 'menu-ready', function( event ) {
311
- // your code
312
- } );
313
- ```
314
-
315
- ## API
316
-
317
- The `RevealMenu` object exposes a JavaScript API for controlling the menu:
318
-
319
- | Function | Description |
320
- |--------------------------|---------------|
321
- | toggle(event) | Toggles the open state of the menu, ie open if it is closed, and close if it is open |
322
- | openMenu(event) | Opens the menu |
323
- | closeMenu(event, force) | Closes the menu. To force the menu to close (ie when `sticky` option is `true`) call `closeMenu(null, true)` |
324
- | openPanel(event, ref) | Opens the menu to a specific panel, passing the name of the panel or the panel element itself |
325
- | isOpen() | Returns true if the menu is open |
326
- | init() | Initialises the menu if it has not already been initialised. Used in conjunction with the `delayInit` option |
327
- | isInit() | Returns true if the menu has been initialised |
328
-
329
-
330
- ## License
331
-
332
- MIT licensed
333
-
334
- Copyright (C) 2015 Greg Denehy
@@ -1,21 +0,0 @@
1
- {
2
- "name": "reveal.js-menu",
3
- "version": "1.1.3",
4
- "homepage": "https://denehyg.github.io/reveal.js-menu",
5
- "authors": [
6
- "Greg Denehy"
7
- ],
8
- "description": "A slideout menu for navigating reveal.js presentations",
9
- "keywords": [
10
- "reveal",
11
- "menu"
12
- ],
13
- "license": "MIT, Copyright (C) 2016 Greg Denehy",
14
- "ignore": [
15
- "**/.*",
16
- "node_modules",
17
- "bower_components",
18
- "test",
19
- "tests"
20
- ]
21
- }
@@ -1,949 +0,0 @@
1
- /*
2
- * Reveal.js menu plugin
3
- * MIT licensed
4
- * (c) Greg Denehy 2015
5
- */
6
-
7
- var RevealMenu = window.RevealMenu || (function(){
8
- var config = Reveal.getConfig();
9
- var options = config.menu || {};
10
- options.path = options.path || scriptPath() || 'plugin/menu/';
11
- if (!options.path.endsWith('/')) {
12
- options.path += '/';
13
- }
14
- var loadIcons = options.loadIcons;
15
- if (typeof loadIcons === "undefined") loadIcons = true;
16
- var initialised = false;
17
-
18
- var module = {};
19
-
20
- loadResource(options.path + 'menu.css', 'stylesheet', function() {
21
- if (loadIcons) {
22
- loadResource(options.path + 'font-awesome/css/all.css', 'stylesheet', loadPlugin)
23
- } else {
24
- loadPlugin();
25
- }
26
- })
27
-
28
- function loadPlugin() {
29
- // does not support IE8 or below
30
- var initialise = !ieVersion || ieVersion >= 9;
31
-
32
- // do not load the menu in the upcoming slide panel in the speaker notes
33
- if (Reveal.isSpeakerNotes() && window.location.search.endsWith('controls=false')) {
34
- initialise = false;
35
- }
36
-
37
- if (initialise) {
38
- //
39
- // Set option defaults
40
- //
41
- var side = options.side || 'left'; // 'left' or 'right'
42
- var width = options.width;
43
- var numbers = options.numbers || false;
44
- var titleSelector = 'h1, h2, h3, h4, h5';
45
- if (typeof options.titleSelector === 'string') titleSelector = options.titleSelector;
46
- var hideMissingTitles = options.hideMissingTitles || false;
47
- var useTextContentForMissingTitles = options.useTextContentForMissingTitles || false;
48
- var markers = options.markers;
49
- if (typeof markers === "undefined") markers = true;
50
- var custom = options.custom;
51
- var themesPath = typeof options.themesPath === 'string' ? options.themesPath : 'css/theme/';
52
- if (!themesPath.endsWith('/')) themesPath += '/';
53
- var themes = select('link#theme') ? options.themes : false;
54
- if (themes === true) {
55
- themes = [
56
- { name: 'Black', theme: themesPath + 'black.css' },
57
- { name: 'White', theme: themesPath + 'white.css' },
58
- { name: 'League', theme: themesPath + 'league.css' },
59
- { name: 'Sky', theme: themesPath + 'sky.css' },
60
- { name: 'Beige', theme: themesPath + 'beige.css' },
61
- { name: 'Simple', theme: themesPath + 'simple.css' },
62
- { name: 'Serif', theme: themesPath + 'serif.css' },
63
- { name: 'Blood', theme: themesPath + 'blood.css' },
64
- { name: 'Night', theme: themesPath + 'night.css' },
65
- { name: 'Moon', theme: themesPath + 'moon.css' },
66
- { name: 'Solarized', theme: themesPath + 'solarized.css' }
67
- ];
68
- } else if (!Array.isArray(themes)) {
69
- themes = false;
70
- }
71
- var transitions = options.transitions || false;
72
- if (transitions === true) {
73
- transitions = ['None', 'Fade', 'Slide', 'Convex', 'Concave', 'Zoom'];
74
- } else if (transitions !== false && (!Array.isArray(transitions) || !transitions.every(function(e) { return typeof e === "string" }))) {
75
- console.error("reveal.js-menu error: transitions config value must be 'true' or an array of strings, eg ['None', 'Fade', 'Slide')");
76
- transitions = false;
77
- }
78
- if (ieVersion && ieVersion <= 9) {
79
- // transitions aren't support in IE9 anyway, so no point in showing them
80
- transitions = false;
81
- }
82
- var openButton = options.openButton;
83
- if (typeof openButton === "undefined") openButton = true;
84
- var openSlideNumber = options.openSlideNumber;
85
- if (typeof openSlideNumber === "undefined") openSlideNumber = false;
86
- var keyboard = options.keyboard;
87
- if (typeof keyboard === "undefined") keyboard = true;
88
- var sticky = options.sticky;
89
- if (typeof sticky === "undefined") sticky = false;
90
- var autoOpen = options.autoOpen;
91
- if (typeof autoOpen === "undefined") autoOpen = true;
92
- var delayInit = options.delayInit;
93
- if (typeof delayInit === "undefined") delayInit = false;
94
- var openOnInit = options.openOnInit || false;
95
-
96
- var mouseSelectionEnabled = true;
97
- function disableMouseSelection() {
98
- mouseSelectionEnabled = false;
99
- }
100
-
101
- function reenableMouseSelection() {
102
- // wait until the mouse has moved before re-enabling mouse selection
103
- // to avoid selections on scroll
104
- select('nav.slide-menu').addEventListener('mousemove', function fn(e) {
105
- select('nav.slide-menu').removeEventListener('mousemove', fn);
106
- //XXX this should select the item under the mouse
107
- mouseSelectionEnabled = true;
108
- });
109
- }
110
-
111
- //
112
- // Keyboard handling
113
- //
114
- function getOffset(el) {
115
- var _x = 0;
116
- var _y = 0;
117
- while(el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) {
118
- _x += el.offsetLeft - el.scrollLeft;
119
- _y += el.offsetTop - el.scrollTop;
120
- el = el.offsetParent;
121
- }
122
- return { top: _y, left: _x };
123
- }
124
-
125
- function visibleOffset(el) {
126
- var offsetFromTop = getOffset(el).top - el.offsetParent.offsetTop;
127
- if (offsetFromTop < 0) return -offsetFromTop
128
- var offsetFromBottom = el.offsetParent.offsetHeight - (el.offsetTop - el.offsetParent.scrollTop + el.offsetHeight);
129
- if (offsetFromBottom < 0) return offsetFromBottom;
130
- return 0;
131
- }
132
-
133
- function keepVisible(el) {
134
- var offset = visibleOffset(el);
135
- if (offset) {
136
- disableMouseSelection();
137
- el.scrollIntoView(offset > 0);
138
- reenableMouseSelection();
139
- }
140
- }
141
-
142
- function scrollItemToTop(el) {
143
- disableMouseSelection();
144
- el.offsetParent.scrollTop = el.offsetTop;
145
- reenableMouseSelection();
146
- }
147
-
148
- function scrollItemToBottom(el) {
149
- disableMouseSelection();
150
- el.offsetParent.scrollTop = el.offsetTop - el.offsetParent.offsetHeight + el.offsetHeight
151
- reenableMouseSelection();
152
- }
153
-
154
- function selectItem(el) {
155
- el.classList.add('selected');
156
- keepVisible(el);
157
- if (sticky && autoOpen) openItem(el);
158
- }
159
-
160
- function onDocumentKeyDown(event) {
161
- if (event.keyCode === 77) {
162
- toggleMenu();
163
- } else if (isOpen()) {
164
- event.stopImmediatePropagation();
165
- switch( event.keyCode ) {
166
- // h, left - change panel
167
- case 72: case 37:
168
- prevPanel();
169
- break;
170
- // l, right - change panel
171
- case 76: case 39:
172
- nextPanel();
173
- break;
174
- // k, up
175
- case 75: case 38:
176
- var currItem = select('.active-menu-panel .slide-menu-items li.selected') || select('.active-menu-panel .slide-menu-items li.active');
177
- if (currItem) {
178
- selectAll('.active-menu-panel .slide-menu-items li').forEach(function(item) { item.classList.remove('selected') });
179
- var nextItem = select('.active-menu-panel .slide-menu-items li[data-item="' + (parseInt(currItem.getAttribute('data-item')) - 1) + '"]') || currItem;
180
- selectItem(nextItem);
181
- } else {
182
- var item = select('.active-menu-panel .slide-menu-items li.slide-menu-item');
183
- if (item) selectItem(item);
184
- }
185
- break;
186
- // j, down
187
- case 74: case 40:
188
- var currItem = select('.active-menu-panel .slide-menu-items li.selected') || select('.active-menu-panel .slide-menu-items li.active');
189
- if (currItem) {
190
- selectAll('.active-menu-panel .slide-menu-items li').forEach(function(item) { item.classList.remove('selected') });
191
- var nextItem = select('.active-menu-panel .slide-menu-items li[data-item="' + (parseInt(currItem.getAttribute('data-item')) + 1) + '"]') || currItem;
192
- selectItem(nextItem);
193
- } else {
194
- var item = select('.active-menu-panel .slide-menu-items li.slide-menu-item');
195
- if (item) selectItem(item);
196
- }
197
- break;
198
- // pageup, u
199
- case 33: case 85:
200
- var itemsAbove = selectAll('.active-menu-panel .slide-menu-items li').filter(function(item) { return visibleOffset(item) > 0; });
201
- var visibleItems = selectAll('.active-menu-panel .slide-menu-items li').filter(function(item) { return visibleOffset(item) == 0; });
202
-
203
- var firstVisible = (itemsAbove.length > 0 && Math.abs(visibleOffset(itemsAbove[itemsAbove.length-1])) < itemsAbove[itemsAbove.length-1].clientHeight ? itemsAbove[itemsAbove.length-1] : visibleItems[0]);
204
- if (firstVisible) {
205
- if (firstVisible.classList.contains('selected') && itemsAbove.length > 0) {
206
- // at top of viewport already, page scroll (if not at start)
207
- // ...move selected item to bottom, and change selection to last fully visible item at top
208
- scrollItemToBottom(firstVisible);
209
- visibleItems = selectAll('.active-menu-panel .slide-menu-items li').filter(function(item) { return visibleOffset(item) == 0; });
210
- if (visibleItems[0] == firstVisible) {
211
- // prev item is still beyond the viewport (for custom panels)
212
- firstVisible = itemsAbove[itemsAbove.length-1];
213
- } else {
214
- firstVisible = visibleItems[0];
215
- }
216
- }
217
- selectAll('.active-menu-panel .slide-menu-items li').forEach(function(item) { item.classList.remove('selected') });
218
- selectItem(firstVisible);
219
- // ensure selected item is positioned at the top of the viewport
220
- scrollItemToTop(firstVisible);
221
- }
222
- break;
223
- // pagedown, d
224
- case 34: case 68:
225
- var visibleItems = selectAll('.active-menu-panel .slide-menu-items li').filter(function(item) { return visibleOffset(item) == 0; });
226
- var itemsBelow = selectAll('.active-menu-panel .slide-menu-items li').filter(function(item) { return visibleOffset(item) < 0; });
227
-
228
- var lastVisible = (itemsBelow.length > 0 && Math.abs(visibleOffset(itemsBelow[0])) < itemsBelow[0].clientHeight ? itemsBelow[0] : visibleItems[visibleItems.length-1]);
229
- if (lastVisible) {
230
- if (lastVisible.classList.contains('selected') && itemsBelow.length > 0) {
231
- // at bottom of viewport already, page scroll (if not at end)
232
- // ...move selected item to top, and change selection to last fully visible item at bottom
233
- scrollItemToTop(lastVisible);
234
- visibleItems = selectAll('.active-menu-panel .slide-menu-items li').filter(function(item) { return visibleOffset(item) == 0; });
235
- if (visibleItems[visibleItems.length-1] == lastVisible) {
236
- // next item is still beyond the viewport (for custom panels)
237
- lastVisible = itemsBelow[0];
238
- } else {
239
- lastVisible = visibleItems[visibleItems.length-1];
240
- }
241
- }
242
- selectAll('.active-menu-panel .slide-menu-items li').forEach(function(item) { item.classList.remove('selected') });
243
- selectItem(lastVisible);
244
- // ensure selected item is positioned at the bottom of the viewport
245
- scrollItemToBottom(lastVisible);
246
- }
247
- break;
248
- // home
249
- case 36:
250
- selectAll('.active-menu-panel .slide-menu-items li').forEach(function(item) { item.classList.remove('selected') });
251
- var item = select('.active-menu-panel .slide-menu-items li:first-of-type');
252
- if (item) {
253
- item.classList.add('selected');
254
- keepVisible(item);
255
- }
256
- break;
257
- // end
258
- case 35:
259
- selectAll('.active-menu-panel .slide-menu-items li').forEach(function(item) { item.classList.remove('selected') });
260
- var item = select('.active-menu-panel .slide-menu-items:last-of-type li:last-of-type');
261
- if (item) {
262
- item.classList.add('selected');
263
- keepVisible(item);
264
- }
265
- break;
266
- // space, return
267
- case 32: case 13:
268
- var currItem = select('.active-menu-panel .slide-menu-items li.selected');
269
- if (currItem) {
270
- openItem(currItem, true);
271
- }
272
- break;
273
- // esc
274
- case 27: closeMenu(null, true); break;
275
- }
276
- }
277
- }
278
-
279
- if (keyboard) {
280
- //XXX add keyboard option for custom key codes, etc.
281
-
282
- document.addEventListener('keydown', onDocumentKeyDown, false);
283
-
284
- // handle key presses within speaker notes
285
- window.addEventListener( 'message', function( event ) {
286
- var data;
287
- try {
288
- data = JSON.parse( event.data );
289
- } catch (e) {
290
- }
291
- if (data && data.method === 'triggerKey') {
292
- onDocumentKeyDown( { keyCode: data.args[0], stopImmediatePropagation: function() {} } );
293
- }
294
- });
295
-
296
- // Prevent reveal from processing keyboard events when the menu is open
297
- if (config.keyboardCondition && typeof config.keyboardCondition === 'function') {
298
- // combine user defined keyboard condition with the menu's own condition
299
- var userCondition = config.keyboardCondition;
300
- config.keyboardCondition = function() {
301
- return userCondition() && !isOpen();
302
- };
303
- } else {
304
- config.keyboardCondition = function() { return !isOpen(); }
305
- }
306
- }
307
-
308
-
309
- //
310
- // Utilty functions
311
- //
312
-
313
- function openMenu(event) {
314
- if (event) event.preventDefault();
315
- if (!isOpen()) {
316
- select('body').classList.add('slide-menu-active');
317
- select('.reveal').classList.add('has-' + options.effect + '-' + side);
318
- select('.slide-menu').classList.add('active');
319
- select('.slide-menu-overlay').classList.add('active');
320
-
321
- // identify active theme
322
- if (themes) {
323
- selectAll('div[data-panel="Themes"] li').forEach(function(i) { i.classList.remove('active') });
324
- selectAll('li[data-theme="' + select('link#theme').getAttribute('href') + '"]').forEach(function(i) { i.classList.add('active') });
325
- }
326
-
327
- // identify active transition
328
- if (transitions) {
329
- selectAll('div[data-panel="Transitions"] li').forEach(function(i) { i.classList.remove('active') });
330
- selectAll('li[data-transition="' + Reveal.getConfig().transition + '"]').forEach(function(i) { i.classList.add('active') });
331
- }
332
-
333
- // set item selections to match active items
334
- var items = selectAll('.slide-menu-panel li.active')
335
- items.forEach(function(i) {
336
- i.classList.add('selected');
337
- keepVisible(i);
338
- });
339
- }
340
- }
341
-
342
- function closeMenu(event, force) {
343
- if (event) event.preventDefault();
344
- if (!sticky || force) {
345
- select('body').classList.remove('slide-menu-active');
346
- select('.reveal').classList.remove('has-' + options.effect + '-' + side);
347
- select('.slide-menu').classList.remove('active');
348
- select('.slide-menu-overlay').classList.remove('active');
349
- selectAll('.slide-menu-panel li.selected').forEach(function(i) { i.classList.remove('selected') });
350
- }
351
- }
352
-
353
- function toggleMenu(event) {
354
- if (isOpen()) {
355
- closeMenu(event, true);
356
- } else {
357
- openMenu(event);
358
- }
359
- }
360
-
361
- function isOpen() {
362
- return select('body').classList.contains('slide-menu-active');
363
- }
364
-
365
- function openPanel(event, ref) {
366
- openMenu(event);
367
- var panel = ref;
368
- if (typeof ref !== "string") {
369
- panel = event.currentTarget.getAttribute('data-panel');
370
- }
371
- select('.slide-menu-toolbar > li.active-toolbar-button').classList.remove('active-toolbar-button');
372
- select('li[data-panel="' + panel + '"]').classList.add('active-toolbar-button');
373
- select('.slide-menu-panel.active-menu-panel').classList.remove('active-menu-panel');
374
- select('div[data-panel="' + panel + '"]').classList.add('active-menu-panel');
375
- }
376
-
377
- function nextPanel() {
378
- var next = (parseInt(select('.active-toolbar-button').getAttribute('data-button')) + 1) % buttons;
379
- openPanel(null, select('.toolbar-panel-button[data-button="' + next + '"]').getAttribute('data-panel'));
380
- }
381
-
382
- function prevPanel() {
383
- var next = parseInt(select('.active-toolbar-button').getAttribute('data-button')) - 1;
384
- if (next < 0) {
385
- next = buttons - 1;
386
- }
387
- openPanel(null, select('.toolbar-panel-button[data-button="' + next + '"]').getAttribute('data-panel'));
388
- }
389
-
390
- function openItem(item, force) {
391
- var h = parseInt(item.getAttribute('data-slide-h'));
392
- var v = parseInt(item.getAttribute('data-slide-v'));
393
- var theme = item.getAttribute('data-theme');
394
- var transition = item.getAttribute('data-transition');
395
- if (!isNaN(h) && !isNaN(v)) {
396
- Reveal.slide(h, v);
397
- closeMenu();
398
- } else if (theme) {
399
- // take note of the previous theme and remove it, then create a new stylesheet reference and insert it
400
- // this is required to force a load event so we can change the menu style to match the new style
401
- var stylesheet = select('link#theme');
402
- var parent = stylesheet.parentElement;
403
- var sibling = stylesheet.nextElementSibling;
404
- stylesheet.remove();
405
-
406
- var newStylesheet = stylesheet.cloneNode();
407
- newStylesheet.setAttribute('href', theme);
408
- newStylesheet.onload = function() { matchRevealStyle() };
409
- parent.insertBefore(newStylesheet, sibling);
410
-
411
- closeMenu();
412
- } else if (transition) {
413
- Reveal.configure({ transition: transition });
414
- closeMenu();
415
- } else {
416
- var link = select('a', item);
417
- if (link) {
418
- if (force || !sticky || (autoOpen && link.href.startsWith('#') || link.href.startsWith(window.location.origin + window.location.pathname + '#'))) {
419
- link.click();
420
- }
421
- }
422
- closeMenu();
423
- }
424
- }
425
-
426
- function clicked(event) {
427
- if (event.target.nodeName !== "A") {
428
- event.preventDefault();
429
- }
430
- openItem(event.currentTarget);
431
- }
432
-
433
- function highlightCurrentSlide() {
434
- var state = Reveal.getState();
435
- selectAll('li.slide-menu-item, li.slide-menu-item-vertical').forEach(function(item) {
436
- item.classList.remove('past');
437
- item.classList.remove('active');
438
- item.classList.remove('future');
439
-
440
- var h = parseInt(item.getAttribute('data-slide-h'));
441
- var v = parseInt(item.getAttribute('data-slide-v'));
442
- if (h < state.indexh || (h === state.indexh && v < state.indexv)) {
443
- item.classList.add('past');
444
- }
445
- else if (h === state.indexh && v === state.indexv) {
446
- item.classList.add('active');
447
- }
448
- else {
449
- item.classList.add('future');
450
- }
451
- });
452
- }
453
-
454
- function matchRevealStyle() {
455
- var revealStyle = window.getComputedStyle(select('.reveal'));
456
- var element = select('.slide-menu');
457
- element.style.fontFamily = revealStyle.fontFamily;
458
- //XXX could adjust the complete menu style to match the theme, ie colors, etc
459
- }
460
-
461
- var buttons = 0;
462
- function init() {
463
- if (!initialised) {
464
- var parent = select('.reveal').parentElement;
465
- var top = create('div', { 'class': 'slide-menu-wrapper'});
466
- parent.appendChild(top);
467
- var panels = create('nav', { 'class': 'slide-menu slide-menu--' + side});
468
- if (typeof width === 'string') {
469
- if (['normal', 'wide', 'third', 'half', 'full'].indexOf(width) != -1) {
470
- panels.classList.add('slide-menu--' + width);
471
- }
472
- else {
473
- panels.classList.add('slide-menu--custom');
474
- panels.style.width = width;
475
- }
476
- }
477
- top.appendChild(panels);
478
- matchRevealStyle();
479
- var overlay = create('div', { 'class': 'slide-menu-overlay'});
480
- top.appendChild(overlay);
481
- overlay.onclick = function() { closeMenu(null, true) };
482
-
483
- var toolbar = create('ol', {'class': 'slide-menu-toolbar'});
484
- select('.slide-menu').appendChild(toolbar);
485
-
486
- function addToolbarButton(title, ref, icon, style, fn, active) {
487
- var attrs = {
488
- 'data-button': '' + (buttons++),
489
- 'class': 'toolbar-panel-button' + (active ? ' active-toolbar-button' : '')
490
- };
491
- if (ref) {
492
- attrs['data-panel'] = ref;
493
- }
494
- var button = create('li', attrs);
495
-
496
- if (icon.startsWith('fa-')) {
497
- button.appendChild(create('i', {'class': style + ' ' + icon}));
498
- } else {
499
- button.innerHTML = icon + '</i>';
500
- }
501
- button.appendChild(create('br'), select('i', button));
502
- button.appendChild(create('span', {'class': 'slide-menu-toolbar-label'}, title), select('i', button));
503
- button.onclick = fn;
504
- toolbar.appendChild(button);
505
- return button;
506
- }
507
-
508
- addToolbarButton('Slides', 'Slides', 'fa-images', 'fas', openPanel, true);
509
-
510
- if (custom) {
511
- custom.forEach(function(element, index, array) {
512
- addToolbarButton(element.title, 'Custom' + index, element.icon, null, openPanel);
513
- });
514
- }
515
-
516
- if (themes) {
517
- addToolbarButton('Themes', 'Themes', 'fa-adjust', 'fas', openPanel);
518
- }
519
- if (transitions) {
520
- addToolbarButton('Transitions', 'Transitions', 'fa-sticky-note', 'fas', openPanel);
521
- }
522
- button = create('li', {id: 'close', 'class': 'toolbar-panel-button'});
523
- button.appendChild(create('i', {'class': 'fas fa-times'}));
524
- button.appendChild(create('br'));
525
- button.appendChild(create('span', {'class': 'slide-menu-toolbar-label'}, 'Close'));
526
- button.onclick = function() { closeMenu(null, true) };
527
- toolbar.appendChild(button);
528
-
529
- //
530
- // Slide links
531
- //
532
- function generateItem(type, section, i, h, v) {
533
- var link = '/#/' + h;
534
- if (typeof v === 'number' && !isNaN( v )) link += '/' + v;
535
-
536
- function text(selector, parent) {
537
- var el = (parent ? select(selector, section) : select(selector));
538
- if (el) return el.textContent;
539
- return null;
540
- }
541
- var title = section.getAttribute('data-menu-title') ||
542
- text('.menu-title', section) ||
543
- text(titleSelector, section);
544
-
545
- if (!title && useTextContentForMissingTitles) {
546
- // attempt to figure out a title based on the text in the slide
547
- title = section.textContent.trim();
548
- if (title) {
549
- title = title.split('\n')
550
- .map(function(t) { return t.trim() }).join(' ').trim()
551
- .replace(/^(.{16}[^\s]*).*/, "$1") // limit to 16 chars plus any consecutive non-whitespace chars (to avoid breaking words)
552
- .replace(/&/g, "&amp;")
553
- .replace(/</g, "&lt;")
554
- .replace(/>/g, "&gt;")
555
- .replace(/"/g, "&quot;")
556
- .replace(/'/g, "&#039;") + '...';
557
- }
558
- }
559
-
560
- if (!title) {
561
- if (hideMissingTitles) return '';
562
- type += ' no-title';
563
- title = "Slide " + i;
564
- }
565
-
566
- var item = create('li', {
567
- class: type,
568
- 'data-item': i,
569
- 'data-slide-h': h,
570
- 'data-slide-v': (v === undefined ? 0 : v)
571
- });
572
-
573
- if (markers) {
574
- item.appendChild(create('i', {class: 'fas fa-check-circle fa-fw past'}));
575
- item.appendChild(create('i', {class: 'fas fa-arrow-alt-circle-right fa-fw active'}));
576
- item.appendChild(create('i', {class: 'far fa-circle fa-fw future'}));
577
- }
578
-
579
- if (numbers) {
580
- // Number formatting taken from reveal.js
581
- var value = [];
582
- var format = 'h.v';
583
-
584
- // Check if a custom number format is available
585
- if( typeof numbers === 'string' ) {
586
- format = numbers;
587
- }
588
- else if (typeof config.slideNumber === 'string') {
589
- // Take user defined number format for slides
590
- format = config.slideNumber;
591
- }
592
-
593
- switch( format ) {
594
- case 'c':
595
- value.push( i );
596
- break;
597
- case 'c/t':
598
- value.push( i, '/', Reveal.getTotalSlides() );
599
- break;
600
- case 'h/v':
601
- value.push( h + 1 );
602
- if( typeof v === 'number' && !isNaN( v ) ) value.push( '/', v + 1 );
603
- break;
604
- default:
605
- value.push( h + 1 );
606
- if( typeof v === 'number' && !isNaN( v ) ) value.push( '.', v + 1 );
607
- }
608
-
609
- item.appendChild(create('span', {class: 'slide-menu-item-number'}, value.join('') + '. '));
610
- }
611
-
612
- item.appendChild(create('span', {class: 'slide-menu-item-title'}, title));
613
-
614
- return item;
615
- }
616
-
617
- function createSlideMenu() {
618
- if ( !document.querySelector('section[data-markdown]:not([data-markdown-parsed])') ) {
619
- var panel = create('div', {
620
- 'data-panel': 'Slides',
621
- 'class': 'slide-menu-panel active-menu-panel'
622
- });
623
- panel.appendChild(create('ul', {class: "slide-menu-items"}));
624
- panels.appendChild(panel);
625
- var items = select('.slide-menu-panel[data-panel="Slides"] > .slide-menu-items');
626
- var slideCount = 0;
627
- selectAll('.slides > section').forEach(function(section, h) {
628
- var subsections = selectAll('section', section);
629
- if (subsections.length > 0) {
630
- subsections.forEach(function(subsection, v) {
631
- var type = (v === 0 ? 'slide-menu-item' : 'slide-menu-item-vertical');
632
- var item = generateItem(type, subsection, slideCount, h, v);
633
- if (item) {
634
- slideCount++;
635
- items.appendChild(item);
636
- }
637
- });
638
- } else {
639
- var item = generateItem('slide-menu-item', section, slideCount, h);
640
- if (item) {
641
- slideCount++;
642
- items.appendChild(item);
643
- }
644
- }
645
- });
646
- selectAll('.slide-menu-item, .slide-menu-item-vertical').forEach(function(i) {
647
- i.onclick = clicked;
648
- });
649
- highlightCurrentSlide();
650
- }
651
- else {
652
- // wait for markdown to be loaded and parsed
653
- setTimeout( createSlideMenu, 100 );
654
- }
655
- }
656
-
657
- createSlideMenu();
658
- Reveal.addEventListener('slidechanged', highlightCurrentSlide);
659
-
660
- //
661
- // Custom menu panels
662
- //
663
- if (custom) {
664
- function xhrSuccess () {
665
- if (this.status >= 200 && this.status < 300) {
666
- this.panel.innerHTML = this.responseText;
667
- enableCustomLinks(this.panel);
668
- }
669
- else {
670
- showErrorMsg(this)
671
- }
672
- }
673
- function xhrError () {
674
- showErrorMsg(this)
675
- }
676
- function loadCustomPanelContent (panel, sURL) {
677
- var oReq = new XMLHttpRequest();
678
- oReq.panel = panel;
679
- oReq.arguments = Array.prototype.slice.call(arguments, 2);
680
- oReq.onload = xhrSuccess;
681
- oReq.onerror = xhrError;
682
- oReq.open("get", sURL, true);
683
- oReq.send(null);
684
- }
685
- function enableCustomLinks(panel) {
686
- selectAll('ul.slide-menu-items li.slide-menu-item', panel).forEach(function(item, i) {
687
- item.setAttribute('data-item', i+1);
688
- item.onclick = clicked;
689
- item.addEventListener("mouseenter", handleMouseHighlight);
690
- });
691
- }
692
-
693
- function showErrorMsg(response) {
694
- var msg = '<p>ERROR: The attempt to fetch ' + response.responseURL + ' failed with HTTP status ' +
695
- response.status + ' (' + response.statusText + ').</p>' +
696
- '<p>Remember that you need to serve the presentation HTML from a HTTP server.</p>';
697
- response.panel.innerHTML = msg;
698
- }
699
-
700
- custom.forEach(function(element, index, array) {
701
- var panel = create('div', {
702
- 'data-panel': 'Custom' + index,
703
- class: 'slide-menu-panel slide-menu-custom-panel'
704
- });
705
- if (element.content) {
706
- panel.innerHTML = element.content;
707
- enableCustomLinks(panel);
708
- }
709
- else if (element.src) {
710
- loadCustomPanelContent(panel, element.src);
711
- }
712
- panels.appendChild(panel);
713
- })
714
- }
715
-
716
- //
717
- // Themes
718
- //
719
- if (themes) {
720
- var panel = create('div', {
721
- class: 'slide-menu-panel',
722
- 'data-panel': 'Themes'
723
- });
724
- panels.appendChild(panel);
725
- var menu = create('ul', {class: 'slide-menu-items'});
726
- panel.appendChild(menu);
727
- themes.forEach(function(t, i) {
728
- var item = create('li', {
729
- class: 'slide-menu-item',
730
- 'data-theme': t.theme,
731
- 'data-item': ''+(i+1)
732
- }, t.name);
733
- menu.appendChild(item);
734
- item.onclick = clicked;
735
- })
736
- }
737
-
738
- //
739
- // Transitions
740
- //
741
- if (transitions) {
742
- var panel = create('div', {
743
- class: 'slide-menu-panel',
744
- 'data-panel': 'Transitions'
745
- });
746
- panels.appendChild(panel);
747
- var menu = create('ul', {class: 'slide-menu-items'});
748
- panel.appendChild(menu);
749
- transitions.forEach(function(name, i) {
750
- var item = create('li', {
751
- class: 'slide-menu-item',
752
- 'data-transition': name.toLowerCase(),
753
- 'data-item': ''+(i+1)
754
- }, name);
755
- menu.appendChild(item);
756
- item.onclick = clicked;
757
- })
758
- }
759
-
760
- //
761
- // Open menu options
762
- //
763
- if (openButton) {
764
- // add menu button
765
- var div = create('div', {class: 'slide-menu-button'});
766
- var link = create('a', {href: '#'});
767
- link.appendChild(create('i', {class: 'fas fa-bars'}));
768
- div.appendChild(link);
769
- select('.reveal').appendChild(div);
770
- div.onclick = openMenu;
771
- }
772
-
773
- if (openSlideNumber) {
774
- // wrap slide number in link
775
- var slideNumber = select('div.slide-number');
776
- var wrapper = create('div', {class: 'slide-number-wrapper'});
777
- var link = create('a', {href: '#'});
778
- wrapper.appendChild(link);
779
- slideNumber.parentElement.insertBefore(wrapper, slideNumber);
780
- link.appendChild(slideNumber);
781
- link.onclick = openMenu;
782
- }
783
-
784
- //
785
- // Handle mouse overs
786
- //
787
- selectAll('.slide-menu-panel .slide-menu-items li').forEach(function(item) {
788
- item.addEventListener("mouseenter", handleMouseHighlight);
789
- });
790
-
791
- function handleMouseHighlight(event) {
792
- if (mouseSelectionEnabled) {
793
- selectAll('.active-menu-panel .slide-menu-items li.selected').forEach(function(i) {
794
- i.classList.remove('selected');
795
- });
796
- event.currentTarget.classList.add('selected');
797
- }
798
- }
799
- }
800
- if (openOnInit) {
801
- openMenu();
802
- }
803
- initialised = true;
804
- }
805
-
806
- module.toggle = toggleMenu;
807
- module.openMenu = openMenu;
808
- module.closeMenu = closeMenu;
809
- module.openPanel = openPanel;
810
- module.isOpen = isOpen;
811
- module.init = init;
812
- module.isInit = function() { return initialised };
813
-
814
- if (!delayInit) {
815
- init();
816
- }
817
-
818
- /**
819
- * Extend object a with the properties of object b.
820
- * If there's a conflict, object b takes precedence.
821
- */
822
- function extend( a, b ) {
823
- for( var i in b ) {
824
- a[ i ] = b[ i ];
825
- }
826
- }
827
-
828
- /**
829
- * Dispatches an event of the specified type from the
830
- * reveal DOM element.
831
- */
832
- function dispatchEvent( type, args ) {
833
- var event = document.createEvent( 'HTMLEvents', 1, 2 );
834
- event.initEvent( type, true, true );
835
- extend( event, args );
836
- document.querySelector('.reveal').dispatchEvent( event );
837
-
838
- // If we're in an iframe, post each reveal.js event to the
839
- // parent window. Used by the notes plugin
840
- if( config.postMessageEvents && window.parent !== window.self ) {
841
- window.parent.postMessage( JSON.stringify({ namespace: 'reveal', eventName: type, state: Reveal.getState() }), '*' );
842
- }
843
- }
844
-
845
- dispatchEvent('menu-ready');
846
- }
847
- }
848
-
849
- function select(selector, el) {
850
- if (!el) {
851
- el = document;
852
- }
853
- return el.querySelector(selector);
854
- }
855
-
856
- function selectAll(selector, el) {
857
- if (!el) {
858
- el = document;
859
- }
860
- return Array.prototype.slice.call(el.querySelectorAll(selector));
861
- }
862
-
863
- function create(tagName, attrs, content) {
864
- var el = document.createElement(tagName);
865
- if (attrs) {
866
- Object.getOwnPropertyNames(attrs).forEach(function(n) {
867
- el.setAttribute(n, attrs[n]);
868
- });
869
- }
870
- if (content) el.innerHTML = content;
871
- return el;
872
- }
873
-
874
- // modified from math plugin
875
- function loadResource( url, type, callback ) {
876
- var head = document.querySelector( 'head' );
877
- var resource;
878
-
879
- if ( type === 'script' ) {
880
- resource = document.createElement( 'script' );
881
- resource.type = 'text/javascript';
882
- resource.src = url;
883
- }
884
- else if ( type === 'stylesheet' ) {
885
- resource = document.createElement( 'link' );
886
- resource.rel = 'stylesheet';
887
- resource.href = url;
888
- }
889
-
890
- // Wrapper for callback to make sure it only fires once
891
- var finish = function() {
892
- if( typeof callback === 'function' ) {
893
- callback.call();
894
- callback = null;
895
- }
896
- }
897
-
898
- resource.onload = finish;
899
-
900
- // IE
901
- resource.onreadystatechange = function() {
902
- if ( this.readyState === 'loaded' ) {
903
- finish();
904
- }
905
- }
906
-
907
- // Normal browsers
908
- head.appendChild( resource );
909
- }
910
-
911
- function scriptPath() {
912
- // obtain plugin path from the script element
913
- var path;
914
- if (document.currentScript) {
915
- path = document.currentScript.src.slice(0, -7);
916
- } else {
917
- var sel = document.querySelector('script[src$="menu.js"]');
918
- if (sel) {
919
- path = sel.src.slice(0, -7);
920
- }
921
- }
922
- return path;
923
- }
924
-
925
- // polyfill
926
- if (!String.prototype.startsWith) {
927
- String.prototype.startsWith = function(searchString, position){
928
- return this.substr(position || 0, searchString.length) === searchString;
929
- };
930
- }
931
- if (!String.prototype.endsWith) {
932
- String.prototype.endsWith = function(search, this_len) {
933
- if (this_len === undefined || this_len > this.length) {
934
- this_len = this.length;
935
- }
936
- return this.substring(this_len - search.length, this_len) === search;
937
- };
938
- }
939
-
940
- var ieVersion = function() {
941
- var browser = /(msie) ([\w.]+)/.exec(window.navigator.userAgent.toLowerCase());
942
- if (browser && browser[1] === "msie") {
943
- return parseFloat(browser[2]);
944
- }
945
- return null;
946
- }();
947
-
948
- return module;
949
- })();