ext-omnibox.js (4928B)
1 /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ 2 /* vim: set sts=2 sw=2 et tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 "use strict"; 8 9 ChromeUtils.defineESModuleGetters(this, { 10 ExtensionSearchHandler: 11 "resource://gre/modules/ExtensionSearchHandler.sys.mjs", 12 }); 13 14 this.omnibox = class extends ExtensionAPIPersistent { 15 PERSISTENT_EVENTS = { 16 onInputStarted({ fire }) { 17 let { extension } = this; 18 let listener = () => { 19 fire.sync(); 20 }; 21 extension.on(ExtensionSearchHandler.MSG_INPUT_STARTED, listener); 22 return { 23 unregister() { 24 extension.off(ExtensionSearchHandler.MSG_INPUT_STARTED, listener); 25 }, 26 convert(_fire) { 27 fire = _fire; 28 }, 29 }; 30 }, 31 onInputCancelled({ fire }) { 32 let { extension } = this; 33 let listener = () => { 34 fire.sync(); 35 }; 36 extension.on(ExtensionSearchHandler.MSG_INPUT_CANCELLED, listener); 37 return { 38 unregister() { 39 extension.off(ExtensionSearchHandler.MSG_INPUT_CANCELLED, listener); 40 }, 41 convert(_fire) { 42 fire = _fire; 43 }, 44 }; 45 }, 46 onInputEntered({ fire }) { 47 let { extension } = this; 48 let listener = (eventName, text, disposition) => { 49 extension.tabManager.addActiveTabPermission(); 50 fire.sync(text, disposition); 51 }; 52 extension.on(ExtensionSearchHandler.MSG_INPUT_ENTERED, listener); 53 return { 54 unregister() { 55 extension.off(ExtensionSearchHandler.MSG_INPUT_ENTERED, listener); 56 }, 57 convert(_fire) { 58 fire = _fire; 59 }, 60 }; 61 }, 62 onInputChanged({ fire }) { 63 let { extension } = this; 64 let listener = (eventName, text, id) => { 65 fire.sync(text, id); 66 }; 67 extension.on(ExtensionSearchHandler.MSG_INPUT_CHANGED, listener); 68 return { 69 unregister() { 70 extension.off(ExtensionSearchHandler.MSG_INPUT_CHANGED, listener); 71 }, 72 convert(_fire) { 73 fire = _fire; 74 }, 75 }; 76 }, 77 onDeleteSuggestion({ fire }) { 78 let { extension } = this; 79 let listener = (eventName, text) => { 80 fire.sync(text); 81 }; 82 extension.on(ExtensionSearchHandler.MSG_INPUT_DELETED, listener); 83 return { 84 unregister() { 85 extension.off(ExtensionSearchHandler.MSG_INPUT_DELETED, listener); 86 }, 87 convert(_fire) { 88 fire = _fire; 89 }, 90 }; 91 }, 92 }; 93 94 onManifestEntry() { 95 let { extension } = this; 96 let { manifest } = extension; 97 98 let keyword = manifest.omnibox.keyword; 99 try { 100 // This will throw if the keyword is already registered. 101 ExtensionSearchHandler.registerKeyword(keyword, extension); 102 this.keyword = keyword; 103 } catch (e) { 104 extension.manifestError(e.message); 105 } 106 } 107 108 onShutdown() { 109 ExtensionSearchHandler.unregisterKeyword(this.keyword); 110 } 111 112 getAPI(context) { 113 return { 114 omnibox: { 115 setDefaultSuggestion: suggestion => { 116 try { 117 // This will throw if the keyword failed to register. 118 ExtensionSearchHandler.setDefaultSuggestion( 119 this.keyword, 120 suggestion 121 ); 122 } catch (e) { 123 return Promise.reject(e.message); 124 } 125 }, 126 127 onInputStarted: new EventManager({ 128 context, 129 module: "omnibox", 130 event: "onInputStarted", 131 extensionApi: this, 132 }).api(), 133 134 onInputCancelled: new EventManager({ 135 context, 136 module: "omnibox", 137 event: "onInputCancelled", 138 extensionApi: this, 139 }).api(), 140 141 onInputEntered: new EventManager({ 142 context, 143 module: "omnibox", 144 event: "onInputEntered", 145 extensionApi: this, 146 inputHandling: true, 147 }).api(), 148 149 onInputChanged: new EventManager({ 150 context, 151 module: "omnibox", 152 event: "onInputChanged", 153 extensionApi: this, 154 }).api(), 155 156 onDeleteSuggestion: new EventManager({ 157 context, 158 module: "omnibox", 159 event: "onDeleteSuggestion", 160 extensionApi: this, 161 }).api(), 162 163 // Internal APIs. 164 addSuggestions: (id, suggestions) => { 165 try { 166 ExtensionSearchHandler.addSuggestions( 167 this.keyword, 168 id, 169 suggestions 170 ); 171 } catch (e) { 172 // Silently fail because the extension developer can not know for sure if the user 173 // has already invalidated the callback when asynchronously providing suggestions. 174 } 175 }, 176 }, 177 }; 178 } 179 };