Table of Contents

What is mOxie?

Quote from moxie repo:

mOxie is combined name for XHR2 and File API pollyfills that we've extracted from Plupload in order to make it more flexible and give it opportunity for further growth. But now that pollyfills are separate, they can be used independently.

XHR2 and File API pollyfills are multi-runtime, which means that they will fallback to Flash and SilverLight (additionally there's Java runtime in production) or even "good old" HTML4, when there are no HTML5 capabilities found in current browser.

Plupload 2 runs on top of mOxie.

Sometimes I see components prefixed with moxie, or mOxie, or even simply - o, what is this?

Plupload is based on mOxie, so it uses its components where possible. mOxie keeps complete hierarchy of all public classes and methods under single global namespace - moxie. It can be accessed as window.moxie as well. For example to instantiate FileInput component using moxie namespace, one would have to reference it like this: moxie.file.FileInput.

Such approach is illustrative and convenient, but historically it was not always organized like that. So for backward compatibility we keep lightweight alias to all popular classes and methods under another global namespace - o. Here how you instantiate FileInput with o namespace: var fileInput = new o.FileInput(...). Much simpler and cleaner.

Although we've not encountered any other library using o as a namespace, but in order to avoid potential conflicts (o is too short after all), we also provide an alias to o and call it mOxie.

So o and mOxie are basically the same thing and represent some kind of compatibility layer, while moxie is the main namespace of the library.

Although I specify file extension in filters, I still cannot pick it up in file dialog or drag and drop, why?

HTML5 is the only runtime affected by this and main reason is accept attribute of the input[type="file"] element, which takes in only mime types and not extensions. To support consistent behavior across the runtimes ('cause other runtimes use extensions) we chose to map extensions to mime types internally, transparently to users. But as you probably know there are hundreds of different mime types, if not thousands, much more then we could store internally. So at some point we stopped extending our built-in map and exposed a method: mOxie.Mime.addMimeType() to extend it from outside. This is how you can use it to add support for your own exotic extensions:

$(function() {

   mOxie.Mime.addMimeType("audio/x-aiff,aif aiff"); // notice that it is called before Plupload initialization

    $("#uploader").plupload({
    ...

Hence the format is: mOxie.Mime.addMimeType("<mime-type>,<ext1> <ext2> <ext2>");.

If you are not sure what the mime type is for the extension in question, here's a nice reference: List of MIME types / Internet Media Types

How do I upload to a page on a different domain/host?

Different runtimes have different pre-requisites.

For html5 you need to send Access-Control-Allow-Origin header from the remote server, with the comma-separated list of domains to accept. Something like:

// example in PHP
header("Access-Control-Allow-Origin: *"); // * - stands for all domains

You should put this in your server-side handler, before any output. If you are using our bundled upload.php, then that's the place to put it. More info about Cross-Origin Resource Sharing (CORS) here. Examples for other languages here.

In case of flash/silverlight you need to have a crossdomain.xml file in the document root of your destination server (it should be accessible at: http://your-domain.com/crossdomain.xml. Here's are the typical contents of crossdomain.xml that will allow you to upload from any domain:

<?xml version="1.0" ?>
<cross-domain-policy>
    <allow-access-from domain="*" />
</cross-domain-policy>

Can I trigger file dialog programmatically?

It depends on the runtime, but the short answer is - no, since it is not possible to achieve consistent behavior across the runtimes for this feature anyway. Specifically it is about Flash and Silverlight shims, that allow opening of browse dialog only as a reaction to an event of some kind - mouse click or key press. This is security constraint.

In Flash Player 10 and Flash Player 9 Update 5, you can only call this method successfully in response to a user event (for example, in an event handler for a mouse click or keypress event). Otherwise, calling this method results in Flash Player throwing an Error exception. Adobe Livedocs - FileReference.browse()

How can I find out what runtime is currently in use in Plupload 2 beta?

Plupload 2 is not strictly attached to a single runtime anymore. File picker might be flash and drop zone html5, at the same time. Not that we make a particular use of this at the moment, but it is potentially possible, so providing specific runtime as uploader's property wouldn't be correct. However every UI component, be it file picker or drop zone is wrapped into a container that usually has unique id of the following format: flash_17nclds0r1j4j5gva0th18rnp3_container. E.g.:

<div id="flash_17nclds0r1j4j5gva0th18rnp3_container" class="moxie-shim moxie-shim-flash" ... >
  <object id="flash_17nclds0r1j4j5gva0th18rnp3" ...>...</object>
</div>

So the prefix in the beginning of id always shows what the runtime for the component is. Notice the class of moxie-shim-flash as well. Hope that helps.

Is there a way to slow down upload for testing purposes?

In upload.php, we got a line:

// Uncomment this one to fake upload time
// usleep(5000);

Uncomment it and regulate value in parenthesis to meet your expectations. If you are using your own upload handler, you will have to add something like this, yourself.

You can also decrease the size of chunk_size option relative to overall file size (for testing purposes you can add it to your config if it's not there yet). This will make UploadProgress event to fire more frequently. For example if the size of the file is around 2mb, and you set the chunk_size to 200kb, you will get UploadProgress fired at least 20 times.

When to use chunking and when not?

Historically chunking was introduced to overcome file size limit on server - by decreasing the chunk size, one could easily pipe the file, that would otherwise fail to constraints, part by part and reassemble safely on the other side.

But as the time went by and HTML5 came into play, idea of chunking changed a bit. Now it is required feature for uploading very big and huge files (of around several gigabytes at least). Without chunking browser might simply run out of memory and hang (best case). While browser producers are working to fix this issue, we have to use chunking to work around it.

In general chunking would be a very good and actually recommended feature to enable by us, if not Flash runtime. Problem with Flash is that it doesn't allow access to raw file source and streaming upload (without preloading the file in memory) at the same time. So here's the paradox - to create a chunk we have to preload the file in memory first, but this operation by itself will obviously ruin the purpose of chunking in first place!.. Although it is still possible to overcome server limit on file size this way.

So to sum this up - use chunking if:

  1. you got to overcome server limitation on file size
  2. you will be uploading huge files, over 2gb (but be sure to omit Flash from list of potential runtimes in this case)
  3. you want to get smoother and more consistent upload progress across runtimes (but this will obviously slow down the upload itself, since there will be more work to do for each file)

Do not use chunking if:

  1. you need to upload huge files and absolutely require Flash to be in the list of fallback runtimes (in default mode Flash streams file directly from the disk, without preloading it in memory; other runtimes may survive this mode as well)

How can I confirm that a file was really uploaded successfully?

Send some kind of confirmation from the server-side and listen to it in a handler for FileUploaded event. Even something simple like JSON: {"OK": 1} will do. Consider the file uploaded only if you receive that confirmation. This is the only reliable way currently.

Fork me on GitHub