Skip to content

Instantly share code, notes, and snippets.

@fuweichin
Last active June 13, 2022 18:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fuweichin/61005d22fffba63218f04a8276481c22 to your computer and use it in GitHub Desktop.
Save fuweichin/61005d22fffba63218f04a8276481c22 to your computer and use it in GitHub Desktop.
screen.orienation polyfill and ponyfill, for Safari
<h2>screen.orientation</h2>
<p id="msg">&#160;</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>
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