on-codemerge
Version:
A WYSIWYG editor for on-codemerge is a user-friendly interface that allows users to edit and view their code in real time, exactly as it will appear in the final product
286 lines (285 loc) • 10.3 kB
JavaScript
/*! on-codemerge v1.3.1 @author Pavel Kuzmin @license MIT @homepage https://s00d.github.io/on-codemerge/ @repository git+https://github.com/s00d/on-codemerge.git Copyright (c) 2026 Pavel Kuzmin - Built on 2026-07-02T13:39:17.947Z */
var E = Object.defineProperty;
var u = (l, e, t) => e in l ? E(l, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[e] = t;
var c = (l, e, t) => u(l, typeof e != "symbol" ? e + "" : e, t);
import { CategoryManager as y } from "./CategoryManager.mjs";
import { ReminderService as p } from "./ReminderService.mjs";
class S {
constructor() {
c(this, "calendarsKey", "html-editor-calendars");
c(this, "eventsKey", "html-editor-calendar-events");
c(this, "categoryManager");
c(this, "reminderService");
this.categoryManager = new y(), this.reminderService = new p(this);
}
getCalendars() {
const e = localStorage.getItem(this.calendarsKey);
return e ? JSON.parse(e) : [];
}
getCalendar(e) {
return this.getCalendars().find((r) => r.id === e) || null;
}
createCalendar(e) {
const t = this.getCalendars(), r = {
id: crypto.randomUUID(),
title: e.title,
description: e.description,
events: e.events ? e.events.map((n) => this.createEvent(n)) : [],
createdAt: Date.now(),
updatedAt: Date.now()
};
return t.push(r), localStorage.setItem(this.calendarsKey, JSON.stringify(t)), r;
}
updateCalendar(e, t) {
const r = this.getCalendars(), n = r.findIndex((i) => i.id === e);
if (n === -1)
throw new Error("Calendar not found");
const { events: a, ...s } = t, o = {
...r[n],
...s,
events: a ? a.map((i) => this.createEvent(i, e)) : r[n].events,
updatedAt: Date.now()
};
return r[n] = o, localStorage.setItem(this.calendarsKey, JSON.stringify(r)), o;
}
deleteCalendar(e) {
const t = this.getCalendars().filter((r) => r.id !== e);
localStorage.setItem(this.calendarsKey, JSON.stringify(t)), this.reminderService.deleteEventReminders(e);
}
getEvents(e) {
return this.getAllEvents().filter((r) => r.calendarId === e);
}
getEvent(e) {
return this.getAllEvents().find((r) => r.id === e) || null;
}
createEvent(e, t) {
const r = this.getAllEvents(), n = {
id: crypto.randomUUID(),
title: e.title,
description: e.description,
date: e.date,
time: e.time,
duration: e.duration,
location: e.location,
color: e.color,
isAllDay: e.isAllDay,
priority: e.priority || "medium",
category: e.category,
tags: e.tags || [],
attendees: e.attendees || [],
reminder: e.reminder,
recurring: e.recurring,
attachments: e.attachments || [],
calendarId: t || "default",
createdAt: Date.now(),
updatedAt: Date.now()
};
return r.push(n), localStorage.setItem(this.eventsKey, JSON.stringify(r)), n.reminder && t && this.reminderService.createReminder(n, t), n;
}
updateEvent(e, t) {
const r = this.getAllEvents(), n = r.findIndex((o) => o.id === e);
if (n === -1)
throw new Error("Event not found");
const a = r[n], s = {
...a,
...t,
updatedAt: Date.now()
};
return r[n] = s, localStorage.setItem(this.eventsKey, JSON.stringify(r)), t.reminder !== void 0 && a.reminder !== t.reminder && (this.reminderService.deleteEventReminders(e), t.reminder && s.calendarId && this.reminderService.createReminder(s, s.calendarId)), s;
}
deleteEvent(e) {
const t = this.getAllEvents().filter((r) => r.id !== e);
localStorage.setItem(this.eventsKey, JSON.stringify(t)), this.reminderService.deleteEventReminders(e);
}
getEventsByDate(e) {
return this.getAllEvents().filter((r) => r.date === e);
}
getEventsByDateRange(e, t) {
return this.getAllEvents().filter((n) => {
const a = new Date(n.date), s = new Date(e), o = new Date(t);
return a >= s && a <= o;
});
}
// Новые методы для работы с категориями и тегами
getEventsByCategory(e) {
return this.getAllEvents().filter((r) => r.category === e);
}
getEventsByTag(e) {
return this.getAllEvents().filter((r) => {
var n;
return (n = r.tags) == null ? void 0 : n.includes(e);
});
}
getEventsByPriority(e) {
return this.getAllEvents().filter((r) => r.priority === e);
}
searchEvents(e) {
const t = this.getAllEvents(), r = e.toLowerCase();
return t.filter(
(n) => {
var a, s, o;
return n.title.toLowerCase().includes(r) || ((a = n.description) == null ? void 0 : a.toLowerCase().includes(r)) || ((s = n.location) == null ? void 0 : s.toLowerCase().includes(r)) || ((o = n.tags) == null ? void 0 : o.some((i) => i.toLowerCase().includes(r)));
}
);
}
// Методы для работы с категориями и тегами
getCategoryManager() {
return this.categoryManager;
}
getReminderService() {
return this.reminderService;
}
// Генерация HTML с напоминаниями
generateCalendarHTMLWithReminders(e) {
const t = this.getCalendar(e);
if (!t) return "";
const r = this.reminderService.generateReminderScript(e);
return `
${this.generateCalendarHTML(t)}
${r}
`;
}
// Генерация HTML календаря
generateCalendarHTML(e) {
const n = this.getEvents(e.id).sort((a, s) => {
const o = /* @__PURE__ */ new Date(`${a.date}T${a.time}`), i = /* @__PURE__ */ new Date(`${s.date}T${s.time}`);
return o.getTime() - i.getTime();
}).map((a) => this.generateEventHTML(a)).join("");
return `
<div class="calendar-widget" data-calendar-id="${e.id}">
<div class="calendar-header">
<h3 class="calendar-title">${e.title}</h3>
</div>
<div class="calendar-body">
<div class="calendar-events">
${n}
</div>
</div>
</div>
`;
}
// Генерация HTML события
generateEventHTML(e) {
const t = e.priority || "medium", r = e.color || "#3b82f6", n = e.category || "General", s = new Date(e.date).toLocaleDateString("ru-RU", {
day: "numeric",
month: "short",
year: "numeric"
}), o = e.tags && e.tags.length > 0 ? `<div class="event-tags">${e.tags.map((h) => `<span class="event-tag">${h}</span>`).join("")}</div>` : "", i = e.attendees && e.attendees.length > 0 ? `<span class="event-attendees">👥 ${e.attendees.join(", ")}</span>` : "", g = e.reminder ? `<span class="event-reminder">⏰ ${e.reminder}</span>` : "", v = e.location ? `<span class="event-location">📍 ${e.location}</span>` : "", m = e.duration ? `<span class="event-duration">⏱️ ${e.duration} min</span>` : "", d = [v, m, i, g].filter(Boolean).join(" • ");
return `
<div class="calendar-event" data-event-id="${e.id}" style="--event-color: ${e.color || "#3b82f6"}">
<div class="event-header">
<div class="event-datetime">
<div class="event-date">${s}</div>
<div class="event-time">${e.time}</div>
</div>
<div class="event-priority priority-${t}">${t.toUpperCase()}</div>
</div>
<div class="event-title">${e.title}</div>
${e.description ? `<div class="event-description">${e.description}</div>` : ""}
<div class="event-meta">
<div class="event-category" style="background-color: ${r}">${n}</div>
${d ? `<div class="event-meta-info">${d}</div>` : ""}
</div>
${o}
</div>
`;
}
getAllEvents() {
const e = localStorage.getItem(this.eventsKey);
return e ? JSON.parse(e) : [];
}
exportCalendar(e) {
const t = this.getCalendar(e);
if (!t)
throw new Error("Calendar not found");
const r = this.getEvents(e), n = {
calendar: t,
events: r,
categories: this.categoryManager.getCategories(),
tags: this.categoryManager.getTags(),
exportDate: (/* @__PURE__ */ new Date()).toISOString()
};
return JSON.stringify(n, null, 2);
}
importCalendar(e) {
try {
const t = JSON.parse(e), r = t.calendar, n = t.events || [], a = t.categories || [], s = t.tags || [];
a.forEach((i) => {
this.categoryManager.createCategory(i.name, i.color);
}), s.forEach((i) => {
this.categoryManager.createTag(i.name, i.color);
});
const o = this.createCalendar({
title: r.title,
description: r.description
});
return n.forEach((i) => {
this.createEvent(i, o.id);
}), o;
} catch {
throw new Error("Invalid calendar data format");
}
}
copyCalendar(e) {
const t = this.getCalendar(e);
if (!t)
throw new Error("Calendar not found");
const r = this.getEvents(e), n = this.createCalendar({
title: `${t.title} (Copy)`,
description: t.description
});
return r.forEach((a) => {
this.createEvent(
{
title: a.title,
description: a.description,
date: a.date,
time: a.time,
duration: a.duration,
location: a.location,
color: a.color,
isAllDay: a.isAllDay,
priority: a.priority,
category: a.category,
tags: a.tags,
attendees: a.attendees,
reminder: a.reminder,
recurring: a.recurring,
attachments: a.attachments
},
n.id
);
}), n;
}
copyEvent(e) {
const t = this.getEvent(e);
if (!t)
throw new Error("Event not found");
const n = this.getAllEvents().find((a) => a.id === e);
if (!n)
throw new Error("Event calendar not found");
return this.createEvent(
{
title: `${t.title} (Copy)`,
description: t.description,
date: t.date,
time: t.time,
duration: t.duration,
location: t.location,
color: t.color,
isAllDay: t.isAllDay,
priority: t.priority,
category: t.category,
tags: t.tags,
attendees: t.attendees,
reminder: t.reminder,
recurring: t.recurring,
attachments: t.attachments
},
n.calendarId
);
}
}
export {
S as CalendarManager
};