fune/browser/components/extensions/ext-find.js
2018-01-30 16:55:54 -07:00

113 lines
4.4 KiB
JavaScript

/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
/* global tabTracker */
"use strict";
/**
* runFindOperation
* Utility for `find` and `highlightResults`.
*
* @param {object} params - params to pass to message sender.
* @param {string} message - identifying component of message name.
*
* @returns {Promise} a promise that will be resolved or rejected based on the
* data received by the message listener.
*/
function runFindOperation(params, message) {
let {tabId} = params;
let tab = tabId ? tabTracker.getTab(tabId) : tabTracker.activeTab;
let browser = tab.linkedBrowser;
let mm = browser.messageManager;
tabId = tabId || tabTracker.getId(tab);
// We disallow find in about: urls.
if (tab.linkedBrowser.contentPrincipal.isSystemPrincipal ||
(["about", "chrome", "resource"].includes(tab.linkedBrowser.currentURI.scheme) &&
tab.linkedBrowser.currentURI.spec != "about:blank")) {
return Promise.reject({message: `Unable to search: ${tabId}`});
}
return new Promise((resolve, reject) => {
mm.addMessageListener(`ext-Finder:${message}Finished`, function messageListener(message) {
mm.removeMessageListener(`ext-Finder:${message}Finished`, messageListener);
switch (message.data) {
case "Success":
resolve();
break;
case "OutOfRange":
reject({message: "index supplied was out of range"});
break;
case "NoResults":
reject({message: "no search results to highlight"});
break;
}
resolve(message.data);
});
mm.sendAsyncMessage(`ext-Finder:${message}`, params);
});
}
this.find = class extends ExtensionAPI {
getAPI(context) {
return {
find: {
/**
* browser.find.find
* Searches document and its frames for a given queryphrase and stores all found
* Range objects in an array accessible by other browser.find methods.
*
* @param {string} queryphrase - The string to search for.
* @param {object} params optional - may contain any of the following properties,
* all of which are optional:
* {number} tabId - Tab to query. Defaults to the active tab.
* {boolean} caseSensitive - Highlight only ranges with case sensitive match.
* {boolean} entireWord - Highlight only ranges that match entire word.
* {boolean} includeRangeData - Whether to return range data.
* {boolean} includeRectData - Whether to return rectangle data.
*
* @returns {object} data received by the message listener that includes:
* {number} count - number of results found.
* {array} rangeData (if opted) - serialized representation of ranges found.
* {array} rectData (if opted) - rect data of ranges found.
*/
find(queryphrase, params) {
params = params || {};
params.queryphrase = queryphrase;
return runFindOperation(params, "CollectResults");
},
/**
* browser.find.highlightResults
* Highlights range(s) found in previous browser.find.find.
*
* @param {object} params optional - may contain any of the following properties,
* all of which are optional:
* {number} rangeIndex - Found range to be highlighted. Default highlights all ranges.
* {number} tabId - Tab to highlight. Defaults to the active tab.
* {boolean} noScroll - Don't scroll to highlighted item.
*
* @returns {string} - data received by the message listener that may be:
* "Success" - Highlighting succeeded.
* "OutOfRange" - The index supplied was out of range.
* "NoResults" - There were no search results to highlight.
*/
highlightResults(params) {
params = params || {};
return runFindOperation(params, "HighlightResults");
},
/**
* browser.find.removeHighlighting
* Removes all hightlighting from previous search.
*
* @param {number} tabId optional
* Tab to clear highlighting in. Defaults to the active tab.
*/
removeHighlighting(tabId) {
let tab = tabId ? tabTracker.getTab(tabId) : tabTracker.activeTab;
tab.linkedBrowser.messageManager.sendAsyncMessage("ext-Finder:clearHighlighting");
},
},
};
}
};