Dan Brown

Added basic markdown scroll syncing

...@@ -265,17 +265,48 @@ module.exports = function (ngApp, events) { ...@@ -265,17 +265,48 @@ module.exports = function (ngApp, events) {
265 link: function (scope, element, attrs) { 265 link: function (scope, element, attrs) {
266 266
267 // Elements 267 // Elements
268 - var input = element.find('textarea[markdown-input]'); 268 + const input = element.find('textarea[markdown-input]');
269 - var insertImage = element.find('button[data-action="insertImage"]'); 269 + const display = element.find('.markdown-display').first();
270 + const insertImage = element.find('button[data-action="insertImage"]');
270 271
271 - var currentCaretPos = 0; 272 + let currentCaretPos = 0;
272 273
273 - input.blur((event) => { 274 + input.blur(event => {
274 currentCaretPos = input[0].selectionStart; 275 currentCaretPos = input[0].selectionStart;
275 }); 276 });
276 277
278 + // Scroll sync
279 + let inputScrollHeight,
280 + inputHeight,
281 + displayScrollHeight,
282 + displayHeight;
283 +
284 + function setScrollHeights() {
285 + inputScrollHeight = input[0].scrollHeight;
286 + inputHeight = input.height();
287 + displayScrollHeight = display[0].scrollHeight;
288 + displayHeight = display.height();
289 + }
290 +
291 + setTimeout(() => {
292 + setScrollHeights();
293 + }, 200);
294 + window.addEventListener('resize', setScrollHeights);
295 + let scrollDebounceTime = 800;
296 + let lastScroll = 0;
297 + input.on('scroll', event => {
298 + let now = Date.now();
299 + if (now - lastScroll > scrollDebounceTime) {
300 + setScrollHeights()
301 + }
302 + let scrollPercent = (input.scrollTop() / (inputScrollHeight-inputHeight));
303 + let displayScrollY = (displayScrollHeight - displayHeight) * scrollPercent;
304 + display.scrollTop(displayScrollY);
305 + lastScroll = now;
306 + });
307 +
277 // Insert image shortcut 308 // Insert image shortcut
278 - input.keydown((event) => { 309 + input.keydown(event => {
279 if (event.which === 73 && event.ctrlKey && event.shiftKey) { 310 if (event.which === 73 && event.ctrlKey && event.shiftKey) {
280 event.preventDefault(); 311 event.preventDefault();
281 var caretPos = input[0].selectionStart; 312 var caretPos = input[0].selectionStart;
...@@ -289,8 +320,8 @@ module.exports = function (ngApp, events) { ...@@ -289,8 +320,8 @@ module.exports = function (ngApp, events) {
289 }); 320 });
290 321
291 // Insert image from image manager 322 // Insert image from image manager
292 - insertImage.click((event) => { 323 + insertImage.click(event => {
293 - window.ImageManager.showExternal((image) => { 324 + window.ImageManager.showExternal(image => {
294 var caretPos = currentCaretPos; 325 var caretPos = currentCaretPos;
295 var currentContent = input.val(); 326 var currentContent = input.val();
296 var mdImageText = "![" + image.name + "](" + image.url + ")"; 327 var mdImageText = "![" + image.name + "](" + image.url + ")";
......
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
61 <button class="text-button" type="button" data-action="insertImage"><i class="zmdi zmdi-image"></i>Insert Image</button> 61 <button class="text-button" type="button" data-action="insertImage"><i class="zmdi zmdi-image"></i>Insert Image</button>
62 </div> 62 </div>
63 </div> 63 </div>
64 - <textarea markdown-input md-change="editorChange" md-model="editContent" name="markdown" rows="5" 64 + <textarea markdown-input md-change="editorChange" id="markdown-editor-input" md-model="editContent" name="markdown" rows="5"
65 @if($errors->has('markdown')) class="neg" @endif>@if(isset($model) || old('markdown')){{htmlspecialchars( old('markdown') ? old('markdown') : ($model->markdown === '' ? $model->html : $model->markdown))}}@endif</textarea> 65 @if($errors->has('markdown')) class="neg" @endif>@if(isset($model) || old('markdown')){{htmlspecialchars( old('markdown') ? old('markdown') : ($model->markdown === '' ? $model->html : $model->markdown))}}@endif</textarea>
66 </div> 66 </div>
67 67
......