@zipify/wysiwyg 3.0.1 → 3.0.2-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/dist/wysiwyg.mjs CHANGED
@@ -26,7 +26,7 @@ var __privateMethod = (obj, member, method) => {
26
26
  __accessCheck(obj, member, "access private method");
27
27
  return method;
28
28
  };
29
- var _buildDecorations, buildDecorations_fn, _domParser, _parser, _NodeFilter, NodeFilter_get, _Node, Node_get, _removeComments, removeComments_fn, _normalizeRootTags, normalizeRootTags_fn, _createNodeIterator, createNodeIterator_fn, _iterateNodes, iterateNodes_fn, _runIterator, runIterator_fn, _removeEmptyNodes, removeEmptyNodes_fn, _normalizeListItems, normalizeListItems_fn, _isBlockNode, isBlockNode_fn, _isRootNode, isRootNode_fn, _assignElementProperties, assignElementProperties_fn, _removeStyleProperties, removeStyleProperties_fn, _normalizeBreakLines, normalizeBreakLines_fn, _normalizeBlockTextDecoration, normalizeBlockTextDecoration_fn, _moveTextDecorationToChildren, moveTextDecorationToChildren_fn, _parseTextDecoration, parseTextDecoration_fn, _normalizeBlockBackgroundColor, normalizeBlockBackgroundColor_fn, _moveBackgroundColorToChildren, moveBackgroundColorToChildren_fn, _wrapTextNode, wrapTextNode_fn, _iterateNodes2, iterateNodes_fn2, _iterateChildNodes, iterateChildNodes_fn, _bubbleMarks, bubbleMarks_fn, _canBubbleMark, canBubbleMark_fn, _includesMark, includesMark_fn, _includesMarkType, includesMarkType_fn, _removeMark, removeMark_fn, _addMark, addMark_fn, _findMarkIndexByType, findMarkIndexByType_fn, _buildHtml, buildHtml_fn, _buildJson, buildJson_fn, _schema, _domParser2, _nodeDomParser, _textBlock, textBlock_fn, _normalizeTextBlockArgs, normalizeTextBlockArgs_fn, _contentSerializer, _getWeights, getWeights_fn;
29
+ var _buildDecorations, buildDecorations_fn, _domParser, _parser, _NodeFilter, NodeFilter_get, _Node, Node_get, _removeComments, removeComments_fn, _normalizeRootTags, normalizeRootTags_fn, _createNodeIterator, createNodeIterator_fn, _iterateNodes, iterateNodes_fn, _runIterator, runIterator_fn, _removeEmptyNodes, removeEmptyNodes_fn, _normalizeListItems, normalizeListItems_fn, _isBlockNode, isBlockNode_fn, _isRootNode, isRootNode_fn, _assignElementProperties, assignElementProperties_fn, _removeStyleProperties, removeStyleProperties_fn, _normalizeBreakLines, normalizeBreakLines_fn, _normalizeBlockTextDecoration, normalizeBlockTextDecoration_fn, _moveTextDecorationToChildren, moveTextDecorationToChildren_fn, _parseTextDecoration, parseTextDecoration_fn, _normalizeBlockBackgroundColor, normalizeBlockBackgroundColor_fn, _moveBackgroundColorToChildren, moveBackgroundColorToChildren_fn, _wrapTextNode, wrapTextNode_fn, _iterateNodes2, iterateNodes_fn2, _iterateChildNodes, iterateChildNodes_fn, _bubbleMarks, bubbleMarks_fn, _canBubbleMark, canBubbleMark_fn, _includesMark, includesMark_fn, _includesMarkType, includesMarkType_fn, _removeMark, removeMark_fn, _addMark, addMark_fn, _findMarkIndexByType, findMarkIndexByType_fn, _buildHtml, buildHtml_fn, _buildJson, buildJson_fn, _schema, _domParser2, _nodeDomParser, _textBlock, textBlock_fn, _normalizeTextBlockArgs, normalizeTextBlockArgs_fn, _contentSerializer, _baseClass, _makeVariable, _linkPresetId, _makeInternalVariableName, makeInternalVariableName_fn, _getWeights, getWeights_fn;
30
30
  import { computed, unref, toRef, reactive, watch, ref, inject, onUnmounted, nextTick, provide, onMounted } from "vue";
31
31
  import { ColorModel, ZipifyColorPicker } from "@zipify/colorpicker";
32
32
  function OrderedMap(content) {
@@ -14408,314 +14408,6 @@ class JsonSerializer {
14408
14408
  return JSON.stringify(json);
14409
14409
  }
14410
14410
  }
