(function(exports) { const DEFAULT_PREVIEW_URL = "data:text/html,No suggestions" const DEFAULT_MAX_SUGGESTIONS = 5 const MIN_MAX_SUGGS = 1 const MAX_MAX_SUGGS = 42 const NULL_QUERY = { suggestionList: [], finished: true, hasResults: false } CommandManager.__defineGetter__("maxSuggestions", function CM_getMaxSuggestions() { return DEFAULT_MAX_SUGGESTIONS }) CommandManager.__defineSetter__("maxSuggestions", function CM_setMaxSuggestions(value) { var num = Math.max(MIN_MAX_SUGGS, Math.min(value | 0, MAX_MAX_SUGGS)); }) function CommandManager(cmdSource, parser, suggsNode, previewPaneNode) { this.__cmdSource = cmdSource; this.__hilitedIndex = 0; this.__lastInput = ""; this.__lastSuggestion = null; this.__queuedExecute = null; this.__lastAsyncSuggestionCb = Boolean; this.__nlParser = parser; this.__activeQuery = NULL_QUERY; this.__domNodes = { suggs: suggsNode, preview: previewPaneNode, }; this._loadCommands(); this.setPreviewState("no-suggestions"); suggsNode.addEventListener("click", this, false); suggsNode.addEventListener("DOMMouseScroll", this, false); } CommandManager.prototype = { handleEvent: function CM_handleEvent(event) { switch (event.type) { case "click": { if (event.button === 2) return; let {target} = event; do { if (!("hasAttribute" in target)) return; if (target.hasAttribute("index")) break; } while ((target = target.parentNode)); let index = +target.getAttribute("index"); if (this.__hilitedIndex === index) return; this.__hilitedIndex = index; this.__lastAsyncSuggestionCb(); } break; case "DOMMouseScroll": { this[event.detail < 0 ? "moveIndicationUp" : "moveIndicationDown"](); this.__lastAsyncSuggestionCb(); } break; default: return; } event.preventDefault(); event.stopPropagation(); }, setPreviewState: function CM_setPreviewState(state) { var {suggs, preview} = this.__domNodes; switch (state) { case "computing-suggestions": case "with-suggestions": { suggs.style.display = "block"; preview.style.display = "block"; break; } case "no-suggestions": { suggs.style.display = "none"; preview.style.display = "none"; preview.setAttribute('src', DEFAULT_PREVIEW_URL) break; } default: throw new Error("Unknown state: " + state); } }, refresh: function CM_refresh() { this.__cmdSource.refresh() this.reset() }, moveIndicationUp: function CM_moveIndicationUp(context) { if (--this.__hilitedIndex < 0) this.__hilitedIndex = this.__activeQuery.suggestionList.length - 1; if (context) this._renderAll(context); }, moveIndicationDown: function CM_moveIndicationDown(context) { if (++this.__hilitedIndex >= this.__activeQuery.suggestionList.length) this.__hilitedIndex = 0; if (context) this._renderAll(context); }, _loadCommands: function CM__loadCommands() { if (this.__nlParser) this.__nlParser.setCommandList(this.__cmdSource.getAllCommands()); }, _renderSuggestions: function CM__renderSuggestions() { var {escapeHtml} = Utils, content = ""; var {__activeQuery: {suggestionList}, __hilitedIndex: hindex} = this; for (let i = 0, l = suggestionList.length; i < l; ++i) { let {displayHtml, icon} = suggestionList[i]; content += ( '
' + (icon ? '' : "") + "
" + displayHtml + "
"); } this.__domNodes.suggs.innerHTML = content; }, _renderPreview: function CM__renderPreview(context) { var activeSugg = this.hilitedSuggestion; if (!activeSugg || activeSugg === this.__lastSuggestion) return; var self = this; this.__lastSuggestion = activeSugg; //console.log('renderPreview', activeSugg.previewUrl, activeSugg) //console.log(activeSugg._verb.arguments[0].id) //console.log(activeSugg.args.object[0].text) //console.log('renderPreview', activeSugg.previewUrl) //console.log(activeSugg) var iframe = this.__domNodes.preview, url = activeSugg.previewUrl //console.log('renderPreview', url) if (iframe.src == url) { iframe.contentWindow.postMessage({input: activeSugg.input}, '*') } else { iframe.src = url } }, _renderAll: function CM__renderAll(context) { this._renderSuggestions(); this._renderPreview(context); }, reset: function CM_reset() { var query = this.__activeQuery; if (!query.finished) query.cancel(); this.__activeQuery = NULL_QUERY; this.__hilitedIndex = 0; this.__lastInput = ""; this.__lastSuggestion = null; this.__queuedExecute = null; }, updateInput: function CM_updateInput(input, context, asyncSuggestionCb) { this.reset(); this.__lastInput = input; var query = this.__activeQuery = this.__nlParser.newQuery(input, context, this.maxSuggestions, true); query.onResults = asyncSuggestionCb || this.__lastAsyncSuggestionCb; if (asyncSuggestionCb) this.__lastAsyncSuggestionCb = asyncSuggestionCb; query.run(); }, onSuggestionsUpdated: function CM_onSuggestionsUpdated(input, context) { if (input !== this.__lastInput) return var {hilitedSuggestion} = this; if (this.__queuedExecute && hilitedSuggestion) { this.__queuedExecute(hilitedSuggestion); this.__queuedExecute = null; } this.setPreviewState(this.__activeQuery.finished ? (hilitedSuggestion ? "with-suggestions" : "no-suggestions") : "computing-suggestions"); this._renderAll(context); }, execute: function CM_execute(context) { function doExecute(activeSugg) { try { this.__nlParser.strengthenMemory(activeSugg); activeSugg.execute(context); } catch (e) { } } var {hilitedSuggestion} = this; if (hilitedSuggestion) doExecute.call(this, hilitedSuggestion); else this.__queuedExecute = doExecute; }, getSuggestionListNoInput: function CM_getSuggListNoInput(context, asyncSuggestionCb) { let noInputQuery = this.__nlParser.newQuery( "", context, 4 * CommandManager.maxSuggestions); noInputQuery.onResults = function onResultsNoInput() { asyncSuggestionCb(noInputQuery.suggestionList); }; }, makeCommandSuggester: function CM_makeCommandSuggester() { var self = this; return function getAvailableCommands(context, popupCb) { self.getSuggestionListNoInput(context, popupCb) } }, remember: function CM_remember() { var {hilitedSuggestion} = this; if (hilitedSuggestion) this.__nlParser.strengthenMemory(hilitedSuggestion); }, get parser() this.__nlParser, get lastInput() this.__lastInput, get maxSuggestions() CommandManager.maxSuggestions, get hasSuggestions() this.__activeQuery.hasResults, get suggestions() this.__activeQuery.suggestionList, get hilitedSuggestion() this.__activeQuery.suggestionList[this.__hilitedIndex], get hilitedIndex() this.__hilitedIndex, set hilitedIndex(i) this.__hilitedIndex = i, } exports.CommandManager = CommandManager; })(window); (function(exports) { function CommandAggregator(arrayOfCommands) { var self = this; var commands = {} var commandNames = []; var commandsByName = {__proto__: null}; var commandsByDomain = {__proto__: null}; self.refresh = function FA_refresh() { commands = {} commandNames = [] commandsByName = {__proto__: null} arrayOfCommands.forEach(self.addCommand) } self.__defineGetter__("commandNames", function FA_cmdNames() commandNames) self.__defineGetter__("commandsByName", function FA_cmdsByName() commandsByName) self.__defineGetter__("commandsByDomain", function FA_cmdsByDomain() commandsByDomain) self.getAllCommands = function FA_getAllCommands() { return commands } self.getCommand = function FA_getCommand(id) { return commands[id] || commandsByName[id] || null } self.addCommand = function FA_addCommand(cmd) { if (cmd.name && !cmd.names) cmd.names = [cmd.name] cmd.id = cmd.url commandNames.push({ name: cmd.name, url: cmd.url, icon: cmd.icon, }) commands[cmd.url] = commandsByName[cmd.name] = cmd } if (arrayOfCommands.length) self.refresh() } exports.CommandAggregator = CommandAggregator; })(window);