mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-14 00:54:32 +08:00
Reimplement custom TinyMCE plugin: customImageUploader [SCI-7151]
This commit is contained in:
parent
08a22cdd47
commit
557c4b205a
4 changed files with 134 additions and 139 deletions
|
@ -1,136 +0,0 @@
|
|||
/* eslint no-underscore-dangle: "off" */
|
||||
/* eslint no-use-before-define: "off" */
|
||||
/* eslint no-restricted-syntax: ["off", "BinaryExpression[operator='in']"] */
|
||||
/* global tinymce I18n HelperModule validateFileSize */
|
||||
|
||||
/*
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
tinymce.PluginManager.requireLangPack('customimageuploader');
|
||||
|
||||
tinymce.add('tinymce.plugins.CustomImageUploader', {
|
||||
CustomImageUploader: function(ed) {
|
||||
var iframe;
|
||||
var editor = ed;
|
||||
var textAreaElement = $('#' + ed.id);
|
||||
|
||||
function loadFiles() {
|
||||
let $fileInput;
|
||||
let hitFileLimit;
|
||||
$('#tinymce_current_upload').remove();
|
||||
$fileInput = $('<input type="file" multiple accept="image/*" id="tinymce_current_upload" style="display: none;">').prependTo(editor.container);
|
||||
$fileInput.click();
|
||||
|
||||
$fileInput.change(function() {
|
||||
let formData = new FormData();
|
||||
let files = $('#tinymce_current_upload')[0].files;
|
||||
|
||||
Array.from(files).forEach(file => formData.append('files[]', file, file.name));
|
||||
|
||||
Array.from(files).every(file => {
|
||||
if (!validateFileSize(file, true)) {
|
||||
hitFileLimit = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if (hitFileLimit) {
|
||||
return;
|
||||
}
|
||||
|
||||
$.post({
|
||||
url: textAreaElement.data('tinymce-asset-path'),
|
||||
data: formData,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
success: function(data) {
|
||||
handleResponse(data);
|
||||
$('#tinymce_current_upload').remove();
|
||||
},
|
||||
error: function(response) {
|
||||
HelperModule.flashAlertMsg(response.responseJSON.errors, 'danger');
|
||||
$('#tinymce_current_upload').remove();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function handleResponse(response) {
|
||||
if (response.errors) {
|
||||
handleError(response.errors.join('<br>'));
|
||||
} else {
|
||||
response.images.forEach(el => editor.execCommand('mceInsertContent', false, buildHTML(el)));
|
||||
updateActiveImages(ed);
|
||||
}
|
||||
}
|
||||
|
||||
function handleError(error) {
|
||||
HelperModule.flashAlertMsg(error, 'danger');
|
||||
}
|
||||
|
||||
function buildHTML(image) {
|
||||
return `<img src="${image.url}"
|
||||
data-mce-token="${image.token}"
|
||||
alt="description-${image.token}" />`;
|
||||
}
|
||||
|
||||
// Create hidden field for images
|
||||
function createImageHiddenField() {
|
||||
textAreaElement.parent().find('input#tiny-mce-images').remove();
|
||||
$('<input type="hidden" id="tiny-mce-images" name="tiny_mce_images" value="[]">').insertAfter(textAreaElement);
|
||||
}
|
||||
|
||||
// Finding images in text
|
||||
function updateActiveImages() {
|
||||
var images;
|
||||
var imageContainer = $('#' + editor.id).next()[0];
|
||||
iframe = $('#' + editor.id).prev().find('.mce-edit-area iframe').contents();
|
||||
images = $.map($('img', iframe), e => {
|
||||
return e.dataset.mceToken;
|
||||
});
|
||||
if (imageContainer === undefined) {
|
||||
createImageHiddenField();
|
||||
}
|
||||
|
||||
// Small fix for ResultText when you cancel after change MarvinJS
|
||||
if (imageContainer === undefined) return [];
|
||||
|
||||
imageContainer.value = JSON.stringify(images);
|
||||
return JSON.stringify(images);
|
||||
}
|
||||
|
||||
// Add a button that opens a window
|
||||
editor.addButton('customimageuploader', {
|
||||
tooltip: I18n.t('tiny_mce.upload_window_label'),
|
||||
icon: 'image',
|
||||
onclick: loadFiles
|
||||
});
|
||||
|
||||
// Adds a menu item to the tools menu
|
||||
editor.addMenuItem('customimageuploader', {
|
||||
text: I18n.t('tiny_mce.upload_window_label'),
|
||||
icon: 'image',
|
||||
context: 'insert',
|
||||
onclick: loadFiles
|
||||
});
|
||||
|
||||
ed.on('NodeChange', function() {
|
||||
// Check editor status
|
||||
if (this.initialized) {
|
||||
updateActiveImages(ed);
|
||||
}
|
||||
});
|
||||
|
||||
createImageHiddenField();
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
tinymce.PluginManager.add(
|
||||
'customimageuploader',
|
||||
tinymce.plugins.CustomImageUploader
|
||||
);
|
||||
}());
|
||||
*/
|
8
app/javascript/packs/tiny_mce.js
vendored
8
app/javascript/packs/tiny_mce.js
vendored
|
@ -23,6 +23,7 @@ import 'tinymce/plugins/insertdatetime';
|
|||
import 'tinymce/plugins/nonbreaking';
|
||||
import 'tinymce/plugins/save';
|
||||
import 'tinymce/plugins/directionality';
|
||||
import './tinymce/custom_image_uploader/plugin';
|
||||
import './tinymce/marvinjs/plugin';
|
||||
import './tinymce/image_toolbar/plugin';
|
||||
import './tinymce/placeholder/plugin';
|
||||
|
@ -156,7 +157,7 @@ window.TinyMCE = (() => {
|
|||
$(selector).closest('.form-group')
|
||||
.before(`<div class="tinymce-placeholder" style="height:${tinyMceInitSize}px"></div>`);
|
||||
tinyMceContainer.addClass('hidden');
|
||||
const plugins = 'table autosave autoresize link advlist codesample autolink lists charmap anchor searchreplace wordcount visualblocks visualchars insertdatetime nonbreaking save directionality marvinjs placeholder custom_image_toolbar';
|
||||
const plugins = 'table autosave autoresize link advlist codesample autolink lists charmap anchor searchreplace wordcount visualblocks visualchars insertdatetime nonbreaking save directionality customimageuploader marvinjs placeholder custom_image_toolbar';
|
||||
// if (typeof (MarvinJsEditor) !== 'undefined') plugins += ' marvinjsplugin';
|
||||
|
||||
if (textAreaObject.data('objectType') === 'step'
|
||||
|
@ -168,8 +169,11 @@ window.TinyMCE = (() => {
|
|||
cache_suffix: '?v=6.1.2', // This suffix should be changed any time library is updated
|
||||
selector,
|
||||
convert_urls: false,
|
||||
menu: {
|
||||
insert: { title: 'Insert', items: 'link codesample inserttable | charmap hr | nonbreaking anchor | insertdatetime customimageuploader marvinjs' },
|
||||
},
|
||||
menubar: 'file edit view insert format table',
|
||||
toolbar: 'undo redo restoredraft | insert | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table | link | forecolor backcolor | codesample | marvinjs',
|
||||
toolbar: 'undo redo restoredraft | insert | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table | link | forecolor backcolor | codesample | customimageuploader marvinjs',
|
||||
plugins,
|
||||
autoresize_bottom_margin: 20,
|
||||
// placeholder: options.placeholder,
|
||||
|
|
127
app/javascript/packs/tinymce/custom_image_uploader/plugin.js
Normal file
127
app/javascript/packs/tinymce/custom_image_uploader/plugin.js
Normal file
|
@ -0,0 +1,127 @@
|
|||
/* eslint no-underscore-dangle: "off" */
|
||||
/* eslint no-use-before-define: "off" */
|
||||
/* eslint no-restricted-syntax: ["off", "BinaryExpression[operator='in']"] */
|
||||
/* global tinymce I18n HelperModule validateFileSize */
|
||||
|
||||
tinymce.PluginManager.requireLangPack('customimageuploader');
|
||||
|
||||
tinymce.PluginManager.add('customimageuploader', (editor) => {
|
||||
var iframe;
|
||||
var textAreaElement = $('#' + editor.id);
|
||||
|
||||
function loadFiles() {
|
||||
let $fileInput;
|
||||
let hitFileLimit;
|
||||
$('#tinymce_current_upload').remove();
|
||||
$fileInput = $('<input type="file" multiple accept="image/*" id="tinymce_current_upload" style="display: none;">')
|
||||
.prependTo(editor.container);
|
||||
$fileInput.click();
|
||||
|
||||
$fileInput.change(function() {
|
||||
let formData = new FormData();
|
||||
let files = $('#tinymce_current_upload')[0].files;
|
||||
|
||||
Array.from(files).forEach(file => formData.append('files[]', file, file.name));
|
||||
|
||||
Array.from(files).every(file => {
|
||||
if (!validateFileSize(file, true)) {
|
||||
hitFileLimit = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if (hitFileLimit) {
|
||||
return;
|
||||
}
|
||||
|
||||
$.post({
|
||||
url: textAreaElement.data('tinymce-asset-path'),
|
||||
data: formData,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
success: function(data) {
|
||||
handleResponse(data);
|
||||
$('#tinymce_current_upload').remove();
|
||||
},
|
||||
error: function(response) {
|
||||
HelperModule.flashAlertMsg(response.responseJSON.errors, 'danger');
|
||||
$('#tinymce_current_upload').remove();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function handleResponse(response) {
|
||||
if (response.errors) {
|
||||
handleError(response.errors.join('<br>'));
|
||||
} else {
|
||||
response.images.forEach(el => editor.execCommand('mceInsertContent', false, buildHTML(el)));
|
||||
updateActiveImages(editor);
|
||||
}
|
||||
}
|
||||
|
||||
function handleError(error) {
|
||||
HelperModule.flashAlertMsg(error, 'danger');
|
||||
}
|
||||
|
||||
function buildHTML(image) {
|
||||
return `<img src="${image.url}"
|
||||
data-mce-token="${image.token}"
|
||||
alt="description-${image.token}" />`;
|
||||
}
|
||||
|
||||
// Create hidden field for images
|
||||
function createImageHiddenField() {
|
||||
textAreaElement.parent().find('input#tiny-mce-images').remove();
|
||||
$('<input type="hidden" id="tiny-mce-images" name="tiny_mce_images" value="[]">').insertAfter(textAreaElement);
|
||||
}
|
||||
|
||||
// Finding images in text
|
||||
function updateActiveImages() {
|
||||
var images;
|
||||
var imageContainer = $('#' + editor.id).next()[0];
|
||||
iframe = $('#' + editor.id).prev().find('.mce-edit-area iframe').contents();
|
||||
images = $.map($('img', iframe), e => {
|
||||
return e.dataset.mceToken;
|
||||
});
|
||||
if (imageContainer === undefined) {
|
||||
createImageHiddenField();
|
||||
}
|
||||
|
||||
// Small fix for ResultText when you cancel after change MarvinJS
|
||||
if (imageContainer === undefined) return [];
|
||||
|
||||
imageContainer.value = JSON.stringify(images);
|
||||
return JSON.stringify(images);
|
||||
}
|
||||
|
||||
// Add a button that opens a window
|
||||
editor.ui.registry.addButton('customimageuploader', {
|
||||
tooltip: I18n.t('tiny_mce.upload_window_label'),
|
||||
icon: 'image',
|
||||
onAction: loadFiles
|
||||
});
|
||||
|
||||
// Adds a menu item to the tools menu
|
||||
editor.ui.registry.addMenuItem('customimageuploader', {
|
||||
text: I18n.t('tiny_mce.upload_window_label'),
|
||||
icon: 'image',
|
||||
context: 'insert',
|
||||
onAction: loadFiles
|
||||
});
|
||||
|
||||
editor.on('NodeChange', function() {
|
||||
// Check editor status
|
||||
if (this.initialized) {
|
||||
updateActiveImages(editor);
|
||||
}
|
||||
});
|
||||
|
||||
createImageHiddenField();
|
||||
|
||||
return {
|
||||
getMetadata: () => ({
|
||||
name: 'Custom Image Uploader Plugin'
|
||||
})
|
||||
};
|
||||
});
|
|
@ -30,7 +30,7 @@ tinymce.PluginManager.add('marvinjs', (editor) => {
|
|||
text: I18n.t('marvinjs.new_button'),
|
||||
icon: 'marvinjs',
|
||||
context: 'insert',
|
||||
onclick: openMarvinJs
|
||||
onAction: openMarvinJs
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
Loading…
Add table
Reference in a new issue