editor-new.js 150 KB

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