mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-09-20 14:45:56 +08:00
Move tinymce to webpacker and upgrade to v6 [SCI-7081] (#4385)
* Move tinymce to webpacker and upgrade to v6 [SCI-7081] * Cleanup and refactor [SCI-7081] * Clean up legacy plugins [SCI-7150] * Linter fix [SCI-7081]]
This commit is contained in:
parent
a5e52069af
commit
44b7c866b5
4
Gemfile
4
Gemfile
|
@ -101,10 +101,6 @@ gem 'rufus-scheduler', '~> 3.5'
|
|||
gem 'discard', '~> 1.0'
|
||||
|
||||
gem 'graphviz'
|
||||
gem 'tinymce-rails', '~> 4.9.10' # Rich text editor - SEE BELOW
|
||||
# Any time you update tinymce-rails Gem, also update the cache_suffix parameter
|
||||
# in sitewide/tiny_mce.js - to prevent browsers from loading old, cached .js
|
||||
# TinyMCE files which might cause errors
|
||||
|
||||
gem 'base62' # Used for smart annotations
|
||||
gem 'newrelic_rpm'
|
||||
|
|
|
@ -588,8 +588,6 @@ GEM
|
|||
thor (1.2.1)
|
||||
tilt (2.0.10)
|
||||
timecop (0.9.2)
|
||||
tinymce-rails (4.9.11)
|
||||
railties (>= 3.1.1)
|
||||
turbolinks (5.1.1)
|
||||
turbolinks-source (~> 5.1)
|
||||
turbolinks-source (5.2.0)
|
||||
|
@ -727,7 +725,6 @@ DEPENDENCIES
|
|||
sneaky-save!
|
||||
spinjs-rails
|
||||
timecop
|
||||
tinymce-rails (~> 4.9.10)
|
||||
turbolinks (~> 5.1.1)
|
||||
tzinfo-data
|
||||
uglifier (>= 1.3.0)
|
||||
|
|
|
@ -1,21 +1,6 @@
|
|||
// turbolinks MUST BE THE LAST inclusion
|
||||
//= require jquery
|
||||
//= require jquery_ujs
|
||||
//= require jquery.mousewheel.min
|
||||
//= require jquery.scrollTo
|
||||
//= require jquery.autosize
|
||||
//= require jquery-ui/widget
|
||||
//= require jquery-ui/widgets/mouse
|
||||
//= require jquery-ui/widgets/draggable
|
||||
//= require jquery-ui/widgets/droppable
|
||||
//= require jquery.ui.touch-punch.min
|
||||
//= require jquery-ui/effects/effect-slide
|
||||
//= require jquery.caret.min
|
||||
//= require jquery.atwho.min
|
||||
//= require hammer
|
||||
//= require js.cookie
|
||||
//= require spin
|
||||
//= require jquery.spin
|
||||
//= require bootstrap-sprockets
|
||||
//= require moment
|
||||
//= require bootstrap-datetimepicker
|
||||
|
@ -25,8 +10,6 @@
|
|||
//= require typeahead.bundle.min
|
||||
//= require nested_form_fields
|
||||
//= require highlight.pack
|
||||
//= require tinymce-jquery
|
||||
//= require_tree ./tinymce/plugins
|
||||
//= require jsPlumb-2.0.4-min
|
||||
//= require jsnetworkx
|
||||
//= require bootstrap-select
|
||||
|
|
15
app/assets/javascripts/jquery_bundle.js
vendored
Normal file
15
app/assets/javascripts/jquery_bundle.js
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
//= require jquery
|
||||
//= require jquery_ujs
|
||||
//= require jquery.mousewheel.min
|
||||
//= require jquery.scrollTo
|
||||
//= require jquery.autosize
|
||||
//= require jquery-ui/widget
|
||||
//= require jquery-ui/widgets/mouse
|
||||
//= require jquery-ui/widgets/draggable
|
||||
//= require jquery-ui/widgets/droppable
|
||||
//= require jquery.ui.touch-punch.min
|
||||
//= require jquery-ui/effects/effect-slide
|
||||
//= require jquery.caret.min
|
||||
//= require jquery.atwho.min
|
||||
//= require spin
|
||||
//= require jquery.spin
|
|
@ -281,13 +281,13 @@ var MarvinJsEditorApi = (function() {
|
|||
});
|
||||
|
||||
// TinyMCE plugin
|
||||
|
||||
/*
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
tinymce.PluginManager.requireLangPack('MarvinJsPlugin');
|
||||
|
||||
tinymce.create('tinymce.plugins.MarvinJsPlugin', {
|
||||
tinymce.add('tinymce.plugins.MarvinJsPlugin', {
|
||||
MarvinJsPlugin: function(ed) {
|
||||
var editor = ed;
|
||||
|
||||
|
@ -320,6 +320,7 @@ var MarvinJsEditorApi = (function() {
|
|||
tinymce.plugins.MarvinJsPlugin
|
||||
);
|
||||
})();
|
||||
*/
|
||||
|
||||
// Initialization
|
||||
$(document).on('click', '.marvinjs-edit-button', function() {
|
||||
|
@ -337,7 +338,7 @@ $(document).on('click', '.marvinjs-edit-button', function() {
|
|||
$(document).on('turbolinks:load', function() {
|
||||
MarvinJsEditor = MarvinJsEditorApi();
|
||||
if (MarvinJsEditor.enabled()) {
|
||||
if ($('#marvinjs-editor')[0].dataset.marvinjsMode === 'remote' && typeof(ChemicalizeMarvinJs) !== 'undefined') {
|
||||
if ($('#marvinjs-editor')[0].dataset.marvinjsMode === 'remote' && typeof (ChemicalizeMarvinJs) !== 'undefined') {
|
||||
ChemicalizeMarvinJs.createEditor('#marvinjs-sketch').then(function(marvin) {
|
||||
marvin.setDisplaySettings({ toolbars: 'reporting' });
|
||||
marvinJsRemoteEditor = marvin;
|
||||
|
|
441
app/assets/javascripts/sitewide/tiny_mce.js
vendored
441
app/assets/javascripts/sitewide/tiny_mce.js
vendored
|
@ -1,441 +0,0 @@
|
|||
/* global _ hljs tinyMCE SmartAnnotation I18n GLOBAL_CONSTANTS HelperModule */
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
var TinyMCE = (function() {
|
||||
'use strict';
|
||||
|
||||
function initHighlightjs() {
|
||||
$('[class*=language]').each(function(i, block) {
|
||||
hljs.highlightBlock(block);
|
||||
});
|
||||
}
|
||||
|
||||
function initHighlightjsIframe(iframe) {
|
||||
$('[class*=language]', iframe).each(function(i, block) {
|
||||
hljs.highlightBlock(block);
|
||||
});
|
||||
}
|
||||
|
||||
// Get LocalStorage auto save path
|
||||
function getAutoSavePrefix(editor) {
|
||||
var prefix = editor.getParam('autosave_prefix', 'tinymce-autosave-{path}{query}{hash}-{id}-');
|
||||
|
||||
prefix = prefix.replace(/\{path\}/g, document.location.pathname);
|
||||
prefix = prefix.replace(/\{query\}/g, document.location.search);
|
||||
prefix = prefix.replace(/\{hash\}/g, document.location.hash);
|
||||
prefix = prefix.replace(/\{id\}/g, editor.id);
|
||||
|
||||
return prefix;
|
||||
}
|
||||
|
||||
// Handles autosave notification if draft is available in the local storage
|
||||
function restoreDraftNotification(selector, editor) {
|
||||
var prefix = getAutoSavePrefix(editor);
|
||||
var lastDraftTime = parseInt(tinyMCE.util.LocalStorage.getItem(prefix + 'time'), 10);
|
||||
var lastUpdated = $(selector).data('last-updated');
|
||||
var notificationBar;
|
||||
var restoreBtn = $('<button class="btn restore-draft-btn">Restore Draft</button>');
|
||||
var cancelBtn = $('<span class="fas fa-times"></span>');
|
||||
|
||||
// Check whether we have draft stored
|
||||
if (editor.plugins.autosave.hasDraft()) {
|
||||
notificationBar = $('<div class="restore-draft-notification"></div>');
|
||||
|
||||
if (lastDraftTime < lastUpdated) {
|
||||
notificationBar.html(`<span class="notification-text">${I18n.t('tiny_mce.older_version_available')}</span>`);
|
||||
} else {
|
||||
notificationBar.html(`<span class="notification-text">${I18n.t('tiny_mce.newer_version_available')}</span>`);
|
||||
}
|
||||
|
||||
// Add notification bar
|
||||
$(notificationBar).append(restoreBtn).append(cancelBtn);
|
||||
$(editor.contentAreaContainer).before(notificationBar);
|
||||
|
||||
$(restoreBtn).click(function() {
|
||||
editor.plugins.autosave.restoreDraft();
|
||||
makeItDirty(editor);
|
||||
notificationBar.remove();
|
||||
});
|
||||
|
||||
$(cancelBtn).click(function() {
|
||||
notificationBar.remove();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function initImageToolBar(editor) {
|
||||
var editorIframe = $('#' + editor.id).prev().find('.mce-edit-area iframe');
|
||||
var primaryColor = '#104da9';
|
||||
editorIframe.contents().find('head').append(`<style type="text/css">
|
||||
img::-moz-selection{background:0 0}
|
||||
img::selection{background:0 0}
|
||||
.mce-content-body img[data-mce-selected]{outline:2px solid ${primaryColor}}
|
||||
.mce-content-body div.mce-resizehandle{background:transparent;border-color:transparent;box-sizing:border-box;height:10px;width:10px}
|
||||
.mce-content-body div.mce-resizehandle:hover{background:transparent}
|
||||
.mce-content-body div#mceResizeHandlenw{border-left: 2px solid ${primaryColor}; border-top: 2px solid ${primaryColor}}
|
||||
.mce-content-body div#mceResizeHandlene{border-right: 2px solid ${primaryColor}; border-top: 2px solid ${primaryColor}}
|
||||
.mce-content-body div#mceResizeHandlesw{border-left: 2px solid ${primaryColor}; border-bottom: 2px solid ${primaryColor}}
|
||||
.mce-content-body div#mceResizeHandlese{border-right: 2px solid ${primaryColor}; border-bottom: 2px solid ${primaryColor}}
|
||||
</style>`);
|
||||
}
|
||||
|
||||
function makeItDirty(editor) {
|
||||
var editorForm = $(editor.getContainer()).closest('form');
|
||||
editorForm.find('.tinymce-status-badge').addClass('hidden');
|
||||
$(editor.getContainer()).find('.tinymce-save-button').removeClass('hidden');
|
||||
}
|
||||
|
||||
function draftLocation() {
|
||||
return 'tinymce-drafts-' + document.location.pathname;
|
||||
}
|
||||
|
||||
function removeDraft(editor, textAreaObject) {
|
||||
var location = draftLocation();
|
||||
var storedDrafts = JSON.parse(sessionStorage.getItem(location) || '[]');
|
||||
var draftId = storedDrafts.indexOf(textAreaObject.data('tinymce-object'));
|
||||
if (draftId > -1) {
|
||||
storedDrafts.splice(draftId, 1);
|
||||
}
|
||||
|
||||
if (storedDrafts.length) {
|
||||
sessionStorage.setItem(location, JSON.stringify(storedDrafts));
|
||||
} else {
|
||||
sessionStorage.removeItem(location);
|
||||
}
|
||||
}
|
||||
|
||||
// Update scroll position after exit
|
||||
function updateScrollPosition(editorForm) {
|
||||
if (editorForm.offset().top < $(window).scrollTop()) {
|
||||
$(window).scrollTop(editorForm.offset().top - 150);
|
||||
}
|
||||
}
|
||||
|
||||
function saveAction(editor) {
|
||||
var editorForm = $(editor.getContainer()).closest('form');
|
||||
editorForm.clearFormErrors();
|
||||
editor.setProgressState(1);
|
||||
editor.save();
|
||||
editorForm.submit();
|
||||
updateScrollPosition(editorForm);
|
||||
}
|
||||
|
||||
// returns a public API for TinyMCE editor
|
||||
return Object.freeze({
|
||||
init: function(selector, onSaveCallback) {
|
||||
var editorInstancePromise;
|
||||
var tinyMceContainer;
|
||||
var tinyMceInitSize;
|
||||
var plugins;
|
||||
var textAreaObject = $(selector);
|
||||
if (typeof tinyMCE !== 'undefined') {
|
||||
// Hide element containing HTML view of RTE field
|
||||
tinyMceContainer = $(selector).closest('form').find('.tinymce-view');
|
||||
tinyMceInitSize = tinyMceContainer.height();
|
||||
$(selector).closest('.form-group')
|
||||
.before('<div class="tinymce-placeholder" style="height:' + tinyMceInitSize + 'px"></div>');
|
||||
tinyMceContainer.addClass('hidden');
|
||||
plugins = 'custom_image_toolbar table autosave autoresize customimageuploader link advlist codesample autolink lists charmap hr anchor searchreplace wordcount visualblocks visualchars insertdatetime nonbreaking save directionality paste textcolor colorpicker textpattern placeholder';
|
||||
if (typeof (MarvinJsEditor) !== 'undefined') plugins += ' marvinjsplugin';
|
||||
|
||||
if (textAreaObject.data('objectType') === 'step'
|
||||
|| textAreaObject.data('objectType') === 'result_text') {
|
||||
document.location.hash = textAreaObject.data('objectType') + '_' + textAreaObject.data('objectId');
|
||||
}
|
||||
|
||||
editorInstancePromise = tinyMCE.init({
|
||||
cache_suffix: '?v=4.9.10', // This suffix should be changed any time library is updated
|
||||
selector: selector,
|
||||
convert_urls: false,
|
||||
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 | customimageuploader marvinjsplugin | codesample',
|
||||
plugins: plugins,
|
||||
autoresize_bottom_margin: 20,
|
||||
codesample_languages: [
|
||||
{ text: 'R', value: 'r' },
|
||||
{ text: 'MATLAB', value: 'matlab' },
|
||||
{ text: 'Python', value: 'python' },
|
||||
{ text: 'JSON', value: 'javascript' },
|
||||
{ text: 'HTML/XML', value: 'markup' },
|
||||
{ text: 'JavaScript', value: 'javascript' },
|
||||
{ text: 'CSS', value: 'css' },
|
||||
{ text: 'PHP', value: 'php' },
|
||||
{ text: 'Ruby', value: 'ruby' },
|
||||
{ text: 'Java', value: 'java' },
|
||||
{ text: 'C', value: 'c' },
|
||||
{ text: 'C#', value: 'csharp' },
|
||||
{ text: 'C++', value: 'cpp' }
|
||||
],
|
||||
browser_spellcheck: true,
|
||||
branding: false,
|
||||
fixed_toolbar_container: '#mytoolbar',
|
||||
autosave_restore_when_empty: false,
|
||||
autosave_interval: '1s',
|
||||
autosave_retention: '1440m',
|
||||
removed_menuitems: 'newdocument',
|
||||
object_resizing: true,
|
||||
elementpath: false,
|
||||
forced_root_block: 'div',
|
||||
force_p_newlines: false,
|
||||
default_link_target: '_blank',
|
||||
target_list: [
|
||||
{ title: 'New page', value: '_blank' },
|
||||
{ title: 'Same page', value: '_self' }
|
||||
],
|
||||
style_formats: [
|
||||
{
|
||||
title: 'Headers',
|
||||
items: [
|
||||
{ title: 'Header 1', format: 'h1' },
|
||||
{ title: 'Header 2', format: 'h2' },
|
||||
{ title: 'Header 3', format: 'h3' },
|
||||
{ title: 'Header 4', format: 'h4' },
|
||||
{ title: 'Header 5', format: 'h5' },
|
||||
{ title: 'Header 6', format: 'h6' }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Inline',
|
||||
items: [
|
||||
{ title: 'Bold', icon: 'bold', format: 'bold' },
|
||||
{ title: 'Italic', icon: 'italic', format: 'italic' },
|
||||
{ title: 'Underline', icon: 'underline', format: 'underline' },
|
||||
{ title: 'Strikethrough', icon: 'strikethrough', format: 'strikethrough' },
|
||||
{ title: 'Superscript', icon: 'superscript', format: 'superscript' },
|
||||
{ title: 'Subscript', icon: 'subscript', format: 'subscript' },
|
||||
{ title: 'Code', icon: 'code', format: 'code' }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Blocks',
|
||||
items: [
|
||||
{ title: 'Paragraph', format: 'p' },
|
||||
{ title: 'Blockquote', format: 'blockquote' }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Alignment',
|
||||
items: [
|
||||
{ title: 'Left', icon: 'alignleft', format: 'alignleft' },
|
||||
{ title: 'Center', icon: 'aligncenter', format: 'aligncenter' },
|
||||
{ title: 'Right', icon: 'alignright', format: 'alignright' },
|
||||
{ title: 'Justify', icon: 'alignjustify', format: 'alignjustify' }
|
||||
]
|
||||
}
|
||||
],
|
||||
init_instance_callback: function(editor) {
|
||||
var editorForm = $(editor.getContainer()).closest('form');
|
||||
var menuBar = editorForm.find('.mce-menubar.mce-toolbar.mce-first .mce-flow-layout');
|
||||
var editorToolbar = editorForm.find('.mce-top-part');
|
||||
|
||||
var editorToolbaroffset;
|
||||
|
||||
$('.tinymce-placeholder').css('height', $(editor.editorContainer).height() + 'px');
|
||||
setTimeout(() => {
|
||||
$(editor.editorContainer).addClass('show');
|
||||
$('.tinymce-placeholder').remove();
|
||||
}, 400);
|
||||
|
||||
// Init saved status label
|
||||
if (editor.getContent() !== '') {
|
||||
editorForm.find('.tinymce-status-badge').removeClass('hidden');
|
||||
}
|
||||
|
||||
if ($('.navbar-secondary').length) {
|
||||
editorToolbaroffset = $('.navbar-secondary').position().top + $('.navbar-secondary').height();
|
||||
} else if ($('#main-nav').length) {
|
||||
editorToolbaroffset = $('#main-nav').height();
|
||||
} else {
|
||||
editorToolbaroffset = 0;
|
||||
}
|
||||
|
||||
if (GLOBAL_CONSTANTS.IS_SAFARI) {
|
||||
editorToolbar.css('position', '-webkit-sticky');
|
||||
} else {
|
||||
editorToolbar.css('position', 'sticky');
|
||||
}
|
||||
editorToolbar.css('top', editorToolbaroffset + 'px').css('z-index', '100');
|
||||
|
||||
// Init image toolbar
|
||||
initImageToolBar(editor);
|
||||
|
||||
// Init Save button
|
||||
editorForm
|
||||
.find('.tinymce-save-button')
|
||||
.clone()
|
||||
.appendTo(menuBar)
|
||||
.on('click', function(event) {
|
||||
event.preventDefault();
|
||||
saveAction(editor);
|
||||
});
|
||||
|
||||
// After save action
|
||||
editorForm
|
||||
.on('ajax:success', function(ev, data) {
|
||||
editor.save();
|
||||
editor.setProgressState(0);
|
||||
editorForm.find('.tinymce-status-badge').removeClass('hidden');
|
||||
editor.remove();
|
||||
editorForm.find('.tinymce-view').html(data.html).removeClass('hidden');
|
||||
editor.plugins.autosave.removeDraft();
|
||||
removeDraft(editor, textAreaObject);
|
||||
if (onSaveCallback) { onSaveCallback(data); }
|
||||
}).on('ajax:error', function(ev, data) {
|
||||
var model = editor.getElement().dataset.objectType;
|
||||
$(this).renderFormErrors(model, data.responseJSON);
|
||||
editor.setProgressState(0);
|
||||
if (data.status === 403) {
|
||||
HelperModule.flashAlertMsg(I18n.t('general.no_permissions'), 'danger');
|
||||
}
|
||||
});
|
||||
|
||||
// Init Cancel button
|
||||
editorForm
|
||||
.find('.tinymce-cancel-button')
|
||||
.clone()
|
||||
.appendTo(menuBar)
|
||||
.on('click', function(event) {
|
||||
$(editorForm).find('.form-group').removeClass('has-error');
|
||||
$(editorForm).find('.help-block').remove();
|
||||
|
||||
event.preventDefault();
|
||||
if (editor.isDirty()) {
|
||||
editor.setContent($(selector).val());
|
||||
}
|
||||
editorForm.find('.tinymce-status-badge').addClass('hidden');
|
||||
editorForm.find('.tinymce-view').removeClass('hidden');
|
||||
editor.remove();
|
||||
|
||||
updateScrollPosition(editorForm);
|
||||
if (onSaveCallback) { onSaveCallback(); }
|
||||
})
|
||||
.removeClass('hidden');
|
||||
|
||||
// Set cursor to the end of the content
|
||||
if (editor.settings.id !== 'step_description_textarea') {
|
||||
editor.focus();
|
||||
}
|
||||
editor.selection.select(editor.getBody(), true);
|
||||
editor.selection.collapse(false);
|
||||
|
||||
SmartAnnotation.init($(editor.contentDocument.activeElement));
|
||||
SmartAnnotation.preventPropagation('.atwho-user-popover');
|
||||
initHighlightjsIframe($(this.iframeElement).contents());
|
||||
},
|
||||
setup: function(editor) {
|
||||
editor.on('keydown', function(e) {
|
||||
if (e.keyCode === 13 && $(editor.contentDocument.activeElement).atwho('isSelecting')) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
editor.on('NodeChange', function(e) {
|
||||
var node = e.element;
|
||||
setTimeout(function() {
|
||||
if ($(node).is('pre') && !editor.isHidden()) {
|
||||
initHighlightjsIframe($(editor.iframeElement).contents());
|
||||
}
|
||||
}, 200);
|
||||
});
|
||||
|
||||
editor.on('Dirty', function() {
|
||||
makeItDirty(editor);
|
||||
});
|
||||
|
||||
editor.on('StoreDraft', function() {
|
||||
var location = draftLocation();
|
||||
var storedDrafts = JSON.parse(sessionStorage.getItem(location) || '[]');
|
||||
var draftName = textAreaObject.data('tinymce-object');
|
||||
if (storedDrafts.includes(draftName) || !draftName) return;
|
||||
storedDrafts.push(draftName);
|
||||
sessionStorage.setItem(location, JSON.stringify(storedDrafts));
|
||||
});
|
||||
|
||||
editor.on('remove', function() {
|
||||
var menuBar = $(editor.getContainer()).find('.mce-menubar.mce-toolbar.mce-first .mce-flow-layout');
|
||||
menuBar.find('.tinymce-save-button').remove();
|
||||
menuBar.find('.tinymce-cancel-button').remove();
|
||||
});
|
||||
|
||||
editor.on('blur', function(e) {
|
||||
if (editor.blurDisabled) return false;
|
||||
|
||||
if ($('.atwho-view:visible').length || $('#MarvinJsModal:visible').length) return false;
|
||||
setTimeout(() => {
|
||||
if (editor.isNotDirty === false) {
|
||||
$(editor.container).find('.tinymce-save-button').click();
|
||||
} else {
|
||||
$(editor.container).find('.tinymce-cancel-button').click();
|
||||
}
|
||||
}, 0);
|
||||
return true;
|
||||
});
|
||||
|
||||
editor.on('init', function(e) {
|
||||
restoreDraftNotification(selector, editor);
|
||||
});
|
||||
},
|
||||
codesample_content_css: $(selector).data('highlightjs-path'),
|
||||
save_onsavecallback: function(editor) { saveAction(editor); }
|
||||
});
|
||||
}
|
||||
|
||||
return editorInstancePromise;
|
||||
},
|
||||
destroyAll: function() {
|
||||
_.each(tinyMCE.editors, function(editor) {
|
||||
if (editor) {
|
||||
editor.remove();
|
||||
initHighlightjs();
|
||||
}
|
||||
});
|
||||
},
|
||||
refresh: function() {
|
||||
this.destroyAll();
|
||||
this.init();
|
||||
},
|
||||
getContent: function() {
|
||||
return tinyMCE.editors[0].getContent();
|
||||
},
|
||||
updateImages(editor) {
|
||||
var images;
|
||||
var iframe = $('#' + editor.id).prev().find('.mce-edit-area iframe').contents();
|
||||
images = $.map($('img', iframe), e => {
|
||||
return e.dataset.mceToken;
|
||||
});
|
||||
$('#' + editor.id).next()[0].value = JSON.stringify(images);
|
||||
return JSON.stringify(images);
|
||||
},
|
||||
makeItDirty: function(editor) {
|
||||
makeItDirty(editor);
|
||||
},
|
||||
highlight: initHighlightjs,
|
||||
initIfHasDraft: function(viewObject) {
|
||||
var storedDrafts = sessionStorage.getItem(draftLocation());
|
||||
var draftName = viewObject.data('tinymce-init');
|
||||
if (storedDrafts && JSON.parse(storedDrafts)[0] === draftName) {
|
||||
let top = viewObject.offset().top;
|
||||
setTimeout(() => {
|
||||
viewObject.click();
|
||||
}, 0);
|
||||
setTimeout(() => {
|
||||
window.scrollTo(0, top - 150);
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
});
|
||||
}());
|
||||
|
||||
$(document).on('turbolinks:before-visit', function(e) {
|
||||
_.each(tinyMCE.editors, function(editor) {
|
||||
if (editor.isNotDirty === false) {
|
||||
if (confirm(I18n.t('tiny_mce.leaving_warning'))) {
|
||||
return false;
|
||||
}
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
});
|
|
@ -2,12 +2,14 @@
|
|||
/* 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.create('tinymce.plugins.CustomImageUploader', {
|
||||
tinymce.add('tinymce.plugins.CustomImageUploader', {
|
||||
CustomImageUploader: function(ed) {
|
||||
var iframe;
|
||||
var editor = ed;
|
||||
|
@ -131,3 +133,4 @@
|
|||
tinymce.plugins.CustomImageUploader
|
||||
);
|
||||
}());
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* global tinymce */
|
||||
|
||||
tinymce.PluginManager.add('placeholder', function(editor) {
|
||||
var Label = function() {
|
||||
var editorForm = $(editor.getContainer()).closest('form');
|
||||
|
|
|
@ -56,6 +56,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
.tinymce-save-controls {
|
||||
display: flex;
|
||||
margin-left: auto !important;
|
||||
}
|
||||
|
||||
.tinymce-status-badge {
|
||||
color: $color-silver-chalice;
|
||||
margin-top: -20px;
|
||||
|
@ -69,18 +74,17 @@
|
|||
background: $color-white !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.restore-draft-notification {
|
||||
align-items: center;
|
||||
background: $state-info-bg !important;
|
||||
display: flex;
|
||||
flex-basis: 100%;
|
||||
height: 30px !important;
|
||||
padding: 0 10px !important;
|
||||
padding: 10px !important;
|
||||
|
||||
.notification-text {
|
||||
flex-grow: 1;
|
||||
max-width: 75%;
|
||||
max-width: 85%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
@ -193,4 +197,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
// fix for TinyMCE 6 vs Boostrap 3 .show conflict
|
||||
.tox.tox-tinymce.show {
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
// scss-lint:enable ImportantRule
|
||||
|
|
467
app/javascript/packs/tiny_mce.js
vendored
Normal file
467
app/javascript/packs/tiny_mce.js
vendored
Normal file
|
@ -0,0 +1,467 @@
|
|||
import tinyMCE from 'tinymce/tinymce';
|
||||
import 'tinymce/models/dom';
|
||||
import 'tinymce/icons/default';
|
||||
import 'tinymce/themes/silver';
|
||||
|
||||
import 'tinymce/plugins/table';
|
||||
import 'tinymce/plugins/autosave';
|
||||
import 'tinymce/plugins/autoresize';
|
||||
import 'tinymce/plugins/link';
|
||||
import 'tinymce/plugins/advlist';
|
||||
import 'tinymce/plugins/codesample';
|
||||
import 'tinymce/plugins/autolink';
|
||||
import 'tinymce/plugins/lists';
|
||||
import 'tinymce/plugins/charmap';
|
||||
import 'tinymce/plugins/anchor';
|
||||
import 'tinymce/plugins/searchreplace';
|
||||
import 'tinymce/plugins/wordcount';
|
||||
import 'tinymce/plugins/visualblocks';
|
||||
import 'tinymce/plugins/visualchars';
|
||||
import 'tinymce/plugins/insertdatetime';
|
||||
import 'tinymce/plugins/nonbreaking';
|
||||
import 'tinymce/plugins/save';
|
||||
import 'tinymce/plugins/directionality';
|
||||
|
||||
window.TinyMCE = (function() {
|
||||
'use strict';
|
||||
|
||||
function initHighlightjs() {
|
||||
$('[class*=language]').each(function(i, block) {
|
||||
hljs.highlightBlock(block);
|
||||
});
|
||||
}
|
||||
|
||||
function initHighlightjsIframe(iframe) {
|
||||
$('[class*=language]', iframe).each(function(i, block) {
|
||||
hljs.highlightBlock(block);
|
||||
});
|
||||
}
|
||||
|
||||
// Get LocalStorage auto save path
|
||||
function getAutoSavePrefix(editor) {
|
||||
var prefix = editor.getParam('autosave_prefix', 'tinymce-autosave-{path}{query}{hash}-{id}-');
|
||||
|
||||
prefix = prefix.replace(/\{path\}/g, document.location.pathname);
|
||||
prefix = prefix.replace(/\{query\}/g, document.location.search);
|
||||
prefix = prefix.replace(/\{hash\}/g, document.location.hash);
|
||||
prefix = prefix.replace(/\{id\}/g, editor.id);
|
||||
|
||||
return prefix;
|
||||
}
|
||||
|
||||
// Handles autosave notification if draft is available in the local storage
|
||||
function restoreDraftNotification(selector, editor) {
|
||||
var prefix = getAutoSavePrefix(editor);
|
||||
var lastDraftTime = parseInt(tinyMCE.util.LocalStorage.getItem(prefix + 'time'), 10);
|
||||
var lastUpdated = $(selector).data('last-updated');
|
||||
var notificationBar;
|
||||
var restoreBtn = $('<button class="btn restore-draft-btn">Restore Draft</button>');
|
||||
var cancelBtn = $('<span class="fas fa-times"></span>');
|
||||
|
||||
// Check whether we have draft stored
|
||||
|
||||
if (editor.plugins.autosave.hasDraft()) {
|
||||
notificationBar = $('<div class="restore-draft-notification"></div>');
|
||||
|
||||
if (lastDraftTime < lastUpdated) {
|
||||
notificationBar.html(`<span class="notification-text">${I18n.t('tiny_mce.older_version_available')}</span>`);
|
||||
} else {
|
||||
notificationBar.html(`<span class="notification-text">${I18n.t('tiny_mce.newer_version_available')}</span>`);
|
||||
}
|
||||
|
||||
// Add notification bar
|
||||
$(notificationBar).append(restoreBtn).append(cancelBtn);
|
||||
$(editor.contentAreaContainer).before(notificationBar);
|
||||
|
||||
$(restoreBtn).click(function() {
|
||||
editor.plugins.autosave.restoreDraft();
|
||||
makeItDirty(editor);
|
||||
notificationBar.remove();
|
||||
});
|
||||
|
||||
$(cancelBtn).click(function() {
|
||||
notificationBar.remove();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function initImageToolBar(editor) {
|
||||
var editorIframe = $('#' + editor.id).prev().find('.mce-edit-area iframe');
|
||||
var primaryColor = '#104da9';
|
||||
editorIframe.contents().find('head').append(`<style type="text/css">
|
||||
img::-moz-selection{background:0 0}
|
||||
img::selection{background:0 0}
|
||||
.mce-content-body img[data-mce-selected]{outline:2px solid ${primaryColor}}
|
||||
.mce-content-body div.mce-resizehandle{background:transparent;border-color:transparent;box-sizing:border-box;height:10px;width:10px}
|
||||
.mce-content-body div.mce-resizehandle:hover{background:transparent}
|
||||
.mce-content-body div#mceResizeHandlenw{border-left: 2px solid ${primaryColor}; border-top: 2px solid ${primaryColor}}
|
||||
.mce-content-body div#mceResizeHandlene{border-right: 2px solid ${primaryColor}; border-top: 2px solid ${primaryColor}}
|
||||
.mce-content-body div#mceResizeHandlesw{border-left: 2px solid ${primaryColor}; border-bottom: 2px solid ${primaryColor}}
|
||||
.mce-content-body div#mceResizeHandlese{border-right: 2px solid ${primaryColor}; border-bottom: 2px solid ${primaryColor}}
|
||||
</style>`);
|
||||
}
|
||||
|
||||
function makeItDirty(editor) {
|
||||
var editorForm = $(editor.getContainer()).closest('form');
|
||||
editorForm.find('.tinymce-status-badge').addClass('hidden');
|
||||
$(editor.getContainer()).find('.tinymce-save-button').removeClass('hidden');
|
||||
}
|
||||
|
||||
function draftLocation() {
|
||||
return 'tinymce-drafts-' + document.location.pathname;
|
||||
}
|
||||
|
||||
function removeDraft(editor, textAreaObject) {
|
||||
var location = draftLocation();
|
||||
var storedDrafts = JSON.parse(sessionStorage.getItem(location) || '[]');
|
||||
var draftId = storedDrafts.indexOf(textAreaObject.data('tinymce-object'));
|
||||
if (draftId > -1) {
|
||||
storedDrafts.splice(draftId, 1);
|
||||
}
|
||||
|
||||
if (storedDrafts.length) {
|
||||
sessionStorage.setItem(location, JSON.stringify(storedDrafts));
|
||||
} else {
|
||||
sessionStorage.removeItem(location);
|
||||
}
|
||||
}
|
||||
|
||||
// Update scroll position after exit
|
||||
function updateScrollPosition(editorForm) {
|
||||
if (editorForm.offset().top < $(window).scrollTop()) {
|
||||
$(window).scrollTop(editorForm.offset().top - 150);
|
||||
}
|
||||
}
|
||||
|
||||
function saveAction(editor) {
|
||||
var editorForm = $(editor.getContainer()).closest('form');
|
||||
editorForm.clearFormErrors();
|
||||
editor.setProgressState(1);
|
||||
editor.save();
|
||||
editorForm.submit();
|
||||
updateScrollPosition(editorForm);
|
||||
}
|
||||
|
||||
// returns a public API for TinyMCE editor
|
||||
return Object.freeze({
|
||||
init: function(selector, options) {
|
||||
var editorInstancePromise;
|
||||
var tinyMceContainer;
|
||||
var tinyMceInitSize;
|
||||
var plugins;
|
||||
var textAreaObject = $(selector);
|
||||
if (typeof tinyMCE !== 'undefined') {
|
||||
// Hide element containing HTML view of RTE field
|
||||
tinyMceContainer = $(selector).closest('form').find('.tinymce-view');
|
||||
tinyMceInitSize = tinyMceContainer.height();
|
||||
$(selector).closest('.form-group')
|
||||
.before('<div class="tinymce-placeholder" style="height:' + tinyMceInitSize + 'px"></div>');
|
||||
tinyMceContainer.addClass('hidden');
|
||||
plugins = 'table autosave autoresize link advlist codesample autolink lists charmap anchor searchreplace wordcount visualblocks visualchars insertdatetime nonbreaking save directionality';
|
||||
|
||||
// if (typeof (MarvinJsEditor) !== 'undefined') plugins += ' marvinjsplugin';
|
||||
|
||||
if (textAreaObject.data('objectType') === 'step'
|
||||
|| textAreaObject.data('objectType') === 'result_text') {
|
||||
document.location.hash = textAreaObject.data('objectType') + '_' + textAreaObject.data('objectId');
|
||||
}
|
||||
|
||||
editorInstancePromise = tinyMCE.init({
|
||||
cache_suffix: '?v=6.1.2', // This suffix should be changed any time library is updated
|
||||
selector: selector,
|
||||
convert_urls: false,
|
||||
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',
|
||||
plugins: plugins,
|
||||
autoresize_bottom_margin: 20,
|
||||
placeholder: options.placeholder,
|
||||
skin: false,
|
||||
content_css: false,
|
||||
content_style: "body { font-family: Lato, sans-serif; }",
|
||||
codesample_languages: [
|
||||
{ text: 'R', value: 'r' },
|
||||
{ text: 'MATLAB', value: 'matlab' },
|
||||
{ text: 'Python', value: 'python' },
|
||||
{ text: 'JSON', value: 'javascript' },
|
||||
{ text: 'HTML/XML', value: 'markup' },
|
||||
{ text: 'JavaScript', value: 'javascript' },
|
||||
{ text: 'CSS', value: 'css' },
|
||||
{ text: 'PHP', value: 'php' },
|
||||
{ text: 'Ruby', value: 'ruby' },
|
||||
{ text: 'Java', value: 'java' },
|
||||
{ text: 'C', value: 'c' },
|
||||
{ text: 'C#', value: 'csharp' },
|
||||
{ text: 'C++', value: 'cpp' }
|
||||
],
|
||||
browser_spellcheck: true,
|
||||
branding: false,
|
||||
fixed_toolbar_container: '#mytoolbar',
|
||||
autosave_restore_when_empty: false,
|
||||
autosave_interval: '1s',
|
||||
autosave_retention: '1440m',
|
||||
removed_menuitems: 'newdocument',
|
||||
object_resizing: true,
|
||||
elementpath: false,
|
||||
forced_root_block: 'div',
|
||||
default_link_target: '_blank',
|
||||
target_list: [
|
||||
{ title: 'New page', value: '_blank' },
|
||||
{ title: 'Same page', value: '_self' }
|
||||
],
|
||||
style_formats: [
|
||||
{
|
||||
title: 'Headers',
|
||||
items: [
|
||||
{ title: 'Header 1', format: 'h1' },
|
||||
{ title: 'Header 2', format: 'h2' },
|
||||
{ title: 'Header 3', format: 'h3' },
|
||||
{ title: 'Header 4', format: 'h4' },
|
||||
{ title: 'Header 5', format: 'h5' },
|
||||
{ title: 'Header 6', format: 'h6' }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Inline',
|
||||
items: [
|
||||
{ title: 'Bold', icon: 'bold', format: 'bold' },
|
||||
{ title: 'Italic', icon: 'italic', format: 'italic' },
|
||||
{ title: 'Underline', icon: 'underline', format: 'underline' },
|
||||
{ title: 'Strikethrough', icon: 'strikethrough', format: 'strikethrough' },
|
||||
{ title: 'Superscript', icon: 'superscript', format: 'superscript' },
|
||||
{ title: 'Subscript', icon: 'subscript', format: 'subscript' },
|
||||
{ title: 'Code', icon: 'code', format: 'code' }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Blocks',
|
||||
items: [
|
||||
{ title: 'Paragraph', format: 'p' },
|
||||
{ title: 'Blockquote', format: 'blockquote' }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Alignment',
|
||||
items: [
|
||||
{ title: 'Left', icon: 'alignleft', format: 'alignleft' },
|
||||
{ title: 'Center', icon: 'aligncenter', format: 'aligncenter' },
|
||||
{ title: 'Right', icon: 'alignright', format: 'alignright' },
|
||||
{ title: 'Justify', icon: 'alignjustify', format: 'alignjustify' }
|
||||
]
|
||||
}
|
||||
],
|
||||
init_instance_callback: function(editor) {
|
||||
var editorForm = $(editor.getContainer()).closest('form');
|
||||
var menuBar = editorForm.find('.tox-menubar');
|
||||
var editorToolbar = editorForm.find('.mce-top-part');
|
||||
|
||||
var editorToolbaroffset;
|
||||
|
||||
$('.tinymce-placeholder').css('height', $(editor.editorContainer).height() + 'px');
|
||||
$(editor.editorContainer).css('max-height', '0').css('opacity', '0')
|
||||
setTimeout(() => {
|
||||
$(editor.editorContainer).css('max-height', '').css('opacity', '')
|
||||
$('.tinymce-placeholder').remove();
|
||||
}, 400);
|
||||
|
||||
// Init saved status label
|
||||
if (editor.getContent() !== '') {
|
||||
editorForm.find('.tinymce-status-badge').removeClass('hidden');
|
||||
}
|
||||
|
||||
if ($('.navbar-secondary').length) {
|
||||
editorToolbaroffset = $('.navbar-secondary').position().top + $('.navbar-secondary').height();
|
||||
} else if ($('#main-nav').length) {
|
||||
editorToolbaroffset = $('#main-nav').height();
|
||||
} else {
|
||||
editorToolbaroffset = 0;
|
||||
}
|
||||
|
||||
if (GLOBAL_CONSTANTS.IS_SAFARI) {
|
||||
editorToolbar.css('position', '-webkit-sticky');
|
||||
} else {
|
||||
editorToolbar.css('position', 'sticky');
|
||||
}
|
||||
editorToolbar.css('top', editorToolbaroffset + 'px').css('z-index', '100');
|
||||
|
||||
// Init image toolbar
|
||||
initImageToolBar(editor);
|
||||
|
||||
// Init save/cancel button wrapper
|
||||
$('<div class="tinymce-save-controls"></div>').appendTo(menuBar);
|
||||
|
||||
// Init Save button
|
||||
editorForm
|
||||
.find('.tinymce-save-button')
|
||||
.clone()
|
||||
.appendTo(menuBar.find('.tinymce-save-controls'))
|
||||
.on('click', function(event) {
|
||||
event.preventDefault();
|
||||
saveAction(editor);
|
||||
});
|
||||
|
||||
// After save action
|
||||
editorForm
|
||||
.on('ajax:success', function(ev, data) {
|
||||
editor.save();
|
||||
editor.setProgressState(0);
|
||||
editorForm.find('.tinymce-status-badge').removeClass('hidden');
|
||||
editor.remove();
|
||||
editorForm.find('.tinymce-view').html(data.html).removeClass('hidden');
|
||||
editor.plugins.autosave.removeDraft();
|
||||
removeDraft(editor, textAreaObject);
|
||||
if (options.onSaveCallback) { options.onSaveCallback(data); }
|
||||
}).on('ajax:error', function(ev, data) {
|
||||
var model = editor.getElement().dataset.objectType;
|
||||
$(this).renderFormErrors(model, data.responseJSON);
|
||||
editor.setProgressState(0);
|
||||
if (data.status === 403) {
|
||||
HelperModule.flashAlertMsg(I18n.t('general.no_permissions'), 'danger');
|
||||
}
|
||||
});
|
||||
|
||||
// Init Cancel button
|
||||
editorForm
|
||||
.find('.tinymce-cancel-button')
|
||||
.clone()
|
||||
.appendTo(menuBar.find('.tinymce-save-controls'))
|
||||
.on('click', function(event) {
|
||||
$(editorForm).find('.form-group').removeClass('has-error');
|
||||
$(editorForm).find('.help-block').remove();
|
||||
|
||||
event.preventDefault();
|
||||
if (editor.isDirty()) {
|
||||
editor.setContent($(selector).val());
|
||||
}
|
||||
editorForm.find('.tinymce-status-badge').addClass('hidden');
|
||||
editorForm.find('.tinymce-view').removeClass('hidden');
|
||||
editor.remove();
|
||||
|
||||
updateScrollPosition(editorForm);
|
||||
if (options.onSaveCallback) { options.onSaveCallback(); }
|
||||
})
|
||||
.removeClass('hidden');
|
||||
|
||||
editor.selection.select(editor.getBody(), true);
|
||||
editor.selection.collapse(false);
|
||||
|
||||
SmartAnnotation.init($(editor.contentDocument.activeElement));
|
||||
SmartAnnotation.preventPropagation('.atwho-user-popover');
|
||||
initHighlightjsIframe($(this.iframeElement).contents());
|
||||
},
|
||||
setup: function(editor) {
|
||||
editor.on('keydown', function(e) {
|
||||
if (e.keyCode === 13 && $(editor.contentDocument.activeElement).atwho('isSelecting')) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
editor.on('NodeChange', function(e) {
|
||||
var node = e.element;
|
||||
setTimeout(function() {
|
||||
if ($(node).is('pre') && !editor.isHidden()) {
|
||||
initHighlightjsIframe($(editor.iframeElement).contents());
|
||||
}
|
||||
}, 200);
|
||||
});
|
||||
|
||||
editor.on('Dirty', function() {
|
||||
makeItDirty(editor);
|
||||
});
|
||||
|
||||
editor.on('StoreDraft', function() {
|
||||
var location = draftLocation();
|
||||
var storedDrafts = JSON.parse(sessionStorage.getItem(location) || '[]');
|
||||
var draftName = textAreaObject.data('tinymce-object');
|
||||
if (storedDrafts.includes(draftName) || !draftName) return;
|
||||
storedDrafts.push(draftName);
|
||||
sessionStorage.setItem(location, JSON.stringify(storedDrafts));
|
||||
});
|
||||
|
||||
editor.on('remove', function() {
|
||||
var menuBar = $(editor.getContainer()).find('.tox-menubar');
|
||||
menuBar.find('.tinymce-save-button').remove();
|
||||
menuBar.find('.tinymce-cancel-button').remove();
|
||||
});
|
||||
|
||||
editor.on('blur', function(e) {
|
||||
if (editor.blurDisabled) return false;
|
||||
|
||||
if ($('.atwho-view:visible').length || $('#MarvinJsModal:visible').length) return false;
|
||||
setTimeout(() => {
|
||||
if (editor.isNotDirty === false) {
|
||||
$(editor.container).find('.tinymce-save-button').click();
|
||||
} else {
|
||||
$(editor.container).find('.tinymce-cancel-button').click();
|
||||
}
|
||||
}, 0);
|
||||
return true;
|
||||
});
|
||||
|
||||
editor.on('init', function(e) {
|
||||
restoreDraftNotification(selector, editor);
|
||||
});
|
||||
},
|
||||
codesample_content_css: $(selector).data('highlightjs-path'),
|
||||
save_onsavecallback: function(editor) { saveAction(editor); }
|
||||
});
|
||||
}
|
||||
|
||||
return editorInstancePromise;
|
||||
},
|
||||
destroyAll: function() {
|
||||
_.each(tinyMCE.editors, function(editor) {
|
||||
if (editor) {
|
||||
editor.remove();
|
||||
initHighlightjs();
|
||||
}
|
||||
});
|
||||
},
|
||||
refresh: function() {
|
||||
this.destroyAll();
|
||||
this.init();
|
||||
},
|
||||
getContent: function() {
|
||||
return tinyMCE.editors[0].getContent();
|
||||
},
|
||||
updateImages(editor) {
|
||||
var images;
|
||||
var iframe = $('#' + editor.id).prev().find('.mce-edit-area iframe').contents();
|
||||
images = $.map($('img', iframe), e => {
|
||||
return e.dataset.mceToken;
|
||||
});
|
||||
$('#' + editor.id).next()[0].value = JSON.stringify(images);
|
||||
return JSON.stringify(images);
|
||||
},
|
||||
makeItDirty: function(editor) {
|
||||
makeItDirty(editor);
|
||||
},
|
||||
highlight: initHighlightjs,
|
||||
initIfHasDraft: function(viewObject) {
|
||||
var storedDrafts = sessionStorage.getItem(draftLocation());
|
||||
var draftName = viewObject.data('tinymce-init');
|
||||
if (storedDrafts && JSON.parse(storedDrafts)[0] === draftName) {
|
||||
let top = viewObject.offset().top;
|
||||
setTimeout(() => {
|
||||
viewObject.click();
|
||||
}, 0);
|
||||
setTimeout(() => {
|
||||
window.scrollTo(0, top - 150);
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
});
|
||||
}());
|
||||
|
||||
$(document).on('turbolinks:before-visit', function(e) {
|
||||
_.each(tinyMCE.editors, function(editor) {
|
||||
if (editor.isNotDirty === false) {
|
||||
if (confirm(I18n.t('tiny_mce.leaving_warning'))) {
|
||||
return false;
|
||||
}
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
});
|
2
app/javascript/packs/tiny_mce_styles.scss
Normal file
2
app/javascript/packs/tiny_mce_styles.scss
Normal file
|
@ -0,0 +1,2 @@
|
|||
@import "tinymce/skins/ui/tinymce-5/skin.min.css";
|
||||
@import "tinymce/skins/ui/tinymce-5/content.min.css";
|
|
@ -3,13 +3,13 @@
|
|||
<div class="tinymce-container" :class="{ 'error': error }">
|
||||
<form class="tiny-mce-editor" role="form" :action="updateUrl" accept-charset="UTF-8" data-remote="true" method="post">
|
||||
<input type="hidden" name="_method" value="patch">
|
||||
<div class="hidden tinymce-cancel-button mce-widget mce-btn mce-menubtn mce-flow-layout-item mce-btn-has-text pull-right" tabindex="-1">
|
||||
<div class="hidden tinymce-cancel-button tox-mbtn" tabindex="-1">
|
||||
<button type="button" tabindex="-1">
|
||||
<span class="fas fa-times"></span>
|
||||
<span class="mce-txt">{{ i18n.t('general.cancel') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="hidden tinymce-save-button mce-widget mce-btn mce-menubtn mce-flow-layout-item mce-btn-has-text mce-last pull-right" tabindex="-1">
|
||||
<div class="hidden tinymce-save-button tox-mbtn" tabindex="-1">
|
||||
<button type="button" tabindex="-1">
|
||||
<span class="fas fa-check"></span>
|
||||
<span class="mce-txt">{{ i18n.t('general.save') }}</span>
|
||||
|
@ -128,12 +128,17 @@
|
|||
if (e && $(e.target).hasClass('record-info-link')) return
|
||||
if (e && $(e.target).parent().hasClass('atwho-inserted')) return
|
||||
|
||||
TinyMCE.init(textArea, (data) => {
|
||||
TinyMCE.init(
|
||||
textArea,
|
||||
{
|
||||
onSaveCallback() {
|
||||
if (data) {
|
||||
this.$emit('update', data)
|
||||
}
|
||||
this.$emit('editingDisabled')
|
||||
}).then(() => {
|
||||
this.$emit('editingDisabled');
|
||||
}
|
||||
}
|
||||
).then(() => {
|
||||
this.active = true;
|
||||
this.initCharacterCount();
|
||||
});
|
||||
|
|
|
@ -8,11 +8,12 @@
|
|||
<meta name="tiny-mce-assets-url" content="<%= tiny_mce_assets_path %>">
|
||||
<meta name="highlightjs-url" content="<%= asset_path('highlightjs-github-theme.css') %>">
|
||||
<%= stylesheet_link_tag 'application', media: 'all' %>
|
||||
|
||||
|
||||
<%= javascript_include_tag 'jquery_bundle' %>
|
||||
<%= javascript_include_tag 'application' %>
|
||||
<%= javascript_pack_tag 'application' %>
|
||||
|
||||
|
||||
|
||||
<% if MarvinJsService.enabled? && ENV['MARVINJS_API_KEY'] %>
|
||||
<script src="https://marvinjs.chemicalize.com/v1/<%= ENV['MARVINJS_API_KEY'] %>/client-settings.js"></script>
|
||||
<script src="https://marvinjs.chemicalize.com/v1/client.js"></script>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
<%= render 'shared/tiny_mce_packs' %>
|
||||
|
||||
<% if flash["repository_snapshot_error"] %>
|
||||
<%= render 'shared/dialog',
|
||||
id: "snapshot-error",
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
<%= render 'shared/tiny_mce_packs' %>
|
||||
|
||||
<% provide(:head_title, t("my_modules.results.head_title", project: h(@project.name), module: h(@my_module.name)).html_safe) %>
|
||||
<% provide(:sidebar_title, t("sidebar.my_module.sidebar_title")) %>
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
<%= render 'shared/tiny_mce_packs' %>
|
||||
|
||||
<div class="content-pane protocols-show" >
|
||||
<div class="protocol-position-container">
|
||||
<div class="protocol-actions">
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<div class="hidden tinymce-cancel-button mce-widget mce-btn mce-menubtn mce-flow-layout-item mce-btn-has-text pull-right" tabindex="-1">
|
||||
<div class="hidden tinymce-cancel-button tox-mbtn" tabindex="-1">
|
||||
<button type="button" tabindex="-1">
|
||||
<span class="fas fa-times"></span>
|
||||
<span class="mce-txt"><%= t('general.cancel') %></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="hidden tinymce-save-button mce-widget mce-btn mce-menubtn mce-flow-layout-item mce-btn-has-text mce-last pull-right" tabindex="-1">
|
||||
<div class="hidden tinymce-save-button tox-mbtn" tabindex="-1">
|
||||
<button type="button" tabindex="-1" >
|
||||
<span class="fas fa-check"></span>
|
||||
<span class="mce-txt"><%= t('general.save') %></span>
|
||||
|
|
2
app/views/shared/_tiny_mce_packs.html.erb
Normal file
2
app/views/shared/_tiny_mce_packs.html.erb
Normal file
|
@ -0,0 +1,2 @@
|
|||
<%= javascript_pack_tag 'tiny_mce' %>
|
||||
<%= stylesheet_pack_tag 'tiny_mce_styles' %>
|
|
@ -105,3 +105,6 @@ Rails.application.config.assets.precompile += %w(ruleJS.js)
|
|||
Rails.application.config.assets.precompile += %w(handsontable.formula.js)
|
||||
Rails.application.config.assets.precompile += %w(handsontable.formula.css)
|
||||
Rails.application.config.assets.precompile += %w(big.min.js)
|
||||
|
||||
# JQuery related includes
|
||||
Rails.application.config.assets.precompile += %w(jquery_bundle.js)
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
"@babel/plugin-proposal-class-properties": "^7.0.0",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
|
||||
"@babel/plugin-transform-runtime": "^7.18.10",
|
||||
"@babel/polyfill": "^7.0.0",
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
|
@ -109,6 +110,7 @@
|
|||
"shortid": "^2.2.12",
|
||||
"style-loader": "^0.18.2",
|
||||
"styled-components": "^2.4.1",
|
||||
"tinymce": "^6.1.2",
|
||||
"tui-code-snippet": "^1.5.0",
|
||||
"tui-color-picker": "^2.2.0",
|
||||
"tui-image-editor": "github:biosistemika/tui.image-editor#3_15_2_updated",
|
||||
|
|
Loading…
Reference in a new issue