aboutsummaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
authorHakim El Hattab <hakim.elhattab@gmail.com>2020-05-26 10:45:05 +0200
committerHakim El Hattab <hakim.elhattab@gmail.com>2020-05-26 10:45:05 +0200
commitb7487b8b4f4b9f6a230cdfc3de327473c5e900b8 (patch)
treea1d86f8006d694a6e1c029243a5dd476ec24121b /js
parente6244a57b549ad788d02596c98ff33f6c348899e (diff)
downloadfosdem-2021-minimalism-presentation-b7487b8b4f4b9f6a230cdfc3de327473c5e900b8.tar
fosdem-2021-minimalism-presentation-b7487b8b4f4b9f6a230cdfc3de327473c5e900b8.tar.gz
polyfill element.closest for ie11
Diffstat (limited to 'js')
-rw-r--r--js/controllers/autoanimate.js10
-rw-r--r--js/controllers/focus.js4
-rw-r--r--js/controllers/slidecontent.js20
-rw-r--r--js/reveal.js2
-rw-r--r--js/utils/util.js27
5 files changed, 31 insertions, 32 deletions
diff --git a/js/controllers/autoanimate.js b/js/controllers/autoanimate.js
index 01711a2..22f7e7c 100644
--- a/js/controllers/autoanimate.js
+++ b/js/controllers/autoanimate.js
@@ -1,4 +1,4 @@
-import { queryAll, extend, createStyleSheet, matchesSelector } from '../utils/util.js'
+import { queryAll, extend, createStyleSheet, matches, closest } from '../utils/util.js'
import { FRAGMENT_STYLE_REGEX } from '../utils/constants.js'
// Counter used to generate unique IDs for auto-animated elements
@@ -299,8 +299,8 @@ export default class AutoAnimate {
options = extend( options, inheritedOptions );
// Inherit options from parent elements
- if( element.closest && element.parentNode ) {
- let autoAnimatedParent = element.parentNode.closest( '[data-auto-animate-target]' );
+ if( element.parentNode ) {
+ let autoAnimatedParent = closest( element.parentNode, '[data-auto-animate-target]' );
if( autoAnimatedParent ) {
options = this.getAutoAnimateOptions( autoAnimatedParent, options );
}
@@ -463,11 +463,11 @@ export default class AutoAnimate {
// Disable scale transformations on text nodes, we transiition
// each individual text property instead
- if( matchesSelector( pair.from, textNodes ) ) {
+ if( matches( pair.from, textNodes ) ) {
pair.options = { scale: false };
}
// Animate individual lines of code
- else if( matchesSelector( pair.from, codeNodes ) ) {
+ else if( matches( pair.from, codeNodes ) ) {
// Transition the code block's width and height instead of scaling
// to prevent its content from being squished
diff --git a/js/controllers/focus.js b/js/controllers/focus.js
index 8e2d8fa..2191807 100644
--- a/js/controllers/focus.js
+++ b/js/controllers/focus.js
@@ -1,3 +1,5 @@
+import { closest } from '../utils/util.js'
+
/**
* Manages focus when a presentation is embedded. This
* helps us only capture keyboard from the presentation
@@ -85,7 +87,7 @@ export default class Focus {
onDocumentPointerDown( event ) {
- let revealElement = event.target.closest( '.reveal' );
+ let revealElement = closest( event.target, '.reveal' );
if( !revealElement || revealElement !== this.Reveal.getRevealElement() ) {
this.blur();
}
diff --git a/js/controllers/slidecontent.js b/js/controllers/slidecontent.js
index 2ed2a47..7ed5573 100644
--- a/js/controllers/slidecontent.js
+++ b/js/controllers/slidecontent.js
@@ -1,5 +1,5 @@
import { HORIZONTAL_SLIDES_SELECTOR, VERTICAL_SLIDES_SELECTOR } from '../utils/constants.js'
-import { extend, queryAll, closestParent } from '../utils/util.js'
+import { extend, queryAll, closest } from '../utils/util.js'
import { isMobile } from '../utils/device.js'
/**
@@ -240,7 +240,7 @@ export default class SlideContent {
// HTML5 media elements
queryAll( element, 'video, audio' ).forEach( el => {
- if( closestParent( el, '.fragment' ) && !closestParent( el, '.fragment.visible' ) ) {
+ if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
return;
}
@@ -250,7 +250,7 @@ export default class SlideContent {
// If no global setting is available, fall back on the element's
// own autoplay setting
if( typeof autoplay !== 'boolean' ) {
- autoplay = el.hasAttribute( 'data-autoplay' ) || !!closestParent( el, '.slide-background' );
+ autoplay = el.hasAttribute( 'data-autoplay' ) || !!closest( el, '.slide-background' );
}
if( autoplay && typeof el.play === 'function' ) {
@@ -288,7 +288,7 @@ export default class SlideContent {
// Normal iframes
queryAll( element, 'iframe[src]' ).forEach( el => {
- if( closestParent( el, '.fragment' ) && !closestParent( el, '.fragment.visible' ) ) {
+ if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
return;
}
@@ -297,7 +297,7 @@ export default class SlideContent {
// Lazy loading iframes
queryAll( element, 'iframe[data-src]' ).forEach( el => {
- if( closestParent( el, '.fragment' ) && !closestParent( el, '.fragment.visible' ) ) {
+ if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
return;
}
@@ -320,8 +320,8 @@ export default class SlideContent {
*/
startEmbeddedMedia( event ) {
- let isAttachedToDOM = !!closestParent( event.target, 'html' ),
- isVisible = !!closestParent( event.target, '.present' );
+ let isAttachedToDOM = !!closest( event.target, 'html' ),
+ isVisible = !!closest( event.target, '.present' );
if( isAttachedToDOM && isVisible ) {
event.target.currentTime = 0;
@@ -344,8 +344,8 @@ export default class SlideContent {
if( iframe && iframe.contentWindow ) {
- let isAttachedToDOM = !!closestParent( event.target, 'html' ),
- isVisible = !!closestParent( event.target, '.present' );
+ let isAttachedToDOM = !!closest( event.target, 'html' ),
+ isVisible = !!closest( event.target, '.present' );
if( isAttachedToDOM && isVisible ) {
@@ -355,7 +355,7 @@ export default class SlideContent {
// If no global setting is available, fall back on the element's
// own autoplay setting
if( typeof autoplay !== 'boolean' ) {
- autoplay = iframe.hasAttribute( 'data-autoplay' ) || !!closestParent( iframe, '.slide-background' );
+ autoplay = iframe.hasAttribute( 'data-autoplay' ) || !!closest( iframe, '.slide-background' );
}
// YouTube postMessage API
diff --git a/js/reveal.js b/js/reveal.js
index 7c3c7f9..4807369 100644
--- a/js/reveal.js
+++ b/js/reveal.js
@@ -148,7 +148,7 @@ export default function( revealElement, options ) {
// Embedded decks use the reveal element as their viewport
if( config.embedded === true ) {
- dom.viewport = revealElement.closest( '.reveal-viewport' ) || revealElement;
+ dom.viewport = Util.closest( revealElement, '.reveal-viewport' ) || revealElement;
}
// Full-page decks use the body as their viewport
else {
diff --git a/js/utils/util.js b/js/utils/util.js
index 392ca72..68ff085 100644
--- a/js/utils/util.js
+++ b/js/utils/util.js
@@ -94,14 +94,10 @@ export const transformElement = ( element, transform ) => {
*
* @return {Boolean}
*/
-export const matchesSelector = ( target, selector ) => {
+export const matches = ( target, selector ) => {
- // There's some overhead doing this each time, we don't
- // want to rewrite the element prototype but should still
- // be enough to feature detect once at startup...
- let matchesMethod = parent.matches || parent.matchesSelector || parent.msMatchesSelector;
+ let matchesMethod = target.matches || target.matchesSelector || target.msMatchesSelector;
- // If we find a match, we're all set
return !!( matchesMethod && matchesMethod.call( target, selector ) );
}
@@ -117,20 +113,21 @@ export const matchesSelector = ( target, selector ) => {
* @return {HTMLElement} The matched parent or null
* if no matching parent was found
*/
-export const closestParent = ( target, selector ) => {
+export const closest = ( target, selector ) => {
- let parent = target.parentNode;
-
- while( parent ) {
+ // Native Element.closest
+ if( typeof target.closest === 'function' ) {
+ return target.closest( selector );
+ }
- // If we find a match, we're all set
- if( matchesSelector( parent, selector ) ) {
- return parent;
+ // Polyfill
+ while( target ) {
+ if( matches( target, selector ) ) {
+ return target;
}
// Keep searching
- parent = parent.parentNode;
-
+ target = target.parentNode;
}
return null;