comfortable_media_surfer 3.0.0 → 3.1.2

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 (131) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +1 -0
  3. data/.github/dependabot.yml +7 -0
  4. data/.github/workflows/coveralls.yml +13 -1
  5. data/.github/workflows/rubyonrails.yml +15 -3
  6. data/.gitignore +4 -0
  7. data/.rubocop.yml +4 -1
  8. data/CHANGELOG.md +86 -0
  9. data/CONTRIBUTING.md +5 -2
  10. data/Gemfile +10 -6
  11. data/README.md +64 -27
  12. data/app/assets/builds/.keep +0 -0
  13. data/app/assets/config/manifest.js +1 -0
  14. data/app/assets/javascripts/comfy/admin/cms/application.js +21 -36
  15. data/app/assets/javascripts/comfy/admin/cms/base.js +6 -5
  16. data/app/assets/javascripts/comfy/admin/cms/codemirror.js +22 -10
  17. data/app/assets/javascripts/comfy/admin/cms/diff.js +7 -5
  18. data/app/assets/javascripts/comfy/admin/cms/file_link.js +17 -11
  19. data/app/assets/javascripts/comfy/admin/cms/file_upload.js +67 -41
  20. data/app/assets/javascripts/comfy/admin/cms/files_modal.js +20 -13
  21. data/app/assets/javascripts/comfy/admin/cms/sortable_list.js +28 -19
  22. data/app/assets/javascripts/comfy/admin/cms/timepicker.js +20 -12
  23. data/app/assets/javascripts/comfy/admin/cms/wysiwyg.js +39 -20
  24. data/app/assets/javascripts/comfy/vendor/diff/pretty_text_diff.js +30 -18
  25. data/app/assets/javascripts/comfy/vendor/redactor/definedlinks.js +31 -34
  26. data/app/assets/javascripts/comfy/vendor/redactor/filemanager.js +77 -62
  27. data/app/assets/javascripts/comfy/vendor/redactor/i18n/hr.js +78 -76
  28. data/app/assets/javascripts/comfy/vendor/redactor/i18n/nb.js +76 -74
  29. data/app/assets/javascripts/comfy/vendor/redactor/i18n/pl.js +77 -75
  30. data/app/assets/javascripts/comfy/vendor/redactor/imagemanager.js +66 -55
  31. data/app/assets/javascripts/comfy/vendor/redactor/table.js +346 -335
  32. data/app/assets/javascripts/comfy/vendor/redactor/video.js +69 -64
  33. data/app/assets/javascripts/comfy/vendor/redactor.js +2 -0
  34. data/app/assets/stylesheets/comfy/admin/cms/application.sass +2 -2
  35. data/app/assets/stylesheets/comfy/admin/cms/codemirror_overrides.sass +1 -1
  36. data/app/helpers/comfy/admin/cms_helper.rb +2 -2
  37. data/app/views/comfy/admin/cms/pages/toggle_branch.js.erb +14 -8
  38. data/comfortable_media_surfer.gemspec +8 -9
  39. data/config/application.rb +4 -1
  40. data/config/environments/development.rb +11 -10
  41. data/config/environments/production.rb +0 -6
  42. data/config/puma.rb +43 -0
  43. data/db/migrate/01_create_cms.rb +0 -1
  44. data/db/migrate/02_add_markdown_to_snippets.rb +5 -0
  45. data/gemfiles/7.1.gemfile +3 -2
  46. data/gemfiles/7.2.gemfile +3 -2
  47. data/gemfiles/{6.1.gemfile → 8.0.gemfile} +3 -2
  48. data/lib/comfortable_media_surfer/content/tags/audio.rb +1 -1
  49. data/lib/comfortable_media_surfer/content/tags/breadcrumbs.rb +1 -1
  50. data/lib/comfortable_media_surfer/content/tags/children.rb +1 -1
  51. data/lib/comfortable_media_surfer/content/tags/siblings.rb +1 -1
  52. data/lib/comfortable_media_surfer/engine.rb +3 -8
  53. data/lib/comfortable_media_surfer/extensions/has_revisions.rb +1 -1
  54. data/lib/comfortable_media_surfer/render_methods.rb +7 -7
  55. data/lib/comfortable_media_surfer/version.rb +1 -1
  56. data/lib/generators/comfy/cms/README +2 -9
  57. data/lib/generators/comfy/cms/cms_generator.rb +9 -7
  58. data/lib/generators/comfy/scaffold/scaffold_generator.rb +1 -1
  59. data/lib/tasks/cms_assets.rake +19 -0
  60. data/package-lock.json +379 -0
  61. data/package.json +23 -0
  62. data/rakelib/create_release.rake +17 -17
  63. metadata +24 -146
  64. data/app/assets/javascripts/comfy/vendor/Moxie.swf +0 -0
  65. data/app/assets/javascripts/comfy/vendor/Moxie.xap +0 -0
  66. data/app/assets/javascripts/comfy/vendor/bootstrap.bundle.min.js +0 -7
  67. data/app/assets/javascripts/comfy/vendor/bootstrap.bundle.min.js.map +0 -1
  68. data/app/assets/javascripts/comfy/vendor/codemirror/addon/edit/closetag.js +0 -169
  69. data/app/assets/javascripts/comfy/vendor/codemirror/mode/css/css.js +0 -832
  70. data/app/assets/javascripts/comfy/vendor/codemirror/mode/htmlmixed/htmlmixed.js +0 -152
  71. data/app/assets/javascripts/comfy/vendor/codemirror/mode/javascript/javascript.js +0 -875
  72. data/app/assets/javascripts/comfy/vendor/codemirror/mode/markdown/markdown.js +0 -861
  73. data/app/assets/javascripts/comfy/vendor/codemirror/mode/xml/xml.js +0 -394
  74. data/app/assets/javascripts/comfy/vendor/codemirror.js +0 -9653
  75. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/ar.js +0 -52
  76. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/bg.js +0 -65
  77. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/bn.js +0 -65
  78. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/ca.js +0 -83
  79. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/cs.js +0 -70
  80. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/cy.js +0 -92
  81. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/da.js +0 -71
  82. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/de.js +0 -70
  83. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/default.js +0 -80
  84. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/eo.js +0 -73
  85. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/es.js +0 -69
  86. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/et.js +0 -73
  87. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/fa.js +0 -68
  88. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/fi.js +0 -69
  89. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/fr.js +0 -75
  90. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/gr.js +0 -74
  91. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/he.js +0 -57
  92. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/hi.js +0 -65
  93. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/hr.js +0 -66
  94. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/hu.js +0 -72
  95. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/id.js +0 -61
  96. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/it.js +0 -70
  97. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/ja.js +0 -57
  98. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/ko.js +0 -60
  99. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/lt.js +0 -72
  100. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/lv.js +0 -67
  101. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/mk.js +0 -69
  102. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/mn.js +0 -67
  103. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/ms.js +0 -68
  104. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/my.js +0 -69
  105. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/nl.js +0 -75
  106. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/no.js +0 -73
  107. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/pa.js +0 -65
  108. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/pl.js +0 -68
  109. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/pt-BR.js +0 -66
  110. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/pt.js +0 -66
  111. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/ro.js +0 -69
  112. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/ru.js +0 -66
  113. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/si.js +0 -65
  114. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/sk.js +0 -70
  115. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/sl.js +0 -70
  116. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/sq.js +0 -65
  117. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/sr.js +0 -69
  118. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/sv.js +0 -70
  119. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/th.js +0 -72
  120. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/tr.js +0 -66
  121. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/uk.js +0 -66
  122. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/vn.js +0 -66
  123. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/zh-CN.js +0 -61
  124. data/app/assets/javascripts/comfy/vendor/flatpickr/i18n/zh-TW.js +0 -61
  125. data/app/assets/javascripts/comfy/vendor/moxie.min.js +0 -16
  126. data/app/assets/javascripts/comfy/vendor/plupload.dev.js +0 -2497
  127. data/app/assets/javascripts/comfy/vendor/sortable.min.js +0 -5
  128. data/app/assets/stylesheets/comfy/vendor/codemirror.css +0 -346
  129. data/app/assets/stylesheets/comfy/vendor/flatpickr.min.css +0 -13
  130. data/config/initializers/assets.rb +0 -14
  131. data/gemfiles/7.0.gemfile +0 -31
