From 6f6c10c601688dddf3d3ad6e307c46ec0c02b821 Mon Sep 17 00:00:00 2001 From: benweet Date: Thu, 17 Apr 2014 00:29:51 +0100 Subject: [PATCH] Implemented macro shortcuts --- public/res/core.js | 57 +------------------ public/res/editor.js | 34 ++++++++--- public/res/eventMgr.js | 2 +- public/res/extensions/comments.js | 9 ++- public/res/extensions/documentTitle.js | 11 +--- public/res/extensions/scrollLink.js | 28 +++------ public/res/extensions/shortcuts.js | 16 ++++-- .../res/extensions/shortcutsDefaultMapping.js | 35 ++++++++---- public/res/layout.js | 27 +++++---- public/res/styles/base.less | 4 +- public/res/styles/main.less | 6 +- 11 files changed, 101 insertions(+), 128 deletions(-) diff --git a/public/res/core.js b/public/res/core.js index 2bd98adf..16e87e74 100644 --- a/public/res/core.js +++ b/public/res/core.js @@ -207,52 +207,6 @@ define([ } } - // Create the layout - function createLayout() { - var layoutGlobalConfig = { - closable: true, - resizable: false, - slidable: false, - livePaneResizing: true, - enableCursorHotkey: false, - resizerDblClickToggle: false, - resizeWithWindow: false, - north__spacing_open: 1, - north__spacing_closed: 1, - spacing_open: 32, - spacing_closed: 32, - togglerLength_open: 60, - togglerLength_closed: 60, - stateManagement__enabled: false, - north__minSize: 49, - center__minWidth: 250, - center__minHeight: 180, - east__onalert: function() { - window.location.href = 'viewer'; - }, - south__onalert: function() { - window.location.href = 'viewer'; - }, - fxSettings: { - easing: "easeInOutQuad", - duration: 350 - }, - onresize_end: function(paneName) { - eventMgr.onLayoutResize(paneName); - }, - }; - eventMgr.onLayoutConfigure(layoutGlobalConfig); - if(settings.layoutOrientation == "horizontal") { - } - else if(settings.layoutOrientation == "vertical") { - } - - //setPanelVisibility(); - //setPreviewButtonsVisibility(); - layout.init(); - eventMgr.onLayoutCreated(layout); - } - var $navbarElt; var $leftBtnElts; var $rightBtnElts; @@ -360,8 +314,6 @@ define([ }; // Initialize multiple things and then fire eventMgr.onReady - var isDocumentPanelShown = false; - var isMenuPanelShown = false; core.onReady = function() { // Add RTL class settings.editMode == 'rtl' && $(document.body).addClass('rtl'); @@ -386,11 +338,6 @@ define([ // Populate shortcuts in settings shortcutMgr.addSettingEntries(); - // Hide shortcuts settings if light mode - if(window.lightMode) { - $('.tab-settings-shortcuts').hide(); - } - // listen to online/offline events $(window).on('offline', core.setOffline); $(window).on('online', setOnline); @@ -401,9 +348,7 @@ define([ // Detect user activity $(document).mousemove(setUserActive).keypress(setUserActive); - // Create UI layout - createLayout(); - + layout.init(); editor.init(); // Do periodic tasks diff --git a/public/res/editor.js b/public/res/editor.js index 5ade9ba7..2ce0e607 100644 --- a/public/res/editor.js +++ b/public/res/editor.js @@ -113,8 +113,9 @@ define([ this.cursorY = 0; this.findOffset = function(offset) { var walker = document.createTreeWalker(contentElt, 4); + var text = ''; while(walker.nextNode()) { - var text = walker.currentNode.nodeValue || ''; + text = walker.currentNode.nodeValue || ''; if (text.length > offset) { return { container: walker.currentNode, @@ -124,11 +125,13 @@ define([ offset -= text.length; } return { - container: contentElt, - offset: 0 + container: walker.currentNode, + offset: text.length }; }; this.createRange = function(start, end) { + start = start < 0 ? 0 : start; + end = end < 0 ? 0 : end; var range = document.createRange(); var offset = _.isObject(start) ? start : this.findOffset(start); range.setStart(offset.container, offset.offset); @@ -185,10 +188,10 @@ define([ var range; var selection = rangy.getSelection(); if(selection.rangeCount > 0) { - range = selection.getRangeAt(0); - var element = range.startContainer; - + var selectionRange = selection.getRangeAt(0); + var element = selectionRange.startContainer; if ((contentElt.compareDocumentPosition(element) & 0x10)) { + range = selectionRange; var container = element; var offset = range.startOffset; do { @@ -288,7 +291,7 @@ define([ } var selectionMgr = new SelectionMgr(); editor.selectionMgr = selectionMgr; - $(document).on('selectionchange', _.bind(selectionMgr.saveSelectionState, selectionMgr, true)); + $(document).on('selectionchange', '.editor-content', _.bind(selectionMgr.saveSelectionState, selectionMgr, true)); var adjustCursorPosition = (function() { var adjust = utils.debounce(function() { @@ -333,6 +336,23 @@ define([ } editor.setValue = setValue; + function replacePreviousText(text, replacement) { + var offset = selectionMgr.selectionStart; + if(offset !== selectionMgr.selectionEnd) { + return false; + } + var range = selectionMgr.createRange(offset - text.length, offset); + if('' + range != text) { + return false; + } + range.deleteContents(); + range.insertNode(document.createTextNode(replacement)); + offset = offset - text.length + replacement.length; + selectionMgr.setSelectionStartEnd(offset, offset); + return true; + } + editor.replacePreviousText = replacePreviousText; + function setValueNoWatch(value) { setValue(value); textContent = value; diff --git a/public/res/eventMgr.js b/public/res/eventMgr.js index 274be13f..eec8f904 100644 --- a/public/res/eventMgr.js +++ b/public/res/eventMgr.js @@ -203,9 +203,9 @@ define([ addEventHook("onPublishRemoved"); // Operations on Layout - addEventHook("onLayoutConfigure"); addEventHook("onLayoutCreated"); addEventHook("onLayoutResize"); + addEventHook("onPreviewToggle"); // Operations on editor addEventHook("onPagedownConfigure"); diff --git a/public/res/extensions/comments.js b/public/res/extensions/comments.js index f8a49b68..df673f94 100644 --- a/public/res/extensions/comments.js +++ b/public/res/extensions/comments.js @@ -458,7 +458,14 @@ define([ $commentElt = $(sortedCommentEltList[(curentIndex + 1) % sortedCommentEltList.length]); } } - $commentElt.click(); + if(currentContext && currentContext.commentElt === $commentElt[0]) { + // Close the popover properly + closeCurrentPopover(); + inputElt.focus(); + } + else { + $commentElt.click(); + } evt.stopPropagation(); }); $openDiscussionIconElt = $openDiscussionElt.find('i'); diff --git a/public/res/extensions/documentTitle.js b/public/res/extensions/documentTitle.js index c58e5513..196bdccc 100644 --- a/public/res/extensions/documentTitle.js +++ b/public/res/extensions/documentTitle.js @@ -6,11 +6,6 @@ define([ var documentTitle = new Extension("documentTitle", "Document Title"); - var layout; - documentTitle.onLayoutCreated = function(layoutParameter) { - layout = layoutParameter; - }; - var fileDesc; var $fileTitleNavbar; var updateTitle = _.debounce(function(fileDescParameter) { @@ -23,8 +18,6 @@ define([ $fileTitleNavbar.html(fileDesc.composeTitle()); $(".file-title").text(title); $(".input-file-title").val(title); - - layout && layout.resizeAll(); }, 50); documentTitle.onFileSelected = function(fileDescParameter) { @@ -38,7 +31,7 @@ define([ documentTitle.onNewPublishSuccess = updateTitle; documentTitle.onPublishRemoved = updateTitle; documentTitle.onReady = updateTitle; - + documentTitle.onReady = function() { $fileTitleNavbar = $(".file-title-navbar"); // Add a scrolling effect on hover @@ -56,4 +49,4 @@ define([ return documentTitle; -}); \ No newline at end of file +}); diff --git a/public/res/extensions/scrollLink.js b/public/res/extensions/scrollLink.js index 7b5c3bcb..cc46f2f4 100644 --- a/public/res/extensions/scrollLink.js +++ b/public/res/extensions/scrollLink.js @@ -17,6 +17,11 @@ define([ sectionList = sectionListParam; }; + var isPreviewVisible = true; + scrollLink.onPreviewToggle = function(isOpen) { + isPreviewVisible = isOpen; + }; + var $editorElt; var $previewElt; var mdSectionList = []; @@ -196,21 +201,6 @@ define([ buildSections(); }; - var isPreviewVisible = true; - function setPreviewHidden() { - isPreviewVisible = false; - } - function setPreviewVisible() { - isPreviewVisible = true; - } - - scrollLink.onLayoutConfigure = function(layoutGlobalConfig) { - layoutGlobalConfig.east__onclose = setPreviewHidden; - layoutGlobalConfig.south__onclose = setPreviewHidden; - layoutGlobalConfig.east__onopen_start = setPreviewVisible; - layoutGlobalConfig.south__onclose_start = setPreviewVisible; - }; - scrollLink.onFileClosed = function() { mdSectionList = []; }; @@ -228,22 +218,20 @@ define([ } scrollAdjust = false; }); - var handleEditorScroll = function() { + $editorElt.scroll(function() { if(isEditorMoving === false) { isScrollEditor = true; isScrollPreview = false; doScrollLink(); } - }; - $editorElt.scroll(handleEditorScroll); + }); }; var $previewContentsElt; scrollLink.onPagedownConfigure = function(editor) { $previewContentsElt = $("#preview-contents"); editor.getConverter().hooks.chain("postConversion", function(text) { - // To avoid losing scrolling position before elements are fully - // loaded + // To avoid losing scrolling position before elements are fully loaded $previewContentsElt.height($previewContentsElt.height()); return text; }); diff --git a/public/res/extensions/shortcuts.js b/public/res/extensions/shortcuts.js index 1c3aaa4d..5087d53e 100644 --- a/public/res/extensions/shortcuts.js +++ b/public/res/extensions/shortcuts.js @@ -15,13 +15,11 @@ define([ }; var eventMgr; - var clickPagedownButton; + var pagedownEditor; shortcuts.onEventMgrCreated = function(eventMgrParameter) { eventMgr = eventMgrParameter; - eventMgr.addListener('onPagedownConfigure', function(pagedownEditor) { - clickPagedownButton = function(buttonName) { - pagedownEditor.uiManager.doClick(pagedownEditor.uiManager.buttons[buttonName]); - }; + eventMgr.addListener('onPagedownConfigure', function(pagedownEditorParam) { + pagedownEditor = pagedownEditorParam; }); }; @@ -42,6 +40,14 @@ define([ } }; + /*jshint unused:false */ + function bindPagedownButton(buttonName) { + return function(evt) { + pagedownEditor.uiManager.doClick(pagedownEditor.uiManager.buttons[buttonName]); + evt.preventDefault(); + }; + } + shortcuts.onInit = function() { try { /*jshint evil: true */ diff --git a/public/res/extensions/shortcutsDefaultMapping.js b/public/res/extensions/shortcutsDefaultMapping.js index 9b332477..86764098 100644 --- a/public/res/extensions/shortcutsDefaultMapping.js +++ b/public/res/extensions/shortcutsDefaultMapping.js @@ -1,17 +1,32 @@ { - 'mod+r': function() { - clickPagedownButton('hr'); + 'mod+b': bindPagedownButton('bold'), + 'mod+i': bindPagedownButton('italic'), + 'mod+l': bindPagedownButton('link'), + 'mod+q': bindPagedownButton('quote'), + 'mod+k': bindPagedownButton('code'), + 'mod+g': bindPagedownButton('image'), + 'mod+o': bindPagedownButton('olist'), + 'mod+u': bindPagedownButton('ulist'), + 'mod+h': bindPagedownButton('heading'), + 'mod+r': bindPagedownButton('hr'), + 'mod+z': bindPagedownButton('undo'), + 'mod+y': bindPagedownButton('redo'), + 'mod+shift+z': bindPagedownButton('redo'), + 'mod+d': function(evt) { + $('.button-open-discussion').click(); + evt.preventDefault(); }, - 'mod+z': function() { - require('editor').undoMgr.undo(); + '= = > space': function() { + setTimeout(function() { + require('editor').replacePreviousText('==> ', '⇒ '); + }, 0); }, - 'mod+y': function() { - require('editor').undoMgr.redo(); - }, - 'mod+shift+z': function() { - require('editor').undoMgr.redo(); + '< = = space': function() { + setTimeout(function() { + require('editor').replacePreviousText('<== ', '⇐ '); + }, 0); }, 'S t a c k E d i t': function() { - eventMgr.onMessage('StackEdit is so good!!!'); + eventMgr.onMessage("You are stunned!!! Aren't you?"); } } diff --git a/public/res/layout.js b/public/res/layout.js index b621cb59..d416e9df 100644 --- a/public/res/layout.js +++ b/public/res/layout.js @@ -109,15 +109,17 @@ define([ }, this)); this.$elt.addClass('bring-to-front'); } - onToggle && onToggle(this.isOpen); + laterCssQueue.push(_.bind(function() { + onToggle && onToggle(this.isOpen); + }, this)); } else { + onToggle && onToggle(false); backdropElt && backdropElt.removeBackdrop(); backdropElt = undefined; laterCssQueue.push(_.bind(function() { !this.isOpen && this.$elt.find('.in').collapse('hide'); this.$elt.toggleClass('panel-open', this.isOpen).toggleClass('bring-to-front', (!!backdrop && this.isOpen)); - onToggle && onToggle(this.isOpen); }, this)); } startAnimation(); @@ -185,11 +187,12 @@ define([ wrapperL3.width = windowSize.width; wrapperL3.height = wrapperL1.height - navbarHeight; + if(navbar.isOpen && wrapperL3.height < editorMinSize.height + resizerSize) { + navbar.isOpen = false; + return resizeAll(); + } + if(isVertical) { - if(navbar.isOpen && wrapperL3.height < editorMinSize.height + resizerSize) { - navbar.isOpen = false; - return resizeAll(); - } if(!previewPanel.isOpen) { previewPanel.y = wrapperL3.height - resizerSize; } @@ -223,10 +226,6 @@ define([ previewResizer.width = previewContainer.width; } else { - if(navbar.isOpen && wrapperL3.height < editorMinSize.height + resizerSize) { - navbar.isOpen = false; - return resizeAll(); - } if(!previewPanel.isOpen) { previewPanel.x = wrapperL3.width - resizerSize; } @@ -306,6 +305,7 @@ define([ previewPanel.isOpen = true; previewPanel.createToggler(false, function(isOpen) { $previewButtonsElt.toggleClass('hide', !isOpen); + eventMgr.onPreviewToggle(isOpen); }); previewPanel.halfSize = true; previewToggler.$elt.click(_.bind(previewPanel.toggle, previewPanel)); @@ -318,8 +318,6 @@ define([ documentPanel.createToggler(true); documentPanel.$elt.find('.toggle-button').click(_.bind(documentPanel.toggle, documentPanel)); - - // Hide menu panel when clicking 'Save as' button $('.collapse-save-as a').click(function() { menuPanel.toggle(false); @@ -385,8 +383,8 @@ define([ }); // Configure Mousetrap - mousetrap.stopCallback = function(e, element) { - return menuPanel.isOpen || documentPanel.isOpen || isModalShown || $(element).is("input, select, textarea:not(.ace_text-input)"); + mousetrap.stopCallback = function() { + return menuPanel.isOpen || documentPanel.isOpen || isModalShown; }; $(window).resize(resizeAll); @@ -427,5 +425,6 @@ define([ resizeAll(); }; + eventMgr.onLayoutCreated(layout); return layout; }); diff --git a/public/res/styles/base.less b/public/res/styles/base.less index bf9f9360..78bc2634 100644 --- a/public/res/styles/base.less +++ b/public/res/styles/base.less @@ -280,7 +280,7 @@ kbd { [class^="icon-"], [class*=" icon-"] { display: inline-block; - line-height: 1.2em; + line-height: 1.35em; vertical-align: middle; background-repeat: no-repeat; } @@ -302,7 +302,7 @@ kbd { } .icon-chart-bar { - font-size: 90%; + font-size: 95%; &:before { margin-left: 0.3em; margin-right: 0.3em; diff --git a/public/res/styles/main.less b/public/res/styles/main.less index 9288c9a9..cd6a39d5 100644 --- a/public/res/styles/main.less +++ b/public/res/styles/main.less @@ -972,7 +972,7 @@ a { } .layout-animate { - .transition(350ms ease-in-out all); + .transition-transform(350ms ease-in-out); } .layout-resizer { @@ -998,7 +998,7 @@ a { } &.layout-toggler-preview { .layout-animate & { - .transition(350ms ease-in-out all); + .transition-transform(350ms ease-in-out); } line-height: 55px; i:before { @@ -1021,7 +1021,7 @@ a { line-height: 0; i { font-size: 16px; - height: 10.5px; + height: 12px; overflow: hidden; } }