diff --git a/www/pad/comments.js b/www/pad/comments.js index 0a3eccf3e..b3ead0a82 100644 --- a/www/pad/comments.js +++ b/www/pad/comments.js @@ -6,44 +6,44 @@ define([ '/common/hyperscript.js', '/common/common-interface.js', '/customize/messages.js' -], function ($, Sortify, Util, Hash, h, UI, Messages) { +], function($, Sortify, Util, Hash, h, UI, Messages) { var Comments = {}; -/* -{ - authors: { - "id": { - name: "", - curvePublic: "", - avatar: "", - profile: "" - } - }, - data: { - "uid": { - m: [{ - u: id, - m: "str", // comment - t: +new Date, - v: "str", // value of the commented content - e: undefined/1, // edited - d: undefined/1, // deleted - }], - d: undefined/1, + /* + { + authors: { + "id": { + name: "", + curvePublic: "", + avatar: "", + profile: "" + } + }, + data: { + "uid": { + m: [{ + u: id, + m: "str", // comment + t: +new Date, + v: "str", // value of the commented content + e: undefined/1, // edited + d: undefined/1, // deleted + }], + d: undefined/1, + } } } -} -*/ + */ var COMMENTS = { authors: {}, data: {} }; - var canonicalize = function (t) { return t.replace(/\r\n/g, '\n'); }; + var canonicalize = function(t) { return t.replace(/\r\n/g, '\n'); }; // XXX function duplicated from www/code/markers.js - var authorUid = function (existing) { + var authorUid = function(existing) { if (!Array.isArray(existing)) { existing = []; } var n; var i = 0; @@ -54,12 +54,12 @@ define([ if (existing.indexOf(n) !== -1) { n = 0; } return n; }; - var getAuthorId = function (Env, curve) { + var getAuthorId = function(Env, curve) { var existing = Object.keys(Env.comments.authors || {}).map(Number); if (!Env.common.isLoggedIn()) { return authorUid(existing); } var uid; - existing.some(function (id) { + existing.some(function(id) { var author = Env.comments.authors[id] || {}; if (author.curvePublic !== curve) { return; } uid = Number(id); @@ -70,7 +70,7 @@ define([ // Return the author ID and add/update the data for registered users // Return the username for unregistered users - var updateAuthorData = function (Env, onChange) { + var updateAuthorData = function(Env, onChange) { var userData = Env.metadataMgr.getUserData(); if (!Env.common.isLoggedIn()) { return userData.name; @@ -89,13 +89,13 @@ define([ return myAuthorId; }; - var updateMetadata = function (Env) { + var updateMetadata = function(Env) { var md = Util.clone(Env.metadataMgr.getMetadata()); md.comments = Util.clone(Env.comments); Env.metadataMgr.updateMetadata(md); }; - var sendReplyNotification = function (Env, uid) { + var sendReplyNotification = function(Env, uid) { if (!Env.comments || !Env.comments.data || !Env.comments.authors) { return; } if (!Env.common.isLoggedIn()) { return; } var thread = Env.comments.data[uid]; @@ -104,7 +104,7 @@ define([ var privateData = Env.metadataMgr.getPrivateData(); var others = {}; // Get all the other registered users with a mailbox - thread.m.forEach(function (obj) { + thread.m.forEach(function(obj) { var u = obj.u; if (typeof(u) !== "number") { return; } var author = Env.comments.authors[u]; @@ -118,7 +118,7 @@ define([ }; }); // Send the notification - Object.keys(others).forEach(function (id) { + Object.keys(others).forEach(function(id) { var data = others[id]; Env.common.mailbox.sendTo("COMMENT_REPLY", { channel: privateData.channel, @@ -132,12 +132,12 @@ define([ }; - var cleanMentions = function ($el) { + var cleanMentions = function($el) { $el.html(''); var el = $el[0]; var allowed = ['data-profile', 'data-name', 'data-avatar', 'class']; // Remove unnecessary/unsafe attributes - for (var i=el.attributes.length-1; i>0; i--) { + for (var i = el.attributes.length - 1; i > 0; i--) { var name = el.attributes[i] && el.attributes[i].name; if (allowed.indexOf(name) === -1) { $el.removeAttr(name); @@ -146,7 +146,7 @@ define([ }; // Seletc all text of a contenteditable element - var selectAll = function (element) { + var selectAll = function(element) { var selection = window.getSelection(); var range = document.createRange(); range.selectNodeContents(element); @@ -159,7 +159,7 @@ define([ Messages.comments_submit = "Submit"; // XXX Messages.comments_reply = "Reply"; // XXX Messages.comments_resolve = "Resolve"; // XXX - var getCommentForm = function (Env, reply, _cb, editContent) { + var getCommentForm = function(Env, reply, _cb, editContent) { var cb = Util.once(_cb); var userData = Env.metadataMgr.getUserData(); var name = Util.fixHTML(userData.name || Messages.anonymous); @@ -188,12 +188,12 @@ define([ ]); // List of allowed attributes in mentions - $(submit).click(function (e) { + $(submit).click(function(e) { e.stopPropagation(); var clone = textarea.cloneNode(true); var notify = {}; var $clone = $(clone); - $clone.find('span.cp-mentions').each(function (i, el) { + $clone.find('span.cp-mentions').each(function(i, el) { var $el = $(el); var curve = $el.attr('data-curve'); var notif = $el.attr('data-notifications'); @@ -209,7 +209,7 @@ define([ // Send notification var privateData = Env.metadataMgr.getPrivateData(); var userData = Env.metadataMgr.getUserData(); - Object.keys(notify).forEach(function (curve) { + Object.keys(notify).forEach(function(curve) { if (curve === userData.curvePublic) { return; } Env.common.mailbox.sendTo("MENTION", { channel: privateData.channel, @@ -222,12 +222,12 @@ define([ // Push the content cb(content); }); - $(cancel).click(function (e) { + $(cancel).click(function(e) { e.stopPropagation(); cb(); }); - var $text = $(textarea).keydown(function (e) { + var $text = $(textarea).keydown(function(e) { e.stopPropagation(); if (e.which === 27) { $(cancel).click(); @@ -243,14 +243,14 @@ define([ e.stopImmediatePropagation(); e.preventDefault(); } - }).click(function (e) { + }).click(function(e) { e.stopPropagation(); }); if (Env.common.isLoggedIn()) { var authors = {}; - Object.keys((Env.comments && Env.comments.authors) || {}).forEach(function (id) { + Object.keys((Env.comments && Env.comments.authors) ||  {}).forEach(function(id) { var obj = Util.clone(Env.comments.authors[id]); authors[obj.curvePublic] = obj; }); @@ -273,14 +273,14 @@ define([ h('i.fa.fa-times'), Messages.kanban_delete ]); - $(deleteButton).click(function (e) { + $(deleteButton).click(function(e) { e.stopPropagation(); cb(false); }); } - setTimeout(function () { + setTimeout(function() { $(textarea).focus(); selectAll(textarea); }); @@ -300,13 +300,13 @@ define([ ]); }; - var isVisible = function (el, $container) { + var isVisible = function(el, $container) { var size = $container.outerHeight(); var pos = el.getBoundingClientRect(); return (pos.bottom < size) && (pos.y > 0); }; - var redrawComments = function (Env) { + var redrawComments = function(Env) { // Don't redraw if there were no change var str = Sortify(Env.comments || {}); if (str === Env.oldComments) { return; } @@ -347,15 +347,15 @@ define([ var userData = Env.metadataMgr.getUserData(); // Get all the comment threads in their order in the pad - var threads = Env.$inner.find('comment').map(function (i, el) { + var threads = Env.$inner.find('comment').map(function(i, el) { return el.getAttribute('data-uid'); }).toArray(); // Draw all comment threads - Util.deduplicateString(threads).forEach(function (key) { + Util.deduplicateString(threads).forEach(function(key) { // Get thread data var obj = Env.comments.data[key]; - if (!obj || obj.d || !Array.isArray(obj.m) || !obj.m.length) { + if (!obj || obj.d ||  !Array.isArray(obj.m) ||  !obj.m.length) { return; } @@ -367,23 +367,22 @@ define([ var $actions; // Draw all messages for this thread - (obj.m || []).forEach(function (msg, i) { + (obj.m || []).forEach(function(msg, i) { var replyCls = i === 0 ? '' : '.cp-comment-reply'; if (msg.d) { - content.push(h('div.cp-comment.cp-comment-deleted'+replyCls, - Messages.comments_deleted)); + content.push(h('div.cp-comment.cp-comment-deleted' + replyCls, + Messages.comments_deleted)); return; } var author = typeof(msg.u) === "number" ? - ((Env.comments.authors || {})[msg.u] || {}) : - { name: msg.u }; + ((Env.comments.authors || {})[msg.u] || {}) : { name: msg.u }; var name = Util.fixHTML(author.name || Messages.anonymous); 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) { + $(avatar).click(function(e) { Env.common.openURL(Hash.hashToHref(author.profile, 'profile')); e.stopPropagation(); }); @@ -394,7 +393,7 @@ define([ m.innerHTML = msg.m; var $m = $(m); $m.find('> *:not(span.cp-mentions)').remove(); - $m.find('span.cp-mentions').each(function (i, el) { + $m.find('span.cp-mentions').each(function(i, el) { var $el = $(el); var name = $el.attr('data-name'); var avatarUrl = $el.attr('data-avatar'); @@ -412,11 +411,11 @@ define([ ]); if (profile) { $el.attr('tabindex', 1); - $el.addClass('cp-mentions-clickable').click(function (e) { + $el.addClass('cp-mentions-clickable').click(function(e) { e.preventDefault(); e.stopPropagation(); Env.common.openURL(Hash.hashToHref(profile, 'profile')); - }).focus(function (e) { + }).focus(function(e) { e.stopPropagation(); }); } @@ -432,18 +431,18 @@ define([ // Add edit button when applicable (last message of the thread, written by ourselves) var edit; - if (i === (obj.m.length -1) && author.curvePublic === userData.curvePublic) { + if (i === (obj.m.length - 1) && author.curvePublic === userData.curvePublic) { edit = h('span.cp-comment-edit', { - tabindex:1, + tabindex: 1, title: Messages.clickToEdit }, h('i.fa.fa-pencil')); - $(edit).click(function (e) { + $(edit).click(function(e) { Env.$container.find('.cp-comment-active').removeClass('cp-comment-active'); $div.addClass('cp-comment-active'); e.stopPropagation(); Env.$container.find('.cp-comment-form').remove(); if ($actions) { $actions.hide(); } - var form = getCommentForm(Env, key, function (val) { + var form = getCommentForm(Env, key, function(val) { // Show the "reply" and "resolve" buttons again $(form).closest('.cp-comment-container') .find('.cp-comment-actions').css('display', ''); @@ -460,7 +459,7 @@ define([ msg.d = 1; if (container) { $(container).addClass('cp-comment-deleted') - .html(Messages.comments_deleted); + .html(Messages.comments_deleted); } if (obj.m.length === 1) { delete Env.comments.data[key]; @@ -481,7 +480,7 @@ define([ } // Add the comment - content.push(container = h('div.cp-comment'+replyCls, [ + content.push(container = h('div.cp-comment' + replyCls, [ h('div.cp-comment-header', [ avatar, h('span.cp-comment-metadata', [ @@ -523,10 +522,10 @@ define([ }, content)); $div = $(div); - $(reply).click(function (e) { + $(reply).click(function(e) { e.stopPropagation(); $actions.hide(); - var form = getCommentForm(Env, key, function (val) { + var form = getCommentForm(Env, key, function(val) { // Show the "reply" and "resolve" buttons again $(form).closest('.cp-comment-container') .find('.cp-comment-actions').css('display', ''); @@ -537,8 +536,8 @@ define([ if (!obj || !Array.isArray(obj.m)) { return; } // Get the value of the commented text - var res = Env.$inner.find('comment[data-uid="'+key+'"]').toArray(); - var value = res.map(function (el) { + var res = Env.$inner.find('comment[data-uid="' + key + '"]').toArray(); + var value = res.map(function(el) { return el.innerText; }).join('\n'); @@ -562,7 +561,7 @@ define([ $div.append(form); // Make sure the submit button is visible: scroll by the height of the form - setTimeout(function () { + setTimeout(function() { var yContainer = Env.$container[0].getBoundingClientRect().bottom; var yActions = form.getBoundingClientRect().bottom; if (yActions > yContainer) { @@ -573,7 +572,7 @@ define([ UI.confirmButton(resolve, { classes: 'btn-danger' - }, function () { + }, function() { // Delete the comment delete Env.comments.data[key]; @@ -582,11 +581,11 @@ define([ Env.framework.localChange(); }); - var focusContent = function () { + var focusContent = function() { // Add class "active" Env.$inner.find('comment.active').removeClass('active'); - Env.$inner.find('comment[data-uid="'+key+'"]').addClass('active'); - var $last = Env.$inner.find('comment[data-uid="'+key+'"]').last(); + Env.$inner.find('comment[data-uid="' + key + '"]').addClass('active'); + var $last = Env.$inner.find('comment[data-uid="' + key + '"]').last(); // Scroll into view if (!$last.length) { return; } @@ -594,7 +593,7 @@ define([ if (!visible) { $last[0].scrollIntoView(); } }; - $div.on('click focus', function (e) { + $div.on('click focus', function(e) { // Prevent the click event to propagate if we're already selected // The propagation to #cp-app-pad-inner would trigger the "unselect" handler e.stopPropagation(); @@ -621,7 +620,7 @@ define([ // Restore selection if (oldRangeObj) { - setTimeout(function () { + setTimeout(function() { if (!oldRangeObj) { return; } var range = document.createRange(); range.setStart(oldRangeObj.start, oldRangeObj.startO); @@ -639,7 +638,7 @@ define([ } }; - var onChange = function (Env) { + var onChange = function(Env) { var md = Util.clone(Env.metadataMgr.getMetadata()); Env.comments = md.comments; var changed = false; @@ -649,7 +648,7 @@ define([ } if (Env.ready === 0) { Env.ready = true; - updateAuthorData(Env, function () { + updateAuthorData(Env, function() { changed = true; }); // On ready, if our user data have changed or if we've added the initial structure @@ -661,7 +660,7 @@ define([ } else if (Env.ready) { // Everytime there is a metadata change, check if our user data have changed // and push the updates if necessary - updateAuthorData(Env, function () { + updateAuthorData(Env, function() { updateMetadata(Env); Env.framework.localChange(); }); @@ -670,7 +669,7 @@ define([ }; // Check if comments have been deleted from the document but not from metadata - var checkDeleted = function (Env) { + var checkDeleted = function(Env) { if (!Env.comments || !Env.comments.data) { return; } // Don't recheck if there were no change @@ -679,7 +678,7 @@ define([ Env.oldCheck = str; // If there is no comment stored in the metadata, abort - var comments = Object.keys(Env.comments.data || {}).filter(function (id) { + var comments = Object.keys(Env.comments.data || {}).filter(function(id) { return !Env.comments.data[id].d; }); @@ -687,7 +686,7 @@ define([ // Get the comments from the document var toUncomment = {}; - var uids = Env.$inner.find('comment').map(function (i, el) { + var uids = Env.$inner.find('comment').map(function(i, el) { var id = el.getAttribute('data-uid'); // Empty comment: remove from dom if (!el.innerHTML && el.parentElement) { @@ -713,13 +712,13 @@ define([ }).toArray(); if (Object.keys(toUncomment).length) { - Object.keys(toUncomment).forEach(function (id) { + Object.keys(toUncomment).forEach(function(id) { Env.editor.plugins.comments.uncomment(id, toUncomment[id]); }); } // Check if a comment has been deleted - comments.forEach(function (uid) { + comments.forEach(function(uid) { if (uids.indexOf(uid) !== -1) { return; } // comment has been deleted var data = Env.comments.data[uid]; @@ -734,19 +733,19 @@ define([ } }; - var removeCommentBubble = function (Env) { + var removeCommentBubble = function(Env) { Env.bubble = undefined; Env.$contentContainer.find('.cp-comment-bubble').remove(); }; - var updateBubble = function (Env) { + 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'); + Env.bubble.button.setAttribute('style', 'top:' + pos.y + 'px'); }; - var addCommentBubble = function (Env) { + var addCommentBubble = function(Env) { var ranges = Env.editor.getSelectedRanges(); if (!ranges.length) { return; } var el = ranges[0].endContainer || ranges[0].startContainer; @@ -760,14 +759,14 @@ define([ var y = pos.y; if (y < 0 || y > Env.$inner.outerHeight()) { return; } var button = h('button.btn.btn-secondary', { - style: 'top:'+y+'px;', + style: 'top:' + y + 'px;', title: Messages.comments_comment - },h('i.fa.fa-comment')); + }, h('i.fa.fa-comment')); Env.bubble = { node: node, button: button }; - $(button).click(function (e) { + $(button).click(function(e)  { e.stopPropagation(); Env.editor.execCommand('comment'); Env.bubble = undefined; @@ -775,8 +774,8 @@ define([ Env.$contentContainer.append(h('div.cp-comment-bubble', button)); }; - var addAddCommentHandler = function (Env) { - Env.editor.plugins.comments.addComment = function (uid, addMark) { + var addAddCommentHandler = function(Env) { + Env.editor.plugins.comments.addComment = function(uid, addMark) { if (!Env.ready) { return; } if (!Env.comments) { Env.comments = Util.clone(COMMENTS); } @@ -786,14 +785,14 @@ define([ // Abort if our selection contains a comment console.error("Can't add a comment here"); // XXX show error - UI.warn(Messages.error); + UI.warn(Messages.comments_error); return; } // Remove active class on other comments Env.$container.find('.cp-comment-active').removeClass('cp-comment-active'); Env.$container.find('.cp-comment-form').remove(); - var form = getCommentForm(Env, false, function (val) { + var form = getCommentForm(Env, false, function(val) { $(form).remove(); Env.$inner.focus(); @@ -833,10 +832,10 @@ define([ }; - Env.$iframe.on('scroll', function () { + Env.$iframe.on('scroll', function() { updateBubble(Env); }); - $(Env.ifrWindow.document).on('selectionchange', function () { + $(Env.ifrWindow.document).on('selectionchange', function() { removeCommentBubble(Env); var applicable = Env.editor.plugins.comments.isApplicable(); if (!applicable) { return; } @@ -844,14 +843,14 @@ define([ }); }; - var onContentUpdate = function (Env) { + var onContentUpdate = function(Env) { if (!Env.ready) { return; } // Check deleted onChange(Env); checkDeleted(Env); }; - var ready = function (Env) { + var ready = function(Env) { Env.ready = 0; // If you're the only edit user online, clear "deleted" comments @@ -862,7 +861,7 @@ define([ // Clear data var data = (Env.comments && Env.comments.data) || {}; - Object.keys(data).forEach(function (uid) { + Object.keys(data).forEach(function(uid) { if (data[uid].d) { delete data[uid]; } }); @@ -871,12 +870,12 @@ define([ Env.framework.localChange(); }; - Comments.create = function (cfg) { + Comments.create = function(cfg) { var Env = cfg; Env.comments = Util.clone(COMMENTS); var ro = cfg.framework.isReadOnly(); - var onEditableChange = function (unlocked) { + var onEditableChange = function(unlocked) { Env.$container.removeClass('cp-comments-readonly'); if (ro || !unlocked) { Env.$container.addClass('cp-comments-readonly'); @@ -888,7 +887,7 @@ define([ addAddCommentHandler(Env); // Unselect comment when clicking outside - $(window).click(function (e) { + $(window).click(function(e) { var $target = $(e.target); if (!$target.length) { return; } if ($target.is('.cp-comment-container')) { return; } @@ -903,21 +902,21 @@ define([ Env.$container.find('.cp-comment-form').remove(); }); // Unselect comment when clicking on another part of the doc - Env.$inner.on('click', function (e) { + Env.$inner.on('click', function(e) { if ($(e.target).closest('comment').length) { return; } Env.$container.find('.cp-comment-active').removeClass('cp-comment-active'); Env.$inner.find('comment.active').removeClass('active'); Env.$container.find('.cp-comment-form').remove(); }); - Env.$inner.on('click', 'comment', function (e) { + Env.$inner.on('click', 'comment', function(e) { var $comment = $(e.target); var uid = $comment.attr('data-uid'); if (!uid) { return; } - Env.$container.find('.cp-comment-container[data-uid="'+uid+'"]').click(); + Env.$container.find('.cp-comment-container[data-uid="' + uid + '"]').click(); }); - var call = function (f) { - return function () { + var call = function(f) { + return function() { try { [].unshift.call(arguments, Env); return f.apply(null, arguments); @@ -936,4 +935,4 @@ define([ }; return Comments; -}); +}); \ No newline at end of file