NAME
ort-javascript
—
produce ort TypeScript
interface
SYNOPSIS
ort-javascript |
[-S sharedir]
[config...] |
DESCRIPTION
Accepts ort(5)
config files, defaulting to standard input, and
creates a TypeScript interface that format the JSON produced by
ort-c-header(1)
json_xxxx
()
functions and ort-nodejs(1) exports. Its arguments are as follows:
-S
sharedir- Directory containing external source files. The default is to use the install-time directory.
Output consists of an ES2021 "ort" namespace with classes that fill data from the JSON into a DOM tree by operating on elements having specific classes. (While ES2021 is an official baseline; in practice, output code conforms to ES7 or even ES6.) The output of is fully documented using TypeDoc.
Namespaces
All data produced by ort-javascript
is
contained within a namespace "ort". For example, let
"foo" be a struct
defined in the
configuration.
namespace ort { export interface DataCallbacks { ... } export interface fooData { ... } export class foo { ... } }
Interfaces
Each struct
in the configuration is
rendered as a TypeScript interface suffixed "Data", for example,
ort.fooData for a structure named "foo".
Each native field is mapped to a native type. For references, the type is
the referenced interface type.
namespace ort { export interface fooData { sometext: string; someint: string|number; somenumber: number; areference: barData; } }
Types are mapped as follows, from ort(5) configuration type to the TypeScript type along with any notes.
bit |
number|string | |
date |
number|string | |
epoch |
number|string | |
int |
number|string | |
real |
number | |
blob |
string | base-64 encoded |
text |
string | |
email |
string | |
enum |
number|string | |
bits |
number|string |
Front-ends should be attentive to integer types being either string or numeric. This is to accommodate for the 53-bit limit of what's stored as 64-bit integers.
If a field may not be exported due to role restrictions, it is marked as optional within the interface.
In addition to this, a ort.DataCallbacks interface is defined for Customisation and contains callback functions for each field for formatting purposes.
Classes
Each struct
in the configuration is
rendered as a class whose members may be used for formatting output. They
are named as found in the configuration.
The following methods are generated for each structure.
- new
foo
(obj: ort.fooData|ort.fooData[]): foo - Constructor passed an object or array. The array may consist of zero objects.
fillInner
(e: HTMLElement|null, custom?: ort.DataCallbacks|null): void- Fill labelled elements within (but not including) element
e, with optional call-backs
custom. If e is
null
, does nothing. fillInnerByClass
(e: HTMLElement|null, name: string, custom?: ort.DataCallbacks|null): void- Convenience method for invoking
fillInner
() over all descendents of element e having class name. If e isnull
, does nothing. The "inner" applies to both e and the matched descendents. fill
(e: HTMLElement|null, custom?: ort.DataCallbacks|null): void- Fill labelled elements within (including) element e,
with optional call-backs custom. If
e is
null
, does nothing. fillByClass
(e: HTMLElement|null, name: string, custom?: ort.DataCallbacks|null): void- Convenience method for invoking
fill
() over all descendents of (and including) element e having class name. If e isnull
, does nothing. fillArray
(e: HTMLElement|null, custom?: ort.DataCallbacks|null): void- First adds the "hide" class to e, then
invokes
fill
() repeatedly over the objects (or standalone object) passed at construction time by removing, then subsequently cloning and appending, the first element of e. Thefill
() function is passed the new element's root and custom. If e isnull
or empty, does nothing except add the "hide" class to e. fillArrayByClass
(e: HTMLElement|null, name: string, custom?: ort.DataCallbacks|null): void- Convenience method for invoking
fillArray
() over all descendents of (and including) element e having class name. If e isnull
, does nothing. fillArrayOrShow
(e: HTMLElement|null, toshow: HTMLElement|null, custom?: ort.DataCallbacks|null): void- Convenience method around fillArray removing the "hide" class from toshow if the object or objects at construction are non-empty.
fillArrayOrHide
(e: HTMLElement|null, tohide: HTMLElement|null, custom?: ort.DataCallbacks|null): void- Convenience method around fillArray adding the "hide" class to tohide if the object or objects at construction are empty.
Formatting within the elements passed to these methods operates on specific class names.
The following class names are recognised, letting "foo" be the name of a structure in the config and "xxxx" be any of its fields. If the field is not exported at all or in the given role, no action is taken at all on the following.
foo-xxxx-bits-checked
- Sets or unsets the
checked
attribute depending upon whether the input'svalue
attribute (if found), as a bit index, is set in the object as a bit-field. Only applicable to bit and bitfield types. foo-xxxx-date-text
- Replaces the contents of the element with the ISO 8601 date of the object's value. Only applicable to date and epoch types. Does nothing if the object is null.
foo-xxxx-date-value
- Sets the
value
attribute to the ISO 8601 date of the object's value. Only applicable to date and epoch types. Does nothing if the object is null. foo-xxxx-enum-select
- Sets or unsets the
selected
attribute on descending (non-inclusive)<option>
elements depending upon whether the input'svalue
attribute (if found) matches. foo-xxxx-obj
- For structures, creates and invokes the
fillInner
() method on the nested structure at the given element and its descendents. This is only applicable for structure types. foo-xxxx-text
- Replaces the contents of the element with the field value. This is not applicable to blob native types.
foo-xxxx-value
- Sets the
value
attribute (as in a form submission) with the field value. This is not applicable to blob native types. foo-xxxx-value-checked
- Sets or unsets the
checked
attribute depending upon whether the input'svalue
attribute matches the objects. This is not applicable to blob or structure types. foo-has-xxxx
- Remove the "hide" class if the object is null, otherwise add the "hide" class.
foo-no-xxxx
- Add the “hide” class if the object is null, otherwise remove the “hide” class.
All class methods accept an optional argument for providing custom per-field or per-structure callbacks. Keys in the object must consist of the structure name, followed by a dash, followed by the field name. For example, assuming a structure “client” with a field “dob” consisting of a UNIX epoch:
const custom: ort.DataCallbacks = { 'client-dob': formatDate }; new ort.client(obj).fillInner(document.body, custom);
And letting a formatting function be:
function formatDate(e: HTMLElement, name: string, v: number|string|null): void { /* Do something... */ }
The same can be applied to structures instead of to fields within structures. The keys for these are simply the structure name.
const custom: ort.DataCallbacks = { 'client': formatClient }; new ort.client(obj).fillInner(document.body, custom);
The callback will then be provided the full client object.
function formatClient(e: HTMLElement, name: string, v: ort.clientData|null): void { /* Do something... */ }
In either case, the value for the custom key may also be an array of functions just as above. Each will be invoked in the order given, in the same way.
const custom: ort.DataCallbacks = { 'client': [ format1, format2 ] };
The callback function (or functions) will be invoked regardless of
whether the value has been set. In the event of an unset field value, the
function is passed null
.
For example, to fill in the label of an enumeration
enum someenum
on a field named
val
, provide a custom callback.
const e = document.getElementById('foo'); const obj = <ort.fooData>JSON.parse(response); const custom: ort.DataCallbacks = { 'foo-val': ort.someenum.format }; new ort.foo(obj).fill(e, custom);
Static Classes
Each enumeration and bitfield corresponds to a class with field values and formatting static methods.
Enumeration classes contains static members with the string value of its items. For example, an enumeration "foo" will produce a class "foo" with static members corresponding to each enumeration item.
Bitfield classes are similarly named and contain two static
members per item: one for the bit index, one for the generated bit mask. The
former is prefixed BITI_
and is a number, the latter
with BITF_
and is a string. Thus an item
"bar" creates numeric static members
BITI_bar and BITF_bar. There is
always a BITI__MAX that is one greater than the
largest item's value.
Each enumeration corresponds to a class with field values and
formatting static methods. These take advantage of the
jslabel
enumeration label described in
ort(5).
format
(e: HTMLElement, name: string|null, value: string|number|null): void- Fills in all elements (not inclusive) descending from
e having class name-label with
the configuration label corresponding to the enumeration value
value. If name is
null
, the element itself has its contents filled in.If value is null, the "ort-class" is added and the
isnull
label is used (or an empty string).
If a language is specified in the root of the HTML or XML document with the "lang" attribute, it is first matched a label for that language. If there is no language, or none for that label, the default label is used. If there is no default label, an empty string is used instead. An empty string is also used for invalid enumeration values.
A common label fill idiom is as follows:
<div id="place"> <span class="foo-val-label>label</span>: <span class="foo-val-text>text</span> </div>
Letting the field "val" have type enum
anenum
, both label and text may be filled in as follows:
const custom: ort.DataCallbacks = { 'foo-val': ort.anenum.format };
This will fill in both the jslabel
of the
value's corresponding item and the value itself.
Bitfields behave similarly and have the same member.
format
(e: HTMLElement, name: string|null, value: string|number|null): void- Fills in all elements (not inclusive) descending from
e having class name-label with
all configuration labels with corresponding bits set in
value. If name is
null
, the element itself has its contents filled in.If value is
null
, the "ort-null" class is added and theisnull
label is used (or an empty string). If value is zero, the "ort-unset" class is added and theisunset
label is used (or an empty string). Multiple matching labels are separated by a comma and space. If any given bit doesn't have or match a label, it is not given any label text.
EXIT STATUS
The ort-javascript
utility exits 0
on success, and >0 if an error occurs.
EXAMPLES
Start with a means to contact a CGI script producing JSON data
formatted by the json_xxxx
() family of
ort-c-header(1). This
does not do any error checking. Let this file be called
script.ts.
function init(): void { const xmh = new XMLHttpRequest(); xmh.onreadystatechange = function(){ const v = xmh.responseText; if (xmh.readyState === 4 && xmh.status === 200) success(v); }; xmh.open('GET', 'https://your-cgi-script', true); xmh.send(); }
Now in the same file, define success
() to
parse the JSON response content using the classes and methods defined in the
output of ort-javascript
.
function success(resp: string): void { const obj = <ort.fooData>JSON.parse(resp); new ort.foo(obj).fill (document.getElementById('place')); }
To drive the script, cause init
() to be
invoked when the page has loaded.
window.addEventListener('load', init);
The following abbreviated HTML in which to display the contents of these objects. Let foo.js be the concatenated transpiled output of all TypeScript files.
<!DOCTYPE html> <html lang="en"> <head> <title>Example</title> <script src="foo.js"></script> </head> <body> <div id="place"> <span class="foo-xxxx-text> Replaced by the "text" field. </span> </div> </body> </html>
Assuming a configuration file foo.ort, the following creates the single JavaScript file:
% ort-javascript foo.ort > foo.ts % npx tsc --outFile foo.js foo.ts script.ts
Depending on the typescript version,
--target
es2021 and
--libs
es2021,dom may need to
passed as additional arguments.