Bug 1966129 - Teach about:logging to copy the current settings to the clipboard as a preset URL. r=julienw,desktop-theme-reviewers,emilio
Differential Revision: https://phabricator.services.mozilla.com/D249082
This commit is contained in:
committed by
padenot@mozilla.com
parent
ab0bcf2219
commit
c0d83d2613
@@ -10,6 +10,32 @@
|
|||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.about-logging-title-bar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#copy-as-url::part(button) {
|
||||||
|
background-image: url("chrome://global/skin/icons/edit-copy.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
#toast-copied {
|
||||||
|
visibility: hidden;
|
||||||
|
background-color: var(--background-color-success);
|
||||||
|
color: var(--text-color);
|
||||||
|
text-align: center;
|
||||||
|
border-radius: var(--border-radius-small);
|
||||||
|
padding: var(--space-medium);
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.5s, visibility 0.5s;
|
||||||
|
margin-left: auto;
|
||||||
|
&.show {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Content area **/
|
/** Content area **/
|
||||||
.main-content {
|
.main-content {
|
||||||
width: min(90%, 1024px);
|
width: min(90%, 1024px);
|
||||||
|
|||||||
@@ -27,7 +27,25 @@
|
|||||||
|
|
||||||
<body id="body">
|
<body id="body">
|
||||||
<main class="main-content">
|
<main class="main-content">
|
||||||
<h1 id="title" data-l10n-id="about-logging-page-title"></h1>
|
<div class="about-logging-title-bar">
|
||||||
|
<h1 id="title" data-l10n-id="about-logging-page-title"></h1>
|
||||||
|
<div id="toast-copied" data-l10n-id="about-logging-url-copied"></div>
|
||||||
|
<moz-button
|
||||||
|
iconsrc="chrome://global/skin/icons/more.svg"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-haspopup="menu"
|
||||||
|
type="default"
|
||||||
|
size="default"
|
||||||
|
id="open-menu-button"
|
||||||
|
></moz-button>
|
||||||
|
<panel-list>
|
||||||
|
<panel-item
|
||||||
|
id="copy-as-url"
|
||||||
|
data-l10n-id="about-logging-copy-as-url"
|
||||||
|
action="copy"
|
||||||
|
></panel-item>
|
||||||
|
</panel-list>
|
||||||
|
</div>
|
||||||
<section>
|
<section>
|
||||||
<div hidden id="error" class="page-subsection info-box">
|
<div hidden id="error" class="page-subsection info-box">
|
||||||
<div class="info-box-label" data-l10n-id="about-logging-error"></div>
|
<div class="info-box-label" data-l10n-id="about-logging-error"></div>
|
||||||
|
|||||||
@@ -295,6 +295,44 @@ class ParseError extends Error {
|
|||||||
value;
|
value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns a URL from the current state of the page
|
||||||
|
function serializeState() {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
|
||||||
|
const logModules = $("#log-modules")?.value;
|
||||||
|
const dropdown = $("#logging-preset-dropdown")?.value;
|
||||||
|
const outputType = $("[name=logging-output]:checked")?.value;
|
||||||
|
const threads = $("#threads")?.value;
|
||||||
|
const profilerPreset = $("#profiler-preset-dropdown")?.value;
|
||||||
|
const profilerStacks = $("#with-profiler-stacks-checkbox")?.checked;
|
||||||
|
|
||||||
|
if (logModules && logModules.trim()) {
|
||||||
|
params.set("modules", logModules.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dropdown && dropdown !== "custom") {
|
||||||
|
params.set("preset", dropdown);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outputType === "profiler" || outputType === "file") {
|
||||||
|
params.set("output", outputType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (threads && threads.trim()) {
|
||||||
|
params.set("threads", threads.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (profilerPreset && profilerPreset !== "none") {
|
||||||
|
params.set("profiler-preset", profilerPreset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (profilerStacks) {
|
||||||
|
params.set("profilerstacks", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
return `about:logging?${params.toString()}`;
|
||||||
|
}
|
||||||
|
|
||||||
function parseURL() {
|
function parseURL() {
|
||||||
let options = new URL(document.location.href).searchParams;
|
let options = new URL(document.location.href).searchParams;
|
||||||
|
|
||||||
@@ -413,6 +451,16 @@ function parseURL() {
|
|||||||
$("#some-elements-unavailable").hidden = !someElementsDisabled;
|
$("#some-elements-unavailable").hidden = !someElementsDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function copyAsURL() {
|
||||||
|
let url = serializeState();
|
||||||
|
await navigator.clipboard.writeText(url);
|
||||||
|
const toast = $("#toast-copied");
|
||||||
|
toast.classList.add("show");
|
||||||
|
setTimeout(() => {
|
||||||
|
toast.classList.remove("show");
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
let gInited = false;
|
let gInited = false;
|
||||||
function init() {
|
function init() {
|
||||||
if (gInited) {
|
if (gInited) {
|
||||||
@@ -437,6 +485,22 @@ function init() {
|
|||||||
let toggleLoggingButton = $("#toggle-logging-button");
|
let toggleLoggingButton = $("#toggle-logging-button");
|
||||||
toggleLoggingButton.addEventListener("click", startStopLogging);
|
toggleLoggingButton.addEventListener("click", startStopLogging);
|
||||||
|
|
||||||
|
$("#copy-as-url").onclick = copyAsURL;
|
||||||
|
|
||||||
|
function openMenu(event) {
|
||||||
|
if (
|
||||||
|
event.type == "mousedown" ||
|
||||||
|
event.inputSource == MouseEvent.MOZ_SOURCE_KEYBOARD ||
|
||||||
|
!event.detail
|
||||||
|
) {
|
||||||
|
document.querySelector("panel-list").toggle(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let menuButton = $("#open-menu-button");
|
||||||
|
menuButton.addEventListener("mousedown", openMenu);
|
||||||
|
menuButton.addEventListener("click", openMenu);
|
||||||
|
|
||||||
$$("input[type=radio]").forEach(radio => {
|
$$("input[type=radio]").forEach(radio => {
|
||||||
radio.onchange = e => {
|
radio.onchange = e => {
|
||||||
updateLoggingOutputType(e.target.value);
|
updateLoggingOutputType(e.target.value);
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ add_task(async function testElementsDisabled() {
|
|||||||
);
|
);
|
||||||
Assert.ok(
|
Assert.ok(
|
||||||
$("#radio-logging-profiler").disabled &&
|
$("#radio-logging-profiler").disabled &&
|
||||||
$("#radio-logging-file").disabled,
|
$("#radio-logging-file").disabled,
|
||||||
"If the ouptut type is configured via URL param, the radio buttons should be disabled."
|
"If the ouptut type is configured via URL param, the radio buttons should be disabled."
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -172,7 +172,7 @@ add_task(async function testURLParameters() {
|
|||||||
var inInputSorted = $("#log-modules").value.split(",").sort().join(",");
|
var inInputSorted = $("#log-modules").value.split(",").sort().join(",");
|
||||||
var presetSorted = content
|
var presetSorted = content
|
||||||
.presets()
|
.presets()
|
||||||
[presetInURL].modules.split(",")
|
[presetInURL].modules.split(",")
|
||||||
.sort()
|
.sort()
|
||||||
.join(",");
|
.join(",");
|
||||||
Assert.equal(
|
Assert.equal(
|
||||||
@@ -610,3 +610,51 @@ add_task(async function testAndroidUI() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
add_task(async function testCopyToClipboard() {
|
||||||
|
await BrowserTestUtils.withNewTab(
|
||||||
|
PAGE,
|
||||||
|
async browser => {
|
||||||
|
const document = browser.contentDocument;
|
||||||
|
const window = browser.contentWindow;
|
||||||
|
// Open the menu, click on the item to copy to the clipboard
|
||||||
|
var menuButton = document.querySelector("#open-menu-button");
|
||||||
|
EventUtils.synthesizeMouseAtCenter(menuButton, {}, window);
|
||||||
|
var copyAction = await getElementFromDocumentByText(
|
||||||
|
document,
|
||||||
|
"Copy current settings as URL"
|
||||||
|
);
|
||||||
|
EventUtils.synthesizeMouseAtCenter(copyAction, {}, window);
|
||||||
|
// In theory, we could wait for the toast, and check that the clipboard
|
||||||
|
// has been filled with reasonnable data. In practice the CI machines
|
||||||
|
// are too slow and miss the toast, so we're repeatedly checking the
|
||||||
|
// content of the clipboard instead.
|
||||||
|
var copiedString = await TestUtils.waitForCondition(() => {
|
||||||
|
const xferable = Cc[
|
||||||
|
"@mozilla.org/widget/transferable;1"
|
||||||
|
].createInstance(Ci.nsITransferable);
|
||||||
|
xferable.init(null);
|
||||||
|
xferable.addDataFlavor("text/plain");
|
||||||
|
Services.clipboard.getData(xferable, Ci.nsIClipboard.kGlobalClipboard);
|
||||||
|
let data = {};
|
||||||
|
let type = {};
|
||||||
|
try {
|
||||||
|
xferable.getAnyTransferData(type, data);
|
||||||
|
data = data.value.QueryInterface(Ci.nsISupportsString).data;
|
||||||
|
} catch {
|
||||||
|
data = "";
|
||||||
|
}
|
||||||
|
if (data.startsWith("about:logging")) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
Assert.stringMatches(
|
||||||
|
copiedString,
|
||||||
|
/^about:logging\?/,
|
||||||
|
`about:logging URL copied successfully ${copiedString}`
|
||||||
|
);
|
||||||
|
},
|
||||||
|
"Waiting to have clipboard data"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ about-logging-set-log-file = Set Log File
|
|||||||
about-logging-set-log-modules = Set Log Modules
|
about-logging-set-log-modules = Set Log Modules
|
||||||
about-logging-start-logging = Start Logging
|
about-logging-start-logging = Start Logging
|
||||||
about-logging-stop-logging = Stop Logging
|
about-logging-stop-logging = Stop Logging
|
||||||
|
about-logging-copy-as-url = Copy current settings as URL
|
||||||
|
about-logging-url-copied = Logging settings copied to the clipboard as a preset URL
|
||||||
about-logging-buttons-disabled = Logging configured via environment variables, dynamic configuration unavailable.
|
about-logging-buttons-disabled = Logging configured via environment variables, dynamic configuration unavailable.
|
||||||
about-logging-some-elements-disabled = Logging configured via URL, some configuration options are unavailable
|
about-logging-some-elements-disabled = Logging configured via URL, some configuration options are unavailable
|
||||||
about-logging-info = Info:
|
about-logging-info = Info:
|
||||||
|
|||||||
@@ -50,3 +50,4 @@ toolkit.jar:
|
|||||||
|
|
||||||
# used in about:logging on Android
|
# used in about:logging on Android
|
||||||
skin/classic/global/icons/open-in-new.svg (../../shared/icons/open-in-new.svg)
|
skin/classic/global/icons/open-in-new.svg (../../shared/icons/open-in-new.svg)
|
||||||
|
skin/classic/global/icons/edit-copy.svg (../../shared/icons/edit-copy.svg)
|
||||||
|
|||||||
Reference in New Issue
Block a user