From 95b1f74a30b793ada999b90f2d6203c9554950f7 Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Fri, 5 Oct 2012 13:59:13 -0700 Subject: [PATCH] Add support for firefox integrated find. --- .../firefox/components/PdfStreamConverter.js | 81 ++++++++++++++++++- web/viewer.html | 2 - web/viewer.js | 38 ++++++--- 3 files changed, 105 insertions(+), 16 deletions(-) diff --git a/extensions/firefox/components/PdfStreamConverter.js b/extensions/firefox/components/PdfStreamConverter.js index 7b3f75cc2..b96f787f6 100644 --- a/extensions/firefox/components/PdfStreamConverter.js +++ b/extensions/firefox/components/PdfStreamConverter.js @@ -55,6 +55,14 @@ if (appInfo.ID === FIREFOX_ID) { isInPrivateBrowsing = function() { return false; }; } +function getChromeWindow(domWindow) { + var containingBrowser = domWindow.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell) + .chromeEventHandler; + return containingBrowser.ownerDocument.defaultView; +} + function getBoolPref(pref, def) { try { return Services.prefs.getBoolPref(pref); @@ -334,8 +342,8 @@ ChromeActions.prototype = { pdfBugEnabled: function() { return getBoolPref(PREF_PREFIX + '.pdfBugEnabled', false); }, - findEnabled: function() { - return getBoolPref(PREF_PREFIX + '.findEnabled', false); + supportsIntegratedFind: function() { + return 'updateControlState' in getChromeWindow(this.domWindow).gFindBar; }, fallback: function(url, sendResponse) { var self = this; @@ -389,6 +397,20 @@ ChromeActions.prototype = { if (!sentResponse) sendResponse(false); }); + }, + updateFindControlState: function(data) { + if (!this.supportsIntegratedFind()) + return; + // Verify what we're sending to the findbar. + var result = data.result; + var findPrevious = data.findPrevious; + var findPreviousType = typeof findPrevious; + if ((typeof result !== 'number' || result < 0 || result > 3) || + (findPreviousType !== 'undefined' && findPreviousType !== 'boolean')) { + return; + } + getChromeWindow(this.domWindow).gFindBar + .updateControlState(result, findPrevious); } }; @@ -429,6 +451,56 @@ RequestListener.prototype.receive = function(event) { } }; +// Forwards events from the eventElement to the contentWindow only if the +// content window matches the currently selected browser window. +function FindEventManager(eventElement, contentWindow, chromeWindow) { + this.types = ['find', + 'findagain', + 'findhighlightallchange', + 'findcasesensitivitychange']; + this.chromeWindow = chromeWindow; + this.contentWindow = contentWindow; + this.eventElement = eventElement; +} + +FindEventManager.prototype.bind = function() { + this.contentWindow.addEventListener('unload', function unload(e) { + this.unbind(); + this.contentWindow.removeEventListener(e.type, unload); + }.bind(this)); + + for (var i = 0, ii = this.types.length; i < ii; ++i) { + var type = this.types[i]; + this.eventElement.addEventListener(type, this, true); + } +}; + +FindEventManager.prototype.handleEvent = function(e) { + var chromeWindow = this.chromeWindow; + var contentWindow = this.contentWindow; + // Only forward the events if they are for our dom window. + if (chromeWindow.gBrowser.selectedBrowser.contentWindow === contentWindow) { + var detail = e.detail; + detail.__exposedProps__ = { + query: 'r', + caseSensitive: 'r', + highlightAll: 'r', + findPrevious: 'r' + }; + var forward = contentWindow.document.createEvent('CustomEvent'); + forward.initCustomEvent(e.type, true, true, detail); + contentWindow.dispatchEvent(forward); + e.preventDefault(); + } +}; + +FindEventManager.prototype.unbind = function() { + for (var i = 0, ii = this.types.length; i < ii; ++i) { + var type = this.types[i]; + this.eventElement.removeEventListener(type, this, true); + } +}; + function PdfStreamConverter() { } @@ -541,6 +613,11 @@ PdfStreamConverter.prototype = { domWindow.addEventListener(PDFJS_EVENT_ID, function(event) { requestListener.receive(event); }, false, true); + var chromeWindow = getChromeWindow(domWindow); + var findEventManager = new FindEventManager(chromeWindow.gFindBar, + domWindow, + chromeWindow); + findEventManager.bind(); } listener.onStopRequest.apply(listener, arguments); } diff --git a/web/viewer.html b/web/viewer.html index 3cdb84378..985e59311 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -117,11 +117,9 @@ limitations under the License. Toggle Sidebar
- -