ORT-JAVASCRIPT(1) | General Commands Manual | ORT-JAVASCRIPT(1) |
ort-javascript
—
produce ort TypeScript interface
ort-javascript |
[-S sharedir]
[config...] |
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
sharedirOutput consists of the "ort" namespace with classes that fill data from the JSON into a DOM tree by operating on elements having specific classes. The output of is fully documented using TypeDoc.
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 { ... } }
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.
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.
foo
(obj:
ort.fooData|ort.fooData[]): foofillInner
(e:
HTMLElement|null, custom?:
ort.DataCallbacks|null): voidnull
, does nothing.fillInnerByClass
(e:
HTMLElement|null, name: string,
custom?: ort.DataCallbacks|null):
voidfillInner
() over
all descendents of element e having class
name. If e is
null
, does nothing. The "inner" applies
to both e and the matched descendents.fill
(e:
HTMLElement|null, custom?:
ort.DataCallbacks|null): voidnull
, does
nothing.fillByClass
(e:
HTMLElement|null, name: string,
custom?: ort.DataCallbacks|null):
voidfill
() over all
descendents of (and including) element e having
class name. If e is
null
, does nothing.fillArray
(e:
HTMLElement|null, custom?:
ort.DataCallbacks|null): voidfill
() repeatedly over the objects (or
standalone object) passed at construction time by removing, then
subsequently cloning and appending, the first element of
e. The fill
() function is
passed the new element's root and custom. If
e is null
or empty, does
nothing except add the "hide" class to
e.fillArrayByClass
(e:
HTMLElement|null, name: string,
custom?: ort.DataCallbacks|null):
voidfillArray
() over
all descendents of (and including) element e having
class name. If e is
null
, does nothing.fillArrayOrShow
(e:
HTMLElement|null, toshow: HTMLElement|null,
custom?: ort.DataCallbacks|null):
voidfillArrayOrHide
(e:
HTMLElement|null, tohide: HTMLElement|null,
custom?: ort.DataCallbacks|null):
voidFormatting 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
checked
attribute depending
upon whether the input's value
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
foo-xxxx-date-value
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
selected
attribute on
descending (non-inclusive) <option>
elements
depending upon whether the input's value
attribute
(if found) matches.foo-xxxx-obj
fillInner
()
method on the nested structure at the given element and its descendents.
This is only applicable for structure types.foo-xxxx-text
foo-xxxx-value
value
attribute (as in a form submission)
with the field value. This is not applicable to blob native types.foo-xxxx-value-checked
checked
attribute depending
upon whether the input's value
attribute matches
the objects. This is not applicable to blob or structure types.foo-has-xxxx
foo-no-xxxx
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: HTMLElement|null = document.getElementById('foo'); const obj: ort.fooData = <ort.fooData>JSON.parse(response); const custom: ort.DataCallbacks = { 'foo-val': ort.someenum.format }; new ort.foo(obj).fill(e, custom);
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):
voidnull
, 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):
voidnull
, the element itself has its contents filled
in.
If value is
null
, the "ort-null" class is added
and the isnull
label is used (or an empty
string). If value is zero, the
"ort-unset" class is added and the
isunset
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.
The ort-javascript
utility exits 0
on success, and >0 if an error occurs.
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 { let xmh: XMLHttpRequest = new XMLHttpRequest(); xmh.onreadystatechange = function(){ let v: string = 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 { let obj: ort.fooData = <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 output of tsc(1) over 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 % tsc --alwaysStrict --strict --outFile foo.js foo.ts script.ts
October 25, 2021 | OpenBSD 6.7 |