@xeokit/xeokit-sdk 2.5.2-beta-3 → 2.5.2-beta-5

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xeokit/xeokit-sdk",
3
- "version": "2.5.2-beta-3",
3
+ "version": "2.5.2-beta-5",
4
4
  "description": "Web Programming Toolkit for 3D/2D BIM and AEC Graphics",
5
5
  "module": "./dist/xeokit-sdk.es.js",
6
6
  "main": "./dist/xeokit-sdk.cjs.js",
@@ -7,6 +7,7 @@ function CubeTextureCanvas(viewer, navCubeScene, cfg = {}) {
7
7
 
8
8
  const cubeColor = "lightgrey";
9
9
  const cubeHighlightColor = cfg.hoverColor || "rgba(0,0,0,0.4)";
10
+ const textColor = cfg.textColor || "black";
10
11
 
11
12
  const height = 500;
12
13
  const width = height + (height / 3);
@@ -158,7 +159,7 @@ function CubeTextureCanvas(viewer, navCubeScene, cfg = {}) {
158
159
  }
159
160
  }
160
161
  if (area.label) {
161
- context.fillStyle = "black";
162
+ context.fillStyle = textColor;
162
163
  context.font = '60px sans-serif';
163
164
  context.textAlign = "center";
164
165
  var xcenter = xmin + (width * 0.5);
@@ -88,7 +88,7 @@ class NavCubePlugin extends Plugin {
88
88
  * @param {String} [cfg.cameraFly=true] Whether the {@link Camera} flies or jumps to each selected axis or diagonal.
89
89
  * @param {String} [cfg.cameraFitFOV=45] How much of the field-of-view, in degrees, that the 3D scene should fill the {@link Canvas} when the {@link Camera} moves to an axis or diagonal.
90
90
  * @param {String} [cfg.cameraFlyDuration=0.5] When flying the {@link Camera} to each new axis or diagonal, how long, in seconds, that the Camera takes to get there.
91
- * @param {String} [cfg.color="lightgrey] Custom uniform color for the faces of the NavCube.
91
+ * @param {String} [cfg.color="lightgrey"] Custom uniform color for the faces of the NavCube.
92
92
  * @param {String} [cfg.frontColor="#55FF55"] Custom color for the front face of the NavCube. Overrides ````color````.
93
93
  * @param {String} [cfg.backColor="#55FF55"] Custom color for the back face of the NavCube. Overrides ````color````.
94
94
  * @param {String} [cfg.leftColor="#FF5555"] Custom color for the left face of the NavCube. Overrides ````color````.
@@ -96,6 +96,7 @@ class NavCubePlugin extends Plugin {
96
96
  * @param {String} [cfg.topColor="#5555FF"] Custom color for the top face of the NavCube. Overrides ````color````.
97
97
  * @param {String} [cfg.bottomColor="#5555FF"] Custom color for the bottom face of the NavCube. Overrides ````color````.
98
98
  * @param {String} [cfg.hoverColor="rgba(0,0,0,0.4)"] Custom color for highlighting regions on the NavCube as we hover the pointer over them.
99
+ * @param {String} [cfg.textColor="black"] Custom text color for labels of the NavCube.
99
100
  * @param {Boolean} [cfg.fitVisible=false] Sets whether the axis, corner and edge-aligned views will fit the
100
101
  * view to the entire {@link Scene} or just to visible object-{@link Entity}s. Entitys are visible objects when {@link Entity#isObject} and {@link Entity#visible} are both ````true````.
101
102
  * @param {Boolean} [cfg.synchProjection=false] Sets whether the NavCube switches between perspective and orthographic projections in synchrony with the {@link Camera}. When ````false````, the NavCube will always be rendered with perspective projection.
@@ -0,0 +1,169 @@
1
+ /**
2
+ * @desc A {@link TreeViewPlugin} render class.
3
+ *
4
+ */
5
+ export class RenderService {
6
+
7
+ /*
8
+ * Creates the root node of the tree.
9
+ * @return {HTMLElement} The root node of the tree.
10
+ */
11
+ createRootNode() {
12
+ return document.createElement('ul')
13
+ }
14
+
15
+ /*
16
+ * Creates node of the tree.
17
+ * @param {Object} node The node to create.
18
+
19
+ * @return {HTMLElement} The html element for the node.
20
+ */
21
+ createNodeElement(node, expandHandler, checkHandler, contextmenuHandler, titleClickHandler) {
22
+ const nodeElement = document.createElement('li');
23
+ nodeElement.id = node.nodeId;
24
+
25
+ if (node.xrayed) {
26
+ nodeElement.classList.add('xrayed-node');
27
+ }
28
+
29
+ if (node.children.length > 0) {
30
+ const switchElement = document.createElement('a');
31
+ switchElement.href = '#';
32
+ switchElement.id = `switch-${node.nodeId}`;
33
+ switchElement.textContent = '+';
34
+ switchElement.classList.add('plus');
35
+ if (expandHandler) switchElement.addEventListener('click', expandHandler);
36
+ nodeElement.appendChild(switchElement);
37
+ }
38
+
39
+ const checkbox = document.createElement('input');
40
+ checkbox.id = `checkbox-${node.nodeId}`;
41
+ checkbox.type = "checkbox";
42
+ checkbox.checked = node.checked;
43
+ checkbox.style["pointer-events"] = "all";
44
+ if (checkHandler) checkbox.addEventListener("change", checkHandler);
45
+ nodeElement.appendChild(checkbox);
46
+
47
+ const span = document.createElement('span');
48
+ span.textContent = node.title;
49
+ nodeElement.appendChild(span);
50
+
51
+ if (contextmenuHandler) {
52
+ span.oncontextmenu = contextmenuHandler;
53
+ }
54
+
55
+ if (titleClickHandler) {
56
+ span.onclick = titleClickHandler;
57
+ }
58
+
59
+ return nodeElement;
60
+ }
61
+
62
+ createDisabledNodeElement(rootName) {
63
+ const li = document.createElement('li');
64
+
65
+ const switchElement = document.createElement('a');
66
+ switchElement.href = '#';
67
+ switchElement.textContent = '!';
68
+ switchElement.classList.add('warn');
69
+ switchElement.classList.add('warning');
70
+ li.appendChild(switchElement);
71
+
72
+ const span = document.createElement('span');
73
+ span.textContent = rootName;
74
+ li.appendChild(span);
75
+
76
+ return li;
77
+ }
78
+
79
+ addChildren(element, nodes) {
80
+ const ul = document.createElement('ul');
81
+ nodes.forEach((nodeElement) => {
82
+ ul.appendChild(nodeElement);
83
+ });
84
+
85
+ element.parentElement.appendChild(ul);
86
+ }
87
+
88
+ expand(element, expandHandler, collapseHandler) {
89
+ element.classList.remove('plus');
90
+ element.classList.add('minus');
91
+ element.textContent = '-';
92
+ element.removeEventListener('click', expandHandler);
93
+ element.addEventListener('click', collapseHandler);
94
+ }
95
+
96
+ collapse(element, expandHandler, collapseHandler) {
97
+ if (!element) {
98
+ return;
99
+ }
100
+ const parent = element.parentElement;
101
+ if (!parent) {
102
+ return;
103
+ }
104
+ const ul = parent.querySelector('ul');
105
+ if (!ul) {
106
+ return;
107
+ }
108
+ parent.removeChild(ul);
109
+ element.classList.remove('minus');
110
+ element.classList.add('plus');
111
+ element.textContent = '+';
112
+ element.removeEventListener('click', collapseHandler);
113
+ element.addEventListener('click', expandHandler);
114
+ }
115
+
116
+ isExpanded(element) {
117
+ const parentElement = element.parentElement;
118
+ return parentElement.getElementsByTagName('li')[0] !== undefined;
119
+ }
120
+
121
+ getId(element) {
122
+ const parentElement = element.parentElement;
123
+ return parentElement.id;
124
+ }
125
+
126
+ getIdFromCheckbox(element) {
127
+ return element.id.replace('checkbox-', '');
128
+ }
129
+
130
+ getSwitchElement(nodeId) {
131
+ return document.getElementById(`switch-${nodeId}`);
132
+ }
133
+
134
+ isChecked(element) {
135
+ return element.checked;
136
+ }
137
+
138
+ setCheckbox(nodeId, checked) {
139
+ const checkbox = document.getElementById(`checkbox-${nodeId}`);
140
+ if (checkbox) {
141
+ if (checked !== checkbox.checked) {
142
+ checkbox.checked = checked;
143
+ }
144
+ }
145
+ }
146
+
147
+ setXRayed(nodeId, xrayed) {
148
+ const treeNode = document.getElementById(nodeId);
149
+ if (treeNode) {
150
+ if (xrayed) {
151
+ treeNode.classList.add('xrayed-node');
152
+ } else {
153
+ treeNode.classList.remove('xrayed-node');
154
+ }
155
+ }
156
+ }
157
+
158
+ setHighlighted(nodeId, highlighted) {
159
+ const treeNode = document.getElementById(nodeId);
160
+ if (treeNode) {
161
+ if (highlighted) {
162
+ treeNode.scrollIntoView({block: "center"});
163
+ treeNode.classList.add('highlighted-node');
164
+ } else {
165
+ treeNode.classList.remove('highlighted-node');
166
+ }
167
+ }
168
+ }
169
+ }
@@ -1,4 +1,5 @@
1
1
  import {Plugin} from "../../viewer/Plugin.js";
2
+ import {RenderService} from "./RenderService.js";
2
3
 
3
4
  const treeViews = [];
4
5
 
@@ -359,6 +360,7 @@ export class TreeViewPlugin extends Plugin {
359
360
  * ````IfcBuildingStorey```` nodes will be ordered spatially, from the highest storey down to the lowest, on the
360
361
  * vertical World axis. For all hierarchy types, other node types will be ordered in the ascending alphanumeric order of their titles.
361
362
  * @param {Boolean} [cfg.pruneEmptyNodes=true] When true, will not contain nodes that don't have content in the {@link Scene}. These are nodes whose {@link MetaObject}s don't have {@link Entity}s.
363
+ * @param {RenderService} [cfg.renderService] Optional {@link RenderService} to use. Defaults to the {@link TreeViewPlugin}'s default {@link RenderService}.
362
364
  */
363
365
  constructor(viewer, cfg = {}) {
364
366
 
@@ -398,7 +400,6 @@ export class TreeViewPlugin extends Plugin {
398
400
  this._autoAddModels = (cfg.autoAddModels !== false);
399
401
  this._autoExpandDepth = (cfg.autoExpandDepth || 0);
400
402
  this._sortNodes = (cfg.sortNodes !== false);
401
- this._pruneEmptyNodes = (cfg.pruneEmptyNodes !== false);
402
403
  this._viewer = viewer;
403
404
  this._rootElement = null;
404
405
  this._muteSceneEvents = false;
@@ -406,10 +407,15 @@ export class TreeViewPlugin extends Plugin {
406
407
  this._rootNodes = [];
407
408
  this._objectNodes = {}; // Object ID -> Node
408
409
  this._nodeNodes = {}; // Node ID -> Node
409
- this._rootName = cfg.rootName;
410
+ this._rootNames = {}; // Node ID -> Root name
410
411
  this._sortNodes = cfg.sortNodes;
411
412
  this._pruneEmptyNodes = cfg.pruneEmptyNodes;
412
413
  this._showListItemElementId = null;
414
+ this._renderService = cfg.renderService || new RenderService();
415
+
416
+ if (!this._renderService) {
417
+ throw new Error('TreeViewPlugin: no render service set');
418
+ }
413
419
 
414
420
  this._containerElement.oncontextmenu = (e) => {
415
421
  e.preventDefault();
@@ -436,10 +442,9 @@ export class TreeViewPlugin extends Plugin {
436
442
  } else {
437
443
  node.numVisibleEntities--;
438
444
  }
439
- const checkbox = document.getElementById(`checkbox-${node.nodeId}`);
440
- if (checkbox) {
441
- checkbox.checked = visible;
442
- }
445
+
446
+ this._renderService.setCheckbox(node.nodeId, visible);
447
+
443
448
  let parent = node.parent;
444
449
  while (parent) {
445
450
  parent.checked = visible;
@@ -448,15 +453,12 @@ export class TreeViewPlugin extends Plugin {
448
453
  } else {
449
454
  parent.numVisibleEntities--;
450
455
  }
451
- const parentCheckbox = document.getElementById(`checkbox-${parent.nodeId}`);
452
- if (parentCheckbox) {
453
- const newChecked = (parent.numVisibleEntities > 0);
454
- if (newChecked !== parentCheckbox.checked) {
455
- parentCheckbox.checked = newChecked;
456
- }
457
- }
456
+
457
+ this._renderService.setCheckbox(parent.nodeId, (parent.numVisibleEntities > 0));
458
+
458
459
  parent = parent.parent;
459
460
  }
461
+
460
462
  this._muteTreeEvents = false;
461
463
  });
462
464
 
@@ -476,15 +478,8 @@ export class TreeViewPlugin extends Plugin {
476
478
  return;
477
479
  }
478
480
  node.xrayed = xrayed;
479
- const listItemElementId = node.nodeId;
480
- const listItemElement = document.getElementById(listItemElementId);
481
- if (listItemElement !== null) {
482
- if (xrayed) {
483
- listItemElement.classList.add('xrayed-node');
484
- } else {
485
- listItemElement.classList.remove('xrayed-node');
486
- }
487
- }
481
+
482
+ this._renderService.setXRayed(node.nodeId, xrayed);
488
483
  this._muteTreeEvents = false;
489
484
  });
490
485
 
@@ -508,14 +503,15 @@ export class TreeViewPlugin extends Plugin {
508
503
  }
509
504
  this._muteSceneEvents = true;
510
505
  const checkbox = event.target;
511
- const visible = checkbox.checked;
512
- const nodeId = checkbox.id.replace('checkbox-', '');
506
+ const visible = this._renderService.isChecked(checkbox);
507
+ const nodeId = this._renderService.getIdFromCheckbox(checkbox);
508
+
513
509
  const checkedNode = this._nodeNodes[nodeId];
514
510
  const objects = this._viewer.scene.objects;
515
511
  let numUpdated = 0;
512
+
516
513
  this._withNodeTree(checkedNode, (node) => {
517
514
  const objectId = node.objectId;
518
- const checkBoxId = `checkbox-${node.nodeId}`;
519
515
  const entity = objects[objectId];
520
516
  const isLeaf = (node.children.length === 0);
521
517
  node.numVisibleEntities = visible ? node.numEntities : 0;
@@ -523,27 +519,26 @@ export class TreeViewPlugin extends Plugin {
523
519
  numUpdated++;
524
520
  }
525
521
  node.checked = visible;
526
- const checkbox2 = document.getElementById(checkBoxId);
527
- if (checkbox2) {
528
- checkbox2.checked = visible;
529
- }
522
+
523
+ this._renderService.setCheckbox(node.nodeId, visible);
524
+
530
525
  if (entity) {
531
526
  entity.visible = visible;
532
527
  }
533
528
  });
529
+
534
530
  let parent = checkedNode.parent;
535
531
  while (parent) {
536
532
  parent.checked = visible;
537
- const checkbox2 = document.getElementById(`checkbox-${parent.nodeId}`); // Parent checkboxes are always in DOM
533
+
538
534
  if (visible) {
539
535
  parent.numVisibleEntities += numUpdated;
540
536
  } else {
541
537
  parent.numVisibleEntities -= numUpdated;
542
538
  }
543
- const newChecked = (parent.numVisibleEntities > 0);
544
- if (newChecked !== checkbox2.checked) {
545
- checkbox2.checked = newChecked;
546
- }
539
+
540
+ this._renderService.setCheckbox(parent.nodeId, (parent.numVisibleEntities > 0));
541
+
547
542
  parent = parent.parent;
548
543
  }
549
544
  this._muteSceneEvents = false;
@@ -641,6 +636,11 @@ export class TreeViewPlugin extends Plugin {
641
636
  return;
642
637
  }
643
638
  this._metaModels[modelId] = metaModel;
639
+
640
+ if (options && options.rootName) {
641
+ this._rootNames[modelId] = options.rootName;
642
+ }
643
+
644
644
  model.on("destroyed", () => {
645
645
  this.removeModel(model.id);
646
646
  });
@@ -662,6 +662,11 @@ export class TreeViewPlugin extends Plugin {
662
662
  if (!metaModel) {
663
663
  return;
664
664
  }
665
+
666
+ if (this._rootNames[modelId]) {
667
+ delete this._rootNames[modelId];
668
+ }
669
+
665
670
  delete this._metaModels[modelId];
666
671
  this._createNodes();
667
672
  }
@@ -683,21 +688,22 @@ export class TreeViewPlugin extends Plugin {
683
688
  * @param {String} objectId ID of the {@link Entity}.
684
689
  */
685
690
  showNode(objectId) {
686
- if (this._showListItemElementId) {
687
- this.unShowNode();
688
- }
691
+ this.unShowNode();
692
+
689
693
  const node = this._objectNodes[objectId];
690
694
  if (!node) {
691
695
  return; // Node may not exist for the given object if (this._pruneEmptyNodes == true)
692
696
  }
697
+
693
698
  const nodeId = node.nodeId;
694
- const switchElementId = "switch-" + nodeId;
695
- const switchElement = document.getElementById(switchElementId);
699
+
700
+ const switchElement = this._renderService.getSwitchElement(nodeId);
696
701
  if (switchElement) {
697
702
  this._expandSwitchElement(switchElement);
698
703
  switchElement.scrollIntoView();
699
- return;
704
+ return true;
700
705
  }
706
+
701
707
  const path = [];
702
708
  path.unshift(node);
703
709
  let parent = node.parent;
@@ -705,20 +711,17 @@ export class TreeViewPlugin extends Plugin {
705
711
  path.unshift(parent);
706
712
  parent = parent.parent;
707
713
  }
714
+
708
715
  for (let i = 0, len = path.length; i < len; i++) {
709
- const node = path[i];
710
- const nodeId = node.nodeId;
711
- const switchElementId = "switch-" + nodeId;
712
- const switchElement = document.getElementById(switchElementId);
716
+ const switchElement = this._renderService.getSwitchElement(path[i].nodeId);
713
717
  if (switchElement) {
714
718
  this._expandSwitchElement(switchElement);
715
719
  }
716
720
  }
717
- const listItemElementId = nodeId;
718
- const listItemElement = document.getElementById(listItemElementId);
719
- listItemElement.scrollIntoView({block: "center"});
720
- listItemElement.classList.add("highlighted-node");
721
- this._showListItemElementId = listItemElementId;
721
+
722
+ this._renderService.setHighlighted(nodeId, true);
723
+
724
+ this._showListItemElementId = nodeId;
722
725
  }
723
726
 
724
727
  /**
@@ -732,12 +735,9 @@ export class TreeViewPlugin extends Plugin {
732
735
  if (!this._showListItemElementId) {
733
736
  return;
734
737
  }
735
- const listItemElement = document.getElementById(this._showListItemElementId);
736
- if (!listItemElement) {
737
- this._showListItemElementId = null;
738
- return;
739
- }
740
- listItemElement.classList.remove("highlighted-node");
738
+
739
+ this._renderService.setHighlighted(this._showListItemElementId, false)
740
+
741
741
  this._showListItemElementId = null;
742
742
  }
743
743
 
@@ -754,9 +754,8 @@ export class TreeViewPlugin extends Plugin {
754
754
  if (countDepth === depth) {
755
755
  return;
756
756
  }
757
- const nodeId = node.nodeId;
758
- const switchElementId = "switch-" + nodeId;
759
- const switchElement = document.getElementById(switchElementId);
757
+
758
+ const switchElement = this._renderService.getSwitchElement(node.nodeId);
760
759
  if (switchElement) {
761
760
  this._expandSwitchElement(switchElement);
762
761
  const childNodes = node.children;
@@ -911,11 +910,12 @@ export class TreeViewPlugin extends Plugin {
911
910
 
912
911
  _createDisabledNodes() {
913
912
 
914
- const ul = document.createElement('ul');
915
- this._rootElement = ul;
916
- this._containerElement.appendChild(ul);
913
+ const rootNode = this._renderService.createRootNode();
914
+ this._rootElement = rootNode;
915
+ this._containerElement.appendChild(rootNode);
917
916
 
918
917
  const rootMetaObjects = this._viewer.metaScene.rootMetaObjects;
918
+
919
919
  for (let objectId in rootMetaObjects) {
920
920
  const rootMetaObject = rootMetaObjects[objectId];
921
921
  const metaObjectType = rootMetaObject.type;
@@ -923,17 +923,9 @@ export class TreeViewPlugin extends Plugin {
923
923
  const rootName = ((metaObjectName && metaObjectName !== ""
924
924
  && metaObjectName !== "Undefined"
925
925
  && metaObjectName !== "Default") ? metaObjectName : metaObjectType);
926
- const li = document.createElement('li');
927
- ul.appendChild(li);
928
- const switchElement = document.createElement('a');
929
- switchElement.href = '#';
930
- switchElement.textContent = '!';
931
- switchElement.classList.add('warn');
932
- switchElement.classList.add('warning');
933
- li.appendChild(switchElement);
934
- const span = document.createElement('span');
935
- span.textContent = rootName;
936
- li.appendChild(span);
926
+
927
+ const childNode = this._renderService.createDisabledNodeElement(rootName);
928
+ rootNode.appendChild(childNode);
937
929
  }
938
930
  }
939
931
 
@@ -984,7 +976,7 @@ export class TreeViewPlugin extends Plugin {
984
976
  buildingNode = {
985
977
  nodeId: `${this._id}-${objectId}`,
986
978
  objectId: objectId,
987
- title: this._rootName || ((metaObjectName && metaObjectName !== "" && metaObjectName !== "Undefined" && metaObjectName !== "Default") ? metaObjectName : metaObjectType),
979
+ title: this._rootNames[metaObject.metaModels[0].id] || ((metaObjectName && metaObjectName !== "" && metaObjectName !== "Undefined" && metaObjectName !== "Default") ? metaObjectName : metaObjectType),
988
980
  type: metaObjectType,
989
981
  parent: null,
990
982
  numEntities: 0,
@@ -1087,7 +1079,7 @@ export class TreeViewPlugin extends Plugin {
1087
1079
  rootNode = {
1088
1080
  nodeId: `${this._id}-${objectId}`,
1089
1081
  objectId: objectId,
1090
- title: this._rootName || ((metaObjectName && metaObjectName !== "" && metaObjectName !== "Undefined" && metaObjectName !== "Default") ? metaObjectName : metaObjectType),
1082
+ title: this._rootNames[metaObject.metaModels[0].id] || ((metaObjectName && metaObjectName !== "" && metaObjectName !== "Undefined" && metaObjectName !== "Default") ? metaObjectName : metaObjectType),
1091
1083
  type: metaObjectType,
1092
1084
  parent: null,
1093
1085
  numEntities: 0,
@@ -1168,7 +1160,7 @@ export class TreeViewPlugin extends Plugin {
1168
1160
  const node = {
1169
1161
  nodeId: `${this._id}-${objectId}`,
1170
1162
  objectId: objectId,
1171
- title: (!parent) ? (this._rootName || metaObjectName) : (metaObjectName && metaObjectName !== "" && metaObjectName !== "Undefined" && metaObjectName !== "Default") ? metaObjectName : metaObjectType,
1163
+ title: (!parent) ? (this._rootNames[metaObject.metaModels[0].id] || metaObjectName) : (metaObjectName && metaObjectName !== "" && metaObjectName !== "Undefined" && metaObjectName !== "Default") ? metaObjectName : metaObjectType,
1172
1164
  type: metaObjectType,
1173
1165
  parent: parent,
1174
1166
  numEntities: 0,
@@ -1316,112 +1308,63 @@ export class TreeViewPlugin extends Plugin {
1316
1308
  const rootNodeElements = this._rootNodes.map((rootNode) => {
1317
1309
  return this._createNodeElement(rootNode);
1318
1310
  });
1319
- const ul = document.createElement('ul');
1311
+
1312
+ const rootNode = this._renderService.createRootNode();
1320
1313
  rootNodeElements.forEach((nodeElement) => {
1321
- ul.appendChild(nodeElement);
1314
+ rootNode.appendChild(nodeElement);
1322
1315
  });
1323
- this._containerElement.appendChild(ul);
1324
- this._rootElement = ul;
1316
+
1317
+ this._containerElement.appendChild(rootNode);
1318
+ this._rootElement = rootNode;
1325
1319
  }
1326
1320
 
1327
1321
  _createNodeElement(node) {
1328
- const nodeElement = document.createElement('li');
1329
- //const nodeId = this._objectToNodeID(node.objectId);
1330
- const nodeId = node.nodeId;
1331
- if (node.xrayed) {
1332
- nodeElement.classList.add('xrayed-node');
1333
- }
1334
- nodeElement.id = nodeId;
1335
- if (node.children.length > 0) {
1336
- const switchElementId = "switch-" + nodeId;
1337
- const switchElement = document.createElement('a');
1338
- switchElement.href = '#';
1339
- switchElement.id = switchElementId;
1340
- switchElement.textContent = '+';
1341
- switchElement.classList.add('plus');
1342
- switchElement.addEventListener('click', this._switchExpandHandler);
1343
- nodeElement.appendChild(switchElement);
1344
- }
1345
- const checkbox = document.createElement('input');
1346
- checkbox.id = `checkbox-${nodeId}`;
1347
- checkbox.type = "checkbox";
1348
- checkbox.checked = node.checked;
1349
- checkbox.style["pointer-events"] = "all";
1350
- checkbox.addEventListener("change", this._checkboxChangeHandler);
1351
- nodeElement.appendChild(checkbox);
1352
- const span = document.createElement('span');
1353
- span.textContent = node.title;
1354
- nodeElement.appendChild(span);
1355
- span.oncontextmenu = (e) => {
1356
- this.fire("contextmenu", {
1357
- event: e,
1322
+ const contextmenuHandler = (event) =>{
1323
+ this.fire("contextmenu", {
1324
+ event: event,
1358
1325
  viewer: this._viewer,
1359
1326
  treeViewPlugin: this,
1360
1327
  treeViewNode: node
1361
1328
  });
1362
- e.preventDefault();
1329
+ event.preventDefault();
1363
1330
  };
1364
- span.onclick = (e) => {
1331
+ const onclickHandler = (event) => {
1365
1332
  this.fire("nodeTitleClicked", {
1366
- event: e,
1333
+ event: event,
1367
1334
  viewer: this._viewer,
1368
1335
  treeViewPlugin: this,
1369
1336
  treeViewNode: node
1370
1337
  });
1371
- e.preventDefault();
1338
+ event.preventDefault();
1372
1339
  };
1373
- return nodeElement;
1340
+
1341
+ return this._renderService.createNodeElement(node, this._switchExpandHandler, this._checkboxChangeHandler, contextmenuHandler, onclickHandler);
1374
1342
  }
1375
1343
 
1376
1344
  _expandSwitchElement(switchElement) {
1377
- const parentElement = switchElement.parentElement;
1378
- const expanded = parentElement.getElementsByTagName('li')[0];
1345
+ const expanded = this._renderService.isExpanded(switchElement);
1379
1346
  if (expanded) {
1380
1347
  return;
1381
1348
  }
1382
- const nodeId = parentElement.id;
1383
- const switchNode = this._nodeNodes[nodeId];
1384
- const childNodes = switchNode.children;
1385
- const nodeElements = childNodes.map((node) => {
1349
+
1350
+ const nodeId = this._renderService.getId(switchElement);
1351
+
1352
+ const nodeElements = this._nodeNodes[nodeId].children.map((node) => {
1386
1353
  return this._createNodeElement(node);
1387
1354
  });
1388
- const ul = document.createElement('ul');
1389
- nodeElements.forEach((nodeElement) => {
1390
- ul.appendChild(nodeElement);
1391
- });
1392
- parentElement.appendChild(ul);
1393
- switchElement.classList.remove('plus');
1394
- switchElement.classList.add('minus');
1395
- switchElement.textContent = '-';
1396
- switchElement.removeEventListener('click', this._switchExpandHandler);
1397
- switchElement.addEventListener('click', this._switchCollapseHandler);
1355
+
1356
+ this._renderService.addChildren(switchElement, nodeElements)
1357
+
1358
+ this._renderService.expand(switchElement, this._switchExpandHandler, this._switchCollapseHandler);
1398
1359
  }
1399
1360
 
1400
- _collapseNode(objectId) {
1401
- const nodeId = objectId;
1402
- const switchElementId = "switch-" + nodeId;
1403
- const switchElement = document.getElementById(switchElementId);
1361
+ _collapseNode(nodeId) {
1362
+ const switchElement = this._renderService.getSwitchElement(nodeId);
1404
1363
  this._collapseSwitchElement(switchElement);
1405
1364
  }
1406
1365
 
1407
1366
  _collapseSwitchElement(switchElement) {
1408
- if (!switchElement) {
1409
- return;
1410
- }
1411
- const parent = switchElement.parentElement;
1412
- if (!parent) {
1413
- return;
1414
- }
1415
- const ul = parent.querySelector('ul');
1416
- if (!ul) {
1417
- return;
1418
- }
1419
- parent.removeChild(ul);
1420
- switchElement.classList.remove('minus');
1421
- switchElement.classList.add('plus');
1422
- switchElement.textContent = '+';
1423
- switchElement.removeEventListener('click', this._switchCollapseHandler);
1424
- switchElement.addEventListener('click', this._switchExpandHandler);
1367
+ this._renderService.collapse(switchElement, this._switchExpandHandler, this._switchCollapseHandler);
1425
1368
  }
1426
1369
  }
1427
1370