Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: undo error when input slash #172

Merged
merged 3 commits into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
"name": "muya-examples",
"version": "0.0.1",
"description": "Muya vanilla ts demo project",
"author": "jocs <[email protected]>",
"scripts": {
"dev:demo": "vite"
},
"keywords": [],
"author": "jocs <[email protected]>",
"license": "MIT",
"dependencies": {
"@muyajs/core": "workspace:*",
"intl-segmenter-polyfill": "^0.4.4"
}
}
}
27 changes: 14 additions & 13 deletions packages/core/src/block/base/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,9 @@ class Content extends TreeNode {
if (
(event.key === EVENT_KEYS.ArrowUp && topOffset > 0)
|| (event.key === EVENT_KEYS.ArrowDown && bottomOffset > 0)
)
) {
return;
}

const { muya } = this;
let cursorBlock = null;
Expand Down Expand Up @@ -328,13 +329,13 @@ class Content extends TreeNode {
else if (
!event.inputType.includes('delete')
&& inputChar === postInputChar
&& ((autoPairQuote && /[']{1}/.test(inputChar))
|| (autoPairQuote && /["]{1}/.test(inputChar))
|| (autoPairBracket && /[}\])]{1}/.test(inputChar))
|| (autoPairMarkdownSyntax && /[$]{1}/.test(inputChar))
&& ((autoPairQuote && /'/.test(inputChar))
|| (autoPairQuote && /"/.test(inputChar))
|| (autoPairBracket && /[}\])]/.test(inputChar))
|| (autoPairMarkdownSyntax && /\$/.test(inputChar))
|| (autoPairMarkdownSyntax
&& /[*$`~_]{1}/.test(inputChar)
&& /[_*~]{1}/.test(prePreInputChar)))
&& /[*$`~_]/.test(inputChar)
&& /[_*~]/.test(prePreInputChar)))
) {
needRender = true;
text = text.substring(0, offset) + text.substring(offset + 1);
Expand All @@ -345,16 +346,16 @@ class Content extends TreeNode {
if (
!/\\/.test(preInputChar)
&& ((autoPairQuote
&& /[']{1}/.test(inputChar)
&& !/[a-zA-Z\d]{1}/.test(preInputChar))
|| (autoPairQuote && /["]{1}/.test(inputChar))
|| (autoPairBracket && /[{[(]{1}/.test(inputChar))
&& /'/.test(inputChar)
&& !/[a-z\d]/i.test(preInputChar))
|| (autoPairQuote && /"/.test(inputChar))
|| (autoPairBracket && /[{[(]/.test(inputChar))
|| (type === 'format'
&& !isInInlineMath
&& !isInInlineCode
&& autoPairMarkdownSyntax
&& !/[a-z0-9]{1}/i.test(preInputChar)
&& /[*$`~_]{1}/.test(inputChar)))
&& !/[a-z0-9]/i.test(preInputChar)
&& /[*$`~_]/.test(inputChar)))
) {
needRender = true;
text
Expand Down
35 changes: 22 additions & 13 deletions packages/core/src/block/base/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,9 @@ class Format extends Content {
[Math.max(0, start - 1), Math.min(textLen, end + 1)],
[focusOffset, focusOffset],
)
)
) {
return true;
}
}

return false;
Expand Down Expand Up @@ -567,8 +568,9 @@ class Format extends Content {
if (
this.isComposed
|| /historyUndo|historyRedo/.test((event as InputEvent).inputType)
)
) {
return;
}

const { domNode } = this;
const { start, end } = this.getCursor()!;
Expand Down Expand Up @@ -720,7 +722,7 @@ class Format extends Content {
for (const l of lines) {
const THEMATIC_BREAK_REG

= / {0,3}(?:\* *\* *\*|- *- *-|_ *_ *_)[ \*\-\_]*$/;
= / {0,3}(?:\* *\* *\*|- *- *-|_ *_ *_)[ *\-_]*$/;
if (THEMATIC_BREAK_REG.test(l) && !thematicLineHasPushed) {
thematicLine = l;
thematicLineHasPushed = true;
Expand Down Expand Up @@ -844,15 +846,16 @@ class Format extends Content {
const { preferLooseListItem } = muya.options;
const listItem = parent!.parent!;
const list = listItem?.parent as BulletList;
const matches = text.match(/^\[([x ]{1})\] {1,4}([\s\S]*)$/i);
const matches = text.match(/^\[([x ])\] {1,4}([\s\S]*)$/i);

if (
!list
|| list.blockName !== 'bullet-list'
|| !parent!.isFirstChild()
|| matches == null
)
) {
return;
}

const listState = {
name: 'task-list',
Expand Down Expand Up @@ -937,8 +940,9 @@ class Format extends Content {
if (
this.parent!.blockName === 'atx-heading'
&& (this.parent as AtxHeading).meta.level === level
)
) {
return;
}

const { hasSelection } = this;
const { start, end } = this.getCursor()!;
Expand All @@ -950,7 +954,7 @@ class Format extends Content {
let atxLineHasPushed = false;

for (const l of lines) {
if (/^ {0,3}#{1,6}(?=\s{1,}|$)/.test(l) && !atxLineHasPushed) {
if (/^ {0,3}#{1,6}(?=\s+|$)/.test(l) && !atxLineHasPushed) {
atxLine = l;
atxLineHasPushed = true;
}
Expand Down Expand Up @@ -1017,8 +1021,9 @@ class Format extends Content {
if (
this.parent?.blockName === 'setext-heading'
&& (this.parent as SetextHeading).meta.level === level
)
) {
return;
}

const { hasSelection } = this;
const { text, muya } = this;
Expand All @@ -1028,7 +1033,7 @@ class Format extends Content {
let setextLineHasPushed = false;

for (const l of lines) {
if (/^ {0,3}(?:={3,}|-{3,})(?= {1,}|$)/.test(l) && !setextLineHasPushed)
if (/^ {0,3}(?:={3,}|-{3,})(?= +|$)/.test(l) && !setextLineHasPushed)
setextLineHasPushed = true;
else if (!setextLineHasPushed)
setextLines.push(l);
Expand Down Expand Up @@ -1211,8 +1216,9 @@ class Format extends Content {
!force
&& (this.parent!.blockName === 'setext-heading'
|| this.parent!.blockName === 'paragraph')
)
) {
return;
}

const { text, muya, hasSelection } = this;
const { start, end } = this.getCursor()!;
Expand Down Expand Up @@ -1335,8 +1341,9 @@ class Format extends Content {
needRemovedBlock
&& needRemovedBlock.isOnlyChild()
&& !needRemovedBlock.isScrollPage
)
) {
needRemovedBlock = needRemovedBlock.parent;
}

this.text = text + nextBlock.text;
this.setCursor(start.offset, end.offset, true);
Expand Down Expand Up @@ -1396,8 +1403,9 @@ class Format extends Content {
checkTokenIsInlineFormat(token)
&& start.offset >= token.range.start
&& end.offset <= token.range.end
)
) {
formats.push(token);
}

if (
checkTokenIsInlineFormat(token)
Expand All @@ -1407,8 +1415,9 @@ class Format extends Content {
&& end.offset <= token.range.end)
|| (start.offset <= token.range.start
&& token.range.end <= end.offset))
)
) {
neighbors.push(token);
}

if ('children' in token && Array.isArray(token.children))
iterator(token.children);
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/block/commonMark/html/htmlPreview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class HTMLPreview extends Parent {
const htmlContent = sanitize(html, PREVIEW_DOMPURIFY_CONFIG, disableHtml) as string;

// handle empty html bock
if (/^<([a-z][a-z\d]*)[^>]*?>(\s*)<\/\1>$/.test(htmlContent.trim())) {
if (/^<([a-z][a-z\d]*)[^>]*>(\s*)<\/\1>$/.test(htmlContent.trim())) {
this.domNode!.innerHTML
= '<div class="mu-empty">&lt;Empty HTML Block&gt;</div>';
}
Expand Down
17 changes: 11 additions & 6 deletions packages/core/src/block/content/paragraphContent/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ import type {
} from '../../../state/types';

enum UnindentType {
INDENT = 'INDENT',
REPLACEMENT = 'REPLACEMENT',
INDENT,
REPLACEMENT,
}

const debug = logger('paragraph:content');

const HTML_BLOCK_REG = /^<([a-zA-Z\d-]+)(?=\s|>)[^<>]*?>$/;
const HTML_BLOCK_REG = /^<([a-z\d-]+)(?=\s|>)[^<>]*>$/i;

const BOTH_SIDES_FORMATS = [
'strong',
Expand Down Expand Up @@ -137,6 +137,7 @@ class ParagraphContent extends Format {
event.preventDefault();
event.stopPropagation();

// eslint-disable-next-line regexp/no-super-linear-backtracking
const TABLE_BLOCK_REG = /^\|.*?(\\*)\|.*?(\\*)\|/;
const MATH_BLOCK_REG = /^\$\$/;
const { text } = this;
Expand Down Expand Up @@ -523,8 +524,9 @@ class ParagraphContent extends Format {
listParent
&& (listParent.blockName === 'list-item'
|| listParent.blockName === 'task-list-item')
)
) {
return list.prev ? UnindentType.INDENT : UnindentType.REPLACEMENT;
}

return null;
}
Expand All @@ -545,8 +547,9 @@ class ParagraphContent extends Format {
(listItem.blockName !== 'list-item'
&& listItem.blockName !== 'task-list-item')
|| !this.isCollapsed
)
) {
return false;
}

return list && /ol|ul/.test(list.tagName) && listItem.prev;
}
Expand All @@ -564,8 +567,9 @@ class ParagraphContent extends Format {
|| list == null
|| listParent == null
|| cursor == null
)
) {
return;
}

const { start, end } = cursor;

Expand Down Expand Up @@ -705,6 +709,7 @@ class ParagraphContent extends Format {
});
let result = null;

// eslint-disable-next-line complexity
const walkTokens = (ts: Token[]) => {
for (const token of ts) {
const { type, range } = token;
Expand Down
6 changes: 4 additions & 2 deletions packages/core/src/clipboard/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ class Clipboard {
/Alt|Option|Meta|Shift|CapsLock|ArrowUp|ArrowDown|ArrowLeft|ArrowRight/.test(
key,
)
)
) {
return;
}

if (metaKey)
return;
Expand Down Expand Up @@ -606,8 +607,9 @@ class Clipboard {
if (
originWrapperBlock?.blockName === 'paragraph'
&& (originWrapperBlock.getState() as any).text === ''
)
) {
originWrapperBlock.remove();
}

const cursorBlock = wrapperBlock?.firstContentInDescendant();
const offset = cursorBlock?.text.length;
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ export const isWin
&& /win32|wow32|win64|wow64/i.test(window.navigator.userAgent);
// http[s] (domain or IPv4 or localhost or IPv6) [port] /not-white-space
export const URL_REG
= /^http(s)?:\/\/([a-z0-9\-._~]+\.[a-z]{2,}|[0-9.]+|localhost|\[[a-f0-9.:]+\])(:[0-9]{1,5})?\/[\S]+/i;
= /^http(s)?:\/\/([\w\-.~]+\.[a-z]{2,}|[0-9.]+|localhost|\[[a-f0-9.:]+\])(:\d{1,5})?\/\S+/i;
export const PREVIEW_DOMPURIFY_CONFIG = {
// do not forbid `class` because `code` element use class to present language
FORBID_ATTR: ['style', 'contenteditable'],
Expand Down
19 changes: 9 additions & 10 deletions packages/core/src/editor/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ import { registerBlocks } from '../block';

const debug = logger('editor:');

class Editor {
public jsonState: JSONState;
public inlineRenderer: InlineRenderer;
public selection: Selection;
public searchModule: Search;
public clipboard: Clipboard;
public history: History;
public scrollPage: Nullable<ScrollPage> = null;
export class Editor {
jsonState: JSONState;
inlineRenderer: InlineRenderer;
selection: Selection;
searchModule: Search;
clipboard: Clipboard;
history: History;
scrollPage: Nullable<ScrollPage> = null;

private _activeContentBlock: Nullable<Content> = null;

constructor(public muya: Muya) {
Expand Down Expand Up @@ -334,5 +335,3 @@ class Editor {
this.focus();
}
}

export default Editor;
3 changes: 2 additions & 1 deletion packages/core/src/event/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,9 @@ class EventCenter {
&& event === cEvent
&& listener === cListener
&& capture === cCapture
)
) {
return true;
}
}

return false;
Expand Down
Loading
Loading