aboutsummaryrefslogtreecommitdiff
path: root/static/ts/lib.ts
diff options
context:
space:
mode:
Diffstat (limited to 'static/ts/lib.ts')
-rw-r--r--static/ts/lib.ts136
1 files changed, 132 insertions, 4 deletions
diff --git a/static/ts/lib.ts b/static/ts/lib.ts
index 2ef5b596..14cdd4f2 100644
--- a/static/ts/lib.ts
+++ b/static/ts/lib.ts
@@ -1,3 +1,86 @@
+/**
+ * General procedures which in theory could be used anywhere.
+ *
+ * Besides exporting the mentioned functions, this module also extends some base
+ * classes.
+ *
+ * ```tex
+@node Default prototype extensions
+@subsubsection Default prototype extensions
+
+
+
+@defmethod HTMLElement addEventListener name proc
+Replace the default @code{addEventListener} with a version that stores
+all listeners in the dictionary @var{listeners}.
+@end defmethod
+
+@defivar HTMLElement listeners
+Dictionary of all registered listeners to this element.
+Keys are taken from @code{addEventListener}.
+@end defivar
+
+@defmethod DOMTokenList find regexp
+Finds the first element of the DOMTokenList whichs value matches
+the supplied regexp. Returns a pair of the index and the value.
+@end defmethod
+
+@defmethod Object format args ...
+Returns a string representation of the given object.
+Allows extending for custom types,
+@ref{date-format}
+@end defmethod
+ * ```
+ *
+ * ---
+ *
+ * ```tex
+Some extensions to the builtin class ``Date'' is made.
+
+@defivar Date utc
+Boolean indicating if the given timestamp is in UTC or local time.
+true means UTC.
+@end defivar
+
+@defivar Date dateonly
+Boolean indicating if the time component of the Date object should be disregarded.
+@end defivar
+
+ * ```
+ * ```tex
+@defmethod Date format str args ...
+@anchor{date-format}
+Formats a Date object according to the format specification @var{str}.
+Keeping with Guile each format specifier starts with a ~.
+
+@table @samp
+@item ~~
+literal ~
+@c Almost all fields are left padded. How do I signify this
+@c with a single footnote?
+@item ~Y
+year, left-padding with zeroes.
+@item ~m
+month number, left padded with zeroes.
+@item ~d
+day of month.
+@item ~H
+hour
+@item ~M
+minute
+@item ~S
+second
+@item ~Z
+'Z' if Date is UTC, otherwise nothing
+@item ~L
+Converts the date to local time
+(@pxref{to_local}) (doesn't modify source object). Outputs nothing
+@end table
+@end defmethod
+```
+ *
+ * @module
+ */
export {
makeElement, date_to_percent,
parseDate, gensym, to_local, to_boolean,
@@ -5,10 +88,6 @@ export {
}
/*
- General procedures which in theory could be used anywhere.
- */
-
-/*
* https://www.typescriptlang.org/docs/handbook/declaration-merging.html
*/
declare global {
@@ -16,6 +95,7 @@ declare global {
format: (fmt: string) => string
}
+ /** HTMLElement extensions */
interface HTMLElement {
_addEventListener: (name: string, proc: (e: Event) => void) => void
listeners: Map<string, ((e: Event) => void)[]>
@@ -70,6 +150,13 @@ HTMLElement.prototype.getListeners = function() {
century, due to how javascript works (...).
*/
+/**
+ * Takes a string `str`, which should be in ISO-8601 date-format, and
+ * returns a javascript Date object.
+ * Handles date-times, with and without seconds, trailing `Z' for
+ * time-zones, and dates without times.
+ * If no time is given the `dateonly` attribute is set to yes.
+ */
function parseDate(str: string): Date {
let year: number;
let month: number;
@@ -112,6 +199,12 @@ function parseDate(str: string): Date {
return date;
}
+/* @anchor{to_local} */
+/**
+ * Returns a Date object (which may be new) which is guaranteed in local time.
+ * This means that the `utc` field is `false`, and that
+ * `to_local(current_time())` should show what your wall-clock shows.
+ */
function to_local(date: Date): Date {
if (!date.utc) return date;
@@ -120,6 +213,27 @@ function to_local(date: Date): Date {
/* -------------------------------------------------- */
+/**
+ * Creates a new DOM element of type `name`, with all keys in
+ * `attr` transfered to it. For example, the equivalent of
+
+ * ```html
+ * <input type='number'/>
+ * ```
+
+ * would be
+
+ * ```js
+ * values.push(makeElement('input', {
+ * type: 'number',
+ * }));
+ * ```
+ *
+ * @param name HTML tagname
+ * @param attr Attributes which will be set on the created element.
+ * @param actualAttr Attributes which will be set on the created element,
+ * but through `el.setAttribute` instead of `el[key] =`...
+ */
function makeElement(name: string, attr = {}, actualAttr = {}): HTMLElement {
let element: HTMLElement = document.createElement(name);
for (let [key, value] of Object.entries(attr)) {
@@ -131,6 +245,7 @@ function makeElement(name: string, attr = {}, actualAttr = {}): HTMLElement {
return element;
}
+/** TODO document me */
function round_time(time: number, fraction: number): number {
let scale = 1 / fraction;
return Math.round(time * scale) / scale;
@@ -142,14 +257,26 @@ function round_time(time: number, fraction: number): number {
Just doing (new Date()/(86400*1000)) would be nice, but there's no good
way to get the time in the current day.
*/
+/**
+ * Retuns how far along the date specified by `date` is, between 0
+ * and 100, where 00:00 maps to 0, and 23:59 to ~100.
+ */
function date_to_percent(date: Date): number /* in 0, 100 */ {
return (date.getHours() + (date.getMinutes() / 60)) * 100 / 24;
}
/* if only there was such a thing as a let to wrap around my lambda... */
/* js infix to not collide with stuff generated backend */
+/**
+ * Generates a new string which is (hopefully) globally unique.
+ * Compare with `gensym` from Lisp.
+ */
const gensym = (counter => (prefix = "gensym") => prefix + "js" + ++counter)(0)
+/**
+ * Ensures that `thing` is a list. Returning it outright if it
+ * already is one, otherwise wrapping it in a list.
+*/
function asList<T>(thing: Array<T> | T): Array<T> {
if (thing instanceof Array) {
return thing;
@@ -182,6 +309,7 @@ function datepad(thing: number | string, width = 2): string {
return (thing + "").padStart(width, "0");
}
+/** Equivalent to `date.format(str)` */
function format_date(date: Date, str: string): string {
let fmtmode = false;
let outstr = "";