From 9b673412333b9210ee7276c54a87703ae0a6a293 Mon Sep 17 00:00:00 2001 From: benweet Date: Thu, 5 Dec 2013 00:25:17 +0000 Subject: [PATCH] Restored PageDown editor in light mode --- public/res/core.js | 185 +- public/res/eventMgr.js | 3 +- public/res/extensions/scrollLink.js | 148 +- public/res/html/bodyIndex.html | 14 +- public/res/libs/Markdown.Editor.light.js | 2253 ++++++++++++++++++++++ public/res/main.js | 8 +- public/res/providers/gdriveProvider.js | 70 +- public/res/settings.js | 2 +- public/res/storage.js | 6 +- public/res/styles/base.less | 26 +- public/res/styles/main.less | 14 + 11 files changed, 2556 insertions(+), 173 deletions(-) create mode 100644 public/res/libs/Markdown.Editor.light.js diff --git a/public/res/core.js b/public/res/core.js index 64615c44..130b51fa 100644 --- a/public/res/core.js +++ b/public/res/core.js @@ -18,6 +18,7 @@ define([ "storage", "uilayout", 'pagedown-ace', + 'pagedown-light', 'libs/ace_mode', 'ace/requirejs/text!ace/css/editor.css', 'ace/requirejs/text!ace/theme/textmate.css', @@ -122,6 +123,8 @@ define([ utils.setInputValue("#input-settings-editor-font-size", settings.editorFontSize); // Max width utils.setInputValue("#input-settings-max-width", settings.maxWidth); + // RTL + utils.setInputChecked("#input-settings-rtl", storage.rtl == 'true'); // Default content utils.setInputValue("#textarea-settings-default-content", settings.defaultContent); // Commit message @@ -160,6 +163,8 @@ define([ newSettings.editorFontSize = utils.getInputIntValue("#input-settings-editor-font-size", event, 1, 99); // Max width newSettings.maxWidth = utils.getInputIntValue("#input-settings-max-width", event, 1); + // RTL + var rtl = utils.getInputChecked("#input-settings-rtl"); // Default content newSettings.defaultContent = utils.getInputValue("#textarea-settings-default-content"); // Commit message @@ -186,6 +191,7 @@ define([ $.extend(settings, newSettings); storage.settings = JSON.stringify(settings); storage.themeV3 = theme; + storage.rtl = rtl; } } @@ -408,7 +414,7 @@ define([ var $rightBtnDropdown; var marginWidth = 40 + 25 + 25; var titleWidth = 20 + 348; - var leftButtonsWidth = window.lightMode ? 0 : 80 + 87 + 174 + 175 + 87; + var leftButtonsWidth = 80 + 87 + 174 + 175 + 87; var rightButtonsWidth = 40 + 88 + 87; var rightButtonsDropdown = 44; function adjustWindow() { @@ -427,10 +433,6 @@ define([ $leftBtnDropdown.hide().after($leftBtnElts); $rightBtnDropdown.hide().after($rightBtnElts); } - if(window.lightMode) { - $leftBtnElts.hide(); - $leftBtnDropdown.hide(); - } } layout.resizeAll(); } @@ -467,7 +469,22 @@ define([ var $previewContainerElt = $(".preview-container"); - if(!window.lightMode) { + if(window.lightMode) { + // Store editor scrollTop on scroll event + $editorElt.scroll(function() { + if(documentContent !== undefined) { + fileDesc.editorScrollTop = $(this).scrollTop(); + } + }); + // Store editor selection on change + $editorElt.bind("keyup mouseup", function() { + if(documentContent !== undefined) { + fileDesc.editorStart = this.selectionStart; + fileDesc.editorEnd = this.selectionEnd; + } + }); + } + else { // Store editor scrollTop on scroll event var saveScroll = _.debounce(function() { if(documentContent !== undefined) { @@ -483,13 +500,13 @@ define([ }, 100); aceEditor.session.selection.on('changeSelection', saveSelection); aceEditor.session.selection.on('changeCursor', saveSelection); - // Store preview scrollTop on scroll event - $previewContainerElt.scroll(function() { - if(documentContent !== undefined) { - fileDesc.previewScrollTop = $previewContainerElt.scrollTop(); - } - }); } + // Store preview scrollTop on scroll event + $previewContainerElt.scroll(function() { + if(documentContent !== undefined) { + fileDesc.previewScrollTop = $previewContainerElt.scrollTop(); + } + }); // Create the converter and the editor var converter = new Markdown.Converter(); @@ -507,101 +524,89 @@ define([ } var previewWrapper; - if(!window.lightMode) { + if(window.lightMode) { + editor = new Markdown.EditorLight(converter); + } + else { editor = new Markdown.Editor(converter, undefined, { keyStrokes: shortcutMgr.getPagedownKeyStrokes() }); - // Custom insert link dialog - editor.hooks.set("insertLinkDialog", function(callback) { - core.insertLinkCallback = callback; - utils.resetModalInputs(); - $(".modal-insert-link").modal(); + } + // Custom insert link dialog + editor.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) { + core.insertLinkCallback = callback; + if(core.catchModal) { return true; - }); - // Custom insert image dialog - editor.hooks.set("insertImageDialog", function(callback) { - core.insertLinkCallback = callback; - if(core.catchModal) { - return true; - } - utils.resetModalInputs(); - $(".modal-insert-image").modal(); - return true; - }); + } + utils.resetModalInputs(); + $(".modal-insert-image").modal(); + return true; + }); - if(settings.lazyRendering === true) { - previewWrapper = function(makePreview) { - var debouncedMakePreview = _.debounce(makePreview, 500); - return function() { - if(documentContent === undefined) { - makePreview(); - eventMgr.onFileOpen(fileDesc); - $previewContainerElt.scrollTop(fileDesc.previewScrollTop); - _.defer(function() { - aceEditor.renderer.scrollToY(fileDesc.editorScrollTop); - }); + if(settings.lazyRendering === true) { + previewWrapper = function(makePreview) { + var debouncedMakePreview = _.debounce(makePreview, 500); + return function() { + if(documentContent === undefined) { + makePreview(); + eventMgr.onFileOpen(fileDesc); + $previewContainerElt.scrollTop(fileDesc.previewScrollTop); + if(window.lightMode) { + $editorElt.scrollTop(fileDesc.editorScrollTop); } else { - debouncedMakePreview(); - } - checkDocumentChanges(); - }; - }; - } - else { - previewWrapper = function(makePreview) { - return function() { - makePreview(); - if(documentContent === undefined) { - eventMgr.onFileOpen(fileDesc); - $previewContainerElt.scrollTop(fileDesc.previewScrollTop); _.defer(function() { aceEditor.renderer.scrollToY(fileDesc.editorScrollTop); }); } - checkDocumentChanges(); - }; + } + else { + debouncedMakePreview(); + } + checkDocumentChanges(); }; - } + }; } else { - // That's the light Markdown editor replacing the one from pagedown - var $wmdPreviewElt = $('#wmd-preview'); - var hooks = new Markdown.HookCollection(); - hooks.addNoop("onPreviewRefresh"); - var makePreviewHtml = function() { - var text = $editorElt.val(); - text = converter.makeHtml(text); - $wmdPreviewElt.html(text); - hooks.onPreviewRefresh(); - }; - var debouncedMakePreview = _.debounce(makePreviewHtml, 1000); - var lightPreviewWrapper = function() { - if(documentContent === undefined) { - makePreviewHtml(); - eventMgr.onFileOpen(fileDesc); - } - else { - debouncedMakePreview(); - } - checkDocumentChanges(); - }; - $editorElt.on("input propertychange", lightPreviewWrapper); - editor = { - hooks: hooks, - getConverter: function() { - return converter; - }, - run: lightPreviewWrapper, - refreshPreview: lightPreviewWrapper + previewWrapper = function(makePreview) { + return function() { + makePreview(); + if(documentContent === undefined) { + eventMgr.onFileOpen(fileDesc); + $previewContainerElt.scrollTop(fileDesc.previewScrollTop); + if(window.lightMode) { + $editorElt.scrollTop(fileDesc.editorScrollTop); + } + else { + _.defer(function() { + aceEditor.renderer.scrollToY(fileDesc.editorScrollTop); + }); + } + } + checkDocumentChanges(); + }; }; } eventMgr.onPagedownConfigure(editor); editor.hooks.chain("onPreviewRefresh", eventMgr.onAsyncPreview); - editor.run(aceEditor, previewWrapper); - aceEditor && aceEditor.selection.setSelectionRange(fileDesc.editorSelectRange); - (aceEditor && aceEditor.focus()) || $editorElt.focus(); + if(window.lightMode) { + editor.run(previewWrapper); + editor.undoManager.reinit(initDocumentContent, fileDesc.editorStart, fileDesc.editorEnd, fileDesc.editorScrollTop); + $editorElt.focus(); + } + else { + editor.run(aceEditor, previewWrapper); + aceEditor.selection.setSelectionRange(fileDesc.editorSelectRange); + aceEditor.focus(); + } // Hide default buttons $(".wmd-button-row li").addClass("btn btn-success").css("left", 0).find("span").hide(); @@ -742,7 +747,7 @@ define([ }); } - $editorElt = $("#wmd-input").css({ + $editorElt = $("#wmd-input, .textarea-helper").css({ // Apply editor font "font-family": settings.editorFontFamily, "font-size": settings.editorFontSize + "px", @@ -917,7 +922,7 @@ define([ }); $(".action-import-docs-settings-confirm").click(function() { storage.clear(); - var allowedKeys = /^file\.|^focusMode$|^folder\.|^publish\.|^settings$|^sync\.|^theme$|^version$|^welcomeTour$/; + var allowedKeys = /^file\.|^focusMode$|^folder\.|^publish\.|^settings$|^sync\.|^themeV3$|^rtl$|^version$|^welcomeTour$/; _.each(newstorage, function(value, key) { if(allowedKeys.test(key)) { storage[key] = value; diff --git a/public/res/eventMgr.js b/public/res/eventMgr.js index 75fc3fd3..289b9d11 100644 --- a/public/res/eventMgr.js +++ b/public/res/eventMgr.js @@ -120,7 +120,8 @@ define([ eventMgr.onLoadSettings = function() { logger.log("onLoadSettings"); _.each(extensionList, function(extension) { - utils.setInputChecked("#input-enable-extension-" + extension.extensionId, extension.enabled === true); + var isChecked = !extension.isOptional || extension.config.enabled === undefined || extension.config.enabled === true; + utils.setInputChecked($("#input-enable-extension-" + extension.extensionId), isChecked); var onLoadSettingsListener = extension.onLoadSettings; onLoadSettingsListener && onLoadSettingsListener(); }); diff --git a/public/res/extensions/scrollLink.js b/public/res/extensions/scrollLink.js index 267db268..df2409e6 100644 --- a/public/res/extensions/scrollLink.js +++ b/public/res/extensions/scrollLink.js @@ -5,7 +5,7 @@ define([ "text!html/scrollLinkSettingsBlock.html" ], function($, _, Extension, scrollLinkSettingsBlockHTML) { - var scrollLink = new Extension("scrollLink", "Scroll Link", true, true, true); + var scrollLink = new Extension("scrollLink", "Scroll Link", true, true); scrollLink.settingsBlock = scrollLinkSettingsBlockHTML; var aceEditor; @@ -23,6 +23,8 @@ define([ offsetBegin = offsetBeginParam; }; + var $textareaElt; + var $textareaHelperElt; var $previewElt; var mdSectionList = []; var htmlSectionList = []; @@ -34,20 +36,62 @@ define([ var mdTextOffset = 0; var mdSectionOffset = 0; var firstSectionOffset = offsetBegin; - _.each(sectionList, function(section) { - mdTextOffset += section.text.length + firstSectionOffset; - firstSectionOffset = 0; - var documentPosition = aceEditor.session.doc.indexToPosition(mdTextOffset); - var screenPosition = aceEditor.session.documentToScreenPosition(documentPosition.row, documentPosition.column); - var newSectionOffset = screenPosition.row * aceEditor.renderer.lineHeight; - var sectionHeight = newSectionOffset - mdSectionOffset; + function addTextareaSection(sectionText) { + var sectionHeight = 0; + if(sectionText !== undefined) { + $textareaHelperElt.text(sectionText); + sectionHeight += $textareaHelperElt.prop('scrollHeight'); + } + var newSectionOffset = mdSectionOffset + sectionHeight; mdSectionList.push({ startOffset: mdSectionOffset, endOffset: newSectionOffset, height: sectionHeight }); mdSectionOffset = newSectionOffset; - }); + } + if(window.lightMode) { + // Special treatment for light mode + $textareaHelperElt.innerWidth($textareaElt.innerWidth()); + _.each(sectionList, function(section, index) { + var sectionText = section.text; + if(index !== sectionList.length - 1) { + if(sectionText.length === 0) { + sectionText = undefined; + } + } + addTextareaSection(sectionText); + }); + + // Apply a coef to manage divergence in some browsers + var theoricalHeight = _.last(mdSectionList).endOffset; + var realHeight = $textareaElt[0].scrollHeight; + var coef = realHeight/theoricalHeight; + mdSectionList = _.map(mdSectionList, function(mdSection) { + return { + startOffset: mdSection.startOffset * coef, + endOffset: mdSection.endOffset * coef, + height: mdSection.height * coef, + }; + }); + } + else { + // Everything's much simpler with ACE + _.each(sectionList, function(section) { + mdTextOffset += section.text.length + firstSectionOffset; + firstSectionOffset = 0; + var documentPosition = aceEditor.session.doc.indexToPosition(mdTextOffset); + var screenPosition = aceEditor.session.documentToScreenPosition(documentPosition.row, documentPosition.column); + var newSectionOffset = screenPosition.row * aceEditor.renderer.lineHeight; + var sectionHeight = newSectionOffset - mdSectionOffset; + mdSectionList.push({ + startOffset: mdSectionOffset, + endOffset: newSectionOffset, + height: sectionHeight + }); + mdSectionOffset = newSectionOffset; + }); + } // Try to find corresponding sections in the preview htmlSectionList = []; @@ -94,7 +138,7 @@ define([ doScrollLink(); return; } - var editorScrollTop = aceEditor.renderer.getScrollTop(); + var editorScrollTop = window.lightMode ? $textareaElt.scrollTop() : aceEditor.renderer.getScrollTop(); editorScrollTop < 0 && (editorScrollTop = 0); var previewScrollTop = $previewElt.scrollTop(); function getDestScrollTop(srcScrollTop, srcSectionList, destSectionList) { @@ -155,33 +199,60 @@ define([ // Animate the editor lastPreviewScrollTop = previewScrollTop; destScrollTop = getDestScrollTop(previewScrollTop, htmlSectionList, mdSectionList); - destScrollTop = _.min([ - destScrollTop, - aceEditor.session.getScreenLength() * aceEditor.renderer.lineHeight + aceEditor.renderer.scrollMargin.bottom - aceEditor.renderer.$size.scrollerHeight - ]); - // If negative, set it to zero - destScrollTop < 0 && (destScrollTop = 0); + if(window.lightMode) { + destScrollTop = _.min([ + destScrollTop, + $textareaElt.prop('scrollHeight') - $textareaElt.outerHeight() + ]); + } + else { + destScrollTop = _.min([ + destScrollTop, + aceEditor.session.getScreenLength() * aceEditor.renderer.lineHeight + aceEditor.renderer.scrollMargin.bottom - aceEditor.renderer.$size.scrollerHeight + ]); + // If negative, set it to zero + destScrollTop < 0 && (destScrollTop = 0); + } if(Math.abs(destScrollTop - editorScrollTop) <= 9) { // Skip the animation if diff is <= 9 lastEditorScrollTop = editorScrollTop; return; } - scrollingHelper.stop(true).css('value', 0).animate({ - value: destScrollTop - editorScrollTop - }, { - easing: 'easeOutSine', - duration: 200, - step: function(now) { - isEditorMoving = true; - lastEditorScrollTop = editorScrollTop + now; - aceEditor.session.setScrollTop(lastEditorScrollTop); - }, - done: function() { - setTimeout(function() { - isEditorMoving = false; - }); - }, - }); + if(window.lightMode) { + $textareaElt.stop(true).animate({ + scrollTop: destScrollTop + }, { + easing: 'easeOutSine', + duration: 200, + step: function(now) { + isEditorMoving = true; + lastEditorScrollTop = editorScrollTop + now; + }, + done: function() { + _.defer(function() { + isEditorMoving = false; + }); + }, + }); + } + else { + scrollingHelper.stop(true).css('value', 0).animate({ + value: destScrollTop - editorScrollTop + }, { + easing: 'easeOutSine', + duration: 200, + step: function(now) { + isEditorMoving = true; + lastEditorScrollTop = editorScrollTop + now; + aceEditor.session.setScrollTop(lastEditorScrollTop); + }, + done: function() { + _.defer(function() { + isEditorMoving = false; + }); + }, + }); + } } }, 100); @@ -197,6 +268,9 @@ define([ var scrollAdjust = false; scrollLink.onReady = function() { $previewElt = $(".preview-container"); + $textareaElt = $("#wmd-input"); + // This helper is used to measure sections height in light mode + $textareaHelperElt = $('.textarea-helper'); $previewElt.scroll(function() { if(isPreviewMoving === false && scrollAdjust === false) { @@ -206,13 +280,19 @@ define([ } scrollAdjust = false; }); - aceEditor.session.on("changeScrollTop", function() { + var handleEditorScroll = function() { if(isEditorMoving === false) { isScrollEditor = true; isScrollPreview = false; doScrollLink(); } - }); + }; + if(window.lightMode) { + $textareaElt.scroll(handleEditorScroll); + } + else { + aceEditor.session.on("changeScrollTop", handleEditorScroll); + } }; var $previewContentsElt; diff --git a/public/res/html/bodyIndex.html b/public/res/html/bodyIndex.html index fb940707..64ae6e8f 100644 --- a/public/res/html/bodyIndex.html +++ b/public/res/html/bodyIndex.html @@ -994,6 +994,17 @@ class="form-control col-lg-3"> px +
+ +
+
+ +
Limited mode. +
+