1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 } from "resource:///modules/UrlbarUtils.sys.mjs";
12 ChromeUtils.defineESModuleGetters(lazy, {
13 UrlbarResult: "resource:///modules/UrlbarResult.sys.mjs",
14 UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs",
15 UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.sys.mjs",
18 const RESULT_MENU_COMMANDS = {
21 const CLIPBOARD_IMPRESSION_LIMIT = 2;
24 * A provider that returns a suggested url to the user based
25 * on a valid URL stored in the clipboard.
27 class ProviderClipboard extends UrlbarProvider {
28 #previousClipboard = {
30 impressionsLeft: CLIPBOARD_IMPRESSION_LIMIT,
38 return "UrlbarProviderClipboard";
42 return UrlbarUtils.PROVIDER_TYPE.PROFILE;
45 setPreviousClipboardValue(newValue) {
46 this.#previousClipboard.value = newValue;
49 isActive(queryContext, controller) {
50 // Return clipboard results only for empty searches.
52 !lazy.UrlbarPrefs.get("clipboard.featureGate") ||
53 !lazy.UrlbarPrefs.get("suggest.clipboard") ||
54 queryContext.searchString ||
55 queryContext.searchMode
61 !TelemetryStopwatch.running(
62 "FX_URLBAR_PROVIDER_CLIPBOARD_READ_TIME_MS",
66 TelemetryStopwatch.start(
67 "FX_URLBAR_PROVIDER_CLIPBOARD_READ_TIME_MS",
71 let textFromClipboard = controller.browserWindow.readFromClipboard();
72 TelemetryStopwatch.finish("FX_URLBAR_PROVIDER_CLIPBOARD_READ_TIME_MS", obj);
74 // Check for spaces in clipboard text to avoid suggesting
75 // clipboard content including both a url and the following text.
78 textFromClipboard.length > 2048 ||
79 lazy.UrlbarTokenizer.REGEXP_SPACES.test(textFromClipboard)
84 controller.input.sanitizeTextFromClipboard(textFromClipboard);
85 const validUrl = this.#validUrl(textFromClipboard);
90 if (this.#previousClipboard.value === validUrl) {
91 if (this.#previousClipboard.impressionsLeft <= 0) {
95 this.#previousClipboard = {
97 impressionsLeft: CLIPBOARD_IMPRESSION_LIMIT,
104 #validUrl(clipboardVal) {
107 givenUrl = new URL(clipboardVal);
108 if (givenUrl.protocol == "http:" || givenUrl.protocol == "https:") {
109 return givenUrl.href;
118 // Zero-prefix suggestions have the same priority as top sites.
122 async startQuery(queryContext, addCallback) {
123 // If the query was started, isActive should have cached a url already.
124 let result = new lazy.UrlbarResult(
125 UrlbarUtils.RESULT_TYPE.URL,
126 UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
127 ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
129 UrlbarUtils.prepareUrlForDisplay(this.#previousClipboard.value, {
132 UrlbarUtils.HIGHLIGHT.NONE,
134 url: [this.#previousClipboard.value, UrlbarUtils.HIGHLIGHT.NONE],
135 icon: "chrome://global/skin/icons/clipboard.svg",
138 id: "urlbar-result-menu-dismiss-firefox-suggest",
143 addCallback(this, result);
146 onEngagement(queryContext, controller, details) {
147 this.#previousClipboard.impressionsLeft = 0; // User has picked the suggested clipboard result
149 this.#handlePossibleCommand(
157 this.#previousClipboard.impressionsLeft--;
160 #handlePossibleCommand(view, result, selType) {
162 case RESULT_MENU_COMMANDS.DISMISS:
163 view.controller.removeResult(result);
164 this.#previousClipboard.impressionsLeft = 0;
170 const UrlbarProviderClipboard = new ProviderClipboard();
171 export { UrlbarProviderClipboard, CLIPBOARD_IMPRESSION_LIMIT };