Skip to content

Commit

Permalink
feat: warn for marks with inclusive as true (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
ocavue authored Aug 6, 2023
1 parent 3343976 commit e67ddcf
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 10 deletions.
22 changes: 19 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,31 @@ npm install prosemirror-virtual-cursor
## Usage

```ts
import 'prosemirror-virtual-cursor/style/virtual-cursor.css'
import 'prosemirror-virtual-cursor/style/virtual-cursor.css';

import { createVirtualCursor } from 'prosemirror-virtual-cursor'
import { createVirtualCursor } from 'prosemirror-virtual-cursor';

const plugin = createVirtualCursor()
const plugin = createVirtualCursor();
```

## Options

### Cursor color

The default color of the cursor is red. You can change it by overriding the CSS variable `--prosemirror-virtual-cursor-color`. You can also copy all the CSS rules from `style/virtual-cursor.css` to your own stylesheet and change more things.

### `skipWarning`

By default, prosemirror-virtual-cursor will warn you if any mark has [`inclusive`](https://prosemirror.net/docs/ref/#model.MarkSpec.inclusive) set to `false`, as `inclusive` is not useful for prosemirror-virtual-cursor. You can disable this warning by setting `skipWarning` to `true`. You can also specify an array of mark names to skip the warning for specific marks.

```ts
const plugin = createVirtualCursor({ skipWarning: true });
```

```ts
const plugin = createVirtualCursor({ skipWarning: ['mark_type_name'] });
```

## License

MIT
3 changes: 1 addition & 2 deletions playground/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@
<body>
<div id=content style="display: none">
<h1>prosemirror-virtual-cursor</h1>
<p>hello <em>italic</em></p>
<p>hello <em>italic</em> and <strong>bold</strong></p>
<p>This is a <a href="https://example.com">Link</a>.</p>
<p>fi ii ff if</p>
</div>
<div class="full" spellcheck="false"></div>
<script type="module" src="/main.ts"></script>
Expand Down
12 changes: 10 additions & 2 deletions playground/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,17 @@ import { exampleSetup } from 'prosemirror-example-setup';

import { createVirtualCursor } from '../src/index';

const { marks, nodes } = schema.spec;

marks.forEach((_key, value) => {
if (value.inclusive === false) {
value.inclusive = true;
}
});

const demoSchema = new Schema({
nodes: addListNodes(schema.spec.nodes as any, 'paragraph block*', 'block'),
marks: schema.spec.marks,
nodes: addListNodes(nodes, 'paragraph block*', 'block'),
marks,
});

const plugins = [
Expand Down
31 changes: 28 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
import type { ResolvedPos } from 'prosemirror-model';
import type { ResolvedPos, Schema } from 'prosemirror-model';
import { Mark } from 'prosemirror-model';
import type { Selection } from 'prosemirror-state';
import { Plugin, PluginKey, TextSelection } from 'prosemirror-state';
import type { EditorView } from 'prosemirror-view';
import { Decoration, DecorationSet } from 'prosemirror-view';

export function createVirtualCursor(): Plugin {
const key = new PluginKey('prosemirror-virtual-cursor');
export interface VirtualCursorOptions {
/**
* An array of ProseMirror mark names that should be ignored when checking the
* [`inclusive`](https://prosemirror.net/docs/ref/#model.MarkSpec.inclusive)
* attribute. You can also set this to `true` to skip the warning altogether.
*/
skipWarning?: string[] | true;
}

export function createVirtualCursor(options?: VirtualCursorOptions): Plugin {
const skipWarning = options?.skipWarning ?? false;

let _cursor: HTMLElement | null =
typeof document === 'undefined' ? null : document.createElement('div');

return new Plugin({
key,
view: (view) => {
if (skipWarning !== true) {
checkInclusive(view.state.schema, skipWarning || []);
}

const doc = view.dom.ownerDocument;
_cursor = _cursor || document.createElement('div');
const cursor = _cursor;
Expand Down Expand Up @@ -122,6 +135,8 @@ export function createVirtualCursor(): Plugin {
});
}

const key = new PluginKey('prosemirror-virtual-cursor');

function getCursorRect(
view: EditorView,
toStart: boolean
Expand Down Expand Up @@ -208,3 +223,13 @@ function restartAnimation(element: HTMLElement, className: string) {
// -> and re-adding the class
element.classList.add(className);
}

function checkInclusive(schema: Schema, skipWarning: string[]) {
for (const [mark, type] of Object.entries(schema.marks)) {
if (type.spec.inclusive === false && !skipWarning.includes(mark)) {
console.warn(
`[prosemirror-virtual-cursor] Virtual cursor does not work well with marks that have inclusive set to false. Please consider removing the inclusive option from the "${mark}" mark or adding it to the "skipWarning" option.`
);
}
}
}

0 comments on commit e67ddcf

Please sign in to comment.