From a7181279472c2437a9a78d57882b8c5fdbcb3ecc Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Wed, 23 Nov 2016 16:38:30 -0500 Subject: [PATCH] Hatch declarative message extension style Avoid the requirement to hard-code the allowed externally_connectable hosts by letting the extension ask for permissions instead. Signed-off-by: Bill Erickson --- INSTALL.adoc | 14 ----- extension/app/content.js | 72 ++++++++++++++++++++++++ extension/app/{main.js => extension.js} | 97 ++++++++++++++++++++++----------- extension/app/manifest.json | 17 ++++-- 4 files changed, 148 insertions(+), 52 deletions(-) create mode 100644 extension/app/content.js rename extension/app/{main.js => extension.js} (57%) diff --git a/INSTALL.adoc b/INSTALL.adoc index 6aa36a1cb6..d971cc03ee 100644 --- a/INSTALL.adoc +++ b/INSTALL.adoc @@ -77,20 +77,6 @@ $ ./hatch.sh test === Setup Chrome Extension === -==== Tweak Extension Values ==== - -Edit extension/app/manifest.json and change the "evergreen.example.org" value -found here to the hostname of your Evergreen server. - -[source,js] -------------------------------------------------------------------------- -... -"externally_connectable": { - "matches": ["*://evergreen.example.org/*"] -} -... -------------------------------------------------------------------------- - NOTE: At time of writing, the Evergreen server used must have the patches included in the http://git.evergreen-ils.org/?p=working/Evergreen.git;a=shortlog;h=refs/heads/user/berick/lp1640255-hatch-native-messaging[Hatch Native Messaging working branch]. diff --git a/extension/app/content.js b/extension/app/content.js new file mode 100644 index 0000000000..07ce8b7165 --- /dev/null +++ b/extension/app/content.js @@ -0,0 +1,72 @@ +/* ----------------------------------------------------------------------- + * Copyright 2016 King County Library System + * Bill Erickson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * ----------------------------------------------------------------------- + * + * Hatch Content Script. + * + * Relays messages between the browser tab and the Hatch extension.js + * script. + */ + +console.debug('Loading Hatch relay content script'); + +// Tell the page DOM we're here. +document.body.setAttribute('hatch-is-open', '4-8-15-16-23-42'); + +/** + * Open a port to our extension. + */ +var port = chrome.runtime.connect(); + +/** + * Relay all messages received from the extension back to the tab + */ +port.onMessage.addListener(function(message) { + + /* + console.debug( + "Content script received from extension: "+ JSON.stringify(message)); + */ + + window.postMessage(message, location.origin); +}); + + +/** + * Receive messages from the browser tab and relay them to the + * Hatch extension script. + */ +window.addEventListener("message", function(event) { + + // We only accept messages from ourselves + if (event.source != window) return; + + var message = event.data; + + // Ignore broadcast messages. We only care about messages + // received from our browser tab/page. + if (message.from != 'page') return; + + /* + console.debug( + "Content script received from page: " + JSON.stringify(message)); + */ + + // standard Hatch-bound message; relay to extension. + port.postMessage(message); + +}, false); + + + diff --git a/extension/app/main.js b/extension/app/extension.js similarity index 57% rename from extension/app/main.js rename to extension/app/extension.js index 64b49c4e3f..a8a72ff69e 100644 --- a/extension/app/main.js +++ b/extension/app/extension.js @@ -1,18 +1,18 @@ -/* ----------------------------------------------------------------------- - * Copyright 2016 King County Library System - * Bill Erickson - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * ----------------------------------------------------------------------- - */ +/* ----------------------------------------------------------------------- + * Copyright 2016 King County Library System + * Bill Erickson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * ----------------------------------------------------------------------- + */ // Singleton connection to Hatch var hatchPort = null; @@ -29,6 +29,7 @@ function onNativeMessage(message) { if (tabId) { if (browserPorts[tabId]) { + message.from = 'extension'; browserPorts[tabId].postMessage(message); } else { @@ -48,28 +49,16 @@ function onNativeMessage(message) { * Called when the connection to Hatch goes away. */ function onDisconnected() { - console.warn("Failed to connect: " + chrome.runtime.lastError.message); + console.warn("Hatch connection failed: " + chrome.runtime.lastError.message); hatchPort = null; browserPorts = {}; } -/** - * Respond to 'ping' requests to let the browser know we exist. - */ -chrome.runtime.onMessageExternal.addListener( - function(request, sender, sendResponse) { - if (request && request.ping) { - console.debug("Got 'ping' request from tab: " + sender.tab.id); - sendResponse({pong : true}); - } - return true; - } -); /** - * Called when a browser tab opens a connection to this extension. + * Called when our content script opens connection to this extension. */ -chrome.runtime.onConnectExternal.addListener(function(port) { +chrome.runtime.onConnect.addListener(function(port) { var tabId = port.sender.tab.id; browserPorts[tabId] = port; @@ -84,7 +73,7 @@ chrome.runtime.onConnectExternal.addListener(function(port) { } // tag the message with the browser tab ID for response routing. - msg.clientid = tabId; + msg.clientid = tabId; if (msg.action == 'init') { // "init" messages require origin info. @@ -101,7 +90,51 @@ chrome.runtime.onConnectExternal.addListener(function(port) { delete browserPorts[tabId]; }); }); - + + +function setPageActionRules() { + // Replace all rules on extension reload + chrome.declarativeContent.onPageChanged.removeRules(undefined, function() { + chrome.declarativeContent.onPageChanged.addRules([ + { + conditions: [ + new chrome.declarativeContent.PageStateMatcher({ + pageUrl : { + pathPrefix : '/eg/staff/', + schemes : ['https'] + }, + css: ["eg-navbar"] // match on + }) + ], + actions: [ + new chrome.declarativeContent.RequestContentScript({ + 'js': ['content.js'] + }) + ] + } + ]); + }); +} + +chrome.browserAction.onClicked.addListener(function (tab) { + chrome.permissions.request({ + origins: ['https://*/eg/staff/*'] + }, function (ok) { + if (ok) { + console.log('access granted'); + } else if (chrome.runtime.lastError) { + alert('Permission Error: ' + chrome.runtime.lastError.message); + } else { + alert('Optional permission denied.'); + } + }); +}); + + +/** + * Link the page action icon to loading the content script + */ +chrome.runtime.onInstalled.addListener(setPageActionRules); /** * Connect to Hatch on startup. diff --git a/extension/app/manifest.json b/extension/app/manifest.json index 902cb48b04..ec39606ff9 100644 --- a/extension/app/manifest.json +++ b/extension/app/manifest.json @@ -1,17 +1,22 @@ { // Extension ID: knldjmfmopnpolahpmmgbagdohdnhkik "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcBHwzDvyBQ6bDppkIs9MP4ksKqCMyXQ/A52JivHZKh4YO/9vJsT3oaYhSpDCE9RPocOEQvwsHsFReW2nUEc6OLLyoCFFxIb7KkLGsmfakkut/fFdNJYh0xOTbSN8YvLWcqph09XAY2Y/f0AL7vfO1cuCqtkMt8hFrBGWxDdf9CQIDAQAB", - "name": "Hatch Native Messaging Extension", + "name": "Hatch Native Messenger", "version": "1.0", "manifest_version": 2, "description": "Relays messages to/from Hatch.", "background" : { - "scripts" : ["main.js"] + "scripts" : ["extension.js"] + }, + "browser_action": { + "default_title": "Hatch" }, "permissions": [ - "nativeMessaging" + "nativeMessaging", + "declarativeContent" + ], + "optional_permissions": [ + "https://*/eg/staff/*" ], - "externally_connectable": { - "matches": ["*://evergreen.example.org/*"] - } + "minimum_chrome_version": "38" } -- 2.11.0