Last active
June 13, 2022 18:29
-
-
Save fuweichin/61005d22fffba63218f04a8276481c22 to your computer and use it in GitHub Desktop.
screen.orienation polyfill and ponyfill, for Safari
This file contains 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
<h2>screen.orientation</h2> | |
<p id="msg"> </p> | |
<pre><code id="output">...</code></pre> | |
<script type="module"> | |
import {ponyfill, polyfill} from './screen-orientation.js'; | |
const $ = (s, c = document) => c.querySelector(s); | |
function main() { | |
if (!screen.orientation) { | |
$('#msg').textContent = 'Your browser doesn\'t support screen.orientation'; | |
} else { | |
$('#msg').textContent = 'Your browser supports screen.orientation'; | |
} | |
let keys = ['angle', 'type']; | |
let orientation = screen.orientation || ponyfill(); | |
$('#output').textContent = JSON.stringify(orientation, keys, 2); | |
orientation.onchange = () => { | |
$('#output').textContent = JSON.stringify(orientation, keys, 2); | |
}; | |
} | |
document.readyState === 'loading' ? document.addEventListener('DOMContentLoaded', main) : main(); | |
</script> |
This file contains 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
let ScreenOrientation; | |
if (('onorientationchange' in window)) { // Safari 15 | |
let weakMap = new WeakMap(); | |
ScreenOrientation = class ScreenOrientation extends EventTarget { | |
constructor() { | |
super(); | |
this._onchange = null; | |
Object.defineProperties(this, { | |
_onchange: {enumerable: false}, | |
}); | |
} | |
get angle() { | |
let angle = window.orientation; | |
if (angle < 0) | |
angle += 360; | |
return angle; | |
} | |
get type() { | |
let angle = this.angle; | |
switch (angle) { | |
case 0: | |
return 'portrait-primary'; | |
case 90: | |
return 'landscape-primary'; | |
case 180: | |
return 'portrait-secondary'; | |
case 270: | |
return 'landscape-secondary'; | |
default: | |
return ''; | |
} | |
} | |
async lock() { | |
} | |
async unlock() { | |
} | |
addEventListener(type, listener) { | |
if (type === 'change') { | |
let middleListener = (e) => { | |
this.dispatchEvent(new Event('change')); | |
}; | |
weakMap.set(listener, middleListener); | |
window.addEventListener('orientationchange', middleListener); | |
} | |
super.addEventListener(type, listener); | |
} | |
removeEventListener(type, listener) { | |
if (type === 'change') { | |
let middleListener = weakMap.get(listener); | |
if (middleListener) { | |
window.removeEventListener('orientationchange', middleListener); | |
} | |
} | |
super.removeEventListener(type, listener); | |
} | |
set onchange(handler) { | |
let oldHandler = this._onchange; | |
if (handler === oldHandler) | |
return; | |
if (oldHandler !== null) { | |
this.removeEventListener('change', oldHandler); | |
this._onchange = null; | |
} | |
if (typeof handler === 'function') { | |
this.addEventListener('change', handler); | |
this._onchange = handler; | |
} | |
} | |
get onchange() { | |
return this._onchange; | |
} | |
}; | |
Object.defineProperty(ScreenOrientation.prototype, Symbol.toStringTag, { | |
enumerable: false, | |
configurable: true, | |
writable: false, | |
value: 'ScreenOrientation' | |
}); | |
} | |
function ponyfill() { | |
if (!ScreenOrientation) { | |
throw new Error('cannot get ponyfill of screen.orientation'); | |
} | |
return new ScreenOrientation(); | |
} | |
function polyfill() { | |
if (!screen.orientation) { | |
if (!ScreenOrientation) { | |
throw new Error('cannot polyfill screen.orientation'); | |
} | |
let orientation = new ScreenOrientation(); | |
Object.defineProperty(Screen.prototype, 'orientation', { | |
enumerable: true, | |
configurable: true, | |
get: function getOrientation() { | |
return orientation; | |
} | |
}); | |
Object.defineProperty(window, 'ScreenOrientation', { | |
enumerable: false, | |
configurable: true, | |
writable: true, | |
value: ScreenOrientation | |
}); | |
} | |
} | |
export {ponyfill, polyfill}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment