Skip to content
This repository was archived by the owner on Feb 25, 2020. It is now read-only.

Commit 25d7a59

Browse files
committed
Merge branch 'source-script-detection'
2 parents 50b3ba8 + a67be17 commit 25d7a59

12 files changed

Lines changed: 345 additions & 127 deletions

File tree

chrome/css/panel.css

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,6 @@ body {
1313
width: 310px;
1414
}
1515

16-
caption {
17-
font-size: 14px;
18-
margin: 10px 0;
19-
}
20-
2116
hr {
2217
background-color: #ddd;
2318
border: 0;

chrome/js/builds/background.js

Lines changed: 73 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2-
3-
},{}],2:[function(require,module,exports){
42
/*!
53
* Chameleon
64
*
@@ -20,7 +18,8 @@ var ALL_URLS = { urls: ['http://*/*', 'https://*/*'] },
2018
ENABLED = true;
2119

2220
var tabData = require('../lib/tabdata'),
23-
sendMessage = require('../lib/utils').sendMessage;
21+
sendMessage = require('../lib/content_script_utils').sendMessage,
22+
utils = require('../lib/utils');
2423

2524
// TODO https://developer.chrome.com/extensions/webRequest#life_cycle_footnote
2625
// The following headers are currently not provided to the onBeforeSendHeaders event.
@@ -103,7 +102,7 @@ function updateBadge(tab_id) {
103102
text = '';
104103

105104
if (data) {
106-
text = _.size(data.counts).toString();
105+
text = utils.getAccessCount(data.counts).toString();
107106
}
108107

109108
chrome.browserAction.setBadgeText({
@@ -228,7 +227,52 @@ chrome.webNavigation.onCommitted.addListener(onNavigation);
228227
// TODO switch to chrome.alarms?
229228
setInterval(tabData.clean, 300000);
230229

231-
},{"../lib/tabdata":3,"../lib/utils":4}],3:[function(require,module,exports){
230+
},{"../lib/content_script_utils":2,"../lib/tabdata":3,"../lib/utils":4}],2:[function(require,module,exports){
231+
/*!
232+
* Chameleon
233+
*
234+
* Copyright 2014 ghostwords.
235+
*
236+
* This Source Code Form is subject to the terms of the Mozilla Public
237+
* License, v. 2.0. If a copy of the MPL was not distributed with this
238+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
239+
*
240+
*/
241+
242+
/*
243+
* This module needs to work both inside content scripts and the rest of the
244+
* extension, like the browser popup.
245+
*
246+
* Content scripts have certain limitations in Chrome:
247+
* https://developer.chrome.com/extensions/content_scripts
248+
*/
249+
250+
// acceptable signatures:
251+
// name
252+
// name, message
253+
// name, callback
254+
// name, message, callback
255+
module.exports.sendMessage = function (name, message, callback) {
256+
var args = [{ name: name }];
257+
258+
if (Object.prototype.toString.call(message) == '[object Function]') {
259+
// name, callback
260+
args.push(message);
261+
} else {
262+
if (message) {
263+
// name, message, [callback]
264+
args[0].message = message;
265+
}
266+
if (callback) {
267+
// name, [message], callback
268+
args.push(callback);
269+
}
270+
}
271+
272+
chrome.runtime.sendMessage.apply(chrome.runtime, args);
273+
};
274+
275+
},{}],3:[function(require,module,exports){
232276
/*!
233277
* Chameleon
234278
*
@@ -246,7 +290,8 @@ var data = {};
246290

247291
var tabData = {
248292
record: function (tab_id, access) {
249-
var key = access.obj + '.' + access.prop;
293+
var key = access.obj + '.' + access.prop,
294+
script_url = access.scriptUrl || '<unknown>';
250295

251296
if (!data.hasOwnProperty(tab_id)) {
252297
data[tab_id] = {
@@ -255,15 +300,22 @@ var tabData = {
255300
};
256301
}
257302

303+
var datum = data[tab_id];
304+
305+
// font enumeration
258306
if (access.prop == 'style.fontFamily') {
259-
data[tab_id].fontEnumeration = true;
307+
datum.fontEnumeration = true;
260308
}
261309

262-
if (!data[tab_id].counts.hasOwnProperty(key)) {
263-
data[tab_id].counts[key] = 0;
310+
// javascript property access counts indexed by script URL
311+
if (!datum.counts.hasOwnProperty(script_url)) {
312+
datum.counts[script_url] = {};
264313
}
265-
266-
data[tab_id].counts[key]++;
314+
var counts = datum.counts[script_url];
315+
if (!counts.hasOwnProperty(key)) {
316+
counts[key] = 0;
317+
}
318+
counts[key]++;
267319
},
268320

269321
get: function (tab_id) {
@@ -300,33 +352,19 @@ module.exports = tabData;
300352
*
301353
*/
302354

303-
/*
304-
* This module needs to work both inside content scripts and the browser popup.
305-
*/
355+
// used by the badge and the popup
356+
module.exports.getAccessCount = function (counts) {
357+
// count unique keys across all counts objects
358+
var props = {};
306359

307-
// acceptable signatures:
308-
// name
309-
// name, message
310-
// name, callback
311-
// name, message, callback
312-
module.exports.sendMessage = function (name, message, callback) {
313-
var args = [{ name: name }];
314-
315-
if (Object.prototype.toString.call(message) == '[object Function]') {
316-
// name, callback
317-
args.push(message);
318-
} else {
319-
if (message) {
320-
// name, message, [callback]
321-
args[0].message = message;
322-
}
323-
if (callback) {
324-
// name, [message], callback
325-
args.push(callback);
360+
// no need for hasOwnProperty loop checks in this context
361+
for (var url in counts) { // jshint ignore:line
362+
for (var prop in counts[url]) { // jshint ignore:line
363+
props[prop] = true;
326364
}
327365
}
328366

329-
chrome.runtime.sendMessage.apply(chrome.runtime, args);
367+
return Object.keys(props).length;
330368
};
331369

332-
},{}]},{},[2])
370+
},{}]},{},[1])

