statixite 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (462) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +145 -0
  4. data/Rakefile +26 -0
  5. data/app/assets/images/statixite/STATIXITE-logo.png +0 -0
  6. data/app/assets/images/statixite/favicon.ico +0 -0
  7. data/app/assets/images/statixite/jekyll.png +0 -0
  8. data/app/assets/images/statixite/md-editor.png +0 -0
  9. data/app/assets/images/statixite/ring-alt.gif +0 -0
  10. data/app/assets/javascripts/controllers/statixite/deployments_create.js +13 -0
  11. data/app/assets/javascripts/controllers/statixite/deployments_index.js +13 -0
  12. data/app/assets/javascripts/controllers/statixite/sites_create.js +27 -0
  13. data/app/assets/javascripts/controllers/statixite/sites_new.js +27 -0
  14. data/app/assets/javascripts/controllers/statixite/templates_edit.js +208 -0
  15. data/app/assets/javascripts/statixite/application.js +8 -0
  16. data/app/assets/javascripts/statixite/array-helpers.js +13 -0
  17. data/app/assets/javascripts/statixite/editor.js +244 -0
  18. data/app/assets/javascripts/statixite/loader.js +14 -0
  19. data/app/assets/javascripts/statixite/notify-defaults.js +5 -0
  20. data/app/assets/stylesheets/statixite/application.less +271 -0
  21. data/app/assets/stylesheets/statixite/bootstrap-glyphicons.less +305 -0
  22. data/app/assets/stylesheets/statixite/bootstrap.less +58 -0
  23. data/app/assets/stylesheets/statixite/bootstrap_and_overrides.less +2 -0
  24. data/app/assets/stylesheets/statixite/landing-page.less +156 -0
  25. data/app/controllers/statixite/application_controller.rb +22 -0
  26. data/app/controllers/statixite/deployments_controller.rb +61 -0
  27. data/app/controllers/statixite/media_controller.rb +61 -0
  28. data/app/controllers/statixite/posts_controller.rb +68 -0
  29. data/app/controllers/statixite/sites_controller.rb +141 -0
  30. data/app/controllers/statixite/templates_controller.rb +233 -0
  31. data/app/helpers/statixite/application_helper.rb +63 -0
  32. data/app/models/statixite/deployment.rb +5 -0
  33. data/app/models/statixite/media.rb +7 -0
  34. data/app/models/statixite/post.rb +76 -0
  35. data/app/models/statixite/site.rb +76 -0
  36. data/app/services/statixite/deployment_service.rb +73 -0
  37. data/app/services/statixite/git_service.rb +102 -0
  38. data/app/services/statixite/site_deactivation_service.rb +52 -0
  39. data/app/services/statixite/site_operation_service.rb +251 -0
  40. data/app/uploaders/statixite/file_uploader.rb +14 -0
  41. data/app/validators/statixite/jekyll_template_validator.rb +16 -0
  42. data/app/validators/statixite/liquid_validator.rb +11 -0
  43. data/app/views/layouts/statixite/_dash_nav.html.haml +20 -0
  44. data/app/views/layouts/statixite/_flash.html.haml +13 -0
  45. data/app/views/layouts/statixite/_head.html.haml +12 -0
  46. data/app/views/layouts/statixite/_header.html.haml +30 -0
  47. data/app/views/layouts/statixite/_site_sub_items.html.haml +38 -0
  48. data/app/views/layouts/statixite/dashboard.html.haml +27 -0
  49. data/app/views/statixite/deployments/_modal.html.haml +18 -0
  50. data/app/views/statixite/deployments/index.html.haml +39 -0
  51. data/app/views/statixite/kaminari/_first_page.html.haml +2 -0
  52. data/app/views/statixite/kaminari/_gap.html.haml +2 -0
  53. data/app/views/statixite/kaminari/_last_page.html.haml +2 -0
  54. data/app/views/statixite/kaminari/_next_page.html.haml +2 -0
  55. data/app/views/statixite/kaminari/_page.html.haml +6 -0
  56. data/app/views/statixite/kaminari/_paginator.html.haml +11 -0
  57. data/app/views/statixite/kaminari/_prev_page.html.haml +2 -0
  58. data/app/views/statixite/media/_index.html.haml +13 -0
  59. data/app/views/statixite/media/_paginate.html.haml +1 -0
  60. data/app/views/statixite/media/index.html.haml +39 -0
  61. data/app/views/statixite/media/index.js.haml +2 -0
  62. data/app/views/statixite/posts/_form.html.haml +65 -0
  63. data/app/views/statixite/posts/_image_modal.html.haml +21 -0
  64. data/app/views/statixite/posts/_modals.html.haml +111 -0
  65. data/app/views/statixite/posts/_posts.html.haml +15 -0
  66. data/app/views/statixite/posts/edit.html.haml +6 -0
  67. data/app/views/statixite/posts/index.html.haml +4 -0
  68. data/app/views/statixite/posts/index.js.haml +1 -0
  69. data/app/views/statixite/posts/new.html.haml +5 -0
  70. data/app/views/statixite/sites/_sites.html.haml +27 -0
  71. data/app/views/statixite/sites/_templates.html.haml +26 -0
  72. data/app/views/statixite/sites/build_and_preview.html.haml +24 -0
  73. data/app/views/statixite/sites/index.html.haml +4 -0
  74. data/app/views/statixite/sites/index.js.haml +1 -0
  75. data/app/views/statixite/sites/new.html.haml +45 -0
  76. data/app/views/statixite/sites/settings.html.haml +77 -0
  77. data/app/views/statixite/templates/edit.html.haml +93 -0
  78. data/app/views/statixite/templates/upload_files.js.haml +2 -0
  79. data/config/routes.rb +24 -0
  80. data/db/migrate/20150525171543_create_statixite_sites.rb +15 -0
  81. data/db/migrate/20150530041055_create_statixite_posts.rb +14 -0
  82. data/db/migrate/20150610024047_create_statixite_deployments.rb +11 -0
  83. data/db/migrate/20151013131224_create_statixite_media.rb +10 -0
  84. data/lib/assets/templates.yaml +734 -0
  85. data/lib/generators/statixite/statixite_generator.rb +49 -0
  86. data/lib/statixite.rb +14 -0
  87. data/lib/statixite/cloud_sync.rb +104 -0
  88. data/lib/statixite/engine.rb +49 -0
  89. data/lib/statixite/version.rb +3 -0
  90. data/lib/tasks/statixite_tasks.rake +4 -0
  91. data/vendor/assets/bower_components/bootstrap/CHANGELOG.md +5 -0
  92. data/vendor/assets/bower_components/bootstrap/Gruntfile.js +533 -0
  93. data/vendor/assets/bower_components/bootstrap/LICENSE +21 -0
  94. data/vendor/assets/bower_components/bootstrap/README.md +139 -0
  95. data/vendor/assets/bower_components/bootstrap/bower.json +34 -0
  96. data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap-theme.css +587 -0
  97. data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap-theme.css.map +1 -0
  98. data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap-theme.min.css +6 -0
  99. data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap-theme.min.css.map +1 -0
  100. data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap.css +6760 -0
  101. data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap.css.map +1 -0
  102. data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap.min.css +6 -0
  103. data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap.min.css.map +1 -0
  104. data/vendor/assets/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.eot +0 -0
  105. data/vendor/assets/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.svg +288 -0
  106. data/vendor/assets/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf +0 -0
  107. data/vendor/assets/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff +0 -0
  108. data/vendor/assets/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 +0 -0
  109. data/vendor/assets/bower_components/bootstrap/dist/js/bootstrap.js +2363 -0
  110. data/vendor/assets/bower_components/bootstrap/dist/js/bootstrap.min.js +7 -0
  111. data/vendor/assets/bower_components/bootstrap/dist/js/npm.js +13 -0
  112. data/vendor/assets/bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot +0 -0
  113. data/vendor/assets/bower_components/bootstrap/fonts/glyphicons-halflings-regular.svg +288 -0
  114. data/vendor/assets/bower_components/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
  115. data/vendor/assets/bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff +0 -0
  116. data/vendor/assets/bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff2 +0 -0
  117. data/vendor/assets/bower_components/bootstrap/grunt/bs-commonjs-generator.js +30 -0
  118. data/vendor/assets/bower_components/bootstrap/grunt/bs-glyphicons-data-generator.js +42 -0
  119. data/vendor/assets/bower_components/bootstrap/grunt/bs-lessdoc-parser.js +237 -0
  120. data/vendor/assets/bower_components/bootstrap/grunt/bs-raw-files-generator.js +44 -0
  121. data/vendor/assets/bower_components/bootstrap/grunt/configBridge.json +46 -0
  122. data/vendor/assets/bower_components/bootstrap/grunt/sauce_browsers.yml +82 -0
  123. data/vendor/assets/bower_components/bootstrap/js/affix.js +162 -0
  124. data/vendor/assets/bower_components/bootstrap/js/alert.js +94 -0
  125. data/vendor/assets/bower_components/bootstrap/js/button.js +120 -0
  126. data/vendor/assets/bower_components/bootstrap/js/carousel.js +237 -0
  127. data/vendor/assets/bower_components/bootstrap/js/collapse.js +211 -0
  128. data/vendor/assets/bower_components/bootstrap/js/dropdown.js +165 -0
  129. data/vendor/assets/bower_components/bootstrap/js/modal.js +337 -0
  130. data/vendor/assets/bower_components/bootstrap/js/popover.js +108 -0
  131. data/vendor/assets/bower_components/bootstrap/js/scrollspy.js +172 -0
  132. data/vendor/assets/bower_components/bootstrap/js/tab.js +155 -0
  133. data/vendor/assets/bower_components/bootstrap/js/tooltip.js +514 -0
  134. data/vendor/assets/bower_components/bootstrap/js/transition.js +59 -0
  135. data/vendor/assets/bower_components/bootstrap/less/alerts.less +73 -0
  136. data/vendor/assets/bower_components/bootstrap/less/badges.less +66 -0
  137. data/vendor/assets/bower_components/bootstrap/less/bootstrap.less +56 -0
  138. data/vendor/assets/bower_components/bootstrap/less/breadcrumbs.less +26 -0
  139. data/vendor/assets/bower_components/bootstrap/less/button-groups.less +244 -0
  140. data/vendor/assets/bower_components/bootstrap/less/buttons.less +166 -0
  141. data/vendor/assets/bower_components/bootstrap/less/carousel.less +270 -0
  142. data/vendor/assets/bower_components/bootstrap/less/close.less +34 -0
  143. data/vendor/assets/bower_components/bootstrap/less/code.less +69 -0
  144. data/vendor/assets/bower_components/bootstrap/less/component-animations.less +33 -0
  145. data/vendor/assets/bower_components/bootstrap/less/dropdowns.less +216 -0
  146. data/vendor/assets/bower_components/bootstrap/less/forms.less +613 -0
  147. data/vendor/assets/bower_components/bootstrap/less/glyphicons.less +305 -0
  148. data/vendor/assets/bower_components/bootstrap/less/grid.less +84 -0
  149. data/vendor/assets/bower_components/bootstrap/less/input-groups.less +171 -0
  150. data/vendor/assets/bower_components/bootstrap/less/jumbotron.less +54 -0
  151. data/vendor/assets/bower_components/bootstrap/less/labels.less +64 -0
  152. data/vendor/assets/bower_components/bootstrap/less/list-group.less +130 -0
  153. data/vendor/assets/bower_components/bootstrap/less/media.less +66 -0
  154. data/vendor/assets/bower_components/bootstrap/less/mixins.less +40 -0
  155. data/vendor/assets/bower_components/bootstrap/less/mixins/alerts.less +14 -0
  156. data/vendor/assets/bower_components/bootstrap/less/mixins/background-variant.less +9 -0
  157. data/vendor/assets/bower_components/bootstrap/less/mixins/border-radius.less +18 -0
  158. data/vendor/assets/bower_components/bootstrap/less/mixins/buttons.less +65 -0
  159. data/vendor/assets/bower_components/bootstrap/less/mixins/center-block.less +7 -0
  160. data/vendor/assets/bower_components/bootstrap/less/mixins/clearfix.less +22 -0
  161. data/vendor/assets/bower_components/bootstrap/less/mixins/forms.less +85 -0
  162. data/vendor/assets/bower_components/bootstrap/less/mixins/gradients.less +59 -0
  163. data/vendor/assets/bower_components/bootstrap/less/mixins/grid-framework.less +91 -0
  164. data/vendor/assets/bower_components/bootstrap/less/mixins/grid.less +122 -0
  165. data/vendor/assets/bower_components/bootstrap/less/mixins/hide-text.less +21 -0
  166. data/vendor/assets/bower_components/bootstrap/less/mixins/image.less +33 -0
  167. data/vendor/assets/bower_components/bootstrap/less/mixins/labels.less +12 -0
  168. data/vendor/assets/bower_components/bootstrap/less/mixins/list-group.less +30 -0
  169. data/vendor/assets/bower_components/bootstrap/less/mixins/nav-divider.less +10 -0
  170. data/vendor/assets/bower_components/bootstrap/less/mixins/nav-vertical-align.less +9 -0
  171. data/vendor/assets/bower_components/bootstrap/less/mixins/opacity.less +8 -0
  172. data/vendor/assets/bower_components/bootstrap/less/mixins/pagination.less +24 -0
  173. data/vendor/assets/bower_components/bootstrap/less/mixins/panels.less +24 -0
  174. data/vendor/assets/bower_components/bootstrap/less/mixins/progress-bar.less +10 -0
  175. data/vendor/assets/bower_components/bootstrap/less/mixins/reset-filter.less +8 -0
  176. data/vendor/assets/bower_components/bootstrap/less/mixins/reset-text.less +18 -0
  177. data/vendor/assets/bower_components/bootstrap/less/mixins/resize.less +6 -0
  178. data/vendor/assets/bower_components/bootstrap/less/mixins/responsive-visibility.less +15 -0
  179. data/vendor/assets/bower_components/bootstrap/less/mixins/size.less +10 -0
  180. data/vendor/assets/bower_components/bootstrap/less/mixins/tab-focus.less +9 -0
  181. data/vendor/assets/bower_components/bootstrap/less/mixins/table-row.less +28 -0
  182. data/vendor/assets/bower_components/bootstrap/less/mixins/text-emphasis.less +9 -0
  183. data/vendor/assets/bower_components/bootstrap/less/mixins/text-overflow.less +8 -0
  184. data/vendor/assets/bower_components/bootstrap/less/mixins/vendor-prefixes.less +227 -0
  185. data/vendor/assets/bower_components/bootstrap/less/modals.less +150 -0
  186. data/vendor/assets/bower_components/bootstrap/less/navbar.less +660 -0
  187. data/vendor/assets/bower_components/bootstrap/less/navs.less +242 -0
  188. data/vendor/assets/bower_components/bootstrap/less/normalize.less +424 -0
  189. data/vendor/assets/bower_components/bootstrap/less/pager.less +54 -0
  190. data/vendor/assets/bower_components/bootstrap/less/pagination.less +89 -0
  191. data/vendor/assets/bower_components/bootstrap/less/panels.less +271 -0
  192. data/vendor/assets/bower_components/bootstrap/less/popovers.less +131 -0
  193. data/vendor/assets/bower_components/bootstrap/less/print.less +101 -0
  194. data/vendor/assets/bower_components/bootstrap/less/progress-bars.less +87 -0
  195. data/vendor/assets/bower_components/bootstrap/less/responsive-embed.less +35 -0
  196. data/vendor/assets/bower_components/bootstrap/less/responsive-utilities.less +194 -0
  197. data/vendor/assets/bower_components/bootstrap/less/scaffolding.less +161 -0
  198. data/vendor/assets/bower_components/bootstrap/less/tables.less +234 -0
  199. data/vendor/assets/bower_components/bootstrap/less/theme.less +291 -0
  200. data/vendor/assets/bower_components/bootstrap/less/thumbnails.less +36 -0
  201. data/vendor/assets/bower_components/bootstrap/less/tooltip.less +101 -0
  202. data/vendor/assets/bower_components/bootstrap/less/type.less +302 -0
  203. data/vendor/assets/bower_components/bootstrap/less/utilities.less +55 -0
  204. data/vendor/assets/bower_components/bootstrap/less/variables.less +869 -0
  205. data/vendor/assets/bower_components/bootstrap/less/wells.less +29 -0
  206. data/vendor/assets/bower_components/bootstrap/nuget/MyGet.ps1 +8 -0
  207. data/vendor/assets/bower_components/bootstrap/nuget/bootstrap.less.nuspec +28 -0
  208. data/vendor/assets/bower_components/bootstrap/nuget/bootstrap.nuspec +28 -0
  209. data/vendor/assets/bower_components/bootstrap/package.js +32 -0
  210. data/vendor/assets/bower_components/bootstrap/package.json +87 -0
  211. data/vendor/assets/bower_components/jquery/AUTHORS.txt +275 -0
  212. data/vendor/assets/bower_components/jquery/LICENSE.txt +36 -0
  213. data/vendor/assets/bower_components/jquery/README.md +5 -0
  214. data/vendor/assets/bower_components/jquery/bower.json +14 -0
  215. data/vendor/assets/bower_components/jquery/dist/jquery.js +9831 -0
  216. data/vendor/assets/bower_components/jquery/dist/jquery.min.js +4 -0
  217. data/vendor/assets/bower_components/jquery/dist/jquery.min.map +1 -0
  218. data/vendor/assets/bower_components/jquery/src/ajax.js +845 -0
  219. data/vendor/assets/bower_components/jquery/src/ajax/jsonp.js +100 -0
  220. data/vendor/assets/bower_components/jquery/src/ajax/load.js +83 -0
  221. data/vendor/assets/bower_components/jquery/src/ajax/parseJSON.js +13 -0
  222. data/vendor/assets/bower_components/jquery/src/ajax/parseXML.js +27 -0
  223. data/vendor/assets/bower_components/jquery/src/ajax/script.js +68 -0
  224. data/vendor/assets/bower_components/jquery/src/ajax/var/location.js +3 -0
  225. data/vendor/assets/bower_components/jquery/src/ajax/var/nonce.js +5 -0
  226. data/vendor/assets/bower_components/jquery/src/ajax/var/rquery.js +3 -0
  227. data/vendor/assets/bower_components/jquery/src/ajax/xhr.js +167 -0
  228. data/vendor/assets/bower_components/jquery/src/attributes.js +11 -0
  229. data/vendor/assets/bower_components/jquery/src/attributes/attr.js +142 -0
  230. data/vendor/assets/bower_components/jquery/src/attributes/classes.js +177 -0
  231. data/vendor/assets/bower_components/jquery/src/attributes/prop.js +109 -0
  232. data/vendor/assets/bower_components/jquery/src/attributes/support.js +36 -0
  233. data/vendor/assets/bower_components/jquery/src/attributes/val.js +170 -0
  234. data/vendor/assets/bower_components/jquery/src/callbacks.js +232 -0
  235. data/vendor/assets/bower_components/jquery/src/core.js +489 -0
  236. data/vendor/assets/bower_components/jquery/src/core/access.js +65 -0
  237. data/vendor/assets/bower_components/jquery/src/core/init.js +134 -0
  238. data/vendor/assets/bower_components/jquery/src/core/parseHTML.js +49 -0
  239. data/vendor/assets/bower_components/jquery/src/core/ready.js +103 -0
  240. data/vendor/assets/bower_components/jquery/src/core/support.js +18 -0
  241. data/vendor/assets/bower_components/jquery/src/core/var/rsingleTag.js +5 -0
  242. data/vendor/assets/bower_components/jquery/src/css.js +515 -0
  243. data/vendor/assets/bower_components/jquery/src/css/addGetHookIf.js +24 -0
  244. data/vendor/assets/bower_components/jquery/src/css/adjustCSS.js +65 -0
  245. data/vendor/assets/bower_components/jquery/src/css/curCSS.js +57 -0
  246. data/vendor/assets/bower_components/jquery/src/css/defaultDisplay.js +72 -0
  247. data/vendor/assets/bower_components/jquery/src/css/hiddenVisibleSelectors.js +18 -0
  248. data/vendor/assets/bower_components/jquery/src/css/showHide.js +48 -0
  249. data/vendor/assets/bower_components/jquery/src/css/support.js +121 -0
  250. data/vendor/assets/bower_components/jquery/src/css/var/cssExpand.js +3 -0
  251. data/vendor/assets/bower_components/jquery/src/css/var/getStyles.js +15 -0
  252. data/vendor/assets/bower_components/jquery/src/css/var/isHidden.js +16 -0
  253. data/vendor/assets/bower_components/jquery/src/css/var/rmargin.js +3 -0
  254. data/vendor/assets/bower_components/jquery/src/css/var/rnumnonpx.js +5 -0
  255. data/vendor/assets/bower_components/jquery/src/css/var/swap.js +24 -0
  256. data/vendor/assets/bower_components/jquery/src/data.js +187 -0
  257. data/vendor/assets/bower_components/jquery/src/data/Data.js +200 -0
  258. data/vendor/assets/bower_components/jquery/src/data/accepts.js +20 -0
  259. data/vendor/assets/bower_components/jquery/src/data/support.js +23 -0
  260. data/vendor/assets/bower_components/jquery/src/data/var/acceptData.js +18 -0
  261. data/vendor/assets/bower_components/jquery/src/data/var/dataPriv.js +5 -0
  262. data/vendor/assets/bower_components/jquery/src/data/var/dataUser.js +5 -0
  263. data/vendor/assets/bower_components/jquery/src/deferred.js +158 -0
  264. data/vendor/assets/bower_components/jquery/src/deprecated.js +32 -0
  265. data/vendor/assets/bower_components/jquery/src/dimensions.js +54 -0
  266. data/vendor/assets/bower_components/jquery/src/effects.js +629 -0
  267. data/vendor/assets/bower_components/jquery/src/effects/Tween.js +121 -0
  268. data/vendor/assets/bower_components/jquery/src/effects/animatedSelector.js +13 -0
  269. data/vendor/assets/bower_components/jquery/src/effects/support.js +58 -0
  270. data/vendor/assets/bower_components/jquery/src/event.js +710 -0
  271. data/vendor/assets/bower_components/jquery/src/event/ajax.js +20 -0
  272. data/vendor/assets/bower_components/jquery/src/event/alias.js +27 -0
  273. data/vendor/assets/bower_components/jquery/src/event/focusin.js +53 -0
  274. data/vendor/assets/bower_components/jquery/src/event/support.js +9 -0
  275. data/vendor/assets/bower_components/jquery/src/event/trigger.js +199 -0
  276. data/vendor/assets/bower_components/jquery/src/exports/amd.js +24 -0
  277. data/vendor/assets/bower_components/jquery/src/exports/global.js +26 -0
  278. data/vendor/assets/bower_components/jquery/src/intro.js +44 -0
  279. data/vendor/assets/bower_components/jquery/src/jquery.js +37 -0
  280. data/vendor/assets/bower_components/jquery/src/manipulation.js +481 -0
  281. data/vendor/assets/bower_components/jquery/src/manipulation/_evalUrl.js +20 -0
  282. data/vendor/assets/bower_components/jquery/src/manipulation/buildFragment.js +102 -0
  283. data/vendor/assets/bower_components/jquery/src/manipulation/createSafeFragment.js +20 -0
  284. data/vendor/assets/bower_components/jquery/src/manipulation/getAll.js +21 -0
  285. data/vendor/assets/bower_components/jquery/src/manipulation/setGlobalEval.js +20 -0
  286. data/vendor/assets/bower_components/jquery/src/manipulation/support.js +33 -0
  287. data/vendor/assets/bower_components/jquery/src/manipulation/var/nodeNames.js +5 -0
  288. data/vendor/assets/bower_components/jquery/src/manipulation/var/rcheckableType.js +3 -0
  289. data/vendor/assets/bower_components/jquery/src/manipulation/var/rleadingWhitespace.js +3 -0
  290. data/vendor/assets/bower_components/jquery/src/manipulation/var/rscriptType.js +3 -0
  291. data/vendor/assets/bower_components/jquery/src/manipulation/var/rtagName.js +3 -0
  292. data/vendor/assets/bower_components/jquery/src/manipulation/wrapMap.js +27 -0
  293. data/vendor/assets/bower_components/jquery/src/offset.js +221 -0
  294. data/vendor/assets/bower_components/jquery/src/outro.js +2 -0
  295. data/vendor/assets/bower_components/jquery/src/queue.js +143 -0
  296. data/vendor/assets/bower_components/jquery/src/queue/delay.js +22 -0
  297. data/vendor/assets/bower_components/jquery/src/selector-native.js +211 -0
  298. data/vendor/assets/bower_components/jquery/src/selector-sizzle.js +14 -0
  299. data/vendor/assets/bower_components/jquery/src/selector.js +1 -0
  300. data/vendor/assets/bower_components/jquery/src/serialize.js +125 -0
  301. data/vendor/assets/bower_components/jquery/src/support.js +63 -0
  302. data/vendor/assets/bower_components/jquery/src/traversing.js +175 -0
  303. data/vendor/assets/bower_components/jquery/src/traversing/findFilter.js +100 -0
  304. data/vendor/assets/bower_components/jquery/src/traversing/var/dir.js +20 -0
  305. data/vendor/assets/bower_components/jquery/src/traversing/var/rneedsContext.js +6 -0
  306. data/vendor/assets/bower_components/jquery/src/traversing/var/siblings.js +15 -0
  307. data/vendor/assets/bower_components/jquery/src/var/arr.js +3 -0
  308. data/vendor/assets/bower_components/jquery/src/var/class2type.js +5 -0
  309. data/vendor/assets/bower_components/jquery/src/var/concat.js +5 -0
  310. data/vendor/assets/bower_components/jquery/src/var/deletedIds.js +3 -0
  311. data/vendor/assets/bower_components/jquery/src/var/document.js +3 -0
  312. data/vendor/assets/bower_components/jquery/src/var/documentElement.js +5 -0
  313. data/vendor/assets/bower_components/jquery/src/var/hasOwn.js +5 -0
  314. data/vendor/assets/bower_components/jquery/src/var/indexOf.js +5 -0
  315. data/vendor/assets/bower_components/jquery/src/var/pnum.js +3 -0
  316. data/vendor/assets/bower_components/jquery/src/var/push.js +5 -0
  317. data/vendor/assets/bower_components/jquery/src/var/rcssNum.js +7 -0
  318. data/vendor/assets/bower_components/jquery/src/var/rnotwhite.js +3 -0
  319. data/vendor/assets/bower_components/jquery/src/var/slice.js +5 -0
  320. data/vendor/assets/bower_components/jquery/src/var/support.js +5 -0
  321. data/vendor/assets/bower_components/jquery/src/var/toString.js +5 -0
  322. data/vendor/assets/bower_components/jquery/src/wrap.js +79 -0
  323. data/vendor/assets/bower_components/jsoneditor/CONTRIBUTING.md +15 -0
  324. data/vendor/assets/bower_components/jsoneditor/HISTORY.md +457 -0
  325. data/vendor/assets/bower_components/jsoneditor/LICENSE +176 -0
  326. data/vendor/assets/bower_components/jsoneditor/NOTICE +17 -0
  327. data/vendor/assets/bower_components/jsoneditor/README.md +155 -0
  328. data/vendor/assets/bower_components/jsoneditor/bower.json +32 -0
  329. data/vendor/assets/bower_components/jsoneditor/dist/img/jsoneditor-icons.svg +893 -0
  330. data/vendor/assets/bower_components/jsoneditor/dist/jsoneditor-minimalist.js +9418 -0
  331. data/vendor/assets/bower_components/jsoneditor/dist/jsoneditor-minimalist.map +1 -0
  332. data/vendor/assets/bower_components/jsoneditor/dist/jsoneditor-minimalist.min.js +35 -0
  333. data/vendor/assets/bower_components/jsoneditor/dist/jsoneditor.css.less +879 -0
  334. data/vendor/assets/bower_components/jsoneditor/dist/jsoneditor.js +35095 -0
  335. data/vendor/assets/bower_components/jsoneditor/dist/jsoneditor.map +1 -0
  336. data/vendor/assets/bower_components/jsoneditor/dist/jsoneditor.min.css +1 -0
  337. data/vendor/assets/bower_components/jsoneditor/dist/jsoneditor.min.js +48 -0
  338. data/vendor/assets/bower_components/jsoneditor/dist/which files do I need.md +41 -0
  339. data/vendor/assets/bower_components/jsoneditor/docs/api.md +286 -0
  340. data/vendor/assets/bower_components/jsoneditor/docs/shortcut_keys.md +38 -0
  341. data/vendor/assets/bower_components/jsoneditor/docs/usage.md +117 -0
  342. data/vendor/assets/bower_components/jsoneditor/examples/01_basic_usage.html +49 -0
  343. data/vendor/assets/bower_components/jsoneditor/examples/02_viewer.html +44 -0
  344. data/vendor/assets/bower_components/jsoneditor/examples/03_switch_mode.html +66 -0
  345. data/vendor/assets/bower_components/jsoneditor/examples/04_load_and_save.html +62 -0
  346. data/vendor/assets/bower_components/jsoneditor/examples/05_custom_fields_editable.html +63 -0
  347. data/vendor/assets/bower_components/jsoneditor/examples/06_custom_styling.html +51 -0
  348. data/vendor/assets/bower_components/jsoneditor/examples/07_json_schema_validation.html +71 -0
  349. data/vendor/assets/bower_components/jsoneditor/examples/css/darktheme.css +76 -0
  350. data/vendor/assets/bower_components/jsoneditor/examples/requirejs_demo/requirejs_demo.html +21 -0
  351. data/vendor/assets/bower_components/jsoneditor/examples/requirejs_demo/scripts/main.js +25 -0
  352. data/vendor/assets/bower_components/jsoneditor/examples/requirejs_demo/scripts/require.js +36 -0
  353. data/vendor/assets/bower_components/jsoneditor/index.js +1 -0
  354. data/vendor/assets/bower_components/jsoneditor/package.json +41 -0
  355. data/vendor/assets/bower_components/jsoneditor/src/css/contextmenu.css +233 -0
  356. data/vendor/assets/bower_components/jsoneditor/src/css/img/description.txt +14 -0
  357. data/vendor/assets/bower_components/jsoneditor/src/css/img/jsoneditor-icons.svg +893 -0
  358. data/vendor/assets/bower_components/jsoneditor/src/css/jsoneditor.css +433 -0
  359. data/vendor/assets/bower_components/jsoneditor/src/css/menu.css +110 -0
  360. data/vendor/assets/bower_components/jsoneditor/src/css/searchbox.css +75 -0
  361. data/vendor/assets/bower_components/jsoneditor/src/docs/which files do I need.md +41 -0
  362. data/vendor/assets/bower_components/jsoneditor/src/js/ContextMenu.js +455 -0
  363. data/vendor/assets/bower_components/jsoneditor/src/js/Highlighter.js +84 -0
  364. data/vendor/assets/bower_components/jsoneditor/src/js/History.js +252 -0
  365. data/vendor/assets/bower_components/jsoneditor/src/js/JSONEditor.js +371 -0
  366. data/vendor/assets/bower_components/jsoneditor/src/js/Node.js +3400 -0
  367. data/vendor/assets/bower_components/jsoneditor/src/js/SearchBox.js +295 -0
  368. data/vendor/assets/bower_components/jsoneditor/src/js/ace/index.js +9 -0
  369. data/vendor/assets/bower_components/jsoneditor/src/js/ace/theme-jsoneditor.js +144 -0
  370. data/vendor/assets/bower_components/jsoneditor/src/js/appendNodeFactory.js +226 -0
  371. data/vendor/assets/bower_components/jsoneditor/src/js/assets/jsonlint/README.md +15 -0
  372. data/vendor/assets/bower_components/jsoneditor/src/js/assets/jsonlint/jsonlint.js +418 -0
  373. data/vendor/assets/bower_components/jsoneditor/src/js/header.js +29 -0
  374. data/vendor/assets/bower_components/jsoneditor/src/js/modeswitcher.js +105 -0
  375. data/vendor/assets/bower_components/jsoneditor/src/js/textmode.js +474 -0
  376. data/vendor/assets/bower_components/jsoneditor/src/js/treemode.js +1150 -0
  377. data/vendor/assets/bower_components/jsoneditor/src/js/util.js +765 -0
  378. data/vendor/assets/bower_components/notifyjs/CHANGES.md +7 -0
  379. data/vendor/assets/bower_components/notifyjs/README.md +31 -0
  380. data/vendor/assets/bower_components/notifyjs/bower.json +14 -0
  381. data/vendor/assets/bower_components/notifyjs/dist/notify.js +586 -0
  382. data/vendor/assets/bower_components/notifyjs/dist/styles/metro/notify-metro.css +40 -0
  383. data/vendor/assets/bower_components/notifyjs/dist/styles/metro/notify-metro.js +39 -0
  384. data/vendor/assets/bower_components/notifyjs/examples/classes.html +49 -0
  385. data/vendor/assets/bower_components/notifyjs/examples/images/Mail.png +0 -0
  386. data/vendor/assets/bower_components/notifyjs/examples/inlines.html +111 -0
  387. data/vendor/assets/bower_components/notifyjs/examples/metro.html +37 -0
  388. data/vendor/assets/bower_components/notifyjs/examples/multi-text.html +55 -0
  389. data/vendor/assets/bower_components/notifyjs/examples/position.html +42 -0
  390. data/vendor/assets/bower_components/notifyjs/notify.jquery.json +28 -0
  391. data/vendor/assets/bower_components/notifyjs/package.json +18 -0
  392. data/vendor/assets/bower_components/vue/LICENSE +21 -0
  393. data/vendor/assets/bower_components/vue/bower.json +19 -0
  394. data/vendor/assets/bower_components/vue/dist/vue.js +10198 -0
  395. data/vendor/assets/bower_components/vue/dist/vue.min.js +8 -0
  396. data/vendor/assets/bower_components/vue/src/api/child.js +49 -0
  397. data/vendor/assets/bower_components/vue/src/api/data.js +159 -0
  398. data/vendor/assets/bower_components/vue/src/api/dom.js +226 -0
  399. data/vendor/assets/bower_components/vue/src/api/events.js +174 -0
  400. data/vendor/assets/bower_components/vue/src/api/global.js +129 -0
  401. data/vendor/assets/bower_components/vue/src/api/lifecycle.js +68 -0
  402. data/vendor/assets/bower_components/vue/src/batcher.js +98 -0
  403. data/vendor/assets/bower_components/vue/src/cache.js +112 -0
  404. data/vendor/assets/bower_components/vue/src/compiler/compile-props.js +183 -0
  405. data/vendor/assets/bower_components/vue/src/compiler/compile.js +630 -0
  406. data/vendor/assets/bower_components/vue/src/compiler/index.js +4 -0
  407. data/vendor/assets/bower_components/vue/src/compiler/transclude.js +144 -0
  408. data/vendor/assets/bower_components/vue/src/config.js +124 -0
  409. data/vendor/assets/bower_components/vue/src/directive.js +254 -0
  410. data/vendor/assets/bower_components/vue/src/directives/attr.js +59 -0
  411. data/vendor/assets/bower_components/vue/src/directives/class.js +70 -0
  412. data/vendor/assets/bower_components/vue/src/directives/cloak.js +10 -0
  413. data/vendor/assets/bower_components/vue/src/directives/component.js +344 -0
  414. data/vendor/assets/bower_components/vue/src/directives/el.js +12 -0
  415. data/vendor/assets/bower_components/vue/src/directives/html.js +40 -0
  416. data/vendor/assets/bower_components/vue/src/directives/if.js +125 -0
  417. data/vendor/assets/bower_components/vue/src/directives/index.js +24 -0
  418. data/vendor/assets/bower_components/vue/src/directives/model/checkbox.js +42 -0
  419. data/vendor/assets/bower_components/vue/src/directives/model/index.js +82 -0
  420. data/vendor/assets/bower_components/vue/src/directives/model/radio.js +33 -0
  421. data/vendor/assets/bower_components/vue/src/directives/model/select.js +236 -0
  422. data/vendor/assets/bower_components/vue/src/directives/model/text.js +132 -0
  423. data/vendor/assets/bower_components/vue/src/directives/on.js +59 -0
  424. data/vendor/assets/bower_components/vue/src/directives/prop.js +62 -0
  425. data/vendor/assets/bower_components/vue/src/directives/ref.js +22 -0
  426. data/vendor/assets/bower_components/vue/src/directives/repeat.js +770 -0
  427. data/vendor/assets/bower_components/vue/src/directives/show.js +8 -0
  428. data/vendor/assets/bower_components/vue/src/directives/style.js +110 -0
  429. data/vendor/assets/bower_components/vue/src/directives/text.js +14 -0
  430. data/vendor/assets/bower_components/vue/src/directives/transition.js +26 -0
  431. data/vendor/assets/bower_components/vue/src/element-directives/content.js +111 -0
  432. data/vendor/assets/bower_components/vue/src/element-directives/index.js +2 -0
  433. data/vendor/assets/bower_components/vue/src/element-directives/partial.js +73 -0
  434. data/vendor/assets/bower_components/vue/src/filters/array-filters.js +97 -0
  435. data/vendor/assets/bower_components/vue/src/filters/index.js +146 -0
  436. data/vendor/assets/bower_components/vue/src/instance/compile.js +200 -0
  437. data/vendor/assets/bower_components/vue/src/instance/events.js +139 -0
  438. data/vendor/assets/bower_components/vue/src/instance/init.js +89 -0
  439. data/vendor/assets/bower_components/vue/src/instance/misc.js +93 -0
  440. data/vendor/assets/bower_components/vue/src/instance/scope.js +282 -0
  441. data/vendor/assets/bower_components/vue/src/observer/array.js +98 -0
  442. data/vendor/assets/bower_components/vue/src/observer/dep.js +61 -0
  443. data/vendor/assets/bower_components/vue/src/observer/index.js +234 -0
  444. data/vendor/assets/bower_components/vue/src/observer/object.js +82 -0
  445. data/vendor/assets/bower_components/vue/src/parsers/directive.js +180 -0
  446. data/vendor/assets/bower_components/vue/src/parsers/expression.js +264 -0
  447. data/vendor/assets/bower_components/vue/src/parsers/path.js +348 -0
  448. data/vendor/assets/bower_components/vue/src/parsers/template.js +288 -0
  449. data/vendor/assets/bower_components/vue/src/parsers/text.js +178 -0
  450. data/vendor/assets/bower_components/vue/src/transition/index.js +128 -0
  451. data/vendor/assets/bower_components/vue/src/transition/queue.js +35 -0
  452. data/vendor/assets/bower_components/vue/src/transition/transition.js +357 -0
  453. data/vendor/assets/bower_components/vue/src/util/component.js +124 -0
  454. data/vendor/assets/bower_components/vue/src/util/debug.js +64 -0
  455. data/vendor/assets/bower_components/vue/src/util/dom.js +272 -0
  456. data/vendor/assets/bower_components/vue/src/util/env.js +85 -0
  457. data/vendor/assets/bower_components/vue/src/util/index.js +9 -0
  458. data/vendor/assets/bower_components/vue/src/util/lang.js +310 -0
  459. data/vendor/assets/bower_components/vue/src/util/options.js +357 -0
  460. data/vendor/assets/bower_components/vue/src/vue.js +89 -0
  461. data/vendor/assets/bower_components/vue/src/watcher.js +312 -0
  462. metadata +870 -0
