chef-server-webui 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (207) hide show
  1. data/LICENSE +201 -0
  2. data/README.rdoc +135 -0
  3. data/Rakefile +62 -0
  4. data/app/controllers/application.rb +281 -0
  5. data/app/controllers/clients.rb +120 -0
  6. data/app/controllers/cookbook_attributes.rb +41 -0
  7. data/app/controllers/cookbook_definitions.rb +41 -0
  8. data/app/controllers/cookbook_files.rb +39 -0
  9. data/app/controllers/cookbook_libraries.rb +41 -0
  10. data/app/controllers/cookbook_recipes.rb +40 -0
  11. data/app/controllers/cookbook_templates.rb +57 -0
  12. data/app/controllers/cookbooks.rb +78 -0
  13. data/app/controllers/databag_items.rb +102 -0
  14. data/app/controllers/databags.rb +83 -0
  15. data/app/controllers/exceptions.rb +19 -0
  16. data/app/controllers/main.rb +7 -0
  17. data/app/controllers/nodes.rb +138 -0
  18. data/app/controllers/openid_consumer.rb +154 -0
  19. data/app/controllers/roles.rb +144 -0
  20. data/app/controllers/search.rb +62 -0
  21. data/app/controllers/search_entries.rb +64 -0
  22. data/app/controllers/status.rb +39 -0
  23. data/app/controllers/users.rb +186 -0
  24. data/app/helpers/application_helper.rb +171 -0
  25. data/app/helpers/cookbook_attributes_helper.rb +7 -0
  26. data/app/helpers/cookbook_definitions_helper.rb +8 -0
  27. data/app/helpers/cookbook_files_helper.rb +8 -0
  28. data/app/helpers/cookbook_libraries_helper.rb +7 -0
  29. data/app/helpers/cookbook_recipes_helper.rb +8 -0
  30. data/app/helpers/cookbook_templates_helper.rb +8 -0
  31. data/app/helpers/exceptions_helper.rb +6 -0
  32. data/app/helpers/global_helpers.rb +35 -0
  33. data/app/helpers/nodes_helper.rb +41 -0
  34. data/app/helpers/openid_consumer_helper.rb +8 -0
  35. data/app/helpers/openid_register_helper.rb +8 -0
  36. data/app/helpers/openid_server_helper.rb +6 -0
  37. data/app/helpers/openid_server_helpers.rb +29 -0
  38. data/app/helpers/roles_helper.rb +5 -0
  39. data/app/helpers/search_entries_helper.rb +8 -0
  40. data/app/helpers/search_helper.rb +38 -0
  41. data/app/helpers/status_helper.rb +26 -0
  42. data/app/views/clients/_form.html.haml +22 -0
  43. data/app/views/clients/_navigation.html.haml +9 -0
  44. data/app/views/clients/edit.html.haml +6 -0
  45. data/app/views/clients/index.html.haml +21 -0
  46. data/app/views/clients/new.html.haml +6 -0
  47. data/app/views/clients/show.html.haml +20 -0
  48. data/app/views/cookbooks/index.html.haml +10 -0
  49. data/app/views/cookbooks/show.html.haml +40 -0
  50. data/app/views/databag_items/_form.html.haml +14 -0
  51. data/app/views/databag_items/_navigation.html.haml +9 -0
  52. data/app/views/databag_items/edit.html.haml +6 -0
  53. data/app/views/databag_items/index.html.haml +0 -0
  54. data/app/views/databag_items/new.html.haml +6 -0
  55. data/app/views/databag_items/show.html.haml +9 -0
  56. data/app/views/databags/_form.html.haml +12 -0
  57. data/app/views/databags/_item_navigation.html.haml +8 -0
  58. data/app/views/databags/_navigation.html.haml +9 -0
  59. data/app/views/databags/edit.html.haml +6 -0
  60. data/app/views/databags/index.html.haml +19 -0
  61. data/app/views/databags/new.html.haml +6 -0
  62. data/app/views/databags/show.html.haml +19 -0
  63. data/app/views/exceptions/bad_request.json.erb +1 -0
  64. data/app/views/exceptions/internal_server_error.html.erb +216 -0
  65. data/app/views/exceptions/not_acceptable.html.erb +63 -0
  66. data/app/views/exceptions/not_found.html.erb +47 -0
  67. data/app/views/exceptions/standard_error.html.erb +217 -0
  68. data/app/views/layout/_jsonedit.html.haml +82 -0
  69. data/app/views/layout/chef_server_webui.html.haml +56 -0
  70. data/app/views/layout/login.html.haml +36 -0
  71. data/app/views/main/index.html.erb +1 -0
  72. data/app/views/nodes/_action.html.haml +13 -0
  73. data/app/views/nodes/_form.html.haml +53 -0
  74. data/app/views/nodes/_navigation.html.haml +9 -0
  75. data/app/views/nodes/_resource.html.haml +22 -0
  76. data/app/views/nodes/edit.html.haml +7 -0
  77. data/app/views/nodes/index.html.haml +25 -0
  78. data/app/views/nodes/new.html.haml +6 -0
  79. data/app/views/nodes/show.html.haml +60 -0
  80. data/app/views/openid_consumer/index.html.haml +28 -0
  81. data/app/views/openid_consumer/start.html.haml +4 -0
  82. data/app/views/openid_login/index.html.haml +5 -0
  83. data/app/views/openid_register/index.html.haml +19 -0
  84. data/app/views/openid_register/show.html.haml +7 -0
  85. data/app/views/roles/_form.html.haml +53 -0
  86. data/app/views/roles/_navigation.html.haml +9 -0
  87. data/app/views/roles/edit.html.haml +6 -0
  88. data/app/views/roles/index.html.haml +21 -0
  89. data/app/views/roles/new.html.haml +6 -0
  90. data/app/views/roles/show.html.haml +54 -0
  91. data/app/views/search/_search_form.html.haml +6 -0
  92. data/app/views/search/index.html.haml +8 -0
  93. data/app/views/search/show.html.haml +13 -0
  94. data/app/views/search_entries/index.html.haml +8 -0
  95. data/app/views/search_entries/show.html.haml +7 -0
  96. data/app/views/status/index.html.haml +90 -0
  97. data/app/views/users/_form.html.haml +39 -0
  98. data/app/views/users/_navigation.html.haml +9 -0
  99. data/app/views/users/edit.html.haml +6 -0
  100. data/app/views/users/index.html.haml +20 -0
  101. data/app/views/users/login.html.haml +16 -0
  102. data/app/views/users/new.html.haml +27 -0
  103. data/app/views/users/show.html.haml +13 -0
  104. data/app/views/users/start.html.haml +4 -0
  105. data/config.ru +84 -0
  106. data/config/init.rb +49 -0
  107. data/config/router.rb +6 -0
  108. data/lib/chef-server-webui.rb +155 -0
  109. data/lib/chef-server-webui/merbtasks.rb +103 -0
  110. data/lib/chef-server-webui/slicetasks.rb +20 -0
  111. data/lib/chef-server-webui/spectasks.rb +53 -0
  112. data/public/facebox/README.txt +4 -0
  113. data/public/facebox/b.png +0 -0
  114. data/public/facebox/bl.png +0 -0
  115. data/public/facebox/br.png +0 -0
  116. data/public/facebox/closelabel.gif +0 -0
  117. data/public/facebox/facebox.css +95 -0
  118. data/public/facebox/facebox.js +319 -0
  119. data/public/facebox/loading.gif +0 -0
  120. data/public/facebox/tl.png +0 -0
  121. data/public/facebox/tr.png +0 -0
  122. data/public/images/avatar.png +0 -0
  123. data/public/images/black_big.png +0 -0
  124. data/public/images/indicator.gif +0 -0
  125. data/public/images/jsonedit/add2.png +0 -0
  126. data/public/images/jsonedit/build-button.png +0 -0
  127. data/public/images/jsonedit/bullet.gif +0 -0
  128. data/public/images/jsonedit/bullet_orange.png +0 -0
  129. data/public/images/jsonedit/cross.png +0 -0
  130. data/public/images/jsonedit/delete.png +0 -0
  131. data/public/images/jsonedit/deleted.png +0 -0
  132. data/public/images/jsonedit/json.jpg +0 -0
  133. data/public/images/jsonedit/label.gif +0 -0
  134. data/public/images/jsonedit/minus.gif +0 -0
  135. data/public/images/jsonedit/pixel.gif +0 -0
  136. data/public/images/jsonedit/plus.gif +0 -0
  137. data/public/images/jsonedit/saved.png +0 -0
  138. data/public/images/jsonedit/table_refresh.png +0 -0
  139. data/public/images/jsonedit/value.gif +0 -0
  140. data/public/images/merb.jpg +0 -0
  141. data/public/images/toggle-collapse-dark.png +0 -0
  142. data/public/images/toggle-collapse-light.png +0 -0
  143. data/public/images/toggle-collapse.gif +0 -0
  144. data/public/images/toggle-expand-dark.png +0 -0
  145. data/public/images/toggle-expand-light.png +0 -0
  146. data/public/images/toggle-expand.gif +0 -0
  147. data/public/images/treeBuilderImages/Thumbs.db +0 -0
  148. data/public/images/treeBuilderImages/doc.gif +0 -0
  149. data/public/images/treeBuilderImages/docNode.gif +0 -0
  150. data/public/images/treeBuilderImages/docNodeLast.gif +0 -0
  151. data/public/images/treeBuilderImages/docNodeLastFirst.gif +0 -0
  152. data/public/images/treeBuilderImages/folder.gif +0 -0
  153. data/public/images/treeBuilderImages/folderNode.gif +0 -0
  154. data/public/images/treeBuilderImages/folderNodeFirst.gif +0 -0
  155. data/public/images/treeBuilderImages/folderNodeLast.gif +0 -0
  156. data/public/images/treeBuilderImages/folderNodeLastFirst.gif +0 -0
  157. data/public/images/treeBuilderImages/folderNodeOpen.gif +0 -0
  158. data/public/images/treeBuilderImages/folderNodeOpenFirst.gif +0 -0
  159. data/public/images/treeBuilderImages/folderNodeOpenLast.gif +0 -0
  160. data/public/images/treeBuilderImages/folderNodeOpenLastFirst.gif +0 -0
  161. data/public/images/treeBuilderImages/folderOpen.gif +0 -0
  162. data/public/images/treeBuilderImages/vertLine.gif +0 -0
  163. data/public/javascripts/chef.js +160 -0
  164. data/public/javascripts/jquery-1.3.2.min.js +19 -0
  165. data/public/javascripts/jquery-ui-1.7.1.custom.min.js +65 -0
  166. data/public/javascripts/jquery.editinline.js +108 -0
  167. data/public/javascripts/jquery.jeditable.mini.js +30 -0
  168. data/public/javascripts/jquery.livequery.js +250 -0
  169. data/public/javascripts/jquery.localscroll.js +104 -0
  170. data/public/javascripts/jquery.scrollTo.js +150 -0
  171. data/public/javascripts/jquery.tools.min.js +17 -0
  172. data/public/javascripts/jquery.treeTable.min.js +165 -0
  173. data/public/javascripts/json.js +153 -0
  174. data/public/javascripts/jsonedit_main.js +675 -0
  175. data/public/javascripts/yetii-min.js +1 -0
  176. data/public/stylesheets/base.css +336 -0
  177. data/public/stylesheets/chef.css +157 -0
  178. data/public/stylesheets/images/ui-bg_diagonals-small_0_aaaaaa_40x40.png +0 -0
  179. data/public/stylesheets/images/ui-bg_diagonals-thick_15_444444_40x40.png +0 -0
  180. data/public/stylesheets/images/ui-bg_glass_100_f0f0f0_1x400.png +0 -0
  181. data/public/stylesheets/images/ui-bg_glass_50_99c2ff_1x400.png +0 -0
  182. data/public/stylesheets/images/ui-bg_glass_55_fbf5d0_1x400.png +0 -0
  183. data/public/stylesheets/images/ui-bg_glass_80_e6e6e6_1x400.png +0 -0
  184. data/public/stylesheets/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  185. data/public/stylesheets/images/ui-bg_highlight-hard_100_f9f9f9_1x100.png +0 -0
  186. data/public/stylesheets/images/ui-bg_highlight-soft_100_e7eef3_1x100.png +0 -0
  187. data/public/stylesheets/images/ui-icons_222222_256x240.png +0 -0
  188. data/public/stylesheets/images/ui-icons_2694e8_256x240.png +0 -0
  189. data/public/stylesheets/images/ui-icons_2e83ff_256x240.png +0 -0
  190. data/public/stylesheets/images/ui-icons_72a7cf_256x240.png +0 -0
  191. data/public/stylesheets/images/ui-icons_888888_256x240.png +0 -0
  192. data/public/stylesheets/images/ui-icons_cd0a0a_256x240.png +0 -0
  193. data/public/stylesheets/images/ui-icons_ffffff_256x240.png +0 -0
  194. data/public/stylesheets/jquery-ui-1.7.1.custom.css +404 -0
  195. data/public/stylesheets/jquery.treeTable.css +43 -0
  196. data/public/stylesheets/jsonedit_main.css +280 -0
  197. data/public/stylesheets/themes/bec-green/style.css +290 -0
  198. data/public/stylesheets/themes/bec/style.css +301 -0
  199. data/public/stylesheets/themes/blue/style.css +280 -0
  200. data/public/stylesheets/themes/default/style.css +267 -0
  201. data/public/stylesheets/themes/djime-cerulean/style.css +298 -0
  202. data/public/stylesheets/themes/kathleene/style.css +272 -0
  203. data/public/stylesheets/themes/orange/style.css +263 -0
  204. data/public/stylesheets/themes/reidb-greenish/style.css +301 -0
  205. data/stubs/app/controllers/application.rb +2 -0
  206. data/stubs/app/controllers/main.rb +2 -0
  207. metadata +399 -0
