@ -1,5 +1,5 @@
|
|||||||
content wappalyzer chrome/content/
|
content wappalyzer content/
|
||||||
locale wappalyzer en-US chrome/locale/en-US/
|
locale wappalyzer en-US locale/en-US/
|
||||||
skin wappalyzer classic/1.0 chrome/skin/
|
skin wappalyzer classic/1.0 skin/
|
||||||
|
|
||||||
overlay chrome://browser/content/browser.xul chrome://wappalyzer/content/wappalyzer.xul
|
overlay chrome://browser/content/browser.xul chrome://wappalyzer/content/xul/wappalyzer.xul
|
||||||
|
@ -1,675 +0,0 @@
|
|||||||
// Wappalyzer by ElbertF 2009 http://elbertf.com
|
|
||||||
|
|
||||||
var wappalyzer = (function() {
|
|
||||||
var self = {
|
|
||||||
apps: {},
|
|
||||||
appsDetected: 0,
|
|
||||||
browser: false,
|
|
||||||
cats: {},
|
|
||||||
checkUnique: {},
|
|
||||||
currentTab: false,
|
|
||||||
customApps: '',
|
|
||||||
debug: false,
|
|
||||||
enableTracking: true,
|
|
||||||
githubUrl: 'https://github.com/ElbertF/Wappalyzer',
|
|
||||||
history: {},
|
|
||||||
hitCount: 0,
|
|
||||||
homeUrl: 'http://wappalyzer.com/',
|
|
||||||
hoverTimeout: false,
|
|
||||||
newInstall: false,
|
|
||||||
popupOnHover: true,
|
|
||||||
prevUrl: '',
|
|
||||||
prefs: {},
|
|
||||||
regexBlacklist: /(dev\.|\/admin|\.local)/,
|
|
||||||
regexDomain: /^[a-z0-9._\-]+\.[a-z]+/,
|
|
||||||
req: false,
|
|
||||||
request: false,
|
|
||||||
showApps: 1,
|
|
||||||
showCats: [],
|
|
||||||
strings: {},
|
|
||||||
twitterUrl: 'https://twitter.com/Wappalyzer',
|
|
||||||
version: '',
|
|
||||||
|
|
||||||
init: function() {
|
|
||||||
self.log('init');
|
|
||||||
|
|
||||||
self.browser = gBrowser;
|
|
||||||
|
|
||||||
self.strings = document.getElementById('wappalyzer-strings');
|
|
||||||
|
|
||||||
// Preferences
|
|
||||||
self.prefs = Components.classes['@mozilla.org/preferences-service;1'].getService(Components.interfaces.nsIPrefService).getBranch('wappalyzer.');
|
|
||||||
|
|
||||||
self.prefs.QueryInterface(Components.interfaces.nsIPrefBranch2);
|
|
||||||
self.prefs.addObserver('', wappalyzer, false);
|
|
||||||
|
|
||||||
self.showApps = self.prefs.getIntPref( 'showApps');
|
|
||||||
self.customApps = self.prefs.getCharPref('customApps');
|
|
||||||
self.debug = self.prefs.getBoolPref('debug');
|
|
||||||
self.enableTracking = self.prefs.getBoolPref('enableTracking');
|
|
||||||
self.popupOnHover = self.prefs.getBoolPref('popupOnHover');
|
|
||||||
self.newInstall = self.prefs.getBoolPref('newInstall');
|
|
||||||
self.version = self.prefs.getCharPref('version');
|
|
||||||
|
|
||||||
var i = 0;
|
|
||||||
|
|
||||||
while ( ++ i ) {
|
|
||||||
try {
|
|
||||||
self.showCats[i] = self.prefs.getBoolPref('cat' + i);
|
|
||||||
} catch (e) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var locationPref = self.prefs.getIntPref('location');
|
|
||||||
|
|
||||||
self.moveLocation(locationPref);
|
|
||||||
|
|
||||||
// Open page after installation
|
|
||||||
if ( self.newInstall ) {
|
|
||||||
self.prefs.setBoolPref('newInstall', false);
|
|
||||||
|
|
||||||
gBrowser.addEventListener('DOMContentLoaded', self.installSuccess, false);
|
|
||||||
} else {
|
|
||||||
// Open page after upgrade
|
|
||||||
try {
|
|
||||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
|
|
||||||
|
|
||||||
var enabledItems = prefs.getCharPref('extensions.enabledAddons');
|
|
||||||
var version = enabledItems.replace(/(^.*wappalyzer[^:]+:)([^,]+),.*$/, '$2');
|
|
||||||
|
|
||||||
if ( version && self.version != version ) {
|
|
||||||
gBrowser.addEventListener('DOMContentLoaded', self.upgradeSuccess, false);
|
|
||||||
|
|
||||||
self.version = version;
|
|
||||||
|
|
||||||
self.prefs.setCharPref('version', self.version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(e) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen messages sent from the content process
|
|
||||||
if ( typeof messageManager != 'undefined' ) {
|
|
||||||
messageManager.addMessageListener('wappalyzer:onPageLoad', self.onContentPageLoad);
|
|
||||||
|
|
||||||
messageManager.loadFrameScript('chrome://wappalyzer/content/content.js', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen for URL changes
|
|
||||||
self.browser.addProgressListener(self.urlChange, Components.interfaces.nsIWebProgress.NOTIFY_LOCATION);
|
|
||||||
|
|
||||||
// Listen for page loads
|
|
||||||
self.browser.addEventListener('DOMContentLoaded', self.onPageLoad, true);
|
|
||||||
|
|
||||||
self.evaluateCustomApps();
|
|
||||||
},
|
|
||||||
|
|
||||||
// Log messages to console
|
|
||||||
log: function(message) {
|
|
||||||
if ( self.debug && message ) {
|
|
||||||
var consoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
|
|
||||||
|
|
||||||
consoleService.logStringMessage("Wappalyzer: " + message);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Listen for preference changes
|
|
||||||
observe: function(subject, topic, data) {
|
|
||||||
if ( topic != 'nsPref:changed' ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(true) {
|
|
||||||
case data == 'customApps':
|
|
||||||
self.customApps = self.prefs.getCharPref('customApps');
|
|
||||||
|
|
||||||
break;
|
|
||||||
case data == 'debug':
|
|
||||||
self.debug = self.prefs.getBoolPref('debug');
|
|
||||||
|
|
||||||
break;
|
|
||||||
case data == 'enableTracking':
|
|
||||||
self.enableTracking = self.prefs.getBoolPref('enableTracking');
|
|
||||||
|
|
||||||
break;
|
|
||||||
case data == 'popupOnHover':
|
|
||||||
self.popupOnHover = self.prefs.getBoolPref('popupOnHover');
|
|
||||||
|
|
||||||
self.moveLocation();
|
|
||||||
|
|
||||||
break;
|
|
||||||
case data == 'showApps':
|
|
||||||
self.showApps = self.prefs.getIntPref('showApps');
|
|
||||||
|
|
||||||
break;
|
|
||||||
case data == 'location':
|
|
||||||
var locationPref = self.prefs.getIntPref('location');
|
|
||||||
|
|
||||||
self.moveLocation(locationPref);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case data.test(/^cat[0-9]+$/):
|
|
||||||
var cat = data.replace(/^cat([0-9]+)$/, '$1');
|
|
||||||
|
|
||||||
self.showCats[cat] = self.prefs.getIntPref('cat' + cat);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
openTab: function(url) {
|
|
||||||
self.browser.selectedTab = self.browser.addTab(url);
|
|
||||||
},
|
|
||||||
|
|
||||||
moveLocation: function(locationPref) {
|
|
||||||
self.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';
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
var containerId = 'urlbar-icons';
|
|
||||||
|
|
||||||
// Hide status bar panel
|
|
||||||
document.getElementById('wappalyzer-statusbar').style.visibility = 'hidden';
|
|
||||||
document.getElementById('wappalyzer-statusbar').style.padding = '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
var e = document.getElementById(containerId);
|
|
||||||
var container = document.getElementById('wappalyzer-container');
|
|
||||||
|
|
||||||
if ( self.popupOnHover ) {
|
|
||||||
container.addEventListener('mouseover', function() {
|
|
||||||
self.hoverTimeout = setTimeout(function() {
|
|
||||||
document.getElementById('wappalyzer-apps').openPopup(document.getElementById('wappalyzer-container'), 'after_end');
|
|
||||||
}, 200);
|
|
||||||
}, false);
|
|
||||||
|
|
||||||
container.addEventListener('mouseout', function() { clearTimeout(self.hoverTimeout); }, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
e.appendChild(container);
|
|
||||||
},
|
|
||||||
|
|
||||||
onPageLoad: function(event) {
|
|
||||||
self.log('onPageLoad');
|
|
||||||
|
|
||||||
var target = event.originalTarget;
|
|
||||||
|
|
||||||
if ( !target.request ) {
|
|
||||||
self.request = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.analyzePage(
|
|
||||||
target.documentElement,
|
|
||||||
target.location.href,
|
|
||||||
target.documentElement.innerHTML,
|
|
||||||
[],
|
|
||||||
[],
|
|
||||||
true
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
onContentPageLoad: function(message) {
|
|
||||||
self.log('onContentPageLoad');
|
|
||||||
|
|
||||||
self.analyzePage(
|
|
||||||
null,
|
|
||||||
message.json.href,
|
|
||||||
message.json.html,
|
|
||||||
message.json.headers,
|
|
||||||
message.json.environmentVars,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
onUrlChange: function(request) {
|
|
||||||
self.log('onUrlChange');
|
|
||||||
|
|
||||||
self.clearDetectedApps();
|
|
||||||
|
|
||||||
var doc = self.browser.contentDocument;
|
|
||||||
|
|
||||||
self.request = doc.request ? doc.request : request;
|
|
||||||
|
|
||||||
self.currentTab = false;
|
|
||||||
|
|
||||||
self.analyzePage(
|
|
||||||
doc,
|
|
||||||
doc.location.href ? doc.location.href : '',
|
|
||||||
doc.documentElement ? doc.documentElement.innerHTML : '',
|
|
||||||
[],
|
|
||||||
[],
|
|
||||||
false
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
urlChange: {
|
|
||||||
QueryInterface: function(iid) {
|
|
||||||
if ( iid.equals(Components.interfaces.nsIWebProgressListener) ||
|
|
||||||
iid.equals(Components.interfaces.nsISupportsWeakReference) ||
|
|
||||||
iid.equals(Components.interfaces.nsISupports) ) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw Components.results.NS_NOINTERFACE;
|
|
||||||
},
|
|
||||||
|
|
||||||
onLocationChange: function(progress, request, url) {
|
|
||||||
self.log('urlChange.onLocationChange');
|
|
||||||
|
|
||||||
if ( !url ) {
|
|
||||||
self.prevUrl = '';
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( url.spec != self.prevUrl ) {
|
|
||||||
self.prevUrl = url.spec;
|
|
||||||
|
|
||||||
self.onUrlChange(request);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onStateChange: function(a, b, c, d) {},
|
|
||||||
onProgressChange: function(a, b, c, d, e, f) {},
|
|
||||||
onStatusChange: function(a, b, c, d) {},
|
|
||||||
onSecurityChange: function(a, b, c) {}
|
|
||||||
},
|
|
||||||
|
|
||||||
analyzePage: function(doc, href, html, headers, environmentVars, doCount) {
|
|
||||||
self.log('analyzePage');
|
|
||||||
|
|
||||||
self.currentTab = false;
|
|
||||||
|
|
||||||
if ( href == self.browser.contentDocument.location.href ) {
|
|
||||||
self.currentTab = true;
|
|
||||||
|
|
||||||
if ( !doc ) {
|
|
||||||
doc = self.browser.contentDocument;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.clearDetectedApps();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( typeof html == 'undefined' ) {
|
|
||||||
html = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prevent large documents from slowing things down
|
|
||||||
if ( html.length > 50000 ) {
|
|
||||||
html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan URL, domain and response headers for patterns
|
|
||||||
if ( html || self.request ) {
|
|
||||||
// Check cached application names
|
|
||||||
if ( doc && typeof doc.detectedApps != 'undefined' ) {
|
|
||||||
for ( i in doc.detectedApps ) {
|
|
||||||
var appName = doc.detectedApps[i];
|
|
||||||
|
|
||||||
if ( typeof self.checkUnique[appName] == 'undefined' ) {
|
|
||||||
self.log('CACHE'); //
|
|
||||||
|
|
||||||
self.showApp(appName, doc, href, doCount);
|
|
||||||
|
|
||||||
self.checkUnique[appName] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( var appName in self.apps ) {
|
|
||||||
// Don't scan for apps that have already been detected
|
|
||||||
if ( typeof self.checkUnique[appName] == 'undefined' ) {
|
|
||||||
// Scan HTML
|
|
||||||
if ( html && typeof self.apps[appName].html != 'undefined' ) {
|
|
||||||
if ( self.apps[appName].html.test(html) ) {
|
|
||||||
self.showApp(appName, doc, href, doCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan script tags
|
|
||||||
if ( html && typeof self.apps[appName].script != 'undefined' ) {
|
|
||||||
var
|
|
||||||
regex = /<script[^>]+src=("|')([^"']+)\1/ig,
|
|
||||||
match = []
|
|
||||||
;
|
|
||||||
|
|
||||||
while ( match = regex.exec(html) ) {
|
|
||||||
if ( self.apps[appName].script.test(match[2]) ) {
|
|
||||||
self.showApp(appName, doc, href, doCount);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan meta tags
|
|
||||||
if ( html && typeof self.apps[appName].meta != 'undefined' ) {
|
|
||||||
var
|
|
||||||
regex = /<meta[^>]+>/ig,
|
|
||||||
match = []
|
|
||||||
;
|
|
||||||
|
|
||||||
while ( match = regex.exec(html) ) {
|
|
||||||
for ( meta in self.apps[appName].meta ) {
|
|
||||||
if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) {
|
|
||||||
var content = match.toString().match(/content=("|')([^"']+)("|')/i);
|
|
||||||
|
|
||||||
if ( self.apps[appName].meta[meta].test(content[2]) ) {
|
|
||||||
self.showApp(appName, doc, href, doCount);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan URL
|
|
||||||
if ( href && typeof self.apps[appName].url != 'undefined' ) {
|
|
||||||
var regex = self.apps[appName].url;
|
|
||||||
|
|
||||||
if ( regex.test(href) ) {
|
|
||||||
self.showApp(appName, doc, href, doCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan response headers
|
|
||||||
if ( typeof self.apps[appName].headers != 'undefined' && self.request ) {
|
|
||||||
for ( var header in self.apps[appName].headers ) {
|
|
||||||
var regex = self.apps[appName].headers[header];
|
|
||||||
|
|
||||||
try {
|
|
||||||
if ( regex.test(self.request.nsIHttpChannel.getResponseHeader(header)) ) {
|
|
||||||
self.showApp(appName, doc, href, doCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(e) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan environment variables
|
|
||||||
if ( environmentVars && typeof self.apps[appName].env != 'undefined' ) {
|
|
||||||
var regex = self.apps[appName].env;
|
|
||||||
|
|
||||||
for ( var i in environmentVars ) {
|
|
||||||
try {
|
|
||||||
if ( regex.test(environmentVars[i]) ) {
|
|
||||||
self.showApp(appName, doc, href, doCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(e) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
html = ''; // Free memory
|
|
||||||
},
|
|
||||||
|
|
||||||
showApp: function(detectedApp, doc, href, doCount) {
|
|
||||||
self.log('showApp ' + detectedApp);
|
|
||||||
|
|
||||||
self.report(detectedApp, href);
|
|
||||||
|
|
||||||
// Keep detected application names in memory
|
|
||||||
if ( doc ) {
|
|
||||||
if ( typeof doc.detectedApps == 'undefined' ) {
|
|
||||||
doc.detectedApps = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
doc.detectedApps.push(detectedApp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( detectedApp && typeof self.checkUnique[detectedApp] == 'undefined' ) {
|
|
||||||
var show = false;
|
|
||||||
|
|
||||||
for ( var i in self.apps[detectedApp].cats ) {
|
|
||||||
if ( self.showCats[self.apps[detectedApp].cats[i]] ) {
|
|
||||||
show = true;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( show && self.currentTab ) {
|
|
||||||
var e = document.getElementById('wappalyzer-detected-apps');
|
|
||||||
|
|
||||||
if ( self.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 = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show app icon and label
|
|
||||||
var child = document.createElement('image');
|
|
||||||
|
|
||||||
if ( typeof self.apps[detectedApp].icon == 'string' ) {
|
|
||||||
child.setAttribute('src', self.apps[detectedApp].icon);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
child.setAttribute('src', 'chrome://wappalyzer/skin/icons/' + detectedApp + '.ico');
|
|
||||||
}
|
|
||||||
|
|
||||||
child.setAttribute('class', 'wappalyzer-icon');
|
|
||||||
|
|
||||||
if ( self.appsDetected ) {
|
|
||||||
child.setAttribute('style', 'margin-left: .5em');
|
|
||||||
}
|
|
||||||
|
|
||||||
e.appendChild(child);
|
|
||||||
|
|
||||||
if ( self.showApps == 0 ) {
|
|
||||||
var child = document.createElement('label');
|
|
||||||
|
|
||||||
child.setAttribute('value', detectedApp);
|
|
||||||
child.setAttribute('class', 'wappalyzer-app-name');
|
|
||||||
|
|
||||||
e.appendChild(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show application in popup
|
|
||||||
var e = document.getElementById('wappalyzer-apps');
|
|
||||||
|
|
||||||
if ( !self.appsDetected ) {
|
|
||||||
// Remove "no apps detected" message
|
|
||||||
document.getElementById('wappalyzer-apps').removeChild(document.getElementById('wappalyzer-no-detected-apps'));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var child = document.createElement('menuseparator');
|
|
||||||
|
|
||||||
e.appendChild(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
var child = document.createElement('menuitem');
|
|
||||||
|
|
||||||
child.setAttribute('class', 'menuitem-iconic');
|
|
||||||
child.setAttribute('type', '');
|
|
||||||
|
|
||||||
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('image', 'chrome://wappalyzer/skin/icons/' + detectedApp + '.ico');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
child.setAttribute('label', detectedApp + ' (' + self.strings.getString('wappalyzer.custom') + ')');
|
|
||||||
child.setAttribute('disabled', 'true');
|
|
||||||
child.setAttribute('image', self.apps[detectedApp].icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
e.appendChild(child);
|
|
||||||
|
|
||||||
if ( self.apps[detectedApp].cats ) {
|
|
||||||
for ( var i in self.apps[detectedApp].cats ) {
|
|
||||||
var child = document.createElement('menuitem');
|
|
||||||
|
|
||||||
child.setAttribute('label', self.cats[self.apps[detectedApp].cats[i]].name);
|
|
||||||
child.setAttribute('disabled', 'true');
|
|
||||||
|
|
||||||
e.appendChild(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( doCount ) {
|
|
||||||
self.report(detectedApp, href);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.appsDetected ++;
|
|
||||||
|
|
||||||
self.checkUnique[detectedApp] = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
report: function(detectedApp, href) {
|
|
||||||
self.log('report');
|
|
||||||
|
|
||||||
if ( typeof self.apps[detectedApp].custom == 'undefined' ) {
|
|
||||||
var
|
|
||||||
regex = /:\/\/(.[^/]+)/,
|
|
||||||
domain = href.match(regex) ? href.match(regex)[1] : ''
|
|
||||||
;
|
|
||||||
|
|
||||||
if ( self.enableTracking && self.regexDomain.test(domain) && !self.regexBlacklist.test(href) ) {
|
|
||||||
if ( typeof self.history[domain] == 'undefined' ) {
|
|
||||||
self.history[domain] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( typeof self.history[domain][detectedApp] == 'undefined' ) {
|
|
||||||
self.history[domain][detectedApp] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.history[domain][detectedApp] ++;
|
|
||||||
|
|
||||||
self.hitCount ++;
|
|
||||||
|
|
||||||
if ( self.hitCount > 200 ) {
|
|
||||||
self.sendReport();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Anonymously send the name of the detected apps and domains to wappalyzer.com
|
|
||||||
// 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
|
|
||||||
sendReport: function() {
|
|
||||||
self.log('sendReport');
|
|
||||||
|
|
||||||
if ( self.enableTracking && !self.req ) {
|
|
||||||
var report = '';
|
|
||||||
|
|
||||||
if ( self.history ) {
|
|
||||||
for ( var i in self.history ) {
|
|
||||||
report += '[' + i;
|
|
||||||
|
|
||||||
for ( var j in self.history[i] ) {
|
|
||||||
report += '|' + j + ':' + self.history[i][j];
|
|
||||||
}
|
|
||||||
|
|
||||||
report += ']';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make POST request
|
|
||||||
self.req = new XMLHttpRequest();
|
|
||||||
|
|
||||||
self.req.open('POST', self.homeUrl + 'report/', true);
|
|
||||||
|
|
||||||
self.req.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE;
|
|
||||||
|
|
||||||
self.req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
|
||||||
|
|
||||||
self.req.onreadystatechange = function(e) {
|
|
||||||
if ( self.req.readyState == 4 ) {
|
|
||||||
if ( self.req.status == 200 ) {
|
|
||||||
// Reset
|
|
||||||
report = '';
|
|
||||||
|
|
||||||
self.hitCount = 0;
|
|
||||||
self.history = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
self.req.close();
|
|
||||||
|
|
||||||
self.req = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.req.send('d=' + encodeURIComponent(report));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
clearDetectedApps: function() {
|
|
||||||
self.log('clearDetectedApps');
|
|
||||||
|
|
||||||
self.appsDetected = 0;
|
|
||||||
self.checkUnique = [];
|
|
||||||
|
|
||||||
// Show Wappalyzer icon
|
|
||||||
document.getElementById('wappalyzer-icon').setAttribute('src', 'chrome://wappalyzer/skin/icon16x16.ico');
|
|
||||||
document.getElementById('wappalyzer-icon').style.display = '';
|
|
||||||
|
|
||||||
// Clear app icons and labels
|
|
||||||
var e = document.getElementById('wappalyzer-detected-apps');
|
|
||||||
|
|
||||||
while ( e.childNodes.length > 0 ) {
|
|
||||||
e.removeChild(e.childNodes.item(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear application popup
|
|
||||||
var e = document.getElementById('wappalyzer-apps');
|
|
||||||
|
|
||||||
while ( e.childNodes.length > 0 ) {
|
|
||||||
e.removeChild(e.childNodes.item(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
var child = document.createElement('menuitem');
|
|
||||||
|
|
||||||
child.setAttribute('label', self.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);
|
|
||||||
},
|
|
||||||
|
|
||||||
installSuccess: function() {
|
|
||||||
self.log('installSuccess');
|
|
||||||
|
|
||||||
gBrowser.removeEventListener('DOMContentLoaded', self.installSuccess, false);
|
|
||||||
|
|
||||||
self.openTab(self.homeUrl + 'install/success/');
|
|
||||||
},
|
|
||||||
|
|
||||||
upgradeSuccess: function() {
|
|
||||||
self.log('upgradeSuccess');
|
|
||||||
|
|
||||||
gBrowser.removeEventListener('DOMContentLoaded', self.upgradeSuccess, false);
|
|
||||||
|
|
||||||
self.openTab(self.homeUrl + 'install/upgraded/');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
addEventListener('load', function() { self.init(); }, false);
|
|
||||||
addEventListener('unload', function() { self.sendReport(); }, false);
|
|
||||||
|
|
||||||
return self;
|
|
||||||
})();
|
|
@ -1,122 +0,0 @@
|
|||||||
(function() {
|
|
||||||
var self = {
|
|
||||||
element: false,
|
|
||||||
prevUrl: '',
|
|
||||||
|
|
||||||
init: function() {
|
|
||||||
self.log('init');
|
|
||||||
|
|
||||||
addEventListener('DOMContentLoaded', self.onPageLoad, false);
|
|
||||||
},
|
|
||||||
|
|
||||||
log: function(message) {
|
|
||||||
return; //
|
|
||||||
|
|
||||||
var consoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
|
|
||||||
|
|
||||||
consoleService.logStringMessage("Wappalyzer content.js: " + message);
|
|
||||||
},
|
|
||||||
|
|
||||||
onPageLoad: function(e) {
|
|
||||||
self.log('onPageLoad');
|
|
||||||
|
|
||||||
self.getEnvironmentVars();
|
|
||||||
},
|
|
||||||
|
|
||||||
onUrlChange: function(request) {
|
|
||||||
self.log('onUrlChange');
|
|
||||||
|
|
||||||
self.getEnvironmentVars();
|
|
||||||
},
|
|
||||||
|
|
||||||
urlChange: {
|
|
||||||
QueryInterface: function(iid) {
|
|
||||||
if ( iid.equals(Components.interfaces.nsIWebProgressListener) ||
|
|
||||||
iid.equals(Components.interfaces.nsISupportsWeakReference) ||
|
|
||||||
iid.equals(Components.interfaces.nsISupports) ) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw Components.results.NS_NOINTERFACE;
|
|
||||||
},
|
|
||||||
|
|
||||||
onLocationChange: function(progress, request, url) {
|
|
||||||
if ( !url ) {
|
|
||||||
self.prevUrl = '';
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( url.spec != self.prevUrl ) {
|
|
||||||
self.prevUrl = url.spec;
|
|
||||||
|
|
||||||
self.onUrlChange(request);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onStateChange: function(a, b, c, d) {},
|
|
||||||
onProgressChange: function(a, b, c, d, e, f) {},
|
|
||||||
onStatusChange: function(a, b, c, d) {},
|
|
||||||
onSecurityChange: function(a, b, c) {}
|
|
||||||
},
|
|
||||||
|
|
||||||
getEnvironmentVars: function() {
|
|
||||||
self.log('getEnvironmentVars');
|
|
||||||
|
|
||||||
if ( content.document.contentType != 'text/html' || typeof content.document.html == 'undefined' ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var environmentVars = '';
|
|
||||||
|
|
||||||
try {
|
|
||||||
var element = content.document.createElement('wappalyzerData');
|
|
||||||
|
|
||||||
element.setAttribute('id', 'wappalyzerData');
|
|
||||||
element.setAttribute('style', 'display: none');
|
|
||||||
|
|
||||||
content.document.documentElement.appendChild(element);
|
|
||||||
|
|
||||||
content.location.href = 'javascript:' +
|
|
||||||
'(function() {' +
|
|
||||||
'try {' +
|
|
||||||
'var event = document.createEvent("Events");' +
|
|
||||||
|
|
||||||
'event.initEvent("wappalyzerEvent", true, false);' +
|
|
||||||
|
|
||||||
'var environmentVars = "";' +
|
|
||||||
|
|
||||||
'for ( var i in window ) environmentVars += i + " ";' +
|
|
||||||
|
|
||||||
'document.getElementById("wappalyzerData").appendChild(document.createComment(environmentVars));' +
|
|
||||||
|
|
||||||
'document.getElementById("wappalyzerData").dispatchEvent(event);' +
|
|
||||||
'}' +
|
|
||||||
'catch(e) { }' +
|
|
||||||
'})();';
|
|
||||||
|
|
||||||
element.addEventListener('wappalyzerEvent', (function(event) {
|
|
||||||
environmentVars = event.target.childNodes[0].nodeValue;
|
|
||||||
|
|
||||||
self.log('getEnvironmentVars: ' + environmentVars);
|
|
||||||
|
|
||||||
element.parentNode.removeChild(element);
|
|
||||||
|
|
||||||
sendAsyncMessage('wappalyzer:onPageLoad', {
|
|
||||||
href: content.document.location.href,
|
|
||||||
html: content.document.documentElement.innerHTML,
|
|
||||||
headers: [],
|
|
||||||
environmentVars: environmentVars.split(' ')
|
|
||||||
});
|
|
||||||
}), true);
|
|
||||||
}
|
|
||||||
catch(e) { }
|
|
||||||
|
|
||||||
return environmentVars;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.init();
|
|
||||||
|
|
||||||
return self;
|
|
||||||
})();
|
|
@ -1,58 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<?xml-stylesheet type="text/css" href="chrome://wappalyzer/skin/wappalyzer.css"?>
|
|
||||||
|
|
||||||
<!DOCTYPE overlay SYSTEM "chrome://wappalyzer/locale/wappalyzer.dtd">
|
|
||||||
|
|
||||||
<overlay id="wappalyzer-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
|
||||||
<script type="application/x-javascript" src="chrome://wappalyzer/content/wappalyzer.js"/>
|
|
||||||
<script type="application/x-javascript" src="chrome://wappalyzer/content/evaluate.js"/>
|
|
||||||
<script type="application/x-javascript" src="chrome://wappalyzer/content/apps.js"/>
|
|
||||||
|
|
||||||
<stringbundleset id="stringbundleset">
|
|
||||||
<stringbundle id="wappalyzer-strings" src="chrome://wappalyzer/locale/wappalyzer.properties"/>
|
|
||||||
</stringbundleset>
|
|
||||||
|
|
||||||
<hbox>
|
|
||||||
<hbox
|
|
||||||
id="wappalyzer-container"
|
|
||||||
context="wappalyzer-menu"
|
|
||||||
popup="wappalyzer-apps"
|
|
||||||
>
|
|
||||||
<image
|
|
||||||
id="wappalyzer-icon"
|
|
||||||
class="wappalyzer-icon"
|
|
||||||
label="&wappalyzer.title;"
|
|
||||||
src="chrome://wappalyzer/skin/icon16x16.ico"/>
|
|
||||||
|
|
||||||
<box align="start" id="wappalyzer-detected-apps"/>
|
|
||||||
|
|
||||||
<menupopup id="wappalyzer-apps" position="after_end"></menupopup>
|
|
||||||
|
|
||||||
<menupopup id="wappalyzer-menu">
|
|
||||||
<menuitem label="&wappalyzer.options;" oncommand="
|
|
||||||
window.openDialog('chrome://wappalyzer/content/options.xul', 'wappalyzer-options', 'chrome, dialog, centerscreen');
|
|
||||||
" image="chrome://wappalyzer/skin/options.png"/>
|
|
||||||
<menuseparator/>
|
|
||||||
<menuitem label="&wappalyzer.donate;" oncommand="wappalyzer.openTab(wappalyzer.homeUrl + 'donate/');" image="chrome://wappalyzer/skin/donate.png"/>
|
|
||||||
<menuitem label="&wappalyzer.feedback;" oncommand="wappalyzer.openTab(wappalyzer.homeUrl + '?redirect=feedback');" image="chrome://wappalyzer/skin/feedback.png"/>
|
|
||||||
<menuitem label="&wappalyzer.forkOnGithub;" oncommand="wappalyzer.openTab(wappalyzer.githubUrl);" image="chrome://wappalyzer/skin/github.ico"/>
|
|
||||||
<menuitem label="&wappalyzer.twitter;" oncommand="wappalyzer.openTab(wappalyzer.twitterUrl);" image="chrome://wappalyzer/skin/twitter.ico"/>
|
|
||||||
<menuitem label="&wappalyzer.home;" oncommand="wappalyzer.openTab(wappalyzer.homeUrl);" image="chrome://wappalyzer/skin/icon16x16_hot.ico"/>
|
|
||||||
</menupopup>
|
|
||||||
</hbox>
|
|
||||||
</hbox>
|
|
||||||
|
|
||||||
<hbox
|
|
||||||
id="urlbar-icons"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<statusbar id="status-bar">
|
|
||||||
<statusbarpanel
|
|
||||||
id="wappalyzer-statusbar"
|
|
||||||
class="statusbarpanel-iconic"
|
|
||||||
context="wappalyzer-menu"
|
|
||||||
popup="wappalyzer-apps"
|
|
||||||
/>
|
|
||||||
</statusbar>
|
|
||||||
</overlay>
|
|
@ -1,51 +0,0 @@
|
|||||||
<!ENTITY wappalyzer.title "Wappalyzer">
|
|
||||||
<!ENTITY wappalyzer.feedback "Feedback">
|
|
||||||
<!ENTITY wappalyzer.forkOnGithub "Fork on Github">
|
|
||||||
<!ENTITY wappalyzer.options "Settings">
|
|
||||||
<!ENTITY wappalyzer.custom "Custom code">
|
|
||||||
<!ENTITY wappalyzer.enableTracking "Allow anonymous application data collection for research">
|
|
||||||
<!ENTITY wappalyzer.general "General">
|
|
||||||
<!ENTITY wappalyzer.location "Display icons in">
|
|
||||||
<!ENTITY wappalyzer.addressBar "Address bar">
|
|
||||||
<!ENTITY wappalyzer.statusBar "Add-on bar">
|
|
||||||
<!ENTITY wappalyzer.showApps "Show applications as">
|
|
||||||
<!ENTITY wappalyzer.labels "Icons, text and popup">
|
|
||||||
<!ENTITY wappalyzer.icons "Icons and popup">
|
|
||||||
<!ENTITY wappalyzer.popup "Popup only">
|
|
||||||
<!ENTITY wappalyzer.popupOnHover "Show popup">
|
|
||||||
<!ENTITY wappalyzer.onHover "On hover and click">
|
|
||||||
<!ENTITY wappalyzer.onClick "On click only">
|
|
||||||
<!ENTITY wappalyzer.categories "Categories">
|
|
||||||
<!ENTITY wappalyzer.twitter "Twitter">
|
|
||||||
<!ENTITY wappalyzer.home "Go to Wappalyzer">
|
|
||||||
<!ENTITY wappalyzer.privacy "Privacy">
|
|
||||||
<!ENTITY wappalyzer.donate "Donate">
|
|
||||||
<!ENTITY wappalyzer.evaluate "Evaluate code">
|
|
||||||
<!ENTITY wappalyzer.customBody "Add applications for personal use with JSON and regular expressions.">
|
|
||||||
<!ENTITY wappalyzer.customMoreInfo "Click here to learn more">
|
|
||||||
|
|
||||||
<!ENTITY wappalyzer.cat1 "CMS">
|
|
||||||
<!ENTITY wappalyzer.cat2 "Message boards">
|
|
||||||
<!ENTITY wappalyzer.cat3 "Database managers">
|
|
||||||
<!ENTITY wappalyzer.cat4 "Documentation tools">
|
|
||||||
<!ENTITY wappalyzer.cat5 "Widgets">
|
|
||||||
<!ENTITY wappalyzer.cat6 "Web shops">
|
|
||||||
<!ENTITY wappalyzer.cat7 "Photo galleries">
|
|
||||||
<!ENTITY wappalyzer.cat8 "Wikis">
|
|
||||||
<!ENTITY wappalyzer.cat9 "Hosting panels">
|
|
||||||
<!ENTITY wappalyzer.cat10 "Analytics">
|
|
||||||
<!ENTITY wappalyzer.cat11 "Blogs">
|
|
||||||
<!ENTITY wappalyzer.cat12 "JavaScript frameworks">
|
|
||||||
<!ENTITY wappalyzer.cat13 "Issue trackers">
|
|
||||||
<!ENTITY wappalyzer.cat14 "Video players">
|
|
||||||
<!ENTITY wappalyzer.cat15 "Comment systems">
|
|
||||||
<!ENTITY wappalyzer.cat16 "CAPTCHAs">
|
|
||||||
<!ENTITY wappalyzer.cat17 "Font scripts">
|
|
||||||
<!ENTITY wappalyzer.cat18 "Web frameworks">
|
|
||||||
<!ENTITY wappalyzer.cat19 "Miscellaneous">
|
|
||||||
<!ENTITY wappalyzer.cat20 "Editors">
|
|
||||||
<!ENTITY wappalyzer.cat21 "LMS">
|
|
||||||
<!ENTITY wappalyzer.cat22 "Web servers">
|
|
||||||
<!ENTITY wappalyzer.cat23 "Cache tools">
|
|
||||||
<!ENTITY wappalyzer.cat24 "Rich text editors">
|
|
||||||
<!ENTITY wappalyzer.cat25 "Javascript Graphics">
|
|
@ -1,3 +0,0 @@
|
|||||||
wappalyzer.title = Wappalyzer
|
|
||||||
wappalyzer.noDetectedApps = No applications detected
|
|
||||||
wappalyzer.custom = custom
|
|
@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
* Firefox adapter
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
if ( wappalyzer == null ) return;
|
||||||
|
|
||||||
|
var w = wappalyzer;
|
||||||
|
|
||||||
|
w.adapter = {
|
||||||
|
/**
|
||||||
|
* Log messages to console
|
||||||
|
*/
|
||||||
|
log: function(args) {
|
||||||
|
var consoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
|
||||||
|
|
||||||
|
consoleService.logStringMessage(args.message);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize
|
||||||
|
*/
|
||||||
|
init: function() {
|
||||||
|
// Get version number
|
||||||
|
Components.utils.import('resource://gre/modules/AddonManager.jsm');
|
||||||
|
|
||||||
|
AddonManager.getAddonByID('wappalyzer@crunchlabz.com', function(extension) {
|
||||||
|
w.version = extension.version;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Load content script
|
||||||
|
if ( messageManager != null ) {
|
||||||
|
// Listen for messages from content script
|
||||||
|
messageManager.addMessageListener('wappalyzer', content);
|
||||||
|
|
||||||
|
messageManager.loadFrameScript('chrome://wappalyzer/content/js/content.js', true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display apps
|
||||||
|
*/
|
||||||
|
displayApps: function(args) {
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Go to URL
|
||||||
|
*/
|
||||||
|
goToURL: function(args) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Content message listener
|
||||||
|
*/
|
||||||
|
function content(msg) {
|
||||||
|
w.log('content.js');
|
||||||
|
|
||||||
|
w.analyze(msg.json.hostname, msg.json.url, {
|
||||||
|
html: msg.json.html,
|
||||||
|
env: msg.json.env
|
||||||
|
});
|
||||||
|
|
||||||
|
delete msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
w.init();
|
||||||
|
})();
|
@ -0,0 +1,28 @@
|
|||||||
|
(function() {
|
||||||
|
addEventListener('DOMContentLoaded', onLoad, false);
|
||||||
|
|
||||||
|
function onLoad() {
|
||||||
|
if ( content.document.contentType != 'text/html' ) return;
|
||||||
|
|
||||||
|
// Environment variables
|
||||||
|
var sandbox = Components.utils.Sandbox(content);
|
||||||
|
|
||||||
|
sandbox.win = content;
|
||||||
|
|
||||||
|
Components.utils.evalInSandbox('var env = new String; for ( i in win.wrappedJSObject ) env += " " + i;', sandbox);
|
||||||
|
|
||||||
|
var env = sandbox.env.split(' ');
|
||||||
|
|
||||||
|
// HTML
|
||||||
|
var html = content.document.documentElement.innerHTML
|
||||||
|
|
||||||
|
if ( html.length > 50000 ) html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length);
|
||||||
|
|
||||||
|
sendAsyncMessage('wappalyzer', {
|
||||||
|
hostname: content.location.hostname,
|
||||||
|
html: html,
|
||||||
|
env: env,
|
||||||
|
url: content.location.href
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<?xml-stylesheet type="text/css" href="chrome://wappalyzer/skin/css/wappalyzer.css"?>
|
||||||
|
|
||||||
|
<!DOCTYPE overlay SYSTEM "chrome://wappalyzer/locale/wappalyzer.dtd">
|
||||||
|
|
||||||
|
<overlay id="wappalyzer-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||||
|
<script type="application/x-javascript" src="chrome://wappalyzer/content/js/wappalyzer.js"/>
|
||||||
|
<script type="application/x-javascript" src="chrome://wappalyzer/content/js/apps.js"/>
|
||||||
|
<script type="application/x-javascript" src="chrome://wappalyzer/content/js/adapter.js"/>
|
||||||
|
|
||||||
|
<stringbundleset id="stringbundleset">
|
||||||
|
<stringbundle id="wappalyzer-strings" src="chrome://wappalyzer/locale/wappalyzer.properties"/>
|
||||||
|
</stringbundleset>
|
||||||
|
|
||||||
|
<hbox id="urlbar-icons">
|
||||||
|
<hbox
|
||||||
|
id="wappalyzer-container"
|
||||||
|
popup="wappalyzer-apps"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
id="wappalyzer-icon"
|
||||||
|
class="wappalyzer-icon"
|
||||||
|
label="&wappalyzer.name;"
|
||||||
|
src="chrome://wappalyzer/skin/images/icon16x16.ico"/>
|
||||||
|
|
||||||
|
<box align="start" id="wappalyzer-apps"/>
|
||||||
|
|
||||||
|
<menupopup id="wappalyzer-menu" position="after_end">
|
||||||
|
<menu label="&wappalyzer.name;">
|
||||||
|
<menupopup>
|
||||||
|
<menuitem label="sub" image="chrome://wappalyzer/skin/images/icon16x16_hot.ico"/>
|
||||||
|
</menupopup>
|
||||||
|
</menu>
|
||||||
|
|
||||||
|
<menuitem label="foo"/>
|
||||||
|
</menupopup>
|
||||||
|
</hbox>
|
||||||
|
</hbox>
|
||||||
|
</overlay>
|
@ -0,0 +1,27 @@
|
|||||||
|
<!ENTITY wappalyzer.name "Wappalyzer">
|
||||||
|
|
||||||
|
<!ENTITY wappalyzer.cat1 "CMS">
|
||||||
|
<!ENTITY wappalyzer.cat2 "Message boards">
|
||||||
|
<!ENTITY wappalyzer.cat3 "Database managers">
|
||||||
|
<!ENTITY wappalyzer.cat4 "Documentation tools">
|
||||||
|
<!ENTITY wappalyzer.cat5 "Widgets">
|
||||||
|
<!ENTITY wappalyzer.cat6 "Web shops">
|
||||||
|
<!ENTITY wappalyzer.cat7 "Photo galleries">
|
||||||
|
<!ENTITY wappalyzer.cat8 "Wikis">
|
||||||
|
<!ENTITY wappalyzer.cat9 "Hosting panels">
|
||||||
|
<!ENTITY wappalyzer.cat10 "Analytics">
|
||||||
|
<!ENTITY wappalyzer.cat11 "Blogs">
|
||||||
|
<!ENTITY wappalyzer.cat12 "JavaScript frameworks">
|
||||||
|
<!ENTITY wappalyzer.cat13 "Issue trackers">
|
||||||
|
<!ENTITY wappalyzer.cat14 "Video players">
|
||||||
|
<!ENTITY wappalyzer.cat15 "Comment systems">
|
||||||
|
<!ENTITY wappalyzer.cat16 "CAPTCHAs">
|
||||||
|
<!ENTITY wappalyzer.cat17 "Font scripts">
|
||||||
|
<!ENTITY wappalyzer.cat18 "Web frameworks">
|
||||||
|
<!ENTITY wappalyzer.cat19 "Miscellaneous">
|
||||||
|
<!ENTITY wappalyzer.cat20 "Editors">
|
||||||
|
<!ENTITY wappalyzer.cat21 "LMS">
|
||||||
|
<!ENTITY wappalyzer.cat22 "Web servers">
|
||||||
|
<!ENTITY wappalyzer.cat23 "Cache tools">
|
||||||
|
<!ENTITY wappalyzer.cat24 "Rich text editors">
|
||||||
|
<!ENTITY wappalyzer.cat25 "Javascript Graphics">
|
@ -0,0 +1 @@
|
|||||||
|
wappalyzer.name = Wappalyzer
|
Before Width: | Height: | Size: 714 B After Width: | Height: | Size: 714 B |
Before Width: | Height: | Size: 782 B After Width: | Height: | Size: 782 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 610 B After Width: | Height: | Size: 610 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 12 KiB |