From e70d5ce76472c661abd94ae73599e4bc391db83b Mon Sep 17 00:00:00 2001 From: iliajie Date: Thu, 15 Jun 2023 18:17:14 +0300 Subject: [PATCH] Add support for awesome replies using new HTML editor --- mailboxes/folders-lib.pl | 98 ++++++++++++++++++++++ mailboxes/reply_mail.cgi | 171 +++++++++++++++++++++++++++++++++------ 2 files changed, 245 insertions(+), 24 deletions(-) diff --git a/mailboxes/folders-lib.pl b/mailboxes/folders-lib.pl index 51c48068b..df6b8ae63 100755 --- a/mailboxes/folders-lib.pl +++ b/mailboxes/folders-lib.pl @@ -2945,6 +2945,104 @@ EOF return &trim($iframe_body); } +# iframe_quote(quote) +# Returns quoted message in an iframe HTML element +sub iframe_quote +{ +my ($quote) = @_; +return $quote if (!$quote); + +# Quote mail iframe inner styles +my $iframe_styles = + ''; +# Add inner styles to the email body +if ($quote =~ /<\/body>/) { + $quote =~ s/<\/body>/$iframe_styles<\/body>/; + } + else { + $quote .= $iframe_styles; + } +$quote = &trim("e_escape($quote, '"')); +# Email iframe stuff +my $iframe_body = < + #quote-mail-iframe { + border: none; + width: calc(100% - 12px); + } + details.iframe_quote_details summary { + display: block; + width: fit-content; + outline: none; + margin-left: 6px; + margin-bottom: 6px; + } + details.iframe_quote_details iframe { + padding-left: 6px; + padding-bottom: 6px; + } + details.iframe_quote_details summary::after { + border: 1px solid #666; + border-radius: 18px; + content: "..."; + cursor: pointer; + display: inline-block; + line-height: 0; + padding: 2px 2px 1px 9px; + width: 18px; + height: 9px; + } + details.iframe_quote_details[open] summary::after { + background-color: #d1dffc; + border: 1px solid #97abd4; + } + + + +EOF +$iframe_body = &ui_details({ + html => 1, + content => $iframe_body, + class => 'iframe_quote_details' + }); + +return &trim($iframe_body); +} + # remove_body_attachments(&mail, &attach) # Returns attachments except for those that make up the message body, and those # that have sub-attachments. diff --git a/mailboxes/reply_mail.cgi b/mailboxes/reply_mail.cgi index d52feb24e..e2225f3f7 100755 --- a/mailboxes/reply_mail.cgi +++ b/mailboxes/reply_mail.cgi @@ -442,35 +442,158 @@ if ($in{'new'}) { # Output message body input print &ui_table_start($text{'reply_body'}, "width=100%", 2, undef, &ui_links_row(\@bodylinks)); +my $html_editor_quote = &iframe_quote($quote); +my $html_editor_template; +my $html_editor_scripts; if ($html_edit) { - if ($current_theme !~ /authentic-theme/) { - # Output HTML editor textarea - print < - _editor_url = "@{[&get_webprefix()]}/$module_name/xinha/"; - _editor_lang = "en"; - - + my %tinfo = &get_theme_info($current_theme); + if (!$tinfo{'spa'}) { + $html_editor_template = < +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ $html_editor_quote + +EOF + # Output HTML editor textarea + my $ts = &get_webmin_version(); + $ts =~ s/[.-]+//g; + $html_editor_scripts = < + + + + var Parchment = Quill.import('parchment'); + // Whitelist attrs (useful on preserving) + const attrs_whitelist = [ + 'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left', + 'padding', 'padding-top', 'padding-right', 'padding-bottom', 'padding-left', + 'border', 'border-right', 'border-left', + 'font-size', 'font-family', 'href', 'target', + ] + + attrs_whitelist.forEach(function(attr) { + Quill.register(new Parchment.Attributor.Style(attr, attr, {})); + }); + + Quill.register(qs, true); + Quill.register(qf, true); + var editor = new Quill('.ql-container', { + modules: { + formula: false, + syntax: false, + imageDrop: true, + imageResize: { + modules: [ + 'DisplaySize', + 'Resize', + ], + }, + toolbar: '.ql-toolbar', + }, + bounds: '.ql-compose-container', + theme: 'snow' + }); + // Google Mail editor like keybind for quoting + var isMacOS = navigator.userAgent.toLowerCase().includes('mac'); + editor.keyboard.addBinding({ + key: '9', + shiftKey: true, + ctrlKey: !isMacOS, + metaKey: isMacOS, + format: ['blockquote'], + }, function(range, context) { + this.quill.format('blockquote', false); + }); + editor.keyboard.addBinding({ + key: '9', + shiftKey: true, + ctrlKey: !isMacOS, + metaKey: isMacOS, + }, function(range, context) { + this.quill.format('blockquote', true); + }); + editor.on('text-change', function() { + targ.value = escapeHTML_(editor.root.innerHTML + "

"); + var quoteHTML = String(), err = false; + try { + quoteHTML = document.querySelector('#quote-mail-iframe').contentWindow.document.querySelector('.iframe_quote[contenteditable]#webmin-iframe-quote').innerHTML; + } catch(e) { + err = true; + } + if (!err) { + targ.value = targ.value + escapeHTML_(quoteHTML); + } + }); + editor.pasteHTML(targ.value); + })(); + EOF } - else { - print ''; - } + $sig =~ s/\n/
\n/g, + $sig =~ s/^\s+//g + if ($sig); print &ui_table_row(undef, - &ui_textarea("body", $quote, 16, 80, undef, 0, - "style='width:99%' id=body"), 2); + &ui_textarea("body", "$sig", 16, 80, undef, 0, + "style='display: none' id=body").$html_editor_template.$html_editor_scripts, 2); } else { # Show text editing area