@mirus/tiptap-editor 2.1.6 → 2.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tiptap-editor.mjs +593 -569
- package/package.json +1 -1
- package/src/App.vue +2 -2
- package/src/tiptap-editor.vue +52 -2
- package/src/warnings.js +1 -1
package/package.json
CHANGED
package/src/App.vue
CHANGED
|
@@ -27,7 +27,7 @@ export default {
|
|
|
27
27
|
value: 'red',
|
|
28
28
|
message: 'did you mean...',
|
|
29
29
|
options: ['read', 'reed'], // optional
|
|
30
|
-
offset:
|
|
30
|
+
offset: 55, // identifies which instance of the word is problematic
|
|
31
31
|
length: 3, // length of the word
|
|
32
32
|
},
|
|
33
33
|
{
|
|
@@ -40,7 +40,7 @@ export default {
|
|
|
40
40
|
isWord: false,
|
|
41
41
|
message: 'you sure you wanted a tag?',
|
|
42
42
|
overrideClass: 'underline-blue', // optional
|
|
43
|
-
offset:
|
|
43
|
+
offset: 11,
|
|
44
44
|
length: 8,
|
|
45
45
|
},
|
|
46
46
|
{
|
package/src/tiptap-editor.vue
CHANGED
|
@@ -163,6 +163,7 @@ export default {
|
|
|
163
163
|
optionsRange: null,
|
|
164
164
|
initialCharacterCount: 0,
|
|
165
165
|
previousCharacterCount: 0,
|
|
166
|
+
previousHTML: '',
|
|
166
167
|
};
|
|
167
168
|
},
|
|
168
169
|
computed: {
|
|
@@ -290,15 +291,22 @@ export default {
|
|
|
290
291
|
this.warnings.forEach((warning) => {
|
|
291
292
|
if (warning.length && warning.offset) {
|
|
292
293
|
if (editor.state.selection.head - 1 <= warning.offset) {
|
|
293
|
-
|
|
294
|
+
let charCountDiff =
|
|
294
295
|
this.currentCharacterCount - this.previousCharacterCount;
|
|
295
|
-
|
|
296
|
+
charCountDiff += this.adjustForNewlines();
|
|
297
|
+
warning.offset += charCountDiff;
|
|
296
298
|
}
|
|
297
299
|
}
|
|
298
300
|
});
|
|
299
301
|
this.previousCharacterCount = this.currentCharacterCount;
|
|
302
|
+
this.previousHTML = this.editor.getHTML();
|
|
300
303
|
this.editor.commands.focus();
|
|
301
304
|
});
|
|
305
|
+
this.warnings.forEach((warning) => {
|
|
306
|
+
if (warning.length && warning.offset >= 0) {
|
|
307
|
+
warning.offset += this.getOffsetAdjustment(warning);
|
|
308
|
+
}
|
|
309
|
+
});
|
|
302
310
|
},
|
|
303
311
|
destroyed() {
|
|
304
312
|
this.editor.destroy();
|
|
@@ -307,6 +315,42 @@ export default {
|
|
|
307
315
|
}
|
|
308
316
|
},
|
|
309
317
|
methods: {
|
|
318
|
+
// compliance checks base offset data off the HTML value of the text
|
|
319
|
+
// ProseMirror uses a unique token sequence indexing system - see https://prosemirror.net/docs/guide/#doc.indexing
|
|
320
|
+
// we need to convert warning offsets to the index values ProseMirror expects
|
|
321
|
+
getOffsetAdjustment(warning) {
|
|
322
|
+
// compliance check offsets count all HTML entities as one character, whereas the editor value does not. compensate for
|
|
323
|
+
// this by adding to the offset until it matches (or equals the length of the editor text as a failsafe break from the loop)
|
|
324
|
+
while (
|
|
325
|
+
this.value.substr(warning.offset, warning.value.length) !== warning.value &&
|
|
326
|
+
warning.offset <= this.value.length
|
|
327
|
+
) {
|
|
328
|
+
warning.offset++;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// obtain the substring up until the beginning of the warning
|
|
332
|
+
const originalLength = warning.offset;
|
|
333
|
+
let substr = this.value.substr(0, warning.offset);
|
|
334
|
+
|
|
335
|
+
// these tags count as one token, so we replace them with a single space
|
|
336
|
+
substr = substr.replace(/<p>|<\/p>|<li>|<ul>|<\/ul>|<\/li>|<div>|<\/div>/g, ' ');
|
|
337
|
+
|
|
338
|
+
// these tags don't count as a token, so we remove them
|
|
339
|
+
const knownTagRegex = /<strong>|<\/strong>|<em>|<\/em>/g;
|
|
340
|
+
substr = substr.replace(knownTagRegex, '');
|
|
341
|
+
|
|
342
|
+
// return the number of chars the offset should be adjusted by
|
|
343
|
+
return substr.length - originalLength;
|
|
344
|
+
},
|
|
345
|
+
// when the user adds a newline to the text of the editor, the character count stays the same, but ProseMirror's token
|
|
346
|
+
// sequence indexing system adds 2 tokens to the content. We need to adjust warning offsets to account for that
|
|
347
|
+
adjustForNewlines() {
|
|
348
|
+
const regex = /<\/p><p>/g;
|
|
349
|
+
const previousNewlines = (this.previousHTML.match(regex) || []).length;
|
|
350
|
+
const newlines = (this.editor.getHTML().match(regex) || []).length;
|
|
351
|
+
// multiply the difference in newlines by 2 since each instance counts as 2 tokens
|
|
352
|
+
return (newlines - previousNewlines) * 2;
|
|
353
|
+
},
|
|
310
354
|
getErrorWords() {
|
|
311
355
|
if (this.errors.length < 1) {
|
|
312
356
|
return [];
|
|
@@ -380,6 +424,12 @@ export default {
|
|
|
380
424
|
watch: {
|
|
381
425
|
warnings: function (n, o) {
|
|
382
426
|
if (this.editor) {
|
|
427
|
+
this.warnings.forEach((warning) => {
|
|
428
|
+
if (warning.length && warning.offset >= 0) {
|
|
429
|
+
warning.offset += this.getOffsetAdjustment(warning);
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
|
|
383
433
|
// preserve selection after updating warnings
|
|
384
434
|
const oldSelection = this.editor.view.state.selection;
|
|
385
435
|
// this.editor.commands.setContent(this.currentValue);
|
package/src/warnings.js
CHANGED
|
@@ -70,7 +70,7 @@ function lint(doc, position, prev, getErrorWords) {
|
|
|
70
70
|
matchingErrorWords.forEach((word) => {
|
|
71
71
|
if (word.length && word.offset >= 0) {
|
|
72
72
|
errorHasOffsetData = true;
|
|
73
|
-
if (indexOfMatchedWord
|
|
73
|
+
if (indexOfMatchedWord === word.offset) {
|
|
74
74
|
record(indexOfMatchedWord, indexOfMatchedWord + m[0].length, m[0]);
|
|
75
75
|
}
|
|
76
76
|
}
|