From 6d5951483575bef7f78c2d8568d0d28b55d9222e Mon Sep 17 00:00:00 2001 From: benweet Date: Sat, 7 Apr 2018 16:00:31 +0100 Subject: [PATCH] Check list button --- src/components/Layout.vue | 2 +- src/components/NavigationBar.vue | 54 +++++++++++++---------- src/components/menus/common/MenuEntry.vue | 12 +---- src/data/defaultSettings.yml | 2 + src/data/pagedownButtons.js | 49 ++++++++++++++++++++ src/icons/FormatHorizontalRule.vue | 5 --- src/icons/FormatListChecks.vue | 5 +++ src/icons/index.js | 4 +- src/libs/pagedown.js | 20 ++++++--- src/services/optional/keystrokes.js | 8 +++- src/store/layout.js | 16 ++++++- 11 files changed, 126 insertions(+), 51 deletions(-) create mode 100644 src/data/pagedownButtons.js delete mode 100644 src/icons/FormatHorizontalRule.vue create mode 100644 src/icons/FormatListChecks.vue diff --git a/src/components/Layout.vue b/src/components/Layout.vue index a587ac95..611d5cb9 100644 --- a/src/components/Layout.vue +++ b/src/components/Layout.vue @@ -207,7 +207,7 @@ $preview-background-dark: #252525; .layout__panel--explorer, .layout__panel--side-bar { - background-color: #dadada; + background-color: #ddd; } .layout__panel--find-replace { diff --git a/src/components/NavigationBar.vue b/src/components/NavigationBar.vue index aef807b7..0a0b36cc 100644 --- a/src/components/NavigationBar.vue +++ b/src/components/NavigationBar.vue @@ -1,5 +1,5 @@ @@ -61,6 +54,7 @@ import publishSvc from '../services/publishSvc'; import animationSvc from '../services/animationSvc'; import tempFileSvc from '../services/tempFileSvc'; import utils from '../services/utils'; +import pagedownButtons from '../data/pagedownButtons'; export default { data: () => ({ @@ -95,6 +89,16 @@ export default { ...mapGetters('publishLocation', { publishLocations: 'current', }), + pagedownButtons() { + return pagedownButtons.map((button) => { + const title = button.title; + return { + ...button, + title, + iconClass: `icon-${button.icon}`, + }; + }); + }, isSyncPossible() { return this.$store.getters['workspace/syncToken'] || this.$store.getters['syncLocation/current'].length; @@ -225,7 +229,7 @@ export default { .navigation-bar__inner--right { float: right; - /* prevent from seeing wrapped buttons */ + /* prevent from seeing wrapped pagedownButtons */ margin-bottom: 20px; } @@ -233,7 +237,7 @@ export default { margin: 0 4px; } -.navigation-bar__inner--edit-buttons { +.navigation-bar__inner--edit-pagedownButtons { margin-left: 15px; .navigation-bar__button, @@ -246,20 +250,18 @@ export default { flex: none; } -$button-size: 36px; - .navigation-bar__button, .navigation-bar__spacer { - height: $button-size; + height: 36px; padding: 0 4px; - /* prevent from seeing wrapped buttons */ + /* prevent from seeing wrapped pagedownButtons */ margin-bottom: 20px; } .navigation-bar__button { - width: $button-size; - padding: 0 8px; + width: 34px; + padding: 0 7px; transition: opacity 0.25s; .navigation-bar__inner--button & { @@ -375,7 +377,7 @@ $button-size: 36px; } .navigation-bar__title--input, -.navigation-bar__inner--edit-buttons { +.navigation-bar__inner--edit-pagedownButtons { display: none; .navigation-bar--editor & { @@ -402,6 +404,10 @@ $button-size: 36px; &.navigation-bar__title--focus { cursor: text; } + + .navigation-bar--light & { + display: none; + } } $r: 10px; diff --git a/src/components/menus/common/MenuEntry.vue b/src/components/menus/common/MenuEntry.vue index f668235d..3bc805c3 100644 --- a/src/components/menus/common/MenuEntry.vue +++ b/src/components/menus/common/MenuEntry.vue @@ -17,23 +17,15 @@ padding: 10px; height: auto; font-size: 17px; - line-height: 1.5; + line-height: 1.4; text-transform: none; white-space: normal; - div div { - text-decoration: underline; - text-decoration-skip: ink; - - .menu-entry__label { - text-decoration: none; - } - } - span { display: inline-block; font-size: 0.75rem; opacity: 0.5; + line-height: 1.3; span { display: inline; diff --git a/src/data/defaultSettings.yml b/src/data/defaultSettings.yml index 235dc7e7..24692fe3 100644 --- a/src/data/defaultSettings.yml +++ b/src/data/defaultSettings.yml @@ -9,6 +9,8 @@ maxWidthFactor: 1 # Editor settings editor: + # Automatic list numbering + listAutoNumber: true # Display images in the editor inlineImages: true # Use monospaced font only diff --git a/src/data/pagedownButtons.js b/src/data/pagedownButtons.js new file mode 100644 index 00000000..ac3fa9a8 --- /dev/null +++ b/src/data/pagedownButtons.js @@ -0,0 +1,49 @@ +export default [{}, { + action: 'bold', + title: 'Bold', + icon: 'format-bold', +}, { + action: 'italic', + title: 'Italic', + icon: 'format-italic', +}, { + action: 'heading', + title: 'Heading', + icon: 'format-size', +}, { + action: 'strikethrough', + title: 'Strikethrough', + icon: 'format-strikethrough', +}, {}, { + action: 'ulist', + title: 'Unordered list', + icon: 'format-list-bulleted', +}, { + action: 'olist', + title: 'Ordered list', + icon: 'format-list-numbers', +}, { + action: 'clist', + title: 'Check list', + icon: 'format-list-checks', +}, {}, { + action: 'quote', + title: 'Blockquote', + icon: 'format-quote-close', +}, { + action: 'code', + title: 'Code', + icon: 'code-tags', +}, { + action: 'table', + title: 'Table', + icon: 'table', +}, { + action: 'link', + title: 'Link', + icon: 'link-variant', +}, { + action: 'image', + title: 'Image', + icon: 'file-image', +}]; diff --git a/src/icons/FormatHorizontalRule.vue b/src/icons/FormatHorizontalRule.vue deleted file mode 100644 index df352828..00000000 --- a/src/icons/FormatHorizontalRule.vue +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/src/icons/FormatListChecks.vue b/src/icons/FormatListChecks.vue new file mode 100644 index 00000000..77e403cf --- /dev/null +++ b/src/icons/FormatListChecks.vue @@ -0,0 +1,5 @@ + diff --git a/src/icons/index.js b/src/icons/index.js index 1badf4d5..38fe599e 100644 --- a/src/icons/index.js +++ b/src/icons/index.js @@ -9,7 +9,6 @@ import Table from './Table'; import FormatListNumbers from './FormatListNumbers'; import FormatListBulleted from './FormatListBulleted'; import FormatSize from './FormatSize'; -import FormatHorizontalRule from './FormatHorizontalRule'; import FormatStrikethrough from './FormatStrikethrough'; import StatusBar from './StatusBar'; import NavigationBar from './NavigationBar'; @@ -49,6 +48,7 @@ import Message from './Message'; import History from './History'; import Database from './Database'; import Magnify from './Magnify'; +import FormatListChecks from './FormatListChecks'; Vue.component('iconProvider', Provider); Vue.component('iconFormatBold', FormatBold); @@ -60,7 +60,6 @@ Vue.component('iconTable', Table); Vue.component('iconFormatListNumbers', FormatListNumbers); Vue.component('iconFormatListBulleted', FormatListBulleted); Vue.component('iconFormatSize', FormatSize); -Vue.component('iconFormatHorizontalRule', FormatHorizontalRule); Vue.component('iconFormatStrikethrough', FormatStrikethrough); Vue.component('iconStatusBar', StatusBar); Vue.component('iconNavigationBar', NavigationBar); @@ -100,3 +99,4 @@ Vue.component('iconMessage', Message); Vue.component('iconHistory', History); Vue.component('iconDatabase', Database); Vue.component('iconMagnify', Magnify); +Vue.component('iconFormatListChecks', FormatListChecks); diff --git a/src/libs/pagedown.js b/src/libs/pagedown.js index 3e77eaef..98002f73 100644 --- a/src/libs/pagedown.js +++ b/src/libs/pagedown.js @@ -477,6 +477,9 @@ function UIManager(input, commandManager) { buttons.ulist = bindCommand(function (chunk, postProcessing) { this.doList(chunk, postProcessing, false); }); + buttons.clist = bindCommand(function (chunk, postProcessing) { + this.doList(chunk, postProcessing, false, true); + }); buttons.heading = bindCommand("doHeading"); buttons.hr = bindCommand("doHorizontalRule"); buttons.table = bindCommand("doTable"); @@ -1032,7 +1035,7 @@ commandProto.doCode = function (chunk) { } }; -commandProto.doList = function (chunk, postProcessing, isNumberedList) { +commandProto.doList = function (chunk, postProcessing, isNumberedList, isCheckList) { // These are identical except at the very beginning and end. // Should probably use the regex extension function to make this clearer. @@ -1048,13 +1051,18 @@ commandProto.doList = function (chunk, postProcessing, isNumberedList) { var num = 1; // Get the item prefix - e.g. " 1. " for a numbered list, " - " for a bulleted list. - var getItemPrefix = function () { + var getItemPrefix = function (checkListContent) { var prefix; if (isNumberedList) { prefix = " " + num + ". "; num++; } else { prefix = " " + bullet + " "; + if (isCheckList) { + prefix += '['; + prefix += checkListContent || ' '; + prefix += '] '; + } } return prefix; }; @@ -1068,9 +1076,11 @@ commandProto.doList = function (chunk, postProcessing, isNumberedList) { } // Renumber/bullet the list element. - itemText = itemText.replace(/^[ ]{0,3}([*+-]|\d+[.])\s/gm, - function () { - return getItemPrefix(); + itemText = itemText.replace(isCheckList + ? /^[ ]{0,3}([*+-]|\d+[.])\s+\[([ xX])\]\s/gm + : /^[ ]{0,3}([*+-]|\d+[.])\s/gm, + function (match, p1, p2) { + return getItemPrefix(p2); }); return itemText; diff --git a/src/services/optional/keystrokes.js b/src/services/optional/keystrokes.js index 32a12c0f..3f696da3 100644 --- a/src/services/optional/keystrokes.js +++ b/src/services/optional/keystrokes.js @@ -1,13 +1,17 @@ import cledit from '../cledit'; import editorSvc from '../editorSvc'; +import store from '../../store'; const Keystroke = cledit.Keystroke; -const indentRegexp = /^ {0,3}>[ ]*|^[ \t]*[*+-][ \t]|^([ \t]*)\d+\.[ \t]|^\s+/; +const indentRegexp = /^ {0,3}>[ ]*|^[ \t]*[*+-][ \t](?:\[[ xX]\][ \t])?|^([ \t]*)\d+\.[ \t](?:\[[ xX]\][ \t])?|^\s+/; let clearNewline; let lastSelection; function fixNumberedList(state, indent) { - if (state.selection || indent === undefined) { + if (state.selection + || indent === undefined + || !store.getters['data/computedSettings'].editor.listAutoNumber + ) { return; } const spaceIndent = indent.replace(/\t/g, ' '); diff --git a/src/store/layout.js b/src/store/layout.js index 62799039..032f1ce1 100644 --- a/src/store/layout.js +++ b/src/store/layout.js @@ -1,11 +1,23 @@ +import pagedownButtons from '../data/pagedownButtons'; + +let buttonCount = 0; +let spacerCount = 0; +pagedownButtons.forEach((button) => { + if (button.action) { + buttonCount += 1; + } else { + spacerCount += 1; + } +}); + const minPadding = 20; const editorTopPadding = 10; -const navigationBarEditButtonsWidth = (36 * 14) + 8; // 14 buttons + 1 spacer +const navigationBarEditButtonsWidth = (34 * buttonCount) + (8 * spacerCount); // buttons + spacers const navigationBarLeftButtonWidth = 38 + 4 + 12; const navigationBarRightButtonWidth = 38 + 8; const navigationBarSpinnerWidth = 24 + 8 + 5; // 5 for left margin const navigationBarLocationWidth = 20; -const navigationBarSyncPublishButtonsWidth = 36 + 10; +const navigationBarSyncPublishButtonsWidth = 34 + 10; const navigationBarTitleMargin = 8; const maxTitleMaxWidth = 800; const minTitleMaxWidth = 200;