"use strict"; /* The MIT License (MIT) Copyright (c) 2014-2018 Nikolai Suslov and the Krestianstvo.org project contributors. (https://github.com/NikolaySuslov/livecodingspace/blob/master/LICENSE.md) Virtual World Framework Apache 2.0 license (https://github.com/NikolaySuslov/livecodingspace/blob/master/licenses/LICENSE_VWF.md) */ // /// vwf/view/editor creates a view interface for editor functions. /// /// @module vwf/view/editor /// @requires version /// @requires vwf/view /// @requires vwf/utility define([ "module", "version", "vwf/view", "vwf/utility", "vwf/view/lib/colorpicker/colorpicker.min" ], function (module, version, view, utility, colorpicker) { var self; return view.load(module, { // == Module Definition ==================================================================== initialize: function () { self = this; this.ace = window.ace; this.widgets = window._cellWidgets; //widgets; this.lang = _LangManager.language; this.helpers = _app.helpers; this.nodes = {}; this.scenes = {}; this.allScripts = {}; //$(document.head).append(''); document.querySelector('head').innerHTML += ''; document.querySelector('head').innerHTML += ''; //document.querySelector('head').innerHTML += ''); ["drawer", "toolbar", "sideBar", "propWindow", "clientsWindow", "codeEditorWindow", "propEditorWindow", "viewSceneProps"].forEach(item => { let el = document.createElement("div"); el.setAttribute("id", item); document.body.appendChild(el); } ); _LCSDB.on('auth', function (ack) { if (ack.sea.pub) { _app.helpers.checkUserCollision(); console.log(_LCSDB.user().is); let loadSave = document.querySelector('#loadSaveSettings'); if(loadSave){ } //self.authGUI(); } }); this.avatarCardDef = function (src, desc, onclickfunc) { return { $cell: true, $type: "div", class: "mdc-card avatar-card", $init: function () { this.style.backgroundImage = 'linear-gradient(0deg, rgba(0, 0, 0, 0.0), rgba(0, 0, 0, 0.0) ), url(' + src + ')' }, onclick: onclickfunc, $components: [ { $type: "section", class: "mdc-card__primary", style: "padding: 1rem;", $components: [ { $type: "h1", class: "mdc-card__title mdc-typography--title", $text: desc.subtitle }, { $type: "h2", class: "mdc-typography--subheading1", $text: desc.title } ] }, { $type: "section", class: "mdc-card__actions", $components: [ { $type: "button", class: "mdc-button mdc-button--compact mdc-card__action", //$text: "Use it", onclick: onclickfunc } ] } ] } } let createSettings = { $cell: true, $type: "div", class: "propGrid max-width mdc-layout-grid mdc-layout-grid--align-left", $components: [ self.widgets.listTitle({text: 'Primitives'}), { $type: "div", class: "mdc-layout-grid__inner", $components: make3DPrimitiveList() }, self.widgets.listTitle({text: 'Lights'}), { $type: "div", class: "mdc-layout-grid__inner", $components: makeLightsList() }, self.widgets.listTitle({text: 'Objects'}), { $type: "div", class: "mdc-layout-grid__inner", $components: [ self.widgets.gridListItem({ imgSrc: "/vwf/view/lib/images/ui/icons/camera.png", title: 'Camera', imgSize: '30px', styleClass: "", onclickfunc: function () { let avatarID = 'avatar-' + vwf.moniker_; //let cubeName = self.GUID(); vwf_view.kernel.callMethod(vwf.application(), "createCamera", [null, null, avatarID]) //let cubeName = self.GUID(); // vwf_view.kernel.callMethod(vwf.application(), "createFloor") } }), self.widgets.gridListItem({ imgSrc: "/vwf/view/lib/images/ui/icons/camera_offset.png", title: 'Camera with view offset', imgSize: '30px', styleClass: "", onclickfunc: function () { let avatarID = 'avatar-' + vwf.moniker_; //let cubeName = self.GUID(); vwf_view.kernel.callMethod(vwf.application(), "createCameraWithOffset", [null, null, avatarID]) //let cubeName = self.GUID(); // vwf_view.kernel.callMethod(vwf.application(), "createFloor") } }), self.widgets.gridListItem({ imgSrc: "/vwf/view/lib/images/ui/icons/mirror.png", title: 'Mirror', imgSize: '30px', styleClass: "", onclickfunc: function () { let avatarID = 'avatar-' + vwf.moniker_; //let cubeName = self.GUID(); vwf_view.kernel.callMethod(vwf.application(), "createMirror", [null, null, avatarID]) //let cubeName = self.GUID(); // vwf_view.kernel.callMethod(vwf.application(), "createFloor") } }), ] }, self.widgets.listTitle({text: 'Assets'}), { $type: "div", class: "mdc-layout-grid__inner", $components: [ { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ self.widgets.inputTextFieldOutlined({ "id": 'assetsrc', "fieldStyle": 'width: 400px', "label": "Enter URL to asset source", "value": '', "change": function (e) { console.log(this.value) } }) ] } ] }, { $type: "div", class: "mdc-layout-grid__inner", $components: [ { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ self.widgets.buttonSimple( { label: "Image", onclick: function (e) { let srcEl = document.querySelector('#assetsrc'); let avatarID = 'avatar-' + vwf.moniker_; vwf_view.kernel.callMethod(vwf.application(), "createImage", [srcEl.value, null, null, avatarID]) } } ), self.widgets.buttonSimple( { label: "Sound", onclick: function (e) { let srcEl = document.querySelector('#assetsrc'); let avatarID = 'avatar-' + vwf.moniker_; vwf_view.kernel.callMethod(vwf.application(), "createAudio", [srcEl.value, null, null, avatarID]) } } ), self.widgets.buttonSimple( { label: "Video", onclick: function (e) { let srcEl = document.querySelector('#assetsrc'); let avatarID = 'avatar-' + vwf.moniker_; vwf_view.kernel.callMethod(vwf.application(), "createVideo", [srcEl.value, null, null, avatarID]) } } ), self.widgets.buttonSimple( { label: "GLTF", onclick: function (e) { let srcEl = document.querySelector('#assetsrc'); let avatarID = 'avatar-' + vwf.moniker_; if (srcEl.value.includes('.gltf')) vwf_view.kernel.callMethod(vwf.application(), "createModel", ['GLTF', srcEl.value, avatarID]) } } ), self.widgets.buttonSimple( { label: "DAE", onclick: function (e) { let srcEl = document.querySelector('#assetsrc'); let avatarID = 'avatar-' + vwf.moniker_; if (srcEl.value.includes('.dae')) vwf_view.kernel.callMethod(vwf.application(), "createModel", ['DAE', srcEl.value, avatarID]) } } ), self.widgets.buttonSimple( { label: "OBJ", onclick: function (e) { let srcEl = document.querySelector('#assetsrc'); let avatarID = 'avatar-' + vwf.moniker_; if (srcEl.value.includes('.obj')) vwf_view.kernel.callMethod(vwf.application(), "createModel", ['OBJ', srcEl.value, avatarID]) } } ) ] } ] }, self.widgets.listTitle({text: 'Resources'}), { $type: "div", class: "mdc-layout-grid__inner", $components: [ self.widgets.gridListItem({ imgSrc: "/vwf/view/lib/images/ui/icons/3ditem.png", title: 'Asset item', imgSize: '30px', styleClass: "", onclickfunc: function () { let srcEl = document.querySelector('#assetsrc'); vwf_view.kernel.callMethod(vwf.application(), "createAssetResource", ['ITEM', srcEl.value]) } }), self.widgets.gridListItem({ imgSrc: "/vwf/view/lib/images/ui/icons/image.png", title: 'Image', imgSize: '30px', styleClass: "", onclickfunc: function () { //let cubeName = self.GUID(); let srcEl = document.querySelector('#assetsrc'); vwf_view.kernel.callMethod(vwf.application(), "createAssetResource", ['IMG', srcEl.value]) } }), self.widgets.gridListItem({ imgSrc: "/vwf/view/lib/images/ui/icons/video.png", title: 'Video', imgSize: '30px', styleClass: "", onclickfunc: function () { let srcEl = document.querySelector('#assetsrc'); vwf_view.kernel.callMethod(vwf.application(), "createAssetResource", ['VIDEO', srcEl.value]) } }), self.widgets.gridListItem({ imgSrc: "/vwf/view/lib/images/ui/icons/sound.png", title: 'Sound', imgSize: '30px', styleClass: "", onclickfunc: function () { let srcEl = document.querySelector('#assetsrc'); vwf_view.kernel.callMethod(vwf.application(), "createAssetResource", ['AUDIO', srcEl.value]) } }), self.widgets.buttonSimple( { label: "MTL", onclick: function (e) { let srcEl = document.querySelector('#assetsrc'); if (srcEl.value.includes('.mtl')) vwf_view.kernel.callMethod(vwf.application(), "createAssetResource", ['ITEM', srcEl.value]) } } ) ] }, { $type: "div", class: "mdc-layout-grid__inner", $components: [ { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ self.widgets.divider ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ { $type: "h3", class: "", $text: 'Google Poly' } ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ self.widgets.inputTextFieldOutlined({ "id": 'googlepolyid', "fieldStyle": 'width: 400px', "label": "Enter Google Poly model ID", "value": '', "change": function (e) { console.log(this.value) } }) ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ self.widgets.buttonSimple( { label: "Load from Poly", onclick: function (e) { let srcEl = document.querySelector('#googlepolyid'); let avatarID = 'avatar-' + vwf.moniker_; vwf_view.kernel.callMethod(vwf.application(), "createGooglePoly", [srcEl.value, null, null, avatarID]) } } ) ] } ] } ] } function getUniqueDisplayName(newname, addcount) { if (!addcount) addcount = 0; if (!newname) newname = 'Object'; newname = newname.replace(/[0-9]*$/g, ""); var nodes = self.nodes; //vwf.models.object.objects; var count = 1 + addcount; for (var i in nodes) { if (nodes[i].id !== 0) { if (nodes[i].id !== "" && nodes[i].properties.length !== 0) { let thisname = vwf.getProperty(nodes[i].ID, 'displayName') || ''; console.log(thisname); if (thisname.replace(/[0-9]*$/g, "") == newname) count++; } } } return newname + count; } function make3DPrimitiveList() { let nodeNames = ['Plane', 'Cube', 'Sphere', 'Cylinder', 'Cone', 'Text']; return nodeNames.map(el => { return self.widgets.gridListItem({ imgSrc: "/vwf/view/lib/images/ui/icons/" + el.toLowerCase() + ".png", imgSize: "30px", styleClass:"", //"createListItem", title: el, onclickfunc: function () { let avatarID = 'avatar-' + vwf.moniker_; //let cubeName = self.GUID(); let displayName = getUniqueDisplayName.call(self, el.toLowerCase()); vwf_view.kernel.callMethod(vwf.application(), "createPrimitive", [el.toLowerCase(), null, displayName, null, avatarID]) } }) }) } function makeLightsList() { let nodeNames = ['Ambient', 'Directional', 'Hemisphere', 'Point', 'Spot']; return nodeNames.map(el => { return self.widgets.gridListItem({ imgSize: "30px", styleClass: "", imgSrc: "/vwf/view/lib/images/ui/icons/light_" + el.toLowerCase() + ".png", title: el, onclickfunc: function () { let avatarID = 'avatar-' + vwf.moniker_; //let cubeName = self.GUID(); let displayName = getUniqueDisplayName.call(self, el.toLowerCase()); vwf_view.kernel.callMethod(vwf.application(), "createPrimitive", ["light", el.toLowerCase(), displayName, null, avatarID]) } }) }) } var saveAvatar = {}; var loadAvatar = {}; if (_LCSDB.user().is) { saveAvatar = self.widgets.floatActionButton({ label: "save", styleClass: "mdc-fab--mini", onclickfunc: function () { //var nodeID = document.querySelector('#currentNode')._currentNode; let nodeID = 'avatar-' + self.kernel.moniker(); let node = self.nodes[nodeID]; let nodeDef = self.helpers.getNodeDef(nodeID).children.avatarNode; console.log(nodeDef); _LCSDB.user().get('profile').get('avatarNode').put(JSON.stringify(nodeDef), acc => { console.log("saved: " + acc) }); //vwf_view.kernel.deleteChild(node.parentID, node.name); //vwf_view.kernel.deleteNode(nodeID); //vwf_view.kernel.callMethod(node.parentID, "deleteNode", [node.name]) } }); loadAvatar = self.widgets.floatActionButton({ label: "restore", styleClass: "mdc-fab--mini", onclickfunc: function () { let nodeID = 'avatar-' + self.kernel.moniker(); _LCSDB.user().get('profile').get('avatarNode').once(res => { if (res) { var myNode = res; if (_app.helpers.testJSON(res)){ myNode = JSON.parse(res); } vwf_view.kernel.callMethod(nodeID, "changeCostume", [myNode, true]); } }) } }) } let avatarSettings = { $cell: true, $type: "div", class: "propGrid max-width mdc-layout-grid mdc-layout-grid--align-left", $components: [ { $type: "div", class: "mdc-layout-grid__inner", $components: [ { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ self.widgets.icontoggle({ 'id': "mobile_joystick", 'label': 'visibility', 'on': JSON.stringify({ "content": "gamepad", "label": "Show" }), 'off': JSON.stringify({ "content": "gamepad", "label": "Hide" }), 'state': false, 'init': function () { this._driver = vwf.views["vwf/view/aframe"]; this._comp = new mdc.iconButton.MDCIconButtonToggle(this); //mdc.iconButton.MDCIconButtonToggle.attachTo(this); if (document.getElementsByClassName('touchZone').length > 0){ this._comp.on = true; this.style.color = "#3e7e40"; } else { this._comp.on = false; this.style.color = "#333333"; } this.addEventListener('MDCIconButtonToggle:change', (e) => { let chkAttr = e.detail.isOn; let driver = e.target._driver; if (chkAttr) { driver.state.showMobileJoystick(); this.style.color = "#3e7e40"; // this.classList.add('mdc-icon-toggle--enabled'); console.log("on"); } else { driver.state.hideMobileJoystick(); this.style.color = "#333333"; //this.classList.add('mdc-icon-toggle--disabled'); console.log("off") } }); } }), self.widgets.divider ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ saveAvatar, loadAvatar, self.widgets.divider, self.widgets.buttonStroked( { "label": "Reset camera view", "onclick": function (e) { //document.querySelector('#' + 'viewSettings').style.visibility = 'hidden'; let controlEl = document.querySelector('#avatarControl'); controlEl.setAttribute('camera', 'active', true); } }), self.widgets.buttonStroked( { "label": "Hide cursor", "onclick": function (e) { //document.querySelector('#' + 'viewSettings').style.visibility = 'hidden'; let avatarID = 'avatar-' + self.kernel.moniker(); let cursorID = vwf.find(avatarID, "./avatarNode/myHead/myCursor")[0]; //let cursorID = 'myCursor-' + avatarID; let controlEl = document.querySelector("[id='" + cursorID + "']"); let vis = controlEl.getAttribute('visible'); this.$text = vis ? 'Show cursor' : 'Hide cursor'; vwf_view.kernel.callMethod(avatarID, "showHideCursor", [!vis]); //controlEl.setAttribute('visible', !vis); } }), self.widgets.buttonStroked( { "label": "Hide Avatar", "onclick": function (e) { //document.querySelector('#' + 'viewSettings').style.visibility = 'hidden'; let avatarID = 'avatar-' + self.kernel.moniker(); //let cursorID = 'myCursor-' + avatarID; let controlEl = document.querySelector("[id='" + avatarID + "']"); let vis = controlEl.getAttribute('visible'); this.$text = vis ? 'Show Avatar' : 'Show Avatar'; vwf_view.kernel.callMethod(avatarID, "showHideAvatar", [!vis]); //controlEl.setAttribute('visible', !vis); } } ), self.widgets.buttonStroked( { "label": "Reset Avatar", "onclick": function (e) { let avatarID = 'avatar-' + self.kernel.moniker(); //TODO: add XR check vwf_view.kernel.callMethod(avatarID, "resetAvatar", []); } } ) ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ { $type: "div", class: "mdc-layout-grid", $components: [ { $type: "div", class: "mdc-layout-grid__inner", $components: [ { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ self.avatarCardDef("/defaults/assets/avatars/ico/simple.jpg", { title: "Simple", subtitle: "Cube" }, function (e) { let avatarID = 'avatar-' + self.kernel.moniker(); vwf_view.kernel.callMethod(avatarID, "createSimpleAvatar"); } ) ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ self.avatarCardDef("/defaults/assets/avatars/ico/female.jpg", { title: "Human", subtitle: "Female" }, function (e) { let avatarID = 'avatar-' + self.kernel.moniker(); vwf_view.kernel.callMethod(avatarID, "createAvatarFromGLTF", ["/defaults/assets/avatars/female/avatar1.gltf"]); } )] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ self.avatarCardDef("/defaults/assets/avatars/ico/male.jpg", { title: "Human", subtitle: "Male" }, function (e) { let avatarID = 'avatar-' + self.kernel.moniker(); vwf_view.kernel.callMethod(avatarID, "createAvatarFromGLTF", ["/defaults/assets/avatars/male/avatar1.gltf"]); } )] } ] } ] } ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ self.widgets.buttonStroked( { "label": "Wide", "onclick": function (e) { let avatarID = 'avatar-' + vwf.moniker_; vwf_view.kernel.callMethod(avatarID, "setBigVideoHead", []); } }), self.widgets.buttonStroked( { "label": "Small", "onclick": function (e) { let avatarID = 'avatar-' + vwf.moniker_; vwf_view.kernel.callMethod(avatarID, "setSmallVideoHead", []); } }) ] } ] } ] } let viewSettings = { $cell: true, $type: "div", class: "propGrid max-width mdc-layout-grid mdc-layout-grid--align-left", $components: [ { $type: "div", class: "mdc-layout-grid__inner", $components: [ { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ self.widgets.buttonStroked( { "label": "OSC Settings", "onclick": function (e) { let sideBar = document.querySelector('#sideBar'); sideBar._sideBarComponent = oscSettings; //document.querySelector('#' + 'viewSettings').style.visibility = 'hidden'; } }) ] } ] } ] } let savedStateEl = function (item) { return { $type: "li", class: "mdc-list-item", role: "option", $components: [ { $text: "Saved world" } ] } } let stateListElement = function (item) { let liEl = { $type: "option", id: "", applicationpath: "", value: "no_saves", $components: [ { $text: "no saves" } ] } let applicationName = item.applicationpath.split("/"); if (applicationName == "") { return liEl } if (applicationName.length > 0) { applicationName = applicationName[applicationName.length - 1]; } if (applicationName.length > 0) { applicationName = applicationName.charAt(0).toUpperCase() + applicationName.slice(1); } if (item.latestsave) { liEl = { $type: "option", id: item.savename, value: item.savename, applicationpath: item.applicationpath, $components: [ { $text: applicationName + ": " + item.savename } ] } } else { liEl = { $type: "option", id: item.savename, value: item.savename, revision: item.revision, applicationpath: item.applicationpath, $components: [ { $text: applicationName + ": " + item.savename + " Rev(" + item.revision + ")" } ] } } return liEl } let oscSettings = { $cell: true, $type: "div", id: "oscSettings", class: "propGrid max-width mdc-layout-grid mdc-layout-grid--align-left", _oscHost: '', _oscPort: '', _oscStatus: '', _updateStatus: function () { this._oscStatus = window._OSCManager.getStatus() }, $init: function () { if (window._OSCManager) { this._oscHost = window._OSCManager.hostValue; this._oscPort = window._OSCManager.portValue; this._oscStatus = window._OSCManager.getStatus(); // var t = this; // setInterval(function () { // t._updateStatus(); // }, 1000); } }, $update: function () { let that = this var buttonText = "Connect"; var buttonFunc = function (e) { } if (this._oscStatus == 1) { buttonText = "Disconnect"; buttonFunc = function (e) { window._OSCManager.disconnect(); } } else { var buttonFunc = function (e) { window._OSCManager.connect(); window._OSCManager.port.on("open", function () { that._oscStatus = window._OSCManager.getStatus(); console.log("connected"); }); window._OSCManager.port.on("close", function () { that._oscStatus = window._OSCManager.getStatus(); console.log("disconnected"); }); } } this.$components = [ { $type: "div", class: "mdc-layout-grid__inner", $components: [ { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ self.widgets.inputTextFieldOutlined({ "id": 'oscHostInput', "label": "Host", "value": this._oscHost, "change": function (e) { this._oscHost = this.value; window._OSCManager.setOSCHostAndPort(this._oscHost, this._oscPort); } }) // { // $type: "span", // $text: "Host: " // }, // { // class: "mdc-text-field", // $type: "span", // $components: [ // { // class: "mdc-text-field__input prop-text-field-input", // id: "oscHost", // $type: "input", // type: "text", // value: this._oscHost, // onchange: function (e) { // this._oscHost = this.value; // window._OSCManager.setOSCHostAndPort(this._oscHost, this._oscPort); // } // } // ] // } ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ self.widgets.inputTextFieldOutlined({ "id": 'oscPortInput', "label": "Port", "value": this._oscPort, "change": function (e) { this._oscPort = this.value; window._OSCManager.setOSCHostAndPort(this._oscHost, this._oscPort); } }) // { // $type: "span", // $text: "Port: " // }, // { // class: "mdc-text-field", // $type: "span", // $components: [ // { // class: "mdc-text-field__input prop-text-field-input", // id: "oscPort", // $type: "input", // type: "text", // value: this._oscPort, // onchange: function (e) { // this._oscPort = this.value; // window._OSCManager.setOSCHostAndPort(this._oscHost, this._oscPort); // } // } // ] // } ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ self.widgets.buttonStroked( { "label": buttonText, "onclick": buttonFunc }) ] } ] } ] } } let loadSaveSettings = { $cell: true, $type: "div", id: "loadSaveSettings", class: "propGrid max-width mdc-layout-grid mdc-layout-grid--align-left", $init: function () { var userGUI = []; let worldOwner = self.helpers.getRoot(false).root.split('/')[0]; if (_LCSDB.user().is) { if (worldOwner == _LCSDB.user().is.alias) { userGUI.push( { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ { $type: "h3", class: "mdc-typography--title", $text: self.helpers.worldStateName }, self.widgets.buttonStroked( { "label": "Save world", "onclick": function (e) { let fileName = self.helpers.worldStateName;//document.querySelector('#fileName') _app.saveStateAsFile(fileName); //document.querySelector("#fileName").value = ''; //document.querySelector('#' + 'viewSettings').style.visibility = 'hidden'; } }) ] } ); } userGUI.push( { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ { $type: "div", $components: [ self.widgets.inputTextFieldOutlined({ "id": 'fileName', "label": "World clone name", "value": 'world' + self.helpers.randId(), //self.getSaveName() //self.getRoot() "change": function (e) { } }) // { // class: "mdc-text-field__input prop-text-field-input", // id: "fileName", // $type: "input", // type: "text", // value: 'world' + self.helpers.randId() //self.getSaveName() //self.getRoot() // } ] } ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ self.widgets.buttonStroked( { "label": "Clone world", "onclick": function (e) { let fileName = document.querySelector('#fileName') let worldOwner = self.helpers.getRoot(false).root.split('/')[0]; if (_LCSDB.user().is) { if (worldOwner == _LCSDB.user().is.alias) { _app.saveStateAsFile(fileName.value); } else { console.log('clone world with prototype to: ' + fileName); _app.cloneWorldState(fileName.value); } } //saveStateAsFile.call(self, fileName.value); //document.querySelector("#fileName").value = ''; //document.querySelector('#' + 'viewSettings').style.visibility = 'hidden'; } }) ] } ) // let saveGUI = document.querySelector('#saveGUI'); // saveGUI.$components = userGUI.concat(saveGUI.$components); //document.querySelector('#fileName').value = 'world' + _app.helpers.randId(); } else { userGUI.push( self.widgets.getLoginGUI() ); } let saveGUI = document.querySelector('#saveGUI'); saveGUI.$components = userGUI.concat(saveGUI.$components); }, $update: function () { }, $components: [ { $type: "div", class: "mdc-layout-grid__inner", id: "saveGUI", $components: [ ] } ] } let protoPropertiesCell = function (m) { return { $type: "div", class: "mdc-layout-grid__inner", _prop: {}, $init: function () { let prop = m[1].prop; if (prop.value == undefined && this._currentNode !== undefined) { prop.value = JSON.stringify(utility.transform(vwf.getProperty(this._currentNode, prop.name, []), utility.transforms.transit)); } this._prop = prop }, $update: function () { this.$components = [ // { // $type: "div", // class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-10", // $components: [ // { $text: this._prop.name } // ] // }, // { // $type: "div", // class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-2", // }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ // { // $type: "span", // class: "mdc-typography--body2 mdc-typography--adjust-margin protoPropLabel", // $text: this._prop.name + ': ' // }, { $type: "div", $components: [ self.widgets.inputTextFieldStandart({ "id": 'proto_' + this._prop.name, "label": this._prop.name, "value": this._prop.getValue(), "change": function (e) { //set property let value = this.value; var propValue = value; if (_app.helpers.testJSON(value)){ propValue = JSON.parse(value); } else { propValue = value; } self.kernel.setProperty(this._currentNode, this._prop.name, propValue); // let propValue = this.value; // try { // propValue = JSON.parse(propValue); // self.kernel.setProperty(this._currentNode, this._prop.name, propValue); // } catch (e) { // // restore the original value on error // this.value = propValue; // } } }) ] } ] } ] } } } let propertiesCell = function (m) { var editComponents = [{}, {}]; // fullWidth: // fullHeight: // xoffset: // yoffset: // width: // height: let sliderPropNames = ['width', 'height', 'depth', 'fullWidth', 'fullHeight', 'xoffset', 'yoffset', 'subcamWidth', 'subcamHeight']; let sliderProps = { 'width': { min: 0, max: 30 }, 'height': { min: 0, max: 30 }, 'depth': { min: 0, max: 30 }, 'fullWidth': { min: 0, max: 5000, step: 10 }, 'fullHeight': { min: 0, max: 5000, step: 10 }, 'xoffset': { min: -10000, max: 10000, step: 10 }, 'yoffset': { min: -10000, max: 10000, step: 10 }, 'subcamWidth': { min: 0, max: 5000, step: 10 }, 'subcamHeight': { min: 0, max: 5000, step: 10 } } if (sliderPropNames.includes(m.name)) { let currenValue = JSON.parse(m.getValue()); var sliderComponent = self.widgets.sliderContinuous({ 'id': 'prop-slider-' + m.name, 'label': 'Slider', 'min': sliderProps[m.name].min, 'max': sliderProps[m.name].max, 'step': sliderProps[m.name].step ? sliderProps[m.name].step : 0.1, 'value': currenValue, 'init': function () { const myEl = this; var continuousSlider = new mdc.slider.MDCSlider(myEl); this._comp = continuousSlider; continuousSlider.listen('MDCSlider:input', function (e) { // console.log(continuousSlider.value) let myEl = e.currentTarget; // let prop = myEl._prop.body; //document.querySelector('#propAceEditor').env.editor.setValue(prop); self.kernel.setProperty(myEl._currentNode, m.name, continuousSlider.value); //continuousValue.textContent = continuousSlider.value; }); continuousSlider.listen('MDCSlider:change', function (e) { //console.log(continuousSlider.value); let myEl = e.currentTarget; // let prop = myEl._prop.body; //document.querySelector('#propAceEditor').env.editor.setValue(prop); self.kernel.setProperty(myEl._currentNode, m.name, continuousSlider.value); //continuousCommittedValue.textContent = continuousSlider.value; }) } }) } else { sliderComponent = {} } if (m.name.indexOf("semantics") > -1) { } else if (m.name.indexOf("grammar") > -1) { } else if (m.name.indexOf("ohm") > -1) { editComponents = [ { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-6", $components: [ { $type: "button", class: "mdc-button", $text: "Edit", //edit grammar onclick: function (e) { var currentNode = document.querySelector('#currentNode')._currentNode; if (currentNode == '') { currentNode = vwf_view.kernel.find("", "/")[0]; } let editor = document.querySelector('#livePropEditor'); editor._setNode(currentNode); editor._propName = m.name; editor._prop = { body: m.rawValue, type: 'complex' } document.querySelector('#propEditorWindow').style.visibility = 'visible'; } } ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-1", $components: [] } ] } else { editComponents = [ { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-6", $components: [ sliderComponent, { class: "mdc-text-field prop-mdc-text-field", $type: "div", $components: [ self.widgets.inputTextFieldStandart({ "id": "prop-" + m.name, "label": m.name, "value": m.getValue(), "change": function (e) { //set property let value = this.value; var propValue = value; if (_app.helpers.testJSON(value)){ propValue = JSON.parse(value); } else { propValue = value; //this.value = JSON.parse(JSON.stringify(propValue)); } self.kernel.setProperty(this._currentNode, m.name, propValue); //this.value = propValue.toString(); // let propValue = this.value; // try { // propValue = JSON.parse(propValue); // self.kernel.setProperty(this._currentNode, m.name, propValue); // } catch (e) { // // restore the original value on error // this.value = propValue; // } } }) ] } ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-1", $components: [ { $type: "button", class: "mdc-button mdc-button--compact", $text: "^", //edit grammar onclick: function (e) { var currentNode = document.querySelector('#currentNode')._currentNode; if (currentNode == '') { currentNode = vwf_view.kernel.find("", "/")[0]; } let editor = document.querySelector('#livePropEditor'); editor._setNode(currentNode); editor._propName = m.name; editor._prop = { body: m.getValue(), type: 'simple' } document.querySelector('#propEditorWindow').style.visibility = 'visible'; } } ] } ]; } return { $type: "div", class: "mdc-layout-grid__inner", $components: [ { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-3", $components: [ { $text: m.name } ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-2", }, editComponents[0], editComponents[1] ] } } let nodeLink = function (m) { var myClass = "nodeItem"; let myAvatarName = 'avatar-' + self.kernel.moniker(); (myAvatarName == m.name) ? (myClass = "avatarName mdc-typography--subheading2") : myClass = "nodeItem" var nodeName = m.name; let displayName = vwf.getProperty(m.ID, 'displayName'); if (displayName) { nodeName = displayName } return { $type: "li", class: "mdc-list-item", $components: [{ $type: "a", class: "mdc-list-item", $href: "#", $components: [{ $type: 'span', class: myClass, $text: nodeName } ], onclick: function (e) { //self.currentNodeID = m.ID; document.querySelector('#currentNode')._setNode(m.ID); // document.querySelector('#liveCodeEditor')._editorNode = m.ID; // createAceEditor(self, m.ID); } }] } }; let listDivider = { $type: "hr", class: "mdc-list-divider", } let webrtcGUI = { $type: "div", class: "propGrid mdc-layout-grid max-width mdc-layout-grid--align-left", $components: [ { $type: "div", class: "mdc-layout-grid__inner", $components: [ { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-2", $components: [ { $type: "span", $text: "Chat" } ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-2", $components: [ self.widgets.icontoggle({ 'id': "webrtcswitch", 'label': 'visibility', 'on': JSON.stringify({ "content": "visibility", "label": "Turn On Mic" }), 'off': JSON.stringify({ "content": "visibility_off", "label": "Turn Off Mic" }), 'state': false, 'init': function () { this._driver = vwf.views["vwf/view/webrtc"]; if (!this._driver) { //this.classList.add('mdc-icon-toggle--disabled'); this.setAttribute('disabled',""); } mdc.iconButton.MDCIconButtonToggle.attachTo(this); this.addEventListener('MDCIconButtonToggle:change', (e) => { let driver = e.target._driver; let chkAttr = e.detail.isOn; let avatarID = 'avatar-' + self.kernel.moniker(); let micToggle = document.querySelector('#webrtcaudio'); let camToggle = document.querySelector('#webrtcvideo'); if (chkAttr) { driver.startWebRTC(avatarID); micToggle.removeAttribute('disabled'); camToggle.removeAttribute('disabled'); //micToggle.classList.remove('mdc-icon-toggle--disabled'); //camToggle.classList.remove('mdc-icon-toggle--disabled'); console.log("on") } else { driver.stopWebRTC(avatarID); micToggle.setAttribute('disabled',""); camToggle.setAttribute('disabled',""); //micToggle.classList.add('mdc-icon-toggle--disabled'); //camToggle.classList.add('mdc-icon-toggle--disabled'); console.log("off") } //console.log(e, detail) //status.textContent = `Icon Toggle is ${detail.isOn ? 'on' : 'off'}`; }); } }) ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-2", $components: [ self.widgets.icontoggle({ 'id': "webrtcaudio", 'label': 'mic', 'on': JSON.stringify({ "content": "mic", "label": "Turn On Mic" }), 'off': JSON.stringify({ "content": "mic_off", "label": "Turn Off Mic" }), 'state': false, 'init': function () { this._driver = vwf.views["vwf/view/webrtc"]; let webrtcswitch = document.querySelector('#webrtcswitch'); if (!this._driver) { //this.classList.add('mdc-icon-toggle--disabled'); this.setAttribute("disabled", ""); } //this.classList.add('mdc-icon-toggle--disabled'); this.setAttribute("disabled", ""); this.addEventListener('MDCIconButtonToggle:change', (e) => { let driver = e.target._driver; let chkAttr = e.detail.isOn; if (chkAttr) { driver.muteAudio(chkAttr); console.log("on") } else { driver.muteAudio(chkAttr); console.log("off") } //console.log(e, detail) //status.textContent = `Icon Toggle is ${detail.isOn ? 'on' : 'off'}`; }); } }) ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-2", $components: [ self.widgets.icontoggle({ 'id': "webrtcvideo", 'label': 'videocam', 'on': JSON.stringify({ "content": "videocam", "label": "Turn On Video" }), 'off': JSON.stringify({ "content": "videocam_off", "label": "Turn Off Video" }), 'state': false, 'init': function () { this._driver = vwf.views["vwf/view/webrtc"]; if (!this._driver) { //this.classList.add('mdc-icon-toggle--disabled'); this.setAttribute("disabled", ""); } // this.classList.add('mdc-icon-toggle--disabled'); this.setAttribute("disabled", ""); this.addEventListener('MDCIconButtonToggle:change', (e) => { let driver = e.target._driver; let chkAttr = e.detail.isOn; if (chkAttr) { driver.muteVideo(chkAttr); console.log("on") } else { driver.muteVideo(chkAttr); console.log("off") } //console.log(e, detail) //status.textContent = `Icon Toggle is ${detail.isOn ? 'on' : 'off'}`; }); } }) ] } ] } ] } let audioGUI = { $type: "div", class: "propGrid mdc-layout-grid max-width mdc-layout-grid--align-left", $components: [ { $type: "div", class: "mdc-layout-grid__inner", $components: [ { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-2", $components: [ { $type: "span", $text: "Sound: " } ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-2", $components: [ self.widgets.icontoggle({ 'id': "soundStopStartSwitch", 'label': 'play', 'on': JSON.stringify({ "content": "pause", "label": "stop" }), 'off': JSON.stringify({ "content": "play_arrow", "label": "play" }), 'state': false, 'init': function () { var nodeID = this._currentNode; this._comp = new mdc.iconButtonToggle.MDCIconButtonToggle(this); this.setAttribute('id', "soundStopStartSwitch-" + nodeID); let isPlaying = vwf.getProperty(nodeID, 'isPlaying'); //mdc.iconToggle.MDCIconToggle.attachTo(this); this._comp.on = isPlaying; this.addEventListener('MDCIconButtonToggle:change', (e) => { // let avatarID = 'avatar-'+ vwf.moniker_; // let avatarNode = self.nodes['avatar-'+ vwf.moniker_]; // let mode = JSON.parse(avatarNode.properties.selectMode.getValue()); var nodeID = document.querySelector('#currentNode')._currentNode; let isPlaying = vwf.getProperty(nodeID, 'isPlaying'); if (isPlaying) { console.log("stop"); vwf_view.kernel.callMethod(nodeID, "pauseSound"); } else { console.log("play") vwf_view.kernel.callMethod(nodeID, "playSound"); } }); } }) ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-2", $components: [ { $type: "div", style: "padding: 12px", $components: [ self.widgets.iconButton({ 'label': 'stop', onclickfunc: function () { var nodeID = this._currentNode; vwf_view.kernel.callMethod(nodeID, "stopSound"); } }) ] } ] } // { // $type: "div", // class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-3", // $components: [ // widgets.switch({ // 'id': 'editnode', // 'init': function(){ // vwf_view.kernel.getProperty(this._currentNode, 'edit'); // }, // 'onchange': function(e){ // var nodeID = document.querySelector('#currentNode')._currentNode; // let chkAttr = this.getAttribute('checked'); // if (chkAttr == "") { // self.kernel.setProperty(this._currentNode, 'edit', false); // } else { // self.kernel.setProperty(this._currentNode, 'edit', true); // } // vwf_view.kernel.callMethod(nodeID, "showCloseGizmo"); // } // } // ) // ] // } ] } ] } var saveGUI = {}; if (_LCSDB.user().is) { saveGUI = self.widgets.floatActionButton({ label: "save", styleClass: "mdc-fab--mini", onclickfunc: function () { var nodeID = document.querySelector('#currentNode')._currentNode; let node = self.nodes[nodeID]; let nodeDef = self.helpers.getNodeDef(nodeID); console.log(nodeDef); //let saveID = this.GUID(); // _LCSUSER.get('saves').get(node.name).put(JSON.stringify(nodeDef), acc=>{ // console.log("saved: " + acc + 'to '+ node.name) // }); } }) } let gizmoEdit = { $type: "div", class: "propGrid mdc-layout-grid max-width mdc-layout-grid--align-left", $components: [ { $type: "div", class: "mdc-layout-grid__inner", $components: [ { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-2", $components: [ { $type: "span", $text: "Edit: ", } ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-3", $components: [ self.widgets.switch({ 'id': 'editnode', 'init': function () { vwf_view.kernel.getProperty(this._currentNode, 'edit'); this._switch = new mdc.switchControl.MDCSwitch(this); this._switch.checked = false; }, 'onchange': function (e) { var nodeID = document.querySelector('#currentNode')._currentNode; if (this._switch) { let chkAttr = this._switch.checked;//this.getAttribute('checked'); if (chkAttr) { self.kernel.setProperty(this._currentNode, 'edit', true); //this._switch.checked = false; } else { self.kernel.setProperty(this._currentNode, 'edit', false); //this._switch.checked = true; } vwf_view.kernel.callMethod(nodeID, "showCloseGizmo"); } } } ) ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-2", $components: [ self.widgets.imageButton({ imgSrc: "/vwf/view/lib/images/ui/icons/translate.png", styleClass: "editButton", onclickfunc: function (e) { vwf_view.kernel.callMethod(this._currentNode, "setGizmoMode", ['translate']) } }) ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-2", $components: [ self.widgets.imageButton({ imgSrc: "/vwf/view/lib/images/ui/icons/rotate.png", styleClass: "editButton", onclickfunc: function (e) { vwf_view.kernel.callMethod(this._currentNode, "setGizmoMode", ['rotate']) } }) ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-2", $components: [ self.widgets.imageButton({ imgSrc: "/vwf/view/lib/images/ui/icons/scale.png", styleClass: "editButton", onclickfunc: function (e) { vwf_view.kernel.callMethod(this._currentNode, "setGizmoMode", ['scale']) } }) ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ // self.widgets.floatActionButton({ // label: "content_copy", // styleClass: "mdc-fab--mini" // }), // { // $type: "span", // $text: " " // }, self.widgets.floatActionButton({ label: "delete_forever", styleClass: "mdc-fab--mini", onclickfunc: function () { var nodeID = document.querySelector('#currentNode')._currentNode; let node = self.nodes[nodeID]; //vwf_view.kernel.deleteChild(node.parentID, node.name); vwf_view.kernel.deleteNode(nodeID); //vwf_view.kernel.callMethod(node.parentID, "deleteNode", [node.name]) } }), // self.widgets.floatActionButton({ // label: "person", // styleClass: "mdc-fab--mini", // onclickfunc: function () { // var nodeID = document.querySelector('#currentNode')._currentNode; // let node = self.nodes[nodeID]; // //vwf_view.kernel.deleteChild(node.parentID, node.name); // let me = self.kernel.moniker(); // vwf_view.kernel.setProperty(nodeID, 'ownedBy', me); // } // }), saveGUI ] }, ] } ] } let nodesCell = { $cell: true, $type: "div", id: "currentNode", _childNodes: [], _currentNode: '', _displayedProperties: {}, _setNode: function (aNode) { this._currentNode = aNode; document.querySelector('#sideBar')._sideCurrentNode = this._currentNode }, $init: function () { this._currentNode = document.querySelector('#sideBar')._sideCurrentNode //this._currentNode = vwf_view.kernel.find("", "/")[0]; //this._currentNode = '3333'; }, _getChildNodes: function () { this._childNodes = self.nodes[this._currentNode]; if (this._childNodes !== undefined) { return this._childNodes.children } else { return [] } //let nodeIDAlpha = he.encode(this._currentNode); }, // _getNodeComplexProperties: function () { // let node = self.nodes[this._currentNode]; // let props = this._getNodeProperties(); // let filterFunction = function (prop) { // return (prop.name == 'ohmLang') // }; // let complexProps = props.filter(filterFunction.bind(this)); // return complexProps // }, _getNodeProperties: function () { let node = self.nodes[this._currentNode]; this._displayedProperties = {}; let filterFunction = function (prop) { return (!this._displayedProperties[prop.name] && prop.name.indexOf('$') === -1) ? (this._displayedProperties[prop.name] = "instance", true) : (false); }; let props = node.properties.filter(filterFunction.bind(this)); return props }, _getNodeProtoProperties: function () { let node = self.nodes[this._currentNode]; let filterFunction = function (prop) { return (!this._displayedProperties[prop[1].prop.name]) ? (this._displayedProperties[prop[1].prop.name] = prop[1].prototype, true) : (false); }; let props = Object.entries(getProperties.call(self, self.kernel, node.extendsID)).filter(filterFunction.bind(this)); return props }, $update: function () { //this.$text = this._currentNode; let node = self.nodes[this._currentNode]; let nodeProtos = getPrototypes(self.kernel, node.extendsID); var viewerProps = {}; var viewerPropsCell = {}; var propsActions = {}; var propsActionsCell = {}; var gizmoCell = {}; if (this._currentNode !== self.kernel.application()) { if (nodeProtos.includes('http://vwf.example.com/aframe/componentNode.vwf')) { //gizmoCell = {}; if (nodeProtos.includes('http://vwf.example.com/aframe/a-sound-component.vwf')) { //console.log("sound gui") gizmoCell = audioGUI } } else { gizmoCell = gizmoEdit } } if (node !== undefined) { propsActions = { $type: "li", class: "mdc-list-item", $components: [ { $text: "Actions", $type: "span", class: "mdc-list-item__text mdc-typography--button" } ] } let actionsGUI = []; if(node.properties.meta) { if(node.properties.meta.rawValue == 'avatarCostume'){ actionsGUI.push(self.widgets.buttonStroked( { "label": "Use this costume", "onclick": function (e) { console.log("COSTUME NEW!!!"); let nodeDef = self.helpers.getNodeDef(this._currentNode); console.log(nodeDef); let avatarID = 'avatar-' + self.kernel.moniker(); vwf_view.kernel.callMethod(avatarID, "changeCostume", [nodeDef]); //vwf_view.kernel.callMethod(this._currentNode, "setCameraToActive", [vwf.moniker_]); } })) } } else if(node.name.includes('xrcontroller')){ actionsGUI.push(self.widgets.buttonStroked( { "label": "Set as World default XR controller", "onclick": function (e) { vwf_view.kernel.callMethod(node.ID, "saveToScene", []); } })) } propsActionsCell = { $cell: true, $type: "div", class: "propGrid mdc-layout-grid max-width mdc-layout-grid--align-left", $components: [ { $type: "div", class: "mdc-layout-grid__inner", $components: [ { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [].concat(actionsGUI) } ] } ] //$components: this._getNodeProtoProperties().map(protoPropertiesCell) } if (node.extendsID == "http://vwf.example.com/aframe/acamera.vwf") { viewerProps = { $type: "li", class: "mdc-list-item", $components: [ { $text: "Viewer properties", $type: "span", class: "mdc-list-item__text mdc-typography--button" } ] } viewerPropsCell = { $cell: true, $type: "div", class: "propGrid mdc-layout-grid max-width mdc-layout-grid--align-left", $components: [ { $type: "div", class: "mdc-layout-grid__inner", $components: [ { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ self.widgets.buttonStroked( { "label": "Active", "onclick": function (e) { //let camera = document.querySelector('#' + this._currentNode); vwf_view.kernel.callMethod(this._currentNode, "setCameraToActive", [vwf.moniker_]); //camera.setAttribute('camera', 'active', true); } }) ] } ] } ] //$components: this._getNodeProtoProperties().map(protoPropertiesCell) } } else { viewerProps = {}; viewerPropsCell = {}; } } this.$components = [ { $type: "ul", class: "mdc-list", $components: [ self.widgets.buttonStroked( { "label": "<--", "onclick": function (e) { let node = self.nodes[this._currentNode]; if (node.parentID !== 0) { //self.currentNodeID = node.parentID, document.querySelector('#currentNode')._setNode(node.parentID) } } }), { $type: "li", class: "mdc-list-item", $components: [ { $text: "name", $type: "span", $init: function () { let node = self.nodes[this._currentNode]; if (node) { let displayName = vwf.getProperty(node.ID, 'displayName'); if (displayName) { this.$text = displayName } else { this.$text = node.name; } } //console.log(node.properties.displayName) }, class: "mdc-list-item__text mdc-typography--headline" //