Permalink
Browse files

major overhaul. refactored to be more modular. fixed having to click …

…button twice bug. now preserves state thru refreshes.
  • Loading branch information...
1 parent 9b435ab commit 3b3214717b73f18ea41041df7b348451ad9ef1b4 @sym3tri committed May 8, 2011
Showing with 124 additions and 44 deletions.
  1. +85 −29 background.html
  2. +39 −15 loadcss.js
View
@@ -3,61 +3,117 @@
<script>
// TODO: Shortcut keys
- // TODO: Optionally remove all existing CSS?
- // TODO: Keep 'on' state after page refresh
+ // TODO: Optionally remove ALL existing CSS?
- var state = 'off';
+ // global object to track on/off state of each tab
+ var state = {};
+ // Displays error messages
function error(msg) {
alert('ERROR: ' + msg);
}
+ // Turn on the plugin badge and inject the css
function turnOn(tabId) {
- state = 'on';
- chrome.browserAction.setBadgeText({text: 'on', tabId: tabId});
- }
-
- function turnOff(tabId) {
- chrome.browserAction.setBadgeText({text: '', tabId: tabId});
- state = 'off';
- }
-
- function isUrlValid(url) {
- return (url && url.length > 3) ? true : false;
- }
-
- // EVENTS
-
- // User clicked the activate action button
- chrome.browserAction.onClicked.addListener(function(tab) {
// error check
if (!isUrlValid(localStorage['cssfile'])) {
error('No CSS url specified. Please specify url in extesion options.');
return;
}
- // toggle state on click
- state = state === 'off' ? 'on' : 'off';
+ // update state
+ state[tabId] = 'on';
+
+ // send request to content script
+ sendInjectionRequest(tabId, state[tabId], function() {
+
+ // update badge
+ chrome.browserAction.setBadgeText({text: 'on', tabId: tabId});
+ });
+ }
+
+ // Turn off the plugin badge
+ function turnOff(tabId) {
+
+ // just delete the property if it exists
+ delete state[tabId];
+
+ // send request to content script
+ sendInjectionRequest(tabId, 'off', function() {
+
+ // update badge
+ chrome.browserAction.setBadgeText({text: '', tabId: tabId});
+ });
+ }
+
+ // send 'load/unload' request to the embedded content script
+ function sendInjectionRequest(tabId, tabState, callback) {
- // send a 'load/unload' msg to the embedded content script
chrome.tabs.sendRequest(
- tab.id,
+ tabId,
{
- state: state,
- id: 'cssinject-injected-cssfile',
+ // state of current tab
+ state: tabState,
+ // id of <link> element to inject
+ id: 'cssinject-injected-cssfile',
+ // css file path specified by user in options plus a timestamp to prevent caching
href: localStorage['cssfile'] + '?' + (new Date()).getTime()
},
function(resp) {
+ // something went wrong
if (!resp.ok) {
error('Could not load CSS file');
}
-
- state === 'on' ? turnOn(tab.id) : turnOff(tab.id);
+ if (callback) {
+ callback();
+ }
}
);
+ }
+
+ // Checks if the supplied url is valid
+ // TODO: make this more robust
+ function isUrlValid(url) {
+ return (url && url.length > 3) ? true : false;
+ }
+
+ // toggles css injection on/off
+ function toggleInjection(tab) {
+
+ // toggle state on click
+ state[tab.id] === 'on' ? turnOff(tab.id) : turnOn(tab.id);
+ }
+
+ // restore state on page reloads
+ function restoreState(req, sender, sendResponse) {
+
+ // first get current window
+ chrome.windows.getCurrent(function(win) {
+
+ // then get current tab
+ chrome.tabs.getSelected(win.id, function(tab) {
+
+ // check the tab's state
+ if (state[tab.id] === 'on') {
+
+ // if it should be on turn it on
+ turnOn(tab.id);
+
+ // notify content script that all is good
+ sendResponse({ok: true});
+ }
+ });
+ });
+ }
+
+ // EVENT HANDLERS
+
+ // User clicked the activate action button, kick off all the injection goodness
+ chrome.browserAction.onClicked.addListener(toggleInjection);
- });
+ // Handle requests from embedded content script
+ chrome.extension.onRequest.addListener(restoreState);
</script>
</head>
View
@@ -1,17 +1,4 @@
-// DOM manipulation must exist inside this "content script" in order to execute in the proper context of the page
-
-// listen to requests from background.html
-chrome.extension.onRequest.addListener(
-
- // depending on state value, injext/remove css
- function(req, sender, sendResponse) {
- req.state === 'on'
- ? appendStyleNode(req.id, req.href)
- : removeStyleNode(req.id);
-
- sendResponse({ok: true});
- }
-);
+// All DOM manipulation must exist inside this "content script" in order to execute in the proper context of the page
// inject the css file into the head element
function appendStyleNode(id, href) {
@@ -23,8 +10,45 @@ function appendStyleNode(id, href) {
document.getElementsByTagName('head')[0].appendChild(cssNode);
}
-// remove the css
+// removes the css
function removeStyleNode(id) {
var node = document.getElementById(id);
node && node.parentNode.removeChild(node);
}
+
+// currently does nothing but alert if error
+function restoreStateCallback(resp) {
+ if (!resp.ok) {
+ alert('Error re-injecting css on refresh. Try pushing the button again');
+ }
+}
+
+
+// EVENT LISTENERS
+
+// override window onload event to check the state of the current tab on each page load
+var oldWindowOnload = window.onload;
+window.onload = function() {
+
+ // send request to background page to restore the state (since only it knows about state)
+ chrome.extension.sendRequest({action: 'restoreState'}, restoreStateCallback);
+
+ // execute any previously existing window onload events
+ if (oldWindowOnload && typeof(oldWindowOnload) === 'function') {
+ oldWindowOnload();
+ }
+};
+
+// listen to injections/removal requests from background.html
+chrome.extension.onRequest.addListener(
+
+ // depending on state value, injext/remove css
+ function(req, sender, sendResponse) {
+ req.state === 'on'
+ ? appendStyleNode(req.id, req.href)
+ : removeStyleNode(req.id);
+
+ // notify of no problems
+ sendResponse({ok: true});
+ }
+);

0 comments on commit 3b32147

Please sign in to comment.