369 lines
11KB

  1. /** Modified from original Node-Red source, for audio system visualization
  2. * vim: set ts=4:
  3. * Copyright 2013 IBM Corp.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. **/
  17. RED.library = (function() {
  18. function loadFlowLibrary() {
  19. $.getJSON("library/flows",function(data) {
  20. //console.log(data);
  21. var buildMenu = function(data,root) {
  22. var i;
  23. var li;
  24. var a;
  25. var ul = document.createElement("ul");
  26. ul.className = "dropdown-menu";
  27. if (data.d) {
  28. for (i in data.d) {
  29. if (data.d.hasOwnProperty(i)) {
  30. li = document.createElement("li");
  31. li.className = "dropdown-submenu pull-left";
  32. a = document.createElement("a");
  33. a.href="#";
  34. a.innerHTML = i;
  35. li.appendChild(a);
  36. li.appendChild(buildMenu(data.d[i],root+(root!==""?"/":"")+i));
  37. ul.appendChild(li);
  38. }
  39. }
  40. }
  41. if (data.f) {
  42. for (i in data.f) {
  43. if (data.f.hasOwnProperty(i)) {
  44. li = document.createElement("li");
  45. a = document.createElement("a");
  46. a.href="#";
  47. a.innerHTML = data.f[i];
  48. a.flowName = root+(root!==""?"/":"")+data.f[i];
  49. a.onclick = function() {
  50. $.get('library/flows/'+this.flowName, function(data) {
  51. RED.view.importNodes(data);
  52. });
  53. };
  54. li.appendChild(a);
  55. ul.appendChild(li);
  56. }
  57. }
  58. }
  59. return ul;
  60. };
  61. var menu = buildMenu(data,"");
  62. $("#flow-menu-parent>ul").replaceWith(menu);
  63. });
  64. }
  65. //loadFlowLibrary();
  66. function createUI(options) {
  67. var libraryData = {};
  68. var selectedLibraryItem = null;
  69. var libraryEditor = null;
  70. function buildFileListItem(item) {
  71. var li = document.createElement("li");
  72. li.onmouseover = function(e) { $(this).addClass("list-hover"); };
  73. li.onmouseout = function(e) { $(this).removeClass("list-hover"); };
  74. return li;
  75. }
  76. function buildFileList(root,data) {
  77. var ul = document.createElement("ul");
  78. var li;
  79. for (var i=0;i<data.length;i++) {
  80. var v = data[i];
  81. if (typeof v === "string") {
  82. // directory
  83. li = buildFileListItem(v);
  84. li.onclick = (function () {
  85. var dirName = v;
  86. return function(e) {
  87. var bcli = $('<li class="active"><span class="divider">/</span> <a href="#">'+dirName+'</a></li>');
  88. $("a",bcli).click(function(e) {
  89. $(this).parent().nextAll().remove();
  90. $.getJSON("library/"+options.url+root+dirName,function(data) {
  91. $("#node-select-library").children().first().replaceWith(buildFileList(root+dirName+"/",data));
  92. });
  93. e.stopPropagation();
  94. });
  95. var bc = $("#node-dialog-library-breadcrumbs");
  96. $(".active",bc).removeClass("active");
  97. bc.append(bcli);
  98. $.getJSON("library/"+options.url+root+dirName,function(data) {
  99. $("#node-select-library").children().first().replaceWith(buildFileList(root+dirName+"/",data));
  100. });
  101. }
  102. })();
  103. li.innerHTML = '<i class="icon-folder-close"></i> '+v+"</i>";
  104. ul.appendChild(li);
  105. } else {
  106. // file
  107. li = buildFileListItem(v);
  108. li.innerHTML = v.name;
  109. li.onclick = (function() {
  110. var item = v;
  111. return function(e) {
  112. $(".list-selected",ul).removeClass("list-selected");
  113. $(this).addClass("list-selected");
  114. $.get("library/"+options.url+root+item.fn, function(data) {
  115. console.log(data);
  116. selectedLibraryItem = item;
  117. libraryEditor.setText(data);
  118. });
  119. }
  120. })();
  121. ul.appendChild(li);
  122. }
  123. }
  124. return ul;
  125. }
  126. $('#node-input-name').addClass('input-append-left').css("width","65%").after(
  127. '<div class="btn-group" style="margin-left: -5px;">'+
  128. '<button id="node-input-'+options.type+'-lookup" class="btn input-append-right" data-toggle="dropdown"><i class="icon-book"></i> <span class="caret"></span></button>'+
  129. '<ul class="dropdown-menu pull-right" role="menu">'+
  130. '<li><a id="node-input-'+options.type+'-menu-open-library" tabindex="-1" href="#">Open Library...</a></li>'+
  131. '<li><a id="node-input-'+options.type+'-menu-save-library" tabindex="-1" href="#">Save to Library...</a></li>'+
  132. '</ul></div>'
  133. );
  134. $('#node-input-'+options.type+'-menu-open-library').click(function(e) {
  135. $("#node-select-library").children().remove();
  136. var bc = $("#node-dialog-library-breadcrumbs");
  137. bc.children().first().nextAll().remove();
  138. libraryEditor.setText('');
  139. $.getJSON("library/"+options.url,function(data) {
  140. $("#node-select-library").append(buildFileList("/",data));
  141. $("#node-dialog-library-breadcrumbs a").click(function(e) {
  142. $(this).parent().nextAll().remove();
  143. $("#node-select-library").children().first().replaceWith(buildFileList("/",data));
  144. e.stopPropagation();
  145. });
  146. $( "#node-dialog-library-lookup" ).dialog( "open" );
  147. });
  148. e.preventDefault();
  149. });
  150. $('#node-input-'+options.type+'-menu-save-library').click(function(e) {
  151. //var found = false;
  152. var name = $("#node-input-name").val().replace(/(^\s*)|(\s*$)/g,"");
  153. //var buildPathList = function(data,root) {
  154. // var paths = [];
  155. // if (data.d) {
  156. // for (var i in data.d) {
  157. // var dn = root+(root==""?"":"/")+i;
  158. // var d = {
  159. // label:dn,
  160. // files:[]
  161. // };
  162. // for (var f in data.d[i].f) {
  163. // d.files.push(data.d[i].f[f].fn.split("/").slice(-1)[0]);
  164. // }
  165. // paths.push(d);
  166. // paths = paths.concat(buildPathList(data.d[i],root+(root==""?"":"/")+i));
  167. // }
  168. // }
  169. // return paths;
  170. //};
  171. $("#node-dialog-library-save-folder").attr("value","");
  172. var filename = name.replace(/[^\w-]/g,"-");
  173. if (filename === "") {
  174. filename = "unnamed-"+options.type;
  175. }
  176. $("#node-dialog-library-save-filename").attr("value",filename+".js");
  177. //var paths = buildPathList(libraryData,"");
  178. //$("#node-dialog-library-save-folder").autocomplete({
  179. // minLength: 0,
  180. // source: paths,
  181. // select: function( event, ui ) {
  182. // $("#node-dialog-library-save-filename").autocomplete({
  183. // minLength: 0,
  184. // source: ui.item.files
  185. // });
  186. // }
  187. //});
  188. $( "#node-dialog-library-save" ).dialog( "open" );
  189. e.preventDefault();
  190. });
  191. require(["orion/editor/edit"], function(edit) {
  192. libraryEditor = edit({
  193. parent:document.getElementById('node-select-library-text'),
  194. lang:"js",
  195. readonly: true
  196. });
  197. });
  198. $( "#node-dialog-library-lookup" ).dialog({
  199. title: options.type+" library",
  200. modal: true,
  201. autoOpen: false,
  202. width: 800,
  203. height: 450,
  204. buttons: [
  205. {
  206. text: "Ok",
  207. click: function() {
  208. if (selectedLibraryItem) {
  209. for (var i=0;i<options.fields.length;i++) {
  210. var field = options.fields[i];
  211. $("#node-input-"+field).val(selectedLibraryItem[field]);
  212. }
  213. options.editor.setText(libraryEditor.getText());
  214. }
  215. $( this ).dialog( "close" );
  216. }
  217. },
  218. {
  219. text: "Cancel",
  220. click: function() {
  221. $( this ).dialog( "close" );
  222. }
  223. }
  224. ],
  225. open: function(e) {
  226. var form = $("form",this);
  227. form.height(form.parent().height()-30);
  228. $("#node-select-library-text").height("100%");
  229. $(".form-row:last-child",form).children().height(form.height()-60);
  230. },
  231. resize: function(e) {
  232. var form = $("form",this);
  233. form.height(form.parent().height()-30);
  234. $(".form-row:last-child",form).children().height(form.height()-60);
  235. }
  236. });
  237. function saveToLibrary(overwrite) {
  238. var name = $("#node-input-name").val().replace(/(^\s*)|(\s*$)/g,"");
  239. if (name === "") {
  240. name = "Unnamed "+options.type;
  241. }
  242. var filename = $("#node-dialog-library-save-filename").val().replace(/(^\s*)|(\s*$)/g,"");
  243. var pathname = $("#node-dialog-library-save-folder").val().replace(/(^\s*)|(\s*$)/g,"");
  244. if (filename === "" || !/.+\.js$/.test(filename)) {
  245. RED.notify("Invalid filename","warning");
  246. return;
  247. }
  248. var fullpath = pathname+(pathname===""?"":"/")+filename;
  249. if (!overwrite) {
  250. //var pathnameParts = pathname.split("/");
  251. //var exists = false;
  252. //var ds = libraryData;
  253. //for (var pnp in pathnameParts) {
  254. // if (ds.d && pathnameParts[pnp] in ds.d) {
  255. // ds = ds.d[pathnameParts[pnp]];
  256. // } else {
  257. // ds = null;
  258. // break;
  259. // }
  260. //}
  261. //if (ds && ds.f) {
  262. // for (var f in ds.f) {
  263. // if (ds.f[f].fn == fullpath) {
  264. // exists = true;
  265. // break;
  266. // }
  267. // }
  268. //}
  269. //if (exists) {
  270. // $("#node-dialog-library-save-type").html(options.type);
  271. // $("#node-dialog-library-save-name").html(fullpath);
  272. // $("#node-dialog-library-save-confirm").dialog( "open" );
  273. // return;
  274. //}
  275. }
  276. var queryArgs = [];
  277. for (var i=0;i<options.fields.length;i++) {
  278. var field = options.fields[i];
  279. if (field == "name") {
  280. queryArgs.push("name="+encodeURIComponent(name));
  281. } else {
  282. queryArgs.push(encodeURIComponent(field)+"="+encodeURIComponent($("#node-input-"+field).val()));
  283. }
  284. }
  285. var queryString = queryArgs.join("&");
  286. var text = options.editor.getText();
  287. $.post("library/"+options.url+'/'+fullpath+"?"+queryString,text,function() {
  288. RED.notify("Saved "+options.type,"success");
  289. });
  290. }
  291. $( "#node-dialog-library-save-confirm" ).dialog({
  292. title: "Save to library",
  293. modal: true,
  294. autoOpen: false,
  295. width: 530,
  296. height: 230,
  297. buttons: [
  298. {
  299. text: "Ok",
  300. click: function() {
  301. saveToLibrary(true);
  302. $( this ).dialog( "close" );
  303. }
  304. },
  305. {
  306. text: "Cancel",
  307. click: function() {
  308. $( this ).dialog( "close" );
  309. }
  310. }
  311. ]
  312. });
  313. $( "#node-dialog-library-save" ).dialog({
  314. title: "Save to library",
  315. modal: true,
  316. autoOpen: false,
  317. width: 530,
  318. height: 230,
  319. buttons: [
  320. {
  321. text: "Ok",
  322. click: function() {
  323. saveToLibrary(false);
  324. $( this ).dialog( "close" );
  325. }
  326. },
  327. {
  328. text: "Cancel",
  329. click: function() {
  330. $( this ).dialog( "close" );
  331. }
  332. }
  333. ]
  334. });
  335. }
  336. return {
  337. create: createUI,
  338. loadFlowLibrary: loadFlowLibrary
  339. }
  340. })();