@vonage/vivid 5.20.1 → 5.21.0
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/alert/index.cjs +1 -1
- package/alert/index.js +1 -1
- package/banner/index.cjs +1 -1
- package/banner/index.js +1 -1
- package/bundled/definition18.cjs +1 -1
- package/bundled/definition18.js +1 -1
- package/bundled/definition6.cjs +1 -1
- package/bundled/definition6.js +1 -1
- package/bundled/vivid-element.cjs +1 -1
- package/bundled/vivid-element.js +1 -1
- package/combobox/index.cjs +1 -1
- package/combobox/index.js +1 -1
- package/custom-elements.json +2479 -2479
- package/file-picker/index.cjs +1 -1
- package/file-picker/index.js +1 -1
- package/lib/rich-text-editor/rte/features/base.d.ts +1 -0
- package/lib/rich-text-editor/rte/features/internal/history.d.ts +6 -0
- package/locales/de-DE.cjs +178 -4
- package/locales/de-DE.js +179 -2
- package/locales/en-GB.cjs +9 -4
- package/locales/en-GB.js +10 -2
- package/locales/en-US.cjs +2 -270
- package/locales/en-US.js +1 -267
- package/locales/ja-JP.cjs +171 -4
- package/locales/ja-JP.js +172 -2
- package/locales/zh-CN.cjs +172 -4
- package/locales/zh-CN.js +173 -2
- package/package.json +6 -5
- package/rich-text-editor/index.cjs +12 -12
- package/rich-text-editor/index.js +1015 -1015
- package/searchable-select/index.cjs +1 -1
- package/searchable-select/index.js +1 -1
- package/switch/index.cjs +1 -1
- package/switch/index.js +1 -1
- package/tabs/index.cjs +1 -1
- package/tabs/index.js +1 -1
- package/unbundled/chunk.cjs +15 -0
- package/unbundled/chunk.js +13 -0
- package/unbundled/definition17.cjs +1 -1
- package/unbundled/definition17.js +1 -1
- package/unbundled/definition30.cjs +1 -1
- package/unbundled/definition30.js +1 -1
- package/unbundled/definition43.cjs +1 -1
- package/unbundled/definition43.js +1 -1
- package/unbundled/definition60.cjs +608 -607
- package/unbundled/definition60.js +608 -607
- package/unbundled/definition61.cjs +1 -1
- package/unbundled/definition61.js +1 -1
- package/unbundled/definition63.cjs +1 -1
- package/unbundled/definition63.js +1 -1
- package/unbundled/definition69.cjs +1 -1
- package/unbundled/definition69.js +1 -1
- package/unbundled/definition7.cjs +1 -1
- package/unbundled/definition7.js +1 -1
- package/unbundled/definition73.cjs +1 -1
- package/unbundled/definition73.js +1 -1
- package/unbundled/definition9.cjs +1 -1
- package/unbundled/definition9.js +1 -1
- package/unbundled/en-US.cjs +449 -0
- package/unbundled/en-US.js +445 -0
- package/unbundled/localized.cjs +2 -2
- package/unbundled/localized.js +1 -1
- package/unbundled/vivid-element.cjs +1 -1
- package/unbundled/vivid-element.js +1 -1
|
@@ -23,9 +23,9 @@ let prosemirror_keymap = require("prosemirror-keymap");
|
|
|
23
23
|
let prosemirror_commands = require("prosemirror-commands");
|
|
24
24
|
let prosemirror_dropcursor = require("prosemirror-dropcursor");
|
|
25
25
|
let prosemirror_gapcursor = require("prosemirror-gapcursor");
|
|
26
|
-
let prosemirror_history = require("prosemirror-history");
|
|
27
26
|
let dompurify = require("dompurify");
|
|
28
27
|
dompurify = require_chunk.__toESM(dompurify, 1);
|
|
28
|
+
let prosemirror_history = require("prosemirror-history");
|
|
29
29
|
let prosemirror_inputrules = require("prosemirror-inputrules");
|
|
30
30
|
let prosemirror_transform = require("prosemirror-transform");
|
|
31
31
|
let prosemirror_schema_basic = require("prosemirror-schema-basic");
|
|
@@ -240,645 +240,330 @@ var FeatureState = class {
|
|
|
240
240
|
//#region src/lib/rich-text-editor/rte/features/internal/core.style.scss?inline
|
|
241
241
|
var core_style_default = ".ProseMirror{box-sizing:border-box;padding:var(--editor-padding-block) var(--editor-padding-inline);outline:none;flex:1 0 0}.ProseMirror-selectednode{--focus-stroke-gap-color:transparent;--focus-border-radius:2px;outline:none;position:relative}.ProseMirror-selectednode:after{box-shadow:0 0 0 4px color-mix(in srgb, var(--focus-stroke-color,var(--vvd-color-cta-500)), transparent 85%), inset 0 0 0 3px var(--focus-stroke-gap-color,currentColor);outline:1px solid var(--focus-stroke-color,var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset,0px));border-radius:var(--focus-border-radius,inherit);block-size:calc(100% + var(--focus-block-size-addition,4px));content:\"\";inline-size:calc(100% + var(--focus-block-size-addition,4px));display:block;position:absolute;inset-block-start:50%;inset-inline-start:50%;transform:translate(-50%,-50%)}.editor--disabled .ProseMirror{color:var(--vvd-color-neutral-300);cursor:not-allowed}";
|
|
242
242
|
//#endregion
|
|
243
|
-
//#region src/lib/rich-text-editor/rte/
|
|
244
|
-
var
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
handler
|
|
249
|
-
];
|
|
250
|
-
var UiCtx = class {
|
|
251
|
-
constructor(view, rte, props) {
|
|
252
|
-
this.view = view;
|
|
253
|
-
this.rte = rte;
|
|
254
|
-
this.props = props;
|
|
255
|
-
this.bindings = [];
|
|
243
|
+
//#region src/lib/rich-text-editor/rte/features/internal/foreign-html.ts
|
|
244
|
+
var RteForeignHtmlFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
|
|
245
|
+
constructor(..._args) {
|
|
246
|
+
super(..._args);
|
|
247
|
+
this.name = "RteForeignHtmlFeature";
|
|
256
248
|
}
|
|
257
|
-
|
|
258
|
-
return
|
|
249
|
+
getPlugins(rte) {
|
|
250
|
+
return [this.contribution(new prosemirror_state.Plugin({ props: {
|
|
251
|
+
transformPastedHTML: (html) => rte.foreignHtmlParser[require_slottable_request.impl].transform(html),
|
|
252
|
+
clipboardParser: rte.foreignHtmlParser[require_slottable_request.impl].parser,
|
|
253
|
+
clipboardSerializer: rte.foreignHtmlSerializer[require_slottable_request.impl].serializer
|
|
254
|
+
} }))];
|
|
259
255
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
256
|
+
};
|
|
257
|
+
//#endregion
|
|
258
|
+
//#region src/lib/rich-text-editor/rte/features/internal/cursor-fix.ts
|
|
259
|
+
/**
|
|
260
|
+
* When the cursor is positioned after an inline atom node at the end of a line,
|
|
261
|
+
* browsers may display the cursor inside the atom.
|
|
262
|
+
*/
|
|
263
|
+
var atomCursorFix = ($cursor) => {
|
|
264
|
+
if (!($cursor.parentOffset === $cursor.parent.content.size)) return null;
|
|
265
|
+
const nodeBefore = $cursor.nodeBefore;
|
|
266
|
+
if (nodeBefore && nodeBefore.isInline && nodeBefore.isAtom && !nodeBefore.isText) return {};
|
|
267
|
+
return null;
|
|
268
|
+
};
|
|
269
|
+
var RteCursorFixFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
|
|
270
|
+
constructor(..._args) {
|
|
271
|
+
super(..._args);
|
|
272
|
+
this.name = "RteCursorFix";
|
|
267
273
|
}
|
|
268
|
-
|
|
269
|
-
|
|
274
|
+
getPlugins(rte) {
|
|
275
|
+
const cursorFixes = [atomCursorFix];
|
|
276
|
+
for (const markType of Object.values(rte.schema.marks)) {
|
|
277
|
+
const spec = markType.spec;
|
|
278
|
+
if (spec.cursorFix) cursorFixes.push(spec.cursorFix);
|
|
279
|
+
}
|
|
280
|
+
return [this.contribution(new prosemirror_state.Plugin({ props: { decorations: (state) => {
|
|
281
|
+
const { $cursor } = state.selection;
|
|
282
|
+
if (!$cursor) return null;
|
|
283
|
+
let cursorFix = null;
|
|
284
|
+
for (const fn of cursorFixes) {
|
|
285
|
+
const result = fn($cursor, state);
|
|
286
|
+
if (result) Object.assign(cursorFix ??= {}, result);
|
|
287
|
+
}
|
|
288
|
+
if (!cursorFix) return null;
|
|
289
|
+
return prosemirror_view.DecorationSet.create(state.doc, [prosemirror_view.Decoration.widget($cursor.pos, () => {
|
|
290
|
+
const span = document.createElement("span");
|
|
291
|
+
span.textContent = "";
|
|
292
|
+
for (const [prop, value] of Object.entries(cursorFix)) span.style.setProperty(prop, value);
|
|
293
|
+
return span;
|
|
294
|
+
}, { side: -1 })]);
|
|
295
|
+
} } }))];
|
|
270
296
|
}
|
|
271
|
-
|
|
272
|
-
|
|
297
|
+
};
|
|
298
|
+
require_slottable_request.featureFacade(RteCursorFixFeatureImpl);
|
|
299
|
+
//#endregion
|
|
300
|
+
//#region src/lib/rich-text-editor/rte/features/internal/core.ts
|
|
301
|
+
/**
|
|
302
|
+
* Plugin to bring state from the host web component into ProseMirror.
|
|
303
|
+
*/
|
|
304
|
+
var hostBridgePlugin = new prosemirror_state.Plugin({ state: {
|
|
305
|
+
init() {
|
|
306
|
+
return null;
|
|
307
|
+
},
|
|
308
|
+
apply(tr, value) {
|
|
309
|
+
const meta = tr.getMeta(hostBridgePlugin);
|
|
310
|
+
if (meta) return meta;
|
|
311
|
+
else return value;
|
|
273
312
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
313
|
+
} });
|
|
314
|
+
var RteCoreImpl = class extends require_slottable_request.RteFeatureImpl {
|
|
315
|
+
constructor(..._args) {
|
|
316
|
+
super(..._args);
|
|
317
|
+
this.name = "RteCore";
|
|
318
|
+
this.disabled = new FeatureState(false);
|
|
319
|
+
}
|
|
320
|
+
getStyles() {
|
|
321
|
+
return [
|
|
322
|
+
this.contribution(prosemirror_default),
|
|
323
|
+
this.contribution(core_style_default),
|
|
324
|
+
this.contribution(ui_style_default)
|
|
325
|
+
];
|
|
326
|
+
}
|
|
327
|
+
getPlugins(rte) {
|
|
328
|
+
const enterKeyChainCommands = (0, prosemirror_commands.chainCommands)(prosemirror_commands.newlineInCode, prosemirror_commands.createParagraphNear, prosemirror_commands.liftEmptyBlock, (0, prosemirror_commands.splitBlockAs)((node, atEnd, $from) => {
|
|
329
|
+
if (!atEnd) return {
|
|
330
|
+
type: node.type,
|
|
331
|
+
attrs: node.attrs
|
|
332
|
+
};
|
|
333
|
+
return {
|
|
334
|
+
type: defaultTextblockForMatch($from.node($from.depth - 1).contentMatchAt($from.indexAfter($from.depth - 1))),
|
|
335
|
+
attrs: rte.textblockAttrs.extractFromNode(node)
|
|
336
|
+
};
|
|
337
|
+
}));
|
|
338
|
+
return [
|
|
339
|
+
this.contribution(this.disabled.plugin),
|
|
340
|
+
this.contribution(new prosemirror_state.Plugin({
|
|
341
|
+
props: {
|
|
342
|
+
editable: () => !this.disabled.getValue(rte),
|
|
343
|
+
handleDOMEvents: { click: (_view, event) => {
|
|
344
|
+
if (this.disabled.getValue(rte)) {
|
|
345
|
+
event.preventDefault();
|
|
346
|
+
return true;
|
|
347
|
+
}
|
|
348
|
+
return false;
|
|
349
|
+
} }
|
|
350
|
+
},
|
|
351
|
+
view: (view) => {
|
|
352
|
+
const popovers = view.dom.getRootNode().querySelector(".popovers");
|
|
353
|
+
const updateDisabled = () => {
|
|
354
|
+
const disabled = this.disabled.getValue(rte);
|
|
355
|
+
popovers.classList.toggle("popovers--disabled", disabled);
|
|
356
|
+
view.dom.parentElement.classList.toggle("editor--disabled", disabled);
|
|
357
|
+
};
|
|
358
|
+
updateDisabled();
|
|
359
|
+
return { update: () => {
|
|
360
|
+
updateDisabled();
|
|
361
|
+
} };
|
|
362
|
+
}
|
|
363
|
+
})),
|
|
364
|
+
this.contribution((0, prosemirror_keymap.keymap)({
|
|
365
|
+
...prosemirror_commands.baseKeymap,
|
|
366
|
+
Enter: enterKeyChainCommands,
|
|
367
|
+
"Shift-Enter": enterKeyChainCommands
|
|
368
|
+
})),
|
|
369
|
+
this.contribution((0, prosemirror_dropcursor.dropCursor)()),
|
|
370
|
+
this.contribution((0, prosemirror_gapcursor.gapCursor)()),
|
|
371
|
+
this.contribution(hostBridgePlugin)
|
|
372
|
+
];
|
|
373
|
+
}
|
|
374
|
+
getFeatures() {
|
|
375
|
+
return [
|
|
376
|
+
this,
|
|
377
|
+
new RteForeignHtmlFeatureImpl(),
|
|
378
|
+
new RteCursorFixFeatureImpl()
|
|
379
|
+
];
|
|
280
380
|
}
|
|
281
381
|
};
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
382
|
+
require_slottable_request.featureFacade(RteCoreImpl);
|
|
383
|
+
//#endregion
|
|
384
|
+
//#region src/lib/rich-text-editor/rte/utils/sanitization.ts
|
|
385
|
+
var DEFAULT_ALLOWED_URI_REGEXP = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i;
|
|
386
|
+
var ALLOWED_URI_REGEXP_WITH_BLOB = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|blob):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i;
|
|
387
|
+
var ATTR_WHITESPACE = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g;
|
|
388
|
+
var domPurifyConfig = { ALLOWED_URI_REGEXP: ALLOWED_URI_REGEXP_WITH_BLOB };
|
|
389
|
+
/**
|
|
390
|
+
* Sanitize potentially dangerous URLs, like "javascript:", in anchor href attributes.
|
|
391
|
+
* Returns empty string if the URL is unsafe.
|
|
392
|
+
*/
|
|
393
|
+
var sanitizeLinkHref = (url) => {
|
|
394
|
+
if (!DEFAULT_ALLOWED_URI_REGEXP.test(url.replace(ATTR_WHITESPACE, ""))) return "";
|
|
291
395
|
const anchor = document.createElement("a");
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
}
|
|
298
|
-
return anchor;
|
|
396
|
+
anchor.setAttribute("href", url);
|
|
397
|
+
/* v8 ignore next -- since href is already validated it's probably always present @preserve */
|
|
398
|
+
return dompurify.default.sanitize(anchor, {
|
|
399
|
+
RETURN_DOM: true,
|
|
400
|
+
...domPurifyConfig
|
|
401
|
+
}).querySelector("a").getAttribute("href") ?? "";
|
|
299
402
|
};
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
tooltip.anchor = enabled ? props.anchor : void 0;
|
|
312
|
-
});
|
|
313
|
-
const wrapper = createDiv(ctx, {
|
|
314
|
-
className: "ui-tooltip-wrapper",
|
|
315
|
-
slot: props.slot,
|
|
316
|
-
children: [props.anchor, tooltip]
|
|
317
|
-
});
|
|
318
|
-
wrapperTargets.set(wrapper, props.anchor);
|
|
319
|
-
return wrapper;
|
|
403
|
+
/**
|
|
404
|
+
* Sanitize potentially dangerous URLs, like "javascript:", in image src attributes.
|
|
405
|
+
* Returns empty string if the URL is unsafe.
|
|
406
|
+
*/
|
|
407
|
+
var sanitizeImageSrc = (url) => {
|
|
408
|
+
const img = document.createElement("img");
|
|
409
|
+
img.setAttribute("src", url);
|
|
410
|
+
return dompurify.default.sanitize(img, {
|
|
411
|
+
RETURN_DOM: true,
|
|
412
|
+
...domPurifyConfig
|
|
413
|
+
}).querySelector("img").getAttribute("src") ?? "";
|
|
320
414
|
};
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
appearance,
|
|
333
|
-
disabled,
|
|
334
|
-
icon: props.icon,
|
|
335
|
-
autofocus: props.autofocus,
|
|
336
|
-
connotation,
|
|
337
|
-
[props.icon ? "ariaLabel" : "label"]: props.label,
|
|
338
|
-
pressed: () => Boolean(ctx.evalProp(props.active)),
|
|
339
|
-
ariaPressed: props.active !== void 0 ? () => ctx.evalProp(props.active) ? "true" : "false" : void 0
|
|
340
|
-
}, [on("click", props.onClick, (onClick) => () => {
|
|
341
|
-
if (!onClick() && ctx.shouldReturnFocusToEditor()) ctx.view.focus();
|
|
342
|
-
})]);
|
|
343
|
-
return createOptionalTooltip(ctx, {
|
|
344
|
-
enabled: () => Boolean(ctx.evalProp(props.icon) && !ctx.evalProp(props.noTooltip) && !disabled()),
|
|
345
|
-
label: props.label,
|
|
346
|
-
anchor: button,
|
|
347
|
-
slot: props.slot
|
|
348
|
-
});
|
|
349
|
-
};
|
|
350
|
-
var createMenu = (ctx, props) => {
|
|
351
|
-
const menu = ctx.rte.createComponent(require_definition$4.Menu);
|
|
352
|
-
ctx.bindToEl(menu, {
|
|
353
|
-
className: "ui-menu",
|
|
354
|
-
autoDismiss: true,
|
|
355
|
-
ariaLabel: props.label,
|
|
356
|
-
anchor: wrapperTargets.get(props.trigger) ?? props.trigger,
|
|
357
|
-
placement: ctx.props.popupPlacement,
|
|
358
|
-
offset: () => ctx.evalProp(ctx.props.menuOffset) ?? null
|
|
359
|
-
}, [], props.children);
|
|
360
|
-
const fragment = document.createDocumentFragment();
|
|
361
|
-
fragment.appendChild(props.trigger);
|
|
362
|
-
fragment.appendChild(menu);
|
|
363
|
-
return fragment;
|
|
364
|
-
};
|
|
365
|
-
var createMenuItem = (ctx, props) => {
|
|
366
|
-
const disabled = () => Boolean(ctx.evalProp(ctx.props.disabled) || ctx.evalProp(props.disabled));
|
|
367
|
-
const item = ctx.rte.createComponent(require_definition$3.MenuItem);
|
|
368
|
-
ctx.bindToEl(item, {
|
|
369
|
-
text: props.text,
|
|
370
|
-
checked: props.checked,
|
|
371
|
-
disabled,
|
|
372
|
-
controlType: "radio",
|
|
373
|
-
checkedAppearance: "tick-only"
|
|
374
|
-
}, [on("change", props.onSelect, (onSelect) => () => {
|
|
375
|
-
if (item.checked && !item.disabled) {
|
|
376
|
-
if (ctx.evalProp(props.checked) !== item.checked) {
|
|
377
|
-
onSelect();
|
|
378
|
-
if (ctx.shouldReturnFocusToEditor()) ctx.view.focus();
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
})]);
|
|
382
|
-
return item;
|
|
383
|
-
};
|
|
384
|
-
var createButtonGroup = (ctx, props) => createDiv(ctx, {
|
|
385
|
-
slot: props.slot,
|
|
386
|
-
className: "ui-button-group",
|
|
387
|
-
children: props.children
|
|
415
|
+
/**
|
|
416
|
+
* Escapes a CSS value for insertion into style attribute.
|
|
417
|
+
* E.g. "15px; background: red" => "15px"
|
|
418
|
+
*/
|
|
419
|
+
var escapeCssProperty = (value) => value.replace(/[;!].*/, "");
|
|
420
|
+
//#endregion
|
|
421
|
+
//#region src/lib/rich-text-editor/rte/html-parser.ts
|
|
422
|
+
var copy = (obj) => ({ ...obj });
|
|
423
|
+
var parseRulesFromSchema = (schema) => ({
|
|
424
|
+
nodes: Object.fromEntries(Object.keys(schema.nodes).map((name) => [name, (schema.nodes[name].spec.parseDOM ?? []).map(copy)])),
|
|
425
|
+
marks: Object.fromEntries(Object.keys(schema.marks).map((name) => [name, (schema.marks[name].spec.parseDOM ?? []).map(copy)]))
|
|
388
426
|
});
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
427
|
+
var RteHtmlParser = class {
|
|
428
|
+
constructor(config, options) {
|
|
429
|
+
this[require_slottable_request.impl] = new RteHtmlParserImpl(config[require_slottable_request.impl], options);
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Converts an HTML string to an RteDocument.
|
|
433
|
+
*/
|
|
434
|
+
parseDocument(html, options) {
|
|
435
|
+
return this[require_slottable_request.impl].parser.parse(this.parseHtml(html, options), { preserveWhitespace: true }).toJSON();
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Converts an HTML string to an RteFragment.
|
|
439
|
+
*/
|
|
440
|
+
parseFragment(html, options) {
|
|
441
|
+
return this[require_slottable_request.impl].parser.parseSlice(this.parseHtml(html, options), { preserveWhitespace: true }).content.toJSON() ?? [];
|
|
442
|
+
}
|
|
443
|
+
parseHtml(html, options) {
|
|
444
|
+
const dom = dompurify.default.sanitize(html, {
|
|
445
|
+
RETURN_DOM: true,
|
|
446
|
+
...domPurifyConfig
|
|
447
|
+
});
|
|
448
|
+
const container = document.createDocumentFragment();
|
|
449
|
+
container.appendChild(dom);
|
|
450
|
+
options?.modifyDom?.(container);
|
|
451
|
+
return container;
|
|
401
452
|
}
|
|
402
|
-
});
|
|
403
|
-
var createOption = (ctx, props) => {
|
|
404
|
-
const disabled = () => Boolean(ctx.evalProp(ctx.props.disabled) || ctx.evalProp(props.disabled));
|
|
405
|
-
const option = ctx.rte.createComponent(require_definition$7.ListboxOption);
|
|
406
|
-
ctx.bindToEl(option, {
|
|
407
|
-
value: props.value,
|
|
408
|
-
text: props.text,
|
|
409
|
-
disabled
|
|
410
|
-
});
|
|
411
|
-
return option;
|
|
412
453
|
};
|
|
413
|
-
var
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
454
|
+
var RteHtmlParserImpl = class {
|
|
455
|
+
constructor(config, options) {
|
|
456
|
+
const rules = parseRulesFromSchema(config.schema);
|
|
457
|
+
options?.modifyParseRules?.(rules);
|
|
458
|
+
this.parser = buildDomParser(config.schema, rules);
|
|
459
|
+
}
|
|
460
|
+
transform(html) {
|
|
461
|
+
return dompurify.default.sanitize(html);
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
var buildDomParser = (schema, { marks, nodes }) => {
|
|
465
|
+
const parserRules = [];
|
|
466
|
+
const priority = (rule) => rule.priority ?? 50;
|
|
467
|
+
function insert(rule) {
|
|
468
|
+
let i = 0;
|
|
469
|
+
for (; i < parserRules.length; i++) {
|
|
470
|
+
const next = parserRules[i];
|
|
471
|
+
if (priority(next) < priority(rule)) break;
|
|
427
472
|
}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
select.addEventListener("vwc-popup:open", () => {
|
|
434
|
-
hideTooltip = true;
|
|
435
|
-
ctx.updateBindings();
|
|
436
|
-
});
|
|
437
|
-
select.addEventListener("vwc-popup:close", () => {
|
|
438
|
-
hideTooltip = false;
|
|
439
|
-
ctx.updateBindings();
|
|
473
|
+
parserRules.splice(i, 0, rule);
|
|
474
|
+
}
|
|
475
|
+
for (const name in marks) marks[name]?.forEach((rule) => {
|
|
476
|
+
insert(rule = copy(rule));
|
|
477
|
+
if (!(rule.mark || rule.ignore || rule.clearMark)) rule.mark = name;
|
|
440
478
|
});
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
anchor: select
|
|
479
|
+
for (const name in nodes) nodes[name]?.forEach((rule) => {
|
|
480
|
+
insert(rule = copy(rule));
|
|
481
|
+
if (!(rule.node || rule.ignore || rule.mark)) rule.node = name;
|
|
445
482
|
});
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
ctx.bindToEl(divider, {
|
|
450
|
-
className: "ui-divider",
|
|
451
|
-
orientation: "vertical"
|
|
483
|
+
parserRules.push({
|
|
484
|
+
tag: "br",
|
|
485
|
+
closeParent: true
|
|
452
486
|
});
|
|
453
|
-
return
|
|
454
|
-
};
|
|
455
|
-
var createTextField = (ctx, props) => {
|
|
456
|
-
const textField = ctx.rte.createComponent(require_definition$5.TextField);
|
|
457
|
-
ctx.bindToEl(textField, {
|
|
458
|
-
label: props.label,
|
|
459
|
-
value: props.value,
|
|
460
|
-
placeholder: props.placeholder,
|
|
461
|
-
slot: props.slot,
|
|
462
|
-
autofocus: props.autofocus,
|
|
463
|
-
type: props.type,
|
|
464
|
-
helperText: props.helperText
|
|
465
|
-
}, [on("input", props.onInput, (onInput) => () => {
|
|
466
|
-
onInput(textField.value);
|
|
467
|
-
})]);
|
|
468
|
-
return textField;
|
|
469
|
-
};
|
|
470
|
-
var createText = (ctx, props) => {
|
|
471
|
-
const textNode = document.createTextNode("");
|
|
472
|
-
ctx.bindToEl(textNode, { textContent: props.text });
|
|
473
|
-
return textNode;
|
|
487
|
+
return new prosemirror_model.DOMParser(schema, parserRules);
|
|
474
488
|
};
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
function cleanup() {
|
|
481
|
-
for (const { el, type, handler } of listeners) el.removeEventListener(type, handler);
|
|
482
|
-
listeners.length = 0;
|
|
483
|
-
currentEl = null;
|
|
489
|
+
//#endregion
|
|
490
|
+
//#region src/lib/rich-text-editor/rte/html-serializer.ts
|
|
491
|
+
var RteHtmlSerializer = class {
|
|
492
|
+
constructor(config, options) {
|
|
493
|
+
this[require_slottable_request.impl] = new RteHtmlSerializerImpl(config[require_slottable_request.impl], options);
|
|
484
494
|
}
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
listeners.push({
|
|
497
|
-
el,
|
|
498
|
-
type,
|
|
499
|
-
handler: listener
|
|
500
|
-
});
|
|
501
|
-
}
|
|
495
|
+
/**
|
|
496
|
+
* Converts an RteDocument to an HTML string.
|
|
497
|
+
*/
|
|
498
|
+
serializeDocument(doc, options) {
|
|
499
|
+
return this[require_slottable_request.impl].serializeFragment(doc.content, options);
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Converts an RteFragment to an HTML string.
|
|
503
|
+
*/
|
|
504
|
+
serializeFragment(fragment, options) {
|
|
505
|
+
return this[require_slottable_request.impl].serializeFragment(fragment, options);
|
|
502
506
|
}
|
|
503
|
-
const processSlot = () => {
|
|
504
|
-
const first = slot.assignedElements({ flatten: true })[0];
|
|
505
|
-
if (first === currentEl) return;
|
|
506
|
-
cleanup();
|
|
507
|
-
if (first) {
|
|
508
|
-
currentEl = first;
|
|
509
|
-
applyPropsAndEvents(first);
|
|
510
|
-
}
|
|
511
|
-
};
|
|
512
|
-
slot.addEventListener("slotchange", processSlot);
|
|
513
|
-
queueMicrotask(processSlot);
|
|
514
|
-
return slot;
|
|
515
507
|
};
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
508
|
+
var RteHtmlSerializerImpl = class RteHtmlSerializerImpl {
|
|
509
|
+
constructor(config, options) {
|
|
510
|
+
this.config = config;
|
|
511
|
+
const serializers = RteHtmlSerializerImpl.domSerializersFromSchema(config.schema);
|
|
512
|
+
Object.assign(serializers.nodes, options?.serializers?.nodes ?? {});
|
|
513
|
+
Object.assign(serializers.marks, options?.serializers?.marks ?? {});
|
|
514
|
+
this.serializer = new prosemirror_model.DOMSerializer(serializers.nodes, serializers.marks);
|
|
522
515
|
}
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
return [this.contribution({
|
|
532
|
-
section: "history",
|
|
533
|
-
render: (ctx) => createButton(ctx, {
|
|
534
|
-
label: (ctx) => ctx.rte.getLocale().richTextEditor.undo,
|
|
535
|
-
icon: "undo-line",
|
|
536
|
-
disabled: (ctx) => !(0, prosemirror_history.undo)(ctx.view.state),
|
|
537
|
-
onClick: () => {
|
|
538
|
-
const { state, dispatch } = ctx.view;
|
|
539
|
-
(0, prosemirror_history.undo)(state, dispatch);
|
|
540
|
-
}
|
|
541
|
-
})
|
|
542
|
-
}, 1), this.contribution({
|
|
543
|
-
section: "history",
|
|
544
|
-
render: (ctx) => createButton(ctx, {
|
|
545
|
-
label: (ctx) => ctx.rte.getLocale().richTextEditor.redo,
|
|
546
|
-
icon: "redo-line",
|
|
547
|
-
disabled: (ctx) => !(0, prosemirror_history.redo)(ctx.view.state),
|
|
548
|
-
onClick: () => {
|
|
549
|
-
const { state, dispatch } = ctx.view;
|
|
550
|
-
(0, prosemirror_history.redo)(state, dispatch);
|
|
551
|
-
}
|
|
552
|
-
})
|
|
553
|
-
}, 2)];
|
|
554
|
-
}
|
|
555
|
-
};
|
|
556
|
-
//#endregion
|
|
557
|
-
//#region src/lib/rich-text-editor/rte/features/internal/foreign-html.ts
|
|
558
|
-
var RteForeignHtmlFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
|
|
559
|
-
constructor(..._args) {
|
|
560
|
-
super(..._args);
|
|
561
|
-
this.name = "RteForeignHtmlFeature";
|
|
562
|
-
}
|
|
563
|
-
getPlugins(rte) {
|
|
564
|
-
return [this.contribution(new prosemirror_state.Plugin({ props: {
|
|
565
|
-
transformPastedHTML: (html) => rte.foreignHtmlParser[require_slottable_request.impl].transform(html),
|
|
566
|
-
clipboardParser: rte.foreignHtmlParser[require_slottable_request.impl].parser,
|
|
567
|
-
clipboardSerializer: rte.foreignHtmlSerializer[require_slottable_request.impl].serializer
|
|
568
|
-
} }))];
|
|
569
|
-
}
|
|
570
|
-
};
|
|
571
|
-
//#endregion
|
|
572
|
-
//#region src/lib/rich-text-editor/rte/features/internal/cursor-fix.ts
|
|
573
|
-
/**
|
|
574
|
-
* When the cursor is positioned after an inline atom node at the end of a line,
|
|
575
|
-
* browsers may display the cursor inside the atom.
|
|
576
|
-
*/
|
|
577
|
-
var atomCursorFix = ($cursor) => {
|
|
578
|
-
if (!($cursor.parentOffset === $cursor.parent.content.size)) return null;
|
|
579
|
-
const nodeBefore = $cursor.nodeBefore;
|
|
580
|
-
if (nodeBefore && nodeBefore.isInline && nodeBefore.isAtom && !nodeBefore.isText) return {};
|
|
581
|
-
return null;
|
|
582
|
-
};
|
|
583
|
-
var RteCursorFixFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
|
|
584
|
-
constructor(..._args) {
|
|
585
|
-
super(..._args);
|
|
586
|
-
this.name = "RteCursorFix";
|
|
587
|
-
}
|
|
588
|
-
getPlugins(rte) {
|
|
589
|
-
const cursorFixes = [atomCursorFix];
|
|
590
|
-
for (const markType of Object.values(rte.schema.marks)) {
|
|
591
|
-
const spec = markType.spec;
|
|
592
|
-
if (spec.cursorFix) cursorFixes.push(spec.cursorFix);
|
|
516
|
+
static domSerializersFromSchema(schema) {
|
|
517
|
+
const result = {
|
|
518
|
+
nodes: {},
|
|
519
|
+
marks: {}
|
|
520
|
+
};
|
|
521
|
+
for (const name in schema.marks) {
|
|
522
|
+
const toDOM = schema.marks[name].spec.toDOM;
|
|
523
|
+
if (toDOM) result.marks[name] = toDOM;
|
|
593
524
|
}
|
|
594
|
-
|
|
595
|
-
const
|
|
596
|
-
if (
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
if (result) Object.assign(cursorFix ??= {}, result);
|
|
601
|
-
}
|
|
602
|
-
if (!cursorFix) return null;
|
|
603
|
-
return prosemirror_view.DecorationSet.create(state.doc, [prosemirror_view.Decoration.widget($cursor.pos, () => {
|
|
604
|
-
const span = document.createElement("span");
|
|
605
|
-
span.textContent = "";
|
|
606
|
-
for (const [prop, value] of Object.entries(cursorFix)) span.style.setProperty(prop, value);
|
|
607
|
-
return span;
|
|
608
|
-
}, { side: -1 })]);
|
|
609
|
-
} } }))];
|
|
610
|
-
}
|
|
611
|
-
};
|
|
612
|
-
require_slottable_request.featureFacade(RteCursorFixFeatureImpl);
|
|
613
|
-
//#endregion
|
|
614
|
-
//#region src/lib/rich-text-editor/rte/features/internal/core.ts
|
|
615
|
-
/**
|
|
616
|
-
* Plugin to bring state from the host web component into ProseMirror.
|
|
617
|
-
*/
|
|
618
|
-
var hostBridgePlugin = new prosemirror_state.Plugin({ state: {
|
|
619
|
-
init() {
|
|
620
|
-
return null;
|
|
621
|
-
},
|
|
622
|
-
apply(tr, value) {
|
|
623
|
-
const meta = tr.getMeta(hostBridgePlugin);
|
|
624
|
-
if (meta) return meta;
|
|
625
|
-
else return value;
|
|
626
|
-
}
|
|
627
|
-
} });
|
|
628
|
-
var RteCoreImpl = class extends require_slottable_request.RteFeatureImpl {
|
|
629
|
-
constructor(..._args) {
|
|
630
|
-
super(..._args);
|
|
631
|
-
this.name = "RteCore";
|
|
632
|
-
this.disabled = new FeatureState(false);
|
|
633
|
-
}
|
|
634
|
-
getStyles() {
|
|
635
|
-
return [
|
|
636
|
-
this.contribution(prosemirror_default),
|
|
637
|
-
this.contribution(core_style_default),
|
|
638
|
-
this.contribution(ui_style_default)
|
|
639
|
-
];
|
|
640
|
-
}
|
|
641
|
-
getPlugins(rte) {
|
|
642
|
-
const enterKeyChainCommands = (0, prosemirror_commands.chainCommands)(prosemirror_commands.newlineInCode, prosemirror_commands.createParagraphNear, prosemirror_commands.liftEmptyBlock, (0, prosemirror_commands.splitBlockAs)((node, atEnd, $from) => {
|
|
643
|
-
if (!atEnd) return {
|
|
644
|
-
type: node.type,
|
|
645
|
-
attrs: node.attrs
|
|
646
|
-
};
|
|
647
|
-
return {
|
|
648
|
-
type: defaultTextblockForMatch($from.node($from.depth - 1).contentMatchAt($from.indexAfter($from.depth - 1))),
|
|
649
|
-
attrs: rte.textblockAttrs.extractFromNode(node)
|
|
650
|
-
};
|
|
651
|
-
}));
|
|
652
|
-
return [
|
|
653
|
-
this.contribution(this.disabled.plugin),
|
|
654
|
-
this.contribution(new prosemirror_state.Plugin({
|
|
655
|
-
props: {
|
|
656
|
-
editable: () => !this.disabled.getValue(rte),
|
|
657
|
-
handleDOMEvents: { click: (_view, event) => {
|
|
658
|
-
if (this.disabled.getValue(rte)) {
|
|
659
|
-
event.preventDefault();
|
|
660
|
-
return true;
|
|
661
|
-
}
|
|
662
|
-
return false;
|
|
663
|
-
} }
|
|
664
|
-
},
|
|
665
|
-
view: (view) => {
|
|
666
|
-
const popovers = view.dom.getRootNode().querySelector(".popovers");
|
|
667
|
-
const updateDisabled = () => {
|
|
668
|
-
const disabled = this.disabled.getValue(rte);
|
|
669
|
-
popovers.classList.toggle("popovers--disabled", disabled);
|
|
670
|
-
view.dom.parentElement.classList.toggle("editor--disabled", disabled);
|
|
671
|
-
};
|
|
672
|
-
updateDisabled();
|
|
673
|
-
return { update: () => {
|
|
674
|
-
updateDisabled();
|
|
675
|
-
} };
|
|
676
|
-
}
|
|
677
|
-
})),
|
|
678
|
-
this.contribution((0, prosemirror_keymap.keymap)({
|
|
679
|
-
...prosemirror_commands.baseKeymap,
|
|
680
|
-
Enter: enterKeyChainCommands,
|
|
681
|
-
"Shift-Enter": enterKeyChainCommands
|
|
682
|
-
})),
|
|
683
|
-
this.contribution((0, prosemirror_dropcursor.dropCursor)()),
|
|
684
|
-
this.contribution((0, prosemirror_gapcursor.gapCursor)()),
|
|
685
|
-
this.contribution(hostBridgePlugin)
|
|
686
|
-
];
|
|
525
|
+
for (const name in schema.nodes) {
|
|
526
|
+
const toDOM = schema.nodes[name].spec.serializeToDOM ?? schema.nodes[name].spec.toDOM;
|
|
527
|
+
if (toDOM) result.nodes[name] = toDOM;
|
|
528
|
+
}
|
|
529
|
+
result.nodes.text = (node) => document.createTextNode(node.text);
|
|
530
|
+
return result;
|
|
687
531
|
}
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
532
|
+
serializeFragment(fragment, options) {
|
|
533
|
+
const parsedFragment = prosemirror_model.Fragment.fromJSON(this.config.schema, fragment);
|
|
534
|
+
const serializedFragment = this.serializer.serializeFragment(parsedFragment);
|
|
535
|
+
const container = document.createDocumentFragment();
|
|
536
|
+
container.appendChild(serializedFragment);
|
|
537
|
+
options?.modifyDom?.(container);
|
|
538
|
+
const output = document.createElement("div");
|
|
539
|
+
output.appendChild(container);
|
|
540
|
+
return output.innerHTML;
|
|
695
541
|
}
|
|
696
542
|
};
|
|
697
|
-
require_slottable_request.featureFacade(RteCoreImpl);
|
|
698
543
|
//#endregion
|
|
699
|
-
//#region src/lib/rich-text-editor/rte/
|
|
700
|
-
var
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
* Sanitize potentially dangerous URLs, like "javascript:", in anchor href attributes.
|
|
706
|
-
* Returns empty string if the URL is unsafe.
|
|
707
|
-
*/
|
|
708
|
-
var sanitizeLinkHref = (url) => {
|
|
709
|
-
if (!DEFAULT_ALLOWED_URI_REGEXP.test(url.replace(ATTR_WHITESPACE, ""))) return "";
|
|
710
|
-
const anchor = document.createElement("a");
|
|
711
|
-
anchor.setAttribute("href", url);
|
|
712
|
-
/* v8 ignore next -- since href is already validated it's probably always present @preserve */
|
|
713
|
-
return dompurify.default.sanitize(anchor, {
|
|
714
|
-
RETURN_DOM: true,
|
|
715
|
-
...domPurifyConfig
|
|
716
|
-
}).querySelector("a").getAttribute("href") ?? "";
|
|
717
|
-
};
|
|
718
|
-
/**
|
|
719
|
-
* Sanitize potentially dangerous URLs, like "javascript:", in image src attributes.
|
|
720
|
-
* Returns empty string if the URL is unsafe.
|
|
721
|
-
*/
|
|
722
|
-
var sanitizeImageSrc = (url) => {
|
|
723
|
-
const img = document.createElement("img");
|
|
724
|
-
img.setAttribute("src", url);
|
|
725
|
-
return dompurify.default.sanitize(img, {
|
|
726
|
-
RETURN_DOM: true,
|
|
727
|
-
...domPurifyConfig
|
|
728
|
-
}).querySelector("img").getAttribute("src") ?? "";
|
|
544
|
+
//#region src/lib/rich-text-editor/rte/instance.ts
|
|
545
|
+
var parseDocument = (schema, doc) => {
|
|
546
|
+
const node = schema.topNodeType.createAndFill(null, doc ? prosemirror_model.Fragment.fromJSON(schema, doc.content) : null);
|
|
547
|
+
if (!node) throw new Error("Document could not be parsed");
|
|
548
|
+
node.check();
|
|
549
|
+
return node;
|
|
729
550
|
};
|
|
730
|
-
|
|
731
|
-
* Escapes a CSS value for insertion into style attribute.
|
|
732
|
-
* E.g. "15px; background: red" => "15px"
|
|
733
|
-
*/
|
|
734
|
-
var escapeCssProperty = (value) => value.replace(/[;!].*/, "");
|
|
735
|
-
//#endregion
|
|
736
|
-
//#region src/lib/rich-text-editor/rte/html-parser.ts
|
|
737
|
-
var copy = (obj) => ({ ...obj });
|
|
738
|
-
var parseRulesFromSchema = (schema) => ({
|
|
739
|
-
nodes: Object.fromEntries(Object.keys(schema.nodes).map((name) => [name, (schema.nodes[name].spec.parseDOM ?? []).map(copy)])),
|
|
740
|
-
marks: Object.fromEntries(Object.keys(schema.marks).map((name) => [name, (schema.marks[name].spec.parseDOM ?? []).map(copy)]))
|
|
741
|
-
});
|
|
742
|
-
var RteHtmlParser = class {
|
|
551
|
+
var RteInstance = class {
|
|
743
552
|
constructor(config, options) {
|
|
744
|
-
this
|
|
553
|
+
this.options = options;
|
|
554
|
+
this.feature = (Feature, featureId) => {
|
|
555
|
+
return this[require_slottable_request.impl].getPublicInterface(Feature, featureId);
|
|
556
|
+
};
|
|
557
|
+
this[require_slottable_request.impl] = new RteInstanceImpl(this, config, options);
|
|
745
558
|
}
|
|
746
559
|
/**
|
|
747
|
-
*
|
|
560
|
+
* Returns the current document state.
|
|
748
561
|
*/
|
|
749
|
-
|
|
750
|
-
return this[require_slottable_request.impl].
|
|
562
|
+
getDocument() {
|
|
563
|
+
return this[require_slottable_request.impl].state.doc.toJSON();
|
|
751
564
|
}
|
|
752
565
|
/**
|
|
753
|
-
*
|
|
754
|
-
*/
|
|
755
|
-
parseFragment(html, options) {
|
|
756
|
-
return this[require_slottable_request.impl].parser.parseSlice(this.parseHtml(html, options), { preserveWhitespace: true }).content.toJSON() ?? [];
|
|
757
|
-
}
|
|
758
|
-
parseHtml(html, options) {
|
|
759
|
-
const dom = dompurify.default.sanitize(html, {
|
|
760
|
-
RETURN_DOM: true,
|
|
761
|
-
...domPurifyConfig
|
|
762
|
-
});
|
|
763
|
-
const container = document.createDocumentFragment();
|
|
764
|
-
container.appendChild(dom);
|
|
765
|
-
options?.modifyDom?.(container);
|
|
766
|
-
return container;
|
|
767
|
-
}
|
|
768
|
-
};
|
|
769
|
-
var RteHtmlParserImpl = class {
|
|
770
|
-
constructor(config, options) {
|
|
771
|
-
const rules = parseRulesFromSchema(config.schema);
|
|
772
|
-
options?.modifyParseRules?.(rules);
|
|
773
|
-
this.parser = buildDomParser(config.schema, rules);
|
|
774
|
-
}
|
|
775
|
-
transform(html) {
|
|
776
|
-
return dompurify.default.sanitize(html);
|
|
777
|
-
}
|
|
778
|
-
};
|
|
779
|
-
var buildDomParser = (schema, { marks, nodes }) => {
|
|
780
|
-
const parserRules = [];
|
|
781
|
-
const priority = (rule) => rule.priority ?? 50;
|
|
782
|
-
function insert(rule) {
|
|
783
|
-
let i = 0;
|
|
784
|
-
for (; i < parserRules.length; i++) {
|
|
785
|
-
const next = parserRules[i];
|
|
786
|
-
if (priority(next) < priority(rule)) break;
|
|
787
|
-
}
|
|
788
|
-
parserRules.splice(i, 0, rule);
|
|
789
|
-
}
|
|
790
|
-
for (const name in marks) marks[name]?.forEach((rule) => {
|
|
791
|
-
insert(rule = copy(rule));
|
|
792
|
-
if (!(rule.mark || rule.ignore || rule.clearMark)) rule.mark = name;
|
|
793
|
-
});
|
|
794
|
-
for (const name in nodes) nodes[name]?.forEach((rule) => {
|
|
795
|
-
insert(rule = copy(rule));
|
|
796
|
-
if (!(rule.node || rule.ignore || rule.mark)) rule.node = name;
|
|
797
|
-
});
|
|
798
|
-
parserRules.push({
|
|
799
|
-
tag: "br",
|
|
800
|
-
closeParent: true
|
|
801
|
-
});
|
|
802
|
-
return new prosemirror_model.DOMParser(schema, parserRules);
|
|
803
|
-
};
|
|
804
|
-
//#endregion
|
|
805
|
-
//#region src/lib/rich-text-editor/rte/html-serializer.ts
|
|
806
|
-
var RteHtmlSerializer = class {
|
|
807
|
-
constructor(config, options) {
|
|
808
|
-
this[require_slottable_request.impl] = new RteHtmlSerializerImpl(config[require_slottable_request.impl], options);
|
|
809
|
-
}
|
|
810
|
-
/**
|
|
811
|
-
* Converts an RteDocument to an HTML string.
|
|
812
|
-
*/
|
|
813
|
-
serializeDocument(doc, options) {
|
|
814
|
-
return this[require_slottable_request.impl].serializeFragment(doc.content, options);
|
|
815
|
-
}
|
|
816
|
-
/**
|
|
817
|
-
* Converts an RteFragment to an HTML string.
|
|
818
|
-
*/
|
|
819
|
-
serializeFragment(fragment, options) {
|
|
820
|
-
return this[require_slottable_request.impl].serializeFragment(fragment, options);
|
|
821
|
-
}
|
|
822
|
-
};
|
|
823
|
-
var RteHtmlSerializerImpl = class RteHtmlSerializerImpl {
|
|
824
|
-
constructor(config, options) {
|
|
825
|
-
this.config = config;
|
|
826
|
-
const serializers = RteHtmlSerializerImpl.domSerializersFromSchema(config.schema);
|
|
827
|
-
Object.assign(serializers.nodes, options?.serializers?.nodes ?? {});
|
|
828
|
-
Object.assign(serializers.marks, options?.serializers?.marks ?? {});
|
|
829
|
-
this.serializer = new prosemirror_model.DOMSerializer(serializers.nodes, serializers.marks);
|
|
830
|
-
}
|
|
831
|
-
static domSerializersFromSchema(schema) {
|
|
832
|
-
const result = {
|
|
833
|
-
nodes: {},
|
|
834
|
-
marks: {}
|
|
835
|
-
};
|
|
836
|
-
for (const name in schema.marks) {
|
|
837
|
-
const toDOM = schema.marks[name].spec.toDOM;
|
|
838
|
-
if (toDOM) result.marks[name] = toDOM;
|
|
839
|
-
}
|
|
840
|
-
for (const name in schema.nodes) {
|
|
841
|
-
const toDOM = schema.nodes[name].spec.serializeToDOM ?? schema.nodes[name].spec.toDOM;
|
|
842
|
-
if (toDOM) result.nodes[name] = toDOM;
|
|
843
|
-
}
|
|
844
|
-
result.nodes.text = (node) => document.createTextNode(node.text);
|
|
845
|
-
return result;
|
|
846
|
-
}
|
|
847
|
-
serializeFragment(fragment, options) {
|
|
848
|
-
const parsedFragment = prosemirror_model.Fragment.fromJSON(this.config.schema, fragment);
|
|
849
|
-
const serializedFragment = this.serializer.serializeFragment(parsedFragment);
|
|
850
|
-
const container = document.createDocumentFragment();
|
|
851
|
-
container.appendChild(serializedFragment);
|
|
852
|
-
options?.modifyDom?.(container);
|
|
853
|
-
const output = document.createElement("div");
|
|
854
|
-
output.appendChild(container);
|
|
855
|
-
return output.innerHTML;
|
|
856
|
-
}
|
|
857
|
-
};
|
|
858
|
-
//#endregion
|
|
859
|
-
//#region src/lib/rich-text-editor/rte/instance.ts
|
|
860
|
-
var parseDocument = (schema, doc) => {
|
|
861
|
-
const node = schema.topNodeType.createAndFill(null, doc ? prosemirror_model.Fragment.fromJSON(schema, doc.content) : null);
|
|
862
|
-
if (!node) throw new Error("Document could not be parsed");
|
|
863
|
-
node.check();
|
|
864
|
-
return node;
|
|
865
|
-
};
|
|
866
|
-
var RteInstance = class {
|
|
867
|
-
constructor(config, options) {
|
|
868
|
-
this.options = options;
|
|
869
|
-
this.feature = (Feature, featureId) => {
|
|
870
|
-
return this[require_slottable_request.impl].getPublicInterface(Feature, featureId);
|
|
871
|
-
};
|
|
872
|
-
this[require_slottable_request.impl] = new RteInstanceImpl(this, config, options);
|
|
873
|
-
}
|
|
874
|
-
/**
|
|
875
|
-
* Returns the current document state.
|
|
876
|
-
*/
|
|
877
|
-
getDocument() {
|
|
878
|
-
return this[require_slottable_request.impl].state.doc.toJSON();
|
|
879
|
-
}
|
|
880
|
-
/**
|
|
881
|
-
* Reset the editor to its initial state. Optionally, an initial document can be provided.
|
|
566
|
+
* Reset the editor to its initial state. Optionally, an initial document can be provided.
|
|
882
567
|
*/
|
|
883
568
|
reset(initialDocument) {
|
|
884
569
|
this[require_slottable_request.impl].reset(initialDocument);
|
|
@@ -1164,6 +849,322 @@ var RteConfigImpl = class {
|
|
|
1164
849
|
}
|
|
1165
850
|
};
|
|
1166
851
|
//#endregion
|
|
852
|
+
//#region src/lib/rich-text-editor/rte/utils/ui.ts
|
|
853
|
+
var isPropBinding = (prop) => typeof prop === "function";
|
|
854
|
+
var on = (event, prop, handler) => [
|
|
855
|
+
event,
|
|
856
|
+
prop,
|
|
857
|
+
handler
|
|
858
|
+
];
|
|
859
|
+
var UiCtx = class {
|
|
860
|
+
constructor(view, rte, props) {
|
|
861
|
+
this.view = view;
|
|
862
|
+
this.rte = rte;
|
|
863
|
+
this.props = props;
|
|
864
|
+
this.bindings = [];
|
|
865
|
+
}
|
|
866
|
+
evalProp(prop) {
|
|
867
|
+
return isPropBinding(prop) ? prop(this) : prop;
|
|
868
|
+
}
|
|
869
|
+
bindProp(prop, bindFn) {
|
|
870
|
+
if (prop === void 0) return;
|
|
871
|
+
else if (isPropBinding(prop)) {
|
|
872
|
+
const binding = () => bindFn(prop(this));
|
|
873
|
+
this.bindings.push(binding);
|
|
874
|
+
binding();
|
|
875
|
+
} else bindFn(prop);
|
|
876
|
+
}
|
|
877
|
+
updateBindings() {
|
|
878
|
+
for (const binding of this.bindings) binding();
|
|
879
|
+
}
|
|
880
|
+
shouldReturnFocusToEditor() {
|
|
881
|
+
return this.evalProp(this.props.shouldReturnFocusToEditor);
|
|
882
|
+
}
|
|
883
|
+
bindToEl(target, props = {}, events = [], children = []) {
|
|
884
|
+
for (const name in props) this.bindProp(props[name], (value) => {
|
|
885
|
+
target[name] = value;
|
|
886
|
+
});
|
|
887
|
+
for (const [name, value, bindFn] of events) if (value) target.addEventListener(name, bindFn(value));
|
|
888
|
+
for (const child of children) target.appendChild(child);
|
|
889
|
+
}
|
|
890
|
+
};
|
|
891
|
+
var createDiv = (ctx, props) => {
|
|
892
|
+
const div = document.createElement("div");
|
|
893
|
+
ctx.bindToEl(div, {
|
|
894
|
+
className: props.className,
|
|
895
|
+
slot: props.slot
|
|
896
|
+
}, [], props.children);
|
|
897
|
+
return div;
|
|
898
|
+
};
|
|
899
|
+
var createAnchor = (ctx, props) => {
|
|
900
|
+
const anchor = document.createElement("a");
|
|
901
|
+
ctx.bindToEl(anchor, {
|
|
902
|
+
href: props.href,
|
|
903
|
+
target: props.target,
|
|
904
|
+
rel: props.rel,
|
|
905
|
+
className: props.className
|
|
906
|
+
}, [], props.children);
|
|
907
|
+
return anchor;
|
|
908
|
+
};
|
|
909
|
+
var wrapperTargets = /* @__PURE__ */ new WeakMap();
|
|
910
|
+
var createOptionalTooltip = (ctx, props) => {
|
|
911
|
+
const tooltip = ctx.rte.createComponent(require_definition$6.Tooltip);
|
|
912
|
+
tooltip.setAttribute("exportparts", "vvd-theme-alternate");
|
|
913
|
+
ctx.bindToEl(tooltip, {
|
|
914
|
+
className: "ui-tooltip",
|
|
915
|
+
text: props.label,
|
|
916
|
+
placement: ctx.props.popupPlacement
|
|
917
|
+
});
|
|
918
|
+
ctx.bindProp(props.enabled, (enabled) => {
|
|
919
|
+
if (!enabled) tooltip.open = false;
|
|
920
|
+
tooltip.anchor = enabled ? props.anchor : void 0;
|
|
921
|
+
});
|
|
922
|
+
const wrapper = createDiv(ctx, {
|
|
923
|
+
className: "ui-tooltip-wrapper",
|
|
924
|
+
slot: props.slot,
|
|
925
|
+
children: [props.anchor, tooltip]
|
|
926
|
+
});
|
|
927
|
+
wrapperTargets.set(wrapper, props.anchor);
|
|
928
|
+
return wrapper;
|
|
929
|
+
};
|
|
930
|
+
var createButton = (ctx, props) => {
|
|
931
|
+
const variant = () => ctx.evalProp(props.variant) ?? "toolbar";
|
|
932
|
+
const size = () => variant() === "toolbar" ? "super-condensed" : "condensed";
|
|
933
|
+
const appearanceInactive = () => variant() === "popover-primary" ? "outlined" : "ghost-light";
|
|
934
|
+
const appearanceActive = () => variant() === "toolbar-menu" || variant() === "popover" ? "filled" : appearanceInactive();
|
|
935
|
+
const appearance = () => ctx.evalProp(props.active) ? appearanceActive() : appearanceInactive();
|
|
936
|
+
const connotation = () => ctx.evalProp(props.connotation) ?? (variant() === "toolbar-menu" && ctx.evalProp(props.active) ? "cta" : void 0);
|
|
937
|
+
const disabled = () => Boolean(ctx.evalProp(ctx.props.disabled) || ctx.evalProp(props.disabled));
|
|
938
|
+
const button = ctx.rte.createComponent(require_definition$1.Button);
|
|
939
|
+
ctx.bindToEl(button, {
|
|
940
|
+
size,
|
|
941
|
+
appearance,
|
|
942
|
+
disabled,
|
|
943
|
+
icon: props.icon,
|
|
944
|
+
autofocus: props.autofocus,
|
|
945
|
+
connotation,
|
|
946
|
+
[props.icon ? "ariaLabel" : "label"]: props.label,
|
|
947
|
+
pressed: () => Boolean(ctx.evalProp(props.active)),
|
|
948
|
+
ariaPressed: props.active !== void 0 ? () => ctx.evalProp(props.active) ? "true" : "false" : void 0
|
|
949
|
+
}, [on("click", props.onClick, (onClick) => () => {
|
|
950
|
+
if (!onClick() && ctx.shouldReturnFocusToEditor()) ctx.view.focus();
|
|
951
|
+
})]);
|
|
952
|
+
return createOptionalTooltip(ctx, {
|
|
953
|
+
enabled: () => Boolean(ctx.evalProp(props.icon) && !ctx.evalProp(props.noTooltip) && !disabled()),
|
|
954
|
+
label: props.label,
|
|
955
|
+
anchor: button,
|
|
956
|
+
slot: props.slot
|
|
957
|
+
});
|
|
958
|
+
};
|
|
959
|
+
var createMenu = (ctx, props) => {
|
|
960
|
+
const menu = ctx.rte.createComponent(require_definition$4.Menu);
|
|
961
|
+
ctx.bindToEl(menu, {
|
|
962
|
+
className: "ui-menu",
|
|
963
|
+
autoDismiss: true,
|
|
964
|
+
ariaLabel: props.label,
|
|
965
|
+
anchor: wrapperTargets.get(props.trigger) ?? props.trigger,
|
|
966
|
+
placement: ctx.props.popupPlacement,
|
|
967
|
+
offset: () => ctx.evalProp(ctx.props.menuOffset) ?? null
|
|
968
|
+
}, [], props.children);
|
|
969
|
+
const fragment = document.createDocumentFragment();
|
|
970
|
+
fragment.appendChild(props.trigger);
|
|
971
|
+
fragment.appendChild(menu);
|
|
972
|
+
return fragment;
|
|
973
|
+
};
|
|
974
|
+
var createMenuItem = (ctx, props) => {
|
|
975
|
+
const disabled = () => Boolean(ctx.evalProp(ctx.props.disabled) || ctx.evalProp(props.disabled));
|
|
976
|
+
const item = ctx.rte.createComponent(require_definition$3.MenuItem);
|
|
977
|
+
ctx.bindToEl(item, {
|
|
978
|
+
text: props.text,
|
|
979
|
+
checked: props.checked,
|
|
980
|
+
disabled,
|
|
981
|
+
controlType: "radio",
|
|
982
|
+
checkedAppearance: "tick-only"
|
|
983
|
+
}, [on("change", props.onSelect, (onSelect) => () => {
|
|
984
|
+
if (item.checked && !item.disabled) {
|
|
985
|
+
if (ctx.evalProp(props.checked) !== item.checked) {
|
|
986
|
+
onSelect();
|
|
987
|
+
if (ctx.shouldReturnFocusToEditor()) ctx.view.focus();
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
})]);
|
|
991
|
+
return item;
|
|
992
|
+
};
|
|
993
|
+
var createButtonGroup = (ctx, props) => createDiv(ctx, {
|
|
994
|
+
slot: props.slot,
|
|
995
|
+
className: "ui-button-group",
|
|
996
|
+
children: props.children
|
|
997
|
+
});
|
|
998
|
+
function markActive(state, type) {
|
|
999
|
+
const { from, $from, to, empty } = state.selection;
|
|
1000
|
+
if (empty) return !!type.isInSet(state.storedMarks || $from.marks());
|
|
1001
|
+
else return state.doc.rangeHasMark(from, to, type);
|
|
1002
|
+
}
|
|
1003
|
+
var createMarkToggle = (ctx, props) => createButton(ctx, {
|
|
1004
|
+
label: props.label,
|
|
1005
|
+
icon: props.icon,
|
|
1006
|
+
active: () => markActive(ctx.view.state, props.markType),
|
|
1007
|
+
disabled: () => !(0, prosemirror_commands.toggleMark)(props.markType)(ctx.view.state),
|
|
1008
|
+
onClick: () => {
|
|
1009
|
+
(0, prosemirror_commands.toggleMark)(props.markType)(ctx.view.state, ctx.view.dispatch);
|
|
1010
|
+
}
|
|
1011
|
+
});
|
|
1012
|
+
var createOption = (ctx, props) => {
|
|
1013
|
+
const disabled = () => Boolean(ctx.evalProp(ctx.props.disabled) || ctx.evalProp(props.disabled));
|
|
1014
|
+
const option = ctx.rte.createComponent(require_definition$7.ListboxOption);
|
|
1015
|
+
ctx.bindToEl(option, {
|
|
1016
|
+
value: props.value,
|
|
1017
|
+
text: props.text,
|
|
1018
|
+
disabled
|
|
1019
|
+
});
|
|
1020
|
+
return option;
|
|
1021
|
+
};
|
|
1022
|
+
var createSelect = (ctx, props) => {
|
|
1023
|
+
const disabled = () => Boolean(ctx.evalProp(ctx.props.disabled));
|
|
1024
|
+
const select = ctx.rte.createComponent(require_definition$9.Select);
|
|
1025
|
+
select.setAttribute("data-class", "ui-select");
|
|
1026
|
+
ctx.bindToEl(select, {
|
|
1027
|
+
placeholder: " ",
|
|
1028
|
+
ariaLabel: props.label,
|
|
1029
|
+
appearance: "ghost",
|
|
1030
|
+
disabled
|
|
1031
|
+
}, [on("change", props.onSelect, (onSelect) => () => {
|
|
1032
|
+
const value = select.value;
|
|
1033
|
+
if (value) {
|
|
1034
|
+
onSelect(value);
|
|
1035
|
+
if (ctx.shouldReturnFocusToEditor()) ctx.view.focus();
|
|
1036
|
+
}
|
|
1037
|
+
})], props.children);
|
|
1038
|
+
queueMicrotask(() => {
|
|
1039
|
+
ctx.bindProp(props.value, (value) => select.value = value);
|
|
1040
|
+
});
|
|
1041
|
+
let hideTooltip = false;
|
|
1042
|
+
select.addEventListener("vwc-popup:open", () => {
|
|
1043
|
+
hideTooltip = true;
|
|
1044
|
+
ctx.updateBindings();
|
|
1045
|
+
});
|
|
1046
|
+
select.addEventListener("vwc-popup:close", () => {
|
|
1047
|
+
hideTooltip = false;
|
|
1048
|
+
ctx.updateBindings();
|
|
1049
|
+
});
|
|
1050
|
+
return createOptionalTooltip(ctx, {
|
|
1051
|
+
enabled: () => !hideTooltip && !disabled(),
|
|
1052
|
+
label: props.label,
|
|
1053
|
+
anchor: select
|
|
1054
|
+
});
|
|
1055
|
+
};
|
|
1056
|
+
var createDivider = (ctx) => {
|
|
1057
|
+
const divider = ctx.rte.createComponent(require_divider.Divider);
|
|
1058
|
+
ctx.bindToEl(divider, {
|
|
1059
|
+
className: "ui-divider",
|
|
1060
|
+
orientation: "vertical"
|
|
1061
|
+
});
|
|
1062
|
+
return divider;
|
|
1063
|
+
};
|
|
1064
|
+
var createTextField = (ctx, props) => {
|
|
1065
|
+
const textField = ctx.rte.createComponent(require_definition$5.TextField);
|
|
1066
|
+
ctx.bindToEl(textField, {
|
|
1067
|
+
label: props.label,
|
|
1068
|
+
value: props.value,
|
|
1069
|
+
placeholder: props.placeholder,
|
|
1070
|
+
slot: props.slot,
|
|
1071
|
+
autofocus: props.autofocus,
|
|
1072
|
+
type: props.type,
|
|
1073
|
+
helperText: props.helperText
|
|
1074
|
+
}, [on("input", props.onInput, (onInput) => () => {
|
|
1075
|
+
onInput(textField.value);
|
|
1076
|
+
})]);
|
|
1077
|
+
return textField;
|
|
1078
|
+
};
|
|
1079
|
+
var createText = (ctx, props) => {
|
|
1080
|
+
const textNode = document.createTextNode("");
|
|
1081
|
+
ctx.bindToEl(textNode, { textContent: props.text });
|
|
1082
|
+
return textNode;
|
|
1083
|
+
};
|
|
1084
|
+
var createSingleSlot = (ctx, props) => {
|
|
1085
|
+
const slot = document.createElement("slot");
|
|
1086
|
+
slot.name = props.name;
|
|
1087
|
+
let currentEl = null;
|
|
1088
|
+
const listeners = [];
|
|
1089
|
+
function cleanup() {
|
|
1090
|
+
for (const { el, type, handler } of listeners) el.removeEventListener(type, handler);
|
|
1091
|
+
listeners.length = 0;
|
|
1092
|
+
currentEl = null;
|
|
1093
|
+
}
|
|
1094
|
+
for (const [key, prop] of Object.entries(props.assignedProps)) ctx.bindProp(prop, (value) => {
|
|
1095
|
+
if (currentEl) currentEl[key] = value;
|
|
1096
|
+
});
|
|
1097
|
+
function applyPropsAndEvents(el) {
|
|
1098
|
+
for (const [key, prop] of Object.entries(props.assignedProps)) el[key] = ctx.evalProp(prop);
|
|
1099
|
+
for (const [type, handler] of Object.entries(props.assignedEvents)) {
|
|
1100
|
+
const listener = (e) => {
|
|
1101
|
+
handler(e);
|
|
1102
|
+
if (ctx.shouldReturnFocusToEditor()) ctx.view.focus();
|
|
1103
|
+
};
|
|
1104
|
+
el.addEventListener(type, listener);
|
|
1105
|
+
listeners.push({
|
|
1106
|
+
el,
|
|
1107
|
+
type,
|
|
1108
|
+
handler: listener
|
|
1109
|
+
});
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
const processSlot = () => {
|
|
1113
|
+
const first = slot.assignedElements({ flatten: true })[0];
|
|
1114
|
+
if (first === currentEl) return;
|
|
1115
|
+
cleanup();
|
|
1116
|
+
if (first) {
|
|
1117
|
+
currentEl = first;
|
|
1118
|
+
applyPropsAndEvents(first);
|
|
1119
|
+
}
|
|
1120
|
+
};
|
|
1121
|
+
slot.addEventListener("slotchange", processSlot);
|
|
1122
|
+
queueMicrotask(processSlot);
|
|
1123
|
+
return slot;
|
|
1124
|
+
};
|
|
1125
|
+
//#endregion
|
|
1126
|
+
//#region src/lib/rich-text-editor/rte/features/internal/history.ts
|
|
1127
|
+
var RteHistoryFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
|
|
1128
|
+
constructor(config) {
|
|
1129
|
+
super();
|
|
1130
|
+
this.config = config;
|
|
1131
|
+
this.name = "RteHistoryFeature";
|
|
1132
|
+
}
|
|
1133
|
+
getPlugins() {
|
|
1134
|
+
return [this.contribution((0, prosemirror_history.history)()), this.contribution((0, prosemirror_keymap.keymap)({
|
|
1135
|
+
"Mod-z": prosemirror_history.undo,
|
|
1136
|
+
"Ctrl-y": prosemirror_history.redo,
|
|
1137
|
+
"Cmd-Z": prosemirror_history.redo
|
|
1138
|
+
}))];
|
|
1139
|
+
}
|
|
1140
|
+
getToolbarItems() {
|
|
1141
|
+
if (!this.config.showToolbarButtons) return [];
|
|
1142
|
+
return [this.contribution({
|
|
1143
|
+
section: "history",
|
|
1144
|
+
render: (ctx) => createButton(ctx, {
|
|
1145
|
+
label: (ctx) => ctx.rte.getLocale().richTextEditor.undo,
|
|
1146
|
+
icon: "undo-line",
|
|
1147
|
+
disabled: (ctx) => !(0, prosemirror_history.undo)(ctx.view.state),
|
|
1148
|
+
onClick: () => {
|
|
1149
|
+
const { state, dispatch } = ctx.view;
|
|
1150
|
+
(0, prosemirror_history.undo)(state, dispatch);
|
|
1151
|
+
}
|
|
1152
|
+
})
|
|
1153
|
+
}, 1), this.contribution({
|
|
1154
|
+
section: "history",
|
|
1155
|
+
render: (ctx) => createButton(ctx, {
|
|
1156
|
+
label: (ctx) => ctx.rte.getLocale().richTextEditor.redo,
|
|
1157
|
+
icon: "redo-line",
|
|
1158
|
+
disabled: (ctx) => !(0, prosemirror_history.redo)(ctx.view.state),
|
|
1159
|
+
onClick: () => {
|
|
1160
|
+
const { state, dispatch } = ctx.view;
|
|
1161
|
+
(0, prosemirror_history.redo)(state, dispatch);
|
|
1162
|
+
}
|
|
1163
|
+
})
|
|
1164
|
+
}, 2)];
|
|
1165
|
+
}
|
|
1166
|
+
};
|
|
1167
|
+
//#endregion
|
|
1167
1168
|
//#region src/lib/rich-text-editor/rte/features/internal/basic-text-blocks.style.scss?inline
|
|
1168
1169
|
var basic_text_blocks_style_default = "h1,h2,h3,p{all:unset;display:block}h1:first-child,h2:first-child,h3:first-child,p:first-child{margin-block-start:0}h1:last-child,h2:last-child,h3:last-child,p:last-child{margin-block-end:0}p{font:var(--vvd-typography-base);font-variant-ligatures:unset;font-feature-settings:unset;margin-block:16px;line-height:20px}.heading-step-1{font:var(--vvd-typography-heading-4);font-variant-ligatures:unset;font-feature-settings:unset;margin-block:24px 12px;line-height:28px}.heading-step-2{font:var(--vvd-typography-heading-3);font-variant-ligatures:unset;font-feature-settings:unset;margin-block:24px 12px;line-height:36px}.heading-step-3{font:var(--vvd-typography-heading-2);font-variant-ligatures:unset;font-feature-settings:unset;margin-block:32px 16px;line-height:42px}";
|
|
1169
1170
|
//#endregion
|
|
@@ -1346,6 +1347,7 @@ var RteBaseImpl = class extends require_slottable_request.RteFeatureImpl {
|
|
|
1346
1347
|
return [
|
|
1347
1348
|
this,
|
|
1348
1349
|
new RteCoreImpl(),
|
|
1350
|
+
new RteHistoryFeatureImpl({ showToolbarButtons: this.config?.historyToolbarButtons ?? true }),
|
|
1349
1351
|
new RteBasicTextBlocksImpl({
|
|
1350
1352
|
heading1: this.config?.heading1 ?? false,
|
|
1351
1353
|
heading2: this.config?.heading2 ?? false,
|
|
@@ -3225,7 +3227,6 @@ var RteInputRuleFeature = require_slottable_request.featureFacade(RteInputRuleFe
|
|
|
3225
3227
|
//#endregion
|
|
3226
3228
|
//#region src/lib/rich-text-editor/rte/features/keyboard-shortcuts.ts
|
|
3227
3229
|
function toCommand(handler, rteInstance) {
|
|
3228
|
-
if (handler.length === 0) return (_state, _dispatch) => handler();
|
|
3229
3230
|
return (_state, _dispatch) => handler(rteInstance);
|
|
3230
3231
|
}
|
|
3231
3232
|
var RteKeyboardShortcutsFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
|