1

I'm wondering if it's possible to for certain JS files to be added to the web extension directory later?

Like say I have an app where users can select certain settings from within the app and those files (js and html files, images or blobs) are somehow added into the extension from the web. Like some sort of ondemand updater without using any native apps but it seems that upgrades are done by the appstores automatically.

I'm reading the files using ajax and adding them to indexeddb but because it could be more than one file that's getting messy.

Say a user wants a certain feature on the extension and there's an html page, js files and images then this gets downloaded to a certain folder inside the installed extension.

function download() { //only saves to downloads directory
  var imgurl = "https://www.google.com.hk/images/srpr/logo11w.png";
  console.log('download');
  browser.downloads.download({url:imgurl},function(downloadId){
      console.log("download begin, the downId is:" + downloadId);
  });
}

I also tried the chrome download function above but that only works for the downloads folder not the extension folder.

Is there any way to make a custom updater?! I know we can't save to disk but any leniency or workarounds for the extension folder?! Even something silly like making a shell call to some dos (and linux/mac) thing that saves the file to the extension folder. I can fetch the files, just not save them.

xmxmxmx
  • 409
  • 1
  • 6
  • 16

2 Answers2

2

Ok so I'll put it as an answer. This is the solution I'm leaning on which works for my scenario and I've listed some alternatives below:

  • Having the other files as separate extensions and giving the user an install link instead where they can install that extension, then those child extensions talk to the mother extension and they know the address to the resources in their child extension folder, so the mother gets the just the file locations from the children to load those assets from that folder. The child extensions are like bundles of those html and js with a background script which sends the addresses of these items to the mother.

https://developer.chrome.com/extensions/messaging#external

The drawback is that I'll have to see how that affects the urls like if I inject the html page from the child extension folder into the main interface using ajax then I can't use relative url's to any images in that 'cos the urls are relative to the mother extension folder.. I'll have to rewrite the child extension urls with the absolute paths into the html page to load images and js from the child extension html code which has relative urls.

Pros:

  • Cleaner and more persistent than indexeddb.

  • Files can be loaded normally from disk.

Cons:

  • User has to install separate extensions.

  • URL structure might be a bit confusing, need to rewrite urls if loading html from child. However this is only for image src's and where the javascript is loaded from so it's not such a big deal.

Other Possible Solutions:

  • Indexeddb which I'm already doing seems to be the preferred way of doing this but I really do not want to store every html asset in indexeddb. The upside is that while extensions need to be installed, this method can be done silently fetching and adding files without user interaction and indexeddb seems to be somewhat persistent. Might still end up using this because it is silent but having to load each asset from a database sounds like a nightmare.

  • The File Handle Api might have worked if I was working on Firefox only https://wiki.mozilla.org/WebAPI/FileHandleAPI

  • I haven't tried the shell copy, maybe if I fetch with ajax and then save to disk using some dos function and then doing different save functions for different OS systems.

  • Filesystem Api only saves to downloads and doesn't work for extensions anyways, so that's useless.

UPDATE

In windows there isn't any sudo, but this worked without admin priveleges for a subfolder (not on the C:\ root though). It would work for a linux only app very nicely. If I just wanted to save a file to a windows machine this might work.

Shell copy method would be to grab the contents of file with ajax from the local or remote location, output to DOS as a stream to save to file on windows. And do this for every operating system with a shell exec command or detect the OS and do that command. This way I can even put the files in the exact folder location.

Like say I make this sort of command from the contents:

//To append you can use >> instead of >
//folder seems necessary, can't save to root without admin
echo the content I want to save > C:\folder\textfile.txt

I thought of calling it using shell exec that only works in nodejs, so digging through the other answers on

How to execute shell command in Javascript

//full code to save file using javascript on windows
var shell = WScript.CreateObject("WScript.Shell");
shell.Run("echo content to save > C:\folder\textfile.txt");

The shell command doesn't seem to work. i can't find what this is for. There doesn't seem to be a shell command in regular javascript for windows. It seems to require IE ActiveX. Doesn't work with Firefox or Chrome.

Community
  • 1
  • 1
xmxmxmx
  • 409
  • 1
  • 6
  • 16
  • 1) "having to load each asset from a database sounds like a nightmare" sounds like something trivial if you use an IndexedDB library or write a simple wrapper yourself. Also you don't have to use IndexedDB, you can use chrome.storage.local or localStorage. 2) Modifying the source directory won't work as I explained in my answer. – wOxxOm Dec 18 '19 at 05:07
  • I've written the indexeddb code that works, that's not the issue. The issue is having to store parts of a UI in the database like say one add-on has 25 images, then i'm storing all of those and the html page that displays them then replacing all the links and displaying them from a database each time. Then I have to keep track of them and how will I know which relative url points to which image and all. That's not a nightmare compared to just grabbing the html from a child extension, injecting it and replacing the relative urls with known full urls instead of keeping any database. – xmxmxmx Dec 18 '19 at 05:14
  • For example [idb.filesystem.js](https://github.com/ebidel/idb.filesystem.js/) can be used as a base of a maintainable solution. As for writing into the extension directory, anything you wrote into the extension directory will be purged on extension update. – wOxxOm Dec 18 '19 at 06:41
  • Oh I didn't know the directory gets purged on update. So I'll have to use indexeddb or package the files as separate extensions that send the main background script the file locations. – xmxmxmx Dec 18 '19 at 07:11
0

Extensions can't modify their sources because the browser verifies them and resets/disables the extension if they change. Also, in Firefox the extensions aren't even unpacked.

The solution is actually quite trivial: save the code in any storage (localStorage, chrome.storage.local, IndexedDB) as a string and then add it in your extension page as a standard DOM script element. You'll have to relax the standard CSP a bit for that.

wOxxOm
  • 65,848
  • 11
  • 132
  • 136
  • I'm already doing that but there are several files so it's a very messy way to do this. – xmxmxmx Dec 18 '19 at 04:42
  • You're doing it wrong then, I guess, but it's a different issue. – wOxxOm Dec 18 '19 at 04:43
  • What do you mean I'm doing it wrong? How?! Every solution depends on the scenario. – xmxmxmx Dec 18 '19 at 05:14
  • Well you didn't show the code so I can't say how. What I know is that there's nothing inherently messy in this approach. – wOxxOm Dec 18 '19 at 05:15
  • I see, it's somewhat more complicated than I thought, but it still seems like something that can be solved in an elegant fashion, no need neither to exaggerate it as a "nightmare" nor to get offended by my comments. – wOxxOm Dec 18 '19 at 05:25
  • BTW I think there's an existing library that builds a proper virtual file system on the top of IndexedDB so like I said, it looks trivial. – wOxxOm Dec 18 '19 at 05:28
  • Thanks that virtual filesystem library looks promising but I do not need it for my purposes, my issue isn't keeping track of files, its keeping track of urls which indexeddb can do on it's own. I'll check it out though looks very interesting but I expect the virtual urls won't be automatically translated from the html file relative urls either. – xmxmxmx Dec 18 '19 at 07:00