ComponentJS
. It is a common convention to change the symbol to cs
(for
"component system/service") to have a convenient short-hand.
.
minor.
micro"
and the corresponding release date (in format YYYYMMDD).
window
in a browser, global
in
Node.js, etc).
0
disables all debug messages, 9
enables all debug messages) or log a particular
message under debug-level level.
debugger
to be loaded!
debugger
to be loaded!
true
/false
open/close the extra browser window
containing the ComponentJS debugger view for the ComponentJS application
identified by name. If autoclose is true
,
optionally automatically close the debugger window with application window
(which usually is inconvenient during debugging because on application
reloads the ComponentJS debugger window is recreated with default width/height
at default position instead of reused). Parameters width and height can be
used to change the initial window size. Parameter natural controls whether
the component tree is drawn with the root component at the bottom (true
)
or at the top (false
).
cs.clazz
!
window
. A namespace has a
dot-separated fully-qualified symbol path like foo.bar.quux
. This
method allows to create the fully-qualified path of nested objects through the
dot-separated path of object names, optionally assign the
right-most/leaf object to leave and finally return the right-most/leaf Object.
path | ::= | segment segment* |
segment | ::= | bybareword | bykey |
bybareword | ::= | ". "? identifier |
bykey | ::= | "[ " key "] " |
identifier | ::= | /[_a-zA-Z$][_a-zA-Z$0-9]* / |
key | ::= | number | squote | dquote |
number | ::= | /[0-9]+ / |
dquote | ::= | /"(?:\\"|.)*?" / |
squote | ::= | /'(?:\\'|.)*?' / |
undefined
effectively removes the
dereferenced value. If the dereferenced parent object is a hash, this
means the value is delete
'ed from it. If the dereferenced parent
object is an array, this means the value is splice
'ed out of it.
RegExp
object for String validation, a validation function of signature
"spec(Object): Boolean" or a string following the following grammar (which
is a mixture of JSON-like structure and RegExp-like quantifiers):
spec | ::= | not | alt | hash | array | any | primary | class | special |
not | ::= | "! " spec |
alt | ::= | "( " spec ("| " spec)* ") " |
hash | ::= | "{ " (key arity? ": " spec (", " key arity? ": " spec)*)? "} " |
array | ::= | "[ " (spec arity? (", " spec arity?)*)? "] " |
arity | ::= | "? " | "* " | "+ " | "{ " number ", " (number | "oo ") "} " |
number | ::= | /^[0-9]+$ / |
key | ::= | /^[_a-zA-Z$][_a-zA-Z$0-9]*$ / | "@ " |
any | ::= | "any " |
primary | ::= | /^(?:null|undefined|boolean|number|string|function|object)$ / |
class | ::= | /^[A-Z][_a-zA-Z$0-9]*$ / |
special | ::= | /^(?:clazz|trait|component)$ / |
@
" can be used to match an arbitrary hash element key.
arguments
array. Parameter name is the name
of the function for use in exceptions in case of invalid parameters.
Parameter args usually is the JavaScript arguments
pseudo-array of
a function. Parameter spec is the parameter specification: each key
is the name of a parameter and the value has to be an Object with
the following possible fields: pos for the optional position in case
of positional usage, def for the default value (of not required
and hence optional parameters), req to indicate whether the
parameter is required and valid for type validation (either
a string accepted by the validate() method,
or a valid regular expression C object
for validating a String against it or an arbitrary validation callback function
of signature "valid(Object): Boolean".
prototypes
object. The statics content is copied into the
Class itself only. In case of extend and/or mixin, both the cons
and methods of protos can call this.base(...)
for the base/super/parent
method.
this.base()
in any method of a class resolves. When on
class Foo
and its instanciated object foo
a method foo.bar()
is called, the following happens:
bar
on object foo
is tried.
This can exist on foo
through (in priority order) a bar
in
either the dynamics definition of a mixin of Foo
, or in the
statics definition of a mixin of Foo
, or in the dynamics
definition of Foo
, or in the statics definition of Foo
.
bar
on object
foo
is tried. This can exist on foo
through (in priority order)
a bar
in either the protos definition of Foo
or in the
protos definition of any extend of Foo
.
Foo
and its instanciated object foo
in any method foo.bar()
the this.base()
is called, the following happens:
prototypes
object. The statics content is copied into the
Class itself only. The optional setup function is called directly at the end of Class
definition (not instantiation) and can further refine the defined Class.
{...}
) of slash-separated (.../...
) paths
of component names. In other words, the specification has to follow the
following grammar:
abs-tree-spec | ::= | "/" rel-tree-spec |
rel-tree-spec | ::= | path | "{ " path (", " path)* "} " |
path | ::= | rel-tree-spec | name ("/" name)* |
name | ::= | /^[^\/]+$ / |
foo/{bar/baz,quux}
is the
tree consisting of the two maximum length paths: foo/bar/baz
and foo/quux
.
For each name from left-to-right in the tree specification you have to give
either a to be instantiated class constructor (Function) or an already
instantiated object (Object).
undefined
) Object
.
" for current component name, "..
" for parent
component name, "*
" for any component name and an empty name (C/>) for
any component trees between current and following components. In any case, the result has
to uniquely identify a single component.
The following usages exist:
1. Lookup Component by absolute path path (this is usually never done explicitly,
but occurs implicitly if the input parameter is already a Component).
2. Lookup Component by path path, relative to Component component.
3. Lookup Component by path path, relative to the Component corresponding
to Object object.
4. Lookup Component object via backing object object.
5. Lookup Component object via the component itself (no-operation).
The paths have to follow the following grammar:
abs-path | ::= | "/" rel-path |
rel-path | ::= | name ("/" name)* |
name | ::= | "" | "* " | /^[^\/]+$ / |
<none>
") really
exists in the component tree.
null
if component is the root or none component.
ctx =
callback(depth++, comp, ctx)
" where
initially ctx=
ctx, comp=
component and depth=
0
was set.
ctx =
callback(depth, comp, ctx, false)
" when entering the component (before all children will be
visited) and once like "ctx =
callback(depth, comp, ctx, true)
" when leaving a component (after all children
were visited). Initially ctx=
ctx, comp=
component and depth=
0
is set.
null
)null
parameter) or add one state transition to target state
target, either at the top of the transition stack or in the middle, above the source state
source. When entering the target state, the optional component backing object method enter is
called. When leaving the target state, the optional component backing object method leave is called.
The color is a "#RRGGBB" string used for visualizing the state in the debugger view. The default
state transition definitions are given as an example.
ComponentJS:state:
state:enter
"
(after the higher state state was entered from the state below it) or
"ComponentJS:state:
state:leave
" (after the higher state
state was left towards the state below it). You can subscribe to those
in order to react to state transitions from outside the component, too.
By default if the current and requested state of component is
just different, the current state is transitioned towards the requested
state. Setting parameter min to true
skips the transition if
the current state is already higher or equal to the requested state.
Setting parameter max to true
skips the transition if
the current state is already lower or equal to the requested state.
+1
and then followed by a -1
is a boolean guard.
An initial call of +N
and then followed by N times a -1
call is a Semaphore-like
guard which ensures that only after the Nth -1
call the guard is finally deactivated
again. This is useful if you activate the guard in order to await N asynchronous operations.
Then the guard should be deactivated once the last asynchronous operation is finished
(independent which one of the N operations this is). A guard level of 0
resets the guard, independent what its current level is.
upward
" or "downward
" direction
during the state transition process.
apply
(ctx, args)" on spool named name.
The name parameter can be either just a plain spool-name "name
"
or a combination of (relative) component-path and spool-name "path
:name
".
This allows one to spool on a component different from component (usually
a relative path back to the component of the caller of the spool() operation).
cs.marker.{service,model,view,controller}
can be mixed into.
undefined
,
def Objectundefined
,
scope Stringundefined
,
bubbling Booleantrue
,
targeting Booleantrue
,
returnowner Booleanfalse
}) Objectfalse
a property get operation does not resolve
on any parent components ("it does not bubble up to the root").
If targeting is set to false
a property get operation does not resolve
on the target component component (resolving starts on parent component).
If returnowner is set to true instead of the property value, the
owning component is returned.
Finally, properties can be scoped with a child component name or even
a descendant component name path: on each attempt
to resolve the property, first the scoped variants are tried. This means,
if a property was set with name "quux@bar
" (or with name "quux
" and an
explicitly scope set to "bar
") on component /foo
,
if you resolve the property with cs("/foo/bar", "quux")
you
get the value, but if you resolve the property with cs("/foo/baz", "quux")
you
do not get the value. This allows you to set the same property with different
values for different child components.
Additionally the scope can be a partial component path, too.
If a property was set with name "quux@bar/baz
" on component /foo
,
if you resolve the property with cs("/foo/bar/baz", "quux")
you
get the value, but if you resolve the property with cs("/foo/bar/baz2", "quux")
you
do not get the value. This allows you for instance to skip so-called intermediate namespace-only
components.
Setting value to "null
" removes the property.
If no property name is found at all, def (by default the value undefined
) is returned.
this
, the object parameter of plug()/unplug() as
first argument and component as the second argument.
The socket() method returns an id which uniquely identifies the socket.
Instead of having to manually release the socket later via unsocket()
you can use the spool mechanism and spool the corresponding unsocket()
operation via option spool.
true
) start the
operation on component instead of its parent component.
Returns an identifier for use with the corresponding unplug() operation.
true
) start the
operation on component instead of its parent component.
This is usually performed indirectly through the Spool mechanism.
localStorage
.
Multiple calls to the model() method on the same component incrementally
add model elements.
true
even setting a model element to its
current value triggers observers.
Setting the option injected to true
should be done by plugins
only and prevents model value observers from rejecting the (already
injected) value.
"get"
, "set"
, ["splice",
offset,
remove]
,
"delete"
, "push"
, "pop"
, "unshift"
and "shift"
.
The last four array operations are internally translated to the
corresponding splice
operation. The arguments to the splice
operation are the same as for JavaScript's Array.prototype.splice
:
"offset" is the 0-based offset into the array to operate at and
"remove" is the number of elements to remove at "offset" (before
the value is added). The operations get
/set
/delete
operate on collection elements while the operations
splice
/push
/pop
/unshift
/shift
operate on
collections, hence you have to provide a path in name which is suitable for them.
The operations get
/set
/delete
can operate on both array and
hash elements while splice
/push
/pop
/unshift
/shift
can operate on
array objects only.
capturing
, targeting
, spreading
or bubbling
{}
,
ctx Objectcomponent,
func Function,
args Object
,
capturing Booleanfalse
,
spreading Booleanfalse
,
bubbling Booleantrue
,
noevent Booleanfalse
,
exclusive Booleanfalse
,
spool Stringnull
}) Number(
ev:
Event
,
args:
Object, ...,
sargs:
Object, ...)
once the event is dispatched to component after it was published.
By default an event is dispatched in the (mandatory) targeting and (optional) bubbling phases.
this
" a particular value for the
callback func. Option args allows you to pass additional
parameters to func (before those passed by publish().
true
" indicates that the event should
be also dispatched in the capturing phase.
true
" indicates that the event should
be also dispatched in the spreading phase.
false
" indicates that the event should
not be dispatched in the bubbling phase.
true
" for an exclusive subscription, i.e.,
a subscription which prevents any subsequent subscriptions.
{}
,
async Booleanfalse
,
capturing Booleantrue
,
spreading Booleanfalse
,
bubbling Booleantrue
,
completed Function,
resultinit Objectundefined
,
resultstep Function,
directresult Booleanfalse
,
noresult Booleanfalse
,
firstonly Booleanfalse
,
silent Booleanfalse
,
args Object
}) Objectfalse
" indicates that the event should
not be intended to be dispatched in the capturing phase. The default
is to be dispatched in the capturing phase.
true
" indicates that the event should
also be intended to be dispatched in the spreading phase.
The default is not to be dispatched in the spreading phase.
false
" indicates that the event should
not be intended to be dispatched in the bubbling phase.
The default is to be dispatched in the bubbling phase.
true
events.
(old: any, cur: any): any
"
which aggregates the initial/old value and the current value into
a new value. The default for resultinit is "undefined
" and
the default for resultstep is "function (old, cur) { return cur }
",
meaning that just the last result will be kept. The result is
delivered with the result() method of returned Event objects.
ev.result()
instead of the Event object ev
.
undefined
instead of the Event object ev
. This
allows publish() to internally optimize the event handling
in case no Event object is necessary at all.
ev.propagation(false)
) once the first subscriber has
accepted the value (meaning: has not called ev.decline()
on the
Event object).
,
spool String,
capturing Booleanfalse
,
spreading Booleanfalse
,
bubbling Booleantrue
}) Numbertrue
to provide the service also in the "capturing" phase.
true
to provide the service also in the "spreading" phase.
false
to not provide the service in the "bubbling" phase.
ComponentJS:service:
name:callable
" is
published with two arguments: the new and old boolean value.
,
capturing Booleanfalse
,
spreading Booleanfalse
,
bubbling Booleantrue
}) Objecttrue
to deliver the underlying service event also in the "capturing" phase.
true
to deliver the underlying service event also in the "spreading" phase.
false
to not deliver the underlying service event in the "bubbling" phase.
testdrive
plugin.
testdrive
to be loaded!
testdrive
to be loaded!
(fulfill: (value?: any) => Promise,
reject: (value?: any) => Promise) => void
" in TypeScript definition syntax)
avoids a temporary variable.
testdrive
to be loaded!
() => void
" in TypeScript definition syntax).
The name is used for driving the use-case with drive()
and conf can be overwritten with drive().
The function func can either execute synchronously
or asynchronously. In case of a synchronous execution, the
return value of func does not matter. In case of an asynchronous
execution, the return value of func has to be a Promise/A+ based
promise (usually created with ensure(), await(), drive or poll implicitly,
or with promise() explicitly). The callback function receives the
actual configuration as the first parameter.
testdrive
to be loaded!
true
)
or rejected with an error message.
true
,
max Booleanfalse
,
sync Booleanfalse
}) Promisetestdrive
to be loaded!
true
), and/or at most (in case of max = true)
a particular state, by synchronously (in case of sync = true
) or asynchronously
(by default), triggering a state change on the component under path.
The state change is explicitly trigger by ensure() itself.
The function returns a Promise/A+ promise which is either fulfilled with the component
object corresponding to path or rejected with an error message.
"enter"
}) Promise"enter"
) Promise
testdrive
to be loaded!
"enter"
) or
leave (in case of direction = "enter"
). The enter/leave methods
of the component will be already called in both cases. The component
under path is NOT required to already exist. It is allowed
that it springs into existence later.
There is NO state change trigger by await() itself.
The function returns a Promise/A+ promise which is either fulfilled with the component
object corresponding to path or rejected with an error message.
600
) Promise
testdrive
to be loaded!
() =
Boolean> in TypeScript definition syntax) and
in case of a still false return waits through wait
and repeat from the beginning with a new round with check.
The wait function has to be of type "() => Promise
"
and usually delays processing (usually with setTimeout
())
and then resolves. If you pass a Number instead of a Function
to wait, a default implementation is used which waits the
number of milliseconds. The default for wait is 100
, i.e.,
it internally maps onto "function () { return cs.sleep(100); }
".
testdrive
to be loaded!
setTimeout
())
and then resolves the promise which is returned by this function.
null
) Promise
testdrive
to be loaded!
jQuery(selector).one(events, subselector, ...)
".
Additionally, in case events = "mutation"
the function
internally uses the HTML5 MutationObserver
functionality to
await a DOM mutation (in this case subselector is ignored).
vue
plugin and the underlying Vue rendering engine.
The vue
plugin provides the following distinct features:
v-bind:
attr="
name"
in the view mask. The
ComponentJS model values (by convention) named eventXXX
are
treated specially: Vue methods of the same name are generated
for them, which can be used like e.g. v-on:click="eventXXX"
(for
passing a Vue Event
instance, which is then converted into true
)
or v-on:click="eventXXX(
arg)"
(for receiving an arbitrary
single argument arg) in the view mask. The names of ComponentJS
model values are converted into valid Vue symbols by replacing
all [^a-zA-Z0-9_$]
characters with "_"
characters. Hence it
is recommended to use camel-case ComponentJS model values like
paramFooBar
, commandFooBar
, stateFooBar
, dataFooBar
, and
eventFooBar
only.utilXXX
in the backing object of the ComponentJS
(view) component. They can be used like v-if="utilXXX(...)"
in the
view masks for complex checks or calculations, if really necessary.data-socket="
[name][@
scope]"
lead to a ComponentJS socket with name and scope. The default
name is default
. The default scope is no scope at all.
The ctx
parameter of ComponentJS socket() is the DOM element
itself.vue
to be loaded!
template
field (with the view mask as either a string, a DOM fragment or a
jQuery DOM fragment) or a Vue render
field (with a compiled Vue
render function). The result is a rendered but unmounted Vue model instance
which can be later plugged into a ComponentJS socket with plug()
and/or further manipulated (with jQuery) through its Vue $el
field.
vue
to be loaded!