GoogleChromeLabs / browser-fs-access

File System Access API with legacy fallback in the browser
https://googlechromelabs.github.io/browser-fs-access/demo/
Apache License 2.0
1.38k stars 84 forks source link

fileSave doesn't write correct mimeType for custom extensions #24

Closed dwelle closed 3 years ago

dwelle commented 3 years ago

I'm not sure if this is a problem with Native FS API or something else, but if you save a blob with a given mimeType, but a custom extension, the file will end up with an empty/missing mimeType (when later opened, for example).

This should be reported upstream/crbug — just wanted to make sure I'm not missing something, first.

fileSave(new Blob([], { type: "application/json" }), {
    fileName: "test",
    extensions: [".excalidraw"]
})

const blob = await fileOpen({
    // if you comment this it won't even show the file
    // in file picker because of missing mimeType
    extensions: [".excalidraw"],
    mimeTypes: ["application/json"]
});
setType(blob.type); // ""

Repro: https://0cglk.csb.app/ Source: https://codesandbox.io/s/sharp-bartik-0cglk?file=/src/App.js (due to security, use the link above to test)

tomayac commented 3 years ago

Under the hood, this is the code browser-nativefs creates for this:

const handle =    
    (await window.showSaveFilePicker({
      types: [
        {          
          accept: {
            ['application/json']: ['.excalidraw'],
          },
        },
      ],
    }));
const writable = await handle.createWritable();
await writable.write(new Blob(["{a:0}"], {type: 'application/json'}));
await writable.close();

The way operating systems like macOS handle this is to give preference to the extension. See how macOS behaves if I change .png to .custompng. The MIME type macOS displays downgrades from "PNG image" (image/png) to "Document", which is its way of saying 🤷‍♀️/🤷‍♂️:

Screen Shot 2020-10-19 at 10 26 11 Screen Shot 2020-10-19 at 10 26 37
dwelle commented 3 years ago

I see. I thought it might be the OS messing it up, but I thought browser or whatever API does the actual writing does have a say and can override the MIME type if it chooses to do so :(.

tomayac commented 3 years ago

MIME type are considered a serious thing that not everyone can freely mess around with, but that need to follow strict processes for registering. Each MIME type has a set of registered extensions (example for application/json). Anything else won't be considered by operating systems.

dwelle commented 3 years ago

I kinda knew about not being able to create your own MIME types on the fly, but naively (my turn) thought that matching file extensions aren't required to reuse an existing MIME type (in our case, application/json). Thanks for setting me straight :).