@bagelink/vue 0.0.1262 → 0.0.1268

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.
Files changed (48) hide show
  1. package/dist/components/AddressSearch.vue.d.ts +6 -0
  2. package/dist/components/AddressSearch.vue.d.ts.map +1 -1
  3. package/dist/components/DropDown.vue.d.ts +51 -48
  4. package/dist/components/DropDown.vue.d.ts.map +1 -1
  5. package/dist/components/form/FieldArray.vue.d.ts.map +1 -1
  6. package/dist/components/form/inputs/DateInput.vue.d.ts +4 -1
  7. package/dist/components/form/inputs/DateInput.vue.d.ts.map +1 -1
  8. package/dist/components/form/inputs/PasswordInput.vue.d.ts.map +1 -1
  9. package/dist/components/form/inputs/RadioGroup.vue.d.ts +1 -1
  10. package/dist/components/form/inputs/RichText/composables/useCommands.d.ts.map +1 -1
  11. package/dist/components/form/inputs/RichText/composables/useEditor.d.ts +31 -23
  12. package/dist/components/form/inputs/RichText/composables/useEditor.d.ts.map +1 -1
  13. package/dist/components/form/inputs/RichText/composables/useEditorKeyboard.d.ts +2 -1
  14. package/dist/components/form/inputs/RichText/composables/useEditorKeyboard.d.ts.map +1 -1
  15. package/dist/components/form/inputs/RichText/config.d.ts +2 -1
  16. package/dist/components/form/inputs/RichText/config.d.ts.map +1 -1
  17. package/dist/components/form/inputs/RichText/index.vue.d.ts.map +1 -1
  18. package/dist/components/form/inputs/RichText/utils/commands.d.ts +1 -0
  19. package/dist/components/form/inputs/RichText/utils/commands.d.ts.map +1 -1
  20. package/dist/components/form/inputs/RichText/utils/media.d.ts +5 -3
  21. package/dist/components/form/inputs/RichText/utils/media.d.ts.map +1 -1
  22. package/dist/components/form/inputs/RichText/utils/selection.d.ts.map +1 -1
  23. package/dist/components/form/inputs/SelectInput.vue.d.ts +12 -0
  24. package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
  25. package/dist/components/form/inputs/TelInput.vue.d.ts +8 -2
  26. package/dist/components/form/inputs/TelInput.vue.d.ts.map +1 -1
  27. package/dist/editor-7QC0nG_c.js +4 -0
  28. package/dist/editor-CpMNx6Eo.cjs +4 -0
  29. package/dist/index.cjs +1327 -756
  30. package/dist/index.mjs +1327 -756
  31. package/dist/style.css +90 -83
  32. package/package.json +1 -1
  33. package/src/components/DataTable/DataTable.vue +1 -1
  34. package/src/components/Dropdown.vue +5 -2
  35. package/src/components/form/FieldArray.vue +3 -0
  36. package/src/components/form/inputs/DateInput.vue +341 -162
  37. package/src/components/form/inputs/PasswordInput.vue +5 -1
  38. package/src/components/form/inputs/RichText/components/EditorToolbar.vue +2 -2
  39. package/src/components/form/inputs/RichText/composables/useCommands.ts +53 -97
  40. package/src/components/form/inputs/RichText/composables/useEditor.ts +377 -270
  41. package/src/components/form/inputs/RichText/composables/useEditorKeyboard.ts +124 -58
  42. package/src/components/form/inputs/RichText/config.ts +27 -3
  43. package/src/components/form/inputs/RichText/editor.css +29 -0
  44. package/src/components/form/inputs/RichText/index.vue +129 -55
  45. package/src/components/form/inputs/RichText/richTextTypes.d.ts +35 -49
  46. package/src/components/form/inputs/RichText/utils/commands.ts +181 -0
  47. package/src/components/form/inputs/RichText/utils/media.ts +64 -3
  48. package/src/components/form/inputs/RichText/utils/selection.ts +40 -5
package/dist/index.mjs CHANGED
@@ -11468,7 +11468,7 @@ const _sfc_main$X = /* @__PURE__ */ defineComponent({
11468
11468
  emits: /* @__PURE__ */ mergeModels(["update:selectedItems", "orderBy", "select", "lastItemVisible"], ["update:loading", "update:itemHeight", "update:selectedItems"]),
11469
11469
  setup(__props, { emit: __emit }) {
11470
11470
  useCssVars((_ctx) => ({
11471
- "1ab0cc24": unref(computedItemHeight)
11471
+ "40bb5b9a": unref(computedItemHeight)
11472
11472
  }));
11473
11473
  const props2 = __props;
11474
11474
  const emit2 = __emit;
@@ -11652,7 +11652,7 @@ const _sfc_main$X = /* @__PURE__ */ defineComponent({
11652
11652
  };
11653
11653
  }
11654
11654
  });
11655
- const DataTable = /* @__PURE__ */ _export_sfc(_sfc_main$X, [["__scopeId", "data-v-8e14fc71"]]);
11655
+ const DataTable = /* @__PURE__ */ _export_sfc(_sfc_main$X, [["__scopeId", "data-v-89f6838b"]]);
11656
11656
  function useDraggable(options = {}) {
11657
11657
  const isDragging = ref(false);
11658
11658
  const dragElement = ref(null);
@@ -14762,7 +14762,9 @@ const _sfc_main$V = /* @__PURE__ */ defineComponent({
14762
14762
  round: { type: Boolean },
14763
14763
  placement: {},
14764
14764
  noAutoFocus: { type: Boolean },
14765
- positioningDisabled: { type: Boolean }
14765
+ positioningDisabled: { type: Boolean },
14766
+ autoHide: { type: Boolean },
14767
+ triggers: {}
14766
14768
  }, {
14767
14769
  "shown": {
14768
14770
  type: Boolean,
@@ -14795,6 +14797,8 @@ const _sfc_main$V = /* @__PURE__ */ defineComponent({
14795
14797
  disabled: _ctx.disabled,
14796
14798
  noAutoFocus: _ctx.noAutoFocus,
14797
14799
  placement: _ctx.placement,
14800
+ autoHide: _ctx.autoHide,
14801
+ triggers: _ctx.triggers,
14798
14802
  onHide: _cache[1] || (_cache[1] = ($event) => emit2("hide")),
14799
14803
  onShow: _cache[2] || (_cache[2] = ($event) => emit2("show"))
14800
14804
  }, {
@@ -14821,7 +14825,7 @@ const _sfc_main$V = /* @__PURE__ */ defineComponent({
14821
14825
  ])
14822
14826
  ]),
14823
14827
  _: 3
14824
- }, 8, ["shown", "disabled", "noAutoFocus", "placement"]);
14828
+ }, 8, ["shown", "disabled", "noAutoFocus", "placement", "autoHide", "triggers"]);
14825
14829
  };
14826
14830
  }
14827
14831
  });
@@ -15769,33 +15773,31 @@ const _hoisted_3$o = {
15769
15773
  key: 0,
15770
15774
  class: "required"
15771
15775
  };
