ruffle/web/js-src/polyfills.js

93 lines
3.2 KiB
JavaScript
Raw Normal View History

2019-08-22 01:02:43 +00:00
import RuffleObject from "./ruffle-object";
import RuffleEmbed from "./ruffle-embed";
import { install_plugin, FLASH_PLUGIN } from "./plugin-polyfill";
2019-08-22 01:02:43 +00:00
/**
2019-10-16 02:02:03 +00:00
* Polyfill native elements with Ruffle equivalents.
2019-08-22 01:02:43 +00:00
*
2019-10-16 02:02:03 +00:00
* This polyfill isn't fool-proof: If there's a chance site JavaScript has
* access to a pre-polyfill element, then this will break horribly. We can
2019-08-22 01:02:43 +00:00
* keep native objects out of the DOM, and thus out of JavaScript's grubby
* little hands, but only if we load first.
*/
function wrap_tree(elem) {
try {
if (elem.nodeName.toLowerCase() === "object" && RuffleObject.is_interdictable(elem)) {
let ruffle_obj = RuffleObject.from_native_object_element(elem);
elem.parentElement.replaceChild(ruffle_obj, elem);
} else if (elem.nodeName.toLowerCase() === "embed" && RuffleEmbed.is_interdictable(elem)) {
let ruffle_obj = RuffleEmbed.from_native_object_element(elem);
elem.parentElement.replaceChild(ruffle_obj, elem);
} else {
for (let node of Array.from(elem.getElementsByTagName("object"))) {
if (RuffleObject.is_interdictable(node)) {
let ruffle_obj = RuffleObject.from_native_object_element(node);
node.parentElement.replaceChild(ruffle_obj, node);
}
}
2019-08-22 01:02:43 +00:00
for (let node of Array.from(elem.getElementsByTagName("embed"))) {
if (RuffleEmbed.is_interdictable(node)) {
let ruffle_obj = RuffleEmbed.from_native_embed_element(node);
node.parentElement.replaceChild(ruffle_obj, node);
}
}
2019-08-22 01:02:43 +00:00
}
} catch (err) {
2019-10-16 02:02:03 +00:00
console.error("Serious error encountered when polyfilling native Flash elements: " + err);
2019-08-22 01:02:43 +00:00
}
}
2019-10-16 02:02:03 +00:00
function polyfill_static_content() {
wrap_tree(document.getElementsByTagName("html")[0]);
}
2019-08-22 01:02:43 +00:00
2019-10-16 02:02:03 +00:00
function polyfill_dynamic_content() {
const observer = new MutationObserver(function (mutationsList, observer) {
for (let mutation of mutationsList) {
for (let node of mutation.addedNodes) {
if (node instanceof Element) {
wrap_tree(node);
} else {
console.error("Cannot process added node of type " + node.constructor.name);
}
}
2019-08-22 01:02:43 +00:00
}
});
2019-08-22 01:02:43 +00:00
observer.observe(document, { childList: true, subtree: true});
}
function falsify_plugin_detection() {
install_plugin(FLASH_PLUGIN);
}
2019-10-16 02:02:03 +00:00
var running_polyfills = [];
var polyfills = {
"static-content": polyfill_static_content,
"dynamic-content": polyfill_dynamic_content,
"plugin-detect": falsify_plugin_detection
};
2019-10-16 02:02:03 +00:00
export function polyfill(polyfill_list) {
for (var i = 0; i < polyfill_list.length; i += 1) {
if (running_polyfills.indexOf(polyfill_list[i]) !== -1) {
continue;
}
2019-10-16 02:02:03 +00:00
if (!polyfills.hasOwnProperty(polyfill_list[i])) {
throw new Error("Requested nonexistent polyfill: " + polyfill_list[i]);
}
2019-10-16 02:02:03 +00:00
running_polyfills.push(polyfill_list[i]);
2019-10-16 02:02:03 +00:00
var this_polyfill = polyfills[polyfill_list[i]];
2019-10-15 02:52:20 +00:00
2019-10-16 02:02:03 +00:00
if (this_polyfill.dependencies !== undefined) {
polyfill(this_polyfill.dependencies);
}
2019-10-16 02:02:03 +00:00
this_polyfill();
}
}