panda_cms 0.5.3 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/builds/panda_cms.css +1 -1
  3. data/app/assets/stylesheets/panda_cms/application.tailwind.css +39 -3
  4. data/app/builders/panda_cms/form_builder.rb +54 -16
  5. data/app/components/panda_cms/admin/button_component.rb +3 -3
  6. data/app/components/panda_cms/admin/flash_message_component.rb +5 -5
  7. data/app/components/panda_cms/admin/user_activity_component.html.erb +3 -3
  8. data/app/components/panda_cms/admin/user_activity_component.rb +18 -6
  9. data/app/components/panda_cms/admin/user_display_component.html.erb +10 -4
  10. data/app/components/panda_cms/rich_text_component.html.erb +1 -3
  11. data/app/components/panda_cms/rich_text_component.rb +2 -0
  12. data/app/controllers/panda_cms/admin/pages_controller.rb +2 -2
  13. data/app/controllers/panda_cms/admin/posts_controller.rb +73 -7
  14. data/app/controllers/panda_cms/pages_controller.rb +1 -1
  15. data/app/controllers/panda_cms/posts_controller.rb +3 -2
  16. data/app/helpers/panda_cms/application_helper.rb +1 -1
  17. data/app/models/action_text/rich_text_version.rb +6 -0
  18. data/app/models/panda_cms/page.rb +7 -0
  19. data/app/models/panda_cms/post.rb +23 -2
  20. data/app/models/panda_cms/post_tag.rb +7 -0
  21. data/app/models/panda_cms/template.rb +1 -0
  22. data/app/models/panda_cms/user.rb +10 -6
  23. data/app/views/active_storage/blobs/blobs/_blob.html.erb +14 -0
  24. data/app/views/layouts/action_text/contents/_content.html.erb +3 -0
  25. data/app/views/panda_cms/admin/pages/index.html.erb +14 -8
  26. data/app/views/panda_cms/admin/pages/new.html.erb +1 -1
  27. data/app/views/panda_cms/admin/posts/_form.html.erb +17 -0
  28. data/app/views/panda_cms/admin/posts/edit.html.erb +6 -0
  29. data/app/views/panda_cms/admin/posts/index.html.erb +2 -0
  30. data/app/views/panda_cms/admin/posts/new.html.erb +6 -0
  31. data/app/views/panda_cms/shared/_header.html.erb +1 -0
  32. data/config/importmap.rb +1 -0
  33. data/config/initializers/panda_cms/form_errors.rb +2 -2
  34. data/config/initializers/panda_cms/paper_trail.rb +7 -0
  35. data/config/locales/en.yml +18 -1
  36. data/config/tailwind.config.js +1 -0
  37. data/db/migrate/20240904200605_create_action_text_tables.action_text.rb +24 -0
  38. data/lib/panda_cms/version.rb +1 -1
  39. data/public/panda-cms-assets/javascripts/embed/editable.js +87 -37
  40. data/public/panda-cms-assets/javascripts/embed/rich_text.css +1294 -0
  41. metadata +40 -42
  42. data/config/tailwind.embed.config.js +0 -20
@@ -27,7 +27,7 @@ module PandaCms
27
27
 
28
28
  def panda_cms_form_with(**options, &)
29
29
  options[:builder] = PandaCms::FormBuilder
30
- options[:class] ||= ""
30
+ options[:class] = "p-6 bg-mid/5 rounded-lg border-mid border"
31
31
  form_with(**options, &)
32
32
  end
33
33
 
@@ -0,0 +1,6 @@
1
+ module ActionText
2
+ class RichTextVersion < ::PandaCms::Version
3
+ self.table_name = :action_text_rich_text_versions
4
+ self.sequence_name = :action_text_rich_text_versions_id_seq
5
+ end
6
+ end
@@ -30,6 +30,13 @@ module PandaCms
30
30
 
31
31
  scope :ordered, -> { order(:lft) }
32
32
 
33
+ enum :status, {
34
+ active: "active",
35
+ draft: "draft",
36
+ hidden: "hidden",
37
+ archived: "archived"
38
+ }
39
+
33
40
  private
34
41
 
35
42
  #
@@ -11,15 +11,36 @@ module PandaCms
11
11
  belongs_to :user, class_name: "PandaCms::User"