@@ -1,3 +1,6 @@
1
+ import jQuery from "jquery";
2
+ import Popover from "bootstrap/js/src/popover";
3
+
1
4
  (() => {
2
5
  const isFirefox = /\bFirefox\//.test(navigator.userAgent);
3
6
 
@@ -6,20 +9,23 @@
6
9
  this.link = link;
7
10
  this.isImage = !!link.dataset.cmsFileThumbUrl;
8
11
 
9
- link.addEventListener('dragstart', (evt) => {
10
- evt.dataTransfer.setData('text/plain', this.link.dataset.cmsFileLinkTag);
12
+ link.addEventListener("dragstart", (evt) => {
13
+ evt.dataTransfer.setData(
14
+ "text/plain",
15
+ this.link.dataset.cmsFileLinkTag
16
+ );
11
17
  });
12
18
 
13
19
  if (this.isImage) {
14
- new bootstrap.Popover(link, {
20
+ new Popover(link, {
15
21
  container: link.parentElement,
16
- trigger: 'hover',
17
- placement: 'top',
22
+ trigger: "hover",
23
+ placement: "top",
18
24
  content: this.buildFileThumbnail(),
19
- html: true
25
+ html: true,
20
26
  });
21
27
 
22
- link.addEventListener('dragstart', (evt) => {
28
+ link.addEventListener("dragstart", (evt) => {
23
29
  evt.dataTransfer.setDragImage(this.buildFileThumbnail(), 4, 2);
24
30
  this.getPopover().hide();
25
31
  });
@@ -41,10 +47,10 @@
41
47
  // https://bugzilla.mozilla.org/show_bug.cgi?id=505521
42
48
  workAroundFirefoxPopoverGlitch() {
43
49
  if (!isFirefox) return;
44
- this.link.addEventListener('dragstart', () => {
50
+ this.link.addEventListener("dragstart", () => {
45
51
  this.getPopover().disable();
46
52
  });
47
- this.link.addEventListener('dragend', () => {
53
+ this.link.addEventListener("dragend", () => {
48
54
  setTimeout(() => {
49
55
  const popover = this.getPopover();
50
56
  popover.enable();
@@ -55,12 +61,12 @@
55
61
 
56
62
  // We can't keep a reference to the Popover object, because Bootstrap re-creates it internally.
57
63
  getPopover() {
58
- return jQuery(this.link).data(bootstrap.Popover.DATA_KEY);
64
+ return jQuery(this.link).data(Popover.DATA_KEY);
59
65
  }
60
66
  }
61
67
 
62
68
  window.CMS.fileLinks = (root = document) => {
63
- for (const link of root.querySelectorAll('[data-cms-file-link-tag]')) {
69
+ for (const link of root.querySelectorAll("[data-cms-file-link-tag]")) {
64
70
  new FileLink(link);
65
71
  }
66
72
  };
@@ -1,26 +1,38 @@
1
- //= require comfy/vendor/moxie.min
2
- //= require comfy/vendor/plupload.dev
1
+ import plupload from "plupload";
3
2
 
4
3
  (() => {
5
- const DROP_TARGET_ACTIVE_CLASS = 'cms-uploader-drag-drop-target-active';
4
+ const DROP_TARGET_ACTIVE_CLASS = "cms-uploader-drag-drop-target-active";
6
5
 
7
6
  class FileUpload {
8
7
  constructor(container, settings) {
9
8
  if (!container.id) container.id = plupload.guid();
10
- settings = Object.assign(FileUpload.defaultUploaderSettings(container.id), settings);
9
+ settings = Object.assign(
10
+ FileUpload.defaultUploaderSettings(container.id),
11
+ settings
12
+ );
11
13
  this.ui = {
12
14
  container,
13
- list: container.querySelector('.cms-uploader-filelist'),
15
+ list: container.querySelector(".cms-uploader-filelist"),
14
16
  dropElement: container.querySelector(`#${settings.drop_element}`),
15
17
  };
16
18
  this.cleanupFns = [];
17
19
  this.uploader = new plupload.Uploader(settings);
18
- this.uploader.bind('PostInit', () => this.onUploaderPostInit());
19
- this.uploader.bind('Error', (_uploader, error) => this.onUploaderError(error));
20
- this.uploader.bind('FilesAdded', (_uploader, files) => this.onUploaderFilesAdded(files));
21
- this.uploader.bind('UploadProgress', (_uploader, file) => this.onUploaderUploadProgress(file));
22
- this.uploader.bind('FileUploaded', (_uploader, file, info) => this.onUploaderFileUploaded(file, info));
23
- this.uploader.bind('FilesRemoved', (_uploader, files) => this.onUploaderFilesRemoved(files));
20
+ this.uploader.bind("PostInit", () => this.onUploaderPostInit());
21
+ this.uploader.bind("Error", (_uploader, error) =>
22
+ this.onUploaderError(error)
23
+ );
24
+ this.uploader.bind("FilesAdded", (_uploader, files) =>
25
+ this.onUploaderFilesAdded(files)
26
+ );
27
+ this.uploader.bind("UploadProgress", (_uploader, file) =>
28
+ this.onUploaderUploadProgress(file)
29
+ );
30
+ this.uploader.bind("FileUploaded", (_uploader, file, info) =>
31
+ this.onUploaderFileUploaded(file, info)
32
+ );
33
+ this.uploader.bind("FilesRemoved", (_uploader, files) =>
34
+ this.onUploaderFilesRemoved(files)
35
+ );
24
36
  this.uploader.init();
25
37
  if (settings.setup) {
26
38
  settings.setup(this.uploader);
@@ -40,8 +52,13 @@
40
52
 
41
53
  onUploaderPostInit() {
42
54
  // Show drag and drop info and attach events only if drag and drop is enabled and supported.
43
- if (!this.uploader.settings.dragdrop || !this.uploader.features.dragdrop) {
44
- this.ui.container.querySelector('.cms-uploader-drag-drop-info').style.display = 'none';
55
+ if (
56
+ !this.uploader.settings.dragdrop ||
57
+ !this.uploader.features.dragdrop
58
+ ) {
59
+ this.ui.container.querySelector(
60
+ ".cms-uploader-drag-drop-info"
61
+ ).style.display = "none";
45
62
  return;
46
63
  }
47
64
  // When dragging over the document add a class to the drop target that puts it on top of every element and remove
@@ -50,15 +67,15 @@
50
67
  const onDragEnter = (e) => {
51
68
  // Only react to drag'n'drops that contain a file. See:
52
69
  // https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/types
53
- if (e.dataTransfer.types.includes('Files')) {
70
+ if (e.dataTransfer.types.includes("Files")) {
54
71
  this.ui.dropElement.classList.add(DROP_TARGET_ACTIVE_CLASS);
55
72
  }
56
73
  };
57
- document.addEventListener('dragenter', onDragEnter);
74
+ document.addEventListener("dragenter", onDragEnter);
58
75
  this.addCleanup(() => {
59
- document.removeEventListener('dragenter', onDragEnter);
76
+ document.removeEventListener("dragenter", onDragEnter);
60
77
  });
61
- for (const eventName of ['drop', 'dragleave']) {
78
+ for (const eventName of ["drop", "dragleave"]) {
62
79
  this.ui.dropElement.addEventListener(eventName, () => {
63
80
  this.ui.dropElement.classList.remove(DROP_TARGET_ACTIVE_CLASS);
64
81
  });
@@ -67,7 +84,7 @@
67
84
 
68
85
  onUploaderError(error) {
69
86
  if (error.code === plupload.INIT_ERROR) {
70
- window.alert('Error: Initialisation error. Reload to try again.');
87
+ window.alert("Error: Initialisation error. Reload to try again.");
71
88
  return;
72
89
  }
73
90
  const file = error.file;
@@ -100,7 +117,7 @@
100
117
 
101
118
  onUploaderFileUploaded(file, info) {
102
119
  // Replace the dummy file entry in the file list with the the entry from the server response.
103
- const template = document.createElement('template');
120
+ const template = document.createElement("template");
104
121
  template.innerHTML = info.response;
105
122
  const newListItem = template.content.firstElementChild;
106
123
  this.ui.list.replaceChild(newListItem, this.fileListItem(file));
@@ -114,11 +131,16 @@
114
131
  }
115
132
 
116
133
  addFile(file) {
117
- this.ui.list.insertAdjacentHTML('afterbegin', FileUpload.buildListItemHTML(file));
118
- this.fileListItem(file).querySelector('.cms-uploader-file-delete').addEventListener('click', (evt) => {
119
- evt.preventDefault();
120
- this.uploader.removeFile(file);
121
- });
134
+ this.ui.list.insertAdjacentHTML(
135
+ "afterbegin",
136
+ FileUpload.buildListItemHTML(file)
137
+ );
138
+ this.fileListItem(file)
139
+ .querySelector(".cms-uploader-file-delete")
140
+ .addEventListener("click", (evt) => {
141
+ evt.preventDefault();
142
+ this.uploader.removeFile(file);
143
+ });
122
144
  this.updateFileStatus(file);
123
145
  }
124
146
 
@@ -127,24 +149,25 @@
127
149
  }
128
150
 
129
151
  updateFileStatus(file) {
130
- const progressBar = this.fileListItem(file).querySelector('.progress-bar');
152
+ const progressBar =
153
+ this.fileListItem(file).querySelector(".progress-bar");
131
154
  switch (file.status) {
132
155
  case plupload.UPLOADING:
133
156
  progressBar.style.width = `${file.percent}%`;
134
157
  break;
135
158
  case plupload.FAILED:
136
- progressBar.style.width = '100%';
137
- progressBar.classList.add('progress-bar-danger');
138
- progressBar.querySelector('span').innerHTML = file.error_message;
159
+ progressBar.style.width = "100%";
160
+ progressBar.classList.add("progress-bar-danger");
161
+ progressBar.querySelector("span").innerHTML = file.error_message;
139
162
  break;
140
163
  }
141
164
  }
142
165
 
143
- fileListItem({id}) {
166
+ fileListItem({ id }) {
144
167
  return this.ui.container.querySelector(`#${id}`);
145
168
  }
146
169
 
147
- static buildListItemHTML({id, name}) {
170
+ static buildListItemHTML({ id, name }) {
148
171
  return `<li id='${id}' class='row temp'>
149
172
  <div class='col-md-9 d-flex align-items-center'>
150
173
  <div class='progress'>
@@ -161,12 +184,12 @@
161
184
 
162
185
  static defaultUploaderSettings(id) {
163
186
  return {
164
- runtimes: 'html5,browserplus,silverlight,flash,gears',
187
+ runtimes: "html5,browserplus,silverlight,flash,gears",
165
188
  dragdrop: true,
166
189
  drop_element: `${id}-drag-drop-target`,
167
190
  browse_button: `${id}-browse`,
168
191
  container: id,
169
- file_data_name: 'file[file]',
192
+ file_data_name: "file[file]",
170
193
  };
171
194
  }
172
195
  }
@@ -174,21 +197,24 @@
174
197
  const uploaders = [];
175
198
  window.CMS.fileUpload = {
176
199
  init(root = document) {
177
- const el = root.querySelector('#cms-uploader');
200
+ const el = root.querySelector("#cms-uploader");
178
201
  if (el === null) return;
179
- uploaders.push(new FileUpload(el, {
180
- url: el.dataset.cmsUploaderUrl,
181
- multipart_params: {
182
- [el.dataset.cmsUploaderTokenName]: el.dataset.cmsUploaderTokenValue,
183
- [el.dataset.cmsUploaderSessionName]: el.dataset.cmsUploaderSessionValue
184
- }
185
- }));
202
+ uploaders.push(
203
+ new FileUpload(el, {
204
+ url: el.dataset.cmsUploaderUrl,
205
+ multipart_params: {
206
+ [el.dataset.cmsUploaderTokenName]: el.dataset.cmsUploaderTokenValue,
207
+ [el.dataset.cmsUploaderSessionName]:
208
+ el.dataset.cmsUploaderSessionValue,
209
+ },
210
+ })
211
+ );
186
212
  },
187
213
  dispose() {
188
214
  for (const uploader of uploader) {
189
215
  uploader.dispose();
190
216
  }
191
217
  uploaders.length = 0;
192
- }
218
+ },
193
219
  };
194
220
  })();
@@ -1,3 +1,5 @@
1
+ import Modal from "bootstrap/js/src/popover";
2
+
1
3
  // Site files modal.
2
4
  (() => {
3
5
  let modal = null;
@@ -5,9 +7,12 @@
5
7
  const initModalContent = (modalContent) => {
6
8
  window.CMS.fileUpload.init(modalContent);
7
9
  window.CMS.fileLinks(modalContent);
8
- modalContent.addEventListener('dragstart', (evt) => {
9
- if (evt.target.nodeType === Node.ELEMENT_NODE &&
10
- evt.target.matches('.cms-uploader-filelist .item-title a') && modal != null) {
10
+ modalContent.addEventListener("dragstart", (evt) => {
11
+ if (
12
+ evt.target.nodeType === Node.ELEMENT_NODE &&
13
+ evt.target.matches(".cms-uploader-filelist .item-title a") &&
14
+ modal != null
15
+ ) {
11
16
  modal.hide();
12
17
  }
13
18
  });
@@ -15,17 +20,19 @@
15
20
 
16
21
  window.CMS.files = {
17
22
  init() {
18
- const modalToggle = document.querySelector('.cms-files-open-modal');
19
- const modalContainer = document.querySelector('.cms-files-modal');
23
+ const modalToggle = document.querySelector(".cms-files-open-modal");
24
+ const modalContainer = document.querySelector(".cms-files-modal");
20
25
  if (modalToggle === null || modalContainer === null) return;
21
- const modalContent = modalContainer.querySelector('.modal-content');
22
- modalToggle.addEventListener('click', (evt) => {
26
+ const modalContent = modalContainer.querySelector(".modal-content");
27
+ modalToggle.addEventListener("click", (evt) => {
23
28
  evt.preventDefault();
24
- fetch(modalContainer.dataset.url, {credentials: 'same-origin'}).then((resp) => resp.text()).then((html) => {
25
- modalContent.innerHTML = `<div class="modal-body">${html}</div>`;
26
- initModalContent(modalContent);
27
- });
28
- modal = modal || new bootstrap.Modal(modalContainer);
29
+ fetch(modalContainer.dataset.url, { credentials: "same-origin" })
30
+ .then((resp) => resp.text())
31
+ .then((html) => {
32
+ modalContent.innerHTML = `<div class="modal-body">${html}</div>`;
33
+ initModalContent(modalContent);
34
+ });
35
+ modal = modal || new Modal(modalContainer);
29
36
  modal.show();
30
37
  });
31
38
  },
@@ -35,6 +42,6 @@
35
42
  modal.dispose();
36
43
  modal = null;
37
44
  }
38
- }
45
+ },
39
46
  };
40
47
  })();
@@ -1,33 +1,42 @@
1
+ import Sortable from "sortablejs";
2
+ import Rails from "@rails/ujs";
3
+
1
4
  (() => {
2
- const Rails = window.Rails;
3
- const DATA_ID_ATTRIBUTE = 'data-id';
5
+ const DATA_ID_ATTRIBUTE = "data-id";
4
6
 
5
7
  const sortableStore = {
6
8
  get(sortable) {
7
- return Array.from(sortable.el.children, (el) => el.getAttribute(DATA_ID_ATTRIBUTE));
9
+ return Array.from(sortable.el.children, (el) =>
10
+ el.getAttribute(DATA_ID_ATTRIBUTE)
11
+ );
8
12
  },
9
13
  set(sortable) {
10
14
  fetch(`${CMS.current_path}/reorder`, {
11
- body: JSON.stringify({order: sortable.toArray()}),
12
- headers: {'Content-Type': 'application/json', 'X-CSRF-Token': Rails.csrfToken()},
13
- credentials: 'same-origin',
14
- method: 'PUT',
15
+ body: JSON.stringify({ order: sortable.toArray() }),
16
+ headers: {
17
+ "Content-Type": "application/json",
18
+ "X-CSRF-Token": Rails.csrfToken(),
19
+ },
20
+ credentials: "same-origin",
21
+ method: "PUT",
15
22
  });
16
- }
23
+ },
17
24
  };
18
25
 
19
26
  const sortableInstances = [];
20
27
  window.CMS.sortableList = {
21
28
  init(root = document) {
22
- for (const sortableRoot of root.querySelectorAll('.sortable')) {
23
- sortableInstances.push(Sortable.create(sortableRoot, {
24
- handle: '.dragger',
25
- draggable: 'li',
26
- dataIdAttr: DATA_ID_ATTRIBUTE,
27
- store: sortableStore,
28
- onStart: (evt) => evt.from.classList.add('sortable-active'),
29
- onEnd: (evt) => evt.from.classList.remove('sortable-active')
30
- }));
29
+ for (const sortableRoot of root.querySelectorAll(".sortable")) {
30
+ sortableInstances.push(
31
+ Sortable.create(sortableRoot, {
32
+ handle: ".dragger",
33
+ draggable: "li",
34
+ dataIdAttr: DATA_ID_ATTRIBUTE,
35
+ store: sortableStore,
36
+ onStart: (evt) => evt.from.classList.add("sortable-active"),
37
+ onEnd: (evt) => evt.from.classList.remove("sortable-active"),
38
+ })
39
+ );
31
40
  }
32
41
  },
33
42
  dispose() {
@@ -35,6 +44,6 @@
35
44
  sortable.destroy();
36
45
  }
37
46
  sortableInstances.length = 0;
38
- }
39
- }
47
+ },
48
+ };
40
49
  })();
@@ -1,23 +1,31 @@
1
+ import flatpickr from "flatpickr";
2
+
1
3
  (() => {
2
4
  const flatpickrInstances = [];
3
5
  window.CMS.timepicker = {
4
6
  init(root = document) {
5
- const datetimes = root.querySelectorAll('input[type=text][data-cms-datetime]');
6
- const dates = root.querySelectorAll('input[type=text][data-cms-date]');
7
+ const datetimes = root.querySelectorAll(
8
+ "input[type=text][data-cms-datetime]"
9
+ );
10
+ const dates = root.querySelectorAll("input[type=text][data-cms-date]");
7
11
  if (datetimes.length === 0 && dates.length === 0) return;
8
12
  const locale = CMS.getLocale();
9
13
  for (const datetime of datetimes) {
10
- flatpickrInstances.push(flatpickr(datetime, {
11
- format: 'yyyy-mm-dd hh:ii',
12
- enableTime: true,
13
- locale: locale,
14
- }));
14
+ flatpickrInstances.push(
15
+ flatpickr(datetime, {
16
+ format: "yyyy-mm-dd hh:ii",
17
+ enableTime: true,
18
+ locale: locale,
19
+ })
20
+ );
15
21
  }
16
22
  for (const date of dates) {
17
- flatpickrInstances.push(flatpickr(date, {
18
- format: 'yyyy-mm-dd',
19
- locale: locale,
20
- }));
23
+ flatpickrInstances.push(
24
+ flatpickr(date, {
25
+ format: "yyyy-mm-dd",
26
+ locale: locale,
27
+ })
28
+ );
21
29
  }
22
30
  },
23
31
  dispose() {
@@ -25,6 +33,6 @@
25
33
  flatpickrInstance.destroy();
26
34
  }
27
35
  flatpickrInstances.length = 0;
28
- }
36
+ },
29
37
  };
30
38
  })();
@@ -1,38 +1,57 @@
1
+ import jQuery from "jquery";
2
+ import Rails from "@rails/ujs";
3
+
4
+ import "../../vendor/redactor";
5
+ import "../../vendor/redactor/filemanager";
6
+ import "../../vendor/redactor/imagemanager";
7
+ import "../../vendor/redactor/definedlinks";
8
+ import "../../vendor/redactor/table";
9
+ import "../../vendor/redactor/video";
10
+
1
11
  (() => {
2
- const Rails = window.Rails;
3
12
  const buildRedactorOptions = () => {
4
- const fileUploadPath = document.querySelector('meta[name="cms-file-upload-path"]').content;
5
- const pagesPath = document.querySelector('meta[name="cms-pages-path"]').content;
13
+ const fileUploadPath = document.querySelector(
14
+ 'meta[name="cms-file-upload-path"]'
15
+ ).content;
16
+ const pagesPath = document.querySelector(
17
+ 'meta[name="cms-pages-path"]'
18
+ ).content;
6
19
  const csrfParam = Rails.csrfParam();
7
20
  const csrfToken = Rails.csrfToken();
8
21
 
9
22
  const imageUpload = new URL(fileUploadPath, document.location.href);
10
- imageUpload.searchParams.set('source', 'redactor');
11
- imageUpload.searchParams.set('type', 'image');
23
+ imageUpload.searchParams.set("source", "redactor");
24
+ imageUpload.searchParams.set("type", "image");
12
25
  imageUpload.searchParams.set(csrfParam, csrfToken);
13
26
 
14
27
  const imageManagerJson = new URL(fileUploadPath, document.location.href);
15
- imageManagerJson.searchParams.set('source', 'redactor');
16
- imageManagerJson.searchParams.set('type', 'image');
28
+ imageManagerJson.searchParams.set("source", "redactor");
29
+ imageManagerJson.searchParams.set("type", "image");
17
30
 
18
31
  const fileUpload = new URL(fileUploadPath, document.location.href);
19
- fileUpload.searchParams.set('source', 'redactor');
20
- fileUpload.searchParams.set('type', 'file');
32
+ fileUpload.searchParams.set("source", "redactor");
33
+ fileUpload.searchParams.set("type", "file");
21
34
  fileUpload.searchParams.set(csrfParam, csrfToken);
22
35
 
23
36
  const fileManagerJson = new URL(fileUploadPath, document.location.href);
24
- fileManagerJson.searchParams.set('source', 'redactor');
25
- fileManagerJson.searchParams.set('type', 'file');
37
+ fileManagerJson.searchParams.set("source", "redactor");
38
+ fileManagerJson.searchParams.set("type", "file");
26
39
 
27
40
  const definedLinks = new URL(pagesPath, document.location.href);
28
- definedLinks.searchParams.set('source', 'redactor');
41
+ definedLinks.searchParams.set("source", "redactor");
29
42
 
30
43
  return {
31
44
  minHeight: 160,
32
45
  autoresize: true,
33
46
  buttonSource: true,
34
- formatting: ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
35
- plugins: ['imagemanager', 'filemanager', 'table', 'video', 'definedlinks'],
47
+ formatting: ["p", "h1", "h2", "h3", "h4", "h5", "h6"],
48
+ plugins: [
49
+ "imagemanager",
50
+ "filemanager",
51
+ "table",
52
+ "video",
53
+ "definedlinks",
54
+ ],
36
55
  lang: CMS.getLocale(),
37
56
  convertDivs: false,
38
57
  imageUpload,
@@ -46,14 +65,16 @@
46
65
  removeComments: false,
47
66
  removeNewLines: false,
48
67
  deniedTags: [],
49
- replaceDivs: false
68
+ replaceDivs: false,
50
69
  };
51
70
  };
52
71
 
53
72
  const redactorInstances = [];
54
73
  window.CMS.wysiwyg = {
55
74
  init(root = document) {
56
- const textareas = root.querySelectorAll('textarea.rich-text-editor, textarea[data-cms-rich-text]');
75
+ const textareas = root.querySelectorAll(
76
+ "textarea.rich-text-editor, textarea[data-cms-rich-text]"
77
+ );
57
78
  if (textareas.length === 0) return;
58
79
  const redactorOptions = buildRedactorOptions();
59
80
  for (const textarea of textareas) {
@@ -65,8 +86,6 @@
65
86
  redactor.core.destroy();
66
87
  }
67
88
  redactorInstances.length = 0;
68
- }
69
- }
89
+ },
90
+ };
70
91
  })();
71
-
72
-
@@ -5,29 +5,31 @@
5
5
  See https://github.com/arnab/jQuery.PrettyTextDiff/
6
6
  */
7
7
 
8
- (function() {
8
+ import jQuery from "jquery";
9
+
10
+ (function () {
9
11
  var $;
10
12
 
11
13
  $ = jQuery;
12
14
 
13
15
  $.fn.extend({
14
- prettyTextDiff: function(options) {
16
+ prettyTextDiff: function (options) {
15
17
  var dmp, settings;
16
18
  settings = {
17
19
  originalContainer: ".original",
18
20
  changedContainer: ".changed",
19
21
  diffContainer: ".diff",
20
22
  cleanup: true,
21
- debug: false
23
+ debug: false,
22
24
  };
23
25
  settings = $.extend(settings, options);
24
26
  $.fn.prettyTextDiff.debug("Options: ", settings, settings);
25
27
  dmp = new diff_match_patch();
26
- return this.each(function() {
28
+ return this.each(function () {
27
29
  var changed, diff_as_html, diffs, original;
28
30
  if (settings.originalContent && settings.changedContent) {
29
- original = $('<div />').html(settings.originalContent).text();
30
- changed = $('<div />').html(settings.changedContent).text();
31
+ original = $("<div />").html(settings.originalContent).text();
32
+ changed = $("<div />").html(settings.changedContent).text();
31
33
  } else {
32
34
  original = $(settings.originalContainer, this).text();
33
35
  changed = $(settings.changedContainer, this).text();
@@ -39,38 +41,48 @@ See https://github.com/arnab/jQuery.PrettyTextDiff/
39
41
  dmp.diff_cleanupSemantic(diffs);
40
42
  }
41
43
  $.fn.prettyTextDiff.debug("Diffs: ", diffs, settings);
42
- diff_as_html = $.map(diffs, function(diff) {
44
+ diff_as_html = $.map(diffs, function (diff) {
43
45
  return $.fn.prettyTextDiff.createHTML(diff);
44
46
  });
45
- $(settings.diffContainer, this).html(diff_as_html.join(''));
47
+ $(settings.diffContainer, this).html(diff_as_html.join(""));
46
48
  return this;
47
49
  });
48
- }
50
+ },
49
51
  });
50
52
 
51
- $.fn.prettyTextDiff.debug = function(message, object, settings) {
53
+ $.fn.prettyTextDiff.debug = function (message, object, settings) {
52
54
  if (settings.debug) {
53
55
  return console.log(message, object);
54
56
  }
55
57
  };
56
58
 
57
- $.fn.prettyTextDiff.createHTML = function(diff) {
58
- var data, html, operation, pattern_amp, pattern_gt, pattern_lt, pattern_para, text;
59
+ $.fn.prettyTextDiff.createHTML = function (diff) {
60
+ var data,
61
+ html,
62
+ operation,
63
+ pattern_amp,
64
+ pattern_gt,
65
+ pattern_lt,
66
+ pattern_para,
67
+ text;
59
68
  html = [];
60
69
  pattern_amp = /&/g;
61
70
  pattern_lt = /</g;
62
71
  pattern_gt = />/g;
63
72
  pattern_para = /\n/g;
64
- operation = diff[0], data = diff[1];
65
- text = data.replace(pattern_amp, '&amp;').replace(pattern_lt, '&lt;').replace(pattern_gt, '&gt;').replace(pattern_para, '<br>');
73
+ (operation = diff[0]), (data = diff[1]);
74
+ text = data
75
+ .replace(pattern_amp, "&amp;")
76
+ .replace(pattern_lt, "&lt;")
77
+ .replace(pattern_gt, "&gt;")
78
+ .replace(pattern_para, "<br>");
66
79
  switch (operation) {
67
80
  case DIFF_INSERT:
68
- return '<ins>' + text + '</ins>';
81
+ return "<ins>" + text + "</ins>";
69
82
  case DIFF_DELETE:
70
- return '<del>' + text + '</del>';
83
+ return "<del>" + text + "</del>";
71
84
  case DIFF_EQUAL:
72
- return '<span>' + text + '</span>';
85
+ return "<span>" + text + "</span>";
73
86
  }
74
87
  };
75
-
76
88
  }).call(this);