comfy_middle_seat 3.2.0 → 4.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 +4 -4
- data/.github/workflows/coveralls.yml +4 -0
- data/CHANGELOG.md +56 -3
- data/CONTRIBUTING.md +8 -5
- data/Gemfile +1 -1
- data/README.md +66 -29
- data/Rakefile +3 -3
- data/app/assets/javascripts/comfy/admin/cms/application.js +2 -0
- data/app/assets/javascripts/comfy/admin/cms/base.js +6 -1
- data/app/assets/javascripts/comfy/admin/cms/codemirror.js +17 -0
- data/app/assets/javascripts/comfy/admin/cms/dirty_forms.js +201 -0
- data/app/assets/javascripts/comfy/admin/cms/draft_forms.js +468 -0
- data/app/assets/javascripts/comfy/admin/cms/page_fragments.js +393 -22
- data/app/assets/javascripts/comfy/admin/cms/wysiwyg.js +21 -0
- data/app/assets/javascripts/comfy/vendor/redactor/filemanager.js +48 -30
- data/app/assets/javascripts/comfy/vendor/redactor/imagemanager.js +43 -25
- data/app/assets/stylesheets/comfy/admin/cms/base.sass +23 -0
- data/app/controllers/comfy/admin/base_controller.rb +3 -3
- data/app/controllers/comfy/admin/cms/base_controller.rb +12 -7
- data/app/controllers/comfy/admin/cms/files_controller.rb +1 -1
- data/app/controllers/comfy/admin/cms/pages_controller.rb +76 -16
- data/app/controllers/comfy/admin/cms/revisions/base_controller.rb +39 -1
- data/app/controllers/comfy/admin/cms/revisions/page_controller.rb +9 -8
- data/app/controllers/comfy/admin/cms/revisions/translation_controller.rb +14 -8
- data/app/controllers/comfy/admin/cms/sites_controller.rb +1 -1
- data/app/controllers/comfy/admin/cms/translations_controller.rb +3 -1
- data/app/controllers/comfy/cms/base_controller.rb +1 -1
- data/app/controllers/comfy/cms/content_controller.rb +5 -5
- data/app/controllers/concerns/comfy/reorder_action.rb +24 -4
- data/app/helpers/comfy/admin/cms_helper.rb +28 -3
- data/app/helpers/comfy/cms_helper.rb +1 -1
- data/app/models/comfy/cms/file.rb +25 -3
- data/app/models/comfy/cms/layout.rb +8 -6
- data/app/models/comfy/cms/page.rb +22 -0
- data/app/models/comfy/cms/site.rb +3 -3
- data/app/models/comfy/cms/snippet.rb +8 -3
- data/app/models/concerns/comfy/cms/with_fragments.rb +2 -2
- data/app/views/comfy/admin/cms/categories/_index.html.haml +1 -1
- data/app/views/comfy/admin/cms/categories/_show.html.haml +1 -1
- data/app/views/comfy/admin/cms/files/_file.html.haml +1 -1
- data/app/views/comfy/admin/cms/files/index.html.haml +9 -2
- data/app/views/comfy/admin/cms/fragments/_form_fragments.html.haml +2 -2
- data/app/views/comfy/admin/cms/pages/_form.html.haml +2 -1
- data/app/views/comfy/admin/cms/pages/_index_branch.html.haml +11 -10
- data/app/views/comfy/admin/cms/pages/edit.html.haml +3 -1
- data/app/views/comfy/admin/cms/pages/index.html.haml +9 -2
- data/app/views/comfy/admin/cms/pages/new.html.haml +3 -1
- data/app/views/comfy/admin/cms/pages/toggle_branch.js.erb +2 -2
- data/app/views/comfy/admin/cms/revisions/show.html.haml +25 -7
- data/app/views/comfy/admin/cms/shared/_search.html.haml +9 -0
- data/app/views/comfy/admin/cms/sites/_form.html.haml +1 -1
- data/app/views/comfy/admin/cms/translations/_form.html.haml +2 -1
- data/app/views/comfy/admin/cms/translations/edit.html.haml +3 -1
- data/app/views/comfy/admin/cms/translations/new.html.haml +3 -1
- data/app/views/layouts/comfy/admin/cms/_flash.html.haml +1 -1
- data/app/views/layouts/comfy/admin/cms/_head.html.haml +3 -1
- data/app/views/layouts/comfy/admin/cms/_left.html.haml +2 -2
- data/comfy_middle_seat.gemspec +10 -5
- data/config/application.rb +3 -2
- data/config/cms_routes.rb +1 -1
- data/config/environment.rb +1 -1
- data/config/environments/development.rb +1 -1
- data/config/environments/production.rb +1 -1
- data/config/environments/test.rb +1 -1
- data/config/initializers/{comfortable_media_surfer.rb → comfy_middle_seat.rb} +4 -4
- data/config/locales/ar.yml +14 -0
- data/config/locales/ca.yml +14 -0
- data/config/locales/cs.yml +14 -0
- data/config/locales/da.yml +14 -0
- data/config/locales/de.yml +14 -0
- data/config/locales/en.yml +14 -0
- data/config/locales/es.yml +14 -0
- data/config/locales/fi.yml +14 -0
- data/config/locales/fr.yml +14 -0
- data/config/locales/gr.yml +14 -0
- data/config/locales/hr.yml +14 -0
- data/config/locales/it.yml +14 -0
- data/config/locales/ja.yml +14 -0
- data/config/locales/nb.yml +14 -0
- data/config/locales/nl.yml +14 -0
- data/config/locales/pl.yml +14 -0
- data/config/locales/pt-BR.yml +14 -0
- data/config/locales/ru.yml +14 -0
- data/config/locales/sk.yml +14 -0
- data/config/locales/sv.yml +14 -0
- data/config/locales/tr.yml +14 -0
- data/config/locales/uk.yml +14 -0
- data/config/locales/zh-CN.yml +14 -0
- data/config/locales/zh-TW.yml +14 -0
- data/config.ru +1 -1
- data/exe/comfy-middle-seat-upgrade +34 -0
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/access_control/admin_authentication.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/access_control/admin_authorization.rb +1 -1
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/access_control/public_authentication.rb +1 -1
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/access_control/public_authorization.rb +1 -1
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/configuration.rb +7 -7
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/block.rb +1 -1
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/params_parser.rb +1 -1
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/renderer.rb +10 -10
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tag.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/asset.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/audio.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/breadcrumbs.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/checkbox.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/children.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/date.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/datetime.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/file.rb +5 -5
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/file_link.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/files.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/fragment.rb +2 -2
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/helper.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/image.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/markdown.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/mixins/file_content.rb +1 -1
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/number.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/page_file_link.rb +5 -5
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/partial.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/siblings.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/snippet.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/template.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/text.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/textarea.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/wysiwyg.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags.rb +1 -1
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content.rb +1 -1
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/engine.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/error.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/extensions/acts_as_tree.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/extensions/has_revisions.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/extensions.rb +1 -1
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/form_builder.rb +2 -2
- data/lib/comfy_middle_seat/initializer_upgrader.rb +115 -0
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/render_methods.rb +7 -7
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/routing.rb +3 -2
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/seeds/file/exporter.rb +5 -5
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/seeds/file/importer.rb +5 -5
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/seeds/layout/exporter.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/seeds/layout/importer.rb +5 -5
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/seeds/page/exporter.rb +5 -5
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/seeds/page/importer.rb +7 -7
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/seeds/snippet/exporter.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/seeds/snippet/importer.rb +5 -5
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/seeds.rb +4 -4
- data/lib/comfy_middle_seat/version.rb +2 -2
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/view_hooks.rb +2 -2
- data/lib/comfy_middle_seat.rb +54 -1
- data/lib/generators/comfy/cms/README +3 -11
- data/lib/generators/comfy/cms/cms_generator.rb +2 -2
- data/lib/generators/comfy/scaffold/templates/tests/controller.rb.tt +2 -2
- data/lib/tasks/cms_seeds.rake +8 -8
- data/package-lock.json +2 -2
- data/package.json +1 -1
- metadata +68 -62
- data/lib/comfortable_media_surfer/version.rb +0 -3
- data/lib/comfortable_media_surfer.rb +0 -56
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e2261f0af74a7d60998b21a9f85feacdb454614e8f8bec638eb9f7a1aa3b2850
|
|
4
|
+
data.tar.gz: 06244651d11d7868006fdb42cea0b0ac9119304af97b42cd563401cd4ee9fd52
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4f52d95a635172aa91cff2536dc87167656c815e23c743cd648a1d2fccf1cccd875e1a1866081ebaa2837b6b3b17690f1e6b59f321a4aaaa915bdc81464374da
|
|
7
|
+
data.tar.gz: 054772f74cc2c0a373bd7939b9a4f47da4f7bfbf71aab88db624da8c6df72614da456c0377d3fd327c9a5a9903f3afc6c823ef5ce0f62c2a642b5b40dc638d17
|
|
@@ -45,6 +45,10 @@ jobs:
|
|
|
45
45
|
- name: Compile assets
|
|
46
46
|
run: bin/bundle exec rails comfy:compile_assets
|
|
47
47
|
|
|
48
|
+
- name: Verify Coveralls token is configured
|
|
49
|
+
run: |
|
|
50
|
+
ruby -e 'abort "COVERALLS_REPO_TOKEN is missing" if ENV.fetch("COVERALLS_REPO_TOKEN", "").strip.empty?'
|
|
51
|
+
|
|
48
52
|
- name: Run tests, report coverage
|
|
49
53
|
run: |
|
|
50
54
|
bin/bundle exec rails db:drop
|
data/CHANGELOG.md
CHANGED
|
@@ -6,12 +6,63 @@ All notable changes to this project's source code will be documented in this fil
|
|
|
6
6
|
|
|
7
7
|
Please follow the recommendations outlined at [keepachangelog.com](https://keepachangelog.com). Please use the existing headings and styling as a guide, and add a link for the version diff at the bottom of the file. Also, please update the `Unreleased` link to compare it to the latest release version.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
This changelog follows the project's lineage: **Comfortable Mexican Sofa → Comfortable Media Surfer → Comfy Middle Seat**. Version **3.2.0** is the first release published as `comfy_middle_seat`. The entries for **3.0.0–3.1.7** below are inherited from `comfortable_media_surfer` and retain their upstream links. For earlier history, see the [Comfortable Mexican Sofa releases](https://github.com/comfy/comfortable-mexican-sofa/releases).
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Comfy Middle Seat
|
|
12
12
|
|
|
13
13
|
## [Unreleased]
|
|
14
14
|
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Complete the implementation namespace and internal-path decoupling from Comfortable Media Surfer: current Ruby APIs now use `ComfyMiddleSeat`, library files live under `comfy_middle_seat`, and generated configuration belongs at `config/initializers/comfy_middle_seat.rb`.
|
|
18
|
+
- Require applications upgrading from `comfortable_media_surfer` to rename the initializer and replace Ruby configuration or integration references from `ComfortableMediaSurfer` to `ComfyMiddleSeat`. The existing `comfy_cms_*` database tables, schema, and stored data remain unchanged, so no database migration is required.
|
|
19
|
+
- Add the standalone `comfy-middle-seat-upgrade` executable to safely preview and convert a legacy initializer without booting Rails, preserving the original as a backup and refusing ambiguous or destructive changes.
|
|
20
|
+
- Preserve Comfortable Media Surfer names and URLs where they describe project history, acknowledgements, inherited release notes, or upstream resources rather than the current API.
|
|
21
|
+
|
|
22
|
+
## [v3.2.1] - 2026-09-17
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- Fix CI eager loading after the gem rename by excluding the explicitly required `comfy_middle_seat` entrypoint and version directory from Zeitwerk autoloading. Add a regression test that also checks eager loading outside CI.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- At the time of this release, update the admin footer branding and repository link to Comfy Middle Seat while retaining the then-current `ComfortableMediaSurfer::VERSION` compatibility constant.
|
|
31
|
+
- Check that `COVERALLS_REPO_TOKEN` is configured before running the coverage job, with a clear error when it is missing.
|
|
32
|
+
- Document asset compilation and explicit test database setup, along with commands for running the main and browser/system test suites.
|
|
33
|
+
- Update README badges and release documentation, preserving the distinction between Seat releases and inherited Surfer history.
|
|
34
|
+
|
|
35
|
+
## [v3.2.0] - 2026-09-17
|
|
36
|
+
|
|
37
|
+
**First Comfy Middle Seat release.** Forked from [Comfortable Media Surfer](https://github.com/shakacode/comfortable-media-surfer), itself a revival of [Comfortable Mexican Sofa](https://github.com/comfy/comfortable-mexican-sofa). The new name keeps the C.M.S. initials and pays homage to the original.
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- Publish the gem as `comfy_middle_seat` and rename the gemspec to `comfy_middle_seat.gemspec`.
|
|
42
|
+
- At the time of v3.2.0, preserve the `ComfortableMediaSurfer` Ruby namespace and configuration while retaining the existing routes and database tables. The Unreleased namespace decoupling supersedes the Ruby compatibility behavior; the database compatibility remains unchanged.
|
|
43
|
+
- Move the version definition to `lib/comfy_middle_seat/version.rb` for release tooling, retaining a compatibility loader at the old path.
|
|
44
|
+
- Run the main test suite in six isolated processes by default, with merged coverage and a separate `test:serial` task for Coveralls.
|
|
45
|
+
- Update CI coverage to Rails 7.2, 8.0, and 8.1, with a separate browser/system test job.
|
|
46
|
+
|
|
47
|
+
### Added
|
|
48
|
+
|
|
49
|
+
- Add `lib/comfy_middle_seat.rb` so Bundler loads the existing implementation automatically under the new gem name.
|
|
50
|
+
- Add controls to publish and unpublish child pages from the admin interface.
|
|
51
|
+
|
|
52
|
+
### Fixed
|
|
53
|
+
|
|
54
|
+
- Strengthen site isolation for admin parameters, cross-site associations, asset lookup, reordering, categories, and fragment ownership.
|
|
55
|
+
- Fix file modal cleanup and reinitialization, and expose jQuery for Bootstrap integration.
|
|
56
|
+
- Remove the unsupported `:escape` option before JSON parsing while preserving other parser options.
|
|
57
|
+
|
|
58
|
+
### Historical v3.2.0 upgrade behavior
|
|
59
|
+
|
|
60
|
+
For v3.2.0, users replaced `comfortable_media_surfer` with `comfy_middle_seat` in the Gemfile while keeping the former Ruby namespace and initializer name. That release-specific compatibility guidance is preserved for history but is superseded by the Unreleased change: current upgrades must rename the initializer to `config/initializers/comfy_middle_seat.rb` and replace `ComfortableMediaSurfer` Ruby references with `ComfyMiddleSeat`. Neither stage changes the database schema.
|
|
61
|
+
|
|
62
|
+
## Comfortable Media Surfer — inherited releases
|
|
63
|
+
|
|
64
|
+
The releases below belong to `comfortable_media_surfer`, not `comfy_middle_seat`. Their original notes and upstream comparison links are preserved.
|
|
65
|
+
|
|
15
66
|
## [v3.1.7] - 2026-02-20
|
|
16
67
|
|
|
17
68
|
### Fixed
|
|
@@ -135,7 +186,9 @@ First release of `comfortable_media_surfer`. This new gem is a revival of [Comfo
|
|
|
135
186
|
|
|
136
187
|
- Rebranded **ComfortableMexicanSofa** as **ComfortableMediaSurfer** in order to publish new gem (database table names and schema have not changed).
|
|
137
188
|
|
|
138
|
-
[Unreleased]: https://github.com/
|
|
189
|
+
[Unreleased]: https://github.com/avonderluft/comfy-middle-seat/compare/v3.2.1...master
|
|
190
|
+
[v3.2.1]: https://github.com/avonderluft/comfy-middle-seat/compare/v3.2.0...v3.2.1
|
|
191
|
+
[v3.2.0]: https://github.com/avonderluft/comfy-middle-seat/compare/eeb5d590f47b5d6bb70191fb81c781540753fa97...v3.2.0
|
|
139
192
|
[v3.1.7]: https://github.com/shakacode/comfortable-media-surfer/compare/v3.1.6...v3.1.7
|
|
140
193
|
[v3.1.6]: https://github.com/shakacode/comfortable-media-surfer/compare/v3.1.5...v3.1.6
|
|
141
194
|
[v3.1.5]: https://github.com/shakacode/comfortable-media-surfer/compare/v3.1.4...v3.1.5
|
data/CONTRIBUTING.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Contributing
|
|
2
2
|
|
|
3
|
-
Contribute
|
|
3
|
+
Contribute to [Comfy Middle Seat](https://github.com/avonderluft/comfy-middle-seat) in five steps:
|
|
4
4
|
|
|
5
5
|
### 1. Fork it
|
|
6
6
|
|
|
7
|
-
Fork the
|
|
7
|
+
Fork the [current repository](https://github.com/avonderluft/comfy-middle-seat). Optionally, create a branch for your work.
|
|
8
8
|
|
|
9
9
|
### 2. Get it running locally
|
|
10
10
|
|
|
@@ -25,9 +25,12 @@ Fork the project. Optionally, create a branch you want to work on.
|
|
|
25
25
|
|
|
26
26
|
### 3. Hack away
|
|
27
27
|
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
28
|
+
- Use the current `ComfyMiddleSeat` Ruby namespace and `comfy_middle_seat` internal paths. New configuration examples and generated initializers belong in `config/initializers/comfy_middle_seat.rb`; do not reintroduce `ComfortableMediaSurfer` as a current API.
|
|
29
|
+
- Keep the existing `comfy_cms_*` database tables and schema stable. The namespace and internal-path decoupling does not require a database migration.
|
|
30
|
+
- Historical release notes, acknowledgements, and upstream links may intentionally retain the Comfortable Media Surfer name.
|
|
31
|
+
- Create a few small pull requests instead of one huge pull request. Smaller changes can be reviewed and merged faster.
|
|
32
|
+
- When adding new code, make sure it follows the same style as the existing code.
|
|
33
|
+
- Avoid adding third-party dependencies if you can.
|
|
31
34
|
- Tests please, but nothing complicated. UnitTest / Fixtures all the way. Make sure all tests pass.
|
|
32
35
|
- Run `bundle exec rubocop` and fix any issues raised.
|
|
33
36
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
[](https://github.com/avonderluft/comfy-middle-seat/actions/workflows/rubyonrails.yml)
|
|
2
|
-
[](https://rubygems.org/gems/comfy_middle_seat)
|
|
3
|
-
[](https://rubygems.org/gems/comfy_middle_seat)
|
|
4
|
-
[](https://github.com/avonderluft/comfy-middle-seat/releases)
|
|
1
|
+
[](https://github.com/avonderluft/comfy-middle-seat/actions/workflows/rubyonrails.yml) [](https://coveralls.io/github/avonderluft/comfy-middle-seat?branch=master) [](https://rubygems.org/gems/comfy_middle_seat) [](https://rubygems.org/gems/comfy_middle_seat) [](https://github.com/avonderluft/comfy-middle-seat/releases)
|
|
5
2
|
|
|
6
3
|
# Comfy Middle Seat
|
|
7
4
|
|
|
8
|
-
|
|
5
|
+
It all depends on who is sitting on your left and on your right.
|
|
9
6
|
|
|
10
|
-
|
|
7
|
+
Comfy Middle Seat is a Rails CMS (Content Management System) engine, published as the `comfy_middle_seat` gem. It is descended from Comfortable Media Surfer and pays homage to the original Comfortable Mexican Sofa—with the same C.M.S. initials with a new place to sit.
|
|
8
|
+
|
|
9
|
+
The current implementation uses the `ComfyMiddleSeat` Ruby namespace, `comfy_middle_seat` internal paths, and the initializer `config/initializers/comfy_middle_seat.rb`. Database storage remains compatible: the existing `comfy_cms_*` tables and schema are unchanged, so this namespace change requires no database migration.
|
|
11
10
|
|
|
12
11
|
## Project History
|
|
13
12
|
|
|
14
|
-
- **[Comfortable Mexican Sofa](https://github.com/comfy/comfortable-mexican-sofa)**, created by Oleg Khabarov, is the original Rails CMS on which this project is built.
|
|
15
|
-
- **[
|
|
16
|
-
- **
|
|
13
|
+
- **[Comfortable Mexican Sofa](https://github.com/comfy/comfortable-mexican-sofa)**, created by Oleg Khabarov, is the original Rails CMS on which this project is built. Oleg deserves the lion's share of kudos.
|
|
14
|
+
- **[oCcaMS](https://github.com/avonderluft/occams)** was an attempted revival of Sofa. Andrew vonderLuft was a contributor to [RadiantCMS](https://github.com/radiant/radiant) back in the day, but that project became inactive. He found Sofa and liked it even better than Radiant, but sadly it too became inactive. Hence Occams.
|
|
15
|
+
- **[Comfortable Media Surfer](https://github.com/shakacode/comfortable-media-surfer)** revived Sofa under the sponsorship of ShakaCode, continuing its development for modern Rails applications.
|
|
16
|
+
- **[Comfy Middle Seat](https://github.com/avonderluft/comfy-middle-seat)** began as a fork of Comfortable Media Surfer and is now implemented under its own `ComfyMiddleSeat` namespace and `comfy_middle_seat` paths.
|
|
17
17
|
|
|
18
18
|
See the [CHANGELOG](CHANGELOG.md) for the inherited development history, and the original [Sofa releases](https://github.com/comfy/comfortable-mexican-sofa/releases) and [Surfer releases](https://github.com/shakacode/comfortable-media-surfer/releases) for earlier releases.
|
|
19
19
|
|
|
@@ -22,10 +22,10 @@ See the [CHANGELOG](CHANGELOG.md) for the inherited development history, and the
|
|
|
22
22
|
- Simple drop-in integration with Rails 7.2+ apps with minimal configuration
|
|
23
23
|
* The CMS keeps clear from the rest of your application
|
|
24
24
|
* Powerful page templating capability using [Content Tags](https://github.com/shakacode/comfortable-media-surfer/wiki/Docs:-Content-Tags)
|
|
25
|
-
* [Multiple Sites](https://github.com/shakacode/comfortable-media-surfer/wiki/
|
|
25
|
+
* [Multiple Sites](https://github.com/shakacode/comfortable-media-surfer/wiki/Sites) from a single installation
|
|
26
26
|
* Multi-Language Support (i18n) (ca, cs, da, de, en, es, fi, fr, gr, hr, it, ja, nb, nl, pl, pt-BR, ru, sv, tr, uk, zh-CN, zh-TW) and page localization.
|
|
27
|
-
* [CMS Seeds](https://github.com/shakacode/comfortable-media-surfer/wiki/
|
|
28
|
-
* [Revision History](https://github.com/shakacode/comfortable-media-surfer/wiki/
|
|
27
|
+
* [CMS Seeds](https://github.com/shakacode/comfortable-media-surfer/wiki/CMS-Seeds) for initial content population
|
|
28
|
+
* [Revision History](https://github.com/shakacode/comfortable-media-surfer/wiki/Revisions) to revert changes
|
|
29
29
|
* [Extendable Admin Area](https://github.com/shakacode/comfortable-media-surfer/wiki/HowTo:-Reusing-Admin-Area) built with [Bootstrap 4](http://getbootstrap.com) (responsive design). Using [CodeMirror](http://codemirror.net) for HTML and Markdown highlighing and [Redactor](http://imperavi.com/redactor) as the WYSIWYG editor.
|
|
30
30
|
|
|
31
31
|
## Dependencies
|
|
@@ -43,18 +43,20 @@ On Ruby 3.2+, 4.x, Rails 7.2+, 8.x
|
|
|
43
43
|
Add gem definition to your Gemfile:
|
|
44
44
|
|
|
45
45
|
```ruby
|
|
46
|
-
gem "comfy_middle_seat", "~> 3.
|
|
46
|
+
gem "comfy_middle_seat", "~> 3.2.0"
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
Then from the Rails project's root
|
|
49
|
+
Then, for a new installation, run these commands from the Rails project's root:
|
|
50
50
|
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
```sh
|
|
52
|
+
bundle install
|
|
53
|
+
rails generate comfy:cms
|
|
54
|
+
rails db:migrate
|
|
55
|
+
rails comfy:compile_assets
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
+
`rails db:migrate` is part of a new installation. Applications upgrading from Comfortable Media Surfer already have the same tables and schema and do not need a database migration for the gem, namespace, or internal-path rename.
|
|
59
|
+
|
|
58
60
|
Now take a look inside your `config/routes.rb` file. You'll see where routes attach for the admin area and content serving. Make sure that content serving route appears as a very last item or it will make all other routes to be inaccessible.
|
|
59
61
|
|
|
60
62
|
```ruby
|
|
@@ -62,24 +64,60 @@ comfy_route :cms_admin, path: "/admin"
|
|
|
62
64
|
comfy_route :cms, path: "/"
|
|
63
65
|
```
|
|
64
66
|
|
|
67
|
+
The generator creates `config/initializers/comfy_middle_seat.rb`. Use `ComfyMiddleSeat` for configuration and other library API references:
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
ComfyMiddleSeat.configure do |config|
|
|
71
|
+
config.cms_title = "My CMS"
|
|
72
|
+
config.admin_base_controller = "ApplicationController"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
ComfyMiddleSeat::AccessControl::AdminAuthentication.username = "user"
|
|
76
|
+
ComfyMiddleSeat::AccessControl::AdminAuthentication.password = "change-me"
|
|
77
|
+
```
|
|
78
|
+
|
|
65
79
|
## Converting from Comfortable Media Surfer, Comfortable Mexican Sofa, or Occams
|
|
66
80
|
|
|
67
81
|
### From Surfer to Middle Seat
|
|
68
82
|
|
|
69
|
-
Replace `comfortable_media_surfer` in your Gemfile with `comfy_middle_seat` and run `bundle install`. Do not include both gems.
|
|
83
|
+
1. Replace `comfortable_media_surfer` in your Gemfile with `comfy_middle_seat` and run `bundle install`. Do not include both gems.
|
|
84
|
+
2. From the Rails application root, preview and run the standalone initializer upgrader. It does not boot Rails:
|
|
85
|
+
|
|
86
|
+
```sh
|
|
87
|
+
bundle exec comfy-middle-seat-upgrade --dry-run
|
|
88
|
+
bundle exec comfy-middle-seat-upgrade
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
It renames `config/initializers/comfortable_media_surfer.rb` to `config/initializers/comfy_middle_seat.rb`, updates the project namespace references inside it, and preserves the original as `config/initializers/comfortable_media_surfer.rb.bak`. It refuses to overwrite an existing initializer or backup.
|
|
92
|
+
3. In any other application integrations, replace Ruby references to `ComfortableMediaSurfer` with `ComfyMiddleSeat`.
|
|
93
|
+
|
|
94
|
+
For example:
|
|
95
|
+
|
|
96
|
+
```ruby
|
|
97
|
+
# Before
|
|
98
|
+
ComfortableMediaSurfer.configure do |config|
|
|
99
|
+
config.cms_title = "My CMS"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# After
|
|
103
|
+
ComfyMiddleSeat.configure do |config|
|
|
104
|
+
config.cms_title = "My CMS"
|
|
105
|
+
end
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Review the converted initializer and remove its `.bak` file when satisfied. The database tables, schema, and stored records remain unchanged; existing `comfy_cms_*` tables are used as-is, and **no database migration is required** for this upgrade.
|
|
70
109
|
|
|
71
110
|
### From Sofa to Middle Seat
|
|
72
111
|
|
|
73
|
-
The database structure is the same.
|
|
74
|
-
Then you should simply be able to update your Gemfile thus, and run bundle
|
|
112
|
+
The database structure is the same, so no database migration is required for the CMS tables. Your Sofa project must first be upgraded to Rails 7.2 or newer. Then update the Gemfile, run `bundle install`, use `config/initializers/comfy_middle_seat.rb`, and update CMS library references in application code to `ComfyMiddleSeat`:
|
|
75
113
|
|
|
76
114
|
```ruby
|
|
77
|
-
gem
|
|
115
|
+
gem "comfy_middle_seat", "~> 3.2.0"
|
|
78
116
|
```
|
|
79
117
|
|
|
80
118
|
### From Occams to Middle Seat
|
|
81
119
|
|
|
82
|
-
|
|
120
|
+
The project must be on Rails 7.2 or newer. Unlike Surfer and Sofa, Occams used different table names, so converting an Occams database requires the following SQL. This is an Occams data conversion, not a migration caused by the current `ComfyMiddleSeat` namespace or internal-path change.
|
|
83
121
|
|
|
84
122
|
```sql
|
|
85
123
|
ALTER TABLE occams_cms_categories RENAME TO comfy_cms_categories;
|
|
@@ -107,7 +145,7 @@ UPDATE active_storage_attachments SET record_type = 'Comfy::Cms::File' WHERE rec
|
|
|
107
145
|
|
|
108
146
|
After finishing installation you should be able to navigate to http://localhost:3000/admin
|
|
109
147
|
|
|
110
|
-
|
|
148
|
+
The default username and password are `user` and `pass`. Change them before exposing the application. Admin credentials and other CMS settings are configured in `config/initializers/comfy_middle_seat.rb` through the `ComfyMiddleSeat` namespace.
|
|
111
149
|
|
|
112
150
|
Before creating pages and populating them with content we need to create a Site. Site defines a hostname, content path and its language.
|
|
113
151
|
|
|
@@ -126,7 +164,7 @@ Once you have a layout, you may start creating pages and populating content. It'
|
|
|
126
164
|
|
|
127
165
|
## Documentation
|
|
128
166
|
|
|
129
|
-
The [Comfortable Media Surfer Wiki](https://github.com/shakacode/comfortable-media-surfer/wiki) remains
|
|
167
|
+
The [Comfortable Media Surfer Wiki](https://github.com/shakacode/comfortable-media-surfer/wiki) remains an upstream reference for inherited CMS features, including [Content Tags](https://github.com/shakacode/comfortable-media-surfer/wiki/Docs:-Content-Tags). These historical upstream links are intentionally preserved. When adapting its examples, use the `comfy_middle_seat` gem, `config/initializers/comfy_middle_seat.rb`, and the `ComfyMiddleSeat` Ruby namespace; upstream examples that use `ComfortableMediaSurfer` show the former API and must be updated.
|
|
130
168
|
|
|
131
169
|
## Add-ons
|
|
132
170
|
|
|
@@ -138,7 +176,7 @@ If you want to add a Blog functionality to your app take a look at
|
|
|
138
176
|
|
|
139
177
|
#### Contributing
|
|
140
178
|
|
|
141
|
-
Comfy Middle Seat can run like any Rails application in development. It's as easy to work on as any other Rails app. For more detail see [CONTRIBUTING](CONTRIBUTING.md).
|
|
179
|
+
Comfy Middle Seat can run like any Rails application in development. It's as easy to work on as any other Rails app. For more detail, see [CONTRIBUTING](CONTRIBUTING.md).
|
|
142
180
|
|
|
143
181
|
#### Testing
|
|
144
182
|
|
|
@@ -154,5 +192,4 @@ Comfy Middle Seat can run like any Rails application in development. It's as eas
|
|
|
154
192
|
|
|
155
193
|
---
|
|
156
194
|
|
|
157
|
-
Copyright 2010-2019 Oleg Khabarov, 2024-2026 ShakaCode LLC, 2026 Andrew vonderLuft
|
|
158
|
-
Released under the [MIT license](LICENSE)
|
|
195
|
+
Copyright 2010-2019 Oleg Khabarov, 2024-2026 ShakaCode LLC, 2026 Andrew vonderLuft.<br/>Released under the [MIT license](LICENSE)
|
data/Rakefile
CHANGED
|
@@ -8,7 +8,7 @@ require 'stringio'
|
|
|
8
8
|
|
|
9
9
|
Rails.application.load_tasks
|
|
10
10
|
|
|
11
|
-
module
|
|
11
|
+
module ComfyMiddleSeatTestOutput
|
|
12
12
|
SUMMARY = %r{(?<assertions>\d+) assertions, (?<errors>\d+) errors, (?<failures>\d+) failures, (?<skips>\d+) skips?, (?<tests>\d+) tests}
|
|
13
13
|
COLORS = { green: 32, yellow: 33, red: 31, cyan: 36 }.freeze
|
|
14
14
|
|
|
@@ -71,7 +71,7 @@ module ComfortableMediaSurferTestOutput
|
|
|
71
71
|
def flush
|
|
72
72
|
return if @pending.empty?
|
|
73
73
|
|
|
74
|
-
@io.print
|
|
74
|
+
@io.print ComfyMiddleSeatTestOutput.progress_color(@pending)
|
|
75
75
|
@io.flush
|
|
76
76
|
@pending.clear
|
|
77
77
|
end
|
|
@@ -197,7 +197,7 @@ namespace :test do
|
|
|
197
197
|
Rake::Task['test:serial'].enhance(['test:prepare_serial'])
|
|
198
198
|
|
|
199
199
|
desc 'Run tests in isolated processes'
|
|
200
|
-
task(:parallel) {
|
|
200
|
+
task(:parallel) { ComfyMiddleSeatTestOutput.run_parallel }
|
|
201
201
|
end
|
|
202
202
|
|
|
203
203
|
Rake::Task[:test].clear
|
|
@@ -25,15 +25,20 @@
|
|
|
25
25
|
CMS.wysiwyg.init();
|
|
26
26
|
CMS.sortableList.init();
|
|
27
27
|
CMS.timepicker.init();
|
|
28
|
-
CMS.pageFragments();
|
|
28
|
+
CMS.pageFragments.init();
|
|
29
29
|
CMS.categories();
|
|
30
30
|
CMS.files.init();
|
|
31
31
|
CMS.fileLinks();
|
|
32
32
|
CMS.fileUpload.init();
|
|
33
33
|
CMS.diff();
|
|
34
|
+
CMS.draftForms.init();
|
|
35
|
+
CMS.dirtyForms.init();
|
|
34
36
|
};
|
|
35
37
|
|
|
36
38
|
CMS.dispose = () => {
|
|
39
|
+
CMS.pageFragments.dispose();
|
|
40
|
+
CMS.draftForms.dispose();
|
|
41
|
+
CMS.dirtyForms.dispose();
|
|
37
42
|
CMS.codemirror.dispose();
|
|
38
43
|
CMS.wysiwyg.dispose();
|
|
39
44
|
CMS.files.dispose();
|
|
@@ -18,6 +18,9 @@ import "codemirror/mode/htmlmixed/htmlmixed";
|
|
|
18
18
|
lineNumbers: true,
|
|
19
19
|
viewportMargin: Infinity,
|
|
20
20
|
});
|
|
21
|
+
codemirror.on("change", () => {
|
|
22
|
+
textarea.dispatchEvent(new Event("input", { bubbles: true }));
|
|
23
|
+
});
|
|
21
24
|
codeMirrorInstances.push(codemirror);
|
|
22
25
|
}
|
|
23
26
|
|
|
@@ -33,6 +36,20 @@ import "codemirror/mode/htmlmixed/htmlmixed";
|
|
|
33
36
|
}
|
|
34
37
|
});
|
|
35
38
|
},
|
|
39
|
+
sync(root = document) {
|
|
40
|
+
for (const codemirror of codeMirrorInstances) {
|
|
41
|
+
if (root.contains(codemirror.getTextArea())) codemirror.save();
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
restore(root = document) {
|
|
45
|
+
for (const codemirror of codeMirrorInstances) {
|
|
46
|
+
const textarea = codemirror.getTextArea();
|
|
47
|
+
if (!root.contains(textarea)) continue;
|
|
48
|
+
|
|
49
|
+
codemirror.setValue(textarea.value);
|
|
50
|
+
codemirror.refresh();
|
|
51
|
+
}
|
|
52
|
+
},
|
|
36
53
|
dispose() {
|
|
37
54
|
for (const codemirror of codeMirrorInstances) {
|
|
38
55
|
codemirror.toTextArea();
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
(() => {
|
|
2
|
+
const defaultMessage =
|
|
3
|
+
"You have unsaved changes. Are you sure you want to leave this page?";
|
|
4
|
+
|
|
5
|
+
let forms = [];
|
|
6
|
+
let baselines = new WeakMap();
|
|
7
|
+
let submittingForms = new WeakSet();
|
|
8
|
+
let navigationAllowed = false;
|
|
9
|
+
|
|
10
|
+
const controlState = (control) => {
|
|
11
|
+
if (!control.name) return null;
|
|
12
|
+
|
|
13
|
+
const type = (control.type || "").toLowerCase();
|
|
14
|
+
if (["button", "image", "reset", "submit"].includes(type)) return null;
|
|
15
|
+
|
|
16
|
+
if (type === "checkbox" || type === "radio") {
|
|
17
|
+
return [control.name, type, control.value, control.checked];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (type === "file") {
|
|
21
|
+
return [
|
|
22
|
+
control.name,
|
|
23
|
+
type,
|
|
24
|
+
Array.from(control.files).map((file) => [
|
|
25
|
+
file.name,
|
|
26
|
+
file.size,
|
|
27
|
+
file.lastModified,
|
|
28
|
+
]),
|
|
29
|
+
];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (control instanceof HTMLSelectElement && control.multiple) {
|
|
33
|
+
return [
|
|
34
|
+
control.name,
|
|
35
|
+
type,
|
|
36
|
+
Array.from(control.selectedOptions).map((option) => option.value),
|
|
37
|
+
];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return [control.name, type, control.value];
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const formState = (form) =>
|
|
44
|
+
JSON.stringify(Array.from(form.elements).map(controlState).filter(Boolean));
|
|
45
|
+
|
|
46
|
+
const syncEditors = () => {
|
|
47
|
+
if (CMS.codemirror && CMS.codemirror.sync) CMS.codemirror.sync();
|
|
48
|
+
if (CMS.wysiwyg && CMS.wysiwyg.sync) CMS.wysiwyg.sync();
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const dirtyForms = () => {
|
|
52
|
+
syncEditors();
|
|
53
|
+
return forms.filter(
|
|
54
|
+
(form) =>
|
|
55
|
+
form.isConnected &&
|
|
56
|
+
baselines.has(form) &&
|
|
57
|
+
baselines.get(form) !== formState(form)
|
|
58
|
+
);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const formsRequiringWarning = () =>
|
|
62
|
+
dirtyForms().filter((form) => !submittingForms.has(form));
|
|
63
|
+
|
|
64
|
+
const warningMessage = (dirtyForm) =>
|
|
65
|
+
dirtyForm.dataset.cmsUnsavedMessage || defaultMessage;
|
|
66
|
+
|
|
67
|
+
const beforeUnload = (event) => {
|
|
68
|
+
if (navigationAllowed || formsRequiringWarning().length === 0) return;
|
|
69
|
+
|
|
70
|
+
event.preventDefault();
|
|
71
|
+
event.returnValue = "";
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const navigationTarget = (event) => {
|
|
75
|
+
if (
|
|
76
|
+
event.defaultPrevented ||
|
|
77
|
+
event.button !== 0 ||
|
|
78
|
+
event.metaKey ||
|
|
79
|
+
event.ctrlKey ||
|
|
80
|
+
event.shiftKey ||
|
|
81
|
+
event.altKey
|
|
82
|
+
) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const link = event.target.closest("a[href]");
|
|
87
|
+
if (!link || link.hasAttribute("download")) return null;
|
|
88
|
+
|
|
89
|
+
const target = link.getAttribute("target");
|
|
90
|
+
if (target && !["_self", "_top", "_parent", window.name].includes(target)) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const url = new URL(link.href, document.location.href);
|
|
95
|
+
if (
|
|
96
|
+
url.origin === document.location.origin &&
|
|
97
|
+
url.pathname === document.location.pathname &&
|
|
98
|
+
url.search === document.location.search &&
|
|
99
|
+
url.hash
|
|
100
|
+
) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return link;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const allowCurrentNavigation = () => {
|
|
108
|
+
navigationAllowed = true;
|
|
109
|
+
window.setTimeout(() => {
|
|
110
|
+
navigationAllowed = false;
|
|
111
|
+
}, 0);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const confirmLinkNavigation = (event) => {
|
|
115
|
+
if (navigationAllowed || !navigationTarget(event)) return;
|
|
116
|
+
|
|
117
|
+
const dirtyForm = formsRequiringWarning()[0];
|
|
118
|
+
if (!dirtyForm) return;
|
|
119
|
+
|
|
120
|
+
if (!window.confirm(warningMessage(dirtyForm))) {
|
|
121
|
+
event.preventDefault();
|
|
122
|
+
event.stopImmediatePropagation();
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
allowCurrentNavigation();
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const confirmTurbolinksNavigation = (event) => {
|
|
130
|
+
if (navigationAllowed) return;
|
|
131
|
+
|
|
132
|
+
const dirtyForm = formsRequiringWarning()[0];
|
|
133
|
+
if (!dirtyForm) return;
|
|
134
|
+
|
|
135
|
+
if (!window.confirm(warningMessage(dirtyForm))) {
|
|
136
|
+
event.preventDefault();
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
allowCurrentNavigation();
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const markSubmitting = (event) => {
|
|
144
|
+
const form = event.target;
|
|
145
|
+
const submitterTarget = event.submitter && event.submitter.formTarget;
|
|
146
|
+
const target = submitterTarget || form.target;
|
|
147
|
+
|
|
148
|
+
if (
|
|
149
|
+
target &&
|
|
150
|
+
!["_self", "_top", "_parent", window.name].includes(target)
|
|
151
|
+
) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
submittingForms.add(form);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
window.CMS.dirtyForms = {
|
|
159
|
+
init() {
|
|
160
|
+
forms = Array.from(
|
|
161
|
+
document.querySelectorAll("form[data-cms-unsaved-message]")
|
|
162
|
+
);
|
|
163
|
+
baselines = new WeakMap();
|
|
164
|
+
submittingForms = new WeakSet();
|
|
165
|
+
navigationAllowed = false;
|
|
166
|
+
|
|
167
|
+
for (const form of forms) {
|
|
168
|
+
const baseline =
|
|
169
|
+
form.dataset.cmsSaveFailed === "true" ? null : formState(form);
|
|
170
|
+
baselines.set(form, baseline);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
window.addEventListener("beforeunload", beforeUnload);
|
|
174
|
+
document.addEventListener("click", confirmLinkNavigation, true);
|
|
175
|
+
document.addEventListener("submit", markSubmitting, true);
|
|
176
|
+
document.addEventListener(
|
|
177
|
+
"turbolinks:before-visit",
|
|
178
|
+
confirmTurbolinksNavigation
|
|
179
|
+
);
|
|
180
|
+
},
|
|
181
|
+
|
|
182
|
+
dispose() {
|
|
183
|
+
window.removeEventListener("beforeunload", beforeUnload);
|
|
184
|
+
document.removeEventListener("click", confirmLinkNavigation, true);
|
|
185
|
+
document.removeEventListener("submit", markSubmitting, true);
|
|
186
|
+
document.removeEventListener(
|
|
187
|
+
"turbolinks:before-visit",
|
|
188
|
+
confirmTurbolinksNavigation
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
forms = [];
|
|
192
|
+
baselines = new WeakMap();
|
|
193
|
+
submittingForms = new WeakSet();
|
|
194
|
+
navigationAllowed = false;
|
|
195
|
+
},
|
|
196
|
+
|
|
197
|
+
isDirty() {
|
|
198
|
+
return dirtyForms().length > 0;
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
})();
|