|
|
@ -133,7 +133,7 @@ jwE50AGjLCVuS8Yt4H7OgZLKK5EKOsLviEWJSL/+0uMi7gLUSBseYwqEbXvSHCec1CJvZPyHCmYQffaB |
|
|
|
display: inline-block; |
|
|
|
float: right; |
|
|
|
vertical-align: top; |
|
|
|
margin-top: 30px; |
|
|
|
margin-top: 15px; |
|
|
|
margin-right: 20px; |
|
|
|
} |
|
|
|
|
|
|
@ -148,6 +148,21 @@ jwE50AGjLCVuS8Yt4H7OgZLKK5EKOsLviEWJSL/+0uMi7gLUSBseYwqEbXvSHCec1CJvZPyHCmYQffaB |
|
|
|
font-family: 'Lucida Console', Monaco, monospace; |
|
|
|
outline: none; |
|
|
|
} |
|
|
|
|
|
|
|
input[type=button] { |
|
|
|
background-color: lightgray; |
|
|
|
border: 4px solid darkgray; |
|
|
|
color: black; |
|
|
|
text-decoration: none; |
|
|
|
cursor: pointer; |
|
|
|
width: 140px; |
|
|
|
height: 50px; |
|
|
|
} |
|
|
|
|
|
|
|
input[type=button]:hover { |
|
|
|
background-color: #f5f5f5ff; |
|
|
|
border-color: black; |
|
|
|
} |
|
|
|
</style> |
|
|
|
</head> |
|
|
|
<body> |
|
|
@ -158,7 +173,8 @@ jwE50AGjLCVuS8Yt4H7OgZLKK5EKOsLviEWJSL/+0uMi7gLUSBseYwqEbXvSHCec1CJvZPyHCmYQffaB |
|
|
|
<div class="emscripten" id="status">Downloading...</div> |
|
|
|
|
|
|
|
<span id='controls'> |
|
|
|
<span><input type="button" value="Fullscreen" onclick="Module.requestFullscreen(false, false)"></span> |
|
|
|
<span><input type="button" value="🖵 FULLSCREEN" onclick="Module.requestFullscreen(false, false)"></span> |
|
|
|
<span><input type="button" id="btn-audio" value="🔇 SUSPEND" onclick="toggleAudio()"></span> |
|
|
|
</span> |
|
|
|
|
|
|
|
<div class="emscripten"> |
|
|
@ -174,7 +190,7 @@ jwE50AGjLCVuS8Yt4H7OgZLKK5EKOsLviEWJSL/+0uMi7gLUSBseYwqEbXvSHCec1CJvZPyHCmYQffaB |
|
|
|
|
|
|
|
<script type='text/javascript' src="https://cdn.jsdelivr.net/gh/eligrey/FileSaver.js/dist/FileSaver.min.js"> </script> |
|
|
|
<script type='text/javascript'> |
|
|
|
function SaveFileFromMEMFSToDisk(memoryFSname, localFSname) // This can be called by C/C++ code |
|
|
|
function saveFileFromMEMFSToDisk(memoryFSname, localFSname) // This can be called by C/C++ code |
|
|
|
{ |
|
|
|
var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); |
|
|
|
var data = FS.readFile(memoryFSname); |
|
|
@ -183,10 +199,10 @@ jwE50AGjLCVuS8Yt4H7OgZLKK5EKOsLviEWJSL/+0uMi7gLUSBseYwqEbXvSHCec1CJvZPyHCmYQffaB |
|
|
|
if (isSafari) blob = new Blob([data.buffer], { type: "application/octet-stream" }); |
|
|
|
else blob = new Blob([data.buffer], { type: "application/octet-binary" }); |
|
|
|
|
|
|
|
// NOTE: SaveAs Dialog is a browser setting. For example, in Google Chrome, |
|
|
|
// NOTE: SaveAsDialog is a browser setting. For example, in Google Chrome, |
|
|
|
// in Settings/Advanced/Downloads section you have a setting: |
|
|
|
// 'Ask where to save each file before downloading' - which you can set true/false. |
|
|
|
// If you enable this setting it would always ask you and bring the SaveAs Dialog |
|
|
|
// If you enable this setting it would always ask you and bring the SaveAsDialog |
|
|
|
saveAs(blob, localFSname); |
|
|
|
} |
|
|
|
</script> |
|
|
@ -276,46 +292,35 @@ jwE50AGjLCVuS8Yt4H7OgZLKK5EKOsLviEWJSL/+0uMi7gLUSBseYwqEbXvSHCec1CJvZPyHCmYQffaB |
|
|
|
}; |
|
|
|
</script> |
|
|
|
|
|
|
|
<!-- NOTE: This code snippet displays a button that resumes blocked AudioContexts by |
|
|
|
the autoplay policy. For more detail on the autoplay change in Chrome, check: |
|
|
|
https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#webaudio. --> |
|
|
|
<!-- REF: https://developers.google.com/web/updates/2018/11/web-audio-autoplay --> |
|
|
|
<script type='text/javascript'> |
|
|
|
/* |
|
|
|
* Copyright 2018 Google Inc. All Rights Reserved. |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 |
|
|
|
* Unless required by applicable law or agreed to in writing, software |
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
|
|
* See the License for the specific language governing permissions and |
|
|
|
* limitations under the License. |
|
|
|
*/ |
|
|
|
var audioBtn = document.querySelector('#btn-audio'); |
|
|
|
|
|
|
|
// An array of all contexts to resume on the page |
|
|
|
const audioContexList = []; |
|
|
|
(function() { |
|
|
|
const list = []; |
|
|
|
// A proxy object to intercept AudioContexts and |
|
|
|
// add them to the array for tracking and resuming later |
|
|
|
self.AudioContext = new Proxy(self.AudioContext, { |
|
|
|
construct(target, args) { |
|
|
|
const result = new target(...args); |
|
|
|
list.push(result); |
|
|
|
audioContexList.push(result); |
|
|
|
if (result.state == "suspended") audioBtn.value = "🔈 RESUME"; |
|
|
|
return result; |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
}); |
|
|
|
})(); |
|
|
|
|
|
|
|
const btn = document.createElement('button'); |
|
|
|
|
|
|
|
btn.classList.add('unmute'); |
|
|
|
btn.style.position = 'fixed'; |
|
|
|
btn.style.bottom = '0'; |
|
|
|
btn.style.right = '0'; |
|
|
|
btn.textContent = '🔇 Unmute'; |
|
|
|
btn.style.fontSize = '5em'; |
|
|
|
btn.onclick = e => { |
|
|
|
list.forEach(ctx => ctx.resume()); |
|
|
|
btn.remove(); |
|
|
|
}; |
|
|
|
function toggleAudio() { |
|
|
|
var resumed = false; |
|
|
|
audioContexList.forEach(ctx => { |
|
|
|
if (ctx.state == "suspended") { ctx.resume(); resumed = true; } |
|
|
|
else if (ctx.state == "running") ctx.suspend(); |
|
|
|
}); |
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', _ => { document.body.appendChild(btn); }); |
|
|
|
})(); |
|
|
|
if (resumed) audioBtn.value = "🔇 SUSPEND"; |
|
|
|
else audioBtn.value = "🔈 RESUME"; |
|
|
|
} |
|
|
|
</script> |
|
|
|
{{{ SCRIPT }}} |
|
|
|
</body> |
|
|
|