aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2022-03-15 01:14:45 +0100
committerHugo Hörnquist <hugo@lysator.liu.se>2022-03-15 01:43:12 +0100
commit2d35caa4b3e025a57c626f89c665da31ffbfe27d (patch)
treef22ad2d5c07626f116ca7c3a8762fd2fe68d6855
parentMake make-routes pre-compile all regexes. (diff)
downloadcalp-2d35caa4b3e025a57c626f89c665da31ffbfe27d.tar.gz
calp-2d35caa4b3e025a57c626f89c665da31ffbfe27d.tar.xz
Introduce concept of VEvent formatters in frontend.
-rw-r--r--doc/ref/javascript.texi1
-rw-r--r--doc/ref/javascript/components/vevent_description.texi6
-rw-r--r--doc/ref/javascript/formatters.texi12
-rw-r--r--doc/ref/javascript/vevent.texi1
-rw-r--r--static/components/vevent-description.ts26
-rw-r--r--static/formatters.ts29
6 files changed, 55 insertions, 20 deletions
diff --git a/doc/ref/javascript.texi b/doc/ref/javascript.texi
index 7510e4f5..434b556f 100644
--- a/doc/ref/javascript.texi
+++ b/doc/ref/javascript.texi
@@ -17,6 +17,7 @@ All elements are initialized in elements.ts
@include javascript/vevent.texi
@include javascript/globals.texi
@include javascript/server_connect.texi
+@include javascript/formatters.texi
@node General Components
@section General Components
diff --git a/doc/ref/javascript/components/vevent_description.texi b/doc/ref/javascript/components/vevent_description.texi
index 492c8dff..54dda7e3 100644
--- a/doc/ref/javascript/components/vevent_description.texi
+++ b/doc/ref/javascript/components/vevent_description.texi
@@ -7,4 +7,10 @@
A text representation of a VEvent. Used as the summary tab of our
popup windows, and in the sidebar.
+
+When redrawn, it looks for an HTML-tag inside its template having the
+attribute @code{data-property} matching the properties name. If one is
+found, it looks in the @code{formatters} table
+(@ref{formatters-proc}), for a field matching the property value, and
+defaults to the key @code{default}.
@end deftp
diff --git a/doc/ref/javascript/formatters.texi b/doc/ref/javascript/formatters.texi
new file mode 100644
index 00000000..65df48c4
--- /dev/null
+++ b/doc/ref/javascript/formatters.texi
@@ -0,0 +1,12 @@
+@node formatters
+@subsection formatters
+
+Formatting procedures used by some components.
+@c TODO can we have a backref of every node containing @ref{formatters-proc}?
+
+@deftypevar {Map<string, (e:HTMLElement, s:any) => void>} formatters
+@anchor{formatters-proc}
+
+Each procedure takes two arguments. The HTML-element which contents
+should be replaced, along with the target value, as returned by @ref{VEvent.getProperty}.
+@end deftypevar
diff --git a/doc/ref/javascript/vevent.texi b/doc/ref/javascript/vevent.texi
index ae54cfd4..4ceaa380 100644
--- a/doc/ref/javascript/vevent.texi
+++ b/doc/ref/javascript/vevent.texi
@@ -31,6 +31,7 @@ through @code{calendar}). Almost all changes through these interfaces
are logged, and can be viewed in @var{_changelog}.
@deftypemethod VEvent {any?} getProperty {key: string}
+@anchor{VEvent.getProperty}
Returns the value of the given property if set, or undefined otherwise.
For the keys
diff --git a/static/components/vevent-description.ts b/static/components/vevent-description.ts
index 4d81d6b3..f0d224be 100644
--- a/static/components/vevent-description.ts
+++ b/static/components/vevent-description.ts
@@ -2,7 +2,7 @@ export { ComponentDescription }
import { VEvent } from '../vevent'
import { ComponentVEvent } from './vevent'
-import { makeElement } from '../lib'
+import { formatters } from '../formatters'
/*
<vevent-description />
@@ -24,26 +24,12 @@ class ComponentDescription extends ComponentVEvent {
for (let el of body.querySelectorAll('[data-property]')) {
if (!(el instanceof HTMLElement)) continue;
let p = el.dataset.property!;
- let d, fmt;
+ let d;
if ((d = data.getProperty(p))) {
- switch (p.toLowerCase()) {
- case 'categories':
- for (let item of d) {
- let q = encodeURIComponent(
- `(member "${item}" (or (prop event (quote CATEGORIES)) (quote ())))`)
- el.appendChild(makeElement('a', {
- textContent: item,
- href: `/search/?q=${q}`,
- }))
- }
- break;
- default:
- if ((fmt = el.dataset.fmt)) {
- el.textContent = d.format(fmt);
- } else {
- el.textContent = d;
- }
- }
+ let key = p.toLowerCase();
+ let f = formatters.get(key);
+ if (f) f(el, d);
+ else window.formatters.get('default')!(el, d);
}
}
diff --git a/static/formatters.ts b/static/formatters.ts
new file mode 100644
index 00000000..38c71e5e
--- /dev/null
+++ b/static/formatters.ts
@@ -0,0 +1,29 @@
+export {
+ formatters,
+}
+
+import { makeElement } from './lib'
+
+let formatters : Map<string, (e : HTMLElement, s : any) => void>;
+formatters = window.formatters = new Map();
+
+
+formatters.set('categories', (el, d) => {
+ for (let item of d) {
+ let q = encodeURIComponent(
+ `(member "${item}" (or (prop event (quote CATEGORIES)) (quote ())))`)
+ el.appendChild(makeElement('a', {
+ textContent: item,
+ href: `/search/?q=${q}`,
+ }))
+ }
+})
+
+formatters.set('default', (el, d) => {
+ let fmt;
+ if ((fmt = el.dataset.fmt)) {
+ el.textContent = d.format(fmt);
+ } else {
+ el.textContent = d;
+ }
+})