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;
|
||||
}
|
||||
|
||||
.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 **/
|
||||
.main-content {
|
||||
width: min(90%, 1024px);
|
||||
|
||||
@@ -27,7 +27,25 @@
|
||||
|
||||
<body id="body">
|
||||
<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>
|
||||
<div hidden id="error" class="page-subsection info-box">
|
||||
<div class="info-box-label" data-l10n-id="about-logging-error"></div>
|
||||
|
||||
@@ -295,6 +295,44 @@ class ParseError extends Error {
|
||||
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() {
|
||||
let options = new URL(document.location.href).searchParams;
|
||||
|
||||
@@ -413,6 +451,16 @@ function parseURL() {
|
||||
$("#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;
|
||||
function init() {
|
||||
if (gInited) {
|
||||
@@ -437,6 +485,22 @@ function init() {
|
||||
let toggleLoggingButton = $("#toggle-logging-button");
|
||||
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 => {
|
||||
radio.onchange = e => {
|
||||
updateLoggingOutputType(e.target.value);
|
||||
|
||||
@@ -99,7 +99,7 @@ add_task(async function testElementsDisabled() {
|
||||
);
|
||||
Assert.ok(
|
||||
$("#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."
|
||||
);
|
||||
});
|
||||
@@ -172,7 +172,7 @@ add_task(async function testURLParameters() {
|
||||
var inInputSorted = $("#log-modules").value.split(",").sort().join(",");
|
||||
var presetSorted = content
|
||||
.presets()
|
||||
[presetInURL].modules.split(",")
|
||||
[presetInURL].modules.split(",")
|
||||
.sort()
|
||||
.join(",");
|
||||
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-start-logging = Start 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-some-elements-disabled = Logging configured via URL, some configuration options are unavailable
|
||||
about-logging-info = Info:
|
||||
|
||||
@@ -50,3 +50,4 @@ toolkit.jar:
|
||||
|
||||
# used in about:logging on Android
|
||||
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