diff options
Diffstat (limited to 'src/js/fiveui/js/background.js')
-rw-r--r-- | src/js/fiveui/js/background.js | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/src/js/fiveui/js/background.js b/src/js/fiveui/js/background.js new file mode 100644 index 0000000..c0d4e07 --- /dev/null +++ b/src/js/fiveui/js/background.js @@ -0,0 +1,210 @@ +/* + * Module : background.js + * Copyright : (c) 2011-2012, Galois, Inc. + * + * Maintainer : + * Stability : Provisional + * Portability: Portable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var fiveui = fiveui || {}; + +(function() { +/** + * @constructor + * + * @param {!function(!string):!string} dataLoader + */ +fiveui.Background = function(settings, updateWidget, loadScripts, dataLoader) { + // Initialize a storage mechanism for FiveUI. + // Chrome utilizes HTML5's localStorage API as a backend, but other + // contexts (such as Firefox) would supply a different backend + // storage to the settings constructor. + // + // The data in settings is persisted across executions of the + // context and the plugin. It is used for long-term storage of user + // preferences, rule sets, and similarly long-lived FiveUI settings. + this.settings = settings; + + // the state of all managed tabs + this.state = new fiveui.State(settings); + + // how we communicate with the status widget + this.updateWidget = updateWidget; + + // how we signal the browser to load a content script + this.loadScripts = loadScripts; + + this.dataLoader = dataLoader; +}; + +fiveui.Background.prototype._registerComputeListeners = function(port, tabState){ + var bg = this; + port.on('ReportProblem', function(request) { + var problem = fiveui.Problem.fromJSON(request); + if(tabState.addProblem(problem) && tabState.uiPort != null) { + bg.updateWidget(tabState); + tabState.uiPort.emit('ShowProblem', problem); + } + }); + port.on('ReportStats', function (stats) { + if (tabState.addStats(stats) && tabState.uiPort != null) { + bg.updateWidget(tabState); + tabState.uiPort.emit('ShowStats', stats); + } + }); +}; + +fiveui.Background.prototype._registerUiListeners = function(port, tabState){ + var bg = this; + port.on('Position', function(request) { + tabState.winState.x = request.left; + tabState.winState.y = request.top; + }); + port.on('Size', function(request) { + tabState.winState.width = request.width; + tabState.winState.height = request.height; + }); + port.on('CloseUI', function(request) { + tabState.winState.closed = true; + }); + port.on('ClearProblems', function(request) { + tabState.clearProblems(); + bg.updateWidget(tabState); + }); + port.on('MaskRules', function(request) { + _.each(tabState.computePorts, function(cp) { + cp.emit('MaskRules', null); + }); + }); + port.on('UnmaskRules', function(request) { + _.each(tabState.computePorts, function(cp) { + cp.emit('UnmaskRules', null); + }); + }); +}; + +/** + * Accept a new connection from a content script. + */ +fiveui.Background.prototype.connect = function(tabId, port, url, isUiPort) { + + var tabState = this.state.acquireTabState(tabId); + + if (isUiPort) { + tabState.uiPort = port; + this._registerUiListeners(port, tabState); + port.emit('RestoreUI', tabState.toEmit()); + this.updateWidget(tabState); + } else { + tabState.computePorts.push(port); + this._registerComputeListeners(port, tabState); + + // get the rule set and send it down to the injected page: + var pat = this.settings.checkUrl(url); + if (!pat) { + console.err('could not find url pattern for tab.url, but one was strongly expected'); + } else { + var ruleSet = this.settings.getRuleSet(pat.rule_id); + + port.emit('SetRules', ruleSet); + } + } +}; + +/** + * @param {!number} tabId + * @param {!string} url + * @param {*} data + */ +fiveui.Background.prototype.pageLoad = function(tabId, url, data) { + var pat = this.settings.checkUrl(url); + + if (null == pat) { + this.updateWidget(null); + } else { + var tabState = this.state.acquireTabState(tabId); + tabState.computePorts = []; + + this.updateWidget(tabState); + + var dependencies = []; + var ruleSet = this.settings.getRuleSet(pat.rule_id); + + if (ruleSet && ruleSet.dependencies ) { + dependencies = ruleSet.dependencies; + } + + var computeScripts = _.flatten( + [ [ this.dataLoader('jquery/jquery-1.8.3.js') + , this.dataLoader('md5.js') + , this.dataLoader('injected/prelude.js') + , this.dataLoader('injected/jquery-plugins.js') + ] + , dependencies + , [ this.dataLoader('injected/compute.js') + ] + ]); + this.loadScripts(tabId, computeScripts, true, data); + + var uiScripts = _.flatten( + [ this.dataLoader('jquery/bundled.css') + , this.dataLoader('jquery/jquery-1.8.3.js') + , this.dataLoader('jquery/jquery-ui-1.9.2.custom.js') + , this.dataLoader('injected/injected.css') + , this.dataLoader('injected/prelude.js') + , this.dataLoader('injected/ui.js') + , this.dataLoader('injected/jquery-plugins.js') + ]); + this.loadScripts(tabId, uiScripts, false, data); + } +}; + +/** + * Updates the widget according to the tab state of the specified tab. + * + * @param {!number} tabId Id of the tab that is currently active, and + * thus, dictating the widget display. + */ +fiveui.Background.prototype.activate = function(tabId) { + var tabState = this.state.getTabState(tabId); + this.updateWidget(tabState); +}; + +/** + * Stop tracking the state of a tab. + * + * @param {!number} tabId Id of the tab to free the state of. + */ +fiveui.Background.prototype.removeTab = function(tabId) { + this.state.removeTabState(tabId); +}; + +/** + * Request that the user interface be restored, if it is closed. + */ +fiveui.Background.prototype.showUI = function(tabId) { + var tabState = this.state.getTabState(tabId); + if(null == tabState) { + return; + } + + if(tabState.winState.closed) { + tabState.winState.closed = false; + tabState.uiPort.emit('ShowUI', null); + } +}; + +})(); |