janusweb 1.5.33 → 1.5.34

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 (46) hide show
  1. package/CHANGELOG +39 -0
  2. package/media/assets/webui/apps/avatar/avatar.js +2 -1
  3. package/media/assets/webui/apps/comms/voip.js +2 -4
  4. package/media/assets/webui/apps/editor/codemirror/addon/hint/javascript-hint.js +162 -0
  5. package/media/assets/webui/apps/editor/codemirror/addon/hint/show-hint.css +36 -0
  6. package/media/assets/webui/apps/editor/codemirror/addon/hint/show-hint.js +529 -0
  7. package/media/assets/webui/apps/editor/codemirror/addon/hint/xml-hint.js +140 -0
  8. package/media/assets/webui/apps/editor/codemirror/keymap/vim.js +5734 -0
  9. package/media/assets/webui/apps/editor/codemirror/lib/codemirror.css +350 -0
  10. package/media/assets/webui/apps/editor/codemirror/lib/codemirror.js +9800 -0
  11. package/media/assets/webui/apps/editor/codemirror/lib/jmldark.css +33 -0
  12. package/media/assets/webui/apps/editor/codemirror/mode/css/css.js +864 -0
  13. package/media/assets/webui/apps/editor/codemirror/mode/htmlmixed/htmlmixed.js +153 -0
  14. package/media/assets/webui/apps/editor/codemirror/mode/javascript/javascript.js +942 -0
  15. package/media/assets/webui/apps/editor/codemirror/mode/xml/xml.js +413 -0
  16. package/media/assets/webui/apps/editor/editor.css +3 -0
  17. package/media/assets/webui/apps/editor/editor.js +407 -9
  18. package/media/assets/webui/apps/editor/editor.json +6 -3
  19. package/media/assets/webui/apps/inventory/inventory.js +1 -1
  20. package/media/assets/webui/apps/locomotion/teleporter.js +1 -1
  21. package/media/assets/webui/apps/navigation/navigation.js +12 -12
  22. package/media/assets/webui/apps/vfs/browserfs/browserfs.js +8 -0
  23. package/media/assets/webui/apps/vfs/vfs.css +52 -0
  24. package/media/assets/webui/apps/vfs/vfs.js +452 -0
  25. package/media/assets/webui/apps/vfs/vfs.json +10 -0
  26. package/media/assets/webui/default.json +2 -1
  27. package/media/assets/webui/themes/default.css +29 -2
  28. package/package.json +2 -9
  29. package/scripts/client.js +64 -44
  30. package/scripts/elements/linesegments.js +5 -2
  31. package/scripts/janusbase.js +21 -9
  32. package/scripts/janusghost.js +0 -1
  33. package/scripts/janusparagraph.js +5 -3
  34. package/scripts/janusparticle.js +11 -12
  35. package/scripts/janusplayer.js +2 -2
  36. package/scripts/janusweb.js +21 -2
  37. package/scripts/janusxrplayer.js +3 -0
  38. package/scripts/multiplayermanager.js +3 -3
  39. package/scripts/object.js +159 -82
  40. package/scripts/portal.js +2 -3
  41. package/scripts/room.js +86 -44
  42. package/scripts/sound.js +0 -1
  43. package/scripts/text.js +10 -2
  44. package/scripts/translators/janusvfs.js +20 -0
  45. package/scripts/video.js +1 -1
  46. package/scripts/websurface.js +11 -2
