diff --git a/docs/src/demos/Experiments/Linter/extension/Linter.ts b/docs/src/demos/Experiments/Linter/extension/Linter.ts index 7da886b328..ab5edc5bfd 100644 --- a/docs/src/demos/Experiments/Linter/extension/Linter.ts +++ b/docs/src/demos/Experiments/Linter/extension/Linter.ts @@ -1,10 +1,15 @@ -// @ts-nocheck import { Extension } from '@tiptap/core' import { Decoration, DecorationSet } from 'prosemirror-view' import { Plugin, PluginKey, TextSelection } from 'prosemirror-state' +import { Node as ProsemirrorNode } from 'prosemirror-model' +import LinterPlugin, { Result as Issue } from './LinterPlugin' -function renderIcon(issue) { - const icon = document.createElement('div') +interface IconDivElement extends HTMLDivElement { + issue?: Issue +} + +function renderIcon(issue: Issue) { + const icon: IconDivElement = document.createElement('div') icon.className = 'lint-icon' icon.title = issue.message @@ -13,11 +18,11 @@ function renderIcon(issue) { return icon } -function runAllLinterPlugins(doc, plugins) { +function runAllLinterPlugins(doc: ProsemirrorNode, plugins: Array) { const decorations: [any?] = [] - const results = plugins.map(LinterPlugin => { - return new LinterPlugin(doc).scan().getResults() + const results = plugins.map(RegisteredLinterPlugin => { + return new RegisteredLinterPlugin(doc).scan().getResults() }).flat() results.forEach(issue => { @@ -31,7 +36,7 @@ function runAllLinterPlugins(doc, plugins) { } export interface LinterOptions { - plugins: [any], + plugins: Array, } export const Linter = Extension.create({ @@ -62,8 +67,9 @@ export const Linter = Extension.create({ return this.getState(state) }, handleClick(view, _, event) { - if (/lint-icon/.test(event.target.className)) { - const { from, to } = event.target.issue + const target = (event.target as IconDivElement) + if (/lint-icon/.test(target.className) && target.issue) { + const { from, to } = target.issue view.dispatch( view.state.tr @@ -73,17 +79,22 @@ export const Linter = Extension.create({ return true } + + return false }, handleDoubleClick(view, _, event) { - if (/lint-icon/.test(event.target.className)) { - const prob = event.target.issue + const target = (event.target as IconDivElement) + if (/lint-icon/.test((event.target as HTMLElement).className) && target.issue) { + const prob = target.issue if (prob.fix) { - prob.fix(view) + prob.fix(view, prob) view.focus() return true } } + + return false }, }, }), diff --git a/docs/src/demos/Experiments/Linter/extension/LinterPlugin.ts b/docs/src/demos/Experiments/Linter/extension/LinterPlugin.ts index 809c660156..200b146b89 100644 --- a/docs/src/demos/Experiments/Linter/extension/LinterPlugin.ts +++ b/docs/src/demos/Experiments/Linter/extension/LinterPlugin.ts @@ -1,8 +1,10 @@ -interface Result { +import { Node as ProsemirrorNode } from 'prosemirror-model' + +export interface Result { message: string, from: number, to: number, - fix?: null + fix?: Function } export default class LinterPlugin { @@ -10,11 +12,11 @@ export default class LinterPlugin { private results: Array = [] - constructor(doc: any) { + constructor(doc: ProsemirrorNode) { this.doc = doc } - record(message: string, from: number, to: number, fix?: null) { + record(message: string, from: number, to: number, fix?: Function) { this.results.push({ message, from, @@ -23,6 +25,10 @@ export default class LinterPlugin { }) } + scan() { + return this + } + getResults() { return this.results } diff --git a/docs/src/demos/Experiments/Linter/extension/plugins/BadWords.ts b/docs/src/demos/Experiments/Linter/extension/plugins/BadWords.ts index 59194c219c..6111b4d8e3 100644 --- a/docs/src/demos/Experiments/Linter/extension/plugins/BadWords.ts +++ b/docs/src/demos/Experiments/Linter/extension/plugins/BadWords.ts @@ -1,4 +1,3 @@ -// @ts-nocheck import LinterPlugin from '../LinterPlugin' export class BadWords extends LinterPlugin { @@ -6,7 +5,7 @@ export class BadWords extends LinterPlugin { public regex = /\b(obviously|clearly|evidently|simply)\b/ig scan() { - this.doc.descendants((node: any, position: any) => { + this.doc.descendants((node: any, position: number) => { if (!node.isText) { return } diff --git a/docs/src/demos/Experiments/Linter/extension/plugins/HeadingLevel.ts b/docs/src/demos/Experiments/Linter/extension/plugins/HeadingLevel.ts index df78dacf55..001d5122ed 100644 --- a/docs/src/demos/Experiments/Linter/extension/plugins/HeadingLevel.ts +++ b/docs/src/demos/Experiments/Linter/extension/plugins/HeadingLevel.ts @@ -1,15 +1,15 @@ -// @ts-nocheck -import LinterPlugin from '../LinterPlugin' +import { EditorView } from 'prosemirror-view' +import LinterPlugin, { Result as Issue } from '../LinterPlugin' export class HeadingLevel extends LinterPlugin { - fixHeader(level) { - return function ({ state, dispatch }) { - dispatch(state.tr.setNodeMarkup(this.from - 1, null, { level })) + fixHeader(level: number) { + return function ({ state, dispatch }: EditorView, issue: Issue) { + dispatch(state.tr.setNodeMarkup(issue.from - 1, undefined, { level })) } } scan() { - let lastHeadLevel = null + let lastHeadLevel: number | null = null this.doc.descendants((node, position) => { if (node.type.name === 'heading') { diff --git a/docs/src/demos/Experiments/Linter/extension/plugins/Punctuation.ts b/docs/src/demos/Experiments/Linter/extension/plugins/Punctuation.ts index d3a228d738..befd7d638a 100644 --- a/docs/src/demos/Experiments/Linter/extension/plugins/Punctuation.ts +++ b/docs/src/demos/Experiments/Linter/extension/plugins/Punctuation.ts @@ -1,14 +1,14 @@ -// @ts-nocheck -import LinterPlugin from '../LinterPlugin' +import { EditorView } from 'prosemirror-view' +import LinterPlugin, { Result as Issue } from '../LinterPlugin' export class Punctuation extends LinterPlugin { public regex = / ([,.!?:]) ?/g fix(replacement: any) { - return function ({ state, dispatch }) { + return function ({ state, dispatch }: EditorView, issue: Issue) { dispatch( state.tr.replaceWith( - this.from, this.to, + issue.from, issue.to, state.schema.text(replacement), ), ) @@ -17,9 +17,9 @@ export class Punctuation extends LinterPlugin { scan() { this.doc.descendants((node, position) => { - if (!node.isText) { - return - } + if (!node.isText) return + + if (!node.text) return const matches = this.regex.exec(node.text) diff --git a/docs/src/docPages/experiments/linter.md b/docs/src/docPages/experiments/linter.md index e85aa7dec0..6d10db6805 100644 --- a/docs/src/docPages/experiments/linter.md +++ b/docs/src/docPages/experiments/linter.md @@ -1,5 +1,7 @@ # Linter -⚠️ Experiment +⚠️ Experiment, currently not supported or maintained + +Linter can be used to check the content as per your wish and highlight it to the user. Linter extension can have multiple plugins for each task you want to achieve.