Bug 1903156 - Remove duplicate code from older menus once the new menus land. r=reader-mode-reviewers,desktop-theme-reviewers,dao,Gijs
Differential Revision: https://phabricator.services.mozilla.com/D218772
@@ -3562,9 +3562,6 @@ pref("reader.content_width", 3);
|
||||
// The default relative line height in reader mode (1-9)
|
||||
pref("reader.line_height", 4);
|
||||
|
||||
// Determines if improved text and layout menu is enabled in reader mode.
|
||||
pref("reader.improved_text_menu.enabled", true);
|
||||
|
||||
// The default character spacing in reader mode (1-9)
|
||||
pref("reader.character_spacing", 0);
|
||||
|
||||
@@ -3582,9 +3579,6 @@ pref("reader.color_scheme", "auto");
|
||||
// Color scheme values available in reader mode UI.
|
||||
pref("reader.color_scheme.values", "[\"auto\",\"light\",\"dark\",\"sepia\",\"contrast\",\"gray\"]");
|
||||
|
||||
// Determines if updated color theme menu is enabled in reader mode.
|
||||
pref("reader.colors_menu.enabled", true);
|
||||
|
||||
// The custom color scheme options in reader colors menu.
|
||||
pref("reader.custom_colors.foreground", "");
|
||||
pref("reader.custom_colors.background", "");
|
||||
|
||||
@@ -16,19 +16,10 @@ export function NarrateControls(win, languagePromise) {
|
||||
|
||||
win.addEventListener("unload", this);
|
||||
|
||||
let improvedTextMenuEnabled = Services.prefs.getBoolPref(
|
||||
"reader.improved_text_menu.enabled",
|
||||
false
|
||||
);
|
||||
|
||||
// Append content style sheet in document head
|
||||
let style = win.document.createElement("link");
|
||||
style.rel = "stylesheet";
|
||||
if (improvedTextMenuEnabled) {
|
||||
style.href = "chrome://global/skin/narrate-improved.css";
|
||||
} else {
|
||||
style.href = "chrome://global/skin/narrate.css";
|
||||
}
|
||||
win.document.head.appendChild(style);
|
||||
|
||||
let elemL10nMap = {
|
||||
@@ -62,12 +53,10 @@ export function NarrateControls(win, languagePromise) {
|
||||
dropdownList.className = "dropdown-popup";
|
||||
dropdown.appendChild(dropdownList);
|
||||
|
||||
if (improvedTextMenuEnabled) {
|
||||
let narrateHeader = win.document.createElement("h2");
|
||||
narrateHeader.id = "narrate-header";
|
||||
narrateHeader.textContent = gStrings.GetStringFromName("read-aloud-header");
|
||||
dropdownList.appendChild(narrateHeader);
|
||||
}
|
||||
|
||||
let narrateControl = win.document.createElement("div");
|
||||
narrateControl.className = "narrate-row narrate-control";
|
||||
@@ -77,17 +66,12 @@ export function NarrateControls(win, languagePromise) {
|
||||
narrateRate.className = "narrate-row narrate-rate";
|
||||
dropdownList.appendChild(narrateRate);
|
||||
|
||||
let selectLabel = "";
|
||||
if (improvedTextMenuEnabled) {
|
||||
let hr = win.document.createElement("hr");
|
||||
let voiceHeader = win.document.createElement("h2");
|
||||
voiceHeader.id = "voice-header";
|
||||
voiceHeader.textContent = gStrings.GetStringFromName("select-voice-header");
|
||||
dropdownList.appendChild(hr);
|
||||
dropdownList.appendChild(voiceHeader);
|
||||
} else {
|
||||
selectLabel = gStrings.GetStringFromName("selectvoicelabel");
|
||||
}
|
||||
|
||||
let narrateVoices = win.document.createElement("div");
|
||||
narrateVoices.className = "narrate-row narrate-voices";
|
||||
@@ -197,7 +181,7 @@ export function NarrateControls(win, languagePromise) {
|
||||
this.narrator = new Narrator(win, languagePromise);
|
||||
|
||||
let branch = Services.prefs.getBranch("narrate.");
|
||||
this.voiceSelect = new VoiceSelect(win, selectLabel);
|
||||
this.voiceSelect = new VoiceSelect(win);
|
||||
this.voiceSelect.element.addEventListener("change", this);
|
||||
this.voiceSelect.element.classList.add("voice-select");
|
||||
this.voiceSelect.selectToggle.setAttribute("aria-labelledby", "voice-header");
|
||||
|
||||
@@ -2,15 +2,13 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
export function VoiceSelect(win, label) {
|
||||
export function VoiceSelect(win) {
|
||||
this._winRef = Cu.getWeakReference(win);
|
||||
|
||||
let element = win.document.createElement("div");
|
||||
element.classList.add("voiceselect");
|
||||
// TODO: remove unused .label span with Bug 1903156.
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
element.innerHTML = `<button class="select-toggle" aria-controls="voice-options" aria-expanded="false" role="combobox">
|
||||
<span class="label">${label}</span> <span class="current-voice"></span>
|
||||
<span class="current-voice"></span>
|
||||
</button>
|
||||
<div class="options" id="voice-options" role="listbox"></div>`;
|
||||
|
||||
|
||||
@@ -9,10 +9,6 @@ import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
|
||||
const lazy = {};
|
||||
let gScrollPositions = new Map();
|
||||
let lastSelectedTheme = "auto";
|
||||
let improvedTextMenuEnabled = Services.prefs.getBoolPref(
|
||||
"reader.improved_text_menu.enabled",
|
||||
false
|
||||
);
|
||||
|
||||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
AsyncPrefs: "resource://gre/modules/AsyncPrefs.sys.mjs",
|
||||
@@ -207,19 +203,9 @@ export var AboutReader = function (
|
||||
);
|
||||
|
||||
// fetch color scheme values from prefs.
|
||||
let colorsMenuColorSchemeValues = JSON.parse(
|
||||
let colorSchemeValues = JSON.parse(
|
||||
Services.prefs.getCharPref("reader.color_scheme.values")
|
||||
);
|
||||
// remove contrast and gray options from regular menu.
|
||||
let colorSchemeValues = [...colorsMenuColorSchemeValues];
|
||||
colorSchemeValues.splice(colorSchemeValues.length - 2, 2);
|
||||
|
||||
let colorsMenuColorSchemeOptions = colorsMenuColorSchemeValues.map(value => ({
|
||||
l10nId: COLORSCHEME_L10N_IDS[value],
|
||||
groupName: "color-scheme",
|
||||
value,
|
||||
itemClass: value + "-button",
|
||||
}));
|
||||
|
||||
let colorSchemeOptions = colorSchemeValues.map(value => ({
|
||||
l10nId: COLORSCHEME_L10N_IDS[value],
|
||||
@@ -229,55 +215,28 @@ export var AboutReader = function (
|
||||
}));
|
||||
let colorScheme = Services.prefs.getCharPref("reader.color_scheme");
|
||||
|
||||
if (Services.prefs.getBoolPref("reader.colors_menu.enabled", false)) {
|
||||
doc.getElementById("regular-color-scheme").hidden = true;
|
||||
doc.getElementById("custom-colors-color-scheme").hidden = false;
|
||||
|
||||
this._setupSegmentedButton(
|
||||
"colors-menu-color-scheme-buttons",
|
||||
colorsMenuColorSchemeOptions,
|
||||
colorScheme,
|
||||
this._setColorSchemePref.bind(this)
|
||||
);
|
||||
this._setupCustomColors(
|
||||
CUSTOM_THEME_COLOR_INPUTS,
|
||||
"custom-colors-selection",
|
||||
"about-reader-custom-colors"
|
||||
);
|
||||
this._setupButton(
|
||||
"custom-colors-reset-button",
|
||||
this._resetCustomColors.bind(this)
|
||||
);
|
||||
this._handleThemeFocus();
|
||||
} else {
|
||||
this._setupSegmentedButton(
|
||||
"color-scheme-buttons",
|
||||
colorSchemeOptions,
|
||||
colorScheme,
|
||||
this._setColorSchemePref.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
this._setupCustomColors(
|
||||
CUSTOM_THEME_COLOR_INPUTS,
|
||||
"custom-colors-selection",
|
||||
"about-reader-custom-colors"
|
||||
);
|
||||
|
||||
this._setupButton(
|
||||
"custom-colors-reset-button",
|
||||
this._resetCustomColors.bind(this)
|
||||
);
|
||||
|
||||
this._handleThemeFocus();
|
||||
|
||||
this._setColorSchemePref(colorScheme);
|
||||
|
||||
let fontTypeOptions = [
|
||||
{
|
||||
l10nId: "about-reader-font-type-sans-serif",
|
||||
groupName: "font-type",
|
||||
value: "sans-serif",
|
||||
itemClass: "sans-serif-button",
|
||||
},
|
||||
{
|
||||
l10nId: "about-reader-font-type-serif",
|
||||
groupName: "font-type",
|
||||
value: "serif",
|
||||
itemClass: "serif-button",
|
||||
},
|
||||
];
|
||||
|
||||
// TODO: Move font type pref getting alongside other prefs when old menu is retired.
|
||||
let fontType = Services.prefs.getCharPref("reader.font_type", "sans-serif");
|
||||
|
||||
// Differentiates between the tick mark labels for width vs spacing controls
|
||||
// for localization purposes.
|
||||
const [standardSpacingLabel, wideSpacingLabel] = lazy.l10n.formatMessagesSync(
|
||||
@@ -353,10 +312,6 @@ export var AboutReader = function (
|
||||
textAlignmentOptions = textAlignmentOptions.reverse();
|
||||
}
|
||||
|
||||
if (improvedTextMenuEnabled) {
|
||||
doc.getElementById("regular-text-menu").hidden = true;
|
||||
doc.getElementById("improved-text-menu").hidden = false;
|
||||
|
||||
let selectorFontTypeValues = ["sans-serif", "serif", "monospace"];
|
||||
try {
|
||||
selectorFontTypeValues = JSON.parse(
|
||||
@@ -368,6 +323,7 @@ export var AboutReader = function (
|
||||
e.message
|
||||
);
|
||||
}
|
||||
let fontType = Services.prefs.getCharPref("reader.font_type", "sans-serif");
|
||||
this._setupSelector(
|
||||
"font-type",
|
||||
selectorFontTypeValues,
|
||||
@@ -388,10 +344,7 @@ export var AboutReader = function (
|
||||
e.message
|
||||
);
|
||||
}
|
||||
let fontWeight = Services.prefs.getCharPref(
|
||||
"reader.font_weight",
|
||||
"regular"
|
||||
);
|
||||
let fontWeight = Services.prefs.getCharPref("reader.font_weight", "regular");
|
||||
this._setupSelector(
|
||||
"font-weight",
|
||||
fontWeightValues,
|
||||
@@ -406,9 +359,9 @@ export var AboutReader = function (
|
||||
"content-width",
|
||||
contentWidthSliderOptions,
|
||||
contentWidth,
|
||||
this._setContentWidthSlider.bind(this)
|
||||
this._setContentWidth.bind(this)
|
||||
);
|
||||
this._setContentWidthSlider(contentWidth);
|
||||
this._setContentWidth(contentWidth);
|
||||
|
||||
let lineSpacing = Services.prefs.getIntPref("reader.line_height", 4);
|
||||
this._setupSlider(
|
||||
@@ -458,20 +411,6 @@ export var AboutReader = function (
|
||||
);
|
||||
|
||||
this._handleTextLayoutFocus();
|
||||
} else {
|
||||
this._setupSegmentedButton(
|
||||
"font-type-buttons",
|
||||
fontTypeOptions,
|
||||
fontType,
|
||||
this._setFontType.bind(this)
|
||||
);
|
||||
|
||||
this._setupContentWidthButtons();
|
||||
|
||||
this._setupLineHeightButtons();
|
||||
|
||||
this._setFontType(fontType);
|
||||
}
|
||||
|
||||
this._setupFontSizeButtons();
|
||||
|
||||
@@ -794,15 +733,8 @@ AboutReader.prototype = {
|
||||
},
|
||||
|
||||
_setupFontSizeButtons() {
|
||||
let plusButton, minusButton;
|
||||
|
||||
if (improvedTextMenuEnabled) {
|
||||
plusButton = this._doc.querySelector(".text-size-plus-button");
|
||||
minusButton = this._doc.querySelector(".text-size-minus-button");
|
||||
} else {
|
||||
plusButton = this._doc.querySelector(".plus-button");
|
||||
minusButton = this._doc.querySelector(".minus-button");
|
||||
}
|
||||
let plusButton = this._doc.querySelector(".text-size-plus-button");
|
||||
let minusButton = this._doc.querySelector(".text-size-minus-button");
|
||||
|
||||
let currentSize = Services.prefs.getIntPref("reader.font_size");
|
||||
this._setFontSize(currentSize);
|
||||
@@ -832,18 +764,9 @@ AboutReader.prototype = {
|
||||
},
|
||||
|
||||
_updateFontSizeButtonControls() {
|
||||
let plusButton, minusButton;
|
||||
let currentSize = this._fontSize;
|
||||
|
||||
if (improvedTextMenuEnabled) {
|
||||
plusButton = this._doc.querySelector(".text-size-plus-button");
|
||||
minusButton = this._doc.querySelector(".text-size-minus-button");
|
||||
} else {
|
||||
plusButton = this._doc.querySelector(".plus-button");
|
||||
minusButton = this._doc.querySelector(".minus-button");
|
||||
let fontValue = this._doc.querySelector(".font-size-value");
|
||||
fontValue.textContent = currentSize;
|
||||
}
|
||||
let plusButton = this._doc.querySelector(".text-size-plus-button");
|
||||
let minusButton = this._doc.querySelector(".text-size-minus-button");
|
||||
|
||||
if (currentSize === this.FONT_SIZE_MIN) {
|
||||
minusButton.setAttribute("disabled", true);
|
||||
@@ -865,172 +788,6 @@ AboutReader.prototype = {
|
||||
this._scheduleToolbarOverlapHandler();
|
||||
},
|
||||
|
||||
_setContentWidth(newContentWidth) {
|
||||
this._contentWidth = newContentWidth;
|
||||
this._displayContentWidth(newContentWidth);
|
||||
let width = 20 + 5 * (this._contentWidth - 1) + "em";
|
||||
this._doc.body.style.setProperty("--content-width", width);
|
||||
this._scheduleToolbarOverlapHandler();
|
||||
return lazy.AsyncPrefs.set("reader.content_width", this._contentWidth);
|
||||
},
|
||||
|
||||
_displayContentWidth(currentContentWidth) {
|
||||
let contentWidthValue = this._doc.querySelector(".content-width-value");
|
||||
contentWidthValue.textContent = currentContentWidth;
|
||||
},
|
||||
|
||||
_setupContentWidthButtons() {
|
||||
const CONTENT_WIDTH_MIN = 1;
|
||||
const CONTENT_WIDTH_MAX = 9;
|
||||
|
||||
let currentContentWidth = Services.prefs.getIntPref("reader.content_width");
|
||||
currentContentWidth = Math.max(
|
||||
CONTENT_WIDTH_MIN,
|
||||
Math.min(CONTENT_WIDTH_MAX, currentContentWidth)
|
||||
);
|
||||
|
||||
this._displayContentWidth(currentContentWidth);
|
||||
|
||||
let plusButton = this._doc.querySelector(".content-width-plus-button");
|
||||
let minusButton = this._doc.querySelector(".content-width-minus-button");
|
||||
|
||||
function updateControls() {
|
||||
if (currentContentWidth === CONTENT_WIDTH_MIN) {
|
||||
minusButton.setAttribute("disabled", true);
|
||||
} else {
|
||||
minusButton.removeAttribute("disabled");
|
||||
}
|
||||
if (currentContentWidth === CONTENT_WIDTH_MAX) {
|
||||
plusButton.setAttribute("disabled", true);
|
||||
} else {
|
||||
plusButton.removeAttribute("disabled");
|
||||
}
|
||||
}
|
||||
|
||||
updateControls();
|
||||
this._setContentWidth(currentContentWidth);
|
||||
|
||||
plusButton.addEventListener(
|
||||
"click",
|
||||
event => {
|
||||
if (!event.isTrusted) {
|
||||
return;
|
||||
}
|
||||
event.stopPropagation();
|
||||
|
||||
if (currentContentWidth >= CONTENT_WIDTH_MAX) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentContentWidth++;
|
||||
updateControls();
|
||||
this._setContentWidth(currentContentWidth);
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
minusButton.addEventListener(
|
||||
"click",
|
||||
event => {
|
||||
if (!event.isTrusted) {
|
||||
return;
|
||||
}
|
||||
event.stopPropagation();
|
||||
|
||||
if (currentContentWidth <= CONTENT_WIDTH_MIN) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentContentWidth--;
|
||||
updateControls();
|
||||
this._setContentWidth(currentContentWidth);
|
||||
},
|
||||
true
|
||||
);
|
||||
},
|
||||
|
||||
_setLineHeight(newLineHeight) {
|
||||
this._displayLineHeight(newLineHeight);
|
||||
let height = 1 + 0.2 * (newLineHeight - 1) + "em";
|
||||
this._containerElement.style.setProperty("--line-height", height);
|
||||
return lazy.AsyncPrefs.set("reader.line_height", newLineHeight);
|
||||
},
|
||||
|
||||
_displayLineHeight(currentLineHeight) {
|
||||
let lineHeightValue = this._doc.querySelector(".line-height-value");
|
||||
lineHeightValue.textContent = currentLineHeight;
|
||||
},
|
||||
|
||||
_setupLineHeightButtons() {
|
||||
const LINE_HEIGHT_MIN = 1;
|
||||
const LINE_HEIGHT_MAX = 9;
|
||||
|
||||
let currentLineHeight = Services.prefs.getIntPref("reader.line_height");
|
||||
currentLineHeight = Math.max(
|
||||
LINE_HEIGHT_MIN,
|
||||
Math.min(LINE_HEIGHT_MAX, currentLineHeight)
|
||||
);
|
||||
|
||||
this._displayLineHeight(currentLineHeight);
|
||||
|
||||
let plusButton = this._doc.querySelector(".line-height-plus-button");
|
||||
let minusButton = this._doc.querySelector(".line-height-minus-button");
|
||||
|
||||
function updateControls() {
|
||||
if (currentLineHeight === LINE_HEIGHT_MIN) {
|
||||
minusButton.setAttribute("disabled", true);
|
||||
} else {
|
||||
minusButton.removeAttribute("disabled");
|
||||
}
|
||||
if (currentLineHeight === LINE_HEIGHT_MAX) {
|
||||
plusButton.setAttribute("disabled", true);
|
||||
} else {
|
||||
plusButton.removeAttribute("disabled");
|
||||
}
|
||||
}
|
||||
|
||||
updateControls();
|
||||
this._setLineHeight(currentLineHeight);
|
||||
|
||||
plusButton.addEventListener(
|
||||
"click",
|
||||
event => {
|
||||
if (!event.isTrusted) {
|
||||
return;
|
||||
}
|
||||
event.stopPropagation();
|
||||
|
||||
if (currentLineHeight >= LINE_HEIGHT_MAX) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentLineHeight++;
|
||||
updateControls();
|
||||
this._setLineHeight(currentLineHeight);
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
minusButton.addEventListener(
|
||||
"click",
|
||||
event => {
|
||||
if (!event.isTrusted) {
|
||||
return;
|
||||
}
|
||||
event.stopPropagation();
|
||||
|
||||
if (currentLineHeight <= LINE_HEIGHT_MIN) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentLineHeight--;
|
||||
updateControls();
|
||||
this._setLineHeight(currentLineHeight);
|
||||
},
|
||||
true
|
||||
);
|
||||
},
|
||||
|
||||
_setupSelector(id, options, initialValue, callback, l10nIds) {
|
||||
let doc = this._doc;
|
||||
let selector = doc.getElementById(`${id}-selector`);
|
||||
@@ -1098,8 +855,7 @@ AboutReader.prototype = {
|
||||
sliderContainer.appendChild(slider);
|
||||
},
|
||||
|
||||
// Rename this function to setContentWidth when the old menu is retired.
|
||||
_setContentWidthSlider(newContentWidth) {
|
||||
_setContentWidth(newContentWidth) {
|
||||
// We map the slider range [1-9] to 20-60em.
|
||||
let width = 20 + 5 * (newContentWidth - 1) + "em";
|
||||
this._doc.body.style.setProperty("--content-width", width);
|
||||
@@ -1206,7 +962,7 @@ AboutReader.prototype = {
|
||||
|
||||
let contentWidth = doc.querySelector("#content-width-slider moz-slider");
|
||||
contentWidth.setAttribute("value", initial.contentWidth);
|
||||
this._setContentWidthSlider(initial.contentWidth);
|
||||
this._setContentWidth(initial.contentWidth);
|
||||
|
||||
let lineSpacing = doc.querySelector("#line-spacing-slider moz-slider");
|
||||
lineSpacing.setAttribute("value", initial.lineSpacing);
|
||||
@@ -1302,14 +1058,10 @@ AboutReader.prototype = {
|
||||
// Pref values include "auto", "dark", "light", "sepia",
|
||||
// "gray", "contrast", and "custom"
|
||||
_setColorSchemePref(colorSchemePref, fromInputEvent = false) {
|
||||
// The input event for the last selected segmented button is fired
|
||||
if (this._colorScheme == "custom" && fromInputEvent) {
|
||||
// The input event for the last selected radio button is fired
|
||||
// upon loading a reader article in the same session. To prevent it
|
||||
// from overwriting custom colors, we return false.
|
||||
const colorsMenuEnabled = Services.prefs.getBoolPref(
|
||||
"reader.colors_menu.enabled",
|
||||
false
|
||||
);
|
||||
if (colorsMenuEnabled && this._colorScheme == "custom" && fromInputEvent) {
|
||||
lastSelectedTheme = colorSchemePref;
|
||||
return false;
|
||||
}
|
||||
@@ -1319,23 +1071,162 @@ AboutReader.prototype = {
|
||||
return true;
|
||||
},
|
||||
|
||||
_setFontType(newFontType) {
|
||||
if (this._fontType === newFontType) {
|
||||
return false;
|
||||
_handleColorsTabClick(option) {
|
||||
let doc = this._doc;
|
||||
let deck = doc.querySelector("named-deck");
|
||||
if (option == deck.getAttribute("selected-view")) {
|
||||
return;
|
||||
}
|
||||
|
||||
let bodyClasses = this._doc.body.classList;
|
||||
if (option == "customtheme") {
|
||||
this._setColorSchemePref("custom");
|
||||
lazy.AsyncPrefs.set("reader.color_scheme", "custom");
|
||||
|
||||
if (this._fontType) {
|
||||
bodyClasses.remove(this._fontType);
|
||||
// Store the last selected preset theme button.
|
||||
const colorSchemePresets = doc.querySelector(".color-scheme-buttons");
|
||||
const labels = colorSchemePresets.querySelectorAll("label");
|
||||
labels.forEach(label => {
|
||||
if (label.hasAttribute("checked")) {
|
||||
lastSelectedTheme = label.className.split("-")[0];
|
||||
}
|
||||
});
|
||||
} else if (option == "fxtheme") {
|
||||
this._setColorSchemePref(lastSelectedTheme);
|
||||
lazy.AsyncPrefs.set("reader.color_scheme", lastSelectedTheme);
|
||||
// set the last selected button to checked.
|
||||
const colorSchemePresets = doc.querySelector(".color-scheme-buttons");
|
||||
const labels = colorSchemePresets.querySelectorAll("label");
|
||||
labels.forEach(label => {
|
||||
if (label.className == `${lastSelectedTheme}-button`) {
|
||||
label.setAttribute("checked", "true");
|
||||
label.previousElementSibling.setAttribute("checked", "true");
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_setupColorsTabs(options, callback) {
|
||||
let doc = this._doc;
|
||||
let colorScheme = Services.prefs.getCharPref("reader.color_scheme");
|
||||
for (let option of options) {
|
||||
let tabButton = doc.getElementById(`tabs-deck-button-${option}`);
|
||||
// Open custom theme tab if color scheme is set to custom.
|
||||
if (option == "customtheme" && colorScheme == "custom") {
|
||||
tabButton.click();
|
||||
}
|
||||
tabButton.addEventListener(
|
||||
"click",
|
||||
function (aEvent) {
|
||||
if (!aEvent.isTrusted) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._fontType = newFontType;
|
||||
bodyClasses.add(this._fontType);
|
||||
callback(option);
|
||||
},
|
||||
true
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
lazy.AsyncPrefs.set("reader.font_type", this._fontType);
|
||||
_setupColorInput(prop) {
|
||||
let doc = this._doc;
|
||||
let input = doc.createElement("color-input");
|
||||
input.setAttribute("prop-name", prop);
|
||||
let labelL10nId = `about-reader-custom-colors-${prop}`;
|
||||
input.setAttribute("data-l10n-id", labelL10nId);
|
||||
|
||||
return true;
|
||||
let pref = `reader.custom_colors.${prop}`;
|
||||
let customColor = Services.prefs.getStringPref(pref, "");
|
||||
// Set the swatch color from prefs if one has been set.
|
||||
if (customColor) {
|
||||
input.setAttribute("color", customColor);
|
||||
} else {
|
||||
let defaultColor = DEFAULT_COLORS[prop];
|
||||
input.setAttribute("color", defaultColor);
|
||||
}
|
||||
|
||||
// Attach event listener to update the pref and page colors on input.
|
||||
input.addEventListener("color-picked", e => {
|
||||
const cssPropToUpdate = `--custom-theme-${prop}`;
|
||||
this._doc.body.style.setProperty(cssPropToUpdate, e.detail);
|
||||
|
||||
const prefToUpdate = `reader.custom_colors.${prop}`;
|
||||
lazy.AsyncPrefs.set(prefToUpdate, e.detail);
|
||||
});
|
||||
|
||||
return input;
|
||||
},
|
||||
|
||||
_setupCustomColors(options, id) {
|
||||
let doc = this._doc;
|
||||
const list = doc.getElementsByClassName(id)[0];
|
||||
|
||||
for (let option of options) {
|
||||
let listItem = doc.createElement("li");
|
||||
let colorInput = this._setupColorInput(option);
|
||||
listItem.appendChild(colorInput);
|
||||
list.appendChild(listItem);
|
||||
}
|
||||
},
|
||||
|
||||
_resetCustomColors() {
|
||||
// Need to reset prefs, page colors, and color inputs.
|
||||
const colorInputs = this._doc.querySelectorAll("color-input");
|
||||
colorInputs.forEach(input => {
|
||||
let property = input.getAttribute("prop-name");
|
||||
let pref = `reader.custom_colors.${property}`;
|
||||
lazy.AsyncPrefs.set(pref, "");
|
||||
|
||||
// Set css props to empty strings so they use fallback value.
|
||||
let cssProp = `--custom-theme-${property}`;
|
||||
this._doc.body.style.setProperty(cssProp, "");
|
||||
|
||||
let defaultColor = DEFAULT_COLORS[property];
|
||||
input.setAttribute("color", defaultColor);
|
||||
});
|
||||
},
|
||||
|
||||
_handleThemeFocus() {
|
||||
// Retain focus inside the menu panel.
|
||||
let doc = this._doc;
|
||||
let themeButtons = doc.querySelector(".color-scheme-buttons");
|
||||
let defaultThemeFirstFocusable = doc.querySelector(
|
||||
"#tabs-deck-button-fxtheme"
|
||||
);
|
||||
let themeResetButton = doc.querySelector(".custom-colors-reset-button");
|
||||
let customThemeFirstFocusable = doc.querySelector(
|
||||
"#tabs-deck-button-customtheme"
|
||||
);
|
||||
|
||||
themeButtons.addEventListener("keydown", e => {
|
||||
if (e.key === "Tab" && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
defaultThemeFirstFocusable.focus();
|
||||
}
|
||||
});
|
||||
themeResetButton.addEventListener("keydown", e => {
|
||||
if (e.key === "Tab" && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
customThemeFirstFocusable.focus();
|
||||
}
|
||||
});
|
||||
defaultThemeFirstFocusable.addEventListener("keydown", e => {
|
||||
if (e.key === "Tab" && e.shiftKey) {
|
||||
e.preventDefault();
|
||||
let themeLabels = themeButtons.getElementsByTagName("label");
|
||||
for (const label of themeLabels) {
|
||||
if (label.hasAttribute("checked")) {
|
||||
doc.querySelector(`.${label.className}`).focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
customThemeFirstFocusable.addEventListener("keydown", e => {
|
||||
if (e.key === "Tab" && e.shiftKey) {
|
||||
e.preventDefault();
|
||||
themeResetButton.focus();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
async _loadArticle(docContentType = "document") {
|
||||
@@ -1702,169 +1593,6 @@ AboutReader.prototype = {
|
||||
);
|
||||
},
|
||||
|
||||
_handleColorsTabClick(option) {
|
||||
let doc = this._doc;
|
||||
let deck = doc.querySelector("named-deck");
|
||||
if (option == deck.getAttribute("selected-view")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (option == "customtheme") {
|
||||
this._setColorSchemePref("custom");
|
||||
lazy.AsyncPrefs.set("reader.color_scheme", "custom");
|
||||
|
||||
// Store the last selected preset theme button.
|
||||
const colorSchemePresets = doc.querySelector(
|
||||
".colors-menu-color-scheme-buttons"
|
||||
);
|
||||
const labels = colorSchemePresets.querySelectorAll("label");
|
||||
labels.forEach(label => {
|
||||
if (label.hasAttribute("checked")) {
|
||||
lastSelectedTheme = label.className.split("-")[0];
|
||||
}
|
||||
});
|
||||
} else if (option == "fxtheme") {
|
||||
this._setColorSchemePref(lastSelectedTheme);
|
||||
lazy.AsyncPrefs.set("reader.color_scheme", lastSelectedTheme);
|
||||
// set the last selected button to checked.
|
||||
const colorSchemePresets = doc.querySelector(
|
||||
".colors-menu-color-scheme-buttons"
|
||||
);
|
||||
const labels = colorSchemePresets.querySelectorAll("label");
|
||||
labels.forEach(label => {
|
||||
if (label.className == `${lastSelectedTheme}-button`) {
|
||||
label.setAttribute("checked", "true");
|
||||
label.previousElementSibling.setAttribute("checked", "true");
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_setupColorsTabs(options, callback) {
|
||||
let doc = this._doc;
|
||||
let colorScheme = Services.prefs.getCharPref("reader.color_scheme");
|
||||
for (let option of options) {
|
||||
let tabButton = doc.getElementById(`tabs-deck-button-${option}`);
|
||||
// Open custom theme tab if color scheme is set to custom.
|
||||
if (option == "customtheme" && colorScheme == "custom") {
|
||||
tabButton.click();
|
||||
}
|
||||
tabButton.addEventListener(
|
||||
"click",
|
||||
function (aEvent) {
|
||||
if (!aEvent.isTrusted) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback(option);
|
||||
},
|
||||
true
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
_setupColorInput(prop) {
|
||||
let doc = this._doc;
|
||||
let input = doc.createElement("color-input");
|
||||
input.setAttribute("prop-name", prop);
|
||||
let labelL10nId = `about-reader-custom-colors-${prop}`;
|
||||
input.setAttribute("data-l10n-id", labelL10nId);
|
||||
input.setAttribute("data-telemetry-id", `custom-color-picker-${prop}`);
|
||||
|
||||
let pref = `reader.custom_colors.${prop}`;
|
||||
let customColor = Services.prefs.getStringPref(pref, "");
|
||||
// Set the swatch color from prefs if one has been set.
|
||||
if (customColor) {
|
||||
input.setAttribute("color", customColor);
|
||||
} else {
|
||||
let defaultColor = DEFAULT_COLORS[prop];
|
||||
input.setAttribute("color", defaultColor);
|
||||
}
|
||||
|
||||
// Attach event listener to update the pref and page colors on input.
|
||||
input.addEventListener("color-picked", e => {
|
||||
const cssPropToUpdate = `--custom-theme-${prop}`;
|
||||
this._doc.body.style.setProperty(cssPropToUpdate, e.detail);
|
||||
|
||||
const prefToUpdate = `reader.custom_colors.${prop}`;
|
||||
lazy.AsyncPrefs.set(prefToUpdate, e.detail);
|
||||
});
|
||||
|
||||
return input;
|
||||
},
|
||||
|
||||
_setupCustomColors(options, id) {
|
||||
let doc = this._doc;
|
||||
const list = doc.getElementsByClassName(id)[0];
|
||||
|
||||
for (let option of options) {
|
||||
let listItem = doc.createElement("li");
|
||||
let colorInput = this._setupColorInput(option);
|
||||
listItem.appendChild(colorInput);
|
||||
list.appendChild(listItem);
|
||||
}
|
||||
},
|
||||
|
||||
_resetCustomColors() {
|
||||
// Need to reset prefs, page colors, and color inputs.
|
||||
const colorInputs = this._doc.querySelectorAll("color-input");
|
||||
colorInputs.forEach(input => {
|
||||
let property = input.getAttribute("prop-name");
|
||||
let pref = `reader.custom_colors.${property}`;
|
||||
lazy.AsyncPrefs.set(pref, "");
|
||||
|
||||
// Set css props to empty strings so they use fallback value.
|
||||
let cssProp = `--custom-theme-${property}`;
|
||||
this._doc.body.style.setProperty(cssProp, "");
|
||||
|
||||
let defaultColor = DEFAULT_COLORS[property];
|
||||
input.setAttribute("color", defaultColor);
|
||||
});
|
||||
},
|
||||
|
||||
_handleThemeFocus() {
|
||||
// Retain focus inside the menu panel.
|
||||
let doc = this._doc;
|
||||
let themeButtons = doc.querySelector(".colors-menu-color-scheme-buttons");
|
||||
let defaultThemeFirstFocusable = doc.querySelector(
|
||||
"#tabs-deck-button-fxtheme"
|
||||
);
|
||||
let themeResetButton = doc.querySelector(".custom-colors-reset-button");
|
||||
let customThemeFirstFocusable = doc.querySelector(
|
||||
"#tabs-deck-button-customtheme"
|
||||
);
|
||||
|
||||
themeButtons.addEventListener("keydown", e => {
|
||||
if (e.key === "Tab" && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
defaultThemeFirstFocusable.focus();
|
||||
}
|
||||
});
|
||||
themeResetButton.addEventListener("keydown", e => {
|
||||
if (e.key === "Tab" && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
customThemeFirstFocusable.focus();
|
||||
}
|
||||
});
|
||||
defaultThemeFirstFocusable.addEventListener("keydown", e => {
|
||||
if (e.key === "Tab" && e.shiftKey) {
|
||||
e.preventDefault();
|
||||
let themeLabels = themeButtons.getElementsByTagName("label");
|
||||
for (const label of themeLabels) {
|
||||
if (label.hasAttribute("checked")) {
|
||||
doc.querySelector(`.${label.className}`).focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
customThemeFirstFocusable.addEventListener("keydown", e => {
|
||||
if (e.key === "Tab" && e.shiftKey) {
|
||||
e.preventDefault();
|
||||
themeResetButton.focus();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_toggleDropdownClicked(event) {
|
||||
let dropdown = event.target.closest(".dropdown");
|
||||
|
||||
|
||||
@@ -54,14 +54,10 @@
|
||||
data-l10n-id="about-reader-toolbar-close"
|
||||
></span>
|
||||
</button>
|
||||
<ul
|
||||
class="dropdown improved-style-dropdown"
|
||||
id="improved-text-menu"
|
||||
hidden="true"
|
||||
>
|
||||
<ul class="dropdown text-layout-dropdown">
|
||||
<li>
|
||||
<button
|
||||
class="dropdown-toggle toolbar-button improved-style-button"
|
||||
class="dropdown-toggle toolbar-button text-layout-button"
|
||||
aria-labelledby="toolbar-text-layout-controls"
|
||||
data-telemetry-id="reader-text-layout-controls"
|
||||
>
|
||||
@@ -155,67 +151,7 @@
|
||||
</details>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="dropdown style-dropdown" id="regular-text-menu">
|
||||
<li>
|
||||
<button
|
||||
class="dropdown-toggle toolbar-button style-button"
|
||||
aria-labelledby="toolbar-type-controls"
|
||||
data-telemetry-id="reader-type-controls"
|
||||
>
|
||||
<span
|
||||
class="hover-label"
|
||||
id="toolbar-type-controls"
|
||||
data-l10n-id="about-reader-toolbar-type-controls"
|
||||
></span>
|
||||
</button>
|
||||
</li>
|
||||
<li class="dropdown-popup">
|
||||
<div class="font-type-buttons radiorow"></div>
|
||||
<div class="font-size-buttons buttonrow">
|
||||
<button
|
||||
class="minus-button"
|
||||
data-l10n-id="about-reader-toolbar-minus"
|
||||
></button>
|
||||
<span class="font-size-value"></span>
|
||||
<button
|
||||
class="plus-button"
|
||||
data-l10n-id="about-reader-toolbar-plus"
|
||||
></button>
|
||||
</div>
|
||||
<div class="content-width-buttons buttonrow">
|
||||
<button
|
||||
class="content-width-minus-button"
|
||||
data-l10n-id="about-reader-toolbar-contentwidthminus"
|
||||
></button>
|
||||
<span class="content-width-value"></span>
|
||||
<button
|
||||
class="content-width-plus-button"
|
||||
data-l10n-id="about-reader-toolbar-contentwidthplus"
|
||||
></button>
|
||||
</div>
|
||||
<div class="line-height-buttons buttonrow">
|
||||
<button
|
||||
class="line-height-minus-button"
|
||||
data-l10n-id="about-reader-toolbar-lineheightminus"
|
||||
></button>
|
||||
<span class="line-height-value"></span>
|
||||
<button
|
||||
class="line-height-plus-button"
|
||||
data-l10n-id="about-reader-toolbar-lineheightplus"
|
||||
></button>
|
||||
</div>
|
||||
<div
|
||||
class="color-scheme-buttons radiorow"
|
||||
id="regular-color-scheme"
|
||||
hidden="false"
|
||||
></div>
|
||||
</li>
|
||||
</ul>
|
||||
<ul
|
||||
class="dropdown colors-dropdown"
|
||||
id="custom-colors-color-scheme"
|
||||
hidden="true"
|
||||
>
|
||||
<ul class="dropdown colors-dropdown">
|
||||
<li>
|
||||
<button
|
||||
class="dropdown-toggle toolbar-button colors-button"
|
||||
@@ -251,10 +187,7 @@
|
||||
></button>
|
||||
</button-group>
|
||||
<named-deck id="tabs-deck" is-tabbed>
|
||||
<div
|
||||
name="fxtheme"
|
||||
class="colors-menu-color-scheme-buttons radiorow"
|
||||
></div>
|
||||
<div name="fxtheme" class="color-scheme-buttons radiorow"></div>
|
||||
<div name="customtheme">
|
||||
<ul class="custom-colors-selection"></ul>
|
||||
<button
|
||||
|
||||
@@ -68,7 +68,6 @@ add_task(async function () {
|
||||
|
||||
async function testColorsFocus() {
|
||||
// Set the theme selection to auto.
|
||||
Services.prefs.setBoolPref("reader.colors_menu.enabled", true);
|
||||
Services.prefs.setCharPref("reader.color_scheme", "auto");
|
||||
|
||||
// Open a browser tab, enter reader mode, and test if focus stays
|
||||
|
||||
@@ -11,7 +11,6 @@ const TEST_PATH = getRootDirectory(gTestPath).replace(
|
||||
|
||||
async function testCustomColors(aPref, color) {
|
||||
// Set the theme selection to custom.
|
||||
Services.prefs.setBoolPref("reader.colors_menu.enabled", true);
|
||||
Services.prefs.setCharPref("reader.color_scheme", "custom");
|
||||
|
||||
// Set the custom pref to the color value.
|
||||
|
||||
@@ -106,9 +106,9 @@ add_task(async function () {
|
||||
|
||||
await SpecialPowers.spawn(browser, [], async function () {
|
||||
let doc = content.document;
|
||||
let dropdown = doc.querySelector(".improved-style-dropdown");
|
||||
let dropdown = doc.querySelector(".text-layout-dropdown");
|
||||
|
||||
doc.querySelector(".improved-style-button").click();
|
||||
doc.querySelector(".text-layout-button").click();
|
||||
ok(dropdown.classList.contains("open"), "dropdown is open");
|
||||
|
||||
// hover outside the dropdown and scroll
|
||||
@@ -122,9 +122,7 @@ add_task(async function () {
|
||||
});
|
||||
await scrollEventPromise;
|
||||
await SpecialPowers.spawn(browser, [], async function () {
|
||||
let dropdown = content.document.querySelector(
|
||||
".improved-style-dropdown"
|
||||
);
|
||||
let dropdown = content.document.querySelector(".text-layout-dropdown");
|
||||
ok(!dropdown.classList.contains("open"), "dropdown is closed");
|
||||
});
|
||||
|
||||
@@ -136,10 +134,10 @@ add_task(async function () {
|
||||
|
||||
await SpecialPowers.spawn(browser, [], async function () {
|
||||
let doc = content.document;
|
||||
let dropdown = doc.querySelector(".improved-style-dropdown");
|
||||
let dropdown = doc.querySelector(".text-layout-dropdown");
|
||||
|
||||
// reopen the dropdown
|
||||
doc.querySelector(".improved-style-button").click();
|
||||
doc.querySelector(".text-layout-button").click();
|
||||
ok(dropdown.classList.contains("open"), "dropdown is open");
|
||||
|
||||
// hover over the dropdown and scroll
|
||||
@@ -155,9 +153,7 @@ add_task(async function () {
|
||||
});
|
||||
await scrollEventPromise;
|
||||
await SpecialPowers.spawn(browser, [], async function () {
|
||||
let dropdown = content.document.querySelector(
|
||||
".improved-style-dropdown"
|
||||
);
|
||||
let dropdown = content.document.querySelector(".text-layout-dropdown");
|
||||
ok(dropdown.classList.contains("open"), "dropdown remains open");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -24,9 +24,6 @@ const defaultValues = {
|
||||
* the document layout correctly.
|
||||
*/
|
||||
async function testTextLayout(aPref, value, cssProp, cssValue) {
|
||||
// Enable the improved text and layout menu.
|
||||
Services.prefs.setBoolPref("reader.improved_text_menu.enabled", true);
|
||||
|
||||
// Set the pref to the custom value.
|
||||
const valueType = typeof value;
|
||||
if (valueType == "number") {
|
||||
@@ -75,9 +72,6 @@ async function testTextLayout(aPref, value, cssProp, cssValue) {
|
||||
* Test that the reset button restores all layout options to defaults.
|
||||
*/
|
||||
async function testTextLayoutReset() {
|
||||
// Enable the improved text and layout menu.
|
||||
Services.prefs.setBoolPref("reader.improved_text_menu.enabled", true);
|
||||
|
||||
// Set all prefs to non-default values.
|
||||
Services.prefs.setIntPref(`reader.font_size`, 15);
|
||||
Services.prefs.setCharPref(`reader.font_type`, "serif");
|
||||
@@ -134,9 +128,6 @@ async function testTextLayoutReset() {
|
||||
* Test that the focus stays within the text and layout menu.
|
||||
*/
|
||||
async function testTextLayoutFocus() {
|
||||
// Enable the improved text and layout menu.
|
||||
Services.prefs.setBoolPref("reader.improved_text_menu.enabled", true);
|
||||
|
||||
// Open a browser tab, enter reader mode, and test if the focus stays
|
||||
// within the menu.
|
||||
await BrowserTestUtils.withNewTab(
|
||||
@@ -153,7 +144,7 @@ async function testTextLayoutFocus() {
|
||||
|
||||
await SpecialPowers.spawn(browser, [], () => {
|
||||
let doc = content.document;
|
||||
doc.querySelector(".improved-style-button").click();
|
||||
doc.querySelector(".text-layout-button").click();
|
||||
|
||||
let firstFocusableElement = doc.querySelector(
|
||||
".text-size-minus-button"
|
||||
|
||||
@@ -22,7 +22,6 @@ next-label = Forward (%S)
|
||||
speed = Speed
|
||||
slow-speed-label = Slow down narration
|
||||
fast-speed-label = Speed up narration
|
||||
selectvoicelabel = Voice:
|
||||
select-voice-header = Voice
|
||||
# Default voice is determined by the language of the document.
|
||||
defaultvoice = Default
|
||||
|
||||
@@ -29,21 +29,6 @@ about-reader-estimated-read-time =
|
||||
*[other] { $range } minutes
|
||||
}
|
||||
|
||||
## These are used as tooltips in Type Control
|
||||
|
||||
about-reader-toolbar-minus =
|
||||
.title = Decrease font size
|
||||
about-reader-toolbar-plus =
|
||||
.title = Increase font size
|
||||
about-reader-toolbar-contentwidthminus =
|
||||
.title = Decrease Content Width
|
||||
about-reader-toolbar-contentwidthplus =
|
||||
.title = Increase Content Width
|
||||
about-reader-toolbar-lineheightminus =
|
||||
.title = Decrease Line Height
|
||||
about-reader-toolbar-lineheightplus =
|
||||
.title = Increase Line Height
|
||||
|
||||
## These are the styles of typeface that are options in the reader view controls.
|
||||
|
||||
about-reader-font-type-serif = Serif
|
||||
@@ -53,7 +38,6 @@ about-reader-font-type-monospace = Monospace
|
||||
## Reader View toolbar buttons
|
||||
|
||||
about-reader-toolbar-close = Close Reader View
|
||||
about-reader-toolbar-type-controls = Type controls
|
||||
about-reader-toolbar-text-layout-controls = Text and layout
|
||||
about-reader-toolbar-theme-controls = Theme
|
||||
about-reader-toolbar-savetopocket = Save to { -pocket-brand-name }
|
||||
@@ -84,11 +68,16 @@ about-reader-custom-colors-selection-highlight = Highlighter for read aloud
|
||||
|
||||
about-reader-reset-button = Reset defaults
|
||||
|
||||
## Reader View improved text and layout menu
|
||||
## Reader View text and layout menu
|
||||
|
||||
about-reader-text-header = Text
|
||||
|
||||
about-reader-text-size-label = Text size
|
||||
about-reader-toolbar-minus =
|
||||
.title = Decrease font size
|
||||
about-reader-toolbar-plus =
|
||||
.title = Increase font size
|
||||
|
||||
about-reader-font-type-selector-label = Font
|
||||
about-reader-font-weight-selector-label = Font weight
|
||||
|
||||
|
||||
@@ -58,8 +58,6 @@ body {
|
||||
--popup-button-border: rgba(0, 0, 0, 0.2);
|
||||
--selected-background: rgba(0, 97, 224, 0.3);
|
||||
--outline-focus-color: var(--primary-color);
|
||||
--font-value-background: rgb(240, 240, 244);
|
||||
--font-value-border: var(--grey-30);
|
||||
--icon-fill: rgb(91, 91, 102);
|
||||
--icon-disabled-fill: rgba(91, 91, 102, 0.4);
|
||||
--text-selected-background: var(--selected-background);
|
||||
@@ -107,8 +105,6 @@ body.contrast {
|
||||
--popup-button-border: rgba(255, 255, 255, 0.2);
|
||||
--popup-line: rgba(249, 249, 250, 0.1);
|
||||
--popup-button-background: rgb(43, 42, 51);
|
||||
--font-value-background: rgba(249, 249, 250, 0.15);
|
||||
--font-value-border: #656468;
|
||||
--icon-disabled-fill: rgba(251, 251, 254, 0.4);
|
||||
--link-selected-foreground: #fff;
|
||||
--visited-link-foreground: #e675fd;
|
||||
@@ -187,8 +183,6 @@ body.hcm {
|
||||
--link-color-hover: SelectedItem;
|
||||
--selected-background: Canvas;
|
||||
--outline-focus-color: CanvasText;
|
||||
--font-value-background: Canvas;
|
||||
--font-value-border: CanvasText;
|
||||
--icon-fill: ButtonText;
|
||||
--icon-disabled-fill: GrayText;
|
||||
--text-selected-background: SelectedItem;
|
||||
@@ -253,31 +247,6 @@ blockquote {
|
||||
border-inline-start: 2px solid var(--main-foreground) !important;
|
||||
}
|
||||
|
||||
.color-scheme-buttons {
|
||||
.light-button,
|
||||
.auto-button {
|
||||
color: var(--light-theme-foreground);
|
||||
background-color: var(--light-theme-background);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.auto-button {
|
||||
color: var(--dark-theme-foreground);
|
||||
background-color: var(--dark-theme-background);
|
||||
}
|
||||
}
|
||||
|
||||
.dark-button {
|
||||
color: var(--dark-theme-foreground);
|
||||
background-color: var(--dark-theme-background);
|
||||
}
|
||||
|
||||
.sepia-button {
|
||||
color: #5b4636;
|
||||
background-color: #f4ecd8;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loading/error message */
|
||||
|
||||
.reader-message {
|
||||
@@ -550,8 +519,6 @@ button:disabled {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* Font style popup */
|
||||
|
||||
.radio-button {
|
||||
/* We visually hide these, but we keep them around so they can be focused
|
||||
* and changed by interacting with them via the label, or the keyboard, or
|
||||
@@ -569,28 +536,7 @@ button:disabled {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.content-width-value,
|
||||
.font-size-value,
|
||||
.line-height-value {
|
||||
box-sizing: border-box;
|
||||
width: 36px;
|
||||
height: 20px;
|
||||
line-height: 18px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
margin: auto;
|
||||
border-radius: 10px;
|
||||
border: 1px solid var(--font-value-border);
|
||||
color: var(--popup-button-foreground);
|
||||
background-color: var(--font-value-background);
|
||||
}
|
||||
|
||||
.buttonrow > button {
|
||||
border: 0;
|
||||
height: 60px;
|
||||
width: 90px;
|
||||
background-color: transparent;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
fill: var(--popup-button-foreground);
|
||||
@@ -610,11 +556,6 @@ button:disabled {
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
.style-dropdown .radiorow:not(:last-child),
|
||||
.style-dropdown .buttonrow:not(:last-child) {
|
||||
border-bottom: 1px solid var(--popup-line);
|
||||
}
|
||||
|
||||
.radiorow > label {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
@@ -636,56 +577,6 @@ button:disabled {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.font-type-buttons > label {
|
||||
height: 64px;
|
||||
width: 105px;
|
||||
/* Slightly more space between these items. */
|
||||
margin: 10px;
|
||||
/* Center the Sans-serif / Serif labels */
|
||||
text-align: center;
|
||||
background-size: 63px 39px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center 18px;
|
||||
background-color: var(--popup-button-background);
|
||||
color: var(--popup-button-foreground);
|
||||
fill: currentColor;
|
||||
-moz-context-properties: fill;
|
||||
/* This mostly matches baselines, but because of differences in font
|
||||
* baselines between serif and sans-serif, this isn't always enough. */
|
||||
line-height: 1;
|
||||
padding-top: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.font-type-buttons {
|
||||
> label:first-of-type {
|
||||
margin-inline-start: var(--space-large);
|
||||
}
|
||||
|
||||
> label:last-of-type {
|
||||
margin-inline-end: var(--space-large);
|
||||
}
|
||||
}
|
||||
|
||||
.font-type-buttons > label[checked] {
|
||||
background-color: var(--selected-background);
|
||||
}
|
||||
|
||||
.sans-serif-button {
|
||||
font-family: sans-serif;
|
||||
background-image: url("chrome://global/skin/reader/RM-Sans-Serif.svg");
|
||||
}
|
||||
|
||||
/* Tweak padding to match the baseline on mac */
|
||||
:root[platform=macosx] .sans-serif-button {
|
||||
padding-top: 3px;
|
||||
}
|
||||
|
||||
.serif-button {
|
||||
font-family: serif;
|
||||
background-image: url("chrome://global/skin/reader/RM-Serif.svg");
|
||||
}
|
||||
|
||||
body.hcm .color-scheme-buttons {
|
||||
/* Disallow selecting themes when HCM is on. */
|
||||
display: none;
|
||||
@@ -930,7 +821,7 @@ label[for="text-alignment-buttons"] {
|
||||
}
|
||||
}
|
||||
|
||||
/* Separate colors menu popup */
|
||||
/* Colors menu popup */
|
||||
|
||||
#color-controls {
|
||||
padding-block: var(--space-small);
|
||||
@@ -975,12 +866,12 @@ div[name="customtheme"] {
|
||||
color: var(--popup-button-foreground);
|
||||
}
|
||||
|
||||
.colors-menu-color-scheme-buttons {
|
||||
.color-scheme-buttons {
|
||||
flex-wrap: wrap;
|
||||
padding-block: var(--space-xsmall) var(--space-small);
|
||||
}
|
||||
|
||||
.colors-menu-color-scheme-buttons > label {
|
||||
.color-scheme-buttons > label {
|
||||
height: 48px;
|
||||
width: calc(50% - 21px);
|
||||
font-size: 15px;
|
||||
@@ -994,7 +885,7 @@ div[name="customtheme"] {
|
||||
margin: var(--space-xsmall);
|
||||
}
|
||||
|
||||
.colors-menu-color-scheme-buttons > label:before {
|
||||
.color-scheme-buttons > label:before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: 24px;
|
||||
@@ -1004,7 +895,7 @@ div[name="customtheme"] {
|
||||
margin-inline: var(--space-medium);
|
||||
}
|
||||
|
||||
.colors-menu-color-scheme-buttons {
|
||||
.color-scheme-buttons {
|
||||
.auto-button:before {
|
||||
background: linear-gradient(to right, var(--light-theme-background) 50%, var(--dark-theme-background) 50%);;
|
||||
}
|
||||
@@ -1059,11 +950,7 @@ div[name="customtheme"] {
|
||||
background-image: url("chrome://global/skin/icons/close.svg");
|
||||
}
|
||||
|
||||
.style-button {
|
||||
background-image: url("chrome://global/skin/reader/RM-Type-Controls-24x24.svg");
|
||||
}
|
||||
|
||||
.improved-style-button {
|
||||
.text-layout-button {
|
||||
background-image: url("chrome://global/skin/reader/RM-Type-Controls-24x24.svg");
|
||||
}
|
||||
|
||||
@@ -1071,42 +958,6 @@ div[name="customtheme"] {
|
||||
background-image: url("chrome://mozapps/skin/extensions/category-themes.svg");
|
||||
}
|
||||
|
||||
.minus-button {
|
||||
background-size: 18px 18px;
|
||||
background-image: url("chrome://global/skin/reader/RM-Minus-24x24.svg");
|
||||
}
|
||||
|
||||
.plus-button {
|
||||
background-size: 18px 18px;
|
||||
background-image: url("chrome://global/skin/reader/RM-Plus-24x24.svg");
|
||||
}
|
||||
|
||||
.content-width-minus-button {
|
||||
background-size: 42px 16px;
|
||||
background-image: url("chrome://global/skin/reader/RM-Content-Width-Minus-42x16.svg");
|
||||
}
|
||||
|
||||
.content-width-plus-button {
|
||||
background-size: 44px 16px;
|
||||
background-image: url("chrome://global/skin/reader/RM-Content-Width-Plus-44x16.svg");
|
||||
}
|
||||
|
||||
.line-height-minus-button {
|
||||
background-size: 34px 14px;
|
||||
background-image: url("chrome://global/skin/reader/RM-Line-Height-Minus-38x14.svg");
|
||||
}
|
||||
|
||||
.line-height-plus-button {
|
||||
background-size: 34px 24px;
|
||||
background-image: url("chrome://global/skin/reader/RM-Line-Height-Plus-38x24.svg");
|
||||
}
|
||||
|
||||
/* Mirror the line height buttons if the article is RTL. */
|
||||
.reader-controls[articledir="rtl"] .line-height-minus-button,
|
||||
.reader-controls[articledir="rtl"] .line-height-plus-button {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
@media print {
|
||||
.toolbar {
|
||||
display: none !important;
|
||||
|
||||
@@ -137,29 +137,15 @@
|
||||
skin/classic/global/media/picture-in-picture-closed.svg (../../shared/media/picture-in-picture-closed.svg)
|
||||
skin/classic/global/icons/minus.svg (../../shared/icons/minus.svg)
|
||||
skin/classic/global/narrate.css (../../shared/narrate.css)
|
||||
skin/classic/global/narrate-improved.css (../../shared/narrate-improved.css)
|
||||
skin/classic/global/narrate/arrow.svg (../../shared/narrate/arrow.svg)
|
||||
skin/classic/global/narrate/back.svg (../../shared/narrate/back.svg)
|
||||
skin/classic/global/narrate/skip-backward-20.svg (../../shared/narrate/skip-backward-20.svg)
|
||||
skin/classic/global/narrate/skip-forward-20.svg (../../shared/narrate/skip-forward-20.svg)
|
||||
skin/classic/global/narrate/fast.svg (../../shared/narrate/fast.svg)
|
||||
skin/classic/global/narrate/forward.svg (../../shared/narrate/forward.svg)
|
||||
skin/classic/global/narrate/slow.svg (../../shared/narrate/slow.svg)
|
||||
skin/classic/global/narrate/start.svg (../../shared/narrate/start.svg)
|
||||
skin/classic/global/narrate/stop.svg (../../shared/narrate/stop.svg)
|
||||
skin/classic/global/narrate/headphone.svg (../../shared/narrate/headphone.svg)
|
||||
skin/classic/global/narrate/headphone-active.svg (../../shared/narrate/headphone-active.svg)
|
||||
skin/classic/global/pictureinpicture/player.css (../../shared/pictureinpicture/player.css)
|
||||
skin/classic/global/pictureinpicture/texttracks.css (../../shared/pictureinpicture/texttracks.css)
|
||||
skin/classic/global/reader/RM-Sans-Serif.svg (../../shared/reader/RM-Sans-Serif.svg)
|
||||
skin/classic/global/reader/RM-Serif.svg (../../shared/reader/RM-Serif.svg)
|
||||
skin/classic/global/reader/RM-Minus-24x24.svg (../../shared/reader/RM-Minus-24x24.svg)
|
||||
skin/classic/global/reader/RM-Plus-24x24.svg (../../shared/reader/RM-Plus-24x24.svg)
|
||||
skin/classic/global/reader/RM-Type-Controls-24x24.svg (../../shared/reader/RM-Type-Controls-24x24.svg)
|
||||
skin/classic/global/reader/RM-Content-Width-Minus-42x16.svg (../../shared/reader/RM-Content-Width-Minus-42x16.svg)
|
||||
skin/classic/global/reader/RM-Content-Width-Plus-44x16.svg (../../shared/reader/RM-Content-Width-Plus-44x16.svg)
|
||||
skin/classic/global/reader/RM-Line-Height-Minus-38x14.svg (../../shared/reader/RM-Line-Height-Minus-38x14.svg)
|
||||
skin/classic/global/reader/RM-Line-Height-Plus-38x24.svg (../../shared/reader/RM-Line-Height-Plus-38x24.svg)
|
||||
skin/classic/global/reader/align-left-20.svg (../../shared/reader/align-left-20.svg)
|
||||
skin/classic/global/reader/align-center-20.svg (../../shared/reader/align-center-20.svg)
|
||||
skin/classic/global/reader/align-right-20.svg (../../shared/reader/align-right-20.svg)
|
||||
|
||||
@@ -1,281 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* Avoid adding ID selector rules in this style sheet, since they could
|
||||
* inadvertently match elements in the article content. */
|
||||
|
||||
body {
|
||||
--narrate-word-highlight-color: #ffe087;
|
||||
--narrating-paragraph-background-color: #ffc;
|
||||
}
|
||||
|
||||
body.sepia {
|
||||
--narrate-word-highlight-color: #bdb5a5;
|
||||
--narrating-paragraph-background-color: #e0d7c5;
|
||||
}
|
||||
|
||||
body.dark,
|
||||
body.contrast {
|
||||
--narrate-word-highlight-color: #6f6f6f;
|
||||
--narrating-paragraph-background-color: #242424;
|
||||
}
|
||||
|
||||
body.custom {
|
||||
--narrating-paragraph-background-color: var(--custom-theme-selection-highlight);
|
||||
}
|
||||
|
||||
body.hcm {
|
||||
--narrate-word-highlight-color: SelectedItem;
|
||||
--narrating-paragraph-background-color: Canvas;
|
||||
}
|
||||
|
||||
.narrating {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
background-color: var(--narrating-paragraph-background-color);
|
||||
}
|
||||
|
||||
.narrate-word-highlight {
|
||||
position: absolute;
|
||||
display: none;
|
||||
transform: translate(-50%, calc(-50% - 2px));
|
||||
z-index: -1;
|
||||
border-bottom: 7px solid var(--narrate-word-highlight-color);
|
||||
transition: left 0.1s ease, width 0.1s ease;
|
||||
}
|
||||
|
||||
body.hcm .narrate-word-highlight {
|
||||
/* Shift the word highlight a bit downwards to not cover the bottom part of characters.
|
||||
* The z-index above is meant to have the highlight appear below the text,
|
||||
* but that's not best practice in HCM so we do this instead. */
|
||||
transform: translate(-50%, calc(-50% + 2px));
|
||||
border-bottom-width: 3px;
|
||||
}
|
||||
|
||||
.narrating > .narrate-word-highlight {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.narrate-word-highlight.newline {
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.narrate-toggle {
|
||||
background-image: url("chrome://global/skin/narrate/headphone.svg");
|
||||
|
||||
.speaking & {
|
||||
/* This shows with an animation. */
|
||||
background-image: url("chrome://global/skin/narrate/headphone-active.svg");
|
||||
fill: var(--toolbar-button-foreground-active);
|
||||
}
|
||||
|
||||
body.hcm .speaking & {
|
||||
background-color: var(--toolbar-button-background-active);
|
||||
border-color: var(--toolbar-button-border-active);
|
||||
}
|
||||
|
||||
body.hcm .speaking:not(.open) &:hover {
|
||||
background-color: var(--toolbar-button-background-hover);
|
||||
border-color: var(--toolbar-button-border-hover);
|
||||
fill: var(--toolbar-button-foreground-hover);
|
||||
}
|
||||
}
|
||||
|
||||
.narrate-dropdown > .dropdown-popup {
|
||||
padding: var(--space-small) var(--space-large);
|
||||
|
||||
button:enabled:hover {
|
||||
background-color: var(--popup-button-background-hover);
|
||||
color: var(--popup-button-foreground-hover);
|
||||
fill: var(--popup-button-foreground-hover);
|
||||
|
||||
body.hcm & {
|
||||
border-color: SelectedItem;
|
||||
}
|
||||
}
|
||||
|
||||
button:enabled:hover:active {
|
||||
background-color: var(--popup-button-background-active);
|
||||
|
||||
body.hcm & {
|
||||
border-color: ButtonText;
|
||||
}
|
||||
}
|
||||
|
||||
button:enabled:focus-visible {
|
||||
outline: 2px solid var(--outline-focus-color);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
}
|
||||
|
||||
.narrate-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-block: var(--space-small);
|
||||
|
||||
&:not(.narrate-voices) {
|
||||
direction: ltr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Control buttons */
|
||||
|
||||
.narrate-control {
|
||||
gap: var(--space-xxsmall);
|
||||
|
||||
button {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
min-height: 36px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: 20px 20px;
|
||||
background-color: var(--popup-button-background);
|
||||
color: var(--popup-button-foreground);
|
||||
fill: currentColor;
|
||||
-moz-context-properties: fill;
|
||||
border: none;
|
||||
|
||||
&:first-of-type {
|
||||
border-start-start-radius: var(--border-radius-small);
|
||||
border-end-start-radius: var(--border-radius-small);
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
border-start-end-radius: var(--border-radius-small);
|
||||
border-end-end-radius: var(--border-radius-small);
|
||||
}
|
||||
|
||||
&.narrate-skip-previous {
|
||||
background-image: url("chrome://global/skin/narrate/skip-backward-20.svg");
|
||||
}
|
||||
|
||||
&.narrate-skip-next {
|
||||
background-image: url("chrome://global/skin/narrate/skip-forward-20.svg");
|
||||
}
|
||||
|
||||
&.narrate-start-stop {
|
||||
background-image: url("chrome://global/skin/media/play-fill.svg");
|
||||
|
||||
.narrate-dropdown.speaking & {
|
||||
background-image: url("chrome://global/skin/media/pause-fill.svg");
|
||||
}
|
||||
}
|
||||
|
||||
body.hcm & {
|
||||
border: 1px solid var(--popup-button-border);
|
||||
|
||||
&:disabled {
|
||||
border-color: var(--icon-disabled-fill);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Rate control */
|
||||
|
||||
.narrate-rate-icon {
|
||||
content: '';
|
||||
width: 48px;
|
||||
height: 40px;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 24px auto;
|
||||
-moz-context-properties: fill;
|
||||
fill: var(--popup-foreground);
|
||||
|
||||
&.slow {
|
||||
background-image: url("chrome://global/skin/narrate/slow.svg");
|
||||
}
|
||||
|
||||
&.fast {
|
||||
background-image: url("chrome://global/skin/narrate/fast.svg");
|
||||
}
|
||||
}
|
||||
|
||||
.narrate-rate-input {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
/* Voice selection */
|
||||
|
||||
.voiceselect {
|
||||
width: 100%;
|
||||
|
||||
> button.select-toggle,
|
||||
> .options > button.option {
|
||||
appearance: none;
|
||||
width: 100%;
|
||||
min-height: 36px;
|
||||
border: 1px solid transparent;
|
||||
color: var(--popup-button-foreground);
|
||||
font-size: 15px;
|
||||
|
||||
body.hcm & {
|
||||
border-color: var(--popup-button-border);
|
||||
}
|
||||
}
|
||||
|
||||
> button.select-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-inline: var(--space-medium);
|
||||
border-radius: var(--border-radius-small);
|
||||
background-color: var(--popup-button-background);
|
||||
font-weight: var(--font-weight-bold);
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
|
||||
.current-voice {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding-inline: var(--space-small);
|
||||
}
|
||||
}
|
||||
|
||||
> button.select-toggle::before,
|
||||
> button.select-toggle::after {
|
||||
content: "";
|
||||
width: 24px;
|
||||
height: var(--icon-size-default);
|
||||
background-repeat: no-repeat;
|
||||
background-size: var(--icon-size-default) auto;
|
||||
}
|
||||
|
||||
> button.select-toggle::before {
|
||||
background-image: url("chrome://global/skin/media/audio.svg");
|
||||
}
|
||||
|
||||
> button.select-toggle::after {
|
||||
background-image: url("chrome://global/skin/icons/arrow-down.svg");
|
||||
}
|
||||
|
||||
&.open > button.select-toggle::after {
|
||||
background-image: url("chrome://global/skin/icons/arrow-up.svg");
|
||||
}
|
||||
|
||||
> .options {
|
||||
display: none;
|
||||
overflow-y: auto;
|
||||
|
||||
> button.option {
|
||||
background-color: transparent;
|
||||
text-align: start;
|
||||
padding-inline-start: var(--space-medium);
|
||||
}
|
||||
|
||||
> button.option::-moz-focus-inner {
|
||||
outline: none;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
&:not(.hovering) > button.option:hover:not(:focus) {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
&.open > .options {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@
|
||||
* inadvertently match elements in the article content. */
|
||||
|
||||
body {
|
||||
--current-voice: #7f7f7f;
|
||||
--narrate-word-highlight-color: #ffe087;
|
||||
--narrating-paragraph-background-color: #ffc;
|
||||
}
|
||||
@@ -18,7 +17,6 @@ body.sepia {
|
||||
|
||||
body.dark,
|
||||
body.contrast {
|
||||
--current-voice: #a09eac;
|
||||
--narrate-word-highlight-color: #6f6f6f;
|
||||
--narrating-paragraph-background-color: #242424;
|
||||
}
|
||||
@@ -28,7 +26,6 @@ body.custom {
|
||||
}
|
||||
|
||||
body.hcm {
|
||||
--current-voice: inherit;
|
||||
--narrate-word-highlight-color: SelectedItem;
|
||||
--narrating-paragraph-background-color: Canvas;
|
||||
}
|
||||
@@ -66,98 +63,119 @@ body.hcm .narrate-word-highlight {
|
||||
|
||||
.narrate-toggle {
|
||||
background-image: url("chrome://global/skin/narrate/headphone.svg");
|
||||
}
|
||||
|
||||
.speaking .narrate-toggle {
|
||||
.speaking & {
|
||||
/* This shows with an animation. */
|
||||
background-image: url("chrome://global/skin/narrate/headphone-active.svg");
|
||||
fill: var(--toolbar-button-foreground-active);
|
||||
}
|
||||
|
||||
body.hcm .speaking .narrate-toggle {
|
||||
body.hcm .speaking & {
|
||||
background-color: var(--toolbar-button-background-active);
|
||||
border-color: var(--toolbar-button-border-active);
|
||||
}
|
||||
|
||||
body.hcm .speaking:not(.open) .narrate-toggle:hover {
|
||||
body.hcm .speaking:not(.open) &:hover {
|
||||
background-color: var(--toolbar-button-background-hover);
|
||||
border-color: var(--toolbar-button-border-hover);
|
||||
fill: var(--toolbar-button-foreground-hover);
|
||||
}
|
||||
|
||||
.narrate-dropdown > .dropdown-popup button {
|
||||
background-color: transparent;
|
||||
fill: var(--popup-button-foreground);
|
||||
}
|
||||
|
||||
.narrate-dropdown > .dropdown-popup button:enabled:hover {
|
||||
.narrate-dropdown > .dropdown-popup {
|
||||
padding: var(--space-small) var(--space-large);
|
||||
|
||||
button:enabled:hover {
|
||||
background-color: var(--popup-button-background-hover);
|
||||
color: var(--popup-button-foreground-hover);
|
||||
fill: var(--popup-button-foreground-hover);
|
||||
|
||||
body.hcm & {
|
||||
border-color: SelectedItem;
|
||||
}
|
||||
}
|
||||
|
||||
.narrate-dropdown > .dropdown-popup button:enabled:hover:active {
|
||||
button:enabled:hover:active {
|
||||
background-color: var(--popup-button-background-active);
|
||||
|
||||
body.hcm & {
|
||||
border-color: ButtonText;
|
||||
}
|
||||
}
|
||||
|
||||
.narrate-dropdown > .dropdown-popup button:enabled:focus-visible {
|
||||
button:enabled:focus-visible {
|
||||
outline: 2px solid var(--outline-focus-color);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
}
|
||||
|
||||
.narrate-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 40px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
padding-block: var(--space-small);
|
||||
|
||||
.narrate-row:not(.narrate-voices) {
|
||||
&:not(.narrate-voices) {
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
.narrate-row:not(:first-child) {
|
||||
border-top: 1px solid var(--popup-line);
|
||||
}
|
||||
|
||||
/* Control buttons */
|
||||
|
||||
.narrate-control > button {
|
||||
background-size: 24px 24px;
|
||||
.narrate-control {
|
||||
gap: var(--space-xxsmall);
|
||||
|
||||
button {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
min-height: 36px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
height: 64px;
|
||||
width: 82px;
|
||||
background-position: center;
|
||||
background-size: 20px 20px;
|
||||
background-color: var(--popup-button-background);
|
||||
color: var(--popup-button-foreground);
|
||||
fill: currentColor;
|
||||
-moz-context-properties: fill;
|
||||
border: none;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:first-of-type {
|
||||
border-start-start-radius: var(--border-radius-small);
|
||||
border-end-start-radius: var(--border-radius-small);
|
||||
}
|
||||
|
||||
.narrate-control > button:not(:first-child) {
|
||||
border-inline-start: 1px solid var(--popup-line);
|
||||
&:last-of-type {
|
||||
border-start-end-radius: var(--border-radius-small);
|
||||
border-end-end-radius: var(--border-radius-small);
|
||||
}
|
||||
|
||||
.narrate-skip-previous {
|
||||
border-top-left-radius: 3px;
|
||||
background-image: url("chrome://global/skin/narrate/back.svg");
|
||||
&.narrate-skip-previous {
|
||||
background-image: url("chrome://global/skin/narrate/skip-backward-20.svg");
|
||||
}
|
||||
|
||||
.narrate-skip-next {
|
||||
border-top-right-radius: 3px;
|
||||
background-image: url("chrome://global/skin/narrate/forward.svg");
|
||||
&.narrate-skip-next {
|
||||
background-image: url("chrome://global/skin/narrate/skip-forward-20.svg");
|
||||
}
|
||||
|
||||
.narrate-start-stop {
|
||||
background-image: url("chrome://global/skin/narrate/start.svg");
|
||||
&.narrate-start-stop {
|
||||
background-image: url("chrome://global/skin/media/play-fill.svg");
|
||||
|
||||
.narrate-dropdown.speaking & {
|
||||
background-image: url("chrome://global/skin/media/pause-fill.svg");
|
||||
}
|
||||
}
|
||||
|
||||
.narrate-dropdown.speaking .narrate-start-stop {
|
||||
background-image: url("chrome://global/skin/narrate/stop.svg");
|
||||
body.hcm & {
|
||||
border: 1px solid var(--popup-button-border);
|
||||
|
||||
&:disabled {
|
||||
border-color: var(--icon-disabled-fill);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Rate control */
|
||||
|
||||
.narrate-rate::before,
|
||||
.narrate-rate::after {
|
||||
.narrate-rate-icon {
|
||||
content: '';
|
||||
width: 48px;
|
||||
height: 40px;
|
||||
@@ -165,115 +183,99 @@ body.hcm .speaking:not(.open) .narrate-toggle:hover {
|
||||
background-repeat: no-repeat;
|
||||
background-size: 24px auto;
|
||||
-moz-context-properties: fill;
|
||||
fill: var(--popup-button-foreground);
|
||||
}
|
||||
fill: var(--popup-foreground);
|
||||
|
||||
.narrate-rate::before {
|
||||
&.slow {
|
||||
background-image: url("chrome://global/skin/narrate/slow.svg");
|
||||
}
|
||||
|
||||
.narrate-rate::after {
|
||||
&.fast {
|
||||
background-image: url("chrome://global/skin/narrate/fast.svg");
|
||||
}
|
||||
}
|
||||
|
||||
.narrate-rate-input {
|
||||
margin: 0 1px;
|
||||
flex-grow: 1;
|
||||
background-color: var(--popup-background);
|
||||
border-radius: 2px;
|
||||
width: 148px;
|
||||
}
|
||||
|
||||
.narrate-rate-input:focus-visible {
|
||||
outline: 2px solid var(--outline-focus-color);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.narrate-rate-input::-moz-range-track {
|
||||
background-color: var(--popup-button-foreground);
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
.narrate-rate-input::-moz-range-progress {
|
||||
background-color: var(--primary-color);
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
.narrate-rate-input::-moz-range-thumb {
|
||||
background-color: var(--popup-button-foreground);
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
border-radius: 8px;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.narrate-rate-input:active::-moz-range-thumb {
|
||||
background-color: var(--primary-color);
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
/* Voice selection */
|
||||
|
||||
.voiceselect {
|
||||
width: 246px;
|
||||
}
|
||||
|
||||
.voiceselect > button.select-toggle,
|
||||
.voiceselect > .options > button.option {
|
||||
appearance: none;
|
||||
border: none;
|
||||
width: 100%;
|
||||
min-height: 40px;
|
||||
|
||||
> button.select-toggle,
|
||||
> .options > button.option {
|
||||
appearance: none;
|
||||
width: 100%;
|
||||
min-height: 36px;
|
||||
border: 1px solid transparent;
|
||||
color: var(--popup-button-foreground);
|
||||
font-size: 15px;
|
||||
|
||||
body.hcm & {
|
||||
border-color: var(--popup-button-border);
|
||||
}
|
||||
}
|
||||
|
||||
.voiceselect > button.select-toggle::after {
|
||||
content: '';
|
||||
background-image: url("chrome://global/skin/narrate/arrow.svg");
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 12px 12px;
|
||||
display: inline-block;
|
||||
width: 1.5em;
|
||||
height: 1em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
> button.select-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-inline: var(--space-medium);
|
||||
border-radius: var(--border-radius-small);
|
||||
background-color: var(--popup-button-background);
|
||||
font-weight: var(--font-weight-bold);
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
|
||||
.current-voice {
|
||||
color: var(--current-voice);
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding-inline: var(--space-small);
|
||||
}
|
||||
}
|
||||
|
||||
.voiceselect .label {
|
||||
color: var(--popup-button-foreground);
|
||||
> button.select-toggle::before,
|
||||
> button.select-toggle::after {
|
||||
content: "";
|
||||
width: 24px;
|
||||
height: var(--icon-size-default);
|
||||
background-repeat: no-repeat;
|
||||
background-size: var(--icon-size-default) auto;
|
||||
}
|
||||
|
||||
.voiceselect > .options {
|
||||
> button.select-toggle::before {
|
||||
background-image: url("chrome://global/skin/media/audio.svg");
|
||||
}
|
||||
|
||||
> button.select-toggle::after {
|
||||
background-image: url("chrome://global/skin/icons/arrow-down.svg");
|
||||
}
|
||||
|
||||
&.open > button.select-toggle::after {
|
||||
background-image: url("chrome://global/skin/icons/arrow-up.svg");
|
||||
}
|
||||
|
||||
> .options {
|
||||
display: none;
|
||||
overflow-y: auto;
|
||||
|
||||
> button.option {
|
||||
background-color: transparent;
|
||||
text-align: start;
|
||||
padding-inline-start: var(--space-medium);
|
||||
}
|
||||
|
||||
.voiceselect.open > .options {
|
||||
display: block;
|
||||
border-top: 1px solid var(--popup-line);
|
||||
}
|
||||
|
||||
.voiceselect > .options > button.option {
|
||||
box-sizing: border-box;
|
||||
color: var(--popup-button-foreground);
|
||||
}
|
||||
|
||||
.voiceselect > .options > button.option:not(:first-child) {
|
||||
border-top: 1px solid var(--popup-line);
|
||||
}
|
||||
|
||||
.voiceselect > .options > button.option::-moz-focus-inner {
|
||||
> button.option::-moz-focus-inner {
|
||||
outline: none;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.voiceselect > .options:not(.hovering) > button.option:hover:not(:focus) {
|
||||
&:not(.hovering) > button.option:hover:not(:focus) {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.voiceselect:not(.open) > button,
|
||||
.voiceselect .option:last-child {
|
||||
border-radius: 0 0 3px 3px;
|
||||
}
|
||||
|
||||
&.open > .options {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="42"
|
||||
height="16"
|
||||
viewBox="0 0 42 16"
|
||||
fill="context-fill">
|
||||
|
||||
<path d="M14.5,7 L8.75,1.25 L10,-1.91791433e-15 L18,8 L17.375,8.625 L10,16 L8.75,14.75 L14.5,9 L1.13686838e-13,9 L1.13686838e-13,7 L14.5,7 Z"/>
|
||||
<path d="M38.5,7 L32.75,1.25 L34,6.58831647e-15 L42,8 L41.375,8.625 L34,16 L32.75,14.75 L38.5,9 L24,9 L24,7 L38.5,7 Z" transform="translate(33.000000, 8.000000) scale(-1, 1) translate(-33.000000, -8.000000)"/>
|
||||
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 744 B |
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="44"
|
||||
height="16"
|
||||
viewBox="0 0 44 16"
|
||||
fill="context-fill">
|
||||
|
||||
<path d="M14.5,7 L8.75,1.25 L10,-1.91791433e-15 L18,8 L17.375,8.625 L10,16 L8.75,14.75 L14.5,9 L1.13686838e-13,9 L1.13686838e-13,7 L14.5,7 Z" transform="translate(9.000000, 8.000000) scale(-1, 1) translate(-9.000000, -8.000000)"/>
|
||||
<path d="M40.5,7 L34.75,1.25 L36,-5.17110888e-16 L44,8 L43.375,8.625 L36,16 L34.75,14.75 L40.5,9 L26,9 L26,7 L40.5,7 Z"/>
|
||||
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 743 B |
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="38"
|
||||
height="14"
|
||||
viewBox="0 0 38 14"
|
||||
fill="context-fill">
|
||||
|
||||
<rect x="0" y="0" width="28" height="2"/>
|
||||
<rect x="0" y="6" width="38" height="2"/>
|
||||
<rect x="0" y="12" width="18" height="2"/>
|
||||
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 520 B |
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="38"
|
||||
height="24"
|
||||
viewBox="0 0 38 24"
|
||||
fill="context-fill">
|
||||
|
||||
<rect x="0" y="0" width="28" height="2"/>
|
||||
<rect x="0" y="11" width="38" height="2"/>
|
||||
<rect x="0" y="22" width="18" height="2"/>
|
||||
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 520 B |
@@ -1,6 +0,0 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="context-fill" d="M0,13.5v-3h24v3H0z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 339 B |
@@ -1,6 +0,0 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="context-fill" d="M24,13.5H13.5V24h-3V13.5H0v-3h10.5V0h3v10.5H24V13.5z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 373 B |
@@ -1,13 +0,0 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="21"
|
||||
height="13"
|
||||
fill="context-fill">
|
||||
<path d="M 7.276027,7.16854 5.432216,1.80247 3.47265,7.16854 Z M 4.572322,0 H 6.43267 l 4.406957,12.146004 H 9.037157 L 7.805193,8.507991 H 3.001361 L 1.686716,12.146004 H 0 Z"/>
|
||||
<path
|
||||
d="m 13.295286,9.789564 q 0,0.64492 0.471288,1.01699 0.471288,0.372069 1.116209,0.372069 0.78548,0 1.521351,-0.363801 1.240232,-0.603579 1.240232,-1.976103 V 7.639828 Q 17.371515,7.813461 16.941568,7.929216 16.511621,8.044971 16.09821,8.09458 L 15.196975,8.210335 Q 14.38669,8.317822 13.981548,8.549332 13.295286,8.937938 13.295286,9.789564 Z m 3.604941,-3.00963 q 0.512629,-0.06614 0.686262,-0.429947 0.09922,-0.198437 0.09922,-0.570507 0,-0.760675 -0.545702,-1.099672 -0.537434,-0.347265 -1.546156,-0.347265 -1.165818,0 -1.653642,0.628384 -0.272851,0.347265 -0.355533,1.033527 h -1.38906 q 0.04134,-1.637106 1.058331,-2.273759 1.025259,-0.64492 2.372977,-0.64492 1.562693,0 2.538342,0.595311 0.967381,0.595311 0.967381,1.85208 v 5.101487 q 0,0.23151 0.09095,0.37207 0.09922,0.140559 0.405142,0.140559 0.09922,0 0.223242,-0.0083 0.124023,-0.01654 0.264583,-0.04134 v 1.099672 q -0.347265,0.09922 -0.529166,0.124024 -0.1819,0.0248 -0.496093,0.0248 -0.768943,0 -1.116208,-0.545702 -0.181901,-0.289387 -0.256315,-0.818553 -0.454752,0.595311 -1.306378,1.033527 -0.851625,0.438215 -1.876884,0.438215 -1.231964,0 -2.017444,-0.744139 -0.777212,-0.752407 -0.777212,-1.876884 0,-1.231964 0.768944,-1.909958 0.768944,-0.677993 2.017444,-0.835089 z M 15.668263,3.075775 Z"
|
||||
/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB |
@@ -1,11 +0,0 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="21" height="13" fill="context-fill">
|
||||
<path
|
||||
d="M 12.088127,11.897958 H 7.2016131 v -0.587043 q 0.6449206,-0.04134 1.0665998,-0.165364 0.4299469,-0.124023 0.4299469,-0.305924 0,-0.07441 -0.01654,-0.181901 -0.01654,-0.107486 -0.04961,-0.190168 L 7.656365,7.838266 H 3.547063 Q 3.315553,8.417041 3.166726,8.846988 3.026166,9.276935 2.910411,9.640736 2.802924,9.996269 2.761583,10.219511 q -0.04134,0.223242 -0.04134,0.363802 0,0.330728 0.520897,0.512629 0.520898,0.1819 1.174087,0.214973 v 0.587043 H 0 v -0.587043 q 0.214974,-0.01654 0.53743401,-0.09095 0.32246003,-0.08268 0.52916499,-0.214974 0.330729,-0.223241 0.51263,-0.46302 0.1819,-0.248046 0.355533,-0.677993 Q 2.819461,7.656365 3.88606,4.90305 4.95266,2.149735 5.787749,0 h 0.661457 l 3.910865,10.120293 q 0.124023,0.32246 0.281119,0.520897 0.157096,0.198437 0.438215,0.388606 0.190169,0.115755 0.496093,0.198437 0.305924,0.07441 0.512629,0.08268 z M 7.3587101,7.102395 5.5810441,2.554878 3.836451,7.102395 Z"
|
||||
/>
|
||||
<path
|
||||
d="m 20.03388,11.749131 q -0.388606,0.140559 -0.686262,0.223241 -0.289387,0.09095 -0.661457,0.09095 -0.64492,0 -1.033526,-0.297656 -0.380338,-0.305924 -0.487825,-0.884699 H 17.1152 q -0.537434,0.595312 -1.15755,0.909504 -0.611848,0.314192 -1.48001,0.314192 -0.917772,0 -1.513083,-0.562239 -0.587043,-0.562238 -0.587043,-1.471742 0,-0.471288 0.132291,-0.843357 0.132291,-0.37207 0.396874,-0.669726 0.206706,-0.248046 0.545702,-0.438215 0.338997,-0.198437 0.636653,-0.314192 0.372069,-0.14056 1.504814,-0.520897 1.141014,-0.380338 1.537888,-0.595312 V 5.87043 q 0,-0.107487 -0.04961,-0.41341 -0.04134,-0.305924 -0.190169,-0.578775 -0.165364,-0.305924 -0.471288,-0.529166 -0.297656,-0.23151 -0.851626,-0.23151 -0.380338,0 -0.711066,0.132291 -0.322461,0.124024 -0.454752,0.264583 0,0.165365 0.07441,0.487825 0.08268,0.32246 0.08268,0.595311 0,0.289388 -0.264583,0.529166 -0.256315,0.239778 -0.719334,0.239778 -0.413411,0 -0.611848,-0.289387 -0.190169,-0.297656 -0.190169,-0.661458 0,-0.380337 0.264583,-0.727602 0.272851,-0.347265 0.702798,-0.620116 0.372069,-0.23151 0.901235,-0.388606 0.529166,-0.165364 1.033527,-0.165364 0.69453,0 1.207159,0.09922 0.520897,0.09095 0.942576,0.405143 0.421679,0.305923 0.636652,0.835089 0.223242,0.520897 0.223242,1.347719 0,1.182354 -0.02481,2.100126 -0.0248,0.909503 -0.0248,1.992639 0,0.32246 0.107487,0.512629 0.115755,0.190169 0.347265,0.322461 0.124023,0.07441 0.388607,0.08268 0.27285,0.0083 0.553969,0.0083 z M 17.148274,7.383514 q -0.702799,0.206705 -1.231964,0.405143 -0.529166,0.198437 -0.983918,0.496092 -0.41341,0.28112 -0.653188,0.669726 -0.239779,0.380337 -0.239779,0.909503 0,0.686262 0.355534,1.008722 0.363801,0.32246 0.917771,0.32246 0.587043,0 1.033527,-0.281119 0.446483,-0.289387 0.752407,-0.677993 z"
|
||||
/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.0 KiB |