package/scripts/room.js CHANGED
@@ -3,7 +3,7 @@ elation.require([
3
3
  'engine.things.generic', 'engine.things.label', 'engine.things.skybox',
4
4
  'janusweb.object', 'janusweb.portal', 'janusweb.image', 'janusweb.video', 'janusweb.text', 'janusweb.janusparagraph',
5
5
  'janusweb.sound', 'janusweb.januslight', 'janusweb.janusparticle', 'janusweb.janusghost',
6
- 'janusweb.translators.bookmarks', 'janusweb.translators.reddit', 'janusweb.translators.error', 'janusweb.translators.blank', 'janusweb.translators.default', 'janusweb.translators.dat'
6
+ 'janusweb.translators.bookmarks', 'janusweb.translators.reddit', 'janusweb.translators.error', 'janusweb.translators.blank', 'janusweb.translators.default', 'janusweb.translators.dat', 'janusweb.translators.janusvfs'
7
7
  ], function() {
8
8
  elation.component.add('engine.things.janusroom', function() {
9
9
  this.postinit = function() {
@@ -27,13 +27,13 @@ elation.require([
27
27
  'baseurl': { type: 'string', default: false },
28
28
  'source': { type: 'string' },
29
29
  'skybox': { type: 'boolean', default: true, set: this.toggleSkybox },
30
- 'skybox_equi': { type: 'string' },
31
- 'skybox_left': { type: 'string' },
32
- 'skybox_right': { type: 'string' },
33
- 'skybox_up': { type: 'string' },
34
- 'skybox_down': { type: 'string' },
35
- 'skybox_front': { type: 'string' },
36
- 'skybox_back': { type: 'string' },
30
+ 'skybox_equi': { type: 'string', set: this.setSkybox },
31
+ 'skybox_left_id': { type: 'string', set: this.setSkybox },
32
+ 'skybox_right_id': { type: 'string', set: this.setSkybox },
33
+ 'skybox_up_id': { type: 'string', set: this.setSkybox },
34
+ 'skybox_down_id': { type: 'string', set: this.setSkybox },
35
+ 'skybox_front_id': { type: 'string', set: this.setSkybox },
36
+ 'skybox_back_id': { type: 'string', set: this.setSkybox },
37
37
  'cubemap_irradiance_id': { type: 'string' },
38
38
  'cubemap_radiance_id': { type: 'string' },
39
39
  'fog': { type: 'boolean', default: false, set: this.setFog },
@@ -76,12 +76,13 @@ elation.require([
76
76
  'className': { type: 'string', default: '', set: this.setClassName },
77
77
  'gazetime': { type: 'float', default: 1000 },
78
78
  'selfavatar': { type: 'boolean', default: false },
79
- 'requirescripts': { type: 'string' },
79
+ 'requires': { type: 'string' },
80
80
  'onload': { type: 'string' },
81
81
  'sync': { type: 'boolean', default: false },
82
82
  'pointerlock': { type: 'boolean', default: true },
83
83
  });
84
84
  this.translators = {
85
+ '^janus-vfs:': elation.janusweb.translators.janusvfs({janus: this.janus}),
85
86
  '^about:blank$': elation.janusweb.translators.blank({janus: this.janus}),
86
87
  '^bookmarks$': elation.janusweb.translators.bookmarks({janus: this.janus}),
87
88
  '^dat:': elation.janusweb.translators.dat({janus: this.janus}),
@@ -296,31 +297,32 @@ elation.require([
296
297
  }
297
298
  if (this.skyboxtexture) {
298
299
  this.skyboxobj.setTexture(this.skyboxtexture);
299
- return;
300
+ //return;
300
301
  }
301
302
 
302
- var hasSkybox = (this.skybox_left || this.skybox_right || this.skybox_top || this.skybox_bottom || this.skybox_left || this.skybox_right) != undefined;
303
+ var hasSkybox = (this.skybox_left_id || this.skybox_right_id || this.skybox_top_id || this.skybox_bottom_id || this.skybox_left_id || this.skybox_right_id) != undefined;
304
+ var assets = [];
303
305
  if (this.skybox_equi) {
304
306
  let equi = this.getAsset('image', this.skybox_equi);
305
- var assets = [];
306
307
  elation.events.add(equi, 'asset_load', ev => {
307
308
  this.skyboxtexture = ev.target._texture;
308
309
  if (this.janus.currentroom === this) {
309
310
  this.skyboxobj.setTexture(this.skyboxtexture);
310
311
  }
311
312
  });
313
+ equi.getInstance();
312
314
  } else if (hasSkybox) {
313
- var assets = [
314
- this.getAsset('image', this.skybox_right || 'black'),
315
- this.getAsset('image', this.skybox_left || 'black'),
316
- this.getAsset('image', this.skybox_up || 'black'),
317
- this.getAsset('image', this.skybox_down || 'black'),
318
- this.getAsset('image', this.skybox_front || 'black'),
319
- this.getAsset('image', this.skybox_back || 'black')
315
+ assets = [
316
+ this.getAsset('image', this.skybox_right_id || 'black'),
317
+ this.getAsset('image', this.skybox_left_id || 'black'),
318
+ this.getAsset('image', this.skybox_up_id || 'black'),
319
+ this.getAsset('image', this.skybox_down_id || 'black'),
320
+ this.getAsset('image', this.skybox_front_id || 'black'),
321
+ this.getAsset('image', this.skybox_back_id || 'black')
320
322
  ];
321
323
  } else {
322
324
  var skyboxname = 'dayskybox';
323
- var assets = [
325
+ assets = [
324
326
  this.getAsset('image', skyboxname + '_right'),
325
327
  this.getAsset('image', skyboxname + '_left'),
326
328
  this.getAsset('image', skyboxname + '_up'),
@@ -705,12 +707,12 @@ elation.require([
705
707
  this.fullsource = data;
706
708
  var titlere = /<title>([\s\S]*?)<\/title>/mi;
707
709
  var re = /<fireboxroom>[\s\S]*?<\/fireboxroom>/mi;
708
- var re2 = /<janus-viewer>[\s\S]*?<\/janus-viewer>/mi;
710
+ var re2 = /<janus-viewer[^>]*>[\s\S]*?<\/janus-viewer>/mi;
709
711
  var mtitle = data.match(titlere);
710
712
  var parsed = {
711
713
  title: 'Untitled Room',
712
714
  source: false
713
- }
715
+ };
714
716
  if (mtitle) {
715
717
  parsed.title = mtitle[1];
716
718
  this.setTitle(mtitle[1]);
@@ -728,6 +730,40 @@ elation.require([
728
730
  }
729
731
  return parsed;
730
732
  }
733
+ this.updateSource = function(source) {
734
+ var datapath = elation.config.get('janusweb.datapath', '/media/janusweb');
735
+ try {
736
+ var roomdata = this.janus.parser.parse(source, this.baseurl, datapath);
737
+ } catch (e) {
738
+ }
739
+ console.log('updated roomdata!', roomdata);
740
+ if (roomdata && roomdata.room) {
741
+ for (let k in roomdata.room) {
742
+ let val = roomdata.room[k];
743
+ if (val !== null && room[k] != val) {
744
+ console.log('update room value', k, room[k], val);
745
+ room[k] = val;
746
+ }
747
+ }
748
+ if (roomdata.object) {
749
+ for (let i = 0; i < roomdata.object.length; i++) {
750
+ let objdata = roomdata.object[i];
751
+ let roomobj = room.objects[objdata.js_id];
752
+ if (roomobj) {
753
+ for (let k in objdata) {
754
+ let val = objdata[k];
755
+ if (roomobj[k] != objdata[k] && val !== null) {
756
+ roomobj[k] = val;
757
+ }
758
+ }
759
+ } else {
760
+ objdata.persist = true;
761
+ this.createObject('object', objdata);
762
+ }
763
+ }
764
+ }
765
+ }
766
+ }
731
767
 
732
768
  this.loadRoomAssets = function(roomdata) {
733
769
  if (roomdata && roomdata.assets && roomdata.assets.assetlist && roomdata.assets.assetlist.length > 0) {
@@ -868,12 +904,12 @@ elation.require([
868
904
 
869
905
  if (typeof room.skybox != 'undefined') this.properties.skybox = room.skybox;
870
906
  if (room.skybox_equi) this.properties.skybox_equi = room.skybox_equi;
871
- if (room.skybox_left_id) this.properties.skybox_left = room.skybox_left_id;
872
- if (room.skybox_right_id) this.properties.skybox_right = room.skybox_right_id;
873
- if (room.skybox_up_id) this.properties.skybox_up = room.skybox_up_id;
874
- if (room.skybox_down_id) this.properties.skybox_down = room.skybox_down_id;
875
- if (room.skybox_front_id) this.properties.skybox_front = room.skybox_front_id;
876
- if (room.skybox_back_id) this.properties.skybox_back = room.skybox_back_id;
907
+ if (room.skybox_left_id) this.properties.skybox_left_id = room.skybox_left_id;
908
+ if (room.skybox_right_id) this.properties.skybox_right_id = room.skybox_right_id;
909
+ if (room.skybox_up_id) this.properties.skybox_up_id = room.skybox_up_id;
910
+ if (room.skybox_down_id) this.properties.skybox_down_id = room.skybox_down_id;
911
+ if (room.skybox_front_id) this.properties.skybox_front_id = room.skybox_front_id;
912
+ if (room.skybox_back_id) this.properties.skybox_back_id = room.skybox_back_id;
877
913
 
878
914
  if (room.cubemap_radiance_id) this.properties.cubemap_radiance_id = room.cubemap_radiance_id;
879
915
  if (room.cubemap_irradiance_id) this.properties.cubemap_irradiance_id = room.cubemap_irradiance_id;
@@ -935,10 +971,12 @@ elation.require([
935
971
  this.pendingScriptMap = {};
936
972
  this.loadScripts(assets.scripts);
937
973
  }
938
- if (room.require) {
974
+
975
+ let requires = room.requires || room.require;
976
+ if (requires) {
939
977
  let roomproxy = this.getProxyObject();
940
- roomproxy.require(room.require);
941
- this.requirescripts = room.require;
978
+ roomproxy.require(requires);
979
+ this.requires = requires;
942
980
  }
943
981
  }
944
982
  this.applyingEdits = false;
@@ -1287,7 +1325,7 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
1287
1325
  objectargs.ghost_id = args.id;
1288
1326
  //objectargs.ghost_scale = args.scale;
1289
1327
  //objectargs.scale = new THREE.Vector3(1,1,1);
1290
- objectargs.orientation = new THREE.Quaternion()
1328
+ objectargs.orientation = new THREE.Quaternion();
1291
1329
  break;
1292
1330
  }
1293
1331
  //console.log('spawn it', realtype, args, objectargs);
@@ -1406,6 +1444,7 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
1406
1444
  hasalpha: args.hasalpha,
1407
1445
  maxsize: args.maxsize,
1408
1446
  preload: args.preload,
1447
+ proxy: args.proxy,
1409
1448
  baseurl: this.baseurl
1410
1449
  };
1411
1450
  assetlist.push(assetargs);
@@ -1446,6 +1485,7 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
1446
1485
  format: args.format,
1447
1486
  hls: args.hls,
1448
1487
  preload: args.preload,
1488
+ proxy: args.proxy,
1449
1489
  baseurl: this.baseurl
1450
1490
  });
1451
1491
  } else if (args.video) {
@@ -1474,6 +1514,7 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
1474
1514
  src: src,
1475
1515
  buffer: args.buffer,
1476
1516
  rate: args.rate,
1517
+ proxy: args.proxy,
1477
1518
  baseurl: this.baseurl
1478
1519
  });
1479
1520
  } else if (type == 'websurface') {
@@ -1525,7 +1566,8 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
1525
1566
  tex0: args.tex || args.tex0 || srcparts[1],
1526
1567
  tex1: args.tex1 || srcparts[2],
1527
1568
  tex2: args.tex2 || srcparts[3],
1528
- tex3: args.tex3 || srcparts[4]
1569
+ tex3: args.tex3 || srcparts[4],
1570
+ proxy: args.proxy,
1529
1571
  });
1530
1572
  } else if (type == 'ghost') {
1531
1573
  var src = (args.src.match(/^file:/) ? args.src.replace(/^file:/, datapath) : args.src);
@@ -2008,7 +2050,7 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
2008
2050
  locked: ['property', 'locked'],
2009
2051
  private: ['property', 'private'],
2010
2052
  selfavatar: ['property', 'selfavatar'],
2011
- requirescripts:['property', 'requirescripts'],
2053
+ requires: ['property', 'requires'],
2012
2054
  pos: ['property', 'spawnpoint.position'],
2013
2055
  sync: ['property', 'sync'],
2014
2056
  js_id: ['property', 'roomid'],
@@ -2016,12 +2058,12 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
2016
2058
 
2017
2059
  skybox: ['property', 'skybox'],
2018
2060
  skybox_equi: ['property', 'skybox_equi'],
2019
- skybox_left_id: ['property', 'skybox_left'],
2020
- skybox_right_id:['property', 'skybox_right'],
2021
- skybox_up_id: ['property', 'skybox_up'],
2022
- skybox_down_id: ['property', 'skybox_down'],
2023
- skybox_front_id:['property', 'skybox_front'],
2024
- skybox_back_id: ['property', 'skybox_back'],
2061
+ skybox_left_id: ['property', 'skybox_left_id'],
2062
+ skybox_right_id:['property', 'skybox_right_id'],
2063
+ skybox_up_id: ['property', 'skybox_up_id'],
2064
+ skybox_down_id: ['property', 'skybox_down_id'],
2065
+ skybox_front_id:['property', 'skybox_front_id'],
2066
+ skybox_back_id: ['property', 'skybox_back_id'],
2025
2067
 
2026
2068
  pendingScripts: ['property', 'pendingScripts'],
2027
2069
  pendingCustomElements: ['property', 'pendingCustomElements'],
@@ -2112,7 +2154,7 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
2112
2154
  var real = this.getObjectFromProxy(change);
2113
2155
  if (real) {
2114
2156
  var xmltype = typemap[real.type] || 'Object';
2115
- xmlnode = xmldoc.createElement(xmltype);
2157
+ let xmlnode = xmldoc.createElement(xmltype);
2116
2158
 
2117
2159
  var attrs = Object.keys(change);
2118
2160
  for (var i = 0; i < attrs.length; i++) {
@@ -2326,7 +2368,7 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
2326
2368
  val = elation.utils.arrayget(this.properties, def[1]);
2327
2369
 
2328
2370
  if (k == 'url' || !propdef) continue;
2329
- if (k == 'requirescripts') k = 'require';
2371
+ if (k == 'requires') k = 'require';
2330
2372
 
2331
2373
  let defaultval = propdef.default;
2332
2374
  if (val instanceof THREE.Vector2) {
@@ -2611,7 +2653,7 @@ console.log('dispatch to parent', event, this, event.target);
2611
2653
  if (!url) url = this.url;
2612
2654
  if (url[0] == '/') {
2613
2655
  url = this.baseurl.replace(/^(https?:\/\/[^\/]+)\/.*$/, '$1') + url;
2614
- } else if (!url.match(/https?:\/\//i)) {
2656
+ } else if (!url.match(/:\/\//i)) {
2615
2657
  url = this.baseurl + url;
2616
2658
  }
2617
2659
  return url;
@@ -2692,7 +2734,7 @@ console.log('dispatch to parent', event, this, event.target);
2692
2734
  this.fadeAudioOut = function(time=4, value=0) {
2693
2735
  if (this.audionodes) {
2694
2736
  let gain = this.audionodes.gain,
2695
- ctx = this.audionodes.listener.context;
2737
+ ctx = this.audionodes.listener.context,
2696
2738
  currentgain = gain.gain.value;
2697
2739
 
2698
2740
  gain.gain.cancelScheduledValues(ctx.currentTime);
package/scripts/sound.js CHANGED
@@ -223,7 +223,6 @@ elation.require(['janusweb.janusbase'], function() {
223
223
  playing: [ 'property', 'playing', 'sound.isPlaying'],
224
224
  pitch: [ 'property', 'pitch'],
225
225
  auto_play: [ 'property', 'auto_play'],
226
- playing: [ 'property', 'playing'],
227
226
  play: [ 'function', 'play'],
228
227
  pause: [ 'function', 'pause'],
229
228
  stop: [ 'function', 'stop'],
package/scripts/text.js CHANGED
@@ -26,6 +26,7 @@ elation.require(['engine.things.label'], function() {
26
26
  'roughness': { type: 'float', default: null, min: 0, max: 1, set: this.updateMaterial, comment: 'Material roughness value' },
27
27
  'metalness': { type: 'float', default: null, set: this.updateMaterial, comment: 'Material metalness value' },
28
28
  'envmap_id': { type: 'string', set: this.updateMaterial, comment: 'Environment map texture ID (overrides skybox reflections)' },
29
+ 'wireframe': { type: 'boolean', default: false, set: this.updateMaterial, comment: 'Wireframe rendering' },
29
30
  });
30
31
  this.emptygeometry = new THREE.BufferGeometry();
31
32
  elation.events.add(this.engine, 'engine_frame', elation.bind(this, this.handleFrameUpdates));
@@ -91,7 +92,8 @@ elation.require(['engine.things.label'], function() {
91
92
  emissive: this.properties.emissive,
92
93
  flatShading: false,
93
94
  depthTest: this.properties.depthTest,
94
- reflectivity: .5
95
+ reflectivity: .5,
96
+ wireframe: this.wireframe,
95
97
  };
96
98
  if (this.room.pbr) {
97
99
  matargs.roughness = this.roughness;
@@ -219,7 +221,6 @@ elation.require(['engine.things.label'], function() {
219
221
  text: [ 'property', 'text'],
220
222
  col: [ 'property', 'color'],
221
223
  emissive: [ 'property', 'emissive'],
222
- font: [ 'property', 'font'],
223
224
  bevel: [ 'property', 'bevel'],
224
225
  bevel_thickness: [ 'property', 'bevel_thickness'],
225
226
  bevel_size: [ 'property', 'bevel_size'],
@@ -228,6 +229,13 @@ elation.require(['engine.things.label'], function() {
228
229
  roughness: [ 'property', 'roughness'],
229
230
  metalness: [ 'property', 'metalness'],
230
231
  envmap_id: [ 'property', 'envmap_id'],
232
+ font: [ 'property', 'font'],
233
+ font_size: [ 'property', 'font_size'],
234
+ font_scale: [ 'property', 'font_scale'],
235
+ align: [ 'property', 'align'],
236
+ verticalalign: [ 'property', 'verticalalign'],
237
+ zalign: [ 'property', 'zalign'],
238
+ wireframe: [ 'property', 'wireframe'],
231
239
  };
232
240
  }
233
241
  return this._proxyobject;
@@ -0,0 +1,20 @@
1
+ elation.require([], function() {
2
+ elation.component.add('janusweb.translators.janusvfs', function() {
3
+ this.exec = function(args) {
4
+ return new Promise(async function(resolve, reject) {
5
+ setTimeout(async () => {
6
+ elation.engine.assetdownloader.fetchURL(args.url).then((ev) => {
7
+ let decoder = new TextDecoder('utf-8');
8
+ let src = decoder.decode(ev.target.data);
9
+ elation.events.fire({element: room._target, type: 'room_load_processing'});
10
+ room.loadFromSource(src);
11
+ resolve({room: { }, source: src});
12
+ }).catch((err) => {
13
+ console.log('oh no', err);
14
+ reject();
15
+ });
16
+ }, 1000);
17
+ });
18
+ }
19
+ });
20
+ });
package/scripts/video.js CHANGED
@@ -32,7 +32,7 @@ elation.require(['janusweb.janusbase'], function() {
32
32
  if (camera.name) {
33
33
  texture.setEye(camera.name);
34
34
  }
35
- }
35
+ };
36
36
  }
37
37
  return mesh;
38
38
  } else {
@@ -5,6 +5,7 @@ elation.require(['engine.things.generic'], function() {
5
5
  this.defineProperties({
6
6
  websurface_id: { type: 'string' },
7
7
  image_id: { type: 'string' },
8
+ url: { type: 'string', set: this.updateURL },
8
9
  color: { type: 'color', default: 0xffffff },
9
10
  hovercolor: { type: 'color', default: 0x009900 },
10
11
  activecolor: { type: 'color', default: 0x00ff00 }
@@ -27,6 +28,8 @@ elation.require(['engine.things.generic'], function() {
27
28
  // and hope that most sites are running both.
28
29
 
29
30
  this.url = url.replace(/^http:/, 'https:');
31
+ } else {
32
+ this.url = this.websurface_id;
30
33
  }
31
34
 
32
35
  // FIXME - binding of member functions should happen at object creation
@@ -78,7 +81,9 @@ elation.require(['engine.things.generic'], function() {
78
81
  }
79
82
  this.createObjectDOM = function() {
80
83
  var websurface = this.room.websurfaces[this.properties.websurface_id];
81
- if (websurface) {
84
+ if (!websurface) {
85
+ websurface = {};
86
+ }
82
87
  var width = websurface.width || 1024,
83
88
  height = websurface.height || 768,
84
89
  border = elation.utils.any(websurface.border, true);
@@ -103,7 +108,6 @@ elation.require(['engine.things.generic'], function() {
103
108
 
104
109
  this.iframe = iframe;
105
110
  this.domobj = obj;
106
- }
107
111
  }
108
112
  this.activate = function() {
109
113
  if (!this.active) {
@@ -167,6 +171,11 @@ setTimeout(elation.bind(this, function() {
167
171
  this.objects['3d'].remove(this.domobj);
168
172
  }
169
173
  }
174
+ this.updateURL = function() {
175
+ if (this.iframe) {
176
+ this.iframe.src = this.url;
177
+ }
178
+ }
170
179
  }, elation.engine.things.janusbase);
171
180
  });
172
181