@bagelink/vue 1.2.13 → 1.2.15
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/components/form/FieldArray.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/components/EditorToolbar.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/components/gridBox.vue.d.ts +6 -3
- package/dist/components/form/inputs/RichText/components/gridBox.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/composables/useCommands.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/config.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/utils/commands.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/utils/formatting.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/utils/table.d.ts.map +1 -1
- package/dist/index.cjs +355 -56
- package/dist/index.mjs +355 -56
- package/dist/style.css +3 -3
- package/package.json +1 -1
- package/src/components/form/FieldArray.vue +1 -1
- package/src/components/form/inputs/RichText/components/EditorToolbar.vue +3 -4
- package/src/components/form/inputs/RichText/components/gridBox.vue +4 -1
- package/src/components/form/inputs/RichText/composables/useCommands.ts +22 -3
- package/src/components/form/inputs/RichText/config.ts +9 -7
- package/src/components/form/inputs/RichText/utils/commands.ts +307 -23
- package/src/components/form/inputs/RichText/utils/formatting.ts +117 -17
- package/src/components/form/inputs/RichText/utils/table.ts +36 -1
package/dist/index.mjs
CHANGED
|
@@ -16076,14 +16076,13 @@ const _sfc_main$R = /* @__PURE__ */ defineComponent({
|
|
|
16076
16076
|
return resolvedSchemaData.value.length > 2 || resolvedSchemaData.value.some((schema) => schema.$el === "richtext");
|
|
16077
16077
|
});
|
|
16078
16078
|
return (_ctx, _cache) => {
|
|
16079
|
-
const _component_Icon = resolveComponent("Icon");
|
|
16080
16079
|
return openBlock(), createElementBlock("div", {
|
|
16081
16080
|
class: normalizeClass(props2.class)
|
|
16082
16081
|
}, [
|
|
16083
16082
|
_ctx.label ? (openBlock(), createElementBlock("p", _hoisted_1$K, toDisplayString(_ctx.label), 1)) : createCommentVNode("", true),
|
|
16084
16083
|
createElementVNode("div", _hoisted_2$x, [
|
|
16085
16084
|
schemaState.value !== "loaded" ? (openBlock(), createElementBlock("div", _hoisted_3$t, [
|
|
16086
|
-
schemaState.value === "loading" ? (openBlock(), createBlock(unref(Loading), { key: 0 })) : schemaState.value === "error" ? (openBlock(), createBlock(
|
|
16085
|
+
schemaState.value === "loading" ? (openBlock(), createBlock(unref(Loading), { key: 0 })) : schemaState.value === "error" ? (openBlock(), createBlock(unref(_sfc_main$s), {
|
|
16087
16086
|
key: 1,
|
|
16088
16087
|
icon: "error",
|
|
16089
16088
|
color: "red"
|
|
@@ -23006,13 +23005,15 @@ const toolbarOptions = [
|
|
|
23006
23005
|
{ name: "fontColor", label: "Font Color", icon: "format_color_text" },
|
|
23007
23006
|
{ name: "bgColor", label: "Background Color", icon: "format_color_fill" },
|
|
23008
23007
|
{ name: "insertTable", label: "Insert Table", icon: "table" },
|
|
23009
|
-
{ name: "deleteTable", label: "Delete Table", icon: "
|
|
23010
|
-
{ name: "
|
|
23011
|
-
{ name: "
|
|
23012
|
-
{ name: "
|
|
23013
|
-
{ name: "
|
|
23014
|
-
{ name: "
|
|
23015
|
-
{ name: "
|
|
23008
|
+
{ name: "deleteTable", label: "Delete Table", icon: "delete_sweep" },
|
|
23009
|
+
{ name: "mergeCells", label: "Merge Cells", icon: "table_chart" },
|
|
23010
|
+
{ name: "splitCells", label: "Split Cells", icon: "dashboard" },
|
|
23011
|
+
{ name: "addRowBefore", label: "Insert Row Above", icon: "add_box" },
|
|
23012
|
+
{ name: "addRowAfter", label: "Insert Row Below", icon: "vertical_align_bottom" },
|
|
23013
|
+
{ name: "deleteRow", label: "Delete Row", icon: "remove" },
|
|
23014
|
+
{ name: "insertColumnLeft", label: "Insert Column Left", icon: "format_indent_decrease" },
|
|
23015
|
+
{ name: "insertColumnRight", label: "Insert Column Right", icon: "format_indent_increase" },
|
|
23016
|
+
{ name: "deleteColumn", label: "Delete Column", icon: "view_week" },
|
|
23016
23017
|
{ name: "separator" },
|
|
23017
23018
|
{ name: "undo", label: "Undo", icon: "undo" },
|
|
23018
23019
|
{ name: "redo", label: "Redo", icon: "redo" },
|
|
@@ -23023,12 +23024,16 @@ const _hoisted_1$u = { class: "grid grid-wrap p-05" };
|
|
|
23023
23024
|
const _hoisted_2$j = ["onMousemove", "onClick"];
|
|
23024
23025
|
const _hoisted_3$g = { class: "txt-center txt-12 color-gray" };
|
|
23025
23026
|
const fb = 1;
|
|
23026
|
-
const base = 5;
|
|
23027
23027
|
const _sfc_main$B = /* @__PURE__ */ defineComponent({
|
|
23028
23028
|
__name: "gridBox",
|
|
23029
|
+
props: {
|
|
23030
|
+
gridSize: {}
|
|
23031
|
+
},
|
|
23029
23032
|
emits: ["select"],
|
|
23030
23033
|
setup(__props, { emit: __emit }) {
|
|
23034
|
+
const props2 = __props;
|
|
23031
23035
|
const emit2 = __emit;
|
|
23036
|
+
const base = props2.gridSize || 5;
|
|
23032
23037
|
const hoveredRow = ref(fb);
|
|
23033
23038
|
const hoveredCol = ref(fb);
|
|
23034
23039
|
const rowSize = computed(() => {
|
|
@@ -23076,7 +23081,7 @@ const _sfc_main$B = /* @__PURE__ */ defineComponent({
|
|
|
23076
23081
|
};
|
|
23077
23082
|
}
|
|
23078
23083
|
});
|
|
23079
|
-
const GridBox = /* @__PURE__ */ _export_sfc(_sfc_main$B, [["__scopeId", "data-v-
|
|
23084
|
+
const GridBox = /* @__PURE__ */ _export_sfc(_sfc_main$B, [["__scopeId", "data-v-2f424c9c"]]);
|
|
23080
23085
|
const _hoisted_1$t = {
|
|
23081
23086
|
class: "toolbar flex gap-025 pb-05 flex-wrap",
|
|
23082
23087
|
role: "toolbar"
|
|
@@ -23109,10 +23114,8 @@ const _sfc_main$A = /* @__PURE__ */ defineComponent({
|
|
|
23109
23114
|
default: withCtx(({ hide }) => [
|
|
23110
23115
|
createVNode(GridBox, {
|
|
23111
23116
|
gridSize: 5,
|
|
23112
|
-
onSelect: (
|
|
23113
|
-
|
|
23114
|
-
runAction("insertTable", $event);
|
|
23115
|
-
(_a = $event.target) == null ? void 0 : _a.blur();
|
|
23117
|
+
onSelect: (value) => {
|
|
23118
|
+
runAction("insertTable", value);
|
|
23116
23119
|
hide();
|
|
23117
23120
|
}
|
|
23118
23121
|
}, null, 8, ["onSelect"])
|
|
@@ -23139,7 +23142,7 @@ const _sfc_main$A = /* @__PURE__ */ defineComponent({
|
|
|
23139
23142
|
};
|
|
23140
23143
|
}
|
|
23141
23144
|
});
|
|
23142
|
-
const EditorToolbar = /* @__PURE__ */ _export_sfc(_sfc_main$A, [["__scopeId", "data-v-
|
|
23145
|
+
const EditorToolbar = /* @__PURE__ */ _export_sfc(_sfc_main$A, [["__scopeId", "data-v-7e9466dc"]]);
|
|
23143
23146
|
function isStyleActive(style, doc) {
|
|
23144
23147
|
const selection = doc.getSelection();
|
|
23145
23148
|
if (!selection || !selection.rangeCount) return false;
|
|
@@ -23259,11 +23262,22 @@ function formatting(state2) {
|
|
|
23259
23262
|
range2.surroundContents(span);
|
|
23260
23263
|
}
|
|
23261
23264
|
} else {
|
|
23262
|
-
|
|
23265
|
+
if (range2.collapsed) return;
|
|
23266
|
+
const span = doc.createElement("span");
|
|
23267
|
+
if (command === "bold") span.style.fontWeight = "bold";
|
|
23268
|
+
else if (command === "italic") span.style.fontStyle = "italic";
|
|
23269
|
+
else if (command === "underline") span.style.textDecoration = "underline";
|
|
23270
|
+
try {
|
|
23271
|
+
range2.surroundContents(span);
|
|
23272
|
+
} catch (e) {
|
|
23273
|
+
const fragment = range2.extractContents();
|
|
23274
|
+
span.appendChild(fragment);
|
|
23275
|
+
range2.insertNode(span);
|
|
23276
|
+
}
|
|
23263
23277
|
}
|
|
23264
23278
|
};
|
|
23265
23279
|
const block = (command, tag) => {
|
|
23266
|
-
var _a
|
|
23280
|
+
var _a;
|
|
23267
23281
|
const selection = doc.getSelection();
|
|
23268
23282
|
if (!selection || !selection.rangeCount) return;
|
|
23269
23283
|
const range2 = selection.getRangeAt(0);
|
|
@@ -23280,10 +23294,18 @@ function formatting(state2) {
|
|
|
23280
23294
|
wrapper.remove();
|
|
23281
23295
|
}
|
|
23282
23296
|
}
|
|
23283
|
-
doc.
|
|
23284
|
-
if (isRTL)
|
|
23285
|
-
|
|
23286
|
-
|
|
23297
|
+
const newBlock = doc.createElement(tag);
|
|
23298
|
+
if (isRTL) newBlock.dir = "rtl";
|
|
23299
|
+
const currentBlock = (parentBlock == null ? void 0 : parentBlock.closest("p,h1,h2,h3,h4,h5,h6,blockquote,div")) || parentBlock;
|
|
23300
|
+
if (currentBlock) {
|
|
23301
|
+
while (currentBlock.firstChild) {
|
|
23302
|
+
newBlock.appendChild(currentBlock.firstChild);
|
|
23303
|
+
}
|
|
23304
|
+
(_a = currentBlock.parentNode) == null ? void 0 : _a.replaceChild(newBlock, currentBlock);
|
|
23305
|
+
range2.selectNodeContents(newBlock);
|
|
23306
|
+
range2.collapse(false);
|
|
23307
|
+
selection.removeAllRanges();
|
|
23308
|
+
selection.addRange(range2);
|
|
23287
23309
|
}
|
|
23288
23310
|
};
|
|
23289
23311
|
const list = (command) => {
|
|
@@ -23348,13 +23370,34 @@ function formatting(state2) {
|
|
|
23348
23370
|
restoreSelection(state2.doc, state2.range, state2.selection, selectionInfo, listEl);
|
|
23349
23371
|
};
|
|
23350
23372
|
const clear = () => {
|
|
23351
|
-
|
|
23373
|
+
console.log("[Clear Format] Starting clear format process", state2);
|
|
23374
|
+
console.assert(state2, "[Clear Format] State must exist");
|
|
23375
|
+
console.assert(state2.doc, "[Clear Format] Document must exist");
|
|
23376
|
+
console.assert(state2.range, "[Clear Format] Range must exist");
|
|
23377
|
+
console.assert(state2.selection, "[Clear Format] Selection must exist");
|
|
23378
|
+
if (!state2.doc || !state2.range || !state2.selection) {
|
|
23379
|
+
console.log("[Clear Format] No document or selection");
|
|
23380
|
+
return;
|
|
23381
|
+
}
|
|
23352
23382
|
const selectionInfo = analyzeSelection(state2.doc, state2.range);
|
|
23353
|
-
|
|
23354
|
-
|
|
23383
|
+
console.log("[Clear Format] Selection info:", selectionInfo);
|
|
23384
|
+
if (!selectionInfo) {
|
|
23385
|
+
console.log("[Clear Format] No valid selection info");
|
|
23386
|
+
return;
|
|
23387
|
+
}
|
|
23388
|
+
if (state2.range.collapsed) {
|
|
23389
|
+
console.log("[Clear Format] Selection is collapsed, nothing to clear");
|
|
23390
|
+
return;
|
|
23391
|
+
}
|
|
23392
|
+
console.log("[Clear Format] Processing selection:", {
|
|
23393
|
+
startContainer: state2.range.startContainer,
|
|
23394
|
+
endContainer: state2.range.endContainer,
|
|
23395
|
+
selectedText: state2.range.toString()
|
|
23396
|
+
});
|
|
23355
23397
|
const fragment = state2.range.cloneContents();
|
|
23356
23398
|
const tempDiv = state2.doc.createElement("div");
|
|
23357
23399
|
tempDiv.appendChild(fragment);
|
|
23400
|
+
console.log("[Clear Format] Original HTML:", tempDiv.innerHTML);
|
|
23358
23401
|
const cleanNode = (node) => {
|
|
23359
23402
|
if (!state2.doc) return node;
|
|
23360
23403
|
if (node.nodeType === 3) {
|
|
@@ -23363,12 +23406,36 @@ function formatting(state2) {
|
|
|
23363
23406
|
if (node.nodeType === 1) {
|
|
23364
23407
|
const el = node;
|
|
23365
23408
|
const nodeName = el.nodeName.toLowerCase();
|
|
23409
|
+
const inlineTags = ["b", "i", "u", "strong", "em", "span", "font", "strike", "sub", "sup"];
|
|
23410
|
+
console.log("[Clear Format] Processing element:", nodeName, {
|
|
23411
|
+
hasStyle: el.hasAttribute("style"),
|
|
23412
|
+
style: el.getAttribute("style"),
|
|
23413
|
+
className: el.className
|
|
23414
|
+
});
|
|
23366
23415
|
if (inlineTags.includes(nodeName)) {
|
|
23367
|
-
|
|
23416
|
+
const textContent = el.textContent || "";
|
|
23417
|
+
console.log("[Clear Format] Extracting text from inline element:", textContent);
|
|
23418
|
+
return state2.doc.createTextNode(textContent);
|
|
23368
23419
|
}
|
|
23369
23420
|
const newEl = state2.doc.createElement(nodeName);
|
|
23370
|
-
|
|
23371
|
-
|
|
23421
|
+
if (el.hasAttribute("style")) {
|
|
23422
|
+
console.log("[Clear Format] Removing style attribute:", el.getAttribute("style"));
|
|
23423
|
+
}
|
|
23424
|
+
if (el.className) {
|
|
23425
|
+
console.log("[Clear Format] Removing class:", el.className);
|
|
23426
|
+
}
|
|
23427
|
+
if (nodeName === "a" && el.hasAttribute("href")) {
|
|
23428
|
+
newEl.setAttribute("href", el.getAttribute("href") || "");
|
|
23429
|
+
if (el.hasAttribute("target")) {
|
|
23430
|
+
newEl.setAttribute("target", el.getAttribute("target") || "");
|
|
23431
|
+
}
|
|
23432
|
+
console.log("[Clear Format] Preserving link attributes");
|
|
23433
|
+
}
|
|
23434
|
+
if (nodeName === "img") {
|
|
23435
|
+
if (el.hasAttribute("src")) newEl.setAttribute("src", el.getAttribute("src") || "");
|
|
23436
|
+
if (el.hasAttribute("alt")) newEl.setAttribute("alt", el.getAttribute("alt") || "");
|
|
23437
|
+
console.log("[Clear Format] Preserving image attributes");
|
|
23438
|
+
}
|
|
23372
23439
|
Array.from(el.childNodes).forEach((child) => {
|
|
23373
23440
|
newEl.appendChild(cleanNode(child));
|
|
23374
23441
|
});
|
|
@@ -23380,9 +23447,14 @@ function formatting(state2) {
|
|
|
23380
23447
|
Array.from(tempDiv.childNodes).forEach((node) => {
|
|
23381
23448
|
cleanedFragment.appendChild(cleanNode(node));
|
|
23382
23449
|
});
|
|
23450
|
+
const debugDiv = state2.doc.createElement("div");
|
|
23451
|
+
debugDiv.appendChild(cleanedFragment.cloneNode(true));
|
|
23452
|
+
console.log("[Clear Format] Cleaned HTML:", debugDiv.innerHTML);
|
|
23383
23453
|
state2.range.deleteContents();
|
|
23384
23454
|
state2.range.insertNode(cleanedFragment);
|
|
23385
23455
|
restoreSelection(state2.doc, state2.range, state2.selection, selectionInfo);
|
|
23456
|
+
state2.content = state2.doc.body.innerHTML;
|
|
23457
|
+
console.log("[Clear Format] Updated document HTML:", state2.content);
|
|
23386
23458
|
};
|
|
23387
23459
|
return { text, block, list, clear };
|
|
23388
23460
|
}
|
|
@@ -23495,16 +23567,44 @@ function insertTable(rows, cols, state2) {
|
|
|
23495
23567
|
const table = state2.doc.createElement("table");
|
|
23496
23568
|
table.style.width = "100%";
|
|
23497
23569
|
table.style.borderCollapse = "collapse";
|
|
23570
|
+
table.style.marginBottom = "1rem";
|
|
23571
|
+
const thead = state2.doc.createElement("thead");
|
|
23572
|
+
const headerRow = thead.insertRow();
|
|
23573
|
+
for (let j = 0; j < cols; j++) {
|
|
23574
|
+
const th = state2.doc.createElement("th");
|
|
23575
|
+
th.innerHTML = `Header ${j + 1}`;
|
|
23576
|
+
th.style.padding = "8px";
|
|
23577
|
+
th.style.border = "1px solid var(--border-color, #ddd)";
|
|
23578
|
+
th.style.backgroundColor = "var(--bgl-gray-light, #f4f4f4)";
|
|
23579
|
+
headerRow.appendChild(th);
|
|
23580
|
+
}
|
|
23581
|
+
table.appendChild(thead);
|
|
23582
|
+
const tbody = state2.doc.createElement("tbody");
|
|
23498
23583
|
for (let i2 = 0; i2 < rows; i2++) {
|
|
23499
|
-
const row =
|
|
23584
|
+
const row = tbody.insertRow();
|
|
23500
23585
|
for (let j = 0; j < cols; j++) {
|
|
23501
23586
|
const cell = row.insertCell();
|
|
23502
23587
|
cell.innerHTML = " ";
|
|
23588
|
+
cell.style.padding = "8px";
|
|
23589
|
+
cell.style.border = "1px solid var(--border-color, #ddd)";
|
|
23503
23590
|
}
|
|
23504
23591
|
}
|
|
23592
|
+
table.appendChild(tbody);
|
|
23505
23593
|
const { range: range2 } = state2;
|
|
23506
23594
|
if (range2) {
|
|
23507
23595
|
range2.insertNode(table);
|
|
23596
|
+
if (state2.doc.getSelection()) {
|
|
23597
|
+
const firstCell = table.querySelector("td");
|
|
23598
|
+
if (firstCell) {
|
|
23599
|
+
range2.selectNodeContents(firstCell);
|
|
23600
|
+
range2.collapse(true);
|
|
23601
|
+
const selection = state2.doc.getSelection();
|
|
23602
|
+
if (selection) {
|
|
23603
|
+
selection.removeAllRanges();
|
|
23604
|
+
selection.addRange(range2);
|
|
23605
|
+
}
|
|
23606
|
+
}
|
|
23607
|
+
}
|
|
23508
23608
|
} else {
|
|
23509
23609
|
state2.doc.body.appendChild(table);
|
|
23510
23610
|
}
|
|
@@ -23665,12 +23765,9 @@ function createFormattingCommand(state2, type3, command, tag) {
|
|
|
23665
23765
|
var _a, _b;
|
|
23666
23766
|
if (!state2.doc) return;
|
|
23667
23767
|
if (type3 === "text") {
|
|
23668
|
-
|
|
23669
|
-
else if (command === "italic") state2.doc.execCommand("italic", false);
|
|
23670
|
-
else if (command === "underline") state2.doc.execCommand("underline", false);
|
|
23671
|
-
else format2.text(command);
|
|
23768
|
+
format2.text(command);
|
|
23672
23769
|
} else if (type3 === "block") {
|
|
23673
|
-
|
|
23770
|
+
format2.block(command, command);
|
|
23674
23771
|
} else if (type3 === "list") {
|
|
23675
23772
|
const selection = state2.doc.getSelection();
|
|
23676
23773
|
if (!selection || !selection.rangeCount) return;
|
|
@@ -23691,10 +23788,7 @@ function createFormattingCommand(state2, type3, command, tag) {
|
|
|
23691
23788
|
selection.removeAllRanges();
|
|
23692
23789
|
selection.addRange(range2);
|
|
23693
23790
|
} else {
|
|
23694
|
-
|
|
23695
|
-
command === "orderedList" ? "insertOrderedList" : "insertUnorderedList",
|
|
23696
|
-
false
|
|
23697
|
-
);
|
|
23791
|
+
format2.list(command);
|
|
23698
23792
|
}
|
|
23699
23793
|
}
|
|
23700
23794
|
},
|
|
@@ -23703,34 +23797,167 @@ function createFormattingCommand(state2, type3, command, tag) {
|
|
|
23703
23797
|
}
|
|
23704
23798
|
function isNodeEmpty$1(node) {
|
|
23705
23799
|
var _a;
|
|
23706
|
-
const text = ((_a = node.textContent) == null ? void 0 : _a.
|
|
23800
|
+
const text = ((_a = node.textContent) == null ? void 0 : _a.replace(/\s/g, "")) || "";
|
|
23707
23801
|
if (text) return false;
|
|
23708
|
-
const brElements = node.getElementsByTagName("br");
|
|
23802
|
+
const brElements = node.getElementsByTagName ? node.getElementsByTagName("br") : [];
|
|
23709
23803
|
if (brElements.length === 0) return true;
|
|
23710
|
-
return brElements.length === 1 && node.childNodes.length
|
|
23804
|
+
return brElements.length === 1 && node.childNodes.length <= 2;
|
|
23711
23805
|
}
|
|
23712
23806
|
function createCommandRegistry(state2) {
|
|
23713
23807
|
const format2 = formatting(state2);
|
|
23714
23808
|
const historyCommands = {
|
|
23715
23809
|
undo: createCommand("Undo", () => {
|
|
23716
|
-
|
|
23717
|
-
|
|
23810
|
+
if (state2.undoStack.length > 0 && state2.doc) {
|
|
23811
|
+
const lastContent = state2.undoStack.pop();
|
|
23812
|
+
if (lastContent !== void 0) {
|
|
23813
|
+
state2.redoStack.push(state2.content);
|
|
23814
|
+
state2.content = lastContent;
|
|
23815
|
+
if (state2.doc) state2.doc.body.innerHTML = lastContent;
|
|
23816
|
+
}
|
|
23817
|
+
}
|
|
23718
23818
|
}),
|
|
23719
23819
|
redo: createCommand("Redo", () => {
|
|
23720
|
-
|
|
23721
|
-
|
|
23820
|
+
if (state2.redoStack.length > 0 && state2.doc) {
|
|
23821
|
+
const nextContent = state2.redoStack.pop();
|
|
23822
|
+
if (nextContent !== void 0) {
|
|
23823
|
+
state2.undoStack.push(state2.content);
|
|
23824
|
+
state2.content = nextContent;
|
|
23825
|
+
if (state2.doc) state2.doc.body.innerHTML = nextContent;
|
|
23826
|
+
}
|
|
23827
|
+
}
|
|
23828
|
+
})
|
|
23829
|
+
};
|
|
23830
|
+
const textCommands = {
|
|
23831
|
+
bold: createCommand("Bold", (state22) => {
|
|
23832
|
+
console.log("[Command] Bold called");
|
|
23833
|
+
if (!state22.doc || !state22.range || !state22.selection) return;
|
|
23834
|
+
const { range: range2 } = state22;
|
|
23835
|
+
if (range2.collapsed) return;
|
|
23836
|
+
try {
|
|
23837
|
+
const span = state22.doc.createElement("span");
|
|
23838
|
+
span.style.fontWeight = "bold";
|
|
23839
|
+
try {
|
|
23840
|
+
range2.surroundContents(span);
|
|
23841
|
+
} catch (e) {
|
|
23842
|
+
const fragment = range2.extractContents();
|
|
23843
|
+
span.appendChild(fragment);
|
|
23844
|
+
range2.insertNode(span);
|
|
23845
|
+
}
|
|
23846
|
+
range2.selectNodeContents(span);
|
|
23847
|
+
state22.selection.removeAllRanges();
|
|
23848
|
+
state22.selection.addRange(range2);
|
|
23849
|
+
state22.content = state22.doc.body.innerHTML;
|
|
23850
|
+
} catch (error) {
|
|
23851
|
+
console.error("[Command] Error applying bold:", error);
|
|
23852
|
+
}
|
|
23853
|
+
}),
|
|
23854
|
+
italic: createCommand("Italic", (state22) => {
|
|
23855
|
+
console.log("[Command] Italic called");
|
|
23856
|
+
if (!state22.doc || !state22.range || !state22.selection) return;
|
|
23857
|
+
const { range: range2 } = state22;
|
|
23858
|
+
if (range2.collapsed) return;
|
|
23859
|
+
try {
|
|
23860
|
+
const span = state22.doc.createElement("span");
|
|
23861
|
+
span.style.fontStyle = "italic";
|
|
23862
|
+
try {
|
|
23863
|
+
range2.surroundContents(span);
|
|
23864
|
+
} catch (e) {
|
|
23865
|
+
const fragment = range2.extractContents();
|
|
23866
|
+
span.appendChild(fragment);
|
|
23867
|
+
range2.insertNode(span);
|
|
23868
|
+
}
|
|
23869
|
+
range2.selectNodeContents(span);
|
|
23870
|
+
state22.selection.removeAllRanges();
|
|
23871
|
+
state22.selection.addRange(range2);
|
|
23872
|
+
state22.content = state22.doc.body.innerHTML;
|
|
23873
|
+
} catch (error) {
|
|
23874
|
+
console.error("[Command] Error applying italic:", error);
|
|
23875
|
+
}
|
|
23876
|
+
}),
|
|
23877
|
+
underline: createCommand("Underline", (state22) => {
|
|
23878
|
+
console.log("[Command] Underline called");
|
|
23879
|
+
if (!state22.doc || !state22.range || !state22.selection) return;
|
|
23880
|
+
const { range: range2 } = state22;
|
|
23881
|
+
if (range2.collapsed) return;
|
|
23882
|
+
try {
|
|
23883
|
+
const span = state22.doc.createElement("span");
|
|
23884
|
+
span.style.textDecoration = "underline";
|
|
23885
|
+
try {
|
|
23886
|
+
range2.surroundContents(span);
|
|
23887
|
+
} catch (e) {
|
|
23888
|
+
const fragment = range2.extractContents();
|
|
23889
|
+
span.appendChild(fragment);
|
|
23890
|
+
range2.insertNode(span);
|
|
23891
|
+
}
|
|
23892
|
+
range2.selectNodeContents(span);
|
|
23893
|
+
state22.selection.removeAllRanges();
|
|
23894
|
+
state22.selection.addRange(range2);
|
|
23895
|
+
state22.content = state22.doc.body.innerHTML;
|
|
23896
|
+
} catch (error) {
|
|
23897
|
+
console.error("[Command] Error applying underline:", error);
|
|
23898
|
+
}
|
|
23722
23899
|
})
|
|
23723
23900
|
};
|
|
23724
|
-
const textCommands = ["bold", "italic", "underline"].reduce((acc, cmd) => ({
|
|
23725
|
-
...acc,
|
|
23726
|
-
[cmd]: createFormattingCommand(state2, "text", cmd)
|
|
23727
|
-
}), {});
|
|
23728
23901
|
const headingCommands = ["h1", "h2", "h3", "h4", "h5", "h6"].reduce((acc, cmd) => ({
|
|
23729
23902
|
...acc,
|
|
23730
|
-
[cmd]:
|
|
23903
|
+
[cmd]: createCommand(`Heading ${cmd}`, (state22) => {
|
|
23904
|
+
var _a;
|
|
23905
|
+
console.log(`[Command] ${cmd} heading called`);
|
|
23906
|
+
if (!state22.doc || !state22.range || !state22.selection) return;
|
|
23907
|
+
const { range: range2, doc, selection } = state22;
|
|
23908
|
+
const container = range2.commonAncestorContainer;
|
|
23909
|
+
const parentBlock = container.nodeType === 3 ? container.parentElement : container;
|
|
23910
|
+
const currentBlock = (parentBlock == null ? void 0 : parentBlock.closest("p,h1,h2,h3,h4,h5,h6,blockquote,div")) || parentBlock;
|
|
23911
|
+
const isToggleOff = (currentBlock == null ? void 0 : currentBlock.tagName.toLowerCase()) === cmd.toLowerCase();
|
|
23912
|
+
const newTag = isToggleOff ? "p" : cmd;
|
|
23913
|
+
try {
|
|
23914
|
+
const newBlock = doc.createElement(newTag);
|
|
23915
|
+
if (currentBlock) {
|
|
23916
|
+
while (currentBlock.firstChild) {
|
|
23917
|
+
newBlock.appendChild(currentBlock.firstChild);
|
|
23918
|
+
}
|
|
23919
|
+
(_a = currentBlock.parentNode) == null ? void 0 : _a.replaceChild(newBlock, currentBlock);
|
|
23920
|
+
range2.selectNodeContents(newBlock);
|
|
23921
|
+
range2.collapse(false);
|
|
23922
|
+
selection.removeAllRanges();
|
|
23923
|
+
selection.addRange(range2);
|
|
23924
|
+
}
|
|
23925
|
+
state22.content = doc.body.innerHTML;
|
|
23926
|
+
} catch (error) {
|
|
23927
|
+
console.error(`[Command] Error applying ${cmd} heading:`, error);
|
|
23928
|
+
}
|
|
23929
|
+
})
|
|
23731
23930
|
}), {});
|
|
23732
23931
|
const blockCommands = {
|
|
23733
|
-
p:
|
|
23932
|
+
p: createCommand("Paragraph", (state22) => {
|
|
23933
|
+
var _a;
|
|
23934
|
+
console.log("[Command] Paragraph called");
|
|
23935
|
+
if (!state22.doc || !state22.range || !state22.selection) return;
|
|
23936
|
+
const { range: range2, doc, selection } = state22;
|
|
23937
|
+
const container = range2.commonAncestorContainer;
|
|
23938
|
+
const parentBlock = container.nodeType === 3 ? container.parentElement : container;
|
|
23939
|
+
const currentBlock = (parentBlock == null ? void 0 : parentBlock.closest("p,h1,h2,h3,h4,h5,h6,blockquote,div")) || parentBlock;
|
|
23940
|
+
if ((currentBlock == null ? void 0 : currentBlock.tagName.toLowerCase()) === "p") {
|
|
23941
|
+
console.log("[Command] Already a paragraph");
|
|
23942
|
+
return;
|
|
23943
|
+
}
|
|
23944
|
+
try {
|
|
23945
|
+
const newParagraph = doc.createElement("p");
|
|
23946
|
+
if (currentBlock) {
|
|
23947
|
+
while (currentBlock.firstChild) {
|
|
23948
|
+
newParagraph.appendChild(currentBlock.firstChild);
|
|
23949
|
+
}
|
|
23950
|
+
(_a = currentBlock.parentNode) == null ? void 0 : _a.replaceChild(newParagraph, currentBlock);
|
|
23951
|
+
range2.selectNodeContents(newParagraph);
|
|
23952
|
+
range2.collapse(false);
|
|
23953
|
+
selection.removeAllRanges();
|
|
23954
|
+
selection.addRange(range2);
|
|
23955
|
+
}
|
|
23956
|
+
state22.content = doc.body.innerHTML;
|
|
23957
|
+
} catch (error) {
|
|
23958
|
+
console.error("[Command] Error applying paragraph:", error);
|
|
23959
|
+
}
|
|
23960
|
+
}),
|
|
23734
23961
|
blockquote: createFormattingCommand(state2, "block", "blockquote")
|
|
23735
23962
|
};
|
|
23736
23963
|
const listCommands = {
|
|
@@ -23773,8 +24000,62 @@ function createCommandRegistry(state2) {
|
|
|
23773
24000
|
embed: createCommand("Insert Embed", (state22) => state22.modal && insertEmbed(state22.modal, state22))
|
|
23774
24001
|
};
|
|
23775
24002
|
const otherCommands = {
|
|
23776
|
-
clear: createCommand("Clear Formatting", () => {
|
|
23777
|
-
|
|
24003
|
+
clear: createCommand("Clear Formatting", (state22) => {
|
|
24004
|
+
var _a;
|
|
24005
|
+
console.log("[Command] Clear formatting called");
|
|
24006
|
+
console.log("[Command] Current selection:", (_a = state22.selection) == null ? void 0 : _a.toString());
|
|
24007
|
+
console.log("[Command] Range exists:", !!state22.range);
|
|
24008
|
+
console.log("[Command] Document exists:", !!state22.doc);
|
|
24009
|
+
try {
|
|
24010
|
+
if (!state22.doc || !state22.range || !state22.selection) {
|
|
24011
|
+
console.log("[Command] Missing required state for clear formatting");
|
|
24012
|
+
return;
|
|
24013
|
+
}
|
|
24014
|
+
const { selection, range: range2, doc } = state22;
|
|
24015
|
+
if (range2.collapsed) {
|
|
24016
|
+
console.log("[Command] Selection is collapsed, nothing to clear");
|
|
24017
|
+
return;
|
|
24018
|
+
}
|
|
24019
|
+
const fragment = range2.cloneContents();
|
|
24020
|
+
const tempDiv = doc.createElement("div");
|
|
24021
|
+
tempDiv.appendChild(fragment);
|
|
24022
|
+
console.log("[Command] Original HTML:", tempDiv.innerHTML);
|
|
24023
|
+
const structuralTags = ["p", "h1", "h2", "h3", "h4", "h5", "h6", "ul", "ol", "li", "blockquote", "div", "table", "tr", "td", "th"];
|
|
24024
|
+
const inlineTags = ["b", "i", "u", "strong", "em", "span", "font", "strike", "sub", "sup"];
|
|
24025
|
+
const cleanElement = (element) => {
|
|
24026
|
+
element.removeAttribute("style");
|
|
24027
|
+
element.removeAttribute("class");
|
|
24028
|
+
Array.from(element.children).forEach((child) => {
|
|
24029
|
+
if (inlineTags.includes(child.tagName.toLowerCase())) {
|
|
24030
|
+
const textContent = child.textContent || "";
|
|
24031
|
+
const textNode = doc.createTextNode(textContent);
|
|
24032
|
+
child.replaceWith(textNode);
|
|
24033
|
+
} else {
|
|
24034
|
+
cleanElement(child);
|
|
24035
|
+
}
|
|
24036
|
+
});
|
|
24037
|
+
};
|
|
24038
|
+
Array.from(tempDiv.querySelectorAll("*")).forEach((element) => {
|
|
24039
|
+
const tagName = element.tagName.toLowerCase();
|
|
24040
|
+
if (structuralTags.includes(tagName)) {
|
|
24041
|
+
cleanElement(element);
|
|
24042
|
+
}
|
|
24043
|
+
});
|
|
24044
|
+
console.log("[Command] Cleaned HTML:", tempDiv.innerHTML);
|
|
24045
|
+
range2.deleteContents();
|
|
24046
|
+
const cleanedFragment = doc.createDocumentFragment();
|
|
24047
|
+
while (tempDiv.firstChild) {
|
|
24048
|
+
cleanedFragment.appendChild(tempDiv.firstChild);
|
|
24049
|
+
}
|
|
24050
|
+
range2.insertNode(cleanedFragment);
|
|
24051
|
+
range2.collapse(false);
|
|
24052
|
+
selection.removeAllRanges();
|
|
24053
|
+
selection.addRange(range2);
|
|
24054
|
+
state22.content = doc.body.innerHTML;
|
|
24055
|
+
console.log("[Command] Clear formatting completed");
|
|
24056
|
+
} catch (error) {
|
|
24057
|
+
console.error("[Command] Error in clear formatting:", error);
|
|
24058
|
+
}
|
|
23778
24059
|
}),
|
|
23779
24060
|
indent: createCommand("Indent", () => {
|
|
23780
24061
|
format2.text("indent");
|
|
@@ -23821,9 +24102,14 @@ function useCommands(state2, debug) {
|
|
|
23821
24102
|
const executor = createCommandExecutor(state2, commands);
|
|
23822
24103
|
return {
|
|
23823
24104
|
execute: (command, value) => {
|
|
23824
|
-
|
|
24105
|
+
console.log(`[useCommands] Executing command: ${command}`, value ? `with value: ${value}` : "");
|
|
24106
|
+
if (!state2.doc) {
|
|
24107
|
+
console.log("[useCommands] No document available, skipping command");
|
|
24108
|
+
return;
|
|
24109
|
+
}
|
|
23825
24110
|
debug == null ? void 0 : debug.logCommand(command, value);
|
|
23826
24111
|
if (["splitView", "codeView", "fullScreen"].includes(command)) {
|
|
24112
|
+
console.log(`[useCommands] Handling view state command: ${command}`);
|
|
23827
24113
|
switch (command) {
|
|
23828
24114
|
case "splitView":
|
|
23829
24115
|
state2.isSplitView = !state2.isSplitView;
|
|
@@ -23836,16 +24122,29 @@ function useCommands(state2, debug) {
|
|
|
23836
24122
|
return;
|
|
23837
24123
|
}
|
|
23838
24124
|
}
|
|
23839
|
-
|
|
23840
|
-
|
|
24125
|
+
try {
|
|
24126
|
+
state2.doc.body.focus();
|
|
24127
|
+
console.log("[useCommands] Editor focused");
|
|
24128
|
+
} catch (e) {
|
|
24129
|
+
console.error("[useCommands] Error focusing editor:", e);
|
|
24130
|
+
}
|
|
24131
|
+
try {
|
|
24132
|
+
console.log("[useCommands] Executing command via executor");
|
|
24133
|
+
executor.execute(command, value);
|
|
24134
|
+
console.log("[useCommands] Command execution completed");
|
|
24135
|
+
} catch (e) {
|
|
24136
|
+
console.error("[useCommands] Error during command execution:", e);
|
|
24137
|
+
}
|
|
23841
24138
|
const newContent = state2.doc.body.innerHTML;
|
|
23842
24139
|
if (newContent !== state2.content) {
|
|
24140
|
+
console.log("[useCommands] Content changed, updating state");
|
|
23843
24141
|
state2.content = newContent;
|
|
23844
24142
|
}
|
|
23845
24143
|
const selection = state2.doc.getSelection();
|
|
23846
24144
|
if (selection == null ? void 0 : selection.rangeCount) {
|
|
23847
24145
|
const hasSelectionChanged = !state2.selection || state2.selection !== selection || state2.rangeCount !== selection.rangeCount;
|
|
23848
24146
|
if (hasSelectionChanged) {
|
|
24147
|
+
console.log("[useCommands] Selection changed, updating state");
|
|
23849
24148
|
state2.selection = selection;
|
|
23850
24149
|
state2.range = selection.getRangeAt(0).cloneRange();
|
|
23851
24150
|
state2.rangeCount = selection.rangeCount;
|
package/dist/style.css
CHANGED
|
@@ -2011,7 +2011,7 @@ input[type="range"][data-v-46e22f3e]:active::-webkit-slider-thumb {
|
|
|
2011
2011
|
}
|
|
2012
2012
|
}
|
|
2013
2013
|
|
|
2014
|
-
.tableBoxSelect[data-v-
|
|
2014
|
+
.tableBoxSelect[data-v-2f424c9c]::after {
|
|
2015
2015
|
content: '';
|
|
2016
2016
|
display: block;
|
|
2017
2017
|
width: calc(100% - 4px);
|
|
@@ -2019,12 +2019,12 @@ input[type="range"][data-v-46e22f3e]:active::-webkit-slider-thumb {
|
|
|
2019
2019
|
border: 1px solid var(--bgl-gray);
|
|
2020
2020
|
background: var(--bgl-gray-light);
|
|
2021
2021
|
}
|
|
2022
|
-
.borderSelect[data-v-
|
|
2022
|
+
.borderSelect[data-v-2f424c9c]::after {
|
|
2023
2023
|
border-color: var(--bgl-primary-tint);
|
|
2024
2024
|
background: var(--bgl-primary-light);
|
|
2025
2025
|
}
|
|
2026
2026
|
|
|
2027
|
-
.toolbar[data-v-
|
|
2027
|
+
.toolbar[data-v-7e9466dc] .active {
|
|
2028
2028
|
background: var(--bgl-primary);
|
|
2029
2029
|
color: white;
|
|
2030
2030
|
}
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@ import type {
|
|
|
7
7
|
BglFormSchemaFnT,
|
|
8
8
|
Field,
|
|
9
9
|
} from '@bagelink/vue'
|
|
10
|
-
import { BagelForm, Btn, Loading } from '@bagelink/vue'
|
|
10
|
+
import { BagelForm, Btn, Loading, Icon } from '@bagelink/vue'
|
|
11
11
|
import { ref, onMounted, computed, watch } from 'vue'
|
|
12
12
|
|
|
13
13
|
const props = withDefaults(
|
|
@@ -23,10 +23,9 @@ function runAction(name: ToolbarConfigOption, value?: string) {
|
|
|
23
23
|
<Dropdown v-if="action.name === 'insertTable'" placement="bottom-start" thin flat icon="table">
|
|
24
24
|
<template #default="{ hide }">
|
|
25
25
|
<GridBox
|
|
26
|
-
:gridSize="5" @select="
|
|
27
|
-
runAction('insertTable',
|
|
28
|
-
(
|
|
29
|
-
hide()
|
|
26
|
+
:gridSize="5" @select="(value) => {
|
|
27
|
+
runAction('insertTable', value);
|
|
28
|
+
hide();
|
|
30
29
|
}"
|
|
31
30
|
/>
|
|
32
31
|
</template>
|