mirror of
https://github.com/marktext/marktext.git
synced 2025-05-02 11:01:34 +08:00
Optimization of code block (#1445)
* duplicate css rule * remove all codeLine * Fix: #1446 * Fix #942 #1310 * Fix copy paste will add one more empty line in code block * remove debug codes * Fix update thematic break error * fix: #1447 * Update octokit/rest and url-loader * Fix: CI test error * Fix comment issue1 * Fix: escape charachters in code block
This commit is contained in:
parent
4a24ff0954
commit
5b8da2cdf4
@ -116,6 +116,7 @@ function greeting () {
|
||||
font: 'simple3d',
|
||||
space: false
|
||||
})
|
||||
} else console.log(chalk.yellow.bold('\n lets-build'))
|
||||
console.log()
|
||||
} else {
|
||||
console.log(chalk.yellow.bold('\n lets-build'))
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
- languageInput
|
||||
|
||||
- codeLine
|
||||
- codeContent (used in code block)
|
||||
|
||||
- atxLine (can not contain soft line break and hard line break use in atx heading)
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
|
||||
- paragraphContent (defaultValue use in paragraph and setext heading)
|
||||
|
||||
- lang - only when it's code line
|
||||
- lang - only when it's functionType is `codeContent`
|
||||
|
||||
- All prismjs support language or empty string
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@hfelix/electron-localshortcut": "^3.1.1",
|
||||
"@octokit/rest": "^16.30.1",
|
||||
"@octokit/rest": "^16.31.0",
|
||||
"arg": "^4.1.1",
|
||||
"axios": "^0.19.0",
|
||||
"ced": "^1.0.0",
|
||||
@ -155,7 +155,7 @@
|
||||
"svgo": "^1.3.0",
|
||||
"svgo-loader": "^2.2.1",
|
||||
"to-string-loader": "^1.1.5",
|
||||
"url-loader": "^2.1.0",
|
||||
"url-loader": "^2.2.0",
|
||||
"vue-html-loader": "^1.2.4",
|
||||
"vue-loader": "^15.7.1",
|
||||
"vue-style-loader": "^4.1.2",
|
||||
|
@ -103,12 +103,12 @@ export const updateSelectionMenus = (applicationMenu, { start, end, affiliation
|
||||
|
||||
if (
|
||||
(/th|td/.test(start.type) && /th|td/.test(end.type)) ||
|
||||
(start.type === 'span' && start.block.functionType === 'codeLine') ||
|
||||
(end.type === 'span' && end.block.functionType === 'codeLine')
|
||||
(start.type === 'span' && start.block.functionType === 'codeContent') ||
|
||||
(end.type === 'span' && end.block.functionType === 'codeContent')
|
||||
) {
|
||||
setParagraphMenuItemStatus(applicationMenu, false)
|
||||
|
||||
if (start.block.functionType === 'codeLine' || end.block.functionType === 'codeLine') {
|
||||
if (start.block.functionType === 'codeContent' || end.block.functionType === 'codeContent') {
|
||||
setMultipleStatus(applicationMenu, ['codeFencesMenuItem'], true)
|
||||
formatMenuItem.submenu.items.forEach(item => (item.enabled = false))
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ div.ag-show-quick-insert-hint p.ag-paragraph.ag-active > span.ag-paragraph-conte
|
||||
|
||||
.ag-atx-line:empty::after,
|
||||
.ag-thematic-break-line:empty::after,
|
||||
.ag-code-line:empty::after,
|
||||
.ag-code-content:empty::after,
|
||||
.ag-paragraph-content:empty::after {
|
||||
content: '\200B';
|
||||
}
|
||||
@ -47,7 +47,7 @@ div.ag-show-quick-insert-hint p.ag-paragraph.ag-active > span.ag-paragraph-conte
|
||||
.ag-atx-line,
|
||||
.ag-thematic-break-line,
|
||||
.ag-paragraph-content,
|
||||
.ag-code-line {
|
||||
.ag-code-content {
|
||||
display: block;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
@ -76,6 +76,7 @@ div.ag-show-quick-insert-hint p.ag-paragraph.ag-active > span.ag-paragraph-conte
|
||||
.ag-hard-line-break-space::after {
|
||||
content: '↩';
|
||||
opacity: .5;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.ag-line-end {
|
||||
@ -402,7 +403,6 @@ li.ag-task-list-item > input[type=checkbox]::before {
|
||||
content: '';
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
border: 2px solid var(--editorColor50);
|
||||
border-radius: 50%;
|
||||
@ -477,7 +477,7 @@ pre.ag-front-matter {
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
pre.ag-front-matter span.ag-code-line:first-of-type:empty::after {
|
||||
pre.ag-front-matter span.ag-code-content:first-of-type:empty::after {
|
||||
content: 'Input YAML Front Matter...';
|
||||
color: var(--editorColor10);
|
||||
}
|
||||
@ -487,7 +487,7 @@ pre[data-role$='code'] span.ag-language-input:empty::after {
|
||||
color: var(--editorColor10);
|
||||
}
|
||||
|
||||
pre.ag-multiple-math span.ag-code-line:first-of-type:empty::after {
|
||||
pre.ag-multiple-math span.ag-code-content:first-of-type:empty::after {
|
||||
content: 'Input Mathematical Formula...';
|
||||
color: var(--editorColor10);
|
||||
}
|
||||
@ -673,7 +673,7 @@ span.ag-emoji-marked-text {
|
||||
.ag-emoji-marked-text::before {
|
||||
position: absolute;
|
||||
content: attr(data-emoji);
|
||||
color: var(--editorColor);
|
||||
color: #000000;
|
||||
top: 0;
|
||||
left: -1.3em;
|
||||
font-size: 1em;
|
||||
|
@ -70,9 +70,6 @@ export const CLASS_OR_ID = genUpper2LowerKeyHash([
|
||||
'AG_BULLET_LIST',
|
||||
'AG_BULLET_LIST_ITEM',
|
||||
'AG_CHECKBOX_CHECKED',
|
||||
'AG_CODE_LINE',
|
||||
'AG_CODE_LINE_ADD',
|
||||
'AG_CODE_LINE_MINUS',
|
||||
'AG_CONTAINER_BLOCK',
|
||||
'AG_CONTAINER_PREVIEW',
|
||||
'AG_CONTAINER_ICON',
|
||||
|
@ -308,7 +308,7 @@ const backspaceCtrl = ContentState => {
|
||||
|
||||
if (
|
||||
block.type === 'span' &&
|
||||
block.functionType === 'codeLine' &&
|
||||
block.functionType === 'codeContent' &&
|
||||
left === 0 &&
|
||||
!block.preSibling
|
||||
) {
|
||||
|
@ -136,7 +136,7 @@ const clickCtrl = ContentState => {
|
||||
start.key === end.key &&
|
||||
start.offset !== end.offset &&
|
||||
HAS_TEXT_BLOCK_REG.test(block.type) &&
|
||||
block.functionType !== 'codeLine' &&
|
||||
block.functionType !== 'codeContent' &&
|
||||
block.functionType !== 'languageInput'
|
||||
) {
|
||||
const reference = this.getPositionReference()
|
||||
|
@ -79,32 +79,41 @@ const codeBlockCtrl = ContentState => {
|
||||
if (block.type === 'span') {
|
||||
block = this.getParent(block)
|
||||
}
|
||||
// if it's not a p block, no need to update
|
||||
// If it's not a p block, no need to update
|
||||
if (block.type !== 'p') return false
|
||||
// if p block's children are more than one, no need to update
|
||||
// If p block's children are more than one, no need to update
|
||||
if (block.children.length !== 1) return false
|
||||
|
||||
const { text } = block.children[0]
|
||||
const match = CODE_UPDATE_REP.exec(text)
|
||||
if (match || lang) {
|
||||
const codeBlock = this.createBlock('code')
|
||||
const firstLine = this.createBlock('span', { text: code })
|
||||
const language = lang || (match ? match[1] : '')
|
||||
const inputBlock = this.createBlock('span', { text: language })
|
||||
const codeBlock = this.createBlock('code', {
|
||||
lang: language
|
||||
})
|
||||
const codeContent = this.createBlock('span', {
|
||||
text: code,
|
||||
lang: language,
|
||||
functionType: 'codeContent'
|
||||
})
|
||||
const inputBlock = this.createBlock('span', {
|
||||
text: language,
|
||||
functionType: 'languageInput'
|
||||
})
|
||||
|
||||
loadLanguage(language)
|
||||
inputBlock.functionType = 'languageInput'
|
||||
|
||||
block.type = 'pre'
|
||||
block.functionType = 'fencecode'
|
||||
block.lang = language
|
||||
block.text = ''
|
||||
block.history = null
|
||||
block.children = []
|
||||
codeBlock.lang = language
|
||||
firstLine.lang = language
|
||||
firstLine.functionType = 'codeLine'
|
||||
this.appendChild(codeBlock, firstLine)
|
||||
|
||||
this.appendChild(codeBlock, codeContent)
|
||||
this.appendChild(block, inputBlock)
|
||||
this.appendChild(block, codeBlock)
|
||||
const { key } = firstLine
|
||||
const { key } = codeContent
|
||||
const offset = code.length
|
||||
this.cursor = {
|
||||
start: { key, offset },
|
||||
|
@ -1,4 +1,3 @@
|
||||
const LINE_BREAKS_REG = /\n/
|
||||
const FUNCTION_TYPE_LANG = {
|
||||
multiplemath: 'latex',
|
||||
flowchart: 'yaml',
|
||||
@ -33,22 +32,20 @@ const containerCtrl = ContentState => {
|
||||
this.appendChild(preBlock, codeBlock)
|
||||
|
||||
if (typeof value === 'string' && value) {
|
||||
value.replace(/^\s+/, '').split(LINE_BREAKS_REG).forEach(line => {
|
||||
const codeLine = this.createBlock('span', {
|
||||
text: line,
|
||||
functionType: 'codeLine',
|
||||
lang
|
||||
})
|
||||
|
||||
this.appendChild(codeBlock, codeLine)
|
||||
value = value.replace(/^\s+/, '')
|
||||
const codeContent = this.createBlock('span', {
|
||||
text: value,
|
||||
lang,
|
||||
functionType: 'codeContent'
|
||||
})
|
||||
this.appendChild(codeBlock, codeContent)
|
||||
} else {
|
||||
const emptyLine = this.createBlock('span', {
|
||||
functionType: 'codeLine',
|
||||
const emptyCodeContent = this.createBlock('span', {
|
||||
functionType: 'codeContent',
|
||||
lang
|
||||
})
|
||||
|
||||
this.appendChild(codeBlock, emptyLine)
|
||||
this.appendChild(codeBlock, emptyCodeContent)
|
||||
}
|
||||
|
||||
const preview = this.createBlock('div', {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import selection from '../selection'
|
||||
import { CLASS_OR_ID } from '../config'
|
||||
import { escapeHtml } from '../utils'
|
||||
import { getSanitizeHtml } from '../utils/exportHtml'
|
||||
import ExportMarkdown from '../utils/exportMarkdown'
|
||||
import marked from '../parser/marked'
|
||||
@ -34,6 +35,19 @@ const copyCutCtrl = ContentState => {
|
||||
}
|
||||
|
||||
ContentState.prototype.getClipBoradData = function () {
|
||||
const { start, end } = selection.getCursorRange()
|
||||
if (start.key === end.key) {
|
||||
const startBlock = this.getBlock(start.key)
|
||||
const { type, text, functionType } = startBlock
|
||||
// Fix issue #942
|
||||
if (type === 'span' && functionType === 'codeContent') {
|
||||
const selectedText = escapeHtml(text.substring(start.offset, end.offset))
|
||||
return {
|
||||
html: marked(selectedText),
|
||||
text: selectedText
|
||||
}
|
||||
}
|
||||
}
|
||||
const html = selection.getSelectionHtml()
|
||||
const wrapper = document.createElement('div')
|
||||
wrapper.innerHTML = html
|
||||
@ -109,8 +123,8 @@ const copyCutCtrl = ContentState => {
|
||||
const id = cf.id
|
||||
const block = this.getBlock(id)
|
||||
const language = block.lang || ''
|
||||
const selectedCodeLines = cf.querySelectorAll('.ag-code-line')
|
||||
const value = Array.from(selectedCodeLines).map(codeLine => codeLine.textContent).join('\n')
|
||||
const codeContent = cf.querySelector('.ag-code-content')
|
||||
const value = escapeHtml(codeContent.textContent)
|
||||
cf.innerHTML = `<code class="language-${language}">${value}</code>`
|
||||
}
|
||||
|
||||
@ -125,10 +139,9 @@ const copyCutCtrl = ContentState => {
|
||||
|
||||
const htmlBlock = wrapper.querySelectorAll('figure[data-role=\'HTML\']')
|
||||
for (const hb of htmlBlock) {
|
||||
const selectedCodeLines = hb.querySelectorAll('span.ag-code-line')
|
||||
const value = Array.from(selectedCodeLines).map(codeLine => codeLine.textContent).join('\n')
|
||||
const codeContent = hb.querySelector('.ag-code-content')
|
||||
const pre = document.createElement('pre')
|
||||
pre.textContent = value
|
||||
pre.textContent = codeContent.textContent
|
||||
hb.replaceWith(pre)
|
||||
}
|
||||
|
||||
@ -142,8 +155,8 @@ const copyCutCtrl = ContentState => {
|
||||
for (const mb of mathBlock) {
|
||||
const preElement = mb.querySelector('pre[data-role]')
|
||||
const functionType = preElement.getAttribute('data-role')
|
||||
const selectedCodeLines = mb.querySelectorAll('span.ag-code-line')
|
||||
const value = Array.from(selectedCodeLines).map(codeLine => codeLine.textContent).join('\n')
|
||||
const codeContent = mb.querySelector('.ag-code-content')
|
||||
const value = codeContent.textContent
|
||||
let pre
|
||||
switch (functionType) {
|
||||
case 'multiplemath':
|
||||
@ -165,7 +178,6 @@ const copyCutCtrl = ContentState => {
|
||||
|
||||
let htmlData = wrapper.innerHTML
|
||||
const textData = this.htmlToMarkdown(htmlData)
|
||||
|
||||
htmlData = marked(textData)
|
||||
return { html: htmlData, text: textData }
|
||||
}
|
||||
|
@ -33,10 +33,11 @@ const deleteCtrl = ContentState => {
|
||||
) {
|
||||
event.preventDefault()
|
||||
if (nextBlock && /h\d|span/.test(nextBlock.type)) {
|
||||
if (nextBlock.functionType === 'codeLine' && nextBlock.nextSibling) {
|
||||
// if code block more than one line, do nothing!
|
||||
// if cursor at the end of code block-language input, do nothing!
|
||||
if (nextBlock.functionType === 'codeContent' && startBlock.functionType === 'languageInput') {
|
||||
return
|
||||
}
|
||||
|
||||
startBlock.text += nextBlock.text
|
||||
|
||||
const toBeRemoved = [nextBlock]
|
||||
|
@ -237,31 +237,21 @@ const enterCtrl = ContentState => {
|
||||
}
|
||||
return this.partialRender()
|
||||
} else if (
|
||||
block.type === 'span' && block.functionType === 'codeLine'
|
||||
block.type === 'span' && block.functionType === 'codeContent'
|
||||
) {
|
||||
const { text } = block
|
||||
const newLineText = text.substring(start.offset)
|
||||
const { text, key } = block
|
||||
const autoIndent = checkAutoIndent(text, start.offset)
|
||||
const indent = getIndentSpace(text)
|
||||
block.text = text.substring(0, start.offset)
|
||||
const newLine = this.createBlock('span', {
|
||||
text: `${indent}${newLineText}`,
|
||||
functionType: block.functionType,
|
||||
lang: block.lang
|
||||
})
|
||||
block.text = text.substring(0, start.offset) +
|
||||
'\n' +
|
||||
(autoIndent ? indent + ' '.repeat(this.tabSize) + '\n' : '') +
|
||||
indent +
|
||||
text.substring(start.offset)
|
||||
|
||||
let offset = start.offset + 1 + indent.length
|
||||
|
||||
this.insertAfter(newLine, block)
|
||||
let { key } = newLine
|
||||
let offset = indent.length
|
||||
if (autoIndent) {
|
||||
const emptyLine = this.createBlock('span', {
|
||||
text: indent + ' '.repeat(this.tabSize)
|
||||
})
|
||||
emptyLine.functionType = block.functionType
|
||||
emptyLine.lang = block.lang
|
||||
this.insertAfter(emptyLine, block)
|
||||
key = emptyLine.key
|
||||
offset = indent.length + this.tabSize
|
||||
offset += this.tabSize
|
||||
}
|
||||
|
||||
this.cursor = {
|
||||
|
@ -16,7 +16,7 @@ const imageCtrl = ContentState => {
|
||||
if (
|
||||
block.type === 'span' &&
|
||||
(
|
||||
block.functionType === 'codeLine' ||
|
||||
block.functionType === 'codeContent' ||
|
||||
block.functionType === 'languageInput' ||
|
||||
block.functionType === 'thematicBreakLine'
|
||||
)
|
||||
|
@ -28,6 +28,7 @@ import linkCtrl from './linkCtrl'
|
||||
import dragDropCtrl from './dragDropCtrl'
|
||||
import importMarkdown from '../utils/importMarkdown'
|
||||
import Cursor from '../selection/cursor'
|
||||
import escapeCharactersMap, { escapeCharacters } from '../parser/escapeCharacter'
|
||||
|
||||
const prototypes = [
|
||||
tabCtrl,
|
||||
@ -253,6 +254,13 @@ class ContentState {
|
||||
blockData.functionType = 'paragraphContent'
|
||||
}
|
||||
|
||||
if (extras.functionType === 'codeContent' && extras.text) {
|
||||
const CHAR_REG = new RegExp(`(${escapeCharacters.join('|')})`, 'gi')
|
||||
extras.text = extras.text.replace(CHAR_REG, (_, p) => {
|
||||
return escapeCharactersMap[p]
|
||||
})
|
||||
}
|
||||
|
||||
Object.assign(blockData, extras)
|
||||
return blockData
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ const inputCtrl = ContentState => {
|
||||
return false
|
||||
}
|
||||
|
||||
ContentState.prototype.inputHandler = function (event) {
|
||||
ContentState.prototype.inputHandler = function (event, notEqual = false) {
|
||||
const { start, end } = selection.getCursorRange()
|
||||
if (!start || !end) {
|
||||
return
|
||||
@ -86,6 +86,27 @@ const inputCtrl = ContentState => {
|
||||
const key = start.key
|
||||
const block = this.getBlock(key)
|
||||
const paragraph = document.querySelector(`#${key}`)
|
||||
|
||||
// Fix issue 1447
|
||||
// Fixme: any better solution?
|
||||
if (
|
||||
oldStart.key === oldEnd.key &&
|
||||
oldStart.offset === oldEnd.offset &&
|
||||
block.text.endsWith('\n') &&
|
||||
oldStart.offset === block.text.length &&
|
||||
event.inputType === 'insertText'
|
||||
) {
|
||||
event.preventDefault()
|
||||
block.text += event.data
|
||||
const offset = block.text.length
|
||||
this.cursor = {
|
||||
start: { key, offset },
|
||||
end: { key, offset }
|
||||
}
|
||||
this.singleRender(block)
|
||||
return this.inputHandler(event, true)
|
||||
}
|
||||
|
||||
let text = getTextContent(paragraph, [CLASS_OR_ID.AG_MATH_RENDER, CLASS_OR_ID.AG_RUBY_RENDER])
|
||||
|
||||
let needRender = false
|
||||
@ -123,7 +144,7 @@ const inputCtrl = ContentState => {
|
||||
}
|
||||
|
||||
// auto pair (not need to auto pair in math block)
|
||||
if (block && block.text !== text) {
|
||||
if (block && (block.text !== text || notEqual)) {
|
||||
if (
|
||||
start.key === end.key &&
|
||||
start.offset === end.offset &&
|
||||
@ -173,7 +194,7 @@ const inputCtrl = ContentState => {
|
||||
((autoPairQuote && /[']{1}/.test(inputChar) && !(/[a-zA-Z\d]{1}/.test(preInputChar))) ||
|
||||
(autoPairQuote && /["]{1}/.test(inputChar)) ||
|
||||
(autoPairBracket && /[\{\[\(]{1}/.test(inputChar)) ||
|
||||
(block.functionType !== 'codeLine' && !isInInlineMath && !isInInlineCode && autoPairMarkdownSyntax && /[*$`~_]{1}/.test(inputChar)))
|
||||
(block.functionType !== 'codeContent' && !isInInlineMath && !isInInlineCode && autoPairMarkdownSyntax && /[*$`~_]{1}/.test(inputChar)))
|
||||
) {
|
||||
needRender = true
|
||||
text = BRACKET_HASH[event.data]
|
||||
@ -250,8 +271,7 @@ const inputCtrl = ContentState => {
|
||||
|
||||
this.muya.eventCenter.dispatch('muya-quick-insert', reference, block, !!checkQuickInsert)
|
||||
|
||||
// Update preview content of math block
|
||||
if (block && block.type === 'span' && block.functionType === 'codeLine') {
|
||||
if (block && block.type === 'span' && block.functionType === 'codeContent') {
|
||||
needRender = true
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,6 @@ import selection from '../selection'
|
||||
import { PARAGRAPH_TYPES, DEFAULT_TURNDOWN_CONFIG } from '../config'
|
||||
import ExportMarkdown from '../utils/exportMarkdown'
|
||||
|
||||
const LINE_BREAKS_REG = /\n/
|
||||
|
||||
// get header level
|
||||
// eg: h1 => 1
|
||||
// h2 => 2
|
||||
@ -99,15 +97,15 @@ const paragraphCtrl = ContentState => {
|
||||
const codeBlock = this.createBlock('code', {
|
||||
lang
|
||||
})
|
||||
const emptyLine = this.createBlock('span', {
|
||||
functionType: 'codeLine',
|
||||
const emptyCodeContent = this.createBlock('span', {
|
||||
functionType: 'codeContent',
|
||||
lang
|
||||
})
|
||||
|
||||
this.appendChild(codeBlock, emptyLine)
|
||||
this.appendChild(codeBlock, emptyCodeContent)
|
||||
this.appendChild(frontMatter, codeBlock)
|
||||
this.insertBefore(frontMatter, firstBlock)
|
||||
const { key } = emptyLine
|
||||
const { key } = emptyCodeContent
|
||||
const offset = 0
|
||||
this.cursor = {
|
||||
start: { key, offset },
|
||||
@ -248,39 +246,21 @@ const paragraphCtrl = ContentState => {
|
||||
// change fenced code block to p paragraph
|
||||
if (affiliation.length && affiliation[0].type === 'pre' && /code/.test(affiliation[0].functionType)) {
|
||||
const preBlock = affiliation[0]
|
||||
const codeLines = preBlock.children[1].children
|
||||
const codeContent = preBlock.children[1].children[0]
|
||||
preBlock.type = 'p'
|
||||
preBlock.children = []
|
||||
|
||||
const newParagraphBlock = this.createBlockP(codeLines.map(l => l.text).join('\n'))
|
||||
const newParagraphBlock = this.createBlockP(codeContent.text)
|
||||
this.insertBefore(newParagraphBlock, preBlock)
|
||||
|
||||
this.removeBlock(preBlock)
|
||||
const { start, end } = this.cursor
|
||||
|
||||
const key = newParagraphBlock.children[0].key
|
||||
let startOffset = 0
|
||||
let endOffset = 0
|
||||
let startStop = false
|
||||
let endStop = false
|
||||
for (const line of codeLines) {
|
||||
if (line.key !== start.key && !startStop) {
|
||||
startOffset += line.text.length + 1
|
||||
} else {
|
||||
startOffset += start.offset
|
||||
startStop = true
|
||||
}
|
||||
if (line.key !== end.key && !endStop) {
|
||||
endOffset += line.text.length + 1
|
||||
} else {
|
||||
endOffset += end.offset
|
||||
endStop = true
|
||||
}
|
||||
}
|
||||
|
||||
this.cursor = {
|
||||
start: { key, offset: startOffset },
|
||||
end: { key, offset: endOffset }
|
||||
start: { key, offset: start.offset },
|
||||
end: { key, offset: end.offset }
|
||||
}
|
||||
} else {
|
||||
if (start.key === end.key) {
|
||||
@ -293,24 +273,20 @@ const paragraphCtrl = ContentState => {
|
||||
})
|
||||
|
||||
const codeBlock = this.createBlock('code', {
|
||||
lang: ''
|
||||
lang
|
||||
})
|
||||
|
||||
const inputBlock = this.createBlock('span', {
|
||||
functionType: 'languageInput'
|
||||
})
|
||||
|
||||
const codes = startBlock.text.split('\n')
|
||||
|
||||
for (const code of codes) {
|
||||
const codeLine = this.createBlock('span', {
|
||||
text: code,
|
||||
functionType: 'codeLine',
|
||||
lang
|
||||
})
|
||||
this.appendChild(codeBlock, codeLine)
|
||||
}
|
||||
const codeContent = this.createBlock('span', {
|
||||
text: startBlock.text,
|
||||
lang,
|
||||
functionType: 'codeContent'
|
||||
})
|
||||
|
||||
this.appendChild(codeBlock, codeContent)
|
||||
this.appendChild(preBlock, inputBlock)
|
||||
this.appendChild(preBlock, codeBlock)
|
||||
this.insertBefore(preBlock, anchorBlock)
|
||||
@ -345,20 +321,15 @@ const paragraphCtrl = ContentState => {
|
||||
|
||||
const listIndentation = this.listIndentation
|
||||
const markdown = new ExportMarkdown(children.slice(startIndex, endIndex + 1), listIndentation).generate()
|
||||
|
||||
markdown.split(LINE_BREAKS_REG).forEach(text => {
|
||||
const codeLine = this.createBlock('span', {
|
||||
text,
|
||||
lang,
|
||||
functionType: 'codeLine'
|
||||
})
|
||||
|
||||
this.appendChild(codeBlock, codeLine)
|
||||
const codeContent = this.createBlock('span', {
|
||||
text: markdown,
|
||||
lang,
|
||||
functionType: 'codeContent'
|
||||
})
|
||||
const inputBlock = this.createBlock('span', {
|
||||
functionType: 'languageInput'
|
||||
})
|
||||
|
||||
this.appendChild(codeBlock, codeContent)
|
||||
this.appendChild(preBlock, inputBlock)
|
||||
this.appendChild(preBlock, codeBlock)
|
||||
this.insertAfter(preBlock, referBlock)
|
||||
@ -774,20 +745,19 @@ const paragraphCtrl = ContentState => {
|
||||
}
|
||||
// Handler selectAll in code block. only select all the code block conent.
|
||||
// `code block` here is Math, HTML, BLOCK CODE, Mermaid, vega-lite, flowchart, front-matter etc...
|
||||
if (startBlock.type === 'span' && startBlock.functionType === 'codeLine') {
|
||||
const codeBlock = this.getParent(startBlock)
|
||||
const firstCodeLine = this.firstInDescendant(codeBlock)
|
||||
const lastCodeLine = this.lastInDescendant(codeBlock)
|
||||
if (startBlock.type === 'span' && startBlock.functionType === 'codeContent') {
|
||||
const { key } = startBlock
|
||||
this.cursor = {
|
||||
start: {
|
||||
key: firstCodeLine.key,
|
||||
key,
|
||||
offset: 0
|
||||
},
|
||||
end: {
|
||||
key: lastCodeLine.key,
|
||||
offset: lastCodeLine.text.length
|
||||
key,
|
||||
offset: startBlock.text.length
|
||||
}
|
||||
}
|
||||
|
||||
return this.partialRender()
|
||||
}
|
||||
// Handler language input, only select language info only...
|
||||
|
@ -314,42 +314,18 @@ const pasteCtrl = ContentState => {
|
||||
return
|
||||
}
|
||||
|
||||
if (startBlock.type === 'span' && startBlock.functionType === 'codeLine') {
|
||||
let referenceBlock = startBlock
|
||||
if (startBlock.type === 'span' && startBlock.functionType === 'codeContent') {
|
||||
const blockText = startBlock.text
|
||||
const prePartText = blockText.substring(0, start.offset)
|
||||
const postPartText = blockText.substring(end.offset)
|
||||
const textList = text.split(LINE_BREAKS_REG)
|
||||
if (textList.length > 1) {
|
||||
textList.forEach((line, i) => {
|
||||
if (i === 0) {
|
||||
startBlock.text = prePartText + line
|
||||
} else {
|
||||
line = i === textList.length - 1 ? line + postPartText : line
|
||||
const lineBlock = this.createBlock('span', { text: line })
|
||||
lineBlock.functionType = startBlock.functionType
|
||||
lineBlock.lang = startBlock.lang
|
||||
this.insertAfter(lineBlock, referenceBlock)
|
||||
referenceBlock = lineBlock
|
||||
if (i === textList.length - 1) {
|
||||
const { key } = lineBlock
|
||||
const offset = line.length
|
||||
this.cursor = {
|
||||
start: { key, offset },
|
||||
end: { key, offset }
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
startBlock.text = prePartText + text + postPartText
|
||||
const key = startBlock.key
|
||||
const offset = start.offset + text.length
|
||||
this.cursor = {
|
||||
start: { key, offset },
|
||||
end: { key, offset }
|
||||
}
|
||||
startBlock.text = prePartText + text + postPartText
|
||||
const { key } = startBlock
|
||||
const offset = start.offset + text.length
|
||||
this.cursor = {
|
||||
start: { key, offset },
|
||||
end: { key, offset }
|
||||
}
|
||||
|
||||
return this.partialRender()
|
||||
}
|
||||
|
||||
|
@ -292,7 +292,7 @@ const tabCtrl = ContentState => {
|
||||
start.key === end.key &&
|
||||
start.offset === end.offset &&
|
||||
HAS_TEXT_BLOCK_REG.test(startBlock.type) &&
|
||||
startBlock.functionType !== 'codeLine' && // code line has no inline syntax
|
||||
startBlock.functionType !== 'codeContent' && // code content has no inline syntax
|
||||
startBlock.functionType !== 'languageInput' // language input textarea has no inline syntax
|
||||
) {
|
||||
const { text, key } = startBlock
|
||||
@ -312,7 +312,7 @@ const tabCtrl = ContentState => {
|
||||
start.key === end.key &&
|
||||
start.offset === end.offset &&
|
||||
startBlock.type === 'span' &&
|
||||
(!startBlock.functionType || startBlock.functionType === 'codeLine' && /markup|html|xml|svg|mathml/.test(startBlock.lang))
|
||||
(!startBlock.functionType || startBlock.functionType === 'codeContent' && /markup|html|xml|svg|mathml/.test(startBlock.lang))
|
||||
) {
|
||||
const { text } = startBlock
|
||||
const lastWordBeforeCursor = text.substring(0, start.offset).split(/\s+/).pop()
|
||||
|
@ -49,7 +49,7 @@ const tableBlockCtrl = ContentState => {
|
||||
const { type, functionType } = block
|
||||
switch (type) {
|
||||
case 'span':
|
||||
if (functionType === 'codeLine') {
|
||||
if (functionType === 'codeContent') {
|
||||
return this.closest(block, 'figure') || this.closest(block, 'pre')
|
||||
} else {
|
||||
return this.getParent(block)
|
||||
|
@ -68,7 +68,7 @@ const updateCtrl = ContentState => {
|
||||
ContentState.prototype.checkInlineUpdate = function (block) {
|
||||
// table cell can not have blocks in it
|
||||
if (/th|td|figure/.test(block.type)) return false
|
||||
if (/codeLine|languageInput/.test(block.functionType)) return false
|
||||
if (/codeContent|languageInput/.test(block.functionType)) return false
|
||||
|
||||
let line = null
|
||||
const { text } = block
|
||||
@ -84,7 +84,7 @@ const updateCtrl = ContentState => {
|
||||
|
||||
switch (true) {
|
||||
case (!!hr && new Set(hr.split('').filter(i => /\S/.test(i))).size === 1):
|
||||
return this.updateHr(block, hr, line)
|
||||
return this.updateThematicBreak(block, hr, line)
|
||||
|
||||
case !!bullet:
|
||||
return this.updateList(block, 'bullet', bullet, line)
|
||||
@ -115,7 +115,7 @@ const updateCtrl = ContentState => {
|
||||
}
|
||||
|
||||
// Thematic break
|
||||
ContentState.prototype.updateHr = function (block, marker, line) {
|
||||
ContentState.prototype.updateThematicBreak = function (block, marker, line) {
|
||||
// If the block is already thematic break, no need to update.
|
||||
if (block.type === 'hr') return null
|
||||
const text = line.text
|
||||
@ -124,9 +124,10 @@ const updateCtrl = ContentState => {
|
||||
let thematicLine = ''
|
||||
const postParagraphLines = []
|
||||
let thematicLineHasPushed = false
|
||||
|
||||
for (const l of lines) {
|
||||
if (/ {0,3}(?:\\* *\\* *\\*|- *- *-|_ *_ *_)[ \\*\\-\\_]*$/.test(l) && !thematicLineHasPushed) {
|
||||
/* eslint-disable no-useless-escape */
|
||||
if (/ {0,3}(?:\* *\* *\*|- *- *-|_ *_ *_)[ \*\-\_]*$/.test(l) && !thematicLineHasPushed) {
|
||||
/* eslint-enable no-useless-escape */
|
||||
thematicLine = l
|
||||
thematicLineHasPushed = true
|
||||
} else if (!thematicLineHasPushed) {
|
||||
@ -155,9 +156,12 @@ const updateCtrl = ContentState => {
|
||||
this.removeBlock(block)
|
||||
const { start, end } = this.cursor
|
||||
const key = thematicBlock.children[0].key
|
||||
const preParagraphLength = preParagraphLines.reduce((acc, i) => acc + i.length + 1, 0) // Add one, because the `\n`
|
||||
const startOffset = start.offset - preParagraphLength
|
||||
const endOffset = end.offset - preParagraphLength
|
||||
this.cursor = {
|
||||
start: { key, offset: start.offset },
|
||||
end: { key, offset: end.offset }
|
||||
start: { key, offset: startOffset },
|
||||
end: { key, offset: endOffset }
|
||||
}
|
||||
return thematicBlock
|
||||
}
|
||||
@ -519,15 +523,16 @@ const updateCtrl = ContentState => {
|
||||
}
|
||||
|
||||
ContentState.prototype.updateIndentCode = function (block, line) {
|
||||
const lang = ''
|
||||
const codeBlock = this.createBlock('code', {
|
||||
lang: ''
|
||||
lang
|
||||
})
|
||||
const inputBlock = this.createBlock('span', {
|
||||
functionType: 'languageInput'
|
||||
})
|
||||
const preBlock = this.createBlock('pre', {
|
||||
functionType: 'indentcode',
|
||||
lang: ''
|
||||
lang
|
||||
})
|
||||
|
||||
const text = line ? line.text : block.text
|
||||
@ -545,15 +550,13 @@ const updateCtrl = ContentState => {
|
||||
paragraphLines.push(l)
|
||||
}
|
||||
}
|
||||
codeLines.forEach(text => {
|
||||
const codeLine = this.createBlock('span', {
|
||||
text,
|
||||
functionType: 'codeLine',
|
||||
lang: ''
|
||||
})
|
||||
this.appendChild(codeBlock, codeLine)
|
||||
const codeContent = this.createBlock('span', {
|
||||
text: codeLines.join('\n'),
|
||||
functionType: 'codeContent',
|
||||
lang
|
||||
})
|
||||
|
||||
this.appendChild(codeBlock, codeContent)
|
||||
this.appendChild(preBlock, inputBlock)
|
||||
this.appendChild(preBlock, codeBlock)
|
||||
this.insertBefore(preBlock, block)
|
||||
|
@ -275,7 +275,7 @@ class Keyboard {
|
||||
}
|
||||
|
||||
const block = contentState.getBlock(anchor.key)
|
||||
if (anchor.key === focus.key && anchor.offset !== focus.offset && block.functionType !== 'codeLine') {
|
||||
if (anchor.key === focus.key && anchor.offset !== focus.offset && block.functionType !== 'codeContent') {
|
||||
const reference = contentState.getPositionReference()
|
||||
const { formats } = contentState.selectionFormats()
|
||||
eventCenter.dispatch('muya-format-picker', { reference, formats })
|
||||
|
@ -56,7 +56,7 @@ Renderer.prototype.code = function (code, infostring, escaped, codeBlockStyle) {
|
||||
className +
|
||||
'">' +
|
||||
(escaped ? code : escape(code, true)) +
|
||||
'\n</code></pre>\n'
|
||||
'</code></pre>\n'
|
||||
}
|
||||
|
||||
Renderer.prototype.blockquote = function (quote) {
|
||||
|
@ -14,21 +14,40 @@ const MARKER_HASK = {
|
||||
"'": `%${getLongUniqueId()}%`
|
||||
}
|
||||
|
||||
const getHighlightHtml = (text, highlights, escape = false) => {
|
||||
const getHighlightHtml = (text, highlights, escape = false, handleLineEnding = false) => {
|
||||
let code = ''
|
||||
let pos = 0
|
||||
const getEscapeHTML = (className, content) => {
|
||||
return `${MARKER_HASK['<']}span class=${MARKER_HASK['"']}${className}${MARKER_HASK['"']}${MARKER_HASK['>']}${content}${MARKER_HASK['<']}/span${MARKER_HASK['>']}`
|
||||
}
|
||||
|
||||
for (const highlight of highlights) {
|
||||
const { start, end, active } = highlight
|
||||
code += text.substring(pos, start)
|
||||
const className = active ? 'ag-highlight' : 'ag-selection'
|
||||
let highlightContent = text.substring(start, end)
|
||||
if (handleLineEnding && text.endsWith('\n') && end === text.length) {
|
||||
highlightContent = highlightContent.substring(start, end - 1) +
|
||||
(escape
|
||||
? getEscapeHTML('ag-line-end', '\n')
|
||||
: '<span class="ag-line-end">\n</span>')
|
||||
}
|
||||
code += escape
|
||||
? `${MARKER_HASK['<']}span class=${MARKER_HASK['"']}${className}${MARKER_HASK['"']}${MARKER_HASK['>']}${text.substring(start, end)}${MARKER_HASK['<']}/span${MARKER_HASK['>']}`
|
||||
: `<span class="${className}">${text.substring(start, end)}</span>`
|
||||
? getEscapeHTML(className, highlightContent)
|
||||
: `<span class="${className}">${highlightContent}</span>`
|
||||
pos = end
|
||||
}
|
||||
if (pos !== text.length) {
|
||||
code += text.substring(pos)
|
||||
if (handleLineEnding && text.endsWith('\n')) {
|
||||
code += text.substring(pos, text.length - 1) +
|
||||
(escape
|
||||
? getEscapeHTML('ag-line-end', '\n')
|
||||
: '<span class="ag-line-end">\n</span>')
|
||||
} else {
|
||||
code += text.substring(pos)
|
||||
}
|
||||
}
|
||||
|
||||
return code
|
||||
}
|
||||
|
||||
@ -81,7 +100,7 @@ export default function renderLeafBlock (block, activeBlocks, matches, useCache
|
||||
tokens = this.tokenCache.get(text)
|
||||
} else if (
|
||||
HAS_TEXT_BLOCK_REG.test(type) &&
|
||||
functionType !== 'codeLine' &&
|
||||
functionType !== 'codeContent' &&
|
||||
functionType !== 'languageInput'
|
||||
) {
|
||||
const hasBeginRules = type === 'span'
|
||||
@ -197,8 +216,8 @@ export default function renderLeafBlock (block, activeBlocks, matches, useCache
|
||||
selector += `.${CLASS_OR_ID.AG_CHECKBOX_CHECKED}`
|
||||
}
|
||||
children = ''
|
||||
} else if (type === 'span' && functionType === 'codeLine') {
|
||||
const code = escapeHtml(getHighlightHtml(text, highlights, true))
|
||||
} else if (type === 'span' && functionType === 'codeContent') {
|
||||
const code = escapeHtml(getHighlightHtml(text, highlights, true, true))
|
||||
.replace(new RegExp(MARKER_HASK['<'], 'g'), '<')
|
||||
.replace(new RegExp(MARKER_HASK['>'], 'g'), '>')
|
||||
.replace(new RegExp(MARKER_HASK['"'], 'g'), '"')
|
||||
|
@ -419,6 +419,7 @@ class Selection {
|
||||
offset
|
||||
}
|
||||
}
|
||||
|
||||
const childNodes = node.childNodes
|
||||
const len = childNodes.length
|
||||
let i
|
||||
@ -429,6 +430,7 @@ class Selection {
|
||||
if (child.classList && child.classList.contains(CLASS_OR_ID.AG_FRONT_ICON)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (count + textLength >= offset) {
|
||||
if (
|
||||
child.classList && child.classList.contains('ag-inline-image')
|
||||
@ -536,8 +538,10 @@ class Selection {
|
||||
|
||||
const anchorParagraph = findNearestParagraph(anchorNode)
|
||||
const focusParagraph = findNearestParagraph(focusNode)
|
||||
|
||||
let aOffset = getOffsetOfParagraph(anchorNode, anchorParagraph) + anchorOffset
|
||||
let fOffset = getOffsetOfParagraph(focusNode, focusParagraph) + focusOffset
|
||||
|
||||
// fix input after image.
|
||||
if (
|
||||
anchorNode === focusNode &&
|
||||
@ -576,6 +580,7 @@ class Selection {
|
||||
}
|
||||
|
||||
const anchor = { key: anchorParagraph.id, offset: aOffset }
|
||||
|
||||
const focus = { key: focusParagraph.id, offset: fOffset }
|
||||
const result = new Cursor({ anchor, focus })
|
||||
|
||||
|
@ -247,7 +247,8 @@ class ExportMarkdown {
|
||||
|
||||
normalizeCodeBlock (block, indent) {
|
||||
const result = []
|
||||
const textList = block.children[1].children.map(codeLine => codeLine.text)
|
||||
const codeContent = block.children[1].children[0]
|
||||
const textList = codeContent.text.split('\n')
|
||||
const { functionType } = block
|
||||
if (functionType === 'fencecode') {
|
||||
result.push(`${indent}${block.lang ? '```' + block.lang + '\n' : '```\n'}`)
|
||||
@ -266,9 +267,10 @@ class ExportMarkdown {
|
||||
|
||||
normalizeHTML (block, indent) { // figure
|
||||
const result = []
|
||||
const codeLines = block.children[0].children[0].children
|
||||
for (const line of codeLines) {
|
||||
result.push(`${indent}${line.text}\n`)
|
||||
const codeContentText = block.children[0].children[0].children[0].text
|
||||
const lines = codeContentText.split('\n')
|
||||
for (const line of lines) {
|
||||
result.push(`${indent}${line}\n`)
|
||||
}
|
||||
return result.join('')
|
||||
}
|
||||
|
@ -11,8 +11,6 @@ import { loadLanguage } from '../prism/index'
|
||||
// To be disabled rules when parse markdown, Because content state don't need to parse inline rules
|
||||
import { CURSOR_ANCHOR_DNA, CURSOR_FOCUS_DNA } from '../config'
|
||||
|
||||
const LINE_BREAKS_REG = /\n/
|
||||
|
||||
// Just because turndown change `\n`(soft line break) to space, So we add `span.ag-soft-line-break` to workaround.
|
||||
const turnSoftBreakToSpan = html => {
|
||||
const parser = new DOMParser()
|
||||
@ -23,7 +21,7 @@ const turnSoftBreakToSpan = html => {
|
||||
const root = doc.querySelector('#turn-root')
|
||||
const travel = childNodes => {
|
||||
for (const node of childNodes) {
|
||||
if (node.nodeType === 3) {
|
||||
if (node.nodeType === 3 && node.parentNode.tagName !== 'CODE') {
|
||||
let startLen = 0
|
||||
let endLen = 0
|
||||
const text = node.nodeValue.replace(/^(\n+)/, (_, p) => {
|
||||
@ -89,27 +87,25 @@ const importRegister = ContentState => {
|
||||
case 'frontmatter': {
|
||||
const { lang, style } = token
|
||||
value = token.text
|
||||
.replace(/^\s+/, '')
|
||||
.replace(/\s$/, '')
|
||||
block = this.createBlock('pre', {
|
||||
functionType: token.type,
|
||||
lang,
|
||||
style
|
||||
})
|
||||
|
||||
const codeBlock = this.createBlock('code', {
|
||||
lang
|
||||
})
|
||||
value
|
||||
.replace(/^\s+/, '')
|
||||
.replace(/\s$/, '')
|
||||
.split(LINE_BREAKS_REG).forEach(line => {
|
||||
const codeLine = this.createBlock('span', {
|
||||
text: line,
|
||||
lang,
|
||||
functionType: 'codeLine'
|
||||
})
|
||||
|
||||
this.appendChild(codeBlock, codeLine)
|
||||
})
|
||||
const codeContent = this.createBlock('span', {
|
||||
text: value,
|
||||
lang,
|
||||
functionType: 'codeContent'
|
||||
})
|
||||
|
||||
this.appendChild(codeBlock, codeContent)
|
||||
this.appendChild(block, codeBlock)
|
||||
this.appendChild(parentList[0], block)
|
||||
break
|
||||
@ -175,13 +171,10 @@ const importRegister = ContentState => {
|
||||
const codeBlock = this.createBlock('code', {
|
||||
lang
|
||||
})
|
||||
value.split(LINE_BREAKS_REG).forEach(line => {
|
||||
const codeLine = this.createBlock('span', {
|
||||
text: line
|
||||
})
|
||||
codeLine.lang = lang
|
||||
codeLine.functionType = 'codeLine'
|
||||
this.appendChild(codeBlock, codeLine)
|
||||
const codeContent = this.createBlock('span', {
|
||||
text: value,
|
||||
lang,
|
||||
functionType: 'codeContent'
|
||||
})
|
||||
const inputBlock = this.createBlock('span', {
|
||||
text: lang,
|
||||
@ -205,6 +198,7 @@ const importRegister = ContentState => {
|
||||
})
|
||||
}
|
||||
|
||||
this.appendChild(codeBlock, codeContent)
|
||||
this.appendChild(block, inputBlock)
|
||||
this.appendChild(block, codeBlock)
|
||||
this.appendChild(parentList[0], block)
|
||||
@ -364,6 +358,7 @@ const importRegister = ContentState => {
|
||||
html = html.replace(/<span> <\/span>/g, String.fromCharCode(160))
|
||||
|
||||
html = turnSoftBreakToSpan(html)
|
||||
|
||||
const markdown = turndownService.turndown(html)
|
||||
return markdown
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import TurndownService from 'turndown'
|
||||
import { CLASS_OR_ID, LINE_BREAK } from '../config'
|
||||
import { identity } from './index'
|
||||
|
||||
const turndownPluginGfm = require('joplin-turndown-plugin-gfm')
|
||||
@ -27,18 +26,6 @@ export const usePluginAddRules = (turndownService, keeps) => {
|
||||
}
|
||||
})
|
||||
|
||||
// Add `LINE_BREAK` to the end of every code line but not the last line.
|
||||
turndownService.addRule('codeLineBreak', {
|
||||
filter (node, options) {
|
||||
return (
|
||||
node.nodeName === 'SPAN' && node.classList.contains(CLASS_OR_ID.AG_CODE_LINE) && node.nextElementSibling
|
||||
)
|
||||
},
|
||||
replacement (content, node, options) {
|
||||
return content + LINE_BREAK
|
||||
}
|
||||
})
|
||||
|
||||
turndownService.escape = identity
|
||||
turndownService.keep(keeps)
|
||||
}
|
||||
|
26
yarn.lock
26
yarn.lock
@ -873,10 +873,10 @@
|
||||
once "^1.4.0"
|
||||
universal-user-agent "^4.0.0"
|
||||
|
||||
"@octokit/rest@^16.30.1":
|
||||
version "16.30.1"
|
||||
resolved "https://registry.npmjs.org/@octokit/rest/-/rest-16.30.1.tgz#03e6dfb93e9a9cd2b3bacb95c49a8c7923f42ad0"
|
||||
integrity sha512-1n2QzTbbaBXNLpx7WHlcsSMdJvxSdKmerXQm+bMYlKDbQM19uq446ZpGs7Ynq5SsdLj1usIfgJ9gJf4LtcWkDw==
|
||||
"@octokit/rest@^16.31.0":
|
||||
version "16.31.0"
|
||||
resolved "https://registry.npmjs.org/@octokit/rest/-/rest-16.31.0.tgz#97ceba8e9b6bfdaffa321d7022917053fcb7dc39"
|
||||
integrity sha512-ZmMpc59N/Ju8FjN2qyOefB+vLppO/8uP/tPyvwEe7cQxdXvPx0OXL/OxDLib8tnT046AtgMNYaXH3FpZnrUdOA==
|
||||
dependencies:
|
||||
"@octokit/request" "^5.0.0"
|
||||
"@octokit/request-error" "^1.0.2"
|
||||
@ -10216,6 +10216,14 @@ schema-utils@^2.2.0:
|
||||
ajv "^6.10.2"
|
||||
ajv-keywords "^3.4.1"
|
||||
|
||||
schema-utils@^2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.4.1.tgz#e89ade5d056dc8bcaca377574bb4a9c4e1b8be56"
|
||||
integrity sha512-RqYLpkPZX5Oc3fw/kHHHyP56fg5Y+XBpIpV8nCg0znIALfq3OH+Ea9Hfeac9BAMwG5IICltiZ0vxFvJQONfA5w==
|
||||
dependencies:
|
||||
ajv "^6.10.2"
|
||||
ajv-keywords "^3.4.1"
|
||||
|
||||
scope-css@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.npmjs.org/scope-css/-/scope-css-1.2.1.tgz#c35768bc900cad030a3e0d663a818c0f6a57f40e"
|
||||
@ -11690,14 +11698,14 @@ urix@^0.1.0:
|
||||
resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
|
||||
integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=
|
||||
|
||||
url-loader@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.npmjs.org/url-loader/-/url-loader-2.1.0.tgz#bcc1ecabbd197e913eca23f5e0378e24b4412961"
|
||||
integrity sha512-kVrp/8VfEm5fUt+fl2E0FQyrpmOYgMEkBsv8+UDP1wFhszECq5JyGF33I7cajlVY90zRZ6MyfgKXngLvHYZX8A==
|
||||
url-loader@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.npmjs.org/url-loader/-/url-loader-2.2.0.tgz#af321aece1fd0d683adc8aaeb27829f29c75b46e"
|
||||
integrity sha512-G8nk3np8ZAnwhHXas1JxJEwJyQdqFXAKJehfgZ/XrC48volFBRtO+FIKtF2u0Ma3bw+4vnDVjHPAQYlF9p2vsw==
|
||||
dependencies:
|
||||
loader-utils "^1.2.3"
|
||||
mime "^2.4.4"
|
||||
schema-utils "^2.0.0"
|
||||
schema-utils "^2.4.1"
|
||||
|
||||
url-parse-lax@^3.0.0:
|
||||
version "3.0.0"
|
||||
|
Loading…
Reference in New Issue
Block a user