editor-new.js 164 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886
  1. "use strict";
  2. // Copyright 2012 United States Government, as represented by the Secretary of Defense, Under
  3. // Secretary of Defense (Personnel & Readiness).
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
  6. // in compliance with the License. You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software distributed under the License
  11. // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
  12. // or implied. See the License for the specific language governing permissions and limitations under
  13. // the License.
  14. /// vwf/view/editor creates a view interface for editor functions.
  15. ///
  16. /// @module vwf/view/editor
  17. /// @requires version
  18. /// @requires vwf/view
  19. /// @requires vwf/utility
  20. define([
  21. "module",
  22. "version",
  23. "vwf/view",
  24. "vwf/utility",
  25. "vwf/view/lib/ace/ace",
  26. "jquery",
  27. "jquery-ui",
  28. "jquery-encoder-0.1.0"
  29. ], function (module, version, view, utility, ace, $) {
  30. return view.load(module, {
  31. // == Module Definition ====================================================================
  32. initialize: function () {
  33. var self = this;
  34. this.ace = window.ace;
  35. this.nodes = {};
  36. this.scenes = {};
  37. this.allScripts = {};
  38. // EDITOR CLOSED --> 0
  39. // HIERARCHY OPEN --> 1
  40. // USER LIST OPEN --> 2
  41. // TIMELINE OPEN --> 3
  42. // ABOUT OPEN --> 4
  43. this.editorView = 0;
  44. this.editorOpen = false;
  45. this.timelineInit = false;
  46. this.aboutInit = false;
  47. this.codeEditorInit = false;
  48. this.modelsInit = false;
  49. this.editingScript = false;
  50. this.topdownName = '#topdown_a';
  51. this.topdownTemp = '#topdown_b';
  52. this.clientList = '#client_list';
  53. this.timeline = '#time_control';
  54. this.about = '#about_tab';
  55. this.codeEditor = '#codeEditor_tab';
  56. this.models = '#model_a';
  57. this.modelsTemp = '#model_b';
  58. this.currentNodeID = '';
  59. this.currentModelID = '';
  60. this.currentModelURL = '';
  61. this.highlightedChild = '';
  62. this.intervalTimer = 0;
  63. this.activeCameraID = undefined;
  64. $(document.head).append('<style type="text/css" media="screen"> #editorlive { height: 500px; width: 800px; } </style>');
  65. document.querySelector('head').innerHTML += '<link rel="stylesheet" href="vwf/view/lib/editorLive.css">';
  66. $(document.head).append('<meta name="viewport" content="width=device-width, initial-scale=1">');
  67. // $('body').append('<script>mdc.autoInit()</script>');
  68. $('body').append(
  69. "<div id='editor' class='relClass'>\n" +
  70. " <div class='uiContainer'>\n" +
  71. " <div class='editor-tabs' id='tabs'>\n" +
  72. " <img id='x' style='display:none' src='images/tab_X.png' alt='x' />\n" +
  73. " <img id='hierarchy' src='images/tab_Application.png' alt='application' />\n" +
  74. " <img id='userlist' src='images/tab_Users.png' alt='users' />\n" +
  75. " <img id='timeline' src='images/tab_Time.png' alt='time' />\n" +
  76. " <img id='models' src='images/tab_Models.png' alt='models' />\n" +
  77. " <img id='about' src='images/tab_About.png' alt='about' />\n" +
  78. " <img id='codeEditor' src='images/tab_CodeEditor.png' alt='code' />\n" +
  79. " </div>\n" +
  80. " </div>\n" +
  81. "</div>" +
  82. "<div class='relClass'><div class='uiContainer'><div class='vwf-tree' id='topdown_a'></div></div></div>" +
  83. "<div class='relClass'><div class='uiContainer'><div class='vwf-tree' id='topdown_b'></div></div></div>" +
  84. "<div class='relClass'><div class='uiContainer'><div class='vwf-tree' id='client_list'></div></div></div>" +
  85. "<div class='relClass'><div class='uiContainer'><div class='vwf-tree' id='time_control'></div></div></div>" +
  86. "<div class='relClass'><div class='uiContainer'><div class='vwf-tree' id='about_tab'></div></div></div>" +
  87. "<div class='relClass'><div class='uiContainer'><div class='vwf-tree' id='codeEditor_tab'></div></div></div>" +
  88. "<div class='relClass'><div class='uiContainer'><div class='vwf-tree' id='model_a'></div></div></div>" +
  89. "<div class='relClass'><div class='uiContainer'><div class='vwf-tree' id='model_b'></div></div></div>"
  90. );
  91. //style: "position: absolute; top: 0; left: 0; z-index: 2",
  92. // let draggie = new Draggabilly('.draggable');
  93. // let dragDiv = document.querySelector("#dragDiv").style.visibility = 'hidden';
  94. // let propDiv = document.createElement("div");
  95. // var newContent = document.createTextNode("Hi there and greetings!");
  96. // newDiv.appendChild(newContent); //add the text node to the newly created div.
  97. //<div id='drawer'></div><div id='toolbar'></div><div id='clientsList'></div>
  98. ["drawer", "toolbar", "sideBar", "propWindow", "clientsWindow", "codeEditorWindow", "viewSceneProps"].forEach(item => {
  99. let el = document.createElement("div");
  100. el.setAttribute("id", item);
  101. document.body.appendChild(el);
  102. }
  103. );
  104. let avatarSettings =
  105. {
  106. $cell: true,
  107. $type: "div",
  108. class: "propGrid max-width mdc-layout-grid mdc-layout-grid--align-left",
  109. $components:[
  110. {
  111. $cell: true,
  112. $type: "div",
  113. class: "mdc-layout-grid__inner",
  114. $components: [
  115. {
  116. $cell: true,
  117. $type: "div",
  118. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12",
  119. $components: [
  120. {
  121. $cell: true,
  122. $type: "button",
  123. class: "mdc-button mdc-button--raised",
  124. $text: "Reset camera view",
  125. onclick: function (e) {
  126. //document.querySelector('#' + 'viewSettings').style.visibility = 'hidden';
  127. let controlEl = document.querySelector('#avatarControl');
  128. controlEl.setAttribute('camera', 'active', true);
  129. }
  130. },
  131. {
  132. $cell: true,
  133. $type: "button",
  134. class: "mdc-button mdc-button--raised",
  135. $text: "Hide cursor",
  136. onclick: function (e) {
  137. //document.querySelector('#' + 'viewSettings').style.visibility = 'hidden';
  138. let cursorID = 'myCursor-avatar-' + self.kernel.moniker();
  139. let controlEl = document.querySelector("[id='"+cursorID+"']");
  140. let vis = controlEl.getAttribute('visible');
  141. this.$text = vis ? 'Show cursor': 'Hide cursor';
  142. controlEl.setAttribute('visible', !vis);
  143. }
  144. }
  145. ]
  146. }
  147. ]
  148. }
  149. ]
  150. }
  151. let viewSettings =
  152. {
  153. $cell: true,
  154. $type: "div",
  155. class: "propGrid max-width mdc-layout-grid mdc-layout-grid--align-left",
  156. $components:[
  157. {
  158. $cell: true,
  159. $type: "div",
  160. class: "mdc-layout-grid__inner",
  161. $components: [
  162. {
  163. $cell: true,
  164. $type: "div",
  165. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12",
  166. $components: [
  167. {
  168. $cell: true,
  169. $type: "button",
  170. class: "mdc-button mdc-button--raised",
  171. $text: "Settings",
  172. onclick: function (e) {
  173. //document.querySelector('#' + 'viewSettings').style.visibility = 'hidden';
  174. }
  175. }
  176. ]
  177. }
  178. ]
  179. }
  180. ]
  181. }
  182. let loadSaveSettings =
  183. {
  184. $cell: true,
  185. $type: "div",
  186. _getRoot: function(){
  187. var app = window.location.pathname;
  188. var pathSplit = app.split('/');
  189. if (pathSplit[0] == "") {
  190. pathSplit.shift();
  191. }
  192. if (pathSplit[pathSplit.length - 1] == "") {
  193. pathSplit.pop();
  194. }
  195. var instIndex = pathSplit.length - 1;
  196. if (pathSplit.length > 2) {
  197. if (pathSplit[pathSplit.length - 2] == "load") {
  198. instIndex = pathSplit.length - 3;
  199. }
  200. }
  201. if (pathSplit.length > 3) {
  202. if (pathSplit[pathSplit.length - 3] == "load") {
  203. instIndex = pathSplit.length - 4;
  204. }
  205. }
  206. var root = "";
  207. for (var i = 0; i < instIndex; i++) {
  208. if (root != "") {
  209. root = root + "/";
  210. }
  211. root = root + pathSplit[i];
  212. }
  213. if (root.indexOf('.vwf') != -1) root = root.substring(0, root.lastIndexOf('/'));
  214. return root
  215. },
  216. class: "propGrid max-width mdc-layout-grid mdc-layout-grid--align-left",
  217. $components:[
  218. {
  219. $cell: true,
  220. $type: "div",
  221. class: "mdc-layout-grid__inner",
  222. $components: [
  223. {
  224. $cell: true,
  225. $type: "div",
  226. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12",
  227. $components: [
  228. {
  229. class: "mdc-textfield",
  230. $cell: true,
  231. $type: "span",
  232. $components: [
  233. {
  234. class: "mdc-textfield__input",
  235. id: "fileName",
  236. $cell: true,
  237. $type: "input",
  238. type: "text",
  239. value: ""
  240. }]
  241. }
  242. ]
  243. },
  244. {
  245. $cell: true,
  246. $type: "div",
  247. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12",
  248. $components: [
  249. {
  250. $cell: true,
  251. $type: "button",
  252. class: "mdc-button mdc-button--raised",
  253. $text: "Save",
  254. onclick: function (e) {
  255. let fileName = document.querySelector('#fileName')
  256. saveStateAsFile.call(self, fileName.value);
  257. document.querySelector("#fileName").value = '';
  258. //document.querySelector('#' + 'viewSettings').style.visibility = 'hidden';
  259. }
  260. }
  261. ]
  262. },
  263. {
  264. $cell: true,
  265. $type: "div",
  266. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12",
  267. $components: [
  268. {
  269. $type: "div",
  270. $text: "Loading" },
  271. ]
  272. },
  273. {
  274. $cell: true,
  275. $type: "div",
  276. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12",
  277. $components: [
  278. {
  279. $cell: true,
  280. $type: "button",
  281. class: "mdc-button mdc-button--raised",
  282. $text: "Load",
  283. onclick: function (e) {
  284. //document.querySelector('#' + 'viewSettings').style.visibility = 'hidden';
  285. }
  286. }
  287. ]
  288. }
  289. ]
  290. }
  291. ]
  292. }
  293. // document.querySelector('#' + 'viewSettings').$cell({
  294. // $cell: true,
  295. // $type: "div",
  296. // id: 'viewSettings',
  297. // //style:'z-index: 10; position: absolute; margin-left: 240px;',
  298. // class: "settingsDiv mdc-toolbar-fixed-adjust",
  299. // $init: function(){
  300. // this.style.visibility = 'hidden';
  301. // },
  302. // $components: [viewSettings]
  303. // })
  304. // document.querySelector('#' + 'viewSettings').$cell({
  305. // $cell: true,
  306. // $type: "div",
  307. // id: 'viewSettings',
  308. // style:'z-index: 10; position: absolute; margin-left: 240px;',
  309. // class: "propGrid mdc-layout-grid max-width mdc-layout-grid--align-left mdc-toolbar-fixed-adjust",
  310. // $init: function(){
  311. // this.style.visibility = 'hidden';
  312. // },
  313. // $components: [viewSettings]
  314. // })
  315. let protoPropertiesCell = function (m) {
  316. return {
  317. $type: "div",
  318. class: "mdc-layout-grid__inner",
  319. _prop: {},
  320. $init: function () {
  321. let prop = m[1].prop;
  322. if (prop.value == undefined) {
  323. prop.value = JSON.stringify(utility.transform(vwf.getProperty(this._currentNode, prop.name, []), utility.transforms.transit));
  324. }
  325. this._prop = prop
  326. },
  327. $update: function () {
  328. this.$components = [
  329. {
  330. $type: "div",
  331. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-3",
  332. $components: [
  333. { $text: this._prop.name }
  334. ]
  335. },
  336. {
  337. $type: "div",
  338. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-2",
  339. },
  340. {
  341. $type: "div",
  342. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-7",
  343. $components: [
  344. {
  345. class: "mdc-textfield",
  346. $cell: true,
  347. $type: "div",
  348. $components: [{
  349. class: "mdc-textfield__input",
  350. $cell: true,
  351. $type: "input",
  352. type: "text",
  353. value: this._prop.value,
  354. onchange: function (e) {
  355. let propValue = this.value;
  356. try {
  357. propValue = JSON.parse(propValue);
  358. self.kernel.setProperty(this._currentNode, this._prop.name, propValue);
  359. } catch (e) {
  360. // restore the original value on error
  361. this.value = propValue;
  362. }
  363. }
  364. }]
  365. }
  366. ]
  367. }
  368. ]
  369. }
  370. }
  371. }
  372. let propertiesCell = function (m) {
  373. return {
  374. $type: "div",
  375. class: "mdc-layout-grid__inner",
  376. $components: [
  377. {
  378. $type: "div",
  379. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-3",
  380. $components: [
  381. { $text: m.name }
  382. ]
  383. },
  384. {
  385. $type: "div",
  386. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-2",
  387. },
  388. {
  389. $type: "div",
  390. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-7",
  391. $components: [
  392. {
  393. class: "mdc-textfield",
  394. $cell: true,
  395. $type: "span",
  396. $components: [
  397. {
  398. class: "mdc-textfield__input",
  399. id: "prop-" + m.name,
  400. $cell: true,
  401. $type: "input",
  402. type: "text",
  403. value: m.getValue(),
  404. onchange: function (e) {
  405. let propValue = this.value;
  406. try {
  407. propValue = JSON.parse(propValue);
  408. self.kernel.setProperty(this._currentNode, m.name, propValue);
  409. } catch (e) {
  410. // restore the original value on error
  411. this.value = propValue;
  412. }
  413. }
  414. }]
  415. }
  416. ]
  417. }
  418. ]
  419. }
  420. }
  421. let nodeLink = function (m) {
  422. var myClass = "nodeItem";
  423. let myAvatarName = 'avatar-'+self.kernel.moniker();
  424. (myAvatarName == m.name) ? (myClass = "avatarName mdc-typography--subheading2") :
  425. myClass = "nodeItem"
  426. return {
  427. $type: "li",
  428. class: "mdc-list-item",
  429. $components: [{
  430. $type: "a",
  431. class: "mdc-list-item",
  432. $href: "#",
  433. $components:[{
  434. $type: 'span',
  435. class: myClass,
  436. $text: m.name
  437. }
  438. ],
  439. onclick: function (e) {
  440. //self.currentNodeID = m.ID;
  441. document.querySelector('#currentNode')._setNode(m.ID);
  442. // document.querySelector('#liveCodeEditor')._editorNode = m.ID;
  443. // createAceEditor(self, m.ID);
  444. }
  445. }]
  446. }
  447. };
  448. let listDivider = {
  449. $cell: true,
  450. $type: "hr",
  451. class: "mdc-list-divider",
  452. }
  453. let nodesCell = {
  454. $cell: true,
  455. $type: "div",
  456. id: "currentNode",
  457. _childNodes: [],
  458. _currentNode: '',
  459. _displayedProperties: {},
  460. _setNode: function (aNode) {
  461. this._currentNode = aNode;
  462. document.querySelector('#sideBar')._sideCurrentNode = this._currentNode
  463. },
  464. $init: function () {
  465. this._currentNode = document.querySelector('#sideBar')._sideCurrentNode
  466. //this._currentNode = vwf_view.kernel.find("", "/")[0];
  467. //this._currentNode = '3333';
  468. },
  469. _getChildNodes: function () {
  470. this._childNodes = self.nodes[this._currentNode];
  471. if (this._childNodes !== undefined) {
  472. return this._childNodes.children
  473. } else {
  474. return []
  475. }
  476. //let nodeIDAlpha = he.encode(this._currentNode);
  477. },
  478. _getNodeProperties: function () {
  479. let node = self.nodes[this._currentNode];
  480. this._displayedProperties = {};
  481. let filterFunction = function (prop) {
  482. return (!this._displayedProperties[prop.name] && prop.name.indexOf('$') === -1) ? (this._displayedProperties[prop.name] = "instance", true) : (false);
  483. };
  484. let props = node.properties.filter(filterFunction.bind(this));
  485. return props
  486. },
  487. _getNodeProtoProperties: function () {
  488. let node = self.nodes[this._currentNode];
  489. let filterFunction = function (prop) {
  490. return (!this._displayedProperties[prop[1].prop.name]) ? (this._displayedProperties[prop[1].prop.name] = prop[1].prototype, true) : (false);
  491. };
  492. let props = Object.entries(getProperties.call(self, self.kernel, node.extendsID)).filter(filterFunction.bind(this));
  493. return props
  494. },
  495. $update: function () {
  496. //this.$text = this._currentNode;
  497. var viewerProps = {};
  498. var viewerPropsCell = {};
  499. let node = self.nodes[this._currentNode];
  500. if (node !== undefined) {
  501. if (node.extendsID == "http://vwf.example.com/aframe/acamera.vwf") {
  502. viewerProps = {
  503. $type: "li",
  504. class: "mdc-list-item",
  505. $components: [
  506. {
  507. $text: "Viewer properties",
  508. $type: "span",
  509. class: "mdc-list-item__text mdc-typography--button"
  510. }
  511. ]
  512. }
  513. viewerPropsCell = {
  514. $cell: true,
  515. $type: "div",
  516. class: "propGrid mdc-layout-grid max-width mdc-layout-grid--align-left",
  517. $components: [
  518. {
  519. $cell: true,
  520. $type: "div",
  521. class: "mdc-layout-grid__inner",
  522. $components: [
  523. {
  524. $cell: true,
  525. $type: "div",
  526. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12",
  527. $components: [
  528. {
  529. $cell: true,
  530. $type: "button",
  531. class: "mdc-button mdc-button--raised",
  532. $text: "Active",
  533. onclick: function (e) {
  534. let camera = document.querySelector('#' + this._currentNode);
  535. camera.setAttribute('active', true);
  536. }
  537. }
  538. ]
  539. }
  540. ]
  541. }
  542. ]
  543. //$components: this._getNodeProtoProperties().map(protoPropertiesCell)
  544. }
  545. } else {
  546. viewerProps = {};
  547. viewerPropsCell = {};
  548. }
  549. }
  550. this.$components = [
  551. {
  552. $cell: true,
  553. $type: "ul",
  554. class: "mdc-list",
  555. $components: [
  556. {
  557. $cell: true,
  558. $type: "button",
  559. class: "mdc-list-item mdc-button mdc-button--raised",
  560. $text: "<--",
  561. onclick: function (e) {
  562. let node = self.nodes[this._currentNode];
  563. if (node.parentID !== 0) {
  564. //self.currentNodeID = node.parentID,
  565. document.querySelector('#currentNode')._setNode(node.parentID)
  566. }
  567. }
  568. },
  569. {
  570. $type: "li",
  571. class: "mdc-list-item",
  572. $components: [
  573. {
  574. $text: "name",
  575. $type: "span",
  576. $init: function () {
  577. let node = self.nodes[this._currentNode];
  578. this.$text = node.name
  579. },
  580. class: "mdc-list-item__text mdc-typography--headline"
  581. //<h1 class="mdc-typography--display4">Big header</h1>
  582. }]
  583. }, listDivider,
  584. {
  585. // $cell: true,
  586. // $type: "ul",
  587. // class: "mdc-list",
  588. $type: "div",
  589. class: "propGrid mdc-layout-grid max-width mdc-layout-grid--align-left",
  590. $components: [
  591. {
  592. $type: "div",
  593. class: "mdc-layout-grid__inner",
  594. $components: [
  595. {
  596. $type: "div",
  597. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12",
  598. $components: [
  599. {
  600. $cell: true,
  601. $type: "button",
  602. class: "mdc-button mdc-button--raised",
  603. $text: "Open in code editor",
  604. onclick: function (e) {
  605. var currentNode = document.querySelector('#currentNode')._currentNode;
  606. if (currentNode == '') {
  607. currentNode = vwf_view.kernel.find("", "/")[0];
  608. }
  609. document.querySelector('#liveCodeEditor')._setNode(currentNode);
  610. //createAceEditor(self, currentNode);
  611. document.querySelector('#codeEditorWindow').style.visibility = 'visible';
  612. }
  613. }
  614. ]
  615. }
  616. ]
  617. }
  618. ]
  619. },
  620. listDivider,
  621. {
  622. $type: "li",
  623. class: "mdc-list-item",
  624. $components: [
  625. {
  626. $text: "Children",
  627. $type: "span",
  628. class: "mdc-list-item__text mdc-typography--button"
  629. }]
  630. },
  631. {
  632. $cell: true,
  633. $type: "ul",
  634. class: "mdc-list",
  635. $components: this._getChildNodes().map(nodeLink)
  636. }, listDivider, {
  637. $type: "li",
  638. class: "mdc-list-item",
  639. $components: [
  640. {
  641. $text: "Properties",
  642. $type: "span",
  643. class: "mdc-list-item__text mdc-typography--button"
  644. //<h1 class="mdc-typography--display4">Big header</h1>
  645. }]
  646. },
  647. {
  648. // $cell: true,
  649. // $type: "ul",
  650. // class: "mdc-list",
  651. $type: "div",
  652. class: "propGrid mdc-layout-grid max-width mdc-layout-grid--align-left",
  653. $components: this._getNodeProperties().map(propertiesCell)
  654. },
  655. listDivider,
  656. {
  657. $type: "li",
  658. class: "mdc-list-item",
  659. $components: [
  660. {
  661. $text: "Proto properties",
  662. $type: "span",
  663. class: "mdc-list-item__text mdc-typography--button"
  664. }]
  665. },
  666. {
  667. $cell: true,
  668. $type: "div",
  669. class: "propGrid mdc-layout-grid max-width mdc-layout-grid--align-left",
  670. $components: this._getNodeProtoProperties().map(protoPropertiesCell)
  671. }, listDivider,
  672. viewerProps,
  673. viewerPropsCell
  674. ]
  675. }
  676. ]
  677. }
  678. }
  679. let codeEditorWindow = {
  680. $cell: true,
  681. $type: "div",
  682. _editorNode: '',
  683. _method: { body: '' },
  684. _methodName: '',
  685. _getNodeMethods: function () {
  686. let node = self.nodes[this._editorNode];
  687. return node.methods
  688. },
  689. _getProtoNodeMethods: function () {
  690. let node = self.nodes[this._editorNode];
  691. let prototypeMethods = getMethods.call(self, self.kernel, node.extendsID);
  692. return prototypeMethods
  693. },
  694. id: "liveCodeEditor",
  695. _setNode: function (node) {
  696. this._editorNode = node;
  697. this._method.body = ''
  698. },
  699. class: "codeEditorGrid mdc-layout-grid max-width mdc-layout-grid--align-left",
  700. _listElement: function (m) {
  701. return {
  702. $type: "li",
  703. class: "mdc-list-item",
  704. $components: [{
  705. $type: "a",
  706. class: "mdc-list-item",
  707. $href: "#",
  708. $text: m[0],
  709. onclick: function (e) {
  710. let method = vwf.getMethod(this._editorNode, m[0]);
  711. //document.querySelector('#aceEditor').
  712. this._method = method;
  713. this._methodName = m[0];
  714. //self.currentNodeID = m.ID;
  715. //document.querySelector('#currentNode')._setNode(m.ID);
  716. }
  717. }]
  718. }
  719. },
  720. $update: function () {
  721. this.$components = [
  722. {
  723. $cell: true,
  724. $type: "div",
  725. class: "mdc-layout-grid__inner",
  726. $components: [
  727. {
  728. $cell: true,
  729. $type: "div",
  730. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-3",
  731. $components: [
  732. {
  733. $type: "h3",
  734. class: "mdc-list-group__subheader mdc-list-item__text mdc-typography--subheading1",
  735. $text: this._editorNode
  736. }
  737. ]
  738. },
  739. {
  740. $cell: true,
  741. $type: "div",
  742. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-2",
  743. $components: [
  744. {
  745. $cell: true,
  746. $type: "button",
  747. class: "mdc-button mdc-button--raised",
  748. $text: "Update",
  749. onclick: function (e) {
  750. let editor = document.querySelector("#aceEditor").env.editor;
  751. let evalText = editor.getValue();
  752. self.kernel.setMethod(this._editorNode, this._methodName,
  753. { body: evalText, type: "application/javascript", parameters: this._method.parameters });
  754. }
  755. }]
  756. },
  757. {
  758. $cell: true,
  759. $type: "div",
  760. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-2",
  761. $components: [
  762. {
  763. $cell: true,
  764. $type: "button",
  765. class: "mdc-button mdc-button--raised",
  766. $text: "Call",
  767. onclick: function (e) {
  768. let params = [];
  769. if (this._method.parameters) {
  770. params = this._method.parameters.length
  771. };
  772. if (params >= 1) { }
  773. self.kernel.callMethod(this._editorNode, this._methodName, this._method.parameters);
  774. }
  775. }]
  776. },
  777. {
  778. $cell: true,
  779. $type: "div",
  780. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-2",
  781. $components: [
  782. {
  783. $cell: true,
  784. $type: "button",
  785. class: "mdc-button mdc-button--raised",
  786. $text: "Do It",
  787. onclick: function (e) {
  788. let editor = document.querySelector("#aceEditor").env.editor;
  789. codeEditorDoit.call(self, editor, this._editorNode);
  790. }
  791. }]
  792. },
  793. {
  794. $cell: true,
  795. $type: "div",
  796. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-3",
  797. $components: [
  798. {
  799. $cell: true,
  800. $type: "button",
  801. class: "mdc-button mdc-button--raised",
  802. $text: "Print It",
  803. onclick: function (e) {
  804. let editor = document.querySelector("#aceEditor").env.editor;
  805. codeEditorPrintit.call(self, editor, this._editorNode);
  806. }
  807. }]
  808. }
  809. ]
  810. },
  811. {
  812. $cell: true,
  813. $type: "div",
  814. class: "mdc-layout-grid__inner",
  815. $components: [
  816. {
  817. $cell: true,
  818. $type: "div",
  819. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-3",
  820. style: "overflow-y: scroll; max-height: 800px;",
  821. $components: [
  822. {
  823. $cell: true,
  824. $type: "div",
  825. class: "mdc-list-group",
  826. $components: [
  827. {
  828. $type: "h3",
  829. class: "mdc-list-group__subheader mdc-list-item__text mdc-typography--button",
  830. $text: "Node methods"
  831. },
  832. {
  833. $cell: true,
  834. $type: "ul",
  835. class: "mdc-list",
  836. $components: Object.entries(this._getNodeMethods()).map(this._listElement)
  837. }, listDivider,
  838. {
  839. $type: "h3",
  840. class: "mdc-list-group__subheader mdc-list-item__text mdc-typography--button",
  841. $text: "Proto methods"
  842. },
  843. {
  844. $cell: true,
  845. $type: "ul",
  846. class: "mdc-list",
  847. $components: Object.entries(this._getProtoNodeMethods()).map(this._listElement)
  848. }
  849. ]
  850. }
  851. ]
  852. },
  853. {
  854. $cell: true,
  855. $type: "div",
  856. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-9",
  857. $components: [
  858. {
  859. $cell: true,
  860. class: "aceEditor",
  861. id: "aceEditor",
  862. $type: "div",
  863. $text: this._method.body,
  864. $init: function () {
  865. createAceEditor(self, this._editorNode);
  866. }
  867. }
  868. ]
  869. }
  870. ]
  871. }
  872. ]
  873. //$components:
  874. }
  875. }
  876. let propWindow = {
  877. $cell: true,
  878. $type: "div",
  879. class: "propGrid mdc-layout-grid max-width mdc-layout-grid--align-left",
  880. style: "overflow-y: scroll; max-height: 800px;",
  881. $components: [
  882. {
  883. $type: "div",
  884. class: "mdc-layout-grid__inner",
  885. $components: [
  886. {
  887. $cell: true,
  888. $type: "div",
  889. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12",
  890. $components: [
  891. nodesCell
  892. ]
  893. }
  894. ]
  895. }
  896. // <button class="mdc-button">
  897. // Flat button
  898. // </button>
  899. ]
  900. }
  901. let clientListCell = {
  902. $cell: true,
  903. $type: "div",
  904. class: "mdc-list",
  905. id: "clientsList",
  906. _watchNodes: [],
  907. _listElement: function (m) {
  908. return {
  909. $type: "a",
  910. class: "mdc-list-item",
  911. $href: "#",
  912. $text: m.name,
  913. onclick: function (e) {
  914. //self.currentNodeID = m.ID;
  915. //document.querySelector('#currentNode')._setNode(m.ID);
  916. }
  917. }
  918. },
  919. $init: function () {
  920. var t = this;
  921. setInterval(function () {
  922. t._updateMe();
  923. }, 1000);
  924. },
  925. _updateMe: function () {
  926. this._watchNodes = self.nodes["http://vwf.example.com/clients.vwf"].children.slice()
  927. },
  928. $update: function () {
  929. //this._clientNodes
  930. this.$components = this._watchNodes.map(this._listElement)
  931. }
  932. }
  933. //createCellWindow("clientsWindow", clientListCell, "Clients");
  934. //createCellWindow("propWindow", propWindow, "Scene");
  935. createCellWindow("codeEditorWindow", codeEditorWindow, "Code editor");
  936. let viewSceneProps = {
  937. $cell: true,
  938. $type: "div",
  939. class: "propGrid mdc-layout-grid mdc-layout-grid--align-left",
  940. //style: "overflow-y: scroll; max-height: 500px; overflow-x: hidden;",
  941. $components:[
  942. {
  943. $type: "div",
  944. class: "mdc-layout-grid__inner",
  945. $components: [
  946. {
  947. $cell: true,
  948. $type: "div",
  949. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12",
  950. $components: [
  951. nodesCell
  952. ]
  953. }
  954. ]
  955. }
  956. ]
  957. }
  958. let sideBar = {
  959. $cell: true,
  960. $type: "div",
  961. id: 'sideBar',
  962. class: "sideBar mdc-toolbar-fixed-adjust",
  963. _sideBarComponent: {},
  964. _sideCurrentNode: '',
  965. $init: function(){
  966. this.style.visibility = 'hidden';
  967. },
  968. $update: function(){
  969. this.$components = [
  970. {
  971. $cell: true,
  972. $type: "button",
  973. class: "mdc-button mdc-button--compact",
  974. $text: "X",
  975. onclick: function (e) {
  976. document.querySelector('#sideBar').style.visibility = 'hidden';
  977. }
  978. },
  979. this._sideBarComponent
  980. ]
  981. }
  982. //$components: [this._sideComponents]
  983. }
  984. document.querySelector('#' + 'sideBar').$cell(sideBar)
  985. let drawerCell = {
  986. $cell: true,
  987. $type: "nav",
  988. class: "mdc-temporary-drawer__drawer",
  989. $components: [
  990. {
  991. $cell: true,
  992. $type: "header",
  993. class: "mdc-temporary-drawer__header",
  994. $components: [
  995. {
  996. $cell: true,
  997. $type: "div",
  998. class: "mdc-temporary-drawer__header-content mdc-theme--primary-bg mdc-theme--text-primary-on-primary",
  999. $text: "Home"
  1000. }
  1001. ]
  1002. },
  1003. {
  1004. $cell: true,
  1005. $type: "nav",
  1006. class: "mdc-temporary-drawer__content mdc-list-group",
  1007. $components: [
  1008. {
  1009. $cell: true,
  1010. $type: "div",
  1011. class: "mdc-list",
  1012. $components: [
  1013. {
  1014. $cell: true,
  1015. $type: "a",
  1016. class: "mdc-list-item",
  1017. $href: "#",
  1018. onclick: function (e) {
  1019. let sideBar = document.querySelector('#sideBar');
  1020. sideBar._sideBarComponent = viewSceneProps;
  1021. let currentNode = document.querySelector('#sideBar')._sideCurrentNode;
  1022. currentNode == '' ? document.querySelector('#sideBar')._sideCurrentNode = (vwf_view.kernel.find("", "/")[0]) :
  1023. document.querySelector('#sideBar')._sideCurrentNode = currentNode;
  1024. document.querySelector('#sideBar').style.visibility = 'visible';
  1025. drawer.open = !drawer.open
  1026. // let currentNode = document.querySelector('#currentNode')._currentNode;
  1027. // currentNode == '' ? document.querySelector('#currentNode')._setNode(vwf_view.kernel.find("", "/")[0]) :
  1028. // document.querySelector('#currentNode')._setNode(currentNode);
  1029. },
  1030. $components: [{
  1031. $cell: true,
  1032. $type: "i",
  1033. class: "material-icons mdc-list-item__start-detail",
  1034. $text: "description"
  1035. },
  1036. {
  1037. $text: "Scene"
  1038. }
  1039. ]
  1040. },
  1041. {
  1042. $cell: true,
  1043. $type: "a",
  1044. class: "mdc-list-item",
  1045. $href: "#",
  1046. onclick: function (e) {
  1047. //self.currentNodeID = m.ID;
  1048. // document.querySelector('#clientsList')._setClientNodes(self.nodes["http://vwf.example.com/clients.vwf"]);
  1049. // document.querySelector('#clientsWindow').style.visibility = 'visible';
  1050. let sideBar = document.querySelector('#sideBar');
  1051. sideBar._sideBarComponent = avatarSettings;
  1052. drawer.open = !drawer.open
  1053. document.querySelector('#sideBar').style.visibility = 'visible';
  1054. },
  1055. $components: [{
  1056. $type: "i",
  1057. class: "material-icons mdc-list-item__start-detail",
  1058. 'aria-hidden': "true",
  1059. $text: "account_circle"
  1060. },
  1061. {
  1062. $text: "My Avatar"
  1063. }]
  1064. },
  1065. {
  1066. $cell: true,
  1067. $type: "a",
  1068. class: "mdc-list-item",
  1069. $href: "#",
  1070. onclick: function (e) {
  1071. //self.currentNodeID = m.ID;
  1072. // document.querySelector('#clientsList')._setClientNodes(self.nodes["http://vwf.example.com/clients.vwf"]);
  1073. let sideBar = document.querySelector('#sideBar');
  1074. sideBar._sideBarComponent = viewSettings;
  1075. drawer.open = !drawer.open
  1076. document.querySelector('#sideBar').style.visibility = 'visible';
  1077. },
  1078. $components: [{
  1079. $type: "i",
  1080. class: "material-icons mdc-list-item__start-detail",
  1081. 'aria-hidden': "true",
  1082. $text: "settings"
  1083. },
  1084. {
  1085. $text: "Settings"
  1086. }]
  1087. },
  1088. {
  1089. $cell: true,
  1090. $type: "a",
  1091. class: "mdc-list-item",
  1092. $href: "#",
  1093. onclick: function (e) {
  1094. //self.currentNodeID = m.ID;
  1095. // document.querySelector('#clientsList')._setClientNodes(self.nodes["http://vwf.example.com/clients.vwf"]);
  1096. let sideBar = document.querySelector('#sideBar');
  1097. sideBar._sideBarComponent = loadSaveSettings;
  1098. //document.querySelector("#fileNameTitle").$text = '';
  1099. drawer.open = !drawer.open
  1100. document.querySelector('#sideBar').style.visibility = 'visible';
  1101. },
  1102. $components: [{
  1103. $type: "i",
  1104. class: "material-icons mdc-list-item__start-detail",
  1105. 'aria-hidden': "true",
  1106. $text: "save"
  1107. },
  1108. {
  1109. $text: "Load/Save"
  1110. }]
  1111. },
  1112. {
  1113. $cell: true,
  1114. $type: "a",
  1115. class: "mdc-list-item",
  1116. $href: "#",
  1117. onclick: function (e) {
  1118. // var currentNode = document.querySelector('#currentNode')._currentNode;
  1119. // if (currentNode == '') {
  1120. // currentNode = vwf_view.kernel.find("", "/")[0];
  1121. // }
  1122. document.querySelector('#liveCodeEditor')._setNode(vwf_view.kernel.find("", "/")[0]);
  1123. //createAceEditor(self, currentNode);
  1124. document.querySelector('#codeEditorWindow').style.visibility = 'visible';
  1125. },
  1126. $components: [{
  1127. $type: "i",
  1128. class: "material-icons mdc-list-item__start-detail",
  1129. 'aria-hidden': "true",
  1130. $text: "code"
  1131. },
  1132. {
  1133. $text: "Code editor"
  1134. }]
  1135. }
  1136. ]
  1137. },
  1138. {
  1139. $cell: true,
  1140. $type: "hr",
  1141. class: "mdc-list-divider",
  1142. },
  1143. {
  1144. $cell: true,
  1145. $type: "h3",
  1146. class: "userList mdc-list-group__subheader",
  1147. $text: "Users online"
  1148. },
  1149. clientListCell
  1150. ]
  1151. }
  1152. // {
  1153. // $cell: true,
  1154. // $type: "div",
  1155. // class: "mdc-persistent-drawer__toolbar-spacer",
  1156. // },
  1157. // {
  1158. // $cell: true,
  1159. // $type: "div",
  1160. // class: "mdc-list-group",
  1161. // $components: [{
  1162. // $cell: true,
  1163. // $type: "nav",
  1164. // class: "mdc-list",
  1165. // $components: [
  1166. // ]
  1167. // }]
  1168. // }
  1169. ]
  1170. };
  1171. // <div class="mdc-form-field">
  1172. // <input type="checkbox" id="input">
  1173. // <label for="input">Input Label</label>
  1174. // </div>
  1175. document.querySelector("#drawer").$cell({
  1176. $cell: true,
  1177. $type: "aside",
  1178. class: "mdc-temporary-drawer",
  1179. $components: [drawerCell]
  1180. }
  1181. );
  1182. let toolbar = {
  1183. $cell: true,
  1184. $type: "div",
  1185. class: "mdc-toolbar__row",
  1186. $components: [{
  1187. $type: "section",
  1188. class: "mdc-toolbar__section mdc-toolbar__section--align-start",
  1189. $components: [
  1190. {
  1191. $type: "button",
  1192. class: "demo-menu material-icons mdc-toolbar__icon--menu",
  1193. $text: "menu"
  1194. },
  1195. {
  1196. $type: "span",
  1197. class: "mdc-toolbar__title catalog-title",
  1198. $text: "LiveCoding.space"
  1199. }
  1200. ]
  1201. }]
  1202. };
  1203. document.querySelector("#toolbar").$cell({
  1204. $cell: true,
  1205. $type: "div",
  1206. class: "mdc-toolbar mdc-toolbar--fixed",
  1207. $components: [toolbar]
  1208. }
  1209. );
  1210. // let drawer = new mdc.drawer.MDCTemporaryDrawer(document.querySelector('.mdc-temporary-drawer'));
  1211. // document.querySelector('.menu').addEventListener('click', () => drawer.open = true);
  1212. var drawerEl = document.querySelector('.mdc-temporary-drawer');
  1213. var MDCTemporaryDrawer = mdc.drawer.MDCTemporaryDrawer;
  1214. var drawer = new MDCTemporaryDrawer(drawerEl);
  1215. document.querySelector('.demo-menu').addEventListener('click', function () {
  1216. //self.currentNodeID = (self.currentNodeID == '') ? (vwf_view.kernel.find("", "/")[0]) : self.currentNodeID;
  1217. // let currentNode = document.querySelector('#currentNode')._currentNode;
  1218. // currentNode == '' ? document.querySelector('#currentNode')._setNode(vwf_view.kernel.find("", "/")[0]) :
  1219. // document.querySelector('#currentNode')._setNode(currentNode);
  1220. //document.querySelector('#currentNode')._setNode(self.currentNodeID);
  1221. drawer.open = !drawer.open;
  1222. });
  1223. drawerEl.addEventListener('MDCTemporaryDrawer:open', function () {
  1224. //console.log('Received MDCPersistentDrawer:open');
  1225. });
  1226. drawerEl.addEventListener('MDCTemporaryDrawer:close', function () {
  1227. //console.log('Received MDCPersistentDrawer:close');
  1228. });
  1229. //==============
  1230. $('#tabs').stop().animate({ opacity: 0.0 }, 0);
  1231. $('#tabs').mouseenter(function (evt) {
  1232. evt.stopPropagation();
  1233. $('#tabs').stop().animate({ opacity: 1.0 }, 175);
  1234. return false;
  1235. });
  1236. $('#tabs').mouseleave(function (evt) {
  1237. evt.stopPropagation();
  1238. $('#tabs').stop().animate({ opacity: 0.0 }, 175);
  1239. return false;
  1240. });
  1241. $('#hierarchy').click(function (evt) {
  1242. openEditor.call(self, 1);
  1243. });
  1244. $('#userlist').click(function (evt) {
  1245. openEditor.call(self, 2);
  1246. });
  1247. $('#timeline').click(function (evt) {
  1248. openEditor.call(self, 3);
  1249. });
  1250. $('#about').click(function (evt) {
  1251. openEditor.call(self, 4);
  1252. });
  1253. $('#models').click(function (evt) {
  1254. openEditor.call(self, 5);
  1255. });
  1256. $('#codeEditor').click(function (evt) {
  1257. openEditor.call(self, 6);
  1258. });
  1259. $('#x').click(function (evt) {
  1260. closeEditor.call(self);
  1261. });
  1262. $('#topdown_a').hide();
  1263. $('#topdown_b').hide();
  1264. $('#client_list').hide();
  1265. $('#time_control').hide();
  1266. $('#about_tab').hide();
  1267. $('#codeEditor_tab').hide();
  1268. $('#model_a').hide();
  1269. $('#model_b').hide();
  1270. var canvas = document.getElementById(vwf_view.kernel.find("", "/")[0]);
  1271. if (canvas) {
  1272. $('#topdown_a').height(canvas.height);
  1273. $('#topdown_b').height(canvas.height);
  1274. $('#client_list').height(canvas.height);
  1275. $('#time_control').height(canvas.height);
  1276. $('#about_tab').height(canvas.height);
  1277. $('#codeEditor_tab').height(canvas.height);
  1278. $('#model_a').height(canvas.height);
  1279. $('#model_b').height(canvas.height);
  1280. }
  1281. else {
  1282. $('#topdown_a').height(window.innerHeight - 20);
  1283. $('#topdown_b').height(window.innerHeight - 20);
  1284. $('#client_list').height(window.innerHeight - 20);
  1285. $('#time_control').height(window.innerHeight - 20);
  1286. $('#about_tab').height(window.innerHeight - 20);
  1287. $('#codeEditor_tab').height(window.innerHeight - 20);
  1288. $('#model_a').height(window.innerHeight - 20);
  1289. $('#model_b').height(window.innerHeight - 20);
  1290. }
  1291. },
  1292. createdNode: function (nodeID, childID, childExtendsID, childImplementsIDs,
  1293. childSource, childType, childIndex, childName, callback /* ( ready ) */) {
  1294. var nodeIDAttribute = $.encoder.encodeForHTMLAttribute("id", nodeID, true);
  1295. var childIDAttribute = $.encoder.encodeForHTMLAttribute("id", childID, true);
  1296. var childIDAlpha = $.encoder.encodeForAlphaNumeric(childID);
  1297. var kernel = this.kernel;
  1298. var self = this;
  1299. var parent = this.nodes[nodeID];
  1300. var node = this.nodes[childID] = {
  1301. children: [],
  1302. properties: [],
  1303. events: {},
  1304. methods: {},
  1305. parent: parent,
  1306. parentID: nodeID,
  1307. ID: childID,
  1308. extendsID: childExtendsID,
  1309. implementsIDs: childImplementsIDs,
  1310. source: childSource,
  1311. name: childName,
  1312. };
  1313. if (parent) {
  1314. parent.children.push(node);
  1315. }
  1316. if (childID == vwf_view.kernel.find("", "/")[0] && childExtendsID && this.kernel.test(childExtendsID,
  1317. "self::element(*,'http://vwf.example.com/aframe/ascene.vwf')", childExtendsID)) {
  1318. this.scenes[childID] = node;
  1319. }
  1320. if (nodeID === this.currentNodeID && this.editingScript == false) {
  1321. $('#children > div:last').css('border-bottom-width', '1px');
  1322. $("#children").append("<div id='" + childIDAlpha + "' data-nodeID='" + childIDAttribute + "' class='childContainer'><div class='childEntry'><b>" + $.encoder.encodeForHTML(childName) + "</b></div></div>");
  1323. $('#' + childIDAlpha).click(function (evt) {
  1324. drillDown.call(self, $(this).attr("data-nodeID"), nodeIDAttribute);
  1325. });
  1326. $('#children > div:last').css('border-bottom-width', '3px');
  1327. }
  1328. if (nodeID === this.kernel.application() && childName === 'camera') {
  1329. this.activeCameraID = childID;
  1330. }
  1331. let nodeCell = document.querySelector("#currentNode");
  1332. if (nodeCell !== null) {
  1333. if (nodeCell._currentNode === nodeID) {
  1334. nodeCell._getChildNodes();
  1335. }
  1336. }
  1337. if (nodeID === this.kernel.application()) {
  1338. // document.querySelector('a-scene').classList.add("mdc-toolbar-fixed-adjust");
  1339. document.querySelector('body').classList.add("editor-body");
  1340. }
  1341. },
  1342. createdProperty: function (nodeID, propertyName, propertyValue) {
  1343. return this.initializedProperty(nodeID, propertyName, propertyValue);
  1344. },
  1345. initializedProperty: function (nodeID, propertyName, propertyValue) {
  1346. var node = this.nodes[nodeID];
  1347. if (!node) return; // TODO: patch until full-graph sync is working; drivers should be able to assume that nodeIDs refer to valid objects
  1348. var property = node.properties[propertyName] = createProperty.call(this, node, propertyName, propertyValue);
  1349. node.properties.push(property);
  1350. },
  1351. deletedNode: function (nodeID) {
  1352. var node = this.nodes[nodeID];
  1353. node.parent.children.splice(node.parent.children.indexOf(node), 1);
  1354. delete this.nodes[nodeID];
  1355. var nodeIDAttribute = $.encoder.encodeForAlphaNumeric(nodeID); // $.encoder.encodeForHTMLAttribute("id", nodeID, true);
  1356. $('#' + nodeIDAttribute).remove();
  1357. $('#children > div:last').css('border-bottom-width', '3px');
  1358. let nodeCell = document.querySelector("#currentNode");
  1359. if (nodeCell) {
  1360. if (nodeCell._currentNode !== "") {
  1361. if (nodeCell._currentNode !== nodeID && (this.nodes[nodeID] !== undefined)) {
  1362. nodeCell._getChildNodes();
  1363. } else {
  1364. nodeCell._setNode(vwf_view.kernel.find("", "/")[0]);
  1365. nodeCell._getChildNodes();
  1366. }
  1367. }
  1368. }
  1369. },
  1370. //addedChild: [ /* nodeID, childID, childName */ ],
  1371. //removedChild: [ /* nodeID, childID */ ],
  1372. satProperty: function (nodeID, propertyName, propertyValue) {
  1373. var node = this.nodes[nodeID];
  1374. if (!node) return; // TODO: patch until full-graph sync is working; drivers should be able to assume that nodeIDs refer to valid objects
  1375. // It is possible for a property to have satProperty called for it without ever getting an
  1376. // initializedProperty (if that property delegated to itself or another on replication)
  1377. // Catch that case here and create the property
  1378. if (!node.properties[propertyName]) {
  1379. var property = node.properties[propertyName] = createProperty.call(this, node, propertyName, propertyValue);
  1380. node.properties.push(property);
  1381. }
  1382. if (propertyName === "activeCamera") {
  1383. if (this.nodes[propertyValue] !== undefined) {
  1384. this.activeCameraID = propertyValue;
  1385. }
  1386. }
  1387. try {
  1388. propertyValue = utility.transform(propertyValue, utility.transforms.transit);
  1389. node.properties[propertyName].value = JSON.stringify(propertyValue);
  1390. node.properties[propertyName].rawValue = propertyValue;
  1391. } catch (e) {
  1392. this.logger.warnx("satProperty", nodeID, propertyName, propertyValue,
  1393. "stringify error:", e.message);
  1394. node.properties[propertyName].value = propertyValue;
  1395. }
  1396. if ((this.editorView == 1) && (this.currentNodeID == nodeID)) {
  1397. var nodeIDAttribute = $.encoder.encodeForAlphaNumeric(nodeID); // $.encoder.encodeForHTMLAttribute("id", nodeID, true);
  1398. var propertyNameAttribute = $.encoder.encodeForAlphaNumeric("id", propertyName, true);
  1399. // No need to escape propertyValue, because .val does its own escaping
  1400. $('#input-' + nodeIDAttribute + '-' + propertyNameAttribute).val(node.properties[propertyName].getValue());
  1401. }
  1402. let propCell = document.querySelector("#currentNode #prop-" + propertyName);
  1403. if (propCell !== null) {
  1404. if (propCell._currentNode == nodeID) {
  1405. propCell.value = node.properties[propertyName].getValue();
  1406. }
  1407. }
  1408. },
  1409. //gotProperty: [ /* nodeID, propertyName, propertyValue */ ],
  1410. createdMethod: function (nodeID, methodName, methodParameters, methodBody) {
  1411. var node = this.nodes[nodeID];
  1412. if (node) {
  1413. node.methods[methodName] = methodParameters;
  1414. }
  1415. },
  1416. //calledMethod: function( nodeID, methodName, methodParameters, methodValue ) {
  1417. //},
  1418. createdEvent: function (nodeID, eventName, eventParameters) {
  1419. var node = this.nodes[nodeID];
  1420. if (node) {
  1421. node.events[eventName] = eventParameters;
  1422. }
  1423. },
  1424. firedEvent: function (nodeID, eventName, eventParameters) {
  1425. if (eventName == "pointerHover") {
  1426. highlightChildInHierarchy.call(this, nodeID);
  1427. }
  1428. },
  1429. executed: function (nodeID, scriptText, scriptType) {
  1430. // var nodeScript = {
  1431. // text: scriptText,
  1432. // type: scriptType,
  1433. // };
  1434. // if ( !this.allScripts[ nodeID ] ) {
  1435. // var nodeScripts = new Array();
  1436. // nodeScripts.push(nodeScript);
  1437. // this.allScripts[ nodeID ] = nodeScripts;
  1438. // }
  1439. // else {
  1440. // this.allScripts[ nodeID ].push(nodeScript);
  1441. // }
  1442. },
  1443. //ticked: [ /* time */ ],
  1444. });
  1445. function createCellWindow(elementID, cellNode, title) {
  1446. document.querySelector('#' + elementID).$cell({
  1447. $cell: true,
  1448. $type: "div",
  1449. id: elementID,
  1450. class: 'draggable',
  1451. $init: function () {
  1452. // let draggie = new Draggabilly('.draggable', {
  1453. // handle: '.handle',
  1454. // containment: true
  1455. // });
  1456. // get all draggie elements
  1457. var draggableElems = document.querySelectorAll('.draggable');
  1458. // array of Draggabillies
  1459. var draggies = []
  1460. // init Draggabillies
  1461. for (var i = 0, len = draggableElems.length; i < len; i++) {
  1462. var draggableElem = draggableElems[i];
  1463. var draggie = new Draggabilly(draggableElem, {
  1464. handle: '.handle',
  1465. containment: true
  1466. });
  1467. draggies.push(draggie);
  1468. }
  1469. this.style.visibility = 'hidden';
  1470. },
  1471. $components: [
  1472. {
  1473. $cell: true,
  1474. $type: "div",
  1475. class: "handle",
  1476. $components: [
  1477. {
  1478. $cell: true,
  1479. $type: "button",
  1480. class: "mdc-button mdc-button--compact",
  1481. $text: "X",
  1482. onclick: function (e) {
  1483. //self.currentNodeID = m.ID;
  1484. document.querySelector('#' + elementID).style.visibility = 'hidden';
  1485. }
  1486. },
  1487. {
  1488. $cell: true,
  1489. $type: "span",
  1490. class: "mdc-typography--button",
  1491. $text: title
  1492. }
  1493. ]
  1494. },
  1495. cellNode,
  1496. {
  1497. $cell: true,
  1498. $type: "div",
  1499. class: "handle",
  1500. style: "height: 10px; width: inherit;",
  1501. //$text: "sdfsdf"
  1502. }
  1503. // { $text: "23423"}
  1504. ]
  1505. }
  1506. );
  1507. }
  1508. // -- getChildByName --------------------------------------------------------------------
  1509. function getChildByName(node, childName) {
  1510. var childNode = undefined;
  1511. for (var i = 0; i < node.children.length && childNode === undefined; i++) {
  1512. if (node.children[i].name == childName) {
  1513. childNode = node.children[i];
  1514. }
  1515. }
  1516. return childNode;
  1517. };
  1518. function updateCameraProperties() {
  1519. if (this.currentNodeID == this.activeCameraID) {
  1520. if (!this.intervalTimer) {
  1521. var self = this;
  1522. this.intervalTimer = setInterval(function () { updateProperties.call(self, self.activeCameraID) }, 200);
  1523. }
  1524. }
  1525. else {
  1526. if (this.intervalTimer) {
  1527. clearInterval(this.intervalTimer);
  1528. this.intervalTimer = 0;
  1529. }
  1530. }
  1531. }
  1532. function updateProperties(nodeName) {
  1533. var nodeID = nodeName;
  1534. var properties = getProperties.call(this, this.kernel, nodeID);
  1535. for (var i in properties) {
  1536. try {
  1537. var propertyName = properties[i].prop.name;
  1538. var propertyValue = JSON.stringify(utility.transform(vwf.getProperty(nodeID, propertyName, []), utility.transforms.transit));
  1539. } catch (e) {
  1540. this.logger.warnx("satProperty", nodeID, propertyName, propertyValue, "stringify error:", e.message);
  1541. }
  1542. if (propertyValue) {
  1543. var nodeIDAttribute = $.encoder.encodeForAlphaNumeric(nodeID);
  1544. var propertyNameAttribute = $.encoder.encodeForHTMLAttribute("id", propertyName, true);
  1545. var inputElement$ = $('#input-' + nodeIDAttribute + '-' + propertyNameAttribute);
  1546. // Only update if property value input is not in focus
  1547. // If in focus, change font style to italic
  1548. if (!inputElement$.is(":focus")) {
  1549. inputElement$.val(propertyValue);
  1550. inputElement$.css("font-style", "normal");
  1551. } else {
  1552. inputElement$.css("font-style", "italic");
  1553. }
  1554. }
  1555. }
  1556. }
  1557. // -- openEditor ------------------------------------------------------------------------
  1558. function openEditor(eView) // invoke with the view as "this"
  1559. {
  1560. if (eView == 0) {
  1561. closeEditor.call(this);
  1562. }
  1563. if (this.editorView != eView) {
  1564. // Hierarchy
  1565. if (eView == 1) {
  1566. var topdownName = this.topdownName;
  1567. var topdownTemp = this.topdownTemp;
  1568. if (!this.currentNodeID) {
  1569. this.currentNodeID = vwf_view.kernel.find("", "/")[0];
  1570. }
  1571. drill.call(this, this.currentNodeID, undefined);
  1572. $(this.clientList).hide();
  1573. $(this.timeline).hide();
  1574. $(this.about).hide();
  1575. $(this.codeEditor).hide();
  1576. $(this.models).hide();
  1577. if (this.editorOpen) {
  1578. $(topdownName).hide();
  1579. $(topdownTemp).show();
  1580. }
  1581. else {
  1582. $(topdownTemp).show('slide', { direction: 'right' }, 175);
  1583. }
  1584. this.topdownName = topdownTemp;
  1585. this.topdownTemp = topdownName;
  1586. }
  1587. else if (this.editingScript) {
  1588. // Reset width if on script
  1589. this.editingScript = false;
  1590. $('#editor').animate({ 'left': "-260px" }, 175);
  1591. $('.vwf-tree').animate({ 'width': "260px" }, 175);
  1592. }
  1593. // User List
  1594. if (eView == 2) {
  1595. $(this.topdownName).hide();
  1596. $(this.topdownTemp).hide();
  1597. $(this.timeline).hide();
  1598. $(this.about).hide();
  1599. $(this.codeEditor).hide();
  1600. $(this.models).hide();
  1601. $(this.modelsTemp).hide();
  1602. showUserList.call(this);
  1603. }
  1604. // Timeline
  1605. else if (eView == 3) {
  1606. $(this.topdownName).hide();
  1607. $(this.topdownTemp).hide();
  1608. $(this.clientList).hide();
  1609. $(this.about).hide();
  1610. $(this.codeEditor).hide();
  1611. $(this.models).hide();
  1612. $(this.modelsTemp).hide();
  1613. showTimeline.call(this);
  1614. }
  1615. // About
  1616. else if (eView == 4) {
  1617. $(this.topdownName).hide();
  1618. $(this.topdownTemp).hide();
  1619. $(this.clientList).hide();
  1620. $(this.timeline).hide();
  1621. $(this.models).hide();
  1622. $(this.modelsTemp).hide();
  1623. $(this.codeEditor).hide();
  1624. showAboutTab.call(this);
  1625. }
  1626. // Models
  1627. else if (eView == 5) {
  1628. var models = this.models;
  1629. var modelsTemp = this.modelsTemp;
  1630. showModelsTab.call(this, this.currentModelID, this.currentModelURL);
  1631. $(this.topdownName).hide();
  1632. $(this.topdownTemp).hide();
  1633. $(this.clientList).hide();
  1634. $(this.timeline).hide();
  1635. $(this.about).hide();
  1636. $(this.codeEditor).hide();
  1637. if (this.editorOpen) {
  1638. $(models).hide();
  1639. $(modelsTemp).show();
  1640. }
  1641. else {
  1642. $(modelsTemp).show('slide', { direction: 'right' }, 175);
  1643. }
  1644. this.models = modelsTemp;
  1645. this.modelsTemp = models;
  1646. }
  1647. // Code Editor
  1648. else if (eView == 6) {
  1649. $(this.topdownName).hide();
  1650. $(this.topdownTemp).hide();
  1651. $(this.clientList).hide();
  1652. $(this.timeline).hide();
  1653. $(this.models).hide();
  1654. $(this.modelsTemp).hide();
  1655. $(this.about).hide();
  1656. showCodeEditorTab.call(this);
  1657. }
  1658. if (this.editorView == 0) {
  1659. $('#vwf-root').animate({ 'left': "-=260px" }, 175);
  1660. $('#editor').animate({ 'left': "-260px" }, 175);
  1661. $('#x').delay(1000).css({ 'display': 'inline' });
  1662. }
  1663. this.editorView = eView;
  1664. this.editorOpen = true;
  1665. }
  1666. }
  1667. // -- closeEditor -----------------------------------------------------------------------
  1668. function closeEditor() // invoke with the view as "this"
  1669. {
  1670. var topdownName = this.topdownName;
  1671. if (this.editorOpen && this.editorView == 1) // Hierarchy view open
  1672. {
  1673. $(topdownName).hide('slide', { direction: 'right' }, 175);
  1674. $(topdownName).empty();
  1675. $(this.clientList).hide();
  1676. $(this.timeline).hide();
  1677. $(this.about).hide();
  1678. $(this.codeEditor).hide();
  1679. $(this.models).hide();
  1680. }
  1681. else if (this.editorOpen && this.editorView == 2) // Client list open
  1682. {
  1683. $(this.clientList).hide('slide', { direction: 'right' }, 175);
  1684. $(topdownName).hide();
  1685. $(this.timeline).hide();
  1686. $(this.about).hide();
  1687. $(this.codeEditor).hide();
  1688. $(this.models).hide();
  1689. }
  1690. else if (this.editorOpen && this.editorView == 3) // Timeline open
  1691. {
  1692. $(this.timeline).hide('slide', { direction: 'right' }, 175);
  1693. $(topdownName).hide();
  1694. $(this.clientList).hide();
  1695. $(this.about).hide();
  1696. $(this.models).hide();
  1697. }
  1698. else if (this.editorOpen && this.editorView == 4) // About open
  1699. {
  1700. $(this.about).hide('slide', { direction: 'right' }, 175);
  1701. $(this.codeEditor).hide();
  1702. $(topdownName).hide();
  1703. $(this.clientList).hide();
  1704. $(this.timeline).hide();
  1705. $(this.models).hide();
  1706. }
  1707. else if (this.editorOpen && this.editorView == 5) // Models open
  1708. {
  1709. $(this.models).hide('slide', { direction: 'right' }, 175);
  1710. $(topdownName).hide();
  1711. $(this.clientList).hide();
  1712. $(this.timeline).hide();
  1713. $(this.about).hide();
  1714. $(this.codeEditor).hide();
  1715. }
  1716. else if (this.editorOpen && this.editorView == 6) // Code Editor open
  1717. {
  1718. $(this.codeEditor).hide('slide', { direction: 'right' }, 175);
  1719. $(this.about).hide();
  1720. $(topdownName).hide();
  1721. $(this.clientList).hide();
  1722. $(this.timeline).hide();
  1723. $(this.models).hide();
  1724. }
  1725. $('#vwf-root').animate({ 'left': "+=260px" }, 175);
  1726. $('#editor').animate({ 'left': "0px" }, 175);
  1727. $('#x').css({ 'display': 'none' });
  1728. this.editorView = 0;
  1729. this.editorOpen = false;
  1730. }
  1731. // -- showUserList ----------------------------------------------------------------------
  1732. function showUserList() // invoke with the view as "this"
  1733. {
  1734. var clientList = this.clientList;
  1735. viewClients.call(this);
  1736. if (!this.editorOpen) {
  1737. $(clientList).show('slide', { direction: 'right' }, 175);
  1738. }
  1739. else {
  1740. $(clientList).show();
  1741. }
  1742. }
  1743. // -- viewClients -----------------------------------------------------------------------
  1744. function viewClients() {
  1745. var self = this;
  1746. var app = window.location.pathname;
  1747. var pathSplit = app.split('/');
  1748. if (pathSplit[0] == "") {
  1749. pathSplit.shift();
  1750. }
  1751. if (pathSplit[pathSplit.length - 1] == "") {
  1752. pathSplit.pop();
  1753. }
  1754. var instIndex = pathSplit.length - 1;
  1755. if (pathSplit.length > 2) {
  1756. if (pathSplit[pathSplit.length - 2] == "load") {
  1757. instIndex = pathSplit.length - 3;
  1758. }
  1759. }
  1760. if (pathSplit.length > 3) {
  1761. if (pathSplit[pathSplit.length - 3] == "load") {
  1762. instIndex = pathSplit.length - 4;
  1763. }
  1764. }
  1765. var root = "";
  1766. for (var i = 0; i < instIndex; i++) {
  1767. if (root != "") {
  1768. root = root + "/";
  1769. }
  1770. root = root + pathSplit[i];
  1771. }
  1772. if (root.indexOf('.vwf') != -1) root = root.substring(0, root.lastIndexOf('/'));
  1773. var clients$ = $(this.clientList);
  1774. var node = this.nodes["http://vwf.example.com/clients.vwf"];
  1775. clients$.html("<div class='header'>Connected Clients</div>");
  1776. // Add node children
  1777. clients$.append("<div id='clientsChildren'></div>");
  1778. for (var i = 0; i < node.children.length; i++) {
  1779. var nodeChildIDAttribute = $.encoder.encodeForHTMLAttribute("id", node.children[i].ID, true);
  1780. var nodeChildIDAlpha = $.encoder.encodeForAlphaNumeric(node.children[i].ID);
  1781. var nodeChildNameHTML = $.encoder.encodeForHTML(node.children[i].name);
  1782. $('#clientsChildren').append("<div id='" + nodeChildIDAlpha + "' data-nodeID='" + nodeChildIDAttribute + "' class='childContainer'><div class='childEntry'><b>" + nodeChildNameHTML + "</b></div></div>");
  1783. $('#' + nodeChildIDAlpha).click(function (evt) {
  1784. viewClient.call(self, $(this).attr("data-nodeID"));
  1785. });
  1786. }
  1787. // Login Information
  1788. clients$.append("<div style='padding:6px'><input class='filename_entry' type='text' id='userName' placeholder='Username' /><!-- <input class='filename_entry' type='password' id='password' placeholder='Password'/> --><input class='update_button' type='button' id='login' value='Login' /></div>");
  1789. clients$.append("<hr/>");
  1790. $('#userName').keydown(function (evt) {
  1791. evt.stopPropagation();
  1792. });
  1793. $('#userName').keypress(function (evt) {
  1794. evt.stopPropagation();
  1795. });
  1796. $('#userName').keyup(function (evt) {
  1797. evt.stopPropagation();
  1798. });
  1799. $('#password').keydown(function (evt) {
  1800. evt.stopPropagation();
  1801. });
  1802. $('#password').keypress(function (evt) {
  1803. evt.stopPropagation();
  1804. });
  1805. $('#password').keyup(function (evt) {
  1806. evt.stopPropagation();
  1807. });
  1808. $('#login').click(function (evt) {
  1809. // Future call to validate username and password
  1810. //login.call(self, $('#userName').val(), $('#password').val());
  1811. var moniker = vwf_view.kernel.moniker();
  1812. var clients = vwf_view.kernel.findClients("", "/*");
  1813. var client = undefined;
  1814. for (var i = 0; i < clients.length; i++) {
  1815. if (clients[i].indexOf(moniker) != -1) {
  1816. client = clients[i];
  1817. break;
  1818. }
  1819. }
  1820. // var client = vwf_view.kernel.findClients("", "/" + moniker)[0];
  1821. if (client) {
  1822. vwf_view.kernel.setProperty(client, "displayName", $('#userName').val());
  1823. }
  1824. });
  1825. // clients$.append("<div style='padding:6px'><input class='live_button' type='button' id='liveeditor' value='Open Code Editor' /></div>");
  1826. // $('#liveeditor').click(function(evt) {
  1827. // openLiveEditor.call(self);
  1828. // });
  1829. // Save / Load
  1830. clients$.append("<div style='padding:6px'><input class='filename_entry' type='text' id='fileName' /><input class='update_button' type='button' id='save' value='Save' /></div>");
  1831. $('#fileName').keydown(function (evt) {
  1832. evt.stopPropagation();
  1833. });
  1834. $('#fileName').keypress(function (evt) {
  1835. evt.stopPropagation();
  1836. });
  1837. $('#fileName').keyup(function (evt) {
  1838. evt.stopPropagation();
  1839. });
  1840. $('#save').click(function (evt) {
  1841. saveStateAsFile.call(self, $('#fileName').val());
  1842. });
  1843. clients$.append("<div style='padding:6px'><select class='filename_select' id='fileToLoad' /></select></div>");
  1844. $('#fileToLoad').append("<option value='none'></option>");
  1845. $.getJSON("/" + root + "/listallsaves", function (data) {
  1846. $.each(data, function (key, value) {
  1847. var applicationName = value['applicationpath'].split("/");
  1848. if (applicationName.length > 0) {
  1849. applicationName = applicationName[applicationName.length - 1];
  1850. }
  1851. if (applicationName.length > 0) {
  1852. applicationName = applicationName.charAt(0).toUpperCase() + applicationName.slice(1);
  1853. }
  1854. if (value['latestsave']) {
  1855. $('#fileToLoad').append("<option value='" + value['savename'] + "' applicationpath='" + value['applicationpath'] + "'>" + applicationName + ": " + value['savename'] + "</option>");
  1856. }
  1857. else {
  1858. $('#fileToLoad').append("<option value='" + value['savename'] + "' applicationpath='" + value['applicationpath'] + "' revision='" + value['revision'] + "'>" + applicationName + ": " + value['savename'] + " Rev(" + value['revision'] + ")</option>");
  1859. }
  1860. });
  1861. });
  1862. clients$.append("<div style='padding:6px'><input class='update_button' type='button' id='load' value='Load' /></div>");
  1863. $('#load').click(function (evt) {
  1864. loadSavedState.call(self, $('#fileToLoad').val(), $('#fileToLoad').find(':selected').attr('applicationpath'), $('#fileToLoad').find(':selected').attr('revision'));
  1865. });
  1866. }
  1867. // -- editor ---
  1868. function openLiveEditor(value) {
  1869. //this.liveditor = document.createElement('div');
  1870. //this.liveditor.setAttribute('id', "editorlive");
  1871. // $('body').append(this.liveditor);
  1872. var editor = this.ace.edit("editorlive");
  1873. editor.setTheme("ace/theme/monokai");
  1874. editor.getSession().setMode("ace/mode/javascript");
  1875. }
  1876. // -- viewClient ------------------------------------------------------------------------
  1877. function viewClient(clientID) {
  1878. var self = this;
  1879. var clients$ = $(this.clientList);
  1880. var node = this.nodes[clientID];
  1881. clients$.html("<div class='header'><img src='images/back.png' id='back' alt='back'/> " + $.encoder.encodeForHTML(node.name) + "</div>");
  1882. $('#back').click(function (evt) {
  1883. viewClients.call(self);
  1884. });
  1885. // Add node properties
  1886. clients$.append("<div id='clientProperties'></div>");
  1887. var displayedProperties = {};
  1888. for (var i = 0; i < node.properties.length; i++) {
  1889. if (!displayedProperties[node.properties[i].name]) {
  1890. displayedProperties[node.properties[i].name] = "instance";
  1891. var nodeIDAlpha = $.encoder.encodeForAlphaNumeric(clientID);
  1892. var propertyNameAttribute = $.encoder.encodeForHTMLAttribute("id", node.properties[i].name, true);
  1893. var propertyNameAlpha = $.encoder.encodeForAlphaNumeric(node.properties[i].name);
  1894. var propertyNameHTML = $.encoder.encodeForHTML(node.properties[i].name);
  1895. var propertyValueAttribute = $.encoder.encodeForHTMLAttribute("val", node.properties[i].getValue(), true);
  1896. $('#clientProperties').append("<div id='" + nodeIDAlpha + "-" + propertyNameAlpha + "' class='propEntry'><table><tr><td><b>" + propertyNameHTML + " </b></td><td><input type='text' class='input_text' id='input-" + nodeIDAlpha + "-" + propertyNameAlpha + "' value='" + propertyValueAttribute + "' data-propertyName='" + propertyNameAttribute + "' readonly></td></tr></table></div>");
  1897. }
  1898. }
  1899. }
  1900. // -- drillDown -------------------------------------------------------------------------
  1901. function drillDown(nodeID, drillBackID) // invoke with the view as "this"
  1902. {
  1903. var topdownName = this.topdownName;
  1904. var topdownTemp = this.topdownTemp;
  1905. drill.call(this, nodeID, drillBackID);
  1906. if (nodeID != vwf_view.kernel.find("", "/")[0]) $(topdownName).hide('slide', { direction: 'left' }, 175);
  1907. $(topdownTemp).show('slide', { direction: 'right' }, 175);
  1908. this.topdownName = topdownTemp;
  1909. this.topdownTemp = topdownName;
  1910. }
  1911. // -- drillUp ---------------------------------------------------------------------------
  1912. function drillUp(nodeID) // invoke with the view as "this"
  1913. {
  1914. var topdownName = this.topdownName;
  1915. var topdownTemp = this.topdownTemp;
  1916. drill.call(this, nodeID, undefined);
  1917. $(topdownName).hide('slide', { direction: 'right' }, 175);
  1918. $(topdownTemp).show('slide', { direction: 'left' }, 175);
  1919. this.topdownName = topdownTemp;
  1920. this.topdownTemp = topdownName;
  1921. }
  1922. // -- drillBack---------------------------------------------------------------------------
  1923. function drillBack(nodeID) // invoke with the view as "this"
  1924. {
  1925. var topdownName = this.topdownName;
  1926. var topdownTemp = this.topdownTemp;
  1927. drill.call(this, nodeID, undefined);
  1928. // No slide motion, when resizing script window back to normal
  1929. $(topdownName).hide();
  1930. $(topdownTemp).show();
  1931. this.topdownName = topdownTemp;
  1932. this.topdownTemp = topdownName;
  1933. }
  1934. // -- drill -----------------------------------------------------------------------------
  1935. function drill(nodeID, drillBackID) // invoke with the view as "this"
  1936. {
  1937. var node = this.nodes[nodeID];
  1938. if (!node) {
  1939. this.logger.errorx("drill: Cannot find node '" + nodeID + "'");
  1940. return;
  1941. }
  1942. var self = this;
  1943. var topdownName = this.topdownName;
  1944. var topdownTemp = this.topdownTemp;
  1945. var nodeIDAlpha = $.encoder.encodeForAlphaNumeric(nodeID);
  1946. $(topdownName).html(''); // Clear alternate div first to ensure content is added correctly
  1947. this.currentNodeID = nodeID;
  1948. if (!drillBackID) drillBackID = node.parentID;
  1949. if (nodeID == vwf_view.kernel.find("", "/")[0]) {
  1950. $(topdownTemp).html("<div class='header'>index</div>");
  1951. }
  1952. else {
  1953. $(topdownTemp).html("<div class='header'><img src='images/back.png' id='" + nodeIDAlpha + "-back' alt='back'/> " + $.encoder.encodeForHTML(node.name) + "</div>");
  1954. $('#' + nodeIDAlpha + '-back').click(function (evt) {
  1955. drillUp.call(self, drillBackID);
  1956. });
  1957. }
  1958. // Add node children
  1959. $(topdownTemp).append("<div id='children'></div>");
  1960. for (var i = 0; i < node.children.length; i++) {
  1961. var nodeChildIDAttribute = $.encoder.encodeForHTMLAttribute("id", node.children[i].ID, true);
  1962. var nodeChildIDAlpha = $.encoder.encodeForAlphaNumeric(node.children[i].ID);
  1963. $('#children').append("<div id='" + nodeChildIDAlpha + "' data-nodeID='" + nodeChildIDAttribute + "' class='childContainer'><div class='childEntry'><b>" + $.encoder.encodeForHTML(node.children[i].name) + "</b></div></div>");
  1964. $('#' + nodeChildIDAlpha).click(function (evt) {
  1965. drillDown.call(self, $(this).attr("data-nodeID"), nodeID);
  1966. });
  1967. }
  1968. $('#children > div:last').css('border-bottom-width', '3px');
  1969. // Add prototype children
  1970. // TODO: Commented out until prototype children inherit from prototypes
  1971. /*
  1972. $(topdownTemp).append("<div id='prototypeChildren'></div>");
  1973. var prototypeChildren = getChildren.call( this, this.kernel, node.extendsID );
  1974. for ( var key in prototypeChildren)
  1975. {
  1976. var child = prototypeChildren[key];
  1977. var prototypeChildIDAttribute = $.encoder.encodeForHTMLAttribute("id", child.ID, true);
  1978. var prototypeChildIDAlpha = $.encoder.encodeForAlphaNumeric(child.ID);
  1979. $('#prototypeChildren').append("<div id='" + prototypeChildIDAlpha + "' data-nodeID='" + prototypeChildIDAttribute + "' class='childContainer'><div class='childEntry'><b>" + $.encoder.encodeForHTML(child.name) + "</b></div></div>");
  1980. $('#' + prototypeChildIDAlpha).click( function(evt) {
  1981. drillDown.call(self, $(this).attr("data-nodeID"), nodeID);
  1982. });
  1983. }
  1984. */ // END TODO:
  1985. $('#prototypeChildren > div:last').css('border-bottom-width', '3px');
  1986. // Add node properties
  1987. $(topdownTemp).append("<div id='properties'></div>");
  1988. var displayedProperties = {};
  1989. for (var i = 0; i < node.properties.length; i++) {
  1990. if (!displayedProperties[node.properties[i].name] && node.properties[i].name.indexOf('$') === -1) {
  1991. displayedProperties[node.properties[i].name] = "instance";
  1992. var propertyNameAttribute = $.encoder.encodeForHTMLAttribute("id", node.properties[i].name, true);
  1993. var propertyNameAlpha = $.encoder.encodeForAlphaNumeric(node.properties[i].name);
  1994. var propertyNameHTML = $.encoder.encodeForHTML(node.properties[i].name);
  1995. var propertyValueAttribute = $.encoder.encodeForHTMLAttribute("val", node.properties[i].getValue(), true);
  1996. if (propertyNameAlpha.indexOf("semantics") > -1) {
  1997. } else if (propertyNameAlpha.indexOf("grammar") > -1) {
  1998. } else if (propertyNameAlpha.indexOf("ohm") > -1) {
  1999. let propName = propertyNameAlpha;
  2000. let propValue = node.properties[i].rawValue;
  2001. $(topdownTemp).append("<div id='" + nodeIDAlpha + "-" + propertyNameAlpha + "'></div>");
  2002. $('#' + nodeIDAlpha + '-' + propertyNameAlpha).append("<div class='childContainer'><div class='childEntry'><b>" + propertyNameHTML + "</div></div>");
  2003. $('#' + nodeIDAlpha + '-' + propertyNameAlpha).click(function (evt) {
  2004. editOhmLang.call(self, nodeID, propName, propValue);
  2005. });
  2006. // $('#properties').append("<div id='" + nodeIDAlpha + "-" + propertyNameAlpha + "' class='propEntry'><table><tr><td><b>" + propertyNameHTML + " </b></td><td><input type='text' class='input_text' id='input-" + nodeIDAlpha + "-" + propertyNameAlpha + "' value='" + propertyValueAttribute + "' data-propertyName='" + propertyNameAttribute + "'></td></tr></table></div>");
  2007. } else {
  2008. $('#properties').append("<div id='" + nodeIDAlpha + "-" + propertyNameAlpha + "' class='propEntry'><table><tr><td><b>" + propertyNameHTML + " </b></td><td><input type='text' class='input_text' id='input-" + nodeIDAlpha + "-" + propertyNameAlpha + "' value='" + propertyValueAttribute + "' data-propertyName='" + propertyNameAttribute + "'></td></tr></table></div>");
  2009. }
  2010. $('#input-' + nodeIDAlpha + '-' + propertyNameAttribute).change(function (evt) {
  2011. var propName = $.encoder.canonicalize($(this).attr("data-propertyName"));
  2012. var propValue = $(this).val();
  2013. try {
  2014. propValue = JSON.parse($.encoder.canonicalize(propValue));
  2015. self.kernel.setProperty(nodeID, propName, propValue);
  2016. } catch (e) {
  2017. // restore the original value on error
  2018. $(this).val(propValue);
  2019. }
  2020. });
  2021. $('#input-' + nodeIDAlpha + '-' + propertyNameAlpha).keydown(function (evt) {
  2022. evt.stopPropagation();
  2023. });
  2024. $('#input-' + nodeIDAlpha + '-' + propertyNameAlpha).keypress(function (evt) {
  2025. evt.stopPropagation();
  2026. });
  2027. $('#input-' + nodeIDAlpha + '-' + propertyNameAlpha).keyup(function (evt) {
  2028. evt.stopPropagation();
  2029. });
  2030. }
  2031. }
  2032. $('#properties > div:last').css('border-bottom-width', '3px');
  2033. this.logger.info(self + " " + nodeID);
  2034. // Add prototype properties
  2035. $(topdownTemp).append("<div id='prototypeProperties'></div>");
  2036. var prototypeProperties = getProperties.call(this, this.kernel, node.extendsID);
  2037. for (var key in prototypeProperties) {
  2038. var prop = prototypeProperties[key].prop;
  2039. if (!displayedProperties[prop.name]) {
  2040. displayedProperties[prop.name] = prototypeProperties[key].prototype;
  2041. if (prop.value == undefined) {
  2042. prop.value = JSON.stringify(utility.transform(vwf.getProperty(nodeID, prop.name, []), utility.transforms.transit));
  2043. }
  2044. var propertyNameAttribute = $.encoder.encodeForHTMLAttribute("id", prop.name, true);
  2045. var propertyNameAlpha = $.encoder.encodeForAlphaNumeric(prop.name);
  2046. var propertyNameHTML = $.encoder.encodeForHTML(prop.name);
  2047. var propertyValueAttribute = $.encoder.encodeForHTMLAttribute("val", prop.value, true);
  2048. $('#prototypeProperties').append("<div id='" + nodeIDAlpha + "-" + propertyNameAlpha + "' class='propEntry'><table><tr><td><b>" + propertyNameHTML + " </b></td><td><input type='text' class='input_text' id='input-" + nodeIDAlpha + "-" + propertyNameAlpha + "' value='" + propertyValueAttribute + "' data-propertyName='" + propertyNameAttribute + "'></td></tr></table></div>");
  2049. $('#input-' + nodeIDAlpha + '-' + propertyNameAlpha).change(function (evt) {
  2050. var propName = $.encoder.canonicalize($(this).attr("data-propertyName"));
  2051. var propValue = $(this).val();
  2052. try {
  2053. propValue = JSON.parse($.encoder.canonicalize(propValue));
  2054. self.kernel.setProperty(nodeID, propName, propValue);
  2055. } catch (e) {
  2056. // restore the original value on error
  2057. $(this).val(propValue);
  2058. }
  2059. });
  2060. $('#input-' + nodeIDAlpha + '-' + propertyNameAlpha).keydown(function (evt) {
  2061. evt.stopPropagation();
  2062. });
  2063. $('#input-' + nodeIDAlpha + '-' + propertyNameAlpha).keypress(function (evt) {
  2064. evt.stopPropagation();
  2065. });
  2066. $('#input-' + nodeIDAlpha + '-' + propertyNameAlpha).keyup(function (evt) {
  2067. evt.stopPropagation();
  2068. });
  2069. }
  2070. }
  2071. $('#prototypeProperties > div:last').css('border-bottom-width', '3px');
  2072. // Add node methods
  2073. $(topdownTemp).append("<div id='methods'></div>");
  2074. for (var key in node.methods) {
  2075. var method = node.methods[key];
  2076. var methodNameAlpha = $.encoder.encodeForAlphaNumeric(key);
  2077. var methodNameAttribute = $.encoder.encodeForHTMLAttribute("id", key, true);
  2078. var methodNameHTML = $.encoder.encodeForHTML(key);
  2079. $('#methods').append("<div id='" + methodNameAlpha + "' class='methodEntry'><table><tr><td><b>" + methodNameHTML + " </b></td><td style='text-align:right;overflow:visible'><div id='rollover-" + methodNameAlpha + "' style='position:relative;left:12px'><input type='button' class='input_button_call' id='call-" + methodNameAlpha + "' value='Call' data-methodName='" + methodNameAttribute + "'><img id='param-" + methodNameAlpha + "' data-methodName='" + methodNameAttribute + "' src='images/arrow.png' alt='arrow' style='position:relative;top:4px;left:2px;visibility:hidden'></div></td></tr></table></div>");
  2080. $('#rollover-' + methodNameAlpha).mouseover(function (evt) {
  2081. $('#param-' + $(this).attr("id").substring(9)).css('visibility', 'visible');
  2082. });
  2083. $('#rollover-' + methodNameAlpha).mouseleave(function (evt) {
  2084. $('#param-' + $(this).attr("id").substring(9)).css('visibility', 'hidden');
  2085. });
  2086. $('#call-' + methodNameAlpha).click(function (evt) {
  2087. self.kernel.callMethod(nodeID, $.encoder.canonicalize($(this).attr("data-methodName")));
  2088. });
  2089. $('#param-' + methodNameAlpha).click(function (evt) {
  2090. setParams.call(self, $.encoder.canonicalize($(this).attr("data-methodName")), method, nodeID);
  2091. });
  2092. }
  2093. $('#methods > div:last').css('border-bottom-width', '3px');
  2094. // Add prototype methods
  2095. $(topdownTemp).append("<div id='prototypeMethods'></div>");
  2096. var prototypeMethods = getMethods.call(this, this.kernel, node.extendsID);
  2097. for (var key in prototypeMethods) {
  2098. var method = prototypeMethods[key];
  2099. var prototypeMethodNameAlpha = $.encoder.encodeForAlphaNumeric(key);
  2100. var prototypeMethodNameAttribute = $.encoder.encodeForHTMLAttribute("id", key, true);
  2101. var prototypeMethodNameHTML = $.encoder.encodeForHTML(key);
  2102. $('#prototypeMethods').append("<div id='" + prototypeMethodNameAlpha + "' class='methodEntry'><table><tr><td><b>" + prototypeMethodNameHTML + " </b></td><td style='text-align:right;overflow:visible'><div id='rollover-" + prototypeMethodNameAlpha + "' style='position:relative;left:12px'><input type='button' class='input_button_call' id='call-" + prototypeMethodNameAlpha + "' value='Call' data-methodName='" + prototypeMethodNameAttribute + "'><img id='param-" + prototypeMethodNameAlpha + "' data-methodName='" + prototypeMethodNameAttribute + "' src='images/arrow.png' alt='arrow' style='position:relative;top:4px;left:2px;visibility:hidden'></div></td></tr></table></div>");
  2103. $('#rollover-' + prototypeMethodNameAlpha).mouseover(function (evt) {
  2104. $('#param-' + $(this).attr("id").substring(9)).css('visibility', 'visible');
  2105. });
  2106. $('#rollover-' + prototypeMethodNameAlpha).mouseleave(function (evt) {
  2107. $('#param-' + $(this).attr("id").substring(9)).css('visibility', 'hidden');
  2108. });
  2109. $('#call-' + prototypeMethodNameAlpha).click(function (evt) {
  2110. self.kernel.callMethod(nodeID, $.encoder.canonicalize($(this).attr("data-methodName")));
  2111. });
  2112. $('#param-' + prototypeMethodNameAlpha).click(function (evt) {
  2113. setParams.call(self, $.encoder.canonicalize($(this).attr("data-methodName")), method, nodeID);
  2114. });
  2115. }
  2116. $('#prototypeMethods > div:last').css('border-bottom-width', '3px');
  2117. // Add node events
  2118. $(topdownTemp).append("<div id='events'></div>");
  2119. for (var key in node.events) {
  2120. var nodeEvent = node.events[key];
  2121. var eventNameAlpha = $.encoder.encodeForAlphaNumeric(key);
  2122. var eventNameAttribute = $.encoder.encodeForHTMLAttribute("id", key, true);
  2123. var eventNameHTML = $.encoder.encodeForHTML(key);
  2124. $('#events').append("<div id='" + eventNameAlpha + "' class='methodEntry'><table><tr><td><b>" + eventNameHTML + " </b></td><td style='text-align:right;overflow:visible'><div id='rollover-" + eventNameAlpha + "' style='position:relative;left:12px'><input type='button' class='input_button_call' id='fire-" + eventNameAlpha + "' value='Fire' data-eventName='" + eventNameAttribute + "'><img id='arg-" + eventNameAlpha + "' data-eventName='" + eventNameAttribute + "' src='images/arrow.png' alt='arrow' style='position:relative;top:4px;left:2px;visibility:hidden'></div></td></tr></table></div>");
  2125. $('#rollover-' + eventNameAlpha).mouseover(function (evt) {
  2126. $('#arg-' + $(this).attr("id").substring(9)).css('visibility', 'visible');
  2127. });
  2128. $('#rollover-' + eventNameAlpha).mouseleave(function (evt) {
  2129. $('#arg-' + $(this).attr("id").substring(9)).css('visibility', 'hidden');
  2130. });
  2131. $('#fire-' + eventNameAlpha).click(function (evt) {
  2132. self.kernel.fireEvent(nodeID, $.encoder.canonicalize($(this).attr("data-eventName")));
  2133. });
  2134. $('#arg-' + eventNameAlpha).click(function (evt) {
  2135. setArgs.call(self, $.encoder.canonicalize($(this).attr("data-eventName")), nodeEvent, nodeID);
  2136. });
  2137. }
  2138. $('#events > div:last').css('border-bottom-width', '3px');
  2139. // Add prototype events
  2140. $(topdownTemp).append("<div id='prototypeEvents'></div>");
  2141. var prototypeEvents = getEvents.call(this, this.kernel, node.extendsID);
  2142. for (var key in prototypeEvents) {
  2143. var nodeEvent = prototypeEvents[key];
  2144. var prototypeEventNameAlpha = $.encoder.encodeForAlphaNumeric(key);
  2145. var prototypeEventNameAttribute = $.encoder.encodeForHTMLAttribute("id", key, true);
  2146. var prototypeEventNameHTML = $.encoder.encodeForHTML(key);
  2147. $('#prototypeEvents').append("<div id='" + prototypeEventNameAlpha + "' class='methodEntry'><table><tr><td><b>" + prototypeEventNameHTML + " </b></td><td style='text-align:right;overflow:visible'><div id='rollover-" + prototypeEventNameAlpha + "' style='position:relative;left:12px'><input type='button' class='input_button_call' id='fire-" + prototypeEventNameAlpha + "' value='Fire' data-eventName='" + prototypeEventNameAttribute + "'><img id='arg-" + prototypeEventNameAlpha + "' data-eventName='" + prototypeEventNameAttribute + "' src='images/arrow.png' alt='arrow' style='position:relative;top:4px;left:2px;visibility:hidden'></div></td></tr></table></div>");
  2148. $('#rollover-' + prototypeEventNameAlpha).mouseover(function (evt) {
  2149. $('#arg-' + $(this).attr("id").substring(9)).css('visibility', 'visible');
  2150. });
  2151. $('#rollover-' + prototypeEventNameAlpha).mouseleave(function (evt) {
  2152. $('#arg-' + $(this).attr("id").substring(9)).css('visibility', 'hidden');
  2153. });
  2154. $('#fire-' + prototypeEventNameAlpha).click(function (evt) {
  2155. self.kernel.fireEvent(nodeID, $.encoder.canonicalize($(this).attr("data-eventName")));
  2156. });
  2157. $('#arg-' + prototypeEventNameAlpha).click(function (evt) {
  2158. setArgs.call(self, $.encoder.canonicalize($(this).attr("data-eventName")), nodeEvent, nodeID);
  2159. });
  2160. }
  2161. $('#prototypeEvents > div:last').css('border-bottom-width', '3px');
  2162. // Add node behaviors
  2163. $(topdownTemp).append("<div id='behaviors'></div>");
  2164. for (var i = 0; i < node.implementsIDs.length; i++) {
  2165. var nodeImplementsIDAlpha = $.encoder.encodeForAlphaNumeric(node.implementsIDs[i]);
  2166. var nodeImplementsIDHTML = $.encoder.encodeForHTML(node.implementsIDs[i]);
  2167. $('#behaviors').append("<div class='propEntry'><table><tr><td style='width:92%'><b>" + nodeImplementsIDHTML + "</b></td><td><input id='" + nodeImplementsIDAlpha + "-enable' type='checkbox' checked='checked' disabled='disabled' /></td></tr></table></div>");
  2168. /*
  2169. //Placeholder to Enable/Disable behaviors
  2170. $('#' + node.implementsID[i] + '-enable').change( function(evt) {
  2171. });
  2172. */
  2173. }
  2174. $('#behaviors > div:last').css('border-bottom-width', '3px');
  2175. // Add prototype behaviors
  2176. $(topdownTemp).append("<div id='prototypeBehaviors'></div>");
  2177. var prototypeNode = this.nodes[node.extendsID];
  2178. for (var i = 0; i < prototypeNode.implementsIDs.length; i++) {
  2179. var prototypeImplementsIDAlpha = $.encoder.encodeForAlphaNumeric(prototypeNode.implementsIDs[i]);
  2180. var prototypeImplementsIDHTML = $.encoder.encodeForHTML(prototypeNode.implementsIDs[i]);
  2181. $('#prototypeBehaviors').append("<div class='propEntry'><table><tr><td style='width:92%'><b>" + prototypeImplementsIDHTML + "</b></td><td><input id='" + prototypeImplementsIDAlpha + "-enable' type='checkbox' checked='checked' disabled='disabled' /></td></tr></table></div>");
  2182. }
  2183. $('#prototypeBehaviors > div:last').css('border-bottom-width', '3px');
  2184. // Create new method
  2185. $(topdownTemp).append("<div id='createMethodID'></div>");
  2186. $('#createMethodID').append("<div class='childContainer'><div class='childEntry'><b>New Method</div></div>");
  2187. $('#createMethodID').click(function (evt) {
  2188. createMethod.call(self, nodeID);
  2189. });
  2190. // Create new Event
  2191. $(topdownTemp).append("<div id='createEventID'></div>");
  2192. $('#createEventID').append("<div class='childContainer'><div class='childEntry'><b>New Event</div></div>");
  2193. $('#createEventID').click(function (evt) {
  2194. createEvent.call(self, nodeID);
  2195. });
  2196. // Create new script
  2197. $(topdownTemp).append("<div id='createScript'></div>");
  2198. $('#createScript').append("<div class='childContainer'><div class='childEntry'><b>New Script</div></div>");
  2199. $('#createScript').click(function (evt) {
  2200. createScript.call(self, nodeID);
  2201. });
  2202. $('#createScript > div:last').css('border-bottom-width', '3px');
  2203. if (this.allScripts[nodeID] !== undefined) {
  2204. // Add node scripts
  2205. $(topdownTemp).append("<div id='scripts'></div>");
  2206. for (var i = 0; i < this.allScripts[nodeID].length; i++) {
  2207. var scriptFull = this.allScripts[nodeID][i].text;
  2208. if (scriptFull != undefined) {
  2209. var scriptName = scriptFull.substring(0, scriptFull.indexOf('='));
  2210. $('#scripts').append("<div id='script-" + nodeIDAlpha + "-" + i + "' class='childContainer'><div class='childEntry'><b>script </b>" + scriptName + "</div></div>");
  2211. $('#script-' + nodeIDAlpha + "-" + i).click(function (evt) {
  2212. var scriptID = $(this).attr("id").substring($(this).attr("id").lastIndexOf('-') + 1);
  2213. viewScript.call(self, nodeID, scriptID, undefined);
  2214. });
  2215. }
  2216. }
  2217. $('#scripts > div:last').css('border-bottom-width', '3px');
  2218. }
  2219. if (this.allScripts[node.extendsID] !== undefined) {
  2220. // Add prototype scripts
  2221. $(topdownTemp).append("<div id='prototypeScripts'></div>");
  2222. for (var i = 0; i < this.allScripts[node.extendsID].length; i++) {
  2223. var scriptFull = this.allScripts[node.extendsID][i].text;
  2224. if (scriptFull != undefined) {
  2225. var nodeExtendsIDAlpha = $.encoder.encodeForAlphaNumeric(node.extendsID);
  2226. var nodeExtendsIDAttribute = $.encoder.encodeForHTMLAttribute("id", node.extendsID, true);
  2227. var scriptName = scriptFull.substring(0, scriptFull.indexOf('='));
  2228. $('#prototypeScripts').append("<div id='script-" + nodeExtendsIDAlpha + "-" + i + "' class='childContainer' data-nodeExtendsID='" + nodeExtendsIDAttribute + "'><div class='childEntry'><b>script </b>" + scriptName + "</div></div>");
  2229. $('#script-' + nodeExtendsIDAlpha + "-" + i).click(function (evt) {
  2230. var extendsId = $.encoder.canonicalize($(this).attr("data-nodeExtendsID"));
  2231. var scriptID = $(this).attr("id").substring($(this).attr("id").lastIndexOf('-') + 1);
  2232. viewScript.call(self, nodeID, scriptID, extendsId);
  2233. });
  2234. }
  2235. }
  2236. $('#prototypeScripts > div:last').css('border-bottom-width', '3px');
  2237. }
  2238. updateCameraProperties.call(self);
  2239. }
  2240. // createEvent
  2241. function createEvent(nodeID) // invoke with the view as "this"
  2242. {
  2243. var self = this;
  2244. var topdownName = this.topdownName;
  2245. var topdownTemp = this.topdownTemp;
  2246. var nodeIDAlpha = $.encoder.encodeForAlphaNumeric(nodeID);
  2247. $(topdownTemp).html("<div class='header'><img src='images/back.png' id='script-" + nodeIDAlpha + "-back' alt='back'/> New event</div>");
  2248. $('#script-' + nodeIDAlpha + '-back').click(function (evt) {
  2249. self.editingScript = false;
  2250. drillBack.call(self, nodeID);
  2251. // Return editor to normal width
  2252. $('#editor').animate({ 'left': "-260px" }, 175);
  2253. $('.vwf-tree').animate({ 'width': "260px" }, 175);
  2254. });
  2255. $(topdownTemp).append("<div id='cm'>Name:<br/><input type='text' class='input_text' id='eventName'/><br/>Parameters:<br/><input type='text' class='input_text' id='eventParams'/></div><hr><input class='update_button' type='button' id='createEvent' value='Create' />");
  2256. $("#createEvent").click(function (evt) {
  2257. console.log("not yet created");
  2258. if ($('#eventName').val()) {
  2259. var eventName = $('#eventName').val();
  2260. //prmtr = JSON.parse(JSON.stringify($.encoder.canonicalize(prmtr)));
  2261. console.log(eventName);
  2262. if ($('#eventParams').val()) {
  2263. var params = $('#eventParams').val();
  2264. params = params.split(',');
  2265. var cleanParams = [];
  2266. for (var i = 0; i < params.length; i++) {
  2267. params[i] = $.trim(params[i]);
  2268. if (params[i] != '' && params[i] != null && params[i] !== undefined)
  2269. cleanParams.push(params[i]);
  2270. }
  2271. console.log(cleanParams);
  2272. //prmtr = JSON.parse(JSON.stringify($.encoder.canonicalize(prmtr)));
  2273. }
  2274. let body = '';
  2275. self.kernel.createEvent(nodeID, eventName, cleanParams);
  2276. }
  2277. //self.kernel.execute( nodeID, editor.getValue() );
  2278. // self.kernel.execute( nodeID, $("#newScriptArea").val() );
  2279. });
  2280. $(topdownName).hide();
  2281. $(topdownTemp).show();
  2282. this.topdownName = topdownTemp;
  2283. this.topdownTemp = topdownName;
  2284. }
  2285. // -- createMethod
  2286. function createMethod(nodeID) // invoke with the view as "this"
  2287. {
  2288. var self = this;
  2289. var topdownName = this.topdownName;
  2290. var topdownTemp = this.topdownTemp;
  2291. var nodeIDAlpha = $.encoder.encodeForAlphaNumeric(nodeID);
  2292. $(topdownTemp).html("<div class='header'><img src='images/back.png' id='script-" + nodeIDAlpha + "-back' alt='back'/> New method</div>");
  2293. $('#script-' + nodeIDAlpha + '-back').click(function (evt) {
  2294. self.editingScript = false;
  2295. drillBack.call(self, nodeID);
  2296. // Return editor to normal width
  2297. $('#editor').animate({ 'left': "-260px" }, 175);
  2298. $('.vwf-tree').animate({ 'width': "260px" }, 175);
  2299. });
  2300. $(topdownTemp).append("<div id='cm'>Name:<br/><input type='text' class='input_text' id='methodName'/><br/>Parameters:<br/><input type='text' class='input_text' id='methodParams'/></div><hr><input class='update_button' type='button' id='createMethod' value='Create' />");
  2301. $("#createMethod").click(function (evt) {
  2302. console.log("not yet created");
  2303. if ($('#methodName').val()) {
  2304. var methodName = $('#methodName').val();
  2305. //prmtr = JSON.parse(JSON.stringify($.encoder.canonicalize(prmtr)));
  2306. console.log(methodName);
  2307. if ($('#methodParams').val()) {
  2308. var params = $('#methodParams').val();
  2309. params = params.split(',');
  2310. var cleanParams = [];
  2311. for (var i = 0; i < params.length; i++) {
  2312. params[i] = $.trim(params[i]);
  2313. if (params[i] != '' && params[i] != null && params[i] !== undefined)
  2314. cleanParams.push(params[i]);
  2315. }
  2316. console.log(cleanParams);
  2317. //prmtr = JSON.parse(JSON.stringify($.encoder.canonicalize(prmtr)));
  2318. }
  2319. let body = '';
  2320. self.kernel.createMethod(nodeID, methodName, cleanParams, body);
  2321. }
  2322. //self.kernel.execute( nodeID, editor.getValue() );
  2323. // self.kernel.execute( nodeID, $("#newScriptArea").val() );
  2324. });
  2325. $(topdownName).hide();
  2326. $(topdownTemp).show();
  2327. this.topdownName = topdownTemp;
  2328. this.topdownTemp = topdownName;
  2329. }
  2330. // -- createScript ----------------------------------------------------------------------
  2331. function createScript(nodeID) // invoke with the view as "this"
  2332. {
  2333. var self = this;
  2334. var topdownName = this.topdownName;
  2335. var topdownTemp = this.topdownTemp;
  2336. var allScripts = this.allScripts;
  2337. var nodeIDAlpha = $.encoder.encodeForAlphaNumeric(nodeID);
  2338. $(topdownTemp).html("<div class='header'><img src='images/back.png' id='script-" + nodeIDAlpha + "-back' alt='back'/> script</div>");
  2339. $('#script-' + nodeIDAlpha + '-back').click(function (evt) {
  2340. self.editingScript = false;
  2341. drillBack.call(self, nodeID);
  2342. // Return editor to normal width
  2343. $('#editor').animate({ 'left': "-260px" }, 175);
  2344. $('.vwf-tree').animate({ 'width': "260px" }, 175);
  2345. });
  2346. // $(topdownTemp).append("<div class='scriptEntry'><pre class='scriptCode'><textarea id='newScriptArea' class='scriptEdit' spellcheck='false' wrap='off'></textarea></pre><input class='update_button' type='button' id='create-" + nodeIDAlpha + "' value='Create' /></div><hr>");
  2347. $(topdownTemp).append("<div class='scriptEntry'><pre class='scriptCode'> <div id='editorlive'></div></pre><input class='update_button' type='button' id='create-" + nodeIDAlpha + "' value='Create' /></div><hr>");
  2348. var editor = createAceEditor(self, nodeID);
  2349. $("#create-" + nodeIDAlpha).click(function (evt) {
  2350. self.kernel.execute(nodeID, editor.getValue());
  2351. // self.kernel.execute( nodeID, $("#newScriptArea").val() );
  2352. });
  2353. // $('#newScriptArea').focus( function(evt) {
  2354. // // Expand the script editor
  2355. // self.editingScript = true;
  2356. // $('#editor').animate({ 'left' : "-500px" }, 175);
  2357. // $('.vwf-tree').animate({ 'width' : "500px" }, 175);
  2358. // });
  2359. $('#editorlive').keydown(function (evt) {
  2360. evt.stopPropagation();
  2361. });
  2362. $(topdownName).hide();
  2363. $(topdownTemp).show();
  2364. this.topdownName = topdownTemp;
  2365. this.topdownTemp = topdownName;
  2366. }
  2367. // -- viewScript ------------------------------------------------------------------------
  2368. function createAceEditor(view, nodeID) {
  2369. var editor = view.ace.edit("aceEditor");
  2370. editor.setTheme("ace/theme/monokai");
  2371. editor.setFontSize(16);
  2372. editor.getSession().setMode("ace/mode/javascript");
  2373. editor.commands.addCommand({
  2374. name: "doit",
  2375. bindKey: { win: "Ctrl-e", mac: "Command-e" },
  2376. exec: function () {
  2377. codeEditorDoit(editor, nodeID);
  2378. }
  2379. });
  2380. editor.commands.addCommand({
  2381. name: "printit",
  2382. bindKey: { win: "Ctrl-b", mac: "Command-b" },
  2383. exec: function () {
  2384. codeEditorPrintit(editor, nodeID);
  2385. }
  2386. });
  2387. return editor;
  2388. }
  2389. function editOhmLang(nodeID, propertyName, propertyValue) {
  2390. var self = this;
  2391. var topdownName = this.topdownName;
  2392. var topdownTemp = this.topdownTemp;
  2393. var nodeIDAlpha = $.encoder.encodeForAlphaNumeric(nodeID);
  2394. $(topdownTemp).html("<div class='header'><img src='images/back.png' id='script-" + nodeIDAlpha + "-back' alt='back'/> script</div>");
  2395. $('#script-' + nodeIDAlpha + '-back').click(function (evt) {
  2396. self.editingScript = false;
  2397. drillBack.call(self, nodeID);
  2398. // Return editor to normal width
  2399. $('#editor').animate({ 'left': "-260px" }, 175);
  2400. $('.vwf-tree').animate({ 'width': "260px" }, 175);
  2401. });
  2402. if (propertyValue != undefined) {
  2403. var propText = propertyValue;
  2404. // var propText = propertyValue.split("\n").map($.trim).filter(function(line) { return line != "" }).join("\n");
  2405. $(topdownTemp).append("<div style='padding:6px'><input class='live_button' type='button' id='update-" + nodeIDAlpha + "-" + propertyName + "' value='Update' /></div>");
  2406. $(topdownTemp).append("<div class='scriptEntry'><pre class='scriptCode'> <div id='editorlive'> </div></pre></div><hr>");
  2407. var editor = createAceEditor(self, nodeID);
  2408. editor.setValue(propText);
  2409. $("#update-" + nodeIDAlpha + "-" + propertyName).click(function (evt) {
  2410. var evalText = editor.getValue();
  2411. self.kernel.setProperty(nodeID, propertyName, evalText);
  2412. });
  2413. $('#editorlive').keydown(function (evt) {
  2414. evt.stopPropagation();
  2415. });
  2416. }
  2417. $(topdownName).hide();
  2418. $(topdownTemp).show();
  2419. this.topdownName = topdownTemp;
  2420. this.topdownTemp = topdownName;
  2421. }
  2422. function viewScript(nodeID, scriptID, extendsID) // invoke with the view as "this"
  2423. {
  2424. var self = this;
  2425. var topdownName = this.topdownName;
  2426. var topdownTemp = this.topdownTemp;
  2427. var allScripts = this.allScripts;
  2428. var nodeIDAlpha = $.encoder.encodeForAlphaNumeric(nodeID);
  2429. $(topdownTemp).html("<div class='header'><img src='images/back.png' id='script-" + nodeIDAlpha + "-back' alt='back'/> script</div>");
  2430. $('#script-' + nodeIDAlpha + '-back').click(function (evt) {
  2431. self.editingScript = false;
  2432. drillBack.call(self, nodeID);
  2433. // Return editor to normal width
  2434. $('#editor').animate({ 'left': "-260px" }, 175);
  2435. $('.vwf-tree').animate({ 'width': "260px" }, 175);
  2436. });
  2437. if (extendsID) {
  2438. nodeID = extendsID;
  2439. nodeIDAlpha = $.encoder.encodeForAlphaNumeric(extendsID);
  2440. }
  2441. var scriptText = self.allScripts[nodeID][scriptID].text;
  2442. if (scriptText != undefined) {
  2443. // $(topdownTemp).append("<div class='scriptEntry'><pre class='scriptCode'><textarea id='scriptTextArea' class='scriptEdit' spellcheck='false' wrap='off'>" + scriptText + "</textarea></pre><input class='update_button' type='button' id='update-" + nodeIDAlpha + "-" + scriptID + "' value='Update' /></div><hr>");
  2444. //Open Live Editor
  2445. $(topdownTemp).append("<div style='padding:6px'><input class='live_button' type='button' id='printit' value='Print It' /><span> </span><input class='live_button' type='button' id='doit-" + nodeIDAlpha + "-" + scriptID + "' value='DoIt' /><span> </span><input class='live_button' type='button' id='update-" + nodeIDAlpha + "-" + scriptID + "' value='Update' /></div>");
  2446. $(topdownTemp).append("<div class='scriptEntry'><pre class='scriptCode'> <div id='editorlive'>" + scriptText + "</div></pre></div><hr>");
  2447. var editor = createAceEditor(self, nodeID);
  2448. // $(topdownTemp).append("<div style='padding:6px'><input class='live_button' type='button' id='doit' value='DoIt' /></div>");
  2449. $("#doit-" + nodeIDAlpha + "-" + scriptID).click(function (evt) {
  2450. var s_id = $(this).attr("id").substring($(this).attr("id").lastIndexOf('-') + 1);
  2451. self.allScripts[nodeID][s_id].text = undefined;;
  2452. codeEditorDoit.call(self, editor, nodeID);
  2453. });
  2454. $("#printit").click(function (evt) {
  2455. codeEditorPrintit.call(self, editor, nodeID);
  2456. });
  2457. $("#update-" + nodeIDAlpha + "-" + scriptID).click(function (evt) {
  2458. var s_id = $(this).attr("id").substring($(this).attr("id").lastIndexOf('-') + 1);
  2459. self.allScripts[nodeID][s_id].text = undefined;
  2460. var evalText = editor.getValue();
  2461. self.kernel.execute(nodeID, evalText);
  2462. });
  2463. // $('#editorlive').focus( function(evt) {
  2464. // // Expand the script editor
  2465. // self.editingScript = true;
  2466. // $('#editor').animate({ 'left' : "-500px" }, 175);
  2467. // $('.vwf-tree').animate({ 'width' : "500px" }, 175);
  2468. // });
  2469. $('#editorlive').keydown(function (evt) {
  2470. evt.stopPropagation();
  2471. });
  2472. }
  2473. $(topdownName).hide();
  2474. $(topdownTemp).show();
  2475. this.topdownName = topdownTemp;
  2476. this.topdownTemp = topdownName;
  2477. }
  2478. // -- setParams -------------------------------------------------------------------------
  2479. function setParams(methodName, methodParams, nodeID) // invoke with the view as "this"
  2480. {
  2481. var self = this;
  2482. var topdownName = this.topdownName;
  2483. var topdownTemp = this.topdownTemp;
  2484. var methodNameAlpha = $.encoder.encodeForAlphaNumeric(methodName);
  2485. var methodNameHTML = $.encoder.encodeForHTML(methodName);
  2486. $(topdownTemp).html("<div class='header'><img src='images/back.png' id='" + methodNameAlpha + "-back' alt='back'/> " + methodNameHTML + "</div>");
  2487. $('#' + methodNameAlpha + '-back').click(function (evt) {
  2488. self.editingScript = false;
  2489. drillUp.call(self, nodeID);
  2490. // Return editor to normal width
  2491. $('#editor').animate({ 'left': "-260px" }, 175);
  2492. $('.vwf-tree').animate({ 'width': "260px" }, 175);
  2493. });
  2494. var nodeIDAlpha = $.encoder.encodeForAlphaNumeric(nodeID);
  2495. var method = vwf.getMethod(nodeID, methodNameAlpha);
  2496. $(topdownTemp).append("<div style='padding:6px'><input class='live_button' type='button' id='printit' value='Print It' /><span> </span><input class='live_button' type='button' id='doit' value='Do It' /><span> </span><input class='live_button' type='button' id='update-" + nodeIDAlpha + "-" + methodNameAlpha + "' value='Update' /><span> </span> <input class='live_button' type='button' id='call' value='Call' /></div>");
  2497. //$(topdownTemp).append("<input class='update_button' type='button' id='call' value='Call' />");
  2498. $(topdownTemp).append("<div id='editorlive'>" + method.body + "</div>");
  2499. var editor = createAceEditor(self, nodeID);
  2500. $("#printit").click(function (evt) {
  2501. codeEditorPrintit.call(self, editor, nodeID);
  2502. });
  2503. $("#doit").click(function (evt) {
  2504. codeEditorDoit.call(self, editor, nodeID);
  2505. });
  2506. $("#update-" + nodeIDAlpha + "-" + methodNameAlpha).click(function (evt) {
  2507. var evalText = editor.getValue();
  2508. self.kernel.setMethod(nodeID, methodNameAlpha,
  2509. { body: evalText, type: "application/javascript", parameters: method.parameters });
  2510. });
  2511. var params = [];
  2512. if (method.parameters) {
  2513. params = method.parameters.length
  2514. };
  2515. if (params >= 1) {
  2516. for (var i = 1; i <= params; i++) {
  2517. $(topdownTemp).append("<div id='param" + i + "' class='propEntry'><table><tr><td><b>" + method.parameters[i - 1] + ": " + i + ": </b></td><td><input type='text' class='input_text' id='input-param" + i + "'></td></tr></table></div>");
  2518. $('#input-param' + i).keydown(function (evt) {
  2519. evt.stopPropagation();
  2520. });
  2521. $('#input-param' + i).keypress(function (evt) {
  2522. evt.stopPropagation();
  2523. });
  2524. $('#input-param' + i).keyup(function (evt) {
  2525. evt.stopPropagation();
  2526. });
  2527. }
  2528. }
  2529. $('#call').click(function (evt) {
  2530. if (params >= 1) {
  2531. var parameters = new Array();
  2532. for (var i = 1; i <= params; i++) {
  2533. if ($('#input-param' + i).val()) {
  2534. var prmtr = $('#input-param' + i).val();
  2535. try {
  2536. prmtr = JSON.parse(JSON.stringify($.encoder.canonicalize(prmtr)));
  2537. parameters.push(prmtr);
  2538. } catch (e) {
  2539. self.logger.error('Invalid Value');
  2540. }
  2541. }
  2542. }
  2543. }
  2544. self.kernel.callMethod(nodeID, methodName, parameters);
  2545. });
  2546. $(topdownName).hide('slide', { direction: 'left' }, 175);
  2547. $(topdownTemp).show('slide', { direction: 'right' }, 175);
  2548. this.topdownName = topdownTemp;
  2549. this.topdownTemp = topdownName;
  2550. }
  2551. // -- setArgs ---------------------------------------------------------------------------
  2552. function setArgs(eventName, eventArgs, nodeID) // invoke with the view as "this"
  2553. {
  2554. var self = this;
  2555. var topdownName = this.topdownName;
  2556. var topdownTemp = this.topdownTemp;
  2557. var eventNameAlpha = $.encoder.encodeForAlphaNumeric(eventName);
  2558. var eventNameHTML = $.encoder.encodeForHTML(eventName);
  2559. $(topdownTemp).html("<div class='header'><img src='images/back.png' id='" + eventNameAlpha + "-back' alt='back'/> " + eventNameHTML + "<input type='button' class='input_button_call' id='fire' value='Fire' style='float:right;position:relative;top:5px;right:33px'></input></div>");
  2560. $('#' + eventNameAlpha + '-back').click(function (evt) {
  2561. drillUp.call(self, nodeID);
  2562. });
  2563. for (var i = 1; i <= 8; i++) {
  2564. $(topdownTemp).append("<div id='arg" + i + "' class='propEntry'><table><tr><td><b>Argument " + i + ": </b></td><td><input type='text' class='input_text' id='input-arg" + i + "'></td></tr></table></div>");
  2565. $('#input-arg' + i).keydown(function (evt) {
  2566. evt.stopPropagation();
  2567. });
  2568. $('#input-arg' + i).keypress(function (evt) {
  2569. evt.stopPropagation();
  2570. });
  2571. $('#input-arg' + i).keyup(function (evt) {
  2572. evt.stopPropagation();
  2573. });
  2574. }
  2575. $(topdownTemp).append("<div style='font-weight:bold;text-align:right;padding-right:10px'></div>");
  2576. $('#fire').click(function (evt) {
  2577. var args = new Array();
  2578. for (var i = 1; i <= 8; i++) {
  2579. if ($('#input-arg' + i).val()) {
  2580. var arg = $('#input-arg' + i).val();
  2581. try {
  2582. arg = JSON.parse($.encoder.canonicalize(arg));
  2583. args.push(arg);
  2584. } catch (e) {
  2585. self.logger.error('Invalid Value');
  2586. }
  2587. }
  2588. }
  2589. self.kernel.fireEvent(nodeID, eventName, args);
  2590. });
  2591. $(topdownName).hide('slide', { direction: 'left' }, 175);
  2592. $(topdownTemp).show('slide', { direction: 'right' }, 175);
  2593. this.topdownName = topdownTemp;
  2594. this.topdownTemp = topdownName;
  2595. }
  2596. function getPrototypes(kernel, extendsID) {
  2597. var prototypes = [];
  2598. var id = extendsID;
  2599. while (id !== undefined) {
  2600. prototypes.push(id);
  2601. id = kernel.prototype(id);
  2602. }
  2603. return prototypes;
  2604. }
  2605. function getPrototypes(kernel, extendsID) {
  2606. var prototypes = [];
  2607. var id = extendsID;
  2608. while (id !== undefined) {
  2609. prototypes.push(id);
  2610. id = kernel.prototype(id);
  2611. }
  2612. return prototypes;
  2613. }
  2614. function createProperty(node, propertyName, propertyValue) {
  2615. var property = {
  2616. name: propertyName,
  2617. rawValue: propertyValue,
  2618. value: undefined,
  2619. getValue: function () {
  2620. var propertyValue;
  2621. if (this.value == undefined) {
  2622. try {
  2623. propertyValue = utility.transform(this.rawValue, utility.transforms.transit);
  2624. this.value = JSON.stringify(propertyValue);
  2625. } catch (e) {
  2626. this.logger.warnx("createdProperty", nodeID, this.propertyName, this.rawValue,
  2627. "stringify error:", e.message);
  2628. this.value = this.rawValue;
  2629. }
  2630. }
  2631. return this.value;
  2632. }
  2633. };
  2634. return property;
  2635. }
  2636. function getProperties(kernel, extendsID) {
  2637. var pTypes = getPrototypes(kernel, extendsID);
  2638. var pProperties = {};
  2639. if (pTypes) {
  2640. for (var i = 0; i < pTypes.length; i++) {
  2641. var nd = this.nodes[pTypes[i]];
  2642. if (nd && nd.properties) {
  2643. for (var key in nd.properties) {
  2644. pProperties[key] = { "prop": nd.properties[key], "prototype": pTypes[i] };
  2645. }
  2646. }
  2647. }
  2648. }
  2649. return pProperties;
  2650. }
  2651. function getChildren(kernel, extendsID) {
  2652. var pTypes = getPrototypes(kernel, extendsID);
  2653. var pChildren = {};
  2654. if (pTypes) {
  2655. for (var i = 0; i < pTypes.length; i++) {
  2656. var nd = this.nodes[pTypes[i]];
  2657. if (nd && nd.children) {
  2658. for (var key in nd.children) {
  2659. pChildren[key] = nd.children[key];
  2660. }
  2661. }
  2662. }
  2663. }
  2664. return pChildren;
  2665. }
  2666. function getEvents(kernel, extendsID) {
  2667. var pTypes = getPrototypes(kernel, extendsID);
  2668. var events = {};
  2669. if (pTypes) {
  2670. for (var i = 0; i < pTypes.length; i++) {
  2671. var nd = this.nodes[pTypes[i]];
  2672. if (nd && nd.events) {
  2673. for (var key in nd.events) {
  2674. events[key] = nd.events[key];
  2675. }
  2676. }
  2677. }
  2678. }
  2679. return events;
  2680. }
  2681. function getMethods(kernel, extendsID) {
  2682. var pTypes = getPrototypes(kernel, extendsID);
  2683. var methods = {};
  2684. if (pTypes) {
  2685. for (var i = 0; i < pTypes.length; i++) {
  2686. var nd = this.nodes[pTypes[i]];
  2687. if (nd && nd.methods) {
  2688. for (var key in nd.methods) {
  2689. methods[key] = nd.methods[key];
  2690. }
  2691. }
  2692. }
  2693. }
  2694. return methods;
  2695. }
  2696. function highlightChildInHierarchy(nodeID) {
  2697. if (this.editorOpen && this.editorView == 1) // Hierarchy view open
  2698. {
  2699. var childDiv = $("div[id='" + nodeID + "']");
  2700. if (childDiv.length > 0) {
  2701. var previousChild = $("div[id='" + this.highlightedChild + "']");
  2702. if (previousChild.length > 0) {
  2703. previousChild.removeClass('childContainerHighlight');
  2704. }
  2705. childDiv.addClass('childContainerHighlight');
  2706. this.highlightedChild = nodeID;
  2707. }
  2708. }
  2709. }
  2710. // -- showTimeline ----------------------------------------------------------------------
  2711. function showTimeline() // invoke with the view as "this"
  2712. {
  2713. var timeline = this.timeline;
  2714. if (!this.timelineInit) {
  2715. $('#time_control').append("<div class='header'>Timeline</div>" +
  2716. "<div style='text-align:center;padding-top:10px'><span><button id='play'></button><button id='stop'></button></span>" +
  2717. "<span><span class='rate slider'></span>&nbsp;" +
  2718. "<span class='rate vwf-label' style='display: inline-block; width:8ex'></span></span></div>");
  2719. var options = {};
  2720. ["play", "pause", "stop"].forEach(function (state) {
  2721. options[state] = { icons: { primary: "ui-icon-" + state }, label: state, text: false };
  2722. });
  2723. options.rate = { value: 0, min: -2, max: 2, step: 0.1, };
  2724. var state = {};
  2725. $.get(
  2726. "admin/state",
  2727. undefined,
  2728. function (data) {
  2729. state = data;
  2730. $("button#play").button("option", state.playing ? options.pause : options.play);
  2731. $("button#stop").button("option", "disabled", state.stopped);
  2732. $(".rate.slider").slider("value", Math.log(state.rate) / Math.LN10);
  2733. if (state.rate < 1.0) {
  2734. var label_rate = 1.0 / state.rate;
  2735. }
  2736. else {
  2737. var label_rate = state.rate;
  2738. }
  2739. var label = label_rate.toFixed(2).toString().replace(/(\.\d*?)0+$/, "$1").replace(/\.$/, "");
  2740. if (state.rate < 1.0) {
  2741. label = "&#x2215; " + label;
  2742. } else {
  2743. label = label + " &times;";
  2744. }
  2745. $(".rate.vwf-label").html(label);
  2746. },
  2747. "json"
  2748. );
  2749. $("button#play").button(
  2750. options.pause
  2751. ).click(function () {
  2752. $.post(
  2753. state.playing ? "admin/pause" : "admin/play",
  2754. undefined,
  2755. function (data) {
  2756. state = data;
  2757. $("button#play").button("option", state.playing ? options.pause : options.play);
  2758. $("button#stop").button("option", "disabled", state.stopped);
  2759. },
  2760. "json"
  2761. );
  2762. });
  2763. $("button#stop").button(
  2764. options.stop
  2765. ).click(function () {
  2766. $.post(
  2767. "admin/stop",
  2768. undefined,
  2769. function (data) {
  2770. state = data;
  2771. $("button#play").button("option", state.playing ? options.pause : options.play);
  2772. $("button#stop").button("option", "disabled", state.stopped);
  2773. },
  2774. "json"
  2775. );
  2776. });
  2777. $(".rate.slider").slider(
  2778. options.rate
  2779. ).bind("slide", function (event, ui) {
  2780. $.get(
  2781. "admin/state",
  2782. { "rate": Math.pow(10, Number(ui.value)) },
  2783. function (data) {
  2784. state = data;
  2785. $(".rate.slider").slider("value", Math.log(state.rate) / Math.LN10);
  2786. if (state.rate < 1.0) {
  2787. var label_rate = 1.0 / state.rate;
  2788. }
  2789. else {
  2790. var label_rate = state.rate;
  2791. }
  2792. var label = label_rate.toFixed(2).toString().replace(/(\.\d*?)0+$/, "$1").replace(/\.$/, "");
  2793. if (state.rate < 1.0) {
  2794. label = "&#x2215; " + label;
  2795. } else {
  2796. label = label + " &times;";
  2797. }
  2798. $(".rate.vwf-label").html(label);
  2799. },
  2800. "json"
  2801. );
  2802. });
  2803. this.timelineInit = true;
  2804. }
  2805. if (!this.editorOpen) {
  2806. $(timeline).show('slide', { direction: 'right' }, 175);
  2807. }
  2808. else {
  2809. $(timeline).show();
  2810. }
  2811. }
  2812. // -- Show Code Editor tab
  2813. function showCodeEditorTab() // invoke with the view as "this"
  2814. {
  2815. var self = this;
  2816. var codeEditor = this.codeEditor;
  2817. if (!this.codeEditorInit) {
  2818. $('#codeEditor_tab').append("<div class='header'>Live Code Editor</div>");
  2819. $('#codeEditor_tab').append("<div style='padding:6px'><input type='button' id='min' value='Min Window' /><span> </span><input class='live_button' type='button' id='printit' value='Print It' /><span> </span><input class='live_button' type='button' id='doit' value='Do It' /></div>");
  2820. $("#doit").click(function (evt) {
  2821. codeEditorDoit.call(self, editor, sceneID);
  2822. });
  2823. $("#printit").click(function (evt) {
  2824. codeEditorPrintit.call(self, editor, sceneID);
  2825. });
  2826. // $('#codeEditor_tab').append("<div style='padding:6px'></div>");
  2827. $('#min').click(function (evt) {
  2828. $('#editor').animate({ 'left': "-260px" }, 175);
  2829. $('.vwf-tree').animate({ 'width': "260px" }, 175);
  2830. });
  2831. //Open Live Editor
  2832. $('#codeEditor_tab').append('<div id="editorlive">console.log("test")</div>');
  2833. var sceneID = self.kernel.application();
  2834. var editor = createAceEditor(self, sceneID);
  2835. editor.on('blur', function (event, editor) {
  2836. // $('#editor').animate({ 'left' : "-260px" }, 175);
  2837. // $('.vwf-tree').animate({ 'width' : "260px" }, 175);
  2838. });
  2839. this.codeEditorInit = true;
  2840. }
  2841. if (!this.editorOpen) {
  2842. $(codeEditor).show('slide', { direction: 'right' }, 175);
  2843. }
  2844. else {
  2845. $(codeEditor).show();
  2846. // $('#editor').animate({ 'left' : "-500px" }, 175);
  2847. // $('.vwf-tree').animate({ 'width' : "500px" }, 175);
  2848. }
  2849. }
  2850. function codeEditorDoit(editor, nodeID) {
  2851. var selectedText = editor.getSession().doc.getTextRange(editor.selection.getRange());
  2852. if (selectedText == "") {
  2853. var currline = editor.getSelectionRange().start.row;
  2854. var selectedText = editor.session.getLine(currline);
  2855. }
  2856. //console.log(selectedText);
  2857. //var sceneID = self.kernel.application();
  2858. vwf_view.kernel.execute(nodeID, selectedText);
  2859. }
  2860. function codeEditorPrintit(editor, nodeID) {
  2861. var selectedText = editor.getSession().doc.getTextRange(editor.selection.getRange());
  2862. if (selectedText == "") {
  2863. var currline = editor.getSelectionRange().start.row;
  2864. var selectedText = editor.session.getLine(currline);
  2865. }
  2866. //console.log(selectedText);
  2867. //var sceneID = self.kernel.application();
  2868. let scriptText = 'console.log(' + selectedText + ');'
  2869. self.kernel.execute(nodeID, scriptText);
  2870. }
  2871. // -- showAboutTab ----------------------------------------------------------------------
  2872. function showAboutTab() // invoke with the view as "this"
  2873. {
  2874. var about = this.about;
  2875. if (!this.aboutInit) {
  2876. $('#about_tab').append("<div id='aboutHeader' class='header'>About</div>" +
  2877. "<div class='about'><p style='font:bold 12pt Arial'>Virtual World Framework & LiveCode editor</p>" +
  2878. "<p><b>Version: </b> 0.1 <b>VWF version: </b>" + version.toString() + "</p>" +
  2879. "<p><b>This project site: </b><a href='http://demo.krestianstvo.org' target='_blank'>http://demo.krestianstvo.org</a></p>" +
  2880. "<p><b>Site VWF: </b><a href='http://virtualworldframework.com' target='_blank'>http://virtualworldframework.com</a></p>" +
  2881. "<p><b>Project source: </b><a href='https://github.com/NikolaySuslov/vwf/tree/aframe' target='_blank'>https://github.com/NikolaySuslov/vwf/tree/aframe</a></p></div>");
  2882. let anotherCell =
  2883. {
  2884. $cell: true,
  2885. $text: "About: ",
  2886. class: "mdc-typography--display2",
  2887. $type: "h2"
  2888. }
  2889. let andAnotherCell =
  2890. {
  2891. $cell: true,
  2892. $text: "hello world"
  2893. }
  2894. document.querySelector("#aboutHeader").$cell({
  2895. $cell: true,
  2896. class: 'header',
  2897. $components: [anotherCell, andAnotherCell]
  2898. });
  2899. // document.querySelector("body").$cell({
  2900. // $cell: true,
  2901. // $components: [toolbarCell]
  2902. // });
  2903. this.aboutInit = true;
  2904. }
  2905. if (!this.editorOpen) {
  2906. $(about).show('slide', { direction: 'right' }, 175);
  2907. }
  2908. else {
  2909. $(about).show();
  2910. }
  2911. }
  2912. // -- showModelsTab ----------------------------------------------------------------------
  2913. function showModelsTab(modelID, modelURL) // invoke with the view as "this"
  2914. {
  2915. var self = this;
  2916. var models = this.models;
  2917. var modelsTemp = this.modelsTemp;
  2918. this.currentModelID = modelID;
  2919. this.currentModelURL = modelURL;
  2920. $(models).html("");
  2921. if (modelID == "") {
  2922. $(modelsTemp).html("<div class='header'>Models</div>");
  2923. $.getJSON("admin/models", function (data) {
  2924. if (data.length > 0) {
  2925. $.each(data, function (key, value) {
  2926. var fileName = encodeURIComponent(value['basename']);
  2927. var divId = fileName;
  2928. if (divId.indexOf('.') != -1) {
  2929. divId = divId.replace(/\./g, "_");
  2930. }
  2931. var url = value['url'];
  2932. $(modelsTemp).append("<div class='childContainer'><div id='" + divId + "' class='modelEntry' data-url='" + url + "'>"
  2933. + fileName + "</div></div>");
  2934. $("#" + divId).click(function (e) {
  2935. modelDrillDown.call(self, e.target.textContent, e.target.getAttribute("data-url"));
  2936. })
  2937. });
  2938. }
  2939. else {
  2940. $(modelsTemp).append("<div class='childEntry'><p style='font:bold 12pt Arial'>No Models Found</p></div>");
  2941. }
  2942. });
  2943. }
  2944. else {
  2945. var divId = modelID;
  2946. if (divId.indexOf('.') != -1) {
  2947. divId = divId.replace(/\./g, "_");
  2948. }
  2949. $(modelsTemp).html("<div id='" + divId + "-backDiv' class='header'><img src='images/back.png' id='" + divId + "-back' alt='back'/>" + modelID + "</div>");
  2950. $("#" + divId + "-back").click(function (e) {
  2951. modelDrillUp.call(self, '');
  2952. });
  2953. $(modelsTemp).append("<div id='" + divId + "-rotation' class='propEntry'><table><tr><td><b>Rotation</b></td><td>" +
  2954. "<input type='text' class='input_text' id='input-" + divId + "-rotation' value='[1,0,0,0]'></td></tr></table></div>");
  2955. $('#input-' + divId + '-rotation').keydown(function (evt) {
  2956. evt.stopPropagation();
  2957. });
  2958. $('#input-' + divId + '-rotation').keypress(function (evt) {
  2959. evt.stopPropagation();
  2960. });
  2961. $('#input-' + divId + '-rotation').keyup(function (evt) {
  2962. evt.stopPropagation();
  2963. });
  2964. $(modelsTemp).append("<div id='" + divId + "-scale' class='propEntry'><table><tr><td><b>Scale</b></td><td>" +
  2965. "<input type='text' class='input_text' id='input-" + divId + "-scale' value='[1,1,1]'></td></tr></table></div>");
  2966. $('#input-' + divId + '-scale').keydown(function (evt) {
  2967. evt.stopPropagation();
  2968. });
  2969. $('#input-' + divId + '-scale').keypress(function (evt) {
  2970. evt.stopPropagation();
  2971. });
  2972. $('#input-' + divId + '-scale').keyup(function (evt) {
  2973. evt.stopPropagation();
  2974. });
  2975. $(modelsTemp).append("<div id='" + divId + "-translation' class='propEntry'><table><tr><td><b>Translation Offset</b></td><td>" +
  2976. "<input type='text' class='input_text' id='input-" + divId + "-translation' value='[0,0,0]'></td></tr></table></div>");
  2977. $('#input-' + divId + '-translation').keydown(function (evt) {
  2978. evt.stopPropagation();
  2979. });
  2980. $('#input-' + divId + '-translation').keypress(function (evt) {
  2981. evt.stopPropagation();
  2982. });
  2983. $('#input-' + divId + '-translation').keyup(function (evt) {
  2984. evt.stopPropagation();
  2985. });
  2986. $(modelsTemp).append("<div class='drag'><div id='" + divId + "-drag' class='modelEntry' draggable='true' data-escaped-name='" + divId + "' data-url='" + modelURL + "'>Drag To Create</div></div>");
  2987. $("#" + divId + "-drag").on("dragstart", function (e) {
  2988. var fileName = $("#" + e.target.getAttribute("data-escaped-name") + "-backDiv").text();
  2989. var rotation = encodeURIComponent($("#input-" + e.target.getAttribute("data-escaped-name") + "-rotation").val());
  2990. var scale = encodeURIComponent($("#input-" + e.target.getAttribute("data-escaped-name") + "-scale").val());
  2991. var translation = encodeURIComponent($("#input-" + e.target.getAttribute("data-escaped-name") + "-translation").val());
  2992. var fileData = "{\"fileName\":\"" + fileName + "\", \"fileUrl\":\"" + e.target.getAttribute("data-url") + "\", " +
  2993. "\"rotation\":\"" + rotation + "\", \"scale\":\"" + scale + "\", \"translation\":\"" + translation + "\"}";
  2994. e.originalEvent.dataTransfer.setData('text/plain', fileData);
  2995. e.originalEvent.dataTransfer.setDragImage(e.target, 0, 0);
  2996. return true;
  2997. });
  2998. }
  2999. }
  3000. // -- Model drillDown -------------------------------------------------------------------------
  3001. function modelDrillDown(modelID, modelURL) // invoke with the view as "this"
  3002. {
  3003. var models = this.models;
  3004. var modelsTemp = this.modelsTemp;
  3005. showModelsTab.call(this, modelID, modelURL);
  3006. if (modelID != "") $(models).hide('slide', { direction: 'left' }, 175);
  3007. $(modelsTemp).show('slide', { direction: 'right' }, 175);
  3008. this.models = modelsTemp;
  3009. this.modelsTemp = models;
  3010. }
  3011. // -- Model drillUp ---------------------------------------------------------------------------
  3012. function modelDrillUp(modelID) // invoke with the view as "this"
  3013. {
  3014. var models = this.models;
  3015. var modelsTemp = this.modelsTemp;
  3016. showModelsTab.call(this, modelID);
  3017. $(models).hide('slide', { direction: 'right' }, 175);
  3018. $(modelsTemp).show('slide', { direction: 'left' }, 175);
  3019. this.models = modelsTemp;
  3020. this.modelsTemp = models;
  3021. }
  3022. // -- SaveStateAsFile -------------------------------------------------------------------------
  3023. function saveStateAsFile(filename) // invoke with the view as "this"
  3024. {
  3025. this.logger.info("Saving: " + filename);
  3026. var clients = this.nodes["http://vwf.example.com/clients.vwf"];
  3027. if (supportAjaxUploadWithProgress.call(this)) {
  3028. var xhr = new XMLHttpRequest();
  3029. // Save State Information
  3030. var state = vwf.getState();
  3031. state.nodes[0].children = {};
  3032. var timestamp = state["queue"].time;
  3033. timestamp = Math.round(timestamp * 1000);
  3034. var objectIsTypedArray = function (candidate) {
  3035. var typedArrayTypes = [
  3036. Int8Array,
  3037. Uint8Array,
  3038. // Uint8ClampedArray,
  3039. Int16Array,
  3040. Uint16Array,
  3041. Int32Array,
  3042. Uint32Array,
  3043. Float32Array,
  3044. Float64Array
  3045. ];
  3046. var isTypedArray = false;
  3047. if (typeof candidate == "object" && candidate != null) {
  3048. typedArrayTypes.forEach(function (typedArrayType) {
  3049. isTypedArray = isTypedArray || candidate instanceof typedArrayType;
  3050. });
  3051. }
  3052. return isTypedArray;
  3053. };
  3054. var transitTransformation = function (object) {
  3055. return objectIsTypedArray(object) ?
  3056. Array.prototype.slice.call(object) : object;
  3057. };
  3058. var json = JSON.stringify(
  3059. require("vwf/utility").transform(
  3060. state, transitTransformation
  3061. )
  3062. );
  3063. json = $.encoder.encodeForURL(json);
  3064. var path = window.location.pathname;
  3065. var pathSplit = path.split('/');
  3066. if (pathSplit[0] == "") {
  3067. pathSplit.shift();
  3068. }
  3069. if (pathSplit[pathSplit.length - 1] == "") {
  3070. pathSplit.pop();
  3071. }
  3072. var inst = undefined;
  3073. var instIndex = pathSplit.length - 1;
  3074. if (pathSplit.length > 2) {
  3075. if (pathSplit[pathSplit.length - 2] == "load") {
  3076. instIndex = pathSplit.length - 3;
  3077. }
  3078. }
  3079. if (pathSplit.length > 3) {
  3080. if (pathSplit[pathSplit.length - 3] == "load") {
  3081. instIndex = pathSplit.length - 4;
  3082. }
  3083. }
  3084. inst = pathSplit[instIndex];
  3085. var root = "";
  3086. for (var i = 0; i < instIndex; i++) {
  3087. if (root != "") {
  3088. root = root + "/";
  3089. }
  3090. root = root + pathSplit[i];
  3091. }
  3092. if (filename == '') filename = inst;
  3093. if (root.indexOf('.vwf') != -1) root = root.substring(0, root.lastIndexOf('/'));
  3094. xhr.open("POST", "/" + root + "/save/" + filename, true);
  3095. xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  3096. xhr.send("root=" + root + "/" + filename + "&filename=saveState&inst=" + inst + "&timestamp=" + timestamp + "&extension=.vwf.json" + "&jsonState=" + json);
  3097. // Save Config Information
  3098. var config = { "info": {}, "model": {}, "view": {} };
  3099. // Save browser title
  3100. config["info"]["title"] = $('title').html();
  3101. // Save model drivers
  3102. Object.keys(vwf_view.kernel.kernel.models).forEach(function (modelDriver) {
  3103. if (modelDriver.indexOf('vwf/model/') != -1) config["model"][modelDriver] = "";
  3104. });
  3105. // If neither glge or threejs model drivers are defined, specify nodriver
  3106. if (config["model"]["vwf/model/glge"] === undefined && config["model"]["vwf/model/threejs"] === undefined) config["model"]["nodriver"] = "";
  3107. // Save view drivers and associated parameters, if any
  3108. Object.keys(vwf_view.kernel.kernel.views).forEach(function (viewDriver) {
  3109. if (viewDriver.indexOf('vwf/view/') != -1) {
  3110. if (vwf_view.kernel.kernel.views[viewDriver].parameters) {
  3111. config["view"][viewDriver] = vwf_view.kernel.kernel.views[viewDriver].parameters;
  3112. }
  3113. else config["view"][viewDriver] = "";
  3114. }
  3115. });
  3116. var jsonConfig = $.encoder.encodeForURL(JSON.stringify(config));
  3117. // Save config file to server
  3118. var xhrConfig = new XMLHttpRequest();
  3119. xhrConfig.open("POST", "/" + root + "/save/" + filename, true);
  3120. xhrConfig.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  3121. xhrConfig.send("root=" + root + "/" + filename + "&filename=saveState&inst=" + inst + "&timestamp=" + timestamp + "&extension=.vwf.config.json" + "&jsonState=" + jsonConfig);
  3122. }
  3123. else {
  3124. console.error("Unable to save state.");
  3125. }
  3126. }
  3127. // -- LoadSavedState --------------------------------------------------------------------------
  3128. function loadSavedState(filename, applicationpath, revision) {
  3129. this.logger.info("Loading: " + filename);
  3130. // Redirect until setState ID conflict is resolved
  3131. var path = window.location.pathname;
  3132. var inst = path.substring(path.length - 17, path.length - 1);
  3133. var pathSplit = path.split('/');
  3134. if (pathSplit[0] == "") {
  3135. pathSplit.shift();
  3136. }
  3137. if (pathSplit[pathSplit.length - 1] == "") {
  3138. pathSplit.pop();
  3139. }
  3140. var inst = undefined;
  3141. var instIndex = pathSplit.length - 1;
  3142. if (pathSplit.length > 2) {
  3143. if (pathSplit[pathSplit.length - 2] == "load") {
  3144. instIndex = pathSplit.length - 3;
  3145. }
  3146. }
  3147. if (pathSplit.length > 3) {
  3148. if (pathSplit[pathSplit.length - 3] == "load") {
  3149. instIndex = pathSplit.length - 4;
  3150. }
  3151. }
  3152. inst = pathSplit[instIndex];
  3153. if (revision) {
  3154. window.location.pathname = applicationpath + "/" + inst + '/load/' + filename + '/' + revision + '/';
  3155. }
  3156. else {
  3157. window.location.pathname = applicationpath + "/" + inst + '/load/' + filename + '/';
  3158. }
  3159. // $.get(filename,function(data,status){
  3160. // vwf.setState(data);
  3161. // });
  3162. }
  3163. // -- SupportAjax -----------------------------------------------------------------------------
  3164. function supportAjaxUploadWithProgress() {
  3165. return supportAjaxUploadProgressEvents();
  3166. function supportAjaxUploadProgressEvents() {
  3167. var xhr = new XMLHttpRequest();
  3168. return !!(xhr && ('upload' in xhr) && ('onprogress' in xhr.upload));
  3169. }
  3170. }
  3171. });