x_ite 8.3.0 → 8.3.2

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.
Files changed (77) hide show
  1. package/README.md +5 -2
  2. package/build/bin/tests.pl +2 -0
  3. package/dist/assets/components/Annotation.js +13 -13
  4. package/dist/assets/components/Annotation.min.js +1 -1
  5. package/dist/assets/components/CADGeometry.js +13 -13
  6. package/dist/assets/components/CADGeometry.min.js +1 -1
  7. package/dist/assets/components/CubeMapTexturing.js +25 -25
  8. package/dist/assets/components/CubeMapTexturing.min.js +1 -1
  9. package/dist/assets/components/DIS.js +13 -13
  10. package/dist/assets/components/DIS.min.js +1 -1
  11. package/dist/assets/components/EventUtilities.js +9 -9
  12. package/dist/assets/components/EventUtilities.min.js +1 -1
  13. package/dist/assets/components/Geometry2D.js +19 -19
  14. package/dist/assets/components/Geometry2D.min.js +1 -1
  15. package/dist/assets/components/Geospatial.js +33 -33
  16. package/dist/assets/components/Geospatial.min.js +1 -1
  17. package/dist/assets/components/HAnim.js +18 -18
  18. package/dist/assets/components/HAnim.min.js +1 -1
  19. package/dist/assets/components/KeyDeviceSensor.js +8 -8
  20. package/dist/assets/components/KeyDeviceSensor.min.js +1 -1
  21. package/dist/assets/components/Layout.js +27 -27
  22. package/dist/assets/components/Layout.min.js +1 -1
  23. package/dist/assets/components/NURBS.js +24 -24
  24. package/dist/assets/components/NURBS.min.js +1 -1
  25. package/dist/assets/components/ParticleSystems.js +23 -23
  26. package/dist/assets/components/ParticleSystems.min.js +1 -1
  27. package/dist/assets/components/Picking.js +19 -19
  28. package/dist/assets/components/Picking.min.js +1 -1
  29. package/dist/assets/components/ProjectiveTextureMapping.js +14 -14
  30. package/dist/assets/components/ProjectiveTextureMapping.min.js +1 -1
  31. package/dist/assets/components/RigidBodyPhysics.js +17 -17
  32. package/dist/assets/components/RigidBodyPhysics.min.js +1 -1
  33. package/dist/assets/components/Scripting.js +28 -28
  34. package/dist/assets/components/Scripting.min.js +1 -1
  35. package/dist/assets/components/Text.js +24 -24
  36. package/dist/assets/components/Text.min.js +1 -1
  37. package/dist/assets/components/Texturing3D.js +46 -46
  38. package/dist/assets/components/Texturing3D.min.js +1 -1
  39. package/dist/assets/components/VolumeRendering.js +19 -19
  40. package/dist/assets/components/VolumeRendering.min.js +1 -1
  41. package/dist/assets/components/X_ITE.js +9 -9
  42. package/dist/assets/components/X_ITE.min.js +1 -1
  43. package/dist/x_ite.css +1 -1
  44. package/dist/x_ite.js +445 -294
  45. package/dist/x_ite.min.js +1 -1
  46. package/dist/x_ite.zip +0 -0
  47. package/docs/_config.yml +2 -1
  48. package/docs/_posts/custom-shaders.md +1 -1
  49. package/docs/_posts/dom-integration.md +52 -25
  50. package/docs/_posts/getting-started.md +6 -3
  51. package/docs/_posts/reference/field-services-and-objects.md +2 -34
  52. package/docs/_posts/tutorials/basic-nodes.md +2 -2
  53. package/docs/_posts/tutorials/building-a-x3d-world.md +20 -4
  54. package/docs/_posts/tutorials/building-primitive-shapes.md +4 -4
  55. package/docs/_posts/tutorials/creating-new-node-types.md +22 -0
  56. package/docs/_posts/tutorials/hello-world.md +6 -6
  57. package/docs/_posts/tutorials/improving-performance.md +2 -2
  58. package/docs/_posts/tutorials/writing-program-scripts-with-ecmascript.md +2 -2
  59. package/docs/_tabs/playground.html +74 -17
  60. package/docs/assets/css/style.scss +7 -1
  61. package/package.json +2 -2
  62. package/src/x_ite/Base/X3DArrayField.js +3 -0
  63. package/src/x_ite/Base/X3DBaseNode.js +4 -0
  64. package/src/x_ite/Base/X3DInfoArray.js +7 -3
  65. package/src/x_ite/Browser/Core/ContextMenu.js +5 -7
  66. package/src/x_ite/Browser/DOMIntegration.js +62 -55
  67. package/src/x_ite/Browser/VERSION.js +1 -1
  68. package/src/x_ite/Browser/X3DBrowser.js +1 -1
  69. package/src/x_ite/Browser/X3DBrowserContext.js +3 -0
  70. package/src/x_ite/Components/Core/X3DPrototypeInstance.js +1 -1
  71. package/src/x_ite/Components/Networking/Inline.js +21 -2
  72. package/src/x_ite/Configuration/SupportedNodes.js +1 -5
  73. package/src/x_ite/Execution/X3DScene.js +74 -58
  74. package/src/x_ite/Parser/JSONParser.js +1 -1
  75. package/src/x_ite/Parser/XMLParser.js +151 -49
  76. package/src/x_ite.html +2 -2
  77. package/webpack.config.js +2 -2
