mirror of
https://github.com/marktext/marktext.git
synced 2025-05-02 17:50:02 +08:00
opti: rewrite TOC and remove hard code theme (#778)
* opti: prevent the duplicated header text error * scroll error in toc * delay the change event when init muya, so that the change event listener can handle change event. * opti: style * almost finished need last check * style in table * clear up some unused codes * clear up theme hard code * add no search data picture and new Folder new File * move search and replace to top of editor * add: no data image when there is no TOC * update structure * little bug fix * update styles * update un_draw icons * update style of editor * add animation when make open folder collapse. * remove theme props in editor component, deprecated lightColor and darkColor * add Ulysses Light * theme: graphite * update Ulysses blockquote * update emoji style * update titleBar height * change theme color * Support macOs dark mode * update style of tooltip in editor * update styles * fix: TOC auto expand all * patch added
This commit is contained in:
parent
07d0bbb249
commit
e1cfec6e3e
@ -88,7 +88,8 @@
|
||||
]
|
||||
},
|
||||
"mac": {
|
||||
"icon": "resources/icons/icon.icns"
|
||||
"icon": "resources/icons/icon.icns",
|
||||
"darkModeSupport": true
|
||||
},
|
||||
"win": {
|
||||
"icon": "resources/icons/icon.ico",
|
||||
@ -143,7 +144,7 @@
|
||||
"chokidar": "^2.1.2",
|
||||
"codemirror": "^5.44.0",
|
||||
"command-exists": "^1.2.8",
|
||||
"diacritics-map": "^0.1.0",
|
||||
"dayjs": "^1.8.10",
|
||||
"dompurify": "^1.0.10",
|
||||
"electron-is-accelerator": "^0.1.2",
|
||||
"element-resize-detector": "^1.2.0",
|
||||
|
@ -1,10 +1,12 @@
|
||||
import path from 'path'
|
||||
import { app } from 'electron'
|
||||
import { app, systemPreferences } from 'electron'
|
||||
import appWindow from './window'
|
||||
import { isOsx } from './config'
|
||||
import { dockMenu } from './menus'
|
||||
import { isDirectory, isMarkdownFile } from './utils'
|
||||
import { isDirectory, isMarkdownFile, getMenuItemById } from './utils'
|
||||
import { watchers } from './utils/imagePathAutoComplement'
|
||||
import { selectTheme } from './actions/theme'
|
||||
import preference from './preference'
|
||||
|
||||
class App {
|
||||
constructor () {
|
||||
@ -22,12 +24,12 @@ class App {
|
||||
app.commandLine.appendSwitch('remote-debugging-port', '8315')
|
||||
}
|
||||
|
||||
app.on('open-file', this.openFile.bind(this))
|
||||
app.on('open-file', this.openFile)
|
||||
|
||||
app.on('ready', this.ready.bind(this))
|
||||
app.on('ready', this.ready)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
app.removeListener('open-file', this.openFile.bind(this))
|
||||
app.removeListener('open-file', this.openFile)
|
||||
// close all the image path watcher
|
||||
for (const watcher of watchers.values()) {
|
||||
watcher.close()
|
||||
@ -63,7 +65,7 @@ class App {
|
||||
})
|
||||
}
|
||||
|
||||
ready () {
|
||||
ready = () => {
|
||||
if (!isOsx && process.argv.length >= 2) {
|
||||
for (const arg of process.argv) {
|
||||
if (arg.startsWith('--')) {
|
||||
@ -79,6 +81,32 @@ class App {
|
||||
// Set dock on macOS
|
||||
if (process.platform === 'darwin') {
|
||||
app.dock.setMenu(dockMenu)
|
||||
|
||||
// listen for system theme change and change Mark Text own `dark` and `light`,
|
||||
// In macOS 10.14 Mojave,
|
||||
// Apple introduced a new system-wide dark mode for all macOS computers.
|
||||
systemPreferences.subscribeNotification(
|
||||
'AppleInterfaceThemeChangedNotification',
|
||||
() => {
|
||||
const { theme } = preference.getAll()
|
||||
let setedTheme = null
|
||||
if (systemPreferences.isDarkMode() && theme !== 'dark') {
|
||||
selectTheme('dark')
|
||||
setedTheme = 'dark'
|
||||
}
|
||||
if (!systemPreferences.isDarkMode() && theme === 'dark') {
|
||||
selectTheme('light')
|
||||
setedTheme = 'light'
|
||||
}
|
||||
if (setedTheme) {
|
||||
const themeMenu = getMenuItemById('themeMenu')
|
||||
const menuItem = themeMenu.submenu.items.filter(item => (item.id === setedTheme))[0]
|
||||
if (menuItem) {
|
||||
menuItem.checked = true
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (this.openFilesCache.length) {
|
||||
@ -89,7 +117,7 @@ class App {
|
||||
}
|
||||
}
|
||||
|
||||
openFile (event, path) {
|
||||
openFile = (event, path) => {
|
||||
const { openFilesCache } = this
|
||||
event.preventDefault()
|
||||
if (app.isReady()) {
|
||||
|
@ -15,7 +15,7 @@ export const defaultWinOptions = {
|
||||
useContentSize: true,
|
||||
show: false,
|
||||
frame: false,
|
||||
titleBarStyle: 'hidden'
|
||||
titleBarStyle: 'hiddenInset'
|
||||
}
|
||||
|
||||
export const EXTENSIONS = [
|
||||
|
@ -5,19 +5,38 @@ const { theme } = userPreference.getAll()
|
||||
|
||||
export default {
|
||||
label: 'Theme',
|
||||
id: 'themeMenu',
|
||||
submenu: [{
|
||||
label: 'Dark',
|
||||
label: 'Mateial Dark',
|
||||
type: 'radio',
|
||||
id: 'dark',
|
||||
checked: theme === 'dark',
|
||||
click (menuItem, browserWindow) {
|
||||
actions.selectTheme('dark')
|
||||
}
|
||||
}, {
|
||||
label: 'Light',
|
||||
label: 'Cadmium Light',
|
||||
type: 'radio',
|
||||
id: 'light',
|
||||
checked: theme === 'light',
|
||||
click (menuItem, browserWindow) {
|
||||
actions.selectTheme('light')
|
||||
}
|
||||
}, {
|
||||
label: 'Ulysses Light',
|
||||
type: 'radio',
|
||||
id: 'ulysses',
|
||||
checked: theme === 'ulysses',
|
||||
click (menuItem, browserWindow) {
|
||||
actions.selectTheme('ulysses')
|
||||
}
|
||||
}, {
|
||||
label: 'Graphite Light',
|
||||
type: 'radio',
|
||||
id: 'graphite',
|
||||
checked: theme === 'graphite',
|
||||
click (menuItem, browserWindow) {
|
||||
actions.selectTheme('graphite')
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
@ -1,22 +1,3 @@
|
||||
/* Common CSS use by both light and dark themes */
|
||||
:root {
|
||||
--brandColor: #5b3cc4;
|
||||
--successColor: rgb(23, 201, 100);
|
||||
--warningColor: rgb(255, 130, 0);
|
||||
--dangerColor: rgb(242, 19, 93);
|
||||
--activeColor: #409eff;
|
||||
--infoColor: #909399;
|
||||
--primaryColor: #303133;
|
||||
--regularColor: #606266;
|
||||
--secondaryColor: #909399;
|
||||
--placeholerColor: #C0C4CC;
|
||||
--baseBorder: #DCDFE6;
|
||||
--lightBorder: #E4E7ED;
|
||||
--lighterBorder: #EBEEF5;
|
||||
--extraLightBorder: #F2F6FC;
|
||||
--editorAreaWidth: 700px;
|
||||
}
|
||||
|
||||
html {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
@ -54,14 +35,14 @@ pre {
|
||||
top: 0;
|
||||
left: -25px;
|
||||
font-size: 14px;
|
||||
color: var(--secondaryColor);
|
||||
color: var(--iconColor);
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.ag-show-quick-insert-hint p.ag-paragraph.ag-active > span.ag-line:first-of-type:empty::after {
|
||||
content: 'Type @ to insert';
|
||||
color: var(--placeholerColor);
|
||||
color: var(--editorColor10);
|
||||
}
|
||||
|
||||
.ag-paragraph:empty::after,
|
||||
@ -81,7 +62,7 @@ div.ag-show-quick-insert-hint p.ag-paragraph.ag-active > span.ag-line:first-of-t
|
||||
|
||||
.ag-reference-marker {
|
||||
font-size: .9em;
|
||||
color: var(--secondaryColor);
|
||||
color: var(--editorColor10);
|
||||
}
|
||||
|
||||
.ag-reference-title {
|
||||
@ -94,19 +75,14 @@ div.ag-show-quick-insert-hint p.ag-paragraph.ag-active > span.ag-line:first-of-t
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
/* .ag-soft-line-break::after {
|
||||
content: '↓';
|
||||
opacity: .5;
|
||||
} */
|
||||
|
||||
.ag-hard-line-break::after {
|
||||
content: '↩';
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
*:not(.ag-hide)::selection, .ag-selection {
|
||||
background: var(--baseBorder);
|
||||
color: var(--primaryColor);
|
||||
background: var(--selectionColor);
|
||||
color: var(--editorColor);
|
||||
}
|
||||
|
||||
.ag-hide::selection {
|
||||
@ -149,19 +125,18 @@ div.ag-function-html.ag-active .ag-html-preview {
|
||||
animation-name: highlight;
|
||||
animation-duration: .25s;
|
||||
display: inline-block;
|
||||
background: rgb(249, 226, 153);
|
||||
color: var(--primaryColor);
|
||||
background: var(--highlightColor);
|
||||
}
|
||||
|
||||
span.ag-html-tag {
|
||||
color: var(--secondaryColor);
|
||||
color: var(--editorColor50);
|
||||
font-weight: 200;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
span.ag-math {
|
||||
position: relative;
|
||||
color: rebeccapurple;
|
||||
color: var(--editorColor);
|
||||
font-family: monospace;
|
||||
display: inline-block;
|
||||
vertical-align: bottom;
|
||||
@ -179,7 +154,7 @@ span.ag-math {
|
||||
|
||||
div.ag-empty {
|
||||
text-align: center;
|
||||
color: var(--regularColor);
|
||||
color: var(--editorColor50);
|
||||
font-size: 14px;
|
||||
font-style: italic;
|
||||
font-family: monospace;
|
||||
@ -187,7 +162,7 @@ div.ag-empty {
|
||||
|
||||
div.ag-math-error,
|
||||
span.ag-math > .ag-math-render.ag-math-error {
|
||||
color: var(--warningColor);
|
||||
color: var(--deleteColor);
|
||||
font-size: 14px;
|
||||
font-style: italic;
|
||||
font-family: monospace;
|
||||
@ -268,11 +243,10 @@ figure {
|
||||
display: flex;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
padding: 2px;
|
||||
margin-right: 3px;
|
||||
cursor: pointer;
|
||||
border-radius: 3px;
|
||||
color: var(--regularColor);
|
||||
color: var(--iconColor);
|
||||
}
|
||||
|
||||
.ag-tool-bar ul li[data-label=delete] {
|
||||
@ -281,23 +255,18 @@ figure {
|
||||
}
|
||||
|
||||
.ag-tool-bar ul li[data-label=delete] {
|
||||
color: var(--dangerColor);
|
||||
color: var(--deleteColor);
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.ag-tool-bar ul li.active svg {
|
||||
fill: #409eff;
|
||||
fill: var(--themeColor);
|
||||
}
|
||||
|
||||
.ag-tool-bar ul li svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
will-change: transform;
|
||||
transition: transform .2s ease-in-out;
|
||||
}
|
||||
|
||||
.ag-tool-bar ul li:hover svg {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
figure.ag-active .ag-tool-bar {
|
||||
@ -313,7 +282,7 @@ figure.ag-active[data-role=HTML]::before {
|
||||
top: 0;
|
||||
left: -45px;
|
||||
font-size: 12px;
|
||||
color: var(--secondaryColor);
|
||||
color: var(--editorColor50);
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
}
|
||||
@ -345,66 +314,56 @@ li.ag-task-list-item {
|
||||
li.ag-task-list-item > input[type=checkbox] {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 4px 0px 0px;
|
||||
top: 0;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
top: 5px;
|
||||
left: -22px;
|
||||
transform-origin: center;
|
||||
transform: rotate(-90deg);
|
||||
transition: all .2s ease;
|
||||
}
|
||||
|
||||
li.ag-task-list-item > input.ag-checkbox-checked {
|
||||
transform: rotate(0);
|
||||
}
|
||||
|
||||
li.ag-task-list-item > input.ag-checkbox-checked ~ * {
|
||||
color: var(--regularColor);
|
||||
color: var(--editorColor50);
|
||||
}
|
||||
|
||||
li.ag-task-list-item > input.ag-checkbox-checked ~ p {
|
||||
text-decoration: line-through;
|
||||
color: var(--secondaryColor);
|
||||
color: var(--editorColor50);
|
||||
}
|
||||
|
||||
li.ag-task-list-item > input[type=checkbox]::before {
|
||||
content: '';
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
border: 2px solid var(--infoColor);
|
||||
border-radius: 2px;
|
||||
background-color: #fff;
|
||||
border: 1px solid var(--iconColor);
|
||||
border-radius: 50%;
|
||||
background-color: var(--editorBgColor);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
top: -2px;
|
||||
left: -2px;
|
||||
transition: all .2s ease;
|
||||
}
|
||||
|
||||
li.ag-task-list-item > input.ag-checkbox-checked::before {
|
||||
border: transparent;
|
||||
background-color: var(--activeColor);
|
||||
}
|
||||
|
||||
li.ag-task-list-item > input::after {
|
||||
content: '';
|
||||
transform: rotate(-45deg) scale(0);
|
||||
width: 9px;
|
||||
height: 5px;
|
||||
border: 2px solid #fff;
|
||||
transform: rotate(-28deg) skew(0, -25deg) scale(0);
|
||||
width: 8px;
|
||||
height: 4px;
|
||||
border: 1px solid var(--iconColor);
|
||||
border-top: none;
|
||||
border-right: none;
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
top: 3px;
|
||||
left: 3px;
|
||||
top: 0px;
|
||||
left: 2px;
|
||||
transform-origin: bottom;
|
||||
transition: all .2s ease;
|
||||
}
|
||||
|
||||
li.ag-task-list-item > input.ag-checkbox-checked::after {
|
||||
transform: rotate(-45deg) scale(1);
|
||||
transform: rotate(-28deg) skew(0, -25deg) scale(1);
|
||||
}
|
||||
|
||||
/* li p .ag-hide:first-child {
|
||||
@ -419,8 +378,8 @@ p:not(.ag-active)[data-role="hr"] {
|
||||
p:not(.ag-active)[data-role="hr"]::before {
|
||||
content: '';
|
||||
width: 100%;
|
||||
height: 5px;
|
||||
background: gainsboro;
|
||||
height: 2px;
|
||||
background: var(--editorColor10);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
@ -433,7 +392,7 @@ p:not(.ag-active)[data-role="hr"] * {
|
||||
pre.ag-multiple-math,
|
||||
pre.ag-front-matter {
|
||||
position: relative;
|
||||
background: #f6f8fa;
|
||||
background: var(--selectionColor);
|
||||
padding: .5rem;
|
||||
border: 5px;
|
||||
font-size: 14px;
|
||||
@ -445,17 +404,17 @@ pre.ag-front-matter {
|
||||
|
||||
pre.ag-front-matter span.ag-code-line:first-of-type:empty::after {
|
||||
content: 'Input YAML Front Matter...';
|
||||
color: var(--placeholerColor);
|
||||
color: var(--editorColor10);
|
||||
}
|
||||
|
||||
pre[data-role$='code'] span.ag-language-input:empty::after {
|
||||
content: 'Input Language...';
|
||||
color: var(--placeholerColor);
|
||||
color: var(--editorColor10);
|
||||
}
|
||||
|
||||
pre.ag-multiple-math span.ag-code-line:first-of-type:empty::after {
|
||||
content: 'Input Mathematical Formula...';
|
||||
color: var(--placeholerColor);
|
||||
color: var(--editorColor10);
|
||||
}
|
||||
|
||||
figure,
|
||||
@ -545,7 +504,7 @@ pre.ag-active.ag-indent-code::before,
|
||||
pre.ag-active.ag-indent-code::after,
|
||||
pre.ag-active.ag-multiple-math::before,
|
||||
pre.ag-active.ag-multiple-math::after {
|
||||
color: var(--regularColor);
|
||||
color: var(--editorColor30);
|
||||
font-family: monospace;
|
||||
position: absolute;
|
||||
font-weight: 600;
|
||||
@ -574,11 +533,6 @@ pre.ag-active.ag-indent-code::after {
|
||||
bottom: -23px;
|
||||
}
|
||||
|
||||
span.ag-multiple-math-line {
|
||||
color: purple;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
figure.ag-container-block div.ag-container-preview {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
@ -593,8 +547,8 @@ figure.ag-active.ag-container-block > div.ag-container-preview {
|
||||
z-index: 10000;
|
||||
transform: translateX(-50%);
|
||||
padding: .5rem;
|
||||
background: #fff;
|
||||
border: 1px solid var(--lightBorder);
|
||||
background: var(--floatBgColor);
|
||||
border: 1px solid var(--floatBorderColor);
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
|
||||
}
|
||||
@ -614,7 +568,7 @@ hr {
|
||||
|
||||
span.ag-emoji-marked-text {
|
||||
position: relative;
|
||||
color: var(--regularColor);
|
||||
color: var(--themeColor);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@ -632,14 +586,14 @@ span.ag-emoji-marked-text {
|
||||
.ag-emoji-marked-text::before {
|
||||
position: absolute;
|
||||
content: attr(data-emoji);
|
||||
color: #000;
|
||||
color: var(--editorColor);
|
||||
top: -6px;
|
||||
left: -1.1em;
|
||||
font-size: 1.5em;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.ag-hide.ag-emoji-marked-text::before {
|
||||
top: -19px;
|
||||
top: -15px;
|
||||
}
|
||||
|
||||
.ag-html-escape {
|
||||
@ -653,7 +607,7 @@ span.ag-emoji-marked-text {
|
||||
top: -2px;
|
||||
left: -1rem;
|
||||
width: 1rem;
|
||||
color: var(--secondaryColor);
|
||||
color: var(--editorColor30);
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
@ -670,14 +624,14 @@ span.ag-emoji-marked-text {
|
||||
font-size: 14px;
|
||||
font-family: monospace;
|
||||
font-weight: 600;
|
||||
color: var(--activeColor);
|
||||
color: var(--themeColor);
|
||||
background: transparent;
|
||||
border: none;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.ag-language-input::placeholder {
|
||||
color: var(--placeholerColor);
|
||||
color: var(--editorColor10);
|
||||
}
|
||||
|
||||
pre.ag-active .ag-language-input {
|
||||
@ -685,14 +639,14 @@ pre.ag-active .ag-language-input {
|
||||
}
|
||||
|
||||
.ag-language {
|
||||
color: var(--activeColor);
|
||||
color: var(--themeColor);
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
span.ag-image-marked-text, span.ag-link-in-bracket, span.ag-link-in-bracket .ag-backlash {
|
||||
color: var(--regularColor);
|
||||
color: var(--editorColor50);
|
||||
font-size: 16px;
|
||||
text-decoration: none;
|
||||
font-family: monospace;
|
||||
@ -703,7 +657,7 @@ span.ag-image-marked-text, span.ag-link-in-bracket, span.ag-link-in-bracket .ag-
|
||||
color: rgb(51, 51, 51);
|
||||
}
|
||||
span.ag-warn.ag-emoji-marked-text {
|
||||
color: var(--warningColor);
|
||||
color: var(--deleteColor);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@ -735,12 +689,12 @@ span.ag-warn.ag-emoji-marked-text {
|
||||
}
|
||||
|
||||
span[data-role="link"], a[data-role="link"], span[data-role="link"] .ag-backlash {
|
||||
color: #0366d6;
|
||||
color: var(--themeColor);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
span.ag-reference-link {
|
||||
color: var(--warningColor);
|
||||
color: var(--deleteColor);
|
||||
}
|
||||
|
||||
.ag-focus-mode p.ag-paragraph,
|
||||
|
@ -218,7 +218,6 @@ export const EXPORT_DOMPURIFY_CONFIG = {
|
||||
|
||||
export const MUYA_DEFAULT_OPTION = {
|
||||
focusMode: false,
|
||||
theme: 'light',
|
||||
markdown: '',
|
||||
preferLooseListItem: true,
|
||||
autoPairBracket: true,
|
||||
|
@ -22,6 +22,7 @@ import imagePathCtrl from './imagePathCtrl'
|
||||
import htmlBlockCtrl from './htmlBlock'
|
||||
import clickCtrl from './clickCtrl'
|
||||
import inputCtrl from './inputCtrl'
|
||||
import tocCtrl from './tocCtrl'
|
||||
import importMarkdown from '../utils/importMarkdown'
|
||||
|
||||
const prototypes = [
|
||||
@ -44,6 +45,7 @@ const prototypes = [
|
||||
htmlBlockCtrl,
|
||||
clickCtrl,
|
||||
inputCtrl,
|
||||
tocCtrl,
|
||||
importMarkdown
|
||||
]
|
||||
|
||||
|
24
src/muya/lib/contentState/tocCtrl.js
Normal file
24
src/muya/lib/contentState/tocCtrl.js
Normal file
@ -0,0 +1,24 @@
|
||||
const tocCtrl = ContentState => {
|
||||
ContentState.prototype.getTOC = function () {
|
||||
const { blocks } = this
|
||||
const toc = []
|
||||
|
||||
for (const block of blocks) {
|
||||
if (/^h\d$/.test(block.type)) {
|
||||
const { headingStyle, text, key, type } = block
|
||||
const content = headingStyle === 'setext' ? text.trim() : text.replace(/^ *#{1,6} {1,}/, '').trim()
|
||||
const lvl = +type.substring(1)
|
||||
const slug = key
|
||||
toc.push({
|
||||
content,
|
||||
lvl,
|
||||
slug
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return toc
|
||||
}
|
||||
}
|
||||
|
||||
export default tocCtrl
|
@ -18,9 +18,8 @@ class Muya {
|
||||
}
|
||||
constructor (container, options) {
|
||||
this.options = Object.assign({}, MUYA_DEFAULT_OPTION, options)
|
||||
const { focusMode, theme, markdown } = this.options
|
||||
const { focusMode, markdown } = this.options
|
||||
this.focusMode = focusMode
|
||||
this.theme = theme
|
||||
this.markdown = markdown
|
||||
this.container = getContainer(container, this.options)
|
||||
this.eventCenter = new EventCenter()
|
||||
@ -42,7 +41,7 @@ class Muya {
|
||||
init () {
|
||||
const { container, contentState, eventCenter } = this
|
||||
contentState.stateRender.setContainer(container.children[0])
|
||||
eventCenter.subscribe('stateChange', this.dispatchChange.bind(this))
|
||||
eventCenter.subscribe('stateChange', this.dispatchChange)
|
||||
eventCenter.attachDOMEvent(container, 'contextmenu', event => {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
@ -61,19 +60,19 @@ class Muya {
|
||||
eventCenter.dispatch('contextmenu', event, sectionChanges)
|
||||
})
|
||||
contentState.listenForPathChange()
|
||||
const { theme, focusMode, markdown } = this
|
||||
this.setTheme(theme)
|
||||
const { focusMode, markdown } = this
|
||||
this.setMarkdown(markdown)
|
||||
this.setFocusMode(focusMode)
|
||||
}
|
||||
|
||||
dispatchChange () {
|
||||
dispatchChange = () => {
|
||||
const { eventCenter } = this
|
||||
const markdown = this.markdown = this.getMarkdown()
|
||||
const wordCount = this.getWordCount(markdown)
|
||||
const cursor = this.getCursor()
|
||||
const history = this.getHistory()
|
||||
eventCenter.dispatch('change', { markdown, wordCount, cursor, history })
|
||||
const toc = this.getTOC()
|
||||
eventCenter.dispatch('change', { markdown, wordCount, cursor, history, toc })
|
||||
}
|
||||
|
||||
getMarkdown () {
|
||||
@ -85,6 +84,10 @@ class Muya {
|
||||
return this.contentState.getHistory()
|
||||
}
|
||||
|
||||
getTOC () {
|
||||
return this.contentState.getTOC()
|
||||
}
|
||||
|
||||
setHistory (history) {
|
||||
return this.contentState.setHistory(history)
|
||||
}
|
||||
@ -119,7 +122,9 @@ class Muya {
|
||||
this.contentState.importMarkdown(newMarkdown)
|
||||
this.contentState.importCursor(cursor)
|
||||
this.contentState.render(isRenderCursor)
|
||||
this.dispatchChange()
|
||||
setTimeout(() => {
|
||||
this.dispatchChange()
|
||||
}, 0)
|
||||
}
|
||||
|
||||
createTable (tableChecker) {
|
||||
@ -140,16 +145,6 @@ class Muya {
|
||||
this.focusMode = bool
|
||||
}
|
||||
|
||||
setTheme (name) {
|
||||
if (!name) return
|
||||
const { eventCenter } = this
|
||||
this.theme = name
|
||||
// Render cursor and refresh code block
|
||||
this.contentState.render(true)
|
||||
// notice the ui components to change theme
|
||||
eventCenter.dispatch('theme-change', name)
|
||||
}
|
||||
|
||||
setFont ({ fontSize, lineHeight }) {
|
||||
if (fontSize) this.contentState.fontSize = parseInt(fontSize, 10)
|
||||
if (lineHeight) this.contentState.lineHeight = lineHeight
|
||||
|
@ -1,8 +1,7 @@
|
||||
import katex from 'katex'
|
||||
import mermaid from 'mermaid'
|
||||
import prism, { loadedCache } from '../../../prism/'
|
||||
import { slugify } from '../../../utils/dirtyToc'
|
||||
import { CLASS_OR_ID, DEVICE_MEMORY, isInElectron, PREVIEW_DOMPURIFY_CONFIG, HAS_TEXT_BLOCK_REG } from '../../../config'
|
||||
import { CLASS_OR_ID, DEVICE_MEMORY, PREVIEW_DOMPURIFY_CONFIG, HAS_TEXT_BLOCK_REG } from '../../../config'
|
||||
import { tokenizer } from '../../parse'
|
||||
import { snakeToCamel, sanitize, escapeHtml, getLongUniqueId, getImageInfo } from '../../../utils'
|
||||
import { h, htmlToVNode } from '../snabbdom'
|
||||
@ -199,8 +198,7 @@ export default function renderLeafBlock (block, cursor, activeBlocks, matches, u
|
||||
// TODO: This should be the best place to create and update the TOC.
|
||||
// Cache `block.key` and title and update only if necessary.
|
||||
Object.assign(data.dataset, {
|
||||
head: type,
|
||||
id: isInElectron ? slugify(text.replace(/^#+\s(.*)/, (_, p1) => p1)) : ''
|
||||
head: type
|
||||
})
|
||||
selector += `.${headingStyle}`
|
||||
}
|
||||
|
@ -7,9 +7,9 @@
|
||||
top: -1000px;
|
||||
right: -1000px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.1);
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0 4px 8px 0 var(--floatBorderColor);
|
||||
border: 1px solid var(--floatBorderColor);
|
||||
background-color: var(--floatBgColor);
|
||||
transition: opacity .25s ease-in-out;
|
||||
transform-origin: top;
|
||||
box-sizing: border-box;
|
||||
@ -17,11 +17,6 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ag-float-wrapper.dark {
|
||||
background: var(--primaryColor);
|
||||
border-color: var(--primaryColor);
|
||||
}
|
||||
|
||||
.ag-float-container::-webkit-scrollbar:vertical {
|
||||
width: 0px;
|
||||
}
|
||||
@ -40,10 +35,6 @@
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.dark[x-placement] .ag-popper-arrow {
|
||||
border-color: var(--primaryColor);
|
||||
}
|
||||
|
||||
[x-placement="bottom-start"] > .ag-popper-arrow {
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
|
@ -88,16 +88,6 @@ class BaseFloat {
|
||||
}
|
||||
}
|
||||
|
||||
const themeChange = theme => {
|
||||
const { container, floatBox } = this
|
||||
;[container, floatBox].forEach(ele => {
|
||||
if (!ele.classList.contains(theme)) {
|
||||
ele.classList.remove(theme === 'dark' ? 'light' : 'dark')
|
||||
ele.classList.add(theme)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
eventCenter.attachDOMEvent(document, 'click', this.hide.bind(this))
|
||||
eventCenter.attachDOMEvent(floatBox, 'click', event => {
|
||||
event.stopPropagation()
|
||||
@ -105,7 +95,6 @@ class BaseFloat {
|
||||
})
|
||||
eventCenter.attachDOMEvent(container, 'keydown', keydownHandler)
|
||||
eventCenter.attachDOMEvent(container, 'scroll', scrollHandler)
|
||||
eventCenter.subscribe('theme-change', themeChange)
|
||||
}
|
||||
|
||||
hide () {
|
||||
|
@ -20,11 +20,14 @@
|
||||
|
||||
.ag-list-picker:hover .active {
|
||||
background: transparent;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.ag-list-picker .item .language {
|
||||
color: var(--editorColor);
|
||||
}
|
||||
|
||||
.ag-list-picker .active, .ag-list-picker .item:hover {
|
||||
background-color: #ecf5ff;
|
||||
color: var(--activeColor);
|
||||
background-color: var(--floatHoverColor);
|
||||
}
|
||||
|
||||
.ag-list-picker .item .icon-wrapper {
|
||||
@ -48,13 +51,4 @@
|
||||
font-size: 14px;
|
||||
line-height: 35px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.ag-list-picker.dark:hover .active {
|
||||
background: transparent;
|
||||
color: currentColor;
|
||||
}
|
||||
.ag-list-picker.dark .active, .ag-list-picker.dark .item:hover {
|
||||
background-color: rgb(71, 72, 66);
|
||||
color: var(--activeColor);
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
}
|
||||
|
||||
.ag-emoji-picker .title {
|
||||
color: rgba(55, 53, 47, 0.6);
|
||||
color: var(--editorColor);
|
||||
line-height: 120%;
|
||||
font-size: 11px;
|
||||
padding: 10px 14px 12px 14px;
|
||||
@ -16,7 +16,7 @@
|
||||
font-weight: 600;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background: #fff;
|
||||
background: var(--floatBgColor);
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
@ -44,8 +44,7 @@
|
||||
}
|
||||
|
||||
.ag-emoji-picker .active, .ag-emoji-picker .item:hover {
|
||||
background-color: #ecf5ff;
|
||||
border: 1px solid var(--activeColor);
|
||||
background-color: var(--floatHoverColor);
|
||||
}
|
||||
|
||||
.ag-emoji-picker section .emoji-wrapper .item span {
|
||||
@ -58,23 +57,4 @@
|
||||
transition: transform .2s ease-in;
|
||||
transform-origin: center;
|
||||
}
|
||||
|
||||
.ag-emoji-picker .active span, .ag-emoji-picker .item:hover span {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.ag-emoji-picker.dark .title {
|
||||
background: var(--primaryColor);
|
||||
color: var(--placeholerColor);
|
||||
}
|
||||
|
||||
.ag-emoji-picker.dark:hover .active {
|
||||
background: transparent;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.ag-emoji-picker.dark .active, .ag-emoji-picker.dark .item:hover {
|
||||
background-color: rgb(72, 71, 66);
|
||||
border: 1px solid var(--primaryColor);
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
}
|
||||
|
||||
.ag-format-picker li.item:hover {
|
||||
background: rgb(243, 243, 243);
|
||||
background: var(--floatHoverColor);
|
||||
}
|
||||
|
||||
.ag-format-picker li.item:last-of-type {
|
||||
@ -38,29 +38,20 @@
|
||||
width: 2px;
|
||||
position: absolute;
|
||||
height: 18px;
|
||||
background: #eee;
|
||||
background: var(--editorColor10);
|
||||
left: -4px;
|
||||
top: 6px;
|
||||
}
|
||||
|
||||
.ag-format-picker li.item svg {
|
||||
fill: #666;
|
||||
fill: var(--iconColor);
|
||||
}
|
||||
|
||||
.ag-format-picker li.item.active svg {
|
||||
fill: var(--activeColor);
|
||||
fill: var(--themeColor);
|
||||
}
|
||||
|
||||
.ag-format-picker li.item .icon-wrapper {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
/* dark theme */
|
||||
.ag-format-picker.dark li.item:hover {
|
||||
background: rgb(60, 60, 60);
|
||||
}
|
||||
|
||||
.ag-format-picker.dark li.item:last-of-type:before {
|
||||
background: rgb(71, 71, 71);
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
}
|
||||
|
||||
.ag-quick-insert .title {
|
||||
color: rgba(0, 0, 0, .6);
|
||||
color: var(--editorColor);
|
||||
line-height: 120%;
|
||||
font-size: 14px;
|
||||
padding: 10px 14px 10px 14px;
|
||||
@ -15,7 +15,7 @@
|
||||
letter-spacing: 1px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background: #fff;
|
||||
background: var(--floatBgColor);
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
@ -32,20 +32,21 @@
|
||||
}
|
||||
.ag-quick-insert .active,
|
||||
.ag-quick-insert div.item:hover {
|
||||
background-color: rgba(0, 0, 0, .04);
|
||||
background-color: var(--floatHoverColor);
|
||||
}
|
||||
|
||||
.ag-quick-insert .no-result {
|
||||
margin-top: 20px;
|
||||
padding: 0 20px;
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
text-align: center;
|
||||
color: var(--themeColor);
|
||||
}
|
||||
|
||||
.ag-quick-insert .icon-container {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 1px solid rgb(0, 0, 0, .1);
|
||||
border: 1px solid var(--floatBorderColor);
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
@ -57,7 +58,7 @@
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
opacity: .6;
|
||||
fill: rgba(0, 0, 0, .6);
|
||||
fill: var(--iconColor);
|
||||
}
|
||||
|
||||
.ag-quick-insert .description {
|
||||
@ -70,49 +71,21 @@
|
||||
margin-right: 20px;
|
||||
flex-shrink: 1;
|
||||
text-align: right;
|
||||
color: rgba(0, 0, 0, .3);
|
||||
color: var(--editorColor50);
|
||||
font-size: 14px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.ag-quick-insert .big-title {
|
||||
font-size: 14px;
|
||||
color: rgba(0, 0, 0, .6);
|
||||
color: var(--editorColor);
|
||||
}
|
||||
|
||||
.ag-quick-insert .sub-title {
|
||||
font-size: 12px;
|
||||
color: rgba(0, 0, 0, .4);
|
||||
color: var(--editorColor50);
|
||||
}
|
||||
|
||||
.ag-quick-insert .hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ag-quick-insert.dark .title {
|
||||
background: var(--primaryColor);
|
||||
color: var(--placeholerColor);
|
||||
}
|
||||
|
||||
.ag-quick-insert.dark .big-title {
|
||||
color: var(--lightBorder);
|
||||
}
|
||||
|
||||
.ag-quick-insert.dark .sub-title {
|
||||
color: rgba(255, 255, 255, .6);
|
||||
}
|
||||
|
||||
.ag-quick-insert.dark .active,
|
||||
.ag-quick-insert.dark div.item:hover {
|
||||
background-color: rgb(71, 72, 66);
|
||||
}
|
||||
|
||||
.ag-quick-insert.dark .icon-container > svg {
|
||||
fill: rgba(255, 255, 255, .5);
|
||||
}
|
||||
|
||||
.ag-quick-insert.dark .short-cut {
|
||||
color: rgba(255, 255, 255, .5);
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,46 +19,54 @@
|
||||
box-sizing: border-box;
|
||||
margin-right: 1px;
|
||||
margin-bottom: 1px;
|
||||
border: 1px solid #ccc;
|
||||
border: 1px solid var(--editorColor10);
|
||||
cursor: pointer;
|
||||
}
|
||||
.ag-table-picker-header span {
|
||||
background: #ddd;
|
||||
background: var(--editorColor10);
|
||||
}
|
||||
.ag-table-picker-cell.current {
|
||||
background: darkgray;
|
||||
background: var(--editorColor30);
|
||||
}
|
||||
.ag-table-picker-header .current {
|
||||
background: #666;
|
||||
background: var(--editorColor50);
|
||||
}
|
||||
.ag-table-picker-cell.selected {
|
||||
background: #ecf5ff;
|
||||
background: var(--selectionColor);
|
||||
}
|
||||
.ag-table-picker-header .selected {
|
||||
background: #ecf5ff;
|
||||
background: var(--selectionColor);
|
||||
}
|
||||
.ag-table-picker-cell:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
.ag-table-picker .footer {
|
||||
padding-top: 5px;
|
||||
border-top: 1px solid #ccc;
|
||||
padding: 10px 0 0 0;
|
||||
border-top: 1px solid var(--floatBorderColor);
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
.ag-table-picker .footer input {
|
||||
color: var(--editorColor);
|
||||
background: var(--floatBorderColor);
|
||||
outline: none;
|
||||
border-radius: 3px;
|
||||
text-align: center;
|
||||
border: none;
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
height: 20px;
|
||||
width: 30px;
|
||||
border: none;
|
||||
}
|
||||
.ag-table-picker .footer button {
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
border-radius: 2px;
|
||||
line-height: 12px;
|
||||
border-radius: 3px;
|
||||
line-height: 20px;
|
||||
border: none;
|
||||
height: 16px;
|
||||
background: #409eff;
|
||||
height: 20px;
|
||||
background: var(--themeColor);
|
||||
color: #fff;
|
||||
}
|
||||
|
@ -4,8 +4,11 @@
|
||||
font-size: 12px;
|
||||
padding: 5px 7px;
|
||||
border-radius: 3px;
|
||||
background: rgb(50, 50, 50);
|
||||
color: rgb(255, 255, 255);
|
||||
background: var(--floatBgColor);
|
||||
color: var(--editorColor);
|
||||
box-shadow: 0 4px 8px 0 var(--floatBorderColor);
|
||||
border: 1px solid var(--floatBorderColor);
|
||||
box-sizing: border-box;
|
||||
z-index: 1000;
|
||||
opacity: 0;
|
||||
}
|
||||
@ -16,10 +19,13 @@
|
||||
}
|
||||
|
||||
.ag-tooltip:after {
|
||||
top: 0;
|
||||
top: -2px;
|
||||
left: 50%;
|
||||
content: '';
|
||||
background: inherit;
|
||||
border: 1px solid var(--floatBorderColor);
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
position: absolute;
|
||||
|
@ -6,7 +6,7 @@ const position = (source, ele) => {
|
||||
|
||||
Object.assign(ele.style, {
|
||||
top: `${top + height + 10}px`,
|
||||
left: `${right - ele.offsetWidth / 2 - 3}px`
|
||||
left: `${right - ele.offsetWidth / 2 - 5}px`
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1,39 +0,0 @@
|
||||
import { Lexer } from '../parser/marked'
|
||||
import diacritics from 'diacritics-map'
|
||||
|
||||
export const getTocFromMarkdown = markdown => {
|
||||
const tokens = new Lexer({ disableInline: true }).lex(markdown)
|
||||
const toc = []
|
||||
let token = null
|
||||
while ((token = tokens.shift())) {
|
||||
switch (token.type) {
|
||||
case 'heading': {
|
||||
const { depth, text } = token
|
||||
toc.push({
|
||||
content: text,
|
||||
lvl: depth,
|
||||
slug: slugify(text)
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return toc
|
||||
}
|
||||
|
||||
export const slugify = str => {
|
||||
str = str.replace(/^\s+|\s+$/g, '').toLowerCase()
|
||||
|
||||
// replace accents
|
||||
str = str.replace(/[À-ž]/g, c => {
|
||||
return diacritics[c] || c
|
||||
})
|
||||
|
||||
return str
|
||||
.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
|
||||
.replace(/\t/g, '--') // collapse tabs and replace by --
|
||||
.replace(/\s+/g, '-') // collapse whitespace and replace by -
|
||||
.replace(/^-+/, '') // trim - from start of text
|
||||
.replace(/-+$/, '') // trim - from end of text
|
||||
.replace(/-+/g, '-') // collapse dashes
|
||||
}
|
@ -1,633 +0,0 @@
|
||||
/*
|
||||
* Open Sans
|
||||
* https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i&subset=latin-ext
|
||||
*/
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: local('Open Sans Light'), local('OpenSans-Light'),
|
||||
url('./fonts/open-sans-v15-latin_latin-ext-300.woff') format('woff');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
src: local('Open Sans Light Italic'), local('OpenSans-LightItalic'),
|
||||
url('./fonts/open-sans-v15-latin_latin-ext-300italic.woff') format('woff');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Open Sans Regular'), local('OpenSans-Regular'),
|
||||
url('./fonts/open-sans-v15-latin_latin-ext-regular.woff') format('woff');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local('Open Sans Italic'), local('OpenSans-Italic'),
|
||||
url('./fonts/open-sans-v15-latin_latin-ext-italic.woff') format('woff');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'),
|
||||
url('./fonts/open-sans-v15-latin_latin-ext-600.woff') format('woff');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
src: local('Open Sans SemiBold Italic'), local('OpenSans-SemiBoldItalic'),
|
||||
url('./fonts/open-sans-v15-latin_latin-ext-600italic.woff') format('woff');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Open Sans Bold'), local('OpenSans-Bold'),
|
||||
url('./fonts/open-sans-v15-latin_latin-ext-700.woff') format('woff');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'),
|
||||
url('./fonts/open-sans-v15-latin_latin-ext-700italic.woff') format('woff');
|
||||
}
|
||||
|
||||
/*
|
||||
* DejaVu Sans Mono
|
||||
*/
|
||||
@font-face {
|
||||
font-family: "DejaVu Sans Mono";
|
||||
src: local('DejaVu Sans Mono'), url('./fonts/DejaVuSansMono.ttf');
|
||||
}
|
||||
@font-face {
|
||||
font-family: "DejaVu Sans Mono";
|
||||
font-weight: bold;
|
||||
src: url('./fonts/DejaVuSansMono-Bold.ttf');
|
||||
}
|
||||
@font-face {
|
||||
font-family: "DejaVu Sans Mono";
|
||||
font-style: oblique;
|
||||
font-weight: bold;
|
||||
src: url('./fonts/DejaVuSansMono-BoldOblique.ttf');
|
||||
}
|
||||
@font-face {
|
||||
font-family: "DejaVu Sans Mono";
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
src: url('./fonts/DejaVuSansMono-BoldOblique.ttf');
|
||||
}
|
||||
@font-face {
|
||||
font-family: "DejaVu Sans Mono";
|
||||
font-style: italic;
|
||||
src: url('./fonts/DejaVuSansMono-Oblique.ttf');
|
||||
}
|
||||
@font-face {
|
||||
font-family: "DejaVu Sans Mono";
|
||||
font-style: oblique;
|
||||
src: url('./fonts/DejaVuSansMono-Oblique.ttf');
|
||||
}
|
||||
|
||||
html, body {
|
||||
font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
color: rgb(217, 217, 217);
|
||||
line-height: 1.6;
|
||||
background: rgb(45, 45, 45);
|
||||
}
|
||||
|
||||
span code,
|
||||
td code,
|
||||
th code,
|
||||
code,
|
||||
code[class*="language-"],
|
||||
.CodeMirror,
|
||||
pre.ag-paragraph {
|
||||
font-family: "DejaVu Sans Mono", "Source Code Pro", "Droid Sans Mono", Consolas, monospace;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
background: rgb(43, 43, 43);
|
||||
}
|
||||
::-webkit-scrollbar:vertical {
|
||||
width: 12px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: rgb(55, 55, 55);
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #3F3F3F;
|
||||
}
|
||||
|
||||
#ag-editor-id {
|
||||
max-width: var(--editorAreaWidth);
|
||||
margin: 0 auto;
|
||||
padding: 20px 50px 40px 50px;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
|
||||
#ag-editor-id, [contenteditable] {
|
||||
outline: none;
|
||||
caret-color: #efefef;
|
||||
}
|
||||
|
||||
.ag-float-box {
|
||||
background: #303133;
|
||||
border: 1px solid #303133;
|
||||
}
|
||||
.ag-float-item {
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.ag-float-item-active {
|
||||
background: #606266;
|
||||
color: #C0C4CC;
|
||||
}
|
||||
|
||||
.ag-table-picker {
|
||||
background: #606266;
|
||||
border: 1px solid #606266;
|
||||
}
|
||||
|
||||
[x-placement] > .ag-popper-arrow {
|
||||
border: 1px solid #606266;
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
figure.ag-active.ag-container-block > div.ag-container-preview {
|
||||
background: rgb(50, 50, 50);
|
||||
border: 1px solid rgb(43, 43, 43);
|
||||
}
|
||||
|
||||
.ag-gray {
|
||||
color: #909399;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.el-dialog {
|
||||
background: rgb(43, 43, 43);
|
||||
}
|
||||
|
||||
.v-modal {
|
||||
backdrop-filter: blur(5px);
|
||||
background: rgba(0, 0, 0, .9);
|
||||
}
|
||||
|
||||
body > *:first-child {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
body>*:last-child {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #4183C4;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
position: relative;
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
font-weight: bold;
|
||||
line-height: 1.4;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
h1:hover a.anchor,
|
||||
h2:hover a.anchor,
|
||||
h3:hover a.anchor,
|
||||
h4:hover a.anchor,
|
||||
h5:hover a.anchor,
|
||||
h6:hover a.anchor {
|
||||
/*background: url("../../images/modules/styleguide/para.png") no-repeat 10px center;*/
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h1 tt,
|
||||
h1 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
h2 tt,
|
||||
h2 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
h3 tt,
|
||||
h3 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
h4 tt,
|
||||
h4 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
h5 tt,
|
||||
h5 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
h6 tt,
|
||||
h6 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
h1 {
|
||||
padding-bottom: .3em;
|
||||
font-size: 2.25em;
|
||||
line-height: 1.2;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
h2 {
|
||||
padding-bottom: .3em;
|
||||
font-size: 1.75em;
|
||||
line-height: 1.225;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.5em;
|
||||
line-height: 1.43;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1em;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
p,
|
||||
blockquote,
|
||||
ul,
|
||||
ol,
|
||||
dl,
|
||||
table {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
li>ol,
|
||||
li>ul {
|
||||
margin: 0 0;
|
||||
}
|
||||
|
||||
hr {
|
||||
height: 4px;
|
||||
padding: 0;
|
||||
margin: 16px 0;
|
||||
background-color: #545454;
|
||||
border: 0 none;
|
||||
overflow: hidden;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
p:not(.ag-active)[data-role="hr"]::before {
|
||||
background-color: #545454;
|
||||
}
|
||||
|
||||
body>h2:first-child {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
body>h1:first-child {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
body>h1:first-child+h2 {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
body>h3:first-child,
|
||||
body>h4:first-child,
|
||||
body>h5:first-child,
|
||||
body>h6:first-child {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
a:first-child h1,
|
||||
a:first-child h2,
|
||||
a:first-child h3,
|
||||
a:first-child h4,
|
||||
a:first-child h5,
|
||||
a:first-child h6 {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
h1 p,
|
||||
h2 p,
|
||||
h3 p,
|
||||
h4 p,
|
||||
h5 p,
|
||||
h6 p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
li p.first {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
li.ag-tight-list-item > p {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
ul:first-child,
|
||||
ol:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
ul:last-child,
|
||||
ol:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 4px solid #606266;
|
||||
padding: 0 15px;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
blockquote blockquote {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
table {
|
||||
padding: 0;
|
||||
word-break: initial;
|
||||
}
|
||||
|
||||
table tr {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
table thead tr,
|
||||
table tr:nth-child(2n) {
|
||||
background-color: #303133;
|
||||
}
|
||||
|
||||
table tr th {
|
||||
font-weight: bold;
|
||||
border: 2px solid #606266;
|
||||
text-align: left;
|
||||
margin: 0;
|
||||
padding: 6px 13px;
|
||||
}
|
||||
|
||||
table tr td {
|
||||
border: 1px solid #606266;
|
||||
text-align: left;
|
||||
margin: 0;
|
||||
padding: 6px 13px;
|
||||
}
|
||||
|
||||
table tr th:first-child,
|
||||
table tr td:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
table tr th:last-child,
|
||||
table tr td:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* custom add */
|
||||
span.ag-line code,
|
||||
th code,
|
||||
td code {
|
||||
border: none;
|
||||
padding: 2px 4px;
|
||||
border-radius: 3px;
|
||||
font-size: 90%;
|
||||
color: #efefef;
|
||||
background-color: #606266;
|
||||
border-radius: 4px;
|
||||
/*font-family: Menlo, Monaco, Consolas, "Courier New", monospace;*/
|
||||
}
|
||||
|
||||
@media print {
|
||||
html {
|
||||
font-size: 13px;
|
||||
}
|
||||
table,
|
||||
pre {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
pre {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
}
|
||||
|
||||
.ag-hide.ag-math > .ag-math-render {
|
||||
color: #efefef;
|
||||
}
|
||||
|
||||
blockquote .ag-hide.ag-math > .ag-math-render {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.ag-gray.ag-math > .ag-math-render {
|
||||
color: #333333;
|
||||
background: #f6f8fa;
|
||||
box-shadow: 0 2px 12px 0 rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
.ag-gray.ag-math > .ag-math-render::before {
|
||||
border-bottom-color: #f6f8fa;
|
||||
}
|
||||
|
||||
#ag-editor-id pre.ag-html-block {
|
||||
padding: 0 .5rem;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#ag-editor-id pre.ag-front-matter {
|
||||
background: transparent;
|
||||
border-bottom: 1px dashed #efefef;
|
||||
}
|
||||
|
||||
#ag-editor-id pre.ag-multiple-math {
|
||||
background: transparent;
|
||||
border: 1px solid #909399;
|
||||
}
|
||||
|
||||
#ag-editor-id span.ag-math-text,
|
||||
#ag-editor-id pre.ag-multiple-math span.ag-multiple-math-line {
|
||||
color: lightsalmon;
|
||||
}
|
||||
|
||||
#ag-editor-id div.ag-math-preview {
|
||||
background: #303133;
|
||||
border-color: #333;
|
||||
}
|
||||
|
||||
#ag-editor-id pre.ag-html-block {
|
||||
font-size: 90%;
|
||||
line-height: 1.6;
|
||||
background: var(--primaryColor);
|
||||
color: #777777;
|
||||
}
|
||||
|
||||
.ag-color-dark {
|
||||
color: #c6c6c6;
|
||||
}
|
||||
|
||||
/**
|
||||
* okaidia theme for JavaScript, CSS and HTML
|
||||
* Loosely based on Monokai textmate theme by http://www.monokai.nl/
|
||||
* @author ocodia
|
||||
*/
|
||||
|
||||
code[class*="language-"],
|
||||
pre.ag-paragraph {
|
||||
color: #f8f8f2;
|
||||
/*font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;*/
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre.ag-paragraph {
|
||||
padding: 1em;
|
||||
margin: 1em 0;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*="language-"],
|
||||
pre.ag-paragraph {
|
||||
background: #272822;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.constant,
|
||||
.token.symbol {
|
||||
color: #f92672;
|
||||
}
|
||||
|
||||
.token.boolean,
|
||||
.token.number {
|
||||
color: #ae81ff;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin {
|
||||
color: #a6e22e;
|
||||
}
|
||||
|
||||
.token.inserted {
|
||||
color: #22863a;
|
||||
background: #f0fff4;
|
||||
}
|
||||
|
||||
.token.deleted {
|
||||
color: #b31d28;
|
||||
background: #ffeef0;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string,
|
||||
.token.variable {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #e6db74;
|
||||
}
|
||||
|
||||
.token.keyword {
|
||||
color: #66d9ef;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important {
|
||||
color: #fd971f;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
|
@ -99,7 +99,6 @@ html, body {
|
||||
font-size: 16px;
|
||||
color: #303133;
|
||||
line-height: 1.6;
|
||||
background: rgb(252, 252, 252);
|
||||
}
|
||||
|
||||
span code,
|
||||
@ -113,19 +112,6 @@ pre.ag-paragraph {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
background: rgb(252, 252, 252);
|
||||
}
|
||||
::-webkit-scrollbar:vertical {
|
||||
width: 12px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #EBEEF5;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #E1E4EA;
|
||||
}
|
||||
|
||||
#ag-editor-id {
|
||||
max-width: var(--editorAreaWidth);
|
||||
margin: 0 auto;
|
||||
@ -136,17 +122,16 @@ pre.ag-paragraph {
|
||||
|
||||
#ag-editor-id, [contenteditable] {
|
||||
outline: none;
|
||||
caret-color: #000000;
|
||||
}
|
||||
|
||||
.ag-gray {
|
||||
color: #C0C4CC;
|
||||
color: var(--editorColor30);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.v-modal {
|
||||
backdrop-filter: blur(5px);
|
||||
background: rgba(230, 230, 230, .9);
|
||||
background: var(--floatBorderColor);
|
||||
}
|
||||
|
||||
body>*:first-child {
|
||||
@ -158,7 +143,7 @@ body>*:last-child {
|
||||
}
|
||||
|
||||
a {
|
||||
color: #4183C4;
|
||||
color: var(--themeColor);
|
||||
}
|
||||
|
||||
h1,
|
||||
@ -216,35 +201,27 @@ h6 code {
|
||||
}
|
||||
|
||||
h1 {
|
||||
padding-bottom: .3em;
|
||||
font-size: 2.25em;
|
||||
line-height: 1.2;
|
||||
border-bottom: 1px solid #eee;
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
padding-bottom: .3em;
|
||||
font-size: 1.75em;
|
||||
line-height: 1.225;
|
||||
border-bottom: 1px solid #eee;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.5em;
|
||||
line-height: 1.43;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.25em;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1em;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1em;
|
||||
color: #777;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
p,
|
||||
@ -271,10 +248,6 @@ hr {
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
p:not(.ag-active)[data-role="hr"]::before {
|
||||
background: gainsboro;
|
||||
}
|
||||
|
||||
body>h2:first-child {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
@ -317,6 +290,14 @@ h6 p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
li.ag-paragraph {
|
||||
color: var(--themeColor);
|
||||
}
|
||||
|
||||
li > * {
|
||||
color: var(--editorColor);
|
||||
}
|
||||
|
||||
li p.first {
|
||||
display: inline-block;
|
||||
}
|
||||
@ -342,9 +323,20 @@ ol:last-child {
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 4px solid #dddddd;
|
||||
padding: 0 15px;
|
||||
color: #777777;
|
||||
position: relative;
|
||||
padding: 0 30px;
|
||||
color: var(--editorColor50);
|
||||
}
|
||||
|
||||
blockquote::before {
|
||||
content: '';
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 2px;
|
||||
position: absolute;
|
||||
left: 13px;
|
||||
top: 0;
|
||||
background: var(--themeColor);
|
||||
}
|
||||
|
||||
blockquote blockquote {
|
||||
@ -363,19 +355,19 @@ table tr {
|
||||
|
||||
table thead tr,
|
||||
table tr:nth-child(2n) {
|
||||
background-color: #fafafa;
|
||||
background-color: var(--codeBlockBgColor);
|
||||
}
|
||||
|
||||
table tr th {
|
||||
font-weight: bold;
|
||||
border: 1px solid #ebeef5;
|
||||
border: 1px solid var(--editorColor10);
|
||||
text-align: left;
|
||||
margin: 0;
|
||||
padding: 6px 13px;
|
||||
}
|
||||
|
||||
table tr td {
|
||||
border: 1px solid #ebeef5;
|
||||
border: 1px solid var(--editorColor10);
|
||||
text-align: left;
|
||||
margin: 0;
|
||||
padding: 6px 13px;
|
||||
@ -394,7 +386,7 @@ table tr td:last-child {
|
||||
span code,
|
||||
td code,
|
||||
th code {
|
||||
background-color: rgba(27, 31, 35, 0.05);
|
||||
background-color: var(--codeBlockBgColor);
|
||||
border-radius: 3px;
|
||||
padding: 0;
|
||||
/*font-family: Menlo, Monaco, Consolas, "Courier New", monospace;*/
|
||||
@ -402,7 +394,7 @@ th code {
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
padding: 0.2em 0.4em;
|
||||
color: #24292e;
|
||||
color: var(--editorColor);
|
||||
}
|
||||
|
||||
:not(pre) > code[class*="language-"],
|
||||
@ -411,10 +403,10 @@ pre[class*="language-"] {
|
||||
overflow: visible;
|
||||
font-size: 90%;
|
||||
line-height: 1.6;
|
||||
background: #f6f8fa;
|
||||
background: var(--codeBlockBgColor);
|
||||
border: 0;
|
||||
border-radius: 3px;
|
||||
color: #777777;
|
||||
color: var(--editorColor50);
|
||||
}
|
||||
|
||||
@media print {
|
||||
@ -431,20 +423,20 @@ pre[class*="language-"] {
|
||||
}
|
||||
|
||||
.ag-hide.ag-math > .ag-math-render {
|
||||
color: #333333;
|
||||
color: var(--editorColor);
|
||||
}
|
||||
|
||||
blockquote .ag-hide.ag-math > .ag-math-render {
|
||||
color: #777777;
|
||||
color: var(--editorColor50);
|
||||
}
|
||||
|
||||
.ag-gray.ag-math > .ag-math-render {
|
||||
color: #f6f8fa;
|
||||
background: #333333;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.3);
|
||||
color: var(--editorColor);
|
||||
background: var(--floatBgColor);
|
||||
box-shadow: 0 4px 8px 0 var(--floatBorderColor);
|
||||
}
|
||||
.ag-gray.ag-math > .ag-math-render::before {
|
||||
border-bottom-color: #333333;
|
||||
border-bottom-color: var(--floatBgColor);
|
||||
}
|
||||
|
||||
#ag-editor-id pre.ag-html-block {
|
||||
@ -454,15 +446,7 @@ blockquote .ag-hide.ag-math > .ag-math-render {
|
||||
}
|
||||
|
||||
#ag-editor-id pre.ag-active.ag-html-block {
|
||||
background: #f6f8fa;
|
||||
}
|
||||
|
||||
p:not(.ag-active)[data-role="hr"]::before {
|
||||
background: gainsboro;
|
||||
}
|
||||
|
||||
.fg-color-dark {
|
||||
color: #303133;
|
||||
background: var(--codeBlockBgColor);
|
||||
}
|
||||
|
||||
/* prismjs default theme */
|
||||
|
@ -2,18 +2,17 @@
|
||||
<div
|
||||
class="editor-container"
|
||||
>
|
||||
<title-bar
|
||||
:project="projectTree"
|
||||
:pathname="pathname"
|
||||
:filename="filename"
|
||||
:active="windowActive"
|
||||
:word-count="wordCount"
|
||||
:theme="theme"
|
||||
:platform="platform"
|
||||
:is-saved="isSaved"
|
||||
></title-bar>
|
||||
<side-bar></side-bar>
|
||||
<div class="editor-middle">
|
||||
<side-bar></side-bar>
|
||||
<title-bar
|
||||
:project="projectTree"
|
||||
:pathname="pathname"
|
||||
:filename="filename"
|
||||
:active="windowActive"
|
||||
:word-count="wordCount"
|
||||
:platform="platform"
|
||||
:is-saved="isSaved"
|
||||
></title-bar>
|
||||
<recent
|
||||
v-if="!hasCurrentFile && init"
|
||||
></recent>
|
||||
@ -22,34 +21,28 @@
|
||||
:markdown="markdown"
|
||||
:filename="filename"
|
||||
:cursor="cursor"
|
||||
:theme="theme"
|
||||
:source-code="sourceCode"
|
||||
:show-tab-bar="showTabBar"
|
||||
:text-direction="textDirection"
|
||||
></editor-with-tabs>
|
||||
<aidou></aidou>
|
||||
<upload-image></upload-image>
|
||||
<about-dialog></about-dialog>
|
||||
<font></font>
|
||||
<rename></rename>
|
||||
<tweet></tweet>
|
||||
<import-modal></import-modal>
|
||||
</div>
|
||||
<bottom-bar
|
||||
:source-code="sourceCode"
|
||||
:theme="theme"
|
||||
></bottom-bar>
|
||||
<aidou></aidou>
|
||||
<upload-image></upload-image>
|
||||
<about-dialog></about-dialog>
|
||||
<font></font>
|
||||
<rename></rename>
|
||||
<tweet></tweet>
|
||||
<import-modal></import-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { remote } from 'electron'
|
||||
import { addStyles } from '@/util/theme'
|
||||
import { addStyles, addThemeStyle } from '@/util/theme'
|
||||
import Recent from '@/components/recent'
|
||||
import EditorWithTabs from '@/components/editorWithTabs'
|
||||
import TitleBar from '@/components/titleBar'
|
||||
import SideBar from '@/components/sideBar'
|
||||
import BottomBar from '@/components/bottomBar'
|
||||
import Aidou from '@/components/aidou/aidou'
|
||||
import UploadImage from '@/components/uploadImage'
|
||||
import AboutDialog from '@/components/about'
|
||||
@ -69,7 +62,6 @@
|
||||
EditorWithTabs,
|
||||
TitleBar,
|
||||
SideBar,
|
||||
BottomBar,
|
||||
UploadImage,
|
||||
AboutDialog,
|
||||
Font,
|
||||
@ -104,6 +96,13 @@
|
||||
return this.markdown !== undefined
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
theme: function (value, oldValue) {
|
||||
if (value !== oldValue) {
|
||||
addThemeStyle(value)
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
const { dispatch } = this.$store
|
||||
// store/index.js
|
||||
@ -182,7 +181,15 @@
|
||||
|
||||
<style scoped>
|
||||
.editor-container {
|
||||
padding-top: var(--titleBarHeight);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
position: absolute;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.editor-container .hide {
|
||||
z-index: -1;
|
||||
@ -192,7 +199,9 @@
|
||||
}
|
||||
.editor-middle {
|
||||
display: flex;
|
||||
min-height: calc(100vh - var(--titleBarHeight));
|
||||
flex: 1;
|
||||
min-height: 100vh;
|
||||
position: relative;
|
||||
& > .editor {
|
||||
flex: 1;
|
||||
}
|
||||
|
1
src/renderer/assets/icons/undraw_content.svg
Normal file
1
src/renderer/assets/icons/undraw_content.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 48 KiB |
1
src/renderer/assets/icons/undraw_empty.svg
Normal file
1
src/renderer/assets/icons/undraw_empty.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 34 KiB |
1
src/renderer/assets/icons/undraw_folder.svg
Normal file
1
src/renderer/assets/icons/undraw_folder.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 19 KiB |
1
src/renderer/assets/icons/undraw_toc_empty.svg
Normal file
1
src/renderer/assets/icons/undraw_toc_empty.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 10 KiB |
@ -1,19 +1,62 @@
|
||||
/* Common CSS use by both light and dark themes */
|
||||
:root {
|
||||
--primary: #409eff;
|
||||
--info: #909399;
|
||||
--warning: rgb(255, 130, 0);
|
||||
--error: rgb(242, 19, 93);
|
||||
--lightBarColor: rgb(245, 245, 245);
|
||||
--lightTabColor: rgb(243, 243, 243);
|
||||
--darkBgColor: rgb(45, 45, 45);
|
||||
--darkInputBgColor: rgb(54, 55, 49);
|
||||
--darkInputColor: rgb(255, 255, 255);
|
||||
--darkHoverColor: rgb(70, 70, 70);
|
||||
--titleBarHeight: 25px;
|
||||
--titleBarHeight: 32px;
|
||||
--editorAreaWidth: 700px;
|
||||
--lightBgHighlightColor: rgb(246, 248, 249);
|
||||
--darkBgHighlightColor: rgb(40, 40, 40);
|
||||
/*editor*/
|
||||
--themeColor: rgba(33, 181, 111, 1);
|
||||
--highlightColor: rgba(33, 181, 111, .7);
|
||||
--selectionColor: rgba(33, 181, 111, .4);
|
||||
--editorColor: rgba(0, 0, 0, .8);
|
||||
--editorColor50: rgba(0, 0, 0, .5);
|
||||
--editorColor30: rgba(0, 0, 0, .3);
|
||||
--editorColor10: rgba(0, 0, 0, .1);
|
||||
--editorBgColor: rgba(255, 255, 255, 1);
|
||||
--deleteColor: #ff6969;
|
||||
--iconColor: #333;
|
||||
--codeBgColor: #d8d8d869;
|
||||
--codeBlockBgColor: rgba(33, 181, 111, 0.08);
|
||||
/*marktext*/
|
||||
--sideBarColor: rgba(0, 0, 0, .6);
|
||||
--sideBarTitleColor: rgba(0, 0, 0, 1);
|
||||
--sideBarTextColor: rgba(0, 0, 0, .4);
|
||||
--sideBarBgColor: rgba(242, 242, 242, 0.9);
|
||||
--sideBarItemHoverBgColor: rgba(0, 0, 0, .03);
|
||||
--itemBgColor: rgba(255, 255, 255, 0.6);
|
||||
--floatBgColor: #fff;
|
||||
--floatHoverColor: rgba(0, 0, 0, .04);
|
||||
--floatBorderColor: rgba(0, 0, 0, .1);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
background: var(--floatHoverColor);
|
||||
}
|
||||
::-webkit-scrollbar:vertical {
|
||||
width: 12px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--editorColor10);
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--editorColor30);
|
||||
}
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent !important;
|
||||
caret-color: var(--editorColor);
|
||||
}
|
||||
|
||||
body {
|
||||
position: fixed;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 1em; height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
@ -26,3 +69,35 @@
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* cover Element style*/
|
||||
.el-tooltip__popper.is-dark {
|
||||
background: var(--floatBgColor);
|
||||
color: var(--sideBarColor);
|
||||
box-shadow: 0 4px 8px 0 var(--floatBorderColor);
|
||||
border: solid 1px var(--floatBorderColor);
|
||||
}
|
||||
|
||||
.el-tooltip__popper.is-dark .popper__arrow {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.el-slider__button {
|
||||
border-color: var(--themeColor);
|
||||
}
|
||||
|
||||
.el-slider__bar {
|
||||
background-color: var(--themeColor);
|
||||
}
|
||||
|
||||
.ag-dialog-table {
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px 0 var(--floatBorderColor);
|
||||
border: solid 1px var(--floatBorderColor);
|
||||
background-color: var(--floatBgColor);
|
||||
}
|
||||
|
||||
.ag-dialog-table .dialog-title svg {
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="about-dialog" :class="theme">
|
||||
<div class="about-dialog">
|
||||
<el-dialog
|
||||
:visible.sync="showAboutDialog"
|
||||
:show-close="false"
|
||||
@ -10,7 +10,7 @@
|
||||
<img class="logo" src="../../assets/images/logo.png" />
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<h3 class="text fg-color-dark">{{ name }}</h3>
|
||||
<h3 class="title">{{ name }}</h3>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<div class="text">{{ appVersion }}</div>
|
||||
@ -37,8 +37,7 @@
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
'appVersion': state => state.appVersion,
|
||||
'theme': state => state.preferences.theme
|
||||
'appVersion': state => state.appVersion
|
||||
})
|
||||
},
|
||||
created () {
|
||||
@ -62,15 +61,24 @@
|
||||
display: block;
|
||||
}
|
||||
|
||||
.about-dialog .logo {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
.about-dialog img.logo {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
display: inherit;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.about-dialog .title,
|
||||
.about-dialog .text {
|
||||
text-align: center;
|
||||
min-height: 32px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.about-dialog .title {
|
||||
color: var(--sideBarTitleColor);
|
||||
}
|
||||
|
||||
.about-dialog .text {
|
||||
color: var(--sideBarTextColor);
|
||||
}
|
||||
</style>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="aidou" :class="theme">
|
||||
<div class="aidou">
|
||||
<el-dialog
|
||||
:visible.sync="showAiDou"
|
||||
:show-close="false"
|
||||
@ -105,9 +105,6 @@
|
||||
'aiList': state => state.aidou.aiList,
|
||||
'aiLoading': state => state.aidou.aiLoading
|
||||
}),
|
||||
...mapState({
|
||||
'theme': state => state.preferences.theme
|
||||
}),
|
||||
emojis () {
|
||||
return this.aiList.map(e => {
|
||||
e.collected = this.collection.findIndex(c => c.link === e.link) > -1
|
||||
@ -253,14 +250,17 @@
|
||||
align-items: center;
|
||||
height: auto;
|
||||
padding: 5px;
|
||||
background: #fff;
|
||||
box-shadow: 0 3px 8px rgba(0, 0, 0, .1);
|
||||
border: 1px solid #eeeeee;
|
||||
color: var(--editorColor);
|
||||
background: var(--floatBgColor);
|
||||
box-shadow: 0 3px 8px 3px var(--floatHoverColor);
|
||||
border: 1px solid var(--floatBorderColor);
|
||||
border-radius: 3px;
|
||||
}
|
||||
.input-wrapper {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
border: 1px solid var(--sideBarTextColor);
|
||||
border-radius: 14px;
|
||||
}
|
||||
.search {
|
||||
width: 100%;
|
||||
@ -270,18 +270,19 @@
|
||||
font-size: 14px;
|
||||
padding: 0 8px;
|
||||
margin: 0 10px;
|
||||
color: #606266;
|
||||
color: var(--editorColor);
|
||||
background: transparent;
|
||||
}
|
||||
.search-wrapper svg {
|
||||
cursor: pointer;
|
||||
margin: 0 5px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
color: #606266;
|
||||
color: var(--iconColor);
|
||||
transition: all .3s ease-in-out;
|
||||
}
|
||||
.search-wrapper svg:hover {
|
||||
color: var(--activeColor);
|
||||
color: var(--themeColor);
|
||||
}
|
||||
ul.history {
|
||||
display: flex;
|
||||
@ -312,12 +313,12 @@
|
||||
}
|
||||
ul.history .clear-history span {
|
||||
font-size: 12px;
|
||||
color: #C0C4CC;
|
||||
color: var(--themeColor);
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
ul.history li.active {
|
||||
background: #EBEEF5;
|
||||
background: var(--floatHoverColor);
|
||||
}
|
||||
ul.history:hover li {
|
||||
background: transparent;
|
||||
@ -326,7 +327,7 @@
|
||||
display: block;
|
||||
}
|
||||
ul.history li:hover {
|
||||
background: #EBEEF5;
|
||||
background: var(--floatHoverColor);
|
||||
}
|
||||
.image-container {
|
||||
height: 410px;
|
||||
@ -358,7 +359,7 @@
|
||||
display: none;
|
||||
}
|
||||
.image-container .img-wrapper > svg.active {
|
||||
color: var(--activeColor);
|
||||
color: var(--themeColor);
|
||||
}
|
||||
.image-container .img-wrapper:hover > svg {
|
||||
display: block;
|
||||
@ -378,20 +379,4 @@
|
||||
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
|
||||
opacity: 0;
|
||||
}
|
||||
/* style for dark theme */
|
||||
.dark .search-wrapper {
|
||||
background: var(--darkInputBgColor);
|
||||
border-color: transparent;
|
||||
& input {
|
||||
background: transparent;
|
||||
color: var(--darkInputColor);
|
||||
}
|
||||
}
|
||||
.dark ul.history li.active {
|
||||
background: rgb(39, 39, 39);
|
||||
}
|
||||
.dark ul.history li:hover {
|
||||
background: rgb(39, 39, 39);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -50,15 +50,15 @@ export default {
|
||||
animation: 3s infinite linear;
|
||||
}
|
||||
.loader span:nth-child(1) {
|
||||
background: #F2F6FC;
|
||||
background: var(--themeColor);
|
||||
animation: kiri 1.2s infinite linear;
|
||||
}
|
||||
.loader span:nth-child(2) {
|
||||
z-index: 100;
|
||||
background: #EBEEF5;
|
||||
background: var(--highlightColor);
|
||||
}
|
||||
.loader span:nth-child(3) {
|
||||
background: #C0C4CC;
|
||||
background: var(--selectionColor);
|
||||
animation: kanan 1.2s infinite linear;
|
||||
}
|
||||
|
||||
|
@ -1,36 +0,0 @@
|
||||
<template>
|
||||
<div class="bottom-bar" :class="theme">
|
||||
<search
|
||||
v-if="!sourceCode"
|
||||
:theme="theme"
|
||||
></search>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Search from './search'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Search
|
||||
},
|
||||
props: {
|
||||
sourceCode: Boolean,
|
||||
theme: String
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.bottom-bar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgb(245, 245, 245);
|
||||
}
|
||||
/* dark theme */
|
||||
.dark {
|
||||
background: rgb(43, 43, 43);
|
||||
}
|
||||
</style>
|
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div
|
||||
class="editor-wrapper"
|
||||
:class="[{ 'typewriter': typewriter, 'focus': focus, 'source': sourceCode }, theme]"
|
||||
:style="{ 'color': theme === 'dark' ? darkColor : lightColor, 'lineHeight': lineHeight, 'fontSize': fontSize,
|
||||
:class="[{ 'typewriter': typewriter, 'focus': focus, 'source': sourceCode }]"
|
||||
:style="{ 'lineHeight': lineHeight, 'fontSize': fontSize,
|
||||
'font-family': editorFontFamily ? `${editorFontFamily}, ${defaultFontFamily}` : `${defaultFontFamily}` }"
|
||||
:dir="textDirection"
|
||||
>
|
||||
@ -20,9 +20,7 @@
|
||||
dir='ltr'
|
||||
>
|
||||
<div slot="title" class="dialog-title">
|
||||
<svg class="icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-table-3d"></use>
|
||||
</svg>
|
||||
Insert Table
|
||||
</div>
|
||||
<el-form :model="tableChecker" :inline="true">
|
||||
<el-form-item label="Rows">
|
||||
@ -47,17 +45,16 @@
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogTableVisible = false" size="mini">
|
||||
<svg class="icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-close"></use>
|
||||
</svg>
|
||||
Cancel
|
||||
</el-button>
|
||||
<el-button type="primary" @click="handleDialogTableConfirm" size="mini">
|
||||
<svg class="icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-gou"></use>
|
||||
</svg>
|
||||
Ok
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<search
|
||||
v-if="!sourceCode"
|
||||
></search>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -71,23 +68,24 @@
|
||||
import ImagePathPicker from 'muya/lib/ui/imagePicker'
|
||||
import FormatPicker from 'muya/lib/ui/formatPicker'
|
||||
import bus from '../../bus'
|
||||
import Search from '../search.vue'
|
||||
import { animatedScrollTo } from '../../util'
|
||||
import { showContextMenu } from '../../contextMenu/editor'
|
||||
import Printer from '@/services/printService'
|
||||
import { DEFAULT_EDITOR_FONT_FAMILY } from '@/config'
|
||||
import { addThemeStyle } from '@/util/theme'
|
||||
|
||||
import 'muya/themes/light.css'
|
||||
|
||||
const STANDAR_Y = 320
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Search
|
||||
},
|
||||
props: {
|
||||
filename: {
|
||||
type: String
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
markdown: String,
|
||||
cursor: Object,
|
||||
textDirection: {
|
||||
@ -138,13 +136,6 @@
|
||||
focus: function (value) {
|
||||
this.editor.setFocusMode(value)
|
||||
},
|
||||
theme: function (value, oldValue) {
|
||||
const { editor } = this
|
||||
if (value !== oldValue && editor) {
|
||||
editor.setTheme(value)
|
||||
addThemeStyle(value)
|
||||
}
|
||||
},
|
||||
fontSize: function (value, oldValue) {
|
||||
const { editor } = this
|
||||
if (value !== oldValue && editor) {
|
||||
@ -175,7 +166,6 @@
|
||||
this.printer = new Printer()
|
||||
const ele = this.$refs.editor
|
||||
const {
|
||||
theme,
|
||||
focus: focusMode,
|
||||
markdown,
|
||||
preferLooseListItem,
|
||||
@ -196,7 +186,6 @@
|
||||
Muya.use(ImagePathPicker)
|
||||
Muya.use(FormatPicker)
|
||||
const { container } = this.editor = new Muya(ele, {
|
||||
theme,
|
||||
focusMode,
|
||||
markdown,
|
||||
preferLooseListItem,
|
||||
@ -212,9 +201,6 @@
|
||||
this.scrollToCursor()
|
||||
}
|
||||
|
||||
// the default theme is light write in the store
|
||||
addThemeStyle(theme)
|
||||
|
||||
// listen for bus events.
|
||||
bus.$on('file-loaded', this.setMarkdownToEditor)
|
||||
bus.$on('undo', this.handleUndo)
|
||||
@ -336,7 +322,7 @@
|
||||
},
|
||||
|
||||
scrollToHeader (slug) {
|
||||
return this.scrollToElement(`[data-id="${slug}"]`)
|
||||
return this.scrollToElement(`#${slug}`)
|
||||
},
|
||||
|
||||
scrollToElement (selector) {
|
||||
@ -445,7 +431,6 @@
|
||||
this.editor.copy(name)
|
||||
}
|
||||
},
|
||||
|
||||
beforeDestroy () {
|
||||
bus.$off('file-loaded', this.setMarkdownToEditor)
|
||||
bus.$off('undo', this.handleUndo)
|
||||
@ -479,6 +464,31 @@
|
||||
height: 100%;
|
||||
position: relative;
|
||||
flex: 1;
|
||||
color: var(--editorColor);
|
||||
& .ag-dialog-table {
|
||||
& .el-button {
|
||||
width: 70px;
|
||||
}
|
||||
& .el-button:focus,
|
||||
& .el-button:hover {
|
||||
color: var(--themeColor);
|
||||
border-color: var(--highlightColor);
|
||||
background-color: var(--selectionColor);
|
||||
}
|
||||
& .el-button--primary {
|
||||
color: #fff;
|
||||
background: var(--themeColor);
|
||||
border-color: var(--highlightColor);
|
||||
|
||||
}
|
||||
& .el-input-number.is-controls-right .el-input__inner {
|
||||
background: var(--itemBgColor);
|
||||
color: var(--editorColor);
|
||||
}
|
||||
& .el-input-number.is-controls-right .el-input__inner:focus {
|
||||
border-color: var(--themeColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
.editor-wrapper.source {
|
||||
position: absolute;
|
||||
@ -496,26 +506,4 @@
|
||||
padding-top: calc(50vh - 136px);
|
||||
padding-bottom: calc(50vh - 54px);
|
||||
}
|
||||
/* for dark theme */
|
||||
.dark.editor-wrapper,
|
||||
.dark.editor-wrapper #ag-editor-id {
|
||||
background: var(--darkBgColor);
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
.ag-dialog-table {
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 1px 3px rgba(230, 230, 230, .3);
|
||||
}
|
||||
|
||||
.dark .ag-dialog-table {
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
|
||||
}
|
||||
|
||||
.ag-dialog-table .dialog-title svg {
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
@ -5,7 +5,6 @@
|
||||
<tabs v-show="showTabBar"></tabs>
|
||||
<div class="container">
|
||||
<editor
|
||||
:theme="theme"
|
||||
:fileanme="filename"
|
||||
:markdown="markdown"
|
||||
:cursor="cursor"
|
||||
@ -13,7 +12,6 @@
|
||||
></editor>
|
||||
<source-code
|
||||
v-if="sourceCode"
|
||||
:theme="theme"
|
||||
:markdown="markdown"
|
||||
:cursor="cursor"
|
||||
:text-direction="textDirection"
|
||||
@ -29,10 +27,6 @@
|
||||
|
||||
export default {
|
||||
props: {
|
||||
theme: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
filename: {
|
||||
type: String
|
||||
},
|
||||
@ -69,11 +63,15 @@
|
||||
|
||||
<style scoped>
|
||||
.editor-with-tabs {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-top: var(--titleBarHeight);
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - var(--titleBarHeight));
|
||||
|
||||
overflow: hidden;
|
||||
background: var(--editorBgColor);
|
||||
& > .container {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
|
@ -1,7 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="source-code"
|
||||
:class="[theme]"
|
||||
ref="sourceCode"
|
||||
>
|
||||
</div>
|
||||
@ -10,15 +9,13 @@
|
||||
<script>
|
||||
import codeMirror, { setMode, setCursorAtLastLine, setTextDirection } from '../../codeMirror'
|
||||
import { wordCount as getWordCount } from 'muya/lib/utils'
|
||||
import { mapState } from 'vuex'
|
||||
import { adjustCursor } from '../../util'
|
||||
import bus from '../../bus'
|
||||
import { railscastsThemes } from '@/config'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
theme: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
markdown: String,
|
||||
cursor: Object,
|
||||
textDirection: {
|
||||
@ -27,6 +24,12 @@
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState({
|
||||
'theme': state => state.preferences.theme
|
||||
})
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
contentState: null,
|
||||
@ -35,18 +38,6 @@
|
||||
},
|
||||
|
||||
watch: {
|
||||
theme: function (value, oldValue) {
|
||||
const cm = this.$refs.sourceCode.querySelector('.CodeMirror')
|
||||
if (value !== oldValue) {
|
||||
if (value === 'dark') {
|
||||
cm.classList.remove('cm-s-default')
|
||||
cm.classList.add('cm-s-railscasts')
|
||||
} else {
|
||||
cm.classList.add('cm-s-default')
|
||||
cm.classList.remove('cm-s-railscasts')
|
||||
}
|
||||
}
|
||||
},
|
||||
textDirection: function (value, oldValue) {
|
||||
const { editor } = this
|
||||
if (value !== oldValue && editor) {
|
||||
@ -74,7 +65,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
if (theme === 'dark') codeMirrorConfig.theme = 'railscasts'
|
||||
if (railscastsThemes.includes(theme)) {
|
||||
codeMirrorConfig.theme = 'railscasts'
|
||||
}
|
||||
const editor = this.editor = codeMirror(container, codeMirrorConfig)
|
||||
bus.$on('file-loaded', this.setMarkdown)
|
||||
bus.$on('file-changed', this.handleMarkdownChange)
|
||||
@ -147,6 +140,7 @@
|
||||
.source-code .CodeMirror {
|
||||
margin: 50px auto;
|
||||
max-width: var(--editorAreaWidth);
|
||||
background: transparent;
|
||||
}
|
||||
.source-code .CodeMirror-gutters {
|
||||
border-right: none;
|
||||
@ -154,14 +148,6 @@
|
||||
}
|
||||
.source-code .CodeMirror-activeline-background,
|
||||
.source-code .CodeMirror-activeline-gutter {
|
||||
background: #F2F6FC;
|
||||
}
|
||||
.source-code.dark,
|
||||
.source-code.dark .CodeMirror {
|
||||
background: var(--darkBgColor);
|
||||
}
|
||||
.dark.source-code .CodeMirror-activeline-background,
|
||||
.dark.source-code .CodeMirror-activeline-gutter {
|
||||
background: #333;
|
||||
background: var(--floatHoverColor);
|
||||
}
|
||||
</style>
|
||||
|
@ -1,7 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="editor-tabs"
|
||||
:class="theme"
|
||||
>
|
||||
<ul class="tabs-container">
|
||||
<li
|
||||
@ -37,7 +36,6 @@
|
||||
mixins: [tabsMixins],
|
||||
computed: {
|
||||
...mapState({
|
||||
theme: state => state.preferences.theme,
|
||||
currentFile: state => state.editor.currentFile,
|
||||
tabs: state => state.editor.tabs
|
||||
})
|
||||
@ -54,7 +52,6 @@
|
||||
.editor-tabs {
|
||||
width: 100%;
|
||||
height: 35px;
|
||||
background: var(--lightBarColor);
|
||||
user-select: none;
|
||||
}
|
||||
.tabs-container {
|
||||
@ -70,21 +67,13 @@
|
||||
& > li {
|
||||
position: relative;
|
||||
padding: 0 8px;
|
||||
color: var(--secondaryColor);
|
||||
color: var(--editorColor50);
|
||||
font-size: 12px;
|
||||
line-height: 35px;
|
||||
height: 35px;
|
||||
background: var(--lightTabColor);
|
||||
background: var(--floatBgColor);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
&:not(:last-child):before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 20%;
|
||||
right: 0;
|
||||
border-right: 1px solid #fff;
|
||||
height: 60%;
|
||||
}
|
||||
& > svg {
|
||||
opacity: 0;
|
||||
}
|
||||
@ -99,7 +88,7 @@
|
||||
}
|
||||
}
|
||||
& > li.active {
|
||||
background: #fff;
|
||||
background: var(--itemBgColor);
|
||||
&:not(:last-child):after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
@ -107,7 +96,7 @@
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background: var(--primary);
|
||||
background: var(--themeColor);
|
||||
}
|
||||
& > svg {
|
||||
opacity: 1;
|
||||
@ -125,16 +114,4 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.editor-tabs.dark {
|
||||
background: var(--darkBgColor);
|
||||
}
|
||||
.editor-tabs.dark ul li {
|
||||
background: var(--darkBgColor);
|
||||
&:not(:last-child):before {
|
||||
border-right-color: var(--darkHoverColor);
|
||||
}
|
||||
&.active {
|
||||
color: var(--lightBorder);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="font" :class="theme">
|
||||
<div class="font">
|
||||
<el-dialog
|
||||
:visible.sync="showFontSetting"
|
||||
:show-close="false"
|
||||
@ -56,7 +56,6 @@
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
'theme': state => state.preferences.theme,
|
||||
'fontSize': state => state.preferences.fontSize,
|
||||
'lightColor': state => state.preferences.lightColor,
|
||||
'darkColor': state => state.preferences.darkColor,
|
||||
|
@ -81,19 +81,20 @@ export default {
|
||||
<style scoped>
|
||||
.drop-container {
|
||||
border-radius: 5px;
|
||||
border: 2px dashed #9c9c9c;
|
||||
color: var(--sideBarColor);
|
||||
border: 1px dashed var(--sideBarTextColor);
|
||||
& div,
|
||||
& p {
|
||||
text-align: center;
|
||||
}
|
||||
&.active {
|
||||
border: 2px dashed #409eff;
|
||||
background-color: rgba(32, 159, 255, 0.06);
|
||||
border: 1px dashed var(--themeColor);
|
||||
background-color: var(--itemBgColor);
|
||||
}
|
||||
}
|
||||
.img-wrapper {
|
||||
width: 70px;
|
||||
height: 100px;
|
||||
width: 50px;
|
||||
height: 70px;
|
||||
margin: 40px auto 0 auto;
|
||||
& img {
|
||||
width: 100%;
|
||||
@ -107,12 +108,12 @@ export default {
|
||||
& div {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
border: 1px solid #eee;
|
||||
border: 1px solid var(--sideBarTextColor);
|
||||
border-radius: 3px;
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
line-height: 70px;
|
||||
color: #999;
|
||||
color: var(--sideBarTitleColor);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,20 +1,25 @@
|
||||
<template>
|
||||
<div
|
||||
class="recent-files-projects"
|
||||
:class="theme"
|
||||
@click="newFile"
|
||||
>
|
||||
<div class="button-group">
|
||||
<svg :viewBox="ContentIcon.viewBox" aria-hidden="true">
|
||||
<use :xlink:href="ContentIcon.url" />
|
||||
</svg>
|
||||
<a href="javascript:;" @click="newFile">
|
||||
New File
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import ContentIcon from '@/assets/icons/undraw_content.svg'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
...mapState({
|
||||
'theme': state => state.preferences.theme
|
||||
})
|
||||
data () {
|
||||
this.ContentIcon = ContentIcon
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
newFile () {
|
||||
@ -26,12 +31,32 @@
|
||||
|
||||
<style scoped>
|
||||
.recent-files-projects {
|
||||
background: var(--editorBgColor);
|
||||
flex: 1;
|
||||
}
|
||||
.dark.recent-files-projects {
|
||||
background: var(--darkBgColor);
|
||||
& > div {
|
||||
color: var(--baseBorder);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
& .button-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
& svg {
|
||||
width: 200px;
|
||||
fill: var(--themeColor);
|
||||
}
|
||||
& a {
|
||||
text-decoration: none;
|
||||
background: var(--themeColor);
|
||||
box-shadow: 0 0 8px 0 var(--selectionColor);
|
||||
display: block;
|
||||
padding: 4px 10px;
|
||||
border-radius: 5px;
|
||||
margin-top: 20px;
|
||||
color: #fff;
|
||||
&:active {
|
||||
opacity: .5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="rename" :class="theme">
|
||||
<div class="rename">
|
||||
<el-dialog
|
||||
:visible.sync="showRename"
|
||||
:show-close="false"
|
||||
@ -44,8 +44,7 @@
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
filename: state => state.editor.currentFile.filename,
|
||||
theme: state => state.preferences.theme
|
||||
filename: state => state.editor.currentFile.filename
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
@ -63,6 +62,10 @@
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.rename .el-dialog__header {
|
||||
height: 42px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.rename .el-dialog__body {
|
||||
display: none;
|
||||
}
|
||||
@ -84,13 +87,16 @@
|
||||
align-items: center;
|
||||
height: auto;
|
||||
padding: 5px;
|
||||
background: #fff;
|
||||
box-shadow: 0 3px 8px rgba(0, 0, 0, .1);
|
||||
border: 1px solid #eeeeee;
|
||||
background: var(--floatBorderColor);
|
||||
box-shadow: 0 3px 8px var(--floatBorderColor);
|
||||
border: 1px solid var(--floatBorderColor);
|
||||
border-radius: 3px;
|
||||
& .input-wrapper {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
& input {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
.search {
|
||||
@ -101,28 +107,17 @@
|
||||
font-size: 14px;
|
||||
padding: 0 8px;
|
||||
margin: 0 10px;
|
||||
color: #606266;
|
||||
color: var(--sideBarColor);
|
||||
}
|
||||
.search-wrapper svg {
|
||||
cursor: pointer;
|
||||
margin: 0 5px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
color: #606266;
|
||||
color: var(--iconColor);
|
||||
transition: all .3s ease-in-out;
|
||||
}
|
||||
.search-wrapper svg:hover {
|
||||
color: var(--activeColor);
|
||||
color: var(--themeColor);
|
||||
}
|
||||
|
||||
/* style for dark theme */
|
||||
.dark .search-wrapper {
|
||||
background: var(--darkInputBgColor);
|
||||
border-color: transparent;
|
||||
& input {
|
||||
background: transparent;
|
||||
color: var(--darkInputColor);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<div class="search-bar"
|
||||
:class="theme"
|
||||
@click.stop="noop"
|
||||
v-show="showSearch"
|
||||
>
|
||||
@ -29,7 +28,7 @@
|
||||
:visible-arrow="false"
|
||||
:open-delay="1000"
|
||||
>
|
||||
<button class="button" @click="caseClick" :class="{ 'active': caseSensitive }">
|
||||
<button class="button left" @click="caseClick" :class="{ 'active': caseSensitive }">
|
||||
<svg class="icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-case"></use>
|
||||
</svg>
|
||||
@ -46,19 +45,19 @@
|
||||
>
|
||||
<span class="search-result">{{`${highlightIndex + 1} / ${highlightCount}`}}</span>
|
||||
</div>
|
||||
<button class="button" @click="find('prev')">
|
||||
<button class="button right" @click="find('prev')">
|
||||
<svg class="icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-arrow-up"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="button" @click="find('next')">
|
||||
<button class="button right" @click="find('next')">
|
||||
<svg class="icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-arrowdown"></use>
|
||||
</svg>
|
||||
</button>
|
||||
</section>
|
||||
<section class="replace" v-if="type === 'replace'">
|
||||
<button class="button active" @click="typeClick">
|
||||
<button class="button active left" @click="typeClick">
|
||||
<svg class="icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-findreplace"></use>
|
||||
</svg>
|
||||
@ -73,7 +72,7 @@
|
||||
:visible-arrow="false"
|
||||
:open-delay="1000"
|
||||
>
|
||||
<button class="button" @click="replace(false)">
|
||||
<button class="button right" @click="replace(false)">
|
||||
<svg class="icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-all-inclusive"></use>
|
||||
</svg>
|
||||
@ -86,7 +85,7 @@
|
||||
:visible-arrow="false"
|
||||
:open-delay="1000"
|
||||
>
|
||||
<button class="button" @click="replace(true)">
|
||||
<button class="button right" @click="replace(true)">
|
||||
<svg class="icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-replace"></use>
|
||||
</svg>
|
||||
@ -101,9 +100,6 @@
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
theme: String
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
showSearch: false,
|
||||
@ -219,8 +215,15 @@
|
||||
|
||||
<style scoped>
|
||||
.search-bar {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
width: 400px;
|
||||
padding: 5px;
|
||||
top: 0;
|
||||
right: 20px;
|
||||
box-shadow: 0 4px 8px 0 var(--floatBorderColor);
|
||||
border: 1px solid var(--floatBorderColor);
|
||||
border-radius: 5px;
|
||||
background: var(--floatBgColor);
|
||||
}
|
||||
.search {
|
||||
margin-bottom: 5px;
|
||||
@ -228,6 +231,7 @@
|
||||
.search, .replace {
|
||||
height: 30px;
|
||||
display: flex;
|
||||
padding: 0 10px;
|
||||
}
|
||||
.search-bar .button {
|
||||
outline: none;
|
||||
@ -236,65 +240,55 @@
|
||||
background: transparent;
|
||||
box-sizing: border-box;
|
||||
height: 30px;
|
||||
width: 50px;
|
||||
width: 30px;
|
||||
text-align: center;
|
||||
padding: 3px 5px;
|
||||
padding: 5px;
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
color: var(--iconColor);
|
||||
&.left {
|
||||
margin-right: 10px;
|
||||
}
|
||||
&.right {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
.button.active {
|
||||
color: rgb(242, 134, 94);
|
||||
color: var(--themeColor);
|
||||
}
|
||||
.search-bar .button > svg {
|
||||
width: 1.6em;
|
||||
height: 1.6em;
|
||||
}
|
||||
.search-bar .button:hover {
|
||||
background: #EBEEF5;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
.search-bar .button:active {
|
||||
background: #DCDFE6;
|
||||
opacity: .5;
|
||||
}
|
||||
.input-wrapper {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
position: relative;
|
||||
margin-right: 5px;
|
||||
background: var(--floatHoverColor);
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.input-wrapper .search-result {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
right: 5px;
|
||||
right: 10px;
|
||||
font-size: 12px;
|
||||
color: #C0C4CC;
|
||||
color: var(--sideBarTitleColor);
|
||||
}
|
||||
.input-wrapper input {
|
||||
flex: 1;
|
||||
padding: 0 8px;
|
||||
height: 30px;
|
||||
outline: none;
|
||||
border: none;
|
||||
box-sizing: border-box;
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
color: var(--editorColor);
|
||||
padding: 0 8px;
|
||||
background: rgb(252, 252, 252);
|
||||
}
|
||||
/* css for dark theme*/
|
||||
.dark {
|
||||
caret-color: #efefef;
|
||||
color: #606266;
|
||||
}
|
||||
.dark input {
|
||||
background: rgb(54, 55, 49);
|
||||
color: #C0C4CC;
|
||||
}
|
||||
.dark .button:hover {
|
||||
background: rgb(71, 72, 66);
|
||||
color: #C0C4CC;
|
||||
}
|
||||
.dark .button:active {
|
||||
background: #303133;
|
||||
background: transparent;
|
||||
}
|
||||
</style>
|
||||
|
@ -4,7 +4,7 @@
|
||||
class="side-bar-file"
|
||||
:style="{'padding-left': `${depth * 5 + 15}px`, 'opacity': file.isMarkdown ? 1 : 0.75 }"
|
||||
@click="handleFileClick()"
|
||||
:class="[{'current': currentFile.pathname === file.pathname, 'active': file.id === activeItem.id }, theme]"
|
||||
:class="[{'current': currentFile.pathname === file.pathname, 'active': file.id === activeItem.id }]"
|
||||
ref="file"
|
||||
>
|
||||
<file-icon
|
||||
@ -53,7 +53,6 @@
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
'theme': state => state.preferences.theme,
|
||||
'renameCache': state => state.project.renameCache,
|
||||
'activeItem': state => state.project.activeItem,
|
||||
'clipboard': state => state.project.clipboard,
|
||||
@ -103,7 +102,7 @@
|
||||
box-sizing: border-box;
|
||||
padding-right: 15px;
|
||||
&:hover {
|
||||
background: var(--extraLightBorder);
|
||||
background: var(--sideBarItemHoverBgColor);
|
||||
}
|
||||
& > span {
|
||||
overflow: hidden;
|
||||
@ -115,7 +114,7 @@
|
||||
position: absolute;
|
||||
display: block;
|
||||
left: 0;
|
||||
background: var(--activeColor);
|
||||
background: var(--themeColor);
|
||||
width: 2px;
|
||||
height: 0;
|
||||
top: 50%;
|
||||
@ -126,19 +125,21 @@
|
||||
.side-bar-file.current::before {
|
||||
height: 100%;
|
||||
}
|
||||
.side-bar-file.active {
|
||||
background: var(--lightBorder);
|
||||
.side-bar-file.current > span {
|
||||
color: var(--themeColor);
|
||||
}
|
||||
.side-bar-file.active > span {
|
||||
color: var(--sideBarTitleColor);
|
||||
}
|
||||
input.rename {
|
||||
height: 22px;
|
||||
outline: none;
|
||||
margin: 5px 0;
|
||||
border: 1px solid var(--lightBorder);
|
||||
padding: 0 8px;
|
||||
color: var(--sideBarColor);
|
||||
border: 1px solid var(--floatBorderColor);
|
||||
background: var(--floatBorderColor);
|
||||
width: 100%;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.dark.side-bar-file:hover {
|
||||
background: var(--darkHoverColor);
|
||||
color: var(--lightTabColor);
|
||||
}
|
||||
</style>
|
||||
|
@ -1,7 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="side-bar-folder"
|
||||
:class="theme"
|
||||
>
|
||||
<div
|
||||
class="folder-name" @click="folderNameClick"
|
||||
@ -80,7 +79,6 @@
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
'theme': state => state.preferences.theme,
|
||||
'renameCache': state => state.project.renameCache,
|
||||
'createCache': state => state.project.createCache,
|
||||
'activeItem': state => state.project.activeItem,
|
||||
@ -132,11 +130,11 @@
|
||||
padding-right: 15px;
|
||||
& > svg {
|
||||
flex-shrink: 0;
|
||||
color: darkgray;
|
||||
color: var(--iconColor);
|
||||
margin-right: 5px;
|
||||
}
|
||||
&:hover {
|
||||
background: var(--extraLightBorder);
|
||||
background: var(--sideBarItemHoverBgColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -144,12 +142,10 @@
|
||||
outline: none;
|
||||
height: 22px;
|
||||
margin: 5px 0;
|
||||
border: 1px solid var(--lightBorder);
|
||||
width: 100%;
|
||||
padding: 0 8px;
|
||||
border: 1px solid var(--floatBorderColor);
|
||||
background: var(--floatBorderColor);
|
||||
width: 70%;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.dark.side-bar-folder > .folder-name:hover {
|
||||
background-color: var(--darkHoverColor);
|
||||
color: var(--lightTabColor);
|
||||
}
|
||||
</style>
|
||||
|
@ -2,11 +2,10 @@
|
||||
<div
|
||||
v-show="showSideBar"
|
||||
class="side-bar"
|
||||
:class="[theme]"
|
||||
ref="sideBar"
|
||||
:style="{ 'width': `${finalSideBarWidth}px` }"
|
||||
>
|
||||
<div class="title-bar-bg" :class="[theme]"></div>
|
||||
<div class="title-bar-bg"></div>
|
||||
<div class="left-column">
|
||||
<ul>
|
||||
<li
|
||||
@ -75,7 +74,6 @@
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
'theme': state => state.preferences.theme,
|
||||
'rightColumn': state => state.layout.rightColumn,
|
||||
'showSideBar': state => state.layout.showSideBar,
|
||||
'projectTree': state => state.project.projectTree,
|
||||
@ -143,26 +141,13 @@
|
||||
<style scoped>
|
||||
.side-bar {
|
||||
display: flex;
|
||||
height: calc(100vh - var(--titleBarHeight));
|
||||
height: 100vh;
|
||||
position: relative;
|
||||
color: var(--secondaryColor);
|
||||
color: var(--sideBarColor);
|
||||
}
|
||||
.side-bar.light,
|
||||
.title-bar-bg.light {
|
||||
background: var(--lightBgHighlightColor);
|
||||
border-right: 1px solid rgb(242, 242, 242);
|
||||
}
|
||||
.side-bar.dark,
|
||||
.title-bar-bg.dark {
|
||||
background: var(--darkBgHighlightColor);
|
||||
}
|
||||
|
||||
.title-bar-bg {
|
||||
position: absolute;
|
||||
top: calc(-1 * var(--titleBarHeight));
|
||||
left: 0;
|
||||
height: var(--titleBarHeight);
|
||||
width: 100%;
|
||||
.side-bar {
|
||||
background: var(--sideBarBgColor);
|
||||
border-right: 1px solid var(--itemBgColor);
|
||||
}
|
||||
|
||||
.left-column {
|
||||
@ -171,6 +156,8 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
padding-top: 40px;
|
||||
box-sizing: border-box;
|
||||
& > ul {
|
||||
opacity: 1;
|
||||
}
|
||||
@ -195,15 +182,14 @@
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
opacity: 1;
|
||||
color: var(--secondaryColor);
|
||||
color: var(--iconColor);
|
||||
transition: transform .25s ease-in-out;
|
||||
}
|
||||
&:hover > svg {
|
||||
color: var(--primary);
|
||||
transform: scale(1.2);
|
||||
color: var(--themeColor);
|
||||
}
|
||||
&.active > svg {
|
||||
color: var(--primary);
|
||||
color: var(--themeColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -222,10 +208,10 @@
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 100%;
|
||||
width: 2px;
|
||||
width: 8px;
|
||||
cursor: col-resize;
|
||||
&:hover {
|
||||
background: var(--secondaryColor);
|
||||
border-right: 2px solid var(--sideBarTextColor);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -2,15 +2,14 @@
|
||||
<div
|
||||
class="side-bar-list-file"
|
||||
@click="handleFileClick"
|
||||
:class="[{ 'active': file.pathname === currentFile.pathname }, theme]"
|
||||
:class="[{ 'active': file.pathname === currentFile.pathname }]"
|
||||
>
|
||||
<div class="title">
|
||||
<span class="filename">{{ filename }}</span>
|
||||
<span>{{ extension }}</span>
|
||||
<span class="filename">{{ filename + extension }}</span>
|
||||
<span class="birth-time">{{ relativeTime }}</span>
|
||||
</div>
|
||||
<div class="folder-date">
|
||||
<span class="folder">{{parent}}</span>
|
||||
<span class="birth-time">{{ new Date(file.birthTime).toLocaleString().split(/\s/)[0] }}</span>
|
||||
</div>
|
||||
<div class="content">
|
||||
{{ file.data.markdown.substring(0, 50) }}
|
||||
@ -23,6 +22,7 @@
|
||||
import { mapState } from 'vuex'
|
||||
import { fileMixins } from '../../mixins'
|
||||
import { PATH_SEPARATOR } from '../../config'
|
||||
import dayjs from '@/util/day'
|
||||
|
||||
export default {
|
||||
mixins: [fileMixins],
|
||||
@ -34,7 +34,6 @@
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
theme: state => state.preferences.theme,
|
||||
tabs: state => state.editor.tabs,
|
||||
currentFile: state => state.editor.currentFile
|
||||
}),
|
||||
@ -44,6 +43,10 @@
|
||||
return path.basename(this.file.name, path.extname(this.file.name))
|
||||
},
|
||||
|
||||
relativeTime () {
|
||||
return dayjs(+new Date(this.file.birthTime)).fromNow()
|
||||
},
|
||||
|
||||
// Return the filename extension or null.
|
||||
extension () {
|
||||
return path.extname(this.file.name)
|
||||
@ -63,20 +66,20 @@
|
||||
position: relative;
|
||||
user-select: none;
|
||||
padding: 10px 20px;
|
||||
color: var(--secondaryColor);
|
||||
color: var(--sideBarColor);
|
||||
font-size: 14px;
|
||||
& .title .filename {
|
||||
font-size: 15px;
|
||||
}
|
||||
&:hover {
|
||||
background: var(--extraLightBorder);
|
||||
background: var(--sideBarItemHoverBgColor);
|
||||
}
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
display: block;
|
||||
left: 0;
|
||||
background: var(--activeColor);
|
||||
background: var(--themeColor);
|
||||
width: 2px;
|
||||
height: 0;
|
||||
top: 50%;
|
||||
@ -86,28 +89,33 @@
|
||||
}
|
||||
.side-bar-list-file.active {
|
||||
font-weight: 600;
|
||||
color: var(--regularColor);
|
||||
.title {
|
||||
color: var(--themeColor);
|
||||
}
|
||||
}
|
||||
.side-bar-list-file.active::before {
|
||||
height: 100%;
|
||||
}
|
||||
.title {
|
||||
display: flex;
|
||||
color: var(--sideBarTitleColor);
|
||||
& .filename {
|
||||
flex: 1;
|
||||
}
|
||||
& .birth-time {
|
||||
color: var(--sideBarTextColor);
|
||||
}
|
||||
}
|
||||
.folder-date {
|
||||
margin-top: 5px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.folder-date .folder,
|
||||
.content {
|
||||
width: 100%;
|
||||
margin-top: 5px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.dark.side-bar-list-file.active {
|
||||
color: var(--lightTabColor);
|
||||
}
|
||||
.dark.side-bar-list-file:hover {
|
||||
background: var(--darkHoverColor);
|
||||
color: var(--lightTabColor);
|
||||
color: var(--sideBarTextColor);
|
||||
}
|
||||
</style>
|
||||
|
@ -3,7 +3,7 @@
|
||||
class="opened-file"
|
||||
:title="file.pathname"
|
||||
@click="selectFile(file)"
|
||||
:class="[{'active': currentFile.id === file.id, 'unsaved': !file.isSaved }, theme]"
|
||||
:class="[{'active': currentFile.id === file.id, 'unsaved': !file.isSaved }]"
|
||||
>
|
||||
<svg class="icon" aria-hidden="true"
|
||||
@click.stop="removeFileInTab(file)"
|
||||
@ -28,7 +28,6 @@
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
'theme': state => state.preferences.theme,
|
||||
'currentFile': state => state.editor.currentFile
|
||||
})
|
||||
}
|
||||
@ -43,7 +42,7 @@
|
||||
line-height: 28px;
|
||||
padding-left: 30px;
|
||||
position: relative;
|
||||
color: var(--regularColor);
|
||||
color: var(--sideBarColor);
|
||||
& > svg {
|
||||
display: none;
|
||||
width: 10px;
|
||||
@ -56,7 +55,7 @@
|
||||
display: inline-block;
|
||||
}
|
||||
&:hover {
|
||||
background: var(--extraLightBorder);
|
||||
background: var(--sideBarItemHoverBgColor);
|
||||
}
|
||||
& > span {
|
||||
overflow: hidden;
|
||||
@ -65,14 +64,14 @@
|
||||
}
|
||||
}
|
||||
.opened-file.active {
|
||||
color: var(--primary);
|
||||
color: var(--themeColor);
|
||||
}
|
||||
.unsaved.opened-file::before {
|
||||
content: '';
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 50%;
|
||||
background: var(--warning);
|
||||
background: var(--themeColor);
|
||||
position: absolute;
|
||||
top: 11px;
|
||||
left: 12px;
|
||||
@ -80,8 +79,4 @@
|
||||
.unsaved.opened-file:hover::before {
|
||||
content: none;
|
||||
}
|
||||
.dark.opened-file:hover {
|
||||
background: var(--darkHoverColor);
|
||||
color: var(--lightTabColor);
|
||||
}
|
||||
</style>
|
||||
|
@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div class="side-bar-search"
|
||||
:class="theme"
|
||||
<div
|
||||
class="side-bar-search"
|
||||
>
|
||||
<div class="search-wrapper">
|
||||
<input
|
||||
type="text" v-model="keyword"
|
||||
placeholder="Search in project..."
|
||||
placeholder="Search in folder..."
|
||||
@keyup="search"
|
||||
>
|
||||
<svg class="icon" aria-hidden="true">
|
||||
@ -20,17 +20,23 @@
|
||||
></list-file>
|
||||
</div>
|
||||
<div class="empty" v-else>
|
||||
<span>{{ !keyword ? 'Input search keyword' : 'No matched files' }}</span>
|
||||
<div class="no-data">
|
||||
<svg :viewBox="EmptyIcon.viewBox" aria-hidden="true">
|
||||
<use :xlink:href="EmptyIcon.url" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters, mapState } from 'vuex'
|
||||
import { mapGetters } from 'vuex'
|
||||
import ListFile from './listFile.vue'
|
||||
import EmptyIcon from '@/assets/icons/undraw_empty.svg'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
this.EmptyIcon = EmptyIcon
|
||||
return {
|
||||
keyword: '',
|
||||
searchResult: []
|
||||
@ -40,9 +46,6 @@
|
||||
ListFile
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
'theme': state => state.preferences.theme
|
||||
}),
|
||||
...mapGetters(['fileList'])
|
||||
},
|
||||
methods: {
|
||||
@ -70,10 +73,14 @@
|
||||
margin: 35px 20px;
|
||||
border-radius: 3px;
|
||||
height: 30px;
|
||||
border: 1px solid var(--lightBorder);
|
||||
border: 1px solid var(--floatBorderColor);
|
||||
background: var(--floatBorderColor);
|
||||
border-radius: 15px;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
& > input {
|
||||
color: var(--sideBarColor);
|
||||
background: transparent;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
border: none;
|
||||
@ -87,16 +94,17 @@
|
||||
flex-shrink: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 5px;
|
||||
margin-right: 10px;
|
||||
&:hover {
|
||||
color: var(--brandColor);
|
||||
color: var(--iconColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
.empty,
|
||||
.search-result {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
&::-webkit-scrollbar:vertical {
|
||||
width: 5px;
|
||||
}
|
||||
@ -104,14 +112,13 @@
|
||||
.empty {
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
.dark.side-bar-search .search-wrapper {
|
||||
background: rgb(54, 55, 49);
|
||||
border-color: transparent;
|
||||
& > input,
|
||||
& > svg {
|
||||
background: transparent;
|
||||
color: #C0C4CC;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
padding-bottom: 100px;
|
||||
& .no-data svg {
|
||||
fill: var(--themeColor);
|
||||
width: 120px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,56 +1,96 @@
|
||||
<template>
|
||||
<ul class="side-bar-toc">
|
||||
<li v-for="(item, index) of toc"
|
||||
:key="index"
|
||||
:style="{'padding-left': `${(item.lvl - startLvl) * 20}px`}"
|
||||
@click="handleClick(item)"
|
||||
:class="{ 'active': item.i === activeIndex }"
|
||||
>
|
||||
{{ item.content }}
|
||||
</li>
|
||||
</ul>
|
||||
<div class="side-bar-toc">
|
||||
<div class="title">Table Of Content</div>
|
||||
<el-tree
|
||||
v-if="toc.length"
|
||||
:data="toc"
|
||||
:props="defaultProps"
|
||||
@node-click="handleClick"
|
||||
:expand-on-click-node="false"
|
||||
:indent="10"
|
||||
></el-tree>
|
||||
<div class="no-data" v-else>
|
||||
<svg aria-hidden="true" :viewBox="EmptyIcon.viewBox">
|
||||
<use :xlink:href="EmptyIcon.url"></use>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { mapState } from 'vuex'
|
||||
import bus from '../../bus'
|
||||
import EmptyIcon from '@/assets/icons/undraw_toc_empty.svg'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
this.EmptyIcon = EmptyIcon
|
||||
return {
|
||||
activeIndex: -1
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'label'
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['toc']),
|
||||
startLvl () {
|
||||
return Math.min(...this.toc.map(h => h.lvl))
|
||||
}
|
||||
...mapState({
|
||||
'toc': state => state.editor.toc
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
handleClick (item) {
|
||||
this.activeIndex = item.i
|
||||
bus.$emit('scroll-to-header', item.slug)
|
||||
handleClick ({ slug }) {
|
||||
bus.$emit('scroll-to-header', slug)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style>
|
||||
.side-bar-toc {
|
||||
height: calc(100% - 35px);
|
||||
margin: 0;
|
||||
margin-top: 35px;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
overflow: scroll;
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
& .title {
|
||||
padding: 5px 0;
|
||||
color: var(--sideBarTitleColor);
|
||||
font-weight: 600px;
|
||||
font-size: 16px;
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
& .el-tree-node {
|
||||
margin-top: 8px;
|
||||
}
|
||||
& .el-tree {
|
||||
background: transparent;
|
||||
color: var(--sideBarColor);
|
||||
}
|
||||
& .el-tree-node:focus > .el-tree-node__content {
|
||||
background-color: var(--sideBarItemHoverBgColor);
|
||||
}
|
||||
& .el-tree-node__content:hover {
|
||||
background: var(--sideBarItemHoverBgColor);
|
||||
}
|
||||
& > li {
|
||||
font-size: 14px;
|
||||
margin-bottom: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
& > li.active {
|
||||
color: var(--primary);
|
||||
& .no-data {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
padding-bottom: 50px;
|
||||
& svg {
|
||||
width: 120px;
|
||||
fill: var(--themeColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -23,7 +23,7 @@
|
||||
<!-- opened files -->
|
||||
<div class="opened-files">
|
||||
<div class="title">
|
||||
<svg class="icon" aria-hidden="true" @click.stop="toggleOpenedFiles()">
|
||||
<svg class="icon icon-arrow" :class="{'fold': !showOpenedFiles}" aria-hidden="true" @click.stop="toggleOpenedFiles()">
|
||||
<use xlink:href="#icon-arrow"></use>
|
||||
</svg>
|
||||
<span class="default-cursor text-overflow" @click.stop="toggleOpenedFiles()">Opened files</span>
|
||||
@ -54,7 +54,7 @@
|
||||
class="project-tree" v-if="projectTree"
|
||||
>
|
||||
<div class="title">
|
||||
<svg class="icon" aria-hidden="true" @click.stop="toggleDirectories()">
|
||||
<svg class="icon icon-arrow" :class="{'fold': !showDirectories}" aria-hidden="true" @click.stop="toggleDirectories()">
|
||||
<use xlink:href="#icon-arrow"></use>
|
||||
</svg>
|
||||
<span class="default-cursor text-overflow" @click.stop="toggleDirectories()">{{ projectTree.name }}</span>
|
||||
@ -91,11 +91,14 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="open-project">
|
||||
<a href="javascript:;" @click="openFolder" title="Open Folder">
|
||||
<svg class="icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-create-project"></use>
|
||||
<div class="button-group">
|
||||
<svg aria-hidden="true" :viewBox="FolderIcon.viewBox">
|
||||
<use :xlink:href="FolderIcon.url"></use>
|
||||
</svg>
|
||||
</a>
|
||||
<a href="javascript:;" @click="openFolder">
|
||||
Open Folder
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -108,11 +111,13 @@
|
||||
import { mapState } from 'vuex'
|
||||
import bus from '../../bus'
|
||||
import { createFileOrDirectoryMixins } from '../../mixins'
|
||||
import FolderIcon from '@/assets/icons/undraw_folder.svg'
|
||||
|
||||
export default {
|
||||
mixins: [createFileOrDirectoryMixins],
|
||||
data () {
|
||||
this.depth = 0
|
||||
this.FolderIcon = FolderIcon
|
||||
return {
|
||||
active: 'tree', // tree or list
|
||||
showDirectories: true,
|
||||
@ -199,6 +204,7 @@
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.list-enter-active, .list-leave-active {
|
||||
transition: all .2s;
|
||||
}
|
||||
@ -209,7 +215,7 @@
|
||||
}
|
||||
.tree-view {
|
||||
font-size: 14px;
|
||||
color: var(--regularColor);
|
||||
color: var(--sideBarColor);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
@ -228,20 +234,31 @@
|
||||
pointer-events: auto;
|
||||
cursor: pointer;
|
||||
margin-left: 8px;
|
||||
color: var(--secondaryColor);
|
||||
color: var(--iconColor);
|
||||
opacity: 0;
|
||||
}
|
||||
& > a:hover {
|
||||
color: var(--primary);
|
||||
color: var(--themeColor);
|
||||
}
|
||||
& > a.active {
|
||||
color: var(--primary);
|
||||
color: var(--themeColor);
|
||||
}
|
||||
}
|
||||
.tree-view:hover .title a {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.icon-arrow {
|
||||
margin-right: 5px;
|
||||
transition: all .25s ease-out;
|
||||
transform: rotate(90deg);
|
||||
fill: var(--sideBarTextColor);
|
||||
}
|
||||
|
||||
.icon-arrow.fold {
|
||||
transform: rotate(0);
|
||||
}
|
||||
|
||||
.opened-files,
|
||||
.project-tree {
|
||||
& > .title {
|
||||
@ -261,7 +278,7 @@
|
||||
& > a {
|
||||
display: none;
|
||||
text-decoration: none;
|
||||
color: var(--secondaryColor);
|
||||
color: var(--sideBarColor);
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
@ -269,7 +286,7 @@
|
||||
.opened-files div.title > a:hover {
|
||||
display: block;
|
||||
&:hover {
|
||||
color: var(--primary);
|
||||
color: var(--sideBarTitleColor);
|
||||
}
|
||||
}
|
||||
.opened-files {
|
||||
@ -277,7 +294,7 @@
|
||||
flex-direction: column;
|
||||
}
|
||||
.default-cursor {
|
||||
cursor: default;
|
||||
cursor: pointer;
|
||||
}
|
||||
.opened-files .opened-files-list {
|
||||
max-height: 200px;
|
||||
@ -308,26 +325,30 @@
|
||||
.open-project {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
margin-top: -100px;
|
||||
& > a {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
border-radius: 50%;
|
||||
text-decoration: none;
|
||||
background: rgba(31, 116, 255, .5);
|
||||
transition: all .3s ease;
|
||||
padding-bottom: 100px;
|
||||
& .button-group {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
& > svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
color: #fff;
|
||||
}
|
||||
&:hover {
|
||||
background: var(--primary);
|
||||
}
|
||||
& svg {
|
||||
width: 120px;
|
||||
fill: var(--themeColor);
|
||||
}
|
||||
& a {
|
||||
text-decoration: none;
|
||||
background: var(--themeColor);
|
||||
box-shadow: 0 0 8px 0 var(--selectionColor);
|
||||
display: block;
|
||||
padding: 4px 7px;
|
||||
border-radius: 5px;
|
||||
margin-top: 20px;
|
||||
color: #fff;
|
||||
&:active {
|
||||
opacity: .5;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -335,7 +356,7 @@
|
||||
outline: none;
|
||||
height: 22px;
|
||||
margin: 5px 0;
|
||||
border: 1px solid var(--lightBorder);
|
||||
border: 1px solid var(--themeColor);
|
||||
width: calc(100% - 45px);
|
||||
border-radius: 3px;
|
||||
}
|
||||
@ -352,7 +373,7 @@
|
||||
padding-top: 40px;
|
||||
align-items: center;
|
||||
& > a {
|
||||
color: var(--primary);
|
||||
color: var(--themeColor);
|
||||
text-align: center;
|
||||
margin-top: 15px;
|
||||
text-decoration: none;
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div
|
||||
class="title-bar"
|
||||
:class="[{ 'active': active }, theme, { 'frameless': titleBarStyle === 'custom' }, { 'isOsx': platform === 'darwin' }]"
|
||||
:class="[{ 'active': active }, { 'frameless': titleBarStyle === 'custom' }, { 'isOsx': platform === 'darwin' }]"
|
||||
>
|
||||
<div class="title">
|
||||
<span v-if="!filename">Mark Text</span>
|
||||
@ -34,11 +34,20 @@
|
||||
<el-tooltip
|
||||
v-if="wordCount"
|
||||
class="item"
|
||||
effect="dark"
|
||||
:content="`${wordCount[show]} ${HASH[show].full + (wordCount[show] > 1 ? 's' : '')}`"
|
||||
:open-delay="500"
|
||||
placement="bottom-end"
|
||||
>
|
||||
<div slot="content">
|
||||
<div class="title-item">
|
||||
<span class="front">Words:</span><span class="text">{{wordCount['word']}}</span>
|
||||
</div>
|
||||
<div class="title-item">
|
||||
<span class="front">Characters:</span><span class="text">{{wordCount['character']}}</span>
|
||||
</div>
|
||||
<div class="title-item">
|
||||
<span class="front">Paragraph:</span><span class="text">{{wordCount['paragraph']}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="wordCount"
|
||||
class="word-count"
|
||||
@ -125,7 +134,6 @@
|
||||
pathname: String,
|
||||
active: Boolean,
|
||||
wordCount: Object,
|
||||
theme: String,
|
||||
platform: String,
|
||||
isSaved: Boolean
|
||||
},
|
||||
@ -206,20 +214,20 @@
|
||||
.title-bar {
|
||||
-webkit-app-region: drag;
|
||||
user-select: none;
|
||||
background: var(--editorBgColor);
|
||||
width: 100%;
|
||||
height: var(--titleBarHeight);
|
||||
box-sizing: border-box;
|
||||
color: #F2F6FC;
|
||||
position: fixed;
|
||||
color: var(--editorColor50);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
z-index: 2;
|
||||
transition: color .4s ease-in-out;
|
||||
cursor: default;
|
||||
}
|
||||
.active {
|
||||
color: #909399;
|
||||
color: var(--editorColor);
|
||||
}
|
||||
img {
|
||||
height: 90%;
|
||||
@ -248,7 +256,7 @@
|
||||
}
|
||||
|
||||
.title-bar .title .filename.isOsx:hover {
|
||||
color: var(--primary);
|
||||
color: var(--themeColor);
|
||||
}
|
||||
|
||||
.active .save-dot {
|
||||
@ -257,7 +265,7 @@
|
||||
height: 7px;
|
||||
display: inline-block;
|
||||
border-radius: 50%;
|
||||
background: var(--warning);
|
||||
background: var(--themeColor);
|
||||
opacity: .7;
|
||||
visibility: hidden;
|
||||
}
|
||||
@ -265,11 +273,9 @@
|
||||
visibility: visible;
|
||||
}
|
||||
.title:hover {
|
||||
color: #303133;
|
||||
}
|
||||
.title:hover .save-dot {
|
||||
background: var(--warning);
|
||||
color: var(sideBarTitleColor);
|
||||
}
|
||||
|
||||
.right-toolbar {
|
||||
padding: 0 10px;
|
||||
height: 100%;
|
||||
@ -278,6 +284,7 @@
|
||||
right: 0;
|
||||
width: 100px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.left-toolbar {
|
||||
@ -293,20 +300,19 @@
|
||||
.word-count {
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
color: #F2F6FC;
|
||||
height: 17px;
|
||||
line-height: 17px;
|
||||
margin-top: 4px;
|
||||
padding: 1px 5px;
|
||||
border-radius: 1px;
|
||||
color: var(--editorColor30);
|
||||
height: 20px;
|
||||
text-align: center;
|
||||
line-height: 24px;
|
||||
padding: 0px 5px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px;
|
||||
transition: all .25s ease-in-out;
|
||||
}
|
||||
.active .word-count {
|
||||
color: #DCDFE6;
|
||||
}
|
||||
|
||||
.word-count:hover {
|
||||
background: #F2F6FC;
|
||||
color: #606266;
|
||||
background: var(--sideBarBgColor);
|
||||
color: var(--sideBarTitleColor);
|
||||
}
|
||||
.title-no-drag {
|
||||
-webkit-app-region: no-drag;
|
||||
@ -326,7 +332,7 @@
|
||||
transform: translateX(-50%) translateY(-50%);
|
||||
}
|
||||
.frameless-titlebar-menu {
|
||||
color: #606266;
|
||||
color: var(--sideBarColor);
|
||||
}
|
||||
.frameless-titlebar-close:hover {
|
||||
background-color: rgb(228, 79, 79);
|
||||
@ -341,26 +347,19 @@
|
||||
.frameless-titlebar-close:hover svg {
|
||||
fill: #ffffff
|
||||
}
|
||||
/* css for dark theme */
|
||||
.dark {
|
||||
background: var(--darkBgColor);
|
||||
color: #909399;
|
||||
}
|
||||
.dark .title:hover {
|
||||
color: #F2F6FC;
|
||||
}
|
||||
.dark .word-count:hover {
|
||||
background: rgb(71, 72, 66);
|
||||
color: #C0C4CC;
|
||||
}
|
||||
.dark .frameless-titlebar-button svg {
|
||||
fill: #909399
|
||||
}
|
||||
.dark .frameless-titlebar-close:hover svg {
|
||||
fill: #ffffff
|
||||
}
|
||||
/* exclude titlebar so we can apply a custom sidebar background color */
|
||||
.title-bar.dark {
|
||||
background: transparent;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
.title-item {
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
& .front {
|
||||
color: var(--editorColor50);
|
||||
}
|
||||
& .text {
|
||||
margin-left: 10px;
|
||||
color: var(--editorColor30);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="tweet-dialog" :class="theme">
|
||||
<div class="tweet-dialog">
|
||||
<el-dialog
|
||||
:visible.sync="showTweetDialog"
|
||||
:show-close="false"
|
||||
@ -68,7 +68,6 @@
|
||||
|
||||
<script>
|
||||
import { shell } from 'electron'
|
||||
import { mapState } from 'vuex'
|
||||
import bus from '../../bus'
|
||||
|
||||
export default {
|
||||
@ -79,11 +78,6 @@
|
||||
selectedFace: 'smile'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
'theme': state => state.preferences.theme
|
||||
})
|
||||
},
|
||||
created () {
|
||||
bus.$on('tweetDialog', this.showDialog)
|
||||
},
|
||||
@ -127,8 +121,7 @@
|
||||
|
||||
<style>
|
||||
.tweet-dialog {
|
||||
width: 450px;
|
||||
color: var(--regularColor);
|
||||
color: var(--sideBarColor);
|
||||
& .title {
|
||||
font-size: 24px;
|
||||
}
|
||||
@ -136,11 +129,14 @@
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
}
|
||||
& .el-dialog__body {
|
||||
color: var(--sideBarColor);
|
||||
}
|
||||
}
|
||||
.feeling, .feedback {
|
||||
.tweet-dialog .feeling, .tweet-dialog .feedback {
|
||||
font-size: 16px;
|
||||
}
|
||||
.feeling {
|
||||
.tweet-dialog .feeling {
|
||||
& ul {
|
||||
display: flex;
|
||||
list-style: none;
|
||||
@ -163,7 +159,7 @@
|
||||
color: rgb(255, 204, 0);
|
||||
}
|
||||
}
|
||||
.feedback {
|
||||
.tweet-dialog .feedback {
|
||||
& > textarea {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
@ -171,19 +167,21 @@
|
||||
padding: .5rem;
|
||||
resize: none;
|
||||
outline: none;
|
||||
border-color: var(--lightBorder);
|
||||
border: 1px solid var(--floatBorderColor);
|
||||
background: var(--floatBorderColor);
|
||||
color: var(--editorColor);
|
||||
border-radius: 5px;
|
||||
font-size: 14px;
|
||||
height: 80px;
|
||||
}
|
||||
}
|
||||
.button {
|
||||
.tweet-dialog .button {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.button a.twitter {
|
||||
color: var(--secondaryColor);
|
||||
.tweet-dialog .button a.twitter {
|
||||
color: var(--themeColor);
|
||||
text-decoration: none;
|
||||
width: auto;
|
||||
height: 30px;
|
||||
@ -195,18 +193,18 @@
|
||||
background: #eee;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.button a.active {
|
||||
background: var(--primary);
|
||||
.tweet-dialog .button a.active {
|
||||
background: var(--themeColor);
|
||||
color: #fff;
|
||||
}
|
||||
.button a.active {
|
||||
.tweet-dialog .button a.active {
|
||||
cursor: pointer;
|
||||
}
|
||||
.button a.github {
|
||||
color: var(--secondaryColor);
|
||||
.tweet-dialog .button a.github {
|
||||
color: var(--iconColor);
|
||||
text-decoration: none;
|
||||
&:hover {
|
||||
color: #1da1f2;
|
||||
color: var(--themeColor);
|
||||
}
|
||||
& > svg {
|
||||
width: 1.4rem;
|
||||
@ -214,13 +212,8 @@
|
||||
vertical-align: bottom;
|
||||
}
|
||||
}
|
||||
.tweet-dialog.dark textarea {
|
||||
background: var(--darkInputBgColor);
|
||||
border-color: transparent;
|
||||
color: var(--darkInputColor);
|
||||
}
|
||||
.tweet-dialog.light .el-dialog__header {
|
||||
background: var(--primary);
|
||||
.tweet-dialog .el-dialog__header {
|
||||
background: var(--themeColor);
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="aidou" :class="theme">
|
||||
<div class="aidou">
|
||||
<el-dialog
|
||||
:visible.sync="showUpload"
|
||||
:show-close="false"
|
||||
@ -27,7 +27,6 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import bus from '../../bus'
|
||||
|
||||
const msg = 'jpg | png | gif | jpeg only, max size 5M'
|
||||
@ -40,11 +39,6 @@
|
||||
error: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
'theme': state => state.preferences.theme
|
||||
})
|
||||
},
|
||||
created () {
|
||||
this.$nextTick(() => {
|
||||
bus.$on('upload-image', this.handleUpload)
|
||||
@ -92,11 +86,21 @@
|
||||
<style>
|
||||
.el-upload__tip {
|
||||
text-align: center;
|
||||
color: var(--sideBarColor);
|
||||
}
|
||||
.el-upload__tip.error {
|
||||
color: #E6A23C;
|
||||
}
|
||||
.dark .el-upload-dragger {
|
||||
background: rgb(39, 39, 39);
|
||||
.el-upload-dragger {
|
||||
background: var(--itemBgColor);
|
||||
& .el-upload__text {
|
||||
color: var(--sideBarColor);
|
||||
& em {
|
||||
color: var(--themeColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-upload-dragger:hover {
|
||||
border-color: var(--themeColor);
|
||||
}
|
||||
</style>
|
||||
|
@ -2,7 +2,7 @@ import path from 'path'
|
||||
|
||||
export const PATH_SEPARATOR = path.sep
|
||||
|
||||
export const THEME_LINK_ID = 'ag-theme'
|
||||
export const THEME_STYLE_ID = 'ag-theme'
|
||||
export const COMMON_STYLE_ID = 'ag-common-style'
|
||||
|
||||
export const DEFAULT_EDITOR_FONT_FAMILY = '"Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif'
|
||||
@ -12,3 +12,5 @@ export const DEFAULT_STYLE = {
|
||||
codeFontSize: '14px',
|
||||
theme: 'light'
|
||||
}
|
||||
|
||||
export const railscastsThemes = ['dark']
|
||||
|
@ -6,7 +6,20 @@ import locale from 'element-ui/lib/locale'
|
||||
import App from './app'
|
||||
import store from './store'
|
||||
import './assets/symbolIcon'
|
||||
import { Dialog, Form, FormItem, InputNumber, Button, Tooltip, Upload, Slider, ColorPicker, Col, Row } from 'element-ui'
|
||||
import {
|
||||
Dialog,
|
||||
Form,
|
||||
FormItem,
|
||||
InputNumber,
|
||||
Button,
|
||||
Tooltip,
|
||||
Upload,
|
||||
Slider,
|
||||
ColorPicker,
|
||||
Col,
|
||||
Row,
|
||||
Tree
|
||||
} from 'element-ui'
|
||||
import services from './services'
|
||||
|
||||
import './assets/styles/index.css'
|
||||
@ -54,6 +67,7 @@ Vue.use(Slider)
|
||||
Vue.use(ColorPicker)
|
||||
Vue.use(Col)
|
||||
Vue.use(Row)
|
||||
Vue.use(Tree)
|
||||
|
||||
if (!process.env.IS_WEB) Vue.use(require('vue-electron'))
|
||||
Vue.http = Vue.prototype.$http = axios
|
||||
|
@ -2,24 +2,16 @@ import { clipboard, ipcRenderer, shell } from 'electron'
|
||||
import path from 'path'
|
||||
import bus from '../bus'
|
||||
import { hasKeys } from '../util'
|
||||
import listToTree from '../util/listToTree'
|
||||
import { createDocumentState, getOptionsFromState, getSingleFileState, getBlankFileState } from './help'
|
||||
import notice from '../services/notification'
|
||||
|
||||
// HACK: When rewriting muya, create and update muya's TOC during heading parsing and pass it to the renderer process.
|
||||
import { getTocFromMarkdown } from 'muya/lib/utils/dirtyToc'
|
||||
|
||||
const state = {
|
||||
lineEnding: 'lf',
|
||||
currentFile: {},
|
||||
tabs: [],
|
||||
textDirection: 'ltr'
|
||||
}
|
||||
|
||||
const getters = {
|
||||
toc: state => {
|
||||
const { markdown } = state.currentFile
|
||||
return getTocFromMarkdown(markdown)
|
||||
}
|
||||
textDirection: 'ltr',
|
||||
toc: []
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
@ -27,6 +19,9 @@ const mutations = {
|
||||
SET_SEARCH (state, value) {
|
||||
state.currentFile.searchMatches = value
|
||||
},
|
||||
SET_TOC (state, toc) {
|
||||
state.toc = listToTree(toc)
|
||||
},
|
||||
SET_CURRENT_FILE (state, currentFile) {
|
||||
const oldCurrentFile = state.currentFile
|
||||
if (!oldCurrentFile.id || oldCurrentFile.id !== currentFile.id) {
|
||||
@ -463,7 +458,7 @@ const actions = {
|
||||
// },
|
||||
|
||||
// Content change from realtime preview editor and source code editor
|
||||
LISTEN_FOR_CONTENT_CHANGE ({ commit, state, rootState }, { markdown, wordCount, cursor, history }) {
|
||||
LISTEN_FOR_CONTENT_CHANGE ({ commit, state, rootState }, { markdown, wordCount, cursor, history, toc }) {
|
||||
const { autoSave } = rootState.preferences
|
||||
const { projectTree } = rootState.project
|
||||
const { pathname, markdown: oldMarkdown, id } = state.currentFile
|
||||
@ -481,6 +476,8 @@ const actions = {
|
||||
if (cursor) commit('SET_CURSOR', cursor)
|
||||
// set history
|
||||
if (history) commit('SET_HISTORY', history)
|
||||
// set toc
|
||||
if (toc) commit('SET_TOC', toc)
|
||||
|
||||
// change save status/save to file only when the markdown changed!
|
||||
if (markdown !== oldMarkdown) {
|
||||
@ -591,4 +588,4 @@ const actions = {
|
||||
}
|
||||
}
|
||||
|
||||
export default { state, getters, mutations, actions }
|
||||
export default { state, mutations, actions }
|
||||
|
9
src/renderer/util/day.js
Normal file
9
src/renderer/util/day.js
Normal file
@ -0,0 +1,9 @@
|
||||
import dayjs from 'dayjs/esm'
|
||||
import relativeTime from 'dayjs/esm/plugin/relativeTime'
|
||||
import 'dayjs/esm/locale/en' // load on demand
|
||||
|
||||
dayjs.locale('en') // use Spanish locale globally
|
||||
|
||||
dayjs.extend(relativeTime)
|
||||
|
||||
export default dayjs
|
30
src/renderer/util/listToTree.js
Normal file
30
src/renderer/util/listToTree.js
Normal file
@ -0,0 +1,30 @@
|
||||
const listToTree = list => {
|
||||
const result = []
|
||||
let parent = null
|
||||
let child = null
|
||||
let tempLvl = 7 // any number great than 6
|
||||
|
||||
for (const { lvl, content, slug } of list) {
|
||||
const item = {
|
||||
lvl, label: content, slug, children: []
|
||||
}
|
||||
if (lvl < tempLvl) {
|
||||
tempLvl = lvl
|
||||
result.push(item)
|
||||
parent = { children: result }
|
||||
child = item
|
||||
} else if (lvl === tempLvl) {
|
||||
parent.children.push(item)
|
||||
child = item
|
||||
} else if (lvl > tempLvl) {
|
||||
tempLvl = lvl
|
||||
child.children.push(item)
|
||||
parent = child
|
||||
child = item
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
export default listToTree
|
@ -1,18 +1,42 @@
|
||||
import { THEME_LINK_ID, COMMON_STYLE_ID, DEFAULT_CODE_FONT_FAMILY } from '../config'
|
||||
import { THEME_STYLE_ID, COMMON_STYLE_ID, DEFAULT_CODE_FONT_FAMILY, railscastsThemes } from '../config'
|
||||
import { dark, ulysses, graphite } from './themeColor'
|
||||
|
||||
export const addThemeStyle = theme => {
|
||||
const href = process.env.NODE_ENV !== 'production'
|
||||
? `./src/muya/themes/${theme}.css`
|
||||
: `./static/themes/${theme}.css`
|
||||
let themeStyleEle = document.querySelector(`#${THEME_STYLE_ID}`)
|
||||
if (!themeStyleEle) {
|
||||
themeStyleEle = document.createElement('style')
|
||||
themeStyleEle.id = THEME_STYLE_ID
|
||||
document.head.appendChild(themeStyleEle)
|
||||
}
|
||||
switch (theme) {
|
||||
case 'light':
|
||||
themeStyleEle.innerHTML = ''
|
||||
break
|
||||
case 'dark':
|
||||
themeStyleEle.innerHTML = dark
|
||||
break
|
||||
case 'ulysses':
|
||||
themeStyleEle.innerHTML = ulysses
|
||||
break
|
||||
case 'graphite':
|
||||
themeStyleEle.innerHTML = graphite
|
||||
break
|
||||
default:
|
||||
console.log('unknown theme')
|
||||
break
|
||||
}
|
||||
|
||||
let link = document.querySelector(`#${THEME_LINK_ID}`)
|
||||
if (!link) {
|
||||
link = document.createElement('link')
|
||||
link.setAttribute('rel', 'stylesheet')
|
||||
link.id = THEME_LINK_ID
|
||||
document.head.appendChild(link)
|
||||
// change codeMirror theme
|
||||
const cm = document.querySelector('.CodeMirror')
|
||||
if (cm) {
|
||||
if (railscastsThemes.includes(theme)) {
|
||||
cm.classList.remove('cm-s-default')
|
||||
cm.classList.add('cm-s-railscasts')
|
||||
} else {
|
||||
cm.classList.add('cm-s-default')
|
||||
cm.classList.remove('cm-s-railscasts')
|
||||
}
|
||||
link.href = href
|
||||
}
|
||||
}
|
||||
|
||||
export const addCommonStyle = style => {
|
||||
|
392
src/renderer/util/themeColor.js
Normal file
392
src/renderer/util/themeColor.js
Normal file
@ -0,0 +1,392 @@
|
||||
// we can load custom theme from userData folder, we also can write this theme in userData folder.
|
||||
|
||||
export const dark = `
|
||||
:root {
|
||||
--themeColor: #f48237;
|
||||
--highlightColor: rgba(244, 130, 55, .9);
|
||||
--selectionColor: rgba(244, 130, 55, .4);
|
||||
--editorColor: rgba(255, 255, 255, .8);
|
||||
--editorColor50: rgba(255, 255, 255, .5);
|
||||
--editorColor30: rgba(255, 255, 255, .3);
|
||||
--editorColor10: rgba(255, 255, 255, .1);
|
||||
--editorBgColor: #34393f;
|
||||
--deleteColor: #ff6969;
|
||||
--iconColor: rgba(255, 255, 255, .8);
|
||||
--codeBgColor: #d8d8d869;
|
||||
--codeBlockBgColor: rgba(244, 130, 55, .04);
|
||||
--sideBarColor: rgba(255, 255, 255, .6);
|
||||
--sideBarTitleColor: rgba(255, 255, 255, 1);
|
||||
--sideBarTextColor: rgba(255, 255, 255, .4);
|
||||
--sideBarBgColor: rgba(26, 33, 41, 0.9);
|
||||
--sideBarItemHoverBgColor: rgba(255, 255, 255, .03);
|
||||
--itemBgColor: rgba(71, 78, 86, 0.6);
|
||||
--floatBgColor: #3c4650;
|
||||
--floatHoverColor: rgba(255, 255, 255, .04);
|
||||
--floatBorderColor: rgba(0, 0, 0, .03);
|
||||
--editorAreaWidth: 700px;
|
||||
}
|
||||
div.title-bar .frameless-titlebar-button > div > svg {
|
||||
fill: #ffffff;
|
||||
}
|
||||
/**
|
||||
* okaidia theme for JavaScript, CSS and HTML
|
||||
* Loosely based on Monokai textmate theme by http://www.monokai.nl/
|
||||
* @author ocodia
|
||||
*/
|
||||
|
||||
code[class*="language-"],
|
||||
pre.ag-paragraph {
|
||||
color: #f8f8f2;
|
||||
/*font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;*/
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre.ag-paragraph {
|
||||
padding: 1em;
|
||||
margin: 1em 0;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*="language-"],
|
||||
pre.ag-paragraph {
|
||||
/*background: #272822;*/
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.constant,
|
||||
.token.symbol {
|
||||
color: #f92672;
|
||||
}
|
||||
|
||||
.token.boolean,
|
||||
.token.number {
|
||||
color: #ae81ff;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin {
|
||||
color: #a6e22e;
|
||||
}
|
||||
|
||||
.token.inserted {
|
||||
color: #22863a;
|
||||
background: #f0fff4;
|
||||
}
|
||||
|
||||
.token.deleted {
|
||||
color: #b31d28;
|
||||
background: #ffeef0;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string,
|
||||
.token.variable {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #e6db74;
|
||||
}
|
||||
|
||||
.token.keyword {
|
||||
color: #66d9ef;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important {
|
||||
color: #fd971f;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
`
|
||||
|
||||
|
||||
export const ulysses = `
|
||||
:root {
|
||||
--themeColor: rgb(12, 139, 186);
|
||||
--highlightColor: rgba(12, 139, 186, .9);
|
||||
--selectionColor: rgba(12, 139, 186, .4);
|
||||
--editorColor: rgba(101, 101, 101, .8);
|
||||
--editorColor50: rgba(101, 101, 101, .5);
|
||||
--editorColor30: rgba(101, 101, 101, .3);
|
||||
--editorColor10: rgba(101, 101, 101, .1);
|
||||
--editorBgColor: #f3f3f3;
|
||||
--deleteColor: #ff6969;
|
||||
--iconColor: rgba(101, 101, 101, .8);
|
||||
--codeBgColor: #d8d8d869;
|
||||
--codeBlockBgColor: rgba(12, 139, 186, .04);
|
||||
--sideBarColor: rgba(101, 101, 101, .6);
|
||||
--sideBarTitleColor: rgba(101, 101, 101, 1);
|
||||
--sideBarTextColor: rgba(101, 101, 101, .4);
|
||||
--sideBarBgColor: rgba(248, 248, 248, 0.9);
|
||||
--sideBarItemHoverBgColor: rgba(101, 101, 101, .03);
|
||||
--itemBgColor: rgba(245, 245, 245, 0.6);
|
||||
--floatBgColor: #ffffff;
|
||||
--floatHoverColor: rgba(101, 101, 101, .04);
|
||||
--floatBorderColor: rgba(0, 0, 0, .03);
|
||||
--editorAreaWidth: 700px;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: var(--themeColor);
|
||||
text-align: center;
|
||||
}
|
||||
li.ag-bullet-list-item {
|
||||
position: relative;
|
||||
list-style: none;
|
||||
}
|
||||
li.ag-bullet-list-item::before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 5px;
|
||||
height: 2px;
|
||||
left: -18px;
|
||||
top: 15px;
|
||||
background: var(--editorColor);
|
||||
}
|
||||
blockquote.ag-paragraph {
|
||||
background: rgb(233, 233, 233);
|
||||
}
|
||||
blockquote.ag-paragraph::before {
|
||||
content: none;
|
||||
}
|
||||
li.ag-paragraph {
|
||||
color: var(--editorColor);
|
||||
}
|
||||
/*task list*/
|
||||
li.ag-task-list-item {
|
||||
list-style-type: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
li.ag-task-list-item > input[type=checkbox] {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 4px 0px 0px;
|
||||
top: 2px;
|
||||
left: -22px;
|
||||
transform-origin: center;
|
||||
transform: rotate(-90deg);
|
||||
transition: all .2s ease;
|
||||
}
|
||||
|
||||
li.ag-task-list-item > input.ag-checkbox-checked {
|
||||
transform: rotate(0);
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
li.ag-task-list-item > input[type=checkbox]::before {
|
||||
content: '';
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
border: 2px solid var(--editorColor);
|
||||
border-radius: 2px;
|
||||
background-color: var(--editorBgColor);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transition: all .2s ease;
|
||||
}
|
||||
|
||||
li.ag-task-list-item > input.ag-checkbox-checked::before {
|
||||
border: transparent;
|
||||
background-color: var(--editorColor);
|
||||
}
|
||||
|
||||
li.ag-task-list-item > input::after {
|
||||
content: '';
|
||||
transform: rotate(-45deg) scale(0);
|
||||
width: 9px;
|
||||
height: 5px;
|
||||
border: 2px solid #fff;
|
||||
border-top: none;
|
||||
border-right: none;
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
top: 1px;
|
||||
left: 5px;
|
||||
transition: all .2s ease;
|
||||
}
|
||||
|
||||
li.ag-task-list-item > input.ag-checkbox-checked::after {
|
||||
transform: rotate(-45deg) scale(1);
|
||||
}
|
||||
/*horizontal line*/
|
||||
p:not(.ag-active)[data-role="hr"]::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 50%;
|
||||
display: block;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
height: 2px;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 2px dashed var(--editorColor50);
|
||||
transform: translateX(-50%) translateY(-50%);
|
||||
}
|
||||
`
|
||||
|
||||
export const graphite = `
|
||||
:root {
|
||||
--themeColor: rgb(104, 134, 170);
|
||||
--highlightColor: rgba(104, 134, 170, .9);
|
||||
--selectionColor: rgba(104, 134, 170, .4);
|
||||
--editorColor: rgba(43, 48, 50, .8);
|
||||
--editorColor50: rgba(43, 48, 50, .5);
|
||||
--editorColor30: rgba(43, 48, 50, .3);
|
||||
--editorColor10: rgba(43, 48, 50, .1);
|
||||
--editorBgColor: #f7f7f7;
|
||||
--deleteColor: #ff6969;
|
||||
--iconColor: rgba(135, 135, 135, .8);
|
||||
--codeBgColor: #d8d8d869;
|
||||
--codeBlockBgColor: rgba(104, 134, 170, .04);
|
||||
--sideBarColor: rgba(188, 193, 197, .8);
|
||||
--sideBarTitleColor: rgba(255, 255, 255, 1);
|
||||
--sideBarTextColor: rgba(188, 193, 197, .4);
|
||||
--sideBarBgColor: rgba(69, 75, 80, 1);
|
||||
--sideBarItemHoverBgColor: rgba(255, 255, 255, .03);
|
||||
--itemBgColor: rgba(43, 48, 50, .5);
|
||||
--floatBgColor: rgb(237, 237, 238);
|
||||
--floatHoverColor: rgba(43, 48, 50, .04);
|
||||
--floatBorderColor: rgba(0, 0, 0, .03);
|
||||
--editorAreaWidth: 700px;
|
||||
}
|
||||
li.ag-paragraph {
|
||||
color: var(--editorColor);
|
||||
}
|
||||
/*task list*/
|
||||
li.ag-task-list-item {
|
||||
list-style-type: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
li.ag-task-list-item > input[type=checkbox] {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 4px 0px 0px;
|
||||
top: 2px;
|
||||
left: -22px;
|
||||
transform-origin: center;
|
||||
transform: rotate(-90deg);
|
||||
transition: all .2s ease;
|
||||
}
|
||||
|
||||
li.ag-task-list-item > input.ag-checkbox-checked {
|
||||
transform: rotate(0);
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
li.ag-task-list-item > input[type=checkbox]::before {
|
||||
content: '';
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
border: 2px solid var(--editorColor);
|
||||
border-radius: 2px;
|
||||
background-color: var(--editorBgColor);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transition: all .2s ease;
|
||||
}
|
||||
|
||||
li.ag-task-list-item > input.ag-checkbox-checked::before {
|
||||
border: transparent;
|
||||
background-color: var(--editorColor);
|
||||
}
|
||||
|
||||
li.ag-task-list-item > input::after {
|
||||
content: '';
|
||||
transform: rotate(-45deg) scale(0);
|
||||
width: 9px;
|
||||
height: 5px;
|
||||
border: 2px solid #fff;
|
||||
border-top: none;
|
||||
border-right: none;
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
top: 1px;
|
||||
left: 5px;
|
||||
transition: all .2s ease;
|
||||
}
|
||||
|
||||
li.ag-task-list-item > input.ag-checkbox-checked::after {
|
||||
transform: rotate(-45deg) scale(1);
|
||||
}
|
||||
/*horizontal line*/
|
||||
p:not(.ag-active)[data-role="hr"]::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
display: block;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
height: 2px;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 2px dashed var(--editorColor50);
|
||||
transform: translateX(-50%) translateY(-50%);
|
||||
}
|
||||
`
|
10
yarn.lock
10
yarn.lock
@ -3168,6 +3168,11 @@ dateformat@^1.0.6:
|
||||
get-stdin "^4.0.1"
|
||||
meow "^3.3.0"
|
||||
|
||||
dayjs@^1.8.10:
|
||||
version "1.8.10"
|
||||
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.10.tgz#fc35a976ccac2a9c44b50485a06c4a5ecf5d1b37"
|
||||
integrity sha512-U+7kBBkJzPWww0vNeMkaBeJwnkivTACoajm+bTfwparjFcPI6/5JSQN40WVnX6yCsm20oGf1SkMkIIp4m/boAw==
|
||||
|
||||
de-indent@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d"
|
||||
@ -3397,11 +3402,6 @@ di@^0.0.1:
|
||||
resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c"
|
||||
integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=
|
||||
|
||||
diacritics-map@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/diacritics-map/-/diacritics-map-0.1.0.tgz#6dfc0ff9d01000a2edf2865371cac316e94977af"
|
||||
integrity sha1-bfwP+dAQAKLt8oZTccrDFulJd68=
|
||||
|
||||
diff@3.5.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
|
||||
|
Loading…
Reference in New Issue
Block a user