Check list button
This commit is contained in:
parent
0a361a5ca0
commit
6d59514835
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
49
src/data/pagedownButtons.js
Normal file
49
src/data/pagedownButtons.js
Normal 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',
|
||||||
|
}];
|
@ -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>
|
|
5
src/icons/FormatListChecks.vue
Normal file
5
src/icons/FormatListChecks.vue
Normal 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>
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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, ' ');
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user