Fix markdown toolbar issues

This commit is contained in:
yflory 2025-06-23 16:48:58 +02:00
parent 4fe08f760a
commit ac0085dd2b
10 changed files with 92 additions and 242 deletions

View File

@ -290,31 +290,31 @@
}
//reusable styling for the markdown toggle button across all apps
.markdown-toolbar-button-style() {
padding: 3px 5px;
height: fit-content;
margin: 0;
line-height: 1;
border-radius: @variables_radius;
display: inline-flex;
background-color: @cp_toolbar-bottom-bg;
color: @cp_toolbar-bottom-fg;
.markdown-toolbar-button-style() {
padding: 3px 5px;
height: fit-content;
margin: 0;
line-height: 1;
border-radius: @variables_radius;
display: inline-flex;
background-color: @cp_toolbar-bottom-bg;
color: @cp_toolbar-bottom-fg;
&:hover {
background-color: fade(@cryptpad_text_col, 20%);
border-color: @cryptpad_text_col;
color: @cryptpad_text_col;
}
&.cp-toolbar-button-active {
background-color: @cp_toolbar-bg;
border-color: @cp_toolbar-fg;
color: @cp_toolbar-fg;
&:hover {
background-color: fade(@cryptpad_text_col, 20%);
border-color: @cryptpad_text_col;
color: @cryptpad_text_col;
}
&.cp-toolbar-button-active {
background-color: @cp_toolbar-bg;
border-color: @cp_toolbar-fg;
color: @cp_toolbar-fg;
&:hover {
background-color: fade(@cryptpad_text_col, 20%);
}
}
}
}

View File

@ -77,10 +77,6 @@
border-radius: @variables_radius;
color: @toolbar-color;
.toolbar_button;
.fa {
font: normal normal normal 14px/1 FontAwesome;
font-family: FontAwesome;
}
&:hover {
background-color: contrast(@cp_toolbar-bg, darken(@cp_toolbar-bg, 5%), lighten(@cp_toolbar-bg, 5%));
}
@ -119,7 +115,7 @@
border: 1px solid transparent;
color: inherit;
font: @toolbar_button-font;
* {
*:not(i) {
color: inherit;
font: @toolbar_button-font;
}

View File

@ -1256,39 +1256,34 @@ define([
}
var toolbarVisibleOnSmallScreen = false;
var $toolbarToggleButton = null;
var appType = common.getMetadataMgr().getPrivateData().app;
function updateToolbarVisibility() {
var $wrapper = $(opts && opts.wrapper ? opts.wrapper : $toolbar.parent());
const $toolbarToggleButton = $(h('button.btn.cp-markdown-toggle-button', {
'aria-label': Messages.toolbar_show_text_tools,
'aria-pressed': 'false',
'data-notippy': 1,
'type': 'button',
'title': Messages.toolbar_show_text_tools
})).append([
h('i.fa.fa-wrench', { 'aria-hidden': 'true' }),
h('span.cp-toolbar-label', {}, Messages.toolbar_text_tools)
]).click(function () {
var isExpanded = $toolbar.is(':visible');
$toolbar.toggle();
$(this).toggleClass('cp-toolbar-button-active', !isExpanded)
.attr('aria-pressed', String(!isExpanded))
.attr('title', !isExpanded ? Messages.toolbar_hide_text_tools : Messages.toolbar_show_text_tools)
.attr('aria-label', !isExpanded ? Messages.toolbar_hide_text_tools : Messages.toolbar_show_text_tools);
toolbarVisibleOnSmallScreen = !isExpanded;
}).on('keydown keyup', e => {
// don't close modals when pressing Enter
// on the button
e.stopPropagation();
}).hide();
const updateToolbarVisibility = () => {
if (isSmallScreen()) {
if (!$toolbarToggleButton) {
$toolbarToggleButton = $(h('button.btn.cp-markdown-toggle-button', {
'aria-label': Messages.toolbar_show_text_tools,
'aria-pressed': 'false',
'data-notippy': 1,
'type': 'button',
'title': Messages.toolbar_show_text_tools
})).append([
h('i.fa.fa-wrench', { 'aria-hidden': 'true' }),
h('span.cp-toolbar-label', {}, Messages.toolbar_text_tools)
]).click(function () {
var isExpanded = $toolbar.is(':visible');
$toolbar.toggle();
$(this).toggleClass('cp-toolbar-button-active', !isExpanded)
.attr('aria-pressed', String(!isExpanded))
.attr('title', !isExpanded ? Messages.toolbar_hide_text_tools : Messages.toolbar_show_text_tools)
.attr('aria-label', !isExpanded ? Messages.toolbar_hide_text_tools : Messages.toolbar_show_text_tools);
toolbarVisibleOnSmallScreen = !isExpanded;
}).on('keydown keyup', e => {
// don't close modals when pressing Enter
// on the button
e.stopPropagation();
});
$wrapper.append($toolbarToggleButton);
}
$toolbarToggleButton.show();
if (toolbarVisibleOnSmallScreen) {
$toolbar.show();
$toolbarToggleButton.addClass('cp-toolbar-button-active')
@ -1298,27 +1293,24 @@ define([
$toolbarToggleButton.removeClass('cp-toolbar-button-active')
.attr('aria-pressed', 'false');
}
} else {
if ($toolbarToggleButton) {
$toolbarToggleButton.remove();
$toolbarToggleButton = null;
}
$toolbar.show();
return;
}
}
if (appType !== 'code' && appType !== 'slide') {
$toolbarToggleButton.hide();
$toolbar.show();
};
if (opts?.toggleBar) {
$(window).on('resize', updateToolbarVisibility);
updateToolbarVisibility();
// Small delay to ensure the toolbar layout has rendered before checking for wrapping (ex: profile medium screen size)
setTimeout(() => {
updateToolbarVisibility();
}, 10);
// Small delay to ensure the toolbar layout has rendered
// before checking for wrapping
setTimeout(updateToolbarVisibility);
}
return {
toolbar: $toolbar,
button: $toolbarButton,
toggleButton: $toolbarToggleButton[0],
setState: setState
};
};

View File

@ -180,9 +180,9 @@
margin: 0.5rem 0;
position: relative;
.cp-markdown-toggle-button {
.markdown-toolbar-button-style() !important;
.markdown-toolbar-button-style();
&.cp-toolbar-button-active {
background-color: transparent !important;
//background-color: transparent !important;
}
}
}
@ -554,10 +554,6 @@
}
.cp-form-response-msg-container {
padding-bottom: 75px;
button {
white-space: initial;
padding: 5.5px 6px;
}
.cp-form-response-msg-hint {
color: @cryptpad_color_link;
}

View File

@ -1123,7 +1123,6 @@ define([
editor.focus(); // fallback
}
});
var toggleRow = h('div.cp-markdown-toggle-row');
if (APP.common && !(tmp && tmp.block) && cm) {
var markdownTb = APP.common.createMarkdownToolbar(editor, {
@ -1131,8 +1130,9 @@ define([
editor.focus();
editor.replaceSelection($(mt)[0].outerHTML);
},
wrapper: toggleRow
toggleBar: true
});
var toggleRow = h('div.cp-markdown-toggle-row', markdownTb.toggleButton);
$(block).prepend(markdownTb.toolbar);
$(block).prepend(toggleRow);
cm.configureTheme(APP.common, function () {});
@ -5580,7 +5580,10 @@ define([
var div = h('div.cp-form-block.editable.nodrag.cp-form-submit-message', [
h('div.cp-form-block-content', [
p,
editDiv = h('div.cp-form-response-modal', toggleRow, markdownWrapper),
editDiv = h('div.cp-form-response-modal', [
toggleRow,
markdownWrapper
]),
previewDiv = h('div.cp-form-response-preview#cp-response-preview'),
editButtons
]),
@ -5598,8 +5601,9 @@ define([
editor.focus();
editor.replaceSelection($(mt)[0].outerHTML);
},
wrapper: toggleRow
toggleBar: true
});
$(toggleRow).append(markdownTb.toggleButton);
$(markdownWrapper).prepend(markdownTb.toolbar);
var $edit = $(editDiv);

View File

@ -129,7 +129,7 @@
margin: 0;
vertical-align: middle;
}
.cp-markdown-toggle-button {
.markdown-toolbar-button-style();
position: absolute;
@ -139,12 +139,12 @@
&.cp-toolbar-button-active {
background-color: transparent;
}
}
}
#cp-kanban-edit-body {
border: 1px solid @cp_forms-border;
border-radius: @variables_radius;
overflow: hidden;
overflow: hidden;
.CodeMirror {
height: 105px;
resize: vertical;

View File

@ -202,7 +202,7 @@ define([
var markdownEditorWrapper = h('div.cp-markdown-label-row', [
h('label', { for: 'cp-kanban-edit-body' }, Messages.kanban_body)
]);
var conflicts, conflictContainer, titleInput, tagsDiv, text;
var content = h('div', [
conflictContainer = h('div#cp-kanban-edit-conflicts', [
@ -284,8 +284,9 @@ define([
editor.focus();
editor.replaceSelection($(mt)[0].outerHTML);
},
wrapper: markdownEditorWrapper
toggleBar: true
});
$(markdownEditorWrapper).append(markdownTb.toggleButton);
$(markdownTb.toolbar).on('keydown', function (e) {
if (e.which === 27) { // Escape key
e.preventDefault();

View File

@ -161,41 +161,6 @@ define([
});
APP.$linkEdit = $();
if (APP.readOnly) { return; }
var button = h('button.btn', {
title: Messages.clickToEdit
}, Messages.profile_addLink);
APP.$linkEdit = $(button);
$block.append(button);
var save = h('button.btn.btn-primary', { 'aria-labelledby': 'cp-save-link' }, Messages.settings_save);
var text = h('input#cp-save-link');
var code = h('div.cp-app-profile-link-code', [
text,
save
]);
var div = h('div.cp-app-profile-link-edit', [
code
]);
$block.append(div);
$(button).click(function () {
$(text).val(APP.$link.attr('href'));
$(code).css('display', 'flex');
APP.editor.refresh();
$(button).hide();
});
$(save).click(function () {
$(save).hide();
APP.module.execCommand('SET', {
key: 'url',
value: $(text).val()
}, function (data) {
APP.updateValues(data);
$(code).hide();
$(button).show();
$(save).show();
});
});
};
var refreshLink = function (data) {
APP.$linkEdit.removeClass('fa-pencil').removeClass('fa');
@ -413,63 +378,12 @@ define([
}
common.displayAvatar($span, val, void 0, void 0,
void 0, badge);
if (APP.readOnly) { return; }
var $delButton = $('<button>', {
'class': 'cp-app-profile-avatar-delete btn btn-danger fa fa-times',
title: Messages.profile_remove_avatar
});
$span.append($delButton);
$delButton.click(function () {
var old = common.getMetadataMgr().getUserData().avatar;
APP.module.execCommand("SET", {
key: 'avatar',
value: ""
}, function () {
sframeChan.query("Q_PROFILE_AVATAR_REMOVE", old, function (err, err2) {
if (err || err2) { return void UI.log(err || err2); }
displayAvatar(void 0, data);
});
});
});
};
var addAvatar = function ($container) {
var $block = $('<div>', {id: AVATAR_ID}).appendTo($container);
APP.$avatar = $(h('span.cp-avatar')).appendTo($block);
var sframeChan = common.getSframeChannel();
displayAvatar();
if (APP.readOnly) { return; }
var data = MT.addAvatar(common, function (ev, data) {
var old = common.getMetadataMgr().getUserData().avatar;
var todo = function () {
APP.module.execCommand("SET", {
key: 'avatar',
value: data.url
}, function (newData) {
sframeChan.query("Q_PROFILE_AVATAR_ADD", data.url, function (err, err2) {
if (err || err2) { return void UI.log(err || err2); }
displayAvatar(data.url, newData);
});
});
};
if (old) {
sframeChan.query("Q_PROFILE_AVATAR_REMOVE", old, function (err, err2) {
if (err || err2) { return void UI.log(err || err2); }
todo();
});
return;
}
todo();
});
//upload profile photo button should be secondary
var $upButton = common.createButton('upload', false, data);
$upButton.removeClass('btn-primary').addClass('btn-secondary');
$upButton.removeProp('title');
$upButton.text(Messages.profile_upload);
$upButton.prepend($('<i>', {'class': 'fa fa-upload', 'aria-hidden': 'true'}));
$block.append($upButton);
};
var refreshAvatar = function (data) {
displayAvatar(data.avatar, data);
@ -484,74 +398,6 @@ define([
}).appendTo($block);
APP.$descriptionEdit = $();
if (APP.readOnly) { return; }
var button = h('button.btn.btn-secondary', {
'aria-labelledby': 'cp-profile-add-description-button'
}, [
h('i.fa.fa-pencil', {'aria-hidden': 'true' }),
h('span#cp-profile-add-description-button', Messages.profile_addDescription)
]);
APP.$descriptionEdit = $(button);
var save = h('button.btn.btn-primary', Messages.settings_save);
var text = h('textarea');
var code = h('div.cp-app-profile-description-code', [
text,
h('br'),
save
]);
var div = h('div.cp-app-profile-description-edit', [
h('p.cp-app-profile-info', Messages.profile_info),
button,
code
]);
$block.append(div);
$(div).insertBefore(APP.$description);
var cm = SFCodeMirror.create("gfm", CodeMirror, text);
var editor = APP.editor = cm.editor;
editor.setOption('lineNumbers', true);
editor.setOption('lineWrapping', true);
editor.setOption('styleActiveLine', true);
editor.setOption('readOnly', false);
cm.configureTheme(common, function () {});
editor.setOption("extraKeys", {
"Esc": function () {
editor.getInputField().blur();
$(save).focus();
}
});
var toggleRow = h('div.cp-markdown-toggle-row');
var markdownTb = common.createMarkdownToolbar(editor, {
wrapper: toggleRow
});
$(code).prepend(markdownTb.toolbar);
$(code).prepend(toggleRow);
if(!Util.isSmallScreen()) {
$(markdownTb.toolbar).show();
}
$(button).click(function () {
$(code).show();
APP.editor.refresh();
$(button).hide();
var firstBtn = $(markdownTb.toolbar).find('button').get(0);
if (firstBtn) {
firstBtn.focus();
}
});
$(save).click(function () {
$(save).hide();
APP.module.execCommand('SET', {
key: 'description',
value: editor.getValue()
}, function (data) {
APP.updateValues(data);
$(code).hide();
$(button).show();
$(save).show();
});
});
};
var refreshDescription = function (data) {
var descriptionData = data.description || "";

View File

@ -11,6 +11,7 @@
@import (reference) '../../customize/src/less2/include/export.less';
@import (reference) '../../customize/src/less2/include/badges.less';
@import (reference) '../../customize/src/less2/include/avatar.less';
@import (reference) "../../customize/src/less2/include/markdown.less";
&.cp-app-settings {
.framework_min_main();
@ -308,7 +309,7 @@
}
}
.cp-settings-profile-description {
width: 31rem;
width: 40rem;
max-width: 100%;
.cp-labelled-input {
max-width: 100% !important;
@ -322,8 +323,9 @@
font-family: monospace;
font-size: 16px;
line-height: initial;
max-width: 31rem;
max-width: 40rem;
border: 1px solid fade(@cryptpad_text_col, 50%);
margin: 5px 0;
pre {
margin: 0;
font-family: inherit;
@ -331,7 +333,9 @@
line-height: inherit;
}
}
.cp-markdown-toggle-button {
.markdown-toolbar-button-style();
}
}
}
}

View File

@ -2102,7 +2102,6 @@ define([
cm.configureTheme(common, function () {});
editor.setOption("extraKeys", {
"Esc": function () {
cm.getInputField().blur();
$(button).focus();
}
});
@ -2120,8 +2119,20 @@ define([
});
});
const markdownTb = common.createMarkdownToolbar(editor, {
embed: function (mt) {
editor.focus();
editor.replaceSelection($(mt)[0].outerHTML);
},
toggleBar: true
});
$(input).before(markdownTb.toggleButton);
$(input).before(markdownTb.toolbar);
onProfileEvt.reg(() => {
editor.setValue(APP.profileData?.description || '');
editor.save();
editor.refresh();
});