@@ -0,0 +1,1150 @@
1
+ var Highlighter = require('./Highlighter');
2
+ var History = require('./History');
3
+ var SearchBox = require('./SearchBox');
4
+ var ContextMenu = require('./ContextMenu');
5
+ var Node = require('./Node');
6
+ var modeswitcher = require('./modeswitcher');
7
+ var util = require('./util');
8
+
9
+ // create a mixin with the functions for tree mode
10
+ var treemode = {};
11
+
12
+ /**
13
+ * Create a tree editor
14
+ * @param {Element} container Container element
15
+ * @param {Object} [options] Object with options. available options:
16
+ * {String} mode Editor mode. Available values:
17
+ * 'tree' (default), 'view',
18
+ * and 'form'.
19
+ * {Boolean} search Enable search box.
20
+ * True by default
21
+ * {Boolean} history Enable history (undo/redo).
22
+ * True by default
23
+ * {function} onChange Callback method, triggered
24
+ * on change of contents
25
+ * {String} name Field name for the root node.
26
+ * {boolean} escapeUnicode If true, unicode
27
+ * characters are escaped.
28
+ * false by default.
29
+ * {Object} schema A JSON Schema for validation
30
+ * @private
31
+ */
32
+ treemode.create = function (container, options) {
33
+ if (!container) {
34
+ throw new Error('No container element provided.');
35
+ }
36
+ this.container = container;
37
+ this.dom = {};
38
+ this.highlighter = new Highlighter();
39
+ this.selection = undefined; // will hold the last input selection
40
+ this.multiselection = {
41
+ nodes: []
42
+ };
43
+ this.validateSchema = null; // will be set in .setSchema(schema)
44
+ this.errorNodes = [];
45
+
46
+
47
+ this._setOptions(options);
48
+
49
+ if (this.options.history && this.options.mode !== 'view') {
50
+ this.history = new History(this);
51
+ }
52
+
53
+ this._createFrame();
54
+ this._createTable();
55
+ };
56
+
57
+ /**
58
+ * Detach the editor from the DOM
59
+ * @private
60
+ */
61
+ treemode._delete = function () {
62
+ if (this.frame && this.container && this.frame.parentNode == this.container) {
63
+ this.container.removeChild(this.frame);
64
+ }
65
+ };
66
+
67
+ /**
68
+ * Initialize and set default options
69
+ * @param {Object} [options] See description in constructor
70
+ * @private
71
+ */
72
+ treemode._setOptions = function (options) {
73
+ this.options = {
74
+ search: true,
75
+ history: true,
76
+ mode: 'tree',
77
+ name: undefined, // field name of root node
78
+ schema: null
79
+ };
80
+
81
+ // copy all options
82
+ if (options) {
83
+ for (var prop in options) {
84
+ if (options.hasOwnProperty(prop)) {
85
+ this.options[prop] = options[prop];
86
+ }
87
+ }
88
+ }
89
+
90
+ // compile a JSON schema validator if a JSON schema is provided
91
+ this.setSchema(this.options.schema);
92
+
93
+ // create a debounced validate function
94
+ this._debouncedValidate = util.debounce(this.validate.bind(this), this.DEBOUNCE_INTERVAL);
95
+ };
96
+
97
+ // node currently being edited
98
+ var focusNode = undefined;
99
+
100
+ // dom having focus
101
+ var domFocus = null;
102
+
103
+ /**
104
+ * Set JSON object in editor
105
+ * @param {Object | undefined} json JSON data
106
+ * @param {String} [name] Optional field name for the root node.
107
+ * Can also be set using setName(name).
108
+ */
109
+ treemode.set = function (json, name) {
110
+ // adjust field name for root node
111
+ if (name) {
112
+ // TODO: deprecated since version 2.2.0. Cleanup some day.
113
+ console.warn('Second parameter "name" is deprecated. Use setName(name) instead.');
114
+ this.options.name = name;
115
+ }
116
+
117
+ // verify if json is valid JSON, ignore when a function
118
+ if (json instanceof Function || (json === undefined)) {
119
+ this.clear();
120
+ }
121
+ else {
122
+ this.content.removeChild(this.table); // Take the table offline
123
+
124
+ // replace the root node
125
+ var params = {
126
+ field: this.options.name,
127
+ value: json
128
+ };
129
+ var node = new Node(this, params);
130
+ this._setRoot(node);
131
+
132
+ // validate JSON schema (if configured)
133
+ this.validate();
134
+
135
+ // expand
136
+ var recurse = false;
137
+ this.node.expand(recurse);
138
+
139
+ this.content.appendChild(this.table); // Put the table online again
140
+ }
141
+
142
+ // TODO: maintain history, store last state and previous document
143
+ if (this.history) {
144
+ this.history.clear();
145
+ }
146
+
147
+ // clear search
148
+ if (this.searchBox) {
149
+ this.searchBox.clear();
150
+ }
151
+ };
152
+
153
+ /**
154
+ * Get JSON object from editor
155
+ * @return {Object | undefined} json
156
+ */
157
+ treemode.get = function () {
158
+ // remove focus from currently edited node
159
+ if (focusNode) {
160
+ focusNode.blur();
161
+ }
162
+
163
+ if (this.node) {
164
+ return this.node.getValue();
165
+ }
166
+ else {
167
+ return undefined;
168
+ }
169
+ };
170
+
171
+ /**
172
+ * Get the text contents of the editor
173
+ * @return {String} jsonText
174
+ */
175
+ treemode.getText = function() {
176
+ return JSON.stringify(this.get());
177
+ };
178
+
179
+ /**
180
+ * Set the text contents of the editor
181
+ * @param {String} jsonText
182
+ */
183
+ treemode.setText = function(jsonText) {
184
+ this.set(util.parse(jsonText));
185
+ };
186
+
187
+ /**
188
+ * Set a field name for the root node.
189
+ * @param {String | undefined} name
190
+ */
191
+ treemode.setName = function (name) {
192
+ this.options.name = name;
193
+ if (this.node) {
194
+ this.node.updateField(this.options.name);
195
+ }
196
+ };
197
+
198
+ /**
199
+ * Get the field name for the root node.
200
+ * @return {String | undefined} name
201
+ */
202
+ treemode.getName = function () {
203
+ return this.options.name;
204
+ };
205
+
206
+ /**
207
+ * Set focus to the editor. Focus will be set to:
208
+ * - the first editable field or value, or else
209
+ * - to the expand button of the root node, or else
210
+ * - to the context menu button of the root node, or else
211
+ * - to the first button in the top menu
212
+ */
213
+ treemode.focus = function () {
214
+ var input = this.content.querySelector('[contenteditable=true]');
215
+ if (input) {
216
+ input.focus();
217
+ }
218
+ else if (this.node.dom.expand) {
219
+ this.node.dom.expand.focus();
220
+ }
221
+ else if (this.node.dom.menu) {
222
+ this.node.dom.menu.focus();
223
+ }
224
+ else {
225
+ // focus to the first button in the menu
226
+ input = this.frame.querySelector('button');
227
+ if (input) {
228
+ input.focus();
229
+ }
230
+ }
231
+ };
232
+
233
+ /**
234
+ * Remove the root node from the editor
235
+ */
236
+ treemode.clear = function () {
237
+ if (this.node) {
238
+ this.node.collapse();
239
+ this.tbody.removeChild(this.node.getDom());
240
+ delete this.node;
241
+ }
242
+ };
243
+
244
+ /**
245
+ * Set the root node for the json editor
246
+ * @param {Node} node
247
+ * @private
248
+ */
249
+ treemode._setRoot = function (node) {
250
+ this.clear();
251
+
252
+ this.node = node;
253
+
254
+ // append to the dom
255
+ this.tbody.appendChild(node.getDom());
256
+ };
257
+
258
+ /**
259
+ * Search text in all nodes
260
+ * The nodes will be expanded when the text is found one of its childs,
261
+ * else it will be collapsed. Searches are case insensitive.
262
+ * @param {String} text
263
+ * @return {Object[]} results Array with nodes containing the search results
264
+ * The result objects contains fields:
265
+ * - {Node} node,
266
+ * - {String} elem the dom element name where
267
+ * the result is found ('field' or
268
+ * 'value')
269
+ */
270
+ treemode.search = function (text) {
271
+ var results;
272
+ if (this.node) {
273
+ this.content.removeChild(this.table); // Take the table offline
274
+ results = this.node.search(text);
275
+ this.content.appendChild(this.table); // Put the table online again
276
+ }
277
+ else {
278
+ results = [];
279
+ }
280
+
281
+ return results;
282
+ };
283
+
284
+ /**
285
+ * Expand all nodes
286
+ */
287
+ treemode.expandAll = function () {
288
+ if (this.node) {
289
+ this.content.removeChild(this.table); // Take the table offline
290
+ this.node.expand();
291
+ this.content.appendChild(this.table); // Put the table online again
292
+ }
293
+ };
294
+
295
+ /**
296
+ * Collapse all nodes
297
+ */
298
+ treemode.collapseAll = function () {
299
+ if (this.node) {
300
+ this.content.removeChild(this.table); // Take the table offline
301
+ this.node.collapse();
302
+ this.content.appendChild(this.table); // Put the table online again
303
+ }
304
+ };
305
+
306
+ /**
307
+ * The method onChange is called whenever a field or value is changed, created,
308
+ * deleted, duplicated, etc.
309
+ * @param {String} action Change action. Available values: "editField",
310
+ * "editValue", "changeType", "appendNode",
311
+ * "removeNode", "duplicateNode", "moveNode", "expand",
312
+ * "collapse".
313
+ * @param {Object} params Object containing parameters describing the change.
314
+ * The parameters in params depend on the action (for
315
+ * example for "editValue" the Node, old value, and new
316
+ * value are provided). params contains all information
317
+ * needed to undo or redo the action.
318
+ * @private
319
+ */
320
+ treemode._onAction = function (action, params) {
321
+ // add an action to the history
322
+ if (this.history) {
323
+ this.history.add(action, params);
324
+ }
325
+
326
+ this._onChange();
327
+ };
328
+
329
+ /**
330
+ * Handle a change:
331
+ * - Validate JSON schema
332
+ * - Send a callback to the onChange listener if provided
333
+ * @private
334
+ */
335
+ treemode._onChange = function () {
336
+ // validate JSON schema (if configured)
337
+ this._debouncedValidate();
338
+
339
+ // trigger the onChange callback
340
+ if (this.options.onChange) {
341
+ try {
342
+ this.options.onChange();
343
+ }
344
+ catch (err) {
345
+ console.error('Error in onChange callback: ', err);
346
+ }
347
+ }
348
+ };
349
+
350
+ /**
351
+ * Validate current JSON object against the configured JSON schema
352
+ * Throws an exception when no JSON schema is configured
353
+ */
354
+ treemode.validate = function () {
355
+ // clear all current errors
356
+ if (this.errorNodes) {
357
+ this.errorNodes.forEach(function (node) {
358
+ node.setError(null);
359
+ });
360
+ }
361
+
362
+ var root = this.node;
363
+ if (!root) { // TODO: this should be redundant but is needed on mode switch
364
+ return;
365
+ }
366
+
367
+ // check for duplicate keys
368
+ var duplicateErrors = root.validate();
369
+
370
+ // validate the JSON
371
+ var schemaErrors = [];
372
+ if (this.validateSchema) {
373
+ var valid = this.validateSchema(root.getValue());
374
+ if (!valid) {
375
+ // apply all new errors
376
+ schemaErrors = this.validateSchema.errors
377
+ .map(function (error) {
378
+ return util.improveSchemaError(error);
379
+ })
380
+ .map(function findNode (error) {
381
+ return {
382
+ node: root.findNode(error.dataPath),
383
+ error: error
384
+ }
385
+ })
386
+ .filter(function hasNode (entry) {
387
+ return entry.node != null
388
+ });
389
+ }
390
+ }
391
+
392
+ // display the error in the nodes with a problem
393
+ this.errorNodes = duplicateErrors
394
+ .concat(schemaErrors)
395
+ .reduce(function expandParents (all, entry) {
396
+ // expand parents, then merge such that parents come first and
397
+ // original entries last
398
+ return entry.node
399
+ .findParents()
400
+ .map(function (parent) {
401
+ return {
402
+ node: parent,
403
+ child: entry.node,
404
+ error: {
405
+ message: parent.type === 'object'
406
+ ? 'Contains invalid properties' // object
407
+ : 'Contains invalid items' // array
408
+ }
409
+ };
410
+ })
411
+ .concat(all, [entry]);
412
+ }, [])
413
+ // TODO: dedupe the parent nodes
414
+ .map(function setError (entry) {
415
+ entry.node.setError(entry.error, entry.child);
416
+ return entry.node;
417
+ });
418
+ };
419
+
420
+ /**
421
+ * Start autoscrolling when given mouse position is above the top of the
422
+ * editor contents, or below the bottom.
423
+ * @param {Number} mouseY Absolute mouse position in pixels
424
+ */
425
+ treemode.startAutoScroll = function (mouseY) {
426
+ var me = this;
427
+ var content = this.content;
428
+ var top = util.getAbsoluteTop(content);
429
+ var height = content.clientHeight;
430
+ var bottom = top + height;
431
+ var margin = 24;
432
+ var interval = 50; // ms
433
+
434
+ if ((mouseY < top + margin) && content.scrollTop > 0) {
435
+ this.autoScrollStep = ((top + margin) - mouseY) / 3;
436
+ }
437
+ else if (mouseY > bottom - margin &&
438
+ height + content.scrollTop < content.scrollHeight) {
439
+ this.autoScrollStep = ((bottom - margin) - mouseY) / 3;
440
+ }
441
+ else {
442
+ this.autoScrollStep = undefined;
443
+ }
444
+
445
+ if (this.autoScrollStep) {
446
+ if (!this.autoScrollTimer) {
447
+ this.autoScrollTimer = setInterval(function () {
448
+ if (me.autoScrollStep) {
449
+ content.scrollTop -= me.autoScrollStep;
450
+ }
451
+ else {
452
+ me.stopAutoScroll();
453
+ }
454
+ }, interval);
455
+ }
456
+ }
457
+ else {
458
+ this.stopAutoScroll();
459
+ }
460
+ };
461
+
462
+ /**
463
+ * Stop auto scrolling. Only applicable when scrolling
464
+ */
465
+ treemode.stopAutoScroll = function () {
466
+ if (this.autoScrollTimer) {
467
+ clearTimeout(this.autoScrollTimer);
468
+ delete this.autoScrollTimer;
469
+ }
470
+ if (this.autoScrollStep) {
471
+ delete this.autoScrollStep;
472
+ }
473
+ };
474
+
475
+
476
+ /**
477
+ * Set the focus to an element in the editor, set text selection, and
478
+ * set scroll position.
479
+ * @param {Object} selection An object containing fields:
480
+ * {Element | undefined} dom The dom element
481
+ * which has focus
482
+ * {Range | TextRange} range A text selection
483
+ * {Node[]} nodes Nodes in case of multi selection
484
+ * {Number} scrollTop Scroll position
485
+ */
486
+ treemode.setSelection = function (selection) {
487
+ if (!selection) {
488
+ return;
489
+ }
490
+
491
+ if ('scrollTop' in selection && this.content) {
492
+ // TODO: animated scroll
493
+ this.content.scrollTop = selection.scrollTop;
494
+ }
495
+ if (selection.nodes) {
496
+ // multi-select
497
+ this.select(selection.nodes);
498
+ }
499
+ if (selection.range) {
500
+ util.setSelectionOffset(selection.range);
501
+ }
502
+ if (selection.dom) {
503
+ selection.dom.focus();
504
+ }
505
+ };
506
+
507
+ /**
508
+ * Get the current focus
509
+ * @return {Object} selection An object containing fields:
510
+ * {Element | undefined} dom The dom element
511
+ * which has focus
512
+ * {Range | TextRange} range A text selection
513
+ * {Node[]} nodes Nodes in case of multi selection
514
+ * {Number} scrollTop Scroll position
515
+ */
516
+ treemode.getSelection = function () {
517
+ var range = util.getSelectionOffset();
518
+ if (range && range.container.nodeName !== 'DIV') { // filter on (editable) divs)
519
+ range = null;
520
+ }
521
+
522
+ return {
523
+ dom: domFocus,
524
+ range: range,
525
+ nodes: this.multiselection.nodes.slice(0),
526
+ scrollTop: this.content ? this.content.scrollTop : 0
527
+ };
528
+ };
529
+
530
+ /**
531
+ * Adjust the scroll position such that given top position is shown at 1/4
532
+ * of the window height.
533
+ * @param {Number} top
534
+ * @param {function(boolean)} [callback] Callback, executed when animation is
535
+ * finished. The callback returns true
536
+ * when animation is finished, or false
537
+ * when not.
538
+ */
539
+ treemode.scrollTo = function (top, callback) {
540
+ var content = this.content;
541
+ if (content) {
542
+ var editor = this;
543
+ // cancel any running animation
544
+ if (editor.animateTimeout) {
545
+ clearTimeout(editor.animateTimeout);
546
+ delete editor.animateTimeout;
547
+ }
548
+ if (editor.animateCallback) {
549
+ editor.animateCallback(false);
550
+ delete editor.animateCallback;
551
+ }
552
+
553
+ // calculate final scroll position
554
+ var height = content.clientHeight;
555
+ var bottom = content.scrollHeight - height;
556
+ var finalScrollTop = Math.min(Math.max(top - height / 4, 0), bottom);
557
+
558
+ // animate towards the new scroll position
559
+ var animate = function () {
560
+ var scrollTop = content.scrollTop;
561
+ var diff = (finalScrollTop - scrollTop);
562
+ if (Math.abs(diff) > 3) {
563
+ content.scrollTop += diff / 3;
564
+ editor.animateCallback = callback;
565
+ editor.animateTimeout = setTimeout(animate, 50);
566
+ }
567
+ else {
568
+ // finished
569
+ if (callback) {
570
+ callback(true);
571
+ }
572
+ content.scrollTop = finalScrollTop;
573
+ delete editor.animateTimeout;
574
+ delete editor.animateCallback;
575
+ }
576
+ };
577
+ animate();
578
+ }
579
+ else {
580
+ if (callback) {
581
+ callback(false);
582
+ }
583
+ }
584
+ };
585
+
586
+ /**
587
+ * Create main frame
588
+ * @private
589
+ */
590
+ treemode._createFrame = function () {
591
+ // create the frame
592
+ this.frame = document.createElement('div');
593
+ this.frame.className = 'jsoneditor jsoneditor-mode-' + this.options.mode;
594
+ this.container.appendChild(this.frame);
595
+
596
+ // create one global event listener to handle all events from all nodes
597
+ var editor = this;
598
+ function onEvent(event) {
599
+ // when switching to mode "code" or "text" via the menu, some events
600
+ // are still fired whilst the _onEvent methods is already removed.
601
+ if (editor._onEvent) {
602
+ editor._onEvent(event);
603
+ }
604
+ }
605
+ this.frame.onclick = function (event) {
606
+ var target = event.target;// || event.srcElement;
607
+
608
+ onEvent(event);
609
+
610
+ // prevent default submit action of buttons when editor is located
611
+ // inside a form
612
+ if (target.nodeName == 'BUTTON') {
613
+ event.preventDefault();
614
+ }
615
+ };
616
+ this.frame.oninput = onEvent;
617
+ this.frame.onchange = onEvent;
618
+ this.frame.onkeydown = onEvent;
619
+ this.frame.onkeyup = onEvent;
620
+ this.frame.oncut = onEvent;
621
+ this.frame.onpaste = onEvent;
622
+ this.frame.onmousedown = onEvent;
623
+ this.frame.onmouseup = onEvent;
624
+ this.frame.onmouseover = onEvent;
625
+ this.frame.onmouseout = onEvent;
626
+ // Note: focus and blur events do not propagate, therefore they defined
627
+ // using an eventListener with useCapture=true
628
+ // see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
629
+ util.addEventListener(this.frame, 'focus', onEvent, true);
630
+ util.addEventListener(this.frame, 'blur', onEvent, true);
631
+ this.frame.onfocusin = onEvent; // for IE
632
+ this.frame.onfocusout = onEvent; // for IE
633
+
634
+ // create menu
635
+ this.menu = document.createElement('div');
636
+ this.menu.className = 'jsoneditor-menu';
637
+ this.frame.appendChild(this.menu);
638
+
639
+ // create expand all button
640
+ var expandAll = document.createElement('button');
641
+ expandAll.className = 'jsoneditor-expand-all';
642
+ expandAll.title = 'Expand all fields';
643
+ expandAll.onclick = function () {
644
+ editor.expandAll();
645
+ };
646
+ this.menu.appendChild(expandAll);
647
+
648
+ // create expand all button
649
+ var collapseAll = document.createElement('button');
650
+ collapseAll.title = 'Collapse all fields';
651
+ collapseAll.className = 'jsoneditor-collapse-all';
652
+ collapseAll.onclick = function () {
653
+ editor.collapseAll();
654
+ };
655
+ this.menu.appendChild(collapseAll);
656
+
657
+ // create undo/redo buttons
658
+ if (this.history) {
659
+ // create undo button
660
+ var undo = document.createElement('button');
661
+ undo.className = 'jsoneditor-undo jsoneditor-separator';
662
+ undo.title = 'Undo last action (Ctrl+Z)';
663
+ undo.onclick = function () {
664
+ editor._onUndo();
665
+ };
666
+ this.menu.appendChild(undo);
667
+ this.dom.undo = undo;
668
+
669
+ // create redo button
670
+ var redo = document.createElement('button');
671
+ redo.className = 'jsoneditor-redo';
672
+ redo.title = 'Redo (Ctrl+Shift+Z)';
673
+ redo.onclick = function () {
674
+ editor._onRedo();
675
+ };
676
+ this.menu.appendChild(redo);
677
+ this.dom.redo = redo;
678
+
679
+ // register handler for onchange of history
680
+ this.history.onChange = function () {
681
+ undo.disabled = !editor.history.canUndo();
682
+ redo.disabled = !editor.history.canRedo();
683
+ };
684
+ this.history.onChange();
685
+ }
686
+
687
+ // create mode box
688
+ if (this.options && this.options.modes && this.options.modes.length) {
689
+ var modeBox = modeswitcher.create(this, this.options.modes, this.options.mode);
690
+ this.menu.appendChild(modeBox);
691
+ this.dom.modeBox = modeBox;
692
+ }
693
+
694
+ // create search box
695
+ if (this.options.search) {
696
+ this.searchBox = new SearchBox(this, this.menu);
697
+ }
698
+ };
699
+
700
+ /**
701
+ * Perform an undo action
702
+ * @private
703
+ */
704
+ treemode._onUndo = function () {
705
+ if (this.history) {
706
+ // undo last action
707
+ this.history.undo();
708
+
709
+ // fire change event
710
+ this._onChange();
711
+ }
712
+ };
713
+
714
+ /**
715
+ * Perform a redo action
716
+ * @private
717
+ */
718
+ treemode._onRedo = function () {
719
+ if (this.history) {
720
+ // redo last action
721
+ this.history.redo();
722
+
723
+ // fire change event
724
+ this._onChange();
725
+ }
726
+ };
727
+
728
+ /**
729
+ * Event handler
730
+ * @param event
731
+ * @private
732
+ */
733
+ treemode._onEvent = function (event) {
734
+ if (event.type == 'keydown') {
735
+ this._onKeyDown(event);
736
+ }
737
+
738
+ if (event.type == 'focus') {
739
+ domFocus = event.target;
740
+ }
741
+
742
+ if (event.type == 'mousedown') {
743
+ this._startDragDistance(event);
744
+ }
745
+ if (event.type == 'mousemove' || event.type == 'mouseup' || event.type == 'click') {
746
+ this._updateDragDistance(event);
747
+ }
748
+
749
+ var node = Node.getNodeFromTarget(event.target);
750
+
751
+ if (node && node.selected) {
752
+ if (event.type == 'click') {
753
+ if (event.target == node.dom.menu) {
754
+ this.showContextMenu(event.target);
755
+
756
+ // stop propagation (else we will open the context menu of a single node)
757
+ return;
758
+ }
759
+
760
+ // deselect a multi selection
761
+ if (!event.hasMoved) {
762
+ this.deselect();
763
+ }
764
+ }
765
+
766
+ if (event.type == 'mousedown') {
767
+ // drag multiple nodes
768
+ Node.onDragStart(this.multiselection.nodes, event);
769
+ }
770
+ }
771
+ else {
772
+ if (event.type == 'mousedown') {
773
+ this.deselect();
774
+
775
+ if (node && event.target == node.dom.drag) {
776
+ // drag a singe node
777
+ Node.onDragStart(node, event);
778
+ }
779
+ else if (!node || (event.target != node.dom.field && event.target != node.dom.value)) {
780
+ // select multiple nodes
781
+ this._onMultiSelectStart(event);
782
+ }
783
+ }
784
+ }
785
+
786
+ if (node) {
787
+ node.onEvent(event);
788
+ }
789
+ };
790
+
791
+ treemode._startDragDistance = function (event) {
792
+ this.dragDistanceEvent = {
793
+ initialTarget: event.target,
794
+ initialPageX: event.pageX,
795
+ initialPageY: event.pageY,
796
+ dragDistance: 0,
797
+ hasMoved: false
798
+ };
799
+ };
800
+
801
+ treemode._updateDragDistance = function (event) {
802
+ if (!this.dragDistanceEvent) {
803
+ this._startDragDistance(event);
804
+ }
805
+
806
+ var diffX = event.pageX - this.dragDistanceEvent.initialPageX;
807
+ var diffY = event.pageY - this.dragDistanceEvent.initialPageY;
808
+
809
+ this.dragDistanceEvent.dragDistance = Math.sqrt(diffX * diffX + diffY * diffY);
810
+ this.dragDistanceEvent.hasMoved =
811
+ this.dragDistanceEvent.hasMoved || this.dragDistanceEvent.dragDistance > 10;
812
+
813
+ event.dragDistance = this.dragDistanceEvent.dragDistance;
814
+ event.hasMoved = this.dragDistanceEvent.hasMoved;
815
+
816
+ return event.dragDistance;
817
+ };
818
+
819
+ /**
820
+ * Start multi selection of nodes by dragging the mouse
821
+ * @param event
822
+ * @private
823
+ */
824
+ treemode._onMultiSelectStart = function (event) {
825
+ var node = Node.getNodeFromTarget(event.target);
826
+
827
+ if (this.options.mode !== 'tree' || this.options.onEditable !== undefined) {
828
+ // dragging not allowed in modes 'view' and 'form'
829
+ // TODO: allow multiselection of items when option onEditable is specified
830
+ return;
831
+ }
832
+
833
+ this.multiselection = {
834
+ start: node || null,
835
+ end: null,
836
+ nodes: []
837
+ };
838
+
839
+ this._startDragDistance(event);
840
+
841
+ var editor = this;
842
+ if (!this.mousemove) {
843
+ this.mousemove = util.addEventListener(window, 'mousemove', function (event) {
844
+ editor._onMultiSelect(event);
845
+ });
846
+ }
847
+ if (!this.mouseup) {
848
+ this.mouseup = util.addEventListener(window, 'mouseup', function (event ) {
849
+ editor._onMultiSelectEnd(event);
850
+ });
851
+ }
852
+
853
+ };
854
+
855
+ /**
856
+ * Multiselect nodes by dragging
857
+ * @param event
858
+ * @private
859
+ */
860
+ treemode._onMultiSelect = function (event) {
861
+ event.preventDefault();
862
+
863
+ this._updateDragDistance(event);
864
+ if (!event.hasMoved) {
865
+ return;
866
+ }
867
+
868
+ var node = Node.getNodeFromTarget(event.target);
869
+
870
+ if (node) {
871
+ if (this.multiselection.start == null) {
872
+ this.multiselection.start = node;
873
+ }
874
+ this.multiselection.end = node;
875
+ }
876
+
877
+ // deselect previous selection
878
+ this.deselect();
879
+
880
+ // find the selected nodes in the range from first to last
881
+ var start = this.multiselection.start;
882
+ var end = this.multiselection.end || this.multiselection.start;
883
+ if (start && end) {
884
+ // find the top level childs, all having the same parent
885
+ this.multiselection.nodes = this._findTopLevelNodes(start, end);
886
+ this.select(this.multiselection.nodes);
887
+ }
888
+ };
889
+
890
+ /**
891
+ * End of multiselect nodes by dragging
892
+ * @param event
893
+ * @private
894
+ */
895
+ treemode._onMultiSelectEnd = function (event) {
896
+ // set focus to the context menu button of the first node
897
+ if (this.multiselection.nodes[0]) {
898
+ this.multiselection.nodes[0].dom.menu.focus();
899
+ }
900
+
901
+ this.multiselection.start = null;
902
+ this.multiselection.end = null;
903
+
904
+ // cleanup global event listeners
905
+ if (this.mousemove) {
906
+ util.removeEventListener(window, 'mousemove', this.mousemove);
907
+ delete this.mousemove;
908
+ }
909
+ if (this.mouseup) {
910
+ util.removeEventListener(window, 'mouseup', this.mouseup);
911
+ delete this.mouseup;
912
+ }
913
+ };
914
+
915
+ /**
916
+ * deselect currently selected nodes
917
+ * @param {boolean} [clearStartAndEnd=false] If true, the `start` and `end`
918
+ * state is cleared too.
919
+ */
920
+ treemode.deselect = function (clearStartAndEnd) {
921
+ this.multiselection.nodes.forEach(function (node) {
922
+ node.setSelected(false);
923
+ });
924
+ this.multiselection.nodes = [];
925
+
926
+ if (clearStartAndEnd) {
927
+ this.multiselection.start = null;
928
+ this.multiselection.end = null;
929
+ }
930
+ };
931
+
932
+ /**
933
+ * select nodes
934
+ * @param {Node[] | Node} nodes
935
+ */
936
+ treemode.select = function (nodes) {
937
+ if (!Array.isArray(nodes)) {
938
+ return this.select([nodes]);
939
+ }
940
+
941
+ if (nodes) {
942
+ this.deselect();
943
+
944
+ this.multiselection.nodes = nodes.slice(0);
945
+
946
+ var first = nodes[0];
947
+ nodes.forEach(function (node) {
948
+ node.setSelected(true, node === first);
949
+ });
950
+ }
951
+ };
952
+
953
+ /**
954
+ * From two arbitrary selected nodes, find their shared parent node.
955
+ * From that parent node, select the two child nodes in the brances going to
956
+ * nodes `start` and `end`, and select all childs in between.
957
+ * @param {Node} start
958
+ * @param {Node} end
959
+ * @return {Array.<Node>} Returns an ordered list with child nodes
960
+ * @private
961
+ */
962
+ treemode._findTopLevelNodes = function (start, end) {
963
+ var startPath = start.getPath();
964
+ var endPath = end.getPath();
965
+ var i = 0;
966
+ while (i < startPath.length && startPath[i] === endPath[i]) {
967
+ i++;
968
+ }
969
+ var root = startPath[i - 1];
970
+ var startChild = startPath[i];
971
+ var endChild = endPath[i];
972
+
973
+ if (!startChild || !endChild) {
974
+ if (root.parent) {
975
+ // startChild is a parent of endChild or vice versa
976
+ startChild = root;
977
+ endChild = root;
978
+ root = root.parent
979
+ }
980
+ else {
981
+ // we have selected the root node (which doesn't have a parent)
982
+ startChild = root.childs[0];
983
+ endChild = root.childs[root.childs.length - 1];
984
+ }
985
+ }
986
+
987
+ if (root && startChild && endChild) {
988
+ var startIndex = root.childs.indexOf(startChild);
989
+ var endIndex = root.childs.indexOf(endChild);
990
+ var firstIndex = Math.min(startIndex, endIndex);
991
+ var lastIndex = Math.max(startIndex, endIndex);
992
+
993
+ return root.childs.slice(firstIndex, lastIndex + 1);
994
+ }
995
+ else {
996
+ return [];
997
+ }
998
+ };
999
+
1000
+ /**
1001
+ * Event handler for keydown. Handles shortcut keys
1002
+ * @param {Event} event
1003
+ * @private
1004
+ */
1005
+ treemode._onKeyDown = function (event) {
1006
+ var keynum = event.which || event.keyCode;
1007
+ var ctrlKey = event.ctrlKey;
1008
+ var shiftKey = event.shiftKey;
1009
+ var handled = false;
1010
+
1011
+ if (keynum == 9) { // Tab or Shift+Tab
1012
+ setTimeout(function () {
1013
+ // select all text when moving focus to an editable div
1014
+ util.selectContentEditable(domFocus);
1015
+ }, 0);
1016
+ }
1017
+
1018
+ if (this.searchBox) {
1019
+ if (ctrlKey && keynum == 70) { // Ctrl+F
1020
+ this.searchBox.dom.search.focus();
1021
+ this.searchBox.dom.search.select();
1022
+ handled = true;
1023
+ }
1024
+ else if (keynum == 114 || (ctrlKey && keynum == 71)) { // F3 or Ctrl+G
1025
+ var focus = true;
1026
+ if (!shiftKey) {
1027
+ // select next search result (F3 or Ctrl+G)
1028
+ this.searchBox.next(focus);
1029
+ }
1030
+ else {
1031
+ // select previous search result (Shift+F3 or Ctrl+Shift+G)
1032
+ this.searchBox.previous(focus);
1033
+ }
1034
+
1035
+ handled = true;
1036
+ }
1037
+ }
1038
+
1039
+ if (this.history) {
1040
+ if (ctrlKey && !shiftKey && keynum == 90) { // Ctrl+Z
1041
+ // undo
1042
+ this._onUndo();
1043
+ handled = true;
1044
+ }
1045
+ else if (ctrlKey && shiftKey && keynum == 90) { // Ctrl+Shift+Z
1046
+ // redo
1047
+ this._onRedo();
1048
+ handled = true;
1049
+ }
1050
+ }
1051
+
1052
+ if (handled) {
1053
+ event.preventDefault();
1054
+ event.stopPropagation();
1055
+ }
1056
+ };
1057
+
1058
+ /**
1059
+ * Create main table
1060
+ * @private
1061
+ */
1062
+ treemode._createTable = function () {
1063
+ var contentOuter = document.createElement('div');
1064
+ contentOuter.className = 'jsoneditor-outer';
1065
+ this.contentOuter = contentOuter;
1066
+
1067
+ this.content = document.createElement('div');
1068
+ this.content.className = 'jsoneditor-tree';
1069
+ contentOuter.appendChild(this.content);
1070
+
1071
+ this.table = document.createElement('table');
1072
+ this.table.className = 'jsoneditor-tree';
1073
+ this.content.appendChild(this.table);
1074
+
1075
+ // create colgroup where the first two columns don't have a fixed
1076
+ // width, and the edit columns do have a fixed width
1077
+ var col;
1078
+ this.colgroupContent = document.createElement('colgroup');
1079
+ if (this.options.mode === 'tree') {
1080
+ col = document.createElement('col');
1081
+ col.width = "24px";
1082
+ this.colgroupContent.appendChild(col);
1083
+ }
1084
+ col = document.createElement('col');
1085
+ col.width = "24px";
1086
+ this.colgroupContent.appendChild(col);
1087
+ col = document.createElement('col');
1088
+ this.colgroupContent.appendChild(col);
1089
+ this.table.appendChild(this.colgroupContent);
1090
+
1091
+ this.tbody = document.createElement('tbody');
1092
+ this.table.appendChild(this.tbody);
1093
+
1094
+ this.frame.appendChild(contentOuter);
1095
+ };
1096
+
1097
+ /**
1098
+ * Show a contextmenu for this node.
1099
+ * Used for multiselection
1100
+ * @param {HTMLElement} anchor Anchor element to attache the context menu to.
1101
+ * @param {function} [onClose] Callback method called when the context menu
1102
+ * is being closed.
1103
+ */
1104
+ treemode.showContextMenu = function (anchor, onClose) {
1105
+ var items = [];
1106
+ var editor = this;
1107
+
1108
+ // create duplicate button
1109
+ items.push({
1110
+ text: 'Duplicate',
1111
+ title: 'Duplicate selected fields (Ctrl+D)',
1112
+ className: 'jsoneditor-duplicate',
1113
+ click: function () {
1114
+ Node.onDuplicate(editor.multiselection.nodes);
1115
+ }
1116
+ });
1117
+
1118
+ // create remove button
1119
+ items.push({
1120
+ text: 'Remove',
1121
+ title: 'Remove selected fields (Ctrl+Del)',
1122
+ className: 'jsoneditor-remove',
1123
+ click: function () {
1124
+ Node.onRemove(editor.multiselection.nodes);
1125
+ }
1126
+ });
1127
+
1128
+ var menu = new ContextMenu(items, {close: onClose});
1129
+ menu.show(anchor, this.content);
1130
+ };
1131
+
1132
+
1133
+ // define modes
1134
+ module.exports = [
1135
+ {
1136
+ mode: 'tree',
1137
+ mixin: treemode,
1138
+ data: 'json'
1139
+ },
1140
+ {
1141
+ mode: 'view',
1142
+ mixin: treemode,
1143
+ data: 'json'
1144
+ },
1145
+ {
1146
+ mode: 'form',
1147
+ mixin: treemode,
1148
+ data: 'json'
1149
+ }
1150
+ ];