Check list button

This commit is contained in:
benweet 2018-04-07 16:00:31 +01:00
parent 0a361a5ca0
commit 6d59514835
11 changed files with 126 additions and 51 deletions

View File

@ -207,7 +207,7 @@ $preview-background-dark: #252525;
.layout__panel--explorer, .layout__panel--explorer,
.layout__panel--side-bar { .layout__panel--side-bar {
background-color: #dadada; background-color: #ddd;
} }
.layout__panel--find-replace { .layout__panel--find-replace {

View File

@ -1,5 +1,5 @@
<template> <template>
<nav class="navigation-bar" :class="{'navigation-bar--editor': styles.showEditor && !revisionContent}"> <nav class="navigation-bar" :class="{'navigation-bar--editor': styles.showEditor && !revisionContent, 'navigation-bar--light': light}">
<!-- Explorer --> <!-- Explorer -->
<div class="navigation-bar__inner navigation-bar__inner--left navigation-bar__inner--button"> <div class="navigation-bar__inner navigation-bar__inner--left navigation-bar__inner--button">
<button class="navigation-bar__button button" v-if="light" @click="close()" v-title="'Close StackEdit'"><icon-close></icon-close></button> <button class="navigation-bar__button button" v-if="light" @click="close()" v-title="'Close StackEdit'"><icon-close></icon-close></button>
@ -33,22 +33,15 @@
<button class="navigation-bar__button navigation-bar__button--revision button" @click="setRevisionContent()" v-title="'Close revision'"><icon-close></icon-close></button> <button class="navigation-bar__button navigation-bar__button--revision button" @click="setRevisionContent()" v-title="'Close revision'"><icon-close></icon-close></button>
</div> </div>
</div> </div>
<div class="navigation-bar__inner navigation-bar__inner--edit-buttons"> <div class="navigation-bar__inner navigation-bar__inner--edit-pagedownButtons">
<button class="navigation-bar__button button" @click="undo" v-title="'Undo'" :disabled="!canUndo"><icon-undo></icon-undo></button> <button class="navigation-bar__button button" @click="undo" v-title="'Undo'" :disabled="!canUndo"><icon-undo></icon-undo></button>
<button class="navigation-bar__button button" @click="redo" v-title="'Redo'" :disabled="!canRedo"><icon-redo></icon-redo></button> <button class="navigation-bar__button button" @click="redo" v-title="'Redo'" :disabled="!canRedo"><icon-redo></icon-redo></button>
<div class="navigation-bar__spacer"></div> <div v-for="button in pagedownButtons" :key="button.action">
<button class="navigation-bar__button button" @click="pagedownClick('bold')" v-title="'Bold'"><icon-format-bold></icon-format-bold></button> <button class="navigation-bar__button button" v-if="button.action" @click="pagedownClick(button.action)" v-title="button.title">
<button class="navigation-bar__button button" @click="pagedownClick('italic')" v-title="'Italic'"><icon-format-italic></icon-format-italic></button> <component :is="button.iconClass"></component>
<button class="navigation-bar__button button" @click="pagedownClick('strikethrough')" v-title="'Strikethrough'"><icon-format-strikethrough></icon-format-strikethrough></button> </button>
<button class="navigation-bar__button button" @click="pagedownClick('heading')" v-title="'Heading'"><icon-format-size></icon-format-size></button> <div class="navigation-bar__spacer" v-else></div>
<button class="navigation-bar__button button" @click="pagedownClick('ulist')" v-title="'Unordered list'"><icon-format-list-bulleted></icon-format-list-bulleted></button> </div>
<button class="navigation-bar__button button" @click="pagedownClick('olist')" v-title="'Ordered list'"><icon-format-list-numbers></icon-format-list-numbers></button>
<button class="navigation-bar__button button" @click="pagedownClick('table')" v-title="'Table'"><icon-table></icon-table></button>
<button class="navigation-bar__button button" @click="pagedownClick('quote')" v-title="'Blockquote'"><icon-format-quote-close></icon-format-quote-close></button>
<button class="navigation-bar__button button" @click="pagedownClick('code')" v-title="'Code'"><icon-code-tags></icon-code-tags></button>
<button class="navigation-bar__button button" @click="pagedownClick('link')" v-title="'Link'"><icon-link-variant></icon-link-variant></button>
<button class="navigation-bar__button button" @click="pagedownClick('image')" v-title="'Image'"><icon-file-image></icon-file-image></button>
<button class="navigation-bar__button button" @click="pagedownClick('hr')" v-title="'Horizontal rule'"><icon-format-horizontal-rule></icon-format-horizontal-rule></button>
</div> </div>
</nav> </nav>
</template> </template>
@ -61,6 +54,7 @@ import publishSvc from '../services/publishSvc';
import animationSvc from '../services/animationSvc'; import animationSvc from '../services/animationSvc';
import tempFileSvc from '../services/tempFileSvc'; import tempFileSvc from '../services/tempFileSvc';
import utils from '../services/utils'; import utils from '../services/utils';
import pagedownButtons from '../data/pagedownButtons';
export default { export default {
data: () => ({ data: () => ({
@ -95,6 +89,16 @@ export default {
...mapGetters('publishLocation', { ...mapGetters('publishLocation', {
publishLocations: 'current', publishLocations: 'current',
}), }),
pagedownButtons() {
return pagedownButtons.map((button) => {
const title = button.title;
return {
...button,
title,
iconClass: `icon-${button.icon}`,
};
});
},
isSyncPossible() { isSyncPossible() {
return this.$store.getters['workspace/syncToken'] || return this.$store.getters['workspace/syncToken'] ||
this.$store.getters['syncLocation/current'].length; this.$store.getters['syncLocation/current'].length;
@ -225,7 +229,7 @@ export default {
.navigation-bar__inner--right { .navigation-bar__inner--right {
float: right; float: right;
/* prevent from seeing wrapped buttons */ /* prevent from seeing wrapped pagedownButtons */
margin-bottom: 20px; margin-bottom: 20px;
} }
@ -233,7 +237,7 @@ export default {
margin: 0 4px; margin: 0 4px;
} }
.navigation-bar__inner--edit-buttons { .navigation-bar__inner--edit-pagedownButtons {
margin-left: 15px; margin-left: 15px;
.navigation-bar__button, .navigation-bar__button,
@ -246,20 +250,18 @@ export default {
flex: none; flex: none;
} }
$button-size: 36px;
.navigation-bar__button, .navigation-bar__button,
.navigation-bar__spacer { .navigation-bar__spacer {
height: $button-size; height: 36px;
padding: 0 4px; padding: 0 4px;
/* prevent from seeing wrapped buttons */ /* prevent from seeing wrapped pagedownButtons */
margin-bottom: 20px; margin-bottom: 20px;
} }
.navigation-bar__button { .navigation-bar__button {
width: $button-size; width: 34px;
padding: 0 8px; padding: 0 7px;
transition: opacity 0.25s; transition: opacity 0.25s;
.navigation-bar__inner--button & { .navigation-bar__inner--button & {
@ -375,7 +377,7 @@ $button-size: 36px;
} }
.navigation-bar__title--input, .navigation-bar__title--input,
.navigation-bar__inner--edit-buttons { .navigation-bar__inner--edit-pagedownButtons {
display: none; display: none;
.navigation-bar--editor & { .navigation-bar--editor & {
@ -402,6 +404,10 @@ $button-size: 36px;
&.navigation-bar__title--focus { &.navigation-bar__title--focus {
cursor: text; cursor: text;
} }
.navigation-bar--light & {
display: none;
}
} }
$r: 10px; $r: 10px;

View File

@ -17,23 +17,15 @@
padding: 10px; padding: 10px;
height: auto; height: auto;
font-size: 17px; font-size: 17px;
line-height: 1.5; line-height: 1.4;
text-transform: none; text-transform: none;
white-space: normal; white-space: normal;
div div {
text-decoration: underline;
text-decoration-skip: ink;
.menu-entry__label {
text-decoration: none;
}
}
span { span {
display: inline-block; display: inline-block;
font-size: 0.75rem; font-size: 0.75rem;
opacity: 0.5; opacity: 0.5;
line-height: 1.3;
span { span {
display: inline; display: inline;

View File

@ -9,6 +9,8 @@ maxWidthFactor: 1
# Editor settings # Editor settings
editor: editor:
# Automatic list numbering
listAutoNumber: true
# Display images in the editor # Display images in the editor
inlineImages: true inlineImages: true
# Use monospaced font only # Use monospaced font only

View File

@ -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',
}];

View File

@ -1,5 +0,0 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24">
<path fill="#000000" fill-opacity="1" stroke-linejoin="round" d="M3,13l5,0l0,-2l-5,0l0,2Zm6.5,0l5,0l0,-2l-5,0l0,2Zm6.5,0l5,0l0,-2l-5,0l0,2Z" />
</svg>
</template>

View File

@ -0,0 +1,5 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24">
<path d="M3,5H9V11H3V5M5,7V9H7V7H5M11,7H21V9H11V7M11,15H21V17H11V15M5,20L1.5,16.5L2.91,15.09L5,17.17L9.59,12.59L11,14L5,20Z" />
</svg>
</template>

View File

@ -9,7 +9,6 @@ import Table from './Table';
import FormatListNumbers from './FormatListNumbers'; import FormatListNumbers from './FormatListNumbers';
import FormatListBulleted from './FormatListBulleted'; import FormatListBulleted from './FormatListBulleted';
import FormatSize from './FormatSize'; import FormatSize from './FormatSize';
import FormatHorizontalRule from './FormatHorizontalRule';
import FormatStrikethrough from './FormatStrikethrough'; import FormatStrikethrough from './FormatStrikethrough';
import StatusBar from './StatusBar'; import StatusBar from './StatusBar';
import NavigationBar from './NavigationBar'; import NavigationBar from './NavigationBar';
@ -49,6 +48,7 @@ import Message from './Message';
import History from './History'; import History from './History';
import Database from './Database'; import Database from './Database';
import Magnify from './Magnify'; import Magnify from './Magnify';
import FormatListChecks from './FormatListChecks';
Vue.component('iconProvider', Provider); Vue.component('iconProvider', Provider);
Vue.component('iconFormatBold', FormatBold); Vue.component('iconFormatBold', FormatBold);
@ -60,7 +60,6 @@ Vue.component('iconTable', Table);
Vue.component('iconFormatListNumbers', FormatListNumbers); Vue.component('iconFormatListNumbers', FormatListNumbers);
Vue.component('iconFormatListBulleted', FormatListBulleted); Vue.component('iconFormatListBulleted', FormatListBulleted);
Vue.component('iconFormatSize', FormatSize); Vue.component('iconFormatSize', FormatSize);
Vue.component('iconFormatHorizontalRule', FormatHorizontalRule);
Vue.component('iconFormatStrikethrough', FormatStrikethrough); Vue.component('iconFormatStrikethrough', FormatStrikethrough);
Vue.component('iconStatusBar', StatusBar); Vue.component('iconStatusBar', StatusBar);
Vue.component('iconNavigationBar', NavigationBar); Vue.component('iconNavigationBar', NavigationBar);
@ -100,3 +99,4 @@ Vue.component('iconMessage', Message);
Vue.component('iconHistory', History); Vue.component('iconHistory', History);
Vue.component('iconDatabase', Database); Vue.component('iconDatabase', Database);
Vue.component('iconMagnify', Magnify); Vue.component('iconMagnify', Magnify);
Vue.component('iconFormatListChecks', FormatListChecks);

View File

@ -477,6 +477,9 @@ function UIManager(input, commandManager) {
buttons.ulist = bindCommand(function (chunk, postProcessing) { buttons.ulist = bindCommand(function (chunk, postProcessing) {
this.doList(chunk, postProcessing, false); this.doList(chunk, postProcessing, false);
}); });
buttons.clist = bindCommand(function (chunk, postProcessing) {
this.doList(chunk, postProcessing, false, true);
});
buttons.heading = bindCommand("doHeading"); buttons.heading = bindCommand("doHeading");
buttons.hr = bindCommand("doHorizontalRule"); buttons.hr = bindCommand("doHorizontalRule");
buttons.table = bindCommand("doTable"); 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. // These are identical except at the very beginning and end.
// Should probably use the regex extension function to make this clearer. // Should probably use the regex extension function to make this clearer.
@ -1048,13 +1051,18 @@ commandProto.doList = function (chunk, postProcessing, isNumberedList) {
var num = 1; var num = 1;
// Get the item prefix - e.g. " 1. " for a numbered list, " - " for a bulleted list. // Get the item prefix - e.g. " 1. " for a numbered list, " - " for a bulleted list.
var getItemPrefix = function () { var getItemPrefix = function (checkListContent) {
var prefix; var prefix;
if (isNumberedList) { if (isNumberedList) {
prefix = " " + num + ". "; prefix = " " + num + ". ";
num++; num++;
} else { } else {
prefix = " " + bullet + " "; prefix = " " + bullet + " ";
if (isCheckList) {
prefix += '[';
prefix += checkListContent || ' ';
prefix += '] ';
}
} }
return prefix; return prefix;
}; };
@ -1068,9 +1076,11 @@ commandProto.doList = function (chunk, postProcessing, isNumberedList) {
} }
// Renumber/bullet the list element. // Renumber/bullet the list element.
itemText = itemText.replace(/^[ ]{0,3}([*+-]|\d+[.])\s/gm, itemText = itemText.replace(isCheckList
function () { ? /^[ ]{0,3}([*+-]|\d+[.])\s+\[([ xX])\]\s/gm
return getItemPrefix(); : /^[ ]{0,3}([*+-]|\d+[.])\s/gm,
function (match, p1, p2) {
return getItemPrefix(p2);
}); });
return itemText; return itemText;

View File

@ -1,13 +1,17 @@
import cledit from '../cledit'; import cledit from '../cledit';
import editorSvc from '../editorSvc'; import editorSvc from '../editorSvc';
import store from '../../store';
const Keystroke = cledit.Keystroke; 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 clearNewline;
let lastSelection; let lastSelection;
function fixNumberedList(state, indent) { function fixNumberedList(state, indent) {
if (state.selection || indent === undefined) { if (state.selection
|| indent === undefined
|| !store.getters['data/computedSettings'].editor.listAutoNumber
) {
return; return;
} }
const spaceIndent = indent.replace(/\t/g, ' '); const spaceIndent = indent.replace(/\t/g, ' ');

View File

@ -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 minPadding = 20;
const editorTopPadding = 10; 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 navigationBarLeftButtonWidth = 38 + 4 + 12;
const navigationBarRightButtonWidth = 38 + 8; const navigationBarRightButtonWidth = 38 + 8;
const navigationBarSpinnerWidth = 24 + 8 + 5; // 5 for left margin const navigationBarSpinnerWidth = 24 + 8 + 5; // 5 for left margin
const navigationBarLocationWidth = 20; const navigationBarLocationWidth = 20;
const navigationBarSyncPublishButtonsWidth = 36 + 10; const navigationBarSyncPublishButtonsWidth = 34 + 10;
const navigationBarTitleMargin = 8; const navigationBarTitleMargin = 8;
const maxTitleMaxWidth = 800; const maxTitleMaxWidth = 800;
const minTitleMaxWidth = 200; const minTitleMaxWidth = 200;