reveal.js-appearance 1.1.3 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,19 +28,62 @@ const Plugin = () => {
28
28
  head.appendChild(style);
29
29
  }
30
30
 
31
+ const isJSON = str => {
32
+ try {
33
+ return (JSON.parse(str) && !!str);
34
+ } catch (e) {
35
+ return false;
36
+ }
37
+ };
38
+
39
+ const isObj = (test) => {
40
+ while ( Object.prototype.toString.call(test) === '[object Object]')
41
+ if ((test = Object.getPrototypeOf(test)) === null)
42
+ return true
43
+ return false
44
+ }
45
+
31
46
  const selectionArray = function (container, selectors) {
32
47
  let selections = container.querySelectorAll(selectors);
33
48
  let selectionarray = Array.prototype.slice.call(selections);
34
49
  return selectionarray;
35
50
  };
36
51
 
52
+ const isStack = function (section) {
53
+ let isStack = false;
54
+ for (let i = 0; i < section.childNodes.length; i++) {
55
+ if (section.childNodes[i].tagName == "SECTION") {
56
+ isStack = true
57
+ break;
58
+ }
59
+ }
60
+ return isStack;
61
+ };
62
+
63
+ function copyDataAttributes(source, target, not) {
64
+ [...source.attributes].filter( attr => attr.nodeName.indexOf('data') > -1).forEach( attr => {
65
+ if ((not && attr.nodeName !== not) || !not) {
66
+ target.setAttribute(attr.nodeName, attr.nodeValue)
67
+ }
68
+ })
69
+ }
70
+
71
+
37
72
  const appear = function (deck, options) {
38
73
 
39
74
  let baseclass = 'animate__animated';
75
+ let viewport = (deck.getRevealElement()).tagName == "BODY" ? document : deck.getRevealElement();
40
76
  let appearanceSelector = options.compatibility ? `.${options.compatibilitybaseclass}` : `.${baseclass}`;
41
- let fragmentSelector = ".fragment"
77
+ let fragmentSelector = ".fragment";
78
+
79
+ let speedClasses = ['slower', 'slow', 'fast', 'faster'];
80
+ speedClasses.push(...speedClasses.map(speed => `animate__${speed}`));
81
+
82
+ const generator = document.querySelector('[name=generator]');
83
+
84
+ const sections = selectionArray(viewport, "section");
85
+ const regularSections = sections.filter( section => !isStack(section) && section.dataset.visibility != "hidden");
42
86
 
43
- const sections = deck.getRevealElement().querySelectorAll(`.slides section`);
44
87
  const fragments = deck.getRevealElement().querySelectorAll(fragmentSelector);
45
88
  let animatecss = '[class^="animate__"],[class*=" animate__"]'
46
89
 
@@ -48,17 +91,164 @@ const Plugin = () => {
48
91
  if (options.debug) console.log(text);
49
92
  }
50
93
 
94
+ let url = new URL(window.location);
95
+ let urlparams = new URLSearchParams(url.search);
96
+ if (urlparams.has('receiver')) {
97
+ viewport.classList.add('sv')
98
+ console.log(viewport)
99
+ }
100
+
101
+ const assignAutoClass = (section, str, kind) => {
102
+
103
+ let index = [...section.parentElement.children].filter(s => s.tagName=="SECTION").indexOf(section) + 1;
104
+
105
+ let warning = kind == 'global' ? `JSON Parse error, please try to correct the global "autoelements" option.` : `JSON Parse error, please try to correct the "data-autoappear" attribute on section ${index}`;
106
+
107
+ if (typeof str === "string") str = str.replace(/[“”]/g,'"').replace(/[‘’]/g,"'");
108
+
109
+ let strJSON = isJSON(str) ? str : typeof str === "object" ? JSON.stringify(str, null, 2) : str.trim().replace(/'/g, '"').charAt(0) === "{" ? str.trim().replace(/'/g, '"') : `{${str.trim().replace(/'/g, '"')}}`;
110
+
111
+
112
+ if (!isJSON(strJSON)) {
113
+ console.log(warning);
114
+ } else {
115
+ let elementsToAnimate = JSON.parse(strJSON);
116
+
117
+ for (const [element, assignables] of Object.entries(elementsToAnimate)) {
118
+
119
+ let elementsInSection = section.querySelectorAll(element);
120
+
121
+ elementsInSection.forEach(elementInSection => {
122
+
123
+ if (!elementInSection.classList.contains(baseclass) || elementInSection.dataset["autoappear"]) {
124
+
125
+ elementInSection.dataset["autoappear"] = true;
126
+
127
+ let newClasses = [], newDelay = null, speedClass = false;
128
+
129
+ if (Array.isArray(assignables)) {
130
+ newClasses = assignables[0].split(/[ ,]+/);
131
+ newDelay = assignables[1];
132
+ } else if (typeof assignables == "string"){
133
+ newClasses = assignables.split(/[ ,]+/);
134
+ }
135
+
136
+ speedClasses.forEach(speed => {
137
+ if (elementInSection.classList.contains(speed)) {
138
+ speedClass = speed;
139
+ }
140
+ })
141
+
142
+ let classesToRemove = [];
143
+ elementInSection.classList.forEach(currentClass => {
144
+ if (String(currentClass).includes("animate__")) {
145
+ classesToRemove.push(currentClass);
146
+ }
147
+ })
148
+ classesToRemove.forEach(currentClass => {elementInSection.classList.remove(currentClass)});
149
+
150
+ newClasses.forEach(newClass => {
151
+ if (speedClasses.includes(newClass)) {
152
+ // There is a speed class from JSON to be assigned
153
+ if (speedClass) { speedClass = newClass }
154
+ }
155
+ });
156
+
157
+ newClasses.forEach(newClass => {
158
+ elementInSection.classList.add(newClass);
159
+ });
160
+
161
+ if (speedClass) {
162
+ elementInSection.classList.add(speedClass);
163
+ }
164
+
165
+
166
+
167
+
168
+ if (newDelay) {
169
+ elementInSection.dataset.delay = newDelay;
170
+ }
171
+
172
+ elementInSection.classList.add(baseclass);
173
+
174
+ }
175
+
176
+
177
+ });
178
+ }
179
+ }
180
+ };
181
+
51
182
  const findAppearancesIn = function (container, includeClass, excludeClass) {
52
183
  if (!isStack(container)) {
53
184
  let appearances = selectionArray(container, `:scope ${includeClass}`);
185
+
186
+ appearances.forEach(appearance => {
187
+
188
+ let convertListItem = (appearance) => {
189
+ let from = appearance, to = appearance.parentNode;
190
+ if (!to) return
191
+ for (let sibling of to.children) {
192
+ if (sibling !== appearance) { if (sibling.dataset.appearParent) return }
193
+ }
194
+ to.classList = from.classList;
195
+ copyDataAttributes(from, to, "data-appear-parent");
196
+ to.innerHTML = from.innerHTML;
197
+ }
198
+
199
+ // Conversion of list items with Appearance classes to the parent, needs manual attribute
200
+ // Relates to Quarto wrapping list content in a span.
201
+ if (appearance.hasAttribute("data-appear-parent")) {
202
+ convertListItem(appearance);
203
+ }
204
+
205
+ // Automatic conversion of list items which directly contain spans.
206
+ // Relates to Quarto wrapping list content in a span.
207
+ if (options.appearparents) {
208
+ if (appearance.parentNode && appearance.parentNode.tagName) {
209
+ if (appearance.tagName == "SPAN" && appearance.parentNode.tagName == "LI") {
210
+ let spanLength = String(appearance.outerHTML).length;
211
+ let liContentLength = String(appearance.parentNode.innerHTML).length;
212
+ if (spanLength == liContentLength) {
213
+ convertListItem(appearance);
214
+ }
215
+ }
216
+ }
217
+ }
218
+
219
+
220
+ });
221
+
222
+ appearances = selectionArray(container, `:scope ${includeClass}`);
54
223
  let excludes = selectionArray(container, `:scope ${excludeClass} ${includeClass}`);
55
224
  let delay = 0;
56
-
225
+
57
226
  appearances.filter(function (appearance, index) {
58
- if ( !(excludes.indexOf(appearance) > -1 ) ) {
227
+ if ( !(excludes.indexOf(appearance) > -1 ) ) {
59
228
  if ((index == 0 && appearance.dataset.delay) || index !=0) {
60
- let elementDelay = appearance.dataset.delay ? (parseInt(appearance.dataset.delay)) : options.delay;
229
+
230
+ let elementDelay = options.delay;
231
+ if (appearance.dataset && appearance.dataset.delay) {
232
+ elementDelay = parseInt(appearance.dataset.delay);
233
+ }
234
+
61
235
  delay = delay + elementDelay;
236
+
237
+ // Allow fragments to be Appearance items
238
+ if (appearance.classList.contains("fragment")) {
239
+ delay = 0;
240
+ if (appearance.querySelectorAll(`.${baseclass}`)) {
241
+ let firstNestedAppearance = appearance.querySelectorAll(`.${baseclass}`)[0];
242
+
243
+ if (firstNestedAppearance) {
244
+ let elementDelay = options.delay;
245
+ if (firstNestedAppearance.dataset && firstNestedAppearance.dataset.delay) {
246
+ elementDelay = parseInt(firstNestedAppearance.dataset.delay);
247
+ }
248
+ firstNestedAppearance.dataset.delay = elementDelay
249
+ }
250
+ }
251
+ }
62
252
  appearance.style.setProperty('animation-delay', delay + "ms");
63
253
  }
64
254
  }
@@ -68,46 +258,46 @@ const Plugin = () => {
68
258
 
69
259
  const autoAdd = function () {
70
260
 
71
- if (options.autoelements) {
261
+ regularSections.forEach(section => {
72
262
 
73
- for (const [autoelement, autoanimation] of Object.entries(options.autoelements)) {
263
+ if (section.hasAttribute("data-autoappear")) {
74
264
 
75
- if (options.autoappear) {
76
- debugLog(`All "${autoelement}"" elements will animate with ${autoanimation}`);
77
- }
78
- let autosection = options.autoappear ? "" : "[data-autoappear] ";
79
- let autoAppearances = deck.getRevealElement().querySelectorAll(`.slides ${autosection}${autoelement}`);
80
-
81
- if (autoAppearances.length > 0) {
82
- autoAppearances.forEach(autoAppearance => {
83
- if (!autoAppearance.classList.contains(baseclass)) {
84
- autoAppearance.classList.add(baseclass);
85
- autoAppearance.classList.add(autoanimation);
265
+ let sectDataAppear = section.dataset.autoappear;
266
+
267
+ if (sectDataAppear == "auto" || sectDataAppear == "" || sectDataAppear.length < 1 || sectDataAppear == "true") {
268
+ // This section should get the global autoappear classes on its objects
269
+ if (options.autoelements) {
270
+ if (!options.autoelements) {
271
+ return console.log(`Please add some elements in the option "autoelements"`);
86
272
  }
87
- });
273
+ assignAutoClass(section, options.autoelements, 'global')
274
+ }
275
+ } else if (sectDataAppear.length > 0) {
276
+ // This section should get the local data-autoappear classes on its objects
277
+ assignAutoClass(section, sectDataAppear, 'local');
278
+ //section.removeAttribute("data-autoappear");
88
279
  }
89
- }
90
- } else if (options.autoappear) {
91
- console.log(`Please set an "autoelements" object.`);
92
- }
93
- }
280
+ } else {
94
281
 
95
- const isStack = function (section) {
96
- let isStack = false;
97
- for (let i = 0; i < section.childNodes.length; i++) {
98
- if (section.childNodes[i].tagName == "SECTION") {
99
- isStack = true
100
- break;
282
+ if (options.autoappear) {
283
+ if (!options.autoelements) {
284
+ return console.log(`Please add some elements in the option "autoelements"`);
285
+ }
286
+ // This section should get the global autoappear classes on its objects
287
+ assignAutoClass(section, options.autoelements, 'global')
288
+ }
101
289
  }
102
- }
103
- return isStack;
104
- };
290
+ });
291
+
292
+ }
105
293
 