12
12
 
13
13
  validates :title, presence: true
14
+ validates :slug, presence: true, uniqueness: true, format: {with: /\A[a-z0-9-]+\z/}
14
15
 
15
16
  scope :ordered, -> { order(published_at: :desc) }
17
+ scope :with_user, -> { includes(:user) }
18
+
19
+ has_rich_text :post_content
20
+
21
+ belongs_to :tag, class_name: "PandaCms::PostTag", foreign_key: :post_tag_id
22
+
23
+ enum :status, {
24
+ active: "active",
25
+ draft: "draft",
26
+ hidden: "hidden",
27
+ archived: "archived"
28
+ }
16
29
 
17
30
  def excerpt(length = 100)
18
- content.gsub(/<[^>]*>/, "").truncate(length)
31
+ content.gsub(/<[^>]*>/, "").truncate(length).html_safe
19
32
  end
20
33
 
21
34
  def path
22
- PandaCms.posts[:prefix] + "/" + slug.to_s
35
+ "/" + PandaCms.posts[:prefix] + slug.to_s
36
+ end
37
+
38
+ def formatted_slug
39
+ if params[:slug][0] != "/"
40
+ "/#{params[:slug]}"
41
+ else
42
+ params[:slug]
43
+ end
23
44
  end
24
45
  end
25
46
  end
@@ -0,0 +1,7 @@
1
+ module PandaCms
2
+ class PostTag < ApplicationRecord
3
+ self.table_name = "panda_cms_post_tags"
4
+
5
+ validates :tag, presence: true
6
+ end
7
+ end
@@ -26,6 +26,7 @@ module PandaCms
26
26
  # Scopes
27
27
  scope :ordered, -> { order(:sort_order) }
28
28
  scope :available, -> { where("max_uses IS NULL OR (pages_count < max_uses)") }
29
+ scope :most_used, -> { order(pages_count: :desc).first }
29
30
 
30
31
  # Generate missing blocks for all templates
31
32
  # @return [void]
@@ -3,13 +3,17 @@ module PandaCms
3
3
  validates :firstname, presence: true
4
4
  validates :lastname, presence: true
5
5
  validates :email, presence: true, uniqueness: {case_sensitive: true}
6
- end
7
6
 
8
- def is_admin?
9
- admin
10
- end
7
+ def is_admin?
8
+ admin
9
+ end
10
+
11
+ def name
12
+ "#{firstname} #{lastname}"
13
+ end
11
14
 
12
- def name
13
- "#{firstname} #{lastname}"
15
+ def self.for_select_list(scope = :all, order = {firstname: :asc, lastname: :asc})
16
+ PandaCms::User.send(scope).order(order).map { |u| [u.name, u.id] }
17
+ end
14
18
  end
15
19
  end
@@ -0,0 +1,14 @@
1
+ <figure class="attachment attachment--<%= blob.representable? ? "preview" : "file" %> attachment--<%= blob.filename.extension %>">
2
+ <% if blob.representable? %>
3
+ <%= image_tag blob.representation(resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ]) %>
4
+ <% end %>
5
+
6
+ <figcaption class="attachment__caption">
7
+ <% if caption = blob.try(:caption) %>
8
+ <%= caption %>
9
+ <% else %>
10
+ <span class="attachment__name"><%= blob.filename %></span>
11
+ <span class="attachment__size"><%= number_to_human_size blob.byte_size %></span>
12
+ <% end %>
13
+ </figcaption>
14
+ </figure>
@@ -0,0 +1,3 @@
1
+ <div class="trix-content">
2
+ <%= yield -%>
3
+ </div>
@@ -3,14 +3,20 @@
3
3
  <% heading.with_button(action: :add, text: "Add Page", link: new_admin_page_path) %>
4
4
  <% end %>
5
5
 
