Firefox driver refactoring, improved multi-window support

main
Elbert Alias 11 years ago
parent abd0e0f4ce
commit b2cd820f16

@ -10,18 +10,18 @@
detectedApps.removeChild(detectedApps.firstChild); detectedApps.removeChild(detectedApps.firstChild);
} }
if ( message.tabCache.count > 0 ) { if ( message.tabs.count > 0 ) {
empty.style.display = 'none'; empty.style.display = 'none';
for ( appName in message.tabCache.appsDetected ) { for ( appName in message.tabs.appsDetected ) {
div = d.createElement('div'); div = d.createElement('div');
a = d.createElement('a'); a = d.createElement('a');
img = d.createElement('img'); img = d.createElement('img');
label = d.createElement('span'); label = d.createElement('span');
name = d.createElement('span'); name = d.createElement('span');
confidence = message.tabCache.appsDetected[appName].confidenceTotal; confidence = message.tabs.appsDetected[appName].confidenceTotal;
version = message.tabCache.appsDetected[appName].version; version = message.tabs.appsDetected[appName].version;
div.setAttribute('class', 'detected-app'); div.setAttribute('class', 'detected-app');

@ -2,19 +2,16 @@
'use strict'; 'use strict';
var var
w = require('wappalyzer').wappalyzer,
{Cc, Ci} = require('chrome'), {Cc, Ci} = require('chrome'),
main = require('wappalyzer'),
w = main.wappalyzer,
tabCache = {},
headersCache = {}, headersCache = {},
categoryNames = {}, categoryNames = {},
initTab, windows = [],
Window,
Tab,
Panel, Panel,
panel,
Widget, Widget,
widget, UrlBar;
UrlBar,
urlBar;
exports.main = function(options, callbacks) { exports.main = function(options, callbacks) {
w.log('main: ' + options.loadReason); w.log('main: ' + options.loadReason);
@ -23,26 +20,144 @@
}; };
exports.onUnload = function(reason) { exports.onUnload = function(reason) {
var win;
w.log('unload: ' + reason); w.log('unload: ' + reason);
if ( urlBar ) { for each ( win in windows ) {
urlBar.destroy(); win.destroy();
}
};
Window = function(win) {
var
self = this,
tab;
this.window = win;
this.tabs = {};
this.urlBar = null;
this.widget = null;
if ( require('sdk/simple-prefs').prefs.urlbar ) {
this.urlBar = new UrlBar();
} else {
this.widget = new Widget();
}
require('sdk/simple-prefs').on('urlbar', function() {
self.destroy();
if ( require('sdk/simple-prefs').prefs.urlbar ) {
self.urlBar = new UrlBar();
} else {
self.widget = new Widget();
} }
if ( widget ) { self.displayApps();
widget.destroy(); });
for each ( tab in this.window.tabs ) {
this.tabs[tab.id] = new Tab(tab);
} }
if ( panel ) { this.window.tabs
panel.destroy(); .on('open', function(tab) {
self.tabs[tab.id] = new Tab(tab);
})
.on('close', function(tab) {
self.tabs[tab.id] = null;
})
.on('activate', function(tab) {
self.displayApps();
});
self.displayApps();
};
Window.prototype.displayApps = function() {
var
self = this,
tab = this.window.tabs.activeTab,
url,
count = 0,
message = {};
w.log('Window.displayApps');
if ( !tab || require('sdk/tabs').activeTab !== tab ) {
return;
} }
url = tab.url.replace(/#.*$/, '');
count = w.detected[url] ? Object.keys(w.detected[url]).length : 0;
this.tabs[tab.id].count = count;
this.tabs[tab.id].appsDetected = w.detected[url];
message = {
tabs: this.tabs[tab.id],
apps: w.apps,
categories: w.categories,
categoryNames: categoryNames
}; };
initTab = function(tab) { if ( this.urlBar ) {
w.log('initTab'); this.urlBar.clear();
tabCache[tab.id] = { count: 0, appsDetected: [] }; // Add icons
if ( count ) {
for ( appName in this.tabs[tab.id].appsDetected ) {
this.urlBar.addIcon(appName);
}
} else {
this.urlBar.addIcon();
}
this.urlBar.panel.get().port.emit('displayApps', message);
}
if ( this.widget ) {
this.widget.setIcon();
if ( count ) {
var
appName,
found = false;
// Find the main application to display
w.driver.categoryOrder.forEach(function(match) {
for ( appName in w.detected[url] ) {
w.apps[appName].cats.forEach(function(cat) {
if ( cat == match && !found ) {
self.widget.setIcon(appName);
found = true;
}
});
}
});
}
this.widget.panel.get().port.emit('displayApps', message);
}
};
Window.prototype.destroy = function() {
if ( this.urlBar ) {
this.urlBar.destroy();
this.urlBar = null;
}
if ( this.widget ) {
this.widget.destroy();
this.widget = null;
}
};
Tab = function(tab) {
tab.on('ready', function(tab) { tab.on('ready', function(tab) {
var worker = tab.attach({ var worker = tab.attach({
contentScriptFile: require('sdk/self').data.url('js/tab.js') contentScriptFile: require('sdk/self').data.url('js/tab.js')
@ -64,11 +179,6 @@
}); });
}; };
require('sdk/tabs')
.on('open', initTab)
.on('close', function(tab) { tabCache[tab.id] = null; })
.on('activate', function(tab) { w.driver.displayApps(); });
Panel = function() { Panel = function() {
var self = this; var self = this;
@ -99,27 +209,37 @@
this.panel.destroy(); this.panel.destroy();
}; };
Widget = function(panel) { Widget = function() {
this.panel = new Panel();
this.widget = require('sdk/widget').Widget({ this.widget = require('sdk/widget').Widget({
id: 'wappalyzer', id: 'wappalyzer-' + ( new Date() ).getTime() + ( Math.floor( Math.random() * 900 ) + 100 ),
label: 'Wappalyzer', label: 'Wappalyzer',
contentURL: require('sdk/self').data.url('images/icon32.png'), contentURL: require('sdk/self').data.url('images/icon32.png'),
panel: panel.get() panel: this.panel.get()
}); });
}; };
Widget.prototype.setIcon = function(appName) {
var url = typeof appName === 'undefined' ? 'images/icon32_hot.png' : 'images/icons/' + appName + '.png';
this.get().contentURL = require('sdk/self').data.url(url);
};
Widget.prototype.get = function() { Widget.prototype.get = function() {
return this.widget; return this.widget;
}; };
Widget.prototype.destroy = function() { Widget.prototype.destroy = function() {
this.panel.destroy();
this.widget.destroy(); this.widget.destroy();
}; };
UrlBar = function(panel) { UrlBar = function() {
var self = this; var self = this;
this.panel = panel; this.panel = new Panel();
this.onClick = function() { this.onClick = function() {
self.panel.get().show(); self.panel.get().show();
@ -146,7 +266,7 @@
UrlBar.prototype.addIcon = function(appName) { UrlBar.prototype.addIcon = function(appName) {
var var
icon = this.document.createElement('image'), icon = this.document.createElement('image'),
url = typeof appName !== 'undefined' ? 'images/icons/' + appName + '.png' : 'images/icon32.png', url = typeof appName === 'undefined' ? 'images/icon32.png' : 'images/icons/' + appName + '.png',
tooltipText = ( typeof appName !== 'undefined' ? appName + ' - ' + require('sdk/l10n').get('clickForDetails') + ' - ' : '' ) + require('sdk/l10n').get('name'); tooltipText = ( typeof appName !== 'undefined' ? appName + ' - ' + require('sdk/l10n').get('clickForDetails') + ' - ' : '' ) + require('sdk/l10n').get('name');
icon.setAttribute('src', require('sdk/self').data.url(url)); icon.setAttribute('src', require('sdk/self').data.url(url));
@ -168,7 +288,7 @@
icons = this.get().getElementsByClassName('wappalyzer-icon'); icons = this.get().getElementsByClassName('wappalyzer-icon');
if ( icons.length ) { if ( icons.length ) {
urlBar.get().removeChild(icons[0]); this.get().removeChild(icons[0]);
} }
} while ( icons.length ); } while ( icons.length );
@ -176,6 +296,8 @@
}; };
UrlBar.prototype.destroy = function() { UrlBar.prototype.destroy = function() {
this.panel.destroy();
this.urlBar.removeEventListener('click', this.onClick); this.urlBar.removeEventListener('click', this.onClick);
this.urlBar.remove(); this.urlBar.remove();
@ -197,23 +319,15 @@
init: function(callback) { init: function(callback) {
var var
id, id,
tab,
version, version,
win,
httpRequestObserver, httpRequestObserver,
json = JSON.parse(require('sdk/self').data.load('apps.json')); json = JSON.parse(require('sdk/self').data.load('apps.json'));
w.log('driver.init'); w.log('driver.init');
panel = new Panel();
if ( require('sdk/simple-prefs').prefs.urlbar ) {
urlBar = new UrlBar(panel);
} else {
widget = new Widget(panel);
}
try { try {
var version = require('sdk/self').version; version = require('sdk/self').version;
if ( !require('sdk/simple-storage').storage.version ) { if ( !require('sdk/simple-storage').storage.version ) {
w.driver.goToURL({ url: w.config.websiteURL + 'installed', medium: 'install' }); w.driver.goToURL({ url: w.config.websiteURL + 'installed', medium: 'install' });
@ -231,26 +345,15 @@
categoryNames[id] = require('sdk/l10n').get('cat' + id); categoryNames[id] = require('sdk/l10n').get('cat' + id);
} }
for each ( tab in require('sdk/tabs') ) { require('sdk/windows').browserWindows
initTab(tab); .on('open', function(win) {
} windows.push(new Window(win));
});
require('sdk/simple-prefs').on('urlbar', function() {
panel = new Panel();
if ( !require('sdk/simple-prefs').prefs.urlbar ) {
urlBar.destroy();
widget = new Widget(panel);
} else {
urlBar = new UrlBar(panel);
widget.get().destroy(); for each ( win in require('sdk/windows').browserWindows ) {
windows.push(new Window(win));
} }
w.driver.displayApps();
});
httpRequestObserver = { httpRequestObserver = {
init: function() { init: function() {
var observerService = Cc['@mozilla.org/observer-service;1'].getService(Ci.nsIObserverService); var observerService = Cc['@mozilla.org/observer-service;1'].getService(Ci.nsIObserverService);
@ -286,8 +389,6 @@
}; };
httpRequestObserver.init(); httpRequestObserver.init();
w.driver.displayApps();
}, },
goToURL: function(args) { goToURL: function(args) {
@ -296,72 +397,6 @@
require('sdk/tabs').open({ url: url, inBackground: typeof args.background !== 'undefined' && args.background }); require('sdk/tabs').open({ url: url, inBackground: typeof args.background !== 'undefined' && args.background });
}, },
displayApps: function() {
var url, count;
w.log('display apps');
if ( !require('sdk/tabs').activeTab ) {
return;
}
url = require('sdk/tabs').activeTab.url.replace(/#.*$/, '');
count = w.detected[url] ? Object.keys(w.detected[url]).length : 0;
if ( !panel.get() ) {
panel = new Panel();
if ( require('sdk/simple-prefs').prefs.urlbar ) {
urlBar = new UrlBar(panel);
} else {
widget = new Widget(panel);
}
}
if ( typeof tabCache[require('sdk/tabs').activeTab.id] === 'undefined' ) {
initTab(require('sdk/tabs').activeTab);
}
tabCache[require('sdk/tabs').activeTab.id].count = count;
tabCache[require('sdk/tabs').activeTab.id].appsDetected = w.detected[url];
if ( require('sdk/simple-prefs').prefs.urlbar ) {
urlBar.clear();
// Add icons
if ( count ) {
for ( appName in tabCache[require('sdk/tabs').activeTab.id].appsDetected ) {
urlBar.addIcon(appName);
}
} else {
urlBar.addIcon();
}
} else {
widget.get().contentURL = require('sdk/self').data.url('images/icon32_hot.png');
if ( count ) {
// Find the main application to display
var
appName,
found = false;
w.driver.categoryOrder.forEach(function(match) {
for ( appName in w.detected[url] ) {
w.apps[appName].cats.forEach(function(cat) {
if ( cat == match && !found ) {
widget.get().contentURL = require('sdk/self').data.url('images/icons/' + appName + '.png'),
found = true;
}
});
}
});
}
}
panel.get().port.emit('displayApps', { tabCache: tabCache[require('sdk/tabs').activeTab.id], apps: w.apps, categories: w.categories, categoryNames: categoryNames });
},
ping: function() { ping: function() {
var Request = require('sdk/request').Request; var Request = require('sdk/request').Request;
@ -380,6 +415,14 @@
} }
}, },
displayApps: function() {
var win;
for each ( win in windows ) {
win.displayApps();
}
},
categoryOrder: [ // Used to pick the main application categoryOrder: [ // Used to pick the main application
1, // CMS 1, // CMS
11, // Blog 11, // Blog