Skip to content

Commit fd7c00e

Browse files
author
Eric Gibby
committed
IL-24401: Added handler so webview can use chrome.runtime.sendMessage to store settings with Chrome storage. Also added handler for opening external links in new browser tab.
1 parent d0ca78c commit fd7c00e

File tree

5 files changed

+140
-70
lines changed

5 files changed

+140
-70
lines changed

browser.html

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
<!DOCTYPE html>
22
<html>
3-
<head>
4-
<link rel="stylesheet" href="browser.css">
5-
<script src="browser.js"></script>
6-
<script src="parseSettings.js"></script>
3+
4+
<head>
5+
<link rel="stylesheet" href="browser.css">
6+
<script src="underscore.js"></script>
7+
<script src="browser.js"></script>
8+
<script src="parseSettings.js"></script>
9+
710
<body>
811
<div id="controls">
912
<button id="reload" title="Reload">&#10227;</button>
@@ -19,8 +22,8 @@
1922
<h2 id="crashed-label">Aw, Snap!</h2>
2023
<h2 id="killed-label">He's Dead, Jim!</h2>
2124

22-
<p>Something went wrong while displaying this webpage.
23-
To continue, reload or go to another page.</p>
25+
<p>Something went wrong while displaying this webpage. To continue, reload or go to another page.</p>
2426
</div>
2527
</body>
28+
2629
</html>

browser.js

Lines changed: 105 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
var reload = chrome.runtime.reload
1+
var reload = chrome.runtime.reload;
2+
var storage = chrome.storage.local;
23
window.onresize = doLayout;
34
var isLoading = false;
45

