1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
function recur_xml_to_rrule(dom_element) {
let rr = new RRule;
for (let child of dom_element.children) {
let key = child.tagName; /* freq */
let val = child.textContent; /* weekly */
rr[key] = val;
}
return rr;
}
function recur_jcal_to_rrule(jcal) {
let rr = new RRule;
for (var key in jcal) {
rr[key] = jcal[key];
}
return rr;
}
class RRule {
/* direct access to fields is fine */
/* setting them however requires methods, since there might
be listeners */
fields = ['freq', 'until', 'count', 'interval',
'bysecond', 'byminute', 'byhour',
'bymonthday', 'byyearday', 'byweekno',
'bymonth', 'bysetpos', 'wkst',
'byday'
]
constructor() {
this.listeners = {}
for (let f of this.fields) {
this[f] = false;
Object.defineProperty(
this, f, {
/*
TODO many of the fields should be wrapped
in type tags. e.g. <until> elements are either
<date> or <date-time>, NOT a raw date.
by* fields should be wrapped with multiple values.
*/
get: () => this['_' + f],
set: (v) => {
this['_' + f] = v
for (let l of this.listeners[f]) {
l(v);
}
}
});
this.listeners[f] = [];
}
}
addListener(field, proc) {
this.listeners[field].push(proc);
}
/* NOTE this function is probably never used.
Deperate it and refer to RRule.asJcal
together with jcal_to_xcal */
asXcal(doc) {
/* TODO empty case */
// let str = "<recur>";
let root = doc.createElementNS(xcal, 'recur');
for (let f of this.fields) {
let v = this.fields[f];
if (! v) continue;
let tag = doc.createElementNS(xcal, f);
/* TODO type formatting */
tag.textContent = `${v}`;
root.appendChild(tag);
}
return root;
}
asJcal() {
let obj = {};
for (let f of this.fields) {
let v = this[f];
if (! v) continue;
/* TODO special formatting for some types */
obj[f] = v;
}
return obj;
}
/*
asIcal() {
return this.fields
.map(f => [f, this.fields[f]])
.filter([_, v] => v)
.map(([k, v]) => `${k}=${v}`)
.join(';');
}
*/
};
|