6
- <%= render PandaCms::Admin::TableComponent.new(rows: root_page.self_and_descendants) do |table| %>
7
- <% table.column("Name") do |page| %>
8
- <div class="<%= table_indent(page) %>">
9
- <%= link_to page.title, edit_admin_page_path(page), class: "block h-full w-full" %>
10
- <span class="block text-xs text-black/60"><%= page.path %></span>
11
- </div>
6
+ <% if root_page %>
7
+ <%= render PandaCms::Admin::TableComponent.new(rows: root_page.self_and_descendants) do |table| %>
8
+ <% table.column("Name") do |page| %>
9
+ <div class="<%= table_indent(page) %>">
10
+ <%= link_to page.title, edit_admin_page_path(page), class: "block h-full w-full" %>
11
+ <span class="block text-xs text-black/60"><%= page.path %></span>
12
+ </div>
13
+ <% end %>
14
+ <% table.column("Status") { |page| render PandaCms::Admin::TagComponent.new(status: page.status) } %>
15
+ <% table.column("Last Updated") { |page| render PandaCms::Admin::UserActivityComponent.new(whodunnit_to: page)} %>
12
16
  <% end %>
13
- <% table.column("Status") { |page| render PandaCms::Admin::TagComponent.new(status: page.status) } %>
14
- <% table.column("Last Updated") { |page| render PandaCms::Admin::UserActivityComponent.new(whodunnit_to: page)} %>
17
+ <% else %>
18
+ <div class="p-6 bg-error/10 text-error rounded-lg">
19
+ <p class="text-base">No homepage (at <code>/</code>) found. Please create a homepage to start building your site.</p>
20
+ </div>
15
21
  <% end %>
16
22
  <% end %>
@@ -8,7 +8,7 @@
8
8
  <input type="hidden" value="<%= PandaCms::Current.root %>" data-text-field-update-target="existing_root">
9
9
  <%= f.select :parent_id, options, {}, { "data-text-field-update-target": "input_select", "data-action": "change->text-field-update#setPrePath" } %>
10
10
  <%= f.text_field :title, { data: { "text-field-update-target": "input_text", action: "focusout->text-field-update#generatePath" } } %>
11
- <%= f.text_field :path, { data: { prefix: PandaCms::Current.root, "text-field-update-target": "output_text" } } %>
11
+ <%= f.text_field :path, { meta: t(".path.meta"), data: { prefix: PandaCms::Current.root, "text-field-update-target": "output_text" } } %>
12
12
  <%= f.collection_select :panda_cms_template_id, PandaCms::Template.available, :id, :name %>
13
13
  <%= f.button %>
14
14
  </div>
@@ -0,0 +1,17 @@
1
+ <%= panda_cms_form_with model: post, url: url do |f| %>
2
+ <div data-controller="text-field-update">
3
+ <input type="hidden" value="<%= PandaCms::Current.root %>" data-text-field-update-target="existing_root">
4
+ <%= f.text_field :title, { required: true, data: { "text-field-update-target": "input_text", action: "focusout->text-field-update#generatePath" } } %>
5
+ <%= f.text_field :slug, { required: true, data: { prefix: PandaCms::Current.root + "/#{PandaCms.posts[:prefix]}", "text-field-update-target": "output_text" } } %>
6
+ <%= f.select :user_id, PandaCms::User.for_select_list %>
7
+ <%= f.datetime_field :published_at, { required: true } %>
8
+ <%= f.select :status, PandaCms::Post.statuses.keys.map { |status| [status.humanize, status] } %>
9
+ <%= f.rich_text_area :post_content, { meta: "Your content here will not auto-save! 😬 Use Ctrl + ⇧ + V (Win) or ⌘ + ⇧ + V (macOS) to paste without formatting." } %>
10
+ <%= f.button %>
11
+ </div>
12
+ <% end %>
13
+
14
+ <% content_for :head do %>
15
+ <link rel="stylesheet" type="text/css" href="https://unpkg.com/trix@2.0.8/dist/trix.css">
16
+ <script type="text/javascript" src="https://unpkg.com/trix@2.0.8/dist/trix.umd.min.js"></script>
17
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <%= render PandaCms::Admin::ContainerComponent.new do |component| %>
2
+ <% component.with_heading(text: "Edit Post", level: 1) do |heading| %>
3
+ <% end %>
4
+
5
+ <%= render "form", post: post, url: url %>
6
+ <% end %>
@@ -1,5 +1,6 @@
1
1
  <%= render PandaCms::Admin::ContainerComponent.new do |component| %>
2
2
  <% component.with_heading(text: "Posts", level: 1) do |heading| %>
3
+ <% heading.with_button(action: :add, text: "Add Post", link: new_admin_post_path) %>
3
4
  <% end %>
