Backed out 3 changesets (bug 1417837) for ESlint failures at /builds/worker/checkouts/gecko/toolkit/components/narrate/NarrateControls.jsm r=backout on a CLOSED TREE

Backed out changeset 0d6b56293cbf (bug 1417837)
Backed out changeset 1c341a427a7a (bug 1417837)
Backed out changeset fa4f488ea88f (bug 1417837)
This commit is contained in:
Coroiu Cristina 2017-12-04 12:34:37 +02:00
Родитель 146148c4c0
Коммит 035be65ea1
18 изменённых файлов: 1337 добавлений и 1338 удалений

Просмотреть файл

@ -2,9 +2,6 @@
* 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. */
html {
-moz-text-size-adjust: none;
}
@ -36,39 +33,39 @@ body.serif {
font-family: serif;
}
.container.font-size1 {
#container.font-size1 {
font-size: 10px;
}
.container.font-size2 {
#container.font-size2 {
font-size: 12px;
}
.container.font-size3 {
#container.font-size3 {
font-size: 14px;
}
.container.font-size4 {
#container.font-size4 {
font-size: 16px;
}
.container.font-size5 {
#container.font-size5 {
font-size: 18px;
}
.container.font-size6 {
#container.font-size6 {
font-size: 20px;
}
.container.font-size7 {
#container.font-size7 {
font-size: 22px;
}
.container.font-size8 {
#container.font-size8 {
font-size: 24px;
}
.container.font-size9 {
#container.font-size9 {
font-size: 26px;
}
@ -121,409 +118,3 @@ body.dark > .container > .content blockquote {
color: #aaaaaa !important;
border-left-color: #777777 !important;
}
.reader-message {
margin-top: 40px;
display: none;
text-align: center;
width: 100%;
font-size: 0.9em;
}
.header {
text-align: start;
display: none;
}
.domain,
.credits {
font-size: 0.9em;
font-family: sans-serif;
}
.domain {
margin-top: 10px;
padding-bottom: 10px;
color: #00acff !important;
text-decoration: none;
}
.domain-border {
margin-top: 15px;
border-bottom: 1.5px solid #777777;
width: 50%;
}
.header > h1 {
font-size: 1.33em;
font-weight: 700;
line-height: 1.1em;
width: 100%;
margin: 0px;
margin-top: 32px;
margin-bottom: 16px;
padding: 0px;
}
.header > .credits {
padding: 0px;
margin: 0px;
margin-bottom: 32px;
}
/*======= Controls toolbar =======*/
.toolbar {
font-family: sans-serif;
position: fixed;
width: 100%;
left: 0;
margin: 0;
padding: 0;
bottom: 0;
list-style: none;
pointer-events: none;
transition: opacity 420ms linear;
}
.toolbar > * {
float: right;
}
.button {
width: 56px;
height: 56px;
display: block;
background-position: center;
background-size: 26px 16px;
background-repeat: no-repeat;
background-color: #0979D9;
border-radius: 10000px;
margin: 20px;
border: 0;
box-shadow: 0px 4px 8px 0px rgba(0,0,0,0.40);
}
.button:active {
background-color: #086ACC;
}
/* Remove dotted border when button is focused */
.button::-moz-focus-inner,
.dropdown-popup > div > button::-moz-focus-inner {
border: 0;
}
.button[hidden],
.toolbar[hidden] {
display: none;
}
.dropdown-toggle,
.dropdown-popup {
pointer-events: auto;
}
.dropdown {
left: 0;
text-align: center;
display: inline-block;
list-style: none;
margin: 0px;
padding: 0px;
}
/*======= Font style popup =======*/
.dropdown-popup {
position: absolute;
left: 0;
width: calc(100% - 30px);
margin: 15px;
z-index: 1000;
background: #EBEBF0;
visibility: hidden;
border: 0;
border-radius: 4px;
box-shadow: 0px 4px 8px 0px rgba(0,0,0,0.40);
-moz-user-select: none;
}
/* Only used on desktop */
.dropdown-popup > hr,
.dropdown-arrow,
.font-type-buttons > button > .name,
.content-width-buttons,
.line-height-buttons {
display: none;
}
.open > .dropdown-popup {
visibility: visible;
bottom: 0;
}
.font-type-buttons,
.font-size-buttons,
.color-scheme-buttons {
display: flex;
flex-direction: row;
}
.font-type-buttons > button,
.color-scheme-buttons > button {
text-align: center;
}
.font-type-buttons > button,
.font-size-buttons > button {
width: 50%;
background-color: transparent;
border: 0;
}
.font-type-buttons > button {
font-size: 24px;
color: #AFB1B3;
padding: 15px 0;
}
.font-type-buttons > button:active,
.font-type-buttons > button.selected {
color: #222222;
}
.font-size-sample {
flex: 0;
font-size: 24px;
color: #000000;
margin: 0 30px;
padding: 0 10px;
}
.serif-button {
font-family: serif;
}
.minus-button,
.plus-button {
background-color: transparent;
border: 0;
height: 60px;
background-size: 18px 18px;
background-repeat: no-repeat;
background-position: center;
}
.minus-button {
background-size: 24px 6px;
margin-left: 50px;
padding: 0 5px;
}
.plus-button {
background-size: 24px 24px;
margin-right: 50px;
padding: 0 5px;
}
.color-scheme-buttons > button {
width: 33%;
border-radius: 4px;
border: 1px solid #BFBFBF;
padding: 10px;
margin: 15px 10px;
font-size: 14px;
}
.color-scheme-buttons > button:active,
.color-scheme-buttons > button.selected {
border: 2px solid #0A84FF;
}
.dark-button {
color: #eeeeee;
background-color: #333333;
}
.auto-button {
color: #000000;
background-color: transparent;
}
.light-button {
color: #333333;
background-color: #ffffff;
}
/*======= Toolbar icons =======*/
/* desktop-only controls */
.close-button {
display: none;
}
.style-button {
background-image: url('chrome://browser/skin/images/reader-style-icon-hdpi.png');
}
.minus-button {
background-image: url('chrome://browser/skin/images/reader-minus-hdpi.png');
}
.plus-button {
background-image: url('chrome://browser/skin/images/reader-plus-hdpi.png');
}
@media screen and (min-resolution: 2dppx) {
.style-button {
background-image: url('chrome://browser/skin/images/reader-style-icon-xhdpi.png');
}
.minus-button {
background-image: url('chrome://browser/skin/images/reader-minus-xhdpi.png');
}
.plus-button {
background-image: url('chrome://browser/skin/images/reader-plus-xhdpi.png');
}
}
@media screen and (min-resolution: 3dppx) {
.style-button {
background-image: url('chrome://browser/skin/images/reader-style-icon-xxhdpi.png');
}
.minus-button {
background-image: url('chrome://browser/skin/images/reader-minus-xxhdpi.png');
}
.plus-button {
background-image: url('chrome://browser/skin/images/reader-plus-xxhdpi.png');
}
}
@media screen and (min-width: 960px) {
.dropdown-popup {
width: 350px;
left: auto;
right: 0;
}
}
/*======= Article content =======*/
/* Note that any class names from the original article that we want to match on
* must be added to CLASSES_TO_PRESERVE in ReaderMode.jsm, so that
* Readability.js doesn't strip them out */
.moz-reader-content {
display: none;
font-size: 1em;
}
.moz-reader-content a {
text-decoration: underline !important;
font-weight: normal;
}
.moz-reader-content a,
.moz-reader-content a:visited,
.moz-reader-content a:hover,
.moz-reader-content a:active {
color: #00acff !important;
}
.moz-reader-content * {
max-width: 100% !important;
height: auto !important;
}
.moz-reader-content p {
line-height: 1.4em !important;
margin: 0px !important;
margin-bottom: 20px !important;
}
/* Covers all images showing edge-to-edge using a
an optional caption text */
.moz-reader-content .wp-caption,
.moz-reader-content figure {
display: block !important;
width: 100% !important;
margin: 0px !important;
margin-bottom: 32px !important;
}
/* Images marked to be shown edge-to-edge with an
optional captio ntext */
.moz-reader-content p > img:only-child,
.moz-reader-content p > a:only-child > img:only-child,
.moz-reader-content .wp-caption img,
.moz-reader-content figure img {
display: block;
margin-left: auto;
margin-right: auto;
}
/* Account for body padding to make image full width */
.moz-reader-content img[moz-reader-full-width] {
width: calc(100% + 40px);
margin-left: -20px;
margin-right: -20px;
max-width: none !important;
}
/* Image caption text */
.moz-reader-content .caption,
.moz-reader-content .wp-caption-text,
.moz-reader-content figcaption {
font-size: 0.9em;
font-family: sans-serif;
margin: 0px !important;
padding-top: 4px !important;
}
/* Ensure all pre-formatted code inside the reader content
are properly wrapped inside content width */
.moz-reader-content code,
.moz-reader-content pre {
white-space: pre-wrap !important;
margin-bottom: 20px !important;
}
.moz-reader-content blockquote {
margin: 0px !important;
margin-bottom: 20px !important;
padding: 0px !important;
padding-inline-start: 16px !important;
border: 0px !important;
border-left: 2px solid !important;
}
.moz-reader-content ul,
.moz-reader-content ol {
margin: 0px !important;
margin-bottom: 20px !important;
padding: 0px !important;
line-height: 1.5em;
}
.moz-reader-content ul {
padding-inline-start: 30px !important;
list-style: disc !important;
}
.moz-reader-content ol {
padding-inline-start: 35px !important;
list-style: decimal !important;
}
/* Hide elements with common "hidden" class names */
.moz-reader-content .visually-hidden,
.moz-reader-content .visuallyhidden,
.moz-reader-content .hidden,
.moz-reader-content .invisible,
.moz-reader-content .sr-only {
display: none;
}

Просмотреть файл

@ -0,0 +1,114 @@
/* 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/. */
#moz-reader-content {
display: none;
font-size: 1em;
}
a {
text-decoration: underline !important;
font-weight: normal;
}
a,
a:visited,
a:hover,
a:active {
color: #00acff !important;
}
* {
max-width: 100% !important;
height: auto !important;
}
p {
line-height: 1.4em !important;
margin: 0px !important;
margin-bottom: 20px !important;
}
/* Covers all images showing edge-to-edge using a
an optional caption text */
.wp-caption,
figure {
display: block !important;
width: 100% !important;
margin: 0px !important;
margin-bottom: 32px !important;
}
/* Images marked to be shown edge-to-edge with an
optional captio ntext */
p > img:only-child,
p > a:only-child > img:only-child,
.wp-caption img,
figure img {
display: block;
margin-left: auto;
margin-right: auto;
}
/* Account for body padding to make image full width */
img[moz-reader-full-width] {
width: calc(100% + 40px);
margin-left: -20px;
margin-right: -20px;
max-width: none !important;
}
/* Image caption text */
.caption,
.wp-caption-text,
figcaption {
font-size: 0.9em;
font-family: sans-serif;
margin: 0px !important;
padding-top: 4px !important;
}
/* Ensure all pre-formatted code inside the reader content
are properly wrapped inside content width */
code,
pre {
white-space: pre-wrap !important;
margin-bottom: 20px !important;
}
blockquote {
margin: 0px !important;
margin-bottom: 20px !important;
padding: 0px !important;
padding-inline-start: 16px !important;
border: 0px !important;
border-left: 2px solid !important;
}
ul,
ol {
margin: 0px !important;
margin-bottom: 20px !important;
padding: 0px !important;
line-height: 1.5em;
}
ul {
padding-inline-start: 30px !important;
list-style: disc !important;
}
ol {
padding-inline-start: 35px !important;
list-style: decimal !important;
}
/* Hide elements with common "hidden" class names */
.visually-hidden,
.visuallyhidden,
.hidden,
.invisible,
.sr-only {
display: none;
}

Просмотреть файл

@ -0,0 +1,292 @@
/* 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/. */
#reader-message {
margin-top: 40px;
display: none;
text-align: center;
width: 100%;
font-size: 0.9em;
}
.header {
text-align: start;
display: none;
}
.domain,
.credits {
font-size: 0.9em;
font-family: sans-serif;
}
.domain {
margin-top: 10px;
padding-bottom: 10px;
color: #00acff !important;
text-decoration: none;
}
.domain-border {
margin-top: 15px;
border-bottom: 1.5px solid #777777;
width: 50%;
}
.header > h1 {
font-size: 1.33em;
font-weight: 700;
line-height: 1.1em;
width: 100%;
margin: 0px;
margin-top: 32px;
margin-bottom: 16px;
padding: 0px;
}
.header > .credits {
padding: 0px;
margin: 0px;
margin-bottom: 32px;
}
/*======= Controls toolbar =======*/
.toolbar {
font-family: sans-serif;
position: fixed;
width: 100%;
left: 0;
margin: 0;
padding: 0;
bottom: 0;
list-style: none;
pointer-events: none;
transition: opacity 420ms linear;
}
.toolbar > * {
float: right;
}
.button {
width: 56px;
height: 56px;
display: block;
background-position: center;
background-size: 26px 16px;
background-repeat: no-repeat;
background-color: #0979D9;
border-radius: 10000px;
margin: 20px;
border: 0;
box-shadow: 0px 4px 8px 0px rgba(0,0,0,0.40);
}
.button:active {
background-color: #086ACC;
}
/* Remove dotted border when button is focused */
.button::-moz-focus-inner,
.dropdown-popup > div > button::-moz-focus-inner {
border: 0;
}
.button[hidden],
.toolbar[hidden] {
display: none;
}
.dropdown-toggle,
#reader-popup {
pointer-events: auto;
}
.dropdown {
left: 0;
text-align: center;
display: inline-block;
list-style: none;
margin: 0px;
padding: 0px;
}
/*======= Font style popup =======*/
.dropdown-popup {
position: absolute;
left: 0;
width: calc(100% - 30px);
margin: 15px;
z-index: 1000;
background: #EBEBF0;
visibility: hidden;
border: 0;
border-radius: 4px;
box-shadow: 0px 4px 8px 0px rgba(0,0,0,0.40);
-moz-user-select: none;
}
/* Only used on desktop */
.dropdown-popup > hr,
.dropdown-arrow,
#font-type-buttons > button > .name,
#content-width-buttons,
#line-height-buttons {
display: none;
}
.open > .dropdown-popup {
visibility: visible;
bottom: 0;
}
#font-type-buttons,
#font-size-buttons,
#color-scheme-buttons {
display: flex;
flex-direction: row;
}
#font-type-buttons > button,
#color-scheme-buttons > button {
text-align: center;
}
#font-type-buttons > button,
#font-size-buttons > button {
width: 50%;
background-color: transparent;
border: 0;
}
#font-type-buttons > button {
font-size: 24px;
color: #AFB1B3;
padding: 15px 0;
}
#font-type-buttons > button:active,
#font-type-buttons > button.selected {
color: #222222;
}
#font-size-sample {
flex: 0;
font-size: 24px;
color: #000000;
margin: 0 30px;
padding: 0 10px;
}
.serif-button {
font-family: serif;
}
.minus-button,
.plus-button {
background-color: transparent;
border: 0;
height: 60px;
background-size: 18px 18px;
background-repeat: no-repeat;
background-position: center;
}
.minus-button {
background-size: 24px 6px;
margin-left: 50px;
padding: 0 5px;
}
.plus-button {
background-size: 24px 24px;
margin-right: 50px;
padding: 0 5px;
}
#color-scheme-buttons > button {
width: 33%;
border-radius: 4px;
border: 1px solid #BFBFBF;
padding: 10px;
margin: 15px 10px;
font-size: 14px;
}
#color-scheme-buttons > button:active,
#color-scheme-buttons > button.selected {
border: 2px solid #0A84FF;
}
.dark-button {
color: #eeeeee;
background-color: #333333;
}
.auto-button {
color: #000000;
background-color: transparent;
}
.light-button {
color: #333333;
background-color: #ffffff;
}
/*======= Toolbar icons =======*/
/* desktop-only controls */
.close-button {
display: none;
}
.style-button {
background-image: url('chrome://browser/skin/images/reader-style-icon-hdpi.png');
}
.minus-button {
background-image: url('chrome://browser/skin/images/reader-minus-hdpi.png');
}
.plus-button {
background-image: url('chrome://browser/skin/images/reader-plus-hdpi.png');
}
@media screen and (min-resolution: 2dppx) {
.style-button {
background-image: url('chrome://browser/skin/images/reader-style-icon-xhdpi.png');
}
.minus-button {
background-image: url('chrome://browser/skin/images/reader-minus-xhdpi.png');
}
.plus-button {
background-image: url('chrome://browser/skin/images/reader-plus-xhdpi.png');
}
}
@media screen and (min-resolution: 3dppx) {
.style-button {
background-image: url('chrome://browser/skin/images/reader-style-icon-xxhdpi.png');
}
.minus-button {
background-image: url('chrome://browser/skin/images/reader-minus-xxhdpi.png');
}
.plus-button {
background-image: url('chrome://browser/skin/images/reader-plus-xxhdpi.png');
}
}
@media screen and (min-width: 960px) {
.dropdown-popup {
width: 350px;
left: auto;
right: 0;
}
}

Просмотреть файл

@ -15,6 +15,8 @@ chrome.jar:
skin/aboutMemory.css (aboutMemory.css)
skin/aboutPrivateBrowsing.css (aboutPrivateBrowsing.css)
skin/aboutReader.css (aboutReader.css)
skin/aboutReaderContent.css (aboutReaderContent.css)
skin/aboutReaderControls.css (aboutReaderControls.css)
skin/aboutSupport.css (aboutSupport.css)
skin/config.css (config.css)
skin/defines.css (defines.css)
@ -23,6 +25,8 @@ chrome.jar:
% override chrome://global/skin/about.css chrome://browser/skin/about.css
% override chrome://global/skin/aboutMemory.css chrome://browser/skin/aboutMemory.css
% override chrome://global/skin/aboutReader.css chrome://browser/skin/aboutReader.css
% override chrome://global/skin/aboutReaderContent.css chrome://browser/skin/aboutReaderContent.css
% override chrome://global/skin/aboutReaderControls.css chrome://browser/skin/aboutReaderControls.css
% override chrome://global/skin/aboutSupport.css chrome://browser/skin/aboutSupport.css
% override chrome://global/skin/netError.css chrome://browser/skin/netError.css

