=== 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].
--- /dev/null
+/* -----------------------------------------------------------------------
+ * Copyright 2016 King County Library System
+ * Bill Erickson <berickxx@gmail.com>
+ *
+ * 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);
+
+
+
--- /dev/null
+/* -----------------------------------------------------------------------
+ * Copyright 2016 King County Library System
+ * Bill Erickson <berickxx@gmail.com>
+ *
+ * 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;
+
+// Map of tab identifers to tab-specific connection ports.
+var browserPorts = {};
+
+
+/**
+ * Handle response messages received from Hatch.
+ */
+function onNativeMessage(message) {
+ var tabId = message.clientid;
+
+ if (tabId) {
+ if (browserPorts[tabId]) {
+ message.from = 'extension';
+ browserPorts[tabId].postMessage(message);
+
+ } else {
+ console.warn(
+ "Hatch message contains port ID " + tabId +
+ " which was not found in the browser tab map. " +
+ "Unable to deliver response to browser");
+ }
+
+ } else {
+ console.warn("Hatch response does not contain a 'clientid' value. " +
+ "Unable to deliver response to browser");
+ }
+}
+
+/**
+ * Called when the connection to Hatch goes away.
+ */
+function onDisconnected() {
+ console.warn("Hatch connection failed: " + chrome.runtime.lastError.message);
+ hatchPort = null;
+ browserPorts = {};
+}
+
+
+/**
+ * Called when our content script opens connection to this extension.
+ */
+chrome.runtime.onConnect.addListener(function(port) {
+ var tabId = port.sender.tab.id;
+
+ browserPorts[tabId] = port;
+ console.debug('new port connected with id ' + tabId);
+
+ port.onMessage.addListener(function(msg) {
+ console.debug("Received message from browser on port " + tabId);
+
+ if (!msg) { // belt+suspenders
+ console.warn("Received NULL message");
+ return;
+ }
+
+ // tag the message with the browser tab ID for response routing.
+ msg.clientid = tabId;
+
+ if (msg.action == 'init') {
+ // "init" messages require origin info.
+ // Extract just the protocol + host
+ msg.origin = port.sender.url.match(/https?:\/\/[^\/]+/)[0];
+ console.debug("Init'ing message with origin: " + msg.origin);
+ }
+
+ hatchPort.postMessage(msg);
+ });
+
+ port.onDisconnect.addListener(function() {
+ console.log("Removing port " + tabId + " on tab disconnect");
+ 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 <eg-navbar/>
+ })
+ ],
+ 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.
+ */
+var hostName = "org.evergreen_ils.hatch";
+console.debug("Connecting to native messaging host: " + hostName);
+hatchPort = chrome.runtime.connectNative(hostName);
+hatchPort.onMessage.addListener(onNativeMessage);
+hatchPort.onDisconnect.addListener(onDisconnected);
+
+++ /dev/null
-/* -----------------------------------------------------------------------
- * Copyright 2016 King County Library System
- * Bill Erickson <berickxx@gmail.com>
- *
- * 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;
-
-// Map of tab identifers to tab-specific connection ports.
-var browserPorts = {};
-
-
-/**
- * Handle response messages received from Hatch.
- */
-function onNativeMessage(message) {
- var tabId = message.clientid;
-
- if (tabId) {
- if (browserPorts[tabId]) {
- browserPorts[tabId].postMessage(message);
-
- } else {
- console.warn(
- "Hatch message contains port ID " + tabId +
- " which was not found in the browser tab map. " +
- "Unable to deliver response to browser");
- }
-
- } else {
- console.warn("Hatch response does not contain a 'clientid' value. " +
- "Unable to deliver response to browser");
- }
-}
-
-/**
- * Called when the connection to Hatch goes away.
- */
-function onDisconnected() {
- console.warn("Failed to connect: " + 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.
- */
-chrome.runtime.onConnectExternal.addListener(function(port) {
- var tabId = port.sender.tab.id;
-
- browserPorts[tabId] = port;
- console.debug('new port connected with id ' + tabId);
-
- port.onMessage.addListener(function(msg) {
- console.debug("Received message from browser on port " + tabId);
-
- if (!msg) { // belt+suspenders
- console.warn("Received NULL message");
- return;
- }
-
- // tag the message with the browser tab ID for response routing.
- msg.clientid = tabId;
-
- if (msg.action == 'init') {
- // "init" messages require origin info.
- // Extract just the protocol + host
- msg.origin = port.sender.url.match(/https?:\/\/[^\/]+/)[0];
- console.debug("Init'ing message with origin: " + msg.origin);
- }
-
- hatchPort.postMessage(msg);
- });
-
- port.onDisconnect.addListener(function() {
- console.log("Removing port " + tabId + " on tab disconnect");
- delete browserPorts[tabId];
- });
-});
-
-
-/**
- * Connect to Hatch on startup.
- */
-var hostName = "org.evergreen_ils.hatch";
-console.debug("Connecting to native messaging host: " + hostName);
-hatchPort = chrome.runtime.connectNative(hostName);
-hatchPort.onMessage.addListener(onNativeMessage);
-hatchPort.onDisconnect.addListener(onDisconnected);
-
{
// 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"
}