kernel.js 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013
  1. /*
  2. The MIT License (MIT)
  3. Copyright (c) 2014-2020 Nikolai Suslov and the Krestianstvo.org project contributors. (https://github.com/NikolaySuslov/livecodingspace/blob/master/LICENSE.md)
  4. Virtual World Framework Apache 2.0 license (https://github.com/NikolaySuslov/livecodingspace/blob/master/licenses/LICENSE_VWF.md)
  5. */
  6. /// Kernel API.
  7. ///
  8. /// @module vwf/api/kernel
  9. class Kernel {
  10. constructor() {
  11. //console.log("Kernel constructor");
  12. // TODO: setState
  13. // TODO: getState
  14. // TODO: hashState
  15. /// Create a node from a component specification. Construction may require loading data from
  16. /// multiple remote documents. This function returns before construction is complete. A callback
  17. /// is invoked once the node has fully loaded.
  18. ///
  19. /// A simple node consists of a set of properties, methods and events, but a node may specialize
  20. /// a prototype component and may also contain multiple child nodes, any of which may specialize
  21. /// a prototype component and contain child nodes, etc. So components cover a vast range of
  22. /// complexity. The application definition for the overall simulation is a single component
  23. /// instance.
  24. ///
  25. /// A node is a component instance--a single, anonymous specialization of its component. Nodes
  26. /// specialize components in the same way that any component may specialize a prototype
  27. /// component. The prototype component is made available as a base, then new or modified
  28. /// properties, methods, events, child nodes and scripts are attached to modify the base
  29. /// implemenation.
  30. ///
  31. /// To create a node, we first make the prototoype available by loading it (if it has not
  32. /// already been loaded). This is a recursive call to createNode() with the prototype
  33. /// specification. Then we add new, and modify existing, properties, methods, and events
  34. /// according to the component specification. Then we load an add any children, again
  35. /// recursively calling createNode() for each. Finally, we attach any new scripts and invoke an
  36. /// initialization function.
  37. ///
  38. /// @function
  39. ///
  40. /// @param {String|Object} nodeComponent
  41. /// @param {String} [nodeAnnotation]
  42. /// @param {String} [baseURI]
  43. /// @param {module:vwf/api/kernel~nodeCallback} [callback]
  44. ///
  45. /// @returns {}
  46. this.createNode = [ /* nodeComponent, nodeAnnotation, baseURI, callback( nodeID ) */ ]
  47. /// Delete a node.
  48. ///
  49. /// The node and all of its descendants will be removed from the application.
  50. ///
  51. /// @function
  52. ///
  53. /// @param {ID} nodeID
  54. ///
  55. /// @returns {}
  56. this.deleteNode = [ /* nodeID */ ]
  57. /// Set node will set the properties of the node specified by the given id and component.
  58. ///
  59. /// @function
  60. ///
  61. /// @param {ID} nodeID
  62. /// @param {String|Object} nodeComponent
  63. /// @param {module:vwf/api/kernel~nodeCallback} [callback]
  64. ///
  65. /// @returns {}
  66. this.setNode = [ /* nodeID, nodeComponent, callback( nodeID ) */ ]
  67. /// Get node will retrieve the component of the node specified by the given id.
  68. ///
  69. /// @function
  70. ///
  71. /// @param {ID} nodeID
  72. /// @param {Boolean} full
  73. /// @param {Boolean} normalize
  74. ///
  75. /// @returns {Object}
  76. this.getNode = [ /* nodeID, full, normalize */ ]
  77. // TODO: hashNode
  78. /// @function
  79. ///
  80. /// @param {ID} nodeID
  81. /// @param {String} childName
  82. /// @param {String|Object} childComponent
  83. /// @param {String} [childURI]
  84. /// @param {module:vwf/api/kernel~nodeCallback} [callback]
  85. ///
  86. /// @returns {}
  87. this.createChild = [ /* nodeID, childName, childComponent, childURI, callback( childID ) */ ]
  88. /// @function
  89. ///
  90. /// @param {ID} nodeID
  91. /// @param {String} childName
  92. ///
  93. /// @returns {}
  94. this.deleteChild = [ /* nodeID, childName */ ]
  95. /// addChild calls addingChild() on each model. The child is considered added after each model has
  96. /// run. Additionally, it calls addedChild() on each view. The view is being notified that a
  97. /// child has been added.
  98. ///
  99. /// @function
  100. ///
  101. /// @param {ID} nodeID
  102. /// @param {ID} childID
  103. /// @param {String} childName
  104. ///
  105. /// @returns {}
  106. this.addChild = [ /* nodeID, childID, childName */ ]
  107. /// removeChild calls removingChild() on each model. The child is considered removed after each model
  108. /// has run. Additionally, it calls removedChild() on each view. The view is being notified that a
  109. /// child has been removed.
  110. ///
  111. /// @function
  112. ///
  113. /// @param {ID} nodeID
  114. /// @param {ID} childID
  115. ///
  116. /// @returns {}
  117. this.removeChild = [ /* nodeID, childID */ ]
  118. /// setProperties sets all of the properties for a node. It will call settingProperties()
  119. /// on each model and satProperties() on each view.
  120. ///
  121. /// @function
  122. ///
  123. /// @param {ID} nodeID
  124. /// @param {Object} properties
  125. ///
  126. /// @returns {Object}
  127. this.setProperties = [ /* nodeID, properties */ ]
  128. /// getProperties will get all of the properties for a node. It will call
  129. /// gettingProperties() on each model and gotProperties() on each view.
  130. ///
  131. /// @function
  132. ///
  133. /// @param {ID} nodeID
  134. ///
  135. /// @returns {Object}
  136. this.getProperties = [ /* nodeID */ ]
  137. /// createProperty will create a property on a node and assign an initial value.
  138. /// It will call creatingProperty() on each model. The property is considered created after each
  139. /// model has run. Additionally, it wil call createdProperty() on each view. The view is being
  140. /// notified that a property has been created.
  141. ///
  142. /// @function
  143. ///
  144. /// @param {ID} nodeID
  145. /// @param {String} propertyName
  146. /// @param propertyValue
  147. /// @param {String} propertyGet
  148. /// @param {String} propertySet
  149. ///
  150. /// @returns {} propertyValue
  151. this.createProperty = [ /* nodeID, propertyName, propertyValue, propertyGet, propertySet */ ]
  152. // TODO: deleteProperty
  153. /// setProperty sets a specific property value on a node. It will call settingProperty()
  154. /// on each model. The first model to return a non-undefined value has performed the
  155. /// set and dictates the return value. The property is considered set after each model has run.
  156. /// It will also call satProperty() on each view. The view is being notified that a property has
  157. /// been set.
  158. ///
  159. /// @function
  160. ///
  161. /// @param {ID} nodeID
  162. /// @param {String} propertyName
  163. /// @param {Value} propertyValue
  164. ///
  165. /// @returns {Value} propertyValue
  166. this.setProperty = [ /* nodeID, propertyName, propertyValue */ ]
  167. /// getProperty will retrive a property value for a node. It will call gettingProperty()
  168. /// on each model. The first model to return a non-undefined value dictates the return value.
  169. /// It will also call gotProperty() on each view.
  170. ///
  171. /// @function
  172. ///
  173. /// @param {ID} nodeID
  174. /// @param {String} propertyName
  175. ///
  176. /// @returns {Value} propertyValue
  177. this.getProperty = [ /* nodeID, propertyName */ ]
  178. /// Create a method on a node. Methods are incoming function calls made to a node.
  179. ///
  180. /// @function
  181. ///
  182. /// @param {ID} nodeID
  183. /// The ID of a node containing a method `methodName`.
  184. /// @param {String} methodName
  185. /// The name of a method on the `nodeID` node.
  186. /// @param {String[]} methodParameters
  187. /// An array of names of the method's positional parameters. The method body uses these
  188. /// names to refer to the caller's arguments.
  189. /// @param {String} methodBody
  190. /// The body of a script to be used as the handler for the method. Strings will be
  191. /// interpreted as JavaScript; other script types may be supported in future releases.
  192. ///
  193. /// @returns {Handler} methodHandler
  194. this.createMethod = [ /* nodeID, methodName, methodParameters, methodBody */ ]
  195. // TODO: deleteMethod
  196. /// Set the handler for a method on a node.
  197. ///
  198. /// @function
  199. ///
  200. /// @param {ID} nodeID
  201. /// The ID of a node containing a method `methodName`.
  202. /// @param {String} methodName
  203. /// The name of a method on the `nodeID` node.
  204. /// @param {Handler} methodHandler
  205. /// A script to set as the handler for the method.
  206. ///
  207. /// @returns {Handler} methodHandler
  208. this.setMethod = [ /* nodeID, methodName, methodHandler */ ]
  209. /// Get the handler for a method on a node.
  210. ///
  211. /// @function
  212. ///
  213. /// @param {ID} nodeID
  214. /// The ID of a node containing a method `methodName`.
  215. /// @param {String} methodName
  216. /// The name of a method on the `nodeID` node.
  217. ///
  218. /// @returns {Handler} methodHandler
  219. this.getMethod = [ /* nodeID, methodName */ ]
  220. /// Invoke a method on a node.
  221. ///
  222. /// @function
  223. ///
  224. /// @param {ID} nodeID
  225. /// The ID of a node containing a method `methodName`.
  226. /// @param {String} methodName
  227. /// The name of a method on the `nodeID` node.
  228. /// @param {Value[]} methodParameters
  229. /// An array of values to pass as arguments to the method call.
  230. ///
  231. /// @returns {Value} returnValue
  232. this.callMethod = [ /* nodeID, methodName, methodParameters */ ]
  233. /// Create an event on a node.
  234. ///
  235. /// Events are outgoing function calls that a node makes to announce changes to the node, or
  236. /// to announce changes within a set of nodes that the node manages. Other nodes may attach
  237. /// listener functions to the event which will be called when the event fires.
  238. ///
  239. /// @function
  240. ///
  241. /// @param {ID} nodeID
  242. /// The ID of a node containing an event `eventName`.
  243. /// @param {String} eventName
  244. /// The name of an event on the `nodeID` node.
  245. /// @param {String[]} eventParameters
  246. /// An array of names of the event's positional parameters. The names are primarily used
  247. /// to describe arguments that the event will pass to listeners when the event is fired.
  248. /// The event's parameter list will be used as the default list for listeners that don't
  249. /// declare their own parameters.
  250. ///
  251. /// @returns {}
  252. this.createEvent = [ /* nodeID, eventName, eventParameters */ ]
  253. // TODO: deleteEvent
  254. /// Set a node's event and its listeners.
  255. ///
  256. /// @function
  257. ///
  258. /// @param {ID} nodeID
  259. /// The ID of a node containing an event `eventName`.
  260. /// @param {String} eventName
  261. /// The name of an event on the `nodeID` node.
  262. /// @param {Event} eventDescriptor
  263. /// The new event, including its listeners.
  264. ///
  265. /// @returns {Event}
  266. this.setEvent = [ /* nodeID, eventName, eventDescriptor */ ]
  267. /// Get a node's event and its listeners.
  268. ///
  269. /// @function
  270. ///
  271. /// @param {ID} nodeID
  272. /// The ID of a node containing an event `eventName`.
  273. /// @param {String} eventName
  274. /// The name of an event on the `nodeID` node.
  275. ///
  276. /// @returns {Event}
  277. this.getEvent = [ /* nodeID, eventName */ ]
  278. /// Add a function to a node's event to be called when the event fires.
  279. ///
  280. /// By default, the handler will be invoked in the context of the sender. For JavaScript
  281. /// handlers, this means that `this` will refer to the node with ID `nodeID`. To invoke the
  282. /// handler on a different node, provide an `eventContextID` when adding the listener.
  283. ///
  284. /// For dispatched events (invoked with `kernel.dispatchEvent`), events are fired from a
  285. /// series of nodes until the event is handled. Starting at the application root, the event
  286. /// is fired on the target's ancestors, downward, in a "capture" phase, then fired on the
  287. /// target node, then again fired on the target's ancestors, upward, in a "bubbling" phase.
  288. ///
  289. /// For dispatched events, after firing the event at a particular node, if any of the
  290. /// handlers returned a truthy value, the event is considered _handled_ and the dispatch
  291. /// process stops at that node. An event that is handled during the capture phase prevents
  292. /// lower nodes or the target node from receiving the event. Events handled during the
  293. /// bubbling phase catch events not handled by the target node or by lower nodes.
  294. ///
  295. /// By default, a listener will only be invoked if it is attached to the event target, or
  296. /// during the bubbling phase, if it attached to a node above the target. To also invoke a
  297. /// listener during the capture phase, pass `eventPhases` as the array `[ "capture" ]`.
  298. ///
  299. /// @function
  300. ///
  301. /// @param {ID} nodeID
  302. /// The ID of a node containing an event `eventName`.
  303. /// @param {String} eventName
  304. /// The name of an event on the `nodeID` node. When the event is fired, all of its
  305. /// listeners will be called.
  306. /// @param {Handler} eventHandler
  307. /// A script to be added as a handler for the event. The `eventParameters` that were
  308. /// provided to the `createEvent` call will be available to the handler body as function
  309. /// parameters if the handler doesn't declare its own parameters.
  310. /// @param {ID} [eventContextID]
  311. /// The ID of the node that the handler is _invoked on_. For JavaScript handlers, `this`
  312. /// will refer to the `eventContextID` node. If `eventContextID` is not provided, the
  313. /// handler will be invoked in the context of the global root pseudo-node.
  314. /// @param {String[]} [eventPhases]
  315. /// An array of strings indicating the event dispatch phases that this handler should
  316. /// respond to. Handlers will be invoked at the target and during the bubbling phase
  317. /// regardless of its `eventPhases`. To also invoke a handler during the capture phase,
  318. /// include `"capture"` in the `eventPhases` array.` `eventPhases` only applies to the
  319. /// propagation performed by `kernel.dispatchEvent`. Once `kernel.fireEvent` is called, it
  320. /// always invokes all of the event's handlers.
  321. ///
  322. /// @returns {ListenerID}
  323. this.addEventListener = [ /* nodeID, eventName, eventHandler, eventContextID, eventPhases */ ]
  324. /// Remove a listener function from a node's event. The handler will no longer be called
  325. /// when the event fires.
  326. ///
  327. /// @function
  328. ///
  329. /// @param {ID} nodeID
  330. /// The ID of a node containing an event `eventName`.
  331. /// @param {String} eventName
  332. /// The name of an event on the `nodeID` node.
  333. /// @param {ListenerID} eventListenerID
  334. /// A listener ID previously returned by `kernel.addEventListener` that identifies a
  335. /// listener attached to this `nodeID` and `eventName`.
  336. ///
  337. /// @returns {ListenerID}
  338. /// `eventListenerID` if the listener was removed successfully. Otherwise, a falsy value.
  339. this.removeEventListener = [ /* nodeID, eventName, eventListenerID */ ]
  340. /// Set the handler for a listener on a node's event.
  341. ///
  342. /// @function
  343. ///
  344. /// @param {ID} nodeID
  345. /// The ID of a node containing an event `eventName`.
  346. /// @param {String} eventName
  347. /// The name of an event on the `nodeID` node.
  348. /// @param {ListenerID} eventListenerID
  349. /// A listener ID previously returned by `kernel.addEventListener` that identifies a
  350. /// listener attached to this `nodeID` and `eventName`.
  351. /// @param {Listener} eventListener
  352. /// A script to set as the handler for the listener. The `eventParameters` that were
  353. /// provided to the `createEvent` call will be available to the handler body as function
  354. /// parameters if the handler doesn't declare its own parameters.
  355. ///
  356. /// @returns {Listener}
  357. this.setEventListener = [ /* nodeID, eventName, eventListenerID, eventListener */ ]
  358. /// Get the handler for a listener on a node's event.
  359. ///
  360. /// @function
  361. ///
  362. /// @param {ID} nodeID
  363. /// The ID of a node containing an event `eventName`.
  364. /// @param {String} eventName
  365. /// The name of an event on the `nodeID` node.
  366. /// @param {ListenerID} eventListenerID
  367. /// A listener ID previously returned by `kernel.addEventListener` that identifies a
  368. /// listener attached to this `nodeID` and `eventName`.
  369. ///
  370. /// @returns {Listener}
  371. this.getEventListener = [ /* nodeID, eventName, eventListenerID */ ]
  372. /// Remove all listener functions from a node's event that are associated with a particular
  373. /// context.
  374. ///
  375. /// @function
  376. ///
  377. /// @param {ID} nodeID
  378. /// The ID of a node containing an event `eventName`.
  379. /// @param {String} eventName
  380. /// The name of an event on the `nodeID` node.
  381. /// @param {ID} eventContextID
  382. /// The ID of a context node that handlers may be associated with. Handler context
  383. /// associations are made when `kernel.addEventListener` adds a handler to an event.
  384. ///
  385. /// @returns {}
  386. this.flushEventListeners = [ /* nodeID, eventName, eventContextID */ ]
  387. /// It will call firingEvent() on each model and firedEvent() on each view.
  388. ///
  389. /// @function
  390. ///
  391. /// @param {ID} nodeID
  392. /// The ID of a node containing an event `eventName`.
  393. /// @param {String} eventName
  394. /// The name of an event on the `nodeID` node.
  395. /// @param {Value[]} eventParameters
  396. /// An array of values to pass as arguments to calls into the event's listeners.
  397. ///
  398. /// @returns {}
  399. this.fireEvent = [ /* nodeID, eventName, eventParameters */ ]
  400. /// Dispatch an event toward a node. Using fireEvent(), capture (down) and bubble (up) along
  401. /// the path from the global root to the node. Cancel when one of the handlers returns a
  402. /// truthy value to indicate that it has handled the event.
  403. ///
  404. /// @function
  405. ///
  406. /// @param {ID} nodeID
  407. /// The ID of a node containing an event `eventName`.
  408. /// @param {String} eventName
  409. /// The name of an event on the `nodeID` node.
  410. /// @param {Value[]} eventParameters
  411. /// An array of values to pass as arguments to calls into the event's listeners. Values
  412. /// from `eventParameters` are sent with the `kernel.fireEvent` call to each node.
  413. /// @param {Object} eventNodeParameters
  414. /// A collection of `ID`-indexed arrays of values to pass as additional arguments for
  415. /// `kernel.fireEvent` calls to specific nodes.
  416. ///
  417. /// @returns {}
  418. this.dispatchEvent = [ /* nodeID, eventName, eventParameters, eventNodeParameters */ ]
  419. /// It will call executing() on each model. The script is considered executed after each model
  420. /// has run and all asynchronous calls made inside them have returned.
  421. /// It will then call executed() on each view to notify it that a script has been executed.
  422. /// It will then call the caller-provided callback to notify the caller that the
  423. /// script has been fully executed and all asynchronous actions have completed.
  424. ///
  425. /// @function
  426. ///
  427. /// @param {ID} nodeID
  428. /// @param {String} scriptText
  429. /// @param {String} scriptType
  430. /// @param {module:vwf/api/kernel~valueCallback} [callback]
  431. ///
  432. /// @returns {Value} returnValue
  433. this.execute =[ /* nodeID, scriptText, scriptType, callback( returnValue ) */ ]
  434. /// @function
  435. ///
  436. /// @param {ID} nodeID
  437. ///
  438. /// @returns {Number}
  439. this.random = [ /* nodeID */ ]
  440. /// @function
  441. ///
  442. /// @param {ID} nodeID
  443. /// @param {String} seed
  444. this.seed = [ /* nodeID, seed */ ]
  445. /// It will return the current simulation time.
  446. ///
  447. /// @function
  448. ///
  449. /// @returns {Number}
  450. this.time = []
  451. /// It will return the moniker of the client responsible for the current action. Will be
  452. /// falsy for actions originating in the server, such as time ticks.
  453. ///
  454. /// @function
  455. ///
  456. /// @returns {String}
  457. this.client = []
  458. /// It will return the identifer the server assigned to this client.
  459. ///
  460. /// @function
  461. ///
  462. /// @returns {String}
  463. this.moniker = []
  464. /// Return the application root node. `kernel.application( initializedOnly )` is equivalent
  465. /// to `kernel.global( "application", initializedOnly )`.
  466. ///
  467. /// @function
  468. ///
  469. /// @param {Boolean} [initializedOnly]
  470. /// If set, only return the application node if the application has completed
  471. /// initialization. Drivers that manage application code should set `initializedOnly`
  472. /// since applications should never have access to uninitialized parts of the application
  473. /// graph.
  474. ///
  475. /// @returns {ID}
  476. /// The ID of the application root. `application` may return `undefined` if the entire
  477. /// application has been deleted.
  478. this.application = [ /* initializedOnly */ ]
  479. /// Return the node's intrinsic state. This consists of:
  480. ///
  481. /// source -- the URI of the node's data blob
  482. /// type -- the MIME type of the node's data blob
  483. ///
  484. /// The values are returned in an Object with the named properties. If the optional result
  485. /// parameter is provided, the fields are added there (without disturbing any other fields) and
  486. /// result is returned. Otherwise, a new object is created, filled, and returned.
  487. ///
  488. /// @function
  489. ///
  490. /// @param {ID} nodeID
  491. /// ID of the node to query.
  492. /// @param {Object} [result]
  493. /// An optional Object to receive the result.
  494. ///
  495. /// @returns {Object}
  496. this.intrinsics = [ /* nodeID, result */ ]
  497. /// Return the node's URI. This value will be the component URI for the root node of a component
  498. /// loaded from a URI, and undefined in all other cases.
  499. ///
  500. /// @function
  501. ///
  502. /// @param {ID} nodeID
  503. /// @param {Boolean} [searchAncestors]
  504. /// If set and the node doesn't have a URI, search the node's ancestors. Return the URI of
  505. /// the closest ancestor with a URI.
  506. /// @param {Boolean} [initializedOnly]
  507. /// If set, only search ancestors through those that have completed initialization.
  508. ///
  509. /// @returns {String}
  510. this.uri = [ /* nodeID, searchAncestors, initializedOnly */ ]
  511. /// Name calls naming() on each model. The first model to return a non-undefined value dictates
  512. /// the return value.
  513. ///
  514. /// @function
  515. ///
  516. /// @param {ID} nodeID
  517. ///
  518. /// @returns {String}
  519. this.name = [ /* nodeID */ ]
  520. /// Return a node's prototype.
  521. ///
  522. /// @function
  523. ///
  524. /// @param {ID} nodeID
  525. ///
  526. /// @returns {ID}
  527. /// The ID of the node's prototype, or `undefined` if called on the proto-prototype,
  528. /// `node.vwf`.
  529. this.prototype = [ /* nodeID */ ]
  530. /// Return a node's prototype, its prototype, etc. up to and including `node.vwf`.
  531. ///
  532. /// @function
  533. ///
  534. /// @param {ID} nodeID
  535. /// @param {Boolean} [includeBehaviors]
  536. /// If set, also include the node's and prototypes' behaviors.
  537. ///
  538. /// @returns {ID[]}
  539. /// An array of IDs of the node's prototypes.
  540. this.prototypes = [ /* nodeID, includeBehaviors */ ]
  541. /// Return a node's behaviors.
  542. ///
  543. /// @function
  544. ///
  545. /// @param {ID} nodeID
  546. ///
  547. /// @returns {ID[]}
  548. /// An array of IDs of the node's behaviors. An empty array is returned if the node
  549. /// doesn't have any behaviors.
  550. this.behaviors = [ /* nodeID */ ]
  551. /// Return the set of global root nodes. Each global node is the root of a tree.
  552. ///
  553. /// @function
  554. ///
  555. /// @param {Boolean} [initializedOnly]
  556. /// If set, only return root nodes that have completed initialization. Drivers that manage
  557. /// application code should set `initializedOnly` and should also only provide the
  558. /// `kernel.globals` result (even with `initializedOnly` set) to the application if the
  559. /// application itself has completed initialization. Applications should never have access
  560. /// to uninitialized parts of the simulation.
  561. ///
  562. /// @returns {Object}
  563. /// An object whose keys are the IDs of the global root nodes. `Object.keys` may be used
  564. /// on the result to get an array of IDs. The global trees are not ordered, and the order
  565. /// of the IDs is not significant.
  566. this.globals = [ /* initializedOnly */ ]
  567. /// Return a global root node selected by its URI or annotation.
  568. ///
  569. /// @function
  570. ///
  571. /// @param {String} globalReference
  572. /// A selector that identifies the root to return. `globalReference` may specify either a
  573. /// URI or annotation. The root nodes are searched first by URI, then by annotation if no
  574. /// match is found.
  575. /// @param {Boolean} [initializedOnly]
  576. /// If set, only return a root node if it has completed initialization. Drivers that
  577. /// manage application code should set `initializedOnly` and should also only provide the
  578. /// result of `kernel.global` (even with `initializedOnly` set) to the application if the
  579. /// application itself has completed initialization. Applications should never have access
  580. /// to uninitialized parts of the simulation.
  581. ///
  582. /// @returns {ID}
  583. /// The ID of the root node of the selected tree, or `undefined` if `globalReference`
  584. /// doesn't match any root or if `initializedOnly` is set and the selected tree has not
  585. /// completed initialization.
  586. this.global = [ /* globalReference, initializedOnly */ ]
  587. /// Return the node at the root of the tree containing a node.
  588. ///
  589. /// @function
  590. ///
  591. /// @param {ID} nodeID
  592. /// @param {Boolean} [initializedOnly]
  593. /// If set, only return the root node if the node and its ancestors have completed
  594. /// initialization. Drivers that manage application code should set `initializedOnly`
  595. /// since applications should never have access to uninitialized parts of the application
  596. /// graph.
  597. ///
  598. /// @returns {ID}
  599. /// The ID of the node at the root of the tree containing the node, or `undefined` if
  600. /// `initializedOnly` is set and the node or one of its ancestors has not completed
  601. /// initialization.
  602. this.root = [ /* nodeID, initializedOnly */ ]
  603. /// Return a node's parent, grandparent, its parent, etc.
  604. ///
  605. /// @function
  606. ///
  607. /// @param {ID} nodeID
  608. /// @param {Boolean} [initializedOnly]
  609. /// If set, only include parents of nodes that have completed initialization. If a portion
  610. /// of the tree containing the node is still initializing, the node's parent, grandparent,
  611. /// etc. will be included if the preceding node is initialized, but the remaining
  612. /// ancestors will be omitted. Drivers that manage application code should set
  613. /// `initializedOnly` since applications should never have access to uninitialized parts
  614. /// of the application graph.
  615. ///
  616. /// @returns {ID[]}
  617. /// An array of IDs of the node's ancestors. An empty array is returned for global,
  618. /// top-level nodes that don't have a parent.
  619. this.ancestors = [ /* nodeID, initializedOnly */ ]
  620. /// Return a node's parent.
  621. ///
  622. /// @function
  623. ///
  624. /// @param {ID} nodeID
  625. /// @param {Boolean} [initializedOnly]
  626. /// If set, only return the parent if the node has completed initialization. Drivers that
  627. /// manage application code should set `initializedOnly` since applications should never
  628. /// have access to uninitialized parts of the application graph.
  629. ///
  630. /// @returns {ID}
  631. /// The ID of the node's parent, or `undefined` for the application root node or other
  632. /// global, top-level nodes.
  633. this.parent = [ /* nodeID, initializedOnly */ ]
  634. /// Return a node's children.
  635. ///
  636. /// @function
  637. ///
  638. /// @param {ID} nodeID
  639. /// @param {Boolean} [initializedOnly]
  640. /// If set, only return children that have completed initialization. Uninitialized
  641. /// children will appear in the result as `undefined`. Drivers that manage application
  642. /// code should set `initializedOnly` since applications should never have access to
  643. /// uninitialized parts of the application graph.
  644. ///
  645. /// @returns {ID[]}
  646. /// An array of IDs of the node's children. An empty array is returned if the node
  647. /// doesn't have any children. The result always contains one element for each child,
  648. /// regardless of their initialization state and whether `initializedOnly` is set.
  649. /// However, `initializedOnly` will cause uninitialized children to appear as `undefined`.
  650. this.children = [ /* nodeID, initializedOnly */ ]
  651. /// Return a node's child selected by index or name.
  652. ///
  653. /// @function
  654. ///
  655. /// @param {ID} nodeID
  656. /// @param {String} childReference
  657. /// A selector indicating the child to return. If `childReference` is a number, the child
  658. /// at that index location is returned. Otherwise, a child with the name matching
  659. /// `childReference` (if any) is returned.
  660. /// @param {Boolean} [initializedOnly]
  661. /// If set, only return a child if it has completed initialization. Drivers that manage
  662. /// application code should set `initializedOnly` since applications should never have
  663. /// access to uninitialized parts of the application graph.
  664. ///
  665. /// @returns {ID}
  666. /// The ID of the selected child, or `undefined` if `childReference` doesn't match a child
  667. /// or if `initializedOnly` is set and the selected child has not completed
  668. /// initialization.
  669. this.child = [ /* nodeID, childReference, initializedOnly */ ]
  670. /// Return a node's children, grandchildren, their children, etc.
  671. ///
  672. /// @function
  673. ///
  674. /// @param {ID} nodeID
  675. /// @param {Boolean} [initializedOnly]
  676. /// If set, only return descendants that have completed initialization. Uninitialized
  677. /// descendants will appear in the result as `undefined`. Descendants of uninitialized
  678. /// descendants will not appear. Drivers that manage application code should set
  679. /// `initializedOnly` since applications should never have access to uninitialized parts
  680. /// of the application graph.
  681. ///
  682. /// @returns {ID[]}
  683. /// An array of IDs of the node's descendants. An empty array is returned if the node
  684. /// doesn't have any descendants. The result may contain `undefined` elements when
  685. /// `initializedOnly` is set and some descendants have not completed initialization.
  686. this.descendants = [ /* nodeID, initializedOnly */ ]
  687. /// Locate nodes matching a search pattern. matchPattern supports an XPath subset consisting of
  688. /// the following:
  689. ///
  690. /// "/" -- the application root node
  691. /// "/*" -- children of the application
  692. /// "/name" -- a child of the application having the specified name
  693. /// "/name1/name2/name3/..." -- a descendant of the application along the specified path
  694. /// "//name" -- descendants of the application having the specified name
  695. /// "//*" -- all descendants of the application
  696. /// "//element(*,uri)" -- descendants of the application having uri in their prototype chain
  697. ///
  698. /// ".." -- the reference node's parent
  699. /// "." -- the reference node
  700. /// "*", "./*" -- children of the reference node
  701. /// "name", "./name" -- a child of the reference node having the specified name
  702. /// "name1/name2/name3/..." -- a descendant of the reference node along the specified path
  703. /// ".//name" -- descendants of the reference node having the specified name
  704. /// ".//*" -- all descendants of the reference node
  705. /// ".//element(name)" -- same as ".//name"
  706. /// ".//element(*)" -- same as ".//*"
  707. /// ".//element(name,uri)" -- descendants having the specified name and extending uri
  708. /// ".//element(*,uri)" -- descendants extending uri
  709. ///
  710. /// "name[name2]" -- a child "name" which also has a child having the second name
  711. /// "name[name2/name3/...]" -- a child "name" which also has a descendant along the path
  712. /// "*[*]" -- children which also have at least one child
  713. /// "name[@property]" -- a child "name" which also has a truthy property with the provided name
  714. /// "*[@*]" -- children which also have at least one truthy property
  715. ///
  716. /// XPath elements are interpreted as VWF nodes and XPath attributes are interpreted as VWF
  717. /// properties. The expression must evaluate to an element (node) set since only nodes are
  718. /// distinctly addressable entities in VWF. Properties may be used in predicates.
  719. ///
  720. /// The following XPath axes are supported:
  721. /// ancestor-or-self, ancestor, parent, self, child, descendant, descendant-or-self, and
  722. /// attribute (predicates only)
  723. /// along with the following node tests:
  724. /// element(name,type), attribute(name) (in predicates only), and node()
  725. /// the shortcut notation:
  726. /// "//": descendant-or-self:node(), ".": self::node(), "..": "parent::node()",
  727. /// "name": "child::name", "@name": "attribute::name"
  728. /// and the wildcard name:
  729. /// "*"
  730. ///
  731. /// This is a naive implementation with several limitations. There is no particular
  732. /// optimization, and some queries can yield large intermediate or final results. Use caution
  733. /// when applying the descendant operators. The results will not necessarily maintain document
  734. /// order. Overlapping queries will cause nodes to be repeated in the results. For example, the
  735. /// query `*``/..` will return the reference node several times, once for each of its children.
  736. ///
  737. /// Names in XPath expressions may only contain the characters A-Z, a-z, 0-9, -, and .
  738. /// (period). As an extension, this implementation allows names to contain any character so
  739. /// long as it is quoted using either double or single quotes. Within a quoted name, use the
  740. /// charater "\" to escape the quoting character or the escape character. When assembling an
  741. /// expression, use vwf.utility.xpath.quoteName() to quote names that may have invalid
  742. /// characters.
  743. ///
  744. /// @function
  745. ///
  746. /// @param {ID} nodeID
  747. /// The reference node. Relative patterns are resolved with respect to this node. `nodeID`
  748. /// is ignored for absolute patterns.
  749. /// @param {String} matchPattern
  750. /// The search pattern.
  751. /// @param {Boolean} [initializedOnly]
  752. /// Interpret nodes that haven't completed initialization as though they don't have
  753. /// ancestors. Drivers that manage application code should set `initializedOnly` since
  754. /// applications should never have access to uninitialized parts of the application graph.
  755. /// @param {module:vwf/api/kernel~nodeCallback} [callback]
  756. /// A callback to receive the search results. If callback is provided, find invokes
  757. /// callback( matchID ) for each match. Otherwise the result is returned as an array.
  758. ///
  759. /// @returns {ID[]|undefined}
  760. /// If callback is provided, undefined; otherwise an array of the node ids of the result.
  761. this.find = [ /* nodeID, matchPattern, initializedOnly, callback( matchID ) */ ]
  762. /// Test a node against a search pattern. See vwf.api.kernel#find for details of the query
  763. /// syntax.
  764. ///
  765. /// @function
  766. ///
  767. /// @param {ID} nodeID
  768. /// The reference node. Relative patterns are resolved with respect to this node. `nodeID`
  769. /// is ignored for absolute patterns.
  770. /// @param {String} matchPattern
  771. /// The search pattern.
  772. /// @param {ID} testID
  773. /// A node to test against the pattern.
  774. /// @param {Boolean} [initializedOnly]
  775. /// Interpret nodes that haven't completed initialization as though they don't have
  776. /// ancestors. Drivers that manage application code should set `initializedOnly` since
  777. /// applications should never have access to uninitialized parts of the application graph.
  778. ///
  779. /// @returns {Boolean}
  780. /// true when testID matches the pattern.
  781. this.test = [ /* nodeID, matchPattern, testID, initializedOnly */ ]
  782. /// Return client object matching the given search pattern.
  783. ///
  784. /// @function
  785. ///
  786. /// @param {ID} nodeID
  787. /// The reference node. Relative patterns are resolved with respect to this node. `nodeID`
  788. /// is ignored for absolute patterns.
  789. /// @param {String} matchPattern
  790. /// The search pattern.
  791. /// @param {module:vwf/api/kernel~nodeCallback} [callback]
  792. /// A callback to receive the search results. If callback is provided, find invokes
  793. /// callback( matchID ) for each match. Otherwise the result is returned as an array.
  794. ///
  795. /// @returns {ID[]|undefined}
  796. /// If callback is provided, undefined; otherwise an array of the node ids of the result.
  797. ///
  798. /// @deprecated in version 0.6.21. Instead of `kernel.findClients( reference, "/pattern" )`,
  799. /// use `kernel.find( reference, "doc('http://vwf.example.com/clients.vwf')/pattern" )`.
  800. this.findClients = [ /* nodeID, matchPattern, callback( matchID ) */ ]
  801. /// Description.
  802. ///
  803. /// @callback module:vwf/api/kernel~nodeCallback
  804. ///
  805. /// @param {ID} nodeID
  806. /// Description.
  807. ///
  808. /// @callback module:vwf/api/kernel~valueCallback
  809. ///
  810. /// @param {Value} returnValue
  811. /// A `Handler` describes a function that may be attached to a property as a setter or
  812. /// getter, to a method, or to an event as a listener.
  813. ///
  814. /// A `Handler` is an object containing the following properties. Alternately, a `Handler`
  815. /// may be provided as a `string` or `function` representing just the `body` field.
  816. ///
  817. /// @typedef {Object|string|function} Handler
  818. ///
  819. /// @property {string[]} [name]
  820. /// The function's name. VWF doesn't make use of the name, but the field is included so
  821. /// that named JavaScript functions can make a round-trip translation through a `Handler`
  822. /// intact.
  823. /// @property {string[]} [parameters]
  824. /// An array of names of the function's positional parameters. The function body uses
  825. /// these names to refer to the caller's arguments. `parameters` may be omitted if the
  826. /// function doesn't declare any parameters, or if `body` is a JavaScript `function`, in
  827. /// which case the parameters are taken from the JavaScript function itself.
  828. /// @property {string|function} body
  829. /// A representation of the statements making up the function body. For handlers of `type`
  830. /// `application/javascript`, `body` should be a string containing JavaScript text that is
  831. /// correct for the span between the opening and closing braces of a JavaScript function
  832. /// definition: `function(...) {` |<= this is the body text =>| `}`. `body` may also be
  833. /// provided as a JavaScript `function` value, in which case the handler's `body` and
  834. /// `arguments` will be taken from the function.
  835. /// @property {string} [type]
  836. /// The {@link https://www.iana.org/assignments/media-types Media Type} of the `body`
  837. /// text. When `body` is a `string`, the default type is `"application/javascript"`, and
  838. /// `type` may be omitted. `type` should be omitted if `body` is a JavaScript `function`
  839. /// value since the type is implicit in that case.
  840. /// A `ListenerID` is a JavaScript primitive value that identifies an event listener. Each
  841. /// listener is assigned a `ListenerID` when it is created that is unique within the node
  842. /// and event.
  843. ///
  844. /// @typedef {string|number|boolean|null} ListenerID
  845. /// A `Listener` is an extended `Handler` with additional fields for event listeners.
  846. ///
  847. /// Like a `Handler`, a `Listener` may be provided as a `string` or `function` representing
  848. /// just the `body` field.
  849. ///
  850. /// @typedef {Object|string|function} Listener
  851. ///
  852. /// @property {ListenerID} [id]
  853. /// A unique ID as returned by `kernel.addEventListener` that identifies the listener for
  854. /// a particular `nodeID` and `eventName`.
  855. /// @property {string[]} [name]
  856. /// @see {@link module:vwf/api/kernel.Handler}
  857. /// @property {string[]} [parameters]
  858. /// @see {@link module:vwf/api/kernel.Handler}
  859. /// @property {string|function} body
  860. /// @see {@link module:vwf/api/kernel.Handler}
  861. /// @property {string} [type]
  862. /// @see {@link module:vwf/api/kernel.Handler}
  863. /// @property {ID} [context]
  864. /// The ID of a node that the handler will be _invoked on_. For JavaScript handlers,
  865. /// `this` will refer to the `context` node. If `context` is not provided, the context
  866. /// will be the global root pseudo-node.
  867. /// @property {String[]} [phases]
  868. /// An array of strings indicating the event dispatch phases that this handler should
  869. /// respond to. Listeners will be invoked at the target and during the bubbling phase
  870. /// regardless of its `phases`. To also invoke a handler during the capture phase, include
  871. /// `"capture"` in the `phases` array.` `phases` only applies to the propagation performed
  872. /// by `kernel.dispatchEvent`. Once `kernel.fireEvent` is called, it always invokes all of
  873. /// the event's handlers.
  874. /// An `Event` describes an event and its listeners.
  875. ///
  876. /// @typedef {Object} Event
  877. ///
  878. /// @property {string[]} [parameters]
  879. /// An array of names of the event's positional parameters. The names are primarily used
  880. /// to describe arguments that the event will pass to listeners when the event is fired.
  881. /// The event's parameter list will be used as the default list for listeners that don't
  882. /// declare their own parameters. `parameters` may be omitted if the event doesn't declare
  883. /// any parameters.
  884. /// @property {Listener[]} [listeners]
  885. /// An array of listeners to be invoked when the event is fired. Listeners will be invoked
  886. /// in the order provided.
  887. }
  888. }
  889. export {
  890. Kernel
  891. }