Local resources path in a chrome extension

If you want to import a resource to your local chrome extension, usually you would duplicate the resource itself into another controlled location.

For a simple and local only chrome extension, what I would find somewhat more efficient to import resources is to save only their local path. Unfortunately browser's apis usually don't give that information.

I used a little workaround, that imply to drag/drop a file in the browser's url bar of the chrome extension. Listening on chrome.tabs.onUpdated allow us to access the absolute local path of the file.

The basic idea is :

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo){
  // Check tabId, check changeInfo.status

  if (changeInfo.url.startsWith('file:///')) {
    // use changeInfo.url
  }
});

It mean that when you drop the file in the url bar the browser navigate to the new resource, then in the listener you need to save the url and reload the extension page (you can do both by passing a get parameter when reloading the extension).

With that in mind, we can use the example to add a check if the tab that fired the event is an extension page.

See the complete implementation bellow :


var baseUrl = chrome.extension.getURL('myextension.html');
var tabIds = [];     // List of the extension tabs
var tabsLoaded = {}; // Status of these tabs

function is_tab_from_ext(tabId){
  return tabIds.indexOf(tabId) > -1;
};

function remove_tab(tabId){
  if (is_tab_from_ext(tabId)){
    tabIds.splice(tabIds.indexOf(tabId), 1);
    delete tabsLoaded[tabId];
  }
};

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo){
  if (changeInfo.status === 'loading'){
    // if loading extension page
    if (changeInfo.url === baseUrl) {
      if (!is_tab_from_ext(tabId)){
        tabIds.push(tabId);
        tabsLoaded[tabId] = false;
      }
      return;
    }
  }

  if (is_tab_from_ext(tabId)){
    if (changeInfo.status === 'complete'){
      // save tab status
      tabsLoaded[tabId] = true;
      return;
    }
  }

  // if new url is a local path
  if (tabsLoaded[tabId]){
    if (typeof changeInfo.url === 'string') {
      // local path check 
      if (changeInfo.url.startsWith('file:///')) {

          // Example
          // changeInfo.url contain the url of the local resource
          chrome.tabs.update(tabId, {url: baseUrl+"?path="+changeInfo.url}, function () {});

      }
      else{
        // tab is updating new url that is not a file, remove tab from list
        remove_tab(tabId);
      }
    }
  }
});

chrome.tabs.onRemoved.addListener(function(tabId) {
  remove_tab(tabId);
});

This code hasn't been used in production and will be updated. I use it in REPR, a project still in development.

, last updated :

Widget is loading comments...