From 219906da467e8f21477f023b4dcf8a9e9480fec6 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Tue, 14 Jul 2026 10:22:21 -0700 Subject: [PATCH 1/2] Remove legacy vendor-prefixed DOM APIs and fallbacks Remove references to `mozRequestFullScreen`, `msRequestFullscreen`, `mozCancelFullScreen`, `msExitFullscreen`, `cancelFullScreen`, `mozfullscreenchange`, and `MSFullscreenChange` across `libbrowser.js` and `libglfw.js`. Convert bracket notation (`canvasContainer['requestFullscreen']`, `document['exitFullscreen']`) to standard dot notation. In `libhtml5.js`, remove `document.mozFullScreenElement`, `document.webkitCurrentFullScreenElement`, and `document.msFullscreenElement` from `$getFullscreenElement()`, leaving `document.fullscreenElement` and `document.webkitFullscreenElement` (guarded by `MIN_SAFARI_VERSION`). Also remove `screen.mozLockOrientation`, `screen.webkitLockOrientation`, `screen.mozUnlockOrientation`, and `screen.webkitUnlockOrientation` from `emscripten_lock_orientation` and `emscripten_unlock_orientation`. In `libbrowser.js`, `libopenal.js`, and `closure-externs.js`, remove obsolete `mozGetUserMedia`, `msGetUserMedia`, and `webkitGetUserMedia` fallbacks and extern definitions, and transition `getUserMedia` calls from the deprecated callback API (`navigator.getUserMedia`) to standard Promise-based `navigator.mediaDevices.getUserMedia`. These prefixed properties and fallbacks are safe to remove because: 1. Fullscreen, Screen Orientation, and MediaDevices APIs became unprefixed standards across Firefox, Chrome, and Safari years ago (e.g. `requestFullscreen` in Firefox 64 / Chrome 71, `navigator.mediaDevices.getUserMedia` in Chrome 53 / Firefox 38 / Safari 11). Emscripten's minimum supported browser versions (`MIN_FIREFOX_VERSION = 79`, `MIN_CHROME_VERSION = 85`) are well beyond when these unprefixed properties and methods became standard across major engines. 2. IE and legacy Edge (`ms` prefix) and Firefox OS (`moz` prefixes) are no longer supported. 3. Safari < 16.4 still requires `webkit` prefixes for Fullscreen, so `webkitRequestFullscreen`, `webkitExitFullscreen`, `webkitfullscreenchange`, and `webkitFullscreenElement` are retained where appropriate. --- src/closure-externs/closure-externs.js | 16 ---------------- src/lib/libbrowser.js | 22 +++++++--------------- src/lib/libglfw.js | 10 +++------- src/lib/libhtml5.js | 16 +++++----------- src/lib/libopenal.js | 22 +++------------------- 5 files changed, 18 insertions(+), 68 deletions(-) diff --git a/src/closure-externs/closure-externs.js b/src/closure-externs/closure-externs.js index 424ca9ebd4166..53a8c0b3269a8 100644 --- a/src/closure-externs/closure-externs.js +++ b/src/closure-externs/closure-externs.js @@ -183,22 +183,6 @@ var devicePixelRatio; */ var id; -/** - * This was removed from upstream closure compiler in - * https://github.com/google/closure-compiler/commit/f83322c1b. - * Perhaps we should remove it too? - * - * @param {MediaStreamConstraints} constraints A MediaStreamConstraints object. - * @param {function(!MediaStream)} successCallback - * A NavigatorUserMediaSuccessCallback function. - * @param {function(!NavigatorUserMediaError)=} errorCallback A - * NavigatorUserMediaErrorCallback function. - * @see http://dev.w3.org/2011/webrtc/editor/getusermedia.html - * @see https://www.w3.org/TR/mediacapture-streams/ - * @return {undefined} - */ -Navigator.prototype.webkitGetUserMedia = function( - constraints, successCallback, errorCallback) {}; // Common between node-externs and v8-externs var os = {}; diff --git a/src/lib/libbrowser.js b/src/lib/libbrowser.js index f5cbbfa506ee2..da403d5bb15cc 100644 --- a/src/lib/libbrowser.js +++ b/src/lib/libbrowser.js @@ -259,9 +259,7 @@ var LibraryBrowser = { if (!Browser.fullscreenHandlersInstalled) { Browser.fullscreenHandlersInstalled = true; document.addEventListener('fullscreenchange', fullscreenChange); - document.addEventListener('mozfullscreenchange', fullscreenChange); document.addEventListener('webkitfullscreenchange', fullscreenChange); - document.addEventListener('MSFullscreenChange', fullscreenChange); } // create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root @@ -270,11 +268,9 @@ var LibraryBrowser = { canvasContainer.appendChild(canvas); // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size) - canvasContainer.requestFullscreen = canvasContainer['requestFullscreen'] || - canvasContainer['mozRequestFullScreen'] || - canvasContainer['msRequestFullscreen'] || - (canvasContainer['webkitRequestFullscreen'] ? () => canvasContainer['webkitRequestFullscreen'](Element['ALLOW_KEYBOARD_INPUT']) : null) || - (canvasContainer['webkitRequestFullScreen'] ? () => canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) : null); + canvasContainer.requestFullscreen = canvasContainer.requestFullscreen || + (canvasContainer.webkitRequestFullscreen ? () => canvasContainer.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT) : null) || + (canvasContainer.webkitRequestFullScreen ? () => canvasContainer.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT) : null); canvasContainer.requestFullscreen(); }, @@ -293,11 +289,9 @@ var LibraryBrowser = { return false; } - var CFS = document['exitFullscreen'] || - document['cancelFullScreen'] || - document['mozCancelFullScreen'] || - document['msExitFullscreen'] || - document['webkitCancelFullScreen'] || + var CFS = document.exitFullscreen || + document.webkitExitFullscreen || + document.webkitCancelFullScreen || (() => {}); CFS.apply(document, []); return true; @@ -325,9 +319,7 @@ var LibraryBrowser = { }, getUserMedia(func) { - window.getUserMedia ||= navigator['getUserMedia'] || - navigator['mozGetUserMedia']; - window.getUserMedia(func); + return navigator.mediaDevices.getUserMedia(func); }, // Browsers specify wheel direction according to the page CSS pixel Y direction: diff --git a/src/lib/libglfw.js b/src/lib/libglfw.js index c6f5d1d09d803..b999b72c46f48 100644 --- a/src/lib/libglfw.js +++ b/src/lib/libglfw.js @@ -1252,9 +1252,7 @@ var LibraryGLFW = { if (!Browser.fullscreenHandlersInstalled) { Browser.fullscreenHandlersInstalled = true; document.addEventListener('fullscreenchange', fullscreenChange); - document.addEventListener('mozfullscreenchange', fullscreenChange); document.addEventListener('webkitfullscreenchange', fullscreenChange); - document.addEventListener('MSFullscreenChange', fullscreenChange); } // create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root @@ -1263,11 +1261,9 @@ var LibraryGLFW = { canvasContainer.appendChild(canvas); // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size) - canvasContainer.requestFullscreen = canvasContainer['requestFullscreen'] || - canvasContainer['mozRequestFullScreen'] || - canvasContainer['msRequestFullscreen'] || - (canvasContainer['webkitRequestFullscreen'] ? () => canvasContainer['webkitRequestFullscreen'](Element['ALLOW_KEYBOARD_INPUT']) : null) || - (canvasContainer['webkitRequestFullScreen'] ? () => canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) : null); + canvasContainer.requestFullscreen = canvasContainer.requestFullscreen || + (canvasContainer.webkitRequestFullscreen ? () => canvasContainer.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT) : null) || + (canvasContainer.webkitRequestFullScreen ? () => canvasContainer.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT) : null); canvasContainer.requestFullscreen(); }, diff --git a/src/lib/libhtml5.js b/src/lib/libhtml5.js index f5349aab502c6..134e078a3900e 100644 --- a/src/lib/libhtml5.js +++ b/src/lib/libhtml5.js @@ -263,9 +263,11 @@ var LibraryHTML5 = { $getFullscreenElement__internal: true, $getFullscreenElement() { - return document.fullscreenElement || document.mozFullScreenElement || - document.webkitFullscreenElement || document.webkitCurrentFullScreenElement || - document.msFullscreenElement; + return document.fullscreenElement +#if MIN_SAFARI_VERSION != TARGET_NOT_SUPPORTED + || document.webkitFullscreenElement +#endif + ; }, $registerKeyEventCallback__noleakcheck: true, @@ -986,10 +988,6 @@ var LibraryHTML5 = { var succeeded; if (screen.lockOrientation) { succeeded = screen.lockOrientation(orientations); - } else if (screen.mozLockOrientation) { - succeeded = screen.mozLockOrientation(orientations); - } else if (screen.webkitLockOrientation) { - succeeded = screen.webkitLockOrientation(orientations); } else { return {{{ cDefs.EMSCRIPTEN_RESULT_NOT_SUPPORTED }}}; } @@ -1003,10 +1001,6 @@ var LibraryHTML5 = { emscripten_unlock_orientation: () => { if (screen.unlockOrientation) { screen.unlockOrientation(); - } else if (screen.mozUnlockOrientation) { - screen.mozUnlockOrientation(); - } else if (screen.webkitUnlockOrientation) { - screen.webkitUnlockOrientation(); } else { return {{{ cDefs.EMSCRIPTEN_RESULT_NOT_SUPPORTED }}}; } diff --git a/src/lib/libopenal.js b/src/lib/libopenal.js index 41e0106d97979..3070aa6b53fa9 100644 --- a/src/lib/libopenal.js +++ b/src/lib/libopenal.js @@ -1642,15 +1642,7 @@ var LibraryOpenAL = { return 0; } - navigator.getUserMedia = navigator.getUserMedia - || navigator.webkitGetUserMedia - || navigator.mozGetUserMedia - || navigator.msGetUserMedia; - var has_getUserMedia = navigator.getUserMedia - || (navigator.mediaDevices - && navigator.mediaDevices.getUserMedia); - - if (!has_getUserMedia) { + if (!navigator.mediaDevices?.getUserMedia) { #if OPENAL_DEBUG dbg('alcCaptureOpenDevice() cannot capture audio, because your browser lacks a `getUserMedia()` implementation'); #endif @@ -1767,7 +1759,7 @@ var LibraryOpenAL = { var onError = (mediaStreamError) => { newCapture.mediaStreamError = mediaStreamError; #if OPENAL_DEBUG - dbg(`navigator.getUserMedia() errored with: ${mediaStreamError}`); + dbg(`getUserMedia() errored with: ${mediaStreamError}`); #endif }; var onSuccess = (mediaStream) => { @@ -1886,15 +1878,7 @@ var LibraryOpenAL = { }; }; - // The latest way to call getUserMedia() - if (navigator.mediaDevices?.getUserMedia) { - navigator.mediaDevices - .getUserMedia({audio: true}) - .then(onSuccess) - .catch(onError); - } else { // The usual (now deprecated) way - navigator.getUserMedia({audio: true}, onSuccess, onError); - } + navigator.mediaDevices.getUserMedia({audio: true}).then(onSuccess).catch(onError); var id = AL.newId(); AL.captures[id] = newCapture; From 137373d009d8218783840c7079e543e12191c407 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Tue, 14 Jul 2026 11:48:55 -0700 Subject: [PATCH 2/2] feedback --- src/closure-externs/closure-externs.js | 18 +++++++++++++ src/lib/libbrowser.js | 19 ++++++++----- src/lib/libglfw.js | 10 ++++--- src/lib/libhtml5.js | 27 ++++++++++--------- .../test_codesize_hello_dylink_all.json | 4 +-- third_party/wrtcp.js | 9 ++----- 6 files changed, 55 insertions(+), 32 deletions(-) diff --git a/src/closure-externs/closure-externs.js b/src/closure-externs/closure-externs.js index 53a8c0b3269a8..54484b15cca31 100644 --- a/src/closure-externs/closure-externs.js +++ b/src/closure-externs/closure-externs.js @@ -183,6 +183,24 @@ var devicePixelRatio; */ var id; +/** + * This was removed from upstream closure compiler in + * https://github.com/google/closure-compiler/commit/f83322c1b. + * Perhaps we should remove it too? + * + * TODO(sbc): Remove this once SDL2 is updated not to depend on it. + * + * @param {MediaStreamConstraints} constraints A MediaStreamConstraints object. + * @param {function(!MediaStream)} successCallback + * A NavigatorUserMediaSuccessCallback function. + * @param {function(!NavigatorUserMediaError)=} errorCallback A + * NavigatorUserMediaErrorCallback function. + * @see http://dev.w3.org/2011/webrtc/editor/getusermedia.html + * @see https://www.w3.org/TR/mediacapture-streams/ + * @return {undefined} + */ +Navigator.prototype.webkitGetUserMedia = function( + constraints, successCallback, errorCallback) {}; // Common between node-externs and v8-externs var os = {}; diff --git a/src/lib/libbrowser.js b/src/lib/libbrowser.js index da403d5bb15cc..c456eea70277b 100644 --- a/src/lib/libbrowser.js +++ b/src/lib/libbrowser.js @@ -268,10 +268,14 @@ var LibraryBrowser = { canvasContainer.appendChild(canvas); // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size) - canvasContainer.requestFullscreen = canvasContainer.requestFullscreen || - (canvasContainer.webkitRequestFullscreen ? () => canvasContainer.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT) : null) || - (canvasContainer.webkitRequestFullScreen ? () => canvasContainer.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT) : null); +#if MIN_SAFARI_VERSION < 160400 + // Safari didn't support Element.requestFullscreen until 16.4 + // See: https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullscreen + /** @suppress {checkTypes} */ + canvasContainer.requestFullscreen ??= (canvasContainer['webkitRequestFullscreen'] ? () => canvasContainer['webkitRequestFullscreen'](Element.ALLOW_KEYBOARD_INPUT) : null) ?? + (canvasContainer['webkitRequestFullScreen'] ? () => canvasContainer['webkitRequestFullScreen'](Element.ALLOW_KEYBOARD_INPUT) : null); +#endif canvasContainer.requestFullscreen(); }, @@ -289,11 +293,12 @@ var LibraryBrowser = { return false; } - var CFS = document.exitFullscreen || - document.webkitExitFullscreen || - document.webkitCancelFullScreen || - (() => {}); +#if MIN_SAFARI_VERSION < 160400 + var CFS = document.exitFullscreen ?? document['webkitCancelFullScreen']; CFS.apply(document, []); +#else + document.exitFullscreen(); +#endif return true; }, diff --git a/src/lib/libglfw.js b/src/lib/libglfw.js index b999b72c46f48..b03a4561cc158 100644 --- a/src/lib/libglfw.js +++ b/src/lib/libglfw.js @@ -1261,9 +1261,13 @@ var LibraryGLFW = { canvasContainer.appendChild(canvas); // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size) - canvasContainer.requestFullscreen = canvasContainer.requestFullscreen || - (canvasContainer.webkitRequestFullscreen ? () => canvasContainer.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT) : null) || - (canvasContainer.webkitRequestFullScreen ? () => canvasContainer.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT) : null); +#if MIN_SAFARI_VERSION < 160400 + // Safari didn't Element.requestFullscreen support until 16.4 + // See: https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullscreen + /** @suppress {checkTypes} */ + canvasContainer.requestFullscreen ??= (canvasContainer.webkitRequestFullscreen ? () => canvasContainer.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT) : null) ?? + (canvasContainer.webkitRequestFullScreen ? () => canvasContainer.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT) : null); +#endif canvasContainer.requestFullscreen(); }, diff --git a/src/lib/libhtml5.js b/src/lib/libhtml5.js index 134e078a3900e..2f64008cd7148 100644 --- a/src/lib/libhtml5.js +++ b/src/lib/libhtml5.js @@ -252,10 +252,10 @@ var LibraryHTML5 = { fullscreenEnabled() { return document.fullscreenEnabled -#if MIN_SAFARI_VERSION != TARGET_NOT_SUPPORTED +#if MIN_SAFARI_VERSION < 160400 // Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitFullscreenEnabled. // TODO: If Safari at some point ships with unprefixed version, update the version check above. - || document.webkitFullscreenEnabled + ?? document.webkitFullscreenEnabled #endif ; }, @@ -264,8 +264,8 @@ var LibraryHTML5 = { $getFullscreenElement__internal: true, $getFullscreenElement() { return document.fullscreenElement -#if MIN_SAFARI_VERSION != TARGET_NOT_SUPPORTED - || document.webkitFullscreenElement +#if MIN_SAFARI_VERSION < 160400 + ?? document.webkitFullscreenElement #endif ; }, @@ -1078,8 +1078,7 @@ var LibraryHTML5 = { #endif if (!target) return {{{ cDefs.EMSCRIPTEN_RESULT_UNKNOWN_TARGET }}}; -#if MIN_SAFARI_VERSION != TARGET_NOT_SUPPORTED - // As of Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitfullscreenchange. TODO: revisit this check once Safari ships unprefixed version. +#if MIN_SAFARI_VERSION < 160400 // TODO: When this block is removed, also change test/test_html5_remove_event_listener.c test expectation on emscripten_set_fullscreenchange_callback(). registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, {{{ cDefs.EMSCRIPTEN_EVENT_FULLSCREENCHANGE }}}, 'webkitfullscreenchange', targetThread); #endif @@ -1117,8 +1116,10 @@ var LibraryHTML5 = { if (target.requestFullscreen) { target.requestFullscreen(); -#if MIN_SAFARI_VERSION != TARGET_NOT_SUPPORTED +#if MIN_SAFARI_VERSION < 160400 } else if (target.webkitRequestFullscreen) { + // Safari didn't Element.requestFullscreen support until 16.4 + // See: https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullscreen target.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); #endif } else { @@ -1215,8 +1216,7 @@ var LibraryHTML5 = { if (!getFullscreenElement()) { document.removeEventListener('fullscreenchange', restoreOldStyle); -#if MIN_SAFARI_VERSION != TARGET_NOT_SUPPORTED - // As of Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitfullscreenchange. TODO: revisit this check once Safari ships unprefixed version. +#if MIN_SAFARI_VERSION < 160400 document.removeEventListener('webkitfullscreenchange', restoreOldStyle); #endif @@ -1248,8 +1248,7 @@ var LibraryHTML5 = { } } document.addEventListener('fullscreenchange', restoreOldStyle); -#if MIN_SAFARI_VERSION != TARGET_NOT_SUPPORTED - // As of Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitfullscreenchange. TODO: revisit this check once Safari ships unprefixed version. +#if MIN_SAFARI_VERSION < 160400 document.addEventListener('webkitfullscreenchange', restoreOldStyle); #endif return restoreOldStyle; @@ -1359,7 +1358,9 @@ var LibraryHTML5 = { if (!target) return {{{ cDefs.EMSCRIPTEN_RESULT_UNKNOWN_TARGET }}}; if (!target.requestFullscreen -#if MIN_SAFARI_VERSION != TARGET_NOT_SUPPORTED +#if MIN_SAFARI_VERSION < 160400 + // Safari didn't Element.requestFullscreen support until 16.4 + // See: https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullscreen && !target.webkitRequestFullscreen #endif ) { @@ -1490,7 +1491,7 @@ var LibraryHTML5 = { var d = specialHTMLTargets[{{{ cDefs.EMSCRIPTEN_EVENT_TARGET_DOCUMENT }}}]; if (d.exitFullscreen) { d.fullscreenElement && d.exitFullscreen(); -#if MIN_SAFARI_VERSION != TARGET_NOT_SUPPORTED // https://caniuse.com/#feat=mdn-api_document_exitfullscreen +#if MIN_SAFARI_VERSION < 160400 // https://caniuse.com/#feat=mdn-api_document_exitfullscreen } else if (d.webkitExitFullscreen) { d.webkitFullscreenElement && d.webkitExitFullscreen(); #endif diff --git a/test/codesize/test_codesize_hello_dylink_all.json b/test/codesize/test_codesize_hello_dylink_all.json index 49dc081cf962c..561830293baae 100644 --- a/test/codesize/test_codesize_hello_dylink_all.json +++ b/test/codesize/test_codesize_hello_dylink_all.json @@ -1,7 +1,7 @@ { - "a.out.js": 268745, + "a.out.js": 268038, "a.out.nodebug.wasm": 588128, - "total": 856873, + "total": 856166, "sent": [ "IMG_Init", "IMG_Load", diff --git a/third_party/wrtcp.js b/third_party/wrtcp.js index e5498abfb8d1c..6dab838563380 100644 --- a/third_party/wrtcp.js +++ b/third_party/wrtcp.js @@ -67,12 +67,7 @@ THE SOFTWARE. var getUserMedia; if(!navigator.getUserMedia) { - if(navigator.mozGetUserMedia) - getUserMedia = navigator.mozGetUserMedia.bind(navigator); - else if(navigator.webkitGetUserMedia) - getUserMedia = navigator.webkitGetUserMedia.bind(navigator); - else - webrtcSupported = false; + webrtcSupported = false; } else { getUserMedia = navigator.getUserMedia.bind(navigator); } @@ -819,4 +814,4 @@ THE SOFTWARE. return Peer; -})(); \ No newline at end of file +})();