2014-03-22 01:57:31 +00:00
|
|
|
define([
|
|
|
|
"jquery",
|
|
|
|
"underscore",
|
|
|
|
"utils",
|
2014-03-24 00:22:46 +00:00
|
|
|
"storage",
|
2014-03-22 01:57:31 +00:00
|
|
|
"crel",
|
|
|
|
"rangy",
|
|
|
|
"classes/Extension",
|
|
|
|
"text!html/commentsPopoverContent.html",
|
|
|
|
"bootstrap"
|
2014-03-24 00:22:46 +00:00
|
|
|
], function($, _, utils, storage, crel, rangy, Extension, commentsPopoverContentHTML) {
|
2014-03-22 01:57:31 +00:00
|
|
|
|
|
|
|
var comments = new Extension("comments", 'Comments');
|
|
|
|
|
2014-03-24 00:22:46 +00:00
|
|
|
var commentTmpl = [
|
2014-03-31 00:10:28 +00:00
|
|
|
'<div class="comment-block<%= reply ? \' reply\' : \'\' %>">',
|
|
|
|
' <div class="comment-author"><i class="icon-comment"></i> <%= author %></div>',
|
2014-03-24 00:22:46 +00:00
|
|
|
' <div class="comment-content"><%= content %></div>',
|
|
|
|
'</div>',
|
|
|
|
].join('');
|
2014-03-25 00:23:42 +00:00
|
|
|
var popoverTitleTmpl = [
|
|
|
|
'<span class="clearfix">',
|
2014-04-02 23:35:07 +00:00
|
|
|
' <a href="#" class="action-remove-discussion pull-right">',
|
2014-03-25 00:23:42 +00:00
|
|
|
' <i class="icon-trash"></i>',
|
|
|
|
' </a>',
|
2014-03-31 00:10:28 +00:00
|
|
|
' “<%- title %>”',
|
2014-03-25 00:23:42 +00:00
|
|
|
'</span>',
|
|
|
|
].join('');
|
2014-03-24 00:22:46 +00:00
|
|
|
|
|
|
|
var eventMgr;
|
|
|
|
comments.onEventMgrCreated = function(eventMgrParam) {
|
|
|
|
eventMgr = eventMgrParam;
|
|
|
|
};
|
|
|
|
|
2014-03-22 01:57:31 +00:00
|
|
|
var offsetMap = {};
|
2014-03-23 02:33:41 +00:00
|
|
|
function setCommentEltCoordinates(commentElt, y) {
|
2014-03-24 00:22:46 +00:00
|
|
|
var lineIndex = Math.round(y / 10);
|
2014-03-31 00:10:28 +00:00
|
|
|
var yOffset = -10;
|
2014-04-02 23:35:07 +00:00
|
|
|
if(commentElt.className.indexOf(' icon-split') !== -1) {
|
2014-03-30 01:44:51 +00:00
|
|
|
yOffset = -12;
|
|
|
|
}
|
|
|
|
var top = (y + yOffset) + 'px';
|
2014-03-23 02:33:41 +00:00
|
|
|
var right = ((offsetMap[lineIndex] || 0) * 25 + 10) + 'px';
|
|
|
|
commentElt.style.top = top;
|
|
|
|
commentElt.style.right = right;
|
|
|
|
return lineIndex;
|
|
|
|
}
|
2014-03-22 01:57:31 +00:00
|
|
|
|
|
|
|
var inputElt;
|
|
|
|
var marginElt;
|
|
|
|
var newCommentElt = crel('a', {
|
2014-03-31 00:10:28 +00:00
|
|
|
class: 'discussion icon-quote-left new'
|
2014-03-22 01:57:31 +00:00
|
|
|
});
|
2014-03-23 02:33:41 +00:00
|
|
|
var cursorY;
|
|
|
|
comments.onCursorCoordinates = function(x, y) {
|
|
|
|
cursorY = y;
|
|
|
|
setCommentEltCoordinates(newCommentElt, cursorY);
|
2014-03-22 01:57:31 +00:00
|
|
|
};
|
|
|
|
|
2014-03-31 00:10:28 +00:00
|
|
|
function Context(commentElt, fileDesc) {
|
|
|
|
this.commentElt = commentElt;
|
|
|
|
this.$commentElt = $(commentElt).addClass('active');
|
|
|
|
this.fileDesc = fileDesc;
|
|
|
|
this.discussionIndex = commentElt.discussionIndex;
|
|
|
|
}
|
|
|
|
Context.prototype.getDiscussion = function() {
|
|
|
|
if(!this.discussionIndex) {
|
|
|
|
return this.fileDesc.newDiscussion;
|
|
|
|
}
|
|
|
|
return this.fileDesc.discussionList[this.discussionIndex];
|
|
|
|
};
|
|
|
|
Context.prototype.getPopoverElt = function() {
|
|
|
|
return document.querySelector('.comments-popover .popover:last-child');
|
|
|
|
};
|
2014-03-27 00:20:08 +00:00
|
|
|
var currentContext;
|
|
|
|
function movePopover(commentElt) {
|
|
|
|
// Move popover in the margin
|
2014-03-31 00:10:28 +00:00
|
|
|
var popoverElt = currentContext.getPopoverElt();
|
2014-03-27 00:20:08 +00:00
|
|
|
var left = 0;
|
2014-03-31 00:10:28 +00:00
|
|
|
if(popoverElt.offsetWidth < marginElt.offsetWidth - 10) {
|
|
|
|
left = marginElt.offsetWidth - 10 - popoverElt.offsetWidth;
|
2014-03-27 00:20:08 +00:00
|
|
|
}
|
2014-03-31 00:10:28 +00:00
|
|
|
popoverElt.style.left = left + 'px';
|
|
|
|
popoverElt.querySelector('.arrow').style.left = (marginElt.offsetWidth - parseInt(commentElt.style.right) - commentElt.offsetWidth / 2 - left) + 'px';
|
2014-03-27 00:20:08 +00:00
|
|
|
}
|
|
|
|
|
2014-03-26 00:29:34 +00:00
|
|
|
var cssApplier;
|
2014-03-24 00:22:46 +00:00
|
|
|
var currentFileDesc;
|
2014-03-30 01:44:51 +00:00
|
|
|
var refreshTimeoutId;
|
2014-03-31 00:10:28 +00:00
|
|
|
var commentEltMap = {};
|
2014-03-27 00:20:08 +00:00
|
|
|
var refreshDiscussions = _.debounce(function() {
|
2014-03-24 00:22:46 +00:00
|
|
|
if(currentFileDesc === undefined) {
|
|
|
|
return;
|
|
|
|
}
|
2014-03-26 00:29:34 +00:00
|
|
|
|
2014-03-24 00:22:46 +00:00
|
|
|
var author = storage['author.name'];
|
2014-03-23 02:33:41 +00:00
|
|
|
offsetMap = {};
|
2014-03-30 01:44:51 +00:00
|
|
|
var discussionList = _.values(currentFileDesc.discussionList);
|
|
|
|
function refreshOne() {
|
|
|
|
if(discussionList.length === 0) {
|
2014-03-31 00:10:28 +00:00
|
|
|
// Remove outdated commentElt
|
|
|
|
_.filter(commentEltMap, function(commentElt, discussionIndex) {
|
|
|
|
return !_.has(currentFileDesc.discussionList, discussionIndex);
|
|
|
|
}).forEach(function(commentElt) {
|
|
|
|
marginElt.removeChild(commentElt);
|
2014-04-02 23:35:07 +00:00
|
|
|
delete commentEltMap[commentElt.discussionIndex];
|
2014-03-31 00:10:28 +00:00
|
|
|
});
|
2014-03-30 01:44:51 +00:00
|
|
|
// Move newCommentElt
|
|
|
|
setCommentEltCoordinates(newCommentElt, cursorY);
|
2014-03-31 00:10:28 +00:00
|
|
|
if(currentContext && !currentContext.discussionIndex) {
|
2014-03-30 01:44:51 +00:00
|
|
|
inputElt.scrollTop += parseInt(newCommentElt.style.top) - inputElt.scrollTop - inputElt.offsetHeight * 3 / 4;
|
|
|
|
movePopover(newCommentElt);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var discussion = discussionList.pop();
|
2014-03-23 02:33:41 +00:00
|
|
|
var commentElt = crel('a', {
|
2014-03-30 01:44:51 +00:00
|
|
|
class: 'discussion'
|
2014-03-23 02:33:41 +00:00
|
|
|
});
|
2014-04-02 23:35:07 +00:00
|
|
|
var isReplied = !discussion.commentList || _.last(discussion.commentList).author != author;
|
|
|
|
commentElt.className += ' icon-quote-left' + (isReplied ? ' replied' : ' added');
|
2014-03-30 01:44:51 +00:00
|
|
|
if(discussion.type == 'conflict') {
|
2014-04-02 23:35:07 +00:00
|
|
|
commentElt.className += ' icon-split';
|
2014-03-30 01:44:51 +00:00
|
|
|
}
|
2014-03-27 00:20:08 +00:00
|
|
|
commentElt.discussionIndex = discussion.discussionIndex;
|
2014-03-23 02:33:41 +00:00
|
|
|
var coordinates = inputElt.getOffsetCoordinates(discussion.selectionEnd);
|
|
|
|
var lineIndex = setCommentEltCoordinates(commentElt, coordinates.y);
|
|
|
|
offsetMap[lineIndex] = (offsetMap[lineIndex] || 0) + 1;
|
2014-03-31 00:10:28 +00:00
|
|
|
|
|
|
|
var oldCommentElt = commentEltMap[discussion.discussionIndex];
|
|
|
|
oldCommentElt && marginElt.removeChild(oldCommentElt);
|
2014-03-23 02:33:41 +00:00
|
|
|
marginElt.appendChild(commentElt);
|
2014-03-31 00:10:28 +00:00
|
|
|
commentEltMap[discussion.discussionIndex] = commentElt;
|
2014-03-23 02:33:41 +00:00
|
|
|
|
2014-03-31 00:10:28 +00:00
|
|
|
if(currentContext && currentContext.getDiscussion() == discussion) {
|
2014-03-27 00:20:08 +00:00
|
|
|
inputElt.scrollTop += parseInt(commentElt.style.top) - inputElt.scrollTop - inputElt.offsetHeight * 3 / 4;
|
|
|
|
movePopover(commentElt);
|
|
|
|
}
|
2014-03-30 01:44:51 +00:00
|
|
|
refreshTimeoutId = setTimeout(refreshOne, 5);
|
2014-03-23 02:33:41 +00:00
|
|
|
}
|
2014-03-30 01:44:51 +00:00
|
|
|
clearTimeout(refreshTimeoutId);
|
|
|
|
refreshTimeoutId = setTimeout(refreshOne, 5);
|
2014-03-27 00:20:08 +00:00
|
|
|
}, 50);
|
2014-03-24 00:22:46 +00:00
|
|
|
|
|
|
|
comments.onFileOpen = function(fileDesc) {
|
|
|
|
currentFileDesc = fileDesc;
|
|
|
|
refreshDiscussions();
|
|
|
|
};
|
|
|
|
|
2014-03-28 00:49:49 +00:00
|
|
|
comments.onContentChanged = function(fileDesc) {
|
2014-03-27 00:20:08 +00:00
|
|
|
currentFileDesc === fileDesc && refreshDiscussions();
|
2014-03-24 00:22:46 +00:00
|
|
|
};
|
|
|
|
|
2014-03-26 00:29:34 +00:00
|
|
|
comments.onCommentsChanged = function(fileDesc) {
|
2014-03-27 00:20:08 +00:00
|
|
|
if(currentFileDesc !== fileDesc) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(currentContext !== undefined) {
|
|
|
|
// Refresh conversation if popover is open
|
|
|
|
var context = currentContext;
|
2014-03-31 00:10:28 +00:00
|
|
|
if(context.discussionIndex) {
|
2014-03-27 00:20:08 +00:00
|
|
|
context.popoverElt.querySelector('.discussion-comment-list').innerHTML = getDiscussionComments();
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
cssApplier.undoToRange(context.rangyRange);
|
|
|
|
}
|
|
|
|
catch(e) {}
|
2014-03-31 00:10:28 +00:00
|
|
|
var discussion = context.getDiscussion();
|
|
|
|
context.selectionRange = inputElt.createRange(discussion.selectionStart, discussion.selectionEnd);
|
2014-03-27 00:20:08 +00:00
|
|
|
|
|
|
|
// Highlight selected text
|
|
|
|
context.rangyRange = rangy.createRange();
|
|
|
|
context.rangyRange.setStart(context.selectionRange.startContainer, context.selectionRange.startOffset);
|
|
|
|
context.rangyRange.setEnd(context.selectionRange.endContainer, context.selectionRange.endOffset);
|
|
|
|
setTimeout(function() { // Need to delay this because it's not refreshed properly
|
|
|
|
if(currentContext === context) {
|
|
|
|
cssApplier.applyToRange(context.rangyRange);
|
|
|
|
}
|
|
|
|
}, 50);
|
|
|
|
}
|
|
|
|
refreshDiscussions();
|
2014-03-26 00:29:34 +00:00
|
|
|
};
|
|
|
|
|
2014-03-24 00:22:46 +00:00
|
|
|
function closeCurrentPopover() {
|
|
|
|
currentContext && currentContext.$commentElt.popover('toggle').popover('destroy');
|
|
|
|
}
|
2014-03-27 00:20:08 +00:00
|
|
|
|
|
|
|
comments.onDiscussionCreated = function(fileDesc) {
|
|
|
|
currentFileDesc === fileDesc && refreshDiscussions();
|
|
|
|
};
|
|
|
|
|
|
|
|
comments.onDiscussionRemoved = function(fileDesc, discussion) {
|
|
|
|
if(currentFileDesc === fileDesc) {
|
2014-03-30 01:44:51 +00:00
|
|
|
// Close popover if the discussion has been removed
|
2014-03-31 00:10:28 +00:00
|
|
|
if(currentContext !== undefined && currentContext.discussionIndex == discussion.discussionIndex) {
|
2014-03-27 00:20:08 +00:00
|
|
|
closeCurrentPopover();
|
|
|
|
}
|
|
|
|
refreshDiscussions();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-03-24 00:22:46 +00:00
|
|
|
comments.onLayoutResize = function() {
|
|
|
|
refreshDiscussions();
|
|
|
|
};
|
|
|
|
|
|
|
|
function getDiscussionComments() {
|
2014-03-31 00:10:28 +00:00
|
|
|
var discussion = currentContext.getDiscussion();
|
|
|
|
var author = storage['author.name'];
|
2014-04-02 23:35:07 +00:00
|
|
|
var result = [];
|
|
|
|
if(discussion.commentList) {
|
|
|
|
result = discussion.commentList.map(function(comment) {
|
|
|
|
var commentAuthor = comment.author || 'Anonymous';
|
|
|
|
return _.template(commentTmpl, {
|
|
|
|
author: commentAuthor,
|
|
|
|
content: comment.content,
|
|
|
|
reply: comment.author != author
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
2014-03-31 00:10:28 +00:00
|
|
|
if(discussion.type == 'conflict') {
|
2014-04-02 23:35:07 +00:00
|
|
|
result.unshift(_.template(commentTmpl, {
|
|
|
|
author: 'StackEdit',
|
|
|
|
content: 'Multiple users have made conflicting modifications that you have to review.',
|
|
|
|
reply: true
|
|
|
|
}));
|
2014-03-30 01:44:51 +00:00
|
|
|
}
|
2014-04-02 23:35:07 +00:00
|
|
|
return result.join('');
|
2014-03-24 00:22:46 +00:00
|
|
|
}
|
2014-03-23 02:33:41 +00:00
|
|
|
|
2014-03-22 01:57:31 +00:00
|
|
|
comments.onReady = function() {
|
2014-03-26 00:29:34 +00:00
|
|
|
cssApplier = rangy.createCssClassApplier("comment-highlight", {
|
2014-03-22 01:57:31 +00:00
|
|
|
normalize: false
|
|
|
|
});
|
2014-03-24 00:22:46 +00:00
|
|
|
var previousContent = '';
|
2014-03-22 01:57:31 +00:00
|
|
|
|
|
|
|
inputElt = document.getElementById('wmd-input');
|
|
|
|
marginElt = document.querySelector('#wmd-input > .editor-margin');
|
|
|
|
marginElt.appendChild(newCommentElt);
|
2014-03-23 02:33:41 +00:00
|
|
|
$(document.body).append(crel('div', {
|
|
|
|
class: 'comments-popover'
|
2014-03-24 00:22:46 +00:00
|
|
|
})).on('click', function(evt) {
|
|
|
|
// Close on click outside the popover
|
|
|
|
if(currentContext && currentContext.$commentElt[0] !== evt.target) {
|
|
|
|
closeCurrentPopover();
|
|
|
|
}
|
|
|
|
}).popover({
|
2014-03-22 01:57:31 +00:00
|
|
|
placement: 'auto top',
|
|
|
|
container: '.comments-popover',
|
|
|
|
html: true,
|
|
|
|
title: function() {
|
2014-03-24 00:22:46 +00:00
|
|
|
if(!currentContext) {
|
|
|
|
return true;
|
2014-03-22 01:57:31 +00:00
|
|
|
}
|
2014-03-31 00:10:28 +00:00
|
|
|
var discussion = currentContext.getDiscussion();
|
|
|
|
var titleLength = discussion.selectionEnd - discussion.selectionStart;
|
|
|
|
var title = inputElt.textContent.substr(discussion.selectionStart, titleLength > 20 ? 20 : titleLength);
|
2014-03-23 02:33:41 +00:00
|
|
|
if(titleLength > 20) {
|
2014-03-22 01:57:31 +00:00
|
|
|
title += '...';
|
|
|
|
}
|
2014-03-25 00:23:42 +00:00
|
|
|
return _.template(popoverTitleTmpl, {
|
2014-03-30 01:44:51 +00:00
|
|
|
title: title,
|
2014-03-25 00:23:42 +00:00
|
|
|
});
|
2014-03-22 01:57:31 +00:00
|
|
|
},
|
|
|
|
content: function() {
|
|
|
|
var content = _.template(commentsPopoverContentHTML, {
|
2014-03-30 01:44:51 +00:00
|
|
|
commentList: getDiscussionComments(),
|
2014-03-22 01:57:31 +00:00
|
|
|
});
|
|
|
|
return content;
|
|
|
|
},
|
2014-03-30 01:44:51 +00:00
|
|
|
selector: '#wmd-input > .editor-margin > .discussion'
|
2014-03-22 01:57:31 +00:00
|
|
|
}).on('show.bs.popover', '#wmd-input > .editor-margin', function(evt) {
|
2014-03-24 00:22:46 +00:00
|
|
|
closeCurrentPopover();
|
2014-03-31 00:10:28 +00:00
|
|
|
var context = new Context(evt.target, currentFileDesc);
|
2014-03-24 00:22:46 +00:00
|
|
|
currentContext = context;
|
2014-03-23 02:33:41 +00:00
|
|
|
inputElt.scrollTop += parseInt(evt.target.style.top) - inputElt.scrollTop - inputElt.offsetHeight * 3 / 4;
|
|
|
|
|
|
|
|
// If it's an existing discussion
|
2014-03-31 00:10:28 +00:00
|
|
|
var discussion = context.getDiscussion();
|
|
|
|
if(discussion) {
|
|
|
|
context.selectionRange = inputElt.createRange(discussion.selectionStart, discussion.selectionEnd);
|
|
|
|
inputElt.setSelectionStartEnd(discussion.selectionStart, discussion.selectionEnd, false);
|
2014-03-23 02:33:41 +00:00
|
|
|
return;
|
|
|
|
}
|
2014-03-22 01:57:31 +00:00
|
|
|
|
|
|
|
// Get selected text
|
2014-03-24 00:22:46 +00:00
|
|
|
var selectionStart = inputElt.selectionStart;
|
|
|
|
var selectionEnd = inputElt.selectionEnd;
|
2014-03-22 01:57:31 +00:00
|
|
|
if(selectionStart === selectionEnd) {
|
|
|
|
var after = inputElt.textContent.substring(selectionStart);
|
|
|
|
var match = /\S+/.exec(after);
|
|
|
|
if(match) {
|
|
|
|
selectionStart += match.index;
|
|
|
|
if(match.index === 0) {
|
2014-03-23 02:33:41 +00:00
|
|
|
while(selectionStart && /\S/.test(inputElt.textContent[selectionStart - 1])) {
|
2014-03-22 01:57:31 +00:00
|
|
|
selectionStart--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
selectionEnd += match.index + match[0].length;
|
|
|
|
}
|
|
|
|
}
|
2014-03-24 00:22:46 +00:00
|
|
|
context.selectionRange = inputElt.createRange(selectionStart, selectionEnd);
|
2014-03-31 00:10:28 +00:00
|
|
|
currentFileDesc.newDiscussion = {
|
2014-03-22 01:57:31 +00:00
|
|
|
selectionStart: selectionStart,
|
|
|
|
selectionEnd: selectionEnd,
|
2014-03-23 02:33:41 +00:00
|
|
|
commentList: []
|
2014-03-22 01:57:31 +00:00
|
|
|
};
|
|
|
|
}).on('shown.bs.popover', '#wmd-input > .editor-margin', function(evt) {
|
2014-03-24 00:22:46 +00:00
|
|
|
var context = currentContext;
|
2014-03-31 00:10:28 +00:00
|
|
|
movePopover(context.commentElt);
|
|
|
|
var popoverElt = context.getPopoverElt();
|
2014-03-22 01:57:31 +00:00
|
|
|
|
2014-03-24 00:22:46 +00:00
|
|
|
// Scroll to the bottom of the discussion
|
2014-03-31 00:10:28 +00:00
|
|
|
popoverElt.querySelector('.popover-content').scrollTop = 9999999;
|
2014-03-24 00:22:46 +00:00
|
|
|
|
2014-03-31 00:10:28 +00:00
|
|
|
context.$authorInputElt = $(popoverElt.querySelector('.input-comment-author')).val(storage['author.name']);
|
|
|
|
context.$contentInputElt = $(popoverElt.querySelector('.input-comment-content'));
|
|
|
|
var $addButton = $(popoverElt.querySelector('.action-add-comment'));
|
|
|
|
$().add(context.$contentInputElt).add(context.$authorInputElt).keydown(function(evt) {
|
2014-03-23 02:33:41 +00:00
|
|
|
// Enter key
|
|
|
|
switch(evt.which) {
|
|
|
|
case 13:
|
|
|
|
evt.preventDefault();
|
|
|
|
$addButton.click();
|
|
|
|
return;
|
|
|
|
case 27:
|
|
|
|
evt.preventDefault();
|
2014-03-24 00:22:46 +00:00
|
|
|
closeCurrentPopover();
|
2014-03-23 02:33:41 +00:00
|
|
|
inputElt.focus();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
$addButton.click(function(evt) {
|
2014-03-24 00:22:46 +00:00
|
|
|
var author = utils.getInputTextValue(context.$authorInputElt);
|
|
|
|
var content = utils.getInputTextValue(context.$contentInputElt, evt);
|
2014-03-22 01:57:31 +00:00
|
|
|
if(evt.isPropagationStopped()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-03-31 00:10:28 +00:00
|
|
|
var discussion = context.getDiscussion();
|
2014-03-24 00:22:46 +00:00
|
|
|
context.$contentInputElt.val('');
|
|
|
|
closeCurrentPopover();
|
|
|
|
|
2014-04-02 23:35:07 +00:00
|
|
|
discussion.commentList = discussion.commentList || [];
|
2014-03-31 00:10:28 +00:00
|
|
|
discussion.commentList.push({
|
2014-03-27 00:20:08 +00:00
|
|
|
author: author,
|
|
|
|
content: content
|
|
|
|
});
|
2014-03-25 00:23:42 +00:00
|
|
|
var discussionList = context.fileDesc.discussionList || {};
|
2014-03-31 00:10:28 +00:00
|
|
|
if(!discussion.discussionIndex) {
|
2014-03-23 02:33:41 +00:00
|
|
|
// Create discussion index
|
|
|
|
var discussionIndex;
|
2014-03-22 01:57:31 +00:00
|
|
|
do {
|
2014-03-30 01:44:51 +00:00
|
|
|
discussionIndex = utils.randomString() + utils.randomString(); // Increased size to prevent collision
|
2014-03-23 02:33:41 +00:00
|
|
|
} while(_.has(discussionList, discussionIndex));
|
2014-03-31 00:10:28 +00:00
|
|
|
discussion.discussionIndex = discussionIndex;
|
|
|
|
discussionList[discussionIndex] = discussion;
|
2014-03-27 00:20:08 +00:00
|
|
|
context.fileDesc.discussionList = discussionList; // Write discussionList in localStorage
|
2014-03-31 00:10:28 +00:00
|
|
|
eventMgr.onDiscussionCreated(context.fileDesc, discussion);
|
2014-03-27 00:20:08 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
context.fileDesc.discussionList = discussionList; // Write discussionList in localStorage
|
|
|
|
eventMgr.onCommentsChanged(context.fileDesc);
|
2014-03-22 01:57:31 +00:00
|
|
|
}
|
2014-03-23 02:33:41 +00:00
|
|
|
inputElt.focus();
|
2014-03-22 01:57:31 +00:00
|
|
|
});
|
|
|
|
|
2014-03-31 00:10:28 +00:00
|
|
|
var $removeButton = $(popoverElt.querySelector('.action-remove-discussion'));
|
2014-03-27 00:20:08 +00:00
|
|
|
if(evt.target.discussionIndex) {
|
2014-03-24 00:22:46 +00:00
|
|
|
// If it's an existing discussion
|
2014-03-31 00:10:28 +00:00
|
|
|
var $removeCancelButton = $(popoverElt.querySelectorAll('.action-remove-discussion-cancel'));
|
|
|
|
var $removeConfirmButton = $(popoverElt.querySelectorAll('.action-remove-discussion-confirm'));
|
2014-03-24 00:22:46 +00:00
|
|
|
$removeButton.click(function() {
|
2014-03-31 00:10:28 +00:00
|
|
|
$(popoverElt.querySelector('.new-comment-block')).addClass('hide');
|
|
|
|
$(popoverElt.querySelector('.remove-discussion-confirm')).removeClass('hide');
|
|
|
|
popoverElt.querySelector('.popover-content').scrollTop = 9999999;
|
2014-03-24 00:22:46 +00:00
|
|
|
});
|
|
|
|
$removeCancelButton.click(function() {
|
2014-03-31 00:10:28 +00:00
|
|
|
$(popoverElt.querySelector('.new-comment-block')).removeClass('hide');
|
|
|
|
$(popoverElt.querySelector('.remove-discussion-confirm')).addClass('hide');
|
|
|
|
popoverElt.querySelector('.popover-content').scrollTop = 9999999;
|
2014-03-24 00:22:46 +00:00
|
|
|
context.$contentInputElt.focus();
|
|
|
|
});
|
|
|
|
$removeConfirmButton.click(function() {
|
|
|
|
closeCurrentPopover();
|
2014-03-31 00:10:28 +00:00
|
|
|
var discussion = context.getDiscussion();
|
|
|
|
delete context.fileDesc.discussionList[discussion.discussionIndex];
|
2014-03-25 00:23:42 +00:00
|
|
|
context.fileDesc.discussionList = context.fileDesc.discussionList; // Write discussionList in localStorage
|
2014-03-31 00:10:28 +00:00
|
|
|
eventMgr.onDiscussionRemoved(context.fileDesc, discussion);
|
2014-03-24 00:22:46 +00:00
|
|
|
inputElt.focus();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Otherwise hide the remove button
|
|
|
|
$removeButton.hide();
|
|
|
|
}
|
|
|
|
|
2014-03-22 01:57:31 +00:00
|
|
|
// Prevent from closing on click inside the popover
|
2014-03-31 00:10:28 +00:00
|
|
|
$(popoverElt).on('click', function(evt) {
|
2014-03-22 01:57:31 +00:00
|
|
|
evt.stopPropagation();
|
|
|
|
});
|
2014-03-24 00:22:46 +00:00
|
|
|
|
|
|
|
// Highlight selected text
|
|
|
|
context.rangyRange = rangy.createRange();
|
|
|
|
context.rangyRange.setStart(context.selectionRange.startContainer, context.selectionRange.startOffset);
|
|
|
|
context.rangyRange.setEnd(context.selectionRange.endContainer, context.selectionRange.endOffset);
|
|
|
|
setTimeout(function() { // Need to delay this because it's not refreshed properly
|
|
|
|
if(currentContext === context) {
|
|
|
|
cssApplier.applyToRange(context.rangyRange);
|
|
|
|
}
|
|
|
|
}, 50);
|
|
|
|
|
|
|
|
// Focus on textarea
|
|
|
|
context.$contentInputElt.focus().val(previousContent);
|
2014-03-28 00:49:49 +00:00
|
|
|
}).on('hide.bs.popover', '#wmd-input > .editor-margin', function() {
|
2014-03-24 00:22:46 +00:00
|
|
|
if(!currentContext) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
currentContext.$commentElt.removeClass('active');
|
|
|
|
|
|
|
|
// Save content and author for later
|
|
|
|
previousContent = currentContext.$contentInputElt.val();
|
|
|
|
storage['author.name'] = currentContext.$authorInputElt.val();
|
2014-03-22 01:57:31 +00:00
|
|
|
|
|
|
|
// Remove highlight
|
2014-03-24 00:22:46 +00:00
|
|
|
cssApplier.undoToRange(currentContext.rangyRange);
|
|
|
|
currentContext = undefined;
|
2014-03-26 00:29:34 +00:00
|
|
|
delete currentFileDesc.newDiscussion;
|
2014-03-22 01:57:31 +00:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
return comments;
|
|
|
|
});
|