Skip to content

Commit 96921f9

Browse files
committed
Improve dev panel implementation and switch to tab-based tracking of resources.
1 parent 808fc3f commit 96921f9

File tree

10 files changed

+168
-77
lines changed

10 files changed

+168
-77
lines changed

chromium/_locales/en/messages.json

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,6 @@
9595
"source_unable_to_download": {
9696
"message": "Unable to download source."
9797
},
98-
"switch_planner": {
99-
"message": "Switch Planner"
100-
},
101-
"switch_planner_description": {
102-
"message": "Unrewritten HTTP resources:"
103-
},
10498
"chrome_stable_rules": {
10599
"message": "Stable rules"
106100
},

chromium/background.js

Lines changed: 58 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
// TODO: This keeps around history across "clear history" events. Fix that.
1+
// Records which tabId's are active in the HTTPS Switch Planner (see
2+
// devtools-panel.js).
23
var switchPlannerEnabledFor = {};
4+
// Detailed information recorded when the HTTPS Switch Planner is active.
5+
// Structure is:
6+
// switchPlannerInfo[tabId][resource_host][active_content][url];
37
var switchPlannerInfo = {};
4-
console.log("XXX TESTING XXX");
58

69
var all_rules = new RuleSets();
710
var wr = chrome.webRequest;
@@ -147,21 +150,12 @@ function onBeforeRequest(details) {
147150

148151
// In Switch Planner Mode, record any non-rewriteable
149152
// HTTP URIs by parent hostname, along with the resource type.
150-
if (uri.protocol() !== "https") {
151-
// In order to figure out the document requesting this resource,
152-
// have to get the tab. TODO: any cheaper way?
153-
// XXX: Because this is async it's actually inaccurate during quick page
154-
// switches. Maybe it only matters when you're switching domains though?
155-
chrome.tabs.get(details.tabId, function(tab) {
156-
var tab_host = new URI(tab.url).hostname();
157-
if (tab_host !== canonical_host) {
158-
writeToSwitchPlanner(details.type,
159-
tab_host,
160-
canonical_host,
161-
details.url,
162-
newuristr);
163-
}
164-
});
153+
if (switchPlannerEnabledFor[details.tabId] && uri.protocol() !== "https") {
154+
writeToSwitchPlanner(details.type,
155+
details.tabId,
156+
canonical_host,
157+
details.url,
158+
newuristr);
165159
}
166160

167161
if (newuristr) {
@@ -188,7 +182,7 @@ var passiveTypes = { main_frame: 1, sub_frame: 1, image: 1, xmlhttprequest: 1};
188182
// use in determining which resources need to be ported to HTTPS.
189183
// TODO: Maybe unique by resource URL, so reloading a single page doesn't double
190184
// the counts?
191-
function writeToSwitchPlanner(type, tab_host, resource_host, resource_url, rewritten_url) {
185+
function writeToSwitchPlanner(type, tab_id, resource_host, resource_url, rewritten_url) {
192186
var rw = "rw";
193187
if (rewritten_url == null)
194188
rw = "no";
@@ -207,14 +201,14 @@ function writeToSwitchPlanner(type, tab_host, resource_host, resource_url, rewri
207201
// TODO: Maybe also count rewritten URLs separately.
208202
if (rewritten_url != null) return;
209203

210-
if (!switchPlannerInfo[tab_host])
211-
switchPlannerInfo[tab_host] = {};
212-
if (!switchPlannerInfo[tab_host][resource_host])
213-
switchPlannerInfo[tab_host][resource_host] = {};
214-
if (!switchPlannerInfo[tab_host][resource_host][active_content])
215-
switchPlannerInfo[tab_host][resource_host][active_content] = {};
204+
if (!switchPlannerInfo[tab_id])
205+
switchPlannerInfo[tab_id] = {};
206+
if (!switchPlannerInfo[tab_id][resource_host])
207+
switchPlannerInfo[tab_id][resource_host] = {};
208+
if (!switchPlannerInfo[tab_id][resource_host][active_content])
209+
switchPlannerInfo[tab_id][resource_host][active_content] = {};
216210

217-
switchPlannerInfo[tab_host][resource_host][active_content][resource_url] = 1;
211+
switchPlannerInfo[tab_id][resource_host][active_content][resource_url] = 1;
218212
}
219213

220214
// Return the number of properties in an object. For associative maps, this is
@@ -230,11 +224,11 @@ function objSize(obj) {
230224

231225
// Make an array of asset hosts by score so we can sort them,
232226
// presenting the most important ones first.
233-
function sortSwitchPlanner(tab_host) {
227+
function sortSwitchPlanner(tab_id) {
234228
var asset_host_list = [];
235-
var parentInfo = switchPlannerInfo[tab_host];
236-
for (var asset_host in parentInfo) {
237-
var ah = parentInfo[asset_host];
229+
var tabInfo = switchPlannerInfo[tab_id];
230+
for (var asset_host in tabInfo) {
231+
var ah = tabInfo[asset_host];
238232
var activeCount = objSize(ah[1]);
239233
var passiveCount = objSize(ah[0]);
240234
var score = activeCount * 100 + passiveCount;
@@ -245,8 +239,8 @@ function sortSwitchPlanner(tab_host) {
245239
}
246240

247241
// Format the switch planner output for presentation to a user.
248-
function switchPlannerSmallHtml(tab_host) {
249-
var asset_host_list = sortSwitchPlanner(tab_host);
242+
function switchPlannerSmallHtml(tab_id) {
243+
var asset_host_list = sortSwitchPlanner(tab_id);
250244
if (asset_host_list.length == 0) {
251245
return "<b>none</b>";
252246
}
@@ -282,8 +276,8 @@ function linksFromKeys(map) {
282276
return output;
283277
}
284278

285-
function switchPlannerDetailsHtml(tab_host) {
286-
var asset_host_list = sortSwitchPlanner(tab_host);
279+
function switchPlannerDetailsHtml(tab_id) {
280+
var asset_host_list = sortSwitchPlanner(tab_id);
287281
var output = "";
288282

289283
for (var i = asset_host_list.length - 1; i >= 0; i--) {
@@ -294,11 +288,11 @@ function switchPlannerDetailsHtml(tab_host) {
294288
output += "<b>" + host + "</b>: ";
295289
if (activeCount > 0) {
296290
output += activeCount + " active<br/>";
297-
output += linksFromKeys(switchPlannerInfo[tab_host][host][1]);
291+
output += linksFromKeys(switchPlannerInfo[tab_id][host][1]);
298292
}
299293
if (passiveCount > 0) {
300294
output += "<br/>" + passiveCount + " passive<br/>";
301-
output += linksFromKeys(switchPlannerInfo[tab_host][host][0]);
295+
output += linksFromKeys(switchPlannerInfo[tab_id][host][0]);
302296
}
303297
output += "<br/>";
304298
}
@@ -407,13 +401,35 @@ chrome.tabs.onReplaced.addListener(function(addedTabId, removedTabId) {
407401
// so we also use onBeforeSendHeaders to prevent a small window where cookies could be stolen.
408402
chrome.cookies.onChanged.addListener(onCookieChanged);
409403

404+
function disableSwitchPlannerFor(tabId) {
405+
delete switchPlannerEnabledFor[tabId];
406+
// Clear stored URL info.
407+
delete switchPlannerInfo[tabId];
408+
}
409+
410+
function enableSwitchPlannerFor(tabId) {
411+
switchPlannerEnabledFor[tabId] = true;
412+
}
413+
410414
// Listen for connection from the DevTools panel so we can set up communication.
411-
chrome.runtime.onMessage.addListener(function(message){
412-
console.log(message);
413-
if (message.hasOwnProperty('enable')) {
414-
var enable = message.enable;
415-
switchPlannerEnabledFor[message.tabId] = enable;
416-
if (!enable)
417-
switchPlannerInfo = {};
415+
chrome.runtime.onConnect.addListener(function (port) {
416+
if (port.name == "devtools-page") {
417+
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse){
418+
var tabId = message.tabId;
419+
420+
var disableOnCloseCallback = function(port) {
421+
log(DBUG, "Devtools window for tab " + tabId + " closed, clearing data.");
422+
disableSwitchPlannerFor(tabId);
423+
};
424+
425+
if (message.type === "enable") {
426+
enableSwitchPlannerFor(tabId);
427+
port.onDisconnect.addListener(disableOnCloseCallback);
428+
} else if (message.type === "disable") {
429+
disableSwitchPlannerFor(tabId);
430+
} else if (message.type === "getSmallHtml") {
431+
sendResponse({html: switchPlannerSmallHtml(tabId)});
432+
}
433+
});
418434
}
419435
});

chromium/devtools-panel.html

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<head>
2+
<title></title>
3+
<script src="devtools-panel.js"></script>
4+
</head>
5+
<body>
6+
<div id=SwitchPlanner>
7+
<input type=checkbox id=SwitchPlannerCheckbox>
8+
<label for=SwitchPlannerCheckbox>Enable HTTPS Switch Planner mode (reloads page).</label>
9+
<p>
10+
<div id=SwitchPlannerDescription>
11+
Switch Planner mode helps prepare for your site's switch to HTTPS by generating
12+
a report of external HTTP resources that might not yet be available on HTTPS.
13+
<p>
14+
After enabling, navigate around your site and try to exercise all
15+
functionality in order to get a comprehensive list of external resources.
16+
<p>
17+
For each group of resources listed as "Unrewritten," find out whether they
18+
are available on HTTPS. If so: add a rule to HTTPS Everywhere! If not: try
19+
to make them available over HTTPS or use a different resource or provider.
20+
Otherwise your site will generate
21+
<a href="https://developer.mozilla.org/en-US/docs/Security/MixedContent#Mixed_passive.2Fdisplay_content">Mixed Content</a>
22+
(passive or active) errors when you turn on HTTPS.
23+
<p>
24+
For most accurate results, disable ad blockers before using. Closing this
25+
panel will deactivate Switch Planner mode and clear stored data.
26+
</div>
27+
<div id=SwitchPlannerResults style="display: none;">
28+
Unrewritten HTTP resources loaded from this tab:
29+
<div id=SwitchPlannerDetails></div>
30+
<a id=SwitchPlannerDetailsLink href="javascript:void(0);">details</a>
31+
</div>
32+
</div>
33+
</body>

chromium/devtools-panel.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
function e(id) {
2+
return document.getElementById(id);
3+
}
4+
5+
function sendMessage(type) {
6+
chrome.runtime.sendMessage({
7+
type: type,
8+
tabId: chrome.devtools.inspectedWindow.tabId,
9+
});
10+
}
11+
12+
// Turn on the Switch Planner recording mode, and hide the long description.
13+
function enableSwitchPlanner() {
14+
sendMessage("enable");
15+
e("SwitchPlannerDescription").style.display = "none";
16+
e("SwitchPlannerDetails").style.display = "block";
17+
// Hack: Fetch and display summary information from background page
18+
// once per second.
19+
setInterval(display, 1000);
20+
chrome.devtools.inspectedWindow.reload();
21+
}
22+
23+
// Disable the switch planner and reload, so any state is forgotten and
24+
// the long description is restored.
25+
function disableSwitchPlanner() {
26+
sendMessage("disable");
27+
document.location.reload();
28+
}
29+
30+
// Fetch summary HTML of the planner results from the background page for
31+
// display in the devtools panel.
32+
function display() {
33+
chrome.runtime.sendMessage({
34+
type: "getSmallHtml",
35+
tabId: chrome.devtools.inspectedWindow.tabId,
36+
}, function(response) {
37+
e("SwitchPlannerDetails").innerHTML = response.html;
38+
e("SwitchPlannerResults").style.display = "block";
39+
});
40+
}
41+
42+
window.onload = function() {
43+
// Open a connection to the background page. Right now this is only used
44+
// by the background page so it knows when the devtools pane has closed.
45+
// We don't receive messages from the background page currently, though that
46+
// may be a future improvement. Sending messages to the background page doesn't
47+
// require an existing connection.
48+
chrome.runtime.connect({ name: "devtools-page" });
49+
50+
var checkbox = e("SwitchPlannerCheckbox");
51+
checkbox.addEventListener("change", function() {
52+
if (checkbox.checked) {
53+
enableSwitchPlanner();
54+
} else {
55+
disableSwitchPlanner();
56+
}
57+
});
58+
59+
e("SwitchPlannerDetailsLink").addEventListener("click", function() {
60+
window.open("switch-planner.html?tab=" + chrome.devtools.inspectedWindow.tabId);
61+
});
62+
};

chromium/devtools.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<head>
2+
<title></title>
3+
<script src="devtools.js"></script>
4+
</head>
5+
<body>
6+
</body>

chromium/devtools.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
chrome.devtools.panels.create("HTTPS Everywhere",
2+
"icon48.png",
3+
"devtools-panel.html",
4+
function(panel) {
5+
}
6+
);

chromium/popup.html

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,6 @@
1212
<header>
1313
<h1 i18n="about_ext_name"></h1>
1414
</header>
15-
<section id="SwitchPlanner" class="switchplanner">
16-
<h3 i18n="switch_planner">Switch Planner</h3>
17-
<p class="description" i18n="switch_planner_description"></p>
18-
<a id=SwitchPlannerDetails href="javascript:void(0);">details</a>
19-
</section>
2015
<section id="StableRules" class="rules">
2116
<h3 i18n="chrome_stable_rules"></h3>
2217
<p class="description" i18n="chrome_stable_rules_description"></p>

chromium/popup.js

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
var backgroundPage = null;
22
var stableRules = null;
33
var unstableRules = null;
4-
var switchPlannerDiv = null;
54
var hostReg = /.*\/\/[^$/]*\//;
65

76
function toggleRuleLine(checkbox, ruleset) {
@@ -62,25 +61,6 @@ function createRuleLine(ruleset) {
6261
}
6362

6463
function gotTab(tab) {
65-
if (backgroundPage.switchPlannerEnabledFor[tab.id]) {
66-
// XXX: Call URI here, but it's not in-scope. Need to make it in-scope.
67-
var tab_hostname = tab.url.match(/https?:\/\/([^\/]*)/)[1];
68-
69-
var detailsLink = document.getElementById("SwitchPlannerDetails");
70-
detailsLink.onclick = function() {
71-
window.open("switch-planner.html?host=" + tab_hostname);
72-
};
73-
74-
var switchPlannerTextDiv = document.createElement("div");
75-
var switchPlannerText = backgroundPage.switchPlannerSmallHtml(tab_hostname);
76-
switchPlannerTextDiv.innerHTML = switchPlannerText;
77-
switchPlannerDiv.className = "switch_planner_info";
78-
switchPlannerDiv.style.position = "static";
79-
switchPlannerDiv.style.visibility = "visible";
80-
81-
switchPlannerDiv.insertBefore(switchPlannerTextDiv, detailsLink);
82-
}
83-
8464
var rulesets = backgroundPage.activeRulesets.getRulesets(tab.id);
8565

8666
for (var r in rulesets) {
@@ -98,7 +78,6 @@ document.addEventListener("DOMContentLoaded", function () {
9878
backgroundPage = chrome.extension.getBackgroundPage();
9979
stableRules = document.getElementById("StableRules");
10080
unstableRules = document.getElementById("UnstableRules");
101-
switchPlannerDiv = document.getElementById("SwitchPlanner");
10281
chrome.tabs.getSelected(null, gotTab);
10382

10483
// auto-translate all elements with i18n attributes

chromium/rules.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ RuleSets.prototype = {
184184
// Have we cached this result? If so, return it!
185185
var cached_item = ruleCache.get(host);
186186
if (cached_item !== undefined) {
187-
log(DBUG, "Rulseset cache hit for " + host);
187+
log(DBUG, "Ruleset cache hit for " + host);
188188
return cached_item;
189189
}
190190
log(DBUG, "Ruleset cache miss for " + host);

chromium/switch-planner.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
window.onload = function() {
22
var backgroundPage = chrome.extension.getBackgroundPage();
3-
var hostname = document.location.search.match(/host=([^&]*)/)[1];
3+
var tab = document.location.search.match(/tab=([^&]*)/)[1];
44
document.getElementById("content").innerHTML =
5-
backgroundPage.switchPlannerDetailsHtml(hostname);
5+
backgroundPage.switchPlannerDetailsHtml(tab);
66
};
77

0 commit comments

Comments
 (0)