Skip to content

Commit

Permalink
Elastic: Change HTML editor widget to improve form flow (#6992)
Browse files Browse the repository at this point in the history
  • Loading branch information
alecpl committed Nov 10, 2019
1 parent 4cc20ee commit 3c01f47
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 71 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
14 changes: 7 additions & 7 deletions program/js/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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;
Expand All @@ -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),
Expand All @@ -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 = {},
Expand Down Expand Up @@ -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));

Expand Down
7 changes: 3 additions & 4 deletions skins/elastic/styles/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -374,20 +374,19 @@ body.task-error-login #layout {
}

#composestatusbar {
position: absolute;
opacity: .3;
right: 2.5rem;

@media screen and (min-width: (@screen-width-small + 1px)) {
display: none;
}

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;
}
}
}
Expand Down
69 changes: 45 additions & 24 deletions skins/elastic/styles/widgets/editor.less
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down
3 changes: 1 addition & 2 deletions skins/elastic/styles/widgets/forms.less
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -984,7 +984,6 @@ html.ms .propform {
float: none;
display: inline-block;
width: 1em;
margin: 0;
line-height: 1.5;
}
}
Expand Down
2 changes: 1 addition & 1 deletion skins/elastic/templates/compose.html
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ <h2 id="aria-label-toolbar" class="voice"><roundcube:label name="arialabeltoolba
<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">
Expand Down Expand Up @@ -214,7 +215,6 @@ <h2 id="aria-label-composeheaders" class="voice"><roundcube:label name="arialabe
<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">
Expand Down
79 changes: 46 additions & 33 deletions skins/elastic/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -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);

Expand All @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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());
Expand All @@ -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
Expand Down

0 comments on commit 3c01f47

Please sign in to comment.