14411
- const FontFamily = Mark.create({
14412
- name: TextSettings.FONT_FAMILY,
14413
- group: MarkGroups.SETTINGS,
14414
- addOptions: () => ({
14415
- fonts: []
14416
- }),
14417
- addAttributes: () => ({
14418
- value: { required: true }
14419
- }),
14420
- addCommands() {
14421
- return {
14422
- applyFontFamily: createCommand(({ commands: commands2 }, value) => {
14423
- commands2.applyMark(this.name, { value });
14424
- const font = commands2.findFontByName(value);
14425
- let fontWeight = unref(commands2.getFontWeight());
14426
- if (!font.isWeightSupported(fontWeight)) {
14427
- fontWeight = font.findClosestWeight(fontWeight);
14428
- commands2.applyFontWeight(fontWeight);
14429
- }
14430
- if (!font.isItalicSupported(fontWeight)) {
14431
- commands2.removeItalic();
14432
- }
14433
- }),
14434
- getFont: createCommand(({ commands: commands2 }) => {
14435
- const defaultPreset = unref(this.options.defaultPreset);
14436
- const defaultFont = commands2.findFontByName(defaultPreset.common.font_family);
14437
- const fontFamily = commands2.getFontFamily();
14438
- return computed(() => commands2.findFontByName(unref(fontFamily)) || defaultFont);
14439
- }),
14440
- findFontByName: createCommand((_, name) => {
14441
- return this.options.fonts.find((font) => font.name === name);
14442
- }),
14443
- getFontFamily: createCommand(({ commands: commands2 }) => {
14444
- return commands2.getCommonSettingMark(this.name, commands2.getDefaultFontFamily());
14445
- }),
14446
- getDefaultFontFamily: createCommand(({ commands: commands2 }) => {
14447
- const preset = commands2.getPreset();
14448
- return computed(() => unref(preset).common.font_family);
14449
- })
14450
- };
14451
- },
14452
- parseHTML() {
14453
- const getAttrs = (input) => ({ value: input.replace(/["']/g, "") });
14454
- return [
14455
- {
14456
- style: "--zw-font-family",
14457
- getAttrs
14458
- },
14459
- {
14460
- style: "font-family",
14461
- getAttrs
14462
- }
14463
- ];
14464
- },
14465
- renderHTML({ HTMLAttributes: attrs }) {
14466
- const font_family = attrs.value ? `"${attrs.value}"` : null;
14467
- return renderMark({ font_family });
14468
- }
14469
- });
14470
- function makePresetClass(base2, preset) {
14471
- const baseClass = base2.split(" ").map((part) => `.${part}`).join("");
14472
- return baseClass + preset.id;
14473
- }
14474
- const StylePreset = Extension.create({
14475
- name: TextSettings.STYLE_PRESET,
14476
- addStorage: () => ({
14477
- presetStyleEl: null
14478
- }),
14479
- addGlobalAttributes() {
14480
- return [
14481
- {
14482
- types: [NodeTypes.PARAGRAPH, NodeTypes.HEADING],
14483
- attributes: {
14484
- preset: {
14485
- isRequired: false,
14486
- default: { id: this.options.defaultId },
14487
- parseHTML: (element) => {
14488
- const presets = unref(this.options.presets);
14489
- if (element.parentElement.tagName === "LI")
14490
- return null;
14491
- for (const { id: id2, node, fallbackClass } of presets) {
14492
- const isFallback = fallbackClass && element.classList.contains(fallbackClass);
14493
- if (isFallback)
14494
- return { id: id2 };
14495
- const className = makePresetClass(this.options.baseClass, { id: id2 });
14496
- if (element.matches(className))
14497
- return { id: id2 };
14498
- if (element.tagName === `H${node == null ? void 0 : node.level}`)
14499
- return { id: id2 };
14500
- }
14501
- return element.tagName === "P" ? { id: this.options.defaultId } : null;
14502
- },
14503
- renderHTML: (attrs) => {
14504
- if (!attrs.preset)
14505
- return null;
14506
- return { class: this.options.baseClass + attrs.preset.id };
14507
- }
14508
- }
14509
- }
14510
- }
14511
- ];
14512
- },
14513
- addCommands() {
14514
- function findPresetById(presets, id2) {
14515
- return presets.find((preset) => id2 === preset.id);
14516
- }
14517
- function mergeSettings(source, target) {
14518
- const settings = {};
14519
- for (const name of Object.keys(source)) {
14520
- const sourceValue = source[name];
14521
- const targetValue = target[name];
14522
- const isInherit = !targetValue || targetValue.toLowerCase() === "inherit";
14523
- settings[name] = isInherit ? sourceValue : targetValue;
14524
- }
14525
- return settings;
14526
- }
14527
- return {
14528
- getPresetList: createCommand(() => computed(() => {
14529
- return this.options.presets.filter((preset) => !preset.hidden);
14530
- })),
14531
- getPreset: createCommand(({ commands: commands2 }) => {
14532
- const selectionRef = commands2.getBlockAttributes("preset", { id: this.options.defaultId });
14533
- const presetsRef = commands2.getPresetList();
14534
- const isLinkRef = commands2.isLink();
14535
- const linkPresetRef = commands2.getLinkPreset();
14536
- return computed(() => {
14537
- const preset = findPresetById(unref(presetsRef), unref(selectionRef).id);
14538
- if (!unref(isLinkRef))
14539
- return preset;
14540
- const linkPreset = unref(linkPresetRef);
14541
- return {
14542
- id: preset.id,
14543
- common: mergeSettings(preset.common, linkPreset.common),
14544
- mobile: mergeSettings(preset.mobile, linkPreset.mobile),
14545
- tablet: mergeSettings(preset.tablet, linkPreset.tablet),
14546
- desktop: mergeSettings(preset.desktop, linkPreset.desktop)
14547
- };
14548
- });
14549
- }),
14550
- applyPreset: createCommand(({ commands: commands2, chain }, presetId) => {
14551
- var _a, _b;
14552
- const presets = unref(commands2.getPresetList());
14553
- const preset = findPresetById(presets, presetId);
14554
- const nodeType = (_b = (_a = preset.node) == null ? void 0 : _a.type) != null ? _b : NodeTypes.PARAGRAPH;
14555
- const attrs = {
14556
- preset: { id: presetId }
14557
- };
14558
- if (preset.node) {
14559
- attrs.level = preset.node.level;
14560
- }
14561
- for (const textAttribute of TextSettings.attributes) {
14562
- attrs[textAttribute] = unref(commands2.getBlockAttributes(textAttribute));
14563
- }
14564
- chain().removeList().setNode(nodeType, attrs).run();
14565
- }),
14566
- applyDefaultPreset: createCommand(({ commands: commands2 }) => {
14567
- commands2.applyPreset(this.options.defaultId);
14568
- }),
14569
- removePreset: createCommand(({ commands: commands2 }) => {
14570
- commands2.setNode(NodeTypes.PARAGRAPH, { preset: null });
14571
- }),
14572
- getPresetCustomization: createCommand(({ editor, commands: commands2 }) => {
14573
- const state = toRef(editor, "state");
14574
- return computed(() => {
14575
- const { selection, doc: doc2 } = unref(state);
14576
- const { from: from2, to } = selection;
14577
- return commands2._getSettingCustomization(doc2, from2, to);
14578
- });
14579
- }),
14580
- isSettingCustomized: createCommand(({ commands: commands2 }, name) => {
14581
- const customization = commands2.getPresetCustomization();
14582
- const group = TextSettings.attributes.includes(name) ? "attributes" : "marks";
14583
- return computed(() => {
14584
- var _a, _b;
14585
- return (_b = (_a = unref(customization)[group]) == null ? void 0 : _a.includes(name)) != null ? _b : false;
14586
- });
14587
- }),
14588
- getContentCustomization: createCommand(({ editor, commands: commands2 }) => {
14589
- const state = toRef(editor, "state");
14590
- return computed(() => {
14591
- const { doc: doc2 } = unref(state);
14592
- return commands2._getSettingCustomization(doc2, 0, doc2.content.size);
14593
- });
14594
- }),
14595
- _getSettingCustomization: createCommand((_, doc2, from2, to) => {
14596
- const marks = /* @__PURE__ */ new Set();
14597
- const attributes = /* @__PURE__ */ new Set();
14598
- doc2.nodesBetween(from2, to, (node) => {
14599
- for (const [name, value] of Object.entries(node.attrs)) {
14600
- const isSetting = TextSettings.attributes.includes(name);
14601
- if (isSetting && value)
14602
- attributes.add(name);
14603
- }
14604
- for (const { type } of node.marks) {
14605
- if (TextSettings.marks.includes(type.name)) {
14606
- marks.add(type.name);
14607
- }
14608
- }
14609
- });
14610
- return {
14611
- attributes: Array.from(attributes),
14612
- marks: Array.from(marks)
14613
- };
14614
- }),
14615
- removePresetCustomization: createCommand(({ chain }) => {
14616
- chain().storeSelection().expandSelectionToBlock().removeMarks(TextSettings.marks).resetAttributes(NodeTypes.PARAGRAPH, TextSettings.attributes).resetAttributes(NodeTypes.HEADING, TextSettings.attributes).restoreSelection().run();
14617
- }),
14618
- removeFormat: createCommand(({ chain }) => {
14619
- chain().storeSelection().expandSelectionToBlock().removeAllMarks().applyDefaultPreset().restoreSelection().run();
14620
- })
14621
- };
14622
- },
14623
- onCreate() {
14624
- const existingStyleEl = ContextWindow.document.querySelector("[data-zw-styles]");
14625
- if (existingStyleEl) {
14626
- this.storage.presetStyleEl = existingStyleEl;
14627
- return;
14628
- }
14629
- this.storage.presetStyleEl = ContextWindow.document.createElement("style");
14630
- this.storage.presetStyleEl.dataset.zwStyles = "";
14631
- for (const preset of this.options.presets) {
14632
- const className = makePresetClass(this.options.baseClass, preset);
14633
- const css = [` ${className} {`];
14634
- for (const device of Devices.values) {
14635
- for (const setting of Object.keys(preset[device])) {
14636
- const variable = this.options.makeVariable({ device, preset, property: setting });
14637
- const property = setting.replace(/_/i, "-");
14638
- const prefix = device === Devices.COMMON ? "preset" : `preset-${device}`;
14639
- css.push(`--zw-${prefix}-${property}: var(${variable}, inherit);`);
14640
- }
14641
- }
14642
- css.push("}");
14643
- this.storage.presetStyleEl.innerHTML += css.join(" ");
14644
- }
14645
- ContextWindow.head.append(this.storage.presetStyleEl);
14646
- }
14647
- });
14648
- const FontWeight = Mark.create({
14649
- name: TextSettings.FONT_WEIGHT,
14650
- group: MarkGroups.SETTINGS,
14651
- addAttributes: () => ({
14652
- value: { required: true }
14653
- }),
14654
- addCommands() {
14655
- return {
14656
- applyFontWeight: createCommand(({ commands: commands2 }, value) => {
14657
- commands2.applyMark(this.name, { value });
14658
- const font = unref(commands2.getFont());
14659
- if (!font.isItalicSupported(value)) {
14660
- commands2.removeItalic();
14661
- }
14662
- }),
14663
- toggleBold: createCommand(({ commands: commands2 }) => {
14664
- const currentWeight = unref(commands2.getFontWeight());
14665
- const currentFont = unref(commands2.getFont());
14666
- const isBold = Number(currentWeight) >= 600;
14667
- const wantedWeight = isBold ? "400" : "700";
14668
- const nextWeight = currentFont.findClosestWeight(wantedWeight);
14669
- commands2.applyFontWeight(nextWeight);
14670
- }),
14671
- getFontWeight: createCommand(({ commands: commands2 }) => {
14672
- const selectionRef = commands2.getCommonSettingMark(this.name, commands2.getDefaultFontWeight());
14673
- const fontRef = commands2.getFont();
14674
- return computed(() => {
14675
- const weight = unref(selectionRef);
14676
- const font = unref(fontRef);
14677
- return font.isWeightSupported(weight) ? weight : font.findClosestWeight(weight);
14678
- });
14679
- }),
14680
- getDefaultFontWeight: createCommand(({ commands: commands2 }) => {
14681
- const preset = commands2.getPreset();
14682
- return computed(() => unref(preset).common.font_weight);
14683
- })
14684
- };
14685
- },
14686
- addKeyboardShortcuts: () => ({
14687
- "Mod-b": createKeyboardShortcut("toggleBold"),
14688
- "Mod-B": createKeyboardShortcut("toggleBold")
14689
- }),
14690
- parseHTML() {
14691
- const getAttrs = (value) => {
14692
- if (value === "bold")
14693
- return { value: "700" };
14694
- return Number(value) ? { value } : false;
14695
- };
14696
- return [
14697
- {
14698
- style: "--zw-font-weight",
14699
- getAttrs
14700
- },
14701
- {
14702
- style: "font-weight",
14703
- getAttrs
14704
- },
14705
- {
14706
- tag: "b",
14707
- attrs: { value: "700" }
14708
- },
14709
- {
14710
- tag: "strong",
14711
- attrs: { value: "700" }
14712
- }
14713
- ];
14714
- },
14715
- renderHTML({ HTMLAttributes: attrs }) {
14716
- return renderMark({ font_weight: attrs.value });
14717
- }
14718
- });
14719
14411
  const Text$1 = Node.create({
14720
14412
  name: "text",
14721
14413
  group: "inline"
@@ -15192,639 +14884,921 @@ function mustPreserveItems(state) {
15192
14884
  break;
15193
14885
  }
15194
14886
  }
15195
- return cachedPreserveItems;
15196
- }
15197
- const historyKey = new PluginKey("history");
15198
- const closeHistoryKey = new PluginKey("closeHistory");
15199
- function history(config = {}) {
15200
- config = {
15201
- depth: config.depth || 100,
15202
- newGroupDelay: config.newGroupDelay || 500
15203
- };
15204
- return new Plugin({
15205
- key: historyKey,
15206
- state: {
15207
- init() {
15208
- return new HistoryState(Branch.empty, Branch.empty, null, 0);
15209
- },
15210
- apply(tr, hist, state) {
15211
- return applyTransaction(hist, state, tr, config);
15212
- }
15213
- },
15214
- config,
15215
- props: {
15216
- handleDOMEvents: {
15217
- beforeinput(view, e) {
15218
- let inputType = e.inputType;
15219
- let command2 = inputType == "historyUndo" ? undo : inputType == "historyRedo" ? redo : null;
15220
- if (!command2)
15221
- return false;
15222
- e.preventDefault();
15223
- return command2(view.state, view.dispatch);
14887
+ return cachedPreserveItems;
14888
+ }
14889
+ const historyKey = new PluginKey("history");
14890
+ const closeHistoryKey = new PluginKey("closeHistory");
14891
+ function history(config = {}) {
14892
+ config = {
14893
+ depth: config.depth || 100,
14894
+ newGroupDelay: config.newGroupDelay || 500
14895
+ };
14896
+ return new Plugin({
14897
+ key: historyKey,
14898
+ state: {
14899
+ init() {
14900
+ return new HistoryState(Branch.empty, Branch.empty, null, 0);
14901
+ },
14902
+ apply(tr, hist, state) {
14903
+ return applyTransaction(hist, state, tr, config);
14904
+ }
14905
+ },
14906
+ config,
14907
+ props: {
14908
+ handleDOMEvents: {
14909
+ beforeinput(view, e) {
14910
+ let inputType = e.inputType;
14911
+ let command2 = inputType == "historyUndo" ? undo : inputType == "historyRedo" ? redo : null;
14912
+ if (!command2)
14913
+ return false;
14914
+ e.preventDefault();
14915
+ return command2(view.state, view.dispatch);
14916
+ }
14917
+ }
14918
+ }
14919
+ });
14920
+ }
14921
+ const undo = (state, dispatch) => {
14922
+ let hist = historyKey.getState(state);
14923
+ if (!hist || hist.done.eventCount == 0)
14924
+ return false;
14925
+ if (dispatch)
14926
+ histTransaction(hist, state, dispatch, false);
14927
+ return true;
14928
+ };
14929
+ const redo = (state, dispatch) => {
14930
+ let hist = historyKey.getState(state);
14931
+ if (!hist || hist.undone.eventCount == 0)
14932
+ return false;
14933
+ if (dispatch)
14934
+ histTransaction(hist, state, dispatch, true);
14935
+ return true;
14936
+ };
14937
+ const History = Extension.create({
14938
+ name: "history",
14939
+ addOptions() {
14940
+ return {
14941
+ depth: 100,
14942
+ newGroupDelay: 500
14943
+ };
14944
+ },
14945
+ addCommands() {
14946
+ return {
14947
+ undo: () => ({ state, dispatch }) => {
14948
+ return undo(state, dispatch);
14949
+ },
14950
+ redo: () => ({ state, dispatch }) => {
14951
+ return redo(state, dispatch);
14952
+ }
14953
+ };
14954
+ },
14955
+ addProseMirrorPlugins() {
14956
+ return [
14957
+ history(this.options)
14958
+ ];
14959
+ },
14960
+ addKeyboardShortcuts() {
14961
+ return {
14962
+ "Mod-z": () => this.editor.commands.undo(),
14963
+ "Mod-y": () => this.editor.commands.redo(),
14964
+ "Shift-Mod-z": () => this.editor.commands.redo(),
14965
+ "Mod-\u044F": () => this.editor.commands.undo(),
14966
+ "Shift-Mod-\u044F": () => this.editor.commands.redo()
14967
+ };
14968
+ }
14969
+ });
14970
+ class RemoveNodeMarkStep extends Step {
14971
+ static fromJSON(schema, json) {
14972
+ if (typeof json.pos != "number") {
14973
+ throw new RangeError("Invalid input for RemoveNodeMarkStep.fromJSON");
14974
+ }
14975
+ return new RemoveNodeMarkStep(json.pos, schema.markFromJSON(json.mark));
14976
+ }
14977
+ constructor(pos, mark) {
14978
+ super();
14979
+ this.pos = pos;
14980
+ this.mark = mark;
14981
+ }
14982
+ apply(doc2) {
14983
+ const node = doc2.nodeAt(this.pos);
14984
+ if (!node)
14985
+ return StepResult.fail("No node at mark step's position");
14986
+ const updated = node.type.create(node.attrs, null, this.mark.removeFromSet(node.marks));
14987
+ const slice2 = new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1);
14988
+ return StepResult.fromReplace(doc2, this.pos, this.pos + 1, slice2);
14989
+ }
14990
+ invert(doc2) {
14991
+ const node = doc2.nodeAt(this.pos);
14992
+ if (!node || !this.mark.isInSet(node.marks))
14993
+ return this;
14994
+ return new AddNodeMarkStep(this.pos, this.mark);
14995
+ }
14996
+ map(mapping) {
14997
+ const pos = mapping.mapResult(this.pos, 1);
14998
+ return pos.deletedAfter ? null : new RemoveNodeMarkStep(pos.pos, this.mark);
14999
+ }
15000
+ toJSON() {
15001
+ return { stepType: "removeNodeMark", pos: this.pos, mark: this.mark.toJSON() };
15002
+ }
15003
+ }
15004
+ Step.jsonID("removeNodeMark", RemoveNodeMarkStep);
15005
+ class AddNodeMarkStep extends Step {
15006
+ static fromJSON(schema, json) {
15007
+ if (typeof json.pos != "number") {
15008
+ throw new RangeError("Invalid input for AddNodeMarkStep.fromJSON");
15009
+ }
15010
+ return new AddNodeMarkStep(json.pos, schema.markFromJSON(json.mark));
15011
+ }
15012
+ constructor(pos, mark) {
15013
+ super();
15014
+ this.pos = pos;
15015
+ this.mark = mark;
15016
+ }
15017
+ apply(doc2) {
15018
+ const node = doc2.nodeAt(this.pos);
15019
+ if (!node)
15020
+ return StepResult.fail("No node at mark step's position");
15021
+ const updated = node.type.create(node.attrs, null, this.mark.addToSet(node.marks));
15022
+ const slice2 = new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1);
15023
+ return StepResult.fromReplace(doc2, this.pos, this.pos + 1, slice2);
15024
+ }
15025
+ invert(doc2) {
15026
+ const node = doc2.nodeAt(this.pos);
15027
+ if (node) {
15028
+ const newSet = this.mark.addToSet(node.marks);
15029
+ if (newSet.length === node.marks.length) {
15030
+ for (const mark of node.marks) {
15031
+ if (!mark.isInSet(newSet)) {
15032
+ return new AddNodeMarkStep(this.pos, mark);
15033
+ }
15224
15034
  }
15035
+ return new AddNodeMarkStep(this.pos, this.mark);
15225
15036
  }
15226
15037
  }
15227
- });
15038
+ return new RemoveNodeMarkStep(this.pos, this.mark);
15039
+ }
15040
+ map(mapping) {
15041
+ const pos = mapping.mapResult(this.pos, 1);
15042
+ return pos.deletedAfter ? null : new AddNodeMarkStep(pos.pos, this.mark);
15043
+ }
15044
+ toJSON() {
15045
+ return { stepType: "addNodeMark", pos: this.pos, mark: this.mark.toJSON() };
15046
+ }
15228
15047
  }
15229
- const undo = (state, dispatch) => {
15230
- let hist = historyKey.getState(state);
15231
- if (!hist || hist.done.eventCount == 0)
15232
- return false;
15233
- if (dispatch)
15234
- histTransaction(hist, state, dispatch, false);
15235
- return true;
15236
- };
15237
- const redo = (state, dispatch) => {
15238
- let hist = historyKey.getState(state);
15239
- if (!hist || hist.undone.eventCount == 0)
15240
- return false;
15241
- if (dispatch)
15242
- histTransaction(hist, state, dispatch, true);
15243
- return true;
15244
- };
15245
- const History = Extension.create({
15246
- name: "history",
15048
+ Step.jsonID("addNodeMark", AddNodeMarkStep);
15049
+ class AttrStep extends Step {
15050
+ static fromJSON(schema, json) {
15051
+ if (typeof json.pos != "number" || typeof json.attr != "string") {
15052
+ throw new RangeError("Invalid input for AttrStep.fromJSON");
15053
+ }
15054
+ return new AttrStep(json.pos, json.attr, json.value);
15055
+ }
15056
+ constructor(pos, attr, value) {
15057
+ super();
15058
+ this.pos = pos;
15059
+ this.attr = attr;
15060
+ this.value = value;
15061
+ }
15062
+ apply(doc2) {
15063
+ const node = doc2.nodeAt(this.pos);
15064
+ if (!node)
15065
+ return StepResult.fail("No node at attribute step's position");
15066
+ const attrs = /* @__PURE__ */ Object.create(null);
15067
+ for (let name in node.attrs)
15068
+ attrs[name] = node.attrs[name];
15069
+ attrs[this.attr] = this.value;
15070
+ const updated = node.type.create(attrs, null, node.marks);
15071
+ const slice2 = new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1);
15072
+ return StepResult.fromReplace(doc2, this.pos, this.pos + 1, slice2);
15073
+ }
15074
+ getMap() {
15075
+ return StepMap.empty;
15076
+ }
15077
+ invert(doc2) {
15078
+ return new AttrStep(this.pos, this.attr, doc2.nodeAt(this.pos).attrs[this.attr]);
15079
+ }
15080
+ map(mapping) {
15081
+ let pos = mapping.mapResult(this.pos, 1);
15082
+ return pos.deletedAfter ? null : new AttrStep(pos.pos, this.attr, this.value);
15083
+ }
15084
+ toJSON() {
15085
+ return { stepType: "attr", pos: this.pos, attr: this.attr, value: this.value };
15086
+ }
15087
+ }
15088
+ Step.jsonID("attr", AttrStep);
15089
+ const NodeProcessor = Extension.create({
15090
+ name: "node_processor",
15091
+ addCommands() {
15092
+ return {
15093
+ setBlockAttributes: createCommand(({ commands: commands2, state }, name, attrs, defaults2 = {}) => {
15094
+ var _a;
15095
+ const current = (_a = unref(commands2.getBlockAttributes(name))) != null ? _a : {};
15096
+ const { doc: doc2, tr } = state;
15097
+ const { from: from2, to } = tr.selection;
15098
+ doc2.nodesBetween(from2, to, (node, position) => {
15099
+ if (!NodeTypes.blocks.includes(node.type.name))
15100
+ return;
15101
+ tr.step(new AttrStep(position, name, { ...defaults2, ...current, ...attrs }));
15102
+ });
15103
+ }),
15104
+ getBlockAttributes: createCommand(({ editor }, name, defaults2) => computed(() => {
15105
+ var _a;
15106
+ let attrs = Object.assign({}, defaults2 || {});
15107
+ for (const type of NodeTypes.blocks) {
15108
+ Object.assign(attrs, ((_a = editor.getAttributes(type)) == null ? void 0 : _a[name]) || {});
15109
+ }
15110
+ return Object.keys(attrs).length ? attrs : null;
15111
+ })),
15112
+ removeBlockAttributes: createCommand(({ commands: commands2 }, names) => {
15113
+ for (const type of NodeTypes.blocks) {
15114
+ commands2.resetAttributes(type, names);
15115
+ }
15116
+ }),
15117
+ applyMark: createCommand(({ state, commands: commands2 }, name, value, customizer = {}) => {
15118
+ const { tr, doc: doc2, schema } = state;
15119
+ const { $from, $to } = tr.selection;
15120
+ const linkMarkType = getMarkType(TextSettings.LINK, schema);
15121
+ const markType = getMarkType(name, schema);
15122
+ const markGroup = markType.spec.group || "";
15123
+ if (!markGroup.includes(MarkGroups.SETTINGS)) {
15124
+ return commands2.setMark(name, value);
15125
+ }
15126
+ if ($from.pos === $to.pos)
15127
+ return;
15128
+ const onAppliedToParent = (context) => {
15129
+ if (!customizer.onAppliedToParent || customizer.onAppliedToParent(context) === false) {
15130
+ const { tr: tr2, node, position, mark } = context;
15131
+ commands2._removeNodeMark({ tr: tr2, node, position, mark: mark.type });
15132
+ }
15133
+ };
15134
+ doc2.nodesBetween($from.pos, $to.pos, (node, position) => {
15135
+ if (node.type.name === NodeTypes.LIST)
15136
+ return;
15137
+ const initialMark = findMarkByType(node.marks, name);
15138
+ const applyingMark = markType.create({ ...(initialMark == null ? void 0 : initialMark.attrs) || {}, ...value });
15139
+ const textPosition = resolveTextPosition($from, $to, node, position);
15140
+ const isAppliedToParent = !linkMarkType.isInSet(node.marks) && isMarkAppliedToParent(tr.doc, position, applyingMark, customizer.isAppliedToParent);
15141
+ if (isAppliedToParent) {
15142
+ return onAppliedToParent({ tr, node, position, mark: applyingMark });
15143
+ }
15144
+ if (node.isText) {
15145
+ tr.addMark(textPosition.from, textPosition.to, applyingMark);
15146
+ return;
15147
+ }
15148
+ if (isNodeFullySelected(tr.doc, tr.selection, node, position)) {
15149
+ tr.step(new AddNodeMarkStep(position, applyingMark));
15150
+ }
15151
+ });
15152
+ }),
15153
+ getMarks: createCommand(({ editor }, name) => {
15154
+ const stateRef = toRef(editor, "state");
15155
+ return computed(() => {
15156
+ const { selection, doc: doc2 } = unref(stateRef);
15157
+ const { from: from2, to } = unref(selection);
15158
+ const marks = [];
15159
+ doc2.nodesBetween(from2, to, (node) => {
15160
+ for (const mark of node.marks) {
15161
+ if (mark.type.name === name)
15162
+ marks.unshift(mark.attrs);
15163
+ }
15164
+ });
15165
+ return marks;
15166
+ });
15167
+ }),
15168
+ getMark: createCommand(({ commands: commands2 }, name) => {
15169
+ const marksRef = commands2.getMarks(name);
15170
+ return computed(() => {
15171
+ var _a;
15172
+ return (_a = unref(marksRef)[0]) != null ? _a : null;
15173
+ });
15174
+ }),
15175
+ hasMark: createCommand(({ commands: commands2 }, name) => {
15176
+ const mark = commands2.getMark(name);
15177
+ return computed(() => !!unref(mark));
15178
+ }),
15179
+ getCommonSettingMark: createCommand(({ commands: commands2 }, name, defaultRef) => {
15180
+ const selectionRef = commands2.getMark(name);
15181
+ return computed(() => {
15182
+ var _a, _b;
15183
+ return (_b = (_a = unref(selectionRef)) == null ? void 0 : _a.value) != null ? _b : unref(defaultRef);
15184
+ });
15185
+ }),
15186
+ getDeviceSettingMark: createCommand(({ commands: commands2 }, name, defaultRef) => {
15187
+ const selectionRef = commands2.getMarks(name);
15188
+ const deviceRef = commands2.getDevice();
15189
+ return computed(() => {
15190
+ for (const attrs of unref(selectionRef)) {
15191
+ const value = attrs[unref(deviceRef)];
15192
+ if (value)
15193
+ return value;
15194
+ }
15195
+ return unref(defaultRef);
15196
+ });
15197
+ }),
15198
+ removeAllMarks: createCommand(({ state, commands: commands2 }) => {
15199
+ const { tr, doc: doc2 } = state;
15200
+ const { from: from2, to } = tr.selection;
15201
+ doc2.nodesBetween(from2, to, (node, position) => {
15202
+ for (const mark of node.marks) {
15203
+ commands2._removeNodeMark({ tr, node, position, mark });
15204
+ }
15205
+ });
15206
+ }),
15207
+ removeMarks: createCommand(({ state, commands: commands2 }, marks) => {
15208
+ const { tr, doc: doc2 } = state;
15209
+ const { from: from2, to } = tr.selection;
15210
+ doc2.nodesBetween(from2, to, (node, position) => {
15211
+ const removingMarks = node.marks.filter((mark) => marks.includes(mark.type.name));
15212
+ for (const mark of removingMarks) {
15213
+ commands2._removeNodeMark({ tr, node, position, mark });
15214
+ }
15215
+ });
15216
+ }),
15217
+ _removeNodeMark: createCommand((context, { tr, node, position, mark }) => {
15218
+ return node.isText ? tr.removeMark(position, position + node.nodeSize, mark) : tr.step(new RemoveNodeMarkStep(position, mark));
15219
+ })
15220
+ };
15221
+ }
15222
+ });
15223
+ const TextProcessor = Extension.create({
15224
+ name: "text_processor",
15225
+ addCommands() {
15226
+ return {
15227
+ getSelectedText: createCommand(({ state }) => {
15228
+ const { from: from2, to } = state.selection;
15229
+ return state.doc.textBetween(from2, to, " ");
15230
+ }),
15231
+ transformText: createCommand(({ state }, transform) => {
15232
+ const { $from, $to } = state.tr.selection;
15233
+ if ($from.pos === $to.pos)
15234
+ return;
15235
+ state.doc.nodesBetween($from.pos, $to.pos, (node, position) => {
15236
+ if (!node.isText)
15237
+ return;
15238
+ const textPosition = resolveTextPosition($from, $to, node, position);
15239
+ const substringFrom = Math.max(0, $from.pos - position);
15240
+ const substringTo = Math.max(0, $to.pos - position);
15241
+ const updatedText = transform({
15242
+ text: node.textContent.substring(substringFrom, substringTo)
15243
+ });
15244
+ const updatedNode = state.schema.text(updatedText, node.marks);
15245
+ state.tr.replaceWith(textPosition.from, textPosition.to, updatedNode);
15246
+ });
15247
+ })
15248
+ };
15249
+ }
15250
+ });
15251
+ const SelectionProcessor = Extension.create({
15252
+ name: "selection_processor",
15253
+ addStorage: () => ({
15254
+ selection: null
15255
+ }),
15256
+ addCommands() {
15257
+ return {
15258
+ storeSelection: createCommand(({ state }) => {
15259
+ this.storage.selection = state.selection;
15260
+ }),
15261
+ restoreSelection: createCommand(({ commands: commands2 }) => {
15262
+ this.storage.selection && commands2.setTextSelection(this.storage.selection);
15263
+ }),
15264
+ expandSelection: createCommand(({ tr, commands: commands2 }, predicate) => {
15265
+ let from2 = tr.selection.from;
15266
+ let to = tr.selection.to;
15267
+ tr.doc.nodesBetween(from2, to, (node, position, parent) => {
15268
+ if (predicate({ node, parent })) {
15269
+ const offset2 = node.isText ? 0 : resolvePositionOffset(tr.doc, position);
15270
+ from2 = Math.min(from2, position + offset2);
15271
+ to = Math.max(to, position + node.nodeSize - offset2);
15272
+ }
15273
+ });
15274
+ commands2.setTextSelection({ from: from2, to });
15275
+ }),
15276
+ expandSelectionToBlock: createCommand(({ commands: commands2 }) => {
15277
+ commands2.expandSelection(({ parent }) => parent.type.name === NodeTypes.DOCUMENT);
15278
+ })
15279
+ };
15280
+ }
15281
+ });
15282
+ const Document$1 = Node.create({
15283
+ name: "doc",
15284
+ topNode: true,
15285
+ content: "block+"
15286
+ });
15287
+ const Document = Document$1.extend({
15288
+ marks: MarkGroups.SETTINGS
15289
+ });
15290
+ const Paragraph$1 = Node.create({
15291
+ name: "paragraph",
15292
+ priority: 1e3,
15247
15293
  addOptions() {
15248
15294
  return {
15249
- depth: 100,
15250
- newGroupDelay: 500
15295
+ HTMLAttributes: {}
15251
15296
  };
15252
15297
  },
15298
+ group: "block",
15299
+ content: "inline*",
15300
+ parseHTML() {
15301
+ return [
15302
+ { tag: "p" }
15303
+ ];
15304
+ },
15305
+ renderHTML({ HTMLAttributes }) {
15306
+ return ["p", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
15307
+ },
15253
15308
  addCommands() {
15254
15309
  return {
15255
- undo: () => ({ state, dispatch }) => {
15256
- return undo(state, dispatch);
15257
- },
15258
- redo: () => ({ state, dispatch }) => {
15259
- return redo(state, dispatch);
15310
+ setParagraph: () => ({ commands: commands2 }) => {
15311
+ return commands2.setNode(this.name);
15260
15312
  }
15261
15313
  };
15262
15314
  },
15263
- addProseMirrorPlugins() {
15264
- return [
15265
- history(this.options)
15266
- ];
15267
- },
15268
15315
  addKeyboardShortcuts() {
15269
15316
  return {
15270
- "Mod-z": () => this.editor.commands.undo(),
15271
- "Mod-y": () => this.editor.commands.redo(),
15272
- "Shift-Mod-z": () => this.editor.commands.redo(),
15273
- "Mod-\u044F": () => this.editor.commands.undo(),
15274
- "Shift-Mod-\u044F": () => this.editor.commands.redo()
15317
+ "Mod-Alt-0": () => this.editor.commands.setParagraph()
15275
15318
  };
15276
15319
  }
15277
15320
  });
15278
- class RemoveNodeMarkStep extends Step {
15279
- static fromJSON(schema, json) {
15280
- if (typeof json.pos != "number") {
15281
- throw new RangeError("Invalid input for RemoveNodeMarkStep.fromJSON");
15282
- }
15283
- return new RemoveNodeMarkStep(json.pos, schema.markFromJSON(json.mark));
15284
- }
15285
- constructor(pos, mark) {
15286
- super();
15287
- this.pos = pos;
15288
- this.mark = mark;
15289
- }
15290
- apply(doc2) {
15291
- const node = doc2.nodeAt(this.pos);
15292
- if (!node)
15293
- return StepResult.fail("No node at mark step's position");
15294
- const updated = node.type.create(node.attrs, null, this.mark.removeFromSet(node.marks));
15295
- const slice2 = new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1);
15296
- return StepResult.fromReplace(doc2, this.pos, this.pos + 1, slice2);
15321
+ const Paragraph = Paragraph$1.extend({
15322
+ marks: MarkGroups.ALL,
15323
+ addOptions: () => ({
15324
+ HTMLAttributes: { class: "zw-style" }
15325
+ })
15326
+ });
15327
+ const Heading$1 = Node.create({
15328
+ name: "heading",
15329
+ addOptions() {
15330
+ return {
15331
+ levels: [1, 2, 3, 4, 5, 6],
15332
+ HTMLAttributes: {}
15333
+ };
15334
+ },
15335
+ content: "inline*",
15336
+ group: "block",
15337
+ defining: true,
15338
+ addAttributes() {
15339
+ return {
15340
+ level: {
15341
+ default: 1,
15342
+ rendered: false
15343
+ }
15344
+ };
15345
+ },
15346
+ parseHTML() {
15347
+ return this.options.levels.map((level) => ({
15348
+ tag: `h${level}`,
15349
+ attrs: { level }
15350
+ }));
15351
+ },
15352
+ renderHTML({ node, HTMLAttributes }) {
15353
+ const hasLevel = this.options.levels.includes(node.attrs.level);
15354
+ const level = hasLevel ? node.attrs.level : this.options.levels[0];
15355
+ return [`h${level}`, mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
15356
+ },
15357
+ addCommands() {
15358
+ return {
15359
+ setHeading: (attributes) => ({ commands: commands2 }) => {
15360
+ if (!this.options.levels.includes(attributes.level)) {
15361
+ return false;
15362
+ }
15363
+ return commands2.setNode(this.name, attributes);
15364
+ },
15365
+ toggleHeading: (attributes) => ({ commands: commands2 }) => {
15366
+ if (!this.options.levels.includes(attributes.level)) {
15367
+ return false;
15368
+ }
15369
+ return commands2.toggleNode(this.name, "paragraph", attributes);
15370
+ }
15371
+ };
15372
+ },
15373
+ addKeyboardShortcuts() {
15374
+ return this.options.levels.reduce((items, level) => ({
15375
+ ...items,
15376
+ ...{
15377
+ [`Mod-Alt-${level}`]: () => this.editor.commands.toggleHeading({ level })
15378
+ }
15379
+ }), {});
15380
+ },
15381
+ addInputRules() {
15382
+ return this.options.levels.map((level) => {
15383
+ return textblockTypeInputRule({
15384
+ find: new RegExp(`^(#{1,${level}})\\s$`),
15385
+ type: this.type,
15386
+ getAttributes: {
15387
+ level
15388
+ }
15389
+ });
15390
+ });
15297
15391
  }
15298
- invert(doc2) {
15299
- const node = doc2.nodeAt(this.pos);
15300
- if (!node || !this.mark.isInSet(node.marks))
15301
- return this;
15302
- return new AddNodeMarkStep(this.pos, this.mark);
15392
+ });
15393
+ const Heading = Heading$1.extend({
15394
+ marks: MarkGroups.ALL,
15395
+ addOptions: () => ({
15396
+ levels: [1, 2, 3, 4],
15397
+ HTMLAttributes: { class: "zw-style" }
15398
+ })
15399
+ });
15400
+ class ProseMirrorPlugin {
15401
+ static create(editor, options) {
15402
+ const plugin = new this(editor, options || {});
15403
+ return new Plugin({
15404
+ key: new PluginKey(this.name),
15405
+ props: plugin.buildProps()
15406
+ });
15303
15407
  }
15304
- map(mapping) {
15305
- const pos = mapping.mapResult(this.pos, 1);
15306
- return pos.deletedAfter ? null : new RemoveNodeMarkStep(pos.pos, this.mark);
15408
+ constructor(editor, options) {
15409
+ this.options = options;
15410
+ this.editor = editor;
15307
15411
  }
15308
- toJSON() {
15309
- return { stepType: "removeNodeMark", pos: this.pos, mark: this.mark.toJSON() };
15412
+ buildProps() {
15413
+ return {};
15310
15414
  }
15311
15415
  }
15312
- Step.jsonID("removeNodeMark", RemoveNodeMarkStep);
15313
- class AddNodeMarkStep extends Step {
15314
- static fromJSON(schema, json) {
15315
- if (typeof json.pos != "number") {
15316
- throw new RangeError("Invalid input for AddNodeMarkStep.fromJSON");
15317
- }
15318
- return new AddNodeMarkStep(json.pos, schema.markFromJSON(json.mark));
15319
- }
15320
- constructor(pos, mark) {
15321
- super();
15322
- this.pos = pos;
15323
- this.mark = mark;
15416
+ class PastePlugin extends ProseMirrorPlugin {
15417
+ buildProps() {
15418
+ return {
15419
+ transformPastedHTML: this._transformPastedHTML.bind(this),
15420
+ handlePaste: this._handlePaste.bind(this)
15421
+ };
15324
15422
  }
15325
- apply(doc2) {
15326
- const node = doc2.nodeAt(this.pos);
15327
- if (!node)
15328
- return StepResult.fail("No node at mark step's position");
15329
- const updated = node.type.create(node.attrs, null, this.mark.addToSet(node.marks));
15330
- const slice2 = new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1);
15331
- return StepResult.fromReplace(doc2, this.pos, this.pos + 1, slice2);
15423
+ _transformPastedHTML(html2) {
15424
+ if (html2.includes("data-pm-slice") && html2.includes("zw-style")) {
15425
+ return html2;
15426
+ }
15427
+ const normalizer = ContentNormalizer.build(html2);
15428
+ normalizer.normalizeHTML();
15429
+ this._removeDeprecatedStyles(normalizer);
15430
+ return normalizer.normalizedHTML;
15332
15431
  }
15333
- invert(doc2) {
15334
- const node = doc2.nodeAt(this.pos);
15335
- if (node) {
15336
- const newSet = this.mark.addToSet(node.marks);
15337
- if (newSet.length === node.marks.length) {
15338
- for (const mark of node.marks) {
15339
- if (!mark.isInSet(newSet)) {
15340
- return new AddNodeMarkStep(this.pos, mark);
15341
- }
15342
- }
15343
- return new AddNodeMarkStep(this.pos, this.mark);
15344
- }
15432
+ _removeDeprecatedStyles(normalizer) {
15433
+ const elements = normalizer.dom.querySelectorAll('[style*="margin"]');
15434
+ for (const element of Array.from(elements)) {
15435
+ element.style.removeProperty("margin");
15436
+ element.style.removeProperty("margin-top");
15437
+ element.style.removeProperty("margin-right");
15438
+ element.style.removeProperty("margin-bottom");
15439
+ element.style.removeProperty("margin-left");
15345
15440
  }
15346
- return new RemoveNodeMarkStep(this.pos, this.mark);
15347
- }
15348
- map(mapping) {
15349
- const pos = mapping.mapResult(this.pos, 1);
15350
- return pos.deletedAfter ? null : new AddNodeMarkStep(pos.pos, this.mark);
15351
15441
  }
15352
- toJSON() {
15353
- return { stepType: "addNodeMark", pos: this.pos, mark: this.mark.toJSON() };
15442
+ _handlePaste(view, _, slice2) {
15443
+ const transaction = this._insertPastedContent(view, slice2).scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste");
15444
+ view.dispatch(transaction);
15445
+ return true;
15354
15446
  }
15355
- }
15356
- Step.jsonID("addNodeMark", AddNodeMarkStep);
15357
- class AttrStep extends Step {
15358
- static fromJSON(schema, json) {
15359
- if (typeof json.pos != "number" || typeof json.attr != "string") {
15360
- throw new RangeError("Invalid input for AttrStep.fromJSON");
15447
+ _insertPastedContent({ state, input }, slice2) {
15448
+ if (!this._isFullBlockSelected(state)) {
15449
+ return state.tr.replaceSelection(slice2);
15361
15450
  }
15362
- return new AttrStep(json.pos, json.attr, json.value);
15363
- }
15364
- constructor(pos, attr, value) {
15365
- super();
15366
- this.pos = pos;
15367
- this.attr = attr;
15368
- this.value = value;
15451
+ return state.tr.replaceSelectionWith(slice2.content, input.shiftKey);
15369
15452
  }
15370
- apply(doc2) {
15371
- const node = doc2.nodeAt(this.pos);
15372
- if (!node)
15373
- return StepResult.fail("No node at attribute step's position");
15374
- const attrs = /* @__PURE__ */ Object.create(null);
15375
- for (let name in node.attrs)
15376
- attrs[name] = node.attrs[name];
15377
- attrs[this.attr] = this.value;
15378
- const updated = node.type.create(attrs, null, node.marks);
15379
- const slice2 = new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1);
15380
- return StepResult.fromReplace(doc2, this.pos, this.pos + 1, slice2);
15453
+ _isFullBlockSelected(state) {
15454
+ const blocksSelection = this._expandSelectionToBlocks(state);
15455
+ const isFromMatch = this._isMatchPosition(blocksSelection.from, state.selection.from);
15456
+ const isToMatch = this._isMatchPosition(blocksSelection.to, state.selection.to);
15457
+ return isFromMatch && isToMatch;
15381
15458
  }
15382
- getMap() {
15383
- return StepMap.empty;
15459
+ _expandSelectionToBlocks({ selection, doc: doc2 }) {
15460
+ let from2 = selection.from;
15461
+ let to = selection.to;
15462
+ doc2.nodesBetween(from2, to, (node, position, parent) => {
15463
+ if (parent.type.name !== NodeTypes.DOCUMENT)
15464
+ return;
15465
+ from2 = Math.min(from2, position + 1);
15466
+ to = Math.max(to, position + node.nodeSize - 1);
15467
+ });
15468
+ return { from: from2, to };
15384
15469
  }
15385
- invert(doc2) {
15386
- return new AttrStep(this.pos, this.attr, doc2.nodeAt(this.pos).attrs[this.attr]);
15470
+ _isMatchPosition(position1, position2) {
15471
+ return Math.abs(position1 - position2) < 5;
15387
15472
  }
15388
- map(mapping) {
15389
- let pos = mapping.mapResult(this.pos, 1);
15390
- return pos.deletedAfter ? null : new AttrStep(pos.pos, this.attr, this.value);
15473
+ }
15474
+ class PlaceholderPlugin extends ProseMirrorPlugin {
15475
+ constructor() {
15476
+ super(...arguments);
15477
+ __privateAdd(this, _buildDecorations);
15391
15478
  }
15392
- toJSON() {
15393
- return { stepType: "attr", pos: this.pos, attr: this.attr, value: this.value };
15479
+ buildProps() {
15480
+ return { decorations: __privateMethod(this, _buildDecorations, buildDecorations_fn).bind(this) };
15394
15481
  }
15395
15482
  }
15396
- Step.jsonID("attr", AttrStep);
15397
- const NodeProcessor = Extension.create({
15398
- name: "node_processor",
15399
- addCommands() {
15400
- return {
15401
- setBlockAttributes: createCommand(({ commands: commands2, state }, name, attrs, defaults2 = {}) => {
15402
- var _a;
15403
- const current = (_a = unref(commands2.getBlockAttributes(name))) != null ? _a : {};
15404
- const { doc: doc2, tr } = state;
15405
- const { from: from2, to } = tr.selection;
15406
- doc2.nodesBetween(from2, to, (node, position) => {
15407
- if (!NodeTypes.blocks.includes(node.type.name))
15408
- return;
15409
- tr.step(new AttrStep(position, name, { ...defaults2, ...current, ...attrs }));
15410
- });
15411
- }),
15412
- getBlockAttributes: createCommand(({ editor }, name, defaults2) => computed(() => {
15413
- var _a;
15414
- let attrs = Object.assign({}, defaults2 || {});
15415
- for (const type of NodeTypes.blocks) {
15416
- Object.assign(attrs, ((_a = editor.getAttributes(type)) == null ? void 0 : _a[name]) || {});
15417
- }
15418
- return Object.keys(attrs).length ? attrs : null;
15419
- })),
15420
- removeBlockAttributes: createCommand(({ commands: commands2 }, names) => {
15421
- for (const type of NodeTypes.blocks) {
15422
- commands2.resetAttributes(type, names);
15423
- }
15424
- }),
15425
- applyMark: createCommand(({ state, commands: commands2 }, name, value, customizer = {}) => {
15426
- const { tr, doc: doc2, schema } = state;
15427
- const { $from, $to } = tr.selection;
15428
- const markType = getMarkType(name, schema);
15429
- const markGroup = markType.spec.group || "";
15430
- if (!markGroup.includes(MarkGroups.SETTINGS)) {
15431
- return commands2.setMark(name, value);
15432
- }
15433
- if ($from.pos === $to.pos)
15434
- return;
15435
- const onAppliedToParent = (context) => {
15436
- if (!customizer.onAppliedToParent || customizer.onAppliedToParent(context) === false) {
15437
- const { tr: tr2, node, position, mark } = context;
15438
- commands2._removeNodeMark({ tr: tr2, node, position, mark: mark.type });
15439
- }
15440
- };
15441
- doc2.nodesBetween($from.pos, $to.pos, (node, position) => {
15442
- if (node.type.name === NodeTypes.LIST)
15443
- return;
15444
- const initialMark = findMarkByType(node.marks, name);
15445
- const applyingMark = markType.create({ ...(initialMark == null ? void 0 : initialMark.attrs) || {}, ...value });
15446
- const textPosition = resolveTextPosition($from, $to, node, position);
15447
- if (isMarkAppliedToParent(tr.doc, position, applyingMark, customizer.isAppliedToParent)) {
15448
- return onAppliedToParent({ tr, node, position, mark: applyingMark });
15449
- }
15450
- if (node.isText) {
15451
- tr.addMark(textPosition.from, textPosition.to, applyingMark);
15452
- return;
15453
- }
15454
- if (isNodeFullySelected(tr.doc, tr.selection, node, position)) {
15455
- tr.step(new AddNodeMarkStep(position, applyingMark));
15456
- }
15457
- });
15458
- }),
15459
- getMarks: createCommand(({ editor }, name) => {
15460
- const stateRef = toRef(editor, "state");
15461
- return computed(() => {
15462
- const { selection, doc: doc2 } = unref(stateRef);
15463
- const { from: from2, to } = unref(selection);
15464
- const marks = [];
15465
- doc2.nodesBetween(from2, to, (node) => {
15466
- for (const mark of node.marks) {
15467
- if (mark.type.name === name)
15468
- marks.unshift(mark.attrs);
15469
- }
15470
- });
15471
- return marks;
15472
- });
15473
- }),
15474
- getMark: createCommand(({ commands: commands2 }, name) => {
15475
- const marksRef = commands2.getMarks(name);
15476
- return computed(() => {
15477
- var _a;
15478
- return (_a = unref(marksRef)[0]) != null ? _a : null;
15479
- });
15480
- }),
15481
- hasMark: createCommand(({ commands: commands2 }, name) => {
15482
- const mark = commands2.getMark(name);
15483
- return computed(() => !!unref(mark));
15484
- }),
15485
- getCommonSettingMark: createCommand(({ commands: commands2 }, name, defaultRef) => {
15486
- const selectionRef = commands2.getMark(name);
15487
- return computed(() => {
15488
- var _a, _b;
15489
- return (_b = (_a = unref(selectionRef)) == null ? void 0 : _a.value) != null ? _b : unref(defaultRef);
15490
- });
15491
- }),
15492
- getDeviceSettingMark: createCommand(({ commands: commands2 }, name, defaultRef) => {
15493
- const selectionRef = commands2.getMarks(name);
15494
- const deviceRef = commands2.getDevice();
15495
- return computed(() => {
15496
- for (const attrs of unref(selectionRef)) {
15497
- const value = attrs[unref(deviceRef)];
15498
- if (value)
15499
- return value;
15500
- }
15501
- return unref(defaultRef);
15502
- });
15503
- }),
15504
- removeAllMarks: createCommand(({ state, commands: commands2 }) => {
15505
- const { tr, doc: doc2 } = state;
15506
- const { from: from2, to } = tr.selection;
15507
- doc2.nodesBetween(from2, to, (node, position) => {
15508
- for (const mark of node.marks) {
15509
- commands2._removeNodeMark({ tr, node, position, mark });
15510
- }
15511
- });
15512
- }),
15513
- removeMarks: createCommand(({ state, commands: commands2 }, marks) => {
15514
- const { tr, doc: doc2 } = state;
15515
- const { from: from2, to } = tr.selection;
15516
- doc2.nodesBetween(from2, to, (node, position) => {
15517
- const removingMarks = node.marks.filter((mark) => marks.includes(mark.type.name));
15518
- for (const mark of removingMarks) {
15519
- commands2._removeNodeMark({ tr, node, position, mark });
15520
- }
15521
- });
15522
- }),
15523
- _removeNodeMark: createCommand((context, { tr, node, position, mark }) => {
15524
- return node.isText ? tr.removeMark(position, position + node.nodeSize, mark) : tr.step(new RemoveNodeMarkStep(position, mark));
15525
- })
15526
- };
15527
- }
15528
- });
15529
- const TextProcessor = Extension.create({
15530
- name: "text_processor",
15531
- addCommands() {
15532
- return {
15533
- getSelectedText: createCommand(({ state }) => {
15534
- const { from: from2, to } = state.selection;
15535
- return state.doc.textBetween(from2, to, " ");
15536
- }),
15537
- transformText: createCommand(({ state }, transform) => {
15538
- const { $from, $to } = state.tr.selection;
15539
- if ($from.pos === $to.pos)
15540
- return;
15541
- state.doc.nodesBetween($from.pos, $to.pos, (node, position) => {
15542
- if (!node.isText)
15543
- return;
15544
- const textPosition = resolveTextPosition($from, $to, node, position);
15545
- const substringFrom = Math.max(0, $from.pos - position);
15546
- const substringTo = Math.max(0, $to.pos - position);
15547
- const updatedText = transform({
15548
- text: node.textContent.substring(substringFrom, substringTo)
15549
- });
15550
- const updatedNode = state.schema.text(updatedText, node.marks);
15551
- state.tr.replaceWith(textPosition.from, textPosition.to, updatedNode);
15552
- });
15553
- })
15554
- };
15483
+ _buildDecorations = new WeakSet();
15484
+ buildDecorations_fn = function({ doc: doc2 }) {
15485
+ const decorations = [];
15486
+ if (!this.editor.isEditable)
15487
+ return null;
15488
+ if (doc2.childCount > 1)
15489
+ return;
15490
+ doc2.descendants((node, pos) => {
15491
+ if (!node.childCount) {
15492
+ const decoration = Decoration.node(pos, pos + node.nodeSize, {
15493
+ class: "zw-wysiwyg__placeholder",
15494
+ "data-placeholder": "Type your text here..."
15495
+ });
15496
+ decorations.push(decoration);
15497
+ }
15498
+ return false;
15499
+ });
15500
+ return DecorationSet.create(doc2, decorations);
15501
+ };
15502
+ const ProseMirrorPlugins = Extension.create({
15503
+ name: "prose_mirror_plugins",
15504
+ addProseMirrorPlugins() {
15505
+ return [
15506
+ PastePlugin.create(this.editor),
15507
+ PlaceholderPlugin.create(this.editor)
15508
+ ];
15555
15509
  }
15556
15510
  });
15557
- const SelectionProcessor = Extension.create({
15558
- name: "selection_processor",
15559
- addStorage: () => ({
15560
- selection: null
15511
+ const buildCoreExtensions = () => [
15512
+ Document,
15513
+ Paragraph,
15514
+ Heading,
15515
+ Text$1,
15516
+ History,
15517
+ NodeProcessor,
15518
+ TextProcessor,
15519
+ SelectionProcessor,
15520
+ ProseMirrorPlugins
15521
+ ];
15522
+ const FontFamily = Mark.create({
15523
+ name: TextSettings.FONT_FAMILY,
15524
+ group: MarkGroups.SETTINGS,
15525
+ addOptions: () => ({
15526
+ fonts: []
15527
+ }),
15528
+ addAttributes: () => ({
15529
+ value: { required: true }
15561
15530
  }),
15562
15531
  addCommands() {
15563
15532
  return {
15564
- storeSelection: createCommand(({ state }) => {
15565
- this.storage.selection = state.selection;
15533
+ applyFontFamily: createCommand(({ commands: commands2 }, value) => {
15534
+ commands2.applyMark(this.name, { value });
15535
+ const font = commands2.findFontByName(value);
15536
+ let fontWeight = unref(commands2.getFontWeight());
15537
+ if (!font.isWeightSupported(fontWeight)) {
15538
+ fontWeight = font.findClosestWeight(fontWeight);
15539
+ commands2.applyFontWeight(fontWeight);
15540
+ }
15541
+ if (!font.isItalicSupported(fontWeight)) {
15542
+ commands2.removeItalic();
15543
+ }
15566
15544
  }),
15567
- restoreSelection: createCommand(({ commands: commands2 }) => {
15568
- this.storage.selection && commands2.setTextSelection(this.storage.selection);
15545
+ getFont: createCommand(({ commands: commands2 }) => {
15546
+ const defaultPreset = unref(this.options.defaultPreset);
15547
+ const defaultFont = commands2.findFontByName(defaultPreset.common.font_family);
15548
+ const fontFamily = commands2.getFontFamily();
15549
+ return computed(() => commands2.findFontByName(unref(fontFamily)) || defaultFont);
15569
15550
  }),
15570
- expandSelection: createCommand(({ tr, commands: commands2 }, predicate) => {
15571
- let from2 = tr.selection.from;
15572
- let to = tr.selection.to;
15573
- tr.doc.nodesBetween(from2, to, (node, position, parent) => {
15574
- if (predicate({ node, parent })) {
15575
- const offset2 = node.isText ? 0 : resolvePositionOffset(tr.doc, position);
15576
- from2 = Math.min(from2, position + offset2);
15577
- to = Math.max(to, position + node.nodeSize - offset2);
15578
- }
15579
- });
15580
- commands2.setTextSelection({ from: from2, to });
15551
+ findFontByName: createCommand((_, name) => {
15552
+ return this.options.fonts.find((font) => font.name === name);
15581
15553
  }),
15582
- expandSelectionToBlock: createCommand(({ commands: commands2 }) => {
15583
- commands2.expandSelection(({ parent }) => parent.type.name === NodeTypes.DOCUMENT);
15554
+ getFontFamily: createCommand(({ commands: commands2 }) => {
15555
+ return commands2.getCommonSettingMark(this.name, commands2.getDefaultFontFamily());
15556
+ }),
15557
+ getDefaultFontFamily: createCommand(({ commands: commands2 }) => {
15558
+ const preset = commands2.getPreset();
15559
+ return computed(() => unref(preset).common.font_family);
15584
15560
  })
15585
15561
  };
15586
- }
15587
- });
15588
- const Document$1 = Node.create({
15589
- name: "doc",
15590
- topNode: true,
15591
- content: "block+"
15592
- });
15593
- const Document = Document$1.extend({
15594
- marks: MarkGroups.SETTINGS
15595
- });
15596
- const Paragraph$1 = Node.create({
15597
- name: "paragraph",
15598
- priority: 1e3,
15599
- addOptions() {
15600
- return {
15601
- HTMLAttributes: {}
15602
- };
15603
15562
  },
15604
- group: "block",
15605
- content: "inline*",
15606
15563
  parseHTML() {
15564
+ const getAttrs = (input) => ({ value: input.replace(/["']/g, "") });
15607
15565
  return [
15608
- { tag: "p" }
15609
- ];
15610
- },
15611
- renderHTML({ HTMLAttributes }) {
15612
- return ["p", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
15613
- },
15614
- addCommands() {
15615
- return {
15616
- setParagraph: () => ({ commands: commands2 }) => {
15617
- return commands2.setNode(this.name);
15566
+ {
15567
+ style: "--zw-font-family",
15568
+ getAttrs
15569
+ },
15570
+ {
15571
+ style: "font-family",
15572
+ getAttrs
15618
15573
  }
15619
- };
15574
+ ];
15620
15575
  },
15621
- addKeyboardShortcuts() {
15622
- return {
15623
- "Mod-Alt-0": () => this.editor.commands.setParagraph()
15624
- };
15576
+ renderHTML({ HTMLAttributes: attrs }) {
15577
+ const font_family = attrs.value ? `"${attrs.value}"` : null;
15578
+ return renderMark({ font_family });
15625
15579
  }
15626
15580
  });
15627
- const Paragraph = Paragraph$1.extend({
15628
- marks: MarkGroups.ALL,
15629
- addOptions: () => ({
15630
- HTMLAttributes: { class: "zw-style" }
15631
- })
15632
- });
15633
- const Heading$1 = Node.create({
15634
- name: "heading",
15635
- addOptions() {
15636
- return {
15637
- levels: [1, 2, 3, 4, 5, 6],
15638
- HTMLAttributes: {}
15639
- };
15581
+ const StylePreset = Extension.create({
15582
+ name: TextSettings.STYLE_PRESET,
15583
+ addGlobalAttributes() {
15584
+ return [
15585
+ {
15586
+ types: [NodeTypes.PARAGRAPH, NodeTypes.HEADING],
15587
+ attributes: {
15588
+ preset: {
15589
+ isRequired: false,
15590
+ default: { id: this.options.defaultId },
15591
+ parseHTML: (element) => {
15592
+ const presets = unref(this.options.presets);
15593
+ if (element.parentElement.tagName === "LI")
15594
+ return null;
15595
+ for (const { id: id2, node, fallbackClass } of presets) {
15596
+ if (fallbackClass && element.classList.contains(fallbackClass)) {
15597
+ return { id: id2 };
15598
+ }
15599
+ const presetSelector = this.options.styleRenderer.makePresetCssClass({ id: id2 });
15600
+ if (element.matches(presetSelector))
15601
+ return { id: id2 };
15602
+ if (element.tagName === `H${node == null ? void 0 : node.level}`)
15603
+ return { id: id2 };
15604
+ }
15605
+ return element.tagName === "P" ? { id: this.options.defaultId } : null;
15606
+ },
15607
+ renderHTML: (attrs) => {
15608
+ if (!attrs.preset)
15609
+ return null;
15610
+ return { class: this.options.styleRenderer.makePresetHtmlClass(attrs.preset) };
15611
+ }
15612
+ }
15613
+ }
15614
+ }
15615
+ ];
15640
15616
  },
15641
- content: "inline*",
15642
- group: "block",
15643
- defining: true,
15644
- addAttributes() {
15645
- return {
15646
- level: {
15647
- default: 1,
15648
- rendered: false
15617
+ addCommands() {
15618
+ function findPresetById(presets, id2) {
15619
+ return presets.find((preset) => id2 === preset.id);
15620
+ }
15621
+ function mergeSettings(source, target) {
15622
+ const settings = {};
15623
+ for (const name of Object.keys(source)) {
15624
+ const sourceValue = source[name];
15625
+ const targetValue = target[name];
15626
+ const isInherit = !targetValue || targetValue.toLowerCase() === "inherit";
15627
+ settings[name] = isInherit ? sourceValue : targetValue;
15649
15628
  }
15629
+ return settings;
15630
+ }
15631
+ return {
15632
+ getPresetList: createCommand(() => computed(() => {
15633
+ return this.options.presets.filter((preset) => !preset.hidden);
15634
+ })),
15635
+ getPreset: createCommand(({ commands: commands2 }) => {
15636
+ const selectionRef = commands2.getBlockAttributes("preset", { id: this.options.defaultId });
15637
+ const presetsRef = commands2.getPresetList();
15638
+ const isLinkRef = commands2.isLink();
15639
+ const linkPresetRef = commands2.getLinkPreset();
15640
+ return computed(() => {
15641
+ const preset = findPresetById(unref(presetsRef), unref(selectionRef).id);
15642
+ if (!unref(isLinkRef))
15643
+ return preset;
15644
+ const linkPreset = unref(linkPresetRef);
15645
+ return {
15646
+ id: preset.id,
15647
+ common: mergeSettings(preset.common, linkPreset.common),
15648
+ mobile: mergeSettings(preset.mobile, linkPreset.mobile),
15649
+ tablet: mergeSettings(preset.tablet, linkPreset.tablet),
15650
+ desktop: mergeSettings(preset.desktop, linkPreset.desktop)
15651
+ };
15652
+ });
15653
+ }),
15654
+ applyPreset: createCommand(({ commands: commands2, chain }, presetId) => {
15655
+ var _a, _b;
15656
+ const presets = unref(commands2.getPresetList());
15657
+ const preset = findPresetById(presets, presetId);
15658
+ const nodeType = (_b = (_a = preset.node) == null ? void 0 : _a.type) != null ? _b : NodeTypes.PARAGRAPH;
15659
+ const attrs = {
15660
+ preset: { id: presetId }
15661
+ };
15662
+ if (preset.node) {
15663
+ attrs.level = preset.node.level;
15664
+ }
15665
+ for (const textAttribute of TextSettings.attributes) {
15666
+ attrs[textAttribute] = unref(commands2.getBlockAttributes(textAttribute));
15667
+ }
15668
+ chain().removeList().setNode(nodeType, attrs).run();
15669
+ }),
15670
+ applyDefaultPreset: createCommand(({ commands: commands2 }) => {
15671
+ commands2.applyPreset(this.options.defaultId);
15672
+ }),
15673
+ removePreset: createCommand(({ commands: commands2 }) => {
15674
+ commands2.setNode(NodeTypes.PARAGRAPH, { preset: null });
15675
+ }),
15676
+ getPresetCustomization: createCommand(({ editor, commands: commands2 }) => {
15677
+ const state = toRef(editor, "state");
15678
+ return computed(() => {
15679
+ const { selection, doc: doc2 } = unref(state);
15680
+ const { from: from2, to } = selection;
15681
+ return commands2._getSettingCustomization(doc2, from2, to);
15682
+ });
15683
+ }),
15684
+ isSettingCustomized: createCommand(({ commands: commands2 }, name) => {
15685
+ const customization = commands2.getPresetCustomization();
15686
+ const group = TextSettings.attributes.includes(name) ? "attributes" : "marks";
15687
+ return computed(() => {
15688
+ var _a, _b;
15689
+ return (_b = (_a = unref(customization)[group]) == null ? void 0 : _a.includes(name)) != null ? _b : false;
15690
+ });
15691
+ }),
15692
+ getContentCustomization: createCommand(({ editor, commands: commands2 }) => {
15693
+ const state = toRef(editor, "state");
15694
+ return computed(() => {
15695
+ const { doc: doc2 } = unref(state);
15696
+ return commands2._getSettingCustomization(doc2, 0, doc2.content.size);
15697
+ });
15698
+ }),
15699
+ _getSettingCustomization: createCommand((_, doc2, from2, to) => {
15700
+ const marks = /* @__PURE__ */ new Set();
15701
+ const attributes = /* @__PURE__ */ new Set();
15702
+ doc2.nodesBetween(from2, to, (node) => {
15703
+ for (const [name, value] of Object.entries(node.attrs)) {
15704
+ const isSetting = TextSettings.attributes.includes(name);
15705
+ if (isSetting && value)
15706
+ attributes.add(name);
15707
+ }
15708
+ for (const { type } of node.marks) {
15709
+ if (TextSettings.marks.includes(type.name)) {
15710
+ marks.add(type.name);
15711
+ }
15712
+ }
15713
+ });
15714
+ return {
15715
+ attributes: Array.from(attributes),
15716
+ marks: Array.from(marks)
15717
+ };
15718
+ }),
15719
+ removePresetCustomization: createCommand(({ chain }) => {
15720
+ chain().storeSelection().expandSelectionToBlock().removeMarks(TextSettings.marks).resetAttributes(NodeTypes.PARAGRAPH, TextSettings.attributes).resetAttributes(NodeTypes.HEADING, TextSettings.attributes).restoreSelection().run();
15721
+ }),
15722
+ removeFormat: createCommand(({ chain }) => {
15723
+ chain().storeSelection().expandSelectionToBlock().removeAllMarks().applyDefaultPreset().restoreSelection().run();
15724
+ })
15650
15725
  };
15651
15726
  },
15652
- parseHTML() {
15653
- return this.options.levels.map((level) => ({
15654
- tag: `h${level}`,
15655
- attrs: { level }
15656
- }));
15657
- },
15658
- renderHTML({ node, HTMLAttributes }) {
15659
- const hasLevel = this.options.levels.includes(node.attrs.level);
15660
- const level = hasLevel ? node.attrs.level : this.options.levels[0];
15661
- return [`h${level}`, mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
15662
- },
15727
+ onCreate() {
15728
+ this.options.styleRenderer.inject(ContextWindow.head, this.options.presets);
15729
+ }
15730
+ });
15731
+ const FontWeight = Mark.create({
15732
+ name: TextSettings.FONT_WEIGHT,
15733
+ group: MarkGroups.SETTINGS,
15734
+ addAttributes: () => ({
15735
+ value: { required: true }
15736
+ }),
15663
15737
  addCommands() {
15664
15738
  return {
15665
- setHeading: (attributes) => ({ commands: commands2 }) => {
15666
- if (!this.options.levels.includes(attributes.level)) {
15667
- return false;
15668
- }
15669
- return commands2.setNode(this.name, attributes);
15670
- },
15671
- toggleHeading: (attributes) => ({ commands: commands2 }) => {
15672
- if (!this.options.levels.includes(attributes.level)) {
15673
- return false;
15739
+ applyFontWeight: createCommand(({ commands: commands2 }, value) => {
15740
+ commands2.applyMark(this.name, { value });
15741
+ const font = unref(commands2.getFont());
15742
+ if (!font.isItalicSupported(value)) {
15743
+ commands2.removeItalic();
15674
15744
  }
15675
- return commands2.toggleNode(this.name, "paragraph", attributes);
15676
- }
15745
+ }),
15746
+ toggleBold: createCommand(({ commands: commands2 }) => {
15747
+ const currentWeight = unref(commands2.getFontWeight());
15748
+ const currentFont = unref(commands2.getFont());
15749
+ const isBold = Number(currentWeight) >= 600;
15750
+ const wantedWeight = isBold ? "400" : "700";
15751
+ const nextWeight = currentFont.findClosestWeight(wantedWeight);
15752
+ commands2.applyFontWeight(nextWeight);
15753
+ }),
15754
+ getFontWeight: createCommand(({ commands: commands2 }) => {
15755
+ const selectionRef = commands2.getCommonSettingMark(this.name, commands2.getDefaultFontWeight());
15756
+ const fontRef = commands2.getFont();
15757
+ return computed(() => {
15758
+ const weight = unref(selectionRef);
15759
+ const font = unref(fontRef);
15760
+ return font.isWeightSupported(weight) ? weight : font.findClosestWeight(weight);
15761
+ });
15762
+ }),
15763
+ getDefaultFontWeight: createCommand(({ commands: commands2 }) => {
15764
+ const preset = commands2.getPreset();
15765
+ return computed(() => unref(preset).common.font_weight);
15766
+ })
15677
15767
  };
15678
15768
  },
15679
- addKeyboardShortcuts() {
15680
- return this.options.levels.reduce((items, level) => ({
15681
- ...items,
15682
- ...{
15683
- [`Mod-Alt-${level}`]: () => this.editor.commands.toggleHeading({ level })
15684
- }
15685
- }), {});
15686
- },
15687
- addInputRules() {
15688
- return this.options.levels.map((level) => {
15689
- return textblockTypeInputRule({
15690
- find: new RegExp(`^(#{1,${level}})\\s$`),
15691
- type: this.type,
15692
- getAttributes: {
15693
- level
15694
- }
15695
- });
15696
- });
15697
- }
15698
- });
15699
- const Heading = Heading$1.extend({
15700
- marks: MarkGroups.ALL,
15701
- addOptions: () => ({
15702
- levels: [1, 2, 3, 4],
15703
- HTMLAttributes: { class: "zw-style" }
15704
- })
15705
- });
15706
- class ProseMirrorPlugin {
15707
- static create(editor, options) {
15708
- const plugin = new this(editor, options || {});
15709
- return new Plugin({
15710
- key: new PluginKey(this.name),
15711
- props: plugin.buildProps()
15712
- });
15713
- }
15714
- constructor(editor, options) {
15715
- this.options = options;
15716
- this.editor = editor;
15717
- }
15718
- buildProps() {
15719
- return {};
15720
- }
15721
- }
15722
- class PastePlugin extends ProseMirrorPlugin {
15723
- buildProps() {
15724
- return {
15725
- transformPastedHTML: this._transformPastedHTML.bind(this),
15726
- handlePaste: this._handlePaste.bind(this)
15769
+ addKeyboardShortcuts: () => ({
15770
+ "Mod-b": createKeyboardShortcut("toggleBold"),
15771
+ "Mod-B": createKeyboardShortcut("toggleBold")
15772
+ }),
15773
+ parseHTML() {
15774
+ const getAttrs = (value) => {
15775
+ if (value === "bold")
15776
+ return { value: "700" };
15777
+ return Number(value) ? { value } : false;
15727
15778
  };
15728
- }
15729
- _transformPastedHTML(html2) {
15730
- if (html2.includes("data-pm-slice") && html2.includes("zw-style")) {
15731
- return html2;
15732
- }
15733
- const normalizer = ContentNormalizer.build(html2);
15734
- normalizer.normalizeHTML();
15735
- this._removeDeprecatedStyles(normalizer);
15736
- return normalizer.normalizedHTML;
15737
- }
15738
- _removeDeprecatedStyles(normalizer) {
15739
- const elements = normalizer.dom.querySelectorAll('[style*="margin"]');
15740
- for (const element of Array.from(elements)) {
15741
- element.style.removeProperty("margin");
15742
- element.style.removeProperty("margin-top");
15743
- element.style.removeProperty("margin-right");
15744
- element.style.removeProperty("margin-bottom");
15745
- element.style.removeProperty("margin-left");
15746
- }
15747
- }
15748
- _handlePaste(view, _, slice2) {
15749
- const transaction = this._insertPastedContent(view, slice2).scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste");
15750
- view.dispatch(transaction);
15751
- return true;
15752
- }
15753
- _insertPastedContent({ state, input }, slice2) {
15754
- if (!this._isFullBlockSelected(state)) {
15755
- return state.tr.replaceSelection(slice2);
15756
- }
15757
- return state.tr.replaceSelectionWith(slice2.content, input.shiftKey);
15758
- }
15759
- _isFullBlockSelected(state) {
15760
- const blocksSelection = this._expandSelectionToBlocks(state);
15761
- const isFromMatch = this._isMatchPosition(blocksSelection.from, state.selection.from);
15762
- const isToMatch = this._isMatchPosition(blocksSelection.to, state.selection.to);
15763
- return isFromMatch && isToMatch;
15764
- }
15765
- _expandSelectionToBlocks({ selection, doc: doc2 }) {
15766
- let from2 = selection.from;
15767
- let to = selection.to;
15768
- doc2.nodesBetween(from2, to, (node, position, parent) => {
15769
- if (parent.type.name !== NodeTypes.DOCUMENT)
15770
- return;
15771
- from2 = Math.min(from2, position + 1);
15772
- to = Math.max(to, position + node.nodeSize - 1);
15773
- });
15774
- return { from: from2, to };
15775
- }
15776
- _isMatchPosition(position1, position2) {
15777
- return Math.abs(position1 - position2) < 5;
15778
- }
15779
- }
15780
- class PlaceholderPlugin extends ProseMirrorPlugin {
15781
- constructor() {
15782
- super(...arguments);
15783
- __privateAdd(this, _buildDecorations);
15784
- }
15785
- buildProps() {
15786
- return { decorations: __privateMethod(this, _buildDecorations, buildDecorations_fn).bind(this) };
15787
- }
15788
- }
15789
- _buildDecorations = new WeakSet();
15790
- buildDecorations_fn = function({ doc: doc2 }) {
15791
- const decorations = [];
15792
- if (!this.editor.isEditable)
15793
- return null;
15794
- if (doc2.childCount > 1)
15795
- return;
15796
- doc2.descendants((node, pos) => {
15797
- if (!node.childCount) {
15798
- const decoration = Decoration.node(pos, pos + node.nodeSize, {
15799
- class: "zw-wysiwyg__placeholder",
15800
- "data-placeholder": "Type your text here..."
15801
- });
15802
- decorations.push(decoration);
15803
- }
15804
- return false;
15805
- });
15806
- return DecorationSet.create(doc2, decorations);
15807
- };
15808
- const ProseMirrorPlugins = Extension.create({
15809
- name: "prose_mirror_plugins",
15810
- addProseMirrorPlugins() {
15811
15779
  return [
15812
- PastePlugin.create(this.editor),
15813
- PlaceholderPlugin.create(this.editor)
15780
+ {
15781
+ style: "--zw-font-weight",
15782
+ getAttrs
15783
+ },
15784
+ {
15785
+ style: "font-weight",
15786
+ getAttrs
15787
+ },
15788
+ {
15789
+ tag: "b",
15790
+ attrs: { value: "700" }
15791
+ },
15792
+ {
15793
+ tag: "strong",
15794
+ attrs: { value: "700" }
15795
+ }
15814
15796
  ];
15797
+ },
15798
+ renderHTML({ HTMLAttributes: attrs }) {
15799
+ return renderMark({ font_weight: attrs.value });
15815
15800
  }
15816
15801
  });
15817
- const buildCoreExtensions = () => [
15818
- Document,
15819
- Paragraph,
15820
- Heading,
15821
- Text$1,
15822
- History,
15823
- NodeProcessor,
15824
- TextProcessor,
15825
- SelectionProcessor,
15826
- ProseMirrorPlugins
15827
- ];
15828
15802
  const FontSize = Mark.create({
15829
15803
  name: TextSettings.FONT_SIZE,
15830
15804
  group: MarkGroups.SETTINGS,
@@ -16231,9 +16205,9 @@ const Alignment = Extension.create({
16231
16205
  if (textAlign) {
16232
16206
  return { desktop: textAlign, tablet: textAlign, mobile: textAlign };
16233
16207
  }
16234
- const mobile = style2.getPropertyValue("--zw-text-align-mobile") || null;
16235
- const tablet = style2.getPropertyValue("--zw-text-align-tablet") || null;
16236
- const desktop = style2.getPropertyValue("--zw-text-align-desktop") || null;
16208
+ const mobile = style2.getPropertyValue("--zw-alignment-mobile") || null;
16209
+ const tablet = style2.getPropertyValue("--zw-alignment-tablet") || null;
16210
+ const desktop = style2.getPropertyValue("--zw-alignment-desktop") || null;
16237
16211
  if (!mobile && !tablet && !desktop)
16238
16212
  return null;
16239
16213
  return { desktop, tablet, mobile };
@@ -16242,9 +16216,9 @@ const Alignment = Extension.create({
16242
16216
  if (!attrs.alignment)
16243
16217
  return null;
16244
16218
  return renderInlineSetting({
16245
- text_align_mobile: attrs.alignment.mobile,
16246
- text_align_tablet: attrs.alignment.tablet,
16247
- text_align_desktop: attrs.alignment.desktop
16219
+ alignment_mobile: attrs.alignment.mobile,
16220
+ alignment_tablet: attrs.alignment.tablet,
16221
+ alignment_desktop: attrs.alignment.desktop
16248
16222
  });
16249
16223
  }
16250
16224
  }
@@ -17675,8 +17649,11 @@ function buildExtensions(options) {
17675
17649
  StylePreset.configure({
17676
17650
  presets: options.presetsRef,
17677
17651
  defaultId: options.defaultPresetId,
17678
- baseClass: options.basePresetClass,
17679
- makeVariable: options.makePresetVariable
17652
+ styleRenderer: new StylePresetRenderer({
17653
+ baseClass: options.basePresetClass,
17654
+ makeVariable: options.makePresetVariable,
17655
+ linkPresetId: options.linkPresetId
17656
+ })
17680
17657
  }),
17681
17658
  List.configure({
17682
17659
  baseClass: options.baseListClass,
@@ -19162,6 +19139,62 @@ const _HtmlToJsonParser = class {
19162
19139
  };
19163
19140
  let HtmlToJsonParser = _HtmlToJsonParser;
19164
19141
  _contentSerializer = new WeakMap();
19142
+ class StylePresetRenderer {
19143
+ constructor({ baseClass, makeVariable, linkPresetId }) {
19144
+ __privateAdd(this, _makeInternalVariableName);
19145
+ __privateAdd(this, _baseClass, void 0);
19146
+ __privateAdd(this, _makeVariable, void 0);
19147
+ __privateAdd(this, _linkPresetId, void 0);
19148
+ __privateSet(this, _baseClass, baseClass);
19149
+ __privateSet(this, _makeVariable, makeVariable);
19150
+ __privateSet(this, _linkPresetId, linkPresetId);
19151
+ }
19152
+ inject(hostEl, presets) {
19153
+ let styleEl = hostEl.querySelector("[data-zw-styles]");
19154
+ if (styleEl)
19155
+ return;
19156
+ styleEl = ContextWindow.document.createElement("style");
19157
+ styleEl.dataset.zwStyles = "";
19158
+ styleEl.innerHTML = this.render(presets);
19159
+ hostEl.append(styleEl);
19160
+ }
19161
+ render(presets) {
19162
+ let css = "";
19163
+ for (const preset of presets) {
19164
+ const isLink = preset.id === __privateGet(this, _linkPresetId);
19165
+ const className = this.makePresetCssClass(preset);
19166
+ css += ` ${className} {`;
19167
+ for (const device of Devices.values) {
19168
+ for (const setting of Object.keys(preset[device])) {
19169
+ const variable = __privateGet(this, _makeVariable).call(this, { device, preset, property: setting });
19170
+ const internalVariable = __privateMethod(this, _makeInternalVariableName, makeInternalVariableName_fn).call(this, setting, device);
19171
+ css += `${internalVariable}: var(${variable}, inherit);`;
19172
+ if (isLink) {
19173
+ const overrideVariable = internalVariable.replace("preset-", "");
19174
+ css += `${overrideVariable}: var(${internalVariable});`;
19175
+ }
19176
+ }
19177
+ }
19178
+ css += "}";
19179
+ }
19180
+ return css;
19181
+ }
19182
+ makePresetHtmlClass(preset) {
19183
+ return __privateGet(this, _baseClass) + preset.id;
19184
+ }
19185
+ makePresetCssClass(preset) {
19186
+ return this.makePresetHtmlClass(preset).split(" ").map((part) => `.${part}`).join("");
19187
+ }
19188
+ }
19189
+ _baseClass = new WeakMap();
19190
+ _makeVariable = new WeakMap();
19191
+ _linkPresetId = new WeakMap();
19192
+ _makeInternalVariableName = new WeakSet();
19193
+ makeInternalVariableName_fn = function(setting, device) {
19194
+ const property = setting === "color" ? "font-color" : setting.replace(/_/i, "-");
19195
+ const prefix = device === Devices.COMMON ? "" : `-${device}`;
19196
+ return `--zw-preset-${property}${prefix}`;
19197
+ };
19165
19198
  function convertFontSize(value, wrapperEl) {
19166
19199
  if (!value.includes("em"))
19167
19200
  return parseInt(value);
@@ -25008,7 +25041,7 @@ var __component__$v = /* @__PURE__ */ normalizeComponent(
25008
25041
  staticRenderFns$v,
25009
25042
  false,
25010
25043
  __vue2_injectStyles$v,
25011
- "eeca926a",
25044
+ "bb5c4efe",
25012
25045
  null,
25013
25046
  null
25014
25047
  );
@@ -25642,7 +25675,7 @@ var __component__$o = /* @__PURE__ */ normalizeComponent(
25642
25675
  staticRenderFns$o,
25643
25676
  false,
25644
25677
  __vue2_injectStyles$o,
25645
- "3739e310",
25678
+ "1f333e30",
25646
25679
  null,
25647
25680
  null
25648
25681
  );
@@ -27874,7 +27907,7 @@ var render = function __render__45() {
27874
27907
  })], 1);
27875
27908
  };
27876
27909
  var staticRenderFns = [];
27877
- const main_css_vue_type_style_index_0_from__2FUsers_2Fmaster_2Fprojects_2FZipifyWysiwyg_2Flib_2FWysiwyg_vue_src_lang = "";
27910
+ const main_css_vue_type_style_index_0_from__2FUsers_2Fmaster_2FProjects_2FZipifyWysiwyg_2Flib_2FWysiwyg_vue_src_lang = "";
27878
27911
  const MIN_FONT_SIZE = 5;
27879
27912
  const MAX_FONT_SIZE = 112;
27880
27913
  const __vue2_script = {