From 400d416e3cf7a9aeec87e40f6c834f5e319e6379 Mon Sep 17 00:00:00 2001 From: benweet Date: Tue, 18 Mar 2014 01:10:22 +0000 Subject: [PATCH] Fixes for new pre editor --- public/res/classes/FileDescriptor.js | 19 ++ public/res/core.js | 65 ++--- public/res/{preEditor.js => editor.js} | 337 ++++++++++++++--------- public/res/extensions/buttonFocusMode.js | 59 ++-- public/res/extensions/scrollLink.js | 2 +- public/res/helpers/googleHelper.js | 5 + public/res/libs/Markdown.Editor.light.js | 11 +- public/res/main.js | 4 + public/res/styles/main.less | 3 +- 9 files changed, 310 insertions(+), 195 deletions(-) rename public/res/{preEditor.js => editor.js} (65%) diff --git a/public/res/classes/FileDescriptor.js b/public/res/classes/FileDescriptor.js index ce0a1e89..63f74bce 100644 --- a/public/res/classes/FileDescriptor.js +++ b/public/res/classes/FileDescriptor.js @@ -22,6 +22,7 @@ define([ return new Range(0, 0, 0, 0); } })(); + this._editorStart = parseInt(storage[fileIndex + ".editorEnd"]) || 0; this._editorEnd = parseInt(storage[fileIndex + ".editorEnd"]) || 0; this._previewScrollTop = parseInt(storage[fileIndex + ".previewScrollTop"]) || 0; this._selectTime = parseInt(storage[fileIndex + ".selectTime"]) || 0; @@ -53,6 +54,24 @@ define([ storage[this.fileIndex + ".editorScrollTop"] = editorScrollTop; } }); + Object.defineProperty(this, 'editorStart', { + get: function() { + return this._editorStart; + }, + set: function(editorStart) { + this._editorStart = editorStart; + storage[this.fileIndex + ".editorStart"] = editorStart; + } + }); + Object.defineProperty(this, 'editorEnd', { + get: function() { + return this._editorEnd; + }, + set: function(editorEnd) { + this._editorEnd = editorEnd; + storage[this.fileIndex + ".editorEnd"] = editorEnd; + } + }); Object.defineProperty(this, 'editorSelectRange', { get: function() { return this._editorSelectRange; diff --git a/public/res/core.js b/public/res/core.js index 8b7e8eb1..34a853a1 100644 --- a/public/res/core.js +++ b/public/res/core.js @@ -4,7 +4,7 @@ define([ "underscore", "crel", "ace", - "preEditor", + "editor", "constants", "utils", "storage", @@ -26,7 +26,7 @@ define([ 'ace/ext/spellcheck', 'ace/ext/searchbox' -], function($, _, crel, ace, preEditor, constants, utils, storage, settings, eventMgr, shortcutMgr, mousetrap, bodyIndexHTML, bodyViewerHTML, settingsTemplateTooltipHTML, settingsUserCustomExtensionTooltipHTML) { +], function($, _, crel, ace, editor, constants, utils, storage, settings, eventMgr, shortcutMgr, mousetrap, bodyIndexHTML, bodyViewerHTML, settingsTemplateTooltipHTML, settingsUserCustomExtensionTooltipHTML) { var core = {}; @@ -385,12 +385,12 @@ define([ } }, onresize_end: function(paneName) { - if(preEditor.$contentElt !== undefined && paneName == 'center') { + if(editor.$contentElt !== undefined && paneName == 'center') { var padding = ($editorElt.width() - getMaxWidth()) / 2; if(padding < constants.EDITOR_DEFAULT_PADDING) { padding = constants.EDITOR_DEFAULT_PADDING; } - preEditor.$contentElt.css({ + editor.$contentElt.css({ 'padding-left': padding + 'px', 'padding-right': padding + 'px' }); @@ -494,7 +494,7 @@ define([ } // Create the PageDown editor - var editor; + var pagedownEditor; var $editorElt; var fileDesc; var documentContent; @@ -512,38 +512,21 @@ define([ aceEditor.getSession().setUndoManager(new UndoManager()); } else { - $editorElt.val(initDocumentContent); + //$editorElt.val(initDocumentContent); } - if(editor !== undefined) { + if(pagedownEditor !== undefined) { // If the editor is already created + $editorElt.val(initDocumentContent); aceEditor && aceEditor.selection.setSelectionRange(fileDesc.editorSelectRange); aceEditor ? aceEditor.focus() : $editorElt.focus(); - editor.refreshPreview(); + //pagedownEditor.refreshPreview(); return; } var $previewContainerElt = $(".preview-container"); - if(window.lightMode) { - // Store editor scrollTop on scroll event - $editorElt.scroll(function() { - if(documentContent !== undefined) { - preEditor.scrollTop = this.scrollTop; - fileDesc.editorScrollTop = preEditor.scrollTop; - } - }); - // Store editor selection on change - $editorElt.bind("keyup mouseup", function() { - preEditor.selectionStart = this.selectionStart; - preEditor.selectionEnd = this.selectionEnd; - if(documentContent !== undefined) { - fileDesc.editorStart = this.selectionStart; - fileDesc.editorEnd = this.selectionEnd; - } - }); - } - else { + if(!window.lightMode) { // Store editor scrollTop on scroll event var saveScroll = _.debounce(function() { if(documentContent !== undefined) { @@ -582,7 +565,7 @@ define([ converter.setOptions(options); function checkDocumentChanges() { - var newDocumentContent = $editorElt.val(); + var newDocumentContent = $editorElt.text(); if(aceEditor !== undefined) { newDocumentContent = aceEditor.getValue(); } @@ -601,7 +584,6 @@ define([ $editorElt.scrollTop(fileDesc.editorScrollTop); } else { - preEditor.scrollTop = fileDesc.editorScrollTop; _.defer(function() { aceEditor.renderer.scrollToY(fileDesc.editorScrollTop); }); @@ -614,22 +596,22 @@ define([ var previewWrapper; if(window.lightMode) { - editor = new Markdown.EditorLight(converter); + pagedownEditor = new Markdown.EditorLight(converter); } else { - editor = new Markdown.Editor(converter, undefined, { + pagedownEditor = new Markdown.Editor(converter, undefined, { keyStrokes: shortcutMgr.getPagedownKeyStrokes() }); } // Custom insert link dialog - editor.hooks.set("insertLinkDialog", function(callback) { + pagedownEditor.hooks.set("insertLinkDialog", function(callback) { core.insertLinkCallback = callback; utils.resetModalInputs(); $(".modal-insert-link").modal(); return true; }); // Custom insert image dialog - editor.hooks.set("insertImageDialog", function(callback) { + pagedownEditor.hooks.set("insertImageDialog", function(callback) { core.insertLinkCallback = callback; if(core.catchModal) { return true; @@ -658,15 +640,16 @@ define([ }; } - eventMgr.onPagedownConfigure(editor); - editor.hooks.chain("onPreviewRefresh", eventMgr.onAsyncPreview); + eventMgr.onPagedownConfigure(pagedownEditor); + pagedownEditor.hooks.chain("onPreviewRefresh", eventMgr.onAsyncPreview); if(window.lightMode) { - editor.run(previewWrapper); - editor.undoManager.reinit(initDocumentContent, fileDesc.editorStart, fileDesc.editorEnd, fileDesc.editorScrollTop); + pagedownEditor.run(); + $editorElt.val(initDocumentContent); + pagedownEditor.undoManager.reinit(initDocumentContent, fileDesc.editorStart, fileDesc.editorEnd, fileDesc.editorScrollTop); $editorElt.focus(); } else { - editor.run(aceEditor, previewWrapper); + pagedownEditor.run(aceEditor, previewWrapper); aceEditor.selection.setSelectionRange(fileDesc.editorSelectRange); aceEditor.focus(); } @@ -847,13 +830,13 @@ define([ if(window.lightMode) { // In pre mode, we replace ACE with an editable pre $('#wmd-input').replaceWith(function() { - var result = $('
').addClass(this.className).addClass('form-control');
-                preEditor.init(result[0]);
-                return result;
+                return $('
').addClass(this.className).addClass('form-control');
             });
             
             // Create UI layout after textarea
             createLayout();
+            
+            editor.init(document.querySelector('#wmd-input'), document.querySelector('.preview-container'));
         }
         else {
             // Create UI layout before ACE editor
diff --git a/public/res/preEditor.js b/public/res/editor.js
similarity index 65%
rename from public/res/preEditor.js
rename to public/res/editor.js
index 033b9921..5871c438 100644
--- a/public/res/preEditor.js
+++ b/public/res/editor.js
@@ -2,11 +2,12 @@
 define([
     'jquery',
     'underscore',
+    'settings',
     'eventMgr',
     'prism-core',
     'crel',
     'libs/prism-markdown'
-], function ($, _, eventMgr, Prism, crel) {
+], function ($, _, settings, eventMgr, Prism, crel) {
     
     String.prototype.splice = function (i, remove, add) {
         remove = +remove || 0;
@@ -14,52 +15,118 @@ define([
         return this.slice(0, i) + add + this.slice(i + remove);
     };
 
-    var preEditor = {};
-
-    var undoManager;
-    eventMgr.addListener('onPagedownConfigure', function(pagedownEditor) {
-        // Undo manager does exist at the moment
-        setTimeout(function () {
-            undoManager = pagedownEditor.undoManager;
-        }, 0);
+    var editor = {};
+    var selectionStart = 0;
+    var selectionEnd = 0;
+    var scrollTop = 0;
+    var inputElt;
+    var previewElt;
+    var pagedownEditor;
+    var refreshPreviewLater = (function() {
+        var elapsedTime = 0;
+        var refreshPreview = function() {
+            var startTime = Date.now();
+            pagedownEditor.refreshPreview();
+            elapsedTime = Date.now() - startTime;
+        };
+        if(settings.lazyRendering === true) {
+            return _.debounce(refreshPreview, 500);
+        }
+        return function() {
+            setTimeout(refreshPreview, elapsedTime < 2000 ? elapsedTime : 2000);
+        };
+    })();
+    eventMgr.addListener('onPagedownConfigure', function(editor) {
+        pagedownEditor = editor;
     });
 
     eventMgr.addListener('onSectionsCreated', function(newSectionList) {
         updateSectionList(newSectionList);
         highlightSections();
+        if(fileChanged === true) {
+            // Refresh preview synchronously
+            pagedownEditor.refreshPreview();
+        }
+        else {
+            refreshPreviewLater();
+        }
     });
 
-    var fileChanged = false;
-    eventMgr.addListener('onFileSelected', function() {
+    var fileChanged = true;
+    var fileDesc;
+    eventMgr.addListener('onFileSelected', function(selectedFileDesc) {
         fileChanged = true;
+        fileDesc = selectedFileDesc;
     });
 
-    preEditor.selectionStart = 0;
-    preEditor.selectionEnd = 0;
-    preEditor.scrollTop = 0;
-    var preElt;
-    preEditor.init = function(elt) {
-        preElt = elt;
-        preEditor.$contentElt = $('
'); - preElt.appendChild(preEditor.$contentElt[0]); - - preElt.focus = function() { - preEditor.$contentElt.focus(); - this.setSelectionRange(preEditor.selectionStart, preEditor.selectionEnd); - preElt.scrollTop = preEditor.scrollTop; + var previousTextContent; + function onInputChange() { + selectionStart = inputElt.selectionStart; + selectionEnd = inputElt.selectionEnd; + var currentTextContent = inputElt.textContent; + if(!/\n$/.test(currentTextContent)) { + currentTextContent += '\n'; + } + if(fileChanged === false) { + fileDesc.editorStart = selectionStart; + fileDesc.editorEnd = selectionEnd; + if(currentTextContent == previousTextContent) { + return; + } + fileDesc.content = currentTextContent; + eventMgr.onContentChanged(fileDesc); + } + else { + eventMgr.onFileOpen(fileDesc); + previewElt.scrollTop = fileDesc.previewScrollTop; + selectionStart = fileDesc.editorStart; + selectionEnd = fileDesc.editorEnd; + scrollTop = fileDesc.editorScrollTop; + inputElt.scrollTop = scrollTop; + fileChanged = false; + } + previousTextContent = currentTextContent; + } + + editor.init = function(elt1, elt2) { + inputElt = elt1; + previewElt = elt2; + editor.contentElt = crel('div', { + class: 'pre-content', + contenteditable: true + }); + editor.$contentElt = $(editor.contentElt); + inputElt.appendChild(editor.contentElt); + + $(inputElt).scroll(function() { + scrollTop = this.scrollTop; + if(fileChanged === false) { + fileDesc.editorScrollTop = scrollTop; + } + }).bind("keyup mouseup", onInputChange); + $(previewElt).scroll(function() { + if(fileChanged === false) { + fileDesc.previewScrollTop = previewElt.scrollTop; + } + }); + + inputElt.focus = function() { + editor.$contentElt.focus(); + this.setSelectionRange(selectionStart, selectionEnd); + inputElt.scrollTop = scrollTop; }; - preEditor.$contentElt.focus(function () { - preElt.focused = true; + editor.$contentElt.focus(function() { + inputElt.focused = true; }); - preEditor.$contentElt.blur(function () { - preElt.focused = false; + editor.$contentElt.blur(function() { + inputElt.focused = false; }); - Object.defineProperty(preElt, 'value', { + + Object.defineProperty(inputElt, 'value', { get: function () { return this.textContent; }, set: function (value) { - //return preEditor.$contentElt.text(value); var currentValue = this.textContent; // Find the first modified char @@ -71,10 +138,6 @@ define([ } startIndex++; } - if (startIndex === startIndexMax) { - return preEditor.$contentElt.text(value); - } - // Find the last modified char var endIndex = 1; var endIndexMax = Math.min(currentValue.length - startIndex, value.length - startIndex); @@ -88,12 +151,14 @@ define([ var replacementText = value.substring(startIndex, value.length - endIndex + 1); endIndex = currentValue.length - endIndex + 1; - var range = createRange(preElt, startIndex, endIndex); + var range = createRange(inputElt, startIndex, endIndex); range.deleteContents(); range.insertNode(document.createTextNode(replacementText)); + onInputChange(); } }); - Object.defineProperty(preElt, 'selectionStart', { + + Object.defineProperty(inputElt, 'selectionStart', { get: function () { var selection = window.getSelection(); @@ -123,14 +188,14 @@ define([ } }, set: function (value) { - preElt.setSelectionRange(value, preEditor.selectionEnd); + inputElt.setSelectionRange(value, selectionEnd); }, enumerable: true, configurable: true }); - Object.defineProperty(preElt, 'selectionEnd', { + Object.defineProperty(inputElt, 'selectionEnd', { get: function () { var selection = window.getSelection(); @@ -141,7 +206,7 @@ define([ } }, set: function (value) { - preElt.setSelectionRange(preEditor.selectionStart, value); + inputElt.setSelectionRange(selectionStart, value); }, enumerable: true, @@ -225,22 +290,63 @@ define([ return range; } - preElt.setSelectionRange = function (ss, se) { - preEditor.selectionStart = ss; - preEditor.selectionEnd = se; - var range = createRange(this, ss, se); + inputElt.setSelectionRange = function (ss, se) { + selectionStart = ss; + selectionEnd = se; + var range = createRange(editor.contentElt, ss, se); var selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(range); }; + editor.$contentElt.on('keydown', function (evt) { + var cmdOrCtrl = evt.metaKey || evt.ctrlKey; + + switch (evt.keyCode) { + case 9: // Tab + if (!cmdOrCtrl) { + action('indent', { + inverse: evt.shiftKey + }); + evt.preventDefault(); + } + break; + case 13: + action('newline'); + evt.preventDefault(); + break; + case 191: + if (cmdOrCtrl && !evt.altKey) { + action('comment', { + lang: this.id + }); + evt.preventDefault(); + } + break; + } + }); + + editor.$contentElt.on('paste', function () { + pagedownEditor.undoManager.setMode("paste"); + setTimeout(function() { + onInputChange(); + }, 0); + }); + + editor.$contentElt.on('cut', function () { + pagedownEditor.undoManager.setMode("cut"); + setTimeout(function() { + onInputChange(); + }, 0); + }); + var action = function (action, options) { options = options || {}; - var text = preElt.value, - ss = options.start || preEditor.selectionStart, - se = options.end || preEditor.selectionEnd, + var text = inputElt.value, + ss = options.start || selectionStart, + se = options.end || selectionEnd, state = { ss: ss, se: se, @@ -251,18 +357,18 @@ define([ actions[action](state, options); - preElt.value = state.before + state.selection + state.after; + inputElt.value = state.before + state.selection + state.after; - preElt.setSelectionRange(state.ss, state.se); + inputElt.setSelectionRange(state.ss, state.se); - preElt.dispatchEvent(new window.Event('input')); + inputElt.dispatchEvent(new window.Event('input')); }; var actions = { indent: function (state, options) { var lf = state.before.lastIndexOf('\n') + 1; - undoManager && undoManager.setMode("typing"); + pagedownEditor.undoManager.setMode("typing"); if (options.inverse) { if (/\s/.test(state.before.charAt(lf))) { @@ -295,9 +401,9 @@ define([ var lf = state.before.lastIndexOf('\n') + 1; var indent = (state.before.slice(lf).match(/^\s+/) || [''])[0]; - undoManager && undoManager.setMode("newlines"); + pagedownEditor.undoManager.setMode("newlines"); - state.before += '\n' + indent; + state.before += '\n'// + indent; state.selection = ''; @@ -315,7 +421,7 @@ define([ closeBefore = state.before.lastIndexOf(close), openAfter = state.after.indexOf(start); - undoManager && undoManager.setMode("typing"); + pagedownEditor.undoManager.setMode("typing"); if (start > -1 && end > -1 && (start > closeBefore || closeBefore === -1) && (end < openAfter || openAfter === -1)) { // Uncomment @@ -386,33 +492,6 @@ define([ } } }; - - preEditor.$contentElt.on('keydown', function (evt) { - var cmdOrCtrl = evt.metaKey || evt.ctrlKey; - - switch (evt.keyCode) { - case 9: // Tab - if (!cmdOrCtrl) { - action('indent', { - inverse: evt.shiftKey - }); - return false; - } - break; - case 13: - action('newline'); - return false; - case 191: - if (cmdOrCtrl && !evt.altKey) { - action('comment', { - lang: this.id - }); - return false; - } - - break; - } - }); }; @@ -446,7 +525,9 @@ define([ // Find modified section starting from bottom var rightIndex = -sectionList.length; _.some(sectionList.slice().reverse(), function(section, index) { - if(index >= newSectionList.length || section.text != newSectionList[newSectionList.length - index - 1].text) { + var newSectionText = newSectionList[newSectionList.length - index - 1].text; + // Check also the content of the node since new lines can be added just at the beggining + if(index >= newSectionList.length || section.text != newSectionText || section.highlightedContent.textContent != newSectionText) { rightIndex = -index; return true; } @@ -456,7 +537,7 @@ define([ // Prevent overlap rightIndex = leftIndex - sectionList.length; } - + // Create an array composed of left unmodified, modified, right // unmodified sections var leftSections = sectionList.slice(0, leftIndex); @@ -467,35 +548,51 @@ define([ sectionList = leftSections.concat(modifiedSections).concat(rightSections); } - var elapsedTime = 0; - var timeoutId; - function highlightSections() { - + function highlightSections() { + selectionStart = inputElt.selectionStart; + selectionEnd = inputElt.selectionEnd; + var newSectionEltList = document.createDocumentFragment(); + modifiedSections.forEach(function(section) { + highlight(section); + newSectionEltList.appendChild(section.highlightedContent); + }); if(fileChanged === true) { - fileChanged = false; - // Perform a synchronous transformation - preEditor.selectionStart = preElt.selectionStart; - preEditor.selectionEnd = preElt.selectionEnd; - var newSectionEltList = document.createDocumentFragment(); - modifiedSections.forEach(function(section) { - highlight(section); - newSectionEltList.appendChild(section.highlightedContent); - }); - preEditor.$contentElt.html(''); - preEditor.$contentElt[0].appendChild(newSectionEltList); - preElt.setSelectionRange(preEditor.selectionStart, preEditor.selectionEnd); - return; + editor.contentElt.innerHTML = ''; + editor.contentElt.appendChild(newSectionEltList); + inputElt.setSelectionRange(selectionStart, selectionEnd); + } + else { + // Remove outdated sections + sectionsToRemove.forEach(function(section) { + var sectionElt = document.getElementById("wmd-input-section-" + section.id); + // section can be already removed + sectionElt && editor.contentElt.removeChild(sectionElt); + }); + + if(insertBeforeSection !== undefined) { + var insertBeforeElt = document.getElementById("wmd-input-section-" + insertBeforeSection.id); + editor.contentElt.insertBefore(newSectionEltList, insertBeforeElt); + } + else { + editor.contentElt.appendChild(newSectionEltList); + } + + //var dummyTextNode = document.createTextNode('\n'); + //editor.contentElt.appendChild(dummyTextNode); + inputElt.setSelectionRange(selectionStart, selectionEnd); + + // Remove textNodes created outside sections + var childNode = editor.contentElt.firstChild; + while(childNode) { + var nextNode = childNode.nextSibling; + if(childNode.nodeType == 3) { + editor.contentElt.removeChild(childNode); + } + childNode = nextNode; + } } - - // Perform an asynchronous transformation on each modified sections - clearTimeout(timeoutId); - //timeoutId = setTimeout(asyncHighlightSections, elapsedTime); - preEditor.selectionStart = preElt.selectionStart; - preEditor.selectionEnd = preElt.selectionEnd; - Prism.highlightElement(preEditor.$contentElt[0]); - //preElt.setSelectionRange(preEditor.selectionStart, preEditor.selectionEnd); } - +/* function asyncHighlightSections() { var startTime = Date.now(); var deferredList = []; @@ -513,16 +610,10 @@ define([ }, ''); // Check that the editor has the actual value - if(preElt.textContent == text) { - preEditor.selectionStart = preElt.selectionStart; - preEditor.selectionEnd = preElt.selectionEnd; + if(inputElt.textContent == text) { + selectionStart = inputElt.selectionStart; + selectionEnd = inputElt.selectionEnd; - // Remove outdated sections - _.each(sectionsToRemove, function(section) { - var sectionElt = document.getElementById("wmd-input-section-" + section.id); - preEditor.$contentElt[0].removeChild(sectionElt); - }); - var newSectionEltList = document.createDocumentFragment(); modifiedSections.forEach(function(section) { newSectionEltList.appendChild(section.highlightedContent); @@ -530,21 +621,21 @@ define([ if(insertBeforeSection !== undefined) { var insertBeforeElt = document.getElementById("wmd-input-section-" + insertBeforeSection.id); - preEditor.$contentElt[0].insertBefore(newSectionEltList, insertBeforeElt); + editor.$contentElt[0].insertBefore(newSectionEltList, insertBeforeElt); } else { - preEditor.$contentElt[0].appendChild(newSectionEltList); + editor.$contentElt[0].appendChild(newSectionEltList); } - preElt.setSelectionRange(preEditor.selectionStart, preEditor.selectionEnd); + inputElt.setSelectionRange(selectionStart, selectionEnd); elapsedTime = Date.now() - startTime; } }); } - +*/ function highlight(section) { var text = section.text.replace(/&/g, '&').replace(/').css('display', 'inline-block'); + var coef = 0.2; + function doFocus() { + setTimeout(function() { + if(!($editorElt && $editorElt[0].focused)) { + return; + } + /* + var range = window.getSelection().getRangeAt(0); + range.insertNode($positionHelper[0]); + var parentNode = $positionHelper[0].parentNode; + */ + var editorHeight = $editorElt.height(); + var cursorMinY = coef*editorHeight; + var cursorMaxY = (1-coef)*editorHeight; + var cursorY = $editorElt.caret('offset').top - $editorElt.offset().top; + console.log($editorElt.caret('offset')); + //$positionHelper.detach(); + //parentNode.normalize(); + /* + if(cursorY < cursorMinY) { + $editorElt.scrollTop($editorElt.scrollTop() - cursorMinY + cursorY); + } + else if(cursorY > cursorMaxY) { + $editorElt.scrollTop($editorElt.scrollTop() + cursorY - cursorMaxY); + } + */ + }, 0); + } + buttonFocusMode.onLayoutResize = doFocus; + buttonFocusMode.onReady = function() { if(aceEditor) { aceEditor.getSession().selection.on('changeCursor', doFocusMode); @@ -36,30 +70,11 @@ define([ }, true); return; } - var $editorElt = $('#wmd-input'); - var $positionHelper = $('').css('display', 'inline-block'); - var coef = 0.2; - $editorElt.on('keydown', function(event) { + $editorElt = $('#wmd-input').on('keydown', function(event) { if(event.altKey || event.ctrlKey || event.shiftKey || event.metaKey) { return; } - setTimeout(function() { - var range = window.getSelection().getRangeAt(0); - range.insertNode($positionHelper[0]); - var parentNode = $positionHelper[0].parentNode; - var editorHeight = $editorElt.height(); - var cursorMinY = coef*editorHeight; - var cursorMaxY = (1-coef)*editorHeight; - var cursorY = $positionHelper.offset().top - $editorElt.offset().top; - $positionHelper.detach(); - parentNode.normalize(); - if(cursorY < cursorMinY) { - $editorElt.scrollTop($editorElt.scrollTop() - cursorMinY + cursorY); - } - else if(cursorY > cursorMaxY) { - $editorElt.scrollTop($editorElt.scrollTop() + cursorY - cursorMaxY); - } - }, 0); + doFocus(); }); }; diff --git a/public/res/extensions/scrollLink.js b/public/res/extensions/scrollLink.js index 9ebc86a4..3a53c52c 100644 --- a/public/res/extensions/scrollLink.js +++ b/public/res/extensions/scrollLink.js @@ -45,7 +45,7 @@ define([ mdSectionOffset = 0; return; } - var $delimiterElt = $(this); + var $delimiterElt = $(this.firstChild); // Consider div scroll position var newSectionOffset = $delimiterElt.position().top + editorScrollTop; mdSectionList.push({ diff --git a/public/res/helpers/googleHelper.js b/public/res/helpers/googleHelper.js index eae8f20e..1b2448c1 100644 --- a/public/res/helpers/googleHelper.js +++ b/public/res/helpers/googleHelper.js @@ -755,6 +755,10 @@ define([ if(pickerType == 'doc' || pickerType == 'folder') { authenticate(task, 'gdrive', accountId); } + else { + accountId = 'google.picasa0'; + authenticate(task, 'picasa', accountId); + } loadPicker(task); task.onRun(function() { var authorizationMgr = authorizationMgrMap[accountId]; @@ -794,6 +798,7 @@ define([ view.setType('ofuser'); pickerBuilder.addView(view); pickerBuilder.addView(google.picker.ViewId.PHOTO_UPLOAD); + authorizationMgr && authorizationMgr.token && pickerBuilder.setOAuthToken(authorizationMgr.token.access_token); } pickerBuilder.setCallback(function(data) { if(data.action == google.picker.Action.PICKED || data.action == google.picker.Action.CANCEL) { diff --git a/public/res/libs/Markdown.Editor.light.js b/public/res/libs/Markdown.Editor.light.js index e294f2e6..8d203e95 100644 --- a/public/res/libs/Markdown.Editor.light.js +++ b/public/res/libs/Markdown.Editor.light.js @@ -119,13 +119,13 @@ panels; var undoManager; - this.run = function (previewWrapper) { + this.run = function () { if (panels) return; // already initialized panels = new PanelCollection(idPostfix); var commandManager = new CommandManager(hooks, getString); - var previewManager = new PreviewManager(markdownConverter, panels, function () { hooks.onPreviewRefresh(); }, previewWrapper); + var previewManager = new PreviewManager(markdownConverter, panels, function () { hooks.onPreviewRefresh(); }); var uiManager; if (!/\?noundo/.test(doc.location.href)) { @@ -844,14 +844,14 @@ this.init(); }; - function PreviewManager(converter, panels, previewRefreshCallback, previewWrapper) { + function PreviewManager(converter, panels, previewRefreshCallback) { var managerObj = this; var timeout; var elapsedTime; var oldInputText; var maxDelay = 3000; - var startType = "delayed"; // The other legal value is "manual" + var startType = "manual"; // The other legal value is "manual" // Adds event listeners to elements var setupEvents = function (inputElem, listener) { @@ -910,9 +910,6 @@ pushPreviewHtml(text); }; - if(previewWrapper !== undefined) { - makePreviewHtml = previewWrapper(makePreviewHtml); - } // setTimeout is already used. Used as an event listener. var applyTimeout = function () { diff --git a/public/res/main.js b/public/res/main.js index 1475a08f..f03fa244 100644 --- a/public/res/main.js +++ b/public/res/main.js @@ -65,6 +65,7 @@ requirejs.config({ normalize: 'bower-libs/require-css/normalize', prism: 'bower-libs/prism/prism', 'prism-core': 'bower-libs/prism/components/prism-core', + caret: 'bower-libs/caret.js/src/jquery.caret' }, shim: { underscore: { @@ -125,6 +126,9 @@ requirejs.config({ bootstrap: [ 'jquery' ], + 'caret': [ + 'jquery' + ], 'jquery-waitforimages': [ 'jquery' ], diff --git a/public/res/styles/main.less b/public/res/styles/main.less index 983a2e82..a6a688da 100644 --- a/public/res/styles/main.less +++ b/public/res/styles/main.less @@ -142,7 +142,7 @@ body { #preview-contents { padding: 30px; - margin: 0 auto 180px; + margin: 0 auto 200px; text-align: justify; } @@ -1252,6 +1252,7 @@ a { word-break: break-word; > div { margin: 0 auto; + padding: 10px 0 230px; } }