From 66b74b0a688b2b51ab08b919e06a6624cee39ac3 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 24 Apr 2020 17:53:33 +0200 Subject: [PATCH] Inline button to add comments --- www/pad/app-pad.less | 23 ++++++++++++-- www/pad/comment.js | 25 +++++++-------- www/pad/comments.js | 73 ++++++++++++++++++++++++++++++++++++++++---- www/pad/inner.js | 2 ++ www/pad/links.js | 1 - 5 files changed, 102 insertions(+), 22 deletions(-) diff --git a/www/pad/app-pad.less b/www/pad/app-pad.less index 507ae0739..1be1d61ce 100644 --- a/www/pad/app-pad.less +++ b/www/pad/app-pad.less @@ -1,5 +1,6 @@ @import (reference) "../../customize/src/less2/include/framework.less"; @import (reference) "../../customize/src/less2/include/comments.less"; +@import (reference) "../../customize/src/less2/include/buttons.less"; body.cp-app-pad { .framework_main( @@ -36,9 +37,6 @@ body.cp-app-pad { align-items: center; padding: 4px; } - .cke_button__comment_label { - display: inline !important; - } } .cke_wysiwyg_frame { width: 100%; @@ -70,14 +68,33 @@ body.cp-app-pad { iframe { flex: 1; min-width: 0; + order: 1; + } + div.cp-comment-bubble { + .buttons_main(); + position: relative; + order: 2; + button { + .fa { + margin: 0 !important; + } + right: 20px; + position: absolute; + } } #cp-app-pad-comments { + order: 3; width: 300px; //background-color: white; margin: 30px; .comments_main(); } &.cke_body_width { + div.cp-comment-bubble { + button { + right: 0px; + } + } iframe { margin: 0 30px; max-width: 800px; diff --git a/www/pad/comment.js b/www/pad/comment.js index 9d91a5a72..0f54ff8ac 100644 --- a/www/pad/comment.js +++ b/www/pad/comment.js @@ -35,21 +35,24 @@ } ], childRule: isUnstylable }; + var removeStyle = new CKEDITOR.style(styleDef, { 'uid': '' }); + + var isApplicable = editor.plugins.comments.isApplicable = function (path, sel) { + path = path || editor.elementPath(); + sel = sel || editor.getSelection(); + var applicable = removeStyle.checkApplicable(path, editor); + var hasComments = editor.getSelectedHtml().$.querySelectorAll('comment').length; + var isComment = removeStyle.checkActive(path, editor); + var empty = !sel.getSelectedText(); + return applicable && !empty && !hasComments && !isComment; + }; // Register the command. - var removeStyle = new CKEDITOR.style(styleDef, { 'uid': '' }); editor.addCommand('comment', { exec: function (editor) { if (editor.readOnly) { return; } editor.focus(); - // If we're inside another comment, abort - var isComment = removeStyle.checkActive(editor.elementPath(), editor); - if (isComment) { return; } - - // We can't comment on empty text! - if (!editor.getSelection().getSelectedText()) { console.warn('there');return; } - var uid = CKEDITOR.tools.getUniqueId(); editor.plugins.comments.addComment(uid, function () { // Make an undo spnashot @@ -91,7 +94,6 @@ range.setStart(node, 0); range.setEnd(node, Number.MAX_SAFE_INTEGER); // Remove style for the comment - console.log(range); try { style.removeFromRange(range, editor); } catch (e) { @@ -158,9 +160,8 @@ }); */ editor.contextMenu.addListener(function (element, sel, path) { - var applicable = removeStyle.checkApplicable(path, editor); - var empty = !sel.getSelectedText(); - if (!applicable || empty) { return; } + var applicable = isApplicable(path, sel); + if (!applicable) { return; } return { comment: CKEDITOR.TRISTATE_OFF, }; diff --git a/www/pad/comments.js b/www/pad/comments.js index 514c1aae7..233bb3a13 100644 --- a/www/pad/comments.js +++ b/www/pad/comments.js @@ -2,10 +2,11 @@ define([ 'jquery', 'json.sortify', '/common/common-util.js', + '/common/common-hash.js', '/common/hyperscript.js', '/common/common-interface.js', '/customize/messages.js' -], function ($, Sortify, Util, h, UI, Messages) { +], function ($, Sortify, Util, Hash, h, UI, Messages) { var Comments = {}; /* @@ -188,6 +189,12 @@ define([ var date = new Date(msg.t); var avatar = h('span.cp-avatar'); Env.common.displayAvatar($(avatar), author.avatar, name); + if (author.profile) { + $(avatar).click(function (e) { + Env.common.openURL(Hash.hashToHref(author.profile, 'profile')); + e.stopPropagation(); + }); + } content.push(h('div.cp-comment'+(i === 0 ? '' : '.cp-comment-reply'), [ h('div.cp-comment-header', [ @@ -400,17 +407,58 @@ define([ } }; + var removeCommentBubble = function (Env) { + Env.bubble = undefined; + Env.$contentContainer.find('.cp-comment-bubble').remove(); + }; + var updateBubble = function (Env) { + if (!Env.bubble) { return; } + var pos = Env.bubble.node.getBoundingClientRect(); + if (pos.y < 0 || pos.y > Env.$inner.outerHeight()) { + //removeCommentBubble(Env); + } + Env.bubble.button.setAttribute('style', 'top:'+pos.y+'px'); + }; + var addCommentBubble = function (Env) { + var ranges = Env.editor.getSelectedRanges(); + if (!ranges.length) { return; } + var el = ranges[0].endContainer || ranges[0].startContainer; + var node = el && el.$; + if (!node) { return; } + if (node.nodeType === Node.TEXT_NODE) { + node = node.parentNode; + if (!node) { return; } + } + var pos = node.getBoundingClientRect(); + var y = pos.y; + if (y < 0 || y > Env.$inner.outerHeight()) { return; } + var button = h('button.btn.btn-secondary', { + style: 'top:'+y+'px;', + title: Messages.comments_comment + },h('i.fa.fa-comment')); + Env.bubble = { + node: node, + button: button + }; + $(button).click(function () { + Env.editor.execCommand('comment'); + Env.bubble = undefined; + }); + Env.$contentContainer.append(h('div.cp-comment-bubble', button)); + }; + var addAddCommentHandler = function (Env) { Env.editor.plugins.comments.addComment = function (uid, addMark) { + if (!Env.ready) { return; } if (!Env.comments) { Env.comments = Util.clone(COMMENTS); } // Get all comments ID contained within the selection - var sel = Env.editor.getSelectedHtml().$.querySelectorAll('comment'); - if (sel.length) { + var applicable = Env.editor.plugins.comments.isApplicable(); + if (!applicable) { // Abort if our selection contains a comment - console.error("Your selection contains a comment"); - UI.warn(Messages.error); + console.error("Can't add a comment here"); // XXX show error + UI.warn(Messages.error); return; } @@ -420,10 +468,12 @@ define([ Env.$inner.focus(); if (!val) { return; } - if (!Env.editor.getSelection().getSelectedText()) { + var applicable = Env.editor.plugins.comments.isApplicable(); + if (!applicable) { // text has been deleted by another user while we were typing our comment? return void UI.warn(Messages.error); } + // Don't override existing data if (Env.comments.data[uid]) { return; } @@ -451,6 +501,17 @@ define([ }); Env.$container.prepend(form).show(); }; + + + Env.$iframe.on('scroll', function () { + updateBubble(Env); + }); + $(Env.ifrWindow.document).on('selectionchange', function () { + removeCommentBubble(Env); + var applicable = Env.editor.plugins.comments.isApplicable(); + if (!applicable) { return; } + addCommentBubble(Env); + }); }; var onContentUpdate = function (Env) { diff --git a/www/pad/inner.js b/www/pad/inner.js index c52e51264..2a6840dca 100644 --- a/www/pad/inner.js +++ b/www/pad/inner.js @@ -507,7 +507,9 @@ define([ common: common, editor: editor, ifrWindow: ifrWindow, + $iframe: $iframe, $inner: $inner, + $contentContainer: $contentContainer, $container: $('#cp-app-pad-comments') }); diff --git a/www/pad/links.js b/www/pad/links.js index 15fc4df66..6445de68b 100644 --- a/www/pad/links.js +++ b/www/pad/links.js @@ -54,7 +54,6 @@ define([ var inner = editor.document.$.body; var $inner = $(inner); - console.log($inner, inner); // Bubble to open the link in a new tab $inner.click(function (e) { removeClickedLink($inner);