@@ -57,6 +57,7 @@ X3DArrayField .prototype = Object .assign (Object .create (X3DField .prototype),
57
57
  constructor: X3DArrayField,
58
58
  at: Array .prototype .at,
59
59
  concat: Array .prototype .concat,
60
+ //Array.prototype.copyWithin,
60
61
  entries: Array .prototype .entries,
61
62
  every: Array .prototype .every,
62
63
  fill: Array .prototype .fill,
@@ -76,8 +77,10 @@ X3DArrayField .prototype = Object .assign (Object .create (X3DField .prototype),
76
77
  map: Array .prototype .map,
77
78
  reduce: Array .prototype .reduce,
78
79
  reduceRight: Array .prototype .reduceRight,
80
+ //Array.prototype.reverse
79
81
  slice: Array .prototype .slice,
80
82
  some: Array .prototype .some,
83
+ //Array.prototype.sort
81
84
  values: Array .prototype .values,
82
85
  });
83
86
 
@@ -51,6 +51,7 @@ import FieldDefinitionArray from "./FieldDefinitionArray.js";
51
51
  import FieldArray from "./FieldArray.js";
52
52
  import Fields from "../Fields.js";
53
53
  import X3DConstants from "./X3DConstants.js";
54
+ import HTMLSupport from "../Parser/HTMLSupport.js";
54
55
 
55
56
  const
56
57
  _executionContext = Symbol (),
@@ -390,6 +391,9 @@ X3DBaseNode .prototype = Object .assign (Object .create (X3DEventObject .prototy
390
391
  enumerable: true,
391
392
  configurable: false,
392
393
  });
394
+
395
+ if (field .isInitializable ())
396
+ HTMLSupport .addFieldName (alias);
393
397
  },
394
398
  removeField: function (name)
