angular-three 3.3.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { untracked, computed, signal, ElementRef, input, inject, ViewContainerRef, TemplateRef, effect, DestroyRef, Directive, InjectionToken, DebugNode, RendererFactory2, Injectable, makeEnvironmentProviders, EnvironmentInjector, InjectFlags, runInInjectionContext, Component, NgZone, Injector, booleanAttribute, output, viewChild, afterNextRender, createEnvironmentInjector, ChangeDetectionStrategy, Pipe, CUSTOM_ELEMENTS_SCHEMA, contentChild, model, Renderer2 } from '@angular/core';
2
+ import { untracked, computed, signal, ElementRef, input, inject, ViewContainerRef, TemplateRef, effect, DestroyRef, Directive, InjectionToken, DebugNode, RendererFactory2, Injectable, makeEnvironmentProviders, EnvironmentInjector, InjectFlags, runInInjectionContext, createEnvironmentInjector, Component, NgZone, Injector, booleanAttribute, output, viewChild, afterNextRender, ChangeDetectionStrategy, Pipe, CUSTOM_ELEMENTS_SCHEMA, contentChild, model, Renderer2 } from '@angular/core';
3
3
  import { outputFromObservable } from '@angular/core/rxjs-interop';
4
4
  import { provideResizeOptions, NgxResize } from 'ngxtension/resize';
5
5
  import { MathUtils, WebGLRenderer, OrthographicCamera, PerspectiveCamera, Vector3, Vector2, Clock, Layers, Color, ColorManagement, Texture, RGBAFormat, UnsignedByteType, EventDispatcher, Raycaster, Scene, PCFSoftShadowMap, BasicShadowMap, PCFShadowMap, VSMShadowMap, NoToneMapping, ACESFilmicToneMapping, Vector4 } from 'three';
@@ -751,6 +751,7 @@ const ROUTED_SCENE = '__ngt_renderer_is_routed_scene__';
751
751
  const HTML = '__ngt_renderer_is_html';
752
752
  const NON_ROOT = '__ngt_renderer_is_non_root__';
753
753
  const SPECIAL_INTERNAL_ADD_COMMENT = '__ngt_renderer_add_comment__';
754
+ const SPECIAL_INTERNAL_SET_PARENT_COMMENT = '__ngt_renderer_set_parent_comment__';
754
755
  const DOM_PARENT = '__ngt_dom_parent__';