4
5
 
5
6
  <%= render PandaCms::Admin::TableComponent.new(rows: posts) do |table| %>
@@ -10,6 +11,7 @@
10
11
  </div>
11
12
  <% end %>
12
13
  <% table.column("Status") { |post| render PandaCms::Admin::TagComponent.new(status: post.status) } %>
14
+ <% table.column("Published") { |post| render PandaCms::Admin::UserActivityComponent.new(at: post.published_at, user: post.user)} %>
13
15
  <% table.column("Last Updated") { |post| render PandaCms::Admin::UserActivityComponent.new(whodunnit_to: post)} %>
14
16
  <% end %>
15
17
 
@@ -0,0 +1,6 @@
1
+ <%= render PandaCms::Admin::ContainerComponent.new do |component| %>
2
+ <% component.with_heading(text: "Add Post", level: 1) do |heading| %>
3
+ <% end %>
4
+
5
+ <%= render "form", post: post, url: url %>
6
+ <% end %>
@@ -9,6 +9,7 @@
9
9
  <%= stylesheet_link_tag "panda_cms", "data-turbo-track": "reload" %>
10
10
  <%= javascript_importmap_tags "panda_cms/base" %>
11
11
  <%= render "panda_cms/shared/favicons" %>
12
+ <%= yield :head %>
12
13
  </head>
13
14
 
14
15
  <body class="overflow-hidden h-full">
data/config/importmap.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  pin "@hotwired/stimulus", to: "https://ga.jspm.io/npm:stimulus@3.2.2/dist/stimulus.js"
2
2
  pin "@hotwired/stimulus-loading", to: "/panda-cms-assets/javascripts/vendor/stimulus-loading.js" # 3.2.2
3
+ pin "@rails/activestorage", to: "https://ga.jspm.io/npm:@rails/activestorage@7.2.0/app/assets/javascripts/activestorage.esm.js"
3
4
 
4
5
  pin "panda_cms/vendor/stimulus-components-rails-nested-form", to: "/panda-cms-assets/javascripts/vendor/stimulus-components-rails-nested-form.js", preload: false
5
6
  pin "panda_cms/vendor/tailwindcss-stimulus-components", to: "/panda-cms-assets/javascripts/vendor/tailwindcss-stimulus-components.js", preload: false
@@ -1,8 +1,8 @@
1
1
  ActionView::Base.field_error_proc = proc do |html_tag, instance|
2
2
  html = ""
3
3
  form_fields = %w[input select textarea trix-editor label].join(", ")
4
- error_class = "text-red-600 dark:text-red-500 bg-red-50 border-red-500 border-1 box-shadow-red-500 focus:ring-red-500 focus:border-red-500 dark:bg-red-900 dark:border-red-500 dark:focus:ring-red-500 dark:focus:border-red-500"
5
- message_class = "block w-full text-sm font-bold p-0 m-0 mt-1 text-red-700"
4
+ error_class = "text-error bg-error border-error border-1 box-shadow-error focus:ring-error focus:border-error "
5
+ message_class = "block w-full text-base p-0 m-0 mt-1 text-error font-semibold"
6
6
  autofocused = false
7
7
 
8
8
  Nokogiri::HTML::DocumentFragment.parse(html_tag).css(form_fields).each do |element|
@@ -0,0 +1,7 @@
1
+ ActiveSupport.on_load(:action_text_rich_text) do
2
+ ActionText::RichText.class_eval do
3
+ has_paper_trail versions: {
4
+ class_name: "ActionText::RichTextVersion"
5
+ }
6
+ end
7
+ end
@@ -3,8 +3,21 @@ en:
3
3
  attributes:
4
4
  panda_cms/page:
5
5
  title: Title
6
- path: Path
6
+ path: URL
7
7
  panda_cms_template_id: Template
8
+ panda_cms/post:
9
+ title: Title
10
+ slug: URL
11
+ content: Content
12
+ panda_cms_template_id: Template
13
+ user_id: Author
14
+ published_at: Published At
15
+ post_content: Content
16
+ statuses:
17
+ active: Active
18
+ draft: Draft
19
+ archived: Archived
20
+ hidden: Hidden
8
21
  panda_cms/menu:
9
22
  name: Menu Name
10
23
  panda_cms/menu_item:
