Skip to content

8. Operations

Contents of DESL 0.2

8.1 Operations

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).

8.2 Actions

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, when included, MUST see the effects of every action run before it, including earlier iterations of an enclosing forEach. The list of a forEach is evaluated once, before its first iteration; a let value once, where it appears.
  • Positional create. after and before (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's children MUST be ordered. Without either, a new child is appended last.
  • Reorder. A reorder MUST change only the order among siblings. A by that would move an element past the first or last place rolls the transaction back.
  • Move (DESL 0.2). A move changes an element's parent, slot and place and nothing else: the element keeps its id, its attributes and everything it contains. after and before (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 whose children, or slot, does not allow the element's type, rolls the transaction back. It is planned as FBL's move change (FBL sections 6.4, 11.2), so the element's bytes travel unchanged, re-indented in the bullets family. A move whose parent and slot are the element's own is planned as a reorder.
"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.

8.3 Confirmation

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.

Referenced from