Elastic: Change HTML editor widget to improve form flow (#6992)

pull/7051/head
Aleksander Machniak 5 years ago
parent 4b24ba1372
commit b63d549834

@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail
===========================
- Elastic: Change HTML editor widget to improve form flow (#6992)
- Managesieve: Fix locked UI after opening filter frame (#7007)
- Fix PHP warning: "array_merge(): Expected parameter 2 to be an array, null given in sendmail.inc (#7003)
- Fix bug where cache keys could exceed length limit specified in db schema (#7004)

@ -134,7 +134,7 @@ function rcube_text_editor(config, id)
$.extend(conf, window.rcmail_editor_settings);
conf.setup = function(ed) {
ed.on('init', function(ed) { ref.init_callback(ed); });
ed.on('init', function() { ref.init_callback(ed); });
// add handler for spellcheck button state update
ed.on('SpellcheckStart SpellcheckEnd', function(args) {
ref.spellcheck_active = args.type == 'spellcheckstart';
@ -159,7 +159,7 @@ function rcube_text_editor(config, id)
conf.setup_callback(ed);
};
rcmail.triggerEvent('editor-init', {config: conf, ref: ref});
rcmail.triggerEvent('editor-init', {config: conf, ref: ref, id: id});
// textarea identifier
this.id = id;
@ -169,11 +169,9 @@ function rcube_text_editor(config, id)
tinymce.init(conf);
// react to real individual tinyMCE editor init
this.init_callback = function(event)
this.init_callback = function(editor)
{
this.editor = event.target;
rcmail.triggerEvent('editor-load', {config: conf, ref: ref});
this.editor = editor;
if (rcmail.env.action == 'compose') {
var area = $('#' + this.id),
@ -182,7 +180,7 @@ function rcube_text_editor(config, id)
// the editor might be still not fully loaded, making the editing area
// inaccessible, wait and try again (#1490310)
if (height > 200 || height > area.height()) {
return setTimeout(function () { ref.init_callback(event); }, 300);
return setTimeout(function () { ref.init_callback(editor); }, 300);
}
var css = {},
@ -212,6 +210,8 @@ function rcube_text_editor(config, id)
}
}
rcmail.triggerEvent('editor-load', {config: conf, ref: ref});
// set tabIndex and set focus to element that was focused before
ref.tabindex(ref.force_focus || (fe && fe.id == ref.id));

@ -374,8 +374,8 @@ body.task-error-login #layout {
}
#composestatusbar {
position: absolute;
opacity: .3;
right: 2.5rem;
@media screen and (min-width: (@screen-width-small + 1px)) {
display: none;
@ -383,11 +383,10 @@ body.task-error-login #layout {
a.button {
display: inline-block;
height: 2.5rem;
margin-right: .25rem;
&:before {
line-height: 2.5rem;
line-height: @layout-touch-header-height;
font-size: 1.25rem !important;
}
}
}

@ -836,42 +836,63 @@ html.touch .mce-grid td {
.html-editor {
position: relative;
display: flex;
margin-bottom: .25rem;
margin-bottom: .2rem;
& > .nav {
border-color: transparent;
z-index: 1;
.editor-toolbar {
position: absolute;
right: 1rem;
a.active {
border-color: @color-input-border !important;
left: 1px;
top: 1px;
right: 1px;
border-radius: .25rem .25rem 0 0;
border-bottom: 1px solid @color-input-border;
background-color: @color-input-addon-background;
&.mode-html {
background-color: @color-input-addon-background;
border-bottom-color: @color-input-addon-background !important;
}
.mce-i-html {
display: block;
padding: 1px 5px;
margin: 2px;
width: 2rem;
height: 24px;
border: 1px solid transparent;
color: #595959;
&.mode-plain {
border-bottom-color: #fff !important;
&:focus,
&:hover {
text-decoration: none;
border-color: #e2e4e7;
background-color: #fff;
}
}
}
a:hover,
a:focus {
border-bottom-color: transparent;
outline: 0;
}
// hide toolbar in html mode and in mailvelope mode
&.mailvelope .editor-toolbar,
.mce-tinymce + textarea + .editor-toolbar {
display: none;
}
.mce-i-html:before,
.mce-i-plaintext:before {
&:extend(.font-icon-class);
margin: 0;
width: 1em;
font-size: 1.2rem;
}
.mce-i-html:before {
content: @fa-var-image;
line-height: 1.2em;
}
.mce-i-plaintext:before {
content: @fa-var-window-close; //@fa-var-align-justify;
}
& > iframe, // e.g. mailvelope frame
& > .googie_edit_layer,
& > .mce-tinymce,
& > textarea {
margin-top: 2.55rem;
font-family: monospace;
width: 100% !important;
padding-top: 2.5rem;
}
& > iframe { // e.g. mailvelope frame
@ -905,7 +926,7 @@ html.touch .mce-grid td {
padding: .5rem .75rem;
border: 1px solid @color-input-border;
border-radius: .3rem;
line-height: 1.25;
line-height: 1.5;
}
.googie_link {

@ -612,7 +612,7 @@ html.ms .propform {
&:extend(.font-icon-class);
margin: 0 !important;
line-height: 1;
font-size: 1.1em;
font-size: 1.1rem;
}
&.user:before {
content: @fa-var-user;
@ -984,7 +984,6 @@ html.ms .propform {
float: none;
display: inline-block;
width: 1em;
margin: 0;
line-height: 1.5;
}
}

@ -77,6 +77,7 @@
<div class="header">
<a class="button icon task-menu-button" href="#menu"><span class="inner"><roundcube:label name="menu" /></span></a>
<span class="header-title"><roundcube:label name="compose" /></span>
<div id="composestatusbar" class="position-absolute"></div>
<!-- toolbar -->
<div id="messagetoolbar" class="toolbar menu" role="toolbar" aria-labelledby="aria-label-toolbar">
<a class="options" href="#options" onclick="UI.show_sidebar()" data-hidden="big">
@ -214,7 +215,6 @@
<div id="composebodycontainer">
<label for="composebody" class="voice"><roundcube:label name="arialabelmessagebody" /></label>
<roundcube:object name="composeBody" id="composebody" form="form" cols="70" rows="20" class="form-control" tabindex="1" />
<div id="composestatusbar"></div>
</div>
</form>
<div class="formbuttons">

@ -1350,6 +1350,9 @@ function rcube_elastic_ui()
*/
function tinymce_init(o)
{
var onload = [],
is_editor = $('#' + o.id).is('[data-html-editor]');
// Enable autoresize plugin
o.config.plugins += ' autoresize';
@ -1374,9 +1377,9 @@ function rcube_elastic_ui()
};
// Shift+Tab on mail compose editor scrolls the page to the top
o.config.setup_callback = function(ed) {
onload.push(function(ed) {
ed.on('keypress', keypress);
};
});
$('#composebody').on('keypress', keypress);
@ -1397,6 +1400,26 @@ function rcube_elastic_ui()
$(window).resize(function() { form.trigger('scroll'); });
}
if (is_editor) {
o.config.toolbar = 'plaintext | ' + o.config.toolbar;
// Use setup_callback, we can't use editor-load event
o.config.setup_callback = function(ed) {
ed.addButton('plaintext', {
tooltip: rcmail.gettext('plaintoggle'),
icon: 'plaintext',
onclick: function(e) {
if (rcmail.command('toggle-editor', {id: ed.id, html: false}, '', e.originalEvent)) {
$('#' + ed.id).parent().removeClass('ishtml');
}
}
});
};
}
rcmail.addEventListener('editor-load', function(e) {
$.each(onload, function() { this(e.ref.editor); });
});
};
function datepicker_init(datepicker)
@ -1665,7 +1688,7 @@ function rcube_elastic_ui()
var title, right = 0, left = 0, padding = 0,
sizes = {left: 0, right: 0};
$(this).children(':visible').each(function() {
$(this).children(':visible:not(.position-absolute)').each(function() {
if (!title && $(this).is('.header-title')) {
title = $(this);
return;
@ -3602,21 +3625,20 @@ function rcube_elastic_ui()
var sw, is_table = false,
editor = $(obj),
parent = editor.parent(),
tabindex = editor.attr('tabindex'),
mode = function() {
if (is_table) {
return sw.is(':checked') ? 'html' : 'plain';
}
return sw.val();
},
tabs = $('<ul class="nav nav-tabs">')
.append($('<li class="nav-item">')
.append($('<a class="nav-link mode-html" href="#">')
.text(rcmail.gettext('htmltoggle'))))
.append($('<li class="nav-item">')
.append($('<a class="nav-link mode-plain" href="#">')
.text(rcmail.gettext('plaintoggle'))));
plain_btn = $('<a class="mce-i-html" href="#" tabindex="-1"></a>')
.attr('title', rcmail.gettext('htmltoggle'))
.on('click', function(e) {
if (rcmail.command('toggle-editor', {id: editor.attr('id'), html: true}, '', e.originalEvent)) {
parent.addClass('ishtml');
}
})
.on('keydown', function(e) {
if (e.which == 9) { // TAB
editor.focus();
return false;
}
}),
toolbar = $('<div class="editor-toolbar">').append(plain_btn);
if (parent.is('td')) {
sw = $('input[type="checkbox"]', parent.parent().next());
@ -3632,23 +3654,14 @@ function rcube_elastic_ui()
}
parent.addClass('html-editor');
editor.before(tabs);
$('a', tabs).attr('tabindex', tabindex)
.on('click', function(e) {
var id = editor.attr('id'), is_html = $(this).is('.mode-html');
e.preventDefault();
if (rcmail.command('toggle-editor', {id: id, html: is_html}, '', e.originalEvent)) {
$(this).tab('show').prop('tabindex', -1);
$('.mode-' + (is_html ? 'plain' : 'html'), tabs).prop('tabindex', tabindex);
if (is_table) {
sw.prop('checked', is_html);
}
editor.after(toolbar)
.on('keydown', function(e) {
// ALT + F10 is the way to access toolbar in TinyMCE, let's do the same for plain editor
if (e.altKey && e.which == 121) {
plain_btn.focus();
}
})
.filter('.mode-' + mode()).tab('show').prop('tabindex', -1);
});
if (is_table) {
// Hide unwanted table cells

Loading…
Cancel
Save