Last active
February 16, 2026 01:22
-
-
Save hjanuschka/3177b6352e95d1b8d069bb91cc599848 to your computer and use it in GitHub Desktop.
screen.orientation.lock() tester for DevTools device emulation (crbug.com/40807290)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>screen.orientation.lock() Test</title> | |
| <style> | |
| * { box-sizing: border-box; margin: 0; padding: 0; } | |
| body { | |
| font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, monospace; | |
| background: #1a1a2e; | |
| color: #e0e0e0; | |
| min-height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| padding: 20px; | |
| } | |
| h1 { color: #00d4ff; margin-bottom: 10px; font-size: 1.4em; } | |
| .subtitle { color: #888; margin-bottom: 20px; font-size: 0.85em; } | |
| .info-box { | |
| background: #16213e; | |
| border: 1px solid #0f3460; | |
| border-radius: 8px; | |
| padding: 16px; | |
| width: 100%; | |
| max-width: 500px; | |
| margin-bottom: 16px; | |
| } | |
| .info-box h2 { color: #e94560; font-size: 1em; margin-bottom: 8px; } | |
| .info-row { | |
| display: flex; | |
| justify-content: space-between; | |
| padding: 4px 0; | |
| font-size: 0.9em; | |
| } | |
| .info-label { color: #888; } | |
| .info-value { color: #00d4ff; font-weight: bold; } | |
| .buttons { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 8px; | |
| width: 100%; | |
| max-width: 500px; | |
| margin-bottom: 16px; | |
| } | |
| button { | |
| background: #0f3460; | |
| color: #e0e0e0; | |
| border: 1px solid #1a5276; | |
| border-radius: 6px; | |
| padding: 12px 8px; | |
| cursor: pointer; | |
| font-size: 0.85em; | |
| transition: all 0.2s; | |
| } | |
| button:hover { background: #1a5276; border-color: #00d4ff; } | |
| button:active { transform: scale(0.97); } | |
| button.unlock-btn { | |
| grid-column: 1 / -1; | |
| background: #e94560; | |
| border-color: #e94560; | |
| } | |
| button.unlock-btn:hover { background: #c0392b; } | |
| #log { | |
| background: #0d1117; | |
| border: 1px solid #333; | |
| border-radius: 8px; | |
| padding: 12px; | |
| width: 100%; | |
| max-width: 500px; | |
| height: 200px; | |
| overflow-y: auto; | |
| font-family: monospace; | |
| font-size: 0.8em; | |
| line-height: 1.6; | |
| } | |
| .log-entry { border-bottom: 1px solid #222; padding: 2px 0; } | |
| .log-ok { color: #2ecc71; } | |
| .log-err { color: #e94560; } | |
| .log-info { color: #f39c12; } | |
| .howto { | |
| background: #16213e; | |
| border: 1px solid #0f3460; | |
| border-radius: 8px; | |
| padding: 16px; | |
| width: 100%; | |
| max-width: 500px; | |
| margin-top: 16px; | |
| font-size: 0.78em; | |
| line-height: 1.7; | |
| color: #aaa; | |
| } | |
| .howto h3 { color: #00d4ff; margin-bottom: 8px; } | |
| .howto code { | |
| background: #0d1117; | |
| padding: 1px 5px; | |
| border-radius: 3px; | |
| color: #f39c12; | |
| } | |
| .howto ol { padding-left: 20px; } | |
| .howto li { margin-bottom: 4px; } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>screen.orientation.lock() Tester</h1> | |
| <p class="subtitle">Chromium Issue <a href="https://issues.chromium.org/issues/40807290" style="color:#00d4ff">40807290</a></p> | |
| <div class="info-box"> | |
| <h2>Current Orientation State</h2> | |
| <div class="info-row"> | |
| <span class="info-label">type:</span> | |
| <span class="info-value" id="ori-type">--</span> | |
| </div> | |
| <div class="info-row"> | |
| <span class="info-label">angle:</span> | |
| <span class="info-value" id="ori-angle">--</span> | |
| </div> | |
| <div class="info-row"> | |
| <span class="info-label">window size:</span> | |
| <span class="info-value" id="win-size">--</span> | |
| </div> | |
| <div class="info-row"> | |
| <span class="info-label">screen size:</span> | |
| <span class="info-value" id="scr-size">--</span> | |
| </div> | |
| <div class="info-row"> | |
| <span class="info-label">lock supported:</span> | |
| <span class="info-value" id="lock-support">checking...</span> | |
| </div> | |
| </div> | |
| <div class="buttons"> | |
| <button onclick="lockTo('portrait-primary')">Lock Portrait Primary</button> | |
| <button onclick="lockTo('portrait-secondary')">Lock Portrait Secondary</button> | |
| <button onclick="lockTo('landscape-primary')">Lock Landscape Primary</button> | |
| <button onclick="lockTo('landscape-secondary')">Lock Landscape Secondary</button> | |
| <button onclick="lockTo('portrait')">Lock Portrait (any)</button> | |
| <button onclick="lockTo('landscape')">Lock Landscape (any)</button> | |
| <button onclick="lockTo('natural')">Lock Natural</button> | |
| <button onclick="lockTo('any')">Lock Any</button> | |
| <button class="unlock-btn" onclick="doUnlock()">Unlock Orientation</button> | |
| </div> | |
| <div id="log"></div> | |
| <div class="howto"> | |
| <h3>How to Test (with DevTools fix for issue 40807290)</h3> | |
| <ol> | |
| <li>Open Chrome and navigate to this file: <code>file:///home/chrome/lock.html</code></li> | |
| <li>Open DevTools (<code>F12</code> or <code>Ctrl+Shift+I</code>)</li> | |
| <li>Click the <strong>device toolbar</strong> toggle (phone icon) to enable mobile emulation</li> | |
| <li>Select a device (e.g. "iPhone 14 Pro Max") or use "Responsive" mode</li> | |
| <li>Click any <strong>"Lock ..."</strong> button on this page</li> | |
| </ol> | |
| <h3>Expected Results</h3> | |
| <ol> | |
| <li><strong>Before fix:</strong> Every lock attempt logs <code style="color:#e94560">NotSupportedError: screen.orientation.lock() is not available on this device</code></li> | |
| <li><strong>After fix (Milestone 1):</strong> Lock succeeds, orientation changes, log shows <code style="color:#2ecc71">OK</code></li> | |
| <li><strong>After fix (Milestone 2):</strong> The <strong>rotate button</strong> in the DevTools device toolbar is <em>disabled</em> while orientation is locked</li> | |
| </ol> | |
| <h3>Verifying Without the Fix</h3> | |
| <p>Open this page in current Chrome stable/canary with device emulation on. Click any Lock button. You will see the <code style="color:#e94560">NotSupportedError</code> -- that confirms the bug.</p> | |
| </div> | |
| <script> | |
| const logEl = document.getElementById('log'); | |
| const oriType = document.getElementById('ori-type'); | |
| const oriAngle = document.getElementById('ori-angle'); | |
| const winSize = document.getElementById('win-size'); | |
| const scrSize = document.getElementById('scr-size'); | |
| const lockSupport = document.getElementById('lock-support'); | |
| function log(msg, cls) { | |
| const d = document.createElement('div'); | |
| d.className = 'log-entry ' + (cls || ''); | |
| const ts = new Date().toLocaleTimeString('en', {hour12:false, hour:'2-digit', minute:'2-digit', second:'2-digit'}); | |
| d.textContent = `[${ts}] ${msg}`; | |
| logEl.prepend(d); | |
| } | |
| function updateInfo() { | |
| const o = screen.orientation; | |
| oriType.textContent = o.type; | |
| oriAngle.textContent = o.angle + 'deg'; | |
| winSize.textContent = window.innerWidth + ' x ' + window.innerHeight; | |
| scrSize.textContent = screen.width + ' x ' + screen.height; | |
| } | |
| // Detect lock support by attempting a harmless lock | |
| async function checkLockSupport() { | |
| try { | |
| // lock('any') is the least restrictive -- if it works, lock is supported | |
| await screen.orientation.lock('any'); | |
| screen.orientation.unlock(); | |
| lockSupport.textContent = 'YES'; | |
| lockSupport.style.color = '#2ecc71'; | |
| } catch (e) { | |
| if (e.name === 'NotSupportedError') { | |
| lockSupport.textContent = 'NO (NotSupportedError)'; | |
| lockSupport.style.color = '#e94560'; | |
| } else if (e.name === 'SecurityError') { | |
| // SecurityError means lock IS supported but requires fullscreen/user gesture | |
| lockSupport.textContent = 'YES (needs gesture/fullscreen)'; | |
| lockSupport.style.color = '#f39c12'; | |
| } else { | |
| lockSupport.textContent = 'UNKNOWN (' + e.name + ')'; | |
| lockSupport.style.color = '#f39c12'; | |
| } | |
| } | |
| } | |
| async function lockTo(orientation) { | |
| log(`Calling screen.orientation.lock("${orientation}")...`, 'log-info'); | |
| try { | |
| await screen.orientation.lock(orientation); | |
| log(`OK -- locked to "${orientation}". Now: type=${screen.orientation.type}, angle=${screen.orientation.angle}`, 'log-ok'); | |
| updateInfo(); | |
| lockSupport.textContent = 'YES'; | |
| lockSupport.style.color = '#2ecc71'; | |
| } catch (e) { | |
| log(`FAIL -- ${e.name}: ${e.message}`, 'log-err'); | |
| } | |
| } | |
| function doUnlock() { | |
| log('Calling screen.orientation.unlock()...', 'log-info'); | |
| try { | |
| screen.orientation.unlock(); | |
| log(`OK -- unlocked. Now: type=${screen.orientation.type}, angle=${screen.orientation.angle}`, 'log-ok'); | |
| updateInfo(); | |
| } catch (e) { | |
| log(`FAIL -- ${e.name}: ${e.message}`, 'log-err'); | |
| } | |
| } | |
| screen.orientation.addEventListener('change', () => { | |
| log(`EVENT orientation change -> type=${screen.orientation.type}, angle=${screen.orientation.angle}`, 'log-info'); | |
| updateInfo(); | |
| }); | |
| window.addEventListener('resize', updateInfo); | |
| // Init | |
| updateInfo(); | |
| checkLockSupport(); | |
| log('Page loaded. Enable DevTools device emulation and click a Lock button.', 'log-info'); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment