mirror of
https://github.com/hensm/fx_cast.git
synced 2026-06-08 08:39:59 +00:00
Add site-specific custom user agent option and new whitelist option UI
This commit is contained in:
@@ -329,10 +329,6 @@
|
|||||||
"message": "Add Item",
|
"message": "Add Item",
|
||||||
"description": "Add new whitelist item button title."
|
"description": "Add new whitelist item button title."
|
||||||
},
|
},
|
||||||
"optionsSiteWhitelistUserAgent": {
|
|
||||||
"message": "Disable UA",
|
|
||||||
"description": "Whitelist item user agent checkbox title."
|
|
||||||
},
|
|
||||||
"optionsSiteWhitelistEditItem": {
|
"optionsSiteWhitelistEditItem": {
|
||||||
"message": "Edit",
|
"message": "Edit",
|
||||||
"description": "Edit whitelist item button title. Displayed on each item."
|
"description": "Edit whitelist item button title. Displayed on each item."
|
||||||
@@ -350,13 +346,29 @@
|
|||||||
"description": "Default <option> for knownApps <select>."
|
"description": "Default <option> for knownApps <select>."
|
||||||
},
|
},
|
||||||
"optionsSiteWhitelistCustomUserAgent": {
|
"optionsSiteWhitelistCustomUserAgent": {
|
||||||
"message": "Custom user agent:",
|
"message": "User agent:",
|
||||||
"description": "Custom user agent option label."
|
"description": "Custom user agent option label."
|
||||||
},
|
},
|
||||||
"optionsSiteWhitelistCustomUserAgentDescription": {
|
"optionsSiteWhitelistCustomUserAgentDescription": {
|
||||||
"message": "If specified, a custom user agent string to use for whitelisted sites.",
|
"message": "If specified, a custom user agent string to use for whitelisted sites.",
|
||||||
"description": "Custom user agent option description."
|
"description": "Custom user agent option description."
|
||||||
},
|
},
|
||||||
|
"optionsSiteWhitelistUserAgentDisabled": {
|
||||||
|
"message": "Disable user agent",
|
||||||
|
"description": "Whitelist item user agent disabled checkbox label."
|
||||||
|
},
|
||||||
|
"optionsSiteWhitelistUserAgentDisabledDescription": {
|
||||||
|
"message": "Entirely disable user agent replacement for sites matching this pattern.",
|
||||||
|
"description": "Whitelist item user agent disabled checkbox description."
|
||||||
|
},
|
||||||
|
"optionsSiteWhitelistSiteSpecificUserAgent": {
|
||||||
|
"message": "User agent:",
|
||||||
|
"description": "Whitelist item user agent option label."
|
||||||
|
},
|
||||||
|
"optionsSiteWhitelistSiteSpecificUserAgentDescription": {
|
||||||
|
"message": "If specified, a custom user agent string to use specifically for this sites matching this pattern.",
|
||||||
|
"description": "Whitelist item user agent option label."
|
||||||
|
},
|
||||||
|
|
||||||
"optionsMirroringCategoryName": {
|
"optionsMirroringCategoryName": {
|
||||||
"message": "Screen/tab casting",
|
"message": "Screen/tab casting",
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import logger from "../lib/logger";
|
|||||||
import options from "../lib/options";
|
import options from "../lib/options";
|
||||||
|
|
||||||
import { getChromeUserAgent } from "../lib/userAgents";
|
import { getChromeUserAgent } from "../lib/userAgents";
|
||||||
|
import { RemoteMatchPattern } from "../lib/matchPattern";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CAST_FRAMEWORK_LOADER_SCRIPT_URL,
|
CAST_FRAMEWORK_LOADER_SCRIPT_URL,
|
||||||
@@ -25,6 +26,7 @@ type OnBeforeRequestDetails = Parameters<
|
|||||||
export interface WhitelistItemData {
|
export interface WhitelistItemData {
|
||||||
pattern: string;
|
pattern: string;
|
||||||
isUserAgentDisabled?: boolean;
|
isUserAgentDisabled?: boolean;
|
||||||
|
customUserAgent?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const originUrlCache: string[] = [];
|
const originUrlCache: string[] = [];
|
||||||
@@ -33,6 +35,8 @@ let platform: string;
|
|||||||
let chromeUserAgent: string | undefined;
|
let chromeUserAgent: string | undefined;
|
||||||
let chromeUserAgentHybrid: string | undefined;
|
let chromeUserAgentHybrid: string | undefined;
|
||||||
|
|
||||||
|
let siteWhitelistEnabled = false;
|
||||||
|
let siteWhitelist: Nullable<WhitelistItemData[]> = null;
|
||||||
let customUserAgent: string | undefined;
|
let customUserAgent: string | undefined;
|
||||||
|
|
||||||
export async function initWhitelist() {
|
export async function initWhitelist() {
|
||||||
@@ -65,7 +69,6 @@ export async function initWhitelist() {
|
|||||||
if (alteredOpts.includes("siteWhitelistCustomUserAgent")) {
|
if (alteredOpts.includes("siteWhitelistCustomUserAgent")) {
|
||||||
customUserAgent = await options.get("siteWhitelistCustomUserAgent");
|
customUserAgent = await options.get("siteWhitelistCustomUserAgent");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
alteredOpts.includes("siteWhitelist") ||
|
alteredOpts.includes("siteWhitelist") ||
|
||||||
alteredOpts.includes("siteWhitelistEnabled")
|
alteredOpts.includes("siteWhitelistEnabled")
|
||||||
@@ -76,6 +79,30 @@ export async function initWhitelist() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the configured user agent matching the specified URL or
|
||||||
|
* undefined if the user agent is disabled.
|
||||||
|
*/
|
||||||
|
function getUserAgent(url: string, host?: string): Optional<string> {
|
||||||
|
if (!siteWhitelistEnabled || !siteWhitelist) return;
|
||||||
|
|
||||||
|
// Search site-specific user agents
|
||||||
|
const matchingItem = siteWhitelist.find(
|
||||||
|
item =>
|
||||||
|
item.customUserAgent &&
|
||||||
|
new RemoteMatchPattern(item.pattern).matches(url)
|
||||||
|
);
|
||||||
|
if (matchingItem) {
|
||||||
|
if (matchingItem.isUserAgentDisabled) return;
|
||||||
|
return matchingItem.customUserAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
customUserAgent ||
|
||||||
|
(host === "www.youtube.com" ? chromeUserAgentHybrid : chromeUserAgent)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Web apps usually only load the sender library and
|
* Web apps usually only load the sender library and
|
||||||
* provide cast functionality if the browser is detected
|
* provide cast functionality if the browser is detected
|
||||||
@@ -99,11 +126,7 @@ async function onWhitelistedBeforeSendHeaders(
|
|||||||
|
|
||||||
for (const header of details.requestHeaders) {
|
for (const header of details.requestHeaders) {
|
||||||
if (header.name === "User-Agent") {
|
if (header.name === "User-Agent") {
|
||||||
header.value =
|
header.value = getUserAgent(details.url, host?.value);
|
||||||
customUserAgent ||
|
|
||||||
(host?.value === "www.youtube.com"
|
|
||||||
? chromeUserAgentHybrid
|
|
||||||
: chromeUserAgent);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,11 +157,7 @@ function onWhitelistedChildBeforeSendHeaders(
|
|||||||
|
|
||||||
for (const header of details.requestHeaders) {
|
for (const header of details.requestHeaders) {
|
||||||
if (header.name === "User-Agent") {
|
if (header.name === "User-Agent") {
|
||||||
header.value =
|
header.value = getUserAgent(details.url, host?.value);
|
||||||
customUserAgent ||
|
|
||||||
(host?.value === "www.youtube.com"
|
|
||||||
? chromeUserAgentHybrid
|
|
||||||
: chromeUserAgent);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -205,7 +224,9 @@ async function onBeforeCastSDKRequest(details: OnBeforeRequestDetails) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function registerSiteWhitelist() {
|
async function registerSiteWhitelist() {
|
||||||
const { siteWhitelist, siteWhitelistEnabled } = await options.getAll();
|
const opts = await options.getAll();
|
||||||
|
siteWhitelist = opts.siteWhitelist;
|
||||||
|
siteWhitelistEnabled = opts.siteWhitelistEnabled;
|
||||||
|
|
||||||
browser.webRequest.onBeforeRequest.addListener(
|
browser.webRequest.onBeforeRequest.addListener(
|
||||||
onBeforeCastSDKRequest,
|
onBeforeCastSDKRequest,
|
||||||
|
|||||||
@@ -18,11 +18,12 @@
|
|||||||
let isFormValid = true;
|
let isFormValid = true;
|
||||||
let isSavedIndicatorVisible = false;
|
let isSavedIndicatorVisible = false;
|
||||||
|
|
||||||
let platform: string;
|
let defaultUserAgent: Optional<string>;
|
||||||
|
|
||||||
let opts: Options | undefined;
|
let opts: Options | undefined;
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
platform = (await browser.runtime.getPlatformInfo()).os;
|
const platform = (await browser.runtime.getPlatformInfo()).os;
|
||||||
|
defaultUserAgent = getChromeUserAgent(platform);
|
||||||
|
|
||||||
opts = await options.getAll();
|
opts = await options.getAll();
|
||||||
options.addEventListener("changed", async () => {
|
options.addEventListener("changed", async () => {
|
||||||
@@ -45,6 +46,9 @@
|
|||||||
if (item.isUserAgentDisabled === false) {
|
if (item.isUserAgentDisabled === false) {
|
||||||
delete item.isUserAgentDisabled;
|
delete item.isUserAgentDisabled;
|
||||||
}
|
}
|
||||||
|
if (item.customUserAgent === "") {
|
||||||
|
delete item.customUserAgent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await options.setAll(opts);
|
await options.setAll(opts);
|
||||||
@@ -68,7 +72,7 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if opts && platform}
|
{#if opts}
|
||||||
<form
|
<form
|
||||||
id="form"
|
id="form"
|
||||||
bind:this={formElement}
|
bind:this={formElement}
|
||||||
@@ -281,7 +285,7 @@
|
|||||||
id="siteWhitelistCustomUserAgent"
|
id="siteWhitelistCustomUserAgent"
|
||||||
type="text"
|
type="text"
|
||||||
bind:value={opts.siteWhitelistCustomUserAgent}
|
bind:value={opts.siteWhitelistCustomUserAgent}
|
||||||
placeholder={getChromeUserAgent(platform)}
|
placeholder={defaultUserAgent}
|
||||||
/>
|
/>
|
||||||
<div class="option__description">
|
<div class="option__description">
|
||||||
{_("optionsSiteWhitelistCustomUserAgentDescription")}
|
{_("optionsSiteWhitelistCustomUserAgentDescription")}
|
||||||
@@ -294,7 +298,11 @@
|
|||||||
{_("optionsSiteWhitelistContent")}
|
{_("optionsSiteWhitelistContent")}
|
||||||
</div>
|
</div>
|
||||||
<div class="option__control">
|
<div class="option__control">
|
||||||
<Whitelist bind:items={opts.siteWhitelist} />
|
<Whitelist
|
||||||
|
bind:items={opts.siteWhitelist}
|
||||||
|
{opts}
|
||||||
|
{defaultUserAgent}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|||||||
@@ -4,11 +4,14 @@
|
|||||||
import knownApps, { KnownApp } from "../../cast/knownApps";
|
import knownApps, { KnownApp } from "../../cast/knownApps";
|
||||||
import { WhitelistItemData } from "../../background/whitelist";
|
import { WhitelistItemData } from "../../background/whitelist";
|
||||||
import { REMOTE_MATCH_PATTERN_REGEX } from "../../lib/matchPattern";
|
import { REMOTE_MATCH_PATTERN_REGEX } from "../../lib/matchPattern";
|
||||||
|
import { Options } from "../../lib/options";
|
||||||
|
|
||||||
const _ = browser.i18n.getMessage;
|
const _ = browser.i18n.getMessage;
|
||||||
|
|
||||||
/** Whitelist items to display. */
|
/** Whitelist items to display. */
|
||||||
export let items: WhitelistItemData[];
|
export let items: WhitelistItemData[];
|
||||||
|
export let opts: Options;
|
||||||
|
export let defaultUserAgent: Optional<string>;
|
||||||
|
|
||||||
let isEditing = false;
|
let isEditing = false;
|
||||||
let isEditingValid = false;
|
let isEditingValid = false;
|
||||||
@@ -16,6 +19,8 @@
|
|||||||
let editingInput: HTMLInputElement;
|
let editingInput: HTMLInputElement;
|
||||||
let editingValue: string;
|
let editingValue: string;
|
||||||
|
|
||||||
|
let expandedItemIndices = new Set();
|
||||||
|
|
||||||
let knownAppToAdd: Nullable<KnownApp> = null;
|
let knownAppToAdd: Nullable<KnownApp> = null;
|
||||||
$: filteredKnownApps = Object.values(knownApps).filter(app => {
|
$: filteredKnownApps = Object.values(knownApps).filter(app => {
|
||||||
// If no pattern or name matches default media sender
|
// If no pattern or name matches default media sender
|
||||||
@@ -115,13 +120,17 @@
|
|||||||
<ul class="whitelist__items">
|
<ul class="whitelist__items">
|
||||||
{#each items as item, i}
|
{#each items as item, i}
|
||||||
{@const isEditingItem = isEditing && editingIndex === i}
|
{@const isEditingItem = isEditing && editingIndex === i}
|
||||||
|
{@const isItemExpanded = expandedItemIndices.has(i)}
|
||||||
|
|
||||||
<li
|
<li
|
||||||
class="whitelist__item"
|
class="whitelist__item"
|
||||||
class:whitelist__item--selected={isEditingItem}
|
class:whitelist__item--selected={isEditingItem}
|
||||||
on:dblclick={() => beginEditing(i)}
|
class:whitelist__item--expanded={isItemExpanded}
|
||||||
>
|
>
|
||||||
<div class="whitelist__title">
|
<div
|
||||||
|
class="whitelist__title"
|
||||||
|
on:dblclick={() => beginEditing(i)}
|
||||||
|
>
|
||||||
{#if isEditingItem}
|
{#if isEditingItem}
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -150,13 +159,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if !isEditingItem}
|
{#if !isEditingItem}
|
||||||
<label class="whitelist__user-agent">
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
bind:checked={item.isUserAgentDisabled}
|
|
||||||
/>
|
|
||||||
{_("optionsSiteWhitelistUserAgent")}
|
|
||||||
</label>
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="whitelist__edit-button ghost"
|
class="whitelist__edit-button ghost"
|
||||||
@@ -177,6 +179,80 @@
|
|||||||
>
|
>
|
||||||
<img src="assets/photon_delete.svg" alt="icon, remove" />
|
<img src="assets/photon_delete.svg" alt="icon, remove" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
{#if !isEditingItem}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="whitelist__expand-button ghost"
|
||||||
|
title={_("optionsSiteWhitelistRemoveItem")}
|
||||||
|
on:click={() => {
|
||||||
|
// Toggle expanded state
|
||||||
|
if (isItemExpanded) {
|
||||||
|
expandedItemIndices.delete(i);
|
||||||
|
} else {
|
||||||
|
expandedItemIndices.add(i);
|
||||||
|
}
|
||||||
|
expandedItemIndices = expandedItemIndices;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="assets/{isItemExpanded
|
||||||
|
? 'photon_arrowhead_up.svg'
|
||||||
|
: 'photon_arrowhead_down.svg'}"
|
||||||
|
alt="icon, arrow down"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{#if isItemExpanded}
|
||||||
|
<div class="whitelist__expanded">
|
||||||
|
<div class="option option--inline">
|
||||||
|
<div class="option__control">
|
||||||
|
<input
|
||||||
|
id="isUserAgentDisabled-{i}"
|
||||||
|
type="checkbox"
|
||||||
|
bind:checked={item.isUserAgentDisabled}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<label
|
||||||
|
class="option__label"
|
||||||
|
for="isUserAgentDisabled-{i}"
|
||||||
|
>
|
||||||
|
{_("optionsSiteWhitelistUserAgentDisabled")}
|
||||||
|
</label>
|
||||||
|
<div class="option__description">
|
||||||
|
{_(
|
||||||
|
"optionsSiteWhitelistUserAgentDisabledDescription"
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="option">
|
||||||
|
<label
|
||||||
|
class="option__label"
|
||||||
|
for="customUserAgentString-{i}"
|
||||||
|
>
|
||||||
|
{_(
|
||||||
|
"optionsSiteWhitelistSiteSpecificUserAgent"
|
||||||
|
)}
|
||||||
|
</label>
|
||||||
|
<div class="option__control">
|
||||||
|
<input
|
||||||
|
id="customUserAgentString-{i}"
|
||||||
|
type="text"
|
||||||
|
bind:value={item.customUserAgent}
|
||||||
|
placeholder={opts.siteWhitelistCustomUserAgent ||
|
||||||
|
defaultUserAgent}
|
||||||
|
/>
|
||||||
|
<div class="option__description">
|
||||||
|
{_(
|
||||||
|
"optionsSiteWhitelistSiteSpecificUserAgentDescription"
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
</li>
|
</li>
|
||||||
{/each}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
13
ext/src/ui/options/assets/photon_arrowhead_down.svg
Normal file
13
ext/src/ui/options/assets/photon_arrowhead_down.svg
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!-- 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="16" height="16" viewBox="0 0 16 16">
|
||||||
|
<style>
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
path {
|
||||||
|
fill: rgba(249, 249, 250, .8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<path fill="rgba(12, 12, 13, .8)" d="M8 12a1 1 0 0 1-.707-.293l-5-5a1 1 0 0 1 1.414-1.414L8 9.586l4.293-4.293a1 1 0 0 1 1.414 1.414l-5 5A1 1 0 0 1 8 12z"></path>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 629 B |
13
ext/src/ui/options/assets/photon_arrowhead_up.svg
Normal file
13
ext/src/ui/options/assets/photon_arrowhead_up.svg
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!-- 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="16" height="16" viewBox="0 0 16 16">
|
||||||
|
<style>
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
path {
|
||||||
|
fill: rgba(249, 249, 250, .8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<path fill="rgba(12, 12, 13, .8)" d="M13 11a1 1 0 0 1-.707-.293L8 6.414l-4.293 4.293a1 1 0 0 1-1.414-1.414l5-5a1 1 0 0 1 1.414 0l5 5A1 1 0 0 1 13 11z"></path>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 625 B |
@@ -1,11 +1,11 @@
|
|||||||
:root {
|
:root {
|
||||||
--border-color: rgb(225, 225, 225);
|
--border-color: var(--grey-90-a20);
|
||||||
--secondary-color: rgb(125, 125, 125);
|
--secondary-color: rgb(125, 125, 125);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
:root {
|
:root {
|
||||||
--border-color: var(--grey-50);
|
--border-color: var(--grey-10-a20);
|
||||||
--secondary-color: var(--grey-10-a60);
|
--secondary-color: var(--grey-10-a60);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,10 +223,6 @@ button.ghost:not(:hover) {
|
|||||||
padding: 10px 0;
|
padding: 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.category:disabled {
|
|
||||||
color: var(--secondary-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
#form > .category {
|
#form > .category {
|
||||||
border-bottom: 1px solid var(--border-color);
|
border-bottom: 1px solid var(--border-color);
|
||||||
}
|
}
|
||||||
@@ -350,13 +346,13 @@ button.ghost:not(:hover) {
|
|||||||
.whitelist__item {
|
.whitelist__item {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 5px;
|
flex-wrap: wrap;
|
||||||
height: 34px;
|
column-gap: 5px;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.whitelist__item:nth-child(even) {
|
.whitelist__item:nth-child(even) {
|
||||||
background-color: rgba(0, 0, 0, 0.05);
|
background-color: rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.whitelist__item--selected {
|
.whitelist__item--selected {
|
||||||
@@ -365,7 +361,9 @@ button.ghost:not(:hover) {
|
|||||||
|
|
||||||
.whitelist__title {
|
.whitelist__title {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
min-height: 34px;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -389,6 +387,16 @@ button.ghost:not(:hover) {
|
|||||||
margin-inline-end: auto;
|
margin-inline-end: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.whitelist__expanded {
|
||||||
|
border-top: 1px solid var(--border-color);
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 80px minmax(0, 1fr);
|
||||||
|
grid-column-gap: 10px;
|
||||||
|
grid-row-gap: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.translator__tag {
|
.translator__tag {
|
||||||
color: #0a84ff;
|
color: #0a84ff;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@@ -399,7 +407,9 @@ button.ghost:not(:hover) {
|
|||||||
vertical-align: text-top;
|
vertical-align: text-top;
|
||||||
}
|
}
|
||||||
|
|
||||||
#siteWhitelistCustomUserAgent {
|
/* Option specific styles */
|
||||||
|
#siteWhitelistCustomUserAgent,
|
||||||
|
input[id^="customUserAgentString-"] {
|
||||||
width: -moz-available;
|
width: -moz-available;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user