statixite 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ ];