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