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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +145 -0
- data/Rakefile +26 -0
- data/app/assets/images/statixite/STATIXITE-logo.png +0 -0
- data/app/assets/images/statixite/favicon.ico +0 -0
- data/app/assets/images/statixite/jekyll.png +0 -0
- data/app/assets/images/statixite/md-editor.png +0 -0
- data/app/assets/images/statixite/ring-alt.gif +0 -0
- data/app/assets/javascripts/controllers/statixite/deployments_create.js +13 -0
- data/app/assets/javascripts/controllers/statixite/deployments_index.js +13 -0
- data/app/assets/javascripts/controllers/statixite/sites_create.js +27 -0
- data/app/assets/javascripts/controllers/statixite/sites_new.js +27 -0
- data/app/assets/javascripts/controllers/statixite/templates_edit.js +208 -0
- data/app/assets/javascripts/statixite/application.js +8 -0
- data/app/assets/javascripts/statixite/array-helpers.js +13 -0
- data/app/assets/javascripts/statixite/editor.js +244 -0
- data/app/assets/javascripts/statixite/loader.js +14 -0
- data/app/assets/javascripts/statixite/notify-defaults.js +5 -0
- data/app/assets/stylesheets/statixite/application.less +271 -0
- data/app/assets/stylesheets/statixite/bootstrap-glyphicons.less +305 -0
- data/app/assets/stylesheets/statixite/bootstrap.less +58 -0
- data/app/assets/stylesheets/statixite/bootstrap_and_overrides.less +2 -0
- data/app/assets/stylesheets/statixite/landing-page.less +156 -0
- data/app/controllers/statixite/application_controller.rb +22 -0
- data/app/controllers/statixite/deployments_controller.rb +61 -0
- data/app/controllers/statixite/media_controller.rb +61 -0
- data/app/controllers/statixite/posts_controller.rb +68 -0
- data/app/controllers/statixite/sites_controller.rb +141 -0
- data/app/controllers/statixite/templates_controller.rb +233 -0
- data/app/helpers/statixite/application_helper.rb +63 -0
- data/app/models/statixite/deployment.rb +5 -0
- data/app/models/statixite/media.rb +7 -0
- data/app/models/statixite/post.rb +76 -0
- data/app/models/statixite/site.rb +76 -0
- data/app/services/statixite/deployment_service.rb +73 -0
- data/app/services/statixite/git_service.rb +102 -0
- data/app/services/statixite/site_deactivation_service.rb +52 -0
- data/app/services/statixite/site_operation_service.rb +251 -0
- data/app/uploaders/statixite/file_uploader.rb +14 -0
- data/app/validators/statixite/jekyll_template_validator.rb +16 -0
- data/app/validators/statixite/liquid_validator.rb +11 -0
- data/app/views/layouts/statixite/_dash_nav.html.haml +20 -0
- data/app/views/layouts/statixite/_flash.html.haml +13 -0
- data/app/views/layouts/statixite/_head.html.haml +12 -0
- data/app/views/layouts/statixite/_header.html.haml +30 -0
- data/app/views/layouts/statixite/_site_sub_items.html.haml +38 -0
- data/app/views/layouts/statixite/dashboard.html.haml +27 -0
- data/app/views/statixite/deployments/_modal.html.haml +18 -0
- data/app/views/statixite/deployments/index.html.haml +39 -0
- data/app/views/statixite/kaminari/_first_page.html.haml +2 -0
- data/app/views/statixite/kaminari/_gap.html.haml +2 -0
- data/app/views/statixite/kaminari/_last_page.html.haml +2 -0
- data/app/views/statixite/kaminari/_next_page.html.haml +2 -0
- data/app/views/statixite/kaminari/_page.html.haml +6 -0
- data/app/views/statixite/kaminari/_paginator.html.haml +11 -0
- data/app/views/statixite/kaminari/_prev_page.html.haml +2 -0
- data/app/views/statixite/media/_index.html.haml +13 -0
- data/app/views/statixite/media/_paginate.html.haml +1 -0
- data/app/views/statixite/media/index.html.haml +39 -0
- data/app/views/statixite/media/index.js.haml +2 -0
- data/app/views/statixite/posts/_form.html.haml +65 -0
- data/app/views/statixite/posts/_image_modal.html.haml +21 -0
- data/app/views/statixite/posts/_modals.html.haml +111 -0
- data/app/views/statixite/posts/_posts.html.haml +15 -0
- data/app/views/statixite/posts/edit.html.haml +6 -0
- data/app/views/statixite/posts/index.html.haml +4 -0
- data/app/views/statixite/posts/index.js.haml +1 -0
- data/app/views/statixite/posts/new.html.haml +5 -0
- data/app/views/statixite/sites/_sites.html.haml +27 -0
- data/app/views/statixite/sites/_templates.html.haml +26 -0
- data/app/views/statixite/sites/build_and_preview.html.haml +24 -0
- data/app/views/statixite/sites/index.html.haml +4 -0
- data/app/views/statixite/sites/index.js.haml +1 -0
- data/app/views/statixite/sites/new.html.haml +45 -0
- data/app/views/statixite/sites/settings.html.haml +77 -0
- data/app/views/statixite/templates/edit.html.haml +93 -0
- data/app/views/statixite/templates/upload_files.js.haml +2 -0
- data/config/routes.rb +24 -0
- data/db/migrate/20150525171543_create_statixite_sites.rb +15 -0
- data/db/migrate/20150530041055_create_statixite_posts.rb +14 -0
- data/db/migrate/20150610024047_create_statixite_deployments.rb +11 -0
- data/db/migrate/20151013131224_create_statixite_media.rb +10 -0
- data/lib/assets/templates.yaml +734 -0
- data/lib/generators/statixite/statixite_generator.rb +49 -0
- data/lib/statixite.rb +14 -0
- data/lib/statixite/cloud_sync.rb +104 -0
- data/lib/statixite/engine.rb +49 -0
- data/lib/statixite/version.rb +3 -0
- data/lib/tasks/statixite_tasks.rake +4 -0
- data/vendor/assets/bower_components/bootstrap/CHANGELOG.md +5 -0
- data/vendor/assets/bower_components/bootstrap/Gruntfile.js +533 -0
- data/vendor/assets/bower_components/bootstrap/LICENSE +21 -0
- data/vendor/assets/bower_components/bootstrap/README.md +139 -0
- data/vendor/assets/bower_components/bootstrap/bower.json +34 -0
- data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap-theme.css +587 -0
- data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap-theme.css.map +1 -0
- data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap-theme.min.css +6 -0
- data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap-theme.min.css.map +1 -0
- data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap.css +6760 -0
- data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap.css.map +1 -0
- data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap.min.css +6 -0
- data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap.min.css.map +1 -0
- data/vendor/assets/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.eot +0 -0
- data/vendor/assets/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.svg +288 -0
- data/vendor/assets/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/vendor/assets/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff +0 -0
- data/vendor/assets/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 +0 -0
- data/vendor/assets/bower_components/bootstrap/dist/js/bootstrap.js +2363 -0
- data/vendor/assets/bower_components/bootstrap/dist/js/bootstrap.min.js +7 -0
- data/vendor/assets/bower_components/bootstrap/dist/js/npm.js +13 -0
- data/vendor/assets/bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot +0 -0
- data/vendor/assets/bower_components/bootstrap/fonts/glyphicons-halflings-regular.svg +288 -0
- data/vendor/assets/bower_components/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/vendor/assets/bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff +0 -0
- data/vendor/assets/bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff2 +0 -0
- data/vendor/assets/bower_components/bootstrap/grunt/bs-commonjs-generator.js +30 -0
- data/vendor/assets/bower_components/bootstrap/grunt/bs-glyphicons-data-generator.js +42 -0
- data/vendor/assets/bower_components/bootstrap/grunt/bs-lessdoc-parser.js +237 -0
- data/vendor/assets/bower_components/bootstrap/grunt/bs-raw-files-generator.js +44 -0
- data/vendor/assets/bower_components/bootstrap/grunt/configBridge.json +46 -0
- data/vendor/assets/bower_components/bootstrap/grunt/sauce_browsers.yml +82 -0
- data/vendor/assets/bower_components/bootstrap/js/affix.js +162 -0
- data/vendor/assets/bower_components/bootstrap/js/alert.js +94 -0
- data/vendor/assets/bower_components/bootstrap/js/button.js +120 -0
- data/vendor/assets/bower_components/bootstrap/js/carousel.js +237 -0
- data/vendor/assets/bower_components/bootstrap/js/collapse.js +211 -0
- data/vendor/assets/bower_components/bootstrap/js/dropdown.js +165 -0
- data/vendor/assets/bower_components/bootstrap/js/modal.js +337 -0
- data/vendor/assets/bower_components/bootstrap/js/popover.js +108 -0
- data/vendor/assets/bower_components/bootstrap/js/scrollspy.js +172 -0
- data/vendor/assets/bower_components/bootstrap/js/tab.js +155 -0
- data/vendor/assets/bower_components/bootstrap/js/tooltip.js +514 -0
- data/vendor/assets/bower_components/bootstrap/js/transition.js +59 -0
- data/vendor/assets/bower_components/bootstrap/less/alerts.less +73 -0
- data/vendor/assets/bower_components/bootstrap/less/badges.less +66 -0
- data/vendor/assets/bower_components/bootstrap/less/bootstrap.less +56 -0
- data/vendor/assets/bower_components/bootstrap/less/breadcrumbs.less +26 -0
- data/vendor/assets/bower_components/bootstrap/less/button-groups.less +244 -0
- data/vendor/assets/bower_components/bootstrap/less/buttons.less +166 -0
- data/vendor/assets/bower_components/bootstrap/less/carousel.less +270 -0
- data/vendor/assets/bower_components/bootstrap/less/close.less +34 -0
- data/vendor/assets/bower_components/bootstrap/less/code.less +69 -0
- data/vendor/assets/bower_components/bootstrap/less/component-animations.less +33 -0
- data/vendor/assets/bower_components/bootstrap/less/dropdowns.less +216 -0
- data/vendor/assets/bower_components/bootstrap/less/forms.less +613 -0
- data/vendor/assets/bower_components/bootstrap/less/glyphicons.less +305 -0
- data/vendor/assets/bower_components/bootstrap/less/grid.less +84 -0
- data/vendor/assets/bower_components/bootstrap/less/input-groups.less +171 -0
- data/vendor/assets/bower_components/bootstrap/less/jumbotron.less +54 -0
- data/vendor/assets/bower_components/bootstrap/less/labels.less +64 -0
- data/vendor/assets/bower_components/bootstrap/less/list-group.less +130 -0
- data/vendor/assets/bower_components/bootstrap/less/media.less +66 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins.less +40 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/alerts.less +14 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/background-variant.less +9 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/border-radius.less +18 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/buttons.less +65 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/center-block.less +7 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/clearfix.less +22 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/forms.less +85 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/gradients.less +59 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/grid-framework.less +91 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/grid.less +122 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/hide-text.less +21 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/image.less +33 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/labels.less +12 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/list-group.less +30 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/nav-divider.less +10 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/nav-vertical-align.less +9 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/opacity.less +8 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/pagination.less +24 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/panels.less +24 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/progress-bar.less +10 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/reset-filter.less +8 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/reset-text.less +18 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/resize.less +6 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/responsive-visibility.less +15 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/size.less +10 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/tab-focus.less +9 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/table-row.less +28 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/text-emphasis.less +9 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/text-overflow.less +8 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/vendor-prefixes.less +227 -0
- data/vendor/assets/bower_components/bootstrap/less/modals.less +150 -0
- data/vendor/assets/bower_components/bootstrap/less/navbar.less +660 -0
- data/vendor/assets/bower_components/bootstrap/less/navs.less +242 -0
- data/vendor/assets/bower_components/bootstrap/less/normalize.less +424 -0
- data/vendor/assets/bower_components/bootstrap/less/pager.less +54 -0
- data/vendor/assets/bower_components/bootstrap/less/pagination.less +89 -0
- data/vendor/assets/bower_components/bootstrap/less/panels.less +271 -0
- data/vendor/assets/bower_components/bootstrap/less/popovers.less +131 -0
- data/vendor/assets/bower_components/bootstrap/less/print.less +101 -0
- data/vendor/assets/bower_components/bootstrap/less/progress-bars.less +87 -0
- data/vendor/assets/bower_components/bootstrap/less/responsive-embed.less +35 -0
- data/vendor/assets/bower_components/bootstrap/less/responsive-utilities.less +194 -0
- data/vendor/assets/bower_components/bootstrap/less/scaffolding.less +161 -0
- data/vendor/assets/bower_components/bootstrap/less/tables.less +234 -0
- data/vendor/assets/bower_components/bootstrap/less/theme.less +291 -0
- data/vendor/assets/bower_components/bootstrap/less/thumbnails.less +36 -0
- data/vendor/assets/bower_components/bootstrap/less/tooltip.less +101 -0
- data/vendor/assets/bower_components/bootstrap/less/type.less +302 -0
- data/vendor/assets/bower_components/bootstrap/less/utilities.less +55 -0
- data/vendor/assets/bower_components/bootstrap/less/variables.less +869 -0
- data/vendor/assets/bower_components/bootstrap/less/wells.less +29 -0
- data/vendor/assets/bower_components/bootstrap/nuget/MyGet.ps1 +8 -0
- data/vendor/assets/bower_components/bootstrap/nuget/bootstrap.less.nuspec +28 -0
- data/vendor/assets/bower_components/bootstrap/nuget/bootstrap.nuspec +28 -0
- data/vendor/assets/bower_components/bootstrap/package.js +32 -0
- data/vendor/assets/bower_components/bootstrap/package.json +87 -0
- data/vendor/assets/bower_components/jquery/AUTHORS.txt +275 -0
- data/vendor/assets/bower_components/jquery/LICENSE.txt +36 -0
- data/vendor/assets/bower_components/jquery/README.md +5 -0
- data/vendor/assets/bower_components/jquery/bower.json +14 -0
- data/vendor/assets/bower_components/jquery/dist/jquery.js +9831 -0
- data/vendor/assets/bower_components/jquery/dist/jquery.min.js +4 -0
- data/vendor/assets/bower_components/jquery/dist/jquery.min.map +1 -0
- data/vendor/assets/bower_components/jquery/src/ajax.js +845 -0
- data/vendor/assets/bower_components/jquery/src/ajax/jsonp.js +100 -0
- data/vendor/assets/bower_components/jquery/src/ajax/load.js +83 -0
- data/vendor/assets/bower_components/jquery/src/ajax/parseJSON.js +13 -0
- data/vendor/assets/bower_components/jquery/src/ajax/parseXML.js +27 -0
- data/vendor/assets/bower_components/jquery/src/ajax/script.js +68 -0
- data/vendor/assets/bower_components/jquery/src/ajax/var/location.js +3 -0
- data/vendor/assets/bower_components/jquery/src/ajax/var/nonce.js +5 -0
- data/vendor/assets/bower_components/jquery/src/ajax/var/rquery.js +3 -0
- data/vendor/assets/bower_components/jquery/src/ajax/xhr.js +167 -0
- data/vendor/assets/bower_components/jquery/src/attributes.js +11 -0
- data/vendor/assets/bower_components/jquery/src/attributes/attr.js +142 -0
- data/vendor/assets/bower_components/jquery/src/attributes/classes.js +177 -0
- data/vendor/assets/bower_components/jquery/src/attributes/prop.js +109 -0
- data/vendor/assets/bower_components/jquery/src/attributes/support.js +36 -0
- data/vendor/assets/bower_components/jquery/src/attributes/val.js +170 -0
- data/vendor/assets/bower_components/jquery/src/callbacks.js +232 -0
- data/vendor/assets/bower_components/jquery/src/core.js +489 -0
- data/vendor/assets/bower_components/jquery/src/core/access.js +65 -0
- data/vendor/assets/bower_components/jquery/src/core/init.js +134 -0
- data/vendor/assets/bower_components/jquery/src/core/parseHTML.js +49 -0
- data/vendor/assets/bower_components/jquery/src/core/ready.js +103 -0
- data/vendor/assets/bower_components/jquery/src/core/support.js +18 -0
- data/vendor/assets/bower_components/jquery/src/core/var/rsingleTag.js +5 -0
- data/vendor/assets/bower_components/jquery/src/css.js +515 -0
- data/vendor/assets/bower_components/jquery/src/css/addGetHookIf.js +24 -0
- data/vendor/assets/bower_components/jquery/src/css/adjustCSS.js +65 -0
- data/vendor/assets/bower_components/jquery/src/css/curCSS.js +57 -0
- data/vendor/assets/bower_components/jquery/src/css/defaultDisplay.js +72 -0
- data/vendor/assets/bower_components/jquery/src/css/hiddenVisibleSelectors.js +18 -0
- data/vendor/assets/bower_components/jquery/src/css/showHide.js +48 -0
- data/vendor/assets/bower_components/jquery/src/css/support.js +121 -0
- data/vendor/assets/bower_components/jquery/src/css/var/cssExpand.js +3 -0
- data/vendor/assets/bower_components/jquery/src/css/var/getStyles.js +15 -0
- data/vendor/assets/bower_components/jquery/src/css/var/isHidden.js +16 -0
- data/vendor/assets/bower_components/jquery/src/css/var/rmargin.js +3 -0
- data/vendor/assets/bower_components/jquery/src/css/var/rnumnonpx.js +5 -0
- data/vendor/assets/bower_components/jquery/src/css/var/swap.js +24 -0
- data/vendor/assets/bower_components/jquery/src/data.js +187 -0
- data/vendor/assets/bower_components/jquery/src/data/Data.js +200 -0
- data/vendor/assets/bower_components/jquery/src/data/accepts.js +20 -0
- data/vendor/assets/bower_components/jquery/src/data/support.js +23 -0
- data/vendor/assets/bower_components/jquery/src/data/var/acceptData.js +18 -0
- data/vendor/assets/bower_components/jquery/src/data/var/dataPriv.js +5 -0
- data/vendor/assets/bower_components/jquery/src/data/var/dataUser.js +5 -0
- data/vendor/assets/bower_components/jquery/src/deferred.js +158 -0
- data/vendor/assets/bower_components/jquery/src/deprecated.js +32 -0
- data/vendor/assets/bower_components/jquery/src/dimensions.js +54 -0
- data/vendor/assets/bower_components/jquery/src/effects.js +629 -0
- data/vendor/assets/bower_components/jquery/src/effects/Tween.js +121 -0
- data/vendor/assets/bower_components/jquery/src/effects/animatedSelector.js +13 -0
- data/vendor/assets/bower_components/jquery/src/effects/support.js +58 -0
- data/vendor/assets/bower_components/jquery/src/event.js +710 -0
- data/vendor/assets/bower_components/jquery/src/event/ajax.js +20 -0
- data/vendor/assets/bower_components/jquery/src/event/alias.js +27 -0
- data/vendor/assets/bower_components/jquery/src/event/focusin.js +53 -0
- data/vendor/assets/bower_components/jquery/src/event/support.js +9 -0
- data/vendor/assets/bower_components/jquery/src/event/trigger.js +199 -0
- data/vendor/assets/bower_components/jquery/src/exports/amd.js +24 -0
- data/vendor/assets/bower_components/jquery/src/exports/global.js +26 -0
- data/vendor/assets/bower_components/jquery/src/intro.js +44 -0
- data/vendor/assets/bower_components/jquery/src/jquery.js +37 -0
- data/vendor/assets/bower_components/jquery/src/manipulation.js +481 -0
- data/vendor/assets/bower_components/jquery/src/manipulation/_evalUrl.js +20 -0
- data/vendor/assets/bower_components/jquery/src/manipulation/buildFragment.js +102 -0
- data/vendor/assets/bower_components/jquery/src/manipulation/createSafeFragment.js +20 -0
- data/vendor/assets/bower_components/jquery/src/manipulation/getAll.js +21 -0
- data/vendor/assets/bower_components/jquery/src/manipulation/setGlobalEval.js +20 -0
- data/vendor/assets/bower_components/jquery/src/manipulation/support.js +33 -0
- data/vendor/assets/bower_components/jquery/src/manipulation/var/nodeNames.js +5 -0
- data/vendor/assets/bower_components/jquery/src/manipulation/var/rcheckableType.js +3 -0
- data/vendor/assets/bower_components/jquery/src/manipulation/var/rleadingWhitespace.js +3 -0
- data/vendor/assets/bower_components/jquery/src/manipulation/var/rscriptType.js +3 -0
- data/vendor/assets/bower_components/jquery/src/manipulation/var/rtagName.js +3 -0
- data/vendor/assets/bower_components/jquery/src/manipulation/wrapMap.js +27 -0
- data/vendor/assets/bower_components/jquery/src/offset.js +221 -0
- data/vendor/assets/bower_components/jquery/src/outro.js +2 -0
- data/vendor/assets/bower_components/jquery/src/queue.js +143 -0
- data/vendor/assets/bower_components/jquery/src/queue/delay.js +22 -0
- data/vendor/assets/bower_components/jquery/src/selector-native.js +211 -0
- data/vendor/assets/bower_components/jquery/src/selector-sizzle.js +14 -0
- data/vendor/assets/bower_components/jquery/src/selector.js +1 -0
- data/vendor/assets/bower_components/jquery/src/serialize.js +125 -0
- data/vendor/assets/bower_components/jquery/src/support.js +63 -0
- data/vendor/assets/bower_components/jquery/src/traversing.js +175 -0
- data/vendor/assets/bower_components/jquery/src/traversing/findFilter.js +100 -0
- data/vendor/assets/bower_components/jquery/src/traversing/var/dir.js +20 -0
- data/vendor/assets/bower_components/jquery/src/traversing/var/rneedsContext.js +6 -0
- data/vendor/assets/bower_components/jquery/src/traversing/var/siblings.js +15 -0
- data/vendor/assets/bower_components/jquery/src/var/arr.js +3 -0
- data/vendor/assets/bower_components/jquery/src/var/class2type.js +5 -0
- data/vendor/assets/bower_components/jquery/src/var/concat.js +5 -0
- data/vendor/assets/bower_components/jquery/src/var/deletedIds.js +3 -0
- data/vendor/assets/bower_components/jquery/src/var/document.js +3 -0
- data/vendor/assets/bower_components/jquery/src/var/documentElement.js +5 -0
- data/vendor/assets/bower_components/jquery/src/var/hasOwn.js +5 -0
- data/vendor/assets/bower_components/jquery/src/var/indexOf.js +5 -0
- data/vendor/assets/bower_components/jquery/src/var/pnum.js +3 -0
- data/vendor/assets/bower_components/jquery/src/var/push.js +5 -0
- data/vendor/assets/bower_components/jquery/src/var/rcssNum.js +7 -0
- data/vendor/assets/bower_components/jquery/src/var/rnotwhite.js +3 -0
- data/vendor/assets/bower_components/jquery/src/var/slice.js +5 -0
- data/vendor/assets/bower_components/jquery/src/var/support.js +5 -0
- data/vendor/assets/bower_components/jquery/src/var/toString.js +5 -0
- data/vendor/assets/bower_components/jquery/src/wrap.js +79 -0
- data/vendor/assets/bower_components/jsoneditor/CONTRIBUTING.md +15 -0
- data/vendor/assets/bower_components/jsoneditor/HISTORY.md +457 -0
- data/vendor/assets/bower_components/jsoneditor/LICENSE +176 -0
- data/vendor/assets/bower_components/jsoneditor/NOTICE +17 -0
- data/vendor/assets/bower_components/jsoneditor/README.md +155 -0
- data/vendor/assets/bower_components/jsoneditor/bower.json +32 -0
- data/vendor/assets/bower_components/jsoneditor/dist/img/jsoneditor-icons.svg +893 -0
- data/vendor/assets/bower_components/jsoneditor/dist/jsoneditor-minimalist.js +9418 -0
- data/vendor/assets/bower_components/jsoneditor/dist/jsoneditor-minimalist.map +1 -0
- data/vendor/assets/bower_components/jsoneditor/dist/jsoneditor-minimalist.min.js +35 -0
- data/vendor/assets/bower_components/jsoneditor/dist/jsoneditor.css.less +879 -0
- data/vendor/assets/bower_components/jsoneditor/dist/jsoneditor.js +35095 -0
- data/vendor/assets/bower_components/jsoneditor/dist/jsoneditor.map +1 -0
- data/vendor/assets/bower_components/jsoneditor/dist/jsoneditor.min.css +1 -0
- data/vendor/assets/bower_components/jsoneditor/dist/jsoneditor.min.js +48 -0
- data/vendor/assets/bower_components/jsoneditor/dist/which files do I need.md +41 -0
- data/vendor/assets/bower_components/jsoneditor/docs/api.md +286 -0
- data/vendor/assets/bower_components/jsoneditor/docs/shortcut_keys.md +38 -0
- data/vendor/assets/bower_components/jsoneditor/docs/usage.md +117 -0
- data/vendor/assets/bower_components/jsoneditor/examples/01_basic_usage.html +49 -0
- data/vendor/assets/bower_components/jsoneditor/examples/02_viewer.html +44 -0
- data/vendor/assets/bower_components/jsoneditor/examples/03_switch_mode.html +66 -0
- data/vendor/assets/bower_components/jsoneditor/examples/04_load_and_save.html +62 -0
- data/vendor/assets/bower_components/jsoneditor/examples/05_custom_fields_editable.html +63 -0
- data/vendor/assets/bower_components/jsoneditor/examples/06_custom_styling.html +51 -0
- data/vendor/assets/bower_components/jsoneditor/examples/07_json_schema_validation.html +71 -0
- data/vendor/assets/bower_components/jsoneditor/examples/css/darktheme.css +76 -0
- data/vendor/assets/bower_components/jsoneditor/examples/requirejs_demo/requirejs_demo.html +21 -0
- data/vendor/assets/bower_components/jsoneditor/examples/requirejs_demo/scripts/main.js +25 -0
- data/vendor/assets/bower_components/jsoneditor/examples/requirejs_demo/scripts/require.js +36 -0
- data/vendor/assets/bower_components/jsoneditor/index.js +1 -0
- data/vendor/assets/bower_components/jsoneditor/package.json +41 -0
- data/vendor/assets/bower_components/jsoneditor/src/css/contextmenu.css +233 -0
- data/vendor/assets/bower_components/jsoneditor/src/css/img/description.txt +14 -0
- data/vendor/assets/bower_components/jsoneditor/src/css/img/jsoneditor-icons.svg +893 -0
- data/vendor/assets/bower_components/jsoneditor/src/css/jsoneditor.css +433 -0
- data/vendor/assets/bower_components/jsoneditor/src/css/menu.css +110 -0
- data/vendor/assets/bower_components/jsoneditor/src/css/searchbox.css +75 -0
- data/vendor/assets/bower_components/jsoneditor/src/docs/which files do I need.md +41 -0
- data/vendor/assets/bower_components/jsoneditor/src/js/ContextMenu.js +455 -0
- data/vendor/assets/bower_components/jsoneditor/src/js/Highlighter.js +84 -0
- data/vendor/assets/bower_components/jsoneditor/src/js/History.js +252 -0
- data/vendor/assets/bower_components/jsoneditor/src/js/JSONEditor.js +371 -0
- data/vendor/assets/bower_components/jsoneditor/src/js/Node.js +3400 -0
- data/vendor/assets/bower_components/jsoneditor/src/js/SearchBox.js +295 -0
- data/vendor/assets/bower_components/jsoneditor/src/js/ace/index.js +9 -0
- data/vendor/assets/bower_components/jsoneditor/src/js/ace/theme-jsoneditor.js +144 -0
- data/vendor/assets/bower_components/jsoneditor/src/js/appendNodeFactory.js +226 -0
- data/vendor/assets/bower_components/jsoneditor/src/js/assets/jsonlint/README.md +15 -0
- data/vendor/assets/bower_components/jsoneditor/src/js/assets/jsonlint/jsonlint.js +418 -0
- data/vendor/assets/bower_components/jsoneditor/src/js/header.js +29 -0
- data/vendor/assets/bower_components/jsoneditor/src/js/modeswitcher.js +105 -0
- data/vendor/assets/bower_components/jsoneditor/src/js/textmode.js +474 -0
- data/vendor/assets/bower_components/jsoneditor/src/js/treemode.js +1150 -0
- data/vendor/assets/bower_components/jsoneditor/src/js/util.js +765 -0
- data/vendor/assets/bower_components/notifyjs/CHANGES.md +7 -0
- data/vendor/assets/bower_components/notifyjs/README.md +31 -0
- data/vendor/assets/bower_components/notifyjs/bower.json +14 -0
- data/vendor/assets/bower_components/notifyjs/dist/notify.js +586 -0
- data/vendor/assets/bower_components/notifyjs/dist/styles/metro/notify-metro.css +40 -0
- data/vendor/assets/bower_components/notifyjs/dist/styles/metro/notify-metro.js +39 -0
- data/vendor/assets/bower_components/notifyjs/examples/classes.html +49 -0
- data/vendor/assets/bower_components/notifyjs/examples/images/Mail.png +0 -0
- data/vendor/assets/bower_components/notifyjs/examples/inlines.html +111 -0
- data/vendor/assets/bower_components/notifyjs/examples/metro.html +37 -0
- data/vendor/assets/bower_components/notifyjs/examples/multi-text.html +55 -0
- data/vendor/assets/bower_components/notifyjs/examples/position.html +42 -0
- data/vendor/assets/bower_components/notifyjs/notify.jquery.json +28 -0
- data/vendor/assets/bower_components/notifyjs/package.json +18 -0
- data/vendor/assets/bower_components/vue/LICENSE +21 -0
- data/vendor/assets/bower_components/vue/bower.json +19 -0
- data/vendor/assets/bower_components/vue/dist/vue.js +10198 -0
- data/vendor/assets/bower_components/vue/dist/vue.min.js +8 -0
- data/vendor/assets/bower_components/vue/src/api/child.js +49 -0
- data/vendor/assets/bower_components/vue/src/api/data.js +159 -0
- data/vendor/assets/bower_components/vue/src/api/dom.js +226 -0
- data/vendor/assets/bower_components/vue/src/api/events.js +174 -0
- data/vendor/assets/bower_components/vue/src/api/global.js +129 -0
- data/vendor/assets/bower_components/vue/src/api/lifecycle.js +68 -0
- data/vendor/assets/bower_components/vue/src/batcher.js +98 -0
- data/vendor/assets/bower_components/vue/src/cache.js +112 -0
- data/vendor/assets/bower_components/vue/src/compiler/compile-props.js +183 -0
- data/vendor/assets/bower_components/vue/src/compiler/compile.js +630 -0
- data/vendor/assets/bower_components/vue/src/compiler/index.js +4 -0
- data/vendor/assets/bower_components/vue/src/compiler/transclude.js +144 -0
- data/vendor/assets/bower_components/vue/src/config.js +124 -0
- data/vendor/assets/bower_components/vue/src/directive.js +254 -0
- data/vendor/assets/bower_components/vue/src/directives/attr.js +59 -0
- data/vendor/assets/bower_components/vue/src/directives/class.js +70 -0
- data/vendor/assets/bower_components/vue/src/directives/cloak.js +10 -0
- data/vendor/assets/bower_components/vue/src/directives/component.js +344 -0
- data/vendor/assets/bower_components/vue/src/directives/el.js +12 -0
- data/vendor/assets/bower_components/vue/src/directives/html.js +40 -0
- data/vendor/assets/bower_components/vue/src/directives/if.js +125 -0
- data/vendor/assets/bower_components/vue/src/directives/index.js +24 -0
- data/vendor/assets/bower_components/vue/src/directives/model/checkbox.js +42 -0
- data/vendor/assets/bower_components/vue/src/directives/model/index.js +82 -0
- data/vendor/assets/bower_components/vue/src/directives/model/radio.js +33 -0
- data/vendor/assets/bower_components/vue/src/directives/model/select.js +236 -0
- data/vendor/assets/bower_components/vue/src/directives/model/text.js +132 -0
- data/vendor/assets/bower_components/vue/src/directives/on.js +59 -0
- data/vendor/assets/bower_components/vue/src/directives/prop.js +62 -0
- data/vendor/assets/bower_components/vue/src/directives/ref.js +22 -0
- data/vendor/assets/bower_components/vue/src/directives/repeat.js +770 -0
- data/vendor/assets/bower_components/vue/src/directives/show.js +8 -0
- data/vendor/assets/bower_components/vue/src/directives/style.js +110 -0
- data/vendor/assets/bower_components/vue/src/directives/text.js +14 -0
- data/vendor/assets/bower_components/vue/src/directives/transition.js +26 -0
- data/vendor/assets/bower_components/vue/src/element-directives/content.js +111 -0
- data/vendor/assets/bower_components/vue/src/element-directives/index.js +2 -0
- data/vendor/assets/bower_components/vue/src/element-directives/partial.js +73 -0
- data/vendor/assets/bower_components/vue/src/filters/array-filters.js +97 -0
- data/vendor/assets/bower_components/vue/src/filters/index.js +146 -0
- data/vendor/assets/bower_components/vue/src/instance/compile.js +200 -0
- data/vendor/assets/bower_components/vue/src/instance/events.js +139 -0
- data/vendor/assets/bower_components/vue/src/instance/init.js +89 -0
- data/vendor/assets/bower_components/vue/src/instance/misc.js +93 -0
- data/vendor/assets/bower_components/vue/src/instance/scope.js +282 -0
- data/vendor/assets/bower_components/vue/src/observer/array.js +98 -0
- data/vendor/assets/bower_components/vue/src/observer/dep.js +61 -0
- data/vendor/assets/bower_components/vue/src/observer/index.js +234 -0
- data/vendor/assets/bower_components/vue/src/observer/object.js +82 -0
- data/vendor/assets/bower_components/vue/src/parsers/directive.js +180 -0
- data/vendor/assets/bower_components/vue/src/parsers/expression.js +264 -0
- data/vendor/assets/bower_components/vue/src/parsers/path.js +348 -0
- data/vendor/assets/bower_components/vue/src/parsers/template.js +288 -0
- data/vendor/assets/bower_components/vue/src/parsers/text.js +178 -0
- data/vendor/assets/bower_components/vue/src/transition/index.js +128 -0
- data/vendor/assets/bower_components/vue/src/transition/queue.js +35 -0
- data/vendor/assets/bower_components/vue/src/transition/transition.js +357 -0
- data/vendor/assets/bower_components/vue/src/util/component.js +124 -0
- data/vendor/assets/bower_components/vue/src/util/debug.js +64 -0
- data/vendor/assets/bower_components/vue/src/util/dom.js +272 -0
- data/vendor/assets/bower_components/vue/src/util/env.js +85 -0
- data/vendor/assets/bower_components/vue/src/util/index.js +9 -0
- data/vendor/assets/bower_components/vue/src/util/lang.js +310 -0
- data/vendor/assets/bower_components/vue/src/util/options.js +357 -0
- data/vendor/assets/bower_components/vue/src/vue.js +89 -0
- data/vendor/assets/bower_components/vue/src/watcher.js +312 -0
- 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
|
+
];
|