755
756
  const SPECIAL_DOM_TAG = {
756
757
  NGT_PORTAL: 'ngt-portal',
@@ -1132,6 +1133,74 @@ function injectStore(options) {
1132
1133
  return inject(NGT_STORE, options);
1133
1134
  }
1134
1135
 
1136
+ class NgtParent {
1137
+ constructor() {
1138
+ this.parent = input.required();
1139
+ this.vcr = inject(ViewContainerRef);
1140
+ this.template = inject(TemplateRef);
1141
+ this.store = injectStore();
1142
+ this.scene = this.store.select('scene');
1143
+ this.injected = false;
1144
+ this.injectedParent = null;
1145
+ this._parent = computed(() => {
1146
+ const parent = this.parent();
1147
+ const rawParent = typeof parent === 'function' ? parent() : parent;
1148
+ if (!rawParent)
1149
+ return null;
1150
+ const scene = this.scene();
1151
+ if (typeof rawParent === 'string') {
1152
+ return scene.getObjectByName(rawParent);
1153
+ }
1154
+ if ('nativeElement' in rawParent) {
1155
+ return rawParent.nativeElement;
1156
+ }
1157
+ return rawParent;
1158
+ });
1159
+ const commentNode = this.vcr.element.nativeElement;
1160
+ if (commentNode[SPECIAL_INTERNAL_ADD_COMMENT]) {
1161
+ commentNode[SPECIAL_INTERNAL_ADD_COMMENT]('parent');
1162
+ delete commentNode[SPECIAL_INTERNAL_ADD_COMMENT];
1163
+ }
1164
+ effect(() => {
1165
+ const parent = this._parent();
1166
+ if (!parent)
1167
+ return;
1168
+ this.injected = false;
1169
+ this.injectedParent = parent;
1170
+ this.createView();
1171
+ });
1172
+ inject(DestroyRef).onDestroy(() => {
1173
+ this.view?.destroy();
1174
+ });
1175
+ }
1176
+ get value() {
1177
+ if (this.validate()) {
1178
+ this.injected = true;
1179
+ return this.injectedParent;
1180
+ }
1181
+ return null;
1182
+ }
1183
+ validate() {
1184
+ return !this.injected && !!this.injectedParent;
1185
+ }
1186
+ createView() {
1187
+ if (this.view && !this.view.destroyed)
1188
+ this.view.destroy();
1189
+ const comment = this.vcr.element.nativeElement;
1190
+ if (comment[SPECIAL_INTERNAL_SET_PARENT_COMMENT]) {
1191
+ comment[SPECIAL_INTERNAL_SET_PARENT_COMMENT](this.injectedParent);
1192
+ }
1193
+ this.view = this.vcr.createEmbeddedView(this.template);
1194
+ this.view.detectChanges();
1195
+ }
1196
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: NgtParent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1197
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.5", type: NgtParent, isStandalone: true, selector: "ng-template[parent]", inputs: { parent: { classPropertyName: "parent", publicName: "parent", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
1198
+ }
1199
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: NgtParent, decorators: [{
1200
+ type: Directive,
1201
+ args: [{ selector: 'ng-template[parent]' }]
1202
+ }], ctorParameters: () => [] });
1203
+
1135
1204
  // This function prepares a set of changes to be applied to the instance
1136
1205
  function diffProps(instance, props) {
1137
1206
  const propsEntries = Object.entries(props);
@@ -1338,7 +1407,7 @@ function detach(parent, child, attachProp) {
1338
1407
  if (Array.isArray(attachProp))
1339
1408
  attach(parent, childLocalState.previousAttach, attachProp, childLocalState.isRaw);
1340
1409
  else
1341
- childLocalState.previousAttach();
1410
+ childLocalState.previousAttach?.();
1342
1411
  }
1343
1412
  }
