sunrize 1.11.0 → 1.11.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.
- package/package.json +14 -13
- package/src/Application/Application.js +1 -1
- package/src/Application/Dashboard.js +12 -3
- package/src/Application/Document.js +13 -8
- package/src/Application/Hierarchy.js +10 -3
- package/src/Controls/AddPrototypePopover.js +2 -2
- package/src/Controls/AnimationPropertiesPopover.js +12 -1
- package/src/Controls/Dialog.js +5 -2
- package/src/Controls/EditNodePopover.js +1 -1
- package/src/Controls/EditUserDefinedFieldPopover.js +1 -1
- package/src/Editors/AnimationEditor.js +105 -73
- package/src/Editors/AnimationMemberList.js +2 -2
- package/src/Editors/BrowserFrame.js +5 -3
- package/src/Editors/Console.js +253 -17
- package/src/Editors/Library.js +1 -1
- package/src/Editors/MaterialsLibrary.js +5 -3
- package/src/Editors/OutlineEditor.js +342 -224
- package/src/Editors/OutlineView.js +149 -174
- package/src/Editors/Panel.js +55 -1
- package/src/Editors/SceneProperties.js +188 -49
- package/src/Fields/MFStringTextArea.js +13 -11
- package/src/Fields/SFStringInput.js +12 -12
- package/src/Tools/Core/X3DNodeTool.js +1 -1
- package/src/Undo/Editor.js +93 -74
- package/src/assets/X3DUOM.xml +13 -4
- package/src/assets/themes/default.css +274 -67
- package/src/assets/themes/media-template.css +1 -9
- package/src/assets/themes/media.css +1 -9
- package/src/assets/themes/system-colors.css +63 -61
|
@@ -51,9 +51,10 @@ module .exports = new class BrowserFrame extends Dialog
|
|
|
51
51
|
|
|
52
52
|
this .numerator = $("<input></input>")
|
|
53
53
|
.attr ("type", "number")
|
|
54
|
+
.attr ("min", 1)
|
|
54
55
|
.attr ("step", "1")
|
|
55
56
|
.css ("width", "calc((100% - 20px) / 2)")
|
|
56
|
-
.on ("change", () => this .onchange ());
|
|
57
|
+
.on ("change input", () => this .onchange ());
|
|
57
58
|
|
|
58
59
|
const slash = $("<span></span>")
|
|
59
60
|
.css ({ "display": "inline-block", "width": "20px", "text-align": "center" })
|
|
@@ -61,9 +62,10 @@ module .exports = new class BrowserFrame extends Dialog
|
|
|
61
62
|
|
|
62
63
|
this .denominator = $("<input></input>")
|
|
63
64
|
.attr ("type", "number")
|
|
65
|
+
.attr ("min", 1)
|
|
64
66
|
.attr ("step", "1")
|
|
65
67
|
.css ("width", "calc((100% - 20px) / 2)")
|
|
66
|
-
.on ("change", () => this .onchange ());
|
|
68
|
+
.on ("change input", () => this .onchange ());
|
|
67
69
|
|
|
68
70
|
$("<tr></tr>")
|
|
69
71
|
.append ($("<th></th>")
|
|
@@ -91,7 +93,7 @@ module .exports = new class BrowserFrame extends Dialog
|
|
|
91
93
|
|
|
92
94
|
configure ()
|
|
93
95
|
{
|
|
94
|
-
super .configure ({ size: [
|
|
96
|
+
super .configure ({ size: [388, 147] });
|
|
95
97
|
|
|
96
98
|
this .connect (Editor .getWorldInfo (this .browser .currentScene));
|
|
97
99
|
this .updateInputs ();
|
package/src/Editors/Console.js
CHANGED
|
@@ -5,6 +5,7 @@ const
|
|
|
5
5
|
$ = require ("jquery"),
|
|
6
6
|
electron = require ("electron"),
|
|
7
7
|
Interface = require ("../Application/Interface"),
|
|
8
|
+
util = require ("util"),
|
|
8
9
|
_ = require ("../Application/GetText");
|
|
9
10
|
|
|
10
11
|
module .exports = class Console extends Interface
|
|
@@ -31,34 +32,103 @@ module .exports = class Console extends Interface
|
|
|
31
32
|
this .history = [ ];
|
|
32
33
|
this .addMessageCallback = this .addMessage .bind (this);
|
|
33
34
|
|
|
34
|
-
this .console
|
|
35
|
-
this .left
|
|
36
|
-
this .toolbar
|
|
37
|
-
|
|
38
|
-
this .
|
|
35
|
+
this .console = element;
|
|
36
|
+
this .left = $("<div></div>") .addClass ("console-left") .appendTo (this .console);
|
|
37
|
+
this .toolbar = $("<div></div>") .addClass (["toolbar", "vertical-toolbar", "console-toolbar"]) .appendTo (this .console);
|
|
38
|
+
|
|
39
|
+
this .output = $("<div></div>")
|
|
40
|
+
.addClass (["console-output", "output"])
|
|
41
|
+
.attr ("tabindex", 0)
|
|
42
|
+
.on ("keydown", event => this .outputKey (event))
|
|
43
|
+
.appendTo (this .left);
|
|
44
|
+
|
|
45
|
+
this .input = $("<div></div>")
|
|
46
|
+
.addClass ("console-input")
|
|
47
|
+
.appendTo (this .left);
|
|
48
|
+
|
|
49
|
+
// Search Widget
|
|
50
|
+
|
|
51
|
+
this .search = $("<div></div>")
|
|
52
|
+
.addClass ("console-search")
|
|
53
|
+
.appendTo (this .left)
|
|
54
|
+
.hide ();
|
|
55
|
+
|
|
56
|
+
this .search .resizable({
|
|
57
|
+
handles: "w",
|
|
58
|
+
minWidth: 285,
|
|
59
|
+
resize: () => this .config .file .searchWidth = this .search .width (),
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
this .searchInputElements = $("<div></div>")
|
|
63
|
+
.addClass ("console-search-input-elements")
|
|
64
|
+
.appendTo (this .search);
|
|
65
|
+
|
|
66
|
+
this .searchInput = $("<input></input>")
|
|
67
|
+
.attr ("type", "text")
|
|
68
|
+
.attr ("placeholder", _("Find"))
|
|
69
|
+
.addClass ("console-search-input")
|
|
70
|
+
.on ("input", () => this .searchString ())
|
|
71
|
+
.on ("keydown", event => this .searchKey (event))
|
|
72
|
+
.appendTo (this .searchInputElements);
|
|
73
|
+
|
|
74
|
+
this .searchCaseSensitiveButton = $("<div></div>")
|
|
75
|
+
.addClass (["codicon", "codicon-case-sensitive", "console-search-case-sensitive"])
|
|
76
|
+
.on ("click", () => this .searchCaseSensitive (!this .config .file .searchCaseSensitive))
|
|
77
|
+
.appendTo (this .searchInputElements);
|
|
78
|
+
|
|
79
|
+
this .searchStatus = $("<div></div>")
|
|
80
|
+
.addClass ("console-search-status")
|
|
81
|
+
.text ("No results")
|
|
82
|
+
.appendTo (this .search);
|
|
83
|
+
|
|
84
|
+
this .searchPreviousButton = $("<div></div>")
|
|
85
|
+
.addClass (["search-previous", "codicon", "codicon-arrow-up", "disabled"])
|
|
86
|
+
.attr ("tabindex", 0)
|
|
87
|
+
.on ("click", () => this .searchPrevious ())
|
|
88
|
+
.appendTo (this .search);
|
|
89
|
+
|
|
90
|
+
this .searchNextButton = $("<div></div>")
|
|
91
|
+
.addClass (["search-next", "codicon", "codicon-arrow-down", "disabled"])
|
|
92
|
+
.attr ("tabindex", 0)
|
|
93
|
+
.on ("click", () => this .searchNext ())
|
|
94
|
+
.appendTo (this .search);
|
|
95
|
+
|
|
96
|
+
// Toolbar
|
|
97
|
+
|
|
98
|
+
this .searchButton = $("<span></span>")
|
|
99
|
+
.addClass ("material-icons")
|
|
100
|
+
.css ("transform", "scale(1.2)")
|
|
101
|
+
.attr ("title", _("Show search widget."))
|
|
102
|
+
.text ("search")
|
|
103
|
+
.on ("click", () => this .toggleSearch (!this .config .file .search))
|
|
104
|
+
.appendTo (this .toolbar);
|
|
105
|
+
|
|
106
|
+
$("<span></span>") .addClass ("separator") .appendTo (this .toolbar);
|
|
39
107
|
|
|
40
108
|
this .suspendButton = $("<span></span>")
|
|
41
109
|
.addClass ("material-icons")
|
|
42
110
|
.attr ("title", _("Suspend console output."))
|
|
43
|
-
.text ("
|
|
44
|
-
.
|
|
45
|
-
.
|
|
111
|
+
.text ("pause_circle")
|
|
112
|
+
.on ("click", () => this .setSuspendConsole (!this .suspendConsole))
|
|
113
|
+
.appendTo (this .toolbar);
|
|
46
114
|
|
|
47
115
|
this .clearButton = $("<span></span>")
|
|
48
116
|
.addClass ("material-icons")
|
|
49
117
|
.attr ("title", _("Clear console."))
|
|
50
118
|
.text ("delete_forever")
|
|
51
|
-
.
|
|
52
|
-
.
|
|
119
|
+
.on ("click", () => this .clearConsole ())
|
|
120
|
+
.appendTo (this .toolbar);
|
|
53
121
|
|
|
54
122
|
$("<span></span>") .addClass ("separator") .appendTo (this .toolbar);
|
|
55
123
|
|
|
124
|
+
// Input
|
|
125
|
+
|
|
56
126
|
this .textarea = $("<textarea></textarea>")
|
|
57
127
|
.attr ("placeholder", _("Evaluate X3D Script code here, e.g. type `Browser.name`."))
|
|
58
128
|
.attr ("tabindex", 0)
|
|
59
|
-
.appendTo (this .input)
|
|
60
129
|
.on ("keydown", event => this .onkeydown (event))
|
|
61
|
-
.on ("keyup", event => this .onkeyup (event))
|
|
130
|
+
.on ("keyup", event => this .onkeyup (event))
|
|
131
|
+
.appendTo (this .input);
|
|
62
132
|
|
|
63
133
|
if (this .console .attr ("id") !== "console")
|
|
64
134
|
{
|
|
@@ -75,10 +145,21 @@ module .exports = class Console extends Interface
|
|
|
75
145
|
{
|
|
76
146
|
super .configure ();
|
|
77
147
|
|
|
78
|
-
this .config .file .setDefaultValues ({
|
|
148
|
+
this .config .file .setDefaultValues ({
|
|
149
|
+
history: [ ],
|
|
150
|
+
search: false,
|
|
151
|
+
searchWidth: 285,
|
|
152
|
+
searchCaseSensitive: false,
|
|
153
|
+
});
|
|
79
154
|
|
|
80
155
|
this .history = this .config .file .history .slice (-this .HISTORY_MAX);
|
|
81
156
|
this .historyIndex = this .history .length;
|
|
157
|
+
|
|
158
|
+
this .output .scrollTop (this .output .prop ("scrollHeight"));
|
|
159
|
+
|
|
160
|
+
this .search .width (this .config .file .searchWidth);
|
|
161
|
+
this .toggleSearch (this .config .file .search);
|
|
162
|
+
this .searchCaseSensitive ();
|
|
82
163
|
}
|
|
83
164
|
|
|
84
165
|
async set_browser_initialized ()
|
|
@@ -97,6 +178,9 @@ module .exports = class Console extends Interface
|
|
|
97
178
|
// Add strings to exclude here:
|
|
98
179
|
excludes = [
|
|
99
180
|
"The vm module of Node.js is unsupported",
|
|
181
|
+
"Uncaught TypeError: Cannot read properties of null (reading 'removeChild')",
|
|
182
|
+
"aria-hidden",
|
|
183
|
+
"<line>",
|
|
100
184
|
// "Invalid asm.js: Invalid member of stdlib",
|
|
101
185
|
];
|
|
102
186
|
|
|
@@ -107,8 +191,14 @@ module .exports = class Console extends Interface
|
|
|
107
191
|
|
|
108
192
|
const
|
|
109
193
|
classes = [this .logLevels [level] ?? "log", this .logClasses [level]],
|
|
110
|
-
title = sourceId ? `${sourceId}:${line}`: ""
|
|
111
|
-
|
|
194
|
+
title = sourceId ? `${sourceId}:${line}`: "";
|
|
195
|
+
|
|
196
|
+
const text = $(message .split ("\n")
|
|
197
|
+
.map (line => $("<p></p>")
|
|
198
|
+
.addClass (classes)
|
|
199
|
+
.attr ("title", title)
|
|
200
|
+
.text (line)
|
|
201
|
+
.get (0)));
|
|
112
202
|
|
|
113
203
|
if (this .messageTime && performance .now () - this .messageTime > 1000)
|
|
114
204
|
this .output .append ($("<p></p>") .addClass ("splitter"));
|
|
@@ -131,6 +221,8 @@ module .exports = class Console extends Interface
|
|
|
131
221
|
|
|
132
222
|
this .output .append (text);
|
|
133
223
|
this .output .scrollTop (this .output .prop ("scrollHeight"));
|
|
224
|
+
|
|
225
|
+
this .findElements (text, this .currentElement, false);
|
|
134
226
|
}
|
|
135
227
|
|
|
136
228
|
setSuspendConsole (value)
|
|
@@ -157,6 +249,7 @@ module .exports = class Console extends Interface
|
|
|
157
249
|
|
|
158
250
|
this .output .empty ();
|
|
159
251
|
this .addMessage (null, "info", __filename, 0, `Console cleared at ${new Date () .toLocaleTimeString ()}.`);
|
|
252
|
+
this .searchString ();
|
|
160
253
|
}
|
|
161
254
|
|
|
162
255
|
onkeydown (event)
|
|
@@ -243,13 +336,156 @@ module .exports = class Console extends Interface
|
|
|
243
336
|
|
|
244
337
|
try
|
|
245
338
|
{
|
|
246
|
-
console .debug (
|
|
339
|
+
console .debug (this .scriptNode .evaluate (text));
|
|
247
340
|
}
|
|
248
341
|
catch (error)
|
|
249
342
|
{
|
|
250
|
-
console .error (
|
|
343
|
+
console .error (error);
|
|
251
344
|
}
|
|
252
345
|
|
|
253
346
|
this .textarea .val ("");
|
|
254
347
|
}
|
|
348
|
+
|
|
349
|
+
toggleSearch (visible)
|
|
350
|
+
{
|
|
351
|
+
this .config .file .search = visible;
|
|
352
|
+
|
|
353
|
+
if (visible)
|
|
354
|
+
{
|
|
355
|
+
this .searchButton .addClass ("active");
|
|
356
|
+
this .search .show ();
|
|
357
|
+
this .searchInput .trigger ("focus");
|
|
358
|
+
|
|
359
|
+
this .searchString ();
|
|
360
|
+
}
|
|
361
|
+
else
|
|
362
|
+
{
|
|
363
|
+
this .searchButton .removeClass ("active");
|
|
364
|
+
this .search .hide ();
|
|
365
|
+
this .output .find (".selected") .removeClass ("selected");
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
searchString ()
|
|
370
|
+
{
|
|
371
|
+
this .foundElements = [ ];
|
|
372
|
+
|
|
373
|
+
this .findElements (this .output .children (), 0, true);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
findElements (elements, currentElement, scroll)
|
|
377
|
+
{
|
|
378
|
+
if (this .search .is (":hidden"))
|
|
379
|
+
return;
|
|
380
|
+
|
|
381
|
+
const
|
|
382
|
+
toString = this .searchCaseSensitiveButton .hasClass ("active") ? "toString" : "toLowerCase",
|
|
383
|
+
string = this .searchInput .val () [toString] ();
|
|
384
|
+
|
|
385
|
+
if (!string)
|
|
386
|
+
return;
|
|
387
|
+
|
|
388
|
+
this .foundElements = this .foundElements .concat (Array .from (elements, element => $(element))
|
|
389
|
+
.filter (element => element .text () [toString] () .includes (string)));
|
|
390
|
+
|
|
391
|
+
this .updateCurrentElement (currentElement, scroll);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
searchKey (event)
|
|
395
|
+
{
|
|
396
|
+
switch (event .key)
|
|
397
|
+
{
|
|
398
|
+
case "Enter":
|
|
399
|
+
{
|
|
400
|
+
if (!this .foundElements .length)
|
|
401
|
+
break;
|
|
402
|
+
|
|
403
|
+
if (event .shiftKey)
|
|
404
|
+
this .searchPrevious ();
|
|
405
|
+
else
|
|
406
|
+
this .searchNext ();
|
|
407
|
+
|
|
408
|
+
break;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
searchCaseSensitive (value = this .config .file .searchCaseSensitive)
|
|
414
|
+
{
|
|
415
|
+
this .config .file .searchCaseSensitive = value;
|
|
416
|
+
|
|
417
|
+
if (this .config .file .searchCaseSensitive)
|
|
418
|
+
this .searchCaseSensitiveButton .addClass ("active");
|
|
419
|
+
else
|
|
420
|
+
this .searchCaseSensitiveButton .removeClass ("active");
|
|
421
|
+
|
|
422
|
+
this .searchInput .trigger ("focus");
|
|
423
|
+
|
|
424
|
+
this .searchString ();
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
searchPrevious ()
|
|
428
|
+
{
|
|
429
|
+
this .updateCurrentElement (this .currentElement - 1);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
searchNext ()
|
|
433
|
+
{
|
|
434
|
+
this .updateCurrentElement (this .currentElement + 1);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
updateCurrentElement (value, scroll = true)
|
|
438
|
+
{
|
|
439
|
+
if (value < 0)
|
|
440
|
+
value = this .foundElements .length - 1;
|
|
441
|
+
|
|
442
|
+
if (value >= this .foundElements .length)
|
|
443
|
+
value = 0;
|
|
444
|
+
|
|
445
|
+
this .currentElement = value;
|
|
446
|
+
|
|
447
|
+
this .output .find (".selected") .removeClass ("selected");
|
|
448
|
+
|
|
449
|
+
if (this .foundElements .length)
|
|
450
|
+
{
|
|
451
|
+
const element = this .foundElements [this .currentElement];
|
|
452
|
+
|
|
453
|
+
element .addClass ("selected");
|
|
454
|
+
|
|
455
|
+
if (scroll)
|
|
456
|
+
{
|
|
457
|
+
element .get (0) .scrollIntoView ({ block: "center", inline: "start", behavior: "smooth" });
|
|
458
|
+
$(window) .scrollTop (0);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
this .searchStatus .text (util .format (_("%d of %d"), this .currentElement + 1, this .foundElements .length));
|
|
462
|
+
this .searchPreviousButton .removeClass ("disabled");
|
|
463
|
+
this .searchNextButton .removeClass ("disabled");
|
|
464
|
+
}
|
|
465
|
+
else
|
|
466
|
+
{
|
|
467
|
+
this .searchStatus .text (`No results`);
|
|
468
|
+
this .searchPreviousButton .addClass ("disabled");
|
|
469
|
+
this .searchNextButton .addClass ("disabled");
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
outputKey (event)
|
|
474
|
+
{
|
|
475
|
+
switch (event .key)
|
|
476
|
+
{
|
|
477
|
+
case "f":
|
|
478
|
+
{
|
|
479
|
+
if (event .ctrlKey || event .metaKey)
|
|
480
|
+
{
|
|
481
|
+
this .searchInput .val (window .getSelection () .toString ());
|
|
482
|
+
this .searchInput .trigger ("select");
|
|
483
|
+
|
|
484
|
+
this .toggleSearch (true);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
break;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
255
491
|
};
|
package/src/Editors/Library.js
CHANGED
|
@@ -26,7 +26,7 @@ module .exports = class Materials extends LibraryPane
|
|
|
26
26
|
|
|
27
27
|
this .#list = $("<ul></ul>")
|
|
28
28
|
.appendTo (this .output)
|
|
29
|
-
.addClass ("library-list");
|
|
29
|
+
.addClass (["library-list", "materials"]);
|
|
30
30
|
|
|
31
31
|
const
|
|
32
32
|
canvas = $("<x3d-canvas preserveDrawingBuffer='true' xrSessionMode='NONE'></x3d-canvas>"),
|
|
@@ -51,9 +51,11 @@ module .exports = class Materials extends LibraryPane
|
|
|
51
51
|
|
|
52
52
|
nodes .push ($("<li></li>")
|
|
53
53
|
.addClass (["node", "icon"])
|
|
54
|
-
.text (`${group .getNodeName ()} ${c + 1}`)
|
|
55
54
|
.attr ("group", g)
|
|
56
55
|
.attr ("child", c)
|
|
56
|
+
.append ($("<span></span>")
|
|
57
|
+
.addClass ("text")
|
|
58
|
+
.text (`${group .getNodeName ()} ${c + 1}`))
|
|
57
59
|
.appendTo (this .#list)
|
|
58
60
|
.on ("dblclick", () => this .importX3D (material .getNodeName (), material .toXMLString ())));
|
|
59
61
|
}
|
|
@@ -65,7 +67,7 @@ module .exports = class Materials extends LibraryPane
|
|
|
65
67
|
.css ({ "position": "absolute", "visibility": "hidden" })
|
|
66
68
|
.prependTo ($("body"));
|
|
67
69
|
|
|
68
|
-
await browser .resize (
|
|
70
|
+
await browser .resize (256, 256);
|
|
69
71
|
await browser .replaceWorld (scene);
|
|
70
72
|
|
|
71
73
|
for (const element of Array .from (this .output .find (".node"), e => $(e)))
|