diff --git a/drivers/firefox/content/js/custom.js b/drivers/firefox/content/js/custom.js
deleted file mode 100644
index 9985186f1..000000000
--- a/drivers/firefox/content/js/custom.js
+++ /dev/null
@@ -1,62 +0,0 @@
-if ( typeof 'wappalyzer' != 'undefined' ) {
- wappalyzer.evaluateCustomApps = function(feedback) {
- wappalyzer.log('evaluateCustomApps');
-
- if ( wappalyzer.customApps ) {
- try {
- var customAppsJSON = JSON.parse(wappalyzer.customApps);
-
- for ( appName in customAppsJSON ) {
- wappalyzer.apps[appName] = {};
-
- // Icon
- if ( typeof(customAppsJSON[appName].icon) == 'string' ) {
- wappalyzer.apps[appName].icon = customAppsJSON[appName].icon;
- }
- else {
- wappalyzer.apps[appName].icon = 'chrome://wappalyzer/skin/app_icons/_placeholder.ico';
- }
-
- // Categories
- if ( typeof(customAppsJSON[appName].categories) == 'object' ) {
- wappalyzer.apps[appName].cats = {};
-
- for ( i in customAppsJSON[appName].categories ) {
- wappalyzer.apps[appName].cats[i] = parseInt(customAppsJSON[appName].categories[i]);
- }
- }
-
- // HTML
- if ( typeof(customAppsJSON[appName].html) == 'string' ) {
- wappalyzer.apps[appName].html = new RegExp(customAppsJSON[appName].html, 'i');
- }
-
- // URL
- if ( typeof(customAppsJSON[appName].url) == 'string' ) {
- wappalyzer.apps[appName].url = new RegExp(customAppsJSON[appName].url, 'i');
- }
-
- // Headers
- if ( typeof(customAppsJSON[appName].headers) == 'object' ) {
- wappalyzer.apps[appName].headers = {};
-
- for ( headerName in customAppsJSON[appName].headers ) {
- wappalyzer.apps[appName].headers[headerName] = new RegExp(customAppsJSON[appName].headers[headerName], 'i');
- }
- }
- }
-
- if ( feedback ) {
- alert('Ok');
- }
- }
- catch(e) {
- wappalyzer.log('JSON error in custom applications');
-
- if ( feedback ) {
- alert('Error: malformed JSON');
- }
- }
- }
- };
-}
diff --git a/drivers/firefox/content/js/evaluate.js b/drivers/firefox/content/js/evaluate.js
deleted file mode 100644
index 7f4866e69..000000000
--- a/drivers/firefox/content/js/evaluate.js
+++ /dev/null
@@ -1,147 +0,0 @@
-if ( typeof(wappalyzer) == 'undefined' )
-{
- var wappalyzer = {};
-
- wappalyzer.log = function(message)
- {
- if ( message )
- {
- var consoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
-
- consoleService.logStringMessage("Wappalyzer: " + message);
- }
- };
-}
-
-wappalyzer.evaluateCustomApps = function(customApps, feedback)
-{
- wappalyzer.log('evaluateCustomApps');
-
- var appsAdded = {};
-
- if ( customApps || wappalyzer.customApps )
- {
- try
- {
- var customAppsJSON = JSON.parse(feedback ? customApps : wappalyzer.customApps);
-
- for ( appName in customAppsJSON )
- {
- wappalyzer.apps[appName] = {
- custom: true
- };
-
- appsAdded[appName] = true;
-
- // Icon
- if ( typeof(customAppsJSON[appName].icon) == 'string' )
- {
- wappalyzer.apps[appName].icon = customAppsJSON[appName].icon;
- }
- else
- {
- wappalyzer.apps[appName].icon = 'chrome://wappalyzer/skin/app_icons/_placeholder.ico';
- }
-
- // Categories
- if ( typeof(customAppsJSON[appName].categories) == 'object' )
- {
- wappalyzer.apps[appName].cats = {};
-
- for ( i in customAppsJSON[appName].categories )
- {
- var id = parseInt(customAppsJSON[appName].categories[i]);
-
- if ( typeof(wappalyzer.cats[id]) != 'undefined' )
- {
- wappalyzer.apps[appName].cats[i] = id;
- }
- }
- }
-
- // HTML
- if ( typeof(customAppsJSON[appName].html) == 'string' )
- {
- wappalyzer.apps[appName].html = new RegExp(customAppsJSON[appName].html, 'i');
- }
-
- // URL
- if ( typeof(customAppsJSON[appName].url) == 'string' )
- {
- wappalyzer.apps[appName].url = new RegExp(customAppsJSON[appName].url, 'i');
- }
-
- // Headers
- if ( typeof(customAppsJSON[appName].headers) == 'object' )
- {
- wappalyzer.apps[appName].headers = {};
-
- for ( headerName in customAppsJSON[appName].headers )
- {
- wappalyzer.apps[appName].headers[headerName] = new RegExp(customAppsJSON[appName].headers[headerName], 'i');
- }
- }
- }
-
- if ( feedback )
- {
- var text = '';
- var count = 0;
-
- for ( appName in appsAdded )
- {
- text += ' \n\n' + appName;
-
- if ( typeof(wappalyzer.apps[appName].cats) == 'object' )
- {
- for ( i in wappalyzer.apps[appName].cats )
- {
- text += ' [' + wappalyzer.cats[wappalyzer.apps[appName].cats[i]].name + ']';
- }
- }
-
- text += '\n Icon [' + ( wappalyzer.apps[appName].icon != 'chrome://wappalyzer/skin/app_icons/_placeholder.ico' ? 'Yes' : 'No' ) + ']';
-
- text +=
- ' HTML [' + ( typeof(wappalyzer.apps[appName].html) == 'object' ? 'Yes' : 'No' ) + ']' +
- ' URL [' + ( typeof(wappalyzer.apps[appName].url) == 'object' ? 'Yes' : 'No' ) + ']'
- ;
-
- text += ' Headers';
-
- if ( typeof(wappalyzer.apps[appName].headers) == 'object' )
- {
- for ( header in wappalyzer.apps[appName].headers )
- {
- text += ' [' + header + ']';
- }
- }
- else
- {
- text += ' [No]';
- }
-
- count ++;
- }
-
- alert('Ok. Found ' + count + ' application(s):' + text);
- }
- }
- catch(e)
- {
- wappalyzer.log('evaluateCustomApps: malformed JSON');
-
- if ( feedback )
- {
- alert('Error: malformed JSON.');
- }
- }
- }
- else
- {
- if ( feedback )
- {
- alert('Nothing to evaluate!');
- }
- }
-};
diff --git a/drivers/firefox/content/xul/preferences.xul b/drivers/firefox/content/xul/preferences.xul
index fcd08bfb0..3b9b75993 100755
--- a/drivers/firefox/content/xul/preferences.xul
+++ b/drivers/firefox/content/xul/preferences.xul
@@ -33,6 +33,8 @@
+
+
@@ -144,6 +146,12 @@
+
+
+
+
+
+
diff --git a/drivers/firefox/defaults/preferences/defaults.js b/drivers/firefox/defaults/preferences/defaults.js
index ae978ff25..1982b0b52 100644
--- a/drivers/firefox/defaults/preferences/defaults.js
+++ b/drivers/firefox/defaults/preferences/defaults.js
@@ -29,3 +29,5 @@ pref('extensions.wappalyzer.cat22', true);
pref('extensions.wappalyzer.cat23', true);
pref('extensions.wappalyzer.cat24', true);
pref('extensions.wappalyzer.cat25', true);
+pref('extensions.wappalyzer.cat26', true);
+pref('extensions.wappalyzer.cat27', true);
diff --git a/share/images/icons/CakePHP.ico b/share/images/icons/CakePHP.ico
new file mode 100644
index 000000000..b88e45daf
Binary files /dev/null and b/share/images/icons/CakePHP.ico differ
diff --git a/share/images/icons/Mongrel.ico b/share/images/icons/Mongrel.ico
new file mode 100644
index 000000000..36829b9a5
Binary files /dev/null and b/share/images/icons/Mongrel.ico differ
diff --git a/share/images/icons/Ruby.ico b/share/images/icons/Ruby.ico
new file mode 100644
index 000000000..7f8cb129e
Binary files /dev/null and b/share/images/icons/Ruby.ico differ
diff --git a/share/js/apps.js b/share/js/apps.js
index f845d9cef..5478763b0 100644
--- a/share/js/apps.js
+++ b/share/js/apps.js
@@ -54,6 +54,7 @@
'Blogger': { cats: { 1: 11 }, meta: { 'generator': /blogger/i }, url: /^(www.)?.+\.blogspot\.com/i },
'Bugzilla': { cats: { 1: 13 }, html: /<[^>]+(id|title|name)=("|')bugzilla/i },
'Burning Board': { cats: { 1: 2 }, html: /]+woltlab\.com.+Burning Board/i },
+ 'CakePHP': { cats: { 1: 18 }, headers: { 'Set-Cookie': /CAKEPHP=/ }, meta: { 'application-name': /CakePHP/ } },
'Chameleon': { cats: { 1: 1 }, meta: { 'generator': /chameleon\-cms/i } },
'chartbeat': { cats: { 1: 10 }, html: /function loadChartbeat\(\) {/i },
'Chamilo': { cats: { 1: 21 }, meta: { 'generator': /Chamilo/i }, headers: { 'X-Powered-By': /Chamilo/ } },
@@ -150,6 +151,7 @@
'Modernizr': { cats: { 1: 12 }, script: /modernizr.*\.js/ },
'MODx': { cats: { 1: 1 }, html: /(]+>Powered by MODx<\/a>|var el= \$\('modxhost'\);|