ruffle/web/packages/demo/www/index.js

279 lines
7.6 KiB
JavaScript
Raw Normal View History

import "./index.css";
import { PublicAPI } from "ruffle-core";
window.RufflePlayer = PublicAPI.negotiate(window.RufflePlayer, "local");
2021-03-26 15:17:00 +00:00
const ruffle = window.RufflePlayer.newest();
2019-04-25 17:52:22 +00:00
let player;
2019-04-25 17:52:22 +00:00
2021-02-20 01:40:43 +00:00
const main = document.getElementById("main");
2021-01-22 02:16:39 +00:00
const overlay = document.getElementById("overlay");
const authorContainer = document.getElementById("author-container");
const author = document.getElementById("author");
const sampleFileInputContainer = document.getElementById(
2023-07-20 11:19:39 +00:00
"sample-swfs-container",
);
const localFileInput = document.getElementById("local-file");
2021-03-26 15:17:00 +00:00
const sampleFileInput = document.getElementById("sample-swfs");
2022-05-06 14:04:16 +00:00
const localFileName = document.getElementById("local-file-name");
2022-08-16 19:44:53 +00:00
const closeModal = document.getElementById("close-modal");
const openModal = document.getElementById("open-modal");
const reloadSwf = document.getElementById("reload-swf");
2022-08-16 19:44:53 +00:00
const metadataModal = document.getElementById("metadata-modal");
2021-07-09 08:40:02 +00:00
// prettier-ignore
const optionGroups = {
"Animation": document.getElementById("anim-optgroup"),
"Game": document.getElementById("games-optgroup"),
};
web: Fix Ruffle configuration not working properly for Polyfill elements Previously, the Ruffle configuration options weren't working properly for polyfilled elements. A polyfilled element can have specific configuration options which overwrite the more general Ruffle configuration settings. But the code handling those specific configuration options has previously set some of them to default values if they haven't been provided, therefore overwriting the more general configuration settings. This has been fixed. A getPolyfillOptions function has been created and returns a URLLoadOptions object, containing only the options that have been set for the respective element. Helper functions have been adapted to not return any default values anymore. getPolyfillOptions is now used in all places where polyfilled options need to be retrieved (therefore reducing duplicated code). Documentation has been added to clarify that these options must not contain any default values, since those would overwrite other configuration settings with a lower priority. The extension and demo code has been changed to clarify that no default values are contained in the element configuration options. The RuffleEmbed::attributeChangedCallback method has previously loaded an SWF file only with the parameters and base options. This has been fixed as well since it now also uses getPolyfillOptions. When using RuffleObject::connectedCallback to load an SWF file, setting an element config option to "" hasn't worked for most config options before either. This has been fixed as well by using the new getPolyfillOptions function. The default WindowMode value of the default Ruffle web config has been set to Window (as it is in the desktop version and according to the documentation). It has previously been set to Opaque (which causes the same functionality).
2023-09-22 19:06:05 +00:00
// This is the base config used by the demo player (except for specific SWF files
// with their own base config).
// It has the highest priority and its options cannot be overwritten.
const baseDemoConfig = {
2021-01-06 07:32:18 +00:00
letterbox: "on",
2021-01-20 02:10:35 +00:00
logLevel: "warn",
2023-04-12 23:32:49 +00:00
forceScale: true,
forceAlign: true,
2021-01-06 07:32:18 +00:00
};
const swfToFlashVersion = {
1: "1",
2: "2",
3: "3",
4: "4",
5: "5",
6: "6",
7: "7",
8: "8",
9: "9.0",
10: "10.0/10.1",
11: "10.2",
12: "10.3",
13: "11.0",
14: "11.1",
15: "11.2",
16: "11.3",
17: "11.4",
18: "11.5",
19: "11.6",
20: "11.7",
21: "11.8",
22: "11.9",
23: "12",
24: "13",
25: "14",
26: "15",
27: "16",
28: "17",
29: "18",
30: "19",
31: "20",
32: "21",
33: "22",
34: "23",
35: "24",
36: "25",
37: "26",
38: "27",
39: "28",
40: "29",
41: "30",
42: "31",
43: "32",
};
2021-03-26 15:17:00 +00:00
function unload() {
2021-02-20 01:40:43 +00:00
if (player) {
player.remove();
document.querySelectorAll("span.metadata").forEach((el) => {
el.textContent = "Loading";
});
document.getElementById("backgroundColor").value = "#FFFFFF";
2021-02-20 01:40:43 +00:00
}
2021-03-26 15:17:00 +00:00
}
function load(options) {
unload();
2021-02-18 11:02:05 +00:00
player = ruffle.createPlayer();
player.id = "player";
2021-02-20 01:40:43 +00:00
main.append(player);
player.load(options, false);
player.addEventListener("loadedmetadata", function () {
if (this.metadata) {
for (const [key, value] of Object.entries(this.metadata)) {
const metadataElement = document.getElementById(key);
if (metadataElement) {
switch (key) {
case "backgroundColor":
metadataElement.value = value ?? "#FFFFFF";
break;
case "uncompressedLength":
metadataElement.textContent = `${value >> 10}Kb`;
break;
case "swfVersion":
document.getElementById(
2023-07-20 11:19:39 +00:00
"flashVersion",
).textContent = swfToFlashVersion[value];
// falls through and executes the default case as well
default:
metadataElement.textContent = value;
break;
}
}
}
}
});
2021-03-26 15:17:00 +00:00
}
function showSample(swfData) {
authorContainer.classList.remove("hidden");
author.textContent = swfData.author;
author.href = swfData.authorLink;
localFileInput.value = null;
}
2021-02-20 01:40:43 +00:00
2021-03-26 15:17:00 +00:00
function hideSample() {
2022-07-12 17:40:08 +00:00
sampleFileInput.selectedIndex = -1;
2021-03-26 15:17:00 +00:00
authorContainer.classList.add("hidden");
2021-02-20 01:40:43 +00:00
author.textContent = "";
author.href = "";
}
async function loadFile(file) {
if (!file) {
return;
}
2022-05-06 14:04:16 +00:00
if (file.name) {
localFileName.textContent = file.name;
}
2021-03-26 15:17:00 +00:00
hideSample();
2021-07-09 08:40:02 +00:00
const data = await new Response(file).arrayBuffer();
web: Fix Ruffle configuration not working properly for Polyfill elements Previously, the Ruffle configuration options weren't working properly for polyfilled elements. A polyfilled element can have specific configuration options which overwrite the more general Ruffle configuration settings. But the code handling those specific configuration options has previously set some of them to default values if they haven't been provided, therefore overwriting the more general configuration settings. This has been fixed. A getPolyfillOptions function has been created and returns a URLLoadOptions object, containing only the options that have been set for the respective element. Helper functions have been adapted to not return any default values anymore. getPolyfillOptions is now used in all places where polyfilled options need to be retrieved (therefore reducing duplicated code). Documentation has been added to clarify that these options must not contain any default values, since those would overwrite other configuration settings with a lower priority. The extension and demo code has been changed to clarify that no default values are contained in the element configuration options. The RuffleEmbed::attributeChangedCallback method has previously loaded an SWF file only with the parameters and base options. This has been fixed as well since it now also uses getPolyfillOptions. When using RuffleObject::connectedCallback to load an SWF file, setting an element config option to "" hasn't worked for most config options before either. This has been fixed as well by using the new getPolyfillOptions function. The default WindowMode value of the default Ruffle web config has been set to Window (as it is in the desktop version and according to the documentation). It has previously been set to Opaque (which causes the same functionality).
2023-09-22 19:06:05 +00:00
load({ data: data, swfFileName: file.name, ...baseDemoConfig });
2021-02-20 01:40:43 +00:00
}
2021-02-21 20:52:04 +00:00
function loadSample() {
2021-02-20 01:40:43 +00:00
const swfData = sampleFileInput[sampleFileInput.selectedIndex].swfData;
2022-05-06 14:04:16 +00:00
localFileName.textContent = "No file selected.";
2021-02-20 01:40:43 +00:00
if (swfData) {
2021-03-26 15:17:00 +00:00
showSample(swfData);
web: Fix Ruffle configuration not working properly for Polyfill elements Previously, the Ruffle configuration options weren't working properly for polyfilled elements. A polyfilled element can have specific configuration options which overwrite the more general Ruffle configuration settings. But the code handling those specific configuration options has previously set some of them to default values if they haven't been provided, therefore overwriting the more general configuration settings. This has been fixed. A getPolyfillOptions function has been created and returns a URLLoadOptions object, containing only the options that have been set for the respective element. Helper functions have been adapted to not return any default values anymore. getPolyfillOptions is now used in all places where polyfilled options need to be retrieved (therefore reducing duplicated code). Documentation has been added to clarify that these options must not contain any default values, since those would overwrite other configuration settings with a lower priority. The extension and demo code has been changed to clarify that no default values are contained in the element configuration options. The RuffleEmbed::attributeChangedCallback method has previously loaded an SWF file only with the parameters and base options. This has been fixed as well since it now also uses getPolyfillOptions. When using RuffleObject::connectedCallback to load an SWF file, setting an element config option to "" hasn't worked for most config options before either. This has been fixed as well by using the new getPolyfillOptions function. The default WindowMode value of the default Ruffle web config has been set to Window (as it is in the desktop version and according to the documentation). It has previously been set to Opaque (which causes the same functionality).
2023-09-22 19:06:05 +00:00
const config = swfData.config || baseDemoConfig;
2021-03-26 15:17:00 +00:00
load({ url: swfData.location, ...config });
2021-02-20 01:40:43 +00:00
} else {
2021-03-26 15:17:00 +00:00
hideSample();
unload();
2021-02-20 01:40:43 +00:00
}
}
localFileInput.addEventListener("change", (event) => {
loadFile(event.target.files[0]);
});
2021-02-21 20:52:04 +00:00
sampleFileInput.addEventListener("change", () => loadSample());
2021-02-20 01:40:43 +00:00
2021-03-26 15:17:00 +00:00
main.addEventListener("dragenter", (event) => {
event.stopPropagation();
event.preventDefault();
2021-02-20 01:40:43 +00:00
});
2021-03-26 15:17:00 +00:00
main.addEventListener("dragleave", (event) => {
event.stopPropagation();
event.preventDefault();
2021-02-20 01:40:43 +00:00
overlay.classList.remove("drag");
});
main.addEventListener("dragover", (event) => {
event.stopPropagation();
event.preventDefault();
2021-03-26 15:17:00 +00:00
overlay.classList.add("drag");
2021-02-20 01:40:43 +00:00
});
main.addEventListener("drop", (event) => {
event.stopPropagation();
event.preventDefault();
overlay.classList.remove("drag");
localFileInput.files = event.dataTransfer.files;
2021-02-20 01:40:43 +00:00
loadFile(event.dataTransfer.files[0]);
});
localFileInput.addEventListener("dragleave", (event) => {
event.stopPropagation();
event.preventDefault();
overlay.classList.remove("drag");
});
localFileInput.addEventListener("dragover", (event) => {
event.stopPropagation();
event.preventDefault();
overlay.classList.add("drag");
});
localFileInput.addEventListener("drop", (event) => {
event.stopPropagation();
event.preventDefault();
overlay.classList.remove("drag");
localFileInput.files = event.dataTransfer.files;
loadFile(event.dataTransfer.files[0]);
});
2021-02-20 01:40:43 +00:00
closeModal.addEventListener("click", () => {
metadataModal.style.display = "none";
});
openModal.addEventListener("click", () => {
metadataModal.style.display = "block";
});
reloadSwf.addEventListener("click", () => {
if (player) {
const confirmReload = confirm("Reload the current SWF?");
if (confirmReload) {
player.reload();
}
}
});
2021-02-20 01:40:43 +00:00
window.addEventListener("load", () => {
if (
navigator.userAgent.match(/iPad/i) ||
navigator.userAgent.match(/iPhone/i)
) {
localFileInput.removeAttribute("accept");
}
2021-03-26 15:17:00 +00:00
overlay.classList.remove("hidden");
2021-02-20 01:40:43 +00:00
});
window.onclick = (event) => {
if (event.target === metadataModal) {
metadataModal.style.display = "none";
}
};
2021-03-26 15:17:00 +00:00
(async () => {
const response = await fetch("swfs.json");
if (response.ok) {
const data = await response.json();
for (const swfData of data.swfs) {
const option = document.createElement("option");
option.textContent = swfData.title;
option.value = swfData.location;
option.swfData = swfData;
2022-07-12 17:40:08 +00:00
if (swfData.type) {
optionGroups[swfData.type].append(option);
} else {
2022-07-12 20:21:32 +00:00
sampleFileInput.insertBefore(
option,
2023-07-20 11:19:39 +00:00
sampleFileInput.firstChild,
2022-07-12 20:21:32 +00:00
);
2022-07-12 17:40:08 +00:00
}
}
sampleFileInputContainer.classList.remove("hidden");
}
2022-07-12 17:40:08 +00:00
sampleFileInput.selectedIndex = 0;
2021-02-21 20:52:04 +00:00
const initialFile = new URL(window.location).searchParams.get("file");
if (initialFile) {
const options = Array.from(sampleFileInput.options);
sampleFileInput.selectedIndex = Math.max(
options.findIndex((swfData) => swfData.value.endsWith(initialFile)),
2023-07-20 11:19:39 +00:00
0,
);
}
2022-07-12 17:40:08 +00:00
loadSample();
2021-03-26 15:17:00 +00:00
})();