106
294
  if (options.compatibility) {
107
295
  animatecss = '.backInDown, .backInLeft, .backInRight, .backInUp, .bounceIn, .bounceInDown, .bounceInLeft, .bounceInRight, .bounceInUp, .fadeIn, .fadeInDown, .fadeInDownBig, .fadeInLeft, .fadeInLeftBig, .fadeInRight, .fadeInRightBig, .fadeInUp, .fadeInUpBig, .fadeInTopLeft, .fadeInTopRight, .fadeInBottomLeft, .fadeInBottomRight, .flipInX, .flipInY, .lightSpeedInRight, .lightSpeedInLeft, .rotateIn, .rotateInDownLeft, .rotateInDownRight, .rotateInUpLeft, .rotateInUpRight, .jackInTheBox, .rollIn, .zoomIn, .zoomInDown, .zoomInLeft, .zoomInRight, .zoomInUp, .slideInDown, .slideInLeft, .slideInRight, .slideInUp, .skidLeft, .skidLeftBig, .skidRight, .skidRightBig, .shrinkIn, .shrinkInBlur';
108
296
  baseclass = options.compatibilitybaseclass
109
297
  }
110
298
 
299
+
300
+
111
301
  let allappearances = deck.getRevealElement().querySelectorAll(animatecss);
112
302
 
113
303
  allappearances.forEach(appearance => {
@@ -210,10 +400,11 @@ const Plugin = () => {
210
400
  appearevent: 'slidetransitionend',
211
401
  autoappear: false,
212
402
  autoelements: false,
403
+ appearparents: false,
213
404
  csspath: '',
214
405
  animatecsspath: {
215
406
  link : 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css',
216
- compat : 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.0.0/animate.compat.css',
407
+ compat : 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.compat.css',
217
408
  },
218
409
  compatibility: false,
219
410
  compatibilitybaseclass: 'animated'
package/screenshot.png CHANGED
Binary file