diff options
Diffstat (limited to '')
-rw-r--r-- | static/ts/lib.ts | 136 |
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 = ""; |