adobe / brackets

An open source code editor for the web, written in JavaScript, HTML and CSS.
http://brackets.io
MIT License
33.26k stars 7.64k forks source link

Phase out file:/// URIs and replace with URL.createObjectURL() and BLOBs #10787

Open humphd opened 9 years ago

humphd commented 9 years ago

Brackets' Filesystem implementation is swappable, which is great, and let's one run in environments other than a native appshell. For example, I'm using an IndexedDB/WebSQL backed filesystem to run Brackets in a browser, and things mostly "Just Work." However, there are still aspects of the code that assume resources are available via a local, native filesystem, the worst being uses of file:/// URIs for loading resources like images.

A better solution is to use the Filesystem to load the resource into a BLOB, and then create a URL Object that can be used with img.src and the like. This is how I get the LiveDev to work in the browser, by having the LiveDev server pre-fetch filesystem resources and turn them into BLOBs and URL Objects that can be "served" to an iframe-based browser.

Some of the places that need this fix include:

QuickView:

src/extensions/default/QuickView/main.js-
src/extensions/default/QuickView/main.js-                if (PathUtils.isAbsoluteUrl(tokenString)) {
src/extensions/default/QuickView/main.js-                    imgPath = tokenString;
src/extensions/default/QuickView/main.js-                } else {
src/extensions/default/QuickView/main.js:                    imgPath = "file:///" + FileUtils.getDirectoryPath(docPath) + tokenString;
src/extensions/default/QuickView/main.js-                }
src/extensions/default/QuickView/main.js-
src/extensions/default/QuickView/main.js-                if (urlMatch) {
src/extensions/default/QuickView/main.js-                    sPos = {line: pos.line, ch: urlMatch.index};

Image View:

src/htmlContent/image-view.html-            <div class="image-path"></div>
src/htmlContent/image-view.html-        </div>
src/htmlContent/image-view.html-        <div class="image">
src/htmlContent/image-view.html-            <div class="image-scale"></div>
src/htmlContent/image-view.html:            <img class="image-preview" src="file:///{{fullPath}}?ver={{now}}">
src/htmlContent/image-view.html-            <div class="image-tip">
src/htmlContent/image-view.html-                <table class="tip-container">
src/htmlContent/image-view.html-                    <tr>
src/htmlContent/image-view.html-                        <td class="variable">x: </td>

The down side is that getting the URL becomes an asynchronous operation because it now depends on reading from the filesystem. But doing so would mean that Brackets can work unchanged on top of any filesystem implementation.

abose commented 9 years ago

I see that file:/// is also used in LiveDevolopment-tests.js, and some other fils too (12 from a find in files search). Have to look at this. But wait; did i just read that you are running brackets in a web browser :open_mouth:

humphd commented 9 years ago

Yeah, there are other places, but not that really affect my use case, and are probably safe to leave (e.g., in cases where you're running node).

Yes, we have it working in browser, you can play with it at http://humphd.github.io/brackets/dist/

humphd commented 9 years ago

I fixed this in our fork, but using a caching layer that doesn't exists in Brackets proper. The commit is here for reference: https://github.com/humphd/brackets/commit/c03ed580bc9e3bfeba995e379ec5ca3f6d0d2481