Add `render` and `addTarget` methods that throw by default. These methods should have a sub-class implementation when a plugin wants to mounts on a DOM element or on another plugin's target.
This makes sure that if an upload has finished, and the user refreshes
the page, the old files won't be sitting there in the completed state.
Files that have finished uploading but were part of a "batch" of files
that hasn't finished uploading are also kept.
The `replaceTargetContent` option wasn't being set correctly, this has been updated.
The `mount` method uses a `render` method (which is not set in the Plugin) so I've had to manually add this to the instance for the tests.
This patch makes sure only blobs that are referenced by the localStorage
state are actually restored. Blobs that are returned from the persistent
serviceWorker or IndexedDB stores, but aren't referenced by the `files`
state object restored from localStorage, will be deleted.
Should fix#348.
Part of #342, but we need to do more before we can call that fixed :)
This is a different approach to React components suggested by @arturi.
Instead of the components adding and removing plugins when mounting and
unmounting, plugins are configured at the start, and the components act
as slots for the plugins to actually mount in. Because all plugins are
still being configured up front here, we don't have to change how the
provider `target:` options work, they can install themselves into eg.
the Dashboard plugin immediately.
The core of this approach is the `UppyWrapper` component, which takes an
Uppy instance and a plugin ID, and mounts the plugin inside itself. The
other components only provide a default plugin ID.
The one change required in Uppy itself for this to work is to the
`mount()` functions: now, `mount()` configures `this.target` on the
plugins. If plugins do not have a `target:` option, they do not mount on
install. Some DOM code also had to be moved into the `mount()` function
for the DragDrop component instead of staying in `install()`, but I
think it makes sense.
(Still have to work out how to make the `DashboardModal` component's
`onRequestClose` option work.)