8. Operations
Contents of DESL 0.2
An Operation ($defs/Operation) is a named command that one gesture of the surface runs. A designer SHOULD declare one operation per gesture, so that every host makes the same model changes for the same gesture; which gesture starts each is the host's, and the specification's prose beside the .des names them.
| Property | Type | Description |
|---|---|---|
label |
Message | Required. Menu and button text; context operation without p. |
doc |
Doc | |
for |
TypeRefs, "selection" or "document" |
Required. What the operation applies to: an element of the types (bound as self), the selected elements (bound as selection), or the document. |
params |
map → Attribute | Its parameters, given by the gesture, as p in its expressions. |
unavailable |
Reason[] | Why it cannot run now; context operation without p. While one applies, the gesture is disabled with that reason, and refused with it when it is invoked anyway. |
confirm |
Message or Confirmation | The question asked before it runs (8.3). |
actions |
Action[] | Required. Its body, run as one transaction (10.3). |
Actions are a small, closed set of steps. Every value in an action is an Expression (2.5).
| Action | Form | Effect |
|---|---|---|
set |
{ "set": { "attr": expr, … }, "target": expr } |
Assign attributes of target (default self); target may be document. |
unset |
{ "unset": ["attr", …], "target": expr } |
Remove stored values. (DESL 0.2) Planned as a set of each attribute to no value (FBL section 11.2). |
create |
{ "create": { "type": expr, "attributes": {…}, "parent": expr, "slot": expr, "after": expr, "before": expr }, "as": "name" } |
Create an element, in parent (default: the document) and its slot; the new element is name in later actions. |
delete |
{ "delete": expr } |
Delete an element or a list of them, with what they contain. |
reorder |
{ "reorder": { "target": expr, "by": expr } }, or with after or before in place of by |
Change only an element's place among its siblings: by a signed number of places, or directly after or before a sibling. |
move |
{ "move": { "target": expr, "parent": expr, "slot": expr, "after": expr, "before": expr } } |
(DESL 0.2) Move target (default self), with everything it contains, into parent (null: among the document's own elements) and its slot, directly after or before a sibling there, else last. |
let |
{ "let": { "name": expr } } |
Bind a name for later actions. |
if |
{ "if": expr, "then": [ … ], "else": [ … ] } |
Run one list or the other. |
forEach |
{ "forEach": expr, "as": "name", "do": [ … ] } |
Run a list for each item of a list, bound as name (default item). |
Every action MAY carry when, which skips it unless true, and doc.
- Order of evaluation. Actions MUST run in order against the transaction's working state, and every expression,
whenincluded, MUST see the effects of every action run before it, including earlier iterations of an enclosingforEach. The list of aforEachis evaluated once, before its first iteration; aletvalue once, where it appears. - Positional create.
afterandbefore(at most one) name a sibling. The new element MUST be placed directly after or before it, and the sibling MUST have the same parent (or both have none); otherwise the transaction is rolled back with an error. The parent'schildrenMUST beordered. Without either, a new child is appended last. - Reorder. A
reorderMUST change only the order among siblings. Abythat would move an element past the first or last place rolls the transaction back. - Move (DESL 0.2). A
movechanges an element's parent, slot and place and nothing else: the element keeps its id, its attributes and everything it contains.afterandbefore(at most one) name a sibling in the new parent, as for a positional create. A move into the element itself or into something it contains, or into a parent whosechildren, or slot, does not allow the element's type, rolls the transaction back. It is planned as FBL'smovechange (FBL sections 6.4, 11.2), so the element's bytes travel unchanged, re-indented in thebulletsfamily. Amovewhose parent and slot are the element's own is planned as areorder.
"moveProperty": { "label": "Move", "for": ["Property"],
"params": { "after": { "type": "Property" } },
"actions": [
{ "reorder": { "after": "p.after" }, "when": "has(p.after)" },
{ "reorder": { "before": "document.elementsOfType('Property')[0]" }, "when": "!has(p.after)" } ] }
Dragging a column header to the far left moves its property before the first one; anywhere else, after the property it was dropped behind.
confirm is a Message, which asks every time, or a Confirmation ($defs/Confirmation):
| Property | Type | Description |
|---|---|---|
message |
Message | Required. The question; it may use count. |
when |
Expression → bool | Ask only while it holds. Default true. |
count |
Expression → int | A number the question is about, bound as count. |
threshold |
int | Ask only when count >= threshold. Default 0. |
doc |
Doc |
A runtime MUST ask before the transaction when when holds and, with count, count >= threshold; otherwise it MUST proceed without asking. Its expressions are evaluated in the operation context, with p once the parameters are known.