diff --git a/src/editor/index.js b/src/editor/index.js index 66345ec..d94f863 100644 --- a/src/editor/index.js +++ b/src/editor/index.js @@ -605,7 +605,7 @@ class Editor extends Component { } } - #chnageFontSize(ev) { + #changeFontSize(ev) { if (ev.target === ev.currentTarget) { return } @@ -677,6 +677,8 @@ class Editor extends Component { grids[i].classList.toggle('active', _x <= x && _y <= y) } } else { + this.#gridx = -1 + this.#gridy = -1 grids.forEach(it => it.classList.remove('active')) } } @@ -826,7 +828,7 @@ class Editor extends Component {
6号字体 5号字体 diff --git a/src/markd/core.js b/src/markd/core.js index f1f4fc0..2f93e0e 100644 --- a/src/markd/core.js +++ b/src/markd/core.js @@ -33,7 +33,7 @@ const Helper = { isHr(str) { var s = str[0] if (HR_LIST.includes(s)) { - return str.slice(0, 3) === s.repeat(3) ? str.slice(3) : false + return str.trim() === s.repeat(3) } return false }, @@ -118,8 +118,8 @@ const Decoder = { .replace(ESCAPE_RE, '$1') // 处理转义字符 }, // 分割线 - hr(name = '') { - return `\n\n
\n\n` + hr() { + return `\n\n
\n\n` }, // 标题 head(str) { @@ -362,10 +362,8 @@ class Tool { } // 无属性标签 - - let hrName = Helper.isHr(it) - if (typeof hrName === 'string') { - html += Decoder.hr(hrName) + if (Helper.isHr(it)) { + html += Decoder.hr() continue } diff --git a/src/markd/index.js b/src/markd/index.js index 74c7fc5..c79a5d7 100644 --- a/src/markd/index.js +++ b/src/markd/index.js @@ -76,19 +76,11 @@ class Markd extends Component { } } - fieldset.md-hr { + hr { + height: 1px; margin: 30px 0; border: 0; border-top: 1px dashed var(--color-plain-3); - - legend { - color: var(--color-grey-1); - text-align: center; - font-size: 12px; - &::before { - content: attr(name); - } - } } ol { margin-left: 1em; diff --git a/src/meditor/addon.js b/src/meditor/addon.js index babfe65..dd78c1d 100644 --- a/src/meditor/addon.js +++ b/src/meditor/addon.js @@ -30,7 +30,7 @@ function showDialog(dialog, elem) { export default { header(elem) { - showDialog(this.__HEADER_ADDON__, elem) + this.$refs.header.classList.add('fadein') }, h(level) { @@ -97,7 +97,8 @@ export default { }, table(elem) { - showDialog(this.__TABLE_ADDON__, elem) + // showDialog(this.__TABLE_ADDON__, elem) + this.$refs.table.classList.add('fadein') }, link(elem) { diff --git a/src/meditor/index.js b/src/meditor/index.js index 5819821..38c818d 100644 --- a/src/meditor/index.js +++ b/src/meditor/index.js @@ -234,57 +234,78 @@ class MEditor extends Component { `, css` - .addon-table { - display: flex; - flex-direction: column; - justify-content: space-between; - width: 222px; - height: 222px; - padding: 2px; + .font-layer, + .table-layer { + visibility: hidden; + position: absolute; + left: 0; + top: 0; + z-index: 99; + width: 80px; + padding: 5px 0; + line-height: 25px; background: #fff; + box-shadow: 0 0 8px rgba(0, 0, 0, 0.2); + font-size: 13px; + opacity: 0; + transition: all ease-in-out 0.2s; - li { - display: flex; - justify-content: space-between; - height: 20px; + &.fadein { + visibility: visible; + top: 34px; + opacity: 1; + } + } - span { - width: 20px; - height: 20px; - background: var(--color-plain-1); + .font-layer { + font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; - &.active { - background: rgba(77, 182, 172, 0.3); - } + span { + display: block; + padding: 0 8px; + + &:hover { + background: #f7f8fb; + } + + &:first-child { + font-size: 24px; + } + &:nth-child(2) { + font-size: 22px; + } + &:nth-child(3) { + font-size: 20px; + } + &:nth-child(4) { + font-size: 18px; + } + &:nth-child(5) { + font-size: 16px; + } + &:nth-child(6) { + font-size: 14px; } } } - .addon-header { - width: 108px; - height: 190px; - padding: 5px 0; - line-height: 30px; - user-select: none; + .table-layer { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + left: 240px; + width: 200px; + height: 200px; + padding: 2px; background: #fff; - li { - display: flex; - align-items: center; - width: 100%; - height: 30px; - padding: 0 12px; - transition: background 0.1s ease-in-out; - cursor: pointer; + span { + width: 20px; + height: 20px; + background: var(--color-plain-1); - .icon { - width: 14px; - height: 14px; - margin-right: 8px; - } - - &:hover { - background: var(--color-plain-1); + &.active { + background: rgba(77, 182, 172, 0.3); } } } @@ -404,6 +425,25 @@ class MEditor extends Component { } } } + `, + + css` + .editor, + wc-markd { + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-thumb { + visibility: hidden; + border-radius: 3px; + } + + &:hover::-webkit-scrollbar-thumb { + visibility: visible; + background: rgba(0, 0, 0, 0.3); + } + } ` ] @@ -411,7 +451,6 @@ class MEditor extends Component { try { return this.$refs.editor.value } catch (err) { - console.log(err) return '' } } @@ -431,7 +470,7 @@ class MEditor extends Component { #toolbar = [...DEFAULT_TOOLS] #value = '' - #cache = { bar: 0, y: 0 } + #gridx = 0 #gridy = 0 @@ -439,49 +478,10 @@ class MEditor extends Component { previewEnabled = false - __init__() { - // - let { outer, inner, thumb } = this.$refs - let height = outer.offsetHeight - let scrollHeight = inner.scrollHeight + 10 - - let bar = 50 // 滚动条的高度 - bar = (height * (height / scrollHeight)) >> 0 - - if (bar < 50) { - bar = 50 - } - - // 100%或主体高度比滚动条还短时不显示 - if (bar >= height) { - bar = 0 - } - - this.#cache.bar = bar - thumb.style.height = bar + 'px' - } - - #fetchScroll(moveY) { - let { bar } = this.#cache - let { outer, thumb, inner } = this.$refs - let height = outer.offsetHeight - let scrollHeight = inner.scrollHeight + 10 - - if (moveY < 0) { - moveY = 0 - } else if (moveY > height - bar) { - moveY = height - bar - } - - inner.scrollTop = (scrollHeight - height) * (moveY / (height - bar)) - thumb.style.transform = `translateY(${moveY}px)` - return moveY - } - #hideLayers() { - this.$refs.font.classList.remove('fadein') - this.$refs.color.classList.remove('fadein') - this.$refs.link.classList.remove('fadein') + this.$refs.header.classList.remove('fadein') + // this.$refs.color.classList.remove('fadein') + // this.$refs.link.classList.remove('fadein') this.$refs.table.classList.remove('fadein') } @@ -548,8 +548,6 @@ class MEditor extends Component { var elem = ev.target var act - this.restoreSelection() - if (elem === ev.currentTarget) { return } @@ -564,20 +562,19 @@ class MEditor extends Component { act = elem.dataset.act - // this.#hideLayers() + this.#hideLayers() Addon[act].call(this, elem) } - #chnageFontSize(ev) { + #setHeaderLevel(ev) { if (ev.target === ev.currentTarget) { return } - this.$refs.font.classList.remove('fadein') + this.$refs.header.classList.remove('fadein') this.$refs.editor.focus() - this.restoreSelection() - this.exec(ACTTION.font, ev.target.dataset.size) - this.saveSelection() + let level = +ev.target.dataset.value + Addon.h.call(this, level) } #chnageColor(ev) { @@ -604,17 +601,16 @@ class MEditor extends Component { } #insertTable(ev) { - let th = ` `.repeat(this.#gridx + 1) - let td = ` `.repeat(this.#gridx + 1) - this.exec( - 'insertHtml', - `
- - ${th} - ${`${td}`.repeat(this.#gridy + 1)} -

` - ) this.$refs.table.classList.remove('fadein') + if (this.#gridx < 0 || this.#gridy < 0) { + return + } + let thead = `\n\n${'| 表头 '.repeat(this.#gridx)}|\n` + let pipe = `${'| -- '.repeat(this.#gridx)}|\n` + let tbody = ('| '.repeat(this.#gridx) + '|\n').repeat(this.#gridy) + this.#gridx = -1 + this.#gridy = -1 + this.insert(thead + pipe + tbody, false) } #tableSelect(ev) { @@ -641,29 +637,12 @@ class MEditor extends Component { grids[i].classList.toggle('active', _x <= x && _y <= y) } } else { + this.#gridx = -1 + this.#gridy = -1 grids.forEach(it => it.classList.remove('active')) } } - // 保存选中 - saveSelection() { - var gs = this.root.getSelection() - if (gs.getRangeAt && gs.rangeCount) { - this.#select = gs.getRangeAt(0) - } - } - - // 清除选中并重置选中 - restoreSelection() { - var gs = this.root.getSelection() - if (this.#select) { - try { - gs.removeAllRanges() - } catch (err) {} - gs.addRange(this.#select) - } - } - /** * 往文本框中插入内容 * @param {String} val [要插入的文本] @@ -907,6 +886,18 @@ class MEditor extends Component { } } + #syncScrollToPreview(ev) { + if (this.previewEnabled) { + let { editor, view } = this.$refs + let st = editor.scrollTop + let eh = editor.clientHeight + let sh = editor.scrollHeight + let veh = view.clientHeight + let vsh = view.scrollHeight + this.$refs.view.scrollTop = (st / (sh - eh)) * (vsh - veh) + } + } + mounted() { Addon.preview.call(this, this) } @@ -934,9 +925,35 @@ class MEditor extends Component { @keydown=${this.#handleKeydown} @paste.prevent=${this.#handlePaste} @input=${this.#updatePreview} + @scroll=${this.#syncScrollToPreview} >
+ +
+ H1 + H2 + H3 + H4 + H5 + H6 +
+ +
+ ${Array(81) + .fill(0) + .map((_, n) => html``)} +
` }