alchemy_cms 8.2.4 → 8.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/builds/alchemy/admin.css +1 -1
  3. data/app/assets/builds/alchemy/alchemy_admin.min.js +1 -1
  4. data/app/assets/builds/alchemy/alchemy_admin.min.js.map +1 -1
  5. data/app/assets/builds/alchemy/dark-theme.css +1 -1
  6. data/app/assets/builds/alchemy/light-theme.css +1 -1
  7. data/app/assets/builds/alchemy/theme.css +1 -1
  8. data/app/assets/builds/alchemy/welcome.css +1 -1
  9. data/app/assets/builds/tinymce/skins/content/alchemy/content.min.css +1 -1
  10. data/app/assets/builds/tinymce/skins/content/alchemy-dark/content.min.css +1 -1
  11. data/app/components/alchemy/admin/locale_select.rb +4 -4
  12. data/app/components/alchemy/admin/timezone_select.rb +1 -1
  13. data/app/controllers/alchemy/admin/pages_controller.rb +4 -4
  14. data/app/controllers/alchemy/api/pages_controller.rb +8 -2
  15. data/app/javascript/alchemy_admin/components/element_editor.js +4 -1
  16. data/app/javascript/alchemy_admin/components/elements_window_handle.js +16 -1
  17. data/app/javascript/alchemy_admin/components/page_publication_fields.js +9 -10
  18. data/app/javascript/alchemy_admin/image_cropper.js +14 -1
  19. data/app/serializers/alchemy/page_tree_serializer.rb +6 -0
  20. data/app/services/alchemy/page_tree_preloader.rb +9 -7
  21. data/app/stylesheets/alchemy/_custom-properties.scss +1 -1
  22. data/app/stylesheets/alchemy/admin/elements.scss +4 -0
  23. data/app/views/alchemy/admin/layoutpages/_layoutpage.html.erb +1 -1
  24. data/lib/alchemy/cache_digests/template_tracker.rb +0 -2
  25. data/lib/alchemy/configuration/collection_option.rb +1 -1
  26. data/lib/alchemy/routing_constraints.rb +11 -1
  27. data/lib/alchemy/version.rb +1 -1
  28. metadata +1 -1
