All driver now using apps.json, more performance improvements

main
Elbert Alias 12 years ago
parent 52ba2d69c1
commit 24b4bed5f3

@ -105,7 +105,7 @@ var wappalyzer = wappalyzer || (function() {
} }
var var
i, app, type, regex, match, content, meta, header, i, app, type, regex, regexMeta, regexScript, match, content, meta, header,
profiler = { profiler = {
regexCount: 0, regexCount: 0,
startTime: ( new Date ).getTime() startTime: ( new Date ).getTime()
@ -113,86 +113,88 @@ var wappalyzer = wappalyzer || (function() {
apps = [] apps = []
; ;
appLoop:
for ( app in w.apps ) { for ( app in w.apps ) {
// Skip if the app has already been detected // Skip if the app has already been detected
if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) {
continue; continue;
} }
next:
for ( type in w.apps[app] ) { for ( type in w.apps[app] ) {
if ( data[type] == null ) {
continue;
}
switch ( type ) { switch ( type ) {
case 'url': case 'url':
regex = new RegExp(w.apps[app][type], 'i'); regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(url) ) { if ( regex.test(url) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
break; break;
case 'html': case 'html':
regex = new RegExp(w.apps[app][type], 'i'); if ( data[type] == null ) {
break;
}
regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(data[type]) ) { if ( regex.test(data[type]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
break; break;
case 'script': case 'script':
if ( data['html'] == null ) { if ( data.html == null ) {
break; break;
} }
regex = new RegExp(w.apps[app][type], 'i'); regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
regexScript = new RegExp('<script[^>]+src=("|\')([^"\']+)\1', 'ig');
profiler.regexCount ++; profiler.regexCount ++;
while ( match = new RegExp('<script[^>]+src=("|\')([^"\']+)\1', 'ig').exec(data['html']) ) { while ( match = regexScript.exec(data.html) ) {
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(match[2]) ) { if ( regex.test(match[2]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
break; break;
case 'meta': case 'meta':
if ( data['html'] == null ) { if ( data.html == null ) {
break; break;
} }
profiler.regexCount ++; profiler.regexCount ++;
while ( match = new RegExp('<meta[^>]+>', 'ig').exec(data['html']) ) { regexMeta = new RegExp('<meta[^>]+>', 'ig');
while ( match = regexMeta.exec(data.html) ) {
for ( meta in w.apps[app][type] ) { for ( meta in w.apps[app][type] ) {
profiler.regexCount ++; profiler.regexCount ++;
if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) {
content = match.toString().match(/content=("|')([^"']+)("|')/i); content = match.toString().match(/content=("|')([^"']+)("|')/i);
regex = new RegExp(w.apps[app].meta[meta], 'i'); regex = new RegExp(w.apps[app].meta[meta].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( content && content.length === 4 && regex.test(content[2]) ) { if ( content && content.length === 4 && regex.test(content[2]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
} }
@ -205,14 +207,14 @@ var wappalyzer = wappalyzer || (function() {
} }
for ( header in w.apps[app].headers ) { for ( header in w.apps[app].headers ) {
regex = new RegExp(w.apps[app][type][header], 'i'); regex = new RegExp(w.apps[app][type][header].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( data[type][header] != null && regex.test(data[type][header]) ) { if ( data[type][header] != null && regex.test(data[type][header]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
@ -222,7 +224,7 @@ var wappalyzer = wappalyzer || (function() {
break; break;
} }
regex = RegExp(w.apps[app][type], 'i'); regex = RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
for ( i in data[type] ) { for ( i in data[type] ) {
profiler.regexCount ++; profiler.regexCount ++;
@ -230,7 +232,7 @@ var wappalyzer = wappalyzer || (function() {
if ( regex.test(data[type][i]) ) { if ( regex.test(data[type][i]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }

@ -767,7 +767,7 @@
}, },
"jQuery": { "jQuery": {
"cats": [ "12" ], "cats": [ "12" ],
"script": "jquery.*.js", "script": "jquery.*\\.js",
"env": "^jQuery$" "env": "^jQuery$"
}, },
"jQuery Mobile": { "jQuery Mobile": {

@ -767,7 +767,7 @@
}, },
"jQuery": { "jQuery": {
"cats": [ "12" ], "cats": [ "12" ],
"script": "jquery.*.js", "script": "jquery.*\\.js",
"env": "^jQuery$" "env": "^jQuery$"
}, },
"jQuery Mobile": { "jQuery Mobile": {

@ -87,7 +87,11 @@
break; break;
case 'get_apps': case 'get_apps':
sendResponse({ tabCache: tabCache[request.tab.id] }); sendResponse({
tabCache: tabCache[request.tab.id],
apps: w.apps,
categories: w.categories
});
break; break;
} }
@ -141,7 +145,7 @@
appName = w.detected[tab.url][i]; appName = w.detected[tab.url][i];
w.apps[appName].cats.map(function(cat) { w.apps[appName].cats.map(function(cat) {
if ( cat === match && !found ) { if ( cat == match && !found ) {
chrome.browserAction.setIcon({ tabId: tab.id, path: 'images/icons/' + appName + '.png' }); chrome.browserAction.setIcon({ tabId: tab.id, path: 'images/icons/' + appName + '.png' });
found = true; found = true;
@ -154,7 +158,6 @@
}; };
}, },
/** /**
* Anonymously track detected applications for research purposes * Anonymously track detected applications for research purposes
*/ */

@ -1,5 +1,3 @@
var wappalyzer = {};
(function() { (function() {
var popup = { var popup = {
pollHeaders: null, pollHeaders: null,
@ -58,9 +56,9 @@ var wappalyzer = {};
'<span class="label">' + appName + '</span>' + '<span class="label">' + appName + '</span>' +
'</a>'; '</a>';
wappalyzer.apps[appName].cats.map(function(cat) { response.apps[appName].cats.map(function(cat) {
html += html +=
'<a target="_blank" href="http://wappalyzer.com/categories/' + wappalyzer.categories[cat] + '?utm_source=chrome&utm_medium=extension&utm_campaign=extensions">' + '<a target="_blank" href="http://wappalyzer.com/categories/' + response.categories[cat] + '?utm_source=chrome&utm_medium=extension&utm_campaign=extensions">' +
'<span class="category">' + chrome.i18n.getMessage('categoryName' + cat) + '</span>' + '<span class="category">' + chrome.i18n.getMessage('categoryName' + cat) + '</span>' +
'</a>'; '</a>';
}); });

@ -105,7 +105,7 @@ var wappalyzer = wappalyzer || (function() {
} }
var var
i, app, type, regex, match, content, meta, header, i, app, type, regex, regexMeta, regexScript, match, content, meta, header,
profiler = { profiler = {
regexCount: 0, regexCount: 0,
startTime: ( new Date ).getTime() startTime: ( new Date ).getTime()
@ -113,86 +113,88 @@ var wappalyzer = wappalyzer || (function() {
apps = [] apps = []
; ;
appLoop:
for ( app in w.apps ) { for ( app in w.apps ) {
// Skip if the app has already been detected // Skip if the app has already been detected
if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) {
continue; continue;
} }
next:
for ( type in w.apps[app] ) { for ( type in w.apps[app] ) {
if ( data[type] == null ) {
continue;
}
switch ( type ) { switch ( type ) {
case 'url': case 'url':
regex = new RegExp(w.apps[app][type], 'i'); regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(url) ) { if ( regex.test(url) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
break; break;
case 'html': case 'html':
regex = new RegExp(w.apps[app][type], 'i'); if ( data[type] == null ) {
break;
}
regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(data[type]) ) { if ( regex.test(data[type]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
break; break;
case 'script': case 'script':
if ( data['html'] == null ) { if ( data.html == null ) {
break; break;
} }
regex = new RegExp(w.apps[app][type], 'i'); regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
regexScript = new RegExp('<script[^>]+src=("|\')([^"\']+)\1', 'ig');
profiler.regexCount ++; profiler.regexCount ++;
while ( match = new RegExp('<script[^>]+src=("|\')([^"\']+)\1', 'ig').exec(data['html']) ) { while ( match = regexScript.exec(data.html) ) {
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(match[2]) ) { if ( regex.test(match[2]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
break; break;
case 'meta': case 'meta':
if ( data['html'] == null ) { if ( data.html == null ) {
break; break;
} }
profiler.regexCount ++; profiler.regexCount ++;
while ( match = new RegExp('<meta[^>]+>', 'ig').exec(data['html']) ) { regexMeta = new RegExp('<meta[^>]+>', 'ig');
while ( match = regexMeta.exec(data.html) ) {
for ( meta in w.apps[app][type] ) { for ( meta in w.apps[app][type] ) {
profiler.regexCount ++; profiler.regexCount ++;
if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) {
content = match.toString().match(/content=("|')([^"']+)("|')/i); content = match.toString().match(/content=("|')([^"']+)("|')/i);
regex = new RegExp(w.apps[app].meta[meta], 'i'); regex = new RegExp(w.apps[app].meta[meta].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( content && content.length === 4 && regex.test(content[2]) ) { if ( content && content.length === 4 && regex.test(content[2]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
} }
@ -205,14 +207,14 @@ var wappalyzer = wappalyzer || (function() {
} }
for ( header in w.apps[app].headers ) { for ( header in w.apps[app].headers ) {
regex = new RegExp(w.apps[app][type][header], 'i'); regex = new RegExp(w.apps[app][type][header].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( data[type][header] != null && regex.test(data[type][header]) ) { if ( data[type][header] != null && regex.test(data[type][header]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
@ -222,7 +224,7 @@ var wappalyzer = wappalyzer || (function() {
break; break;
} }
regex = RegExp(w.apps[app][type], 'i'); regex = RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
for ( i in data[type] ) { for ( i in data[type] ) {
profiler.regexCount ++; profiler.regexCount ++;
@ -230,7 +232,7 @@ var wappalyzer = wappalyzer || (function() {
if ( regex.test(data[type][i]) ) { if ( regex.test(data[type][i]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }

@ -767,7 +767,7 @@
}, },
"jQuery": { "jQuery": {
"cats": [ "12" ], "cats": [ "12" ],
"script": "jquery.*.js", "script": "jquery.*\\.js",
"env": "^jQuery$" "env": "^jQuery$"
}, },
"jQuery Mobile": { "jQuery Mobile": {

@ -105,7 +105,7 @@ var wappalyzer = wappalyzer || (function() {
} }
var var
i, app, type, regex, match, content, meta, header, i, app, type, regex, regexMeta, regexScript, match, content, meta, header,
profiler = { profiler = {
regexCount: 0, regexCount: 0,
startTime: ( new Date ).getTime() startTime: ( new Date ).getTime()
@ -113,86 +113,88 @@ var wappalyzer = wappalyzer || (function() {
apps = [] apps = []
; ;
appLoop:
for ( app in w.apps ) { for ( app in w.apps ) {
// Skip if the app has already been detected // Skip if the app has already been detected
if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) {
continue; continue;
} }
next:
for ( type in w.apps[app] ) { for ( type in w.apps[app] ) {
if ( data[type] == null ) {
continue;
}
switch ( type ) { switch ( type ) {
case 'url': case 'url':
regex = new RegExp(w.apps[app][type], 'i'); regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(url) ) { if ( regex.test(url) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
break; break;
case 'html': case 'html':
regex = new RegExp(w.apps[app][type], 'i'); if ( data[type] == null ) {
break;
}
regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(data[type]) ) { if ( regex.test(data[type]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
break; break;
case 'script': case 'script':
if ( data['html'] == null ) { if ( data.html == null ) {
break; break;
} }
regex = new RegExp(w.apps[app][type], 'i'); regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
regexScript = new RegExp('<script[^>]+src=("|\')([^"\']+)\1', 'ig');
profiler.regexCount ++; profiler.regexCount ++;
while ( match = new RegExp('<script[^>]+src=("|\')([^"\']+)\1', 'ig').exec(data['html']) ) { while ( match = regexScript.exec(data.html) ) {
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(match[2]) ) { if ( regex.test(match[2]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
break; break;
case 'meta': case 'meta':
if ( data['html'] == null ) { if ( data.html == null ) {
break; break;
} }
profiler.regexCount ++; profiler.regexCount ++;
while ( match = new RegExp('<meta[^>]+>', 'ig').exec(data['html']) ) { regexMeta = new RegExp('<meta[^>]+>', 'ig');
while ( match = regexMeta.exec(data.html) ) {
for ( meta in w.apps[app][type] ) { for ( meta in w.apps[app][type] ) {
profiler.regexCount ++; profiler.regexCount ++;
if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) {
content = match.toString().match(/content=("|')([^"']+)("|')/i); content = match.toString().match(/content=("|')([^"']+)("|')/i);
regex = new RegExp(w.apps[app].meta[meta], 'i'); regex = new RegExp(w.apps[app].meta[meta].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( content && content.length === 4 && regex.test(content[2]) ) { if ( content && content.length === 4 && regex.test(content[2]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
} }
@ -205,14 +207,14 @@ var wappalyzer = wappalyzer || (function() {
} }
for ( header in w.apps[app].headers ) { for ( header in w.apps[app].headers ) {
regex = new RegExp(w.apps[app][type][header], 'i'); regex = new RegExp(w.apps[app][type][header].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( data[type][header] != null && regex.test(data[type][header]) ) { if ( data[type][header] != null && regex.test(data[type][header]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
@ -222,7 +224,7 @@ var wappalyzer = wappalyzer || (function() {
break; break;
} }
regex = RegExp(w.apps[app][type], 'i'); regex = RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
for ( i in data[type] ) { for ( i in data[type] ) {
profiler.regexCount ++; profiler.regexCount ++;
@ -230,7 +232,7 @@ var wappalyzer = wappalyzer || (function() {
if ( regex.test(data[type][i]) ) { if ( regex.test(data[type][i]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }

@ -767,7 +767,7 @@
}, },
"jQuery": { "jQuery": {
"cats": [ "12" ], "cats": [ "12" ],
"script": "jquery.*.js", "script": "jquery.*\\.js",
"env": "^jQuery$" "env": "^jQuery$"
}, },
"jQuery Mobile": { "jQuery Mobile": {

@ -4,38 +4,38 @@
var var
data = {}, data = {},
lastEnv = [], lastEnv = [],
prefs = null prefs = sendSyncMessage('wappalyzer', { action: 'get prefs' })[0]
; ;
addEventListener('DOMContentLoaded', function() { addEventListener('DOMContentLoaded', function() {
removeEventListener('DOMContentLoaded', onLoad, false); removeEventListener('DOMContentLoaded', onLoad, false);
if ( prefs != null || content.document.contentType != 'text/html' ) {
return;
}
prefs = sendSyncMessage('wappalyzer', { action: 'get prefs' })[0];
onLoad(); onLoad();
}, false); }, false);
function onLoad() { function onLoad() {
if ( content.document.contentType != 'text/html' ) {
return;
}
if ( prefs.analyzeJavaScript && prefs.analyzeOnLoad ) { if ( prefs.analyzeJavaScript && prefs.analyzeOnLoad ) {
content.document.documentElement.addEventListener('load', function() { content.document.documentElement.addEventListener('load', function() {
var env = Object.keys(content.wrappedJSObject); var env = Object.keys(content.wrappedJSObject).slice(0, 500);
// Only analyze new variables
data = { env: env.filter(function(i) { return lastEnv.indexOf(i) === -1; }) };
lastEnv = env; lastEnv = env;
if ( data.env.length ) { // Only analyze new variables
env = { env: env.filter(function(i) { return lastEnv.indexOf(i) === -1; }) };
if ( env.length ) {
sendAsyncMessage('wappalyzer', { sendAsyncMessage('wappalyzer', {
action: 'analyze', action: 'analyze',
analyze: data analyze: { env: env }
}); });
} }
env = null;
removeEventListener('load', onLoad, true); removeEventListener('load', onLoad, true);
}, true); }, true);
} }
@ -55,7 +55,9 @@
data = { html: html }; data = { html: html };
if ( prefs.analyzeJavaScript ) { if ( prefs.analyzeJavaScript ) {
data.env = Object.keys(content.wrappedJSObject); data.env = Object.keys(content.wrappedJSObject).slice(0, 500);
lastEnv = data.env;
} }
sendAsyncMessage('wappalyzer', { sendAsyncMessage('wappalyzer', {
@ -64,5 +66,7 @@
url: content.location.href, url: content.location.href,
analyze: data analyze: data
}); });
data = null;
} }
})(); })();

@ -105,7 +105,7 @@ var wappalyzer = wappalyzer || (function() {
} }
var var
i, app, type, regex, match, content, meta, header, i, app, type, regex, regexMeta, regexScript, match, content, meta, header,
profiler = { profiler = {
regexCount: 0, regexCount: 0,
startTime: ( new Date ).getTime() startTime: ( new Date ).getTime()
@ -113,86 +113,88 @@ var wappalyzer = wappalyzer || (function() {
apps = [] apps = []
; ;
appLoop:
for ( app in w.apps ) { for ( app in w.apps ) {
// Skip if the app has already been detected // Skip if the app has already been detected
if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) {
continue; continue;
} }
next:
for ( type in w.apps[app] ) { for ( type in w.apps[app] ) {
if ( data[type] == null ) {
continue;
}
switch ( type ) { switch ( type ) {
case 'url': case 'url':
regex = new RegExp(w.apps[app][type], 'i'); regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(url) ) { if ( regex.test(url) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
break; break;
case 'html': case 'html':
regex = new RegExp(w.apps[app][type], 'i'); if ( data[type] == null ) {
break;
}
regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(data[type]) ) { if ( regex.test(data[type]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
break; break;
case 'script': case 'script':
if ( data['html'] == null ) { if ( data.html == null ) {
break; break;
} }
regex = new RegExp(w.apps[app][type], 'i'); regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
regexScript = new RegExp('<script[^>]+src=("|\')([^"\']+)\1', 'ig');
profiler.regexCount ++; profiler.regexCount ++;
while ( match = new RegExp('<script[^>]+src=("|\')([^"\']+)\1', 'ig').exec(data['html']) ) { while ( match = regexScript.exec(data.html) ) {
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(match[2]) ) { if ( regex.test(match[2]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
break; break;
case 'meta': case 'meta':
if ( data['html'] == null ) { if ( data.html == null ) {
break; break;
} }
profiler.regexCount ++; profiler.regexCount ++;
while ( match = new RegExp('<meta[^>]+>', 'ig').exec(data['html']) ) { regexMeta = new RegExp('<meta[^>]+>', 'ig');
while ( match = regexMeta.exec(data.html) ) {
for ( meta in w.apps[app][type] ) { for ( meta in w.apps[app][type] ) {
profiler.regexCount ++; profiler.regexCount ++;
if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) {
content = match.toString().match(/content=("|')([^"']+)("|')/i); content = match.toString().match(/content=("|')([^"']+)("|')/i);
regex = new RegExp(w.apps[app].meta[meta], 'i'); regex = new RegExp(w.apps[app].meta[meta].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( content && content.length === 4 && regex.test(content[2]) ) { if ( content && content.length === 4 && regex.test(content[2]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
} }
@ -205,14 +207,14 @@ var wappalyzer = wappalyzer || (function() {
} }
for ( header in w.apps[app].headers ) { for ( header in w.apps[app].headers ) {
regex = new RegExp(w.apps[app][type][header], 'i'); regex = new RegExp(w.apps[app][type][header].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( data[type][header] != null && regex.test(data[type][header]) ) { if ( data[type][header] != null && regex.test(data[type][header]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
@ -222,7 +224,7 @@ var wappalyzer = wappalyzer || (function() {
break; break;
} }
regex = RegExp(w.apps[app][type], 'i'); regex = RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
for ( i in data[type] ) { for ( i in data[type] ) {
profiler.regexCount ++; profiler.regexCount ++;
@ -230,7 +232,7 @@ var wappalyzer = wappalyzer || (function() {
if ( regex.test(data[type][i]) ) { if ( regex.test(data[type][i]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }

@ -767,7 +767,7 @@
}, },
"jQuery": { "jQuery": {
"cats": [ "12" ], "cats": [ "12" ],
"script": "jquery.*.js", "script": "jquery.*\\.js",
"env": "^jQuery$" "env": "^jQuery$"
}, },
"jQuery Mobile": { "jQuery Mobile": {

@ -15,6 +15,22 @@
* Initialize * Initialize
*/ */
init: function() { init: function() {
// Load apps.json
var xhr = new XMLHttpRequest();
xhr.open('GET', 'apps.json', true);
xhr.overrideMimeType('application/json');
xhr.onload = function() {
var json = JSON.parse(xhr.responseText);
w.categories = json.categories;
w.apps = json.apps;
};
xhr.send(null);
window.document.addEventListener('DOMContentLoaded', function() { window.document.addEventListener('DOMContentLoaded', function() {
w.analyze('google.com', 'http://google.com', { w.analyze('google.com', 'http://google.com', {
html: '<script src="jquery.js"><meta name="generator" content="WordPress"/>', html: '<script src="jquery.js"><meta name="generator" content="WordPress"/>',

@ -105,7 +105,7 @@ var wappalyzer = wappalyzer || (function() {
} }
var var
i, app, type, regex, match, content, meta, header, i, app, type, regex, regexMeta, regexScript, match, content, meta, header,
profiler = { profiler = {
regexCount: 0, regexCount: 0,
startTime: ( new Date ).getTime() startTime: ( new Date ).getTime()
@ -113,86 +113,88 @@ var wappalyzer = wappalyzer || (function() {
apps = [] apps = []
; ;
appLoop:
for ( app in w.apps ) { for ( app in w.apps ) {
// Skip if the app has already been detected // Skip if the app has already been detected
if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) {
continue; continue;
} }
next:
for ( type in w.apps[app] ) { for ( type in w.apps[app] ) {
if ( data[type] == null ) {
continue;
}
switch ( type ) { switch ( type ) {
case 'url': case 'url':
regex = new RegExp(w.apps[app][type], 'i'); regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(url) ) { if ( regex.test(url) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
break; break;
case 'html': case 'html':
regex = new RegExp(w.apps[app][type], 'i'); if ( data[type] == null ) {
break;
}
regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(data[type]) ) { if ( regex.test(data[type]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
break; break;
case 'script': case 'script':
if ( data['html'] == null ) { if ( data.html == null ) {
break; break;
} }
regex = new RegExp(w.apps[app][type], 'i'); regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
regexScript = new RegExp('<script[^>]+src=("|\')([^"\']+)\1', 'ig');
profiler.regexCount ++; profiler.regexCount ++;
while ( match = new RegExp('<script[^>]+src=("|\')([^"\']+)\1', 'ig').exec(data['html']) ) { while ( match = regexScript.exec(data.html) ) {
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(match[2]) ) { if ( regex.test(match[2]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
break; break;
case 'meta': case 'meta':
if ( data['html'] == null ) { if ( data.html == null ) {
break; break;
} }
profiler.regexCount ++; profiler.regexCount ++;
while ( match = new RegExp('<meta[^>]+>', 'ig').exec(data['html']) ) { regexMeta = new RegExp('<meta[^>]+>', 'ig');
while ( match = regexMeta.exec(data.html) ) {
for ( meta in w.apps[app][type] ) { for ( meta in w.apps[app][type] ) {
profiler.regexCount ++; profiler.regexCount ++;
if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) {
content = match.toString().match(/content=("|')([^"']+)("|')/i); content = match.toString().match(/content=("|')([^"']+)("|')/i);
regex = new RegExp(w.apps[app].meta[meta], 'i'); regex = new RegExp(w.apps[app].meta[meta].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( content && content.length === 4 && regex.test(content[2]) ) { if ( content && content.length === 4 && regex.test(content[2]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
} }
@ -205,14 +207,14 @@ var wappalyzer = wappalyzer || (function() {
} }
for ( header in w.apps[app].headers ) { for ( header in w.apps[app].headers ) {
regex = new RegExp(w.apps[app][type][header], 'i'); regex = new RegExp(w.apps[app][type][header].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( data[type][header] != null && regex.test(data[type][header]) ) { if ( data[type][header] != null && regex.test(data[type][header]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
@ -222,7 +224,7 @@ var wappalyzer = wappalyzer || (function() {
break; break;
} }
regex = RegExp(w.apps[app][type], 'i'); regex = RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
for ( i in data[type] ) { for ( i in data[type] ) {
profiler.regexCount ++; profiler.regexCount ++;
@ -230,7 +232,7 @@ var wappalyzer = wappalyzer || (function() {
if ( regex.test(data[type][i]) ) { if ( regex.test(data[type][i]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }

@ -12,6 +12,8 @@ class Wappalyzer
protected protected
$v8, $v8,
$apps,
$categories,
$host, $host,
$url, $url,
$html, $html,
@ -23,9 +25,16 @@ class Wappalyzer
*/ */
public function __construct($url) public function __construct($url)
{ {
chdir(dirname(__FILE__));
$this->v8 = new V8Js(); $this->v8 = new V8Js();
$this->url = $url; $this->url = $url;
$json = json_decode(file_get_contents('apps.json'));
$this->apps = $json->apps;
$this->categories = $json->categories;
} }
/** /**
@ -35,7 +44,7 @@ class Wappalyzer
public function analyze() public function analyze()
{ {
try { try {
$this->load(array('wappalyzer.js', 'apps.js', 'driver.js')); $this->load(array('wappalyzer.js', 'driver.js'));
$result = $this->curl($this->url); $result = $this->curl($this->url);
@ -47,6 +56,8 @@ class Wappalyzer
)); ));
return $this->v8->executeString(' return $this->v8->executeString('
w.apps = ' . json_encode($this->apps) . ';
w.categories = ' . json_encode($this->categories) . ';
w.driver.debug = ' . ( $this->debug ? 'true' : 'false' ) . '; w.driver.debug = ' . ( $this->debug ? 'true' : 'false' ) . ';
w.driver.data = ' . $json . '; w.driver.data = ' . $json . ';

@ -767,7 +767,7 @@
}, },
"jQuery": { "jQuery": {
"cats": [ "12" ], "cats": [ "12" ],
"script": "jquery.*.js", "script": "jquery.*\\.js",
"env": "^jQuery$" "env": "^jQuery$"
}, },
"jQuery Mobile": { "jQuery Mobile": {

@ -105,7 +105,7 @@ var wappalyzer = wappalyzer || (function() {
} }
var var
i, app, type, regex, match, content, meta, header, i, app, type, regex, regexMeta, regexScript, match, content, meta, header,
profiler = { profiler = {
regexCount: 0, regexCount: 0,
startTime: ( new Date ).getTime() startTime: ( new Date ).getTime()
@ -113,86 +113,88 @@ var wappalyzer = wappalyzer || (function() {
apps = [] apps = []
; ;
appLoop:
for ( app in w.apps ) { for ( app in w.apps ) {
// Skip if the app has already been detected // Skip if the app has already been detected
if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) {
continue; continue;
} }
next:
for ( type in w.apps[app] ) { for ( type in w.apps[app] ) {
if ( data[type] == null ) {
continue;
}
switch ( type ) { switch ( type ) {
case 'url': case 'url':
regex = new RegExp(w.apps[app][type], 'i'); regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(url) ) { if ( regex.test(url) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
break; break;
case 'html': case 'html':
regex = new RegExp(w.apps[app][type], 'i'); if ( data[type] == null ) {
break;
}
regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(data[type]) ) { if ( regex.test(data[type]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
break; break;
case 'script': case 'script':
if ( data['html'] == null ) { if ( data.html == null ) {
break; break;
} }
regex = new RegExp(w.apps[app][type], 'i'); regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
regexScript = new RegExp('<script[^>]+src=("|\')([^"\']+)\1', 'ig');
profiler.regexCount ++; profiler.regexCount ++;
while ( match = new RegExp('<script[^>]+src=("|\')([^"\']+)\1', 'ig').exec(data['html']) ) { while ( match = regexScript.exec(data.html) ) {
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(match[2]) ) { if ( regex.test(match[2]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
break; break;
case 'meta': case 'meta':
if ( data['html'] == null ) { if ( data.html == null ) {
break; break;
} }
profiler.regexCount ++; profiler.regexCount ++;
while ( match = new RegExp('<meta[^>]+>', 'ig').exec(data['html']) ) { regexMeta = new RegExp('<meta[^>]+>', 'ig');
while ( match = regexMeta.exec(data.html) ) {
for ( meta in w.apps[app][type] ) { for ( meta in w.apps[app][type] ) {
profiler.regexCount ++; profiler.regexCount ++;
if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) {
content = match.toString().match(/content=("|')([^"']+)("|')/i); content = match.toString().match(/content=("|')([^"']+)("|')/i);
regex = new RegExp(w.apps[app].meta[meta], 'i'); regex = new RegExp(w.apps[app].meta[meta].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( content && content.length === 4 && regex.test(content[2]) ) { if ( content && content.length === 4 && regex.test(content[2]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
} }
@ -205,14 +207,14 @@ var wappalyzer = wappalyzer || (function() {
} }
for ( header in w.apps[app].headers ) { for ( header in w.apps[app].headers ) {
regex = new RegExp(w.apps[app][type][header], 'i'); regex = new RegExp(w.apps[app][type][header].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( data[type][header] != null && regex.test(data[type][header]) ) { if ( data[type][header] != null && regex.test(data[type][header]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
@ -222,7 +224,7 @@ var wappalyzer = wappalyzer || (function() {
break; break;
} }
regex = RegExp(w.apps[app][type], 'i'); regex = RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
for ( i in data[type] ) { for ( i in data[type] ) {
profiler.regexCount ++; profiler.regexCount ++;
@ -230,7 +232,7 @@ var wappalyzer = wappalyzer || (function() {
if ( regex.test(data[type][i]) ) { if ( regex.test(data[type][i]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }

@ -767,7 +767,7 @@
}, },
"jQuery": { "jQuery": {
"cats": [ "12" ], "cats": [ "12" ],
"script": "jquery.*.js", "script": "jquery.*\\.js",
"env": "^jQuery$" "env": "^jQuery$"
}, },
"jQuery Mobile": { "jQuery Mobile": {

@ -105,7 +105,7 @@ var wappalyzer = wappalyzer || (function() {
} }
var var
i, app, type, regex, match, content, meta, header, i, app, type, regex, regexMeta, regexScript, match, content, meta, header,
profiler = { profiler = {
regexCount: 0, regexCount: 0,
startTime: ( new Date ).getTime() startTime: ( new Date ).getTime()
@ -113,86 +113,88 @@ var wappalyzer = wappalyzer || (function() {
apps = [] apps = []
; ;
appLoop:
for ( app in w.apps ) { for ( app in w.apps ) {
// Skip if the app has already been detected // Skip if the app has already been detected
if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) {
continue; continue;
} }
next:
for ( type in w.apps[app] ) { for ( type in w.apps[app] ) {
if ( data[type] == null ) {
continue;
}
switch ( type ) { switch ( type ) {
case 'url': case 'url':
regex = new RegExp(w.apps[app][type], 'i'); regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(url) ) { if ( regex.test(url) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
break; break;
case 'html': case 'html':
regex = new RegExp(w.apps[app][type], 'i'); if ( data[type] == null ) {
break;
}
regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(data[type]) ) { if ( regex.test(data[type]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
break; break;
case 'script': case 'script':
if ( data['html'] == null ) { if ( data.html == null ) {
break; break;
} }
regex = new RegExp(w.apps[app][type], 'i'); regex = new RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
regexScript = new RegExp('<script[^>]+src=("|\')([^"\']+)\1', 'ig');
profiler.regexCount ++; profiler.regexCount ++;
while ( match = new RegExp('<script[^>]+src=("|\')([^"\']+)\1', 'ig').exec(data['html']) ) { while ( match = regexScript.exec(data.html) ) {
profiler.regexCount ++; profiler.regexCount ++;
if ( regex.test(match[2]) ) { if ( regex.test(match[2]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
break; break;
case 'meta': case 'meta':
if ( data['html'] == null ) { if ( data.html == null ) {
break; break;
} }
profiler.regexCount ++; profiler.regexCount ++;
while ( match = new RegExp('<meta[^>]+>', 'ig').exec(data['html']) ) { regexMeta = new RegExp('<meta[^>]+>', 'ig');
while ( match = regexMeta.exec(data.html) ) {
for ( meta in w.apps[app][type] ) { for ( meta in w.apps[app][type] ) {
profiler.regexCount ++; profiler.regexCount ++;
if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) {
content = match.toString().match(/content=("|')([^"']+)("|')/i); content = match.toString().match(/content=("|')([^"']+)("|')/i);
regex = new RegExp(w.apps[app].meta[meta], 'i'); regex = new RegExp(w.apps[app].meta[meta].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( content && content.length === 4 && regex.test(content[2]) ) { if ( content && content.length === 4 && regex.test(content[2]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
} }
@ -205,14 +207,14 @@ var wappalyzer = wappalyzer || (function() {
} }
for ( header in w.apps[app].headers ) { for ( header in w.apps[app].headers ) {
regex = new RegExp(w.apps[app][type][header], 'i'); regex = new RegExp(w.apps[app][type][header].replace('/', '\\\/'), 'i');
profiler.regexCount ++; profiler.regexCount ++;
if ( data[type][header] != null && regex.test(data[type][header]) ) { if ( data[type][header] != null && regex.test(data[type][header]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }
@ -222,7 +224,7 @@ var wappalyzer = wappalyzer || (function() {
break; break;
} }
regex = RegExp(w.apps[app][type], 'i'); regex = RegExp(w.apps[app][type].replace('/', '\\\/'), 'i');
for ( i in data[type] ) { for ( i in data[type] ) {
profiler.regexCount ++; profiler.regexCount ++;
@ -230,7 +232,7 @@ var wappalyzer = wappalyzer || (function() {
if ( regex.test(data[type][i]) ) { if ( regex.test(data[type][i]) ) {
apps.push(app); apps.push(app);
break next; continue appLoop;
} }
} }

Loading…
Cancel
Save