Whakerexa > JavaScript > Design

Definition of the needs

The problem, and what is aimed at

A page uses Whakerexa where it is read: served by a server, or opened from a disk with nothing serving it. The two do not load the same way — modules over http, one file from a disk — and a page that has to work both ways wrote that choice itself, in twenty lines it copied from another page.

What is aimed at is a page that says once what it loads and what it brings, and a framework whose parts do not know each other: a component announces what it has done without naming who listens, and a page starts what is its own when everything is there.

This dossier records what the JavaScript base of the framework decides. It was written after the code it describes, which is the wrong order: it is the state of the decisions, to be amended where they do not suit.

Organisation of the needs

J10 Loading

  • J11 One tag loads the framework, whatever the protocol the document is read under.
  • J12 What a page calls is named the same way whether the modules or the single file answered.
  • J13 A page says what it brings — its themes, its sets of icons, its extras — where it already says what it loads.
  • J14 A path a page writes is read as the page wrote it: from the page, from the root of the site, from another host, and from where the tool stands only when nothing else is said.
  • J15 What a page brings is registered before anything reads the address, a name registered afterwards being one the framework has already refused.

J20 What the framework holds

  • J21 A service that must exist once is already built and answers under a lowercase name.
  • J22 A component a page may own several of is given as a class, under its own name.
  • J23 The framework holds one global and no more: what a page or a build leaves for it is left on that one.

J30 What a page runs of its own

  • J31 Code that waits for the document runs when the document is there, in the order it was given.
  • J32 A page starts what is its own once the framework and the extras it asked for are there, and receives them.

J40 Between the components

  • J41 A component announces what it has done without knowing who listens.
  • J42 What is announced is named by its domain first, then by what happened.

J50 What is said to whoever wrote the page

  • J51 What the framework says is filtered by level.
  • J52 What goes wrong is said in the console, and the page holds.

What was set aside

Loading a part of the framework alone: every page of the documentation uses the whole of it, and a page that uses two components would gain a few kilobytes against a mechanism nobody asked for.

A page that adds a theme or a set once it is open. What a page brings is known when it is written.

The decisions

Loading

D1. The loader, or the page's own wiring, and never half of each. Either wexa.loader.js is asked for everything — it reads the protocol, registers the themes and the sets, and hands the namespace to bootPage —, or the page names wexa.js or wexa.bundle.js and does the registering itself. Half of each is what J15 forbids: a theme registered after the loader has read the address is a name already refused.

D2. A path is read from the base only when it is written bare. js/extras/book.js stands where the framework stands, and nothing else does: ./ and ../ are read from the page, / from the root of the site, a scheme from its host J14. What a page brings has no reason to stand under wexa_statics/, nor to be written as if it did.

D3. What the framework carries of its own is written by a build, not held in the loader. The themes of the framework and the drawings of its reference set are inventories, written from the folders that hold them. The loader reads them; it does not know them.

The namespace

D4. One global, and everything on it. Wexa is made by whoever gets there first and completed by the others: a file that a page loads before the framework makes the object if it has to, and wexa.js adds to what it finds J23. A second global would be one too many, which the style guide of the project already says.

D5. A service is built, a component is given. What must exist once — the logger, the manager of the icons, the one of the dialogs — is already built and answers under a lowercase name. What a page may own several of — a menu, a progress bar, a keyboard — is a class it builds itself J21 J22.

Between the components

D6. A component dispatches an event on the document rather than calling what listens. What is announced does not have to know who hears it J41, and a page that hears nothing loses nothing. The name carries its domain first, then what happened — slides:navigate, slides:viewmode, wexa:slides:ready J42 — so that a page reads what it listens to. It is also what a keyboard shortcut may be given instead of a function.

D7. Nothing raises in the reader's face. What goes wrong is said in the console, at its level, and the page holds J51 J52: a drawing that does not arrive leaves a button without a drawing, not a page without a menu.

The tests, and the build

What follows is of the repository and not of the distribution: neither the tests nor the script that writes the bundle are given to whoever uses Whakerexa.

Tests

The unit tests are in js/tests/, one file per tested class, and they run in a browser: tests.html puts the classes on the global object, imports the test files, and every assertion writes in the console, green or red. The page has to be served, since it loads modules.

From the root of the repository, then open http://localhost:8000/wexa_statics/js/tests/tests.html.

python3 -m http.server 8000

A test file builds a UnitTest, adds its functions, and launches them at the end of the file.

const keyboard_tests = new UnitTest('KeyboardController');

keyboard_tests.add_test(function test_declared_key() {
    const controller = new KeyboardController();
    controller.register({keys: ['n'], action: 'page:next'});
    UnitTest.assert_values_equals(controller.shortcuts.length, 1);
});

keyboard_tests.launch_unit_test();

Building the bundle

The bundle is generated from the sources: the script reads the files in the order it declares, removes the import and export lines, and writes one file. A source that changes leaves the bundle behind until it is built again, and a page opened from the disk keeps showing the old behaviour.

You have nothing to build: wexa.bundle.js is written before every release and comes with the framework. The script that writes it lives in the repository, for whoever works on Whakerexa itself.