UrlbarProviderUnitConversion.sys.mjs (4490B)
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/. */ 4 5 /** 6 * Provide unit converter. 7 */ 8 9 import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs"; 10 11 import { UnitConverterSimple } from "resource:///modules/UnitConverterSimple.sys.mjs"; 12 import { UnitConverterTemperature } from "resource:///modules/UnitConverterTemperature.sys.mjs"; 13 import { UnitConverterTimezone } from "resource:///modules/UnitConverterTimezone.sys.mjs"; 14 import { 15 UrlbarProvider, 16 UrlbarUtils, 17 } from "moz-src:///browser/components/urlbar/UrlbarUtils.sys.mjs"; 18 19 const lazy = {}; 20 21 ChromeUtils.defineESModuleGetters(lazy, { 22 UrlbarPrefs: "moz-src:///browser/components/urlbar/UrlbarPrefs.sys.mjs", 23 UrlbarResult: "moz-src:///browser/components/urlbar/UrlbarResult.sys.mjs", 24 UrlbarView: "moz-src:///browser/components/urlbar/UrlbarView.sys.mjs", 25 }); 26 27 XPCOMUtils.defineLazyServiceGetter( 28 lazy, 29 "ClipboardHelper", 30 "@mozilla.org/widget/clipboardhelper;1", 31 Ci.nsIClipboardHelper 32 ); 33 34 const CONVERTERS = [ 35 new UnitConverterSimple(), 36 new UnitConverterTemperature(), 37 new UnitConverterTimezone(), 38 ]; 39 40 const DYNAMIC_RESULT_TYPE = "unitConversion"; 41 const VIEW_TEMPLATE = { 42 attributes: { 43 selectable: true, 44 }, 45 children: [ 46 { 47 name: "content", 48 tag: "span", 49 classList: ["urlbarView-no-wrap"], 50 children: [ 51 { 52 name: "icon", 53 tag: "img", 54 classList: ["urlbarView-favicon"], 55 attributes: { 56 src: "chrome://global/skin/icons/edit-copy.svg", 57 }, 58 }, 59 { 60 name: "output", 61 tag: "strong", 62 attributes: { 63 dir: "ltr", 64 }, 65 }, 66 { 67 name: "action", 68 tag: "span", 69 }, 70 ], 71 }, 72 ], 73 }; 74 75 /** 76 * Provide a feature that converts given units. 77 */ 78 export class UrlbarProviderUnitConversion extends UrlbarProvider { 79 constructor() { 80 super(); 81 lazy.UrlbarResult.addDynamicResultType(DYNAMIC_RESULT_TYPE); 82 lazy.UrlbarView.addDynamicViewTemplate(DYNAMIC_RESULT_TYPE, VIEW_TEMPLATE); 83 } 84 85 /** 86 * @returns {Values<typeof UrlbarUtils.PROVIDER_TYPE>} 87 */ 88 get type() { 89 return UrlbarUtils.PROVIDER_TYPE.PROFILE; 90 } 91 92 /** 93 * Whether the provider should be invoked for the given context. If this 94 * method returns false, the providers manager won't start a query with this 95 * provider, to save on resources. 96 * 97 * @param {UrlbarQueryContext} queryContext 98 * The query context object. 99 */ 100 async isActive({ searchString }) { 101 if (!lazy.UrlbarPrefs.get("unitConversion.enabled")) { 102 return false; 103 } 104 105 for (const converter of CONVERTERS) { 106 const result = converter.convert(searchString); 107 if (result) { 108 this._activeResult = result; 109 return true; 110 } 111 } 112 113 this._activeResult = null; 114 return false; 115 } 116 117 /** 118 * This is called only for dynamic result types, when the urlbar view updates 119 * the view of one of the results of the provider. It should return an object 120 * describing the view update. 121 * 122 * @param {UrlbarResult} result The result whose view will be updated. 123 * @returns {object} An object describing the view update. 124 */ 125 getViewUpdate(result) { 126 return { 127 output: { 128 textContent: result.payload.output, 129 }, 130 action: { 131 l10n: { id: "urlbar-result-action-copy-to-clipboard" }, 132 }, 133 }; 134 } 135 136 /** 137 * Starts querying. 138 * 139 * @param {UrlbarQueryContext} queryContext 140 * @param {(provider: UrlbarProvider, result: UrlbarResult) => void} addCallback 141 * Callback invoked by the provider to add a new result. 142 */ 143 startQuery(queryContext, addCallback) { 144 const result = new lazy.UrlbarResult({ 145 type: UrlbarUtils.RESULT_TYPE.DYNAMIC, 146 source: UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL, 147 suggestedIndex: lazy.UrlbarPrefs.get("unitConversion.suggestedIndex"), 148 payload: { 149 dynamicType: DYNAMIC_RESULT_TYPE, 150 output: this._activeResult, 151 input: queryContext.searchString, 152 }, 153 }); 154 addCallback(this, result); 155 } 156 157 onEngagement(queryContext, controller, details) { 158 let { element } = details; 159 const { textContent } = element.querySelector( 160 ".urlbarView-dynamic-unitConversion-output" 161 ); 162 lazy.ClipboardHelper.copyString(textContent); 163 } 164 }