extension: Add log level option
This commit is contained in:
parent
1d324e81b0
commit
d5b223c1b3
|
@ -47,13 +47,15 @@ body {
|
|||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.option input {
|
||||
.option input,
|
||||
.option select {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.option.checkbox input {
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
cursor: pointer;
|
||||
z-index: 1;
|
||||
|
@ -65,8 +67,8 @@ body {
|
|||
padding-right: 40px;
|
||||
}
|
||||
|
||||
.option label::before,
|
||||
.option label::after {
|
||||
.option.checkbox label::before,
|
||||
.option.checkbox label::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
border-radius: 10px;
|
||||
|
@ -76,25 +78,25 @@ body {
|
|||
transition: background 0.2s, right 0.2s;
|
||||
}
|
||||
|
||||
.option label::before {
|
||||
.option.checkbox label::before {
|
||||
height: 20px;
|
||||
width: 40px;
|
||||
right: 0;
|
||||
background: gray;
|
||||
}
|
||||
|
||||
.option label::after {
|
||||
.option.checkbox label::after {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
right: 21px;
|
||||
background: silver;
|
||||
}
|
||||
|
||||
.option input:checked + label::before {
|
||||
.option.checkbox input:checked + label::before {
|
||||
background: var(--ruffle-dark-orange);
|
||||
}
|
||||
|
||||
.option input:checked + label::after {
|
||||
.option.checkbox input:checked + label::after {
|
||||
background: var(--ruffle-orange);
|
||||
right: 1px;
|
||||
}
|
||||
|
|
|
@ -19,18 +19,26 @@
|
|||
</a>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="option">
|
||||
<div class="option checkbox">
|
||||
<input type="checkbox" id="ruffle_enable" />
|
||||
<label for="ruffle_enable">Play Flash content in Ruffle</label>
|
||||
</div>
|
||||
<div class="option">
|
||||
<div class="option checkbox">
|
||||
<input type="checkbox" id="ignore_optout" />
|
||||
<label for="ignore_optout">Ignore website compatibility warnings</label>
|
||||
</div>
|
||||
<div class="option">
|
||||
<div class="option checkbox">
|
||||
<input type="checkbox" id="warn_on_unsupported_content" />
|
||||
<label for="warn_on_unsupported_content">Warn on unsupported content</label>
|
||||
</div>
|
||||
<div class="option select">
|
||||
<select id="log_level">
|
||||
<option value="info">Info</option>
|
||||
<option value="warn">Warning</option>
|
||||
<option value="error">Error</option>
|
||||
</select>
|
||||
<label for="log_level">Log level</label>
|
||||
</div>
|
||||
</div>
|
||||
<script src="dist/options.js"></script>
|
||||
</body>
|
||||
|
|
|
@ -23,11 +23,11 @@
|
|||
<span id="status-text">Ruffle is running.</span>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="option">
|
||||
<div class="option checkbox">
|
||||
<input type="checkbox" id="ruffle_enable" />
|
||||
<label for="ruffle_enable">Play Flash content in Ruffle</label>
|
||||
</div>
|
||||
<div class="option">
|
||||
<div class="option checkbox">
|
||||
<input type="checkbox" id="ignore_optout" />
|
||||
<label for="ignore_optout">Ignore website compatibility warnings</label>
|
||||
</div>
|
||||
|
|
|
@ -1,57 +1,122 @@
|
|||
import * as utils from "./utils";
|
||||
import type { LogLevel } from "ruffle-core";
|
||||
|
||||
export interface Options {
|
||||
ruffleEnable: boolean;
|
||||
ignoreOptout: boolean;
|
||||
warnOnUnsupportedContent: boolean;
|
||||
logLevel: LogLevel;
|
||||
}
|
||||
|
||||
function getBooleanElements() {
|
||||
interface OptionElement<T> {
|
||||
readonly input: Element;
|
||||
readonly label: HTMLLabelElement;
|
||||
value: T;
|
||||
}
|
||||
|
||||
class CheckboxOption implements OptionElement<boolean> {
|
||||
private checkbox: HTMLInputElement;
|
||||
readonly label: HTMLLabelElement;
|
||||
|
||||
constructor(checkbox: HTMLInputElement, label: HTMLLabelElement) {
|
||||
this.checkbox = checkbox;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
get input() {
|
||||
return this.checkbox;
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this.checkbox.checked;
|
||||
}
|
||||
|
||||
set value(value: boolean) {
|
||||
this.checkbox.checked = value;
|
||||
}
|
||||
}
|
||||
|
||||
class SelectOption implements OptionElement<string> {
|
||||
private select: HTMLSelectElement;
|
||||
readonly label: HTMLLabelElement;
|
||||
|
||||
constructor(select: HTMLSelectElement, label: HTMLLabelElement) {
|
||||
this.select = select;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
get input() {
|
||||
return this.select;
|
||||
}
|
||||
|
||||
get value() {
|
||||
const index = this.select.selectedIndex;
|
||||
const option = this.select.options[index];
|
||||
return option.value;
|
||||
}
|
||||
|
||||
set value(value: string) {
|
||||
const options = Array.from(this.select.options);
|
||||
const index = options.findIndex((option) => option.value === value);
|
||||
this.select.selectedIndex = index;
|
||||
}
|
||||
}
|
||||
|
||||
function getElement(option: Element): OptionElement<unknown> {
|
||||
const [label] = option.getElementsByTagName("label");
|
||||
|
||||
const [checkbox] = option.getElementsByTagName("input");
|
||||
if (checkbox && checkbox.type === "checkbox") {
|
||||
return new CheckboxOption(checkbox, label);
|
||||
}
|
||||
|
||||
const [select] = option.getElementsByTagName("select");
|
||||
if (select) {
|
||||
return new SelectOption(select, label);
|
||||
}
|
||||
|
||||
throw new Error("Unknown option element");
|
||||
}
|
||||
|
||||
function findOptionElements() {
|
||||
const camelize = (s: string) =>
|
||||
s.replace(/[^a-z\d](.)/gi, (_, char) => char.toUpperCase());
|
||||
|
||||
const elements = new Map<
|
||||
keyof Options,
|
||||
{ option: Element; checkbox: HTMLInputElement; label: HTMLLabelElement }
|
||||
>();
|
||||
const elements = new Map<keyof Options, OptionElement<unknown>>();
|
||||
for (const option of document.getElementsByClassName("option")) {
|
||||
const [checkbox] = option.getElementsByTagName("input");
|
||||
if (checkbox.type !== "checkbox") {
|
||||
continue;
|
||||
}
|
||||
const [label] = option.getElementsByTagName("label");
|
||||
const key = camelize(checkbox.id) as keyof Options;
|
||||
elements.set(key, { option, checkbox, label });
|
||||
const element = getElement(option);
|
||||
const key = camelize(element.input.id) as keyof Options;
|
||||
elements.set(key, element);
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
export async function bindBooleanOptions(
|
||||
export async function bindOptions(
|
||||
onChange?: (options: Options) => void
|
||||
): Promise<void> {
|
||||
const elements = getBooleanElements();
|
||||
const elements = findOptionElements();
|
||||
const options = await utils.getOptions(Array.from(elements.keys()));
|
||||
|
||||
for (const [key, { checkbox, label }] of elements.entries()) {
|
||||
for (const [key, element] of elements.entries()) {
|
||||
// Bind initial value.
|
||||
checkbox.checked = options[key];
|
||||
element.value = options[key];
|
||||
|
||||
// Prevent transition on load.
|
||||
// Method from https://stackoverflow.com/questions/11131875.
|
||||
label.classList.add("notransition");
|
||||
label.offsetHeight; // Trigger a reflow, flushing the CSS changes.
|
||||
label.classList.remove("notransition");
|
||||
element.label.classList.add("notransition");
|
||||
element.label.offsetHeight; // Trigger a reflow, flushing the CSS changes.
|
||||
element.label.classList.remove("notransition");
|
||||
|
||||
// Localize label.
|
||||
const message = utils.i18n.getMessage(`settings_${checkbox.id}`);
|
||||
const message = utils.i18n.getMessage(`settings_${element.input.id}`);
|
||||
if (message) {
|
||||
label.textContent = message;
|
||||
element.label.textContent = message;
|
||||
}
|
||||
|
||||
// Listen for user input.
|
||||
checkbox.addEventListener("change", () => {
|
||||
const value = checkbox.checked;
|
||||
options[key] = value;
|
||||
element.input.addEventListener("change", () => {
|
||||
const value = element.value;
|
||||
options[key] = value as never;
|
||||
utils.storage.sync.set({ [key]: value });
|
||||
});
|
||||
}
|
||||
|
@ -67,8 +132,8 @@ export async function bindBooleanOptions(
|
|||
if (!element) {
|
||||
continue;
|
||||
}
|
||||
element.checkbox.checked = option.newValue;
|
||||
options[key as keyof Options] = option.newValue;
|
||||
element.value = option.newValue;
|
||||
options[key as keyof Options] = option.newValue as never;
|
||||
}
|
||||
|
||||
if (onChange) {
|
||||
|
|
|
@ -110,6 +110,7 @@ function isXMLDocument(): boolean {
|
|||
"ruffleEnable",
|
||||
"ignoreOptout",
|
||||
"warnOnUnsupportedContent",
|
||||
"logLevel",
|
||||
]);
|
||||
const pageOptout = checkPageOptout();
|
||||
const shouldLoad =
|
||||
|
@ -175,6 +176,7 @@ function isXMLDocument(): boolean {
|
|||
type: "load",
|
||||
config: {
|
||||
warnOnUnsupportedContent: options.warnOnUnsupportedContent,
|
||||
logLevel: options.logLevel,
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import * as utils from "./utils";
|
||||
import { bindBooleanOptions } from "./common";
|
||||
import { bindOptions } from "./common";
|
||||
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
document.title = utils.i18n.getMessage("settings_page");
|
||||
bindBooleanOptions();
|
||||
bindOptions();
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as utils from "./utils";
|
||||
import { PublicAPI, SourceAPI, Letterbox, LogLevel } from "ruffle-core";
|
||||
import { PublicAPI, SourceAPI, Letterbox } from "ruffle-core";
|
||||
|
||||
const api = PublicAPI.negotiate(
|
||||
window.RufflePlayer!,
|
||||
|
@ -30,8 +30,7 @@ window.addEventListener("DOMContentLoaded", async () => {
|
|||
|
||||
const config = {
|
||||
letterbox: Letterbox.On,
|
||||
logLevel: LogLevel.Warn,
|
||||
...(await utils.getOptions(["warnOnUnsupportedContent"])),
|
||||
...(await utils.getOptions(["warnOnUnsupportedContent", "logLevel"])),
|
||||
};
|
||||
player.load({ url: swfUrl, base: swfUrl, ...config });
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as utils from "./utils";
|
||||
import { Options, bindBooleanOptions } from "./common";
|
||||
import { Options, bindOptions } from "./common";
|
||||
|
||||
let activeTab: chrome.tabs.Tab | browser.tabs.Tab;
|
||||
let savedOptions: Options;
|
||||
|
@ -114,7 +114,7 @@ function displayTabStatus() {
|
|||
}
|
||||
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
bindBooleanOptions((options) => {
|
||||
bindOptions((options) => {
|
||||
savedOptions = options;
|
||||
optionsChanged();
|
||||
});
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { Options } from "./common";
|
||||
import { LogLevel } from "ruffle-core";
|
||||
|
||||
const DEFAULT_OPTIONS: Options = {
|
||||
ruffleEnable: true,
|
||||
ignoreOptout: false,
|
||||
warnOnUnsupportedContent: true,
|
||||
logLevel: LogLevel.Error,
|
||||
};
|
||||
|
||||
export let i18n: {
|
||||
|
|
Loading…
Reference in New Issue