aboutsummaryrefslogtreecommitdiff
path: root/static/ts/vevent.ts
diff options
context:
space:
mode:
Diffstat (limited to 'static/ts/vevent.ts')
-rw-r--r--static/ts/vevent.ts126
1 files changed, 102 insertions, 24 deletions
diff --git a/static/ts/vevent.ts b/static/ts/vevent.ts
index 07f25d02..6aaa6984 100644
--- a/static/ts/vevent.ts
+++ b/static/ts/vevent.ts
@@ -2,13 +2,20 @@ import { ical_type, valid_input_types, JCal, JCalProperty, ChangeLogEntry } from
import { parseDate } from './lib'
export {
- VEvent, xml_to_vcal,
RecurrenceRule,
+ Redrawable,
+ VEvent,
+ VEventValue,
+ freqType,
isRedrawable,
+ list_values,
+ weekday,
+ xml_to_vcal,
}
/** Something which can be redrawn */
interface Redrawable extends HTMLElement {
+ /** Method which will be called upon a redraw request. */
redraw(data: VEvent): void
}
@@ -17,14 +24,27 @@ function isRedrawable(x: HTMLElement): x is Redrawable {
return 'redraw' in x
}
+/**
+ A single value from a vcomponent.
+ This is basically a type tagged tuple, with an optional map of parameters.
+*/
class VEventValue {
+ /** The value type of the contained value. */
type: ical_type
- /* value should NEVER be a list, since multi-valued properties should
- be split into multiple VEventValue objects! */
+ /**
+ The actual value.
+
+ Should NEVER be a list, since those are coded as
+ lists of `VEventValue`:s in `Vevent.properties`
+ */
value: any
+
+ /**
+ VComponent parameters attached to the value.
+ */
parameters: Map<string, any>
constructor(type: ical_type, value: any, parameters = new Map) {
@@ -82,34 +102,46 @@ class VEventValue {
}
/* TODO maybe ... */
-class VEventDuration extends VEventValue {
-}
+// class VEventDuration extends VEventValue {
+// }
+/** VComponent properties which contain lists */
type list_values
= 'categories' | 'resources' | 'freebusy' | 'exdate' | 'rdate'
| 'CATEGORIES' | 'RESOURCES' | 'FREEBUSY' | 'EXDATE' | 'RDATE';
-/*
- Abstract representation of a calendar event (or similar).
-All "live" calendar data in the frontend should live in an object of this type.
- */
/**
- * Component for a single instance of a calendar event. Almost all data
- * access should go through `getProperty` and `setProperty`,
- * with the exception of the current calendar (which is accessed directly
- * through `calendar`). Almost all changes through these interfaces
- * are logged, and can be viewed through `changelog`.
+ This class is the data container for the underlying VEVENT objects in the
+ backend calendar files. They also keep track on all Web Components which
+ wants to render part of the event.
+
+ Note that despite the name this component isn't limited to VEVENT:s, but is
+ used for all VComponents in the tree. This means that even calendars and
+ alarms can be instances of this class.
+
+ Property access is done through `getProperty` and `setProperty` (properties
+ are things such as 'SUMMARY', 'DTSTART', ...)
*/
class VEvent {
- /* Calendar properties */
+ /**
+ Properties bound directly on this object.
+
+ These are things such as 'DTSTART', 'SUMMARY', ...
+ */
private properties: Map<string, VEventValue | VEventValue[]>
- /* Children (such as alarms for events) */
+ /**
+ Children to this component.
+
+ Valid children depends on the type. For example, for calendars this is
+ primarily events, while for events it's alarm components
+ */
components: VEvent[]
- /* HTMLElements which wants to be redrawn when this object changes.
- Elements can be registered with the @code{register} method.
+ /**
+ HTMLElements which wants to be redrawn when this object changes.
+ Elements can be registered with the `register` method.
*/
registered: Redrawable[]
@@ -122,13 +154,19 @@ class VEvent {
*/
#changelog: ChangeLogEntry[] = []
- /* Iterator instead of direct return to ensure the receiver doesn't
- modify the array */
- /** Public (read only) interface to changelog. */
+ /**
+ The changelog for this component.
+
+ An iterator is returned rather than an array, to ensure modifications are
+ impossible.
+ */
get changelog(): IterableIterator<[number, ChangeLogEntry]> {
return this.#changelog.entries();
}
+ /**
+ Add an entry to the changelog.
+ */
addlog(entry: ChangeLogEntry) {
let len = this.#changelog.length
let last = this.#changelog[len - 1]
@@ -153,6 +191,17 @@ class VEvent {
}
}
+ /**
+ Construct a new Component.
+
+ @param properties
+ Initial properties for the component
+
+ @param components
+ Initial children for the component
+
+ TODO where is the type of the component registered?
+ */
constructor(
properties: Map<string, VEventValue | VEventValue[]> = new Map(),
components: VEvent[] = []
@@ -202,7 +251,7 @@ class VEvent {
return this.properties.keys()
}
- private setPropertyInternal(key: string, value: any, type?: ical_type) {
+ #setPropertyInternal(key: string, value: any, type?: ical_type) {
function resolve_type(key: string, type?: ical_type): ical_type {
if (type) {
return type;
@@ -273,7 +322,7 @@ class VEvent {
* objects, notifying them of the change.
*/
setProperty(key: string, value: any, type?: ical_type) {
- this.setPropertyInternal(key, value, type);
+ this.#setPropertyInternal(key, value, type);
for (let el of this.registered) {
el.redraw(this);
@@ -286,7 +335,7 @@ class VEvent {
*/
setProperties(pairs: [string, any, ical_type?][]) {
for (let pair of pairs) {
- this.setPropertyInternal(...pair);
+ this.#setPropertyInternal(...pair);
}
for (let el of this.registered) {
el.redraw(this);
@@ -307,6 +356,11 @@ class VEvent {
}
}
+ /**
+ Get the name of the containing calendar for this component.
+
+ This is only valid for VEVENT components (I think)
+ */
get calendar(): string | null {
return this.#calendar;
}
@@ -354,6 +408,7 @@ class VEvent {
}
}
+/** Helper procedure when converting xml to vcal */
function make_vevent_value(value_tag: Element): VEventValue {
/* TODO parameters */
return new VEventValue(
@@ -367,23 +422,46 @@ function make_vevent_value(value_tag: Element): VEventValue {
+/** Different frequency internals for recurrence rules. */
type freqType = 'SECONDLY' | 'MINUTELY' | 'HOURLY' | 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'YEARLY'
+
+/** Alternatives for when a week start, for recurrence rules */
type weekday = 'MO' | 'TU' | 'WE' | 'TH' | 'FR' | 'SA' | 'SU'
+/**
+ A recurrence rule.
+
+ The basic semantics of this class is borrowed from RFC 5545, and maps 1-to-1
+ on those instances. See individual fields for mappings.
+ */
class RecurrenceRule {
+ /** The type of frequency of this rule */
freq?: freqType
+ /** Final instance of this rule. */
until?: Date
+ /** Maximum number of recurrences for this rule */
count?: number
+ /** The multiplier to `freq` */
interval?: number
+ /** Which seconds are relevant for this rule */
bysecond?: number[]
+ /** Which minutes are relevant for this rule */
byminute?: number[]
+ /** Which hours are relevant for this rule */
byhour?: number[]
+ /** Which weekday or weekday offsets are relevant for this rule */
byday?: (weekday | [number, weekday])[]
+ /** Which month days are relevant for this rule */
bymonthday?: number[]
+ /** Which year days are relevant for this rule */
byyearday?: number[]
+ /** Which week number are relevant for this rule */
byweekno?: number[]
+ /** Which months relevant for this rule (interval 1-12) */
bymonth?: number[]
+ /** TODO see the RFC */
bysetpos?: number[]
+ /** Which day the week start, according to this rule */
wkst?: weekday
/** Converts ourselves to JCal data. */