Permalink
Browse files

Modify keypress navigation to only work when focus is on body or html…

… element.

This is to allow presentations to have, for example, form elements, where
users can type text, including spaces, use arrows, etc.

Exception: TAB will always cause navigation to next step.

Adds new Form plugin, which blurs() focus on impress:stepleave. This is to
prevent an input field from being focused when it is no longer visible.
  • Loading branch information...
henrikingo committed Aug 14, 2016
1 parent 527d207 commit b7024817395d06222aa576d357be46b1482baf54
View
@@ -6,6 +6,7 @@ buildify()
.concat(['src/plugins/autoplay/autoplay.js',
'src/plugins/blackout/blackout.js',
'src/plugins/extras/extras.js',
'src/plugins/form/form.js',
'src/plugins/goto/goto.js',
'src/plugins/mouse-timeout/mouse-timeout.js',
'src/plugins/mobile/mobile.js',
@@ -360,7 +360,52 @@ body.impress-mouse-timeout {
opacity: 0.6;
}
/*
Styles for specific slides.
*/
/* The bar graph for Acme Inc profits */
#acme-graph-bottom {
position: absolute;
bottom: 100px;
left: 440px;
background-color: black;
width: 410px;
height: 2px;
}
/* height: is set from javascript */
#acme-graph-q1,
#acme-graph-q2,
#acme-graph-q3,
#acme-graph-q4 {
border: solid 1px black;
width: 70px;
margin-left: 10px;
position: absolute;
bottom: 100px;
}
#acme-graph-q1 {
background-color: red;
left: 450px;
}
#acme-graph-q2 {
background-color: blue;
left: 550px;
}
#acme-graph-q3 {
background-color: green;
left: 650px;
}
#acme-graph-q4 {
background-color: purple;
left: 750px;
}
/*
And as the last thing there is a workaround for quite strange bug.
@@ -325,11 +325,74 @@ <h1>Mermaid.js</h1>
* [A more advanced Markdown presentation is here.](../markdown/)
</div>
<div id="acme" class="step slide" data-rel-x="300" data-rel-y="-1100" data-rotate="300">
<ul>
<li>Remember, in <em>impress.js</em> the full power of HTML5, CSS3 &amp; JavaScript is always at your fingertips!</li>
<li>For example, you can use tables, forms, or dynamic charts as you would on any web page:</li>
</ul>
<h2>Acme Inc Quarterly Profits</h2>
<!-- Improvised bar graph of divs, to avoid copying something like NVD3 into the repo. -->
<div id="acme-graph">
<div id="acme-graph-bars">
<div id="acme-graph-q1"></div>
<div id="acme-graph-q2"></div>
<div id="acme-graph-q3"></div>
<div id="acme-graph-q4"></div>
</div>
<div id="acme-graph-bottom"></div>
</div>
<table border="1">
<tr><td>Q1</td><td id="acme-q1">234€</td></tr>
<tr><td>Q2</td><td id="acme-q2">255€</td></tr>
<tr><td>Q3</td><td><input id="acme-q3" size="5" oninput="acmeDrawGraph();" />€ <small>(insert here)</small></td></tr>
<tr><td>Q4</td><td><input id="acme-q4" size="5" oninput="acmeDrawGraph();" />€</td></tr>
</table>
<div class="notes">
</div>
</div>
<script type="text/javascript">
var acmeDrawGraph = function() {
var profits = {};
// Q1-Q2: get innerHTML, remove €
var value = document.getElementById('acme-q1').innerHTML;
if( value[value.length-1] == "" ) value = value.substring(0, value.length-1);
profits['q1'] = value;
var value = document.getElementById('acme-q2').innerHTML;
if( value[value.length-1] == "" ) value = value.substring(0, value.length-1);
profits['q2'] = value;
// Q3-Q4: get input.value
profits['q3'] = document.getElementById('acme-q3').value;
profits['q4'] = document.getElementById('acme-q4').value;
// Convert all to numeric value, and remember max value for scaling purposes.
var max = profits['q1'];
for ( var q in profits ) {
profits[q] = isNaN(profits[q]) ? 0 : Number(profits[q]);
if( profits[q] > max ) {
max = profits[q];
}
}
// Draw the bar graph
for ( var q in profits ) {
var h = 200 * profits[q] / max;
var div = document.getElementById('acme-graph-'+q);
div.style = 'height: ' + h + 'px';
}
};
// This draws the first 2 bars during page load
acmeDrawGraph();
</script>
<!--
Finally, the relative positioning plugin also supports values that are a multiple of the windows size.
Add "w" or "h" to specify a multiple of window width or height, respectively.
-->
<div id="moreinfo" class="step slide" data-rel-x="1.5w" data-rel-y="-0.3w" data-rotate="720">
<div id="moreinfo" class="step slide" data-rel-x="1.4w" data-rel-y="0.8w" data-rotate="720">
<h1>More info</h1>
<ul>
<li>Official documentation
View
@@ -1149,6 +1149,28 @@
})(document, window);
/**
* Form support
*
* Functionality to better support use of input, textarea, button... elements in a presentation.
*
* Currently this does only one single thing: On impress:stepleave, de-focus any potentially active element.
* This is to prevent the focus from being left in a form element that is no longer visible in the window, and
* user therefore typing garbage into the form.
*
* Copyright 2016 Henrik Ingo
* MIT License
*/
(function ( document, window ) {
'use strict';
document.addEventListener("impress:stepleave", function (event) {
document.activeElement.blur()
}, false);
})(document, window);
/**
* Goto Plugin
*
@@ -1406,18 +1428,8 @@
// or anything. `impress:init` event data gives you everything you
// need to control the presentation that was just initialized.
var api = event.detail.api;
// KEYBOARD NAVIGATION HANDLERS
// Prevent default keydown action when one of supported key is pressed.
document.addEventListener("keydown", function ( event ) {
if ( event.keyCode === 9 || ( event.keyCode >= 32 && event.keyCode <= 34 ) || (event.keyCode >= 37 && event.keyCode <= 40) ) {
event.preventDefault();
}
}, false);
// Trigger impress action (next or prev) on keyup.
var tab = 9;
// Supported keys are:
// [space] - quite common in presentation software to move forward
// [up] [right] / [down] [left] - again common and natural addition,
@@ -1431,13 +1443,42 @@
// positioning. I didn't want to just prevent this default action, so I used [tab]
// as another way to moving to next step... And yes, I know that for the sake of
// consistency I should add [shift+tab] as opposite action...
document.addEventListener("keyup", function ( event ) {
var isNavigationEvent = function (event) {
// Don't trigger navigation for example when user returns to browser window with ALT+TAB
if ( event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ){
return;
return false;
}
// In the case of TAB, we force step navigation always, overriding the browser navigation between
// input elements, buttons and links.
if ( event.keyCode === 9 ) {
return true;
}
if ( event.keyCode === 9 || ( event.keyCode >= 32 && event.keyCode <= 34 ) || (event.keyCode >= 37 && event.keyCode <= 40) ) {
// For arrows, etc, check that event target is html or body element. This is to allow presentations to have,
// for example, forms with input elements where user can type text, including space, and not move to next step.
if ( event.target.nodeName != "BODY" && event.target.nodeName != "HTML" ) {
return false;
}
if ( ( event.keyCode >= 32 && event.keyCode <= 34 ) || (event.keyCode >= 37 && event.keyCode <= 40 ) ) {
return true;
}
};
// KEYBOARD NAVIGATION HANDLERS
// Prevent default keydown action when one of supported key is pressed.
document.addEventListener("keydown", function ( event ) {
if ( isNavigationEvent(event) ) {
event.preventDefault();
}
}, false);
// Trigger impress action (next or prev) on keyup.
document.addEventListener("keyup", function ( event ) {
if ( isNavigationEvent(event) ) {
switch( event.keyCode ) {
case 33: // pg up
case 37: // left
@@ -1452,7 +1493,6 @@
api.next();
break;
}
event.preventDefault();
}
}, false);
@@ -1716,7 +1756,6 @@
} else {
var value = parseFloat(ratio[1]);
var multiplier = ratio[2] == 'w' ? window.innerWidth : window.innerHeight;
console.log(value*multiplier);
return value * multiplier;
}
};
View
@@ -0,0 +1,26 @@
/**
* Form support
*
* Functionality to better support use of input, textarea, button... elements in a presentation.
*
* Currently this does only one single thing: On impress:stepleave, de-focus any potentially active element.
* This is to prevent the focus from being left in a form element that is no longer visible in the window, and
* user therefore typing garbage into the form.
*
* TODO: Currently it is not possible to use TAB to navigate between form elements. Impress.js, and in particular the
* navigation plugin, unfortunately must fully take control of the tab key, otherwise a user could cause
* the browser to scroll to a link or button that's not on the current step. However, it could be possible to allow
* tab navigation between form elements, as long as they are on the active step. This is a topic for further study.
*
* Copyright 2016 Henrik Ingo
* MIT License
*/
(function ( document, window ) {
'use strict';
document.addEventListener("impress:stepleave", function (event) {
document.activeElement.blur()
}, false);
})(document, window);
@@ -44,18 +44,8 @@
// or anything. `impress:init` event data gives you everything you
// need to control the presentation that was just initialized.
var api = event.detail.api;
// KEYBOARD NAVIGATION HANDLERS
// Prevent default keydown action when one of supported key is pressed.
document.addEventListener("keydown", function ( event ) {
if ( event.keyCode === 9 || ( event.keyCode >= 32 && event.keyCode <= 34 ) || (event.keyCode >= 37 && event.keyCode <= 40) ) {
event.preventDefault();
}
}, false);
// Trigger impress action (next or prev) on keyup.
var tab = 9;
// Supported keys are:
// [space] - quite common in presentation software to move forward
// [up] [right] / [down] [left] - again common and natural addition,
@@ -69,13 +59,42 @@
// positioning. I didn't want to just prevent this default action, so I used [tab]
// as another way to moving to next step... And yes, I know that for the sake of
// consistency I should add [shift+tab] as opposite action...
document.addEventListener("keyup", function ( event ) {
var isNavigationEvent = function (event) {
// Don't trigger navigation for example when user returns to browser window with ALT+TAB
if ( event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ){
return;
return false;
}
// In the case of TAB, we force step navigation always, overriding the browser navigation between
// input elements, buttons and links.
if ( event.keyCode === 9 ) {
return true;
}
if ( event.keyCode === 9 || ( event.keyCode >= 32 && event.keyCode <= 34 ) || (event.keyCode >= 37 && event.keyCode <= 40) ) {
// For arrows, etc, check that event target is html or body element. This is to allow presentations to have,
// for example, forms with input elements where user can type text, including space, and not move to next step.
if ( event.target.nodeName != "BODY" && event.target.nodeName != "HTML" ) {
return false;
}
if ( ( event.keyCode >= 32 && event.keyCode <= 34 ) || (event.keyCode >= 37 && event.keyCode <= 40 ) ) {
return true;
}
};
// KEYBOARD NAVIGATION HANDLERS
// Prevent default keydown action when one of supported key is pressed.
document.addEventListener("keydown", function ( event ) {
if ( isNavigationEvent(event) ) {
event.preventDefault();
}
}, false);
// Trigger impress action (next or prev) on keyup.
document.addEventListener("keyup", function ( event ) {
if ( isNavigationEvent(event) ) {
switch( event.keyCode ) {
case 33: // pg up
case 37: // left
@@ -90,7 +109,6 @@
api.next();
break;
}
event.preventDefault();
}
}, false);
View
@@ -68,7 +68,6 @@
} else {
var value = parseFloat(ratio[1]);
var multiplier = ratio[2] == 'w' ? window.innerWidth : window.innerHeight;
console.log(value*multiplier);
return value * multiplier;
}
};

0 comments on commit b702481

Please sign in to comment.