You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

719 lines
20 KiB

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