UNPKG

@vipindev/tinymce-s3-uploader-plugin

Version:

152 lines (124 loc) 5.15 kB
import tinymce from 'tinymce/tinymce' import AWS from 'aws-sdk' /** * This class contains all core logic for the AWS plugin. * * @class tinymce.AWsS3Upload.Plugin * @private */ tinymce.PluginManager.add('AwsS3Upload', (editor, url) => { // Grab the params from TinyMCE init const { bucketName, folderName = '', awsAuth, buttonText = 'Upload File', conditions = {}, progress, secondFileSelectedBeforeFirstUpload } = editor.getParam('Awss3UploadSettings') const { secretAccessKey, accessKeyId, region } = awsAuth const { contentLengthRange = { min: 0, max: null } } = conditions let inProgress = false // Initializing parameters control if (!bucketName) { console.log('`bucketName` parameter missing on init AwsS3Upload TinyMCE plugin.') return false } // awsAuth control if (awsAuth && typeof awsAuth === 'object') { if (!accessKeyId) { console.log('`awsAuth` parameter missing `accessKeyId` property on init AwsS3Upload TinyMCE plugin.') return false } if (!secretAccessKey) { console.log('`awsAuth` parameter missing `secretAccessKey` property on init AwsS3Upload TinyMCE plugin.') return false } if (!region) { console.log('`awsAuth` parameter missing `secretAccessKey` property on init AwsS3Upload TinyMCE plugin.') return false } // Let's update the auth config AWS.config.update({ region, accessKeyId, secretAccessKey }) } // Adding file input to DOM const textarea = editor.targetElm let inputEl = document.createElement('input') inputEl.type = 'file' inputEl.style.cssText = 'display:none' textarea.parentNode.insertBefore(inputEl, textarea) // Create progress element let progressEl = document.createElement('progress') progressEl.max = 100 progressEl.value = 10 progressEl.style.cssText = 'display:none' textarea.parentNode.insertBefore(progressEl, textarea) // Creating bucket let bucket = new AWS.S3({ params: { Bucket: bucketName } }) inputEl.addEventListener('change', e => { e.preventDefault() // Select the file & contentAreaContainer let file = inputEl.files[0] let contentAreaContainer = editor.contentAreaContainer // If file exists if (file) { checkContentLenghtRange(file) // Put the progress bar inside content area of TinyMCE contentAreaContainer.parentNode.insertBefore(progressEl, contentAreaContainer) if (progress.bar && typeof progress.bar === 'boolean') { progressEl.style.cssText = 'display:block;position: absolute;z-index: 9999;width: 120px;height: 15px;right: 10px;top:45px' } // We are uploading right now inProgress = true let extension = file.name.split('.').pop() let fileName = file.name.split('.' + extension)[0] let objKey = (folderName ? `${folderName}/` : '') + fileName + '-' + Date.now() + '.' + extension let params = { Key: objKey, ContentType: file.type, Body: file, ACL: 'public-read' } bucket .putObject(params) .on('httpUploadProgress', progressObj => { let progressPercentage = parseInt((progressObj.loaded / progressObj.total) * 100) // Change the value of progressbar. No matter if it's visible or not progressEl.value = progressPercentage // Call the callback function if it's exists if (progress.callback && typeof progress.callback === 'function') { progress.callback(progressPercentage) } }).send((err, data) => { inProgress = false progressEl.style.cssText = 'display:none' if (err) { if (progress.errorCallback && typeof progress.errorCallback === 'function') { progress.errorCallback(err) } } else { let url = `https://${bucketName}.s3.amazonaws.com/${objKey}` if (progress.successCallback && typeof progress.successCallback === 'function') { progress.successCallback(editor, url) } } }) } else { } }) editor.ui.registry.addButton('AwsS3UploadButton', { text: buttonText, onAction () { if (!inProgress) { inputEl.click() } else { if (secondFileSelectedBeforeFirstUpload.callback && typeof secondFileSelectedBeforeFirstUpload.callback === 'function') { secondFileSelectedBeforeFirstUpload.callback() } else { alert('Progress allready') } } } }) function checkContentLenghtRange (file) { let isContentLengthOutOfRange = (typeof contentLengthRange.min === 'number' && file.size < contentLengthRange.min) || (typeof contentLengthRange.max === 'number' && file.size > contentLengthRange.max) if (isContentLengthOutOfRange) { let err = new RangeError( `The content length of '${file.name}' must be between ${contentLengthRange.min} and ${contentLengthRange.max} bytes.` ) // err.fileSize = file.size; if (contentLengthRange.errorCallback && typeof contentLengthRange.errorCallback === 'function') { contentLengthRange.errorCallback(err) } throw err } } }) export default function () {}