Просмотреть файл

@ -38,12 +38,17 @@ function NarrateControls(mm, win, languagePromise) {
}
let dropdown = win.document.createElement("ul");
dropdown.className = "dropdown narrate-dropdown";
dropdown.className = "dropdown";
dropdown.id = "narrate-dropdown";
// We need inline svg here for the animation to work (bug 908634 & 1190881).
// The style animation can't be scoped (bug 830056).
// eslint-disable-next-line no-unsanitized/property
dropdown.innerHTML =
localize`<li>
<button class="dropdown-toggle button narrate-toggle"
localize`<style scoped>
@import url("chrome://global/skin/narrateControls.css");
</style>
<li>
<button class="dropdown-toggle button" id="narrate-toggle"
title="${"narrate"}" hidden>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
@ -57,11 +62,11 @@ function NarrateControls(mm, win, languagePromise) {
100% { transform: scaleY(1); }
}
.waveform > rect {
#waveform > rect {
fill: #808080;
}
.speaking .waveform > rect {
.speaking #waveform > rect {
fill: #58bf43;
transform-box: fill-box;
transform-origin: 50% 50%;
@ -71,15 +76,15 @@ function NarrateControls(mm, win, languagePromise) {
animation-timing-function: linear;
}
.waveform > rect:nth-child(2) { animation-delay: 250ms; }
.waveform > rect:nth-child(3) { animation-delay: 500ms; }
.waveform > rect:nth-child(4) { animation-delay: 750ms; }
.waveform > rect:nth-child(5) { animation-delay: 1000ms; }
.waveform > rect:nth-child(6) { animation-delay: 1250ms; }
.waveform > rect:nth-child(7) { animation-delay: 1500ms; }
#waveform > rect:nth-child(2) { animation-delay: 250ms; }
#waveform > rect:nth-child(3) { animation-delay: 500ms; }
#waveform > rect:nth-child(4) { animation-delay: 750ms; }
#waveform > rect:nth-child(5) { animation-delay: 1000ms; }
#waveform > rect:nth-child(6) { animation-delay: 1250ms; }
#waveform > rect:nth-child(7) { animation-delay: 1500ms; }
</style>
<g class="waveform">
<g id="waveform">
<rect x="1" y="8" width="2" height="8" rx=".5" ry=".5" />
<rect x="4" y="5" width="2" height="14" rx=".5" ry=".5" />
<rect x="7" y="8" width="2" height="8" rx=".5" ry=".5" />
@ -92,18 +97,18 @@ function NarrateControls(mm, win, languagePromise) {
</button>
</li>
<li class="dropdown-popup">
<div class="narrate-row narrate-control">
<button disabled class="narrate-skip-previous"
<div id="narrate-control" class="narrate-row">
<button disabled id="narrate-skip-previous"
title="${"back"}"></button>
<button class="narrate-start-stop" title="${"start"}"></button>
<button disabled class="narrate-skip-next"
<button id="narrate-start-stop" title="${"start"}"></button>
<button disabled id="narrate-skip-next"
title="${"forward"}"></button>
</div>
<div class="narrate-row narrate-rate">
<input class="narrate-rate-input" value="0" title="${"speed"}"
<div id="narrate-rate" class="narrate-row">
<input id="narrate-rate-input" value="0" title="${"speed"}"
step="5" max="100" min="-100" type="range">
</div>
<div class="narrate-row narrate-voices"></div>
<div id="narrate-voices" class="narrate-row"></div>
<div class="dropdown-arrow"></div>
</li>`;
@ -113,14 +118,14 @@ function NarrateControls(mm, win, languagePromise) {
let selectLabel = gStrings.GetStringFromName("selectvoicelabel");
this.voiceSelect = new VoiceSelect(win, selectLabel);
this.voiceSelect.element.addEventListener("change", this);
this.voiceSelect.element.classList.add("voice-select");
this.voiceSelect.element.id = "voice-select";
win.speechSynthesis.addEventListener("voiceschanged", this);
dropdown.querySelector(".narrate-voices").appendChild(
dropdown.querySelector("#narrate-voices").appendChild(
this.voiceSelect.element);
dropdown.addEventListener("click", this, true);
let rateRange = dropdown.querySelector(".narrate-rate > input");
let rateRange = dropdown.querySelector("#narrate-rate > input");
rateRange.addEventListener("change", this);
// The rate is stored as an integer.
@ -128,7 +133,7 @@ function NarrateControls(mm, win, languagePromise) {
this._setupVoices();
let tb = win.document.querySelector(".reader-toolbar");
let tb = win.document.getElementById("reader-toolbar");
tb.appendChild(dropdown);
}
@ -136,7 +141,7 @@ NarrateControls.prototype = {
handleEvent(evt) {
switch (evt.type) {
case "change":
if (evt.target.classList.contains("narrate-rate-input")) {
if (evt.target.id == "narrate-rate-input") {
this._onRateInput(evt);
} else {
this._onVoiceChange();
@ -187,7 +192,7 @@ NarrateControls.prototype = {
this.voiceSelect.addOptions(options);
}
let narrateToggle = win.document.querySelector(".narrate-toggle");
let narrateToggle = win.document.getElementById("narrate-toggle");
let histogram = Services.telemetry.getKeyedHistogramById(
"NARRATE_CONTENT_BY_LANGUAGE_2");
let initial = !this._voicesInitialized;
@ -234,38 +239,41 @@ NarrateControls.prototype = {
},
_onButtonClick(evt) {
var classList = evt.target.classList;
if (classList.contains("narrate-skip-previous")) {
this.narrator.skipPrevious();
} else if (classList.contains("narrate-skip-next")) {
this.narrator.skipNext();
} else if (classList.contains("narrate-start-stop")) {
if (this.narrator.speaking) {
this.narrator.stop();
} else {
this._updateSpeechControls(true);
let options = { rate: this.rate, voice: this.voice };
this.narrator.start(options).then(() => {
this._updateSpeechControls(false);
}, err => {
Cu.reportError(`Narrate failed: ${err}.`);
this._updateSpeechControls(false);
});
}
switch (evt.target.id) {
case "narrate-skip-previous":
this.narrator.skipPrevious();
break;
case "narrate-skip-next":
this.narrator.skipNext();
break;
case "narrate-start-stop":
if (this.narrator.speaking) {
this.narrator.stop();
} else {
this._updateSpeechControls(true);
let options = { rate: this.rate, voice: this.voice };
this.narrator.start(options).then(() => {
this._updateSpeechControls(false);
}, err => {
Cu.reportError(`Narrate failed: ${err}.`);
this._updateSpeechControls(false);
});
}
break;
}
},
_updateSpeechControls(speaking) {
let dropdown = this._doc.querySelector(".narrate-dropdown");
let dropdown = this._doc.getElementById("narrate-dropdown");
dropdown.classList.toggle("keep-open", speaking);
dropdown.classList.toggle("speaking", speaking);
let startStopButton = this._doc.querySelector(".narrate-start-stop");
let startStopButton = this._doc.getElementById("narrate-start-stop");
startStopButton.title =
gStrings.GetStringFromName(speaking ? "stop" : "start");
this._doc.querySelector(".narrate-skip-previous").disabled = !speaking;
this._doc.querySelector(".narrate-skip-next").disabled = !speaking;
this._doc.getElementById("narrate-skip-previous").disabled = !speaking;
this._doc.getElementById("narrate-skip-next").disabled = !speaking;
if (speaking) {
TelemetryStopwatch.start("NARRATE_CONTENT_SPEAKTIME_MS", this);
@ -328,7 +336,7 @@ NarrateControls.prototype = {
get rate() {
return this._convertRate(
this._doc.querySelector(".narrate-rate-input").value);
this._doc.getElementById("narrate-rate-input").value);
},
get voice() {

Просмотреть файл

@ -89,7 +89,7 @@ Narrator.prototype = {
// are no other strong references, and it will be GC'ed. Instead,
// we rely on the window's lifetime and use it as a weak reference.
this._treeWalkerRef.set(this._win,
this._doc.createTreeWalker(this._doc.querySelector(".container"),
this._doc.createTreeWalker(this._doc.getElementById("container"),
nf.SHOW_ELEMENT, filter, false));
}

Просмотреть файл

@ -4,9 +4,9 @@
/* This file defines specific rules for print preview when using simplify mode.
* Some of these rules (styling for title and author on the header element)
* already exist in aboutReader.css, however, we decoupled it from the original
* file so we don't need to load a bunch of extra queries that will not take
* effect when using the simplify page checkbox. */
* already exist on aboutReaderControls.css, however, we decoupled it from the
* original file so we don't need to load a bunch of extra queries that will not
* take effect when using the simplify page checkbox. */
body {
padding-top: 0px;
@ -29,4 +29,4 @@ body {
line-height: 1.48em;
margin: 0 0 30px 0;
font-style: italic;
}
}

Просмотреть файл

@ -55,15 +55,14 @@ var AboutReader = function(mm, win, articlePromise) {
this._articlePromise = articlePromise;
}
this._headerElementRef = Cu.getWeakReference(doc.querySelector(".reader-header"));
this._domainElementRef = Cu.getWeakReference(doc.querySelector(".reader-domain"));
this._titleElementRef = Cu.getWeakReference(doc.querySelector(".reader-title"));
this._readTimeElementRef = Cu.getWeakReference(doc.querySelector(".reader-estimated-time"));
this._creditsElementRef = Cu.getWeakReference(doc.querySelector(".reader-credits"));
this._contentElementRef = Cu.getWeakReference(doc.querySelector(".moz-reader-content"));
this._toolbarElementRef = Cu.getWeakReference(doc.querySelector(".reader-toolbar"));
this._messageElementRef = Cu.getWeakReference(doc.querySelector(".reader-message"));
this._containerElementRef = Cu.getWeakReference(doc.querySelector(".container"));
this._headerElementRef = Cu.getWeakReference(doc.getElementById("reader-header"));
this._domainElementRef = Cu.getWeakReference(doc.getElementById("reader-domain"));
this._titleElementRef = Cu.getWeakReference(doc.getElementById("reader-title"));
this._readTimeElementRef = Cu.getWeakReference(doc.getElementById("reader-estimated-time"));
this._creditsElementRef = Cu.getWeakReference(doc.getElementById("reader-credits"));
this._contentElementRef = Cu.getWeakReference(doc.getElementById("moz-reader-content"));
this._toolbarElementRef = Cu.getWeakReference(doc.getElementById("reader-toolbar"));
this._messageElementRef = Cu.getWeakReference(doc.getElementById("reader-message"));
this._scrollOffset = win.pageYOffset;
@ -174,10 +173,6 @@ AboutReader.prototype = {
return this._messageElementRef.get();
},
get _containerElement() {
return this._containerElementRef.get();
},
get _isToolbarVertical() {
if (this._toolbarVertical !== undefined) {
return this._toolbarVertical;
@ -205,26 +200,26 @@ AboutReader.prototype = {
case "Reader:AddButton": {
if (message.data.id && message.data.image &&
!this._doc.getElementsByClassName(message.data.id)[0]) {
!this._doc.getElementById(message.data.id)) {
let btn = this._doc.createElement("button");
btn.dataset.buttonid = message.data.id;
btn.className = "button " + message.data.id;
btn.style.backgroundImage = "url('" + message.data.image + "')";
btn.setAttribute("class", "button");
btn.setAttribute("style", "background-image: url('" + message.data.image + "')");
btn.setAttribute("id", message.data.id);
if (message.data.title)
btn.title = message.data.title;
btn.setAttribute("title", message.data.title);
if (message.data.text)
btn.textContent = message.data.text;
let tb = this._toolbarElement;
let tb = this._doc.getElementById("reader-toolbar");
tb.appendChild(btn);
this._setupButton(message.data.id, button => {
this._mm.sendAsyncMessage("Reader:Clicked-" + button.dataset.buttonid, { article: this._article });
this._mm.sendAsyncMessage("Reader:Clicked-" + button.getAttribute("id"), { article: this._article });
});
}
break;
}
case "Reader:RemoveButton": {
if (message.data.id) {
let btn = this._doc.getElementsByClassName(message.data.id)[0];
let btn = this._doc.getElementById(message.data.id);
if (btn)
btn.remove();
}
@ -308,7 +303,7 @@ AboutReader.prototype = {
},
_setFontSize(newFontSize) {
let containerClasses = this._containerElement.classList;
let containerClasses = this._doc.getElementById("container").classList;
if (this._fontSize > 0)
containerClasses.remove("font-size" + this._fontSize);
@ -323,14 +318,14 @@ AboutReader.prototype = {
const FONT_SIZE_MAX = 9;
// Sample text shown in Android UI.
let sampleText = this._doc.querySelector(".font-size-sample");
let sampleText = this._doc.getElementById("font-size-sample");
sampleText.textContent = gStrings.GetStringFromName("aboutReader.fontTypeSample");
let currentSize = Services.prefs.getIntPref("reader.font_size");
currentSize = Math.max(FONT_SIZE_MIN, Math.min(FONT_SIZE_MAX, currentSize));
let plusButton = this._doc.querySelector(".plus-button");
let minusButton = this._doc.querySelector(".minus-button");
let plusButton = this._doc.getElementById("font-size-plus");
let minusButton = this._doc.getElementById("font-size-minus");
function updateControls() {
if (currentSize === FONT_SIZE_MIN) {
@ -380,7 +375,7 @@ AboutReader.prototype = {
},
_setContentWidth(newContentWidth) {
let containerClasses = this._containerElement.classList;
let containerClasses = this._doc.getElementById("container").classList;
if (this._contentWidth > 0)
containerClasses.remove("content-width" + this._contentWidth);
@ -397,8 +392,8 @@ AboutReader.prototype = {
let currentContentWidth = Services.prefs.getIntPref("reader.content_width");
currentContentWidth = Math.max(CONTENT_WIDTH_MIN, Math.min(CONTENT_WIDTH_MAX, currentContentWidth));
let plusButton = this._doc.querySelector(".content-width-plus-button");
let minusButton = this._doc.querySelector(".content-width-minus-button");
let plusButton = this._doc.getElementById("content-width-plus");
let minusButton = this._doc.getElementById("content-width-minus");
function updateControls() {
if (currentContentWidth === CONTENT_WIDTH_MIN) {
@ -448,7 +443,7 @@ AboutReader.prototype = {
},
_setLineHeight(newLineHeight) {
let contentClasses = this._contentElement.classList;
let contentClasses = this._doc.getElementById("moz-reader-content").classList;
if (this._lineHeight > 0)
contentClasses.remove("line-height" + this._lineHeight);
@ -465,8 +460,8 @@ AboutReader.prototype = {
let currentLineHeight = Services.prefs.getIntPref("reader.line_height");
currentLineHeight = Math.max(LINE_HEIGHT_MIN, Math.min(LINE_HEIGHT_MAX, currentLineHeight));
let plusButton = this._doc.querySelector(".line-height-plus-button");
let minusButton = this._doc.querySelector(".line-height-minus-button");
let plusButton = this._doc.getElementById("line-height-plus");
let minusButton = this._doc.getElementById("line-height-minus");
function updateControls() {
if (currentLineHeight === LINE_HEIGHT_MIN) {
@ -881,7 +876,7 @@ AboutReader.prototype = {
_setupSegmentedButton(id, options, initialValue, callback) {
let doc = this._doc;
let segmentedButton = doc.getElementsByClassName(id)[0];
let segmentedButton = doc.getElementById(id);
for (let i = 0; i < options.length; i++) {
let option = options[i];
@ -935,7 +930,7 @@ AboutReader.prototype = {
this._setButtonTip(id, titleEntity);
}
let button = this._doc.getElementsByClassName(id)[0];
let button = this._doc.getElementById(id);
if (textEntity) {
button.textContent = gStrings.GetStringFromName(textEntity);
}
@ -956,12 +951,12 @@ AboutReader.prototype = {
* @param Localizable string providing UI element usage tip.
*/
_setButtonTip(id, titleEntity) {
let button = this._doc.getElementsByClassName(id)[0];
let button = this._doc.getElementById(id);
button.setAttribute("title", gStrings.GetStringFromName(titleEntity));
},
_setupStyleDropdown() {
let dropdownToggle = this._doc.querySelector(".style-dropdown .dropdown-toggle");
let dropdownToggle = this._doc.querySelector("#style-dropdown .dropdown-toggle");
dropdownToggle.setAttribute("title", gStrings.GetStringFromName("aboutReader.toolbar.typeControls"));
},

Просмотреть файл

@ -18,19 +18,6 @@ const PARSE_ERROR_TOO_MANY_ELEMENTS = 1;
const PARSE_ERROR_WORKER = 2;
const PARSE_ERROR_NO_ARTICLE = 3;
// Class names to preserve in the readerized output. We preserve these class
// names so that rules in aboutReader.css can match them.
const CLASSES_TO_PRESERVE = [
"caption",
"hidden",
"invisble",
"sr-only",
"visually-hidden",
"visuallyhidden",
"wp-caption",
"wp-caption-text",
];
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
@ -466,13 +453,9 @@ this.ReaderMode = {
createInstance(Ci.nsIDOMSerializer);
let serializedDoc = serializer.serializeToString(doc);
let options = {
classesToPreserve: CLASSES_TO_PRESERVE,
};
let article = null;
try {
article = await ReaderWorker.post("parseDocument", [uriParam, serializedDoc, options]);
article = await ReaderWorker.post("parseDocument", [uriParam, serializedDoc]);
} catch (e) {
Cu.reportError("Error in ReaderWorker: " + e);
histogram.add(PARSE_ERROR_WORKER);

Просмотреть файл

@ -42,12 +42,11 @@ var Agent = {
*
* @param {object} uri URI data for the document.
* @param {string} serializedDoc The serialized document.
* @param {object} options Options object to pass to Readability.
*
* @return {object} Article object returned from Readability.
*/
parseDocument(uri, serializedDoc, options) {
parseDocument(uri, serializedDoc) {
let doc = new JSDOMParser().parse(serializedDoc);
return new Readability(uri, doc, options).parse();
return new Readability(uri, doc).parse();
},
};

Просмотреть файл

@ -11,52 +11,64 @@
</head>
<body>
<div class="container">
<div class="header reader-header">
<a class="domain reader-domain"></a>
<div id="container" class="container">
<div id="reader-header" class="header">
<style scoped>
@import url("chrome://global/skin/aboutReaderControls.css");
</style>
<a id="reader-domain" class="domain"></a>
<div class="domain-border"></div>
<h1 class="reader-title"></h1>
<div class="credits reader-credits"></div>
<div class="meta-data">
<div class="reader-estimated-time"></div>
<h1 id="reader-title"></h1>
<div id="reader-credits" class="credits"></div>
<div id="meta-data" class="meta-data">
<div id="reader-estimated-time"></div>
</div>
</div>
<hr>
<div class="content">
<div class="moz-reader-content"></div>
<style scoped>
@import url("chrome://global/skin/aboutReaderContent.css");
</style>
<div id="moz-reader-content"></div>
</div>
<div>
<div class="reader-message"></div>
<style scoped>
@import url("chrome://global/skin/aboutReaderControls.css");
</style>
<div id="reader-message"></div>
</div>
</div>
<ul class="toolbar reader-toolbar">
<li><button class="button close-button"/></li>
<ul class="dropdown style-dropdown">
<ul id="reader-toolbar" class="toolbar">
<style scoped>
@import url("chrome://global/skin/aboutReaderControls.css");
</style>
<li><button id="close-button" class="button close-button"/></li>
<ul id="style-dropdown" class="dropdown">
<li><button class="dropdown-toggle button style-button"/></li>
<li class="dropdown-popup">
<div class="font-type-buttons"></div>
<li id="reader-popup" class="dropdown-popup">
<div id="font-type-buttons"></div>
<hr>
<div class="font-size-buttons">
<button class="minus-button"/>
<button class="font-size-sample"/>
<button class="plus-button"/>
<div id="font-size-buttons">
<button id="font-size-minus" class="minus-button"/>
<button id="font-size-sample"/>
<button id="font-size-plus" class="plus-button"/>
</div>
<hr>
<div class="content-width-buttons">
<button class="content-width-minus-button"/>
<button class="content-width-plus-button"/>
<div id="content-width-buttons">
<button id="content-width-minus" class="content-width-minus-button"/>
<button id="content-width-plus" class="content-width-plus-button"/>
</div>
<hr>
<div class="line-height-buttons">
<button class="line-height-minus-button"/>
<button class="line-height-plus-button"/>
<div id="line-height-buttons">
<button id="line-height-minus" class="line-height-minus-button"/>
<button id="line-height-plus" class="line-height-plus-button"/>
</div>
<hr>
<div class="color-scheme-buttons"></div>
<div id="color-scheme-buttons"></div>
<div class="dropdown-arrow"/>
</li>
</ul>

Просмотреть файл

@ -677,6 +677,12 @@ var Printing = {
contentElement.setAttribute("class", "content");
containerElement.appendChild(contentElement);
// Create style element for content div and import aboutReaderContent.css
let controlContentStyle = content.document.createElement("style");
controlContentStyle.setAttribute("scoped", "");
controlContentStyle.textContent = "@import url(\"chrome://global/skin/aboutReaderContent.css\");";
contentElement.appendChild(controlContentStyle);
// Jam the article's content into content div
let readerContent = content.document.createElement("div");
readerContent.setAttribute("id", "moz-reader-content");

Просмотреть файл

@ -2,9 +2,6 @@
* 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 {
padding: 64px 51px;
}
@ -46,80 +43,80 @@ body.serif .remove-button {
font-family: Georgia, "Times New Roman", serif;
}
.container {
#container {
max-width: 30em;
margin: 0 auto;
}
.container.font-size1 {
#container.font-size1 {
font-size: 12px;
}
.container.font-size2 {
#container.font-size2 {
font-size: 14px;
}
.container.font-size3 {
#container.font-size3 {
font-size: 16px;
}
.container.font-size4 {
#container.font-size4 {
font-size: 18px;
}
.container.font-size5 {
#container.font-size5 {
font-size: 20px;
}
.container.font-size6 {
#container.font-size6 {
font-size: 22px;
}
.container.font-size7 {
#container.font-size7 {
font-size: 24px;
}
.container.font-size8 {
#container.font-size8 {
font-size: 26px;
}
.container.font-size9 {
#container.font-size9 {
font-size: 28px;
}
.container.content-width1 {
#container.content-width1 {
max-width: 20em;
}
.container.content-width2 {
#container.content-width2 {
max-width: 25em;
}
.container.content-width3 {
#container.content-width3 {
max-width: 30em;
}
.container.content-width4 {
#container.content-width4 {
max-width: 35em;
}
.container.content-width5 {
#container.content-width5 {
max-width: 40em;
}
.container.content-width6 {
#container.content-width6 {
max-width: 45em;
}
.container.content-width7 {
#container.content-width7 {
max-width: 50em;
}
.container.content-width8 {
#container.content-width8 {
max-width: 55em;
}
.container.content-width9 {
#container.content-width9 {
max-width: 60em;
}
@ -166,576 +163,3 @@ body:not(.loaded) .toolbar:-moz-locale-dir(ltr) {
body:not(.loaded) .toolbar:-moz-locale-dir(rtl) {
transform: translateX(100%);
}
.light-button {
color: #333333;
background-color: #ffffff;
}
.dark-button {
color: #eeeeee;
background-color: #333333;
}
.sepia-button {
color: #5b4636;
background-color: #f4ecd8;
}
.sans-serif-button {
font-family: Helvetica, Arial, sans-serif;
}
.serif-button {
font-family: Georgia, "Times New Roman", serif;
}
/* Loading/error message */
.reader-message {
margin-top: 40px;
display: none;
text-align: center;
width: 100%;
font-size: 0.9em;
}
/* Header */
.header {
text-align: start;
display: none;
}
.domain {
font-size: 0.9em;
line-height: 1.48em;
padding-bottom: 4px;
font-family: Helvetica, Arial, sans-serif;
text-decoration: none;
border-bottom: 1px solid;
color: #0095dd;
}
.header > h1 {
font-size: 1.6em;
line-height: 1.25em;
width: 100%;
margin: 30px 0;
padding: 0;
}
.header > .credits {
font-size: 0.9em;
line-height: 1.48em;
margin: 0 0 10px 0;
padding: 0;
font-style: italic;
}
.header > .meta-data {
font-size: 0.65em;
margin: 0 0 15px 0;
}
/*======= Controls toolbar =======*/
.toolbar {
font-family: Helvetica, Arial, sans-serif;
position: fixed;
height: 100%;
top: 0;
left: 0;
margin: 0;
padding: 0;
list-style: none;
background-color: #fbfbfb;
-moz-user-select: none;
border-right: 1px solid #b5b5b5;
z-index: 1;
}
.button {
display: block;
background-size: 24px 24px;
background-repeat: no-repeat;
color: #333;
background-color: #fbfbfb;
height: 40px;
padding: 0;
}
.toolbar .button {
width: 40px;
background-position: center;
margin-right: -1px;
border-top: 0;
border-left: 0;
border-right: 1px solid #b5b5b5;
border-bottom: 1px solid #c1c1c1;
}
.button[hidden] {
display: none;
}
.dropdown {
text-align: center;
list-style: none;
margin: 0;
padding: 0;
}
.dropdown li {
margin: 0;
padding: 0;
}
/*======= Popup =======*/
.dropdown-popup {
min-width: 300px;
text-align: start;
position: absolute;
left: 48px; /* offset to account for toolbar width */
z-index: 1000;
background-color: #fbfbfb;
visibility: hidden;
border-radius: 4px;
border: 1px solid #b5b5b5;
border-bottom-width: 0;
box-shadow: 0 1px 3px #c1c1c1;
}
.keep-open .dropdown-popup {
z-index: initial;
}
.dropdown-popup > hr {
display: none;
}
.open > .dropdown-popup {
visibility: visible;
}
.dropdown-arrow {
position: absolute;
top: 30px; /* offset arrow from top of popup */
left: -16px;
width: 16px;
height: 24px;
background-image: url("chrome://global/skin/reader/RM-Type-Controls-Arrow.svg");
display: block;
}
/*======= Font style popup =======*/
.font-type-buttons,
.font-size-buttons,
.color-scheme-buttons,
.content-width-buttons,
.line-height-buttons {
display: flex;
flex-direction: row;
}
.font-type-buttons > button:first-child {
border-top-left-radius: 3px;
}
.font-type-buttons > button:last-child {
border-top-right-radius: 3px;
}
.color-scheme-buttons > button:first-child {
border-bottom-left-radius: 3px;
}
.color-scheme-buttons > button:last-child {
border-bottom-right-radius: 3px;
}
.font-type-buttons > button,
.font-size-buttons > button,
.color-scheme-buttons > button,
.content-width-buttons > button,
.line-height-buttons > button {
text-align: center;
border: 0;
}
.font-type-buttons > button,
.font-size-buttons > button,
.content-width-buttons > button,
.line-height-buttons > button {
width: 50%;
background-color: transparent;
border-left: 1px solid #B5B5B5;
border-bottom: 1px solid #B5B5B5;
}
.color-scheme-buttons > button {
width: 33.33%;
font-size: 14px;
}
.color-scheme-buttons > .dark-button {
margin-top: -1px;
height: 61px;
}
.font-type-buttons > button:first-child,
.font-size-buttons > button:first-child,
.content-width-buttons > button:first-child,
.line-height-buttons > button:first-child {
border-left: 0;
}
.font-type-buttons > button {
display: inline-block;
font-size: 62px;
height: 100px;
}
.font-size-buttons > button,
.color-scheme-buttons > button,
.content-width-buttons > button,
.line-height-buttons > button {
height: 60px;
}
.font-type-buttons > button:active:hover,
.font-type-buttons > button.selected,
.color-scheme-buttons > button:active:hover,
.color-scheme-buttons > button.selected {
box-shadow: inset 0 -3px 0 0 #fc6420;
}
.font-type-buttons > button:active:hover,
.font-type-buttons > button.selected {
border-bottom: 1px solid #FC6420;
}
/* Make the serif button content the same size as the sans-serif button content. */
.font-type-buttons > button > .description {
color: #666;
font-size: 12px;
margin-top: -5px;
}
/* Font sizes are different per-platform, so we need custom CSS to line them up. */
%ifdef XP_MACOSX
.font-type-buttons > .sans-serif-button > .name {
margin-top: 10px;
}
.font-type-buttons > .sans-serif-button > .description {
margin-top: -4px;
}
.font-type-buttons > .serif-button > .name {
font-size: 63px;
}
%elifdef XP_WIN
.font-type-buttons > .sans-serif-button > .name {
margin-top: 2px;
}
.font-type-buttons > .sans-serif-button > .description {
margin-top: -4px;
}
.font-type-buttons > .serif-button > .name {
font-size: 63px;
}
%else
.font-type-buttons > .sans-serif-button > .name {
margin-top: 5px;
}
.font-type-buttons > .sans-serif-button > .description {
margin-top: -8px;
}
.font-type-buttons > .serif-button > .name {
font-size: 70px;
}
%endif
.button:hover,
.font-size-buttons > button:hover,
.font-type-buttons > button:hover,
.content-width-buttons > button:hover,
.line-height-buttons > button:hover {
background-color: #ebebeb;
}
.dropdown.open,
.button:active,
.font-size-buttons > button:active,
.font-size-buttons > button.selected,
.content-width-buttons > button:active,
.content-width-buttons > button.selected,
.line-height-buttons > button:active,
.line-height-buttons > button.selected {
background-color: #dadada;
}
/* Only used on Android */
.font-size-sample {
display: none;
}
.minus-button,
.plus-button,
.content-width-minus-button,
.content-width-plus-button,
.line-height-minus-button,
.line-height-plus-button {
background-color: transparent;
border: 0;
background-size: 18px 18px;
background-repeat: no-repeat;
background-position: center;
}
/*======= Toolbar icons =======*/
.close-button {
background-image: url("chrome://global/skin/reader/RM-Close-24x24.svg");
-moz-context-properties: fill;
fill: #808080;
height: 68px;
background-position: center 8px;
}
.close-button:hover {
fill: #fff;
background-color: #d94141;
border-bottom: 1px solid #d94141;
border-right: 1px solid #d94141;
}
.close-button:hover:active {
background-color: #AE2325;
border-bottom: 1px solid #AE2325;
border-right: 1px solid #AE2325;
}
.style-button {
background-image: url("chrome://global/skin/reader/RM-Type-Controls-24x24.svg");
}
.minus-button {
background-image: url("chrome://global/skin/reader/RM-Minus-24x24.svg");
}
.plus-button {
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");
}
@media print {
.toolbar {
display: none !important;
}
}
/*======= Article content =======*/
/* Note that any class names from the original article that we want to match on
* must be added to CLASSES_TO_PRESERVE in ReaderMode.jsm, so that
* Readability.js doesn't strip them out */
.moz-reader-content {
display: none;
font-size: 1em;
line-height: 1.6em;
}
.moz-reader-content.line-height1 {
line-height: 1em;
}
.moz-reader-content.line-height2 {
line-height: 1.2em;
}
.moz-reader-content.line-height3 {
line-height: 1.4em;
}
.moz-reader-content.line-height4 {
line-height: 1.6em;
}
.moz-reader-content.line-height5 {
line-height: 1.8em;
}
.moz-reader-content.line-height6 {
line-height: 2.0em;
}
.moz-reader-content.line-height7 {
line-height: 2.2em;
}
.moz-reader-content.line-height8 {
line-height: 2.4em;
}
.moz-reader-content.line-height9 {
line-height: 2.6em;
}
@media print {
.moz-reader-content p,
.moz-reader-content code,
.moz-reader-content pre,
.moz-reader-content blockquote,
.moz-reader-content ul,
.moz-reader-content ol,
.moz-reader-content li,
.moz-reader-content figure,
.moz-reader-content .wp-caption {
margin: 0 0 10px 0 !important;
padding: 0 !important;
}
}
.moz-reader-content h1,
.moz-reader-content h2,
.moz-reader-content h3 {
font-weight: bold;
}
.moz-reader-content h1 {
font-size: 1.6em;
line-height: 1.25em;
}
.moz-reader-content h2 {
font-size: 1.2em;
line-height: 1.51em;
}
.moz-reader-content h3 {
font-size: 1em;
line-height: 1.66em;
}
.moz-reader-content a:link {
text-decoration: underline;
font-weight: normal;
}
.moz-reader-content a:link,
.moz-reader-content a:link:hover,
.moz-reader-content a:link:active {
color: #0095dd;
}
.moz-reader-content a:visited {
color: #c2e;
}
.moz-reader-content * {
max-width: 100%;
height: auto;
}
.moz-reader-content p,
.moz-reader-content p,
.moz-reader-content code,
.moz-reader-content pre,
.moz-reader-content blockquote,
.moz-reader-content ul,
.moz-reader-content ol,
.moz-reader-content li,
.moz-reader-content figure,
.moz-reader-content .wp-caption {
margin: -10px -10px 20px -10px;
padding: 10px;
border-radius: 5px;
}
.moz-reader-content li {
margin-bottom: 0;
}
.moz-reader-content li > ul,
.moz-reader-content li > ol {
margin-bottom: -10px;
}
.moz-reader-content p > img:only-child,
.moz-reader-content p > a:only-child > img:only-child,
.moz-reader-content .wp-caption img,
.moz-reader-content figure img {
display: block;
}
.moz-reader-content img[moz-reader-center] {
margin-left: auto;
margin-right: auto;
}
.moz-reader-content .caption,
.moz-reader-content .wp-caption-text
.moz-reader-content figcaption {
font-size: 0.9em;
line-height: 1.48em;
font-style: italic;
}
.moz-reader-content code,
.moz-reader-content pre {
white-space: pre-wrap;
}
.moz-reader-content blockquote {
padding: 0;
padding-inline-start: 16px;
}
.moz-reader-content ul,
.moz-reader-content ol {
padding: 0;
}
.moz-reader-content ul {
padding-inline-start: 30px;
list-style: disc;
}
.moz-reader-content ol {
padding-inline-start: 30px;
list-style: decimal;
}
/* Hide elements with common "hidden" class names */
.moz-reader-content .visually-hidden,
.moz-reader-content .visuallyhidden,
.moz-reader-content .hidden,
.moz-reader-content .invisible,
.moz-reader-content .sr-only {
display: none;
}

Просмотреть файл

@ -0,0 +1,178 @@
/* 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/. */
#moz-reader-content {
display: none;
font-size: 1em;
line-height: 1.6em;
}
#moz-reader-content.line-height1 {
line-height: 1em;
}
#moz-reader-content.line-height2 {
line-height: 1.2em;
}
#moz-reader-content.line-height3 {
line-height: 1.4em;
}
#moz-reader-content.line-height4 {
line-height: 1.6em;
}
#moz-reader-content.line-height5 {
line-height: 1.8em;
}
#moz-reader-content.line-height6 {
line-height: 2.0em;
}
#moz-reader-content.line-height7 {
line-height: 2.2em;
}
#moz-reader-content.line-height8 {
line-height: 2.4em;
}
#moz-reader-content.line-height9 {
line-height: 2.6em;
}
@media print {
p,
code,
pre,
blockquote,
ul,
ol,
li,
figure,
.wp-caption {
margin: 0 0 10px 0 !important;
padding: 0 !important;
}
}
h1,
h2,
h3 {
font-weight: bold;
}
h1 {
font-size: 1.6em;
line-height: 1.25em;
}
h2 {
font-size: 1.2em;
line-height: 1.51em;
}
h3 {
font-size: 1em;
line-height: 1.66em;
}
a:link {
text-decoration: underline;
font-weight: normal;
}
a:link,
a:link:hover,
a:link:active {
color: #0095dd;
}
a:visited {
color: #c2e;
}
* {
max-width: 100%;
height: auto;
}
p,
code,
pre,
blockquote,
ul,
ol,
li,
figure,
.wp-caption {
margin: -10px -10px 20px -10px;
padding: 10px;
border-radius: 5px;
}
li {
margin-bottom: 0;
}
li > ul,
li > ol {
margin-bottom: -10px;
}
p > img:only-child,
p > a:only-child > img:only-child,
.wp-caption img,
figure img {
display: block;
}
img[moz-reader-center] {
margin-left: auto;
margin-right: auto;
}
.caption,
.wp-caption-text,
figcaption {
font-size: 0.9em;
line-height: 1.48em;
font-style: italic;
}
code,
pre {
white-space: pre-wrap;
}
blockquote {
padding: 0;
padding-inline-start: 16px;
}
ul,
ol {
padding: 0;
}
ul {
padding-inline-start: 30px;
list-style: disc;
}
ol {
padding-inline-start: 30px;
list-style: decimal;
}
/* Hide elements with common "hidden" class names */
.visually-hidden,
.visuallyhidden,
.hidden,
.invisible,
.sr-only {
display: none;
}

Просмотреть файл

@ -0,0 +1,394 @@
/* 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/. */
.light-button {
color: #333333;
background-color: #ffffff;
}
.dark-button {
color: #eeeeee;
background-color: #333333;
}
.sepia-button {
color: #5b4636;
background-color: #f4ecd8;
}
.sans-serif-button {
font-family: Helvetica, Arial, sans-serif;
}
.serif-button {
font-family: Georgia, "Times New Roman", serif;
}
/* Loading/error message */
#reader-message {
margin-top: 40px;
display: none;
text-align: center;
width: 100%;
font-size: 0.9em;
}
/* Header */
.header {
text-align: start;
display: none;
}
.domain {
font-size: 0.9em;
line-height: 1.48em;
padding-bottom: 4px;
font-family: Helvetica, Arial, sans-serif;
text-decoration: none;
border-bottom: 1px solid;
color: #0095dd;
}
.header > h1 {
font-size: 1.6em;
line-height: 1.25em;
width: 100%;
margin: 30px 0;
padding: 0;
}
.header > .credits {
font-size: 0.9em;
line-height: 1.48em;
margin: 0 0 10px 0;
padding: 0;
font-style: italic;
}
.header > .meta-data {
font-size: 0.65em;
margin: 0 0 15px 0;
}
/*======= Controls toolbar =======*/
.toolbar {
font-family: Helvetica, Arial, sans-serif;
position: fixed;
height: 100%;
top: 0;
left: 0;
margin: 0;
padding: 0;
list-style: none;
background-color: #fbfbfb;
-moz-user-select: none;
border-right: 1px solid #b5b5b5;
z-index: 1;
}
.button {
display: block;
background-size: 24px 24px;
background-repeat: no-repeat;
color: #333;
background-color: #fbfbfb;
height: 40px;
padding: 0;
}
.toolbar .button {
width: 40px;
background-position: center;
margin-right: -1px;
border-top: 0;
border-left: 0;
border-right: 1px solid #b5b5b5;
border-bottom: 1px solid #c1c1c1;
}
.button[hidden] {
display: none;
}
.dropdown {
text-align: center;
list-style: none;
margin: 0;
padding: 0;
}
.dropdown li {
margin: 0;
padding: 0;
}
/*======= Popup =======*/
.dropdown-popup {
min-width: 300px;
text-align: start;
position: absolute;
left: 48px; /* offset to account for toolbar width */
z-index: 1000;
background-color: #fbfbfb;
visibility: hidden;
border-radius: 4px;
border: 1px solid #b5b5b5;
border-bottom-width: 0;
box-shadow: 0 1px 3px #c1c1c1;
}
.keep-open .dropdown-popup {
z-index: initial;
}
.dropdown-popup > hr {
display: none;
}
.open > .dropdown-popup {
visibility: visible;
}
.dropdown-arrow {
position: absolute;
top: 30px; /* offset arrow from top of popup */
left: -16px;
width: 16px;
height: 24px;
background-image: url("chrome://global/skin/reader/RM-Type-Controls-Arrow.svg");
display: block;
}
/*======= Font style popup =======*/
#font-type-buttons,
#font-size-buttons,
#color-scheme-buttons,
#content-width-buttons,
#line-height-buttons {
display: flex;
flex-direction: row;
}
#font-type-buttons > button:first-child {
border-top-left-radius: 3px;
}
#font-type-buttons > button:last-child {
border-top-right-radius: 3px;
}
#color-scheme-buttons > button:first-child {
border-bottom-left-radius: 3px;
}
#color-scheme-buttons > button:last-child {
border-bottom-right-radius: 3px;
}
#font-type-buttons > button,
#font-size-buttons > button,
#color-scheme-buttons > button,
#content-width-buttons > button,
#line-height-buttons > button {
text-align: center;
border: 0;
}
#font-type-buttons > button,
#font-size-buttons > button,
#content-width-buttons > button,
#line-height-buttons > button {
width: 50%;
background-color: transparent;
border-left: 1px solid #B5B5B5;
border-bottom: 1px solid #B5B5B5;
}
#color-scheme-buttons > button {
width: 33.33%;
font-size: 14px;
}
#color-scheme-buttons > .dark-button {
margin-top: -1px;
height: 61px;
}
#font-type-buttons > button:first-child,
#font-size-buttons > button:first-child,
#content-width-buttons > button:first-child,
#line-height-buttons > button:first-child {
border-left: 0;
}
#font-type-buttons > button {
display: inline-block;
font-size: 62px;
height: 100px;
}
#font-size-buttons > button,
#color-scheme-buttons > button,
#content-width-buttons > button,
#line-height-buttons > button {
height: 60px;
}
#font-type-buttons > button:active:hover,
#font-type-buttons > button.selected,
#color-scheme-buttons > button:active:hover,
#color-scheme-buttons > button.selected {
box-shadow: inset 0 -3px 0 0 #fc6420;
}
#font-type-buttons > button:active:hover,
#font-type-buttons > button.selected {
border-bottom: 1px solid #FC6420;
}
/* Make the serif button content the same size as the sans-serif button content. */
#font-type-buttons > button > .description {
color: #666;
font-size: 12px;
margin-top: -5px;
}
/* Font sizes are different per-platform, so we need custom CSS to line them up. */
%ifdef XP_MACOSX
#font-type-buttons > .sans-serif-button > .name {
margin-top: 10px;
}
#font-type-buttons > .sans-serif-button > .description {
margin-top: -4px;
}
#font-type-buttons > .serif-button > .name {
font-size: 63px;
}
%elifdef XP_WIN
#font-type-buttons > .sans-serif-button > .name {
margin-top: 2px;
}
#font-type-buttons > .sans-serif-button > .description {
margin-top: -4px;
}
#font-type-buttons > .serif-button > .name {
font-size: 63px;
}
%else
#font-type-buttons > .sans-serif-button > .name {
margin-top: 5px;
}
#font-type-buttons > .sans-serif-button > .description {
margin-top: -8px;
}
#font-type-buttons > .serif-button > .name {
font-size: 70px;
}
%endif
.button:hover,
#font-size-buttons > button:hover,
#font-type-buttons > button:hover,
#content-width-buttons > button:hover,
#line-height-buttons > button:hover {
background-color: #ebebeb;
}
.dropdown.open,
.button:active,
#font-size-buttons > button:active,
#font-size-buttons > button.selected,
#content-width-buttons > button:active,
#content-width-buttons > button.selected,
#line-height-buttons > button:active,
#line-height-buttons > button.selected {
background-color: #dadada;
}
/* Only used on Android */
#font-size-sample {
display: none;
}
.minus-button,
.plus-button,
.content-width-minus-button,
.content-width-plus-button,
.line-height-minus-button,
.line-height-plus-button {
background-color: transparent;
border: 0;
background-size: 18px 18px;
background-repeat: no-repeat;
background-position: center;
}
/*======= Toolbar icons =======*/
.close-button {
background-image: url("chrome://global/skin/reader/RM-Close-24x24.svg");
-moz-context-properties: fill;
fill: #808080;
height: 68px;
background-position: center 8px;
}
.close-button:hover {
fill: #fff;
background-color: #d94141;
border-bottom: 1px solid #d94141;
border-right: 1px solid #d94141;
}
.close-button:hover:active {
background-color: #AE2325;
border-bottom: 1px solid #AE2325;
border-right: 1px solid #AE2325;
}
.style-button {
background-image: url("chrome://global/skin/reader/RM-Type-Controls-24x24.svg");
}
.minus-button {
background-image: url("chrome://global/skin/reader/RM-Minus-24x24.svg");
}
.plus-button {
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");
}
@media print {
.toolbar {
display: none !important;
}
}

Просмотреть файл

@ -15,7 +15,9 @@ toolkit.jar:
skin/classic/global/aboutCache.css (../../shared/aboutCache.css)
skin/classic/global/aboutCacheEntry.css (../../shared/aboutCacheEntry.css)
skin/classic/global/aboutMemory.css (../../shared/aboutMemory.css)
* skin/classic/global/aboutReader.css (../../shared/aboutReader.css)
skin/classic/global/aboutReader.css (../../shared/aboutReader.css)
skin/classic/global/aboutReaderContent.css (../../shared/aboutReaderContent.css)
* skin/classic/global/aboutReaderControls.css (../../shared/aboutReaderControls.css)
skin/classic/global/aboutRights.css (../../shared/aboutRights.css)
skin/classic/global/aboutLicense.css (../../shared/aboutLicense.css)
skin/classic/global/aboutSupport.css (../../shared/aboutSupport.css)
@ -48,6 +50,7 @@ toolkit.jar:
skin/classic/global/icons/blocked.svg (../../shared/incontent-icons/blocked.svg)
skin/classic/global/illustrations/about-license.svg (../../shared/illustrations/about-license.svg)
skin/classic/global/narrate.css (../../shared/narrate.css)
skin/classic/global/narrateControls.css (../../shared/narrateControls.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/fast.svg (../../shared/narrate/fast.svg)

Просмотреть файл

@ -1,6 +1,3 @@
/* Avoid adding ID selector rules in this style sheet, since they could
* inadvertently match elements in the article content. */
.narrating {
position: relative;
z-index: 1;
@ -47,190 +44,3 @@ body.sepia .narrate-word-highlight {
body.dark .narrate-word-highlight {
border-bottom-color: #6f6f6f;
}
.narrate-dropdown {
--border-color: #e5e5e5;
}
.narrate-toggle > svg {
display: block;
margin: 0 8px;
}
.narrate-dropdown > .dropdown-popup button {
background-color: transparent;
}
.narrate-dropdown > .dropdown-popup button:hover:not(:disabled) {
background-color: #eaeaea;
}
.narrate-row {
display: flex;
align-items: center;
min-height: 40px;
box-sizing: border-box;
}
.narrate-row:not(:first-child) {
border-top: 1px solid var(--border-color);
}
/* Control buttons */
.narrate-control > button {
background-size: 24px 24px;
background-repeat: no-repeat;
background-position: center center;
height: 64px;
width: 100px;
border: none;
color: #666;
box-sizing: border-box;
}
.narrate-control > button:not(:first-child) {
border-left: 1px solid var(--border-color);
}
.narrate-skip-previous {
border-top-left-radius: 3px;
background-image: url("chrome://global/skin/narrate/back.svg");
-moz-context-properties: fill;
fill: rgb(128 128 128);
}
.narrate-skip-next {
border-top-right-radius: 3px;
background-image: url("chrome://global/skin/narrate/forward.svg");
-moz-context-properties: fill;
fill: rgb(128 128 128);
}
.narrate-skip-previous:disabled,
.narrate-skip-next:disabled {
fill: rgb(128 128 128 / 50%);
}
.narrate-start-stop {
background-image: url("chrome://global/skin/narrate/start.svg");
}
.narrate-dropdown.speaking .narrate-start-stop {
background-image: url("chrome://global/skin/narrate/stop.svg");
}
/* Rate control */
.narrate-rate::before, .narrate-rate::after {
content: '';
width: 48px;
height: 40px;
background-position: center;
background-repeat: no-repeat;
background-size: 24px auto;
}
.narrate-rate::before {
background-image: url("chrome://global/skin/narrate/slow.svg");
}
.narrate-rate::after {
background-image: url("chrome://global/skin/narrate/fast.svg");
}
.narrate-rate-input {
margin: 0 1px;
flex-grow: 1;
}
.narrate-rate-input::-moz-range-track {
background-color: #979797;
height: 2px;
}
.narrate-rate-input::-moz-range-progress {
background-color: #2EA3FF;
height: 2px;
}
.narrate-rate-input::-moz-range-thumb {
background-color: #808080;
height: 16px;
width: 16px;
border-radius: 8px;
border-width: 0;
}
.narrate-rate-input:active::-moz-range-thumb {
background-color: #2EA3FF;
}
/* Voice selection */
.voiceselect {
width: 100%;
}
.voiceselect > button.select-toggle,
.voiceselect > .options > button.option {
-moz-appearance: none;
border: none;
width: 100%;
min-height: 40px;
}
.voiceselect.open > button.select-toggle {
border-bottom: 1px solid var(--border-color);
}
.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;
}
.voiceselect > .options > button.option:not(:first-child) {
border-top: 1px solid var(--border-color);
}
.voiceselect > .options > button.option {
box-sizing: border-box;
}
.voiceselect > .options:not(.hovering) > button.option:focus {
background-color: #eaeaea;
}
.voiceselect > .options:not(.hovering) > button.option:hover:not(:focus) {
background-color: transparent;
}
.voiceselect > .options > button.option::-moz-focus-inner {
outline: none;
border: 0;
}
.voiceselect > .options {
display: none;
overflow-y: auto;
}
.voiceselect.open > .options {
display: block;
}
.current-voice {
color: #7f7f7f;
}
.voiceselect:not(.open) > button,
.voiceselect .option:last-child {
border-radius: 0 0 3px 3px;
}

Просмотреть файл

@ -0,0 +1,186 @@
:scope {
--border-color: #e5e5e5;
}
#narrate-toggle > svg {
display: block;
margin: 0 8px;
}
.dropdown-popup button {
background-color: transparent;
}
.dropdown-popup button:hover:not(:disabled) {
background-color: #eaeaea;
}
.narrate-row {
display: flex;
align-items: center;
min-height: 40px;
box-sizing: border-box;
}
.narrate-row:not(:first-child) {
border-top: 1px solid var(--border-color);
}
/* Control buttons */
#narrate-control > button {
background-size: 24px 24px;
background-repeat: no-repeat;
background-position: center center;
height: 64px;
width: 100px;
border: none;
color: #666;
box-sizing: border-box;
}
#narrate-control > button:not(:first-child) {
border-left: 1px solid var(--border-color);
}
#narrate-skip-previous {
border-top-left-radius: 3px;
background-image: url("chrome://global/skin/narrate/back.svg");
-moz-context-properties: fill;
fill: rgb(128 128 128);
}
#narrate-skip-next {
border-top-right-radius: 3px;
background-image: url("chrome://global/skin/narrate/forward.svg");
-moz-context-properties: fill;
fill: rgb(128 128 128);
}
#narrate-skip-previous:disabled,
#narrate-skip-next:disabled {
fill: rgb(128 128 128 / 50%);
}
#narrate-start-stop {
background-image: url("chrome://global/skin/narrate/start.svg");
}
#narrate-dropdown.speaking #narrate-start-stop {
background-image: url("chrome://global/skin/narrate/stop.svg");
}
/* Rate control */
#narrate-rate::before, #narrate-rate::after {
content: '';
width: 48px;
height: 40px;
background-position: center;
background-repeat: no-repeat;
background-size: 24px auto;
}
#narrate-rate::before {
background-image: url("chrome://global/skin/narrate/slow.svg");
}
#narrate-rate::after {
background-image: url("chrome://global/skin/narrate/fast.svg");
}
#narrate-rate-input {
margin: 0 1px;
flex-grow: 1;
}
#narrate-rate-input::-moz-range-track {
background-color: #979797;
height: 2px;
}
#narrate-rate-input::-moz-range-progress {
background-color: #2EA3FF;
height: 2px;
}
#narrate-rate-input::-moz-range-thumb {
background-color: #808080;
height: 16px;
width: 16px;
border-radius: 8px;
border-width: 0;
}
#narrate-rate-input:active::-moz-range-thumb {
background-color: #2EA3FF;
}
/* Voice selection */
.voiceselect {
width: 100%;
}
.voiceselect > button.select-toggle,
.voiceselect > .options > button.option {
-moz-appearance: none;
border: none;
width: 100%;
min-height: 40px;
}
.voiceselect.open > button.select-toggle {
border-bottom: 1px solid var(--border-color);
}
.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;
}
.voiceselect > .options > button.option:not(:first-child) {
border-top: 1px solid var(--border-color);
}
.voiceselect > .options > button.option {
box-sizing: border-box;
}
.voiceselect > .options:not(.hovering) > button.option:focus {
background-color: #eaeaea;
}
.voiceselect > .options:not(.hovering) > button.option:hover:not(:focus) {
background-color: transparent;
}
.voiceselect > .options > button.option::-moz-focus-inner {
outline: none;
border: 0;
}
.voiceselect > .options {
display: none;
overflow-y: auto;
}
.voiceselect.open > .options {
display: block;
}
.current-voice {
color: #7f7f7f;
}
.voiceselect:not(.open) > button,
.option:last-child {
border-radius: 0 0 3px 3px;
}