@fastkit/vui 0.7.56 → 0.7.61
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/vui.cjs.js +387 -25
- package/dist/vui.cjs.prod.js +387 -25
- package/dist/vui.css +67 -0
- package/dist/vui.d.ts +89 -1
- package/dist/vui.min.css +1 -1
- package/dist/vui.min.css.map +1 -1
- package/dist/vui.mjs +382 -27
- package/package.json +6 -6
- package/src/components/VWysiwygEditor/.DS_Store +0 -0
- package/src/components/VWysiwygEditor/VWysiwygEditor.scss +2 -0
- package/src/components/VWysiwygEditor/VWysiwygEditor.tsx +80 -49
- package/src/components/VWysiwygEditor/extensions/.DS_Store +0 -0
- package/src/components/VWysiwygEditor/extensions/index.ts +1 -0
- package/src/components/VWysiwygEditor/extensions/linter/.DS_Store +0 -0
- package/src/components/VWysiwygEditor/extensions/linter/Linter.scss +75 -0
- package/src/components/VWysiwygEditor/extensions/linter/Linter.ts +262 -0
- package/src/components/VWysiwygEditor/extensions/linter/LinterPlugin.ts +44 -0
- package/src/components/VWysiwygEditor/extensions/linter/index.ts +5 -0
- package/src/components/VWysiwygEditor/extensions/linter/plugins/BadWords.ts +34 -0
- package/src/components/VWysiwygEditor/extensions/linter/plugins/HeadingLevel.ts +33 -0
- package/src/components/VWysiwygEditor/extensions/linter/plugins/Punctuation.ts +43 -0
- package/src/components/VWysiwygEditor/extensions/linter/plugins/index.ts +3 -0
- package/src/components/VWysiwygEditor/index.ts +1 -0
- package/src/components/VWysiwygEditor/schemes.ts +107 -3
package/dist/vui.cjs.js
CHANGED
|
@@ -15,6 +15,9 @@ var vueAppLayout = require('@fastkit/vue-app-layout');
|
|
|
15
15
|
var vueFormControl = require('@fastkit/vue-form-control');
|
|
16
16
|
var vue3 = require('@tiptap/vue-3');
|
|
17
17
|
var StarterKit = require('@tiptap/starter-kit');
|
|
18
|
+
var core = require('@tiptap/core');
|
|
19
|
+
var prosemirrorView = require('prosemirror-view');
|
|
20
|
+
var prosemirrorState = require('prosemirror-state');
|
|
18
21
|
var extensionBulletList = require('@tiptap/extension-bullet-list');
|
|
19
22
|
var extensionBold = require('@tiptap/extension-bold');
|
|
20
23
|
var extensionItalic = require('@tiptap/extension-italic');
|
|
@@ -2874,13 +2877,63 @@ const VTextarea = vue.defineComponent({
|
|
|
2874
2877
|
|
|
2875
2878
|
});
|
|
2876
2879
|
|
|
2880
|
+
const EDITOR_EVENTS = [
|
|
2881
|
+
'beforeCreate',
|
|
2882
|
+
'create',
|
|
2883
|
+
'update',
|
|
2884
|
+
'selectionUpdate',
|
|
2885
|
+
'transaction',
|
|
2886
|
+
'focus',
|
|
2887
|
+
'blur',
|
|
2888
|
+
'destroy',
|
|
2889
|
+
];
|
|
2890
|
+
const prefixedEventName = (source) => {
|
|
2891
|
+
return `on${source.charAt(0).toUpperCase()}${source.slice(1)}`;
|
|
2892
|
+
};
|
|
2893
|
+
class WysiwygEditorInitializeContext {
|
|
2894
|
+
listeners = {};
|
|
2895
|
+
constructor(opts = {}) {
|
|
2896
|
+
EDITOR_EVENTS.forEach((event) => {
|
|
2897
|
+
this.listeners[event] = [];
|
|
2898
|
+
const prefixed = prefixedEventName(event);
|
|
2899
|
+
const fn = opts[prefixed];
|
|
2900
|
+
fn && this.listeners[event].push(fn);
|
|
2901
|
+
});
|
|
2902
|
+
}
|
|
2903
|
+
on(ev, handler) {
|
|
2904
|
+
this.listeners[ev].push(handler);
|
|
2905
|
+
return () => this.off(ev, handler);
|
|
2906
|
+
}
|
|
2907
|
+
off(ev, handler) {
|
|
2908
|
+
this.listeners[ev] = this.listeners[ev].filter((_handler) => _handler !== handler);
|
|
2909
|
+
}
|
|
2910
|
+
editorOptions() {
|
|
2911
|
+
const opts = {};
|
|
2912
|
+
EDITOR_EVENTS.forEach((event) => {
|
|
2913
|
+
const prefixed = prefixedEventName(event);
|
|
2914
|
+
opts[prefixed] = (props) => {
|
|
2915
|
+
const handlers = this.listeners[event];
|
|
2916
|
+
handlers.forEach((handler) => {
|
|
2917
|
+
handler(props);
|
|
2918
|
+
});
|
|
2919
|
+
};
|
|
2920
|
+
});
|
|
2921
|
+
return opts;
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2924
|
+
function resolveRawWysiwygExtension(raw, ctx) {
|
|
2925
|
+
return typeof raw === 'function' ? raw(ctx) : raw;
|
|
2926
|
+
}
|
|
2927
|
+
function resolveRawWysiwygExtensions(raws, ctx) {
|
|
2928
|
+
return raws.map((raw) => resolveRawWysiwygExtension(raw, ctx));
|
|
2929
|
+
}
|
|
2877
2930
|
function resolveRawWysiwygEditorTool(raw, vui) {
|
|
2878
2931
|
return typeof raw === 'function' ? raw(vui) : raw;
|
|
2879
2932
|
}
|
|
2880
|
-
function resolveRawWysiwygEditorTools(
|
|
2933
|
+
function resolveRawWysiwygEditorTools(rawTools, vui) {
|
|
2881
2934
|
const tools = [];
|
|
2882
2935
|
const extensions = [];
|
|
2883
|
-
|
|
2936
|
+
rawTools.forEach((raw) => {
|
|
2884
2937
|
let resolved = resolveRawWysiwygEditorTool(raw, vui);
|
|
2885
2938
|
if (!Array.isArray(resolved)) {
|
|
2886
2939
|
resolved = [resolved];
|
|
@@ -2911,6 +2964,10 @@ const VWysiwygEditor = vue.defineComponent({
|
|
|
2911
2964
|
...createControlFieldProviderProps(),
|
|
2912
2965
|
...createControlProps(),
|
|
2913
2966
|
...vueKit.defineSlotsProps(),
|
|
2967
|
+
extensions: {
|
|
2968
|
+
type: Array,
|
|
2969
|
+
default: () => []
|
|
2970
|
+
},
|
|
2914
2971
|
tools: {
|
|
2915
2972
|
type: Array,
|
|
2916
2973
|
default: () => []
|
|
@@ -2933,13 +2990,40 @@ const VWysiwygEditor = vue.defineComponent({
|
|
|
2933
2990
|
nodeType: VUI_WYSIWYG_EDITOR_SYMBOL,
|
|
2934
2991
|
validationValue: () => textRef.value
|
|
2935
2992
|
});
|
|
2993
|
+
const initializeCtx = new WysiwygEditorInitializeContext({
|
|
2994
|
+
onCreate: ({
|
|
2995
|
+
editor
|
|
2996
|
+
}) => {
|
|
2997
|
+
textRef.value = editor.getText();
|
|
2998
|
+
updateEditable();
|
|
2999
|
+
},
|
|
3000
|
+
onFocus: ({
|
|
3001
|
+
event
|
|
3002
|
+
}) => {
|
|
3003
|
+
inputControl.focusHandler(event);
|
|
3004
|
+
},
|
|
3005
|
+
onBlur: ({
|
|
3006
|
+
event
|
|
3007
|
+
}) => {
|
|
3008
|
+
inputControl.blurHandler(event);
|
|
3009
|
+
},
|
|
3010
|
+
onUpdate: ({
|
|
3011
|
+
editor
|
|
3012
|
+
}) => {
|
|
3013
|
+
inputControl.value = editor.getHTML();
|
|
3014
|
+
textRef.value = editor.getText();
|
|
3015
|
+
}
|
|
3016
|
+
});
|
|
2936
3017
|
const extensions = [StarterKit__default.configure({
|
|
2937
3018
|
bold: false,
|
|
2938
3019
|
bulletList: false,
|
|
2939
3020
|
orderedList: false,
|
|
2940
3021
|
history: false,
|
|
2941
3022
|
italic: false
|
|
2942
|
-
}),
|
|
3023
|
+
}), // Linter.configure({
|
|
3024
|
+
// plugins: [BadWords(['abc', 'evidently']), Punctuation, HeadingLevel],
|
|
3025
|
+
// }),
|
|
3026
|
+
...resolveRawWysiwygExtensions(props.extensions, initializeCtx), ...wysiwygSettings.value.extensions];
|
|
2943
3027
|
|
|
2944
3028
|
const updateEditable = () => {
|
|
2945
3029
|
if (!editor.value) return;
|
|
@@ -2953,23 +3037,13 @@ const VWysiwygEditor = vue.defineComponent({
|
|
|
2953
3037
|
$editor.commands.setContent(modelValue == null ? '' : modelValue, false);
|
|
2954
3038
|
textRef.value = $editor.getText();
|
|
2955
3039
|
});
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
onFocus: ctx => {
|
|
2964
|
-
inputControl.focusHandler(ctx.event);
|
|
2965
|
-
},
|
|
2966
|
-
onBlur: ctx => {
|
|
2967
|
-
inputControl.blurHandler(ctx.event);
|
|
2968
|
-
},
|
|
2969
|
-
onUpdate: ev => {
|
|
2970
|
-
inputControl.value = ev.editor.getHTML();
|
|
2971
|
-
textRef.value = ev.editor.getText();
|
|
2972
|
-
},
|
|
3040
|
+
initializeCtx.on('create', ({
|
|
3041
|
+
editor
|
|
3042
|
+
}) => {
|
|
3043
|
+
textRef.value = editor.getText();
|
|
3044
|
+
updateEditable();
|
|
3045
|
+
});
|
|
3046
|
+
const editor = vue3.useEditor({ ...initializeCtx.editorOptions(),
|
|
2973
3047
|
autofocus: props.autofocus,
|
|
2974
3048
|
content: props.modelValue,
|
|
2975
3049
|
extensions,
|
|
@@ -3052,6 +3126,9 @@ const VWysiwygEditor = vue.defineComponent({
|
|
|
3052
3126
|
});
|
|
3053
3127
|
};
|
|
3054
3128
|
|
|
3129
|
+
vue.onBeforeUnmount(() => {
|
|
3130
|
+
editor.value && editor.value.destroy();
|
|
3131
|
+
});
|
|
3055
3132
|
return {
|
|
3056
3133
|
editor,
|
|
3057
3134
|
...inputControl.expose(),
|
|
@@ -3087,9 +3164,7 @@ const VWysiwygEditor = vue.defineComponent({
|
|
|
3087
3164
|
} = this;
|
|
3088
3165
|
return vue.createVNode("div", {
|
|
3089
3166
|
"class": "v-wysiwyg-editor__wrapper"
|
|
3090
|
-
}, [!this.isReadonly && this.createTools(), vue.createVNode(
|
|
3091
|
-
"class": "v-wysiwyg-editor__body"
|
|
3092
|
-
}, [vue.createVNode(VControlField, {
|
|
3167
|
+
}, [!this.isReadonly && this.createTools(), vue.createVNode(VControlField, {
|
|
3093
3168
|
"class": "v-wysiwyg-editor__input",
|
|
3094
3169
|
"autoHeight": true,
|
|
3095
3170
|
"startAdornment": this.startAdornment,
|
|
@@ -3099,7 +3174,9 @@ const VWysiwygEditor = vue.defineComponent({
|
|
|
3099
3174
|
default: () => {
|
|
3100
3175
|
let _slot2;
|
|
3101
3176
|
|
|
3102
|
-
return vue.createVNode(
|
|
3177
|
+
return vue.createVNode("div", {
|
|
3178
|
+
"class": "v-wysiwyg-editor__body"
|
|
3179
|
+
}, [vue.createVNode(vue3.EditorContent, {
|
|
3103
3180
|
"class": "v-wysiwyg-editor__input__element wysiwyg",
|
|
3104
3181
|
"editor": editor
|
|
3105
3182
|
}, null), !this.floatingToolbar && !!editor && !this.isReadonly && vue.createVNode(vue3.BubbleMenu, {
|
|
@@ -3109,7 +3186,7 @@ const VWysiwygEditor = vue.defineComponent({
|
|
|
3109
3186
|
default: () => [_slot2]
|
|
3110
3187
|
})]);
|
|
3111
3188
|
}
|
|
3112
|
-
})])
|
|
3189
|
+
})]);
|
|
3113
3190
|
},
|
|
3114
3191
|
infoAppends: () => {
|
|
3115
3192
|
const {
|
|
@@ -3127,6 +3204,284 @@ function resolveContextableValue(ctx, source) {
|
|
|
3127
3204
|
return typeof source === 'function' ? source(ctx) : source;
|
|
3128
3205
|
}
|
|
3129
3206
|
|
|
3207
|
+
const PROBLEM_CLASS_NAME = 'v-linter__problem';
|
|
3208
|
+
const ISSUE_ICON_CLASS_NAME = 'v-linter__issue-icon';
|
|
3209
|
+
const ISSUE_MENU_CLASS_NAME = 'v-linter__issue-menu';
|
|
3210
|
+
function renderIcon(view, issue) {
|
|
3211
|
+
const { level = 'warning' } = issue;
|
|
3212
|
+
const icon = document.createElement('div');
|
|
3213
|
+
icon.className = `${ISSUE_ICON_CLASS_NAME} ${level}-scope`;
|
|
3214
|
+
icon.title = issue.message;
|
|
3215
|
+
icon.issue = issue;
|
|
3216
|
+
return icon;
|
|
3217
|
+
}
|
|
3218
|
+
function renderMenu(view, issue) {
|
|
3219
|
+
const menuWrapper = document.createElement('div');
|
|
3220
|
+
menuWrapper.className = 'v-linter__issue-menu-wrapper';
|
|
3221
|
+
const menu = document.createElement('div');
|
|
3222
|
+
menu.className = `${ISSUE_MENU_CLASS_NAME} elevation-3`;
|
|
3223
|
+
menu.innerText = issue.message;
|
|
3224
|
+
const { fix, fixMessage } = issue;
|
|
3225
|
+
if (fix && fixMessage) {
|
|
3226
|
+
const $fix = document.createElement('button');
|
|
3227
|
+
$fix.type = 'button';
|
|
3228
|
+
$fix.innerHTML = fixMessage;
|
|
3229
|
+
$fix.addEventListener('click', () => {
|
|
3230
|
+
fix(view, issue);
|
|
3231
|
+
});
|
|
3232
|
+
$fix.className = `v-linter__issue-menu__fix`;
|
|
3233
|
+
menu.appendChild($fix);
|
|
3234
|
+
}
|
|
3235
|
+
menu.issue = issue;
|
|
3236
|
+
menuWrapper.appendChild(menu);
|
|
3237
|
+
return menuWrapper;
|
|
3238
|
+
}
|
|
3239
|
+
function getIssueElement(source, className) {
|
|
3240
|
+
if (!source || !(source instanceof HTMLElement)) {
|
|
3241
|
+
return;
|
|
3242
|
+
}
|
|
3243
|
+
if (source.classList.contains(className)) {
|
|
3244
|
+
return source;
|
|
3245
|
+
}
|
|
3246
|
+
const el = source.closest(`.${className}`);
|
|
3247
|
+
if (el) {
|
|
3248
|
+
return el;
|
|
3249
|
+
}
|
|
3250
|
+
}
|
|
3251
|
+
function getIconElement(source) {
|
|
3252
|
+
return getIssueElement(source, ISSUE_ICON_CLASS_NAME);
|
|
3253
|
+
}
|
|
3254
|
+
function getMenuElement(source) {
|
|
3255
|
+
return getIssueElement(source, ISSUE_MENU_CLASS_NAME);
|
|
3256
|
+
}
|
|
3257
|
+
function getProblemElement(source) {
|
|
3258
|
+
return getIssueElement(source, PROBLEM_CLASS_NAME);
|
|
3259
|
+
}
|
|
3260
|
+
function runAllLinterPlugins(doc, plugins) {
|
|
3261
|
+
const decorations = [];
|
|
3262
|
+
const results = plugins
|
|
3263
|
+
.map((RegisteredLinterPlugin) => {
|
|
3264
|
+
return new RegisteredLinterPlugin(doc).scan().getResults();
|
|
3265
|
+
})
|
|
3266
|
+
.flat();
|
|
3267
|
+
results.forEach((issue) => {
|
|
3268
|
+
const { level = 'warning' } = issue;
|
|
3269
|
+
decorations.push(prosemirrorView.Decoration.inline(issue.from, issue.to, {
|
|
3270
|
+
class: `${PROBLEM_CLASS_NAME} ${level}-scope`,
|
|
3271
|
+
'data-issue': JSON.stringify(issue),
|
|
3272
|
+
title: issue.message,
|
|
3273
|
+
}), prosemirrorView.Decoration.widget(issue.from, (view) => renderIcon(view, issue)), prosemirrorView.Decoration.widget(issue.from, (view) => renderMenu(view, issue)));
|
|
3274
|
+
});
|
|
3275
|
+
return prosemirrorView.DecorationSet.create(doc, decorations);
|
|
3276
|
+
}
|
|
3277
|
+
function updateMenusPosition(editorElement) {
|
|
3278
|
+
const { left, right } = editorElement.getBoundingClientRect();
|
|
3279
|
+
const menus = Array.from(editorElement.querySelectorAll(`.${ISSUE_MENU_CLASS_NAME}`));
|
|
3280
|
+
menus.forEach((menu) => {
|
|
3281
|
+
const { left: menuLeft, right: menuRight } = menu.getBoundingClientRect();
|
|
3282
|
+
const overflow = menuRight - right;
|
|
3283
|
+
let offset = 0;
|
|
3284
|
+
if (overflow > 0) {
|
|
3285
|
+
offset = -overflow;
|
|
3286
|
+
if (menuLeft + offset < left) {
|
|
3287
|
+
offset = 0;
|
|
3288
|
+
}
|
|
3289
|
+
}
|
|
3290
|
+
menu.style.transform = `translateX(${offset}px)`;
|
|
3291
|
+
});
|
|
3292
|
+
}
|
|
3293
|
+
const debouncedUpdateMenusPosition = helpers.debounce(updateMenusPosition, 250);
|
|
3294
|
+
const Linter = core.Extension.create({
|
|
3295
|
+
name: 'linter',
|
|
3296
|
+
addOptions() {
|
|
3297
|
+
return {
|
|
3298
|
+
plugins: [],
|
|
3299
|
+
};
|
|
3300
|
+
},
|
|
3301
|
+
onCreate() {
|
|
3302
|
+
const { dom } = this.editor.view;
|
|
3303
|
+
debouncedUpdateMenusPosition(dom);
|
|
3304
|
+
},
|
|
3305
|
+
onUpdate() {
|
|
3306
|
+
const { dom } = this.editor.view;
|
|
3307
|
+
debouncedUpdateMenusPosition(dom);
|
|
3308
|
+
},
|
|
3309
|
+
addProseMirrorPlugins() {
|
|
3310
|
+
const { plugins } = this.options;
|
|
3311
|
+
return [
|
|
3312
|
+
new prosemirrorState.Plugin({
|
|
3313
|
+
key: new prosemirrorState.PluginKey('linter'),
|
|
3314
|
+
state: {
|
|
3315
|
+
init(_, { doc }) {
|
|
3316
|
+
return runAllLinterPlugins(doc, plugins);
|
|
3317
|
+
},
|
|
3318
|
+
apply(transaction, oldState) {
|
|
3319
|
+
return transaction.docChanged
|
|
3320
|
+
? runAllLinterPlugins(transaction.doc, plugins)
|
|
3321
|
+
: oldState;
|
|
3322
|
+
},
|
|
3323
|
+
},
|
|
3324
|
+
props: {
|
|
3325
|
+
decorations(state) {
|
|
3326
|
+
return this.getState(state);
|
|
3327
|
+
},
|
|
3328
|
+
handleClick(view, _, event) {
|
|
3329
|
+
const activeMenus = Array.from(view.dom.querySelectorAll(`.${ISSUE_MENU_CLASS_NAME}--active`));
|
|
3330
|
+
activeMenus.forEach((menu) => menu.classList.remove(`${ISSUE_MENU_CLASS_NAME}--active`));
|
|
3331
|
+
const problem = getProblemElement(event.target);
|
|
3332
|
+
const issueString = problem && problem.dataset['issue'];
|
|
3333
|
+
const issue = issueString && JSON.parse(issueString);
|
|
3334
|
+
if (issue) {
|
|
3335
|
+
const menuWrapper = problem.previousElementSibling;
|
|
3336
|
+
const menu = menuWrapper &&
|
|
3337
|
+
menuWrapper.querySelector(`.${ISSUE_MENU_CLASS_NAME}`);
|
|
3338
|
+
menu && menu.classList.add(`${ISSUE_MENU_CLASS_NAME}--active`);
|
|
3339
|
+
const { from, to } = issue;
|
|
3340
|
+
view.dispatch(view.state.tr
|
|
3341
|
+
.setSelection(prosemirrorState.TextSelection.create(view.state.doc, from, to))
|
|
3342
|
+
.scrollIntoView());
|
|
3343
|
+
return true;
|
|
3344
|
+
}
|
|
3345
|
+
const menu = getMenuElement(event.target);
|
|
3346
|
+
if (menu) {
|
|
3347
|
+
menu.classList.add(`${ISSUE_MENU_CLASS_NAME}--active`);
|
|
3348
|
+
}
|
|
3349
|
+
const target = getIconElement(event.target);
|
|
3350
|
+
if (target && target.issue) {
|
|
3351
|
+
const menuWrapper = target.nextElementSibling;
|
|
3352
|
+
const menu = menuWrapper &&
|
|
3353
|
+
menuWrapper.querySelector(`.${ISSUE_MENU_CLASS_NAME}`);
|
|
3354
|
+
menu && menu.classList.add(`${ISSUE_MENU_CLASS_NAME}--active`);
|
|
3355
|
+
const { from, to } = target.issue;
|
|
3356
|
+
view.dispatch(view.state.tr
|
|
3357
|
+
.setSelection(prosemirrorState.TextSelection.create(view.state.doc, from, to))
|
|
3358
|
+
.scrollIntoView());
|
|
3359
|
+
return true;
|
|
3360
|
+
}
|
|
3361
|
+
return false;
|
|
3362
|
+
},
|
|
3363
|
+
handleDoubleClick(view, _, event) {
|
|
3364
|
+
const target = getIconElement(event.target);
|
|
3365
|
+
if (target && target.issue) {
|
|
3366
|
+
const prob = target.issue;
|
|
3367
|
+
if (prob.fix) {
|
|
3368
|
+
prob.fix(view, prob);
|
|
3369
|
+
view.focus();
|
|
3370
|
+
return true;
|
|
3371
|
+
}
|
|
3372
|
+
}
|
|
3373
|
+
return false;
|
|
3374
|
+
},
|
|
3375
|
+
},
|
|
3376
|
+
}),
|
|
3377
|
+
];
|
|
3378
|
+
},
|
|
3379
|
+
});
|
|
3380
|
+
|
|
3381
|
+
class LinterPlugin {
|
|
3382
|
+
doc;
|
|
3383
|
+
results = [];
|
|
3384
|
+
constructor(doc) {
|
|
3385
|
+
this.doc = doc;
|
|
3386
|
+
}
|
|
3387
|
+
record(result) {
|
|
3388
|
+
this.results.push({
|
|
3389
|
+
level: 'error',
|
|
3390
|
+
...result,
|
|
3391
|
+
});
|
|
3392
|
+
}
|
|
3393
|
+
scan() {
|
|
3394
|
+
return this;
|
|
3395
|
+
}
|
|
3396
|
+
getResults() {
|
|
3397
|
+
return this.results;
|
|
3398
|
+
}
|
|
3399
|
+
}
|
|
3400
|
+
|
|
3401
|
+
function BadWords(words) {
|
|
3402
|
+
const regex = new RegExp(`\\b(${words.join('|')})\\b`);
|
|
3403
|
+
return class BadWords extends LinterPlugin {
|
|
3404
|
+
scan() {
|
|
3405
|
+
this.doc.descendants((node, position) => {
|
|
3406
|
+
if (!node.isText) {
|
|
3407
|
+
return;
|
|
3408
|
+
}
|
|
3409
|
+
const matches = regex.exec(node.text);
|
|
3410
|
+
if (matches) {
|
|
3411
|
+
const fixValue = matches[0] + '!!!!!';
|
|
3412
|
+
this.record({
|
|
3413
|
+
level: 'warning',
|
|
3414
|
+
message: `Try not to say '${matches[0]}'`,
|
|
3415
|
+
from: position + matches.index,
|
|
3416
|
+
to: position + matches.index + matches[0].length,
|
|
3417
|
+
fix: () => {
|
|
3418
|
+
console.log('hoge');
|
|
3419
|
+
},
|
|
3420
|
+
fixMessage: `「${fixValue}」に修正する。`,
|
|
3421
|
+
});
|
|
3422
|
+
}
|
|
3423
|
+
});
|
|
3424
|
+
return this;
|
|
3425
|
+
}
|
|
3426
|
+
};
|
|
3427
|
+
}
|
|
3428
|
+
|
|
3429
|
+
class HeadingLevel extends LinterPlugin {
|
|
3430
|
+
fixHeader(level) {
|
|
3431
|
+
return function ({ state, dispatch }, issue) {
|
|
3432
|
+
dispatch(state.tr.setNodeMarkup(issue.from - 1, undefined, { level }));
|
|
3433
|
+
};
|
|
3434
|
+
}
|
|
3435
|
+
scan() {
|
|
3436
|
+
let lastHeadLevel = null;
|
|
3437
|
+
this.doc.descendants((node, position) => {
|
|
3438
|
+
if (node.type.name === 'heading') {
|
|
3439
|
+
// Check whether heading levels fit under the current level
|
|
3440
|
+
const { level } = node.attrs;
|
|
3441
|
+
if (lastHeadLevel != null && level > lastHeadLevel + 1) {
|
|
3442
|
+
this.record({
|
|
3443
|
+
message: `Heading too small (${level} under ${lastHeadLevel})`,
|
|
3444
|
+
from: position + 1,
|
|
3445
|
+
to: position + 1 + node.content.size,
|
|
3446
|
+
fix: this.fixHeader(lastHeadLevel + 1),
|
|
3447
|
+
});
|
|
3448
|
+
}
|
|
3449
|
+
lastHeadLevel = level;
|
|
3450
|
+
}
|
|
3451
|
+
});
|
|
3452
|
+
return this;
|
|
3453
|
+
}
|
|
3454
|
+
}
|
|
3455
|
+
|
|
3456
|
+
class Punctuation extends LinterPlugin {
|
|
3457
|
+
regex = / ([,.!?:]) ?/g;
|
|
3458
|
+
fix(replacement) {
|
|
3459
|
+
return function ({ state, dispatch }, issue) {
|
|
3460
|
+
dispatch(state.tr.replaceWith(issue.from, issue.to, state.schema.text(replacement)));
|
|
3461
|
+
};
|
|
3462
|
+
}
|
|
3463
|
+
scan() {
|
|
3464
|
+
this.doc.descendants((node, position) => {
|
|
3465
|
+
if (!node.isText) {
|
|
3466
|
+
return;
|
|
3467
|
+
}
|
|
3468
|
+
if (!node.text) {
|
|
3469
|
+
return;
|
|
3470
|
+
}
|
|
3471
|
+
const matches = this.regex.exec(node.text);
|
|
3472
|
+
if (matches) {
|
|
3473
|
+
this.record({
|
|
3474
|
+
message: 'Suspicious spacing around punctuation',
|
|
3475
|
+
from: position + matches.index,
|
|
3476
|
+
to: position + matches.index + matches[0].length,
|
|
3477
|
+
fix: this.fix(`${matches[1]} `),
|
|
3478
|
+
});
|
|
3479
|
+
}
|
|
3480
|
+
});
|
|
3481
|
+
return this;
|
|
3482
|
+
}
|
|
3483
|
+
}
|
|
3484
|
+
|
|
3130
3485
|
const WysiwygBulletListTool = (vui, options) => {
|
|
3131
3486
|
const tool = {
|
|
3132
3487
|
key: 'bulletList',
|
|
@@ -5052,11 +5407,16 @@ exports.VSnackbar = vueKit.VSnackbar;
|
|
|
5052
5407
|
exports.VTooltip = vueKit.VTooltip;
|
|
5053
5408
|
exports.ICON_NAMES = iconFont.ICON_NAMES;
|
|
5054
5409
|
exports.AVATAR_SIZES = AVATAR_SIZES;
|
|
5410
|
+
exports.BadWords = BadWords;
|
|
5055
5411
|
exports.CHIP_SIZES = CHIP_SIZES;
|
|
5056
5412
|
exports.CONTROL_FIELD_VARIANTS = CONTROL_FIELD_VARIANTS;
|
|
5057
5413
|
exports.CONTROL_LOADING_SPINNER_SIZES = CONTROL_LOADING_SPINNER_SIZES;
|
|
5058
5414
|
exports.CONTROL_SIZES = CONTROL_SIZES;
|
|
5415
|
+
exports.HeadingLevel = HeadingLevel;
|
|
5416
|
+
exports.Linter = Linter;
|
|
5417
|
+
exports.LinterPlugin = LinterPlugin;
|
|
5059
5418
|
exports.PAGINATION_ALIGNS = PAGINATION_ALIGNS;
|
|
5419
|
+
exports.Punctuation = Punctuation;
|
|
5060
5420
|
exports.VApp = VApp;
|
|
5061
5421
|
exports.VAvatar = VAvatar;
|
|
5062
5422
|
exports.VBreadcrumbs = VBreadcrumbs;
|
|
@@ -5119,6 +5479,7 @@ exports.VuiInjectionKey = VuiInjectionKey;
|
|
|
5119
5479
|
exports.VuiPlugin = VuiPlugin;
|
|
5120
5480
|
exports.VuiService = VuiService;
|
|
5121
5481
|
exports.WysiwygBulletListTool = WysiwygBulletListTool;
|
|
5482
|
+
exports.WysiwygEditorInitializeContext = WysiwygEditorInitializeContext;
|
|
5122
5483
|
exports.WysiwygFormatBoldTool = WysiwygFormatBoldTool;
|
|
5123
5484
|
exports.WysiwygFormatItalicTool = WysiwygFormatItalicTool;
|
|
5124
5485
|
exports.WysiwygFormatUnderlineTool = WysiwygFormatUnderlineTool;
|
|
@@ -5153,6 +5514,7 @@ exports.renderNavigationItemInput = renderNavigationItemInput;
|
|
|
5153
5514
|
exports.resolveNavigationItemInput = resolveNavigationItemInput;
|
|
5154
5515
|
exports.resolveRawIconProp = resolveRawIconProp;
|
|
5155
5516
|
exports.resolveRawWysiwygEditorTools = resolveRawWysiwygEditorTools;
|
|
5517
|
+
exports.resolveRawWysiwygExtensions = resolveRawWysiwygExtensions;
|
|
5156
5518
|
exports.splitAttrs = splitAttrs;
|
|
5157
5519
|
exports.useControl = useControl;
|
|
5158
5520
|
exports.useControlField = useControlField;
|