Reputation: 551
I've written a chrome extension that redirects the current tab based on the value of a timer injected as a content script. A background script keeps track of elapsed times across all open tabs by polling each timer every once in a while, and if time spent on a particular site is over a given limit, redirects the active tab to an interstitial page with the option to reset the timer and restore the previous URL. This works, but once the timer has been reset once, chrome.tabs.update()
redirects the active tab to chrome-extension://invalid/
. I'm not sure why, or even how to diagnose what's going on here.
Here's how it's supposed to work, step by step. First, an if
block in the background script is triggered when time's up:
background.js:
if (time_elapsed > time_limit) {
settings.restore_url = tab.url;
var timeup_url = chrome.extension.getURL('timeup.html');
update_icon("off");
chrome.tabs.update({url: timeup_url});
}
This saves the current tab's url to a settings
object, gets the URL of the static page timeup.html
from the extension directory, updates the toolbar icon, and redirects the current tab to timeup.html
.
timeup.html:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="bootstrap.css" type="text/css">
<style>
.hero-unit {
background-color: #ffffff;
text-align: center;
}
.icon {
vertical-align: middle;
}
.xlarge {
font-size: 20px;
}
</style>
<script src="timeup.js" type="text/javascript"></script>
<title>Tabminder</title>
</head>
<body>
<div class="container">
<div class="row-responsive">
<div class="hero-unit">
<h1>Don't get distracted!</h1>
<p>You've been browsing a timesink site for too long.</p>
<p>
<a class="btn btn-inverse btn-large xlarge" id="close-tabs"><img src="img/remove.png">
<span class="icon"> Close tab</span>
</a>
<a class="btn btn-danger btn-large xlarge" id="restart-timer"><img src="img/repeat.png">
<span class="icon"> Restart timer</span>
</a>
</p>
</div>
</div>
</div>
</body>
</html>
This is pretty simple. Two buttons that are hooked up to 'click'
event listeners in...
timeup.js:
document.addEventListener('DOMContentLoaded', function () {
document.getElementById("close-tabs").addEventListener('click', close_tabs);
document.getElementById("restart-timer").addEventListener('click', restart_timer);
});
var port = chrome.extension.connect();
function close_tabs () {
port.postMessage({close_tabs: true});
}
function restart_timer () {
port.postMessage({restart_timer: true});
}
The #restart-timer
button calls restart_timer()
, which sends a message back to the content script to redirect the tab:
background.js:
// Listen for connections from content scripts
chrome.extension.onConnect.addListener(function(port) {
port.onMessage.addListener(function(msg) {
if (msg.name == "update") {
update_times(msg.update, port.sender.tab);
}
// Messages from timeup page:
if (msg.close_tabs === true) {
chrome.tabs.remove(port.sender.tab.id);
}
if (msg.restart_timer === true) {
var reset_hostname = get_location(settings.restore_url).hostname;
settings.elapsed_times[reset_hostname] = 0;
chrome.tabs.update({url: settings.restore_url});
}
});
});
This should reset the elapsed time stored in settings
and redirect the tab to settings.restore_url
. This works correctly the first time through, but once the timer has been reset, seems to redirect to chrome-extension://invalid/
. Even after the first reset, the correct value of settings.restore_url
is passed to chrome.tabs.update()
, so I'm not sure where the redirect is coming from. What's going wrong here? How can I diagnose this sort of error in the future?
Upvotes: 3
Views: 6224
Reputation: 15587
As @RobW pointed out, add files you need the host page to access to web_accessible_resources
:
Manifest - Web Accessible Resources
An array of strings specifying the paths of packaged resources that are expected to be usable in the context of a web page. These paths are relative to the package root, and may contain wildcards.
...
These resources would then be available in a webpage via the URL
chrome-extension://[PACKAGE ID]/[PATH]
, which can be generated with theextension.getURL
method. Whitelisted resources are served with appropriate CORS headers, so they're available via mechanisms like XHR.A navigation from a web origin to an extension resource will be blocked unless the resource is listed as web accessible.
(excerpt only)
Upvotes: 1