56
function ui_ready() {
6-
77
if (window.webapp) {
88
if (!(webapp.started || webapp.starting)) {
99
// autostart ?
@@ -18,37 +18,32 @@ function settings_ready(d) {
1818
ui_ready();
1919
}
2020

21-
chrome.runtime.getBackgroundPage(function (bg) {
21+
chrome.runtime.getBackgroundPage(function(bg) {
2222
window.bg = bg;
23-
chrome.storage.local.get(null, settings_ready);
24-
})
25-
23+
storage.get(null, settings_ready);
24+
});
2625

27-
28-
onload = function () {
26+
onload = function() {
2927
getServerSettings(receivedServerSettings);
3028
var webview = document.querySelector('webview');
3129
doLayout();
3230

33-
document.querySelector('#reset').onclick = function () {
31+
document.querySelector('#reset').onclick = function() {
3432
window.close();
3533
};
3634

37-
document.querySelector('#reload').onclick = function () {
35+
document.querySelector('#reload').onclick = function() {
3836
if (isLoading) {
3937
webview.stop();
4038
} else {
4139
webview.reload();
4240
}
4341
};
44-
document.querySelector('#reload').addEventListener(
45-
'webkitAnimationIteration',
46-
function () {
47-
if (!isLoading) {
48-
document.body.classList.remove('loading');
49-
}
50-
});
51-
42+
document.querySelector('#reload').addEventListener('webkitAnimationIteration', function() {
43+
if (!isLoading) {
44+
document.body.classList.remove('loading');
45+
}
46+
});
5247

5348
webview.addEventListener('exit', handleExit);
5449
webview.addEventListener('loadstart', handleLoadStart);
@@ -57,44 +52,42 @@ onload = function () {
5752
webview.addEventListener('loadredirect', handleLoadRedirect);
5853
webview.addEventListener('loadcommit', handleLoadCommit);
5954
webview.addEventListener('permissionrequest', handleRequest);
55+
webview.addEventListener('newwindow', handleNewWindow);
6056
};
6157

62-
6358
function getServerSettings(callback) {
64-
chrome.storage.managed.get("serverSettings", function (results) {
59+
storage.get('serverSettings', function(results) {
6560
if (chrome.runtime.lastError) {
66-
console.log("error, returning empty. Error Message: " + chrome.runtime.lastError.message);
61+
console.log('error, returning empty. Error Message: ' + chrome.runtime.lastError.message);
6762
return;
6863
} else {
69-
console.log("got server settings, returning");
70-
callback(results.serverSettings)
71-
64+
console.log('got server settings, returning');
65+
callback(results.serverSettings);
7266
}
7367
});
7468
}
7569

7670
function receivedServerSettings(serverSettings) {
77-
console.log("got server settings");
71+
console.log('got server settings');
7872
console.log(serverSettings);
79-
chrome.storage.local.get('relativeLaunchUrl', function (obj) {
73+
storage.get('relativeLaunchUrl', function(obj) {
8074
var relativeLaunchUrl = obj && obj.relativeLaunchUrl,
8175
url = convertServerSettingsToUrl(serverSettings, relativeLaunchUrl);
8276

8377
if (url && url.length > 0) {
84-
console.log("calling navigateTo url: " + url);
78+
console.log('calling navigateTo url: ' + url);
8579
navigateTo(url);
8680
}
8781
});
8882
}
8983

90-
9184
function handleRequest(e) {
92-
console.log("permission request");
85+
console.log('permission request');
9386
if (e.permission === 'media') {
94-
console.log("Audio permission request");
87+
console.log('Audio permission request');
9588
e.request.allow();
9689
}
97-
console.log("Done with permission request");
90+
console.log('Done with permission request');
9891
}
9992

10093
function navigateTo(url) {
@@ -142,7 +135,6 @@ function handleLoadCommit(event) {
142135
return;
143136
}
144137

145-
146138
var webview = document.querySelector('webview');
147139
}
148140

@@ -162,49 +154,47 @@ function handleLoadStop(event) {
162154
// finish, so that the spinner doesn't jerkily reset back to the 0 position.
163155
isLoading = false;
164156

165-
chrome.storage.sync.get(null, function (items) {
157+
chrome.storage.sync.get(null, function(items) {
166158
settings = items;
167159

168160
var webview = document.querySelector('webview');
169161
//by sending this message the webview can then send messages back to the listener added above
170-
webview.contentWindow.postMessage({
171-
command: 'handshake',
172-
settings: settings
173-
}, '*');
162+
webview.contentWindow.postMessage(
163+
{
164+
command: 'handshake',
165+
settings: settings
166+
},
167+
'*'
168+
);
174169
});
175170

176-
window.addEventListener("message", function (event) {
171+
window.addEventListener('message', function(event) {
177172
console.log('window received message:', event.data);
178173
processCommand(event.data);
179174
});
180175
}
181176

182177
function processCommand(data) {
183-
184178
if (data.command === 'handshakereply') {
185179
//ignore because this is just the client telling us it can talk back
186180
return;
187181
}
188182

189183
if (data.command === 'deletePref') {
190184
delete settings[data.data.key];
191-
}
192-
else if (data.command === 'setPref') {
185+
} else if (data.command === 'setPref') {
193186
settings[data.data.key] = data.data;
194187
}
195188

196-
chrome.storage.sync.set(settings, function () {
197-
189+
chrome.storage.sync.set(settings, function() {
198190
if (!chrome.runtime.lastError) {
199191
console.log('settings set');
200192
}
201193
});
202-
203-
204194
}
205195

206196
function handleLoadAbort(event) {
207-
console.log('oadAbort');
197+
console.log('loadAbort');
208198
console.log(' url: ' + event.url);
209199
console.log(' isTopLevel: ' + event.isTopLevel);
210200
console.log(' type: ' + event.type);
@@ -217,4 +207,72 @@ function handleLoadRedirect(event) {
217207
}
218208

219209
document.querySelector('#location').value = event.newUrl;
220-
}
210+
}
211+
212+
function handleNewWindow(event) {
213+
event.preventDefault();
214+
215+
// event.targetUrl contains the target URL of the original link click
216+
// or window.open() call: use it to open your own window to it.
217+
// See: https://stackoverflow.com/a/18452171/6326743
218+
var url = event.targetUrl;
219+
220+
// `chrome.browser.openTab` with `browser` permission will open the link in the browser.
221+
// See: https://stackoverflow.com/a/36530347/6326743
222+
chrome.browser.openTab({ url: url });
223+
}
224+
225+
/**
226+
* Handler for messages sent with `chrome.runtime.sendMessage`
227+
*
228+
* @param {any} message The message sent by the calling script
229+
* @param {MessageSender} sender
230+
* @param {function} sendResponse Function to call (at most once) when you have a response.
231+
*/
232+
function handleMessage(message, sender, sendResponse) {
233+
console.log('handleMessage:', message);
234+
if (message.command === 'settings.get') {
235+
storage.get('serverSettings', function(items) {
236+
if (sendResponse) {
237+
var response = {
238+
success: !chrome.runtime.lastError,
239+
data: chrome.runtime.lastError
240+
};
241+
if (response.success) {
242+
var data = items.serverSettings || {};
243+
if (typeof message.data === 'string') {
244+
response.data = data[message.data];
245+
} else if (Array.isArray(message.data)) {
246+
response.data = message.data.reduce(function(aggregator, current) {
247+
return (aggregator[current] = data[current]);
248+
}, {});
249+
} else {
250+
response.data = data;
251+
}
252+
}
253+
console.log('response:', response);
254+
sendResponse(response);
255+
}
256+
});
257+
return !!sendResponse; // wait for response
258+
} else if (message.command === 'settings.patch') {
259+
storage.get('serverSettings', function(items) {
260+
var settings = {
261+
serverSettings: _.extend(items.serverSettings || {}, message.data)
262+
};
263+
storage.set(settings, function() {
264+
if (sendResponse) {
265+
var response = {
266+
success: !chrome.runtime.lastError,
267+
data: chrome.runtime.lastError
268+
};
269+
console.log('response:', response);
270+
sendResponse(response);
271+
}
272+
});
273+
});
274+
return !!sendResponse; // wait for response
275+
}
276+
}
277+
278+
chrome.runtime.onMessageExternal.addListener(handleMessage);

manifest.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
},
1717
"permissions": [
1818
"webview",
19+
"browser",
1920
"alarms",
2021
"storage",
2122
"power",
@@ -61,5 +62,8 @@
6162
],
6263
"title": "Open Imagine Learning"
6364
}
65+
},
66+
"externally_connectable": {
67+
"matches": ["*://localhost:*/*", "*://127.0.0.1:*/*", "*://*.imaginelearning.com/*"]
6468
}
6569
}

manifest_unityclient.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
},
1919
"permissions": [
2020
"webview",
21+
"browser",
2122
"alarms",
2223
"storage",
2324
"system.network",
@@ -42,5 +43,8 @@
4243
},
4344
"icons": {
4445
"128": "images/ilandl_128.png"
46+
},
47+
"externally_connectable": {
48+
"matches": ["*://localhost:*/*", "*://127.0.0.1:*/*", "*://*.imaginelearning.com/*"]
4549
}
4650
}

parseSettings.js

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
var baseUrl = "localhost:8887/";
2-
1+
var baseUrl = 'localhost:8887/';
32

43
function convertServerSettingsToUrl(serverSettings, launchUrl) {
54
var url = 'http://' + baseUrl;
@@ -8,35 +7,37 @@ function convertServerSettingsToUrl(serverSettings, launchUrl) {
87
url += launchUrl.replace(/^\//, '');
98
}
109

10+
var queryString = ['chromeappid=' + chrome.runtime.id];
11+
1112
if (serverSettings) {
12-
var queryString = [];
13-
if (serverSettings && serverSettings.cloudSiteCode && serverSettings.cloudSiteCode.length > 0 && url.indexOf('sitecode') < 0) {
14-
queryString.push('sitecode=' + serverSettings.cloudSiteCode);
15-
} else if (serverSettings && serverSettings.engineAddress && serverSettings.engineAddress.length > 0) {
13+
if ((serverSettings.sitecode || serverSettings.cloudSiteCode) && url.indexOf('sitecode') < 0) {
14+
queryString.push('sitecode=' + serverSettings.sitecode || serverSettings.cloudSiteCode);
15+
} else if (serverSettings.engineAddress) {
1616
queryString.push('engineaddress=' + serverSettings.engineAddress);
1717
}
18-
19-
if (serverSettings && serverSettings.forceCloudLogUpload && serverSettings.forceCloudLogUpload === true) {
18+
19+
if (serverSettings.forceCloudLogUpload && serverSettings.forceCloudLogUpload === true) {
2020
queryString.push('forceCloudLogUpload');
2121
}
2222

23-
if (serverSettings && serverSettings.adaptive && serverSettings.adaptive === true) {
23+
if (serverSettings.adaptive && serverSettings.adaptive === true) {
2424
queryString.push('adaptive');
2525
}
2626

27-
if (serverSettings && serverSettings.env && serverSettings.env.length > 0) {
27+
if (serverSettings.env) {
2828
queryString.push('env=' + serverSettings.env);
2929
}
30-
31-
if (queryString.length) {
32-
url += (url.indexOf('?') < 0 ? '?' : '&') + queryString.join('&');
33-
}
3430
}
3531

3632
//if no environment set then default to production
37-
if(url.indexOf("env") < 0) {
38-
url += (url.indexOf('?') < 0 ? '?' : '&') + 'env=production';
33+
var envIndex = queryString.findIndex(function(item) {
34+
return /^env=/.test(item);
35+
});
36+
if (envIndex < 0) {
37+
queryString.push('env=production');
3938
}
4039

40+
url += (url.indexOf('?') < 0 ? '?' : '&') + queryString.join('&');
41+
4142
return url;
42-
}
43+
}

0 commit comments

Comments
 (0)