mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-29 11:45:18 +08:00
[SCI-3751] Improve the auto-save functionality on RTF fields (#2086)
[SCI-3751] Improve the auto-save functionality on RTF fields
This commit is contained in:
commit
4b605d357a
10 changed files with 123 additions and 13 deletions
|
@ -366,6 +366,7 @@
|
|||
});
|
||||
toggleButtons(true);
|
||||
DragNDropSteps.clearFiles();
|
||||
|
||||
tinyMCE.editors.step_description_textarea.remove();
|
||||
});
|
||||
}
|
||||
|
|
78
app/assets/javascripts/sitewide/tiny_mce.js
vendored
78
app/assets/javascripts/sitewide/tiny_mce.js
vendored
|
@ -16,6 +16,65 @@ var TinyMCE = (function() {
|
|||
});
|
||||
}
|
||||
|
||||
function makeItDirty(editor) {
|
||||
var editorForm = $(editor.getContainer()).closest('form');
|
||||
editorForm.find('.tinymce-status-badge').addClass('hidden');
|
||||
$(editor.getContainer())
|
||||
.find('.tinymce-save-button').removeClass('hidden');
|
||||
}
|
||||
|
||||
|
||||
// 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 restoreBtn = $('<button class="btn restore-draft-btn pull-right">Restore Draft</button>');
|
||||
var cancelBtn = $(`<div class="tinymce-cancel-notification-button pull-right">
|
||||
<button type="button">
|
||||
<span class="fas fa-times"></span>
|
||||
</button>
|
||||
</div>`);
|
||||
|
||||
// Check whether we have draft stored
|
||||
if (editor.plugins.autosave.hasDraft()) {
|
||||
var notificationBar = $('<div class="restore-draft-notification"></div>');
|
||||
|
||||
if (lastDraftTime < lastUpdated) {
|
||||
notificationBar.text(I18n.t('tiny_mce.older_version_available'));
|
||||
} else {
|
||||
notificationBar.text(I18n.t('tiny_mce.newer_version_available'));
|
||||
}
|
||||
|
||||
// Add notification bar
|
||||
$(notificationBar).append(cancelBtn).append(restoreBtn);
|
||||
$(editor.contentAreaContainer).before(notificationBar);
|
||||
|
||||
$(restoreBtn).click(function() {
|
||||
editor.plugins.autosave.restoreDraft();
|
||||
makeItDirty(editor);
|
||||
notificationBar.remove();
|
||||
});
|
||||
|
||||
$(cancelBtn).click(function() {
|
||||
notificationBar.remove();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// returns a public API for TinyMCE editor
|
||||
return Object.freeze({
|
||||
init: function(selector, onSaveCallback) {
|
||||
|
@ -30,16 +89,16 @@ var TinyMCE = (function() {
|
|||
.before('<div class="tinymce-placeholder" style="height:' + tinyMceInitSize + 'px"></div>');
|
||||
tinyMceContainer.addClass('hidden');
|
||||
|
||||
if (textAreaObject.data('objectType') === 'step') {
|
||||
if (textAreaObject.data('objectType') === 'step'
|
||||
|| textAreaObject.data('objectType') === 'result_text') {
|
||||
document.location.hash = textAreaObject.data('objectType') + '_' + textAreaObject.data('objectId');
|
||||
}
|
||||
|
||||
|
||||
tinyMCE.init({
|
||||
cache_suffix: '?v=4.9.3', // This suffix should be changed any time library is updated
|
||||
selector: selector,
|
||||
menubar: 'file edit view insert format table',
|
||||
toolbar: 'undo redo restoredraft | insert | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link | forecolor backcolor | customimageuploader | codesample | table tabledelete | tableprops tablerowprops tablecellprops | tableinsertrowbefore tableinsertrowafter tabledeleterow | tableinsertcolbefore tableinsertcolafter tabledeletecol ',
|
||||
toolbar: 'undo redo | insert | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link | forecolor backcolor | customimageuploader | codesample | table tabledelete | tableprops tablerowprops tablecellprops | tableinsertrowbefore tableinsertrowafter tabledeleterow | tableinsertcolbefore tableinsertcolafter tabledeletecol',
|
||||
plugins: 'autosave autoresize customimageuploader link advlist codesample autolink lists charmap hr anchor searchreplace wordcount visualblocks visualchars insertdatetime nonbreaking save directionality paste textcolor placeholder colorpicker textpattern table',
|
||||
autoresize_bottom_margin: 20,
|
||||
codesample_languages: [
|
||||
|
@ -60,7 +119,8 @@ var TinyMCE = (function() {
|
|||
browser_spellcheck: true,
|
||||
branding: false,
|
||||
fixed_toolbar_container: '#mytoolbar',
|
||||
autosave_interval: '15s',
|
||||
autosave_restore_when_empty: false,
|
||||
autosave_interval: '1s',
|
||||
autosave_retention: '1440m',
|
||||
removed_menuitems: 'newdocument',
|
||||
object_resizing: true,
|
||||
|
@ -117,6 +177,7 @@ var TinyMCE = (function() {
|
|||
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');
|
||||
|
@ -226,10 +287,7 @@ var TinyMCE = (function() {
|
|||
});
|
||||
|
||||
editor.on('Dirty', function() {
|
||||
var editorForm = $(editor.getContainer()).closest('form');
|
||||
editorForm.find('.tinymce-status-badge').addClass('hidden');
|
||||
$(editor.getContainer())
|
||||
.find('.tinymce-save-button').removeClass('hidden');
|
||||
makeItDirty(editor);
|
||||
});
|
||||
|
||||
editor.on('remove', function() {
|
||||
|
@ -237,6 +295,10 @@ var TinyMCE = (function() {
|
|||
menuBar.find('.tinymce-save-button').remove();
|
||||
menuBar.find('.tinymce-cancel-button').remove();
|
||||
});
|
||||
|
||||
editor.on('init', function(e) {
|
||||
restoreDraftNotification(selector, editor);
|
||||
});
|
||||
},
|
||||
codesample_content_css: $(selector).data('highlightjs-path')
|
||||
});
|
||||
|
|
|
@ -27,12 +27,26 @@ tinymce.PluginManager.add('placeholder', function(editor) {
|
|||
editor.on('init', function() {
|
||||
var label = new Label();
|
||||
|
||||
// Correct top css property due to notification bar
|
||||
function calculatePlaceholderPosition() {
|
||||
var editorForm = $(editor.getContainer()).closest('form');
|
||||
var editorToolbar = editorForm.find('.mce-top-part');
|
||||
|
||||
var restoreDraftNotification = $(editorForm).find('.restore-draft-notification');
|
||||
var restoreDraftHeight = restoreDraftNotification.context ? restoreDraftNotification.height() : 0;
|
||||
var newTop = $(editorToolbar).height() + restoreDraftHeight;
|
||||
$(label.el).css('top', newTop + 'px');
|
||||
}
|
||||
|
||||
function checkPlaceholder() {
|
||||
// Show/hide depending on the content
|
||||
if (editor.getContent() === '') {
|
||||
label.show();
|
||||
} else {
|
||||
label.hide();
|
||||
}
|
||||
|
||||
calculatePlaceholderPosition();
|
||||
}
|
||||
|
||||
function onKeydown() {
|
||||
|
|
|
@ -66,4 +66,30 @@
|
|||
.mce-toolbar {
|
||||
background: $color-white !important;
|
||||
}
|
||||
|
||||
.tinymce-cancel-notification-button {
|
||||
cursor: pointer;
|
||||
|
||||
.fas {
|
||||
color: $color-silver-chalice;
|
||||
font-family: 'Font Awesome 5 Free';
|
||||
font-weight: 501;
|
||||
margin-left: 10px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.restore-draft-notification {
|
||||
background: $state-info-bg !important;
|
||||
height: 25px !important;
|
||||
padding: 5px 10px 0 !important;
|
||||
|
||||
.restore-draft-btn {
|
||||
border: 1px solid $color-silver-chalice;
|
||||
font-size: 12px;
|
||||
margin-top: -2px;
|
||||
padding: 3px 10px 3px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
// scss-lint:enable ImportantRule
|
||||
|
|
|
@ -23,5 +23,6 @@
|
|||
data: {
|
||||
object_type: 'my_module',
|
||||
object_id: @my_module.id,
|
||||
highlightjs_path: asset_path('highlightjs-github-theme.css') } ) %>
|
||||
highlightjs_path: asset_path('highlightjs-github-theme.css'),
|
||||
last_updated: @my_module.updated_at.to_i * 1000 } ) %>
|
||||
<% end %>
|
||||
|
|
|
@ -23,5 +23,6 @@
|
|||
data: {
|
||||
object_type: 'protocol',
|
||||
object_id: protocol.id,
|
||||
highlightjs_path: asset_path('highlightjs-github-theme.css') } ) %>
|
||||
highlightjs_path: asset_path('highlightjs-github-theme.css'),
|
||||
last_updated: protocol.updated_at.to_i * 1000 } ) %>
|
||||
<% end %>
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
value: @result.result_text.tinymce_render(:text),
|
||||
data: { object_type: 'result_text',
|
||||
object_id: @result.result_text.id,
|
||||
highlightjs_path: asset_path('highlightjs-github-theme.css') }) %>
|
||||
highlightjs_path: asset_path('highlightjs-github-theme.css'),
|
||||
last_updated: @result.updated_at.to_i * 1000 }) %>
|
||||
<% end %><br />
|
||||
<div class="align-right">
|
||||
<button type="button" class="btn btn-default cancel-edit">
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
id: :result_text_attributes_textarea,
|
||||
data: { object_type: 'result_text',
|
||||
object_id: @result.result_text.id,
|
||||
highlightjs_path: asset_path('highlightjs-github-theme.css') }) %>
|
||||
highlightjs_path: asset_path('highlightjs-github-theme.css'),
|
||||
last_updated: @result.updated_at.to_i * 1000 }) %>
|
||||
<% end %><br />
|
||||
<div class="align-right">
|
||||
<button type="button" class="btn btn-default cancel-new">
|
||||
|
|
|
@ -36,7 +36,8 @@
|
|||
data: {
|
||||
object_type: 'step',
|
||||
object_id: @step.id,
|
||||
highlightjs_path: asset_path('highlightjs-github-theme.css') } ) %>
|
||||
highlightjs_path: asset_path('highlightjs-github-theme.css'),
|
||||
last_updated: @step.updated_at.to_i * 1000 }) %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane" role="tabpanel" id="new-step-checklists">
|
||||
|
|
|
@ -2007,6 +2007,8 @@ en:
|
|||
server_not_respond: "Didn't get a response from the server"
|
||||
saved_label: "Saved"
|
||||
leaving_warning: "You have made some changes, are you sure you want to leave this page?"
|
||||
older_version_available: "Older version of the text below has been saved in the browser. Do you want to restore it?"
|
||||
newer_version_available: "Newer version of the text below has been saved in the browser. Do you want to restore it?"
|
||||
general:
|
||||
save: "Save"
|
||||
update: "Update"
|
||||
|
|
Loading…
Reference in a new issue