mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Move polyfill loading
This commit is contained in:
parent
7c651d0a5d
commit
385a01d5ad
8 changed files with 19 additions and 15 deletions
36
src/lib/legacy/domParserTextHtml.js
Normal file
36
src/lib/legacy/domParserTextHtml.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* DOMParser HTML extension
|
||||
* 2019-11-13
|
||||
*
|
||||
* By Eli Grey, http://eligrey.com
|
||||
* Public domain.
|
||||
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
*/
|
||||
|
||||
/*! @source https://gist.github.com/1129031 */
|
||||
|
||||
(function (DOMParser) {
|
||||
'use strict';
|
||||
|
||||
const DOMParser_proto = DOMParser.prototype;
|
||||
const real_parseFromString = DOMParser_proto.parseFromString;
|
||||
|
||||
// Firefox/Opera/IE throw errors on unsupported types
|
||||
try {
|
||||
// WebKit returns null on unsupported types
|
||||
if ((new DOMParser).parseFromString('', 'text/html')) {
|
||||
// text/html parsing is natively supported
|
||||
return;
|
||||
}
|
||||
} catch (ex) { /* noop */ }
|
||||
|
||||
DOMParser_proto.parseFromString = function (markup, type) {
|
||||
if (/^\s*text\/html\s*(?:;|$)/i.test(type)) {
|
||||
const doc = document.implementation.createHTMLDocument('');
|
||||
doc.documentElement.innerHTML = markup;
|
||||
return doc;
|
||||
} else {
|
||||
return real_parseFromString.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
}(DOMParser));
|
42
src/lib/legacy/focusPreventScroll.js
Normal file
42
src/lib/legacy/focusPreventScroll.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Polyfill to add support for preventScroll by focus function
|
||||
|
||||
if (HTMLElement.prototype.nativeFocus === undefined) {
|
||||
(function () {
|
||||
let supportsPreventScrollOption = false;
|
||||
try {
|
||||
const focusElem = document.createElement('div');
|
||||
|
||||
focusElem.addEventListener('focus', function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}, true);
|
||||
|
||||
const opts = Object.defineProperty({}, 'preventScroll', {
|
||||
get: function () {
|
||||
supportsPreventScrollOption = true;
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
focusElem.focus(opts);
|
||||
} catch {
|
||||
// no preventScroll supported
|
||||
}
|
||||
|
||||
if (!supportsPreventScrollOption) {
|
||||
HTMLElement.prototype.nativeFocus = HTMLElement.prototype.focus;
|
||||
|
||||
HTMLElement.prototype.focus = function(options) {
|
||||
const scrollX = window.scrollX;
|
||||
const scrollY = window.scrollY;
|
||||
|
||||
this.nativeFocus();
|
||||
|
||||
// Restore window scroll if preventScroll
|
||||
if (options?.preventScroll) {
|
||||
window.scroll(scrollX, scrollY);
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
||||
}
|
26
src/lib/legacy/htmlMediaElement.js
Normal file
26
src/lib/legacy/htmlMediaElement.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* Polyfill for HTMLMediaElement
|
||||
* - HTMLMediaElement.play
|
||||
* Return a `Promise`.
|
||||
*/
|
||||
|
||||
(function (HTMLMediaElement) {
|
||||
'use strict';
|
||||
|
||||
const HTMLMediaElement_proto = HTMLMediaElement.prototype;
|
||||
const real_play = HTMLMediaElement_proto.play;
|
||||
|
||||
HTMLMediaElement_proto.play = function () {
|
||||
try {
|
||||
const promise = real_play.apply(this, arguments);
|
||||
|
||||
if (typeof promise?.then === 'function') {
|
||||
return promise;
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
} catch (err) {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
};
|
||||
}(HTMLMediaElement));
|
16
src/lib/legacy/index.ts
Normal file
16
src/lib/legacy/index.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import 'core-js/stable';
|
||||
import 'regenerator-runtime/runtime';
|
||||
import 'jquery';
|
||||
import 'fast-text-encoding';
|
||||
import 'intersection-observer';
|
||||
import 'classlist.js';
|
||||
import 'whatwg-fetch';
|
||||
import 'abortcontroller-polyfill'; // requires fetch
|
||||
import 'resize-observer-polyfill';
|
||||
|
||||
import './domParserTextHtml';
|
||||
import './focusPreventScroll';
|
||||
import './htmlMediaElement';
|
||||
import './keyboardEvent';
|
||||
import './patchHeaders';
|
||||
import './vendorStyles';
|
46
src/lib/legacy/keyboardEvent.js
Normal file
46
src/lib/legacy/keyboardEvent.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* Polyfill for KeyboardEvent
|
||||
* - Constructor.
|
||||
*/
|
||||
|
||||
(function (window) {
|
||||
'use strict';
|
||||
|
||||
try {
|
||||
new window.KeyboardEvent('event', { bubbles: true, cancelable: true });
|
||||
} catch (e) {
|
||||
// We can't use `KeyboardEvent` in old WebKit because `initKeyboardEvent`
|
||||
// doesn't seem to populate some properties (`keyCode`, `which`) that
|
||||
// are read-only.
|
||||
const KeyboardEventOriginal = window.Event;
|
||||
|
||||
const KeyboardEvent = function (eventName, options) {
|
||||
options = options || {};
|
||||
|
||||
const event = new Event(eventName, { bubbles: !!options.bubbles, cancelable: !!options.cancelable });
|
||||
|
||||
event.view = options.view || document.defaultView;
|
||||
|
||||
event.key = options.key || options.keyIdentifier || '';
|
||||
event.keyCode = options.keyCode || 0;
|
||||
event.code = options.code || '';
|
||||
event.charCode = options.charCode || 0;
|
||||
event.char = options.char || '';
|
||||
event.which = options.which || 0;
|
||||
|
||||
event.location = options.location || options.keyLocation || 0;
|
||||
|
||||
event.ctrlKey = !!options.ctrlKey;
|
||||
event.altKey = !!options.altKey;
|
||||
event.shiftKey = !!options.shiftKey;
|
||||
event.metaKey = !!options.metaKey;
|
||||
|
||||
event.repeat = !!options.repeat;
|
||||
|
||||
return event;
|
||||
};
|
||||
|
||||
KeyboardEvent.prototype = KeyboardEventOriginal.prototype;
|
||||
window.KeyboardEvent = KeyboardEvent;
|
||||
}
|
||||
}(window));
|
26
src/lib/legacy/patchHeaders.js
Normal file
26
src/lib/legacy/patchHeaders.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* Patch 'Headers' to accept 'undefined'.
|
||||
* Fixes `TypeError: Failed to construct 'Headers': No matching constructor signature.`
|
||||
* Affected platforms:
|
||||
* - Tizen 3
|
||||
* - Tizen 4
|
||||
* - webOS 4
|
||||
*/
|
||||
|
||||
(function (window) {
|
||||
'use strict';
|
||||
|
||||
if (window.Headers) {
|
||||
try {
|
||||
new window.Headers(undefined);
|
||||
} catch (_) {
|
||||
console.debug('patch \'Headers\' to accept \'undefined\'');
|
||||
|
||||
const _Headers = window.Headers;
|
||||
|
||||
window.Headers = function (init) {
|
||||
return init ? new _Headers(init) : new _Headers();
|
||||
};
|
||||
}
|
||||
}
|
||||
}(window));
|
34
src/lib/legacy/vendorStyles.js
Normal file
34
src/lib/legacy/vendorStyles.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Polyfill for vendor prefixed style properties
|
||||
|
||||
(function () {
|
||||
const vendorProperties = {
|
||||
'transform': ['webkitTransform'],
|
||||
'transition': ['webkitTransition']
|
||||
};
|
||||
|
||||
const elem = document.createElement('div');
|
||||
|
||||
function polyfillProperty(name) {
|
||||
if (!(name in elem.style)) {
|
||||
(vendorProperties[name] || []).every((vendorName) => {
|
||||
if (vendorName in elem.style) {
|
||||
console.debug(`polyfill '${name}' with '${vendorName}'`);
|
||||
|
||||
Object.defineProperty(CSSStyleDeclaration.prototype, name, {
|
||||
get: function () { return this[vendorName]; },
|
||||
set: function (val) { this[vendorName] = val; }
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (elem.style instanceof CSSStyleDeclaration) {
|
||||
polyfillProperty('transform');
|
||||
polyfillProperty('transition');
|
||||
}
|
||||
})();
|
Loading…
Add table
Add a link
Reference in a new issue