editor-new.js 115 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812
  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='drawer'></div><div id='toolbar'></div<div id='clientsList'></div><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 protoPropertiesCell = function(m) {
  92. return {
  93. $type: "li",
  94. class: "mdc-list-item",
  95. _prop: {},
  96. $init: function () {
  97. let prop = m[1].prop;
  98. if (prop.value == undefined) {
  99. prop.value = JSON.stringify(utility.transform(vwf.getProperty(self.currentNodeID, prop.name, []), utility.transforms.transit));
  100. }
  101. this._prop = prop
  102. },
  103. $update: function () {
  104. this.$components = [{
  105. $type: "span",
  106. class: "mdc-list-item",
  107. $text: this._prop.name,
  108. },
  109. {
  110. class: "mdc-textfield",
  111. $cell: true,
  112. $type: "div",
  113. $components: [{
  114. class: "mdc-textfield__input",
  115. $cell: true,
  116. $type: "input",
  117. type: "text",
  118. value: this._prop.value,
  119. onchange: function(e){
  120. let propValue = this.value;
  121. try {
  122. propValue = JSON.parse(propValue);
  123. self.kernel.setProperty(self.currentNodeID, m.name, propValue);
  124. } catch (e) {
  125. // restore the original value on error
  126. this.value = propValue;
  127. }
  128. }
  129. }]
  130. }
  131. ]
  132. }
  133. }
  134. }
  135. let propertiesCell = function(m) {
  136. return {
  137. $type: "li",
  138. class: "mdc-list-item",
  139. $components: [{
  140. $type: "span",
  141. class: "mdc-list-item",
  142. $text: m.name,
  143. },
  144. {
  145. class: "mdc-textfield",
  146. $cell: true,
  147. $type: "div",
  148. $components: [{
  149. class: "mdc-textfield__input",
  150. $cell: true,
  151. $type: "input",
  152. type: "text",
  153. value: m.getValue(),
  154. onchange: function(e){
  155. let propValue = this.value;
  156. try {
  157. propValue = JSON.parse(propValue);
  158. self.kernel.setProperty(self.currentNodeID, m.name, propValue);
  159. } catch (e) {
  160. // restore the original value on error
  161. this.value = propValue;
  162. }
  163. }
  164. }]
  165. }
  166. ]
  167. }
  168. }
  169. let nodeLink = function(m){
  170. return {
  171. $type: "li",
  172. class: "mdc-list-item",
  173. $components: [{
  174. $type: "a",
  175. class: "mdc-list-item mdc-persistent-drawer--selected",
  176. $href: "#",
  177. $text: m.name,
  178. onclick: function(e){
  179. self.currentNodeID = m.ID;
  180. document.querySelector('#currentNode')._setNode(m.ID);
  181. }
  182. }]
  183. }
  184. };
  185. let listDivider = {
  186. //<li role="separator" class="mdc-list-divider"></li>
  187. $cell: true,
  188. $type: "li",
  189. class: "mdc-list-divider",
  190. role: "separator"
  191. }
  192. let nodesCell = {
  193. style:"overflow: scroll; max-height: 600px;",
  194. $cell: true,
  195. $type: "div",
  196. id: "currentNode",
  197. _currentNode: '',
  198. _setNode: function (aNode) {
  199. this._currentNode = aNode
  200. },
  201. $init: function () {
  202. //this._currentNode = vwf_view.kernel.find("", "/")[0];
  203. //this._currentNode = '3333';
  204. },
  205. _getChildNodes: function() {
  206. let node = self.nodes[this._currentNode];
  207. //let nodeIDAlpha = he.encode(this._currentNode);
  208. return node.children
  209. },
  210. _getNodeProperties: function() {
  211. let node = self.nodes[this._currentNode];
  212. return node.properties
  213. },
  214. _getNodeProtoProperties: function() {
  215. let node = self.nodes[this._currentNode];
  216. let prototypeProperties = getProperties.call(self, self.kernel, node.extendsID);
  217. return prototypeProperties
  218. },
  219. $update: function () {
  220. //this.$text = this._currentNode;
  221. this.$components = [
  222. {
  223. $cell: true,
  224. $type: "a",
  225. class: "mdc-list-item mdc-persistent-drawer--selected",
  226. $href: "#",
  227. $text: "<--",
  228. onclick: function(e){
  229. let node = self.nodes[this._currentNode];
  230. if (node.parentID !== 0) {
  231. self.currentNodeID = node.parentID,
  232. document.querySelector('#currentNode')._setNode(self.currentNodeID)
  233. }
  234. }
  235. },
  236. {
  237. $cell: true,
  238. $type: "a",
  239. class: "mdc-list-item mdc-persistent-drawer--selected",
  240. $href: "#",
  241. $text: this._currentNode
  242. }, listDivider,
  243. {
  244. $cell: true,
  245. $type: "ul",
  246. class: "mdc-list",
  247. $components: this._getChildNodes().map(nodeLink)
  248. }, listDivider,
  249. {
  250. $cell: true,
  251. $type: "ul",
  252. class: "mdc-list",
  253. $components: this._getNodeProperties().map(propertiesCell)
  254. }, listDivider,
  255. {
  256. $cell: true,
  257. $type: "ul",
  258. class: "mdc-list",
  259. $components: Object.entries(this._getNodeProtoProperties()).map(protoPropertiesCell)
  260. }
  261. ]
  262. }
  263. }
  264. let clientListCell = {
  265. $cell: true,
  266. $type: "div",
  267. _clientNodes: [],
  268. _setNode: function (aNodes) {
  269. this._clientNodes = aNodes
  270. },
  271. $init: function () {
  272. // var t = this;
  273. // t._clientNodes = self.nodes["http://vwf.example.com/clients.vwf"];
  274. },
  275. $update: function () {
  276. this.$components = this._filteredItems.map(Tr);
  277. },
  278. $components: [{
  279. $cell: true,
  280. $type: "ul",
  281. class: "mdc-list",
  282. _items: [],
  283. $components: [{
  284. $cell: true,
  285. $type: "li",
  286. class: "mdc-list-item",
  287. $text: "client"
  288. }
  289. ]
  290. }]
  291. }
  292. let drawerCell = {
  293. $cell: true,
  294. $type: "nav",
  295. class: "mdc-persistent-drawer__drawer",
  296. $components: [
  297. {
  298. $cell: true,
  299. $type: "div",
  300. class: "mdc-persistent-drawer__toolbar-spacer",
  301. },
  302. {
  303. $cell: true,
  304. $type: "div",
  305. class: "mdc-list-group",
  306. $components: [{
  307. $cell: true,
  308. $type: "nav",
  309. class: "mdc-list",
  310. $components: [{
  311. $cell: true,
  312. $type: "a",
  313. class: "mdc-list-item mdc-persistent-drawer--selected",
  314. $href: "#",
  315. $components: [{
  316. $cell: true,
  317. $type: "i",
  318. class: "material-icons mdc-list-item__start-detail",
  319. $text: "inbox"
  320. },
  321. {
  322. $text: "Inbox "
  323. }
  324. ]
  325. },
  326. {
  327. $cell: true,
  328. $type: "a",
  329. class: "mdc-list-item mdc-persistent-drawer--selected",
  330. $href: "#",
  331. $components: [{
  332. $type: "i",
  333. class: "material-icons mdc-list-item__start-detail",
  334. 'aria-hidden': "true",
  335. $text: "star"
  336. },
  337. {
  338. $text: "Star "
  339. }]
  340. },
  341. {
  342. class: "mdc-textfield",
  343. $cell: true,
  344. $type: "div",
  345. $components: [{
  346. class: "mdc-textfield__input",
  347. $cell: true,
  348. $type: "input",
  349. type: "text"
  350. }]
  351. }, nodesCell
  352. ]
  353. }]
  354. }]
  355. };
  356. // <div class="mdc-form-field">
  357. // <input type="checkbox" id="input">
  358. // <label for="input">Input Label</label>
  359. // </div>
  360. document.querySelector("#drawer").$cell({
  361. $cell: true,
  362. $type: "aside",
  363. class: "mdc-persistent-drawer",
  364. $components: [drawerCell]
  365. }
  366. );
  367. let toolbar = {
  368. $cell: true,
  369. $type: "div",
  370. class: "mdc-toolbar__row",
  371. $components: [{
  372. $type: "section",
  373. class: "mdc-toolbar__section mdc-toolbar__section--align-start",
  374. $components: [
  375. {
  376. $type: "button",
  377. class: "demo-menu material-icons mdc-toolbar__icon--menu",
  378. $text: "menu"
  379. },
  380. {
  381. $type: "span",
  382. class: "mdc-toolbar__title catalog-title",
  383. $text: "LiveCoding.space"
  384. }
  385. ]
  386. }]
  387. };
  388. document.querySelector("#toolbar").$cell({
  389. $cell: true,
  390. $type: "div",
  391. class: "mdc-toolbar mdc-toolbar--fixed",
  392. $components: [toolbar]
  393. }
  394. );
  395. // let drawer = new mdc.drawer.MDCTemporaryDrawer(document.querySelector('.mdc-temporary-drawer'));
  396. // document.querySelector('.menu').addEventListener('click', () => drawer.open = true);
  397. var drawerEl = document.querySelector('.mdc-persistent-drawer');
  398. var MDCPersistentDrawer = mdc.drawer.MDCPersistentDrawer;
  399. var drawer = new MDCPersistentDrawer(drawerEl);
  400. document.querySelector('.demo-menu').addEventListener('click', function () {
  401. self.currentNodeID = (self.currentNodeID == '') ? (vwf_view.kernel.find("", "/")[0]) : self.currentNodeID;
  402. document.querySelector('#currentNode')._setNode(self.currentNodeID);
  403. drawer.open = !drawer.open;
  404. });
  405. drawerEl.addEventListener('MDCPersistentDrawer:open', function () {
  406. console.log('Received MDCPersistentDrawer:open');
  407. });
  408. drawerEl.addEventListener('MDCPersistentDrawer:close', function () {
  409. console.log('Received MDCPersistentDrawer:close');
  410. });
  411. $('#tabs').stop().animate({ opacity: 0.0 }, 0);
  412. $('#tabs').mouseenter(function (evt) {
  413. evt.stopPropagation();
  414. $('#tabs').stop().animate({ opacity: 1.0 }, 175);
  415. return false;
  416. });
  417. $('#tabs').mouseleave(function (evt) {
  418. evt.stopPropagation();
  419. $('#tabs').stop().animate({ opacity: 0.0 }, 175);
  420. return false;
  421. });
  422. $('#hierarchy').click(function (evt) {
  423. openEditor.call(self, 1);
  424. });
  425. $('#userlist').click(function (evt) {
  426. openEditor.call(self, 2);
  427. });
  428. $('#timeline').click(function (evt) {
  429. openEditor.call(self, 3);
  430. });
  431. $('#about').click(function (evt) {
  432. openEditor.call(self, 4);
  433. });
  434. $('#models').click(function (evt) {
  435. openEditor.call(self, 5);
  436. });
  437. $('#codeEditor').click(function (evt) {
  438. openEditor.call(self, 6);
  439. });
  440. $('#x').click(function (evt) {
  441. closeEditor.call(self);
  442. });
  443. $('#topdown_a').hide();
  444. $('#topdown_b').hide();
  445. $('#client_list').hide();
  446. $('#time_control').hide();
  447. $('#about_tab').hide();
  448. $('#codeEditor_tab').hide();
  449. $('#model_a').hide();
  450. $('#model_b').hide();
  451. var canvas = document.getElementById(vwf_view.kernel.find("", "/")[0]);
  452. if (canvas) {
  453. $('#topdown_a').height(canvas.height);
  454. $('#topdown_b').height(canvas.height);
  455. $('#client_list').height(canvas.height);
  456. $('#time_control').height(canvas.height);
  457. $('#about_tab').height(canvas.height);
  458. $('#codeEditor_tab').height(canvas.height);
  459. $('#model_a').height(canvas.height);
  460. $('#model_b').height(canvas.height);
  461. }
  462. else {
  463. $('#topdown_a').height(window.innerHeight - 20);
  464. $('#topdown_b').height(window.innerHeight - 20);
  465. $('#client_list').height(window.innerHeight - 20);
  466. $('#time_control').height(window.innerHeight - 20);
  467. $('#about_tab').height(window.innerHeight - 20);
  468. $('#codeEditor_tab').height(window.innerHeight - 20);
  469. $('#model_a').height(window.innerHeight - 20);
  470. $('#model_b').height(window.innerHeight - 20);
  471. }
  472. },
  473. createdNode: function (nodeID, childID, childExtendsID, childImplementsIDs,
  474. childSource, childType, childIndex, childName, callback /* ( ready ) */) {
  475. var nodeIDAttribute = $.encoder.encodeForHTMLAttribute("id", nodeID, true);
  476. var childIDAttribute = $.encoder.encodeForHTMLAttribute("id", childID, true);
  477. var childIDAlpha = $.encoder.encodeForAlphaNumeric(childID);
  478. var kernel = this.kernel;
  479. var self = this;
  480. var parent = this.nodes[nodeID];
  481. var node = this.nodes[childID] = {
  482. children: [],
  483. properties: [],
  484. events: {},
  485. methods: {},
  486. parent: parent,
  487. parentID: nodeID,
  488. ID: childID,
  489. extendsID: childExtendsID,
  490. implementsIDs: childImplementsIDs,
  491. source: childSource,
  492. name: childName,
  493. };
  494. if (parent) {
  495. parent.children.push(node);
  496. }
  497. if (childID == vwf_view.kernel.find("", "/")[0] && childExtendsID && this.kernel.test(childExtendsID,
  498. "self::element(*,'http://vwf.example.com/aframe/ascene.vwf')", childExtendsID)) {
  499. this.scenes[childID] = node;
  500. }
  501. if (nodeID === this.currentNodeID && this.editingScript == false) {
  502. $('#children > div:last').css('border-bottom-width', '1px');
  503. $("#children").append("<div id='" + childIDAlpha + "' data-nodeID='" + childIDAttribute + "' class='childContainer'><div class='childEntry'><b>" + $.encoder.encodeForHTML(childName) + "</b></div></div>");
  504. $('#' + childIDAlpha).click(function (evt) {
  505. drillDown.call(self, $(this).attr("data-nodeID"), nodeIDAttribute);
  506. });
  507. $('#children > div:last').css('border-bottom-width', '3px');
  508. }
  509. if (nodeID === this.kernel.application() && childName === 'camera') {
  510. this.activeCameraID = childID;
  511. }
  512. if (nodeID === this.kernel.application()) {
  513. // document.querySelector('a-scene').classList.add("mdc-toolbar-fixed-adjust");
  514. document.querySelector('body').classList.add("editor-body");
  515. }
  516. },
  517. createdProperty: function (nodeID, propertyName, propertyValue) {
  518. return this.initializedProperty(nodeID, propertyName, propertyValue);
  519. },
  520. initializedProperty: function (nodeID, propertyName, propertyValue) {
  521. var node = this.nodes[nodeID];
  522. if (!node) return; // TODO: patch until full-graph sync is working; drivers should be able to assume that nodeIDs refer to valid objects
  523. var property = node.properties[propertyName] = createProperty.call(this, node, propertyName, propertyValue);
  524. node.properties.push(property);
  525. },
  526. deletedNode: function (nodeID) {
  527. var node = this.nodes[nodeID];
  528. node.parent.children.splice(node.parent.children.indexOf(node), 1);
  529. delete this.nodes[nodeID];
  530. var nodeIDAttribute = $.encoder.encodeForAlphaNumeric(nodeID); // $.encoder.encodeForHTMLAttribute("id", nodeID, true);
  531. $('#' + nodeIDAttribute).remove();
  532. $('#children > div:last').css('border-bottom-width', '3px');
  533. },
  534. //addedChild: [ /* nodeID, childID, childName */ ],
  535. //removedChild: [ /* nodeID, childID */ ],
  536. satProperty: function (nodeID, propertyName, propertyValue) {
  537. var node = this.nodes[nodeID];
  538. if (!node) return; // TODO: patch until full-graph sync is working; drivers should be able to assume that nodeIDs refer to valid objects
  539. // It is possible for a property to have satProperty called for it without ever getting an
  540. // initializedProperty (if that property delegated to itself or another on replication)
  541. // Catch that case here and create the property
  542. if (!node.properties[propertyName]) {
  543. var property = node.properties[propertyName] = createProperty.call(this, node, propertyName, propertyValue);
  544. node.properties.push(property);
  545. }
  546. if (propertyName === "activeCamera") {
  547. if (this.nodes[propertyValue] !== undefined) {
  548. this.activeCameraID = propertyValue;
  549. }
  550. }
  551. try {
  552. propertyValue = utility.transform(propertyValue, utility.transforms.transit);
  553. node.properties[propertyName].value = JSON.stringify(propertyValue);
  554. node.properties[propertyName].rawValue = propertyValue;
  555. } catch (e) {
  556. this.logger.warnx("satProperty", nodeID, propertyName, propertyValue,
  557. "stringify error:", e.message);
  558. node.properties[propertyName].value = propertyValue;
  559. }
  560. if ((this.editorView == 1) && (this.currentNodeID == nodeID)) {
  561. var nodeIDAttribute = $.encoder.encodeForAlphaNumeric(nodeID); // $.encoder.encodeForHTMLAttribute("id", nodeID, true);
  562. var propertyNameAttribute = $.encoder.encodeForAlphaNumeric("id", propertyName, true);
  563. // No need to escape propertyValue, because .val does its own escaping
  564. $('#input-' + nodeIDAttribute + '-' + propertyNameAttribute).val(node.properties[propertyName].getValue());
  565. }
  566. },
  567. //gotProperty: [ /* nodeID, propertyName, propertyValue */ ],
  568. createdMethod: function (nodeID, methodName, methodParameters, methodBody) {
  569. var node = this.nodes[nodeID];
  570. if (node) {
  571. node.methods[methodName] = methodParameters;
  572. }
  573. },
  574. //calledMethod: function( nodeID, methodName, methodParameters, methodValue ) {
  575. //},
  576. createdEvent: function (nodeID, eventName, eventParameters) {
  577. var node = this.nodes[nodeID];
  578. if (node) {
  579. node.events[eventName] = eventParameters;
  580. }
  581. },
  582. firedEvent: function (nodeID, eventName, eventParameters) {
  583. if (eventName == "pointerHover") {
  584. highlightChildInHierarchy.call(this, nodeID);
  585. }
  586. },
  587. executed: function (nodeID, scriptText, scriptType) {
  588. // var nodeScript = {
  589. // text: scriptText,
  590. // type: scriptType,
  591. // };
  592. // if ( !this.allScripts[ nodeID ] ) {
  593. // var nodeScripts = new Array();
  594. // nodeScripts.push(nodeScript);
  595. // this.allScripts[ nodeID ] = nodeScripts;
  596. // }
  597. // else {
  598. // this.allScripts[ nodeID ].push(nodeScript);
  599. // }
  600. },
  601. //ticked: [ /* time */ ],
  602. });
  603. // -- getChildByName --------------------------------------------------------------------
  604. function getChildByName(node, childName) {
  605. var childNode = undefined;
  606. for (var i = 0; i < node.children.length && childNode === undefined; i++) {
  607. if (node.children[i].name == childName) {
  608. childNode = node.children[i];
  609. }
  610. }
  611. return childNode;
  612. };
  613. function updateCameraProperties() {
  614. if (this.currentNodeID == this.activeCameraID) {
  615. if (!this.intervalTimer) {
  616. var self = this;
  617. this.intervalTimer = setInterval(function () { updateProperties.call(self, self.activeCameraID) }, 200);
  618. }
  619. }
  620. else {
  621. if (this.intervalTimer) {
  622. clearInterval(this.intervalTimer);
  623. this.intervalTimer = 0;
  624. }
  625. }
  626. }
  627. function updateProperties(nodeName) {
  628. var nodeID = nodeName;
  629. var properties = getProperties.call(this, this.kernel, nodeID);
  630. for (var i in properties) {
  631. try {
  632. var propertyName = properties[i].prop.name;
  633. var propertyValue = JSON.stringify(utility.transform(vwf.getProperty(nodeID, propertyName, []), utility.transforms.transit));
  634. } catch (e) {
  635. this.logger.warnx("satProperty", nodeID, propertyName, propertyValue, "stringify error:", e.message);
  636. }
  637. if (propertyValue) {
  638. var nodeIDAttribute = $.encoder.encodeForAlphaNumeric(nodeID);
  639. var propertyNameAttribute = $.encoder.encodeForHTMLAttribute("id", propertyName, true);
  640. var inputElement$ = $('#input-' + nodeIDAttribute + '-' + propertyNameAttribute);
  641. // Only update if property value input is not in focus
  642. // If in focus, change font style to italic
  643. if (!inputElement$.is(":focus")) {
  644. inputElement$.val(propertyValue);
  645. inputElement$.css("font-style", "normal");
  646. } else {
  647. inputElement$.css("font-style", "italic");
  648. }
  649. }
  650. }
  651. }
  652. // -- openEditor ------------------------------------------------------------------------
  653. function openEditor(eView) // invoke with the view as "this"
  654. {
  655. if (eView == 0) {
  656. closeEditor.call(this);
  657. }
  658. if (this.editorView != eView) {
  659. // Hierarchy
  660. if (eView == 1) {
  661. var topdownName = this.topdownName;
  662. var topdownTemp = this.topdownTemp;
  663. if (!this.currentNodeID) {
  664. this.currentNodeID = vwf_view.kernel.find("", "/")[0];
  665. }
  666. drill.call(this, this.currentNodeID, undefined);
  667. $(this.clientList).hide();
  668. $(this.timeline).hide();
  669. $(this.about).hide();
  670. $(this.codeEditor).hide();
  671. $(this.models).hide();
  672. if (this.editorOpen) {
  673. $(topdownName).hide();
  674. $(topdownTemp).show();
  675. }
  676. else {
  677. $(topdownTemp).show('slide', { direction: 'right' }, 175);
  678. }
  679. this.topdownName = topdownTemp;
  680. this.topdownTemp = topdownName;
  681. }
  682. else if (this.editingScript) {
  683. // Reset width if on script
  684. this.editingScript = false;
  685. $('#editor').animate({ 'left': "-260px" }, 175);
  686. $('.vwf-tree').animate({ 'width': "260px" }, 175);
  687. }
  688. // User List
  689. if (eView == 2) {
  690. $(this.topdownName).hide();
  691. $(this.topdownTemp).hide();
  692. $(this.timeline).hide();
  693. $(this.about).hide();
  694. $(this.codeEditor).hide();
  695. $(this.models).hide();
  696. $(this.modelsTemp).hide();
  697. showUserList.call(this);
  698. }
  699. // Timeline
  700. else if (eView == 3) {
  701. $(this.topdownName).hide();
  702. $(this.topdownTemp).hide();
  703. $(this.clientList).hide();
  704. $(this.about).hide();
  705. $(this.codeEditor).hide();
  706. $(this.models).hide();
  707. $(this.modelsTemp).hide();
  708. showTimeline.call(this);
  709. }
  710. // About
  711. else if (eView == 4) {
  712. $(this.topdownName).hide();
  713. $(this.topdownTemp).hide();
  714. $(this.clientList).hide();
  715. $(this.timeline).hide();
  716. $(this.models).hide();
  717. $(this.modelsTemp).hide();
  718. $(this.codeEditor).hide();
  719. showAboutTab.call(this);
  720. }
  721. // Models
  722. else if (eView == 5) {
  723. var models = this.models;
  724. var modelsTemp = this.modelsTemp;
  725. showModelsTab.call(this, this.currentModelID, this.currentModelURL);
  726. $(this.topdownName).hide();
  727. $(this.topdownTemp).hide();
  728. $(this.clientList).hide();
  729. $(this.timeline).hide();
  730. $(this.about).hide();
  731. $(this.codeEditor).hide();
  732. if (this.editorOpen) {
  733. $(models).hide();
  734. $(modelsTemp).show();
  735. }
  736. else {
  737. $(modelsTemp).show('slide', { direction: 'right' }, 175);
  738. }
  739. this.models = modelsTemp;
  740. this.modelsTemp = models;
  741. }
  742. // Code Editor
  743. else if (eView == 6) {
  744. $(this.topdownName).hide();
  745. $(this.topdownTemp).hide();
  746. $(this.clientList).hide();
  747. $(this.timeline).hide();
  748. $(this.models).hide();
  749. $(this.modelsTemp).hide();
  750. $(this.about).hide();
  751. showCodeEditorTab.call(this);
  752. }
  753. if (this.editorView == 0) {
  754. $('#vwf-root').animate({ 'left': "-=260px" }, 175);
  755. $('#editor').animate({ 'left': "-260px" }, 175);
  756. $('#x').delay(1000).css({ 'display': 'inline' });
  757. }
  758. this.editorView = eView;
  759. this.editorOpen = true;
  760. }
  761. }
  762. // -- closeEditor -----------------------------------------------------------------------
  763. function closeEditor() // invoke with the view as "this"
  764. {
  765. var topdownName = this.topdownName;
  766. if (this.editorOpen && this.editorView == 1) // Hierarchy view open
  767. {
  768. $(topdownName).hide('slide', { direction: 'right' }, 175);
  769. $(topdownName).empty();
  770. $(this.clientList).hide();
  771. $(this.timeline).hide();
  772. $(this.about).hide();
  773. $(this.codeEditor).hide();
  774. $(this.models).hide();
  775. }
  776. else if (this.editorOpen && this.editorView == 2) // Client list open
  777. {
  778. $(this.clientList).hide('slide', { direction: 'right' }, 175);
  779. $(topdownName).hide();
  780. $(this.timeline).hide();
  781. $(this.about).hide();
  782. $(this.codeEditor).hide();
  783. $(this.models).hide();
  784. }
  785. else if (this.editorOpen && this.editorView == 3) // Timeline open
  786. {
  787. $(this.timeline).hide('slide', { direction: 'right' }, 175);
  788. $(topdownName).hide();
  789. $(this.clientList).hide();
  790. $(this.about).hide();
  791. $(this.models).hide();
  792. }
  793. else if (this.editorOpen && this.editorView == 4) // About open
  794. {
  795. $(this.about).hide('slide', { direction: 'right' }, 175);
  796. $(this.codeEditor).hide();
  797. $(topdownName).hide();
  798. $(this.clientList).hide();
  799. $(this.timeline).hide();
  800. $(this.models).hide();
  801. }
  802. else if (this.editorOpen && this.editorView == 5) // Models open
  803. {
  804. $(this.models).hide('slide', { direction: 'right' }, 175);
  805. $(topdownName).hide();
  806. $(this.clientList).hide();
  807. $(this.timeline).hide();
  808. $(this.about).hide();
  809. $(this.codeEditor).hide();
  810. }
  811. else if (this.editorOpen && this.editorView == 6) // Code Editor open
  812. {
  813. $(this.codeEditor).hide('slide', { direction: 'right' }, 175);
  814. $(this.about).hide();
  815. $(topdownName).hide();
  816. $(this.clientList).hide();
  817. $(this.timeline).hide();
  818. $(this.models).hide();
  819. }
  820. $('#vwf-root').animate({ 'left': "+=260px" }, 175);
  821. $('#editor').animate({ 'left': "0px" }, 175);
  822. $('#x').css({ 'display': 'none' });
  823. this.editorView = 0;
  824. this.editorOpen = false;
  825. }
  826. // -- showUserList ----------------------------------------------------------------------
  827. function showUserList() // invoke with the view as "this"
  828. {
  829. var clientList = this.clientList;
  830. viewClients.call(this);
  831. if (!this.editorOpen) {
  832. $(clientList).show('slide', { direction: 'right' }, 175);
  833. }
  834. else {
  835. $(clientList).show();
  836. }
  837. }
  838. // -- viewClients -----------------------------------------------------------------------
  839. function viewClients() {
  840. var self = this;
  841. var app = window.location.pathname;
  842. var pathSplit = app.split('/');
  843. if (pathSplit[0] == "") {
  844. pathSplit.shift();
  845. }
  846. if (pathSplit[pathSplit.length - 1] == "") {
  847. pathSplit.pop();
  848. }
  849. var instIndex = pathSplit.length - 1;
  850. if (pathSplit.length > 2) {
  851. if (pathSplit[pathSplit.length - 2] == "load") {
  852. instIndex = pathSplit.length - 3;
  853. }
  854. }
  855. if (pathSplit.length > 3) {
  856. if (pathSplit[pathSplit.length - 3] == "load") {
  857. instIndex = pathSplit.length - 4;
  858. }
  859. }
  860. var root = "";
  861. for (var i = 0; i < instIndex; i++) {
  862. if (root != "") {
  863. root = root + "/";
  864. }
  865. root = root + pathSplit[i];
  866. }
  867. if (root.indexOf('.vwf') != -1) root = root.substring(0, root.lastIndexOf('/'));
  868. var clients$ = $(this.clientList);
  869. var node = this.nodes["http://vwf.example.com/clients.vwf"];
  870. clients$.html("<div class='header'>Connected Clients</div>");
  871. // Add node children
  872. clients$.append("<div id='clientsChildren'></div>");
  873. for (var i = 0; i < node.children.length; i++) {
  874. var nodeChildIDAttribute = $.encoder.encodeForHTMLAttribute("id", node.children[i].ID, true);
  875. var nodeChildIDAlpha = $.encoder.encodeForAlphaNumeric(node.children[i].ID);
  876. var nodeChildNameHTML = $.encoder.encodeForHTML(node.children[i].name);
  877. $('#clientsChildren').append("<div id='" + nodeChildIDAlpha + "' data-nodeID='" + nodeChildIDAttribute + "' class='childContainer'><div class='childEntry'><b>" + nodeChildNameHTML + "</b></div></div>");
  878. $('#' + nodeChildIDAlpha).click(function (evt) {
  879. viewClient.call(self, $(this).attr("data-nodeID"));
  880. });
  881. }
  882. // Login Information
  883. 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>");
  884. clients$.append("<hr/>");
  885. $('#userName').keydown(function (evt) {
  886. evt.stopPropagation();
  887. });
  888. $('#userName').keypress(function (evt) {
  889. evt.stopPropagation();
  890. });
  891. $('#userName').keyup(function (evt) {
  892. evt.stopPropagation();
  893. });
  894. $('#password').keydown(function (evt) {
  895. evt.stopPropagation();
  896. });
  897. $('#password').keypress(function (evt) {
  898. evt.stopPropagation();
  899. });
  900. $('#password').keyup(function (evt) {
  901. evt.stopPropagation();
  902. });
  903. $('#login').click(function (evt) {
  904. // Future call to validate username and password
  905. //login.call(self, $('#userName').val(), $('#password').val());
  906. var moniker = vwf_view.kernel.moniker();
  907. var clients = vwf_view.kernel.findClients("", "/*");
  908. var client = undefined;
  909. for (var i = 0; i < clients.length; i++) {
  910. if (clients[i].indexOf(moniker) != -1) {
  911. client = clients[i];
  912. break;
  913. }
  914. }
  915. // var client = vwf_view.kernel.findClients("", "/" + moniker)[0];
  916. if (client) {
  917. vwf_view.kernel.setProperty(client, "displayName", $('#userName').val());
  918. }
  919. });
  920. // clients$.append("<div style='padding:6px'><input class='live_button' type='button' id='liveeditor' value='Open Code Editor' /></div>");
  921. // $('#liveeditor').click(function(evt) {
  922. // openLiveEditor.call(self);
  923. // });
  924. // Save / Load
  925. 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>");
  926. $('#fileName').keydown(function (evt) {
  927. evt.stopPropagation();
  928. });
  929. $('#fileName').keypress(function (evt) {
  930. evt.stopPropagation();
  931. });
  932. $('#fileName').keyup(function (evt) {
  933. evt.stopPropagation();
  934. });
  935. $('#save').click(function (evt) {
  936. saveStateAsFile.call(self, $('#fileName').val());
  937. });
  938. clients$.append("<div style='padding:6px'><select class='filename_select' id='fileToLoad' /></select></div>");
  939. $('#fileToLoad').append("<option value='none'></option>");
  940. $.getJSON("/" + root + "/listallsaves", function (data) {
  941. $.each(data, function (key, value) {
  942. var applicationName = value['applicationpath'].split("/");
  943. if (applicationName.length > 0) {
  944. applicationName = applicationName[applicationName.length - 1];
  945. }
  946. if (applicationName.length > 0) {
  947. applicationName = applicationName.charAt(0).toUpperCase() + applicationName.slice(1);
  948. }
  949. if (value['latestsave']) {
  950. $('#fileToLoad').append("<option value='" + value['savename'] + "' applicationpath='" + value['applicationpath'] + "'>" + applicationName + ": " + value['savename'] + "</option>");
  951. }
  952. else {
  953. $('#fileToLoad').append("<option value='" + value['savename'] + "' applicationpath='" + value['applicationpath'] + "' revision='" + value['revision'] + "'>" + applicationName + ": " + value['savename'] + " Rev(" + value['revision'] + ")</option>");
  954. }
  955. });
  956. });
  957. clients$.append("<div style='padding:6px'><input class='update_button' type='button' id='load' value='Load' /></div>");
  958. $('#load').click(function (evt) {
  959. loadSavedState.call(self, $('#fileToLoad').val(), $('#fileToLoad').find(':selected').attr('applicationpath'), $('#fileToLoad').find(':selected').attr('revision'));
  960. });
  961. }
  962. // -- editor ---
  963. function openLiveEditor(value) {
  964. //this.liveditor = document.createElement('div');
  965. //this.liveditor.setAttribute('id', "editorlive");
  966. // $('body').append(this.liveditor);
  967. var editor = this.ace.edit("editorlive");
  968. editor.setTheme("ace/theme/monokai");
  969. editor.getSession().setMode("ace/mode/javascript");
  970. }
  971. // -- viewClient ------------------------------------------------------------------------
  972. function viewClient(clientID) {
  973. var self = this;
  974. var clients$ = $(this.clientList);
  975. var node = this.nodes[clientID];
  976. clients$.html("<div class='header'><img src='images/back.png' id='back' alt='back'/> " + $.encoder.encodeForHTML(node.name) + "</div>");
  977. $('#back').click(function (evt) {
  978. viewClients.call(self);
  979. });
  980. // Add node properties
  981. clients$.append("<div id='clientProperties'></div>");
  982. var displayedProperties = {};
  983. for (var i = 0; i < node.properties.length; i++) {
  984. if (!displayedProperties[node.properties[i].name]) {
  985. displayedProperties[node.properties[i].name] = "instance";
  986. var nodeIDAlpha = $.encoder.encodeForAlphaNumeric(clientID);
  987. var propertyNameAttribute = $.encoder.encodeForHTMLAttribute("id", node.properties[i].name, true);
  988. var propertyNameAlpha = $.encoder.encodeForAlphaNumeric(node.properties[i].name);
  989. var propertyNameHTML = $.encoder.encodeForHTML(node.properties[i].name);
  990. var propertyValueAttribute = $.encoder.encodeForHTMLAttribute("val", node.properties[i].getValue(), true);
  991. $('#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>");
  992. }
  993. }
  994. }
  995. // -- drillDown -------------------------------------------------------------------------
  996. function drillDown(nodeID, drillBackID) // invoke with the view as "this"
  997. {
  998. var topdownName = this.topdownName;
  999. var topdownTemp = this.topdownTemp;
  1000. drill.call(this, nodeID, drillBackID);
  1001. if (nodeID != vwf_view.kernel.find("", "/")[0]) $(topdownName).hide('slide', { direction: 'left' }, 175);
  1002. $(topdownTemp).show('slide', { direction: 'right' }, 175);
  1003. this.topdownName = topdownTemp;
  1004. this.topdownTemp = topdownName;
  1005. }
  1006. // -- drillUp ---------------------------------------------------------------------------
  1007. function drillUp(nodeID) // invoke with the view as "this"
  1008. {
  1009. var topdownName = this.topdownName;
  1010. var topdownTemp = this.topdownTemp;
  1011. drill.call(this, nodeID, undefined);
  1012. $(topdownName).hide('slide', { direction: 'right' }, 175);
  1013. $(topdownTemp).show('slide', { direction: 'left' }, 175);
  1014. this.topdownName = topdownTemp;
  1015. this.topdownTemp = topdownName;
  1016. }
  1017. // -- drillBack---------------------------------------------------------------------------
  1018. function drillBack(nodeID) // invoke with the view as "this"
  1019. {
  1020. var topdownName = this.topdownName;
  1021. var topdownTemp = this.topdownTemp;
  1022. drill.call(this, nodeID, undefined);
  1023. // No slide motion, when resizing script window back to normal
  1024. $(topdownName).hide();
  1025. $(topdownTemp).show();
  1026. this.topdownName = topdownTemp;
  1027. this.topdownTemp = topdownName;
  1028. }
  1029. // -- drill -----------------------------------------------------------------------------
  1030. function drill(nodeID, drillBackID) // invoke with the view as "this"
  1031. {
  1032. var node = this.nodes[nodeID];
  1033. if (!node) {
  1034. this.logger.errorx("drill: Cannot find node '" + nodeID + "'");
  1035. return;
  1036. }
  1037. var self = this;
  1038. var topdownName = this.topdownName;
  1039. var topdownTemp = this.topdownTemp;
  1040. var nodeIDAlpha = $.encoder.encodeForAlphaNumeric(nodeID);
  1041. $(topdownName).html(''); // Clear alternate div first to ensure content is added correctly
  1042. this.currentNodeID = nodeID;
  1043. if (!drillBackID) drillBackID = node.parentID;
  1044. if (nodeID == vwf_view.kernel.find("", "/")[0]) {
  1045. $(topdownTemp).html("<div class='header'>index</div>");
  1046. }
  1047. else {
  1048. $(topdownTemp).html("<div class='header'><img src='images/back.png' id='" + nodeIDAlpha + "-back' alt='back'/> " + $.encoder.encodeForHTML(node.name) + "</div>");
  1049. $('#' + nodeIDAlpha + '-back').click(function (evt) {
  1050. drillUp.call(self, drillBackID);
  1051. });
  1052. }
  1053. // Add node children
  1054. $(topdownTemp).append("<div id='children'></div>");
  1055. for (var i = 0; i < node.children.length; i++) {
  1056. var nodeChildIDAttribute = $.encoder.encodeForHTMLAttribute("id", node.children[i].ID, true);
  1057. var nodeChildIDAlpha = $.encoder.encodeForAlphaNumeric(node.children[i].ID);
  1058. $('#children').append("<div id='" + nodeChildIDAlpha + "' data-nodeID='" + nodeChildIDAttribute + "' class='childContainer'><div class='childEntry'><b>" + $.encoder.encodeForHTML(node.children[i].name) + "</b></div></div>");
  1059. $('#' + nodeChildIDAlpha).click(function (evt) {
  1060. drillDown.call(self, $(this).attr("data-nodeID"), nodeID);
  1061. });
  1062. }
  1063. $('#children > div:last').css('border-bottom-width', '3px');
  1064. // Add prototype children
  1065. // TODO: Commented out until prototype children inherit from prototypes
  1066. /*
  1067. $(topdownTemp).append("<div id='prototypeChildren'></div>");
  1068. var prototypeChildren = getChildren.call( this, this.kernel, node.extendsID );
  1069. for ( var key in prototypeChildren)
  1070. {
  1071. var child = prototypeChildren[key];
  1072. var prototypeChildIDAttribute = $.encoder.encodeForHTMLAttribute("id", child.ID, true);
  1073. var prototypeChildIDAlpha = $.encoder.encodeForAlphaNumeric(child.ID);
  1074. $('#prototypeChildren').append("<div id='" + prototypeChildIDAlpha + "' data-nodeID='" + prototypeChildIDAttribute + "' class='childContainer'><div class='childEntry'><b>" + $.encoder.encodeForHTML(child.name) + "</b></div></div>");
  1075. $('#' + prototypeChildIDAlpha).click( function(evt) {
  1076. drillDown.call(self, $(this).attr("data-nodeID"), nodeID);
  1077. });
  1078. }
  1079. */ // END TODO:
  1080. $('#prototypeChildren > div:last').css('border-bottom-width', '3px');
  1081. // Add node properties
  1082. $(topdownTemp).append("<div id='properties'></div>");
  1083. var displayedProperties = {};
  1084. for (var i = 0; i < node.properties.length; i++) {
  1085. if (!displayedProperties[node.properties[i].name] && node.properties[i].name.indexOf('$') === -1) {
  1086. displayedProperties[node.properties[i].name] = "instance";
  1087. var propertyNameAttribute = $.encoder.encodeForHTMLAttribute("id", node.properties[i].name, true);
  1088. var propertyNameAlpha = $.encoder.encodeForAlphaNumeric(node.properties[i].name);
  1089. var propertyNameHTML = $.encoder.encodeForHTML(node.properties[i].name);
  1090. var propertyValueAttribute = $.encoder.encodeForHTMLAttribute("val", node.properties[i].getValue(), true);
  1091. if (propertyNameAlpha.indexOf("semantics") > -1) {
  1092. } else if (propertyNameAlpha.indexOf("grammar") > -1) {
  1093. } else if (propertyNameAlpha.indexOf("ohm") > -1) {
  1094. let propName = propertyNameAlpha;
  1095. let propValue = node.properties[i].rawValue;
  1096. $(topdownTemp).append("<div id='" + nodeIDAlpha + "-" + propertyNameAlpha + "'></div>");
  1097. $('#' + nodeIDAlpha + '-' + propertyNameAlpha).append("<div class='childContainer'><div class='childEntry'><b>" + propertyNameHTML + "</div></div>");
  1098. $('#' + nodeIDAlpha + '-' + propertyNameAlpha).click(function (evt) {
  1099. editOhmLang.call(self, nodeID, propName, propValue);
  1100. });
  1101. // $('#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>");
  1102. } else {
  1103. $('#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>");
  1104. }
  1105. $('#input-' + nodeIDAlpha + '-' + propertyNameAttribute).change(function (evt) {
  1106. var propName = $.encoder.canonicalize($(this).attr("data-propertyName"));
  1107. var propValue = $(this).val();
  1108. try {
  1109. propValue = JSON.parse($.encoder.canonicalize(propValue));
  1110. self.kernel.setProperty(nodeID, propName, propValue);
  1111. } catch (e) {
  1112. // restore the original value on error
  1113. $(this).val(propValue);
  1114. }
  1115. });
  1116. $('#input-' + nodeIDAlpha + '-' + propertyNameAlpha).keydown(function (evt) {
  1117. evt.stopPropagation();
  1118. });
  1119. $('#input-' + nodeIDAlpha + '-' + propertyNameAlpha).keypress(function (evt) {
  1120. evt.stopPropagation();
  1121. });
  1122. $('#input-' + nodeIDAlpha + '-' + propertyNameAlpha).keyup(function (evt) {
  1123. evt.stopPropagation();
  1124. });
  1125. }
  1126. }
  1127. $('#properties > div:last').css('border-bottom-width', '3px');
  1128. this.logger.info(self + " " + nodeID);
  1129. // Add prototype properties
  1130. $(topdownTemp).append("<div id='prototypeProperties'></div>");
  1131. var prototypeProperties = getProperties.call(this, this.kernel, node.extendsID);
  1132. for (var key in prototypeProperties) {
  1133. var prop = prototypeProperties[key].prop;
  1134. if (!displayedProperties[prop.name]) {
  1135. displayedProperties[prop.name] = prototypeProperties[key].prototype;
  1136. if (prop.value == undefined) {
  1137. prop.value = JSON.stringify(utility.transform(vwf.getProperty(nodeID, prop.name, []), utility.transforms.transit));
  1138. }
  1139. var propertyNameAttribute = $.encoder.encodeForHTMLAttribute("id", prop.name, true);
  1140. var propertyNameAlpha = $.encoder.encodeForAlphaNumeric(prop.name);
  1141. var propertyNameHTML = $.encoder.encodeForHTML(prop.name);
  1142. var propertyValueAttribute = $.encoder.encodeForHTMLAttribute("val", prop.value, true);
  1143. $('#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>");
  1144. $('#input-' + nodeIDAlpha + '-' + propertyNameAlpha).change(function (evt) {
  1145. var propName = $.encoder.canonicalize($(this).attr("data-propertyName"));
  1146. var propValue = $(this).val();
  1147. try {
  1148. propValue = JSON.parse($.encoder.canonicalize(propValue));
  1149. self.kernel.setProperty(nodeID, propName, propValue);
  1150. } catch (e) {
  1151. // restore the original value on error
  1152. $(this).val(propValue);
  1153. }
  1154. });
  1155. $('#input-' + nodeIDAlpha + '-' + propertyNameAlpha).keydown(function (evt) {
  1156. evt.stopPropagation();
  1157. });
  1158. $('#input-' + nodeIDAlpha + '-' + propertyNameAlpha).keypress(function (evt) {
  1159. evt.stopPropagation();
  1160. });
  1161. $('#input-' + nodeIDAlpha + '-' + propertyNameAlpha).keyup(function (evt) {
  1162. evt.stopPropagation();
  1163. });
  1164. }
  1165. }
  1166. $('#prototypeProperties > div:last').css('border-bottom-width', '3px');
  1167. // Add node methods
  1168. $(topdownTemp).append("<div id='methods'></div>");
  1169. for (var key in node.methods) {
  1170. var method = node.methods[key];
  1171. var methodNameAlpha = $.encoder.encodeForAlphaNumeric(key);
  1172. var methodNameAttribute = $.encoder.encodeForHTMLAttribute("id", key, true);
  1173. var methodNameHTML = $.encoder.encodeForHTML(key);
  1174. $('#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>");
  1175. $('#rollover-' + methodNameAlpha).mouseover(function (evt) {
  1176. $('#param-' + $(this).attr("id").substring(9)).css('visibility', 'visible');
  1177. });
  1178. $('#rollover-' + methodNameAlpha).mouseleave(function (evt) {
  1179. $('#param-' + $(this).attr("id").substring(9)).css('visibility', 'hidden');
  1180. });
  1181. $('#call-' + methodNameAlpha).click(function (evt) {
  1182. self.kernel.callMethod(nodeID, $.encoder.canonicalize($(this).attr("data-methodName")));
  1183. });
  1184. $('#param-' + methodNameAlpha).click(function (evt) {
  1185. setParams.call(self, $.encoder.canonicalize($(this).attr("data-methodName")), method, nodeID);
  1186. });
  1187. }
  1188. $('#methods > div:last').css('border-bottom-width', '3px');
  1189. // Add prototype methods
  1190. $(topdownTemp).append("<div id='prototypeMethods'></div>");
  1191. var prototypeMethods = getMethods.call(this, this.kernel, node.extendsID);
  1192. for (var key in prototypeMethods) {
  1193. var method = prototypeMethods[key];
  1194. var prototypeMethodNameAlpha = $.encoder.encodeForAlphaNumeric(key);
  1195. var prototypeMethodNameAttribute = $.encoder.encodeForHTMLAttribute("id", key, true);
  1196. var prototypeMethodNameHTML = $.encoder.encodeForHTML(key);
  1197. $('#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>");
  1198. $('#rollover-' + prototypeMethodNameAlpha).mouseover(function (evt) {
  1199. $('#param-' + $(this).attr("id").substring(9)).css('visibility', 'visible');
  1200. });
  1201. $('#rollover-' + prototypeMethodNameAlpha).mouseleave(function (evt) {
  1202. $('#param-' + $(this).attr("id").substring(9)).css('visibility', 'hidden');
  1203. });
  1204. $('#call-' + prototypeMethodNameAlpha).click(function (evt) {
  1205. self.kernel.callMethod(nodeID, $.encoder.canonicalize($(this).attr("data-methodName")));
  1206. });
  1207. $('#param-' + prototypeMethodNameAlpha).click(function (evt) {
  1208. setParams.call(self, $.encoder.canonicalize($(this).attr("data-methodName")), method, nodeID);
  1209. });
  1210. }
  1211. $('#prototypeMethods > div:last').css('border-bottom-width', '3px');
  1212. // Add node events
  1213. $(topdownTemp).append("<div id='events'></div>");
  1214. for (var key in node.events) {
  1215. var nodeEvent = node.events[key];
  1216. var eventNameAlpha = $.encoder.encodeForAlphaNumeric(key);
  1217. var eventNameAttribute = $.encoder.encodeForHTMLAttribute("id", key, true);
  1218. var eventNameHTML = $.encoder.encodeForHTML(key);
  1219. $('#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>");
  1220. $('#rollover-' + eventNameAlpha).mouseover(function (evt) {
  1221. $('#arg-' + $(this).attr("id").substring(9)).css('visibility', 'visible');
  1222. });
  1223. $('#rollover-' + eventNameAlpha).mouseleave(function (evt) {
  1224. $('#arg-' + $(this).attr("id").substring(9)).css('visibility', 'hidden');
  1225. });
  1226. $('#fire-' + eventNameAlpha).click(function (evt) {
  1227. self.kernel.fireEvent(nodeID, $.encoder.canonicalize($(this).attr("data-eventName")));
  1228. });
  1229. $('#arg-' + eventNameAlpha).click(function (evt) {
  1230. setArgs.call(self, $.encoder.canonicalize($(this).attr("data-eventName")), nodeEvent, nodeID);
  1231. });
  1232. }
  1233. $('#events > div:last').css('border-bottom-width', '3px');
  1234. // Add prototype events
  1235. $(topdownTemp).append("<div id='prototypeEvents'></div>");
  1236. var prototypeEvents = getEvents.call(this, this.kernel, node.extendsID);
  1237. for (var key in prototypeEvents) {
  1238. var nodeEvent = prototypeEvents[key];
  1239. var prototypeEventNameAlpha = $.encoder.encodeForAlphaNumeric(key);
  1240. var prototypeEventNameAttribute = $.encoder.encodeForHTMLAttribute("id", key, true);
  1241. var prototypeEventNameHTML = $.encoder.encodeForHTML(key);
  1242. $('#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>");
  1243. $('#rollover-' + prototypeEventNameAlpha).mouseover(function (evt) {
  1244. $('#arg-' + $(this).attr("id").substring(9)).css('visibility', 'visible');
  1245. });
  1246. $('#rollover-' + prototypeEventNameAlpha).mouseleave(function (evt) {
  1247. $('#arg-' + $(this).attr("id").substring(9)).css('visibility', 'hidden');
  1248. });
  1249. $('#fire-' + prototypeEventNameAlpha).click(function (evt) {
  1250. self.kernel.fireEvent(nodeID, $.encoder.canonicalize($(this).attr("data-eventName")));
  1251. });
  1252. $('#arg-' + prototypeEventNameAlpha).click(function (evt) {
  1253. setArgs.call(self, $.encoder.canonicalize($(this).attr("data-eventName")), nodeEvent, nodeID);
  1254. });
  1255. }
  1256. $('#prototypeEvents > div:last').css('border-bottom-width', '3px');
  1257. // Add node behaviors
  1258. $(topdownTemp).append("<div id='behaviors'></div>");
  1259. for (var i = 0; i < node.implementsIDs.length; i++) {
  1260. var nodeImplementsIDAlpha = $.encoder.encodeForAlphaNumeric(node.implementsIDs[i]);
  1261. var nodeImplementsIDHTML = $.encoder.encodeForHTML(node.implementsIDs[i]);
  1262. $('#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>");
  1263. /*
  1264. //Placeholder to Enable/Disable behaviors
  1265. $('#' + node.implementsID[i] + '-enable').change( function(evt) {
  1266. });
  1267. */
  1268. }
  1269. $('#behaviors > div:last').css('border-bottom-width', '3px');
  1270. // Add prototype behaviors
  1271. $(topdownTemp).append("<div id='prototypeBehaviors'></div>");
  1272. var prototypeNode = this.nodes[node.extendsID];
  1273. for (var i = 0; i < prototypeNode.implementsIDs.length; i++) {
  1274. var prototypeImplementsIDAlpha = $.encoder.encodeForAlphaNumeric(prototypeNode.implementsIDs[i]);
  1275. var prototypeImplementsIDHTML = $.encoder.encodeForHTML(prototypeNode.implementsIDs[i]);
  1276. $('#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>");
  1277. }
  1278. $('#prototypeBehaviors > div:last').css('border-bottom-width', '3px');
  1279. // Create new method
  1280. $(topdownTemp).append("<div id='createMethodID'></div>");
  1281. $('#createMethodID').append("<div class='childContainer'><div class='childEntry'><b>New Method</div></div>");
  1282. $('#createMethodID').click(function (evt) {
  1283. createMethod.call(self, nodeID);
  1284. });
  1285. // Create new Event
  1286. $(topdownTemp).append("<div id='createEventID'></div>");
  1287. $('#createEventID').append("<div class='childContainer'><div class='childEntry'><b>New Event</div></div>");
  1288. $('#createEventID').click(function (evt) {
  1289. createEvent.call(self, nodeID);
  1290. });
  1291. // Create new script
  1292. $(topdownTemp).append("<div id='createScript'></div>");
  1293. $('#createScript').append("<div class='childContainer'><div class='childEntry'><b>New Script</div></div>");
  1294. $('#createScript').click(function (evt) {
  1295. createScript.call(self, nodeID);
  1296. });
  1297. $('#createScript > div:last').css('border-bottom-width', '3px');
  1298. if (this.allScripts[nodeID] !== undefined) {
  1299. // Add node scripts
  1300. $(topdownTemp).append("<div id='scripts'></div>");
  1301. for (var i = 0; i < this.allScripts[nodeID].length; i++) {
  1302. var scriptFull = this.allScripts[nodeID][i].text;
  1303. if (scriptFull != undefined) {
  1304. var scriptName = scriptFull.substring(0, scriptFull.indexOf('='));
  1305. $('#scripts').append("<div id='script-" + nodeIDAlpha + "-" + i + "' class='childContainer'><div class='childEntry'><b>script </b>" + scriptName + "</div></div>");
  1306. $('#script-' + nodeIDAlpha + "-" + i).click(function (evt) {
  1307. var scriptID = $(this).attr("id").substring($(this).attr("id").lastIndexOf('-') + 1);
  1308. viewScript.call(self, nodeID, scriptID, undefined);
  1309. });
  1310. }
  1311. }
  1312. $('#scripts > div:last').css('border-bottom-width', '3px');
  1313. }
  1314. if (this.allScripts[node.extendsID] !== undefined) {
  1315. // Add prototype scripts
  1316. $(topdownTemp).append("<div id='prototypeScripts'></div>");
  1317. for (var i = 0; i < this.allScripts[node.extendsID].length; i++) {
  1318. var scriptFull = this.allScripts[node.extendsID][i].text;
  1319. if (scriptFull != undefined) {
  1320. var nodeExtendsIDAlpha = $.encoder.encodeForAlphaNumeric(node.extendsID);
  1321. var nodeExtendsIDAttribute = $.encoder.encodeForHTMLAttribute("id", node.extendsID, true);
  1322. var scriptName = scriptFull.substring(0, scriptFull.indexOf('='));
  1323. $('#prototypeScripts').append("<div id='script-" + nodeExtendsIDAlpha + "-" + i + "' class='childContainer' data-nodeExtendsID='" + nodeExtendsIDAttribute + "'><div class='childEntry'><b>script </b>" + scriptName + "</div></div>");
  1324. $('#script-' + nodeExtendsIDAlpha + "-" + i).click(function (evt) {
  1325. var extendsId = $.encoder.canonicalize($(this).attr("data-nodeExtendsID"));
  1326. var scriptID = $(this).attr("id").substring($(this).attr("id").lastIndexOf('-') + 1);
  1327. viewScript.call(self, nodeID, scriptID, extendsId);
  1328. });
  1329. }
  1330. }
  1331. $('#prototypeScripts > div:last').css('border-bottom-width', '3px');
  1332. }
  1333. updateCameraProperties.call(self);
  1334. }
  1335. // createEvent
  1336. function createEvent(nodeID) // invoke with the view as "this"
  1337. {
  1338. var self = this;
  1339. var topdownName = this.topdownName;
  1340. var topdownTemp = this.topdownTemp;
  1341. var nodeIDAlpha = $.encoder.encodeForAlphaNumeric(nodeID);
  1342. $(topdownTemp).html("<div class='header'><img src='images/back.png' id='script-" + nodeIDAlpha + "-back' alt='back'/> New event</div>");
  1343. $('#script-' + nodeIDAlpha + '-back').click(function (evt) {
  1344. self.editingScript = false;
  1345. drillBack.call(self, nodeID);
  1346. // Return editor to normal width
  1347. $('#editor').animate({ 'left': "-260px" }, 175);
  1348. $('.vwf-tree').animate({ 'width': "260px" }, 175);
  1349. });
  1350. $(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' />");
  1351. $("#createEvent").click(function (evt) {
  1352. console.log("not yet created");
  1353. if ($('#eventName').val()) {
  1354. var eventName = $('#eventName').val();
  1355. //prmtr = JSON.parse(JSON.stringify($.encoder.canonicalize(prmtr)));
  1356. console.log(eventName);
  1357. if ($('#eventParams').val()) {
  1358. var params = $('#eventParams').val();
  1359. params = params.split(',');
  1360. var cleanParams = [];
  1361. for (var i = 0; i < params.length; i++) {
  1362. params[i] = $.trim(params[i]);
  1363. if (params[i] != '' && params[i] != null && params[i] !== undefined)
  1364. cleanParams.push(params[i]);
  1365. }
  1366. console.log(cleanParams);
  1367. //prmtr = JSON.parse(JSON.stringify($.encoder.canonicalize(prmtr)));
  1368. }
  1369. let body = '';
  1370. self.kernel.createEvent(nodeID, eventName, cleanParams);
  1371. }
  1372. //self.kernel.execute( nodeID, editor.getValue() );
  1373. // self.kernel.execute( nodeID, $("#newScriptArea").val() );
  1374. });
  1375. $(topdownName).hide();
  1376. $(topdownTemp).show();
  1377. this.topdownName = topdownTemp;
  1378. this.topdownTemp = topdownName;
  1379. }
  1380. // -- createMethod
  1381. function createMethod(nodeID) // invoke with the view as "this"
  1382. {
  1383. var self = this;
  1384. var topdownName = this.topdownName;
  1385. var topdownTemp = this.topdownTemp;
  1386. var nodeIDAlpha = $.encoder.encodeForAlphaNumeric(nodeID);
  1387. $(topdownTemp).html("<div class='header'><img src='images/back.png' id='script-" + nodeIDAlpha + "-back' alt='back'/> New method</div>");
  1388. $('#script-' + nodeIDAlpha + '-back').click(function (evt) {
  1389. self.editingScript = false;
  1390. drillBack.call(self, nodeID);
  1391. // Return editor to normal width
  1392. $('#editor').animate({ 'left': "-260px" }, 175);
  1393. $('.vwf-tree').animate({ 'width': "260px" }, 175);
  1394. });
  1395. $(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' />");
  1396. $("#createMethod").click(function (evt) {
  1397. console.log("not yet created");
  1398. if ($('#methodName').val()) {
  1399. var methodName = $('#methodName').val();
  1400. //prmtr = JSON.parse(JSON.stringify($.encoder.canonicalize(prmtr)));
  1401. console.log(methodName);
  1402. if ($('#methodParams').val()) {
  1403. var params = $('#methodParams').val();
  1404. params = params.split(',');
  1405. var cleanParams = [];
  1406. for (var i = 0; i < params.length; i++) {
  1407. params[i] = $.trim(params[i]);
  1408. if (params[i] != '' && params[i] != null && params[i] !== undefined)
  1409. cleanParams.push(params[i]);
  1410. }
  1411. console.log(cleanParams);
  1412. //prmtr = JSON.parse(JSON.stringify($.encoder.canonicalize(prmtr)));
  1413. }
  1414. let body = '';
  1415. self.kernel.createMethod(nodeID, methodName, cleanParams, body);
  1416. }
  1417. //self.kernel.execute( nodeID, editor.getValue() );
  1418. // self.kernel.execute( nodeID, $("#newScriptArea").val() );
  1419. });
  1420. $(topdownName).hide();
  1421. $(topdownTemp).show();
  1422. this.topdownName = topdownTemp;
  1423. this.topdownTemp = topdownName;
  1424. }
  1425. // -- createScript ----------------------------------------------------------------------
  1426. function createScript(nodeID) // invoke with the view as "this"
  1427. {
  1428. var self = this;
  1429. var topdownName = this.topdownName;
  1430. var topdownTemp = this.topdownTemp;
  1431. var allScripts = this.allScripts;
  1432. var nodeIDAlpha = $.encoder.encodeForAlphaNumeric(nodeID);
  1433. $(topdownTemp).html("<div class='header'><img src='images/back.png' id='script-" + nodeIDAlpha + "-back' alt='back'/> script</div>");
  1434. $('#script-' + nodeIDAlpha + '-back').click(function (evt) {
  1435. self.editingScript = false;
  1436. drillBack.call(self, nodeID);
  1437. // Return editor to normal width
  1438. $('#editor').animate({ 'left': "-260px" }, 175);
  1439. $('.vwf-tree').animate({ 'width': "260px" }, 175);
  1440. });
  1441. // $(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>");
  1442. $(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>");
  1443. var editor = createAceEditor(self, nodeID);
  1444. $("#create-" + nodeIDAlpha).click(function (evt) {
  1445. self.kernel.execute(nodeID, editor.getValue());
  1446. // self.kernel.execute( nodeID, $("#newScriptArea").val() );
  1447. });
  1448. // $('#newScriptArea').focus( function(evt) {
  1449. // // Expand the script editor
  1450. // self.editingScript = true;
  1451. // $('#editor').animate({ 'left' : "-500px" }, 175);
  1452. // $('.vwf-tree').animate({ 'width' : "500px" }, 175);
  1453. // });
  1454. $('#editorlive').keydown(function (evt) {
  1455. evt.stopPropagation();
  1456. });
  1457. $(topdownName).hide();
  1458. $(topdownTemp).show();
  1459. this.topdownName = topdownTemp;
  1460. this.topdownTemp = topdownName;
  1461. }
  1462. // -- viewScript ------------------------------------------------------------------------
  1463. function createAceEditor(view, nodeID) {
  1464. var editor = view.ace.edit("editorlive");
  1465. editor.setTheme("ace/theme/monokai");
  1466. editor.setFontSize(16);
  1467. editor.getSession().setMode("ace/mode/javascript");
  1468. editor.commands.addCommand({
  1469. name: "doit",
  1470. bindKey: { win: "Ctrl-e", mac: "Command-e" },
  1471. exec: function () {
  1472. codeEditorDoit(editor, nodeID);
  1473. }
  1474. });
  1475. editor.commands.addCommand({
  1476. name: "printit",
  1477. bindKey: { win: "Ctrl-b", mac: "Command-b" },
  1478. exec: function () {
  1479. codeEditorPrintit(editor, nodeID);
  1480. }
  1481. });
  1482. editor.on('focus', function (event, editor) {
  1483. // Expand the script editor
  1484. self.editingScript = true;
  1485. $('#editor').animate({ 'left': "-800px" }, 175);
  1486. $('.vwf-tree').animate({ 'width': "800px" }, 175);
  1487. });
  1488. editor.on('blur', function (event, editor) {
  1489. // $('#editor').animate({ 'left' : "-260px" }, 175);
  1490. // $('.vwf-tree').animate({ 'width' : "260px" }, 175);
  1491. });
  1492. return editor;
  1493. }
  1494. function editOhmLang(nodeID, propertyName, propertyValue) {
  1495. var self = this;
  1496. var topdownName = this.topdownName;
  1497. var topdownTemp = this.topdownTemp;
  1498. var nodeIDAlpha = $.encoder.encodeForAlphaNumeric(nodeID);
  1499. $(topdownTemp).html("<div class='header'><img src='images/back.png' id='script-" + nodeIDAlpha + "-back' alt='back'/> script</div>");
  1500. $('#script-' + nodeIDAlpha + '-back').click(function (evt) {
  1501. self.editingScript = false;
  1502. drillBack.call(self, nodeID);
  1503. // Return editor to normal width
  1504. $('#editor').animate({ 'left': "-260px" }, 175);
  1505. $('.vwf-tree').animate({ 'width': "260px" }, 175);
  1506. });
  1507. if (propertyValue != undefined) {
  1508. var propText = propertyValue;
  1509. // var propText = propertyValue.split("\n").map($.trim).filter(function(line) { return line != "" }).join("\n");
  1510. $(topdownTemp).append("<div style='padding:6px'><input class='live_button' type='button' id='update-" + nodeIDAlpha + "-" + propertyName + "' value='Update' /></div>");
  1511. $(topdownTemp).append("<div class='scriptEntry'><pre class='scriptCode'> <div id='editorlive'> </div></pre></div><hr>");
  1512. var editor = createAceEditor(self, nodeID);
  1513. editor.setValue(propText);
  1514. $("#update-" + nodeIDAlpha + "-" + propertyName).click(function (evt) {
  1515. var evalText = editor.getValue();
  1516. self.kernel.setProperty(nodeID, propertyName, evalText);
  1517. });
  1518. $('#editorlive').keydown(function (evt) {
  1519. evt.stopPropagation();
  1520. });
  1521. }
  1522. $(topdownName).hide();
  1523. $(topdownTemp).show();
  1524. this.topdownName = topdownTemp;
  1525. this.topdownTemp = topdownName;
  1526. }
  1527. function viewScript(nodeID, scriptID, extendsID) // invoke with the view as "this"
  1528. {
  1529. var self = this;
  1530. var topdownName = this.topdownName;
  1531. var topdownTemp = this.topdownTemp;
  1532. var allScripts = this.allScripts;
  1533. var nodeIDAlpha = $.encoder.encodeForAlphaNumeric(nodeID);
  1534. $(topdownTemp).html("<div class='header'><img src='images/back.png' id='script-" + nodeIDAlpha + "-back' alt='back'/> script</div>");
  1535. $('#script-' + nodeIDAlpha + '-back').click(function (evt) {
  1536. self.editingScript = false;
  1537. drillBack.call(self, nodeID);
  1538. // Return editor to normal width
  1539. $('#editor').animate({ 'left': "-260px" }, 175);
  1540. $('.vwf-tree').animate({ 'width': "260px" }, 175);
  1541. });
  1542. if (extendsID) {
  1543. nodeID = extendsID;
  1544. nodeIDAlpha = $.encoder.encodeForAlphaNumeric(extendsID);
  1545. }
  1546. var scriptText = self.allScripts[nodeID][scriptID].text;
  1547. if (scriptText != undefined) {
  1548. // $(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>");
  1549. //Open Live Editor
  1550. $(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>");
  1551. $(topdownTemp).append("<div class='scriptEntry'><pre class='scriptCode'> <div id='editorlive'>" + scriptText + "</div></pre></div><hr>");
  1552. var editor = createAceEditor(self, nodeID);
  1553. // $(topdownTemp).append("<div style='padding:6px'><input class='live_button' type='button' id='doit' value='DoIt' /></div>");
  1554. $("#doit-" + nodeIDAlpha + "-" + scriptID).click(function (evt) {
  1555. var s_id = $(this).attr("id").substring($(this).attr("id").lastIndexOf('-') + 1);
  1556. self.allScripts[nodeID][s_id].text = undefined;;
  1557. codeEditorDoit.call(self, editor, nodeID);
  1558. });
  1559. $("#printit").click(function (evt) {
  1560. codeEditorPrintit.call(self, editor, nodeID);
  1561. });
  1562. $("#update-" + nodeIDAlpha + "-" + scriptID).click(function (evt) {
  1563. var s_id = $(this).attr("id").substring($(this).attr("id").lastIndexOf('-') + 1);
  1564. self.allScripts[nodeID][s_id].text = undefined;
  1565. var evalText = editor.getValue();
  1566. self.kernel.execute(nodeID, evalText);
  1567. });
  1568. // $('#editorlive').focus( function(evt) {
  1569. // // Expand the script editor
  1570. // self.editingScript = true;
  1571. // $('#editor').animate({ 'left' : "-500px" }, 175);
  1572. // $('.vwf-tree').animate({ 'width' : "500px" }, 175);
  1573. // });
  1574. $('#editorlive').keydown(function (evt) {
  1575. evt.stopPropagation();
  1576. });
  1577. }
  1578. $(topdownName).hide();
  1579. $(topdownTemp).show();
  1580. this.topdownName = topdownTemp;
  1581. this.topdownTemp = topdownName;
  1582. }
  1583. // -- setParams -------------------------------------------------------------------------
  1584. function setParams(methodName, methodParams, nodeID) // invoke with the view as "this"
  1585. {
  1586. var self = this;
  1587. var topdownName = this.topdownName;
  1588. var topdownTemp = this.topdownTemp;
  1589. var methodNameAlpha = $.encoder.encodeForAlphaNumeric(methodName);
  1590. var methodNameHTML = $.encoder.encodeForHTML(methodName);
  1591. $(topdownTemp).html("<div class='header'><img src='images/back.png' id='" + methodNameAlpha + "-back' alt='back'/> " + methodNameHTML + "</div>");
  1592. $('#' + methodNameAlpha + '-back').click(function (evt) {
  1593. self.editingScript = false;
  1594. drillUp.call(self, nodeID);
  1595. // Return editor to normal width
  1596. $('#editor').animate({ 'left': "-260px" }, 175);
  1597. $('.vwf-tree').animate({ 'width': "260px" }, 175);
  1598. });
  1599. var nodeIDAlpha = $.encoder.encodeForAlphaNumeric(nodeID);
  1600. var method = vwf.getMethod(nodeID, methodNameAlpha);
  1601. $(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>");
  1602. //$(topdownTemp).append("<input class='update_button' type='button' id='call' value='Call' />");
  1603. $(topdownTemp).append("<div id='editorlive'>" + method.body + "</div>");
  1604. var editor = createAceEditor(self, nodeID);
  1605. $("#printit").click(function (evt) {
  1606. codeEditorPrintit.call(self, editor, nodeID);
  1607. });
  1608. $("#doit").click(function (evt) {
  1609. codeEditorDoit.call(self, editor, nodeID);
  1610. });
  1611. $("#update-" + nodeIDAlpha + "-" + methodNameAlpha).click(function (evt) {
  1612. var evalText = editor.getValue();
  1613. self.kernel.setMethod(nodeID, methodNameAlpha,
  1614. { body: evalText, type: "application/javascript", parameters: method.parameters });
  1615. });
  1616. var params = [];
  1617. if (method.parameters) {
  1618. params = method.parameters.length
  1619. };
  1620. if (params >= 1) {
  1621. for (var i = 1; i <= params; i++) {
  1622. $(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>");
  1623. $('#input-param' + i).keydown(function (evt) {
  1624. evt.stopPropagation();
  1625. });
  1626. $('#input-param' + i).keypress(function (evt) {
  1627. evt.stopPropagation();
  1628. });
  1629. $('#input-param' + i).keyup(function (evt) {
  1630. evt.stopPropagation();
  1631. });
  1632. }
  1633. }
  1634. $('#call').click(function (evt) {
  1635. if (params >= 1) {
  1636. var parameters = new Array();
  1637. for (var i = 1; i <= params; i++) {
  1638. if ($('#input-param' + i).val()) {
  1639. var prmtr = $('#input-param' + i).val();
  1640. try {
  1641. prmtr = JSON.parse(JSON.stringify($.encoder.canonicalize(prmtr)));
  1642. parameters.push(prmtr);
  1643. } catch (e) {
  1644. self.logger.error('Invalid Value');
  1645. }
  1646. }
  1647. }
  1648. }
  1649. self.kernel.callMethod(nodeID, methodName, parameters);
  1650. });
  1651. $(topdownName).hide('slide', { direction: 'left' }, 175);
  1652. $(topdownTemp).show('slide', { direction: 'right' }, 175);
  1653. this.topdownName = topdownTemp;
  1654. this.topdownTemp = topdownName;
  1655. }
  1656. // -- setArgs ---------------------------------------------------------------------------
  1657. function setArgs(eventName, eventArgs, nodeID) // invoke with the view as "this"
  1658. {
  1659. var self = this;
  1660. var topdownName = this.topdownName;
  1661. var topdownTemp = this.topdownTemp;
  1662. var eventNameAlpha = $.encoder.encodeForAlphaNumeric(eventName);
  1663. var eventNameHTML = $.encoder.encodeForHTML(eventName);
  1664. $(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>");
  1665. $('#' + eventNameAlpha + '-back').click(function (evt) {
  1666. drillUp.call(self, nodeID);
  1667. });
  1668. for (var i = 1; i <= 8; i++) {
  1669. $(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>");
  1670. $('#input-arg' + i).keydown(function (evt) {
  1671. evt.stopPropagation();
  1672. });
  1673. $('#input-arg' + i).keypress(function (evt) {
  1674. evt.stopPropagation();
  1675. });
  1676. $('#input-arg' + i).keyup(function (evt) {
  1677. evt.stopPropagation();
  1678. });
  1679. }
  1680. $(topdownTemp).append("<div style='font-weight:bold;text-align:right;padding-right:10px'></div>");
  1681. $('#fire').click(function (evt) {
  1682. var args = new Array();
  1683. for (var i = 1; i <= 8; i++) {
  1684. if ($('#input-arg' + i).val()) {
  1685. var arg = $('#input-arg' + i).val();
  1686. try {
  1687. arg = JSON.parse($.encoder.canonicalize(arg));
  1688. args.push(arg);
  1689. } catch (e) {
  1690. self.logger.error('Invalid Value');
  1691. }
  1692. }
  1693. }
  1694. self.kernel.fireEvent(nodeID, eventName, args);
  1695. });
  1696. $(topdownName).hide('slide', { direction: 'left' }, 175);
  1697. $(topdownTemp).show('slide', { direction: 'right' }, 175);
  1698. this.topdownName = topdownTemp;
  1699. this.topdownTemp = topdownName;
  1700. }
  1701. function getPrototypes(kernel, extendsID) {
  1702. var prototypes = [];
  1703. var id = extendsID;
  1704. while (id !== undefined) {
  1705. prototypes.push(id);
  1706. id = kernel.prototype(id);
  1707. }
  1708. return prototypes;
  1709. }
  1710. function getPrototypes(kernel, extendsID) {
  1711. var prototypes = [];
  1712. var id = extendsID;
  1713. while (id !== undefined) {
  1714. prototypes.push(id);
  1715. id = kernel.prototype(id);
  1716. }
  1717. return prototypes;
  1718. }
  1719. function createProperty(node, propertyName, propertyValue) {
  1720. var property = {
  1721. name: propertyName,
  1722. rawValue: propertyValue,
  1723. value: undefined,
  1724. getValue: function () {
  1725. var propertyValue;
  1726. if (this.value == undefined) {
  1727. try {
  1728. propertyValue = utility.transform(this.rawValue, utility.transforms.transit);
  1729. this.value = JSON.stringify(propertyValue);
  1730. } catch (e) {
  1731. this.logger.warnx("createdProperty", nodeID, this.propertyName, this.rawValue,
  1732. "stringify error:", e.message);
  1733. this.value = this.rawValue;
  1734. }
  1735. }
  1736. return this.value;
  1737. }
  1738. };
  1739. return property;
  1740. }
  1741. function getProperties(kernel, extendsID) {
  1742. var pTypes = getPrototypes(kernel, extendsID);
  1743. var pProperties = {};
  1744. if (pTypes) {
  1745. for (var i = 0; i < pTypes.length; i++) {
  1746. var nd = this.nodes[pTypes[i]];
  1747. if (nd && nd.properties) {
  1748. for (var key in nd.properties) {
  1749. pProperties[key] = { "prop": nd.properties[key], "prototype": pTypes[i] };
  1750. }
  1751. }
  1752. }
  1753. }
  1754. return pProperties;
  1755. }
  1756. function getChildren(kernel, extendsID) {
  1757. var pTypes = getPrototypes(kernel, extendsID);
  1758. var pChildren = {};
  1759. if (pTypes) {
  1760. for (var i = 0; i < pTypes.length; i++) {
  1761. var nd = this.nodes[pTypes[i]];
  1762. if (nd && nd.children) {
  1763. for (var key in nd.children) {
  1764. pChildren[key] = nd.children[key];
  1765. }
  1766. }
  1767. }
  1768. }
  1769. return pChildren;
  1770. }
  1771. function getEvents(kernel, extendsID) {
  1772. var pTypes = getPrototypes(kernel, extendsID);
  1773. var events = {};
  1774. if (pTypes) {
  1775. for (var i = 0; i < pTypes.length; i++) {
  1776. var nd = this.nodes[pTypes[i]];
  1777. if (nd && nd.events) {
  1778. for (var key in nd.events) {
  1779. events[key] = nd.events[key];
  1780. }
  1781. }
  1782. }
  1783. }
  1784. return events;
  1785. }
  1786. function getMethods(kernel, extendsID) {
  1787. var pTypes = getPrototypes(kernel, extendsID);
  1788. var methods = {};
  1789. if (pTypes) {
  1790. for (var i = 0; i < pTypes.length; i++) {
  1791. var nd = this.nodes[pTypes[i]];
  1792. if (nd && nd.methods) {
  1793. for (var key in nd.methods) {
  1794. methods[key] = nd.methods[key];
  1795. }
  1796. }
  1797. }
  1798. }
  1799. return methods;
  1800. }
  1801. function highlightChildInHierarchy(nodeID) {
  1802. if (this.editorOpen && this.editorView == 1) // Hierarchy view open
  1803. {
  1804. var childDiv = $("div[id='" + nodeID + "']");
  1805. if (childDiv.length > 0) {
  1806. var previousChild = $("div[id='" + this.highlightedChild + "']");
  1807. if (previousChild.length > 0) {
  1808. previousChild.removeClass('childContainerHighlight');
  1809. }
  1810. childDiv.addClass('childContainerHighlight');
  1811. this.highlightedChild = nodeID;
  1812. }
  1813. }
  1814. }
  1815. // -- showTimeline ----------------------------------------------------------------------
  1816. function showTimeline() // invoke with the view as "this"
  1817. {
  1818. var timeline = this.timeline;
  1819. if (!this.timelineInit) {
  1820. $('#time_control').append("<div class='header'>Timeline</div>" +
  1821. "<div style='text-align:center;padding-top:10px'><span><button id='play'></button><button id='stop'></button></span>" +
  1822. "<span><span class='rate slider'></span>&nbsp;" +
  1823. "<span class='rate vwf-label' style='display: inline-block; width:8ex'></span></span></div>");
  1824. var options = {};
  1825. ["play", "pause", "stop"].forEach(function (state) {
  1826. options[state] = { icons: { primary: "ui-icon-" + state }, label: state, text: false };
  1827. });
  1828. options.rate = { value: 0, min: -2, max: 2, step: 0.1, };
  1829. var state = {};
  1830. $.get(
  1831. "admin/state",
  1832. undefined,
  1833. function (data) {
  1834. state = data;
  1835. $("button#play").button("option", state.playing ? options.pause : options.play);
  1836. $("button#stop").button("option", "disabled", state.stopped);
  1837. $(".rate.slider").slider("value", Math.log(state.rate) / Math.LN10);
  1838. if (state.rate < 1.0) {
  1839. var label_rate = 1.0 / state.rate;
  1840. }
  1841. else {
  1842. var label_rate = state.rate;
  1843. }
  1844. var label = label_rate.toFixed(2).toString().replace(/(\.\d*?)0+$/, "$1").replace(/\.$/, "");
  1845. if (state.rate < 1.0) {
  1846. label = "&#x2215; " + label;
  1847. } else {
  1848. label = label + " &times;";
  1849. }
  1850. $(".rate.vwf-label").html(label);
  1851. },
  1852. "json"
  1853. );
  1854. $("button#play").button(
  1855. options.pause
  1856. ).click(function () {
  1857. $.post(
  1858. state.playing ? "admin/pause" : "admin/play",
  1859. undefined,
  1860. function (data) {
  1861. state = data;
  1862. $("button#play").button("option", state.playing ? options.pause : options.play);
  1863. $("button#stop").button("option", "disabled", state.stopped);
  1864. },
  1865. "json"
  1866. );
  1867. });
  1868. $("button#stop").button(
  1869. options.stop
  1870. ).click(function () {
  1871. $.post(
  1872. "admin/stop",
  1873. undefined,
  1874. function (data) {
  1875. state = data;
  1876. $("button#play").button("option", state.playing ? options.pause : options.play);
  1877. $("button#stop").button("option", "disabled", state.stopped);
  1878. },
  1879. "json"
  1880. );
  1881. });
  1882. $(".rate.slider").slider(
  1883. options.rate
  1884. ).bind("slide", function (event, ui) {
  1885. $.get(
  1886. "admin/state",
  1887. { "rate": Math.pow(10, Number(ui.value)) },
  1888. function (data) {
  1889. state = data;
  1890. $(".rate.slider").slider("value", Math.log(state.rate) / Math.LN10);
  1891. if (state.rate < 1.0) {
  1892. var label_rate = 1.0 / state.rate;
  1893. }
  1894. else {
  1895. var label_rate = state.rate;
  1896. }
  1897. var label = label_rate.toFixed(2).toString().replace(/(\.\d*?)0+$/, "$1").replace(/\.$/, "");
  1898. if (state.rate < 1.0) {
  1899. label = "&#x2215; " + label;
  1900. } else {
  1901. label = label + " &times;";
  1902. }
  1903. $(".rate.vwf-label").html(label);
  1904. },
  1905. "json"
  1906. );
  1907. });
  1908. this.timelineInit = true;
  1909. }
  1910. if (!this.editorOpen) {
  1911. $(timeline).show('slide', { direction: 'right' }, 175);
  1912. }
  1913. else {
  1914. $(timeline).show();
  1915. }
  1916. }
  1917. // -- Show Code Editor tab
  1918. function showCodeEditorTab() // invoke with the view as "this"
  1919. {
  1920. var self = this;
  1921. var codeEditor = this.codeEditor;
  1922. if (!this.codeEditorInit) {
  1923. $('#codeEditor_tab').append("<div class='header'>Live Code Editor</div>");
  1924. $('#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>");
  1925. $("#doit").click(function (evt) {
  1926. codeEditorDoit.call(self, editor, sceneID);
  1927. });
  1928. $("#printit").click(function (evt) {
  1929. codeEditorPrintit.call(self, editor, sceneID);
  1930. });
  1931. // $('#codeEditor_tab').append("<div style='padding:6px'></div>");
  1932. $('#min').click(function (evt) {
  1933. $('#editor').animate({ 'left': "-260px" }, 175);
  1934. $('.vwf-tree').animate({ 'width': "260px" }, 175);
  1935. });
  1936. //Open Live Editor
  1937. $('#codeEditor_tab').append('<div id="editorlive">console.log("test")</div>');
  1938. var sceneID = self.kernel.application();
  1939. var editor = createAceEditor(self, sceneID);
  1940. editor.on('blur', function (event, editor) {
  1941. // $('#editor').animate({ 'left' : "-260px" }, 175);
  1942. // $('.vwf-tree').animate({ 'width' : "260px" }, 175);
  1943. });
  1944. this.codeEditorInit = true;
  1945. }
  1946. if (!this.editorOpen) {
  1947. $(codeEditor).show('slide', { direction: 'right' }, 175);
  1948. }
  1949. else {
  1950. $(codeEditor).show();
  1951. // $('#editor').animate({ 'left' : "-500px" }, 175);
  1952. // $('.vwf-tree').animate({ 'width' : "500px" }, 175);
  1953. }
  1954. }
  1955. function codeEditorDoit(editor, nodeID) {
  1956. var selectedText = editor.getSession().doc.getTextRange(editor.selection.getRange());
  1957. if (selectedText == "") {
  1958. var currline = editor.getSelectionRange().start.row;
  1959. var selectedText = editor.session.getLine(currline);
  1960. }
  1961. //console.log(selectedText);
  1962. //var sceneID = self.kernel.application();
  1963. vwf_view.kernel.execute(nodeID, selectedText);
  1964. }
  1965. function codeEditorPrintit(editor, nodeID) {
  1966. var selectedText = editor.getSession().doc.getTextRange(editor.selection.getRange());
  1967. if (selectedText == "") {
  1968. var currline = editor.getSelectionRange().start.row;
  1969. var selectedText = editor.session.getLine(currline);
  1970. }
  1971. //console.log(selectedText);
  1972. //var sceneID = self.kernel.application();
  1973. let scriptText = 'console.log(' + selectedText + ');'
  1974. self.kernel.execute(nodeID, scriptText);
  1975. }
  1976. // -- showAboutTab ----------------------------------------------------------------------
  1977. function showAboutTab() // invoke with the view as "this"
  1978. {
  1979. var about = this.about;
  1980. if (!this.aboutInit) {
  1981. $('#about_tab').append("<div id='aboutHeader' class='header'>About</div>" +
  1982. "<div class='about'><p style='font:bold 12pt Arial'>Virtual World Framework & LiveCode editor</p>" +
  1983. "<p><b>Version: </b> 0.1 <b>VWF version: </b>" + version.toString() + "</p>" +
  1984. "<p><b>This project site: </b><a href='http://demo.krestianstvo.org' target='_blank'>http://demo.krestianstvo.org</a></p>" +
  1985. "<p><b>Site VWF: </b><a href='http://virtualworldframework.com' target='_blank'>http://virtualworldframework.com</a></p>" +
  1986. "<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>");
  1987. let anotherCell =
  1988. {
  1989. $cell: true,
  1990. $text: "About: ",
  1991. class: "mdc-typography--display2",
  1992. $type: "h2"
  1993. }
  1994. let andAnotherCell =
  1995. {
  1996. $cell: true,
  1997. $text: "hello world"
  1998. }
  1999. document.querySelector("#aboutHeader").$cell({
  2000. $cell: true,
  2001. class: 'header',
  2002. $components: [anotherCell, andAnotherCell]
  2003. });
  2004. // document.querySelector("body").$cell({
  2005. // $cell: true,
  2006. // $components: [toolbarCell]
  2007. // });
  2008. this.aboutInit = true;
  2009. }
  2010. if (!this.editorOpen) {
  2011. $(about).show('slide', { direction: 'right' }, 175);
  2012. }
  2013. else {
  2014. $(about).show();
  2015. }
  2016. }
  2017. // -- showModelsTab ----------------------------------------------------------------------
  2018. function showModelsTab(modelID, modelURL) // invoke with the view as "this"
  2019. {
  2020. var self = this;
  2021. var models = this.models;
  2022. var modelsTemp = this.modelsTemp;
  2023. this.currentModelID = modelID;
  2024. this.currentModelURL = modelURL;
  2025. $(models).html("");
  2026. if (modelID == "") {
  2027. $(modelsTemp).html("<div class='header'>Models</div>");
  2028. $.getJSON("admin/models", function (data) {
  2029. if (data.length > 0) {
  2030. $.each(data, function (key, value) {
  2031. var fileName = encodeURIComponent(value['basename']);
  2032. var divId = fileName;
  2033. if (divId.indexOf('.') != -1) {
  2034. divId = divId.replace(/\./g, "_");
  2035. }
  2036. var url = value['url'];
  2037. $(modelsTemp).append("<div class='childContainer'><div id='" + divId + "' class='modelEntry' data-url='" + url + "'>"
  2038. + fileName + "</div></div>");
  2039. $("#" + divId).click(function (e) {
  2040. modelDrillDown.call(self, e.target.textContent, e.target.getAttribute("data-url"));
  2041. })
  2042. });
  2043. }
  2044. else {
  2045. $(modelsTemp).append("<div class='childEntry'><p style='font:bold 12pt Arial'>No Models Found</p></div>");
  2046. }
  2047. });
  2048. }
  2049. else {
  2050. var divId = modelID;
  2051. if (divId.indexOf('.') != -1) {
  2052. divId = divId.replace(/\./g, "_");
  2053. }
  2054. $(modelsTemp).html("<div id='" + divId + "-backDiv' class='header'><img src='images/back.png' id='" + divId + "-back' alt='back'/>" + modelID + "</div>");
  2055. $("#" + divId + "-back").click(function (e) {
  2056. modelDrillUp.call(self, '');
  2057. });
  2058. $(modelsTemp).append("<div id='" + divId + "-rotation' class='propEntry'><table><tr><td><b>Rotation</b></td><td>" +
  2059. "<input type='text' class='input_text' id='input-" + divId + "-rotation' value='[1,0,0,0]'></td></tr></table></div>");
  2060. $('#input-' + divId + '-rotation').keydown(function (evt) {
  2061. evt.stopPropagation();
  2062. });
  2063. $('#input-' + divId + '-rotation').keypress(function (evt) {
  2064. evt.stopPropagation();
  2065. });
  2066. $('#input-' + divId + '-rotation').keyup(function (evt) {
  2067. evt.stopPropagation();
  2068. });
  2069. $(modelsTemp).append("<div id='" + divId + "-scale' class='propEntry'><table><tr><td><b>Scale</b></td><td>" +
  2070. "<input type='text' class='input_text' id='input-" + divId + "-scale' value='[1,1,1]'></td></tr></table></div>");
  2071. $('#input-' + divId + '-scale').keydown(function (evt) {
  2072. evt.stopPropagation();
  2073. });
  2074. $('#input-' + divId + '-scale').keypress(function (evt) {
  2075. evt.stopPropagation();
  2076. });
  2077. $('#input-' + divId + '-scale').keyup(function (evt) {
  2078. evt.stopPropagation();
  2079. });
  2080. $(modelsTemp).append("<div id='" + divId + "-translation' class='propEntry'><table><tr><td><b>Translation Offset</b></td><td>" +
  2081. "<input type='text' class='input_text' id='input-" + divId + "-translation' value='[0,0,0]'></td></tr></table></div>");
  2082. $('#input-' + divId + '-translation').keydown(function (evt) {
  2083. evt.stopPropagation();
  2084. });
  2085. $('#input-' + divId + '-translation').keypress(function (evt) {
  2086. evt.stopPropagation();
  2087. });
  2088. $('#input-' + divId + '-translation').keyup(function (evt) {
  2089. evt.stopPropagation();
  2090. });
  2091. $(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>");
  2092. $("#" + divId + "-drag").on("dragstart", function (e) {
  2093. var fileName = $("#" + e.target.getAttribute("data-escaped-name") + "-backDiv").text();
  2094. var rotation = encodeURIComponent($("#input-" + e.target.getAttribute("data-escaped-name") + "-rotation").val());
  2095. var scale = encodeURIComponent($("#input-" + e.target.getAttribute("data-escaped-name") + "-scale").val());
  2096. var translation = encodeURIComponent($("#input-" + e.target.getAttribute("data-escaped-name") + "-translation").val());
  2097. var fileData = "{\"fileName\":\"" + fileName + "\", \"fileUrl\":\"" + e.target.getAttribute("data-url") + "\", " +
  2098. "\"rotation\":\"" + rotation + "\", \"scale\":\"" + scale + "\", \"translation\":\"" + translation + "\"}";
  2099. e.originalEvent.dataTransfer.setData('text/plain', fileData);
  2100. e.originalEvent.dataTransfer.setDragImage(e.target, 0, 0);
  2101. return true;
  2102. });
  2103. }
  2104. }
  2105. // -- Model drillDown -------------------------------------------------------------------------
  2106. function modelDrillDown(modelID, modelURL) // invoke with the view as "this"
  2107. {
  2108. var models = this.models;
  2109. var modelsTemp = this.modelsTemp;
  2110. showModelsTab.call(this, modelID, modelURL);
  2111. if (modelID != "") $(models).hide('slide', { direction: 'left' }, 175);
  2112. $(modelsTemp).show('slide', { direction: 'right' }, 175);
  2113. this.models = modelsTemp;
  2114. this.modelsTemp = models;
  2115. }
  2116. // -- Model drillUp ---------------------------------------------------------------------------
  2117. function modelDrillUp(modelID) // invoke with the view as "this"
  2118. {
  2119. var models = this.models;
  2120. var modelsTemp = this.modelsTemp;
  2121. showModelsTab.call(this, modelID);
  2122. $(models).hide('slide', { direction: 'right' }, 175);
  2123. $(modelsTemp).show('slide', { direction: 'left' }, 175);
  2124. this.models = modelsTemp;
  2125. this.modelsTemp = models;
  2126. }
  2127. // -- SaveStateAsFile -------------------------------------------------------------------------
  2128. function saveStateAsFile(filename) // invoke with the view as "this"
  2129. {
  2130. this.logger.info("Saving: " + filename);
  2131. if (supportAjaxUploadWithProgress.call(this)) {
  2132. var xhr = new XMLHttpRequest();
  2133. // Save State Information
  2134. var state = vwf.getState();
  2135. var timestamp = state["queue"].time;
  2136. timestamp = Math.round(timestamp * 1000);
  2137. var objectIsTypedArray = function (candidate) {
  2138. var typedArrayTypes = [
  2139. Int8Array,
  2140. Uint8Array,
  2141. // Uint8ClampedArray,
  2142. Int16Array,
  2143. Uint16Array,
  2144. Int32Array,
  2145. Uint32Array,
  2146. Float32Array,
  2147. Float64Array
  2148. ];
  2149. var isTypedArray = false;
  2150. if (typeof candidate == "object" && candidate != null) {
  2151. typedArrayTypes.forEach(function (typedArrayType) {
  2152. isTypedArray = isTypedArray || candidate instanceof typedArrayType;
  2153. });
  2154. }
  2155. return isTypedArray;
  2156. };
  2157. var transitTransformation = function (object) {
  2158. return objectIsTypedArray(object) ?
  2159. Array.prototype.slice.call(object) : object;
  2160. };
  2161. var json = JSON.stringify(
  2162. require("vwf/utility").transform(
  2163. state, transitTransformation
  2164. )
  2165. );
  2166. json = $.encoder.encodeForURL(json);
  2167. var path = window.location.pathname;
  2168. var pathSplit = path.split('/');
  2169. if (pathSplit[0] == "") {
  2170. pathSplit.shift();
  2171. }
  2172. if (pathSplit[pathSplit.length - 1] == "") {
  2173. pathSplit.pop();
  2174. }
  2175. var inst = undefined;
  2176. var instIndex = pathSplit.length - 1;
  2177. if (pathSplit.length > 2) {
  2178. if (pathSplit[pathSplit.length - 2] == "load") {
  2179. instIndex = pathSplit.length - 3;
  2180. }
  2181. }
  2182. if (pathSplit.length > 3) {
  2183. if (pathSplit[pathSplit.length - 3] == "load") {
  2184. instIndex = pathSplit.length - 4;
  2185. }
  2186. }
  2187. inst = pathSplit[instIndex];
  2188. var root = "";
  2189. for (var i = 0; i < instIndex; i++) {
  2190. if (root != "") {
  2191. root = root + "/";
  2192. }
  2193. root = root + pathSplit[i];
  2194. }
  2195. if (filename == '') filename = inst;
  2196. if (root.indexOf('.vwf') != -1) root = root.substring(0, root.lastIndexOf('/'));
  2197. xhr.open("POST", "/" + root + "/save/" + filename, true);
  2198. xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  2199. xhr.send("root=" + root + "/" + filename + "&filename=saveState&inst=" + inst + "&timestamp=" + timestamp + "&extension=.vwf.json" + "&jsonState=" + json);
  2200. // Save Config Information
  2201. var config = { "info": {}, "model": {}, "view": {} };
  2202. // Save browser title
  2203. config["info"]["title"] = $('title').html();
  2204. // Save model drivers
  2205. Object.keys(vwf_view.kernel.kernel.models).forEach(function (modelDriver) {
  2206. if (modelDriver.indexOf('vwf/model/') != -1) config["model"][modelDriver] = "";
  2207. });
  2208. // If neither glge or threejs model drivers are defined, specify nodriver
  2209. if (config["model"]["vwf/model/glge"] === undefined && config["model"]["vwf/model/threejs"] === undefined) config["model"]["nodriver"] = "";
  2210. // Save view drivers and associated parameters, if any
  2211. Object.keys(vwf_view.kernel.kernel.views).forEach(function (viewDriver) {
  2212. if (viewDriver.indexOf('vwf/view/') != -1) {
  2213. if (vwf_view.kernel.kernel.views[viewDriver].parameters) {
  2214. config["view"][viewDriver] = vwf_view.kernel.kernel.views[viewDriver].parameters;
  2215. }
  2216. else config["view"][viewDriver] = "";
  2217. }
  2218. });
  2219. var jsonConfig = $.encoder.encodeForURL(JSON.stringify(config));
  2220. // Save config file to server
  2221. var xhrConfig = new XMLHttpRequest();
  2222. xhrConfig.open("POST", "/" + root + "/save/" + filename, true);
  2223. xhrConfig.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  2224. xhrConfig.send("root=" + root + "/" + filename + "&filename=saveState&inst=" + inst + "&timestamp=" + timestamp + "&extension=.vwf.config.json" + "&jsonState=" + jsonConfig);
  2225. }
  2226. else {
  2227. console.error("Unable to save state.");
  2228. }
  2229. }
  2230. // -- LoadSavedState --------------------------------------------------------------------------
  2231. function loadSavedState(filename, applicationpath, revision) {
  2232. this.logger.info("Loading: " + filename);
  2233. // Redirect until setState ID conflict is resolved
  2234. var path = window.location.pathname;
  2235. var inst = path.substring(path.length - 17, path.length - 1);
  2236. var pathSplit = path.split('/');
  2237. if (pathSplit[0] == "") {
  2238. pathSplit.shift();
  2239. }
  2240. if (pathSplit[pathSplit.length - 1] == "") {
  2241. pathSplit.pop();
  2242. }
  2243. var inst = undefined;
  2244. var instIndex = pathSplit.length - 1;
  2245. if (pathSplit.length > 2) {
  2246. if (pathSplit[pathSplit.length - 2] == "load") {
  2247. instIndex = pathSplit.length - 3;
  2248. }
  2249. }
  2250. if (pathSplit.length > 3) {
  2251. if (pathSplit[pathSplit.length - 3] == "load") {
  2252. instIndex = pathSplit.length - 4;
  2253. }
  2254. }
  2255. inst = pathSplit[instIndex];
  2256. if (revision) {
  2257. window.location.pathname = applicationpath + "/" + inst + '/load/' + filename + '/' + revision + '/';
  2258. }
  2259. else {
  2260. window.location.pathname = applicationpath + "/" + inst + '/load/' + filename + '/';
  2261. }
  2262. // $.get(filename,function(data,status){
  2263. // vwf.setState(data);
  2264. // });
  2265. }
  2266. // -- SupportAjax -----------------------------------------------------------------------------
  2267. function supportAjaxUploadWithProgress() {
  2268. return supportAjaxUploadProgressEvents();
  2269. function supportAjaxUploadProgressEvents() {
  2270. var xhr = new XMLHttpRequest();
  2271. return !!(xhr && ('upload' in xhr) && ('onprogress' in xhr.upload));
  2272. }
  2273. }
  2274. });