Permalink
8587f9e Oct 31, 2016
208 lines (170 sloc) 6.08 KB
"use strict";
/*********************************************************************************
Disable HTML5 Autoplay: A webbrowser extension to disable HTML5 autoplaying
Copyright (C) 2016 Eloston
This file is part of Disable HTML5 Autoplay.
Disable HTML5 Autoplay is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Disable HTML5 Autoplay is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Disable HTML5 Autoplay. If not, see <http://www.gnu.org/licenses/>.
********************************************************************************/
function g_error_handler(value) {
console.error(value);
}
const PROTOCOL = {
PAGE_FRAME: {
PORT_NAME: "frame"
},
POPUP: {
PORT_NAME: "popup",
INITIALIZE: "initialize"
}
};
class TabInstance {
constructor(tabid) {
this._tab_id = tabid;
this._pageframe_port = null;
this._popup_port = null;
this._metadata = new Object(); // TODO: Initialize actual tab metadata here
}
_api_error_logging_callback() {
if (chrome.runtime.lastError) {
g_error_handler(chrome.runtime.lastError);
}
}
_pageframe_port_onmessage(message) {
}
_pageframe_port_ondisconnect() {
this._pageframe_port = null;
// TODO: Initialize tab metadata here
}
_popup_port_onmessage(message) {
}
_popup_port_ondisconnect() {
this._popup_port = null;
}
_set_browser_action_icon(active) {
if (active) {
var icon_set = {
"19": "images/active_19.png",
"38": "images/active_38.png"
};
} else {
var icon_set = {
"19": "images/dormant_19.png",
"38": "images/dormant_38.png"
};
}
chrome.browserAction.setIcon({
tabId: this._tab_id,
path: icon_set
}, this._api_error_logging_callback.bind(this));
}
_set_browser_action_badge(value) {
chrome.browserAction.setBadgeText({
tabId: this._tab_id,
text: value
});
}
reload_tab() {
chrome.tabs.reload(this._tab_id, new Object(), this._api_error_logging_callback.bind(this));
}
get_current_mode() {
}
get_pending_mode() {
}
get_statistics() {
}
deconstruct() {
// TODO: Unregister event handlers and delete all links to this object (excluding TabManager)
// Also reset browser action back to original state?
}
// Move stuff using tabid from TabManager to this class
// Add callbacks here to listen to tabid changes
}
class TabManager {
constructor() {
// TODO: Should this change to WeakMap?
this._instances = new Map(); // mapping: tab id -> TabInstance
this._port_bootstrap_functions = new WeakMap();
}
_api_error_logging_callback() {
if (chrome.runtime.lastError) {
g_error_handler(chrome.runtime.lastError);
}
}
_popup_port_onmessage_boostrap(port, message) {
if (message.action = PROTOCOL.POPUP.INITIALIZE) {
if (message.tabid.constructor == Number) {
port.onMessage.removeListener(this._port_bootstrap_functions.get(port));
this._port_bootstrap_functions.delete(port);
let tab_instance = this._get_tab_instance(message.tabid);
port.onMessage.addListener(tab_instance._popup_port_onmessage.bind(tab_instance));
port.onDisconnect.addListener(tab_instance._popup_port_ondisconnect.bind(tab_instance));
} else {
// Throw error
}
} else {
// Throw error
}
}
_on_port_connect(port) {
if (port.name == PROTOCOL.PAGE_FRAME.PORT_NAME && ("tab" in port.sender)) {
if (port.sender.tab.id.constructor === Number) {
let tab_instance = this._get_tab_instance(message.tabid);
port.onMessage.addListener(tab_instance._pageframe_port_onmessage.bind(tab_instance));
port.onDisconnect.addListener(tab_instance._pageframe_port_ondisconnect.bind(tab_instance));
} else {
// Throw error
}
} else if (port.name == PROTOCOL.POPUP.PORT_NAME && !("tab" in port.sender)) {
let bootstrap_function = this._popup_port_onmessage_bootstrap.bind(this, port);
port.onMessage.addListener(bootstrap_function);
this._port_bootstrap_functions.set(port, bootstrap_function);
}
}
_add_tab_instance(tabid) {
if (this._instances.has(tabid)) {
// Throw error
} else {
this._instances.set(tabid, new TabInstance(tabid));
}
}
_get_tab_instance(tabid) {
if (!this.has_tab_instance(tabid)) {
// Throw error
}
return this._instances.get(tabid);
has_tab_instance(tabid) {
return this._instances.has(tabid);
}
remove_tab_instance(tabid) {
if (this._instances.has(tabid)) {
tab_instance = this._instances.get(tabid)
tab_instance.deconstruct();
this._instances.remove(tabid);
} else {
// Throw error
}
}
initialize() {
chrome.browserAction.setBadgeBackgroundColor({
color: [32, 32, 32, 200]
});
chrome.runtime.onConnect.addListener(this._on_port_connect.bind(this));
// Put chrome.tabs and other event handlers here
}
}
class StorageManager {
}
class OptionsManager {
}
g_tab_manager = new TabManager();
g_storage_manager = new StorageManager();
g_options_manager = new OptionsManager();