15772
- const _hoisted_4$g = { class: "date-picker-container" };
15773
- const _hoisted_5$f = { class: "flex gap-075 p-05 m_flex-wrap calendar-container justify-content-center h-100p" };
15774
- const _hoisted_6$c = { class: "calendar-section m_border-none pe-05 m_p-0" };
15775
- const _hoisted_7$9 = { class: "flex space-between pb-1" };
15776
- const _hoisted_8$6 = { class: "flex gap-05" };
15777
- const _hoisted_9$5 = { class: "month-year" };
15778
- const _hoisted_10$5 = {
15776
+ const _hoisted_4$g = { class: "calendar-section m_border-none pe-05 m_p-0" };
15777
+ const _hoisted_5$f = { class: "flex space-between pb-1" };
15778
+ const _hoisted_6$c = { class: "flex gap-05" };
15779
+ const _hoisted_7$9 = { class: "month-year" };
15780
+ const _hoisted_8$6 = {
15779
15781
  key: 0,
15780
15782
  class: "calendar-grid grid gap-025"
15781
15783
  };
15782
- const _hoisted_11$5 = ["disabled", "onClick"];
15783
- const _hoisted_12$5 = {
15784
+ const _hoisted_9$5 = ["disabled", "onClick"];
15785
+ const _hoisted_10$5 = {
15784
15786
  key: 1,
15785
15787
  class: "month-grid grid gap-05 p-05"
15786
15788
  };
15787
- const _hoisted_13$4 = ["disabled", "onClick"];
15788
- const _hoisted_14$4 = {
15789
+ const _hoisted_11$5 = ["disabled", "onClick"];
15790
+ const _hoisted_12$5 = {
15789
15791
  key: 2,
15790
15792
  class: "year-grid grid gap-05 p-0"
15791
15793
  };
15792
- const _hoisted_15$4 = ["disabled", "onClick"];
15793
- const _hoisted_16$4 = {
15794
+ const _hoisted_13$4 = ["disabled", "onClick"];
15795
+ const _hoisted_14$4 = {
15794
15796
  key: 0,
15795
15797
  class: "time-picker border-start flex column gap-1 w-120px"
15796
15798
  };
15797
- const _hoisted_17$4 = { class: "flex gap-025" };
15798
- const _hoisted_18$2 = { class: "txt-center opacity-6 txt14" };
15799
+ const _hoisted_15$4 = { class: "flex gap-025" };
15800
+ const _hoisted_16$4 = { class: "txt-center opacity-6 txt14" };
15799
15801
  const _sfc_main$M = /* @__PURE__ */ defineComponent({
15800
15802
  __name: "DateInput",
15801
15803
  props: {
@@ -15809,7 +15811,7 @@ const _sfc_main$M = /* @__PURE__ */ defineComponent({
15809
15811
  max: {},
15810
15812
  timezone: { default: "UTC" },
15811
15813
  mode: { default: "day" },
15812
- firstDayOfWeek: { default: WEEK_START_DAY.MONDAY },
15814
+ firstDayOfWeek: { default: WEEK_START_DAY.SUNDAY },
15813
15815
  locale: { default: "" },
15814
15816
  center: { type: Boolean }
15815
15817
  },
@@ -15817,235 +15819,392 @@ const _sfc_main$M = /* @__PURE__ */ defineComponent({
15817
15819
  setup(__props, { emit: __emit }) {
15818
15820
  const props2 = __props;
15819
15821
  const emit2 = __emit;
15820
- let isOpen = ref(false);
15821
- let currentMonth = ref(/* @__PURE__ */ new Date());
15822
- let currentView = ref("days");
15822
+ const isOpen = ref(false);
15823
+ const currentMonth = ref(/* @__PURE__ */ new Date());
15824
+ const currentView = ref("days");
15823
15825
  const time = new Time(props2.firstDayOfWeek, props2.locale);
15824
- function formatDisplayDate(date2) {
15825
- if (!date2) return "";
15826
- const dateObj = typeof date2 === "string" ? new Date(date2) : date2;
15827
- if (props2.enableTime) {
15828
- return dateObj.toLocaleString(props2.locale || void 0, {
15826
+ function useFormatting() {
15827
+ const formatDisplayDate = (date2) => {
15828
+ if (!date2) return "";
15829
+ const dateObj = typeof date2 === "string" ? new Date(date2) : date2;
15830
+ const options = {
15829
15831
  year: "numeric",
15830
15832
  month: "short",
15831
15833
  day: "numeric",
15832
- hour: "2-digit",
15833
- minute: "2-digit",
15834
+ ...props2.enableTime && {
15835
+ hour: "2-digit",
15836
+ minute: "2-digit"
15837
+ },
15834
15838
  timeZone: props2.timezone
15835
- });
15836
- }
15837
- return dateObj.toLocaleString(props2.locale || void 0, {
15838
- year: "numeric",
15839
- month: "short",
15840
- day: "numeric",
15841
- timeZone: props2.timezone
15842
- });
15839
+ };
15840
+ return dateObj.toLocaleString(props2.locale || void 0, options);
15841
+ };
15842
+ const formatDate = (date2) => {
15843
+ if (!date2) return "";
15844
+ const dateObj = typeof date2 === "string" ? new Date(date2) : date2;
15845
+ return props2.enableTime ? dateObj.toISOString().slice(0, 16) : dateObj.toISOString().split("T")[0];
15846
+ };
15847
+ const parseUserInput = (input) => {
15848
+ const date2 = new Date(input);
15849
+ if (!Number.isNaN(date2.getTime())) {
15850
+ return date2;
15851
+ }
15852
+ const parts = input.split(/[/.-]/);
15853
+ if (parts.length === 3) {
15854
+ const [day, month, year] = parts.map((p2) => Number.parseInt(p2, 10));
15855
+ if (!Number.isNaN(day) && !Number.isNaN(month) && !Number.isNaN(year)) {
15856
+ const date22 = new Date(year, month - 1, day);
15857
+ if (date22.getFullYear() === year && date22.getMonth() === month - 1 && date22.getDate() === day) {
15858
+ return date22;
15859
+ }
15860
+ }
15861
+ }
15862
+ return null;
15863
+ };
15864
+ return {
15865
+ formatDisplayDate,
15866
+ formatDate,
15867
+ parseUserInput
15868
+ };
15843
15869
  }
15844
- function formatDate(date2) {
15845
- if (!date2) return "";
15846
- const dateObj = typeof date2 === "string" ? new Date(date2) : date2;
15847
- return props2.enableTime ? dateObj.toISOString().slice(0, 16) : dateObj.toISOString().split("T")[0];
15870
+ function useDateValidation() {
15871
+ const isDateDisabled2 = (date2) => {
15872
+ if (!date2) return true;
15873
+ const minDate = props2.min ? new Date(props2.min) : null;
15874
+ const maxDate = props2.max ? new Date(props2.max) : null;
15875
+ if (minDate && date2 < minDate) return true;
15876
+ if (maxDate && date2 > maxDate) return true;
15877
+ return false;
15878
+ };
15879
+ const isYearDisabled2 = (year) => {
15880
+ const minDate = props2.min ? new Date(props2.min) : null;
15881
+ const maxDate = props2.max ? new Date(props2.max) : null;
15882
+ if (minDate && year < minDate.getFullYear()) return true;
15883
+ if (maxDate && year > maxDate.getFullYear()) return true;
15884
+ return false;
15885
+ };
15886
+ return {
15887
+ isDateDisabled: isDateDisabled2,
15888
+ isYearDisabled: isYearDisabled2
15889
+ };
15848
15890
  }
15849
- const formattedDisplayValue = computed(() => formatDisplayDate(props2.modelValue));
15850
- const formattedMin = computed(() => formatDate(props2.min));
15851
- const formattedMax = computed(() => formatDate(props2.max));
15852
- const selectedDate = computed(() => {
15853
- if (!props2.modelValue) return null;
15854
- return typeof props2.modelValue === "string" ? new Date(props2.modelValue) : props2.modelValue;
15855
- });
15856
- const currentMonthDays = computed(() => {
15857
- const year = currentMonth.value.getFullYear();
15858
- const month = currentMonth.value.getMonth();
15859
- return time.getCalendarMonthSplitInWeeks(year, month).flat();
15860
- });
15861
- const currentMonthValue = computed(() => ({
15862
- month: currentMonth.value.getMonth(),
15863
- year: currentMonth.value.getFullYear(),
15864
- formatted: {
15865
- month: time.getLocalizedNameOfMonth(currentMonth.value, "long"),
15866
- year: time.getLocalizedDateString(currentMonth.value).split("/").pop()
15867
- // Get just the year part
15868
- }
15869
- }));
15870
- const months = computed(() => Array.from({ length: 12 }, (_2, i2) => {
15871
- const date2 = new Date(currentMonthValue.value.year, i2, 1);
15891
+ function useDateState() {
15892
+ const { formatDisplayDate, formatDate } = useFormatting();
15893
+ const formattedDisplayValue2 = computed(() => formatDisplayDate(props2.modelValue));
15894
+ const formattedMin2 = computed(() => formatDate(props2.min));
15895
+ const formattedMax2 = computed(() => formatDate(props2.max));
15896
+ const selectedDate2 = computed(() => {
15897
+ if (!props2.modelValue) return null;
15898
+ return typeof props2.modelValue === "string" ? new Date(props2.modelValue) : props2.modelValue;
15899
+ });
15872
15900
  return {
15873
- name: time.getLocalizedNameOfMonth(date2, "short"),
15874
- value: i2,
15875
- disabled: isDateDisabled(date2)
15901
+ formattedDisplayValue: formattedDisplayValue2,
15902
+ formattedMin: formattedMin2,
15903
+ formattedMax: formattedMax2,
15904
+ selectedDate: selectedDate2
15876
15905
  };
15877
- }));
15878
- const years = computed(() => {
15879
- const startYear = currentMonthValue.value.year - 10;
15880
- return Array.from({ length: 21 }, (_2, i2) => ({
15881
- value: startYear + i2,
15882
- disabled: isYearDisabled(startYear + i2)
15906
+ }
15907
+ const { isDateDisabled, isYearDisabled } = useDateValidation();
15908
+ const { formattedDisplayValue, formattedMin, formattedMax, selectedDate } = useDateState();
15909
+ function useCalendarView() {
15910
+ const currentMonthDays2 = computed(() => {
15911
+ const year = currentMonth.value.getFullYear();
15912
+ const month = currentMonth.value.getMonth();
15913
+ return time.getCalendarMonthSplitInWeeks(year, month).flat();
15914
+ });
15915
+ const currentMonthValue2 = computed(() => ({
15916
+ month: currentMonth.value.getMonth(),
15917
+ year: currentMonth.value.getFullYear(),
15918
+ formatted: {
15919
+ month: time.getLocalizedNameOfMonth(currentMonth.value, "long"),
15920
+ year: time.getLocalizedDateString(currentMonth.value).split("/").pop()
15921
+ }
15883
15922
  }));
15884
- });
15885
- const weekDays = computed(() => {
15886
- const weekStart = /* @__PURE__ */ new Date();
15887
- weekStart.setDate(weekStart.getDate() - weekStart.getDay() + (props2.firstDayOfWeek === WEEK_START_DAY.MONDAY ? 1 : 0));
15888
- return Array.from({ length: 7 }, (_2, i2) => {
15889
- const day = new Date(weekStart);
15890
- day.setDate(weekStart.getDate() + i2);
15891
- return time.getLocalizedNameOfWeekday(day, "short");
15923
+ const months2 = computed(() => Array.from({ length: 12 }, (_2, i2) => {
15924
+ const date2 = new Date(currentMonthValue2.value.year, i2, 1);
15925
+ return {
15926
+ name: time.getLocalizedNameOfMonth(date2, "short"),
15927
+ value: i2,
15928
+ disabled: isDateDisabled(date2)
15929
+ };
15930
+ }));
15931
+ const years2 = computed(() => {
15932
+ const startYear = currentMonthValue2.value.year - 10;
15933
+ return Array.from({ length: 21 }, (_2, i2) => ({
15934
+ value: startYear + i2,
15935
+ disabled: isYearDisabled(startYear + i2)
15936
+ }));
15892
15937
  });
15893
- });
15894
- function isDateDisabled(date2) {
15895
- if (!date2) return true;
15896
- const minDate = props2.min ? new Date(props2.min) : null;
15897
- const maxDate = props2.max ? new Date(props2.max) : null;
15898
- if (minDate && date2 < minDate) return true;
15899
- if (maxDate && date2 > maxDate) return true;
15900
- return false;
15901
- }
15902
- function isYearDisabled(year) {
15903
- const minDate = props2.min ? new Date(props2.min) : null;
15904
- const maxDate = props2.max ? new Date(props2.max) : null;
15905
- if (minDate && year < minDate.getFullYear()) return true;
15906
- if (maxDate && year > maxDate.getFullYear()) return true;
15907
- return false;
15908
- }
15909
- function selectMonth(monthIndex) {
15910
- currentMonth.value = new Date(currentMonth.value.getFullYear(), monthIndex, 1);
15911
- currentView.value = "days";
15912
- }
15913
- function selectYear(year) {
15914
- currentMonth.value = new Date(year, currentMonth.value.getMonth(), 1);
15915
- currentView.value = "months";
15916
- }
15917
- function previousMonth() {
15918
- currentMonth.value = new Date(currentMonth.value.getFullYear(), currentMonth.value.getMonth() - 1, 1);
15938
+ const weekDays2 = computed(() => {
15939
+ const weekStart = /* @__PURE__ */ new Date();
15940
+ weekStart.setDate(weekStart.getDate() - weekStart.getDay() + (props2.firstDayOfWeek === WEEK_START_DAY.MONDAY ? 1 : 0));
15941
+ return Array.from({ length: 7 }, (_2, i2) => {
15942
+ const day = new Date(weekStart);
15943
+ day.setDate(weekStart.getDate() + i2);
15944
+ return time.getLocalizedNameOfWeekday(day, "short");
15945
+ });
15946
+ });
15947
+ const isSelected2 = (date2) => {
15948
+ if (!date2 || !selectedDate.value) return false;
15949
+ return date2.getFullYear() === selectedDate.value.getFullYear() && date2.getMonth() === selectedDate.value.getMonth() && date2.getDate() === selectedDate.value.getDate();
15950
+ };
15951
+ const isToday2 = (date2) => {
15952
+ if (!date2) return false;
15953
+ return time.dateIsToday(date2);
15954
+ };
15955
+ const isNotInMonth2 = (date2) => {
15956
+ return time.isTrailingOrLeadingDate(date2, currentMonth.value.getMonth());
15957
+ };
15958
+ return {
15959
+ currentMonthDays: currentMonthDays2,
15960
+ currentMonthValue: currentMonthValue2,
15961
+ months: months2,
15962
+ years: years2,
15963
+ weekDays: weekDays2,
15964
+ isSelected: isSelected2,
15965
+ isToday: isToday2,
15966
+ isNotInMonth: isNotInMonth2
15967
+ };
15919
15968
  }
15920
- function nextMonth() {
15921
- currentMonth.value = new Date(currentMonth.value.getFullYear(), currentMonth.value.getMonth() + 1, 1);
15969
+ function useNavigation() {
15970
+ const selectMonth2 = (monthIndex) => {
15971
+ currentMonth.value = new Date(currentMonth.value.getFullYear(), monthIndex, 1);
15972
+ currentView.value = "days";
15973
+ };
15974
+ const selectYear2 = (year) => {
15975
+ currentMonth.value = new Date(year, currentMonth.value.getMonth(), 1);
15976
+ currentView.value = "months";
15977
+ };
15978
+ const previousMonth2 = () => {
15979
+ currentMonth.value = new Date(currentMonth.value.getFullYear(), currentMonth.value.getMonth() - 1, 1);
15980
+ };
15981
+ const nextMonth2 = () => {
15982
+ currentMonth.value = new Date(currentMonth.value.getFullYear(), currentMonth.value.getMonth() + 1, 1);
15983
+ };
15984
+ const previousYear2 = () => {
15985
+ const offset2 = currentView.value === "months" ? 1 : 21;
15986
+ currentMonth.value = new Date(currentMonth.value.getFullYear() - offset2, currentMonth.value.getMonth(), 1);
15987
+ };
15988
+ const nextYear2 = () => {
15989
+ const offset2 = currentView.value === "months" ? 1 : 21;
15990
+ currentMonth.value = new Date(currentMonth.value.getFullYear() + offset2, currentMonth.value.getMonth(), 1);
15991
+ };
15992
+ return {
15993
+ selectMonth: selectMonth2,
15994
+ selectYear: selectYear2,
15995
+ previousMonth: previousMonth2,
15996
+ nextMonth: nextMonth2,
15997
+ previousYear: previousYear2,
15998
+ nextYear: nextYear2
15999
+ };
15922
16000
  }
15923
- function previousYear() {
15924
- const offset2 = currentView.value === "months" ? 1 : 21;
15925
- currentMonth.value = new Date(currentMonth.value.getFullYear() - offset2, currentMonth.value.getMonth(), 1);
16001
+ function useTimeHandling() {
16002
+ const hours2 = computed(() => {
16003
+ var _a2;
16004
+ return ((_a2 = selectedDate.value) == null ? void 0 : _a2.getHours()) ?? 0;
16005
+ });
16006
+ const minutes2 = computed(() => {
16007
+ var _a2;
16008
+ return ((_a2 = selectedDate.value) == null ? void 0 : _a2.getMinutes()) ?? 0;
16009
+ });
16010
+ const handleHourInput2 = (value) => {
16011
+ if (!selectedDate.value) return;
16012
+ const newDate = new Date(selectedDate.value);
16013
+ newDate.setHours(value);
16014
+ emit2("update:modelValue", newDate.toISOString());
16015
+ };
16016
+ const handleMinuteInput2 = (value) => {
16017
+ if (!selectedDate.value) return;
16018
+ const newDate = new Date(selectedDate.value);
16019
+ newDate.setMinutes(value);
16020
+ emit2("update:modelValue", newDate.toISOString());
16021
+ };
16022
+ const timezoneDisplay2 = computed(() => {
16023
+ if (!props2.enableTime) return "";
16024
+ try {
16025
+ return (/* @__PURE__ */ new Date()).toLocaleString("en-US", {
16026
+ timeZoneName: "short",
16027
+ timeZone: props2.timezone
16028
+ }).split(" ").pop();
16029
+ } catch {
16030
+ return "UTC";
16031
+ }
16032
+ });
16033
+ return {
16034
+ hours: hours2,
16035
+ minutes: minutes2,
16036
+ handleHourInput: handleHourInput2,
16037
+ handleMinuteInput: handleMinuteInput2,
16038
+ timezoneDisplay: timezoneDisplay2
16039
+ };
15926
16040
  }
15927
- function nextYear() {
15928
- const offset2 = currentView.value === "months" ? 1 : 21;
15929
- currentMonth.value = new Date(currentMonth.value.getFullYear() + offset2, currentMonth.value.getMonth(), 1);
16041
+ function useInputHandling() {
16042
+ const { parseUserInput } = useFormatting();
16043
+ const inputValue2 = ref("");
16044
+ const handleInput2 = (event) => {
16045
+ const input = event.target;
16046
+ inputValue2.value = input.value;
16047
+ const date2 = parseUserInput(input.value);
16048
+ if (date2) {
16049
+ if (props2.enableTime) {
16050
+ emit2("update:modelValue", date2.toISOString());
16051
+ } else {
16052
+ const utcDate = new Date(Date.UTC(date2.getFullYear(), date2.getMonth(), date2.getDate()));
16053
+ emit2("update:modelValue", utcDate.toISOString().split("T")[0]);
16054
+ }
16055
+ }
16056
+ };
16057
+ const handleFocus2 = (e) => {
16058
+ e.preventDefault();
16059
+ e.stopPropagation();
16060
+ isOpen.value = true;
16061
+ };
16062
+ const handleClick2 = (e) => {
16063
+ e.preventDefault();
16064
+ e.stopPropagation();
16065
+ };
16066
+ const handleKeydown2 = (event) => {
16067
+ if (event.key === "Escape") {
16068
+ isOpen.value = false;
16069
+ } else if (event.key === "Enter" && inputValue2.value) {
16070
+ const date2 = parseUserInput(inputValue2.value);
16071
+ if (date2) {
16072
+ if (props2.enableTime) {
16073
+ emit2("update:modelValue", date2.toISOString());
16074
+ } else {
16075
+ const utcDate = new Date(Date.UTC(date2.getFullYear(), date2.getMonth(), date2.getDate()));
16076
+ emit2("update:modelValue", utcDate.toISOString().split("T")[0]);
16077
+ }
16078
+ isOpen.value = false;
16079
+ }
16080
+ }
16081
+ };
16082
+ return {
16083
+ inputValue: inputValue2,
16084
+ handleInput: handleInput2,
16085
+ handleFocus: handleFocus2,
16086
+ handleClick: handleClick2,
16087
+ handleKeydown: handleKeydown2
16088
+ };
15930
16089
  }
16090
+ const { inputValue, handleInput, handleFocus, handleClick, handleKeydown } = useInputHandling();
16091
+ const { currentMonthDays, currentMonthValue, months, years, weekDays, isSelected, isToday, isNotInMonth } = useCalendarView();
16092
+ const { selectMonth, selectYear, previousMonth, nextMonth, previousYear, nextYear } = useNavigation();
16093
+ const { hours, minutes, handleHourInput, handleMinuteInput, timezoneDisplay } = useTimeHandling();
15931
16094
  function selectDate(date2) {
15932
16095
  var _a2, _b;
15933
16096
  if (!date2 || !props2.editMode) return;
16097
+ const tzOffset = (/* @__PURE__ */ new Date()).getTimezoneOffset();
15934
16098
  const newDate = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate());
15935
16099
  if (props2.enableTime) {
15936
16100
  const currentHours = ((_a2 = selectedDate.value) == null ? void 0 : _a2.getHours()) ?? (/* @__PURE__ */ new Date()).getHours();
15937
16101
  const currentMinutes = ((_b = selectedDate.value) == null ? void 0 : _b.getMinutes()) ?? (/* @__PURE__ */ new Date()).getMinutes();
15938
16102
  newDate.setHours(currentHours);
15939
16103
  newDate.setMinutes(currentMinutes);
16104
+ if (props2.timezone === "UTC") {
16105
+ newDate.setMinutes(newDate.getMinutes() + tzOffset);
16106
+ }
15940
16107
  emit2("update:modelValue", newDate.toISOString());
15941
16108
  } else {
15942
- newDate.setUTCHours(0, 0, 0, 0);
15943
- emit2("update:modelValue", newDate.toISOString().split("T")[0]);
16109
+ const utcDate = new Date(Date.UTC(date2.getFullYear(), date2.getMonth(), date2.getDate()));
16110
+ emit2("update:modelValue", utcDate.toISOString().split("T")[0]);
15944
16111
  isOpen.value = false;
15945
16112
  }
15946
16113
  }
15947
- const hours = computed(() => {
15948
- var _a2;
15949
- return ((_a2 = selectedDate.value) == null ? void 0 : _a2.getHours()) ?? 0;
15950
- });
15951
- const minutes = computed(() => {
15952
- var _a2;
15953
- return ((_a2 = selectedDate.value) == null ? void 0 : _a2.getMinutes()) ?? 0;
15954
- });
15955
- function handleHourInput(value) {
15956
- if (!selectedDate.value) return;
15957
- const newDate = new Date(selectedDate.value);
15958
- newDate.setHours(value);
15959
- emit2("update:modelValue", newDate.toISOString());
15960
- }
15961
- function handleMinuteInput(value) {
15962
- if (!selectedDate.value) return;
15963
- const newDate = new Date(selectedDate.value);
15964
- newDate.setMinutes(value);
15965
- emit2("update:modelValue", newDate.toISOString());
15966
- }
15967
- function isSelected(date2) {
15968
- if (!date2 || !selectedDate.value) return false;
15969
- return date2.toISOString().split("T")[0] === selectedDate.value.toISOString().split("T")[0];
15970
- }
15971
- function isToday(date2) {
15972
- if (!date2) return false;
15973
- return time.dateIsToday(date2);
15974
- }
15975
- const timezoneDisplay = computed(() => {
15976
- if (!props2.enableTime) return "";
15977
- try {
15978
- return (/* @__PURE__ */ new Date()).toLocaleString("en-US", {
15979
- timeZoneName: "short",
15980
- timeZone: props2.timezone
15981
- }).split(" ").pop();
15982
- } catch {
15983
- return "UTC";
15984
- }
16114
+ const datePickerRef = ref(null);
16115
+ const calendarRef = ref(null);
16116
+ onMounted(() => {
16117
+ const handleDocumentClick = (e) => {
16118
+ var _a2, _b;
16119
+ const target = e.target;
16120
+ if (!((_a2 = datePickerRef.value) == null ? void 0 : _a2.contains(target)) && !((_b = calendarRef.value) == null ? void 0 : _b.contains(target))) {
16121
+ isOpen.value = false;
16122
+ }
16123
+ };
16124
+ document.addEventListener("click", handleDocumentClick);
16125
+ onBeforeUnmount(() => {
16126
+ document.removeEventListener("click", handleDocumentClick);
16127
+ });
15985
16128
  });
15986
- function isNotInMonth(date2) {
15987
- return time.isTrailingOrLeadingDate(date2, currentMonth.value.getMonth());
15988
- }
15989
16129
  return (_ctx, _cache) => {
15990
16130
  return openBlock(), createElementBlock("div", {
15991
16131
  class: normalizeClass(["bagel-input", { small: _ctx.small }]),
15992
- title: _ctx.label
16132
+ title: _ctx.label,
16133
+ onFocusin: _cache[6] || (_cache[6] = //@ts-ignore
16134
+ (...args) => unref(handleFocus) && unref(handleFocus)(...args))
15993
16135
  }, [
15994
16136
  _ctx.label ? (openBlock(), createElementBlock("label", _hoisted_2$t, [
15995
16137
  createTextVNode(toDisplayString(_ctx.label) + " ", 1),
15996
16138
  _ctx.required ? (openBlock(), createElementBlock("span", _hoisted_3$o, "*")) : createCommentVNode("", true)
15997
16139
  ])) : createCommentVNode("", true),
15998
16140
  createVNode(unref(_sfc_main$V), {
15999
- shown: unref(isOpen),
16141
+ shown: isOpen.value,
16000
16142
  placement: "bottom-start",
16001
- onApplyShow: _cache[4] || (_cache[4] = ($event) => isRef(isOpen) ? isOpen.value = true : isOpen = true),
16002
- onApplyHide: _cache[5] || (_cache[5] = ($event) => isRef(isOpen) ? isOpen.value = false : isOpen = false)
16143
+ autoHide: false,
16144
+ triggers: ["click"]
16003
16145
  }, {
16004
16146
  trigger: withCtx(() => [
16005
- createElementVNode("div", _hoisted_4$g, [
16147
+ createElementVNode("div", {
16148
+ ref_key: "datePickerRef",
16149
+ ref: datePickerRef,
16150
+ class: "date-picker-container",
16151
+ onMousedown: _cache[0] || (_cache[0] = withModifiers(() => {
16152
+ }, ["stop"])),
16153
+ onClick: _cache[1] || (_cache[1] = withModifiers(() => {
16154
+ }, ["stop"]))
16155
+ }, [
16006
16156
  createVNode(unref(TextInput), {
16007
- modelValue: formattedDisplayValue.value,
16157
+ modelValue: unref(formattedDisplayValue),
16008
16158
  icon: "calendar",
16009
- min: formattedMin.value,
16010
- max: formattedMax.value,
16159
+ min: unref(formattedMin),
16160
+ max: unref(formattedMax),
16011
16161
  required: _ctx.required,
16012
16162
  disabled: !_ctx.editMode,
16013
16163
  class: normalizeClass(["date-input", {
16014
16164
  "txt-center": _ctx.center
16015
16165
  }]),
16016
- readonly: "",
16017
- onClick: _cache[0] || (_cache[0] = ($event) => isRef(isOpen) ? isOpen.value = true : isOpen = true)
16018
- }, null, 8, ["modelValue", "min", "max", "required", "disabled", "class"])
16019
- ])
16166
+ readonly: false,
16167
+ onInput: unref(handleInput),
16168
+ onFocus: unref(handleFocus),
16169
+ onClick: unref(handleClick),
16170
+ onKeydown: unref(handleKeydown)
16171
+ }, null, 8, ["modelValue", "min", "max", "required", "disabled", "class", "onInput", "onFocus", "onClick", "onKeydown"])
16172
+ ], 544)
16020
16173
  ]),
16021
16174
  default: withCtx(() => [
16022
- createElementVNode("div", _hoisted_5$f, [
16023
- createElementVNode("div", _hoisted_6$c, [
16024
- createElementVNode("div", _hoisted_7$9, [
16025
- unref(currentView) === "days" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
16175
+ createElementVNode("div", {
16176
+ ref_key: "calendarRef",
16177
+ ref: calendarRef,
16178
+ class: "ltr flex gap-075 p-05 m_flex-wrap calendar-container justify-content-center h-100p",
16179
+ onClick: _cache[5] || (_cache[5] = withModifiers(() => {
16180
+ }, ["stop"]))
16181
+ }, [
16182
+ createElementVNode("div", _hoisted_4$g, [
16183
+ createElementVNode("div", _hoisted_5$f, [
16184
+ currentView.value === "days" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
16026
16185
  createVNode(unref(Btn), {
16027
16186
  flat: "",
16028
16187
  icon: "chevron_left",
16029
- onClick: previousMonth
16030
- }),
16031
- createElementVNode("div", _hoisted_8$6, [
16188
+ onClick: unref(previousMonth)
16189
+ }, null, 8, ["onClick"]),
16190
+ createElementVNode("div", _hoisted_6$c, [
16032
16191
  createVNode(unref(Btn), {
16033
16192
  flat: "",
16034
16193
  class: "month-btn",
16035
- onClick: _cache[1] || (_cache[1] = ($event) => isRef(currentView) ? currentView.value = "months" : currentView = "months")
16194
+ onClick: _cache[2] || (_cache[2] = ($event) => currentView.value = "months")
16036
16195
  }, {
16037
16196
  default: withCtx(() => [
16038
- createTextVNode(toDisplayString(currentMonthValue.value.formatted.month), 1)
16197
+ createTextVNode(toDisplayString(unref(currentMonthValue).formatted.month), 1)
16039
16198
  ]),
16040
16199
  _: 1
16041
16200
  }),
16042
16201
  createVNode(unref(Btn), {
16043
16202
  flat: "",
16044
16203
  class: "year-btn",
16045
- onClick: _cache[2] || (_cache[2] = ($event) => isRef(currentView) ? currentView.value = "years" : currentView = "years")
16204
+ onClick: _cache[3] || (_cache[3] = ($event) => currentView.value = "years")
16046
16205
  }, {
16047
16206
  default: withCtx(() => [
16048
- createTextVNode(toDisplayString(currentMonthValue.value.formatted.year), 1)
16207
+ createTextVNode(toDisplayString(unref(currentMonthValue).formatted.year), 1)
16049
16208
  ]),
16050
16209
  _: 1
16051
16210
  })
@@ -16053,114 +16212,114 @@ const _sfc_main$M = /* @__PURE__ */ defineComponent({
16053
16212
  createVNode(unref(Btn), {
16054
16213
  flat: "",
16055
16214
  icon: "chevron_right",
16056
- onClick: nextMonth
16057
- })
16215
+ onClick: unref(nextMonth)
16216
+ }, null, 8, ["onClick"])
16058
16217
  ], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
16059
16218
  createVNode(unref(Btn), {
16060
16219
  flat: "",
16061
16220
  icon: "chevron_left",
16062
- onClick: previousYear
16063
- }),
16064
- createElementVNode("span", _hoisted_9$5, toDisplayString(currentMonthValue.value.formatted.year), 1),
16221
+ onClick: unref(previousYear)
16222
+ }, null, 8, ["onClick"]),
16223
+ createElementVNode("span", _hoisted_7$9, toDisplayString(unref(currentMonthValue).formatted.year), 1),
16065
16224
  createVNode(unref(Btn), {
16066
16225
  flat: "",
16067
16226
  icon: "chevron_right",
16068
- onClick: nextYear
16069
- })
16227
+ onClick: unref(nextYear)
16228
+ }, null, 8, ["onClick"])
16070
16229
  ], 64))
16071
16230
  ]),
16072
- unref(currentView) === "days" ? (openBlock(), createElementBlock("div", _hoisted_10$5, [
16073
- (openBlock(true), createElementBlock(Fragment, null, renderList(weekDays.value, (day) => {
16231
+ currentView.value === "days" ? (openBlock(), createElementBlock("div", _hoisted_8$6, [
16232
+ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(weekDays), (day) => {
16074
16233
  return openBlock(), createElementBlock("div", {
16075
16234
  key: day,
16076
16235
  class: "txt-center txt-12 opacity-6"
16077
16236
  }, toDisplayString(day), 1);
16078
16237
  }), 128)),
16079
- (openBlock(true), createElementBlock(Fragment, null, renderList(currentMonthDays.value, (date2) => {
16238
+ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(currentMonthDays), (date2) => {
16080
16239
  return openBlock(), createElementBlock("button", {
16081
16240
  key: date2 == null ? void 0 : date2.toISOString(),
16082
16241
  type: "button",
16083
16242
  class: normalizeClass(["day aspect-ratio-1 flex align-items-center justify-content-center pointer round txt14 p-0", {
16084
- "selected": isSelected(date2),
16085
- "today": isToday(date2),
16086
- "disabled": isDateDisabled(date2),
16087
- "not-in-month": isNotInMonth(date2)
16243
+ "selected": unref(isSelected)(date2),
16244
+ "today": unref(isToday)(date2),
16245
+ "disabled": unref(isDateDisabled)(date2),
16246
+ "not-in-month": unref(isNotInMonth)(date2)
16088
16247
  }]),
16089
- disabled: isDateDisabled(date2),
16248
+ disabled: unref(isDateDisabled)(date2),
16090
16249
  onClick: ($event) => selectDate(date2)
16091
- }, toDisplayString(date2 == null ? void 0 : date2.getDate()), 11, _hoisted_11$5);
16250
+ }, toDisplayString(date2 == null ? void 0 : date2.getDate()), 11, _hoisted_9$5);
16092
16251
  }), 128))
16093
- ])) : unref(currentView) === "months" ? (openBlock(), createElementBlock("div", _hoisted_12$5, [
16094
- (openBlock(true), createElementBlock(Fragment, null, renderList(months.value, (month) => {
16252
+ ])) : currentView.value === "months" ? (openBlock(), createElementBlock("div", _hoisted_10$5, [
16253
+ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(months), (month) => {
16095
16254
  return openBlock(), createElementBlock("button", {
16096
16255
  key: month.value,
16097
16256
  class: normalizeClass(["month-item flex align-items-center justify-content-center pointer rounded p-05 txt14 border-none", {
16098
- selected: month.value === currentMonthValue.value.month,
16257
+ selected: month.value === unref(currentMonthValue).month,
16099
16258
  disabled: month.disabled
16100
16259
  }]),
16101
16260
  disabled: month.disabled,
16102
- onClick: ($event) => selectMonth(month.value)
16103
- }, toDisplayString(month.name), 11, _hoisted_13$4);
16261
+ onClick: ($event) => unref(selectMonth)(month.value)
16262
+ }, toDisplayString(month.name), 11, _hoisted_11$5);
16104
16263
  }), 128))
16105
- ])) : (openBlock(), createElementBlock("div", _hoisted_14$4, [
16106
- (openBlock(true), createElementBlock(Fragment, null, renderList(years.value, (year) => {
16264
+ ])) : (openBlock(), createElementBlock("div", _hoisted_12$5, [
16265
+ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(years), (year) => {
16107
16266
  return openBlock(), createElementBlock("button", {
16108
16267
  key: year.value,
16109
16268
  class: normalizeClass(["year-item flex align-items-center justify-content-center pointer rounded p-05 txt14 border-none", {
16110
- selected: year.value === currentMonthValue.value.year,
16269
+ selected: year.value === unref(currentMonthValue).year,
16111
16270
  disabled: year.disabled
16112
16271
  }]),
16113
16272
  disabled: year.disabled,
16114
- onClick: ($event) => selectYear(year.value)
16115
- }, toDisplayString(year.value), 11, _hoisted_15$4);
16273
+ onClick: ($event) => unref(selectYear)(year.value)
16274
+ }, toDisplayString(year.value), 11, _hoisted_13$4);
16116
16275
  }), 128))
16117
16276
  ]))
16118
16277
  ]),
16119
- _ctx.enableTime && unref(currentView) === "days" ? (openBlock(), createElementBlock("div", _hoisted_16$4, [
16120
- createElementVNode("div", _hoisted_17$4, [
16278
+ _ctx.enableTime && currentView.value === "days" ? (openBlock(), createElementBlock("div", _hoisted_14$4, [
16279
+ createElementVNode("div", _hoisted_15$4, [
16121
16280
  createVNode(unref(NumberInput), {
16122
16281
  center: "",
16123
- "model-value": hours.value,
16124
- disabled: !selectedDate.value,
16282
+ "model-value": unref(hours),
16283
+ disabled: !unref(selectedDate),
16125
16284
  min: 0,
16126
16285
  max: 23,
16127
16286
  layout: "vertical",
16128
16287
  padZero: 2,
16129
- "onUpdate:modelValue": handleHourInput
16130
- }, null, 8, ["model-value", "disabled"]),
16131
- _cache[6] || (_cache[6] = createElementVNode("p", { class: "pb-075" }, " : ", -1)),
16288
+ "onUpdate:modelValue": unref(handleHourInput)
16289
+ }, null, 8, ["model-value", "disabled", "onUpdate:modelValue"]),
16290
+ _cache[7] || (_cache[7] = createElementVNode("p", { class: "pb-075" }, " : ", -1)),
16132
16291
  createVNode(unref(NumberInput), {
16133
16292
  center: "",
16134
- "model-value": minutes.value,
16135
- disabled: !selectedDate.value,
16293
+ "model-value": unref(minutes),
16294
+ disabled: !unref(selectedDate),
16136
16295
  min: 0,
16137
16296
  max: 59,
16138
16297
  padZero: 2,
16139
16298
  layout: "vertical",
16140
- "onUpdate:modelValue": handleMinuteInput
16141
- }, null, 8, ["model-value", "disabled"])
16299
+ "onUpdate:modelValue": unref(handleMinuteInput)
16300
+ }, null, 8, ["model-value", "disabled", "onUpdate:modelValue"])
16142
16301
  ]),
16143
- createElementVNode("span", _hoisted_18$2, toDisplayString(timezoneDisplay.value), 1),
16144
- selectedDate.value ? (openBlock(), createBlock(unref(Btn), {
16302
+ createElementVNode("span", _hoisted_16$4, toDisplayString(unref(timezoneDisplay)), 1),
16303
+ unref(selectedDate) ? (openBlock(), createBlock(unref(Btn), {
16145
16304
  key: 0,
16146
16305
  flat: "",
16147
- onClick: _cache[3] || (_cache[3] = ($event) => isRef(isOpen) ? isOpen.value = false : isOpen = false)
16306
+ onClick: _cache[4] || (_cache[4] = ($event) => isOpen.value = false)
16148
16307
  }, {
16149
- default: withCtx(() => _cache[7] || (_cache[7] = [
16308
+ default: withCtx(() => _cache[8] || (_cache[8] = [
16150
16309
  createTextVNode(" Done ")
16151
16310
  ])),
16152
16311
  _: 1
16153
16312
  })) : createCommentVNode("", true)
16154
16313
  ])) : createCommentVNode("", true)
16155
- ])
16314
+ ], 512)
16156
16315
  ]),
16157
16316
  _: 1
16158
16317
  }, 8, ["shown"])
16159
- ], 10, _hoisted_1$F);
16318
+ ], 42, _hoisted_1$F);
16160
16319
  };
16161
16320
  }
16162
16321
  });
16163
- const DateInput = /* @__PURE__ */ _export_sfc(_sfc_main$M, [["__scopeId", "data-v-a2f98d6e"]]);
16322
+ const DateInput = /* @__PURE__ */ _export_sfc(_sfc_main$M, [["__scopeId", "data-v-5d1b6a15"]]);
16164
16323
  const _hoisted_1$E = ["title"];
16165
16324
  const _hoisted_2$s = { key: 0 };
16166
16325
  const _hoisted_3$n = {
@@ -25987,7 +26146,7 @@ const _sfc_main$G = /* @__PURE__ */ defineComponent({
25987
26146
  }
25988
26147
  });
25989
26148
  const OTP = /* @__PURE__ */ _export_sfc(_sfc_main$G, [["__scopeId", "data-v-8e8db33e"]]);
25990
- const _hoisted_1$y = { class: "relative" };
26149
+ const _hoisted_1$y = { class: "relative passwordInput" };
25991
26150
  const _hoisted_2$n = { class: "m-password position-bottom-end flex column justify-content-center" };
25992
26151
  const _sfc_main$F = /* @__PURE__ */ defineComponent({
25993
26152
  __name: "PasswordInput",
@@ -26402,53 +26561,27 @@ const _sfc_main$C = /* @__PURE__ */ defineComponent({
26402
26561
  }
26403
26562
  });
26404
26563
  const RangeInput = /* @__PURE__ */ _export_sfc(_sfc_main$C, [["__scopeId", "data-v-25d991e5"]]);
26405
- const tableTools = [
26406
- "mergeCells",
26407
- "splitCells",
26408
- "addRowBefore",
26409
- "addRowAfter",
26410
- "deleteRow",
26411
- "insertColumnLeft",
26412
- "insertColumnRight",
26413
- "deleteColumn",
26414
- "alignLeft",
26415
- "alignCenter",
26416
- "alignRight",
26417
- "alignJustify",
26418
- "deleteTable"
26419
- ];
26420
- const defaultToolbarConfig = [
26564
+ const basicToolbarConfig = [
26421
26565
  "h2",
26422
26566
  "h3",
26423
26567
  "h4",
26424
26568
  "h5",
26425
26569
  "h6",
26426
26570
  "separator",
26427
- "bold",
26428
- "italic",
26429
- "underline",
26430
- "separator",
26431
- "fontColor",
26432
- "bgColor",
26433
- "separator",
26434
26571
  "p",
26435
26572
  "blockquote",
26436
26573
  "orderedList",
26437
26574
  "unorderedList",
26438
- "indent",
26439
- "outdent",
26575
+ "separator",
26576
+ "bold",
26577
+ "italic",
26578
+ "underline",
26440
26579
  "separator",
26441
26580
  "link",
26442
26581
  "image",
26443
- // 'youtube',
26444
- "separator",
26445
- "splitView",
26582
+ "embed",
26446
26583
  "clear",
26447
- "insertTable",
26448
- ...tableTools,
26449
- "separator",
26450
- "undo",
26451
- "redo",
26584
+ "splitView",
26452
26585
  "fullScreen"
26453
26586
  ];
26454
26587
  const toolbarOptions = [
@@ -26466,7 +26599,7 @@ const toolbarOptions = [
26466
26599
  { name: "unorderedList", label: "Unordered List", icon: "format_list_bulleted" },
26467
26600
  { name: "link", label: "Link", icon: "add_link" },
26468
26601
  { name: "image", label: "Image", icon: "add_photo_alternate" },
26469
- { name: "youtube", label: "YouTube", icon: "youtube_activity" },
26602
+ { name: "embed", label: "Embed", icon: "media_link" },
26470
26603
  { name: "splitView", label: "Split View", icon: "code" },
26471
26604
  { name: "clear", label: "Clear Formatting", icon: "format_clear" },
26472
26605
  { name: "alignLeft", label: "Align Left", icon: "format_align_left" },
@@ -26556,7 +26689,7 @@ const _hoisted_1$t = {
26556
26689
  const _sfc_main$A = /* @__PURE__ */ defineComponent({
26557
26690
  __name: "EditorToolbar",
26558
26691
  props: {
26559
- config: { default: defaultToolbarConfig },
26692
+ config: { default: basicToolbarConfig },
26560
26693
  selectedStyles: {}
26561
26694
  },
26562
26695
  emits: ["action"],
@@ -26611,45 +26744,50 @@ const _sfc_main$A = /* @__PURE__ */ defineComponent({
26611
26744
  };
26612
26745
  }
26613
26746
  });
26614
- const EditorToolbar = /* @__PURE__ */ _export_sfc(_sfc_main$A, [["__scopeId", "data-v-bcd681b9"]]);
26615
- function createCommandExecutor(state2, commands) {
26616
- return {
26617
- execute(command, value) {
26618
- const cmd = commands[command];
26619
- if (cmd) {
26620
- cmd.execute(state2, value);
26621
- }
26622
- },
26623
- isActive(command) {
26624
- var _a2;
26625
- const cmd = commands[command];
26626
- return ((_a2 = cmd.isActive) == null ? void 0 : _a2.call(cmd, state2)) || false;
26627
- },
26628
- getValue(command) {
26629
- var _a2;
26630
- const cmd = commands[command];
26631
- return ((_a2 = cmd.getValue) == null ? void 0 : _a2.call(cmd, state2)) || null;
26632
- }
26633
- };
26634
- }
26747
+ const EditorToolbar = /* @__PURE__ */ _export_sfc(_sfc_main$A, [["__scopeId", "data-v-9d8a6eb6"]]);
26635
26748
  function isStyleActive(style, doc) {
26636
26749
  const selection = doc.getSelection();
26637
26750
  if (!selection || !selection.rangeCount) return false;
26638
26751
  const range2 = selection.getRangeAt(0);
26639
26752
  const container = range2.commonAncestorContainer;
26640
- const parent = container.nodeType === 3 ? container.parentElement : container;
26753
+ const parent = container.nodeType === Node.TEXT_NODE ? container.parentElement : container;
26641
26754
  if (!parent) return false;
26642
- const checkParent = (element, tags) => {
26643
- if (!element) return false;
26644
- if (tags.includes(element.tagName.toLowerCase())) return true;
26645
- return checkParent(element.parentElement, tags);
26646
- };
26647
- const styleTags = {
26755
+ const checkParent = (element, tags2) => {
26756
+ if (!element || !element.tagName) return false;
26757
+ const tagName = element.tagName.toLowerCase();
26758
+ if (tags2.includes(tagName)) return true;
26759
+ return checkParent(element.parentElement, tags2);
26760
+ };
26761
+ const styleMappings = {
26762
+ // Inline styles
26648
26763
  bold: ["strong", "b"],
26649
26764
  italic: ["em", "i"],
26650
- underline: ["u"]
26651
- };
26652
- return checkParent(parent, styleTags[style] ?? [style]);
26765
+ underline: ["u"],
26766
+ // Block styles
26767
+ h1: ["h1"],
26768
+ h2: ["h2"],
26769
+ h3: ["h3"],
26770
+ h4: ["h4"],
26771
+ h5: ["h5"],
26772
+ h6: ["h6"],
26773
+ p: ["p"],
26774
+ blockquote: ["blockquote"],
26775
+ // List styles
26776
+ orderedList: ["ol"],
26777
+ unorderedList: ["ul"]
26778
+ };
26779
+ if (["splitView", "codeView", "fullScreen"].includes(style)) {
26780
+ return false;
26781
+ }
26782
+ if (style === "orderedList" || style === "unorderedList") {
26783
+ const listParent = parent.closest(style === "orderedList" ? "ol" : "ul");
26784
+ return !!listParent;
26785
+ }
26786
+ const tags = styleMappings[style];
26787
+ if (tags) {
26788
+ return checkParent(parent, tags);
26789
+ }
26790
+ return checkParent(parent, [style]);
26653
26791
  }
26654
26792
  function analyzeSelection(doc, range2) {
26655
26793
  const container = range2.commonAncestorContainer;
@@ -26909,6 +27047,52 @@ function insertLink(modal, state2) {
26909
27047
  }
26910
27048
  });
26911
27049
  }
27050
+ function insertEmbed(modal, state2) {
27051
+ const { range: range2, doc } = state2;
27052
+ if (!range2 || !doc) return;
27053
+ modal.showModalForm({
27054
+ title: "Insert Embed",
27055
+ schema: [
27056
+ { id: "url", $el: "text", label: "URL", attrs: { placeholder: "Enter URL (YouTube, Vimeo, etc.)" } },
27057
+ frmRow(
27058
+ numField("width", "Width", { min: 200, placeholder: "560" }),
27059
+ numField("height", "Height", { min: 200, placeholder: "315" })
27060
+ ),
27061
+ { id: "allowFullscreen", $el: "check", label: "Allow Fullscreen", value: true }
27062
+ ],
27063
+ onSubmit: (data2) => {
27064
+ if (!data2.url) return;
27065
+ const url = new URL(data2.url);
27066
+ let embedUrl = data2.url;
27067
+ if (url.hostname.includes("youtube.com") || url.hostname === "youtu.be") {
27068
+ const videoId = url.hostname === "youtu.be" ? url.pathname.slice(1) : url.searchParams.get("v");
27069
+ if (videoId) {
27070
+ embedUrl = `https://www.youtube.com/embed/${videoId}`;
27071
+ }
27072
+ } else if (url.hostname.includes("vimeo.com")) {
27073
+ const videoId = url.pathname.split("/").pop();
27074
+ if (videoId) {
27075
+ embedUrl = `https://player.vimeo.com/video/${videoId}`;
27076
+ }
27077
+ }
27078
+ const iframe = doc.createElement("iframe");
27079
+ Object.assign(iframe, {
27080
+ src: embedUrl,
27081
+ width: data2.width || 560,
27082
+ height: data2.height || 315,
27083
+ frameBorder: "0",
27084
+ allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
27085
+ allowFullscreen: data2.allowFullscreen
27086
+ });
27087
+ const wrapper = doc.createElement("div");
27088
+ wrapper.style.textAlign = "center";
27089
+ wrapper.style.margin = "1em 0";
27090
+ wrapper.appendChild(iframe);
27091
+ range2.deleteContents();
27092
+ range2.insertNode(wrapper);
27093
+ }
27094
+ });
27095
+ }
26912
27096
  function insertTable(rows, cols, state2) {
26913
27097
  if (!state2.doc) return;
26914
27098
  const table = state2.doc.createElement("table");
@@ -27030,145 +27214,393 @@ function alignColumn(range2, alignment) {
27030
27214
  }
27031
27215
  }
27032
27216
  }
27033
- function useCommands(state2, debug) {
27034
- const format2 = () => formatting(state2);
27035
- const commands = {
27036
- // Text formatting commands
27037
- bold: {
27038
- name: "Bold",
27039
- execute: (state22) => {
27040
- format2().text("bold");
27041
- },
27042
- isActive: (state22) => state22.selectedStyles.has("bold")
27043
- },
27044
- italic: {
27045
- name: "Italic",
27046
- execute: (state22) => {
27047
- format2().text("italic");
27048
- },
27049
- isActive: (state22) => state22.selectedStyles.has("italic")
27050
- },
27051
- underline: {
27052
- name: "Underline",
27053
- execute: (state22) => {
27054
- format2().text("underline");
27055
- },
27056
- isActive: (state22) => state22.selectedStyles.has("underline")
27057
- },
27058
- // Block formatting commands
27059
- h1: { name: "Heading 1", execute: (state22) => {
27060
- format2().block("h1", "h1");
27061
- }, isActive: (state22) => state22.selectedStyles.has("h1") },
27062
- h2: { name: "Heading 2", execute: (state22) => {
27063
- format2().block("h2", "h2");
27064
- }, isActive: (state22) => state22.selectedStyles.has("h2") },
27065
- h3: { name: "Heading 3", execute: (state22) => {
27066
- format2().block("h3", "h3");
27067
- }, isActive: (state22) => state22.selectedStyles.has("h3") },
27068
- h4: { name: "Heading 4", execute: (state22) => {
27069
- format2().block("h4", "h4");
27070
- }, isActive: (state22) => state22.selectedStyles.has("h4") },
27071
- h5: { name: "Heading 5", execute: (state22) => {
27072
- format2().block("h5", "h5");
27073
- }, isActive: (state22) => state22.selectedStyles.has("h5") },
27074
- h6: { name: "Heading 6", execute: (state22) => {
27075
- format2().block("h6", "h6");
27076
- }, isActive: (state22) => state22.selectedStyles.has("h6") },
27077
- p: { name: "Paragraph", execute: (state22) => {
27078
- format2().block("p", "p");
27079
- }, isActive: (state22) => state22.selectedStyles.has("p") },
27080
- blockquote: {
27081
- name: "Blockquote",
27082
- execute: (state22) => {
27083
- format2().block("blockquote", "blockquote");
27084
- },
27085
- isActive: (state22) => state22.selectedStyles.has("blockquote")
27217
+ function createCommand(name, execute, isActive) {
27218
+ return {
27219
+ name,
27220
+ execute: (state2, value) => {
27221
+ if (!state2.doc) return;
27222
+ execute(state2, value);
27086
27223
  },
27087
- // List commands
27088
- orderedList: {
27089
- name: "Ordered List",
27090
- execute: (state22) => {
27091
- format2().list("orderedList");
27092
- },
27093
- isActive: (state22) => state22.selectedStyles.has("orderedList")
27224
+ isActive
27225
+ };
27226
+ }
27227
+ function createFormattingCommand(state2, type3, command, tag) {
27228
+ const format2 = formatting(state2);
27229
+ return createCommand(
27230
+ command,
27231
+ () => {
27232
+ var _a2, _b;
27233
+ if (!state2.doc) return;
27234
+ if (type3 === "text") {
27235
+ if (command === "bold") state2.doc.execCommand("bold", false);
27236
+ else if (command === "italic") state2.doc.execCommand("italic", false);
27237
+ else if (command === "underline") state2.doc.execCommand("underline", false);
27238
+ else format2.text(command);
27239
+ } else if (type3 === "block") {
27240
+ state2.doc.execCommand("formatBlock", false, `<${command}>`);
27241
+ } else if (type3 === "list") {
27242
+ const selection = state2.doc.getSelection();
27243
+ if (!selection || !selection.rangeCount) return;
27244
+ const range2 = selection.getRangeAt(0);
27245
+ if (range2.collapsed && (!((_a2 = range2.startContainer.textContent) == null ? void 0 : _a2.trim()) || range2.startContainer === state2.doc.body)) {
27246
+ const list = state2.doc.createElement(command === "orderedList" ? "ol" : "ul");
27247
+ const li = state2.doc.createElement("li");
27248
+ li.innerHTML = "&nbsp;<br>";
27249
+ list.appendChild(li);
27250
+ const currentBlock = range2.startContainer.nodeType === 1 ? range2.startContainer : range2.startContainer.parentElement;
27251
+ if ((currentBlock == null ? void 0 : currentBlock.tagName.toLowerCase()) === "p" && isNodeEmpty$1(currentBlock)) {
27252
+ (_b = currentBlock.parentNode) == null ? void 0 : _b.replaceChild(list, currentBlock);
27253
+ } else {
27254
+ range2.insertNode(list);
27255
+ }
27256
+ range2.selectNodeContents(li);
27257
+ range2.collapse(true);
27258
+ selection.removeAllRanges();
27259
+ selection.addRange(range2);
27260
+ } else {
27261
+ state2.doc.execCommand(
27262
+ command === "orderedList" ? "insertOrderedList" : "insertUnorderedList",
27263
+ false
27264
+ );
27265
+ }
27266
+ }
27094
27267
  },
27095
- unorderedList: {
27096
- name: "Unordered List",
27097
- execute: (state22) => {
27098
- format2().list("unorderedList");
27099
- },
27100
- isActive: (state22) => state22.selectedStyles.has("unorderedList")
27101
- },
27102
- // Table commands
27103
- insertTable: {
27104
- name: "Insert Table",
27105
- execute: (state22, value) => {
27106
- const [rows, cols] = (value == null ? void 0 : value.split("x").map(Number)) || [3, 3];
27107
- insertTable(rows, cols, state22);
27108
- }
27109
- },
27110
- deleteTable: { name: "Delete Table", execute: (state22) => state22.range && deleteTable(state22.range) },
27111
- mergeCells: { name: "Merge Cells", execute: (state22) => state22.range && state22.doc && mergeCells(state22.range, state22.doc) },
27112
- splitCells: { name: "Split Cells", execute: (state22) => state22.range && state22.doc && splitCell(state22.range, state22.doc) },
27113
- addRowBefore: { name: "Add Row Before", execute: (state22) => state22.range && state22.doc && addRow("before", state22.range, state22.doc) },
27114
- addRowAfter: { name: "Add Row After", execute: (state22) => state22.range && state22.doc && addRow("after", state22.range, state22.doc) },
27115
- deleteRow: { name: "Delete Row", execute: (state22) => state22.range && deleteRow(state22.range) },
27116
- insertColumnLeft: { name: "Insert Column Left", execute: (state22) => state22.range && insertColumn("before", state22.range) },
27117
- insertColumnRight: { name: "Insert Column Right", execute: (state22) => state22.range && insertColumn("after", state22.range) },
27118
- deleteColumn: { name: "Delete Column", execute: (state22) => state22.range && deleteColumn(state22.range) },
27119
- // Alignment commands
27120
- alignLeft: { name: "Align Left", execute: (state22) => state22.range && alignColumn(state22.range, "left") },
27121
- alignCenter: { name: "Align Center", execute: (state22) => state22.range && alignColumn(state22.range, "center") },
27122
- alignRight: { name: "Align Right", execute: (state22) => state22.range && alignColumn(state22.range, "right") },
27123
- alignJustify: { name: "Align Justify", execute: (state22) => state22.range && alignColumn(state22.range, "justify") },
27124
- // Media commands
27125
- image: { name: "Insert Image", execute: (state22) => state22.modal && insertImage(state22.modal, state22) },
27126
- link: { name: "Insert Link", execute: (state22) => state22.modal && state22.range && insertLink(state22.modal, state22) },
27127
- // Other commands
27128
- clear: { name: "Clear Formatting", execute: (state22) => {
27129
- format2().clear();
27130
- } },
27131
- indent: { name: "Indent", execute: (state22) => {
27132
- format2().text("indent");
27133
- } },
27134
- outdent: { name: "Outdent", execute: (state22) => {
27135
- format2().text("outdent");
27136
- } },
27137
- fullScreen: {
27138
- name: "Full Screen",
27139
- execute: (state22) => {
27140
- state22.isFullscreen = !state22.isFullscreen;
27141
- },
27142
- isActive: (state22) => state22.isFullscreen
27268
+ () => state2.selectedStyles.has(command)
27269
+ );
27270
+ }
27271
+ function isNodeEmpty$1(node) {
27272
+ var _a2;
27273
+ const text = ((_a2 = node.textContent) == null ? void 0 : _a2.trim()) || "";
27274
+ if (text) return false;
27275
+ const brElements = node.getElementsByTagName("br");
27276
+ if (brElements.length === 0) return true;
27277
+ return brElements.length === 1 && node.childNodes.length === 1;
27278
+ }
27279
+ function createCommandRegistry(state2) {
27280
+ const format2 = formatting(state2);
27281
+ const historyCommands = {
27282
+ undo: createCommand("Undo", () => {
27283
+ var _a2;
27284
+ return (_a2 = state2.doc) == null ? void 0 : _a2.execCommand("undo", false);
27285
+ }),
27286
+ redo: createCommand("Redo", () => {
27287
+ var _a2;
27288
+ return (_a2 = state2.doc) == null ? void 0 : _a2.execCommand("redo", false);
27289
+ })
27290
+ };
27291
+ const textCommands = ["bold", "italic", "underline"].reduce((acc, cmd) => ({
27292
+ ...acc,
27293
+ [cmd]: createFormattingCommand(state2, "text", cmd)
27294
+ }), {});
27295
+ const headingCommands = ["h1", "h2", "h3", "h4", "h5", "h6"].reduce((acc, cmd) => ({
27296
+ ...acc,
27297
+ [cmd]: createFormattingCommand(state2, "block", cmd)
27298
+ }), {});
27299
+ const blockCommands = {
27300
+ p: createFormattingCommand(state2, "block", "p"),
27301
+ blockquote: createFormattingCommand(state2, "block", "blockquote")
27302
+ };
27303
+ const listCommands = {
27304
+ orderedList: createFormattingCommand(state2, "list", "orderedList"),
27305
+ unorderedList: createFormattingCommand(state2, "list", "unorderedList")
27306
+ };
27307
+ const tableCommands = {
27308
+ insertTable: createCommand("Insert Table", (state22, value) => {
27309
+ const [rows, cols] = (value == null ? void 0 : value.split("x").map(Number)) || [3, 3];
27310
+ insertTable(rows, cols, state22);
27311
+ }),
27312
+ deleteTable: createCommand("Delete Table", (state22) => state22.range && deleteTable(state22.range)),
27313
+ mergeCells: createCommand("Merge Cells", (state22) => state22.range && state22.doc && mergeCells(state22.range, state22.doc)),
27314
+ splitCells: createCommand("Split Cells", (state22) => state22.range && state22.doc && splitCell(state22.range, state22.doc)),
27315
+ addRowBefore: createCommand("Add Row Before", (state22) => state22.range && state22.doc && addRow("before", state22.range, state22.doc)),
27316
+ addRowAfter: createCommand("Add Row After", (state22) => state22.range && state22.doc && addRow("after", state22.range, state22.doc)),
27317
+ deleteRow: createCommand("Delete Row", (state22) => state22.range && deleteRow(state22.range)),
27318
+ insertColumnLeft: createCommand("Insert Column Left", (state22) => state22.range && insertColumn("before", state22.range)),
27319
+ insertColumnRight: createCommand("Insert Column Right", (state22) => state22.range && insertColumn("after", state22.range)),
27320
+ deleteColumn: createCommand("Delete Column", (state22) => state22.range && deleteColumn(state22.range))
27321
+ };
27322
+ const alignmentCommands = ["Left", "Center", "Right", "Justify"].reduce((acc, align) => ({
27323
+ ...acc,
27324
+ [`align${align}`]: createCommand(`Align ${align}`, (state22) => state22.range && alignColumn(state22.range, align.toLowerCase()))
27325
+ }), {});
27326
+ const viewCommands = {
27327
+ fullScreen: createCommand("Full Screen", (state22) => {
27328
+ state22.isFullscreen = !state22.isFullscreen;
27329
+ }, (state22) => state22.isFullscreen),
27330
+ splitView: createCommand("Split View", (state22) => {
27331
+ state22.isSplitView = !state22.isSplitView;
27332
+ }, (state22) => state22.isSplitView),
27333
+ codeView: createCommand("Code View", (state22) => {
27334
+ state22.isCodeView = !state22.isCodeView;
27335
+ }, (state22) => state22.isCodeView)
27336
+ };
27337
+ const mediaCommands = {
27338
+ image: createCommand("Insert Image", (state22) => state22.modal && insertImage(state22.modal, state22)),
27339
+ link: createCommand("Insert Link", (state22) => state22.modal && state22.range && insertLink(state22.modal, state22)),
27340
+ embed: createCommand("Insert Embed", (state22) => state22.modal && insertEmbed(state22.modal, state22))
27341
+ };
27342
+ const otherCommands = {
27343
+ clear: createCommand("Clear Formatting", () => {
27344
+ format2.clear();
27345
+ }),
27346
+ indent: createCommand("Indent", () => {
27347
+ format2.text("indent");
27348
+ }),
27349
+ outdent: createCommand("Outdent", () => {
27350
+ format2.text("outdent");
27351
+ })
27352
+ };
27353
+ return {
27354
+ ...historyCommands,
27355
+ ...textCommands,
27356
+ ...headingCommands,
27357
+ ...blockCommands,
27358
+ ...listCommands,
27359
+ ...tableCommands,
27360
+ ...alignmentCommands,
27361
+ ...viewCommands,
27362
+ ...mediaCommands,
27363
+ ...otherCommands
27364
+ };
27365
+ }
27366
+ function createCommandExecutor(state2, commands) {
27367
+ return {
27368
+ execute(command, value) {
27369
+ const cmd = commands[command];
27370
+ if (cmd) {
27371
+ cmd.execute(state2, value);
27372
+ }
27143
27373
  },
27144
- splitView: {
27145
- name: "Split View",
27146
- execute: (state22) => {
27147
- state22.isSplitView = !state22.isSplitView;
27148
- },
27149
- isActive: (state22) => state22.isSplitView
27374
+ isActive(command) {
27375
+ var _a2;
27376
+ const cmd = commands[command];
27377
+ return ((_a2 = cmd.isActive) == null ? void 0 : _a2.call(cmd, state2)) || false;
27150
27378
  },
27151
- codeView: {
27152
- name: "Code View",
27153
- execute: (state22) => {
27154
- state22.isCodeView = !state22.isCodeView;
27155
- },
27156
- isActive: (state22) => state22.isCodeView
27379
+ getValue(command) {
27380
+ var _a2;
27381
+ const cmd = commands[command];
27382
+ return ((_a2 = cmd.getValue) == null ? void 0 : _a2.call(cmd, state2)) || null;
27157
27383
  }
27158
27384
  };
27385
+ }
27386
+ function useCommands(state2, debug) {
27387
+ const commands = createCommandRegistry(state2);
27159
27388
  const executor = createCommandExecutor(state2, commands);
27160
27389
  return {
27161
27390
  execute: (command, value) => {
27391
+ if (!state2.doc) return;
27392
+ console.log("[useCommands.execute] Starting command execution:", command, value);
27162
27393
  debug == null ? void 0 : debug.logCommand(command, value);
27394
+ if (["splitView", "codeView", "fullScreen"].includes(command)) {
27395
+ console.log("[useCommands.execute] Handling view state command:", command);
27396
+ switch (command) {
27397
+ case "splitView":
27398
+ state2.isSplitView = !state2.isSplitView;
27399
+ return;
27400
+ case "codeView":
27401
+ state2.isCodeView = !state2.isCodeView;
27402
+ return;
27403
+ case "fullScreen":
27404
+ state2.isFullscreen = !state2.isFullscreen;
27405
+ return;
27406
+ }
27407
+ }
27408
+ console.log("[useCommands.execute] Focusing editor");
27409
+ state2.doc.body.focus();
27410
+ console.log("[useCommands.execute] Executing command");
27163
27411
  executor.execute(command, value);
27412
+ const newContent = state2.doc.body.innerHTML;
27413
+ console.log("[useCommands.execute] Checking content changes");
27414
+ console.log("[useCommands.execute] Old content length:", state2.content.length);
27415
+ console.log("[useCommands.execute] New content length:", newContent.length);
27416
+ if (newContent !== state2.content) {
27417
+ console.log("[useCommands.execute] Content changed, updating state");
27418
+ state2.content = newContent;
27419
+ }
27420
+ console.log("[useCommands.execute] Checking selection changes");
27421
+ const selection = state2.doc.getSelection();
27422
+ if (selection == null ? void 0 : selection.rangeCount) {
27423
+ const hasSelectionChanged = !state2.selection || state2.selection !== selection || state2.rangeCount !== selection.rangeCount;
27424
+ console.log("[useCommands.execute] Selection changed:", hasSelectionChanged);
27425
+ if (hasSelectionChanged) {
27426
+ console.log("[useCommands.execute] Updating selection state");
27427
+ state2.selection = selection;
27428
+ state2.range = selection.getRangeAt(0).cloneRange();
27429
+ state2.rangeCount = selection.rangeCount;
27430
+ }
27431
+ }
27164
27432
  },
27165
27433
  isActive: executor.isActive,
27166
27434
  getValue: executor.getValue
27167
27435
  };
27168
27436
  }
27437
+ class EditorDebugger {
27438
+ constructor(maxActions = 1e3) {
27439
+ __publicField(this, "session");
27440
+ __publicField(this, "maxActions");
27441
+ __publicField(this, "isDevelopment");
27442
+ this.maxActions = maxActions;
27443
+ this.session = this.createNewSession();
27444
+ this.isDevelopment = false;
27445
+ }
27446
+ createNewSession() {
27447
+ return {
27448
+ id: `session_${Date.now()}`,
27449
+ startTime: Date.now(),
27450
+ actions: []
27451
+ };
27452
+ }
27453
+ getNodeDescription(node) {
27454
+ var _a2;
27455
+ if (node.nodeType === Node.TEXT_NODE) {
27456
+ return `Text("${(_a2 = node.textContent) == null ? void 0 : _a2.slice(0, 20)}${node.textContent && node.textContent.length > 20 ? "..." : ""}")`;
27457
+ }
27458
+ const element = node;
27459
+ return `${element.tagName.toLowerCase()}${element.id ? `#${element.id}` : ""}`;
27460
+ }
27461
+ captureState(state2) {
27462
+ if (!state2.doc || !state2.selection) {
27463
+ return {
27464
+ content: "",
27465
+ selection: null,
27466
+ activeStyles: [],
27467
+ caretPosition: null
27468
+ };
27469
+ }
27470
+ const { selection } = state2;
27471
+ const range2 = selection.rangeCount ? selection.getRangeAt(0) : null;
27472
+ return {
27473
+ content: state2.doc.body.innerHTML,
27474
+ selection: range2 ? {
27475
+ start: range2.startOffset,
27476
+ end: range2.endOffset,
27477
+ collapsed: range2.collapsed,
27478
+ text: range2.toString()
27479
+ } : null,
27480
+ activeStyles: Array.from(state2.selectedStyles),
27481
+ caretPosition: range2 ? {
27482
+ node: this.getNodeDescription(range2.startContainer),
27483
+ offset: range2.startOffset
27484
+ } : null
27485
+ };
27486
+ }
27487
+ logCommand(command, value, state2) {
27488
+ this.addAction({
27489
+ type: "command",
27490
+ name: command,
27491
+ timestamp: Date.now(),
27492
+ details: { value },
27493
+ state: this.captureState(state2)
27494
+ });
27495
+ }
27496
+ logPaste(data2, state2) {
27497
+ this.addAction({
27498
+ type: "paste",
27499
+ name: "paste",
27500
+ timestamp: Date.now(),
27501
+ details: {
27502
+ html: data2.getData("text/html"),
27503
+ text: data2.getData("text/plain"),
27504
+ types: Array.from(data2.types)
27505
+ },
27506
+ state: this.captureState(state2)
27507
+ });
27508
+ }
27509
+ logKeyboard(event, state2) {
27510
+ this.addAction({
27511
+ type: "keyboard",
27512
+ name: "keypress",
27513
+ timestamp: Date.now(),
27514
+ details: {
27515
+ key: event.key,
27516
+ code: event.code,
27517
+ ctrl: event.ctrlKey,
27518
+ alt: event.altKey,
27519
+ shift: event.shiftKey,
27520
+ meta: event.metaKey
27521
+ },
27522
+ state: this.captureState(state2)
27523
+ });
27524
+ }
27525
+ logSelection(state2) {
27526
+ this.addAction({
27527
+ type: "selection",
27528
+ name: "selection_change",
27529
+ timestamp: Date.now(),
27530
+ details: {},
27531
+ state: this.captureState(state2)
27532
+ });
27533
+ }
27534
+ logInput(inputType, data2, state2) {
27535
+ this.addAction({
27536
+ type: "input",
27537
+ name: inputType,
27538
+ timestamp: Date.now(),
27539
+ details: { data: data2 },
27540
+ state: this.captureState(state2)
27541
+ });
27542
+ }
27543
+ addAction(action) {
27544
+ this.session.actions.push(action);
27545
+ if (this.session.actions.length > this.maxActions) {
27546
+ this.session.actions.shift();
27547
+ }
27548
+ if (this.isDevelopment) {
27549
+ console.log("Editor Action:", action);
27550
+ }
27551
+ }
27552
+ getSession() {
27553
+ return this.session;
27554
+ }
27555
+ clearSession() {
27556
+ this.session = this.createNewSession();
27557
+ }
27558
+ exportSession() {
27559
+ return JSON.stringify(this.session, null, 2);
27560
+ }
27561
+ downloadSession() {
27562
+ const blob = new Blob([this.exportSession()], { type: "application/json" });
27563
+ const url = URL.createObjectURL(blob);
27564
+ const a2 = document.createElement("a");
27565
+ a2.href = url;
27566
+ a2.download = `editor_session_${this.session.id}.json`;
27567
+ document.body.appendChild(a2);
27568
+ a2.click();
27569
+ document.body.removeChild(a2);
27570
+ URL.revokeObjectURL(url);
27571
+ }
27572
+ exportSessionWithPrompt(userMessage) {
27573
+ const prompt = {
27574
+ message: userMessage || "here is a debug log, can you analyze and fix accordingly?",
27575
+ session: this.session
27576
+ };
27577
+ return JSON.stringify(prompt, null, 2);
27578
+ }
27579
+ }
27580
+ function preserveIframes(content) {
27581
+ const temp = document.createElement("div");
27582
+ temp.innerHTML = content;
27583
+ const iframes = [];
27584
+ temp.querySelectorAll("iframe").forEach((iframe, index2) => {
27585
+ const placeholder = `<!--iframe-${index2}-->`;
27586
+ iframes.push(iframe.cloneNode(true));
27587
+ iframe.replaceWith(placeholder);
27588
+ });
27589
+ return {
27590
+ html: temp.innerHTML,
27591
+ iframes
27592
+ };
27593
+ }
27594
+ function restoreIframes(doc, content, iframes) {
27595
+ const placeholderPattern = /<!--iframe-(\d+)-->/g;
27596
+ doc.body.innerHTML = content.replace(placeholderPattern, (_2, index2) => {
27597
+ const iframe = iframes[Number(index2)];
27598
+ return iframe ? iframe.outerHTML : "";
27599
+ });
27600
+ }
27169
27601
  function useEditor() {
27170
- const editorDebugger = ref();
27171
27602
  const modal = useModal();
27603
+ let cleanupListeners = null;
27172
27604
  const state2 = reactive({
27173
27605
  content: "",
27174
27606
  doc: void 0,
@@ -27182,95 +27614,142 @@ function useEditor() {
27182
27614
  redoStack: [],
27183
27615
  rangeCount: 0,
27184
27616
  range: null,
27185
- modal
27617
+ modal,
27618
+ debug: void 0
27186
27619
  });
27187
- function updateActiveStyles() {
27188
- if (!state2.doc) return;
27189
- const styles = /* @__PURE__ */ new Set();
27190
- const styleTypes = [
27191
- "bold",
27192
- "italic",
27193
- "underline",
27194
- "h1",
27195
- "h2",
27196
- "h3",
27197
- "h4",
27198
- "h5",
27199
- "h6",
27200
- "blockquote",
27201
- "table",
27202
- "p",
27203
- "ol",
27204
- "li"
27205
- ];
27206
- styleTypes.forEach((style) => {
27207
- if (state2.doc && isStyleActive(style, state2.doc)) {
27208
- styles.add(style);
27620
+ const updateState = {
27621
+ styles: () => {
27622
+ if (!state2.doc) return;
27623
+ console.log("[updateState.styles] Starting style update");
27624
+ const styles = /* @__PURE__ */ new Set();
27625
+ const styleTypes = [
27626
+ "bold",
27627
+ "italic",
27628
+ "underline",
27629
+ "h1",
27630
+ "h2",
27631
+ "h3",
27632
+ "h4",
27633
+ "h5",
27634
+ "h6",
27635
+ "blockquote",
27636
+ "table",
27637
+ "p",
27638
+ "ol",
27639
+ "li"
27640
+ ];
27641
+ styleTypes.forEach((style) => {
27642
+ if (state2.doc && isStyleActive(style, state2.doc)) {
27643
+ styles.add(style);
27644
+ }
27645
+ });
27646
+ console.log("[updateState.styles] New styles:", Array.from(styles));
27647
+ state2.selectedStyles = styles;
27648
+ },
27649
+ content: (source) => {
27650
+ if (!state2.doc) return;
27651
+ console.log("[updateState.content] Starting content update, source:", source);
27652
+ const currentContent = state2.doc.body.innerHTML;
27653
+ console.log("[updateState.content] Current content length:", currentContent.length);
27654
+ console.log("[updateState.content] State content length:", state2.content.length);
27655
+ if (currentContent !== state2.content) {
27656
+ console.log("[updateState.content] Content changed, pushing to undo stack");
27657
+ state2.undoStack.push(state2.content);
27658
+ state2.redoStack = [];
27659
+ }
27660
+ const selection = state2.doc.getSelection();
27661
+ const range2 = (selection == null ? void 0 : selection.rangeCount) ? selection.getRangeAt(0).cloneRange() : null;
27662
+ console.log("[updateState.content] Has selection:", !!selection, "Has range:", !!range2);
27663
+ if (source === "html") {
27664
+ console.log("[updateState.content] Processing HTML content");
27665
+ const preserved = preserveIframes(state2.content);
27666
+ console.log("[updateState.content] Preserved iframes count:", preserved.iframes.length);
27667
+ state2.doc.body.innerHTML = preserved.html;
27668
+ setTimeout(() => {
27669
+ console.log("[updateState.content] Restoring iframes");
27670
+ if (state2.doc) {
27671
+ restoreIframes(state2.doc, state2.content, preserved.iframes);
27672
+ if (range2 && selection) {
27673
+ try {
27674
+ selection.removeAllRanges();
27675
+ selection.addRange(range2);
27676
+ console.log("[updateState.content] Selection restored");
27677
+ } catch (e) {
27678
+ console.warn("[updateState.content] Could not restore selection:", e);
27679
+ }
27680
+ }
27681
+ }
27682
+ }, 0);
27683
+ } else {
27684
+ console.log("[updateState.content] Setting text content");
27685
+ state2.doc.body.textContent = state2.content;
27209
27686
  }
27210
- });
27211
- state2.selectedStyles = styles;
27212
- }
27213
- function updateContent(source) {
27214
- if (!state2.doc) return;
27215
- state2.undoStack.push(state2.content);
27216
- state2.redoStack = [];
27217
- if (source === "html") {
27218
- state2.doc.body.innerHTML = state2.content;
27219
- } else {
27220
- state2.doc.body.textContent = state2.content;
27221
- }
27222
- updateActiveStyles();
27223
- }
27224
- function updateSelection() {
27225
- if (!state2.doc) return;
27226
- state2.selection = state2.doc.getSelection();
27227
- if (!state2.selection) return;
27228
- try {
27229
- if (!state2.doc.body.contains(state2.selection.anchorNode)) {
27230
- state2.doc.body.focus();
27687
+ },
27688
+ selection: () => {
27689
+ if (!state2.doc) return;
27690
+ console.log("[updateState.selection] Starting selection update");
27691
+ const newSelection = state2.doc.getSelection();
27692
+ if (!newSelection) {
27693
+ console.log("[updateState.selection] No selection available");
27231
27694
  return;
27232
27695
  }
27233
- state2.rangeCount = state2.selection.rangeCount;
27234
- if (!state2.rangeCount) {
27235
- const range2 = state2.doc.createRange();
27236
- range2.selectNodeContents(state2.doc.body);
27237
- range2.collapse(false);
27238
- state2.selection.removeAllRanges();
27239
- state2.selection.addRange(range2);
27696
+ try {
27697
+ if (!state2.doc.body.contains(newSelection.anchorNode)) {
27698
+ console.log("[updateState.selection] Selection outside editor body, refocusing");
27699
+ state2.doc.body.focus();
27700
+ return;
27701
+ }
27702
+ const hasSelectionChanged = !state2.selection || state2.selection !== newSelection || state2.rangeCount !== newSelection.rangeCount || newSelection.rangeCount > 0 && state2.range && (state2.range.startContainer !== newSelection.getRangeAt(0).startContainer || state2.range.startOffset !== newSelection.getRangeAt(0).startOffset || state2.range.endContainer !== newSelection.getRangeAt(0).endContainer || state2.range.endOffset !== newSelection.getRangeAt(0).endOffset);
27703
+ console.log("[updateState.selection] Selection changed:", hasSelectionChanged);
27704
+ if (hasSelectionChanged) {
27705
+ state2.selection = newSelection;
27706
+ state2.rangeCount = newSelection.rangeCount;
27707
+ if (newSelection.rangeCount > 0) {
27708
+ state2.range = newSelection.getRangeAt(0).cloneRange();
27709
+ console.log("[updateState.selection] New range:", {
27710
+ startOffset: state2.range.startOffset,
27711
+ endOffset: state2.range.endOffset,
27712
+ collapsed: state2.range.collapsed
27713
+ });
27714
+ }
27715
+ requestAnimationFrame(() => {
27716
+ console.log("[updateState.selection] Updating styles in RAF");
27717
+ updateState.styles();
27718
+ });
27719
+ }
27720
+ } catch (e) {
27721
+ console.warn("[updateState.selection] Selection error:", e);
27722
+ state2.selection = null;
27723
+ state2.range = null;
27724
+ state2.rangeCount = 0;
27725
+ state2.selectedStyles = /* @__PURE__ */ new Set();
27240
27726
  }
27241
- state2.range = state2.selection.getRangeAt(0).cloneRange();
27242
- updateActiveStyles();
27243
- } catch (e) {
27244
- console.warn("Selection error:", e);
27245
- state2.selection = null;
27246
- state2.range = null;
27247
- state2.rangeCount = 0;
27248
- state2.selectedStyles = /* @__PURE__ */ new Set();
27249
27727
  }
27250
- }
27251
- function setupEventListeners(doc) {
27252
- doc.addEventListener("input", () => {
27253
- state2.content = doc.body.innerHTML;
27254
- updateActiveStyles();
27255
- });
27256
- doc.addEventListener("selectionchange", () => {
27257
- updateSelection();
27258
- });
27259
- doc.addEventListener("mouseup", () => {
27260
- updateSelection();
27261
- });
27262
- doc.addEventListener("keyup", (e) => {
27263
- if (["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].includes(e.key)) {
27264
- updateSelection();
27728
+ };
27729
+ const history = {
27730
+ undo: () => {
27731
+ if (state2.undoStack.length === 0) return;
27732
+ state2.redoStack.push(state2.content);
27733
+ const lastContent = state2.undoStack.pop();
27734
+ if (lastContent !== void 0) {
27735
+ state2.content = lastContent;
27736
+ updateState.content("html");
27265
27737
  }
27266
- });
27267
- const cleanEmptyTags = () => {
27738
+ },
27739
+ redo: () => {
27740
+ if (state2.redoStack.length === 0) return;
27741
+ state2.undoStack.push(state2.content);
27742
+ const nextContent = state2.redoStack.pop();
27743
+ if (nextContent !== void 0) {
27744
+ state2.content = nextContent;
27745
+ updateState.content("html");
27746
+ }
27747
+ }
27748
+ };
27749
+ const cleanup = {
27750
+ emptyTags: (doc) => {
27268
27751
  var _a2, _b;
27269
- const walker = doc.createTreeWalker(
27270
- doc.body,
27271
- NodeFilter.SHOW_ELEMENT,
27272
- null
27273
- );
27752
+ const walker = doc.createTreeWalker(doc.body, NodeFilter.SHOW_ELEMENT, null);
27274
27753
  const nodesToRemove = [];
27275
27754
  let node = walker.nextNode();
27276
27755
  while (node) {
@@ -27285,12 +27764,10 @@ function useEditor() {
27285
27764
  const isEmpty = !textContent && !innerHTML;
27286
27765
  const isDirectChildOfBody = node.parentElement === doc.body;
27287
27766
  if (isEmpty || hasOnlyNbsp || hasOnlyBr && !isDirectChildOfBody) {
27288
- if (isDirectChildOfBody) {
27289
- if (!node.matches("p")) {
27290
- const p2 = doc.createElement("p");
27291
- p2.innerHTML = "<br>";
27292
- (_b = node.parentNode) == null ? void 0 : _b.replaceChild(p2, node);
27293
- }
27767
+ if (isDirectChildOfBody && !node.matches("p")) {
27768
+ const p2 = doc.createElement("p");
27769
+ p2.innerHTML = "<br>";
27770
+ (_b = node.parentNode) == null ? void 0 : _b.replaceChild(p2, node);
27294
27771
  } else {
27295
27772
  nodesToRemove.push(node);
27296
27773
  }
@@ -27300,237 +27777,283 @@ function useEditor() {
27300
27777
  nodesToRemove.forEach((node2) => {
27301
27778
  node2.remove();
27302
27779
  });
27780
+ },
27781
+ normalizeContent: (doc) => {
27782
+ if (!doc.body.firstElementChild) {
27783
+ const p2 = doc.createElement("p");
27784
+ p2.dir = doc.body.dir;
27785
+ p2.innerHTML = "<br>";
27786
+ doc.body.appendChild(p2);
27787
+ } else {
27788
+ const walker = doc.createTreeWalker(doc.body, NodeFilter.SHOW_TEXT);
27789
+ const textNodes = [];
27790
+ let node;
27791
+ while (node = walker.nextNode()) {
27792
+ if (node.parentElement === doc.body) {
27793
+ textNodes.push(node);
27794
+ }
27795
+ }
27796
+ textNodes.forEach((textNode) => {
27797
+ var _a2;
27798
+ if ((_a2 = textNode.textContent) == null ? void 0 : _a2.trim()) {
27799
+ const p2 = doc.createElement("p");
27800
+ p2.dir = doc.body.dir;
27801
+ p2.appendChild(textNode.cloneNode());
27802
+ doc.body.replaceChild(p2, textNode);
27803
+ } else {
27804
+ doc.body.removeChild(textNode);
27805
+ }
27806
+ });
27807
+ }
27808
+ }
27809
+ };
27810
+ function setupEventListeners(doc) {
27811
+ console.log("[setupEventListeners] Starting setup");
27812
+ if (cleanupListeners) {
27813
+ console.log("[setupEventListeners] Cleaning up existing listeners");
27814
+ cleanupListeners();
27815
+ cleanupListeners = null;
27816
+ }
27817
+ let isUpdating = false;
27818
+ let contentUpdateTimeout = null;
27819
+ let selectionUpdateTimeout = null;
27820
+ let updateCount = 0;
27821
+ const events = {
27822
+ input: () => {
27823
+ updateCount++;
27824
+ console.log(`[input event #${updateCount}] Starting, isUpdating:`, isUpdating);
27825
+ if (isUpdating) {
27826
+ console.log(`[input event #${updateCount}] Skipped - already updating`);
27827
+ return;
27828
+ }
27829
+ isUpdating = true;
27830
+ if (contentUpdateTimeout) {
27831
+ console.log(`[input event #${updateCount}] Clearing previous timeout`);
27832
+ window.clearTimeout(contentUpdateTimeout);
27833
+ }
27834
+ contentUpdateTimeout = window.setTimeout(() => {
27835
+ console.log(`[input event #${updateCount}] Timeout fired`);
27836
+ const newContent = doc.body.innerHTML;
27837
+ if (newContent !== state2.content) {
27838
+ console.log(`[input event #${updateCount}] Content changed, updating state`);
27839
+ state2.content = newContent;
27840
+ } else {
27841
+ console.log(`[input event #${updateCount}] Content unchanged`);
27842
+ }
27843
+ isUpdating = false;
27844
+ }, 100);
27845
+ },
27846
+ selectionchange: () => {
27847
+ updateCount++;
27848
+ console.log(`[selectionchange #${updateCount}] Starting, isUpdating:`, isUpdating);
27849
+ if (isUpdating) {
27850
+ console.log(`[selectionchange #${updateCount}] Skipped - already updating`);
27851
+ return;
27852
+ }
27853
+ if (selectionUpdateTimeout) {
27854
+ console.log(`[selectionchange #${updateCount}] Clearing previous timeout`);
27855
+ window.clearTimeout(selectionUpdateTimeout);
27856
+ }
27857
+ selectionUpdateTimeout = window.setTimeout(() => {
27858
+ console.log(`[selectionchange #${updateCount}] Timeout fired`);
27859
+ if (!isUpdating) {
27860
+ updateState.selection();
27861
+ } else {
27862
+ console.log(`[selectionchange #${updateCount}] Skipped - still updating`);
27863
+ }
27864
+ }, 150);
27865
+ },
27866
+ mouseup: () => {
27867
+ updateCount++;
27868
+ console.log(`[mouseup #${updateCount}] Starting, isUpdating:`, isUpdating);
27869
+ if (isUpdating) return;
27870
+ updateState.selection();
27871
+ },
27872
+ keyup: (e) => {
27873
+ updateCount++;
27874
+ console.log(`[keyup #${updateCount}] Key:`, e.key, "isUpdating:", isUpdating);
27875
+ if (isUpdating) return;
27876
+ if (["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].includes(e.key)) {
27877
+ updateState.selection();
27878
+ }
27879
+ }
27880
+ };
27881
+ Object.entries(events).forEach(([event, handler]) => {
27882
+ doc.addEventListener(event, handler);
27883
+ console.log("[setupEventListeners] Added listener for:", event);
27884
+ });
27885
+ cleanupListeners = () => {
27886
+ console.log("[setupEventListeners] Cleaning up event listeners");
27887
+ if (contentUpdateTimeout) window.clearTimeout(contentUpdateTimeout);
27888
+ if (selectionUpdateTimeout) window.clearTimeout(selectionUpdateTimeout);
27889
+ Object.entries(events).forEach(([event, handler]) => {
27890
+ doc.removeEventListener(event, handler);
27891
+ });
27303
27892
  };
27304
- const observer = new MutationObserver(() => {
27305
- cleanEmptyTags();
27306
- });
27307
- observer.observe(doc.body, {
27308
- childList: true,
27309
- subtree: true,
27310
- characterData: true
27311
- });
27893
+ return cleanupListeners;
27312
27894
  }
27313
27895
  function init(doc) {
27896
+ console.log("[init] Starting initialization");
27897
+ if (state2.hasInit) {
27898
+ console.log("[init] Already initialized, cleaning up first");
27899
+ if (cleanupListeners) {
27900
+ cleanupListeners();
27901
+ cleanupListeners = null;
27902
+ }
27903
+ }
27314
27904
  state2.doc = doc;
27315
27905
  state2.hasInit = true;
27316
- setupEventListeners(doc);
27317
- updateContent("html");
27318
- }
27319
- function handleUndo() {
27320
- if (state2.undoStack.length === 0) return;
27321
- state2.redoStack.push(state2.content);
27322
- const lastContent = state2.undoStack.pop();
27323
- if (lastContent !== void 0) {
27324
- state2.content = lastContent;
27325
- updateContent("html");
27326
- }
27327
- }
27328
- function handleRedo() {
27329
- if (state2.redoStack.length === 0) return;
27330
- state2.undoStack.push(state2.content);
27331
- const nextContent = state2.redoStack.pop();
27332
- if (nextContent !== void 0) {
27333
- state2.content = nextContent;
27334
- updateContent("html");
27335
- }
27336
- }
27337
- function handleToolbarAction(action, value) {
27338
- if (!state2.doc) return;
27339
- if (action === "undo") {
27340
- handleUndo();
27341
- return;
27342
- }
27343
- if (action === "redo") {
27344
- handleRedo();
27345
- return;
27346
- }
27347
- if (action === "fullScreen") {
27348
- state2.isFullscreen = !state2.isFullscreen;
27349
- return;
27350
- }
27351
- if (action === "splitView") {
27352
- state2.isSplitView = !state2.isSplitView;
27353
- return;
27906
+ if (state2.content) {
27907
+ const preserved = preserveIframes(state2.content);
27908
+ doc.body.innerHTML = preserved.html;
27909
+ setTimeout(() => {
27910
+ if (state2.doc) {
27911
+ restoreIframes(doc, state2.content, preserved.iframes);
27912
+ }
27913
+ }, 0);
27354
27914
  }
27355
- if (action === "codeView") {
27356
- state2.isCodeView = !state2.isCodeView;
27357
- return;
27915
+ cleanup.normalizeContent(doc);
27916
+ const range2 = doc.createRange();
27917
+ const selection = doc.getSelection();
27918
+ if (selection) {
27919
+ range2.selectNodeContents(doc.body);
27920
+ range2.collapse(false);
27921
+ selection.removeAllRanges();
27922
+ selection.addRange(range2);
27923
+ state2.range = range2.cloneRange();
27924
+ state2.selection = selection;
27925
+ state2.rangeCount = selection.rangeCount;
27926
+ }
27927
+ cleanupListeners = setupEventListeners(doc);
27928
+ }
27929
+ function initDebugger() {
27930
+ if (!state2.debug) {
27931
+ const debugInstance = new EditorDebugger();
27932
+ const debug = {
27933
+ debugger: debugInstance,
27934
+ logCommand: (command, value) => {
27935
+ debugInstance.logCommand(command, value, state2);
27936
+ },
27937
+ getSession: () => debugInstance.getSession(),
27938
+ clearSession: () => {
27939
+ debugInstance.clearSession();
27940
+ },
27941
+ downloadSession: () => {
27942
+ debugInstance.downloadSession();
27943
+ },
27944
+ exportDebugWithPrompt: (message2) => debugInstance.exportSessionWithPrompt(message2)
27945
+ };
27946
+ state2.debug = debug;
27358
27947
  }
27359
- const format2 = formatting(state2);
27360
- state2.doc.body.focus();
27361
- switch (action) {
27362
- case "bold":
27363
- case "italic":
27364
- case "underline":
27365
- format2.text(action);
27366
- break;
27367
- case "orderedList":
27368
- format2.list("ol");
27369
- break;
27370
- case "unorderedList":
27371
- format2.list("ul");
27372
- break;
27373
- case "blockquote":
27374
- case "p":
27375
- case "h1":
27376
- case "h2":
27377
- case "h3":
27378
- case "h4":
27379
- case "h5":
27380
- case "h6":
27381
- format2.block(action, action);
27382
- break;
27383
- case "insertTable": {
27384
- const [rows, cols] = (value == null ? void 0 : value.split("x").map(Number)) || [3, 3];
27385
- insertTable(rows, cols, state2);
27386
- break;
27948
+ }
27949
+ if (typeof window !== "undefined") {
27950
+ window.addEventListener("beforeunload", () => {
27951
+ if (cleanupListeners) {
27952
+ cleanupListeners();
27387
27953
  }
27388
- case "deleteTable":
27389
- if (state2.range) deleteTable(state2.range);
27390
- break;
27391
- case "mergeCells":
27392
- if (state2.range && state2.doc) mergeCells(state2.range, state2.doc);
27393
- break;
27394
- case "splitCells":
27395
- if (state2.range && state2.doc) splitCell(state2.range, state2.doc);
27396
- break;
27397
- case "addRowBefore":
27398
- case "addRowAfter":
27399
- if (state2.range && state2.doc) {
27400
- addRow(action === "addRowBefore" ? "before" : "after", state2.range, state2.doc);
27401
- }
27402
- break;
27403
- case "deleteRow":
27404
- if (state2.range) deleteRow(state2.range);
27405
- break;
27406
- case "insertColumnLeft":
27407
- case "insertColumnRight":
27408
- if (state2.range) {
27409
- insertColumn(action === "insertColumnLeft" ? "before" : "after", state2.range);
27410
- }
27411
- break;
27412
- case "deleteColumn":
27413
- if (state2.range) deleteColumn(state2.range);
27414
- break;
27415
- case "alignLeft":
27416
- case "alignCenter":
27417
- case "alignRight":
27418
- case "alignJustify":
27419
- if (state2.range) {
27420
- alignColumn(state2.range, action.replace("align", "").toLowerCase());
27421
- }
27422
- break;
27423
- case "clear":
27424
- format2.clear();
27425
- break;
27426
- default:
27427
- format2.text(action);
27428
- }
27429
- updateContent("html");
27954
+ });
27430
27955
  }
27431
- const getDebugSession = () => {
27432
- var _a2;
27433
- return (_a2 = editorDebugger.value) == null ? void 0 : _a2.getSession();
27434
- };
27435
- const clearDebugSession = () => {
27436
- var _a2;
27437
- return (_a2 = editorDebugger.value) == null ? void 0 : _a2.clearSession();
27438
- };
27439
- const downloadDebugSession = () => {
27440
- var _a2;
27441
- return (_a2 = editorDebugger.value) == null ? void 0 : _a2.downloadSession();
27442
- };
27443
- const logCommand = (command, value) => {
27444
- var _a2;
27445
- return (_a2 = editorDebugger.value) == null ? void 0 : _a2.logCommand(command, value, state2);
27446
- };
27447
- const exportDebugWithPrompt = (message2) => {
27448
- var _a2;
27449
- return (_a2 = editorDebugger.value) == null ? void 0 : _a2.exportSessionWithPrompt(message2);
27450
- };
27451
27956
  return {
27452
27957
  state: state2,
27453
27958
  init,
27454
- handleToolbarAction,
27455
- updateContent,
27456
- handleUndo,
27457
- handleRedo,
27458
- // Debug methods
27459
- debug: {
27460
- getSession: getDebugSession,
27461
- clearSession: clearDebugSession,
27462
- downloadSession: downloadDebugSession,
27463
- logCommand,
27464
- exportDebugWithPrompt
27465
- }
27466
- };
27467
- }
27468
- function useEditorKeyboard(doc, handleToolbarAction) {
27959
+ updateState,
27960
+ history,
27961
+ initDebugger,
27962
+ cleanup: () => {
27963
+ if (cleanupListeners) {
27964
+ cleanupListeners();
27965
+ cleanupListeners = null;
27966
+ }
27967
+ }
27968
+ };
27969
+ }
27970
+ const shortcuts = [
27971
+ { key: "b", command: "bold" },
27972
+ { key: "i", command: "italic" },
27973
+ { key: "u", command: "underline" },
27974
+ { key: "z", command: "undo" },
27975
+ { key: "z", modifiers: { shift: true }, command: "redo" },
27976
+ { key: "y", command: "redo" },
27977
+ { key: ".", modifiers: { shift: true }, command: "orderedList" },
27978
+ { key: "/", modifiers: { shift: true }, command: "unorderedList" },
27979
+ { key: "]", command: "indent" },
27980
+ { key: "[", command: "outdent" },
27981
+ ...Array.from({ length: 6 }, (_2, i2) => ({
27982
+ key: String(i2 + 1),
27983
+ modifiers: { alt: true },
27984
+ command: `h${i2 + 1}`
27985
+ }))
27986
+ ];
27987
+ function useEditorKeyboard(doc, executor) {
27469
27988
  doc.addEventListener("keydown", (e) => {
27470
- if (e.ctrlKey || e.metaKey) {
27471
- switch (e.key) {
27472
- case "b":
27473
- e.preventDefault();
27474
- handleToolbarAction("bold");
27475
- break;
27476
- case "i":
27477
- e.preventDefault();
27478
- handleToolbarAction("italic");
27479
- break;
27480
- case "u":
27481
- e.preventDefault();
27482
- handleToolbarAction("underline");
27483
- break;
27484
- case "z":
27485
- e.preventDefault();
27486
- if (e.shiftKey) {
27487
- handleToolbarAction("redo");
27488
- } else {
27489
- handleToolbarAction("undo");
27490
- }
27491
- break;
27492
- case "y":
27493
- e.preventDefault();
27494
- handleToolbarAction("redo");
27495
- break;
27496
- // List shortcuts
27497
- case ".":
27498
- if (e.shiftKey) {
27499
- e.preventDefault();
27500
- handleToolbarAction("orderedList");
27501
- }
27502
- break;
27503
- case "/":
27504
- if (e.shiftKey) {
27989
+ var _a2, _b;
27990
+ if (e.key === "Enter" && !e.shiftKey) {
27991
+ const selection = doc.getSelection();
27992
+ if (!selection || !selection.rangeCount) return;
27993
+ const range2 = selection.getRangeAt(0);
27994
+ const container = range2.commonAncestorContainer;
27995
+ const listItem = (_a2 = container.nodeType === 3 ? container.parentElement : container) == null ? void 0 : _a2.closest("li");
27996
+ if (listItem) {
27997
+ if (range2.collapsed && isAtEndOfNode(listItem, range2)) {
27998
+ if (isNodeEmpty(listItem)) {
27505
27999
  e.preventDefault();
27506
- handleToolbarAction("unorderedList");
27507
- }
27508
- break;
27509
- // Heading shortcuts
27510
- case "1":
27511
- case "2":
27512
- case "3":
27513
- case "4":
27514
- case "5":
27515
- case "6":
27516
- if (e.altKey) {
28000
+ const list = listItem.parentElement;
28001
+ if (!list) return;
28002
+ listItem.remove();
28003
+ if (!list.querySelector("li")) {
28004
+ const p2 = doc.createElement("p");
28005
+ p2.innerHTML = "<br>";
28006
+ (_b = list.parentNode) == null ? void 0 : _b.replaceChild(p2, list);
28007
+ range2.selectNodeContents(p2);
28008
+ range2.collapse(true);
28009
+ selection.removeAllRanges();
28010
+ selection.addRange(range2);
28011
+ }
28012
+ } else {
27517
28013
  e.preventDefault();
27518
- handleToolbarAction(`h${e.key}`);
28014
+ const newLi = doc.createElement("li");
28015
+ newLi.innerHTML = "&nbsp;<br>";
28016
+ listItem.insertAdjacentElement("afterend", newLi);
28017
+ range2.selectNodeContents(newLi);
28018
+ range2.collapse(true);
28019
+ selection.removeAllRanges();
28020
+ selection.addRange(range2);
27519
28021
  }
27520
- break;
27521
- // Indentation
27522
- case "]":
27523
- e.preventDefault();
27524
- handleToolbarAction("indent");
27525
- break;
27526
- case "[":
27527
- e.preventDefault();
27528
- handleToolbarAction("outdent");
27529
- break;
28022
+ }
27530
28023
  }
27531
28024
  }
28025
+ if (!e.ctrlKey && !e.metaKey) return;
28026
+ const matchingShortcut = shortcuts.find((shortcut) => {
28027
+ const keyMatch = shortcut.key === e.key;
28028
+ const modifiersMatch = !shortcut.modifiers || (!shortcut.modifiers.ctrl || e.ctrlKey || e.metaKey) && (!shortcut.modifiers.alt || e.altKey) && (!shortcut.modifiers.shift || e.shiftKey);
28029
+ return keyMatch && modifiersMatch;
28030
+ });
28031
+ if (matchingShortcut) {
28032
+ e.preventDefault();
28033
+ executor.execute(matchingShortcut.command);
28034
+ }
27532
28035
  });
27533
28036
  }
28037
+ function isAtEndOfNode(node, range2) {
28038
+ var _a2;
28039
+ if (node.nodeType === 3) {
28040
+ return range2.startOffset === node.length;
28041
+ }
28042
+ const { lastChild: lastChild2 } = node;
28043
+ if (!lastChild2) return true;
28044
+ if (lastChild2.nodeType === 3) {
28045
+ return range2.startContainer === lastChild2 && range2.startOffset === ((_a2 = lastChild2.textContent) == null ? void 0 : _a2.length);
28046
+ }
28047
+ return range2.startContainer === node && range2.startOffset === node.childNodes.length;
28048
+ }
28049
+ function isNodeEmpty(node) {
28050
+ var _a2;
28051
+ const text = ((_a2 = node.textContent) == null ? void 0 : _a2.replace(/\s/g, "")) || "";
28052
+ if (text) return false;
28053
+ const brElements = node.getElementsByTagName("br");
28054
+ if (brElements.length === 0) return true;
28055
+ return brElements.length === 1 && node.childNodes.length <= 2;
28056
+ }
27534
28057
  const _hoisted_1$s = { class: "bagel-input" };
27535
28058
  const _hoisted_2$i = { class: "content-area radius-05" };
27536
28059
  const _hoisted_3$e = {
@@ -27551,58 +28074,104 @@ const _sfc_main$z = /* @__PURE__ */ defineComponent({
27551
28074
  const emit2 = __emit;
27552
28075
  const iframe = ref();
27553
28076
  const editor = useEditor();
27554
- const commands = useCommands(editor.state, props2.debug ? editor.debug : void 0);
27555
- const debugMethods = computed(() => props2.debug ? editor.debug : void 0);
28077
+ const isInitializing = ref(false);
28078
+ const hasInitialized = ref(false);
28079
+ if (props2.debug) {
28080
+ editor.initDebugger();
28081
+ }
28082
+ const commands = useCommands(editor.state, editor.state.debug);
28083
+ const debugMethods = computed(() => editor.state.debug);
27556
28084
  const hasRTL = computed(() => /[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]/.test(props2.modelValue));
28085
+ onUnmounted(() => {
28086
+ editor.cleanup();
28087
+ });
27557
28088
  async function initEditor() {
27558
28089
  var _a2;
27559
- if (!iframe.value) {
27560
- setTimeout(initEditor, 100);
28090
+ console.log("[initEditor] Starting, isInitializing:", isInitializing.value, "hasInitialized:", hasInitialized.value);
28091
+ if (isInitializing.value || !iframe.value || hasInitialized.value) {
28092
+ console.log("[initEditor] Skipped - already initializing/initialized or no iframe");
27561
28093
  return;
27562
28094
  }
27563
- editor.state.content = props2.modelValue || "";
27564
- const doc = iframe.value.contentDocument || ((_a2 = iframe.value.contentWindow) == null ? void 0 : _a2.document);
27565
- if (!doc) return;
27566
- doc.designMode = "on";
27567
- doc.body.contentEditable = "true";
27568
- doc.body.dir = hasRTL.value ? "rtl" : "ltr";
27569
- const style = doc.createElement("style");
27570
- style.textContent = (await import("./editor-BKPRpAjr.js")).default;
27571
- doc.head.appendChild(style);
27572
- editor.init(doc);
27573
- useEditorKeyboard(doc, commands.execute);
27574
- if (!doc.body.firstElementChild) {
27575
- const p2 = doc.createElement("p");
27576
- p2.dir = doc.body.dir;
27577
- p2.innerHTML = "<br>";
27578
- doc.body.appendChild(p2);
27579
- } else {
27580
- const walker = doc.createTreeWalker(doc.body, NodeFilter.SHOW_TEXT);
27581
- const textNodes = [];
27582
- let node;
27583
- while (node = walker.nextNode()) {
27584
- if (node.parentElement === doc.body) {
27585
- textNodes.push(node);
27586
- }
28095
+ isInitializing.value = true;
28096
+ try {
28097
+ const editorStyles = await import("./editor-7QC0nG_c.js");
28098
+ const htmlContent = `
28099
+ <!DOCTYPE html>
28100
+ <html>
28101
+ <head>
28102
+ <meta charset="UTF-8">
28103
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
28104
+ <meta http-equiv="Content-Security-Policy" content="
28105
+ default-src * data: blob: 'unsafe-inline' 'unsafe-eval';
28106
+ img-src * data: blob:;
28107
+ style-src * 'unsafe-inline';
28108
+ script-src * 'unsafe-inline' 'unsafe-eval';
28109
+ frame-src * data: blob:;
28110
+ connect-src *;
28111
+ media-src *;
28112
+ ">
28113
+ <base target="_blank">
28114
+ <style id="editor-styles">${editorStyles.default}</style>
28115
+ </head>
28116
+ <body>${props2.modelValue || ""}</body>
28117
+ </html>
28118
+ `;
28119
+ const doc = iframe.value.contentDocument || ((_a2 = iframe.value.contentWindow) == null ? void 0 : _a2.document);
28120
+ if (!doc) {
28121
+ console.warn("[initEditor] No document found");
28122
+ return;
27587
28123
  }
27588
- textNodes.forEach((textNode) => {
27589
- var _a3;
27590
- if ((_a3 = textNode.textContent) == null ? void 0 : _a3.trim()) {
27591
- const p2 = doc.createElement("p");
27592
- p2.dir = doc.body.dir;
27593
- p2.appendChild(textNode.cloneNode());
27594
- doc.body.replaceChild(p2, textNode);
27595
- } else {
27596
- doc.body.removeChild(textNode);
28124
+ doc.open();
28125
+ doc.write(htmlContent);
28126
+ doc.close();
28127
+ await new Promise((resolve) => setTimeout(resolve, 0));
28128
+ doc.designMode = "on";
28129
+ doc.body.contentEditable = "true";
28130
+ doc.body.dir = hasRTL.value ? "rtl" : "ltr";
28131
+ editor.init(doc);
28132
+ useEditorKeyboard(doc, commands);
28133
+ if (!doc.body.firstElementChild) {
28134
+ const p2 = doc.createElement("p");
28135
+ p2.dir = doc.body.dir;
28136
+ p2.innerHTML = "<br>";
28137
+ doc.body.appendChild(p2);
28138
+ } else {
28139
+ const walker = doc.createTreeWalker(doc.body, NodeFilter.SHOW_TEXT);
28140
+ const textNodes = [];
28141
+ let node;
28142
+ while (node = walker.nextNode()) {
28143
+ if (node.parentElement === doc.body) {
28144
+ textNodes.push(node);
28145
+ }
27597
28146
  }
27598
- });
28147
+ textNodes.forEach((textNode) => {
28148
+ var _a3;
28149
+ if ((_a3 = textNode.textContent) == null ? void 0 : _a3.trim()) {
28150
+ const p2 = doc.createElement("p");
28151
+ p2.dir = doc.body.dir;
28152
+ p2.appendChild(textNode.cloneNode());
28153
+ doc.body.replaceChild(p2, textNode);
28154
+ } else {
28155
+ doc.body.removeChild(textNode);
28156
+ }
28157
+ });
28158
+ }
28159
+ doc.body.focus();
28160
+ hasInitialized.value = true;
28161
+ } catch (error) {
28162
+ console.error("[initEditor] Error during initialization:", error);
28163
+ } finally {
28164
+ isInitializing.value = false;
27599
28165
  }
27600
- doc.body.focus();
27601
28166
  }
27602
- watch(() => props2.modelValue, (newValue) => {
28167
+ watch(() => props2.modelValue, (newValue, oldValue) => {
27603
28168
  if (newValue !== editor.state.content) {
27604
- editor.state.content = newValue;
27605
- editor.updateContent("html");
28169
+ if (!oldValue || Math.abs(newValue.length - oldValue.length) > 50) {
28170
+ console.log("[watch] Significant content change, resetting initialization state");
28171
+ hasInitialized.value = false;
28172
+ editor.state.content = newValue;
28173
+ editor.updateState.content("html");
28174
+ }
27606
28175
  }
27607
28176
  });
27608
28177
  watch(() => editor.state.content, (newValue) => {
@@ -27635,6 +28204,8 @@ const _sfc_main$z = /* @__PURE__ */ defineComponent({
27635
28204
  ref: iframe,
27636
28205
  class: "editableContent",
27637
28206
  title: "Editor",
28207
+ sandbox: "allow-same-origin allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-presentation allow-scripts allow-top-navigation allow-top-navigation-by-user-activation",
28208
+ src: "about:blank",
27638
28209
  onLoad: initEditor
27639
28210
  }, null, 544)
27640
28211
  ]),
@@ -27643,7 +28214,7 @@ const _sfc_main$z = /* @__PURE__ */ defineComponent({
27643
28214
  modelValue: unref(editor).state.content,
27644
28215
  "onUpdate:modelValue": [
27645
28216
  _cache[0] || (_cache[0] = ($event) => unref(editor).state.content = $event),
27646
- _cache[1] || (_cache[1] = ($event) => unref(editor).updateContent("html"))
28217
+ _cache[1] || (_cache[1] = ($event) => unref(editor).updateState.content("html"))
27647
28218
  ],
27648
28219
  language: "html"
27649
28220
  }, null, 8, ["modelValue"])) : createCommentVNode("", true)
@@ -27692,7 +28263,7 @@ const _sfc_main$z = /* @__PURE__ */ defineComponent({
27692
28263
  };
27693
28264
  }
27694
28265
  });
27695
- const RichText = /* @__PURE__ */ _export_sfc(_sfc_main$z, [["__scopeId", "data-v-08117333"]]);
28266
+ const RichText = /* @__PURE__ */ _export_sfc(_sfc_main$z, [["__scopeId", "data-v-b58de58d"]]);
27696
28267
  const _hoisted_1$r = { class: "flex gap-05" };
27697
28268
  const _hoisted_2$h = ["disabled"];
27698
28269
  const _hoisted_3$d = { key: 1 };