1344
1413
  function assignEmpty(obj, base, shouldAssignStoreForApplyProps = false) {
@@ -1623,6 +1692,7 @@ class NgtRenderer {
1623
1692
  this.catalogue = catalogue;
1624
1693
  this.isRoot = isRoot;
1625
1694
  this.argsCommentNodes = [];
1695
+ this.parentCommentNodes = [];
1626
1696
  this.createText = this.delegate.createText.bind(this.delegate);
1627
1697
  this.destroy = this.delegate.destroy.bind(this.delegate);
1628
1698
  this.destroyNode = null;
@@ -1658,17 +1728,25 @@ class NgtRenderer {
1658
1728
  if (name === SPECIAL_DOM_TAG.NGT_VALUE) {
1659
1729
  return createNode('three', prepare({ __ngt_renderer__: { rawValue: undefined } }, { store: this.rootStore, isRaw: true }), this.document);
1660
1730
  }
1661
- const [injectedArgs] = [this.getNgtArgs()?.value || []];
1731
+ const [injectedArgs, injectedParent] = [
1732
+ this.getNgtDirective(NgtArgs, this.argsCommentNodes)?.value || [],
1733
+ this.getNgtDirective(NgtParent, this.parentCommentNodes)?.value,
1734
+ ];
1662
1735
  if (name === SPECIAL_DOM_TAG.NGT_PRIMITIVE) {
1663
1736
  if (!injectedArgs[0])
1664
1737
  throw new Error(`[NGT] ngt-primitive without args is invalid`);
1665
1738
  const object = injectedArgs[0];
1666
- const localState = getLocalState(object);
1739
+ let localState = getLocalState(object);
1667
1740
  if (!localState) {
1668
1741
  // NOTE: if an object isn't already "prepared", we prepare it
1669
1742
  prepare(object, { store: this.rootStore, primitive: true });
1743
+ localState = getLocalState(object);
1744
+ }
1745
+ const primitiveNode = createNode('three', object, this.document);
1746
+ if (injectedParent) {
1747
+ primitiveNode.__ngt_renderer__[1 /* NgtRendererClassId.parent */] = injectedParent;
1670
1748
  }
1671
- return createNode('three', object, this.document);
1749
+ return primitiveNode;
1672
1750
  }
1673
1751
  const threeName = kebabToPascal(name.startsWith('ngt-') ? name.slice(4) : name);
1674
1752
  const threeTarget = this.catalogue[threeName];
@@ -1684,12 +1762,16 @@ class NgtRenderer {
1684
1762
  else if (is.material(instance)) {
1685
1763
  localState.attach = ['material'];
1686
1764
  }
1765
+ if (injectedParent) {
1766
+ node.__ngt_renderer__[1 /* NgtRendererClassId.parent */] = injectedParent;
1767
+ }
1687
1768
  return node;
1688
1769
  }
1689
1770
  return createNode('dom', element, this.document);
1690
1771
  }
1691
1772
  createComment(value) {
1692
1773
  const comment = this.delegate.createComment(value);
1774
+ const commentNode = createNode('comment', comment, this.document);
1693
1775
  // NOTE: we attach an arrow function to the Comment node
1694
1776
  // In our directives, we can call this function to then start tracking the RendererNode
1695
1777
  // this is done to limit the amount of Nodes we need to process for getCreationState
@@ -1697,11 +1779,17 @@ class NgtRenderer {
1697
1779
  if (node === 'args') {
1698
1780
  this.argsCommentNodes.push(comment);
1699
1781
  }
1782
+ else if (node === 'parent') {
1783
+ this.parentCommentNodes.push(comment);
1784
+ comment[SPECIAL_INTERNAL_SET_PARENT_COMMENT] = (ngtParent) => {
1785
+ commentNode.__ngt_renderer__[1 /* NgtRendererClassId.parent */] = ngtParent;
1786
+ };
1787
+ }
1700
1788
  else if (typeof node === 'object') {
1701
1789
  this.portalCommentsNodes.push(node);
1702
1790
  }
1703
1791
  };
1704
- return createNode('comment', comment, this.document);
1792
+ return commentNode;
1705
1793
  }
1706
1794
  appendChild(parent, newChild) {
1707
1795
  const pRS = parent.__ngt_renderer__;
@@ -2074,12 +2162,12 @@ class NgtRenderer {
2074
2162
  const isChildStillDOM = cType === 'dom';
2075
2163
  return isDanglingThreeChild || (isParentStillDOM && isChildStillDOM) || isParentStillDOM;
2076
2164
  }
2077
- getNgtArgs() {
2078
- let directive;
2165
+ getNgtDirective(directive, commentNodes) {
2166
+ let directiveInstance;
2079
2167
  const destroyed = [];
2080
- let i = this.argsCommentNodes.length - 1;
2168
+ let i = commentNodes.length - 1;
2081
2169
  while (i >= 0) {
2082
- const comment = this.argsCommentNodes[i];
2170
+ const comment = commentNodes[i];
2083
2171
  if (comment.__ngt_renderer__[3 /* NgtRendererClassId.destroyed */]) {
2084
2172
  destroyed.push(i);
2085
2173
  i--;
@@ -2090,17 +2178,21 @@ class NgtRenderer {
2090
2178
  i--;
2091
2179
  continue;
2092
2180
  }
2093
- const instance = injector.get(NgtArgs, null);
2094
- if (instance && instance.validate()) {
2095
- directive = instance;
2181
+ const instance = injector.get(directive, null);
2182
+ if (instance &&
2183
+ typeof instance === 'object' &&
2184
+ 'validate' in instance &&
2185
+ typeof instance.validate === 'function' &&
2186
+ instance.validate()) {
2187
+ directiveInstance = instance;
2096
2188
  break;
2097
2189
  }
2098
2190
  i--;
2099
2191
  }
2100
2192
  destroyed.forEach((index) => {
2101
- this.argsCommentNodes.splice(index, 1);
2193
+ commentNodes.splice(index, 1);
2102
2194
  });
2103
- return directive;
2195
+ return directiveInstance;
2104
2196
  }
2105
2197
  get data() {
2106
2198
  return this.delegate.data;
@@ -2433,7 +2525,10 @@ class NgtRouterOutlet extends RouterOutlet {
2433
2525
  this.environmentInjector = inject(EnvironmentInjector);
2434
2526
  }
2435
2527
  activateWith(activatedRoute, environmentInjector) {
2436
- return super.activateWith(activatedRoute, new NgtOutletEnvironmentInjector(environmentInjector, this.environmentInjector));
2528
+ const activateWithEnvInjector = this.environmentInjector === environmentInjector
2529
+ ? environmentInjector
2530
+ : createEnvironmentInjector([], new NgtOutletEnvironmentInjector(environmentInjector, this.environmentInjector));
2531
+ return super.activateWith(activatedRoute, activateWithEnvInjector);
2437
2532
  }
2438
2533
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: NgtRouterOutlet, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2439
2534
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.5", type: NgtRouterOutlet, isStandalone: true, selector: "ngt-router-outlet", usesInheritance: true, ngImport: i0 }); }
@@ -3339,5 +3434,5 @@ const vector4 = createVectorComputed(Vector4);
3339
3434
  * Generated bundle index. Do not edit.
3340
3435
  */
3341
3436
 
3342
- export { HTML, NGT_APPLY_PROPS, NGT_STORE, NON_ROOT, NgtArgs, NgtCanvas, NgtHTML, NgtHexify, NgtObjectEvents, NgtPortal, NgtPortalBeforeRender, NgtPortalContent, NgtRenderer, NgtRendererFactory, NgtRoutedScene, NgtRouterOutlet, NgtSelect, NgtSelection, ROUTED_SCENE, addAfterEffect, addEffect, addTail, applyProps, attach, checkNeedsUpdate, checkUpdate, createAttachFunction, detach, dispose, extend, flushGlobalEffects, getEmitter, getLocalState, hasListener, injectBeforeRender, injectCanvasRootInitializer, injectLoader, injectLoop, injectObjectEvents, injectStore, invalidateInstance, is, makeCameraInstance, makeDpr, makeId, makeObjectGraph, makeRendererInstance, merge, omit, pick, prepare, privateKeys, provideHTMLDomElement, provideNgtRenderer, provideStore, resolveRef, roots, signalStore, updateCamera, vector2, vector3, vector4 };
3437
+ export { HTML, NGT_APPLY_PROPS, NGT_STORE, NON_ROOT, NgtArgs, NgtCanvas, NgtHTML, NgtHexify, NgtObjectEvents, NgtParent, NgtPortal, NgtPortalBeforeRender, NgtPortalContent, NgtRenderer, NgtRendererFactory, NgtRoutedScene, NgtRouterOutlet, NgtSelect, NgtSelection, ROUTED_SCENE, addAfterEffect, addEffect, addTail, applyProps, attach, checkNeedsUpdate, checkUpdate, createAttachFunction, detach, dispose, extend, flushGlobalEffects, getEmitter, getLocalState, hasListener, injectBeforeRender, injectCanvasRootInitializer, injectLoader, injectLoop, injectObjectEvents, injectStore, invalidateInstance, is, makeCameraInstance, makeDpr, makeId, makeObjectGraph, makeRendererInstance, merge, omit, pick, prepare, privateKeys, provideHTMLDomElement, provideNgtRenderer, provideStore, resolveRef, roots, signalStore, updateCamera, vector2, vector3, vector4 };
3343
3438
  //# sourceMappingURL=angular-three.mjs.map