Merge pull request #2390 from betagouv/fix-activestorage

javascript: transpile activestorage files (instead of copying them)
This commit is contained in:
Pierre de La Morinerie 2018-08-14 11:48:31 +02:00 committed by GitHub
commit dd252b515b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 12 additions and 175 deletions

View file

@ -1,69 +0,0 @@
import { DirectUpload } from 'activestorage';
import { dispatchEvent } from './helpers';
export class DirectUploadController {
constructor(input, file) {
this.input = input;
this.file = file;
this.directUpload = new DirectUpload(this.file, this.url, this);
this.dispatch('initialize');
}
start(callback) {
const hiddenInput = document.createElement('input');
hiddenInput.type = 'hidden';
hiddenInput.name = this.input.name;
this.input.insertAdjacentElement('beforebegin', hiddenInput);
this.dispatch('start');
this.directUpload.create((error, attributes) => {
if (error) {
hiddenInput.parentNode.removeChild(hiddenInput);
this.dispatchError(error);
} else {
hiddenInput.value = attributes.signed_id;
}
this.dispatch('end');
callback(error);
});
}
uploadRequestDidProgress(event) {
const progress = (event.loaded / event.total) * 100;
if (progress) {
this.dispatch('progress', { progress });
}
}
get url() {
return this.input.getAttribute('data-direct-upload-url');
}
dispatch(name, detail = {}) {
detail.file = this.file;
detail.id = this.directUpload.id;
return dispatchEvent(this.input, `direct-upload:${name}`, { detail });
}
dispatchError(error) {
const event = this.dispatch('error', { error });
if (!event.defaultPrevented) {
alert(error);
}
}
// DirectUpload delegate
directUploadWillCreateBlobWithXHR(xhr) {
this.dispatch('before-blob-request', { xhr });
}
directUploadWillStoreFileWithXHR(xhr) {
this.dispatch('before-storage-request', { xhr });
xhr.upload.addEventListener('progress', event =>
this.uploadRequestDidProgress(event)
);
}
}

View file

@ -1,53 +0,0 @@
import { DirectUploadController } from './direct_upload_controller';
import { findElements, dispatchEvent, toArray } from './helpers';
const inputSelector =
'input[type=file][data-direct-upload-url]:not([disabled])';
export class DirectUploadsController {
constructor(form) {
this.form = form;
this.inputs = findElements(form, inputSelector).filter(
input => input.files.length
);
}
start(callback) {
const controllers = this.createDirectUploadControllers();
const startNextController = () => {
const controller = controllers.shift();
if (controller) {
controller.start(error => {
if (error) {
callback(error);
this.dispatch('end');
} else {
startNextController();
}
});
} else {
callback();
this.dispatch('end');
}
};
this.dispatch('start');
startNextController();
}
createDirectUploadControllers() {
const controllers = [];
this.inputs.forEach(input => {
toArray(input.files).forEach(file => {
const controller = new DirectUploadController(input, file);
controllers.push(controller);
});
});
return controllers;
}
dispatch(name, detail = {}) {
return dispatchEvent(this.form, `direct-uploads:${name}`, { detail });
}
}

View file

@ -1,51 +0,0 @@
export function getMetaValue(name) {
const element = findElement(document.head, `meta[name="${name}"]`);
if (element) {
return element.getAttribute('content');
}
}
export function findElements(root, selector) {
if (typeof root == 'string') {
selector = root;
root = document;
}
const elements = root.querySelectorAll(selector);
return toArray(elements);
}
export function findElement(root, selector) {
if (typeof root == 'string') {
selector = root;
root = document;
}
return root.querySelector(selector);
}
export function dispatchEvent(element, type, eventInit = {}) {
const { disabled } = element;
const { bubbles, cancelable, detail } = eventInit;
const event = document.createEvent('Event');
event.initEvent(type, bubbles || true, cancelable || true);
event.detail = detail || {};
try {
element.disabled = false;
element.dispatchEvent(event);
} finally {
element.disabled = disabled;
}
return event;
}
export function toArray(value) {
if (Array.isArray(value)) {
return value;
} else if (Array.from) {
return Array.from(value);
} else {
return [].slice.call(value);
}
}

View file

@ -1,5 +1,5 @@
import { DirectUploadsController } from './direct_uploads_controller';
import { findElement } from './helpers';
import { DirectUploadsController } from 'activestorage/src/direct_uploads_controller';
import { findElement } from 'activestorage/src/helpers';
import './progress';
// This is a patched copy of https://github.com/rails/rails/blob/master/activestorage/app/javascript/activestorage/ujs.js

View file

@ -1,3 +1,13 @@
const { environment } = require('@rails/webpacker')
// By default don't transpile JS files in ./node_modules except for some specific modules.
const babelLoader = environment.loaders.get('babel');
babelLoader.exclude = function(modulePath) {
let forcedModules = [
'activestorage' // ActiveStorage uses 'class', which is not supported by IE 11 and older Safari version
];
return modulePath.includes('node_modules')
&& forcedModules.every(forcedModule => !modulePath.includes('node_modules/' + forcedModule));
}
module.exports = environment