ContextNode.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import Node from './Node.js';
  2. import { addMethodChaining, nodeProxy } from '../tsl/TSLCore.js';
  3. /**
  4. * This node can be used as a context management component for another node.
  5. * {@link NodeBuilder} performs its node building process in a specific context and
  6. * this node allows the modify the context. A typical use case is to overwrite `getUV()` e.g.:
  7. *
  8. * ```js
  9. *node.context( { getUV: () => customCoord } );
  10. *```
  11. * @augments Node
  12. */
  13. class ContextNode extends Node {
  14. static get type() {
  15. return 'ContextNode';
  16. }
  17. /**
  18. * Constructs a new context node.
  19. *
  20. * @param {Node} node - The node whose context should be modified.
  21. * @param {Object} [value={}] - The modified context data.
  22. */
  23. constructor( node, value = {} ) {
  24. super();
  25. /**
  26. * This flag can be used for type testing.
  27. *
  28. * @type {Boolean}
  29. * @readonly
  30. * @default true
  31. */
  32. this.isContextNode = true;
  33. /**
  34. * The node whose context should be modified.
  35. *
  36. * @type {Node}
  37. */
  38. this.node = node;
  39. /**
  40. * The modified context data.
  41. *
  42. * @type {Object}
  43. * @default {}
  44. */
  45. this.value = value;
  46. }
  47. /**
  48. * This method is overwritten to ensure it returns the reference to {@link ContextNode#node}.
  49. *
  50. * @return {Node} A reference to {@link ContextNode#node}.
  51. */
  52. getScope() {
  53. return this.node.getScope();
  54. }
  55. /**
  56. * This method is overwritten to ensure it returns the type to {@link ContextNode#node}.
  57. *
  58. * @param {NodeBuilder} builder - The current node builder.
  59. * @return {String} The type of {@link ContextNode#node}.
  60. */
  61. getNodeType( builder ) {
  62. return this.node.getNodeType( builder );
  63. }
  64. analyze( builder ) {
  65. this.node.build( builder );
  66. }
  67. setup( builder ) {
  68. const previousContext = builder.getContext();
  69. builder.setContext( { ...builder.context, ...this.value } );
  70. const node = this.node.build( builder );
  71. builder.setContext( previousContext );
  72. return node;
  73. }
  74. generate( builder, output ) {
  75. const previousContext = builder.getContext();
  76. builder.setContext( { ...builder.context, ...this.value } );
  77. const snippet = this.node.build( builder, output );
  78. builder.setContext( previousContext );
  79. return snippet;
  80. }
  81. }
  82. export default ContextNode;
  83. export const context = /*@__PURE__*/ nodeProxy( ContextNode );
  84. export const label = ( node, name ) => context( node, { label: name } );
  85. addMethodChaining( 'context', context );
  86. addMethodChaining( 'label', label );
粤ICP备19079148号