From 8b14eda98fd3b8de7e541888fc431072df751e51 Mon Sep 17 00:00:00 2001 From: Henrik Ingo Date: Mon, 1 Jan 2018 16:03:13 +0200 Subject: [PATCH] Broader try-catch for handling impress-console-button disappearance (#652) The previous attempt at merely reading a property of event.target was incorrect. It worked at first but errors reappeared later, so must have been a reace. This wraps the entire navigation event handlers in the try-catch, and then checks for the very specific error and suppresses it. Other errors are rethrown as is. --- js/impress.js | 77 ++++++++++++++++------------ src/plugins/navigation/navigation.js | 77 ++++++++++++++++------------ 2 files changed, 86 insertions(+), 68 deletions(-) diff --git a/js/impress.js b/js/impress.js index cd2a87d..3032780 100644 --- a/js/impress.js +++ b/js/impress.js @@ -2965,33 +2965,35 @@ // check if event target (or any of its parents is a link) var target = event.target; try { + while ( ( target.tagName !== "A" ) && + ( target !== document.documentElement ) ) { + target = target.parentNode; + } + + if ( target.tagName === "A" ) { + var href = target.getAttribute( "href" ); + + // If it's a link to presentation step, target this step + if ( href && href[ 0 ] === "#" ) { + target = document.getElementById( href.slice( 1 ) ); + } + } + + if ( api.goto( target ) ) { + event.stopImmediatePropagation(); + event.preventDefault(); + } + } + catch ( err ) { // For example, when clicking on the button to launch speaker console, the button // is immediately deleted from the DOM. In this case target is a DOM element when // we get it, but turns out to be null if you try to actually do anything with it. - var foo = target.id; // jshint ignore:line - } - catch ( err ) { - return; - } - - while ( ( target.tagName !== "A" ) && - ( target !== document.documentElement ) ) { - target = target.parentNode; - } - - if ( target.tagName === "A" ) { - var href = target.getAttribute( "href" ); - - // If it's a link to presentation step, target this step - if ( href && href[ 0 ] === "#" ) { - target = document.getElementById( href.slice( 1 ) ); + if ( err instanceof TypeError && + err.message === "target is null" ) { + return; } - } - - if ( api.goto( target ) ) { - event.stopImmediatePropagation(); - event.preventDefault(); + throw err; } }, false ); @@ -2999,21 +3001,28 @@ gc.addEventListener( document, "click", function( event ) { var target = event.target; try { - var foo = target.id; // jshint ignore:line + + // Find closest step element that is not active + while ( !( target.classList.contains( "step" ) && + !target.classList.contains( "active" ) ) && + ( target !== document.documentElement ) ) { + target = target.parentNode; + } + + if ( api.goto( target ) ) { + event.preventDefault(); + } } catch ( err ) { - return; - } - // Find closest step element that is not active - while ( !( target.classList.contains( "step" ) && - !target.classList.contains( "active" ) ) && - ( target !== document.documentElement ) ) { - target = target.parentNode; - } - - if ( api.goto( target ) ) { - event.preventDefault(); + // For example, when clicking on the button to launch speaker console, the button + // is immediately deleted from the DOM. In this case target is a DOM element when + // we get it, but turns out to be null if you try to actually do anything with it. + if ( err instanceof TypeError && + err.message === "target is null" ) { + return; + } + throw err; } }, false ); diff --git a/src/plugins/navigation/navigation.js b/src/plugins/navigation/navigation.js index 477e123..3c2a7bc 100644 --- a/src/plugins/navigation/navigation.js +++ b/src/plugins/navigation/navigation.js @@ -125,33 +125,35 @@ // check if event target (or any of its parents is a link) var target = event.target; try { + while ( ( target.tagName !== "A" ) && + ( target !== document.documentElement ) ) { + target = target.parentNode; + } + + if ( target.tagName === "A" ) { + var href = target.getAttribute( "href" ); + + // If it's a link to presentation step, target this step + if ( href && href[ 0 ] === "#" ) { + target = document.getElementById( href.slice( 1 ) ); + } + } + + if ( api.goto( target ) ) { + event.stopImmediatePropagation(); + event.preventDefault(); + } + } + catch ( err ) { // For example, when clicking on the button to launch speaker console, the button // is immediately deleted from the DOM. In this case target is a DOM element when // we get it, but turns out to be null if you try to actually do anything with it. - var foo = target.id; // jshint ignore:line - } - catch ( err ) { - return; - } - - while ( ( target.tagName !== "A" ) && - ( target !== document.documentElement ) ) { - target = target.parentNode; - } - - if ( target.tagName === "A" ) { - var href = target.getAttribute( "href" ); - - // If it's a link to presentation step, target this step - if ( href && href[ 0 ] === "#" ) { - target = document.getElementById( href.slice( 1 ) ); + if ( err instanceof TypeError && + err.message === "target is null" ) { + return; } - } - - if ( api.goto( target ) ) { - event.stopImmediatePropagation(); - event.preventDefault(); + throw err; } }, false ); @@ -159,21 +161,28 @@ gc.addEventListener( document, "click", function( event ) { var target = event.target; try { - var foo = target.id; // jshint ignore:line + + // Find closest step element that is not active + while ( !( target.classList.contains( "step" ) && + !target.classList.contains( "active" ) ) && + ( target !== document.documentElement ) ) { + target = target.parentNode; + } + + if ( api.goto( target ) ) { + event.preventDefault(); + } } catch ( err ) { - return; - } - // Find closest step element that is not active - while ( !( target.classList.contains( "step" ) && - !target.classList.contains( "active" ) ) && - ( target !== document.documentElement ) ) { - target = target.parentNode; - } - - if ( api.goto( target ) ) { - event.preventDefault(); + // For example, when clicking on the button to launch speaker console, the button + // is immediately deleted from the DOM. In this case target is a DOM element when + // we get it, but turns out to be null if you try to actually do anything with it. + if ( err instanceof TypeError && + err.message === "target is null" ) { + return; + } + throw err; } }, false );