|
57 | 57 | e.stopPropagation(); |
58 | 58 | }); |
59 | 59 | </script> |
| 60 | + |
| 61 | + <script> |
| 62 | + document.body.addEventListener("contextmenu", (e) => { |
| 63 | + e.preventDefault(); |
| 64 | + e.stopPropagation(); |
| 65 | + }); |
| 66 | + |
| 67 | + // Insert hack to make sound autoplay on Chrome as soon as the user interacts with the tab: |
| 68 | + // https://developers.google.com/web/updates/2018/11/web-audio-autoplay#moving-forward |
| 69 | + |
| 70 | + // the following function keeps track of all AudioContexts and resumes them on the first user |
| 71 | + // interaction with the page. If the function is called and all contexts are already running, |
| 72 | + // it will remove itself from all event listeners. |
| 73 | + (function () { |
| 74 | + // An array of all contexts to resume on the page |
| 75 | + const audioContextList = []; |
| 76 | + |
| 77 | + // An array of various user interaction events we should listen for |
| 78 | + const userInputEventNames = [ |
| 79 | + "click", |
| 80 | + "contextmenu", |
| 81 | + "auxclick", |
| 82 | + "dblclick", |
| 83 | + "mousedown", |
| 84 | + "mouseup", |
| 85 | + "pointerup", |
| 86 | + "touchend", |
| 87 | + "keydown", |
| 88 | + "keyup", |
| 89 | + ]; |
| 90 | + |
| 91 | + // A proxy object to intercept AudioContexts and |
| 92 | + // add them to the array for tracking and resuming later |
| 93 | + self.AudioContext = new Proxy(self.AudioContext, { |
| 94 | + construct(target, args) { |
| 95 | + const result = new target(...args); |
| 96 | + audioContextList.push(result); |
| 97 | + return result; |
| 98 | + }, |
| 99 | + }); |
| 100 | + |
| 101 | + // To resume all AudioContexts being tracked |
| 102 | + function resumeAllContexts(_event) { |
| 103 | + let count = 0; |
| 104 | + |
| 105 | + audioContextList.forEach((context) => { |
| 106 | + if (context.state !== "running") { |
| 107 | + context.resume(); |
| 108 | + } else { |
| 109 | + count++; |
| 110 | + } |
| 111 | + }); |
| 112 | + |
| 113 | + // If all the AudioContexts have now resumed then we unbind all |
| 114 | + // the event listeners from the page to prevent unnecessary resume attempts |
| 115 | + // Checking count > 0 ensures that the user interaction happens AFTER the game started up |
| 116 | + if (count > 0 && count === audioContextList.length) { |
| 117 | + userInputEventNames.forEach((eventName) => { |
| 118 | + document.removeEventListener(eventName, resumeAllContexts); |
| 119 | + }); |
| 120 | + } |
| 121 | + } |
| 122 | + |
| 123 | + // We bind the resume function for each user interaction |
| 124 | + // event on the page |
| 125 | + userInputEventNames.forEach((eventName) => { |
| 126 | + document.addEventListener(eventName, resumeAllContexts); |
| 127 | + }); |
| 128 | + })(); |
| 129 | + </script> |
60 | 130 | </body> |
61 | 131 |
|
62 | 132 | </html> |
0 commit comments