ecmendenhall
ecmendenhall

Reputation: 551

chrome.tabs.update() redirects to 'chrome-extension://invalid/'

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

Answers (1)

ptim
ptim

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 the extension.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

Related Questions