Thanks to @GuyIncognito's comment, here's my (minimal) solution.
( function () {
'use strict';
function onChange() {
// just a status update, nothing real
alert( 'contents overwritten' );
}
function onClickDialog( e ) {
if ( e.target.id === 'OK' ) {
// pass the click along
document.getElementById( 'input' ).click();
}
// re-hide the dialog
document.getElementById( 'modal' ).classList = 'hidden';
}
function onClickFile() {
// unhide the dialog
document.getElementById( 'modal' ).classList = '';
}
function onContentLoaded() {
document.getElementById( 'button' ).addEventListener( 'click', onClickFile );
document.getElementById( 'OK' ).addEventListener( 'click', onClickDialog );
document.getElementById( 'Cancel' ).addEventListener( 'click', onClickDialog );
document.getElementById( 'input' ).addEventListener( 'change', onChange )
}
document.addEventListener( 'DOMContentLoaded', onContentLoaded, { once: true } );
} () );
button {
font-size: inherit;
}
input,
.hidden {
display: none;
}
#modal {
background-color: #0001;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
#dialog {
background-color: #fff;
display: inline-block;
left: 50%;
padding: 1em;
position: relative;
top:50%;
transform: translate( -50%, -50% );
}
<!DOCTYPE html><html lang="en"><head>
<title>Stack Overflow QA</title>
<link rel="stylesheet" href="page.css">
<script src="page.js"></script>
</head><body>
<div id="modal" class="hidden"><div id="dialog">
<p>There are unsaved changes.</p>
<p>Is it OK to discard the changes?</p>
<button id="OK">OK</button> <button id="Cancel">Cancel</button>
</div></div>
<button id="button">Open File ...</button>
<input id="input" type="file">
</body></html>