Improved environment variable detection

main
ElbertF 14 years ago
parent 3cdb11e0b2
commit 9f18b3dec6

@ -1,8 +1,4 @@
if ( typeof(wappalyzer) == 'undefined' ) if ( typeof wappalyzer != 'undefined' ) {
{
var wappalyzer = {};
}
wappalyzer.cats = { wappalyzer.cats = {
1: { name: 'CMS', plural: 'CMS' }, 1: { name: 'CMS', plural: 'CMS' },
2: { name: 'Message Board', plural: 'Message Boards' }, 2: { name: 'Message Board', plural: 'Message Boards' },
@ -224,3 +220,4 @@ wappalyzer.apps = {
'Zen Cart': { cats: { 1: 6 }, html: /<meta name=("|')generator("|') [^>]+Zen Cart/i }, 'Zen Cart': { cats: { 1: 6 }, html: /<meta name=("|')generator("|') [^>]+Zen Cart/i },
'Zend': { cats: { 1: 18 }, headers: { 'X-Powered-By': /Zend/ } } 'Zend': { cats: { 1: 18 }, headers: { 'X-Powered-By': /Zend/ } }
}; };
}

@ -1,68 +1,53 @@
var wappalyzer = {}; (function() {
self = {
wappalyzer =
{
prevUrl: '', prevUrl: '',
init: function() init: function() {
{ self.log('init');
wappalyzer.log('init');
addEventListener('DOMContentLoaded', wappalyzer.onPageLoad, false); addEventListener('DOMContentLoaded', self.onPageLoad, false);
}, },
log: function(message) log: function(message) {
{
var consoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService); var consoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
consoleService.logStringMessage("Wappalyzer content.js: " + message); consoleService.logStringMessage("Wappalyzer content.js: " + message);
}, },
onPageLoad: function(e) onPageLoad: function(e) {
{ self.log('onPageLoad');
wappalyzer.log('onPageLoad');
sendAsyncMessage('wappalyzer:onPageLoad', { self.getEnvironmentVars();
href: content.document.location.href,
html: content.document.documentElement.innerHTML,
headers: [],
environmentVars: wappalyzer.getEnvironmentVars()
});
}, },
onUrlChange: function(request) onUrlChange: function(request) {
{ self.log('onUrlChange');
wappalyzer.log('onUrlChange');
self.getEnvironmentVars();
}, },
urlChange: urlChange: {
{ QueryInterface: function(iid) {
QueryInterface: function(iid)
{
if ( iid.equals(Components.interfaces.nsIWebProgressListener) || if ( iid.equals(Components.interfaces.nsIWebProgressListener) ||
iid.equals(Components.interfaces.nsISupportsWeakReference) || iid.equals(Components.interfaces.nsISupportsWeakReference) ||
iid.equals(Components.interfaces.nsISupports) ) iid.equals(Components.interfaces.nsISupports) ) {
{
return this; return this;
} }
throw Components.results.NS_NOINTERFACE; throw Components.results.NS_NOINTERFACE;
}, },
onLocationChange: function(progress, request, url) onLocationChange: function(progress, request, url) {
{ if ( !url ) {
if ( !url ) self.prevUrl = '';
{
wappalyzer.prevUrl = '';
return; return;
} }
if ( url.spec != wappalyzer.prevUrl ) if ( url.spec != self.prevUrl ) {
{ self.prevUrl = url.spec;
wappalyzer.prevUrl = url.spec;
wappalyzer.onUrlChange(request); self.onUrlChange(request);
} }
}, },
@ -72,28 +57,52 @@ wappalyzer =
onSecurityChange: function(a, b, c) {} onSecurityChange: function(a, b, c) {}
}, },
getEnvironmentVars: function() getEnvironmentVars: function() {
{ self.log('getEnvironmentVars');
var environmentVars = '';
try {
var element = content.document.createElement('wappalyzerData'); var element = content.document.createElement('wappalyzerData');
element.setAttribute('id', 'wappalyzer-data'); element.setAttribute('id', 'wappalyzerData');
element.setAttribute('style', 'display: none;');
content.document.documentElement.appendChild(element); element.addEventListener('wappalyzerEvent', (function(event) {
environmentVars = event.target.innerHTML.split(' ');
self.log('getEnvironmentVars: ' + environmentVars);
var script = content.document.createElement('script'); element.parentNode.removeChild(element);
script.innerHTML = 'for ( i in window ) document.getElementById("wappalyzer-data").innerHTML += i + " ";'; sendAsyncMessage('wappalyzer:onPageLoad', {
href: content.document.location.href,
html: content.document.documentElement.innerHTML,
headers: [],
environmentVars: environmentVars
});
}), true);
content.document.documentElement.appendChild(script); content.document.documentElement.appendChild(element);
var environmentVars = content.document.getElementById('wappalyzer-data').innerHTML.split(' '); content.location.href = 'javascript:' +
'(function() {' +
'try {' +
'for ( i in window ) {' +
'window.document.getElementById("wappalyzerData").innerHTML += i + " ";' +
'}' +
element.parentNode.removeChild(element); 'var event = document.createEvent("Events");' + 'event.initEvent("wappalyzerEvent", true, false);' +
script .parentNode.removeChild(script);
'document.getElementById("wappalyzerData").dispatchEvent(event);' +
'}' +
'catch(e) { }' +
'})();';
}
catch(e) { }
return environmentVars; return environmentVars;
} }
}; }
wappalyzer.init(); self.init();
})();

@ -1,80 +1,62 @@
if ( typeof('wappalyzer') != 'undefined' ) if ( typeof 'wappalyzer' != 'undefined' ) {
{ wappalyzer.evaluateCustomApps = function(feedback) {
var wappalyzer = {};
}
wappalyzer.evaluateCustomApps = function(feedback)
{
wappalyzer.log('evaluateCustomApps'); wappalyzer.log('evaluateCustomApps');
if ( wappalyzer.customApps ) if ( wappalyzer.customApps ) {
{ try {
try
{
var customAppsJSON = JSON.parse(wappalyzer.customApps); var customAppsJSON = JSON.parse(wappalyzer.customApps);
for ( appName in customAppsJSON ) for ( appName in customAppsJSON ) {
{
wappalyzer.apps[appName] = {}; wappalyzer.apps[appName] = {};
// Icon // Icon
if ( typeof(customAppsJSON[appName].icon) == 'string' ) if ( typeof(customAppsJSON[appName].icon) == 'string' ) {
{
wappalyzer.apps[appName].icon = customAppsJSON[appName].icon; wappalyzer.apps[appName].icon = customAppsJSON[appName].icon;
} }
else else {
{
wappalyzer.apps[appName].icon = 'chrome://wappalyzer/skin/app_icons/_placeholder.ico'; wappalyzer.apps[appName].icon = 'chrome://wappalyzer/skin/app_icons/_placeholder.ico';
} }
// Categories // Categories
if ( typeof(customAppsJSON[appName].categories) == 'object' ) if ( typeof(customAppsJSON[appName].categories) == 'object' ) {
{
wappalyzer.apps[appName].cats = {}; wappalyzer.apps[appName].cats = {};
for ( i in customAppsJSON[appName].categories ) for ( i in customAppsJSON[appName].categories ) {
{
wappalyzer.apps[appName].cats[i] = parseInt(customAppsJSON[appName].categories[i]); wappalyzer.apps[appName].cats[i] = parseInt(customAppsJSON[appName].categories[i]);
} }
} }
// HTML // HTML
if ( typeof(customAppsJSON[appName].html) == 'string' ) if ( typeof(customAppsJSON[appName].html) == 'string' ) {
{
wappalyzer.apps[appName].html = new RegExp(customAppsJSON[appName].html, 'i'); wappalyzer.apps[appName].html = new RegExp(customAppsJSON[appName].html, 'i');
} }
// URL // URL
if ( typeof(customAppsJSON[appName].url) == 'string' ) if ( typeof(customAppsJSON[appName].url) == 'string' ) {
{
wappalyzer.apps[appName].url = new RegExp(customAppsJSON[appName].url, 'i'); wappalyzer.apps[appName].url = new RegExp(customAppsJSON[appName].url, 'i');
} }
// Headers // Headers
if ( typeof(customAppsJSON[appName].headers) == 'object' ) if ( typeof(customAppsJSON[appName].headers) == 'object' ) {
{
wappalyzer.apps[appName].headers = {}; wappalyzer.apps[appName].headers = {};
for ( headerName in customAppsJSON[appName].headers ) for ( headerName in customAppsJSON[appName].headers ) {
{
wappalyzer.apps[appName].headers[headerName] = new RegExp(customAppsJSON[appName].headers[headerName], 'i'); wappalyzer.apps[appName].headers[headerName] = new RegExp(customAppsJSON[appName].headers[headerName], 'i');
} }
} }
} }
if ( feedback ) if ( feedback ) {
{
alert('Ok'); alert('Ok');
} }
} }
catch(e) catch(e) {
{
wappalyzer.log('JSON error in custom applications'); wappalyzer.log('JSON error in custom applications');
if ( feedback ) if ( feedback ) {
{
alert('Error: malformed JSON'); alert('Error: malformed JSON');
} }
} }
} }
}; };
}

@ -1,12 +1,7 @@
// Wappalyzer by ElbertF 2009 http://elbertf.com // Wappalyzer by ElbertF 2009 http://elbertf.com
var wappalyzer = {}; var wappalyzer = (function() {
self = {
addEventListener('load', function() { wappalyzer.init(); }, false);
addEventListener('unload', function() { wappalyzer.sendReport(); }, false);
wappalyzer =
{
apps: {}, apps: {},
appsDetected: 0, appsDetected: 0,
autoDetect: true, autoDetect: true,
@ -33,164 +28,151 @@ wappalyzer =
strings: {}, strings: {},
version: '', version: '',
init: function() init: function() {
{ self.log('init');
wappalyzer.log('init');
wappalyzer.browser = gBrowser; self.browser = gBrowser;
wappalyzer.strings = document.getElementById('wappalyzer-strings'); self.strings = document.getElementById('wappalyzer-strings');
// Preferences // Preferences
wappalyzer.prefs = Components.classes['@mozilla.org/preferences-service;1'].getService(Components.interfaces.nsIPrefService).getBranch('wappalyzer.'); self.prefs = Components.classes['@mozilla.org/preferences-service;1'].getService(Components.interfaces.nsIPrefService).getBranch('wappalyzer.');
wappalyzer.prefs.QueryInterface(Components.interfaces.nsIPrefBranch2); self.prefs.QueryInterface(Components.interfaces.nsIPrefBranch2);
wappalyzer.prefs.addObserver('', wappalyzer, false); self.prefs.addObserver('', wappalyzer, false);
wappalyzer.showApps = wappalyzer.prefs.getIntPref('showApps'); self.showApps = self.prefs.getIntPref( 'showApps');
wappalyzer.autoDetect = wappalyzer.prefs.getBoolPref('autoDetect'); self.autoDetect = self.prefs.getBoolPref('autoDetect');
wappalyzer.customApps = wappalyzer.prefs.getCharPref('customApps'); self.customApps = self.prefs.getCharPref('customApps');
wappalyzer.debug = wappalyzer.prefs.getBoolPref('debug'); self.debug = self.prefs.getBoolPref('debug');
wappalyzer.enableTracking = wappalyzer.prefs.getBoolPref('enableTracking'); self.enableTracking = self.prefs.getBoolPref('enableTracking');
wappalyzer.newInstall = wappalyzer.prefs.getBoolPref('newInstall'); self.newInstall = self.prefs.getBoolPref('newInstall');
wappalyzer.version = wappalyzer.prefs.getCharPref('version'); self.version = self.prefs.getCharPref('version');
for ( var i = 1; i <= 23; i ++ ) for ( var i = 1; i <= 23; i ++ ) {
{ self.showCats[i] = self.prefs.getBoolPref('cat' + i);
wappalyzer.showCats[i] = wappalyzer.prefs.getBoolPref('cat' + i);
} }
var locationPref = wappalyzer.prefs.getIntPref('location'); var locationPref = self.prefs.getIntPref('location');
wappalyzer.moveLocation(locationPref); self.moveLocation(locationPref);
// Open page after upgrade // Open page after upgrade
try try {
{
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch); var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
var enabledItems = prefs.getCharPref('extensions.enabledItems'); var enabledItems = prefs.getCharPref('extensions.enabledAddons');
var version = enabledItems.replace(/(^.*wappalyzer[^:]+:)([^,]+),.*$/, '$2'); var version = enabledItems.replace(/(^.*wappalyzer[^:]+:)([^,]+),.*$/, '$2');
if ( version && wappalyzer.version != version ) if ( version && self.version != version ) {
{ self.browser.addEventListener('load', self.upgradeSuccess, false);
wappalyzer.browser.addEventListener('load', wappalyzer.upgradeSuccess, false);
wappalyzer.version = version; self.version = version;
wappalyzer.prefs.setCharPref('version', wappalyzer.version); self.prefs.setCharPref('version', self.version);
}
} }
catch(e)
{
} }
catch(e) { }
// Open page after installation // Open page after installation
if ( wappalyzer.newInstall ) if ( self.newInstall ) {
{ self.prefs.setBoolPref('newInstall', false);
wappalyzer.prefs.setBoolPref('newInstall', false);
wappalyzer.browser.addEventListener('load', wappalyzer.installSuccess, false); self.browser.addEventListener('load', self.installSuccess, false);
} }
if ( typeof messageManager != 'undefined' )
{
// Listen messages sent from the content process // Listen messages sent from the content process
messageManager.addMessageListener('wappalyzer:onPageLoad', wappalyzer.onContentPageLoad); if ( typeof messageManager != 'undefined' ) {
messageManager.addMessageListener('wappalyzer:onPageLoad', self.onContentPageLoad);
messageManager.loadFrameScript('chrome://wappalyzer/content/content.js', true); messageManager.loadFrameScript('chrome://wappalyzer/content/content.js', true);
} }
// Listen for URL changes // Listen for URL changes
wappalyzer.browser.addProgressListener(wappalyzer.urlChange, Components.interfaces.nsIWebProgress.NOTIFY_LOCATION); self.browser.addProgressListener(self.urlChange, Components.interfaces.nsIWebProgress.NOTIFY_LOCATION);
// Listen for page loads // Listen for page loads
wappalyzer.browser.addEventListener('DOMContentLoaded', wappalyzer.onPageLoad, true); self.browser.addEventListener('DOMContentLoaded', self.onPageLoad, true);
wappalyzer.evaluateCustomApps(); self.evaluateCustomApps();
}, },
log: function(message) // Log messages to console
{ log: function(message) {
if ( wappalyzer.debug && message ) if ( self.debug && message ) {
{
var consoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService); var consoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
consoleService.logStringMessage("Wappalyzer: " + message); consoleService.logStringMessage("Wappalyzer: " + message);
} }
}, },
observe: function(subject, topic, data) // Listen for preference changes
{ observe: function(subject, topic, data) {
if ( topic != 'nsPref:changed' ) if ( topic != 'nsPref:changed' ) {
{
return; return;
} }
switch(data) switch(data) {
{
case 'autoDetect': case 'autoDetect':
wappalyzer.autoDetect = wappalyzer.prefs.getBoolPref('autoDetect'); self.autoDetect = self.prefs.getBoolPref('autoDetect');
break; break;
case 'customApps': case 'customApps':
wappalyzer.customApps = wappalyzer.prefs.getCharPref('customApps'); self.customApps = self.prefs.getCharPref('customApps');
break; break;
case 'debug': case 'debug':
wappalyzer.debug = wappalyzer.prefs.getBoolPref('debug'); self.debug = self.prefs.getBoolPref('debug');
break; break;
case 'enableTracking': case 'enableTracking':
wappalyzer.enableTracking = wappalyzer.prefs.getBoolPref('enableTracking'); self.enableTracking = self.prefs.getBoolPref('enableTracking');
break; break;
case 'showApps': case 'showApps':
wappalyzer.showApps = wappalyzer.prefs.getIntPref('showApps'); self.showApps = self.prefs.getIntPref('showApps');
break; break;
case 'location': case 'location':
var locationPref = wappalyzer.prefs.getIntPref('location'); var locationPref = self.prefs.getIntPref('location');
wappalyzer.moveLocation(locationPref); self.moveLocation(locationPref);
break; break;
case 'cat1': wappalyzer.showCats[1] = wappalyzer.prefs.getIntPref('cat1'); break; case 'cat1': self.showCats[ 1] = self.prefs.getIntPref( 'cat1'); break;
case 'cat2': wappalyzer.showCats[2] = wappalyzer.prefs.getIntPref('cat2'); break; case 'cat2': self.showCats[ 2] = self.prefs.getIntPref( 'cat2'); break;
case 'cat3': wappalyzer.showCats[3] = wappalyzer.prefs.getIntPref('cat3'); break; case 'cat3': self.showCats[ 3] = self.prefs.getIntPref( 'cat3'); break;
case 'cat4': wappalyzer.showCats[4] = wappalyzer.prefs.getIntPref('cat4'); break; case 'cat4': self.showCats[ 4] = self.prefs.getIntPref( 'cat4'); break;
case 'cat5': wappalyzer.showCats[5] = wappalyzer.prefs.getIntPref('cat5'); break; case 'cat5': self.showCats[ 5] = self.prefs.getIntPref( 'cat5'); break;
case 'cat6': wappalyzer.showCats[6] = wappalyzer.prefs.getIntPref('cat6'); break; case 'cat6': self.showCats[ 6] = self.prefs.getIntPref( 'cat6'); break;
case 'cat7': wappalyzer.showCats[7] = wappalyzer.prefs.getIntPref('cat7'); break; case 'cat7': self.showCats[ 7] = self.prefs.getIntPref( 'cat7'); break;
case 'cat8': wappalyzer.showCats[8] = wappalyzer.prefs.getIntPref('cat8'); break; case 'cat8': self.showCats[ 8] = self.prefs.getIntPref( 'cat8'); break;
case 'cat9': wappalyzer.showCats[9] = wappalyzer.prefs.getIntPref('cat9'); break; case 'cat9': self.showCats[ 9] = self.prefs.getIntPref( 'cat9'); break;
case 'cat10': wappalyzer.showCats[10] = wappalyzer.prefs.getIntPref('cat10'); break; case 'cat10': self.showCats[10] = self.prefs.getIntPref('cat10'); break;
case 'cat11': wappalyzer.showCats[11] = wappalyzer.prefs.getIntPref('cat11'); break; case 'cat11': self.showCats[11] = self.prefs.getIntPref('cat11'); break;
case 'cat12': wappalyzer.showCats[12] = wappalyzer.prefs.getIntPref('cat12'); break; case 'cat12': self.showCats[12] = self.prefs.getIntPref('cat12'); break;
case 'cat13': wappalyzer.showCats[13] = wappalyzer.prefs.getIntPref('cat13'); break; case 'cat13': self.showCats[13] = self.prefs.getIntPref('cat13'); break;
case 'cat14': wappalyzer.showCats[14] = wappalyzer.prefs.getIntPref('cat14'); break; case 'cat14': self.showCats[14] = self.prefs.getIntPref('cat14'); break;
case 'cat15': wappalyzer.showCats[15] = wappalyzer.prefs.getIntPref('cat15'); break; case 'cat15': self.showCats[15] = self.prefs.getIntPref('cat15'); break;
case 'cat16': wappalyzer.showCats[16] = wappalyzer.prefs.getIntPref('cat16'); break; case 'cat16': self.showCats[16] = self.prefs.getIntPref('cat16'); break;
case 'cat17': wappalyzer.showCats[17] = wappalyzer.prefs.getIntPref('cat17'); break; case 'cat17': self.showCats[17] = self.prefs.getIntPref('cat17'); break;
case 'cat18': wappalyzer.showCats[18] = wappalyzer.prefs.getIntPref('cat18'); break; case 'cat18': self.showCats[18] = self.prefs.getIntPref('cat18'); break;
case 'cat19': wappalyzer.showCats[19] = wappalyzer.prefs.getIntPref('cat19'); break; case 'cat19': self.showCats[19] = self.prefs.getIntPref('cat19'); break;
case 'cat20': wappalyzer.showCats[20] = wappalyzer.prefs.getIntPref('cat20'); break; case 'cat20': self.showCats[20] = self.prefs.getIntPref('cat20'); break;
case 'cat21': wappalyzer.showCats[21] = wappalyzer.prefs.getIntPref('cat21'); break; case 'cat21': self.showCats[21] = self.prefs.getIntPref('cat21'); break;
case 'cat22': wappalyzer.showCats[22] = wappalyzer.prefs.getIntPref('cat22'); break; case 'cat22': self.showCats[22] = self.prefs.getIntPref('cat22'); break;
case 'cat23': wappalyzer.showCats[23] = wappalyzer.prefs.getIntPref('cat23'); break; case 'cat23': self.showCats[23] = self.prefs.getIntPref('cat23'); break;
} }
}, },
openTab: function(url) openTab: function(url) {
{ self.browser.selectedTab = self.browser.addTab(url);
wappalyzer.browser.selectedTab = wappalyzer.browser.addTab(url);
}, },
moveLocation: function(locationPref) { moveLocation: function(locationPref) {
wappalyzer.log('moveLocation'); self.log('moveLocation');
switch ( locationPref ) switch ( locationPref ) {
{
case 1: case 1:
var containerId = 'wappalyzer-statusbar'; var containerId = 'wappalyzer-statusbar';
@ -213,18 +195,17 @@ wappalyzer =
e.appendChild(container); e.appendChild(container);
}, },
onPageLoad: function(event) onPageLoad: function(event) {
{ self.log('onPageLoad');
wappalyzer.log('onPageLoad');
var target = event.originalTarget; var target = event.originalTarget;
if ( !target.request ) if ( !target.request ) {
{ self.request = false;
wappalyzer.request = false;
} }
wappalyzer.analyzePage( self.analyzePage(
target.documentElement,
target.location.href, target.location.href,
target.documentElement.innerHTML, target.documentElement.innerHTML,
[], [],
@ -234,11 +215,11 @@ wappalyzer =
); );
}, },
onContentPageLoad: function(message) onContentPageLoad: function(message) {
{ self.log('onContentPageLoad');
wappalyzer.log('onContentPageLoad');
wappalyzer.analyzePage( self.analyzePage(
null,
message.json.href, message.json.href,
message.json.html, message.json.html,
message.json.headers, message.json.headers,
@ -248,24 +229,19 @@ wappalyzer =
); );
}, },
onUrlChange: function(request) onUrlChange: function(request) {
{ self.log('onUrlChange');
wappalyzer.log('onUrlChange');
wappalyzer.clearDetectedApps(); self.clearDetectedApps();
var doc = wappalyzer.browser.contentDocument; var doc = self.browser.contentDocument;
if ( !doc.request )
{
doc.request = request;
}
wappalyzer.request = doc.request; self.request = doc.request ? doc.request : request;
wappalyzer.currentTab = false; self.currentTab = false;
wappalyzer.analyzePage( self.analyzePage(
doc,
doc.location.href ? doc.location.href : '', doc.location.href ? doc.location.href : '',
doc.documentElement ? doc.documentElement.innerHTML : '', doc.documentElement ? doc.documentElement.innerHTML : '',
[], [],
@ -275,36 +251,30 @@ wappalyzer =
); );
}, },
urlChange: urlChange: {
{ QueryInterface: function(iid) {
QueryInterface: function(iid)
{
if ( iid.equals(Components.interfaces.nsIWebProgressListener) || if ( iid.equals(Components.interfaces.nsIWebProgressListener) ||
iid.equals(Components.interfaces.nsISupportsWeakReference) || iid.equals(Components.interfaces.nsISupportsWeakReference) ||
iid.equals(Components.interfaces.nsISupports) ) iid.equals(Components.interfaces.nsISupports) ) {
{
return this; return this;
} }
throw Components.results.NS_NOINTERFACE; throw Components.results.NS_NOINTERFACE;
}, },
onLocationChange: function(progress, request, url) onLocationChange: function(progress, request, url) {
{ self.log('urlChange.onLocationChange');
wappalyzer.log('urlChange.onLocationChange');
if ( !url ) if ( !url ) {
{ self.prevUrl = '';
wappalyzer.prevUrl = '';
return; return;
} }
if ( url.spec != wappalyzer.prevUrl ) if ( url.spec != self.prevUrl ) {
{ self.prevUrl = url.spec;
wappalyzer.prevUrl = url.spec;
wappalyzer.onUrlChange(request); self.onUrlChange(request);
} }
}, },
@ -314,113 +284,94 @@ wappalyzer =
onSecurityChange: function(a, b, c) {} onSecurityChange: function(a, b, c) {}
}, },
analyzePage: function(href, html, headers, environmentVars, doCount, manualDetect) analyzePage: function(doc, href, html, headers, environmentVars, doCount, manualDetect) {
{ self.log('analyzePage');
wappalyzer.log('analyzePage');
wappalyzer.currentTab = false; self.currentTab = false;
if ( href == wappalyzer.browser.contentDocument.location.href ) if ( href == self.browser.contentDocument.location.href ) {
{ self.currentTab = true;
wappalyzer.currentTab = true;
wappalyzer.clearDetectedApps(); if ( !doc ) {
doc = self.browser.contentDocument;
} }
if ( typeof html == 'undefined' ) self.clearDetectedApps();
{ }
if ( typeof html == 'undefined' ) {
html = ''; html = '';
} }
if ( wappalyzer.autoDetect || ( !wappalyzer.autoDetect && manualDetect ) ) if ( self.autoDetect || ( !self.autoDetect && manualDetect ) ) {
{ // Prevent large documents from slowing things down
// Scan URL, domain and response headers for patterns if ( html.length > 50000 ) {
if ( html.length > 50000 ) // Prevent large documents from slowing things down
{
html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length); html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length);
} }
if ( html ) // Scan URL, domain and response headers for patterns
{ if ( html ) {
// Check cached application names // Check cached application names
if ( typeof wappalyzer.browser.contentDocument.wappalyzerApps != 'undefined' ) if ( doc && typeof doc.detectedApps != 'undefined' ) {
{ for ( i in doc.detectedApps ) {
for ( i in wappalyzer.browser.contentDocument.wappalyzerApps ) var appName = doc.detectedApps[i];
{
var appName = wappalyzer.browser.contentDocument.wappalyzerApps[i]; if ( typeof self.checkUnique[appName] == 'undefined' ) {
self.log('CACHE'); //
if ( typeof wappalyzer.checkUnique[appName] == 'undefined' ) self.showApp(appName, doc, href, doCount);
{
wappalyzer.showApp(appName, href, doCount);
wappalyzer.checkUnique[appName] = true; self.checkUnique[appName] = true;
} }
} }
} }
for ( var appName in wappalyzer.apps ) for ( var appName in self.apps ) {
{ // Don't scan for apps that have already been detected
if ( typeof wappalyzer.checkUnique[appName] == 'undefined' ) // Don't scan for apps that have already been detected if ( typeof self.checkUnique[appName] == 'undefined' ) {
{
// Scan HTML // Scan HTML
if ( typeof wappalyzer.apps[appName].html != 'undefined' ) if ( typeof self.apps[appName].html != 'undefined' ) {
{ var regex = self.apps[appName].html;
var regex = wappalyzer.apps[appName].html;
if ( regex.test(html) ) if ( regex.test(html) ) {
{ self.showApp(appName, doc, href, doCount);
wappalyzer.showApp(appName, href, doCount);
} }
} }
// Scan URL // Scan URL
if ( href && typeof wappalyzer.apps[appName].url != 'undefined' ) if ( href && typeof self.apps[appName].url != 'undefined' ) {
{ var regex = self.apps[appName].url;
var regex = wappalyzer.apps[appName].url;
if ( regex.test(href) ) if ( regex.test(href) ) {
{ self.showApp(appName, doc, href, doCount);
wappalyzer.showApp(appName, href, doCount);
} }
} }
// Scan response headers // Scan response headers
if ( typeof wappalyzer.apps[appName].headers != 'undefined' && wappalyzer.request ) if ( typeof self.apps[appName].headers != 'undefined' && self.request ) {
{ for ( var header in self.apps[appName].headers ) {
for ( var header in wappalyzer.apps[appName].headers ) var regex = self.apps[appName].headers[header];
{
var regex = wappalyzer.apps[appName].headers[header];
try try {
{ if ( regex.test(self.request.nsIHttpChannel.getResponseHeader(header)) ) {
if ( regex.test(wappalyzer.request.nsIHttpChannel.getResponseHeader(header)) ) self.showApp(appName, doc, href, doCount);
{
wappalyzer.showApp(appName, href, doCount);
} }
} }
catch(e) catch(e) { }
{
}
} }
} }
// Scan environment variables // Scan environment variables
if ( environmentVars && typeof wappalyzer.apps[appName].env != 'undefined' ) if ( environmentVars && typeof self.apps[appName].env != 'undefined' ) {
{ var regex = self.apps[appName].env;
var regex = wappalyzer.apps[appName].env;
for ( var i in environmentVars ) for ( var i in environmentVars ) {
{ try {
try if ( regex.test(environmentVars[i]) ) {
{ self.showApp(appName, doc, href, doCount);
if ( regex.test(environmentVars[i]) )
{
wappalyzer.showApp(appName, href, doCount);
}
} }
catch(e)
{
} }
catch(e) { }
} }
} }
} }
@ -431,48 +382,41 @@ wappalyzer =
} }
}, },
showApp: function(detectedApp, href, doCount) showApp: function(detectedApp, doc, href, doCount) {
{ self.log('showApp ' + detectedApp);
wappalyzer.log('showApp ' + detectedApp);
self.report(detectedApp, href);
// Keep detected application names in memory // Keep detected application names in memory
if ( typeof wappalyzer.browser.contentDocument.wappalyzerApps == 'undefined' ) if ( doc ) {
{ if ( typeof doc.detectedApps == 'undefined' ) {
wappalyzer.browser.contentDocument.wappalyzerApps = []; doc.detectedApps = [];
} }
wappalyzer.browser.contentDocument.wappalyzerApps.push(detectedApp); doc.detectedApps.push(detectedApp);
}
wappalyzer.report(detectedApp, href);
if ( detectedApp && typeof wappalyzer.checkUnique[detectedApp] == 'undefined' ) if ( detectedApp && typeof self.checkUnique[detectedApp] == 'undefined' ) {
{
var show = false; var show = false;
for ( var i in wappalyzer.apps[detectedApp].cats ) for ( var i in self.apps[detectedApp].cats ) {
{ if ( self.showCats[self.apps[detectedApp].cats[i]] ) {
if ( wappalyzer.showCats[wappalyzer.apps[detectedApp].cats[i]] )
{
show = true; show = true;
break; break;
} }
} }
if ( show ) if ( show && self.currentTab ) {
{
var e = document.getElementById('wappalyzer-detected-apps'); var e = document.getElementById('wappalyzer-detected-apps');
if ( wappalyzer.autoDetect ) if ( self.autoDetect ) {
{ if ( self.showApps == 2 ) {
if ( wappalyzer.showApps == 2 )
{
document.getElementById('wappalyzer-icon').setAttribute('src', 'chrome://wappalyzer/skin/icon16x16_hot.ico'); document.getElementById('wappalyzer-icon').setAttribute('src', 'chrome://wappalyzer/skin/icon16x16_hot.ico');
document.getElementById('wappalyzer-detected-apps').style.display = 'none'; document.getElementById('wappalyzer-detected-apps').style.display = 'none';
} }
else else {
{
// Hide Wappalyzer icon // Hide Wappalyzer icon
document.getElementById('wappalyzer-icon').style.display = 'none'; document.getElementById('wappalyzer-icon').style.display = 'none';
@ -482,27 +426,23 @@ wappalyzer =
// Show app icon and label // Show app icon and label
var child = document.createElement('image'); var child = document.createElement('image');
if ( typeof wappalyzer.apps[detectedApp].icon == 'string' ) if ( typeof self.apps[detectedApp].icon == 'string' ) {
{ child.setAttribute('src', self.apps[detectedApp].icon);
child.setAttribute('src', wappalyzer.apps[detectedApp].icon);
} }
else else {
{
child.setAttribute('src', 'chrome://wappalyzer/skin/icons/' + detectedApp + '.ico'); child.setAttribute('src', 'chrome://wappalyzer/skin/icons/' + detectedApp + '.ico');
} }
child.setAttribute('class', 'wappalyzer-icon'); child.setAttribute('class', 'wappalyzer-icon');
if ( wappalyzer.appsDetected ) if ( self.appsDetected ) {
{
child.setAttribute('style', 'margin-left: .5em'); child.setAttribute('style', 'margin-left: .5em');
} }
e.appendChild(child); e.appendChild(child);
} }
if ( wappalyzer.showApps == 0 ) if ( self.showApps == 0 ) {
{
var child = document.createElement('label'); var child = document.createElement('label');
child.setAttribute('value', detectedApp); child.setAttribute('value', detectedApp);
@ -514,13 +454,11 @@ wappalyzer =
// Show application in popup // Show application in popup
var e = document.getElementById('wappalyzer-apps'); var e = document.getElementById('wappalyzer-apps');
if ( !wappalyzer.appsDetected ) if ( !self.appsDetected ) {
{
// Remove "no apps detected" message // Remove "no apps detected" message
document.getElementById('wappalyzer-apps').removeChild(document.getElementById('wappalyzer-no-detected-apps')); document.getElementById('wappalyzer-apps').removeChild(document.getElementById('wappalyzer-no-detected-apps'));
} }
else else {
{
var child = document.createElement('menuseparator'); var child = document.createElement('menuseparator');
e.appendChild(child); e.appendChild(child);
@ -530,29 +468,26 @@ wappalyzer =
child.setAttribute('class', 'menuitem-iconic'); child.setAttribute('class', 'menuitem-iconic');
child.setAttribute('type', ''); child.setAttribute('type', '');
child.setAttribute('oncommand', 'wappalyzer.openTab(\'' + wappalyzer.homeUrl + 'stats/app/' + escape(detectedApp) + '\');');
if ( typeof wappalyzer.apps[detectedApp].custom == 'undefined' ) child.addEventListener('command', function() { self.openTab(self.homeUrl + 'stats/app/' + escape(detectedApp)); }, false);
{
if ( typeof self.apps[detectedApp].custom == 'undefined' ) {
child.setAttribute('label', detectedApp); child.setAttribute('label', detectedApp);
child.setAttribute('image', 'chrome://wappalyzer/skin/icons/' + detectedApp + '.ico'); child.setAttribute('image', 'chrome://wappalyzer/skin/icons/' + detectedApp + '.ico');
} }
else else {
{ child.setAttribute('label', detectedApp + ' (' + self.strings.getString('wappalyzer.custom') + ')');
child.setAttribute('label', detectedApp + ' (' + wappalyzer.strings.getString('wappalyzer.custom') + ')');
child.setAttribute('disabled', 'true'); child.setAttribute('disabled', 'true');
child.setAttribute('image', wappalyzer.apps[detectedApp].icon); child.setAttribute('image', self.apps[detectedApp].icon);
} }
e.appendChild(child); e.appendChild(child);
if ( wappalyzer.apps[detectedApp].cats ) if ( self.apps[detectedApp].cats ) {
{ for ( var i in self.apps[detectedApp].cats ) {
for ( var i in wappalyzer.apps[detectedApp].cats )
{
var child = document.createElement('menuitem'); var child = document.createElement('menuitem');
child.setAttribute('label', wappalyzer.cats[wappalyzer.apps[detectedApp].cats[i]].name); child.setAttribute('label', self.cats[self.apps[detectedApp].cats[i]].name);
child.setAttribute('disabled', 'true'); child.setAttribute('disabled', 'true');
e.appendChild(child); e.appendChild(child);
@ -560,72 +495,60 @@ wappalyzer =
} }
} }
if ( doCount ) if ( doCount ) {
{ self.report(detectedApp, href);
wappalyzer.report(detectedApp, href);
} }
wappalyzer.appsDetected ++; self.appsDetected ++;
wappalyzer.checkUnique[detectedApp] = true; self.checkUnique[detectedApp] = true;
} }
}, },
report: function(detectedApp, href) report: function(detectedApp, href) {
{ self.log('report');
wappalyzer.log('report');
if ( typeof wappalyzer.apps[detectedApp].custom == 'undefined' ) if ( typeof self.apps[detectedApp].custom == 'undefined' ) {
{
var var
regex = /:\/\/(.[^/]+)/, regex = /:\/\/(.[^/]+)/,
domain = href.match(regex) ? href.match(regex)[1] : '' domain = href.match(regex) ? href.match(regex)[1] : ''
; ;
if ( wappalyzer.enableTracking && wappalyzer.regexDomain.test(domain) && !wappalyzer.regexBlacklist.test(href) ) if ( self.enableTracking && self.regexDomain.test(domain) && !self.regexBlacklist.test(href) ) {
{ if ( typeof self.history[domain] == 'undefined' ) {
if ( typeof wappalyzer.history[domain] == 'undefined' ) self.history[domain] = [];
{
wappalyzer.history[domain] = [];
} }
if ( typeof wappalyzer.history[domain][detectedApp] == 'undefined' ) if ( typeof self.history[domain][detectedApp] == 'undefined' ) {
{ self.history[domain][detectedApp] = 0;
wappalyzer.history[domain][detectedApp] = 0;
} }
wappalyzer.history[domain][detectedApp] ++; self.history[domain][detectedApp] ++;
wappalyzer.hitCount ++; self.hitCount ++;
if ( wappalyzer.hitCount > 200 ) if ( self.hitCount > 200 ) {
{ self.sendReport();
wappalyzer.sendReport();
} }
} }
} }
}, },
sendReport: function()
// Anonymously send the name of the detected apps and domains to wappalyzer.com // Anonymously send the name of the detected apps and domains to wappalyzer.com
// You can turn this off in the options dialog // You can turn this off in the options dialog
// This is used to track the distribution of software, stats are publicly available on the site // This is used to track the distribution of software, stats are publicly available on the site
{ sendReport: function() {
wappalyzer.log('sendReport'); self.log('sendReport');
if ( wappalyzer.enableTracking && !wappalyzer.req ) if ( self.enableTracking && !self.req ) {
{
var report = ''; var report = '';
if ( wappalyzer.history ) if ( self.history ) {
{ for ( var i in self.history ) {
for ( var i in wappalyzer.history )
{
report += '[' + i; report += '[' + i;
for ( var j in wappalyzer.history[i] ) for ( var j in self.history[i] ) {
{ report += '|' + j + ':' + self.history[i][j];
report += '|' + j + ':' + wappalyzer.history[i][j];
} }
report += ']'; report += ']';
@ -633,43 +556,39 @@ wappalyzer =
} }
// Make POST request // Make POST request
wappalyzer.req = new XMLHttpRequest(); self.req = new XMLHttpRequest();
wappalyzer.req.open('POST', wappalyzer.homeUrl + 'report/', true); self.req.open('POST', self.homeUrl + 'report/', true);
wappalyzer.req.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE; self.req.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE;
wappalyzer.req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); self.req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
wappalyzer.req.onreadystatechange = function(e) self.req.onreadystatechange = function(e) {
{ if ( self.req.readyState == 4 ) {
if ( wappalyzer.req.readyState == 4 ) if ( self.req.status == 200 ) {
{
if ( wappalyzer.req.status == 200 )
{
// Reset // Reset
report = ''; report = '';
wappalyzer.hitCount = 0; self.hitCount = 0;
wappalyzer.history = []; self.history = [];
} }
wappalyzer.req.close(); self.req.close();
wappalyzer.req = false; self.req = false;
} }
}; };
wappalyzer.req.send('d=' + encodeURIComponent(report)); self.req.send('d=' + encodeURIComponent(report));
} }
}, },
clearDetectedApps: function() clearDetectedApps: function() {
{ self.log('clearDetectedApps');
wappalyzer.log('clearDetectedApps');
wappalyzer.appsDetected = 0; self.appsDetected = 0;
wappalyzer.checkUnique = []; self.checkUnique = [];
// Show Wappalyzer icon // Show Wappalyzer icon
document.getElementById('wappalyzer-icon').setAttribute('src', 'chrome://wappalyzer/skin/icon16x16.ico'); document.getElementById('wappalyzer-icon').setAttribute('src', 'chrome://wappalyzer/skin/icon16x16.ico');
@ -678,22 +597,20 @@ wappalyzer =
// Clear app icons and labels // Clear app icons and labels
var e = document.getElementById('wappalyzer-detected-apps'); var e = document.getElementById('wappalyzer-detected-apps');
while ( e.childNodes.length > 0 ) while ( e.childNodes.length > 0 ) {
{
e.removeChild(e.childNodes.item(0)); e.removeChild(e.childNodes.item(0));
} }
// Clear application popup // Clear application popup
var e = document.getElementById('wappalyzer-apps'); var e = document.getElementById('wappalyzer-apps');
while ( e.childNodes.length > 0 ) while ( e.childNodes.length > 0 ) {
{
e.removeChild(e.childNodes.item(0)); e.removeChild(e.childNodes.item(0));
} }
var child = document.createElement('menuitem'); var child = document.createElement('menuitem');
child.setAttribute('label', wappalyzer.strings.getString('wappalyzer.noDetectedApps')); child.setAttribute('label', self.strings.getString('wappalyzer.noDetectedApps'));
child.setAttribute('id', 'wappalyzer-no-detected-apps'); child.setAttribute('id', 'wappalyzer-no-detected-apps');
child.setAttribute('class', 'menuitem-iconic'); child.setAttribute('class', 'menuitem-iconic');
child.setAttribute('disabled', 'true'); child.setAttribute('disabled', 'true');
@ -702,17 +619,25 @@ wappalyzer =
e.appendChild(child); e.appendChild(child);
}, },
installSuccess: function() installSuccess: function() {
{ self.log('installSuccess');
wappalyzer.browser.removeEventListener('load', wappalyzer.installSuccess, false);
self.browser.removeEventListener('load', self.installSuccess, false);
wappalyzer.openTab(wappalyzer.homeUrl + 'install/success/'); self.openTab(self.homeUrl + 'install/success/');
}, },
upgradeSuccess: function() upgradeSuccess: function() {
{ self.log('upgradeSuccess');
wappalyzer.browser.removeEventListener('load', wappalyzer.upgradeSuccess, false);
self.browser.removeEventListener('load', self.upgradeSuccess, false);
wappalyzer.openTab(wappalyzer.homeUrl + 'install/upgraded/'); self.openTab(self.homeUrl + 'install/upgraded/');
} }
}; };
addEventListener('load', function() { self.init(); }, false);
addEventListener('unload', function() { self.sendReport(); }, false);
return self;
})();

@ -5,7 +5,7 @@
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#"> <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest"> <Description about="urn:mozilla:install-manifest">
<em:id>wappalyzer@crunchlabz.com</em:id> <em:id>wappalyzer@crunchlabz.com</em:id>
<em:version>1.15</em:version> <em:version>1.15.2</em:version>
<em:type>2</em:type> <em:type>2</em:type>
<em:unpack>true</em:unpack> <em:unpack>true</em:unpack>
@ -14,7 +14,7 @@
<Description> <Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>4.0</em:minVersion> <em:minVersion>4.0</em:minVersion>
<em:maxVersion>7.*</em:maxVersion> <em:maxVersion>8.*</em:maxVersion>
</Description> </Description>
</em:targetApplication> </em:targetApplication>

Binary file not shown.