@@ -19,6 +32,10 @@ en:
19
32
  google: Google
20
33
  microsoft: Microsoft 365
21
34
  admin:
35
+ pages:
36
+ new:
37
+ path:
38
+ meta: "This will be the URL of the page. It should be unique and not contain spaces or special characters. If you're unsure, it'll be auto-generated for you. 🐼"
22
39
  sessions:
23
40
  create:
24
41
  error: There was an error logging you in. Please check your login details and try again, or contact support.
@@ -4,6 +4,7 @@ module.exports = {
4
4
  files: [
5
5
  "../public/*.html",
6
6
  "../app/views/**/*.html.erb",
7
+ "../app/builders/panda_cms/**/*.rb",
7
8
  "../app/components/panda_cms/**/*.html.erb",
8
9
  "../app/components/panda_cms/**/*.rb",
9
10
  "../app/helpers/panda_cms/**/*.rb",
@@ -0,0 +1,24 @@
1
+ # This migration comes from action_text (originally 20180528164100)
2
+ class CreateActionTextTables < ActiveRecord::Migration[7.2]
3
+ def change
4
+ create_table :action_text_rich_texts, id: :uuid do |t|
5
+ t.string :name, null: false
6
+ t.text :body, limit: 16.megabytes - 1
7
+ t.references :record, null: false, polymorphic: true, index: false, type: :uuid
8
+ t.timestamps
9
+ t.index [:record_type, :record_id, :name], name: "index_action_text_rich_texts_uniqueness", unique: true
10
+ end
11
+
12
+ create_table :action_text_rich_text_versions, id: :uuid do |t|
13
+ t.string :item_type, null: false
14
+ t.string :item_id, null: false
15
+ t.string :event, null: false
16
+ t.string :whodunnit
17
+ t.jsonb :object
18
+ t.jsonb :object_changes
19
+ t.datetime :created_at
20
+ end
21
+
22
+ add_index :action_text_rich_text_versions, %i[item_type item_id]
23
+ end
24
+ end
@@ -1,3 +1,3 @@
1
1
  module PandaCms
2
- VERSION = "0.5.3"
2
+ VERSION = "0.5.5"
3
3
  end
@@ -30,7 +30,6 @@ class EditableController {
30
30
 
31
31
  this.embedPlainTextEditors();
32
32
 
33
- this.styleRichTextEditor();
34
33
  this.embedRichTextEditor();
35
34
  }
36
35
 
@@ -119,23 +118,87 @@ class EditableController {
119
118
  }
120
119
 
121
120
  embedRichTextEditor() {
122
- if (this.body.getElementsByClassName("ql-editor").length == 0) {
121
+ if (this.body.getElementsByClassName("content-rich-text").length == 0) {
123
122
  this.setFrameVisible();
124
123
  return;
125
124
  }
126
125
 
126
+ console.debug("[Panda CMS] Loading Quill rich text editor...");
127
+
127
128
  this.addStylesheet(
128
129
  this.frameDocument,
129
130
  this.head,
130
- "https://cdn.jsdelivr.net/npm/quill@2.0.2/dist/quill.bubble.css"
131
+ "/panda-cms-assets/javascripts/embed/rich_text.css?ver=1.0.0"
132
+ );
133
+
134
+ var style = this.frameDocument.createElement("style");
135
+ // TODO: Base these on "default" set styles
136
+ style.innerHTML = `
137
+ .ql-snow .ql-editor h2 {
138
+ font-size: 1.5em
139
+ }
140
+
141
+ .ql-snow .ql-editor h3 {
142
+ font-size: 1.17em
143
+ }
144
+
145
+ .ql-snow .ql-editor h4 {
146
+ font-size: 1em
147
+ }
148
+
149
+ .ql-snow .ql-editor h5 {
150
+ font-size: .83em
151
+ }
152
+
153
+ .ql-snow .ql-editor h6 {
154
+ font-size: .67em
155
+ }
156
+
157
+ .ql-snow .ql-editor a {
158
+ text-decoration: underline
159
+ }
160
+
161
+ .ql-snow .ql-editor blockquote {
162
+ border-left: 4px solid #ccc;
163
+ margin-bottom: 5px;
164
+ margin-top: 5px;
165
+ padding-left: 16px
166
+ }
167
+
168
+ .ql-snow .ql-editor code,
169
+ .ql-snow .ql-editor .ql-code-block-container {
170
+ background-color: #f0f0f0;
171
+ border-radius: 3px
172
+ }
173
+
174
+ .ql-snow .ql-editor .ql-code-block-container {
175
+ margin-bottom: 5px;
176
+ margin-top: 5px;
177
+ padding: 5px 10px
178
+ }
179
+
180
+ .ql-snow .ql-editor code {
181
+ font-size: 85%;
182
+ padding: 2px 4px
183
+ }
184
+
185
+ .ql-snow .ql-editor .ql-code-block-container {
186
+ background-color: #23241f;
187
+ color: #f8f8f2;
188
+ overflow: visible
189
+ }
190
+
191
+ .ql-snow .ql-editor img {
192
+ max-width: 100%
193
+ }
194
+ `;
195
+ this.head.append(style);
196
+
197
+ this.loadScript(
198
+ this.frameDocument,
199
+ this.head,
200
+ "https://cdn.jsdelivr.net/npm/quill@2.0.2/dist/quill.js"
131
201
  )
132
- .then(() => {
133
- return this.loadScript(
134
- this.frameDocument,
135
- this.head,
136
- "https://cdn.jsdelivr.net/npm/quill@2.0.2/dist/quill.js"
137
- );
138
- })
139
202
  .then(() => {
140
203
  return this.loadScript(
141
204
  this.frameDocument,
@@ -150,14 +213,16 @@ class EditableController {
150
213
  "https://unpkg.com/quill-magic-url@3.0.0/dist/index.js"
151
214
  );
152
215
  })
216
+ // .then(() => {
217
+ // return this.loadScript(
218
+ // this.frameDocument,
219
+ // this.head,
220
+ // "https://cdn.jsdelivr.net/npm/quill-markdown-shortcuts@latest/dist/markdownShortcuts.js"
221
+ // );
222
+ // })
153
223
  .then(() => {
154
- return this.loadScript(
155
- this.frameDocument,
156
- this.head,
157
- "https://cdn.jsdelivr.net/npm/quill-markdown-shortcuts@latest/dist/markdownShortcuts.js"
158
- );
159
- })
160
- .then(() => {
224
+ this.styleRichTextEditor();
225
+
161
226
  console.debug(
162
227
  "[Panda CMS] Dispatching event: pandaCmsRichTextEditorLoaded"
163
228
  );
@@ -203,28 +268,17 @@ class EditableController {
203
268
  }
204
269
 
205
270
  var style = this.frameDocument.createElement("style");
206
- style.innerHTML = `.ql-container,
207
- .ql-editor, .ql-editor * {
208
- margin: inherit !important;
209
- padding: inherit !important;
210
- font-size: inherit !important;
211
- line-height: inherit !important;
212
- font-family: inherit !important;
271
+ style.innerHTML = `.ql-editor:hover, .ql-container:hover {
272
+ cursor: pointer !important;
213
273
  }
214
274
 
215
- .ql-toolbar {
216
- background-color: #282e3270;
217
- border-radius: 10px;
218
- }
219
-
220
- .ql-editor:hover, .ql-container:hover {
221
- cursor: pointer !important;
275
+ .ql-container.ql-snow {
276
+ margin-top: 0 important;
222
277
  }
223
278
 
224
279
  .ql-editor:hover, .ql-editor:focus, .ql-editor:active {
225
280
  background-color: #e1effa;
226
281
  cursor: pointer !important;
227
- font-size: inherit !important;
228
282
  -webkit-transition: background-color 500ms linear;
229
283
  -ms-transition: background-color 500ms linear;
230
284
  transition: background-color 500ms linear;
@@ -235,14 +289,10 @@ class EditableController {
235
289
  -webkit-transition: background-color 1000ms linear;
236
290
  -ms-transition: background-color 1000ms linear;
237
291
  transition: background-color 1000ms linear;
238
- }
239
-
240
- .ql-tooltip {
241
- z-index: 999;
242
- min-width: 90vw;
243
292
  }`;
244
293
 
245
294
  this.head.append(style);
295
+ console.log("Appended styles to head");
246
296
  }
247
297
 
248
298
  bindSaveHandler(blockContentId, content) {