alchemy_cms 7.0.14 → 7.1.0.pre.b1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/backport.yml +36 -0
- data/.github/workflows/test.yml +3 -2
- data/.gitignore +0 -1
- data/.standard.yml +1 -1
- data/CHANGELOG.md +144 -33
- data/Gemfile +7 -11
- data/README.md +10 -8
- data/alchemy_cms.gemspec +4 -3
- data/app/assets/config/alchemy_manifest.js +0 -1
- data/app/assets/javascripts/alchemy/admin.js +1 -19
- data/app/assets/javascripts/alchemy/alchemy.confirm_dialog.js.coffee +2 -3
- data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +19 -34
- data/app/assets/javascripts/alchemy/alchemy.elements_window.js.coffee +38 -13
- data/app/assets/javascripts/alchemy/alchemy.file_progress.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.fixed_elements.js +32 -25
- data/app/assets/javascripts/alchemy/alchemy.growler.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.image_overlay.coffee +3 -5
- data/app/assets/javascripts/alchemy/alchemy.initializer.js.coffee +0 -57
- data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +22 -63
- data/app/assets/javascripts/alchemy/alchemy.list_filter.js.coffee +2 -2
- data/app/assets/javascripts/alchemy/alchemy.preview.js.coffee +5 -4
- data/app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee +5 -5
- data/app/assets/javascripts/alchemy/templates/index.js +0 -2
- data/app/assets/javascripts/alchemy/templates/node_folder.hbs +1 -1
- data/app/assets/javascripts/alchemy/templates/page.hbs +1 -1
- data/app/assets/javascripts/alchemy/templates/page_folder.hbs +2 -2
- data/app/assets/stylesheets/alchemy/_custom-properties.scss +82 -0
- data/app/assets/stylesheets/alchemy/_mixins.scss +38 -30
- data/app/assets/stylesheets/alchemy/_variables.scss +12 -5
- data/app/assets/stylesheets/alchemy/admin.scss +3 -4
- data/app/assets/stylesheets/alchemy/archive.scss +107 -50
- data/app/assets/stylesheets/alchemy/attachments.scss +5 -4
- data/app/assets/stylesheets/alchemy/buttons.scss +38 -164
- data/app/assets/stylesheets/alchemy/dashboard.scss +31 -6
- data/app/assets/stylesheets/alchemy/dialogs.scss +12 -28
- data/app/assets/stylesheets/alchemy/elements.scss +273 -282
- data/app/assets/stylesheets/alchemy/flash.scss +20 -12
- data/app/assets/stylesheets/alchemy/forms.scss +21 -34
- data/app/assets/stylesheets/alchemy/frame.scss +11 -32
- data/app/assets/stylesheets/alchemy/hints.scss +4 -62
- data/app/assets/stylesheets/alchemy/image_library.scss +36 -33
- data/app/assets/stylesheets/alchemy/labels.scss +4 -1
- data/app/assets/stylesheets/alchemy/menubar.scss +7 -6
- data/app/assets/stylesheets/alchemy/navigation.scss +27 -15
- data/app/assets/stylesheets/alchemy/nodes.scss +11 -7
- data/app/assets/stylesheets/alchemy/notices.scss +16 -4
- data/app/assets/stylesheets/alchemy/page-select.scss +10 -2
- data/app/assets/stylesheets/alchemy/pagination.scss +22 -13
- data/app/assets/stylesheets/alchemy/preview_window.scss +4 -8
- data/app/assets/stylesheets/alchemy/resource_info.scss +7 -5
- data/app/assets/stylesheets/alchemy/selects.scss +49 -42
- data/app/assets/stylesheets/alchemy/shoelace.scss +345 -0
- data/app/assets/stylesheets/alchemy/sitemap.scss +24 -14
- data/app/assets/stylesheets/alchemy/spinner.scss +9 -19
- data/app/assets/stylesheets/alchemy/tables.scss +16 -24
- data/app/assets/stylesheets/alchemy/tags.scss +4 -0
- data/app/assets/stylesheets/alchemy/toolbar.scss +29 -25
- data/app/assets/stylesheets/alchemy/upload.scss +140 -89
- data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +80 -108
- data/app/components/alchemy/admin/node_select.rb +39 -0
- data/app/components/alchemy/admin/page_select.rb +42 -0
- data/app/components/alchemy/ingredients/audio_view.rb +1 -1
- data/app/components/alchemy/ingredients/base_view.rb +1 -1
- data/app/components/alchemy/ingredients/boolean_view.rb +1 -1
- data/app/components/alchemy/ingredients/datetime_view.rb +1 -1
- data/app/components/alchemy/ingredients/file_view.rb +1 -1
- data/app/components/alchemy/ingredients/headline_view.rb +7 -16
- data/app/components/alchemy/ingredients/link_view.rb +1 -1
- data/app/components/alchemy/ingredients/page_view.rb +1 -1
- data/app/components/alchemy/ingredients/picture_view.rb +1 -1
- data/app/components/alchemy/ingredients/richtext_view.rb +1 -1
- data/app/components/alchemy/ingredients/text_view.rb +1 -1
- data/app/components/alchemy/ingredients/video_view.rb +1 -1
- data/app/controllers/alchemy/admin/base_controller.rb +5 -6
- data/app/controllers/alchemy/admin/elements_controller.rb +63 -35
- data/app/controllers/alchemy/admin/languages_controller.rb +1 -2
- data/app/controllers/alchemy/base_controller.rb +4 -2
- data/app/controllers/concerns/alchemy/admin/current_language.rb +1 -5
- data/app/controllers/concerns/alchemy/admin/uploader_responses.rb +1 -1
- data/app/controllers/concerns/alchemy/site_redirects.rb +1 -1
- data/app/decorators/alchemy/element_editor.rb +0 -2
- data/app/helpers/alchemy/admin/attachments_helper.rb +6 -5
- data/app/helpers/alchemy/admin/base_helper.rb +17 -12
- data/app/helpers/alchemy/admin/ingredients_helper.rb +4 -1
- data/app/helpers/alchemy/admin/pages_helper.rb +5 -11
- data/app/helpers/alchemy/base_helper.rb +47 -13
- data/app/javascript/alchemy_admin/components/alchemy_html_element.js +129 -0
- data/app/javascript/alchemy_admin/components/button.js +59 -0
- data/app/javascript/alchemy_admin/components/char_counter.js +40 -0
- data/app/javascript/alchemy_admin/components/datepicker.js +39 -0
- data/app/javascript/alchemy_admin/components/dialog_link.js +45 -0
- data/app/javascript/alchemy_admin/components/element_editor/publish_element_button.js +36 -0
- data/app/javascript/alchemy_admin/components/element_editor.js +553 -0
- data/app/javascript/alchemy_admin/components/ingredient_group.js +54 -0
- data/app/javascript/alchemy_admin/components/link_buttons/link_button.js +48 -0
- data/app/javascript/alchemy_admin/components/link_buttons/unlink_button.js +38 -0
- data/app/javascript/alchemy_admin/components/link_buttons.js +79 -0
- data/app/javascript/alchemy_admin/components/node_select.js +45 -0
- data/app/javascript/alchemy_admin/components/overlay.js +18 -0
- data/app/javascript/alchemy_admin/components/page_select.js +63 -0
- data/app/javascript/alchemy_admin/components/remote_select.js +134 -0
- data/app/javascript/alchemy_admin/components/select.js +12 -0
- data/app/javascript/alchemy_admin/components/spinner.js +31 -0
- data/app/javascript/alchemy_admin/components/tinymce.js +146 -0
- data/app/javascript/alchemy_admin/components/uploader/file_upload.js +266 -0
- data/app/javascript/alchemy_admin/components/uploader/progress.js +258 -0
- data/app/javascript/alchemy_admin/components/uploader.js +132 -0
- data/app/javascript/alchemy_admin/dirty.js +49 -0
- data/app/javascript/alchemy_admin/file_editors.js +1 -1
- data/app/javascript/alchemy_admin/gui.js +14 -0
- data/app/javascript/alchemy_admin/i18n.js +12 -8
- data/app/javascript/alchemy_admin/image_cropper.js +6 -3
- data/app/javascript/alchemy_admin/image_loader.js +7 -15
- data/app/javascript/alchemy_admin/ingredient_anchor_link.js +2 -5
- data/app/javascript/alchemy_admin/initializer.js +65 -0
- data/app/javascript/alchemy_admin/locales/en.js +31 -0
- data/app/javascript/alchemy_admin/picture_editors.js +2 -2
- data/app/javascript/alchemy_admin/picture_selector.js +38 -0
- data/app/javascript/alchemy_admin/please_wait_overlay.js +8 -0
- data/app/javascript/alchemy_admin/sortable_elements.js +78 -0
- data/app/javascript/alchemy_admin/spinner.js +36 -0
- data/app/javascript/alchemy_admin/tags_autocomplete.js +46 -0
- data/app/javascript/alchemy_admin/utils/ajax.js +6 -5
- data/app/javascript/alchemy_admin/utils/dom_helpers.js +20 -0
- data/app/javascript/alchemy_admin/utils/format.js +11 -0
- data/app/javascript/alchemy_admin/utils/string_conversions.js +10 -0
- data/app/javascript/alchemy_admin.js +70 -13
- data/app/javascript/menubar.js +10 -0
- data/app/models/alchemy/attachment.rb +9 -11
- data/app/models/alchemy/element.rb +11 -0
- data/app/models/alchemy/ingredients/audio.rb +0 -11
- data/app/models/alchemy/ingredients/richtext.rb +1 -10
- data/app/models/alchemy/ingredients/video.rb +0 -12
- data/app/models/alchemy/node.rb +4 -0
- data/app/models/alchemy/page/page_elements.rb +2 -11
- data/app/models/alchemy/page/page_natures.rb +10 -2
- data/app/models/alchemy/page.rb +9 -51
- data/app/models/alchemy/picture/url.rb +1 -9
- data/app/serializers/alchemy/page_tree_serializer.rb +2 -1
- data/app/services/alchemy/copy_page.rb +98 -0
- data/app/views/alchemy/_menubar.html.erb +17 -13
- data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +14 -10
- data/app/views/alchemy/admin/attachments/_attachment.html.erb +44 -36
- data/app/views/alchemy/admin/attachments/_replace_button.html.erb +15 -21
- data/app/views/alchemy/admin/attachments/archive_overlay.js.erb +0 -1
- data/app/views/alchemy/admin/attachments/assign.js.erb +1 -1
- data/app/views/alchemy/admin/attachments/index.html.erb +6 -4
- data/app/views/alchemy/admin/attachments/show.html.erb +8 -8
- data/app/views/alchemy/admin/clipboard/clear.js.erb +1 -1
- data/app/views/alchemy/admin/clipboard/index.html.erb +3 -7
- data/app/views/alchemy/admin/clipboard/insert.js.erb +1 -1
- data/app/views/alchemy/admin/crop.html.erb +1 -1
- data/app/views/alchemy/admin/dashboard/_locked_pages.html.erb +1 -1
- data/app/views/alchemy/admin/dashboard/index.html.erb +13 -11
- data/app/views/alchemy/admin/dashboard/info.html.erb +7 -7
- data/app/views/alchemy/admin/elements/_add_nested_element_form.html.erb +21 -23
- data/app/views/alchemy/admin/elements/_element.html.erb +52 -44
- data/app/views/alchemy/admin/elements/_footer.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_form.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_header.html.erb +11 -12
- data/app/views/alchemy/admin/elements/_toolbar.html.erb +33 -45
- data/app/views/alchemy/admin/elements/create.js.erb +7 -15
- data/app/views/alchemy/admin/elements/destroy.js.erb +0 -2
- data/app/views/alchemy/admin/elements/index.html.erb +27 -24
- data/app/views/alchemy/admin/elements/new.html.erb +9 -11
- data/app/views/alchemy/admin/ingredients/_file_fields.html.erb +2 -2
- data/app/views/alchemy/admin/ingredients/_picture_fields.html.erb +3 -3
- data/app/views/alchemy/admin/ingredients/_video_fields.html.erb +1 -2
- data/app/views/alchemy/admin/languages/_form.html.erb +2 -3
- data/app/views/alchemy/admin/languages/_language.html.erb +15 -8
- data/app/views/alchemy/admin/languages/_table.html.erb +1 -0
- data/app/views/alchemy/admin/layoutpages/_layoutpage.html.erb +28 -16
- data/app/views/alchemy/admin/layoutpages/index.html.erb +2 -2
- data/app/views/alchemy/admin/legacy_page_urls/_legacy_page_url.html.erb +12 -8
- data/app/views/alchemy/admin/legacy_page_urls/_new.html.erb +1 -1
- data/app/views/alchemy/admin/nodes/_form.html.erb +20 -21
- data/app/views/alchemy/admin/nodes/_node.html.erb +39 -34
- data/app/views/alchemy/admin/nodes/index.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_anchor_link.html.erb +4 -4
- data/app/views/alchemy/admin/pages/_create_language_form.html.erb +2 -2
- data/app/views/alchemy/admin/pages/_current_page.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_external_link.html.erb +4 -4
- data/app/views/alchemy/admin/pages/_file_link.html.erb +5 -5
- data/app/views/alchemy/admin/pages/_form.html.erb +10 -21
- data/app/views/alchemy/admin/pages/_internal_link.html.erb +4 -4
- data/app/views/alchemy/admin/pages/_locked_page.html.erb +2 -2
- data/app/views/alchemy/admin/pages/_new_page_form.html.erb +4 -17
- data/app/views/alchemy/admin/pages/_page.html.erb +76 -72
- data/app/views/alchemy/admin/pages/_page_infos.html.erb +23 -7
- data/app/views/alchemy/admin/pages/_page_layout_filter.html.erb +2 -1
- data/app/views/alchemy/admin/pages/_page_status.html.erb +11 -21
- data/app/views/alchemy/admin/pages/_publication_fields.html.erb +2 -5
- data/app/views/alchemy/admin/pages/_table.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_table_row.html.erb +43 -39
- data/app/views/alchemy/admin/pages/_toolbar.html.erb +43 -38
- data/app/views/alchemy/admin/pages/configure.html.erb +12 -14
- data/app/views/alchemy/admin/pages/edit.html.erb +80 -103
- data/app/views/alchemy/admin/pages/info.html.erb +20 -11
- data/app/views/alchemy/admin/pages/link.html.erb +22 -16
- data/app/views/alchemy/admin/pages/new.html.erb +9 -11
- data/app/views/alchemy/admin/pages/unlock.js.erb +10 -3
- data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +15 -13
- data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +3 -5
- data/app/views/alchemy/admin/partials/_routes.html.erb +10 -2
- data/app/views/alchemy/admin/partials/_site_select.html.erb +6 -5
- data/app/views/alchemy/admin/partials/_toolbar_button.html.erb +28 -23
- data/app/views/alchemy/admin/pictures/_archive.html.erb +5 -5
- data/app/views/alchemy/admin/pictures/_archive_overlay.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +21 -23
- data/app/views/alchemy/admin/pictures/_infos.html.erb +2 -6
- data/app/views/alchemy/admin/pictures/_picture.html.erb +15 -17
- data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +17 -16
- data/app/views/alchemy/admin/pictures/_tag_list.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/archive_overlay.js.erb +1 -1
- data/app/views/alchemy/admin/pictures/assign.js.erb +1 -1
- data/app/views/alchemy/admin/pictures/index.html.erb +34 -30
- data/app/views/alchemy/admin/pictures/show.html.erb +3 -3
- data/app/views/alchemy/admin/resources/_filter.html.erb +2 -2
- data/app/views/alchemy/admin/resources/_form.html.erb +2 -2
- data/app/views/alchemy/admin/resources/_per_page_select.html.erb +1 -1
- data/app/views/alchemy/admin/resources/_resource.html.erb +16 -9
- data/app/views/alchemy/admin/resources/_table.html.erb +4 -1
- data/app/views/alchemy/admin/resources/index.html.erb +22 -19
- data/app/views/alchemy/admin/sites/index.html.erb +2 -1
- data/app/views/alchemy/admin/styleguide/index.html.erb +54 -28
- data/app/views/alchemy/admin/tags/_tag.html.erb +16 -18
- data/app/views/alchemy/admin/tags/index.html.erb +15 -12
- data/app/views/alchemy/admin/tinymce/_setup.html.erb +29 -0
- data/app/views/alchemy/admin/uploader/_button.html.erb +23 -29
- data/app/views/alchemy/admin/uploader/_setup.html.erb +3 -8
- data/app/views/alchemy/base/500.html.erb +1 -1
- data/app/views/alchemy/base/error_notice.js.erb +0 -1
- data/app/views/alchemy/ingredients/_boolean_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/_datetime_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/_file_editor.html.erb +5 -5
- data/app/views/alchemy/ingredients/_link_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/_node_editor.html.erb +6 -19
- data/app/views/alchemy/ingredients/_page_editor.html.erb +7 -19
- data/app/views/alchemy/ingredients/_picture_editor.html.erb +2 -2
- data/app/views/alchemy/ingredients/_richtext_editor.html.erb +6 -15
- data/app/views/alchemy/ingredients/_select_editor.html.erb +2 -1
- data/app/views/alchemy/ingredients/_text_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/shared/_anchor.html.erb +1 -1
- data/app/views/alchemy/ingredients/shared/_link_tools.html.erb +10 -20
- data/app/views/alchemy/ingredients/shared/_picture_tools.html.erb +42 -49
- data/app/views/kaminari/alchemy/_first_page.html.erb +4 -2
- data/app/views/kaminari/alchemy/_gap.html.erb +1 -1
- data/app/views/kaminari/alchemy/_last_page.html.erb +4 -2
- data/app/views/kaminari/alchemy/_next_page.html.erb +4 -2
- data/app/views/kaminari/alchemy/_prev_page.html.erb +4 -2
- data/app/views/layouts/alchemy/admin.html.erb +10 -29
- data/config/alchemy/modules.yml +30 -30
- data/config/importmap.rb +10 -1
- data/config/initializers/rails_live_reload.rb +13 -0
- data/config/locales/alchemy.en.yml +23 -9
- data/config/routes.rb +2 -1
- data/lib/alchemy/auth_accessors.rb +6 -1
- data/lib/alchemy/controller_actions.rb +17 -4
- data/lib/alchemy/dev_support/live_reload_watcher.rb +5 -0
- data/lib/alchemy/engine.rb +8 -2
- data/lib/alchemy/forms/builder.rb +18 -12
- data/lib/alchemy/modules.rb +2 -2
- data/lib/alchemy/resources_helper.rb +3 -3
- data/lib/alchemy/routing_constraints.rb +1 -1
- data/lib/alchemy/test_support/capybara_helpers.rb +8 -5
- data/lib/alchemy/test_support/rspec_matchers.rb +14 -0
- data/lib/alchemy/test_support/shared_uploader_examples.rb +1 -1
- data/lib/alchemy/tinymce.rb +8 -3
- data/lib/alchemy/version.rb +1 -1
- data/package.json +14 -5
- data/vendor/assets/fonts/remixicon.eot +0 -0
- data/vendor/assets/fonts/remixicon.svg +7816 -0
- data/vendor/assets/fonts/remixicon.ttf +0 -0
- data/vendor/assets/fonts/remixicon.woff +0 -0
- data/vendor/assets/fonts/remixicon.woff2 +0 -0
- data/vendor/assets/stylesheets/remixicon.scss +10480 -0
- metadata +85 -97
- data/.gem_release.yml +0 -8
- data/app/assets/javascripts/alchemy/alchemy.autocomplete.js.coffee +0 -30
- data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +0 -53
- data/app/assets/javascripts/alchemy/alchemy.buttons.js.coffee +0 -45
- data/app/assets/javascripts/alchemy/alchemy.char_counter.js.coffee +0 -19
- data/app/assets/javascripts/alchemy/alchemy.dirty.js.coffee +0 -59
- data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +0 -79
- data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +0 -267
- data/app/assets/javascripts/alchemy/alchemy.gui.js.coffee +0 -27
- data/app/assets/javascripts/alchemy/alchemy.spinner.js +0 -32
- data/app/assets/javascripts/alchemy/alchemy.tooltips.coffee +0 -10
- data/app/assets/javascripts/alchemy/alchemy.uploader.js.coffee +0 -131
- data/app/assets/javascripts/alchemy/menubar.js.coffee +0 -8
- data/app/assets/javascripts/alchemy/node_select.js +0 -39
- data/app/assets/javascripts/alchemy/page_select.js +0 -46
- data/app/assets/javascripts/alchemy/templates/node.hbs +0 -16
- data/app/assets/javascripts/alchemy/templates/spinner.hbs +0 -7
- data/app/assets/stylesheets/alchemy/jquery-ui.scss +0 -435
- data/app/javascript/alchemy_admin/datepicker.js +0 -40
- data/app/javascript/alchemy_admin/tinymce.js +0 -146
- data/app/javascript/alchemy_admin/translations.js +0 -32
- data/app/views/alchemy/admin/elements/fold.js.erb +0 -33
- data/app/views/alchemy/admin/elements/order.js.erb +0 -11
- data/app/views/alchemy/admin/elements/publish.js.erb +0 -21
- data/app/views/alchemy/admin/elements/update.js.erb +0 -27
- data/vendor/assets/fonts/fa-regular-400.eot +0 -0
- data/vendor/assets/fonts/fa-regular-400.svg +0 -803
- data/vendor/assets/fonts/fa-regular-400.ttf +0 -0
- data/vendor/assets/fonts/fa-regular-400.woff +0 -0
- data/vendor/assets/fonts/fa-regular-400.woff2 +0 -0
- data/vendor/assets/fonts/fa-solid-900.eot +0 -0
- data/vendor/assets/fonts/fa-solid-900.svg +0 -4938
- data/vendor/assets/fonts/fa-solid-900.ttf +0 -0
- data/vendor/assets/fonts/fa-solid-900.woff +0 -0
- data/vendor/assets/fonts/fa-solid-900.woff2 +0 -0
- data/vendor/assets/javascripts/fileupload/jquery.fileupload-process.js +0 -178
- data/vendor/assets/javascripts/fileupload/jquery.fileupload-validate.js +0 -125
- data/vendor/assets/javascripts/fileupload/jquery.fileupload.js +0 -1502
- data/vendor/assets/javascripts/fileupload/jquery.iframe-transport.js +0 -224
- data/vendor/assets/javascripts/jquery-ui/data.js +0 -45
- data/vendor/assets/javascripts/jquery-ui/ie.js +0 -20
- data/vendor/assets/javascripts/jquery-ui/keycode.js +0 -51
- data/vendor/assets/javascripts/jquery-ui/plugin.js +0 -49
- data/vendor/assets/javascripts/jquery-ui/safe-active-element.js +0 -46
- data/vendor/assets/javascripts/jquery-ui/safe-blur.js +0 -27
- data/vendor/assets/javascripts/jquery-ui/scroll-parent.js +0 -50
- data/vendor/assets/javascripts/jquery-ui/unique-id.js +0 -54
- data/vendor/assets/javascripts/jquery-ui/version.js +0 -20
- data/vendor/assets/javascripts/jquery-ui/widget.js +0 -754
- data/vendor/assets/javascripts/jquery-ui/widgets/draggable.js +0 -1268
- data/vendor/assets/javascripts/jquery-ui/widgets/mouse.js +0 -241
- data/vendor/assets/javascripts/jquery-ui/widgets/sortable.js +0 -1623
- data/vendor/assets/javascripts/jquery-ui/widgets/tabs.js +0 -931
- data/vendor/assets/javascripts/jquery_plugins/jquery.scrollTo.min.js +0 -7
- data/vendor/assets/javascripts/jquery_plugins/jquery.ui.tabspaging.js +0 -296
- data/vendor/assets/stylesheets/fontawesome/_animated.scss +0 -20
- data/vendor/assets/stylesheets/fontawesome/_bordered-pulled.scss +0 -20
- data/vendor/assets/stylesheets/fontawesome/_core.scss +0 -21
- data/vendor/assets/stylesheets/fontawesome/_fixed-width.scss +0 -6
- data/vendor/assets/stylesheets/fontawesome/_icons.scss +0 -1441
- data/vendor/assets/stylesheets/fontawesome/_larger.scss +0 -23
- data/vendor/assets/stylesheets/fontawesome/_list.scss +0 -18
- data/vendor/assets/stylesheets/fontawesome/_mixins.scss +0 -56
- data/vendor/assets/stylesheets/fontawesome/_rotated-flipped.scss +0 -24
- data/vendor/assets/stylesheets/fontawesome/_screen-reader.scss +0 -5
- data/vendor/assets/stylesheets/fontawesome/_stacked.scss +0 -31
- data/vendor/assets/stylesheets/fontawesome/_variables.scss +0 -1458
- data/vendor/assets/stylesheets/fontawesome/fontawesome.scss +0 -16
- data/vendor/assets/stylesheets/fontawesome/regular.scss +0 -23
- data/vendor/assets/stylesheets/fontawesome/solid.scss +0 -24
@@ -1,59 +0,0 @@
|
|
1
|
-
window.Alchemy = {} if typeof (window.Alchemy) is "undefined"
|
2
|
-
|
3
|
-
$.extend Alchemy,
|
4
|
-
|
5
|
-
ElementDirtyObserver: (selector) ->
|
6
|
-
$(selector).find('input[type="text"], select').change (e) =>
|
7
|
-
$content = $(e.target)
|
8
|
-
$content.addClass('dirty')
|
9
|
-
@setElementDirty $content.closest(".element-editor")
|
10
|
-
return
|
11
|
-
|
12
|
-
setElementDirty: (element) ->
|
13
|
-
$element = $(element)
|
14
|
-
$element.addClass('dirty')
|
15
|
-
window.onbeforeunload = @pageUnload
|
16
|
-
|
17
|
-
pageUnload: ->
|
18
|
-
Alchemy.t('page_dirty_notice')
|
19
|
-
|
20
|
-
setElementClean: (element) ->
|
21
|
-
$element = $(element)
|
22
|
-
$element.removeClass('dirty')
|
23
|
-
$element.find('> .element-body .dirty').removeClass('dirty')
|
24
|
-
window.onbeforeunload = undefined
|
25
|
-
|
26
|
-
isPageDirty: ->
|
27
|
-
$('#element_area').find('.element-editor.dirty').length > 0
|
28
|
-
|
29
|
-
isElementDirty: (element) ->
|
30
|
-
$(element).hasClass('dirty')
|
31
|
-
|
32
|
-
checkPageDirtyness: (element) ->
|
33
|
-
callback = undefined
|
34
|
-
if $(element).is("form")
|
35
|
-
callback = ->
|
36
|
-
$form = $("<form action=\"#{element.action}\" method=\"POST\" style=\"display: none\" />")
|
37
|
-
$form.append $(element).find("input")
|
38
|
-
$form.appendTo "body"
|
39
|
-
Alchemy.pleaseWaitOverlay()
|
40
|
-
$form.submit()
|
41
|
-
else if $(element).is("a")
|
42
|
-
callback = ->
|
43
|
-
Turbo.visit(element.pathname)
|
44
|
-
if Alchemy.isPageDirty()
|
45
|
-
Alchemy.openConfirmDialog Alchemy.t('page_dirty_notice'),
|
46
|
-
title: Alchemy.t('warning')
|
47
|
-
ok_label: Alchemy.t('ok')
|
48
|
-
cancel_label: Alchemy.t('cancel')
|
49
|
-
on_ok: ->
|
50
|
-
window.onbeforeunload = undefined
|
51
|
-
callback()
|
52
|
-
false
|
53
|
-
else
|
54
|
-
true
|
55
|
-
|
56
|
-
PageLeaveObserver: ->
|
57
|
-
$('#main_navi a').click (event) ->
|
58
|
-
unless Alchemy.checkPageDirtyness(event.currentTarget)
|
59
|
-
event.preventDefault()
|
@@ -1,79 +0,0 @@
|
|
1
|
-
#= require jquery-ui/widgets/draggable
|
2
|
-
#= require jquery-ui/widgets/sortable
|
3
|
-
#
|
4
|
-
window.Alchemy = {} if typeof (window.Alchemy) is "undefined"
|
5
|
-
|
6
|
-
$.extend Alchemy,
|
7
|
-
|
8
|
-
SortableElements: (page_id, form_token, selector = '#element_area .sortable-elements') ->
|
9
|
-
Alchemy.initializedSortableElements = false
|
10
|
-
$sortable_area = $(selector)
|
11
|
-
|
12
|
-
getTinymceIDs = (ui) ->
|
13
|
-
ids = []
|
14
|
-
$textareas = ui.item.find('textarea.has_tinymce')
|
15
|
-
$($textareas).each ->
|
16
|
-
id = this.id.replace(/tinymce_/, '')
|
17
|
-
ids.push parseInt(id, 10)
|
18
|
-
return ids
|
19
|
-
|
20
|
-
sortable_options =
|
21
|
-
items: "> .element-editor"
|
22
|
-
handle: "> .element-header .element-handle"
|
23
|
-
placeholder: "droppable_element_placeholder"
|
24
|
-
dropOnEmpty: true
|
25
|
-
opacity: 0.5
|
26
|
-
cursor: "move"
|
27
|
-
containment: $('#element_area')
|
28
|
-
tolerance: "pointer"
|
29
|
-
update: (event, ui) ->
|
30
|
-
# This callback is called twice for both elements, the source and the receiving
|
31
|
-
# but, we only want to call ajax callback once on the receiving element.
|
32
|
-
return if Alchemy.initializedSortableElements
|
33
|
-
$this = ui.item.parent().closest('.ui-sortable')
|
34
|
-
params = {}
|
35
|
-
Alchemy.initializedSortableElements = true
|
36
|
-
element_ids = $.map $this.children(), (child) ->
|
37
|
-
$(child).attr("data-element-id")
|
38
|
-
parent_element_id = ui.item.parent().closest("[data-element-id]").data('element-id')
|
39
|
-
params =
|
40
|
-
page_id: page_id
|
41
|
-
authenticity_token: encodeURIComponent(form_token)
|
42
|
-
element_ids: element_ids
|
43
|
-
if parent_element_id?
|
44
|
-
params['parent_element_id'] = parent_element_id
|
45
|
-
$(event.target).css("cursor", "progress")
|
46
|
-
$.ajax
|
47
|
-
url: Alchemy.routes.order_admin_elements_path
|
48
|
-
type: "POST"
|
49
|
-
data: params
|
50
|
-
complete: ->
|
51
|
-
Alchemy.initializedSortableElements = false
|
52
|
-
$(event.target).css("cursor", "")
|
53
|
-
return
|
54
|
-
start: (event, ui) ->
|
55
|
-
$this = $(this)
|
56
|
-
name = ui.item.data('element-name')
|
57
|
-
$dropzone = $("[data-droppable-elements~='#{name}']")
|
58
|
-
ids = getTinymceIDs(ui)
|
59
|
-
$this.sortable('option', 'connectWith', $dropzone)
|
60
|
-
$this.sortable('refresh')
|
61
|
-
$dropzone.css('minHeight', 36)
|
62
|
-
ui.item.addClass('dragged')
|
63
|
-
if ui.item.hasClass('compact')
|
64
|
-
ui.placeholder.addClass('compact').css
|
65
|
-
height: ui.item.outerHeight()
|
66
|
-
Alchemy.Tinymce.remove(ids)
|
67
|
-
return
|
68
|
-
stop: (event, ui) ->
|
69
|
-
ids = getTinymceIDs(ui)
|
70
|
-
name = ui.item.data('element-name')
|
71
|
-
$dropzone = $("[data-droppable-elements~='#{name}']")
|
72
|
-
$dropzone.css('minHeight', '')
|
73
|
-
ui.item.removeClass('dragged')
|
74
|
-
Alchemy.Tinymce.init(ids)
|
75
|
-
return
|
76
|
-
|
77
|
-
$sortable_area.sortable(sortable_options)
|
78
|
-
$sortable_area.find('.nested-elements').sortable(sortable_options)
|
79
|
-
return
|
@@ -1,267 +0,0 @@
|
|
1
|
-
window.Alchemy = {} if typeof(window.Alchemy) is 'undefined'
|
2
|
-
|
3
|
-
# Handlers for element editors.
|
4
|
-
#
|
5
|
-
# It provides folding of element editors and
|
6
|
-
# selecting element editors from the preview frame
|
7
|
-
# and the elenents window.
|
8
|
-
#
|
9
|
-
Alchemy.ElementEditors =
|
10
|
-
|
11
|
-
# Binds all events to element editor partials.
|
12
|
-
#
|
13
|
-
# Calles once per page load.
|
14
|
-
#
|
15
|
-
init: ->
|
16
|
-
@element_area = $("#element_area")
|
17
|
-
@bindEvents()
|
18
|
-
@expandIngredientGroups()
|
19
|
-
return
|
20
|
-
|
21
|
-
# Binds click events on several DOM elements from element editors
|
22
|
-
# Uses event delegation, so it is not necessary to rebind these events.
|
23
|
-
bindEvents: ->
|
24
|
-
$('body').on 'click', (e) =>
|
25
|
-
@onClickBody(e)
|
26
|
-
@element_area.on "click", ".element-editor", (e) =>
|
27
|
-
@onClickElement(e)
|
28
|
-
@element_area.on "dblclick", ".element-header", (e) =>
|
29
|
-
@onDoubleClickElement(e)
|
30
|
-
@element_area.on "click", "[data-element-toggle]", (e) =>
|
31
|
-
@onClickToggle(e)
|
32
|
-
# Binds the custom FocusElementEditor event
|
33
|
-
@element_area.on "FocusElementEditor.Alchemy", '.element-editor', (e) =>
|
34
|
-
@onFocusElement(e)
|
35
|
-
# Binds the custom SaveElement event
|
36
|
-
@element_area.on "SaveElement.Alchemy", '.element-editor', (e, data) =>
|
37
|
-
@onSaveElement(e, data)
|
38
|
-
@element_area.on "click", '[data-toggle-ingredient-group]', (e) =>
|
39
|
-
@onToggleIngredientGroup(e)
|
40
|
-
# Listen to postMessage messages from the preview frame
|
41
|
-
window.addEventListener 'message', (e) =>
|
42
|
-
@onMessage(e.data)
|
43
|
-
true
|
44
|
-
return
|
45
|
-
|
46
|
-
# Expands ingredient groups that are stored in sessionStorage as expanded
|
47
|
-
expandIngredientGroups: ->
|
48
|
-
if $expanded_ingredient_groups = sessionStorage.getItem('Alchemy.expanded_ingredient_groups')
|
49
|
-
for header_id in JSON.parse($expanded_ingredient_groups) then do (header_id) =>
|
50
|
-
$('#' + header_id).closest('.ingredient-group').addClass('expanded');
|
51
|
-
|
52
|
-
# Selects and scrolls to element with given id in the preview window.
|
53
|
-
#
|
54
|
-
focusElementPreview: (element_id) ->
|
55
|
-
Alchemy.PreviewWindow.postMessage
|
56
|
-
message: 'Alchemy.focusElement'
|
57
|
-
element_id: element_id
|
58
|
-
return
|
59
|
-
|
60
|
-
# Selects element
|
61
|
-
# Scrolls to element
|
62
|
-
# Unfold if folded
|
63
|
-
# Also chooses the right fixed elements tab, if necessary.
|
64
|
-
# Can be triggered through custom event 'FocusElementEditor.Alchemy'
|
65
|
-
# Used by the elements on click events in the preview frame.
|
66
|
-
focusElement: ($element) ->
|
67
|
-
element_id = $element.attr('id').replace(/\D/g, "")
|
68
|
-
Alchemy.ElementsWindow.show()
|
69
|
-
@selectTabForElement($element)
|
70
|
-
# If we have folded parents we need to unfold each of them
|
71
|
-
# and then finally scroll to or unfold ourself
|
72
|
-
$folded_parents = $element.parents('.element-editor.folded')
|
73
|
-
if $folded_parents.length > 0
|
74
|
-
@unfoldParents $folded_parents, =>
|
75
|
-
@scrollToOrUnfold(element_id)
|
76
|
-
return
|
77
|
-
else
|
78
|
-
@scrollToOrUnfold(element_id)
|
79
|
-
return
|
80
|
-
|
81
|
-
# Selects tab for given element
|
82
|
-
selectTabForElement: ($element) ->
|
83
|
-
$tabs = $("#fixed-elements .sortable-elements")
|
84
|
-
if $tabs.size() > 0
|
85
|
-
$tab = $element.closest(".sortable-elements")
|
86
|
-
$("#fixed-elements").tabs("option", "active", $tabs.index($tab))
|
87
|
-
|
88
|
-
# Marks an element as selected in the element window and scrolls to it.
|
89
|
-
#
|
90
|
-
selectElement: ($element, scroll = false) ->
|
91
|
-
$("#element_area .element-editor").not($element[0]).removeClass("selected")
|
92
|
-
$element.addClass("selected")
|
93
|
-
@scrollToElement($element) if scroll
|
94
|
-
return
|
95
|
-
|
96
|
-
# Unfolds given parents until the last one is reached, then calls callback
|
97
|
-
unfoldParents: ($folded_parents, callback) ->
|
98
|
-
last_parent = $folded_parents[$folded_parents.length - 1]
|
99
|
-
$folded_parents.each (_index, parent_element) =>
|
100
|
-
parent_id = parent_element.id.replace(/\D/g, "")
|
101
|
-
if last_parent == parent_element
|
102
|
-
@scrollToOrUnfold(parent_id, callback)
|
103
|
-
else
|
104
|
-
@scrollToOrUnfold(parent_id)
|
105
|
-
return
|
106
|
-
return
|
107
|
-
|
108
|
-
# Scrolls to element with given id
|
109
|
-
#
|
110
|
-
# If it's folded it unfolds it.
|
111
|
-
#
|
112
|
-
# Also takes an optional callback that gets triggered after element is unfolded.
|
113
|
-
#
|
114
|
-
scrollToOrUnfold: (element_id, callback) ->
|
115
|
-
$el = $("#element_#{element_id}")
|
116
|
-
if $el.hasClass("folded")
|
117
|
-
@toggleFold(element_id, callback)
|
118
|
-
else
|
119
|
-
@selectElement($el, true)
|
120
|
-
return
|
121
|
-
|
122
|
-
# Scrolls the element window to given element editor dom element.
|
123
|
-
#
|
124
|
-
scrollToElement: (el) ->
|
125
|
-
$("#element_area").scrollTo el,
|
126
|
-
axis: 'y',
|
127
|
-
duration: 400
|
128
|
-
offset: -6
|
129
|
-
|
130
|
-
# Expands or folds a element editor
|
131
|
-
#
|
132
|
-
# If the element is dirty (has unsaved changes) it displays a warning.
|
133
|
-
#
|
134
|
-
toggle: (id, text) ->
|
135
|
-
el = $("#element_#{id}")
|
136
|
-
if Alchemy.isElementDirty(el)
|
137
|
-
Alchemy.openConfirmDialog Alchemy.t('element_dirty_notice'),
|
138
|
-
title: Alchemy.t('warning')
|
139
|
-
ok_label: Alchemy.t('ok')
|
140
|
-
cancel_label: Alchemy.t('cancel')
|
141
|
-
on_ok: =>
|
142
|
-
@toggleFold(id)
|
143
|
-
false
|
144
|
-
else
|
145
|
-
@toggleFold(id)
|
146
|
-
|
147
|
-
# Folds or expands the element editor with the given id.
|
148
|
-
#
|
149
|
-
toggleFold: (id, callback) ->
|
150
|
-
spinner = new Alchemy.Spinner('small')
|
151
|
-
spinner.spin("#element_#{id} > .element-header .ajax-folder")
|
152
|
-
$("#element_#{id}_folder .icon").hide()
|
153
|
-
$.post Alchemy.routes.fold_admin_element_path(id), =>
|
154
|
-
callback.call() if callback?
|
155
|
-
return
|
156
|
-
|
157
|
-
# Updates the title quote if one of the several conditions are met
|
158
|
-
updateTitle: (element, title, event) ->
|
159
|
-
return true if not @_shouldUpdateTitle(element, event)
|
160
|
-
@setTitle(element, title)
|
161
|
-
return
|
162
|
-
|
163
|
-
# Sets the title quote without checking that the conditions are met
|
164
|
-
setTitle: (element, title) ->
|
165
|
-
$quote = element.find('> .element-header .preview_text_quote')
|
166
|
-
$quote.text(title)
|
167
|
-
return
|
168
|
-
|
169
|
-
# Sets the element to saved state
|
170
|
-
onSaveElement: (event, data) ->
|
171
|
-
$element = $(event.currentTarget)
|
172
|
-
# JS event bubbling will also update the parents element quote.
|
173
|
-
@updateTitle($element, data.previewText, event)
|
174
|
-
# Prevent this event from beeing called twice on the same element
|
175
|
-
if event.currentTarget == event.target
|
176
|
-
Alchemy.setElementClean($element)
|
177
|
-
Alchemy.Buttons.enable($element)
|
178
|
-
true
|
179
|
-
|
180
|
-
# Toggle visibility of the ingredient fields in the group
|
181
|
-
onToggleIngredientGroup: (event) ->
|
182
|
-
$group_div = $(event.currentTarget).closest('.ingredient-group');
|
183
|
-
$group_div.toggleClass('expanded');
|
184
|
-
|
185
|
-
$expanded_ingredient_groups = JSON.parse(sessionStorage.getItem('Alchemy.expanded_ingredient_groups') || '[]');
|
186
|
-
# Add or remove depending on whether this ingredient group is expanded
|
187
|
-
if $group_div.hasClass('expanded')
|
188
|
-
if $expanded_ingredient_groups.indexOf(event.currentTarget.id) == -1
|
189
|
-
$expanded_ingredient_groups.push(event.currentTarget.id);
|
190
|
-
else
|
191
|
-
$expanded_ingredient_groups = $expanded_ingredient_groups.filter (value) ->
|
192
|
-
value != event.currentTarget.id
|
193
|
-
|
194
|
-
sessionStorage.setItem('Alchemy.expanded_ingredient_groups', JSON.stringify($expanded_ingredient_groups))
|
195
|
-
false
|
196
|
-
|
197
|
-
# Event handlers
|
198
|
-
|
199
|
-
onMessage: (data) ->
|
200
|
-
if data.message == 'Alchemy.focusElementEditor'
|
201
|
-
$element = $("#element_#{data.element_id}")
|
202
|
-
Alchemy.ElementEditors.focusElement($element)
|
203
|
-
|
204
|
-
onClickBody: (e) ->
|
205
|
-
element = $(e.target).parents('.element-editor')[0]
|
206
|
-
$('#element_area .element-editor').not(element).removeClass('selected')
|
207
|
-
unless element
|
208
|
-
Alchemy.PreviewWindow.postMessage(message: 'Alchemy.blurElements')
|
209
|
-
return
|
210
|
-
|
211
|
-
# Click event handler for element body.
|
212
|
-
#
|
213
|
-
# - Focuses the element
|
214
|
-
# - Sends 'Alchemy.focusElement' message to preview frame.
|
215
|
-
#
|
216
|
-
onClickElement: (e) ->
|
217
|
-
$target = $(e.target)
|
218
|
-
$element = $target.closest(".element-editor")
|
219
|
-
element_id = $element.attr("id").replace(/\D/g, "")
|
220
|
-
@selectElement($element)
|
221
|
-
@focusElementPreview(element_id)
|
222
|
-
return
|
223
|
-
|
224
|
-
# Double click event handler for element head.
|
225
|
-
onDoubleClickElement: (e) ->
|
226
|
-
id = $(e.target).closest('.element-editor').attr('id').replace(/\D/g, '')
|
227
|
-
@toggle(id)
|
228
|
-
e.preventDefault()
|
229
|
-
return
|
230
|
-
|
231
|
-
# Click event handler for element toggle icon.
|
232
|
-
onClickToggle: (e) ->
|
233
|
-
id = $(e.currentTarget).data('element-toggle')
|
234
|
-
@toggle(id)
|
235
|
-
e.preventDefault()
|
236
|
-
e.stopPropagation()
|
237
|
-
return
|
238
|
-
|
239
|
-
# Handles the custom 'FocusElementEditor.Alchemy' event.
|
240
|
-
#
|
241
|
-
# Triggered, if a user clicks on an element inside the preview iframe.
|
242
|
-
#
|
243
|
-
onFocusElement: (e) ->
|
244
|
-
$element = $(e.target)
|
245
|
-
@focusElement($element)
|
246
|
-
e.stopPropagation()
|
247
|
-
false
|
248
|
-
|
249
|
-
# private
|
250
|
-
|
251
|
-
_shouldUpdateTitle: (element, event) ->
|
252
|
-
editors = element.find('> .element-body .element-ingredient-editors').children()
|
253
|
-
if @_hasParents(element)
|
254
|
-
editors.length != 0
|
255
|
-
else if @_isParent(element) && @_isFirstChild $(event.target)
|
256
|
-
editors.length == 0
|
257
|
-
else
|
258
|
-
not @_isParent(element)
|
259
|
-
|
260
|
-
_hasParents: (element) ->
|
261
|
-
element.parents('.element-editor').length != 0
|
262
|
-
|
263
|
-
_isParent: (element) ->
|
264
|
-
element.find('.nestable-elements').length != 0
|
265
|
-
|
266
|
-
_isFirstChild: (element) ->
|
267
|
-
element.closest('.nestable-elements').find(':first-child').is(element)
|
@@ -1,27 +0,0 @@
|
|
1
|
-
window.Alchemy = {} if window.Alchemy == undefined
|
2
|
-
|
3
|
-
# Alchemy GUI initializers
|
4
|
-
Alchemy.GUI =
|
5
|
-
|
6
|
-
# Initializes all Alchemy GUI elements in given scope
|
7
|
-
init: (scope) ->
|
8
|
-
Alchemy.SelectBox(scope)
|
9
|
-
Alchemy.Datepicker(scope && scope.selector)
|
10
|
-
Alchemy.Tooltips(scope)
|
11
|
-
Alchemy.Buttons.observe(scope)
|
12
|
-
# Dialog links use event delegation and therefore do not
|
13
|
-
# need to be re-initialized after dom elements get replaced
|
14
|
-
unless scope
|
15
|
-
Alchemy.watchForDialogs()
|
16
|
-
Alchemy.Hotkeys(scope)
|
17
|
-
Alchemy.ListFilter(scope)
|
18
|
-
Alchemy.Autocomplete.tags(scope)
|
19
|
-
$('[data-alchemy-char-counter]', scope).each ->
|
20
|
-
new Alchemy.CharCounter(this)
|
21
|
-
|
22
|
-
initElement: ($el) ->
|
23
|
-
Alchemy.ElementDirtyObserver($el)
|
24
|
-
Alchemy.GUI.init($el && $el.selector)
|
25
|
-
Alchemy.ImageLoader($el[0])
|
26
|
-
Alchemy.fileEditors($el.find(".ingredient-editor.file, .ingredient-editor.audio, .ingredient-editor.video").selector)
|
27
|
-
Alchemy.pictureEditors($el.find(".ingredient-editor.picture").selector)
|
@@ -1,32 +0,0 @@
|
|
1
|
-
Alchemy.Spinner = function Spinner(size, styles) {
|
2
|
-
var html = HandlebarsTemplates.spinner(),
|
3
|
-
$spinner = $(html),
|
4
|
-
$svg = $spinner.find('svg'),
|
5
|
-
className;
|
6
|
-
|
7
|
-
switch (size) {
|
8
|
-
case 'small': className = 'spinner--small';
|
9
|
-
break;
|
10
|
-
case 'large': className = 'spinner--large';
|
11
|
-
break;
|
12
|
-
default: className = 'spinner--medium';
|
13
|
-
}
|
14
|
-
|
15
|
-
$spinner.addClass(className);
|
16
|
-
|
17
|
-
if (styles) {
|
18
|
-
$svg.find('path').css(styles);
|
19
|
-
}
|
20
|
-
|
21
|
-
this.el = $spinner;
|
22
|
-
|
23
|
-
this.spin = function spin(parent) {
|
24
|
-
if (parent === undefined) parent = 'body';
|
25
|
-
$(parent).append($spinner);
|
26
|
-
return this;
|
27
|
-
};
|
28
|
-
|
29
|
-
this.stop = function stop() {
|
30
|
-
$spinner.remove();
|
31
|
-
};
|
32
|
-
};
|
@@ -1,10 +0,0 @@
|
|
1
|
-
window.Alchemy = {} if typeof(window.Alchemy) is 'undefined'
|
2
|
-
|
3
|
-
Alchemy.Tooltips = (scope) ->
|
4
|
-
$('[data-alchemy-tooltip]', scope).each ->
|
5
|
-
$el = $(this)
|
6
|
-
text = $el.data('alchemy-tooltip')
|
7
|
-
$el.wrap('<span class="with-hint"/>')
|
8
|
-
$el.after('<span class="hint-bubble">'+text+'</span>')
|
9
|
-
return
|
10
|
-
return
|
@@ -1,131 +0,0 @@
|
|
1
|
-
#= require jquery-ui/widget
|
2
|
-
#= require alchemy/alchemy.file_progress
|
3
|
-
#= require fileupload/jquery.iframe-transport
|
4
|
-
#= require fileupload/jquery.fileupload
|
5
|
-
#= require fileupload/jquery.fileupload-process
|
6
|
-
#= require fileupload/jquery.fileupload-validate
|
7
|
-
|
8
|
-
window.Alchemy = {} if typeof(window.Alchemy) is 'undefined'
|
9
|
-
|
10
|
-
Alchemy.Uploader = (settings) ->
|
11
|
-
totalFilesCount = 0
|
12
|
-
completedUploads = 0
|
13
|
-
$filesContainer = $('.upload-progress-container')
|
14
|
-
selector = settings.selector || '.fileupload'
|
15
|
-
$fields = $(selector)
|
16
|
-
$dropZone = $(settings.dropzone)
|
17
|
-
|
18
|
-
# Normalize file types regex
|
19
|
-
file_types = if settings.file_types == '*' then '.+' else settings.file_types
|
20
|
-
|
21
|
-
# Disable the default browser dragdrop handling
|
22
|
-
$(document).bind 'drop dragover', (e) ->
|
23
|
-
e.preventDefault()
|
24
|
-
|
25
|
-
$dropZone.on 'dragleave', ->
|
26
|
-
$dropZone.removeClass('dragover')
|
27
|
-
|
28
|
-
getNumberOfFiles = ->
|
29
|
-
$filesContainer
|
30
|
-
.children()
|
31
|
-
.not('.progress-bar-in-progress').length - 1
|
32
|
-
|
33
|
-
dragover = ->
|
34
|
-
$dropZone.addClass('dragover')
|
35
|
-
return
|
36
|
-
|
37
|
-
add = (e, data) ->
|
38
|
-
$this = $(this)
|
39
|
-
data.context = new Alchemy.FileProgress(data.files[0])
|
40
|
-
totalFilesCount = data.originalFiles.length
|
41
|
-
$('.total-files-count').text(totalFilesCount)
|
42
|
-
$dropZone.removeClass('dragover').addClass('upload-in-progress')
|
43
|
-
$('.overall-upload').addClass('visible')
|
44
|
-
# trigger validations
|
45
|
-
data.process -> $this.fileupload('process', data)
|
46
|
-
if data.files.error
|
47
|
-
data.context.setError()
|
48
|
-
data.context.setStatus(data.files[0].error)
|
49
|
-
data.context.$fileProgressCancel.click (e) ->
|
50
|
-
data.context.setCancelled()
|
51
|
-
data.context.setStatus('cancelled')
|
52
|
-
return false
|
53
|
-
return false
|
54
|
-
else
|
55
|
-
xhr = data.submit()
|
56
|
-
data.context.$fileProgressCancel.click (e) ->
|
57
|
-
xhr.abort()
|
58
|
-
data.context.setCancelled()
|
59
|
-
data.context.setStatus('cancelled')
|
60
|
-
return false
|
61
|
-
return xhr
|
62
|
-
|
63
|
-
progress = (e, data) ->
|
64
|
-
progress = parseInt(data.loaded / data.total * 100, 10)
|
65
|
-
data.context.setProgress(progress)
|
66
|
-
return
|
67
|
-
|
68
|
-
progressall = (e, data) ->
|
69
|
-
progress = parseInt(data.loaded / data.total * 100, 10)
|
70
|
-
bar = $('.overall-upload .progress')
|
71
|
-
bar.css width: "#{progress}%"
|
72
|
-
$('.progress-status').text("#{progress}%")
|
73
|
-
return
|
74
|
-
|
75
|
-
done = (e, data) ->
|
76
|
-
completedUploads += 1
|
77
|
-
$('.uploaded-files-count').text(completedUploads)
|
78
|
-
data.context.setComplete()
|
79
|
-
data.context.setStatus('complete')
|
80
|
-
response_data = data.xhr().response
|
81
|
-
if completedUploads == totalFilesCount
|
82
|
-
completedUploads = 0
|
83
|
-
totalFilesCount = 0
|
84
|
-
$('.overall-upload').removeClass('visible')
|
85
|
-
settings.complete()
|
86
|
-
return
|
87
|
-
|
88
|
-
fail = (e, data) ->
|
89
|
-
data.context.setError()
|
90
|
-
response_data = data.xhr().response
|
91
|
-
if response_data
|
92
|
-
response = JSON.parse(response_data)
|
93
|
-
error = response.files[0].error
|
94
|
-
data.context.setStatus(error || data.textStatus)
|
95
|
-
return
|
96
|
-
|
97
|
-
always = (e, data) ->
|
98
|
-
xhr = data.xhr()
|
99
|
-
response_data = xhr.response
|
100
|
-
if response_data
|
101
|
-
response = JSON.parse(response_data)
|
102
|
-
if response.growl_message
|
103
|
-
Alchemy.growl(response.growl_message, if xhr.status == 422 then 'alert' else 'notice')
|
104
|
-
return
|
105
|
-
|
106
|
-
$fields.each ->
|
107
|
-
$field = $(this)
|
108
|
-
$form = $field.parents('form')
|
109
|
-
url = $form.attr('action')
|
110
|
-
http_method = $form.find('[name="_method"]').val()
|
111
|
-
# Init jquery.fileupload
|
112
|
-
$field.fileupload
|
113
|
-
url: url
|
114
|
-
type: if http_method then http_method.toUpperCase() else 'POST'
|
115
|
-
dropZone: $dropZone
|
116
|
-
dataType: 'json'
|
117
|
-
filesContainer: $filesContainer
|
118
|
-
acceptFileTypes: new RegExp("(.|/)(#{file_types})", "i")
|
119
|
-
maxNumberOfFiles: Alchemy.uploader_defaults.file_upload_limit
|
120
|
-
maxFileSize: Alchemy.uploader_defaults.file_size_limit * 1000000
|
121
|
-
getNumberOfFiles: getNumberOfFiles
|
122
|
-
dragover: dragover
|
123
|
-
add: add
|
124
|
-
progress: progress
|
125
|
-
progressall: progressall
|
126
|
-
done: done
|
127
|
-
fail: fail
|
128
|
-
always: always
|
129
|
-
return
|
130
|
-
|
131
|
-
return
|
@@ -1,39 +0,0 @@
|
|
1
|
-
$.fn.alchemyNodeSelect = function (options) {
|
2
|
-
var renderNodeTemplate = function (node) {
|
3
|
-
return HandlebarsTemplates.node({ node: node })
|
4
|
-
}
|
5
|
-
var queryParamsFromTerm = function (term) {
|
6
|
-
return {
|
7
|
-
filter: Object.assign(
|
8
|
-
{ name_or_page_name_cont: term },
|
9
|
-
options.query_params
|
10
|
-
)
|
11
|
-
}
|
12
|
-
}
|
13
|
-
var resultsFromResponse = function (response) {
|
14
|
-
var meta = response.meta
|
15
|
-
var data = response.data
|
16
|
-
var more = meta.page * meta.per_page < meta.total_count
|
17
|
-
return { results: data, more: more }
|
18
|
-
}
|
19
|
-
|
20
|
-
return this.select2({
|
21
|
-
placeholder: options.placeholder,
|
22
|
-
allowClear: true,
|
23
|
-
minimumInputLength: 3,
|
24
|
-
initSelection: function (_$el, callback) {
|
25
|
-
if (options.initialSelection) {
|
26
|
-
callback(options.initialSelection)
|
27
|
-
}
|
28
|
-
},
|
29
|
-
ajax: {
|
30
|
-
url: options.url,
|
31
|
-
datatype: "json",
|
32
|
-
quietMillis: 300,
|
33
|
-
data: queryParamsFromTerm,
|
34
|
-
results: resultsFromResponse
|
35
|
-
},
|
36
|
-
formatSelection: renderNodeTemplate,
|
37
|
-
formatResult: renderNodeTemplate
|
38
|
-
})
|
39
|
-
}
|