@@ -1 +1 @@
1
- :root{--a-lightest-grey: hsl(200deg, 5%, 90%);--a-lighter-grey: hsl(200deg, 5%, 70%);--a-light-grey: hsl(200deg, 5%, 35%);--a-grey: hsl(200deg, 5%, 22.5%);--a-dark-grey: hsl(200deg, 5%, 17.5%);--a-darker-grey: hsl(200deg, 5%, 15%);--a-darkest-grey: hsl(200deg, 5%, 12.5%);--color-blue_very_light: hsl(203deg, 32%, 97%);--color-blue_light: hsl(203deg, 32%, 85%);--color-blue_medium: hsl(212deg, 52%, 36%);--color-blue_dark: hsl(212deg, 52%, 26%);--color-green_very_light: hsl(88deg, 47%, 88%);--color-green_light: hsl(127deg, 25%, 69%);--color-green_medium: hsl(127deg, 25%, 48%);--color-green_dark: hsl(128deg, 32%, 26%);--color-yellow_light: hsl(60deg, 81%, 92%);--color-yellow_medium: hsl(56deg, 68%, 85%);--color-yellow_dark: hsl(56deg, 53%, 29%);--color-orange_medium: hsl(42deg, 100%, 74%);--color-orange_dark: hsl(28deg, 77%, 68%);--color-orange_very_dark: hsl(28deg, 77%, 48%);--color-red_very_light: hsl(0deg, 47%, 88%);--color-red_light: hsl(0deg, 25%, 69%);--color-red_medium: hsl(0deg, 51%, 42%);--color-red_dark: hsl(0deg, 51%, 25%);--color-grey_very_light: hsl(0deg, 0%, 97%);--color-grey_light: hsl(0deg, 0%, 94%);--color-grey_medium: hsl(0deg, 0%, 78%);--color-grey_dark: hsl(0deg, 0%, 40%);--color-grey_very_dark: hsl(0deg, 0%, 20%);--color-white: hsl(0deg, 0%, 100%);--spacing-0: 2px;--spacing-1: 4px;--spacing-2: 8px;--spacing-3: 12px;--spacing-4: 16px;--spacing-5: 20px;--spacing-6: 24px;--spacing-7: 28px;--spacing-8: 32px;--spacing-9: 36px;--spacing-10: 40px;--font-mono: Menlo, Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;--font-sans: "Open Sans", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif;--font-size_small: 10px;--font-size_medium: 12px;--font-size_large: 16px;--font-weight_normal: 500;--font-weight_bold: 700;--font-default: var(--font-size_medium) var(--font-sans);--border-radius_medium: 3px;--border-width_small: 1px;--border-style: solid;--border-default: var(--border-width_small) var(--border-style) var(--border-color);--transition-duration: 250ms;--transition-easing: linear;--button-border-radius: var(--border-radius_medium);--button-border-style: var(--border-style);--button-border-width: var(--border-width_small);--button-border: var(--button-border-width) var(--button-border-style) var(--button-border-color);--button-font-size: var(--font-size_medium);--button-font-weight: var(--font-weight_bold);--button-height: 30px;--button-line-height: var(--form-field-line-height);--button-margin: var(--form-field-margin);--button-padding: var(--spacing-1) var(--spacing-5);--button-small-padding: 0.4em 0.8em;--datepicker-font-size: var(--font-size_medium);--dialog-header-height: 36px;--dialog-header-font-size: var(--font-size_medium);--dialog-header-padding: 0 var(--spacing-2);--dialog-transition-duration: 150ms;--elements-window-width: 0px;--elements-window-min-width: 400px;--elements-window-transition-easing: ease-in-out;--form-left-column-width: 35%;--form-right-column-width: 65%;--form-field-margin: var(--spacing-1) 0;--form-field-height: 31px;--form-field-addon-width: 30px;--form-field-border-width: var(--border-width_small);--form-field-border-style: var(--border-style);--form-field-padding: var(--spacing-1) var(--spacing-2);--form-field-font-size: var(--font-size_medium);--form-field-line-height: 1.25;--header-height: 29px;--header-border-bottom: var(--border-default);--icon-button-height: 30px;--icon-button-width: 30px;--icon-button-medium-height: 26px;--icon-button-medium-width: 26px;--icon-button-small-height: 15px;--icon-button-small-width: 15px;--icon-size-xs: 0.75rem;--icon-size-sm: 0.875rem;--icon-size-1x: 1rem;--icon-size-md: 1.3rem;--icon-size-xl: 1.5rem;--icon-size-xxl: 1.6rem;--main-menu-width: 170px;--top-menu-height: 75px;--main-menu-entry-max-width: 110px;--pagination-height: 52px;--select-medium-width: 90px;--select-large-width: 120px;--select-x-large-width: 180px;--sidebar-width: 232px;--toolbar-height: 46px;--toolbar-padding: var(--spacing-2) var(--spacing-1)}html{font-size:13px}body{font-family:var(--font-sans);line-height:1.4;margin:1em;color:#333}a{color:#000}table{border-collapse:collapse}table td,table th{border:1px solid #666;padding:.4rem}figure{display:table;margin:1rem auto}figure figcaption{color:#333;display:block;margin-top:.25rem;text-align:center}hr{border-color:#666;border-style:solid;border-width:1px 0 0 0}code{background-color:#999;border-radius:var(--border-radius_medium);padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #666;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #666;margin-right:1.5rem;padding-right:1rem}
1
+ :root{--a-lightest-grey: hsl(200deg, 5%, 90%);--a-lighter-grey: hsl(200deg, 5%, 70%);--a-light-grey: hsl(200deg, 5%, 35%);--a-grey: hsl(200deg, 5%, 22.5%);--a-dark-grey: hsl(200deg, 5%, 17.5%);--a-darker-grey: hsl(200deg, 5%, 15%);--a-darkest-grey: hsl(200deg, 5%, 12.5%);--color-blue_very_light: hsl(203deg, 32%, 97%);--color-blue_light: hsl(203deg, 32%, 85%);--color-blue_medium: hsl(212deg, 52%, 36%);--color-blue_dark: hsl(212deg, 52%, 26%);--color-green_very_light: hsl(88deg, 47%, 88%);--color-green_light: hsl(127deg, 25%, 69%);--color-green_medium: hsl(127deg, 25%, 48%);--color-green_dark: hsl(128deg, 32%, 26%);--color-yellow_light: hsl(60deg, 81%, 92%);--color-yellow_medium: hsl(56deg, 68%, 85%);--color-yellow_dark: hsl(56deg, 53%, 29%);--color-orange_medium: hsl(42deg, 100%, 74%);--color-orange_dark: hsl(28deg, 77%, 68%);--color-orange_very_dark: hsl(28deg, 77%, 48%);--color-red_very_light: hsl(0deg, 47%, 88%);--color-red_light: hsl(0deg, 25%, 69%);--color-red_medium: hsl(0deg, 51%, 42%);--color-red_dark: hsl(0deg, 51%, 25%);--color-grey_very_light: hsl(0deg, 0%, 97%);--color-grey_light: hsl(0deg, 0%, 94%);--color-grey_medium: hsl(0deg, 0%, 78%);--color-grey_dark: hsl(0deg, 0%, 40%);--color-grey_very_dark: hsl(0deg, 0%, 20%);--color-white: hsl(0deg, 0%, 100%);--spacing-0: 2px;--spacing-1: 4px;--spacing-2: 8px;--spacing-3: 12px;--spacing-4: 16px;--spacing-5: 20px;--spacing-6: 24px;--spacing-7: 28px;--spacing-8: 32px;--spacing-9: 36px;--spacing-10: 40px;--font-mono: Menlo, Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;--font-sans: "Open Sans", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif;--font-size_small: 10px;--font-size_medium: 12px;--font-size_large: 16px;--font-weight_normal: 500;--font-weight_bold: 700;--font-default: var(--font-size_medium) var(--font-sans);--border-radius_medium: 3px;--border-width_small: 1px;--border-style: solid;--border-default: var(--border-width_small) var(--border-style) var(--border-color);--transition-duration: 250ms;--transition-easing: linear;--button-border-radius: var(--border-radius_medium);--button-border-style: var(--border-style);--button-border-width: var(--border-width_small);--button-border: var(--button-border-width) var(--button-border-style) var(--button-border-color);--button-font-size: var(--font-size_medium);--button-font-weight: var(--font-weight_bold);--button-height: 30px;--button-line-height: var(--form-field-line-height);--button-margin: var(--form-field-margin);--button-padding: var(--spacing-1) var(--spacing-5);--button-small-padding: 0.4em 0.8em;--datepicker-font-size: var(--font-size_medium);--dialog-header-height: 36px;--dialog-header-font-size: var(--font-size_medium);--dialog-header-padding: 0 var(--spacing-2);--dialog-transition-duration: 150ms;--elements-window-width: 0px;--elements-window-min-width: 300px;--elements-window-transition-easing: ease-in-out;--form-left-column-width: 35%;--form-right-column-width: 65%;--form-field-margin: var(--spacing-1) 0;--form-field-height: 31px;--form-field-addon-width: 30px;--form-field-border-width: var(--border-width_small);--form-field-border-style: var(--border-style);--form-field-padding: var(--spacing-1) var(--spacing-2);--form-field-font-size: var(--font-size_medium);--form-field-line-height: 1.25;--header-height: 29px;--header-border-bottom: var(--border-default);--icon-button-height: 30px;--icon-button-width: 30px;--icon-button-medium-height: 26px;--icon-button-medium-width: 26px;--icon-button-small-height: 15px;--icon-button-small-width: 15px;--icon-size-xs: 0.75rem;--icon-size-sm: 0.875rem;--icon-size-1x: 1rem;--icon-size-md: 1.3rem;--icon-size-xl: 1.5rem;--icon-size-xxl: 1.6rem;--main-menu-width: 170px;--top-menu-height: 75px;--main-menu-entry-max-width: 110px;--pagination-height: 52px;--select-medium-width: 90px;--select-large-width: 120px;--select-x-large-width: 180px;--sidebar-width: 232px;--toolbar-height: 46px;--toolbar-padding: var(--spacing-2) var(--spacing-1)}html{font-size:13px}body{font-family:var(--font-sans);line-height:1.4;margin:1em;color:#333}a{color:#000}table{border-collapse:collapse}table td,table th{border:1px solid #666;padding:.4rem}figure{display:table;margin:1rem auto}figure figcaption{color:#333;display:block;margin-top:.25rem;text-align:center}hr{border-color:#666;border-style:solid;border-width:1px 0 0 0}code{background-color:#999;border-radius:var(--border-radius_medium);padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #666;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #666;margin-right:1.5rem;padding-right:1rem}
@@ -1 +1 @@
1
- :root{--a-lightest-grey: hsl(200deg, 5%, 90%);--a-lighter-grey: hsl(200deg, 5%, 70%);--a-light-grey: hsl(200deg, 5%, 35%);--a-grey: hsl(200deg, 5%, 22.5%);--a-dark-grey: hsl(200deg, 5%, 17.5%);--a-darker-grey: hsl(200deg, 5%, 15%);--a-darkest-grey: hsl(200deg, 5%, 12.5%);--color-blue_very_light: hsl(203deg, 32%, 97%);--color-blue_light: hsl(203deg, 32%, 85%);--color-blue_medium: hsl(212deg, 52%, 36%);--color-blue_dark: hsl(212deg, 52%, 26%);--color-green_very_light: hsl(88deg, 47%, 88%);--color-green_light: hsl(127deg, 25%, 69%);--color-green_medium: hsl(127deg, 25%, 48%);--color-green_dark: hsl(128deg, 32%, 26%);--color-yellow_light: hsl(60deg, 81%, 92%);--color-yellow_medium: hsl(56deg, 68%, 85%);--color-yellow_dark: hsl(56deg, 53%, 29%);--color-orange_medium: hsl(42deg, 100%, 74%);--color-orange_dark: hsl(28deg, 77%, 68%);--color-orange_very_dark: hsl(28deg, 77%, 48%);--color-red_very_light: hsl(0deg, 47%, 88%);--color-red_light: hsl(0deg, 25%, 69%);--color-red_medium: hsl(0deg, 51%, 42%);--color-red_dark: hsl(0deg, 51%, 25%);--color-grey_very_light: hsl(0deg, 0%, 97%);--color-grey_light: hsl(0deg, 0%, 94%);--color-grey_medium: hsl(0deg, 0%, 78%);--color-grey_dark: hsl(0deg, 0%, 40%);--color-grey_very_dark: hsl(0deg, 0%, 20%);--color-white: hsl(0deg, 0%, 100%);--spacing-0: 2px;--spacing-1: 4px;--spacing-2: 8px;--spacing-3: 12px;--spacing-4: 16px;--spacing-5: 20px;--spacing-6: 24px;--spacing-7: 28px;--spacing-8: 32px;--spacing-9: 36px;--spacing-10: 40px;--font-mono: Menlo, Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;--font-sans: "Open Sans", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif;--font-size_small: 10px;--font-size_medium: 12px;--font-size_large: 16px;--font-weight_normal: 500;--font-weight_bold: 700;--font-default: var(--font-size_medium) var(--font-sans);--border-radius_medium: 3px;--border-width_small: 1px;--border-style: solid;--border-default: var(--border-width_small) var(--border-style) var(--border-color);--transition-duration: 250ms;--transition-easing: linear;--button-border-radius: var(--border-radius_medium);--button-border-style: var(--border-style);--button-border-width: var(--border-width_small);--button-border: var(--button-border-width) var(--button-border-style) var(--button-border-color);--button-font-size: var(--font-size_medium);--button-font-weight: var(--font-weight_bold);--button-height: 30px;--button-line-height: var(--form-field-line-height);--button-margin: var(--form-field-margin);--button-padding: var(--spacing-1) var(--spacing-5);--button-small-padding: 0.4em 0.8em;--datepicker-font-size: var(--font-size_medium);--dialog-header-height: 36px;--dialog-header-font-size: var(--font-size_medium);--dialog-header-padding: 0 var(--spacing-2);--dialog-transition-duration: 150ms;--elements-window-width: 0px;--elements-window-min-width: 400px;--elements-window-transition-easing: ease-in-out;--form-left-column-width: 35%;--form-right-column-width: 65%;--form-field-margin: var(--spacing-1) 0;--form-field-height: 31px;--form-field-addon-width: 30px;--form-field-border-width: var(--border-width_small);--form-field-border-style: var(--border-style);--form-field-padding: var(--spacing-1) var(--spacing-2);--form-field-font-size: var(--font-size_medium);--form-field-line-height: 1.25;--header-height: 29px;--header-border-bottom: var(--border-default);--icon-button-height: 30px;--icon-button-width: 30px;--icon-button-medium-height: 26px;--icon-button-medium-width: 26px;--icon-button-small-height: 15px;--icon-button-small-width: 15px;--icon-size-xs: 0.75rem;--icon-size-sm: 0.875rem;--icon-size-1x: 1rem;--icon-size-md: 1.3rem;--icon-size-xl: 1.5rem;--icon-size-xxl: 1.6rem;--main-menu-width: 170px;--top-menu-height: 75px;--main-menu-entry-max-width: 110px;--pagination-height: 52px;--select-medium-width: 90px;--select-large-width: 120px;--select-x-large-width: 180px;--sidebar-width: 232px;--toolbar-height: 46px;--toolbar-padding: var(--spacing-2) var(--spacing-1)}html{font-size:13px}body{font-family:var(--font-sans);line-height:1.4;margin:1em;background-color:var(--a-darkest-grey);color:var(--a-lighter-grey)}a{color:var(--a-lightest-grey)}table{border-collapse:collapse}table td,table th{border:1px solid var(--a-grey);padding:.4rem}figure{display:table;margin:1rem auto}figure figcaption{color:var(--a-lighter-grey);display:block;margin-top:.25rem;text-align:center}hr{border-color:var(--a-grey);border-style:solid;border-width:1px 0 0 0}code{background-color:var(--a-darkest-grey);border-radius:var(--border-radius_medium);padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid var(--a-grey);margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid var(--a-grey);margin-right:1.5rem;padding-right:1rem}
1
+ :root{--a-lightest-grey: hsl(200deg, 5%, 90%);--a-lighter-grey: hsl(200deg, 5%, 70%);--a-light-grey: hsl(200deg, 5%, 35%);--a-grey: hsl(200deg, 5%, 22.5%);--a-dark-grey: hsl(200deg, 5%, 17.5%);--a-darker-grey: hsl(200deg, 5%, 15%);--a-darkest-grey: hsl(200deg, 5%, 12.5%);--color-blue_very_light: hsl(203deg, 32%, 97%);--color-blue_light: hsl(203deg, 32%, 85%);--color-blue_medium: hsl(212deg, 52%, 36%);--color-blue_dark: hsl(212deg, 52%, 26%);--color-green_very_light: hsl(88deg, 47%, 88%);--color-green_light: hsl(127deg, 25%, 69%);--color-green_medium: hsl(127deg, 25%, 48%);--color-green_dark: hsl(128deg, 32%, 26%);--color-yellow_light: hsl(60deg, 81%, 92%);--color-yellow_medium: hsl(56deg, 68%, 85%);--color-yellow_dark: hsl(56deg, 53%, 29%);--color-orange_medium: hsl(42deg, 100%, 74%);--color-orange_dark: hsl(28deg, 77%, 68%);--color-orange_very_dark: hsl(28deg, 77%, 48%);--color-red_very_light: hsl(0deg, 47%, 88%);--color-red_light: hsl(0deg, 25%, 69%);--color-red_medium: hsl(0deg, 51%, 42%);--color-red_dark: hsl(0deg, 51%, 25%);--color-grey_very_light: hsl(0deg, 0%, 97%);--color-grey_light: hsl(0deg, 0%, 94%);--color-grey_medium: hsl(0deg, 0%, 78%);--color-grey_dark: hsl(0deg, 0%, 40%);--color-grey_very_dark: hsl(0deg, 0%, 20%);--color-white: hsl(0deg, 0%, 100%);--spacing-0: 2px;--spacing-1: 4px;--spacing-2: 8px;--spacing-3: 12px;--spacing-4: 16px;--spacing-5: 20px;--spacing-6: 24px;--spacing-7: 28px;--spacing-8: 32px;--spacing-9: 36px;--spacing-10: 40px;--font-mono: Menlo, Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;--font-sans: "Open Sans", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif;--font-size_small: 10px;--font-size_medium: 12px;--font-size_large: 16px;--font-weight_normal: 500;--font-weight_bold: 700;--font-default: var(--font-size_medium) var(--font-sans);--border-radius_medium: 3px;--border-width_small: 1px;--border-style: solid;--border-default: var(--border-width_small) var(--border-style) var(--border-color);--transition-duration: 250ms;--transition-easing: linear;--button-border-radius: var(--border-radius_medium);--button-border-style: var(--border-style);--button-border-width: var(--border-width_small);--button-border: var(--button-border-width) var(--button-border-style) var(--button-border-color);--button-font-size: var(--font-size_medium);--button-font-weight: var(--font-weight_bold);--button-height: 30px;--button-line-height: var(--form-field-line-height);--button-margin: var(--form-field-margin);--button-padding: var(--spacing-1) var(--spacing-5);--button-small-padding: 0.4em 0.8em;--datepicker-font-size: var(--font-size_medium);--dialog-header-height: 36px;--dialog-header-font-size: var(--font-size_medium);--dialog-header-padding: 0 var(--spacing-2);--dialog-transition-duration: 150ms;--elements-window-width: 0px;--elements-window-min-width: 300px;--elements-window-transition-easing: ease-in-out;--form-left-column-width: 35%;--form-right-column-width: 65%;--form-field-margin: var(--spacing-1) 0;--form-field-height: 31px;--form-field-addon-width: 30px;--form-field-border-width: var(--border-width_small);--form-field-border-style: var(--border-style);--form-field-padding: var(--spacing-1) var(--spacing-2);--form-field-font-size: var(--font-size_medium);--form-field-line-height: 1.25;--header-height: 29px;--header-border-bottom: var(--border-default);--icon-button-height: 30px;--icon-button-width: 30px;--icon-button-medium-height: 26px;--icon-button-medium-width: 26px;--icon-button-small-height: 15px;--icon-button-small-width: 15px;--icon-size-xs: 0.75rem;--icon-size-sm: 0.875rem;--icon-size-1x: 1rem;--icon-size-md: 1.3rem;--icon-size-xl: 1.5rem;--icon-size-xxl: 1.6rem;--main-menu-width: 170px;--top-menu-height: 75px;--main-menu-entry-max-width: 110px;--pagination-height: 52px;--select-medium-width: 90px;--select-large-width: 120px;--select-x-large-width: 180px;--sidebar-width: 232px;--toolbar-height: 46px;--toolbar-padding: var(--spacing-2) var(--spacing-1)}html{font-size:13px}body{font-family:var(--font-sans);line-height:1.4;margin:1em;background-color:var(--a-darkest-grey);color:var(--a-lighter-grey)}a{color:var(--a-lightest-grey)}table{border-collapse:collapse}table td,table th{border:1px solid var(--a-grey);padding:.4rem}figure{display:table;margin:1rem auto}figure figcaption{color:var(--a-lighter-grey);display:block;margin-top:.25rem;text-align:center}hr{border-color:var(--a-grey);border-style:solid;border-width:1px 0 0 0}code{background-color:var(--a-darkest-grey);border-radius:var(--border-radius_medium);padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid var(--a-grey);margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid var(--a-grey);margin-right:1.5rem;padding-right:1rem}
@@ -10,12 +10,12 @@ module Alchemy
10
10
  end
11
11
 
12
12
  def call
13
- form_tag(helpers.url_for, method: :get) do
14
- if auto_submit
13
+ if auto_submit
14
+ form_tag(helpers.url_for, method: :get) do
15
15
  content_tag("alchemy-auto-submit", locale_select)
16
- else
17
- locale_select
18
16
  end
17
+ else
18
+ locale_select
19
19
  end
20
20
  end
21
21
 
@@ -22,7 +22,7 @@ module Alchemy
22
22
 
23
23
  def popover_content
24
24
  content_tag(:div, class: "alchemy-popover") do
25
- form_tag(helpers.url_for, method: :get, class: "timezone-select") do
25
+ form_tag(request.path, method: :get, class: "timezone-select") do
26
26
  label_tag(:admin_timezone, Alchemy.t(:timezone)) +
27
27
  content_tag("alchemy-auto-submit") do
28
28
  select_tag(
@@ -68,8 +68,8 @@ module Alchemy
68
68
  def tree
69
69
  @root_page = Alchemy::PageTreePreloader.new(
70
70
  page: @current_language.root_page,
71
- user: current_alchemy_user,
72
- admin_includes: true
71
+ ability: current_ability,
72
+ user: current_alchemy_user
73
73
  ).call
74
74
  end
75
75
 
@@ -181,8 +181,8 @@ module Alchemy
181
181
  if was_folded
182
182
  @page = PageTreePreloader.new(
183
183
  page: @page,
184
- user: current_alchemy_user,
185
- admin_includes: true
184
+ ability: current_ability,
185
+ user: current_alchemy_user
186
186
  ).call
187
187
  else
188
188
  head 200
@@ -28,8 +28,14 @@ module Alchemy
28
28
  def nested
29
29
  @page = Page.find_by(id: params[:page_id]) || Language.current_root_page
30
30
 
31
- # Preload the full tree from this page
32
- preloaded_page = PageTreePreloader.new(page: @page, user: current_alchemy_user).call
31
+ authorize! :show, @page
32
+
33
+ # Preload the full tree from this page, scoped to what the user may see
34
+ preloaded_page = PageTreePreloader.new(
35
+ page: @page,
36
+ user: current_alchemy_user,
37
+ ability: current_ability
38
+ ).call
33
39
 
34
40
  render json: PageTreeSerializer.new(
35
41
  preloaded_page,
@@ -250,7 +250,10 @@ export class ElementEditor extends HTMLElement {
250
250
  */
251
251
  setTitle(title) {
252
252
  const quote = this.querySelector(".element-header .preview_text_quote")
253
- quote.textContent = title
253
+ // Fixed elements have no header, so there is no quote to update.
254
+ if (quote) {
255
+ quote.textContent = title
256
+ }
254
257
  }
255
258
 
256
259
  /**
@@ -1,7 +1,11 @@
1
+ const MIN_WIDTH = 400
2
+ const MAX_WIDTH = 1000
1
3
  class ElementsWindowHandle extends HTMLElement {
2
4
  #dragging = false
3
5
  #elementsWindow = null
4
6
  #previewWindow = null
7
+ #minWidth = MIN_WIDTH
8
+ #maxWidth = MAX_WIDTH
5
9
 
6
10
  constructor() {
7
11
  super()
@@ -30,6 +34,13 @@ class ElementsWindowHandle extends HTMLElement {
30
34
 
31
35
  onMouseDown() {
32
36
  this.#dragging = true
37
+ // Read the resolved min/max width the browser computed from the CSS
38
+ // custom properties (incl. calc() and active media queries) once, so the
39
+ // drag stays clamped to the same bounds the stylesheet defines.
40
+ const styles = getComputedStyle(this.elementsWindow)
41
+ this.#minWidth = parseFloat(styles.minWidth) || MIN_WIDTH
42
+ this.#maxWidth =
43
+ styles.maxWidth === "none" ? MAX_WIDTH : parseFloat(styles.maxWidth)
33
44
  this.elementsWindow.isDragged = true
34
45
  this.previewWindow.isDragged = true
35
46
  this.classList.add("is-dragged")
@@ -44,7 +55,11 @@ class ElementsWindowHandle extends HTMLElement {
44
55
 
45
56
  onDrag(pageX) {
46
57
  const elementWindowWidth = window.innerWidth - pageX
47
- this.elementsWindow.resize(elementWindowWidth)
58
+ const width = Math.min(
59
+ Math.max(elementWindowWidth, this.#minWidth),
60
+ this.#maxWidth
61
+ )
62
+ this.elementsWindow.resize(width)
48
63
  }
49
64
 
50
65
  get elementsWindow() {
@@ -1,12 +1,8 @@
1
1
  // Handles the page publication date fields
2
2
  export class PagePublicationFields extends HTMLElement {
3
3
  connectedCallback() {
4
- const public_on_picker = this.querySelector(
5
- "alchemy-datepicker:has(#page_public_on)"
6
- )
7
- const public_until_picker = this.querySelector(
8
- "alchemy-datepicker:has(#page_public_until)"
9
- )
4
+ const public_on_picker = this.querySelector("input#page_public_on")
5
+ const public_until_picker = this.querySelector("input#page_public_until")
10
6
  const publication_date_fields = this.querySelector(
11
7
  ".page-publication-date-fields"
12
8
  )
@@ -16,16 +12,19 @@ export class PagePublicationFields extends HTMLElement {
16
12
 
17
13
  public_field.addEventListener("click", function (evt) {
18
14
  const checkbox = evt.target
19
- const now = new Date()
15
+ const date = new Date()
16
+ const now = new Date(
17
+ date.getTime() - date.getTimezoneOffset() * 60000
18
+ ).toISOString()
20
19
 
21
20
  if (checkbox.checked) {
22
21
  publication_date_fields.classList.remove("hidden")
23
- public_on_picker.flatpickr.setDate(now)
22
+ public_on_picker.value = now.substring(0, now.indexOf("T") + 6)
24
23
  } else {
25
24
  publication_date_fields.classList.add("hidden")
26
- public_on_picker.flatpickr.clear()
25
+ public_on_picker.value = ""
27
26
  }
28
- public_until_picker.flatpickr?.clear()
27
+ public_until_picker.value = ""
29
28
  })
30
29
  }
31
30
  }
@@ -89,7 +89,20 @@ export default class ImageCropper {
89
89
  }
90
90
 
91
91
  reset() {
92
- this.#cropper.setData(this.defaultBoxSize)
92
+ const cropper = this.#cropper
93
+ // Apply the default size. cropperjs clamps the crop box to its maximum size.
94
+ cropper.setData(this.defaultBoxSize)
95
+ // When the default box sits at the maximum crop box size, sub-pixel rounding
96
+ // makes cropperjs treat setData's box as oversized and revert its position
97
+ // (renderCropBox resets top/left to their old values). Re-apply the position
98
+ // in canvas coordinates afterwards – that does not touch the size, so it is
99
+ // not reverted and the mask actually moves to the default box.
100
+ const canvas = cropper.getCanvasData()
101
+ const scale = canvas.width / canvas.naturalWidth
102
+ cropper.setCropBoxData({
103
+ left: canvas.left + this.defaultBoxSize.x * scale,
104
+ top: canvas.top + this.defaultBoxSize.y * scale
105
+ })
93
106
  this.update(this.defaultBoxSize)
94
107
  }
95
108
 
@@ -63,6 +63,12 @@ module Alchemy
63
63
  end
64
64
 
65
65
  def page_elements(page)
66
+ # Pages usually arrive wrapped in a PageTreePage delegator. Unwrap it so
67
+ # the ability matches the Alchemy::Page rules instead of the delegator
68
+ # class, while still supporting a plain Alchemy::Page being passed in.
69
+ authorized_page = page.try(:__getobj__) || page
70
+ return Alchemy::Element.none unless opts[:ability].can?(:read, authorized_page)
71
+
66
72
  elements = page.public_version&.elements || Alchemy::Element.none
67
73
  if opts[:elements] == "true"
68
74
  elements
@@ -7,24 +7,24 @@ module Alchemy
7
7
  # It handles folded pages and preloads all necessary associations.
8
8
  #
9
9
  # @example Preload subtree from a specific page
10
- # preloader = Alchemy::PageTreePreloader.new(page: page, user: current_user)
10
+ # preloader = Alchemy::PageTreePreloader.new(page: page, ability: current_ability, user: current_user)
11
11
  # page_with_descendants = preloader.call
12
12
  #
13
13
  class PageTreePreloader
14
14
  # @param page [Page] Starting page for loading descendants
15
+ # @param ability [CanCan::Ability] Ability used to scope descendants to readable pages
15
16
  # @param user [User, nil] User for folding support
16
- # @param admin_includes [Boolean] Whether to include admin-only associations like :locker
17
- def initialize(page:, user: nil, admin_includes: false)
17
+ def initialize(page:, ability:, user: nil)
18
18
  @page = page
19
+ @ability = ability
19
20
  @user = user
20
- @admin_includes = admin_includes
21
21
  end
22
22
 
23
23
  # Preloads and returns the page tree
24
24
  #
25
25
  # @return [Array<Page>] Pages with preloaded children, or array with single page when using from:
26
26
  def call
27
- pages = page.self_and_descendants
27
+ pages = page.self_and_descendants.accessible_by(ability, :read)
28
28
  folded_page_ids = load_folded_page_ids
29
29
  if folded_page_ids.any?
30
30
  pages = pages.where(
@@ -45,7 +45,7 @@ module Alchemy
45
45
 
46
46
  private
47
47
 
48
- attr_reader :page, :user, :admin_includes
48
+ attr_reader :page, :user, :ability
49
49
 
50
50
  # Load folded page IDs for the user
51
51
  def load_folded_page_ids
@@ -93,7 +93,9 @@ module Alchemy
93
93
  },
94
94
  :public_version
95
95
  ]
96
- associations.push(:locker) if admin_includes
96
+ # The admin sitemap (and the serializer's admin fields) render lock info,
97
+ # so only eager-load the locker when the user may administer pages.
98
+ associations.push(:locker) if ability.can?(:index, :alchemy_admin_pages)
97
99
  associations
98
100
  end
99
101
  end
@@ -107,7 +107,7 @@
107
107
 
108
108
  /* Elements */
109
109
  --elements-window-width: 0px;
110
- --elements-window-min-width: 400px;
110
+ --elements-window-min-width: 300px;
111
111
  --elements-window-transition-easing: ease-in-out;
112
112
 
113
113
  /* Form */
@@ -32,6 +32,10 @@
32
32
  .elements-window-visible {
33
33
  --elements-window-width: calc(100vw - var(--main-menu-width));
34
34
 
35
+ @media screen and (min-width: vars.$large-screen-break-point) {
36
+ --elements-window-min-width: 400px;
37
+ }
38
+
35
39
  @media screen and (min-width: vars.$large-screen-break-point) {
36
40
  --elements-window-width: var(--elements-window-min-width);
37
41
  }
@@ -8,7 +8,7 @@
8
8
  <%= render_icon "file-edit", size: "xl" %>
9
9
  </sl-tooltip>
10
10
  <% else %>
11
- <%= render_icon "file-edit", size: "xl" %>
11
+ <%= render_icon "file", size: "xl" %>
12
12
  <% end %>
13
13
  </div>
14
14
  <div class="sitemap_sitename without-status">
@@ -18,8 +18,6 @@ module Alchemy
18
18
  when /^alchemy\/page_layouts\/_(\w+)/
19
19
  page_definition = PageDefinition.get($1)
20
20
  page_definition.elements.map { "alchemy/elements/_#{_1}" }
21
- when /^alchemy\/elements\/_(\w+)/
22
- ingredient_types($1).map { "alchemy/ingredients/_#{_1.underscore}_view" }.tap(&:uniq!)
23
21
  else
24
22
  ActionView::DependencyTracker::ERBTracker.call(@name, @template)
25
23
  end
@@ -66,7 +66,7 @@ module Alchemy
66
66
  end
67
67
 
68
68
  def get_item_class(item_type)
69
- "Alchemy::Configuration::#{item_type.to_s.classify}Option".constantize
69
+ "Alchemy::Configuration::#{item_type.to_s.camelcase}Option".constantize
70
70
  end
71
71
  end
72
72
  end
@@ -16,11 +16,21 @@ module Alchemy
16
16
  @request = request
17
17
  @params = @request.params
18
18
 
19
- handable_format? && no_rails_route?
19
+ handable_format? && no_dotfile_route? && no_rails_route?
20
20
  end
21
21
 
22
22
  private
23
23
 
24
+ # We don't want to handle requests to dotfile URLs.
25
+ #
26
+ # A page urlname never starts with a dot, so any such request
27
+ # (/.well-known/ ACME challenges, /.env or /.git probes, etc.)
28
+ # should never be served by a page.
29
+ #
30
+ def no_dotfile_route?
31
+ !@params["urlname"].start_with?(".")
32
+ end
33
+
24
34
  # We only want html requests to be handled by us.
25
35
  #
26
36
  # If an unknown format is requested we want to handle this,
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Alchemy
4
- VERSION = "8.2.4"
4
+ VERSION = "8.2.6"
5
5
 
6
6
  def self.version
7
7
  VERSION
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alchemy_cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.2.4
4
+ version: 8.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas von Deyen