@@ -0,0 +1,17 @@
1
+ /*
2
+ * jquery.tools 1.0.0 - The missing UI library
3
+ *
4
+ * [tools.tooltip-1.0.0, tools.expose-1.0.2]
5
+ *
6
+ * Copyright (c) 2009 Tero Piirainen
7
+ * http://flowplayer.org/tools/
8
+ *
9
+ * Dual licensed under MIT and GPL 2+ licenses
10
+ * http://www.opensource.org/licenses
11
+ *
12
+ * -----
13
+ *
14
+ * Build: Wed Jun 03 19:51:51 GMT+00:00 2009
15
+ */
16
+ (function(c){c.tools=c.tools||{version:{}};c.tools.version.tooltip="1.0.0";var b={toggle:[function(){this.getTip().show()},function(){this.getTip().hide()}]};c.tools.addTipEffect=function(d,f,e){b[d]=[f,e]};c.tools.addTipEffect("slideup",function(){var d=this.getConf();var e=d.slideOffset||10;this.getTip().css({opacity:0}).animate({top:"-="+e,opacity:d.opacity},d.slideInSpeed||200).show()},function(){var d=this.getConf();var e=d.slideOffset||10;this.getTip().animate({top:"-="+e,opacity:0},d.slideOutSpeed||200,function(){c(this).hide().animate({top:"+="+(e*2)},0)})});function a(g,e){var d=this;function i(j,k){c(d).bind(j,function(m,l){if(k&&k.call(this)===false&&l){l.proceed=false}});return d}c.each(e,function(j,k){if(c.isFunction(k)){i(j,k)}});var f=e.triggers?c(e.triggers):g.prev(e.trigger);if(!f.length){throw"cannot find trigges for tip: "+g.selector}f.bind(f.is("input")?"focus":"mouseover",function(j){d.show(j);g.hover(function(){d.show()},function(){d.hide()})});f.bind(f.is("input")?"blur":"mouseout",function(){d.hide()});g.css("opacity",e.opacity);var h=0;c.extend(d,{show:function(o){if(o){f=c(o.target)}clearTimeout(h);if(g.is(":animated")||g.is(":visible")){return d}var n={proceed:true};c(d).trigger("onBeforeShow",n);if(!n.proceed){return d}var m=f.position().top-g.outerHeight();var j=g.outerHeight()+f.outerHeight();var q=e.position[0];if(q=="center"){m+=j/2}if(q=="bottom"){m+=j}var k=f.outerWidth()+g.outerWidth();var l=f.position().left+f.outerWidth();q=e.position[1];if(q=="center"){l-=k/2}if(q=="left"){l-=k}m+=e.offset[0];l+=e.offset[1];g.css({position:"absolute",top:m,left:l});b[e.effect][0].call(d);c(d).trigger("onShow");return d},hide:function(){clearTimeout(h);h=setTimeout(function(){if(g.is(":animated")||!g.is(":visible")){return d}var j={proceed:true};c(d).trigger("onBeforeHide",j);if(!j.proceed){return d}b[e.effect][1].call(d);c(d).trigger("onHide")},e.delay||1);return d},isShown:function(){return g.is(":visible, :animated")},getConf:function(){return e},getTip:function(){return g},getTrigger:function(){return f},onBeforeShow:function(j){return i("onBeforeShow",j)},onShow:function(j){return i("onShow",j)},onBeforeHide:function(j){return i("onBeforeHide",j)},onHide:function(j){return i("onHide",j)}})}c.prototype.tooltip=function(d){var e=this.eq(typeof d=="number"?d:0).data("tooltip");if(e){return e}var f={trigger:null,triggers:null,effect:"slideup",delay:30,opacity:1,position:["top","center"],offset:[0,0],api:false};if(c.isFunction(d)){d={onBeforeShow:d}}c.extend(f,d);this.each(function(){e=new a(c(this),f);c(this).data("tooltip",e)});return f.api?e:this}})(jQuery);
17
+ (function(b){b.tools=b.tools||{version:{}};b.tools.version.expose="1.0.2";function a(){var e=b(window).width();if(b.browser.mozilla){return e}var d;if(window.innerHeight&&window.scrollMaxY){d=window.innerWidth+window.scrollMaxX}else{if(document.body.scrollHeight>document.body.offsetHeight){d=document.body.scrollWidth}else{d=document.body.offsetWidth}}return d<e?d+20:e}function c(g,h){var e=this,d=null,f=false,i=0;function j(k,l){b(e).bind(k,function(n,m){if(l&&l.call(this)===false&&m){m.proceed=false}});return e}b.each(h,function(k,l){if(b.isFunction(l)){j(k,l)}});b(window).bind("resize.expose",function(){if(d){d.css({width:a(),height:b(document).height()})}});b.extend(this,{getMask:function(){return d},getExposed:function(){return g},getConf:function(){return h},isLoaded:function(){return f},load:function(){if(f){return e}i=g.eq(0).css("zIndex");if(h.maskId){d=b("#"+h.maskId)}if(!d||!d.length){d=b("<div/>").css({position:"absolute",top:0,left:0,width:a(),height:b(document).height(),display:"none",opacity:0,zIndex:h.zIndex});if(h.maskId){d.attr("id",h.maskId)}b("body").append(d);var k=d.css("backgroundColor");if(!k||k=="transparent"||k=="rgba(0, 0, 0, 0)"){d.css("backgroundColor",h.color)}if(h.closeOnEsc){b(document).bind("keydown.unexpose",function(n){if(n.keyCode==27){e.close()}})}if(h.closeOnClick){d.bind("click.unexpose",function(){e.close()})}}var m={proceed:true};b(e).trigger("onBeforeLoad",m);if(!m.proceed){return e}b.each(g,function(){var n=b(this);if(!/relative|absolute/i.test(n.css("position"))){n.css("position","relative")}});g.css({zIndex:h.zIndex+1});var l=d.height();if(!this.isLoaded()){d.css({opacity:0,display:"block"}).fadeTo(h.loadSpeed,h.opacity,function(){if(d.height()!=l){d.css("height",l)}b(e).trigger("onLoad")})}f=true;return e},close:function(){if(!f){return e}var k={proceed:true};b(e).trigger("onBeforeClose",k);if(k.proceed===false){return e}d.fadeOut(h.closeSpeed,function(){b(e).trigger("onClose");g.css({zIndex:b.browser.msie?i:null})});f=false;return e},onBeforeLoad:function(k){return j("onBeforeLoad",k)},onLoad:function(k){return j("onLoad",k)},onBeforeClose:function(k){return j("onBeforeClose",k)},onClose:function(k){return j("onClose",k)}})}b.fn.expose=function(d){var e=this.eq(typeof d=="number"?d:0).data("expose");if(e){return e}var f={maskId:null,loadSpeed:"slow",closeSpeed:"fast",closeOnClick:true,closeOnEsc:true,zIndex:9998,opacity:0.8,color:"#456",api:false};if(typeof d=="string"){d={color:d}}b.extend(f,d);this.each(function(){e=new c(b(this),f);b(this).data("expose",e)});return f.api?e:this}})(jQuery);
@@ -0,0 +1,165 @@
1
+ /* jQuery treeTable Plugin 2.2.1 - http://ludo.cubicphuse.nl/jquery-plugins/treeTable/ */
2
+ (function($) {
3
+ // Helps to make options available to all functions
4
+ // TODO: This gives problems when there are both expandable and non-expandable
5
+ // trees on a page. The options shouldn't be global to all these instances!
6
+ var options;
7
+
8
+ $.fn.treeTable = function(opts) {
9
+ options = $.extend({}, $.fn.treeTable.defaults, opts);
10
+
11
+ return this.each(function() {
12
+ $(this).addClass("treeTable").find("tbody tr").each(function() {
13
+ // Initialize root nodes only whenever possible
14
+ if(!options.expandable || $(this)[0].className.search("child-of-") == -1) {
15
+ initialize($(this));
16
+ }
17
+ });
18
+ });
19
+ };
20
+
21
+ $.fn.treeTable.defaults = {
22
+ childPrefix: "child-of-",
23
+ expandable: true,
24
+ indent: 19,
25
+ initialState: "collapsed",
26
+ treeColumn: 0
27
+ };
28
+
29
+ // Recursively hide all node's children in a tree
30
+ $.fn.collapse = function() {
31
+ $(this).addClass("collapsed");
32
+
33
+ childrenOf($(this)).each(function() {
34
+ initialize($(this));
35
+
36
+ if(!$(this).hasClass("collapsed")) {
37
+ $(this).collapse();
38
+ }
39
+
40
+ $(this).hide();
41
+ });
42
+
43
+ return this;
44
+ };
45
+
46
+ // Recursively show all node's children in a tree
47
+ $.fn.expand = function() {
48
+ $(this).removeClass("collapsed").addClass("expanded");
49
+
50
+ childrenOf($(this)).each(function() {
51
+ initialize($(this));
52
+
53
+ if($(this).is(".expanded.parent")) {
54
+ $(this).expand();
55
+ }
56
+
57
+ $(this).show();
58
+ });
59
+
60
+ return this;
61
+ };
62
+
63
+ // Add an entire branch to +destination+
64
+ $.fn.appendBranchTo = function(destination) {
65
+ var node = $(this);
66
+ var parent = parentOf(node);
67
+
68
+ var ancestorNames = $.map(ancestorsOf($(destination)), function(a) { return a.id; });
69
+
70
+ // Conditions:
71
+ // 1: +node+ should not be inserted in a location in a branch if this would
72
+ // result in +node+ being an ancestor of itself.
73
+ // 2: +node+ should not have a parent OR the destination should not be the
74
+ // same as +node+'s current parent (this last condition prevents +node+
75
+ // from being moved to the same location where it already is).
76
+ // 3: +node+ should not be inserted as a child of +node+ itself.
77
+ if($.inArray(node[0].id, ancestorNames) == -1 && (!parent || (destination.id != parent[0].id)) && destination.id != node[0].id) {
78
+ indent(node, ancestorsOf(node).length * options.indent * -1); // Remove indentation
79
+
80
+ if(parent) { node.removeClass(options.childPrefix + parent[0].id); }
81
+
82
+ node.addClass(options.childPrefix + destination.id);
83
+ move(node, destination); // Recursively move nodes to new location
84
+ indent(node, ancestorsOf(node).length * options.indent);
85
+ }
86
+
87
+ return this;
88
+ };
89
+
90
+ // Add reverse() function from JS Arrays
91
+ $.fn.reverse = function() {
92
+ return this.pushStack(this.get().reverse(), arguments);
93
+ };
94
+
95
+ // Toggle an entire branch
96
+ $.fn.toggleBranch = function() {
97
+ if($(this).hasClass("collapsed")) {
98
+ $(this).expand();
99
+ } else {
100
+ $(this).removeClass("expanded").collapse();
101
+ }
102
+
103
+ return this;
104
+ };
105
+
106
+ // === Private functions
107
+
108
+ function ancestorsOf(node) {
109
+ var ancestors = [];
110
+ while(node = parentOf(node)) {
111
+ ancestors[ancestors.length] = node[0];
112
+ }
113
+ return ancestors;
114
+ };
115
+
116
+ function childrenOf(node) {
117
+ return $("table.treeTable tbody tr." + options.childPrefix + node[0].id);
118
+ };
119
+
120
+ function indent(node, value) {
121
+ var cell = $(node.children("td")[options.treeColumn]);
122
+ var padding = parseInt(cell.css("padding-left"), 10) + value;
123
+
124
+ cell.css("padding-left", + padding + "px");
125
+
126
+ childrenOf(node).each(function() {
127
+ indent($(this), value);
128
+ });
129
+ };
130
+
131
+ function initialize(node) {
132
+ if(!node.hasClass("initialized")) {
133
+ node.addClass("initialized");
134
+
135
+ var childNodes = childrenOf(node);
136
+
137
+ if(node.hasClass("parent")) {
138
+ var cell = $(node.children("td")[options.treeColumn]);
139
+ var padding = parseInt(cell.css("padding-left"), 10) + options.indent;
140
+
141
+ childNodes.each(function() {
142
+ $($(this).children("td")[options.treeColumn]).css("padding-left", padding + "px");
143
+ });
144
+
145
+ $(cell[0].firstChild).css({ "margin-left": '-' + options.indent + 'px', "padding-left": options.indent + 'px' });
146
+ }
147
+ }
148
+ };
149
+
150
+ function move(node, destination) {
151
+ node.insertAfter(destination);
152
+ childrenOf(node).reverse().each(function() { move($(this), node[0]); });
153
+ };
154
+
155
+ function parentOf(node) {
156
+ var classNames = node[0].className.split(' ');
157
+
158
+ for(key in classNames) {
159
+ if(classNames[key].match("child-of-")) {
160
+ return $("#" + classNames[key].substring(9));
161
+ }
162
+ }
163
+ };
164
+ })(jQuery);
165
+
@@ -0,0 +1,153 @@
1
+ /*
2
+ Do NOT use this version as it was slightly modified to accomodate editing and returning of functions!
3
+ use this version instead: http://www.JSON.org/json2.js
4
+ */
5
+
6
+ if (!this.JSON) {
7
+ JSON = function () {
8
+ function f(n) {return n < 10 ? '0' + n : n;}
9
+ Date.prototype.toJSON = function () {
10
+ return this.getUTCFullYear() + '-' +
11
+ f(this.getUTCMonth() + 1) + '-' +
12
+ f(this.getUTCDate()) + 'T' +
13
+ f(this.getUTCHours()) + ':' +
14
+ f(this.getUTCMinutes()) + ':' +
15
+ f(this.getUTCSeconds()) + 'Z';
16
+ };
17
+ var meta = {
18
+ '\b': '\\b',
19
+ '\t': '\\t',
20
+ '\n': '\\n',
21
+ '\f': '\\f',
22
+ '\r': '\\r',
23
+ '"' : '\\"',
24
+ '\\': '\\\\'
25
+ },
26
+ escapeable = /["\\\x00-\x1f\x7f-\x9f]/g;
27
+
28
+ function quote(string) {
29
+ return escapeable.test(string) ?
30
+ '"' + string.replace(escapeable, function (a) {
31
+ var c = meta[a];
32
+ if (typeof c === 'string') {
33
+ return c;
34
+ }
35
+ c = a.charCodeAt();
36
+ return '\\u00' + Math.floor(c / 16).toString(16) +
37
+ (c % 16).toString(16);
38
+ }) + '"' :
39
+ '"' + string + '"';
40
+ }
41
+
42
+ function stringify(key, holder, replacer) {
43
+ var i,
44
+ k,
45
+ v,
46
+ length,
47
+ partial,
48
+ value = holder[key];
49
+ if (value && typeof value === 'object' &&
50
+ typeof value.toJSON === 'function') {
51
+ value = value.toJSON(key);
52
+ }
53
+ if (typeof replacer === 'function') {
54
+ value = replacer.call(holder, key, value);
55
+ }
56
+ switch (typeof value) {
57
+ case 'string':
58
+ return quote(value);
59
+
60
+ /* added for the BC Json Editor to enable editing of functions */
61
+ case 'function':
62
+ return value;
63
+
64
+ case 'number':
65
+ return isFinite(value) ? String(value) : 'null';
66
+ case 'boolean':
67
+ case 'null':
68
+ return String(value);
69
+ case 'object':
70
+ if (!value) {
71
+ return 'null';
72
+ }
73
+ partial = [];
74
+ if (typeof value.length === 'number' &&
75
+ !(value.propertyIsEnumerable('length'))) {
76
+ length = value.length;
77
+ for (i = 0; i < length; i += 1) {
78
+ partial[i] = stringify(i, value, replacer) || 'null';
79
+ }
80
+ return '[' + partial.join(',') + ']';
81
+ }
82
+ if (typeof replacer === 'object') {
83
+ length = replacer.length;
84
+ for (i = 0; i < length; i += 1) {
85
+ k = replacer[i];
86
+ if (typeof k === 'string') {
87
+ v = stringify(k, value, replacer);
88
+ if (v) {
89
+ partial.push(quote(k) + ':' + v);
90
+ }
91
+ }
92
+ }
93
+ } else {
94
+ for (k in value) {
95
+ v = stringify(k, value, replacer);
96
+ if (v) {
97
+ partial.push(quote(k) + ':' + v);
98
+ }
99
+ }
100
+ }
101
+ return '{' + partial.join(',') + '}';
102
+ }
103
+ }
104
+ return {
105
+ stringify: function (value, replacer) {
106
+ if (typeof replacer !== 'function') {
107
+ if (!replacer) {
108
+ replacer = function (key, value) {
109
+ if (!Object.hasOwnProperty.call(this, key)) {
110
+ return undefined;
111
+ }
112
+ return value;
113
+ };
114
+ } else if (typeof replacer !== 'object' ||
115
+ typeof replacer.length !== 'number') {
116
+ throw new Error('JSON.stringify');
117
+ }
118
+ }
119
+ return stringify('', {'': value}, replacer);
120
+ },
121
+
122
+ parse: function (text, reviver) {
123
+ var j;
124
+ function walk(holder, key) {
125
+ var k, v, value = holder[key];
126
+ if (value && typeof value === 'object') {
127
+ for (k in value) {
128
+ if (Object.hasOwnProperty.call(value, k)) {
129
+ v = walk(value, k);
130
+ if (v !== undefined) {
131
+ value[k] = v;
132
+ } else {
133
+ delete value[k];
134
+ }
135
+ }
136
+ }
137
+ }
138
+ return reviver.call(holder, key, value);
139
+ }
140
+ if (/^[\],:{}\s]*$/.test(text.replace(/\\["\\\/bfnrtu]/g, '@').
141
+ replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
142
+ replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
143
+ j = eval('(' + text + ')');
144
+ return typeof reviver === 'function' ?
145
+ walk({'': j}, '') : j;
146
+ }
147
+ throw new SyntaxError('JSON.parse');
148
+ },
149
+ info:{"version":"","www":"http://www.json.org/","date":"2008-03-22","description":"Open source code of a JSON parser and JSON stringifier. [Douglas Crockford]"},
150
+ quote: quote
151
+ };
152
+ }();
153
+ }
@@ -0,0 +1,675 @@
1
+ /*
2
+ "version": "1.1", "www": "http://braincast.nl", "date": "april 2008", "description": "Braincast Json Tree object." },
3
+ */
4
+ var BCJT = function() {
5
+ return {
6
+ info: { "version": "1.1", "www": "http://braincast.nl", "date": "april 2008", "description": "Braincast Json Tree object." },
7
+ util: function() {
8
+ function addLoadEvent(func) { var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = func; } else { window.onload = function() { if (oldonload) { oldonload(); } func(); }; } }
9
+ function addEvent(obj, type, fn) { if (obj.attachEvent) { obj['e' + type + fn] = fn; obj[type + fn] = function() { obj['e' + type + fn](window.event); }; obj.attachEvent('on' + type, obj[type + fn]); } else { obj.addEventListener(type, fn, false); } }
10
+ function getElementById(strid) { return document.getElementById(strid); }
11
+ return { addLoadEvent: addLoadEvent, addEvent: addEvent, $$: getElementById };
12
+ } (),
13
+ tree: function() {
14
+ var treeIndex = 0;
15
+ var li = 0;
16
+ function TreeUtil() {
17
+ var oldA;
18
+ function makeUrl(jsonpath, text, li, index, clickable) { return (clickable) ? "<a id=\"a" + li + "\" onclick=\"BCJT.tree.forest[" + index + "].getNodeValue('" + escape(jsonpath) + "', this);return false\">" + text + "</a>" : text; }
19
+ function isTypeOf(thing) { return (thing !== null) ? thing.constructor : thing; }
20
+ function strIsTypeOf(con) { switch (con) { case Array: return 'array'; case Object: return 'object'; case Function: return 'function'; case String: return 'string'; case Number: return 'number'; case Boolean: return 'boolean'; case null: return 'null'; default: return 'undeterimable type'; } }
21
+ function getParentLi(item) {
22
+ /* not used */
23
+ return (item.nodeName == "LI") ? item.id : getParentLi(item.parentNode);
24
+ }
25
+ return {
26
+ strIsTypeOf: strIsTypeOf,
27
+ isTypeOf: isTypeOf,
28
+ getNodeValue: function(jsonPath, aobj) {
29
+ if (aobj) {
30
+ if (isTypeOf(aobj) == String) {
31
+ aobj = document.getElementById(aobj);
32
+ }
33
+ if (oldA) { oldA.className = "au"; } aobj.className = "as"; oldA = aobj;
34
+ }
35
+ this.cp = "BCJT.tree.forest[" + this.index + "]." + unescape(jsonPath);
36
+ this.ca = aobj;
37
+ this.cli = document.getElementById("li" + aobj.id.substr(1));
38
+ var params = { "jsonPath": "", "jsonValue": "", "jsonType": null, "a": {}, li: {} };
39
+ try {
40
+ var jsval = eval("BCJT.tree.forest[" + this.index + "]." + BCJTEP.escapeslashes(unescape(jsonPath)));
41
+ var typ = isTypeOf(jsval);
42
+ var txt;
43
+ if (typ == Function) {
44
+ txt = (jsval.toSource) ? jsval.toSource() : txt = jsval;
45
+ } else if (typ == String) {
46
+ txt = JSON.stringify(jsval).replace(/(^")|("$)/g, "");
47
+ } else {
48
+ txt = JSON.stringify(jsval);
49
+ }
50
+ params.jsonPath = jsonPath;
51
+ params.jsonValue = txt;
52
+ params.jsonType = strIsTypeOf(typ);
53
+ params.a = this.ca;
54
+ params.li = this.cli;
55
+ $$("autodetect").checked = false;
56
+ this.nodeclick(params);
57
+ } catch (e) {
58
+ BCJT.tree.error = "Could not get value!<br />" + e;
59
+ $$("log").innerHTML = BCJT.tree.error;
60
+ $$("console").style.display = "block";
61
+ }
62
+ },
63
+ makeTree: function(content, dots, inside) {
64
+ var out = ""; var t;
65
+ if (content === null) {
66
+ if (!inside) { out += "<ul><li><s>null</s></li></ul>"; }
67
+ } else if (isTypeOf(content) == Array) {
68
+ out += "<ul>";
69
+ for (var i = 0; i < content.length; i++) {
70
+ dots += "[" + i + "]";
71
+ t = this.makeTree(content[i], dots, false);
72
+ dots = dots.substr(0, dots.length - ("" + i).length - 2);
73
+ li++;
74
+ out += "<li id=\"li" + li + "\">" + makeUrl(dots + "[" + i + "]", i + " (index)", li, this.index, this.clickable) + " " + t;
75
+ }
76
+ out += "</ul>";
77
+ } else if (isTypeOf(content) == Object) {
78
+ out += "<ul>";
79
+ for (var j in content) {
80
+ dots += "['" + j + "']";
81
+ t = this.makeTree(content[j], dots, true);
82
+ dots = dots.substr(0, dots.length - j.length - 4);
83
+ li++;
84
+ out += "<li id=\"li" + li + "\">" + makeUrl(dots + "['" + j + "']", j, li, this.index, this.clickable) + " " + t;
85
+ }
86
+ out += "</ul>";
87
+ } else if (isTypeOf(content) == String) {
88
+ out += "</li>";
89
+ } else { out += "</li>"; }
90
+ return out;
91
+ },
92
+ reloadTree: function() {
93
+ li = 0;
94
+ if (this.clickable) {
95
+ if (this.rootLink === "") { this.rootLink = "BCJT.tree.forest[" + this.index + "].getNodeValue('json', this);return false"; }
96
+ this.el.innerHTML = "<ul id=\"tree" + this.index + "\" class=\"mktree\"><li><a id=\"a0\" onclick=\"" + this.rootLink + "\">" + this.rootNode + "</a><ul>" + this.makeTree(this.json, "json", false).substr(4) + "</ul></li></ul>";
97
+ } else { this.el.innerHTML = "<ul id=\"tree" + this.index + "\" class=\"mktree\"><li>" + this.rootNode + "<ul>" + this.makeTree(this.json, "json", false).substr(4) + "</ul></li></ul>"; }
98
+ if (this.mktree) { BCJT.mktree.processList(document.getElementById("tree" + this.index)); }
99
+ }
100
+ };
101
+ }
102
+ function Tree(json, div, params) {
103
+ if (!params) { params = {}; }
104
+ var options = { "json": json, "nodeclick": function() { }, "mktree": true, "clickable": true, "index": treeIndex, "el": document.getElementById(div), "cp": null, "ca": null, "cli": null, rootNode: "json", rootLink: "", "newtree": true };
105
+ for (var key in options) { this[key] = (params[key] !== undefined) ? params[key] : options[key]; }
106
+ if (this.newtree) {
107
+ if (this.clickable) {
108
+ if (this.rootLink === "") { this.rootLink = "BCJT.tree.forest[" + this.index + "].getNodeValue('json', this);return false"; }
109
+ this.el.innerHTML = "<ul id=\"tree" + treeIndex + "\" class=\"mktree\"><li><a id=\"a0\" onclick=\"" + this.rootLink + "\">" + this.rootNode + "</a><ul>" + this.makeTree(json, "json", false).substr(4) + "</ul></li></ul>";
110
+ } else { this.el.innerHTML = "<ul id=\"tree" + treeIndex + "\" class=\"mktree\"><li>" + this.rootNode + "<ul>" + this.makeTree(json, "json", false).substr(4) + "</ul></li></ul>"; }
111
+ BCJT.tree.forest.push(this);
112
+ treeIndex++;
113
+ } else {
114
+ if (this.clickable) {
115
+ if (this.rootLink === "") { this.rootLink = "BCJT.tree.forest[" + this.index + "].getNodeValue('json', this);return false"; }
116
+ this.el.innerHTML = "<ul id=\"tree" + this.index + "\" class=\"mktree\"><li><a id=\"a0\" onclick=\"" + this.rootLink + "\">" + this.rootNode + "</a><ul>" + this.makeTree(json, "json", false).substr(4) + "</ul></li></ul>";
117
+ } else { this.el.innerHTML = "<ul id=\"tree" + this.index + "\" class=\"mktree\"><li>" + this.rootNode + "<ul>" + this.makeTree(json, "json", false).substr(4) + "</ul></li></ul>"; }
118
+ li = 0;
119
+ BCJT.tree.forest[this.index] = this;
120
+ }
121
+ if (this.mktree) { BCJT.mktree.processList(document.getElementById("tree" + this.index)); }
122
+ return this;
123
+ }
124
+ Tree.prototype = new TreeUtil();
125
+ return {
126
+ forest: [],
127
+ _tree: Tree, /* expose the internal Tree object for prototype purposes */
128
+ init: function(json, div, params) {
129
+ try {
130
+ var j = (json.constructor === Object) ? json : eval('(' +json+ ')');
131
+ new Tree(j, div, params);
132
+ return true;
133
+ } catch (e) {
134
+ BCJT.tree.error = "Build tree failed!<br />" + e;
135
+ return false;
136
+ }
137
+ },
138
+ error: ""
139
+ };
140
+ } (),
141
+ mktree: function() {
142
+ /* All below code was obtained from: http://www.javascripttoolbox.com/lib/mktree/
143
+ the autor is: Matt Kruse (http://www.mattkruse.com/)
144
+ (The code below was slightly modified!)
145
+ */
146
+ var nodeClosedClass = "liClosed", nodeOpenClass = "liOpen", nodeBulletClass = "liBullet", nodeLinkClass = "bullet";
147
+
148
+ /* the two below functions will prevent memory leaks in IE */
149
+ function treeNodeOnclick() { this.parentNode.className = (this.parentNode.className == nodeOpenClass) ? nodeClosedClass : nodeOpenClass; return false; }
150
+ function retFalse() { return false; }
151
+ function processList(ul) {
152
+ if (!ul.childNodes || ul.childNodes.length === 0) { return; }
153
+ var childNodesLength = ul.childNodes.length;
154
+ for (var itemi = 0; itemi < childNodesLength; itemi++) {
155
+ var item = ul.childNodes[itemi];
156
+ if (item.nodeName == "LI") {
157
+ var subLists = false;
158
+ var itemChildNodesLength = item.childNodes.length;
159
+ for (var sitemi = 0; sitemi < itemChildNodesLength; sitemi++) {
160
+ var sitem = item.childNodes[sitemi];
161
+ if (sitem.nodeName == "UL") { subLists = true; processList(sitem); }
162
+ }
163
+ var s = document.createElement("SPAN");
164
+ var t = '\u00A0';
165
+ s.className = nodeLinkClass;
166
+ if (subLists) {
167
+ if (item.className === null || item.className === "") { item.className = nodeClosedClass; }
168
+ if (item.firstChild.nodeName == "#text") { t = t + item.firstChild.nodeValue; item.removeChild(item.firstChild); }
169
+ s.onclick = treeNodeOnclick;
170
+ } else { item.className = nodeBulletClass; s.onclick = retFalse; }
171
+ s.appendChild(document.createTextNode(t));
172
+ item.insertBefore(s, item.firstChild);
173
+ }
174
+ }
175
+ }
176
+ // Performs 3 functions:
177
+ // a) Expand all nodes
178
+ // b) Collapse all nodes
179
+ // c) Expand all nodes to reach a certain ID
180
+ function expandCollapseList(ul, nodeOpenClass, itemId) {
181
+ if (!ul.childNodes || ul.childNodes.length === 0) { return false; }
182
+ for (var itemi = 0; itemi < ul.childNodes.length; itemi++) {
183
+ var item = ul.childNodes[itemi];
184
+ if (itemId !== null && item.id == itemId) { return itemId; }
185
+ if (item.nodeName == "LI") {
186
+ var subLists = false;
187
+ for (var sitemi = 0; sitemi < item.childNodes.length; sitemi++) {
188
+ var sitem = item.childNodes[sitemi];
189
+ if (sitem.nodeName == "UL") {
190
+ subLists = true;
191
+ var ret = expandCollapseList(sitem, nodeOpenClass, itemId);
192
+ if (itemId !== null && ret) { item.className = nodeOpenClass; return itemId; }
193
+ }
194
+ }
195
+ if (subLists && itemId === null) { item.className = nodeOpenClass; }
196
+ }
197
+ }
198
+ }
199
+ // Full expands a tree with a given ID
200
+ function expandTree(treeId) {
201
+ var ul = document.getElementById(treeId);
202
+ if (ul === null) { return false; }
203
+ expandCollapseList(ul, nodeOpenClass);
204
+ }
205
+
206
+ // Fully collapses a tree with a given ID
207
+ function collapseTree(treeId) {
208
+ var ul = document.getElementById(treeId);
209
+ if (ul === null) { return false; }
210
+ expandCollapseList(ul, nodeClosedClass);
211
+ }
212
+
213
+ // Expands enough nodes to expose an LI with a given ID
214
+ function expandToItem(treeId, itemId) {
215
+ var ul = document.getElementById(treeId);
216
+ if (ul === null) { return false; }
217
+ var ret = expandCollapseList(ul, nodeOpenClass, itemId);
218
+ if (ret) {
219
+ var o = document.getElementById(itemId);
220
+ if (o.scrollIntoView) {
221
+ o.scrollIntoView(false);
222
+ }
223
+ }
224
+ }
225
+ return {
226
+ processList: processList,
227
+ expandCollapseList: expandCollapseList,
228
+ expandTree: expandTree,
229
+ collapseTree: collapseTree,
230
+ expandToItem: expandToItem
231
+ };
232
+ } ()
233
+ };
234
+ } ();
235
+ if ( typeof $$ == "undefined" ) var $$ = BCJT.util.$$;
236
+ var addE = BCJT.util.addEvent;
237
+
238
+ var BCJTE = function(){
239
+ if (!BCJT){
240
+ throw new Error("BCJTE needs the BCJT object!");
241
+ }
242
+ var tp = BCJT.tree._tree;
243
+ tp.prototype.deleteNode = function(){
244
+ if (this.cp !== null){
245
+ var del = this.cp.substring(this.cp.lastIndexOf("[")+2,this.cp.lastIndexOf("]")-1);
246
+ var pp = this.cp.substring(0, this.cp.lastIndexOf("["));
247
+ var parent = eval(BCJTEP.escapeslashes(pp));
248
+ var no = {};
249
+ for(var i in parent){if (i !== del){no[i] = parent[i];}}
250
+ eval(pp +"="+ JSON.stringify(no));
251
+ var pn = this.cli.parentNode.parentNode.id;
252
+ this.cli.parentNode.removeChild(this.cli);
253
+ this.reloadTree();
254
+
255
+ //clear boxes
256
+ if (this.mktree){
257
+ this.ca = null;
258
+ this.cp = null;
259
+ this.cli = null;
260
+
261
+ //clear boxes
262
+ $$("jsonname").value = "";
263
+ $$("jsonvalue").value = "";
264
+ $$("jsonpath").innerHTML = "";
265
+ $$("jsontypes").selectedIndex= 0;
266
+ $$("jsonnameinput").style.display = "none";
267
+ $$("addbutton").style.display = "none";
268
+ $$("savebutton").style.display = "inline";
269
+ $$("savedstatus").style.display = "none";
270
+ $$("deletedstatus").style.display = "block";
271
+ }
272
+
273
+ /* expanding fails because the tree is being reindexed during reload... the old id probably doens't exist anymore */
274
+ BCJT.mktree.expandToItem("tree"+this.index, pn);
275
+ //alert(this.index +"\n"+ pn);
276
+
277
+ }
278
+ };
279
+ tp.prototype.addNode = function(nn, nv, t){
280
+ if (this.cp !== null){
281
+ var obj = eval(BCJTEP.escapeslashes(this.cp));
282
+ var objJSON = JSON.stringify(obj);
283
+ var objType = this.strIsTypeOf(this.isTypeOf(obj));
284
+ var cid = this.cli ? this.cli.id : null;
285
+ var nObj = null;
286
+ try {
287
+ $$("jsonmode").innerHTML = "Mode: " + ($$("autodetect").checked ? "Automatic" : "Standard");
288
+ $$("jsonname").readonly=null;
289
+
290
+ //what type are we creating?
291
+ if (t === undefined){ t = this.strIsTypeOf(this.isTypeOf(nv));}
292
+ switch(t){
293
+ case 'string': nObj = nv; break;
294
+ case 'object': case 'boolean': case 'function': case 'number': nObj = JSON.parse(nv); break;
295
+ case 'array': nObj = JSON.parse(""+Array(nv)); break;
296
+ default: nObj = null; break;
297
+ }
298
+ //what is the current type?
299
+ switch (objType) {
300
+ case 'object':
301
+ obj[nn] = nObj;
302
+ break;
303
+ case 'array':
304
+ obj.push(nObj);
305
+ break;
306
+ default: throw "Unable to add a child to type: " + objType;
307
+ }
308
+ } catch (e) {
309
+ $$("log").innerHTML = e;
310
+ $$("console").style.display = "block";
311
+ }
312
+ this.reloadTree();
313
+ if (this.mktree){
314
+ var liid = BCJT.mktree.expandCollapseList(document.getElementById("tree"+this.index), this.cli.id);
315
+ this.ca = null;
316
+ this.cp = null;
317
+ this.cli = null;
318
+
319
+ //clear boxes
320
+ $$("jsonname").value = "";
321
+ $$("jsonvalue").value = "";
322
+ $$("jsontypes").selectedIndex= 0;
323
+ $$("jsonpath").innerHTML = "";
324
+ $$("jsonmode").innerHTML = "";
325
+ $$("jsonnameinput").style.display = "none";
326
+ $$("addbutton").style.display = "none";
327
+ $$("savebutton").style.display = "inline";
328
+ $$("savedstatus").style.display = "block";
329
+ $$("deletedstatus").style.display = "none";
330
+ }
331
+
332
+ /* expanding fails because the tree is being reindexed during reload... the old id probably doens't exist anymore */
333
+ BCJT.mktree.expandToItem("tree"+this.index, cid);
334
+
335
+ }
336
+ };
337
+ tp.prototype.save = function(nv,t){
338
+ if (this.cp !== null){
339
+ var obj = eval(BCJTEP.escapeslashes(this.cp));
340
+ var pp = this.cp.substring(0, this.cp.lastIndexOf("["));
341
+ var parent = eval(BCJTEP.escapeslashes(pp));
342
+ var pt = this.strIsTypeOf(this.isTypeOf(parent));
343
+ var nn = "";
344
+ if (pt == 'array') {
345
+ nn = this.cp.substring(this.cp.lastIndexOf("[")+1,this.cp.lastIndexOf("]"));
346
+
347
+ } else {
348
+ nn = this.cp.substring(this.cp.lastIndexOf("[")+2,this.cp.lastIndexOf("]")-1);
349
+ }
350
+ var nObj = null;
351
+ if (t === undefined){ t = this.strIsTypeOf(this.isTypeOf(nv));}
352
+ try{
353
+ switch(t){
354
+ case 'string':
355
+ nObj = nv;
356
+ break;
357
+ case 'object': case 'boolean': case 'function': case 'number':
358
+ nObj = JSON.parse(nv);
359
+ break;
360
+ case 'array':
361
+ nObj = JSON.parse(nv);
362
+ break;
363
+ case 'null':
364
+ nObj = null;
365
+ break;
366
+ default: return t;
367
+ }
368
+ parent[nn] = nObj;
369
+
370
+ if (t == "object" || t == "array"){
371
+ if (window.confirm("New value's have been saved.\nDo you want to rebuild the tree?")){
372
+ this.reloadTree();
373
+ if (this.mktree){
374
+ var liid = BCJT.mktree.expandCollapseList(document.getElementById("tree"+this.index), this.cli.id);
375
+ this.ca = null;
376
+ this.cp = null;
377
+ this.cli = null;
378
+ }
379
+ //clear boxes
380
+ $$("jsonname").value = "";
381
+ $$("jsonvalue").value = "";
382
+ $$("jsontypes").selectedIndex= 0;
383
+ $$("jsonpath").innerHTML = "";
384
+ $$("jsonnameinput").style.display = "none";
385
+ $$("addbutton").style.display = "none";
386
+ $$("savebutton").style.display = "inline";
387
+ }
388
+ }
389
+ $$("savedstatus").style.display = "block";
390
+ }catch(e){
391
+ $$("log").innerHTML = "There's an error in your value!<br />" + e;
392
+ $$("console").style.display = "block";
393
+ }
394
+ }
395
+ };
396
+
397
+ function searchJson(tree, keyword){
398
+ var results = [];
399
+ var li = 0;
400
+ function searchKeyword(input,word){if (input===null){return -1;}return input.toString().search(new RegExp(word,"gi"));}
401
+ function searchTree(content,index,dots,inside,keyword){
402
+ if (tree.isTypeOf(content) == Array){
403
+ for (var i=0; i<content.length; i++){
404
+ dots+="["+i+"]";
405
+ searchTree(content[i], i, dots, false,keyword);
406
+ li++;
407
+ dots=dots.substr(0, dots.length - (""+i).length-2);
408
+ }
409
+ }else if(tree.isTypeOf(content) == Object){
410
+ for(var i in content){
411
+ dots+="['"+i+"']";
412
+ searchTree(content[i], -1, dots,true,keyword);
413
+ li++;
414
+ if (searchKeyword(i,keyword) > -1 && tree.isTypeOf(i)!==Object){makeList(dots, i, li, "label");}
415
+ if (searchKeyword(content[i],keyword) > -1 && tree.isTypeOf(content[i])!==Object){makeList(dots, i, li, "value");}
416
+ dots=dots.substr(0, dots.length - i.length - 4);
417
+ }
418
+ }
419
+ }
420
+ function makeList(dots, where, id, val){results.push({"a":"a"+id,"li":"li"+id,"path":escape(dots),"value":where,"where":val});}
421
+ return function(){
422
+ li =0;
423
+ results.length = 0;
424
+ searchTree(tree.json, -1, "json", false, keyword);
425
+ return results;
426
+ }();
427
+ }
428
+ tp.prototype.search = function(keyword){
429
+ return searchJson(this, keyword);
430
+ };
431
+ return{
432
+ addOptions: function(object, oValue, oText){object.options[object.length] = new Option(oText, oValue, false, false);},
433
+ objectTypes: ['array','object','function','string','number','boolean','null','undeterimable type'],
434
+ info: {"version": "1.2", "www": "http://braincast.nl", "date": "april 2008", "description": "Editor extension object for the Braincast Json Tree object."}
435
+ };
436
+ }();
437
+
438
+
439
+ var BCJTEP = function(){
440
+ if (!BCJT && !BCJTE){
441
+ throw new Error("BCJTEP needs the BCJT object and the BCJTE object!");
442
+ }
443
+ function selectType(object, type){
444
+ var l = object.options.length;
445
+ for (var i=0;i<l;i++){
446
+ if (object.options[i].text == type){
447
+ object.selectedIndex= i;
448
+ break;
449
+ }
450
+ }
451
+ }
452
+ function escapeslashes(str){
453
+ str = str.replace(/\\\\/g, '\\\\\\\\');
454
+ return str;
455
+ }
456
+ function stripslashes(str){
457
+ str = str.replace(/\\'/g, '\'');
458
+ str = str.replace(/\\"/g, '"');
459
+ str = str.replace(/\\\\/g, '\\');
460
+ //str = str.replace(/\\0/g, '\0');
461
+ str = str.replace(/\\0/g, '0');
462
+ return str;
463
+ }
464
+ function determineUserType(a){
465
+ try{var y = eval(a);
466
+ }catch(e){
467
+ try{y = eval('('+a+')');
468
+ }catch(f){return 'string';}
469
+ }
470
+ var x = typeof y;
471
+ if (x == 'object'){
472
+ try{
473
+ x = y.constructor;
474
+ if (x === Array){return 'array';}
475
+ else if (x === Object){return 'object';}
476
+ }catch(g){return 'null';}
477
+ }else if (x == 'undefined'){return 'object';}
478
+ else{return x;}
479
+ }
480
+ return{
481
+ save: function(jsonPath){
482
+ if (jsonPath) {
483
+ var jsval = eval("BCJT.tree.forest[0]." + BCJTEP.escapeslashes(jsonPath));
484
+ return JSON.stringify(jsval);
485
+ } else {
486
+ return JSON.stringify(BCJT.tree.forest[0].json);
487
+ }
488
+ },
489
+ build: function(){
490
+ var jsonstr = $$("jsonstr").value;
491
+ if (jsonstr == "") return false;
492
+ var r = BCJT.tree.init(jsonstr, "div1", {"rootNode": "json", "index": 0,"newtree":false, "nodeclick": function(p){
493
+ //make sure the add dialogs are not shown
494
+ $$("jsonname").value = "";
495
+ $$("jsonvalue").value = "";
496
+ $$("jsonpath").innerHTML = "";
497
+ $$("jsonmode").innerHTML = "";
498
+ $$("jsontypes").selectedIndex= 0;
499
+ $$("jsonnameinput").style.display = "none";
500
+ $$("addbutton").style.display = "none";
501
+ $$("savebutton").style.display = "inline";
502
+ $$("savedstatus").style.display = "none";
503
+ $$("deletedstatus").style.display = "none";
504
+
505
+ if ("json" == unescape(p.jsonPath)){
506
+ tabber1.show(3);
507
+ $$("jsonstr").value = p.jsonValue;
508
+ }else{
509
+ if ($$("tab2").style.display != "block"){tabber1.show(2);}
510
+ /*
511
+ alert("type: " + p.jsonType + "\n" +
512
+ "value: " + p.jsonValue + "\n" +
513
+ "path: " + p.jsonPath + "\n" +
514
+ "li: " + p.li
515
+ );*/
516
+ var jsonmode = "Standard";
517
+ if (p.jsonType == 'object' || p.jsonType == 'array') {
518
+ $$("jsonvalue").value = p.jsonValue;
519
+ jsonmode = "<b>NATIVE JSON</b>";
520
+ } else {
521
+ $$("jsonvalue").value = BCJTEP.stripslashes(p.jsonValue);
522
+ }
523
+ $$("jsonpath").innerHTML = "Path: " + unescape(p.jsonPath);
524
+ $$("jsonmode").innerHTML = "Mode: " + jsonmode;
525
+ selectType($$("jsontypes"),p.jsonType);
526
+ }
527
+ }});
528
+ if (r){return r;
529
+ }else{
530
+ $$("log").innerHTML = BCJT.tree.error;
531
+ $$("console").style.display = "block";
532
+ return false;
533
+ }
534
+ },
535
+ escapeslashes: escapeslashes,
536
+ stripslashes: stripslashes,
537
+ uType: determineUserType,
538
+ selectType: selectType,
539
+ writeResults: function(){
540
+ var results = BCJT.tree.forest[0].search($$("keyword").value);
541
+ var res = $$("results");
542
+ res.innerHTML = "";
543
+ var strtable = "<table width=\"100%\"><tbody>";
544
+ for (var i=0; i< results.length; i++){
545
+ strtable += "<tr><td width=\"15\"><img src=\"/images/jsonedit/" + results[i].where + ".gif\" title=\"Result found in the "+results[i].where+"\" border=\"0\" /></td>";
546
+ strtable += "<td><a href=\"#\" onclick=\"BCJT.mktree.expandToItem('tree0', '"+results[i].li+"');BCJT.tree.forest[0].getNodeValue('"+results[i].path+"', '"+results[i].a+"');tabber1.show(2);return false\">" + results[i].value + "</td>";
547
+ strtable += "<td class=\"path\">" + unescape(results[i].path) + "</td></tr>";
548
+ }
549
+ strtable += "</tbody></table>";
550
+ res.innerHTML = strtable;
551
+ },
552
+ info: {"version": "1.3", "www": "http://braincast.nl", "date": "april 2008", "description": "Braincast Json Tree Presentation object."}
553
+ };
554
+ }();
555
+
556
+ BCJTEP.prototype = function(){
557
+ BCJT.util.addLoadEvent(function(){
558
+ tabber1 = new Yetii({id: 'tab-container-1'});
559
+ tabber2 = new Yetii({id: 'tab-container-2',tabclass: 'tabn'});
560
+ addE($$("buildbutton"), "click", function(){
561
+ if (BCJTEP.build()){
562
+ $$("results").innerHTML = "&nbsp;";
563
+ $$("sourcetab").className = "show";
564
+ $$("editortab").className = "show";
565
+ $$("searchtab").className = "show";
566
+ }
567
+ })
568
+
569
+ var jsontypes = $$("jsontypes");
570
+ var j = BCJTE.objectTypes.length;
571
+ for (var i = 0; i<j; i++){BCJTE.addOptions(jsontypes, i ,BCJTE.objectTypes[i]);}
572
+
573
+ addE($$("savebutton"), "click", function(){
574
+ if ($$("autodetect").checked){
575
+ BCJTEP.selectType( $$("jsontypes"), BCJTEP.uType($$("jsonvalue").value) );
576
+ }
577
+ var obj = BCJT.tree.forest[0];
578
+ var listtype = $$("jsontypes").options[$$("jsontypes").selectedIndex].text;
579
+ obj.save($$("jsonvalue").value,listtype);
580
+ });
581
+
582
+ addE($$("addbutton"), "click", function(){
583
+ if ($$("autodetect").checked){
584
+ BCJTEP.selectType( $$("jsontypes"), BCJTEP.uType($$("jsonvalue").value) );
585
+ }
586
+
587
+ var obj = BCJT.tree.forest[0];
588
+ var listtype = $$("jsontypes").options[$$("jsontypes").selectedIndex].text;
589
+
590
+ obj.addNode($$("jsonname").value,$$("jsonvalue").value,listtype);
591
+ });
592
+ /*
593
+ addE($("jsonvalue"), "keydown", function(e){
594
+ if (e.keyCode == 83 && e.ctrlKey){
595
+ e.preventDefault();
596
+ alert("Save");
597
+ }
598
+ });*/
599
+
600
+ addE($$("refresh"), "mousedown", function(){
601
+ $$("refresh").className = "button buttondown";
602
+ $$("refresh").style.backgroundPosition = "right bottom";
603
+ if (BCJT.tree.forest[0]) BCJT.tree.forest[0].getNodeValue('json', 'a0');
604
+ });
605
+ addE($$("refresh"), "mouseup", function(){
606
+ $$("refresh").className = "button";
607
+ $$("refresh").style.backgroundPosition = "center center";
608
+ });
609
+
610
+
611
+ addE($$("add"), "mousedown", function(){
612
+ $$("add").className = "button buttondown";
613
+ $$("add").style.backgroundPosition = "right bottom";
614
+ $$("savebutton").style.display = "none";
615
+ $$("addbutton").style.display = "inline";
616
+ $$("jsonnameinput").style.display = "inline";
617
+ $$("jsonvalue").value = "";
618
+ $$("jsontypes").selectedIndex = 0;
619
+
620
+ var objTree = BCJT.tree.forest[0];
621
+ var obj = eval(BCJTEP.escapeslashes(objTree.cp));
622
+ var objType = objTree.strIsTypeOf(objTree.isTypeOf(obj));
623
+
624
+ var jsonmode = "Automatic";
625
+ $$("autodetect").checked = true;
626
+ $$("jsonmode").innerHTML = "Mode: " + jsonmode;
627
+
628
+ if (objType == "array") {
629
+ $$("jsonname").value = "Array Index";
630
+ $$("jsonname").disabled = true;
631
+ } else {
632
+ $$("jsonname").value = "";
633
+ $$("jsonname").disabled = false;
634
+ }
635
+
636
+ });
637
+ addE($$("add"), "mouseup", function(){
638
+ $$("add").className = "button";
639
+ $$("add").style.backgroundPosition = "center center";
640
+ });
641
+
642
+ addE($$("jsontypes"), "change", function(){
643
+ var listtype = $$("jsontypes").options[$$("jsontypes").selectedIndex].text;
644
+ var jsonmode = $$("autodetect").checked ? "Automatic" : "Standard";
645
+ if (listtype == "object" || listtype == "array") {
646
+ jsonmode = "<b>NATIVE JSON</b>";
647
+ }
648
+ $$("jsonmode").innerHTML = "Mode: " + jsonmode;
649
+
650
+ });
651
+
652
+ addE($$("delete"), "mousedown", function(){
653
+ $$("delete").className = "button buttondown";
654
+ $$("delete").style.backgroundPosition = "right bottom";
655
+ if (confirm("Are you sure you want to delete this attribute?")) BCJT.tree.forest[0].deleteNode();
656
+ });
657
+ addE($$("delete"), "mouseup", function(){
658
+ $$("delete").className = "button";
659
+ $$("delete").style.backgroundPosition = "center center";
660
+ });
661
+
662
+ addE($$("search"), "click", function(){
663
+ BCJTEP.writeResults();
664
+ });
665
+ addE($$("keyword"), "keydown", function(e){
666
+ if (e.keyCode == 13){
667
+ BCJTEP.writeResults();
668
+ }
669
+ });
670
+ addE($$("consolebar"), "click", function(){
671
+ $$("console").style.display = "none";
672
+ return false;
673
+ });
674
+ });
675
+ }();