Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

User-agent aliases, strong task selection, and cssproperties task

  • Loading branch information...
commit 535fb8348df4f9585f3a808d96110b15a054efff 1 parent 31f85ed
@jamesgpearce authored
Showing with 116 additions and 5 deletions.
  1. +13 −1 README.md
  2. +97 −3 confess.js
  3. +6 −1 config.json
View
14 README.md
@@ -143,6 +143,11 @@ Using the <code>performance</code> task argument will get confess.js to load the
It will list the fastest and slowest resources, and also the largest and smallest (subject to the availability of the <code>content-length</code> header). With the verbose configuration enabled, it will also list out all the resources loaded as part of the page, and display an ASCII-art waterfall chart of their timings.
+## The cssproperties task
+
+Using the <code>cssproperties</code> task argument will get confess.js to load the page, and then parse the styles in the DOM and CSSOM to identify which CSS properties are being used by the page.
+
+
## Configuration
The following is the default <code>config.json</code> file for confess.js, but you can of course alter any of the values in this file, or a new config file of your own.
@@ -150,6 +155,11 @@ The following is the default <code>config.json</code> file for confess.js, but y
{
"task": "appcache",
"userAgent": "default",
+ "userAgentAliases": {
+ "iphone": "Mozilla/5.0 (iPhone; ...",
+ "android": "Mozilla/5.0 (Linux; U; Android ...",
+ "chrome": "Mozilla/5.0 (Macintosh; Intel Mac OS X ..."
+ },
"wait": 0,
"consolePrefix": "#",
"verbose": true,
@@ -163,10 +173,12 @@ The following is the default <code>config.json</code> file for confess.js, but y
These properties are used as follows:
- * <code>task</code> - the default type of task you want confess.js to perform, if not specified on the command line. <code>appcache</code> and <code>performance</code> are the only supported values
+ * <code>task</code> - the default type of task you want confess.js to perform, if not specified on the command line. <code>appcache</code>, <code>performance</code>, and <code>cssproperties</code> are the supported values
* <code>userAgent</code> - the user-agent to make the request as, or <code>default</code> to use PhantomJS's usual user-agent string
+ * <code>userAgentAliases</code> - common aliases for the userAgent setting. For example, you could use the setting <code>"userAgent": "iphone"</code> and it will resolve to the iPhone's full UA provided here.
+
* <code>wait</code> - the number of milliseconds to wait after the document has loaded before parsing for resources. This might be useful if you know that a deferred script might be making relevant additions to the DOM.
* <code>consolePrefix</code> - if set, confess.js will output the *browser's* console to the standard output. Useful for detecting if there are also any issues with the app's execution itself.
View
100 confess.js
@@ -4,9 +4,23 @@ var confess = {
run: function () {
var cliConfig = {};
if (!this.processArgs(cliConfig, [
- {name:'url', def:"http://google.com", req:true, desc:"the URL of the app to cache"},
- {name:'task', def:"appcache", req:false, desc:"the task to perform"},
- {name:'configFile', def:"config.json", req:false, desc:"a local configuration file of further confess settings"},
+ {
+ name: 'url',
+ def: 'http://google.com',
+ req: true,
+ desc: 'the URL of the app to cache'
+ }, {
+ name: 'task',
+ def: 'appcache',
+ req: false,
+ desc: 'the task to perform',
+ oneof: ['performance', 'appcache', 'cssproperties']
+ }, {
+ name: 'configFile',
+ def: 'config.json',
+ req: false,
+ desc: 'a local configuration file of further confess settings'
+ },
])) {
phantom.exit();
return;
@@ -182,6 +196,30 @@ var confess = {
}
},
+ cssproperties: {
+ resourceUrls: {},
+ onResourceRequested: function (page, config, request) {
+ if (config.appcache.urlsFromRequests) {
+ this.appcache.resourceUrls[request.url] = true;
+ }
+ },
+ onLoadFinished: function (page, config, status) {
+ if (status!='success') {
+ console.log('# FAILED TO LOAD');
+ return;
+ }
+ if (config.verbose) {
+ console.log('');
+ this.emitConfig(config, '');
+ }
+ console.log('');
+ console.log('CSS properties used:');
+ for (property in this.getCssProperties(page)) {
+ console.log(property);
+ }
+ }
+ },
+
getFinalUrl: function (page) {
return page.evaluate(function () {
return document.location.toString();
@@ -261,6 +299,51 @@ var confess = {
});
},
+ getCssProperties: function (page) {
+ return page.evaluate(function () {
+ var properties = {},
+ tallyProperty = function (property) {
+ if (!properties[property]) {
+ properties[property] = 0;
+ }
+ properties[property]++;
+ },
+ stylesheets, stylesheetsLength, ss,
+ rules, rulesLength, r,
+ style, styleLength, s,
+ property;
+
+ // properties in stylesheets
+ stylesheets = document.styleSheets;
+ for (ss = 0, stylesheetsLength = stylesheets.length; ss < stylesheetsLength; ss++) {
+ rules = stylesheets[ss].rules;
+ if (!rules) { continue; }
+ for (r = 0, rulesLength = rules.length; r < rulesLength; r++) {
+ if (!rules[r]['style']) { continue; }
+ style = rules[r].style;
+ for (s = 0, styleLength = style.length; s < styleLength; s++) {
+ tallyProperty(style[s]);
+ }
+ }
+ }
+
+ // properties in styles on DOM
+ elements = document.querySelectorAll('*');
+ for (e = 0, elementsLength = elements.length; e < elementsLength; e++) {
+ rules = elements[e].ownerDocument.defaultView.getMatchedCSSRules(elements[e], '');
+ if (!rules) { continue; }
+ for (r = 0, rulesLength = rules.length; r < rulesLength; r++) {
+ if (!rules[r]['style']) { continue; }
+ style = rules[r].style;
+ for (s = 0, styleLength = style.length; s < styleLength; s++) {
+ tallyProperty(style[s]);
+ }
+ }
+ }
+ return properties;
+ });
+ },
+
emitConfig: function (config, prefix) {
console.log(prefix + 'Config:');
for (key in config) {
@@ -286,6 +369,9 @@ var confess = {
}
}
if (config.userAgent && config.userAgent != "default") {
+ if (config.userAgentAliases[config.userAgent]) {
+ config.userAgent = config.userAgentAliases[config.userAgent];
+ }
page.settings.userAgent = config.userAgent;
}
['onInitialized', 'onLoadStarted', 'onResourceRequested', 'onResourceReceived']
@@ -316,6 +402,10 @@ var confess = {
phantom.exit();
}
};
+ } else {
+ page.onLoadFinished = function (status) {
+ phantom.exit();
+ }
}
page.open(config.url);
},
@@ -334,6 +424,10 @@ var confess = {
config[argument.name] = argument.def;
}
}
+ if (argument.oneof && argument.oneof.indexOf(config[argument.name])==-1) {
+ console.log('"' + argument.name + '" argument must be one of: ' + argument.oneof.join(', '));
+ ok = false;
+ }
a++;
});
return ok;
View
7 config.json
@@ -1,6 +1,11 @@
{
"task": "appcache",
- "userAgent": "default",
+ "userAgent": "chrome",
+ "userAgentAliases": {
+ "iphone": "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7",
+ "android": "Mozilla/5.0 (Linux; U; Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
+ "chrome": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.12 Safari/535.11"
+ },
"wait": 0,
"consolePrefix": "#",
"verbose": true,
Please sign in to comment.
Something went wrong with that request. Please try again.