Bug 1953575 - abstract out a reasonable API to copy links, r=places-reviewers,adw

Differential Revision: https://phabricator.services.mozilla.com/D241486
This commit is contained in:
Gijs Kruitbosch
2025-03-20 15:54:31 +00:00
parent fcab2ecd6a
commit 28515892e4
3 changed files with 56 additions and 42 deletions

View File

@@ -1520,48 +1520,9 @@ export var PlacesUIUtils = {
let window = this.triggerNode.ownerGlobal;
switch (command) {
case "placesCmd_copy": {
// This is a little hacky, but there is a lot of code in Places that handles
// clipboard stuff, so it's easier to reuse.
let node = {};
node.type = 0;
node.title = this.triggerNode.label;
node.uri = this.triggerNode.link;
// Copied from _populateClipboard in controller.js
// This order is _important_! It controls how this and other applications
// select data to be inserted based on type.
let contents = [
{ type: lazy.PlacesUtils.TYPE_X_MOZ_URL, entries: [] },
{ type: lazy.PlacesUtils.TYPE_HTML, entries: [] },
{ type: lazy.PlacesUtils.TYPE_PLAINTEXT, entries: [] },
];
contents.forEach(function (content) {
content.entries.push(lazy.PlacesUtils.wrapNode(node, content.type));
});
let xferable = Cc[
"@mozilla.org/widget/transferable;1"
].createInstance(Ci.nsITransferable);
xferable.init(null);
function addData(type, data) {
xferable.addDataFlavor(type);
xferable.setTransferData(
type,
lazy.PlacesUtils.toISupportsString(data)
);
}
contents.forEach(function (content) {
addData(content.type, content.entries.join(lazy.PlacesUtils.endl));
});
Services.clipboard.setData(
xferable,
null,
Ci.nsIClipboard.kGlobalClipboard
lazy.BrowserUtils.copyLink(
this.triggerNode.link,
this.triggerNode.label
);
break;
}

View File

@@ -972,6 +972,40 @@ export var PlacesUtils = {
return url.host.split("").reverse().join("") + ".";
},
/**
* Copy a single places result node, recursively if applicable.
*
* @param {Object} node
* The node to copy. If not a real places node but a single
* title/URL combination, you must set `type` to 0 (aka RESULT_TYPE_URI),
* and provide a `title` and `uri` property which should both be strings.
*/
copyNode(node) {
// This order is _important_! It controls how this and other applications
// select data to be inserted based on type.
let contentTypes = [
this.TYPE_X_MOZ_URL,
this.TYPE_HTML,
this.TYPE_PLAINTEXT,
];
let xferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(
Ci.nsITransferable
);
xferable.init(null);
for (let contentType of contentTypes) {
xferable.addDataFlavor(contentType);
let data = this.wrapNode(node, contentType);
xferable.setTransferData(contentType, this.toISupportsString(data));
}
Services.clipboard.setData(
xferable,
null,
Ci.nsIClipboard.kGlobalClipboard
);
},
/**
* String-wraps a result node according to the rules of the specified
* content type for copy or move operations.

View File

@@ -9,6 +9,7 @@ import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
ReaderMode: "moz-src:///toolkit/components/reader/ReaderMode.sys.mjs",
Region: "resource://gre/modules/Region.sys.mjs",
});
@@ -144,6 +145,24 @@ export var BrowserUtils = {
);
},
/**
* Copy a link with a text label to the clipboard.
*
* @param {string} url
* The URL we're wanting to copy to the clipboard.
* @param {string} title
* The label/title of the URL
*/
copyLink(url, title) {
// This is a little hacky, but there is a lot of code in Places that handles
// clipboard stuff, so it's easier to reuse.
let node = {};
node.type = 0;
node.title = title;
node.uri = url;
lazy.PlacesUtils.copyNode(node);
},
/**
* Returns true if |mimeType| is text-based, or false otherwise.
*