395
399
  {
@@ -201,24 +201,28 @@ X3DInfoArray .prototype = {
201
201
  },
202
202
  at: Array .prototype .at,
203
203
  concat: Array .prototype .concat,
204
- //entries: function () { return iterator -> [index, value]; },
204
+ entries: Array .prototype .entries,
205
205
  every: Array .prototype .every,
206
206
  fill: Array .prototype .fill,
207
207
  filter: Array .prototype .filter,
208
208
  find: Array .prototype .find,
209
209
  findIndex: Array .prototype .findIndex,
210
+ findLast: Array .prototype .findLast,
211
+ findLastIndex: Array .prototype .findLastIndex,
212
+ flat: Array .prototype .flat,
213
+ flatMap: Array .prototype .flatMap,
210
214
  forEach: Array .prototype .forEach,
211
215
  includes: Array .prototype .includes,
212
216
  indexOf: Array .prototype .indexOf,
213
217
  join: Array .prototype .join,
214
- keys: function () { return Array (this .length) .keys (); },
218
+ keys: Array .prototype .keys,
215
219
  lastIndexOf: Array .prototype .lastIndexOf,
216
220
  map: Array .prototype .map,
217
221
  reduce: Array .prototype .reduce,
218
222
  reduceRight: Array .prototype .reduceRight,
219
223
  slice: Array .prototype .slice,
220
224
  some: Array .prototype .some,
221
- values: function () { return this [Symbol .iterator]; },
225
+ values: Array .prototype .values,
222
226
  toString: function (scene)
223
227
  {
224
228
  const stream = { string: "" };
@@ -604,17 +604,13 @@ ContextMenu .prototype = Object .assign (Object .create (X3DBaseNode .prototype)
604
604
 
605
605
  // Menu
606
606
 
607
- const
608
- x = event .pageX - $(document) .scrollLeft (),
609
- y = event .pageY - $(document) .scrollTop ();
610
-
611
607
  const ul = $("<ul></ul>")
612
608
  .hide ()
609
+ .addClass ("context-menu-root")
613
610
  .addClass ("context-menu-list")
614
611
  .addClass (menu .className)
615
- .addClass ("context-menu-root")
616
- .css ({ "left": x, "top": y })
617
- .appendTo (options .appendTo);
612
+ .appendTo (options .appendTo)
613
+ .offset ({ "left": event .pageX, "top": event .pageY });
618
614
 
619
615
  for (const k in menu .items)
620
616
  ul .append (this .createItem (menu .items [k], "context-menu-root", k, level + 1, hide));
@@ -623,6 +619,8 @@ ContextMenu .prototype = Object .assign (Object .create (X3DBaseNode .prototype)
623
619
 
624
620
  // Reposition menu if to right or to low.
625
621
 
622
+ ul .offset ({ "left": event .pageX, "top": event .pageY }); // Do it again!
623
+
626
624
  if (ul .offset () .left - $(document) .scrollLeft () + ul .outerWidth () > $(window) .width ())
627
625
  ul .offset ({ "left": $(document) .scrollLeft () + Math .max (0, $(window) .width () - ul .outerWidth ()) });
628
626
 
@@ -25,31 +25,28 @@
25
25
 
26
26
  import XMLParser from "../Parser/XMLParser.js"
27
27
  import X3DConstants from "../Base/X3DConstants.js";
28
- import SFNodeCache from "../Fields/SFNodeCache.js";
29
28
 
30
29
  class DOMIntegration
31
30
  {
32
31
  constructor (browser)
33
32
  {
34
- this .browser = browser;
35
- this .rootElement = undefined;
33
+ this .browser = browser;
34
+ this .rootElement = undefined;
35
+ this .canvasObserver = new MutationObserver (() => this .processCanvasMutation (browser));
36
36
 
37
- this .canvasObserver = new MutationObserver (() =>
38
- {
39
- this .observeRoot (this .browser .getElement () .children ("X3D") [0]);
40
- });
41
-
42
- this .canvasObserver .observe (this .browser .getElement () [0], {
37
+ this .canvasObserver .observe (browser .getElement () [0], {
43
38
  childList: true,
44
39
  });
45
40
 
46
- const rootElement = this .browser .getElement () .children ("X3D") [0];
41
+ this .processCanvasMutation (browser)
42
+ }
47
43
 
48
- if (rootElement)
49
- this .observeRoot (rootElement);
44
+ processCanvasMutation (browser)
45
+ {
46
+ this .processRootElement (browser, browser .getElement () .children ("X3D") .get (-1));
50
47
  }
51
48
 
52
- async observeRoot (rootElement)
49
+ async processRootElement (browser, rootElement)
53
50
  {
54
51
  try
55
52
  {
@@ -62,21 +59,20 @@ class DOMIntegration
62
59
  {
63
60
  // Display splash screen.
64
61
 
65
- this .browser .setBrowserLoading (true);
66
- this .browser .addLoadingObject (this);
62
+ browser .setBrowserLoading (true);
63
+ browser .addLoadingObject (this);
67
64
 
68
- // Preprocess script nodes if not xhtml.
65
+ // Now also attached node property to each node element.
69
66
 
70
- if (! location .pathname .toLowerCase () .endsWith (".xhtml"))
71
- this .preprocessScriptElements (rootElement);
67
+ const scene = browser .createScene ();
72
68
 
73
- // Now also attached x3d property to each node element.
69
+ this .parser = new XMLParser (scene);
74
70
 
75
- const importedScene = await this .browser .importDocument (rootElement, true);
71
+ this .parser .setInput (rootElement);
76
72
 
77
- this .browser .replaceWorld (importedScene);
73
+ await new Promise (this .parser .parseIntoScene .bind (this .parser));
78
74
 
79
- this .parser = new XMLParser (importedScene);
75
+ browser .replaceWorld (scene);
80
76
 
81
77
  // Create an observer instance.
82
78
 
@@ -101,11 +97,11 @@ class DOMIntegration
101
97
  this .processInlineElements (rootElement);
102
98
  this .addEventDispatchersAll (rootElement);
103
99
 
104
- this .browser .removeLoadingObject (this);
100
+ browser .removeLoadingObject (this);
105
101
  }
106
102
  else
107
103
  {
108
- this .browser .replaceWorld (null);
104
+ browser .replaceWorld (null);
109
105
  }
110
106
  }
111
107
  catch (error)
@@ -114,27 +110,6 @@ class DOMIntegration
114
110
  }
115
111
  }
116
112
 
117
- preprocessScriptElements (rootElement)
118
- {
119
- const scriptElements = rootElement .querySelectorAll ("Script");
120
-
121
- for (const scriptElement of scriptElements)
122
- this .appendScriptElementChildren (scriptElement);
123
- }
124
-
125
- appendScriptElementChildren (scriptElement)
126
- {
127
- const
128
- domParser = new DOMParser (),
129
- scriptDoc = domParser .parseFromString (scriptElement .outerHTML, "application/xml"),
130
- scriptNodes = scriptDoc .children [0] .childNodes;
131
-
132
- scriptElement .textContent = "// Content moved into childNodes.";
133
-
134
- for (const scriptNode of scriptNodes)
135
- scriptElement .appendChild (scriptNode);
136
- }
137
-
138
113
  processMutation (mutation)
139
114
  {
140
115
  switch (mutation .type)
@@ -159,13 +134,15 @@ class DOMIntegration
159
134
 
160
135
  processAttribute (mutation, element)
161
136
  {
137
+ const parser = this .parser;
138
+
162
139
  if ($.data (element, "node"))
163
140
  {
164
141
  const
165
142
  attributeName = mutation .attributeName,
166
143
  attribute = element .attributes .getNamedItem (attributeName);
167
144
 
168
- this .parser .nodeAttribute (attribute, $.data (element, "node"));
145
+ parser .nodeAttribute (attribute, $.data (element, "node"));
169
146
  }
170
147
  else
171
148
  {
@@ -175,11 +152,11 @@ class DOMIntegration
175
152
  parentNode = element .parentNode,
176
153
  node = $.data (parentNode, "node");
177
154
 
178
- this .parser .pushExecutionContext (node .getExecutionContext ());
179
- this .parser .pushParent (node);
180
- this .parser .childElement (element);
181
- this .parser .popParent ();
182
- this .parser .popExecutionContext ();
155
+ parser .pushExecutionContext (node .getExecutionContext ());
156
+ parser .pushParent (node);
157
+ parser .childElement (element);
158
+ parser .popParent ();
159
+ parser .popExecutionContext ();
183
160
  }
184
161
  }
185
162
 
@@ -275,6 +252,8 @@ class DOMIntegration
275
252
  return;
276
253
 
277
254
  node ._loadState .addInterest ("appendInlineChildElement", this, element);
255
+
256
+ this .appendInlineChildElement (element);
278
257
  }
279
258
 
280
259
  appendInlineChildElement (element)
@@ -309,12 +288,36 @@ class DOMIntegration
309
288
 
310
289
  // Add Inline elements, and connect to node events.
311
290
 
312
- this .processInlineElements (element);
313
- this .addEventDispatchersAll (element);
291
+ this .processInlineElements (X3DElement);
292
+ this .addEventDispatchersAll (X3DElement);
314
293
 
315
294
  break;
316
295
  }
317
296
  }
297
+
298
+ switch (node .checkLoadState ())
299
+ {
300
+ case X3DConstants .COMPLETE_STATE:
301
+ {
302
+ const event = new CustomEvent ("load",
303
+ {
304
+ detail: { node: node .valueOf () },
305
+ });
306
+
307
+ element .dispatchEvent (event);
308
+ break;
309
+ }
310
+ case X3DConstants .FAILED_STATE:
311
+ {
312
+ const event = new CustomEvent ("error",
313
+ {
314
+ detail: { node: node .valueOf () },
315
+ });
316
+
317
+ element .dispatchEvent (event);
318
+ break;
319
+ }
320
+ }
318
321
  }
319
322
 
320
323
  addEventDispatchersAll (element)
@@ -356,9 +359,13 @@ class DOMIntegration
356
359
  {
357
360
  const node = $.data (element, "node");
358
361
 
359
- const event = new CustomEvent (field .getName (), {
362
+ if (! node)
363
+ return;
364
+
365
+ const event = new CustomEvent (field .getName (),
366
+ {
360
367
  detail: {
361
- node: node ? SFNodeCache .get (node) : null,
368
+ node: node .valueOf (),
362
369
  value: field .valueOf (),
363
370
  },
364
371
  });
@@ -45,4 +45,4 @@
45
45
  *
46
46
  ******************************************************************************/
47
47
 
48
- export default "8.3.0";
48
+ export default "8.3.2";
@@ -333,7 +333,7 @@ X3DBrowser .prototype = Object .assign (Object .create (X3DBrowserContext .proto
333
333
  if (loadCount .getValue ())
334
334
  return;
335
335
 
336
- this ._loadCount .removeInterest ("checkLoadCount", this);
336
+ loadCount .removeInterest ("checkLoadCount", this);
337
337
  this .initialized () .set (this .getCurrentTime ());
338
338
  this .initialized () .processInterests ();
339
339
  this .callBrowserCallbacks (X3DConstants .INITIALIZED_EVENT);
@@ -341,6 +341,9 @@ Object .assign (X3DBrowserContext,
341
341
  X3D = window [Symbol .for ("X_ITE.X3D")],
342
342
  browser = X3D .getBrowser (canvas);
343
343
 
344
+ if (! browser)
345
+ return;
346
+
344
347
  browserContext .call (browser);
345
348
 
346
349
  if (typeof browserContext .prototype .initialize === "function")
@@ -291,7 +291,7 @@ X3DPrototypeInstance .prototype = Object .assign (Object .create (X3DNode .proto
291
291
  },
292
292
  getInnerNode: function ()
293
293
  {
294
- const rootNodes = this [_body] .getRootNodes () .getValue ();
294
+ const rootNodes = this [_body] .getRootNodes ();
295
295
 
296
296
  if (rootNodes .length)
297
297
  {
@@ -135,18 +135,28 @@ Inline .prototype = Object .assign (Object .create (X3DChildNode .prototype),
135
135
  },
136
136
  unLoadNow: function ()
137
137
  {
138
+ this .abortLoading ();
138
139
  this .setInternalScene (this .getBrowser () .getDefaultScene ());
139
140
  },
140
141
  loadNow: function ()
141
142
  {
142
- new FileLoader (this) .createX3DFromURL (this ._url, null, this .setInternalSceneAsync .bind (this));
143
+ this .abortLoading ();
144
+ this .fileLoader = new FileLoader (this) .createX3DFromURL (this ._url, null, this .setInternalSceneAsync .bind (this));
145
+ },
146
+ abortLoading: function ()
147
+ {
148
+ this .scene ._loadCount .removeInterest ("checkLoadCount", this);
149
+
150
+ if (this .fileLoader)
151
+ this .fileLoader .abort ();
143
152
  },
144
153
  setInternalSceneAsync: function (scene)
145
154
  {
146
155
  if (scene)
147
156
  {
157
+ scene ._loadCount .addInterest ("checkLoadCount", this);
148
158
  this .setInternalScene (scene);
149
- this .setLoadState (X3DConstants .COMPLETE_STATE);
159
+ this .checkLoadCount (scene ._loadCount);
150
160
  }
151
161
  else
152
162
  {
@@ -154,6 +164,15 @@ Inline .prototype = Object .assign (Object .create (X3DChildNode .prototype),
154
164
  this .setLoadState (X3DConstants .FAILED_STATE);
155
165
  }
156
166
  },
167
+ checkLoadCount: function (loadCount)
168
+ {
169
+ if (loadCount .getValue ())
170
+ return;
171
+
172
+ loadCount .removeInterest ("checkLoadCount", this);
173
+
174
+ this .setLoadState (X3DConstants .COMPLETE_STATE);
175
+ },
157
176
  setInternalScene: function (scene)
158
177
  {
159
178
  this .scene .setLive (false);
@@ -68,12 +68,8 @@ const SupportedNodes =
68
68
 
69
69
  // HTML Support
70
70
 
71
- for (const fieldDefinition of Type .prototype [_fieldDefinitions])
71
+ for (const { name, accessType } of Type .prototype [_fieldDefinitions])
72
72
  {
73
- const
74
- name = fieldDefinition .name,
75
- accessType = fieldDefinition .accessType;
76
-
77
73
  if (accessType & X3DConstants .initializeOnly)
78
74
  HTMLSupport .addFieldName (name)
79
75
  }
@@ -374,7 +374,7 @@ X3DScene .prototype = Object .assign (Object .create (X3DExecutionContext .proto
374
374
  stream .string += " ";
375
375
  stream .string += this .getBrowser () .name;
376
376
  stream .string += " ";
377
- stream .string += "v";
377
+ stream .string += "V";
378
378
  stream .string += this .getBrowser () .version;
379
379
  stream .string += "\n";
380
380
  stream .string += "\n";
@@ -472,7 +472,7 @@ X3DScene .prototype = Object .assign (Object .create (X3DExecutionContext .proto
472
472
  stream .string += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
473
473
  stream .string += "<!DOCTYPE X3D PUBLIC \"ISO//Web3D//DTD X3D ";
474
474
  stream .string += LATEST_VERSION;
475
- stream .string += "//EN\" \"https://www.web3d.org/specifications/x3d-";
475
+ stream .string += "//EN\" \"http://www.web3d.org/specifications/x3d-";
476
476
  stream .string += LATEST_VERSION;
477
477
  stream .string += ".dtd\">\n";
478
478
 
@@ -486,92 +486,108 @@ X3DScene .prototype = Object .assign (Object .create (X3DExecutionContext .proto
486
486
  stream .string += LATEST_VERSION;
487
487
  stream .string += "'";
488
488
  stream .string += " ";
489
- stream .string += "xmlns:xsd='https://www.w3.org/2001/XMLSchema-instance'";
489
+ stream .string += "xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance'";
490
490
  stream .string += " ";
491
- stream .string += "xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-";
491
+ stream .string += "xsd:noNamespaceSchemaLocation='http://www.web3d.org/specifications/x3d-";
492
492
  stream .string += LATEST_VERSION;
493
493
  stream .string += ".xsd'>\n";
494
494
 
495
495
  generator .IncIndent ();
496
496
 
497
- stream .string += generator .Indent ();
498
- stream .string += "<head>\n";
497
+ if (this .getComponents () .length ||
498
+ this .getUnits () .some (unit => unit .conversionFactor !== 1) ||
499
+ this .getMetaDatas () .size)
500
+ {
501
+ stream .string += generator .Indent ();
502
+ stream .string += "<head>\n";
499
503
 
500
- generator .IncIndent ();
504
+ generator .IncIndent ();
501
505
 
502
- // <head>
506
+ // <head>
503
507
 
504
- this .getComponents () .toXMLStream (stream);
508
+ this .getComponents () .toXMLStream (stream);
505
509
 
506
- for (const unit of this .getUnits ())
507
- {
508
- if (unit .conversionFactor !== 1)
510
+ for (const unit of this .getUnits ())
509
511
  {
510
- unit .toXMLStream (stream);
512
+ if (unit .conversionFactor !== 1)
513
+ {
514
+ unit .toXMLStream (stream);
511
515
 
512
- stream .string += "\n";
516
+ stream .string += "\n";
517
+ }
513
518
  }
519
+
520
+ this .getMetaDatas () .forEach (function (value, key)
521
+ {
522
+ stream .string += generator .Indent ();
523
+ stream .string += "<meta";
524
+ stream .string += " ";
525
+ stream .string += "name='";
526
+ stream .string += generator .XMLEncode (key);
527
+ stream .string += "'";
528
+ stream .string += " ";
529
+ stream .string += "content='";
530
+ stream .string += generator .XMLEncode (value);
531
+ stream .string += "'";
532
+ stream .string += "/>\n";
533
+ });
534
+
535
+ // </head>
536
+
537
+ generator .DecIndent ();
538
+
539
+ stream .string += generator .Indent ();
540
+ stream .string += "</head>\n";
514
541
  }
515
542
 
516
- this .getMetaDatas () .forEach (function (value, key)
543
+ if (this .getExternProtoDeclarations () .length ||
544
+ this .getProtoDeclarations () .length ||
545
+ this .getRootNodes () .length)
517
546
  {
518
547
  stream .string += generator .Indent ();
519
- stream .string += "<meta";
520
- stream .string += " ";
521
- stream .string += "name='";
522
- stream .string += generator .XMLEncode (key);
523
- stream .string += "'";
524
- stream .string += " ";
525
- stream .string += "content='";
526
- stream .string += generator .XMLEncode (value);
527
- stream .string += "'";
528
- stream .string += "/>\n";
529
- });
530
-
531
- // </head>
532
-
533
- generator .DecIndent ();
548
+ stream .string += "<Scene>\n";
534
549
 
535
- stream .string += generator .Indent ();
536
- stream .string += "</head>\n";
537
- stream .string += generator .Indent ();
538
- stream .string += "<Scene>\n";
550
+ generator .IncIndent ();
539
551
 
540
- generator .IncIndent ();
541
-
542
- // <Scene>
552
+ // <Scene>
543
553
 
544
- const exportedNodes = this .getExportedNodes ();
554
+ const exportedNodes = this .getExportedNodes ();
545
555
 
546
- generator .PushExecutionContext (this);
547
- generator .EnterScope ();
548
- generator .ExportedNodes (exportedNodes);
556
+ generator .PushExecutionContext (this);
557
+ generator .EnterScope ();
558
+ generator .ExportedNodes (exportedNodes);
549
559
 
550
- X3DExecutionContext .prototype .toXMLStream .call (this, stream);
560
+ X3DExecutionContext .prototype .toXMLStream .call (this, stream);
551
561
 
552
- for (const exportedNode of exportedNodes)
553
- {
554
- try
562
+ for (const exportedNode of exportedNodes)
555
563
  {
556
- exportedNode .toXMLStream (stream);
564
+ try
565
+ {
566
+ exportedNode .toXMLStream (stream);
557
567
 
558
- stream .string += "\n";
559
- }
560
- catch (error)
561
- {
562
- console .error (error);
568
+ stream .string += "\n";
569
+ }
570
+ catch (error)
571
+ {
572
+ console .error (error);
573
+ }
563
574
  }
564
- }
565
575
 
566
- generator .LeaveScope ();
567
- generator .PopExecutionContext ();
576
+ generator .LeaveScope ();
577
+ generator .PopExecutionContext ();
568
578
 
569
- // </Scene>
579
+ // </Scene>
570
580
 
571
- generator .DecIndent ();
581
+ generator .DecIndent ();
572
582
 
573
- stream .string += generator .Indent ();
574
- stream .string += "</Scene>\n";
583
+ stream .string += generator .Indent ();
584
+ stream .string += "</Scene>\n";
585
+ }
586
+ else
587
+ {
588
+ stream .string += generator .Indent ();
589
+ stream .string += "<Scene/>\n";
590
+ }
575
591
 
576
592
  generator .DecIndent ();
577
593
 
@@ -54,7 +54,7 @@ function JSONParser (scene)
54
54
  {
55
55
  X3DParser .call (this, scene);
56
56
 
57
- this .namespace = "https://www.web3d.org/specifications/x3d-namespace";
57
+ this .namespace = "http://www.web3d.org/specifications/x3d-namespace";
58
58
  }
59
59
 
60
60
  JSONParser .prototype = Object .assign (Object .create (X3DParser .prototype),