From b5191a74573e1bb89199f7e1046bd0e1e7b50bc2 Mon Sep 17 00:00:00 2001 From: benweet Date: Sat, 19 Apr 2014 02:09:25 +0100 Subject: [PATCH] Fixed editor copy/paste --- public/res/classes/Provider.js | 7 +--- public/res/editor.js | 40 ++++++++---------- public/res/extensions/comments.js | 69 ++++++++++++++++--------------- public/res/layout.js | 18 +++++--- public/res/libs/prism-markdown.js | 6 +-- public/res/styles/main.less | 5 +-- 6 files changed, 72 insertions(+), 73 deletions(-) diff --git a/public/res/classes/Provider.js b/public/res/classes/Provider.js index f8627a3a..e84d67eb 100644 --- a/public/res/classes/Provider.js +++ b/public/res/classes/Provider.js @@ -92,8 +92,8 @@ define([ result.push([0, removeDiff[1] + addDiff[1]]); } else { - removeDiff[1] = '//' + removeDiff[1] + '//'; - addDiff[1] += '//'; + removeDiff[1] = '∕∕' + removeDiff[1] + '∕∕'; + addDiff[1] += '∕∕'; result.push(removeDiff); result.push(addDiff); } @@ -330,9 +330,6 @@ define([ if(contentChanged || discussionListChanged) { editor.watcher.noWatch(_.bind(function() { if(contentChanged) { - if(!/\n$/.test(newContent)) { - newContent += '\n'; - } if(fileMgr.currentFile === fileDesc) { editor.setValueNoWatch(newContent); editorSelection && editor.selectionMgr.setSelectionStartEnd( diff --git a/public/res/editor.js b/public/res/editor.js index 286f2a62..5abd8915 100644 --- a/public/res/editor.js +++ b/public/res/editor.js @@ -148,17 +148,6 @@ define([ if(end === undefined) { end = this.selectionEnd; } - var textContent = inputElt.textContent; - if(start === textContent.length && textContent[textContent.length -1 ] == '\n') { - start--; - range = undefined; - skipSelectionUpdate = false; - } - if(end === textContent.length && textContent[textContent.length - 1] == '\n') { - end--; - range = undefined; - skipSelectionUpdate = false; - } this.selectionStart = start; this.selectionEnd = end; var min = Math.min(start, end); @@ -223,6 +212,9 @@ define([ }; })(); this.getCoordinates = function(inputOffset, container, offset) { + if(inputOffset === textContent.length) { + return this.getCoordinates(inputOffset - 1); + } if(!container) { offset = this.findOffset(inputOffset); container = offset.container; @@ -508,15 +500,17 @@ define([ eventMgr.addListener('onDiscussionRemoved', onComment); eventMgr.addListener('onCommentsChanged', onComment); + var trailingLfNode; function checkContentChange() { var newTextContent = inputElt.textContent; + if(contentElt.lastChild === trailingLfNode && trailingLfNode.textContent.slice(-1) === '\n') { + newTextContent = newTextContent.slice(0, -1); + } + if(fileChanged === false) { - if(newTextContent == textContent) { + if(contentElt.children.length && newTextContent == textContent) { return; } - if(!/\n$/.test(newTextContent)) { - newTextContent += '\n'; - } undoMgr.currentMode = undoMgr.currentMode || 'typing'; var discussionList = _.values(fileDesc.discussionList); fileDesc.newDiscussion && discussionList.push(fileDesc.newDiscussion); @@ -533,11 +527,8 @@ define([ } else { textContent = newTextContent; - if(!/\n$/.test(textContent)) { - textContent += '\n'; - fileDesc.content = textContent; - } selectionMgr.setSelectionStartEnd(fileDesc.editorStart, fileDesc.editorEnd); + selectionMgr.saveSelectionState(); eventMgr.onFileOpen(fileDesc, textContent); previewElt.scrollTop = fileDesc.previewScrollTop; scrollTop = fileDesc.editorScrollTop; @@ -713,8 +704,10 @@ define([ actions[action](state, options); setValue(state.before + state.selection + state.after); - selectionMgr.setSelectionStartEnd(state.selectionStart, state.selectionEnd); - $inputElt.trigger('input'); + _.defer(function() { + selectionMgr.setSelectionStartEnd(state.selectionStart, state.selectionEnd); + //$inputElt.trigger('input'); + }); }; var actions = { @@ -855,7 +848,6 @@ define([ if(fileChanged === true) { contentElt.innerHTML = ''; contentElt.appendChild(newSectionEltList); - selectionMgr.setSelectionStartEnd(); } else { // Remove outdated sections @@ -880,8 +872,10 @@ define([ } childNode = nextNode; } - selectionMgr.setSelectionStartEnd(); } + trailingLfNode = document.createTextNode('\n'); + contentElt.appendChild(trailingLfNode); + selectionMgr.setSelectionStartEnd(); }); } diff --git a/public/res/extensions/comments.js b/public/res/extensions/comments.js index 305184d4..3833ae7b 100644 --- a/public/res/extensions/comments.js +++ b/public/res/extensions/comments.js @@ -39,29 +39,25 @@ define([ selectionMgr = editor.selectionMgr; }; - var offsetMap = {}; - function setCommentEltCoordinates(commentElt, y) { - var lineIndex = Math.round(y / 5); - // Try to find the nearest existing lineIndex - if(offsetMap.hasOwnProperty(lineIndex)) { - // Keep current lineIndex - } - else if(offsetMap.hasOwnProperty(lineIndex - 1)) { - lineIndex--; - } - else if(offsetMap.hasOwnProperty(lineIndex + 1)) { - lineIndex++; + var yList = []; + function setCommentEltCoordinates(commentElt, y, isNew) { + y = Math.round(y); + var yListIndex = y - 21; + // Avoid overlap of comment icons + while(yListIndex < y + 22) { + if(yList[yListIndex]) { + y = yListIndex + 22; + } + yListIndex++; } + !isNew && (yList[y] = 1); var yOffset = -8; if(commentElt.className.indexOf(' icon-split') !== -1) { yOffset = -12; } var top = y + yOffset; - var right = (offsetMap[lineIndex] || 0) * 25 + 10; - commentElt.orderedIndex = lineIndex * 10000 + right; commentElt.style.top = top + 'px'; - commentElt.style.right = right + 'px'; - return lineIndex; + commentElt.style.right = '12px'; } var inputElt; @@ -116,8 +112,10 @@ define([ someReplies = false; sortedCommentEltList = []; var author = storage['author.name']; - offsetMap = {}; - var discussionList = _.values(currentFileDesc.discussionList); + yList = []; + var discussionList = _.sortBy(currentFileDesc.discussionList, function(discussion) { + return discussion.selectionEnd; + }); function refreshOne() { var coordinates; if(discussionList.length === 0) { @@ -131,19 +129,19 @@ define([ // Move newCommentElt if(currentContext && !currentContext.discussionIndex) { coordinates = selectionMgr.getCoordinates(currentContext.getDiscussion().selectionEnd); - setCommentEltCoordinates(newCommentElt, coordinates.y); + setCommentEltCoordinates(newCommentElt, coordinates.y, true); inputElt.scrollTop += parseInt(newCommentElt.style.top) - inputElt.scrollTop - inputElt.offsetHeight * 3 / 4; movePopover(newCommentElt); } sortedCommentEltList = _.sortBy(commentEltMap, function(commentElt) { - return commentElt.orderedIndex; + return commentElt.selectionEnd; }); $openDiscussionElt.toggleClass('some', sortedCommentEltList.length !== 0); $openDiscussionElt.toggleClass('replied', someReplies); $openDiscussionIconElt.toggleClass('icon-chat', sortedCommentEltList.length !== 0); return; } - var discussion = discussionList.pop(); + var discussion = discussionList.shift(); var commentElt = commentEltMap[discussion.discussionIndex]; if(!commentElt) { commentElt = crel('a'); @@ -160,9 +158,9 @@ define([ className += isReplied ? ' replied' : ' added'; commentElt.className = className; commentElt.discussionIndex = discussion.discussionIndex; + commentElt.selectionEnd = discussion.selectionEnd; coordinates = selectionMgr.getCoordinates(discussion.selectionEnd); - var lineIndex = setCommentEltCoordinates(commentElt, coordinates.y); - offsetMap[lineIndex] = (offsetMap[lineIndex] || 0) + 1; + setCommentEltCoordinates(commentElt, coordinates.y); marginElt.appendChild(commentElt); commentEltMap[discussion.discussionIndex] = commentElt; @@ -268,9 +266,10 @@ define([ inputElt = document.getElementById('wmd-input'); marginElt = document.querySelector('#wmd-input > .editor-margin'); marginElt.appendChild(newCommentElt); - $(document.body).append(crel('div', { + var $popoverContainer = $(crel('div', { class: 'comments-popover' - })).on('click', function(evt) { + })); + $(document.body).append($popoverContainer).on('click', function(evt) { // Close on click outside the popover if(currentContext && currentContext.$commentElt[0] !== evt.target) { closeCurrentPopover(); @@ -300,7 +299,8 @@ define([ return content; }, selector: '#wmd-input > .editor-margin > .discussion' - }).on('show.bs.popover', '#wmd-input > .editor-margin', function(evt) { + }); + $(marginElt).on('show.bs.popover', function(evt) { closeCurrentPopover(); var context = new Context(evt.target, currentFileDesc); currentContext = context; @@ -323,12 +323,12 @@ define([ }; currentFileDesc.newDiscussion = discussion; var coordinates = selectionMgr.getCoordinates(selectionStart); - setCommentEltCoordinates(newCommentElt, coordinates.y); + setCommentEltCoordinates(newCommentElt, coordinates.y, true); } context.selectionRange = selectionMgr.createRange(discussion.selectionStart, discussion.selectionEnd); inputElt.scrollTop += parseInt(evt.target.style.top) - inputElt.scrollTop - inputElt.offsetHeight * 3 / 4; - }).on('shown.bs.popover', '#wmd-input > .editor-margin', function(evt) { + }).on('shown.bs.popover', function(evt) { var context = currentContext; var popoverElt = context.getPopoverElt(); context.$authorInputElt = $(popoverElt.querySelector('.input-comment-author')).val(storage['author.name']); @@ -407,11 +407,6 @@ define([ $removeButton.hide(); } - // Prevent from closing on click inside the popover - $(popoverElt).on('click', function(evt) { - evt.stopPropagation(); - }); - // Highlight selected text context.rangyRange = rangy.createRange(); context.rangyRange.setStart(context.selectionRange.startContainer, context.selectionRange.startOffset); @@ -424,7 +419,7 @@ define([ // Focus on textarea context.$contentInputElt.focus().val(previousContent); - }).on('hide.bs.popover', '#wmd-input > .editor-margin', function() { + }).on('hide.bs.popover', function() { if(!currentContext) { return; } @@ -440,6 +435,12 @@ define([ delete currentFileDesc.newDiscussion; }); + // Prevent from closing on click inside the popover + $popoverContainer.on('click', '.popover', function(evt) { + evt.stopPropagation(); + }); + + var $newCommentElt = $(newCommentElt); $openDiscussionElt = $('.button-open-discussion').click(function(evt) { var $commentElt = $newCommentElt; diff --git a/public/res/layout.js b/public/res/layout.js index 3fb1a965..3c9e43b4 100644 --- a/public/res/layout.js +++ b/public/res/layout.js @@ -146,14 +146,16 @@ define([ var navbarInnerElt; var navbarDropdownElt; var $navbarDropdownBtnElt; - var navbarTitleElt; + var navbarTitleContainerElt; + var $navbarTitleElt; var navbarBtnGroups = []; var navbarBtnGroupsWidth = [80, 80, 160, 160, 80, 40].map(function(width) { return width + 18; // Add margin }); var navbarMarginWidth = 18 * 2 + 25 + 25; var buttonsDropdownWidth = 40; - var titleWidth = 18 + 350; + var titleMinWidth = 200; + var workingIndicatorWidth = 18 + 70; function onResize() { var editorPadding = (editor.elt.offsetWidth - getMaxWidth()) / 2; @@ -172,7 +174,8 @@ define([ previewContentElt.style.paddingRight = previewPadding + 'px'; if(!window.viewerMode) { - var maxWidth = navbarMarginWidth + titleWidth + buttonsDropdownWidth; + var maxWidth = navbarMarginWidth + workingIndicatorWidth + titleMinWidth + buttonsDropdownWidth; + var titleWidth = windowSize.width - maxWidth + titleMinWidth; navbarBtnGroups.forEach(function(group, index) { maxWidth += group.width; index === navbarBtnGroups.length - 1 && (maxWidth -= buttonsDropdownWidth); @@ -180,9 +183,13 @@ define([ navbarDropdownElt.appendChild(group.elt); } else { - navbarInnerElt.insertBefore(group.elt, navbarTitleElt); + navbarInnerElt.insertBefore(group.elt, navbarTitleContainerElt); + titleWidth = windowSize.width - maxWidth + titleMinWidth; } }); + $navbarTitleElt.css({ + maxWidth: titleWidth + }); $navbarDropdownBtnElt.toggleClass('hide', navbarDropdownElt.children.length === 0); } @@ -323,7 +330,8 @@ define([ navbarInnerElt = navbar.elt.querySelector('.navbar-inner'); navbarDropdownElt = navbar.elt.querySelector('.buttons-dropdown .dropdown-menu'); $navbarDropdownBtnElt = navbar.$elt.find('.buttons-dropdown'); - navbarTitleElt = navbar.elt.querySelector('.title-container'); + navbarTitleContainerElt = navbar.elt.querySelector('.title-container'); + $navbarTitleElt = navbar.$elt.find('.file-title-navbar, .input-file-title'); _.each(navbar.elt.querySelectorAll('.right-buttons'), function(btnGroupElt) { navbarBtnGroups.push({ diff --git a/public/res/libs/prism-markdown.js b/public/res/libs/prism-markdown.js index fa01fd3f..f645d3f9 100644 --- a/public/res/libs/prism-markdown.js +++ b/public/res/libs/prism-markdown.js @@ -255,7 +255,7 @@ Prism.languages.md = (function() { strong: md.strong, em: md.em, strike: md.strike, - conflict: /\/\//g, + conflict: /⧸⧸/g, comment: Prism.languages.markup.comment, tag: Prism.languages.markup.tag, entity: Prism.languages.markup.entity @@ -275,7 +275,7 @@ Prism.languages.md = (function() { fn: md.fn, link: md.link, linkref: md.linkref, - conflict: /\/\//g, + conflict: /⧸⧸/g, }; md.strong.inside.rest = rest; md.em.inside.rest = rest; @@ -286,7 +286,7 @@ Prism.languages.md = (function() { strong: md.strong, em: md.em, strike: md.strike, - conflict: /\/\//g, + conflict: /⧸⧸/g, comment: Prism.languages.markup.comment, tag: Prism.languages.markup.tag, entity: Prism.languages.markup.entity diff --git a/public/res/styles/main.less b/public/res/styles/main.less index 14309475..a0f8f7cb 100644 --- a/public/res/styles/main.less +++ b/public/res/styles/main.less @@ -50,7 +50,7 @@ @jgrowl-bg-color: fade(@modal-backdrop-bg, 90%); /* Sizes */ -@file-title-width: 280px; +@title-max-width: 400px; @menu-panel-width: 280px; @document-panel-width: 320px; @jgrowl-width: 260px; @@ -487,7 +487,6 @@ a { font-size: 1.5em; line-height: 1.4em; font-weight: 200; - max-width: @file-title-width; overflow: hidden; white-space: nowrap; } @@ -496,7 +495,7 @@ a { display: inline-block; vertical-align: middle; .input-file-title { - width: @file-title-width; + width: @title-max-width; font-size: 16px; height: @input-height-slim; }