Skip to content

Commit

Permalink
Migrate Tinymce module into a web component
Browse files Browse the repository at this point in the history
Instead of multiple initializations and removals let the browser handle the problem. Web components have life cycle hooks to create and destroy the Tinymce editor.
  • Loading branch information
sascha-karnatz committed Aug 4, 2023
1 parent a7e29cd commit daa9338
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 164 deletions.
4 changes: 0 additions & 4 deletions app/assets/javascripts/alchemy/alchemy.dialog.js.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ class window.Alchemy.Dialog
@overlay.removeClass('open') if @overlay?
@$document.on 'webkitTransitionEnd transitionend oTransitionEnd', =>
@$document.off 'webkitTransitionEnd transitionend oTransitionEnd'
Alchemy.Tinymce.removeFrom $('.tinymce', @dialog_body)
@dialog_container.remove()
@overlay.remove() if @overlay?
@$body.removeClass('prevent-scrolling')
Expand Down Expand Up @@ -105,9 +104,6 @@ class window.Alchemy.Dialog
# Initializes the Dialog body
init: ->
Alchemy.GUI.init(@dialog_body)
Alchemy.Tinymce.initWith
selector: ".alchemy-dialog-body textarea.tinymce",
width: '65%'
$('#overlay_tabs', @dialog_body).tabs()
@watch_remote_forms()

Expand Down
2 changes: 0 additions & 2 deletions app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,13 @@ $.extend Alchemy,
if ui.item.hasClass('compact')
ui.placeholder.addClass('compact').css
height: ui.item.outerHeight()
Alchemy.Tinymce.remove(ids)
return
stop: (event, ui) ->
ids = getTinymceIDs(ui)
name = ui.item.data('element-name')
$dropzone = $("[data-droppable-elements~='#{name}']")
$dropzone.css('minHeight', '')
ui.item.removeClass('dragged')
Alchemy.Tinymce.init(ids)
return

$sortable_area.sortable(sortable_options)
Expand Down
8 changes: 1 addition & 7 deletions app/javascript/alchemy_admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import ImageCropper from "alchemy_admin/image_cropper"
import Initializer from "alchemy_admin/initializer"
import Datepicker from "alchemy_admin/datepicker"
import Sitemap from "alchemy_admin/sitemap"
import Tinymce from "alchemy_admin/tinymce"
import PagePublicationFields from "alchemy_admin/page_publication_fields"

// Web Components
import "alchemy_admin/components/char_counter"
import "alchemy_admin/components/tinymce"

// Global Alchemy object
if (typeof window.Alchemy === "undefined") {
Expand All @@ -39,13 +39,7 @@ Object.assign(Alchemy, {
IngredientAnchorLink,
Datepicker,
Sitemap,
Tinymce,
PagePublicationFields
})

$(document).on("turbo:load", Initializer)

$(document).on("turbo:before-fetch-request", function () {
Alchemy.Tinymce.removeIntersectionObserver()
Alchemy.Tinymce.removeFrom($(".has_tinymce"))
})
67 changes: 67 additions & 0 deletions app/javascript/alchemy_admin/components/tinymce.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
class Tinymce extends HTMLTextAreaElement {
constructor() {
super()
this.externalConfig = {}
}
/**
* the observer will initialize Tinymce if the textarea becomes visible
*/
connectedCallback() {
const observerCallback = (entries, observer) => {
entries.forEach((entry) => {
if (entry.intersectionRatio > 0) {
this.initTinymceEditor(entry.target)
// disable observer after the Tinymce was initialized
observer.unobserve(entry.target)
}
})
}

const options = {
root: document.getElementById("element_area"),
rootMargin: "0px",
threshold: [0.05]
}

this.tinymceIntersectionObserver = new IntersectionObserver(
observerCallback,
options
)
this.tinymceIntersectionObserver.observe(this)
}

/**
* disconnect intersection observer and remove Tinymce editor if the web components get destroyed
*/
disconnectedCallback() {
if (this.tinymceIntersectionObserver !== null) {
this.tinymceIntersectionObserver.disconnect()
}

const editor = tinymce.get(this.id)
if (editor) {
editor.remove()
}
}

initTinymceEditor() {
const spinner = new Alchemy.Spinner("small")
this.closest(".tinymce_container").prepend(spinner.spin().el.get(0))
tinymce.init(this.configuration)
}

get configuration() {
return {
...Alchemy.TinymceDefaults,
...this.externalConfig,
locale: Alchemy.locale,
selector: `#${this.id}`
}
}

set configuration(config) {
this.externalConfig = config
}
}

customElements.define("alchemy-tinymce", Tinymce, { extends: "textarea" })
146 changes: 0 additions & 146 deletions app/javascript/alchemy_admin/tinymce.js

This file was deleted.

1 change: 0 additions & 1 deletion app/views/alchemy/admin/elements/create.js.erb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@

Alchemy.growl('<%= Alchemy.t(:successfully_added_element) %>');
Alchemy.closeCurrentDialog();
Alchemy.Tinymce.init(<%= @element.richtext_ingredients_ids.to_json %>);
Alchemy.PreviewWindow.refresh(function() {
Alchemy.ElementEditors.focusElementPreview(<%= @element.id %>);
});
Expand Down
1 change: 0 additions & 1 deletion app/views/alchemy/admin/pages/edit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@
Alchemy.SortableElements(<%= @page.id %>, '<%= form_authenticity_token %>');
Alchemy.ElementEditors.init();
Alchemy.SelectBox('.element-editor');
Alchemy.Tinymce.init(<%= @page.richtext_ingredients_ids.to_json %>);
$('#fixed-elements').tabs().tabs('paging', {
follow: true,
followOnSelect: true,
Expand Down
7 changes: 4 additions & 3 deletions app/views/alchemy/ingredients/_richtext_editor.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@
<%= ingredient_label(richtext_editor, :value, for: richtext_dom_id) %>
<div class="tinymce_container">
<%= f.text_area :value,
id: richtext_dom_id,
class: "has_tinymce",
id: richtext_dom_id %>
is: "alchemy-tinymce" %>
</div>
<% end %>
<% if richtext_editor.has_custom_tinymce_config? %>
<script type="text/javascript" charset="utf-8">
Alchemy.Tinymce.setCustomConfig("<%= richtext_dom_id %>", {
document.getElementById("<%= richtext_dom_id %>").configuration = {
<% richtext_editor.custom_tinymce_config.each do |k, v| %>
<%= k %>: <%== v.to_json %>,
<% end %>
});
};
</script>
<% end %>
<% end %>

0 comments on commit daa9338

Please sign in to comment.