chrome/js/builds/inject.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

chrome/js/builds/injected.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

chrome/js/builds/panel.js

Lines changed: 80 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2-
3-
},{}],2:[function(require,module,exports){
42
/** @jsx React.DOM */
53

64
/*!
@@ -17,7 +15,8 @@
1715
/*jshint newcap:false */
1816

1917
var React = require('react'),
20-
sendMessage = require('../lib/utils').sendMessage;
18+
sendMessage = require('../lib/content_script_utils').sendMessage,
19+
utils = require('../lib/utils');
2120

2221
var PanelApp = React.createClass({displayName: 'PanelApp',
2322
getInitialState: function () {
@@ -71,8 +70,8 @@ var PanelApp = React.createClass({displayName: 'PanelApp',
7170
toggle:this.toggle} ),
7271
React.DOM.hr(null ),
7372
Report(
74-
{fontEnumeration:this.state.fontEnumeration,
75-
counts:this.state.counts} )
73+
{counts:this.state.counts,
74+
fontEnumeration:this.state.fontEnumeration} )
7675
)
7776
);
7877
}
@@ -124,28 +123,62 @@ var Header = React.createClass({displayName: 'Header',
124123

125124
var Report = React.createClass({displayName: 'Report',
126125
render: function () {
127-
var rows = [],
128-
fontEnumeration,
129-
table;
126+
var fontEnumeration,
127+
reports = [];
130128

131129
if (this.props.fontEnumeration) {
132130
fontEnumeration = (
133131
React.DOM.p(null, "Font enumeration detected.")
134132
);
135133
}
136134

135+
Object.keys(this.props.counts).sort().forEach(function (url) {
136+
reports.push(
137+
ScriptReport(
138+
{key:url,
139+
url:url,
140+
counts:this.props.counts[url]} )
141+
);
142+
}, this);
143+
144+
var status = reports.length ?
145+
React.DOM.p(null,
146+
React.DOM.b(null, utils.getAccessCount(this.props.counts)), " property"+' '+
147+
"accesses detected across ", React.DOM.b(null, reports.length), " scripts."
148+
) :
149+
React.DOM.p(null, "No property accesses detected.");
150+
151+
return (
152+
React.DOM.div(null,
153+
fontEnumeration,
154+
status,
155+
reports
156+
)
157+
);
158+
}
159+
});
160+
161+
var ScriptReport = React.createClass({displayName: 'ScriptReport',
162+
render: function () {
163+
var rows = [];
164+
137165
Object.keys(this.props.counts).sort().forEach(function (name) {
138166
rows.push(
139167
ReportRow( {key:name, name:name, count:this.props.counts[name]} )
140168
);
141169
}, this);
142170

143-
if (rows.length) {
144-
table = (
171+
return (
172+
React.DOM.div(null,
173+
React.DOM.p( {title:this.props.url, style:{
174+
margin: '20px 0 5px',
175+
overflow: 'hidden',
176+
textOverflow: 'ellipsis',
177+
whiteSpace: 'nowrap'
178+
}},
179+
this.props.url
180+
),
145181
React.DOM.table(null,
146-
React.DOM.caption(null,
147-
React.DOM.b(null, rows.length), " property accesses detected"
148-
),
149182
React.DOM.thead(null,
150183
React.DOM.tr(null,
151184
React.DOM.th(null, "property"),
@@ -156,13 +189,6 @@ var Report = React.createClass({displayName: 'Report',
156189
rows
157190
)
158191
)
159-
);
160-
}
161-
162-
return (
163-
React.DOM.div(null,
164-
fontEnumeration,
165-
table ? table : React.DOM.p(null, "No property accesses detected.")
166192
)
167193
);
168194
}
@@ -185,7 +211,7 @@ var ReportRow = React.createClass({displayName: 'ReportRow',
185211

186212
React.renderComponent(PanelApp(null ), document.body);
187213

188-
},{"../lib/utils":3}],3:[function(require,module,exports){
214+
},{"../lib/content_script_utils":2,"../lib/utils":3}],2:[function(require,module,exports){
189215
/*!
190216
* Chameleon
191217
*
@@ -198,7 +224,11 @@ React.renderComponent(PanelApp(null ), document.body);
198224
*/
199225

200226
/*
201-
* This module needs to work both inside content scripts and the browser popup.
227+
* This module needs to work both inside content scripts and the rest of the
228+
* extension, like the browser popup.
229+
*
230+
* Content scripts have certain limitations in Chrome:
231+
* https://developer.chrome.com/extensions/content_scripts
202232
*/
203233

204234
// acceptable signatures:
@@ -226,4 +256,31 @@ module.exports.sendMessage = function (name, message, callback) {
226256
chrome.runtime.sendMessage.apply(chrome.runtime, args);
227257
};
228258

229-
},{}]},{},[2])
259+
},{}],3:[function(require,module,exports){
260+
/*!
261+
* Chameleon
262+
*
263+
* Copyright 2014 ghostwords.
264+
*
265+
* This Source Code Form is subject to the terms of the Mozilla Public
266+
* License, v. 2.0. If a copy of the MPL was not distributed with this
267+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
268+
*
269+
*/
270+
271+
// used by the badge and the popup
272+
module.exports.getAccessCount = function (counts) {
273+
// count unique keys across all counts objects
274+
var props = {};
275+
276+
// no need for hasOwnProperty loop checks in this context
277+
for (var url in counts) { // jshint ignore:line
278+
for (var prop in counts[url]) { // jshint ignore:line
279+
props[prop] = true;
280+
}
281+
}
282+
283+
return Object.keys(props).length;
284+
};
285+
286+
},{}]},{},[1])

src/js/background.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ var ALL_URLS = { urls: ['http://*/*', 'https://*/*'] },
1717
ENABLED = true;
1818

1919
var tabData = require('../lib/tabdata'),
20-
sendMessage = require('../lib/utils').sendMessage;
20+
sendMessage = require('../lib/content_script_utils').sendMessage,
21+
utils = require('../lib/utils');
2122

2223
// TODO https://developer.chrome.com/extensions/webRequest#life_cycle_footnote
2324
// The following headers are currently not provided to the onBeforeSendHeaders event.
@@ -100,7 +101,7 @@ function updateBadge(tab_id) {
100101
text = '';
101102

102103
if (data) {
103-
text = _.size(data.counts).toString();
104+
text = utils.getAccessCount(data.counts).toString();
104105
}
105106

106107
chrome.browserAction.setBadgeText({

src/js/inject.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
(function () {
1919

20-
var sendMessage = require('../lib/utils').sendMessage;
20+
var sendMessage = require('../lib/content_script_utils').sendMessage;
2121

2222
function insertScript(url, data) {
2323
var head = document.getElementsByTagName('head')[0] || document.documentElement,

0 commit comments

Comments
 (0)