Skip to content

Commit

Permalink
Calculate height of tinymce editor upfront
Browse files Browse the repository at this point in the history
Using the configuration to calculate the space tinymce will
use if it is initialized upfront, so we can reserve the space for
calculating the element editor height correctly so the browser
is able to scroll to it when we click on the element in the preview.
  • Loading branch information
tvdeyen committed Nov 28, 2023
1 parent 6f60f67 commit 6160be7
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 8 deletions.
9 changes: 4 additions & 5 deletions app/assets/stylesheets/alchemy/elements.scss
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,17 @@

textarea {
width: 100%;

&.has_tinymce {
// We need to do this, because globally all texareas have height: auto !important
height: 140px !important;
}
}

> .message {
margin: 2 * $default-margin;
}
}

alchemy-tinymce {
display: block;
}

#main-content-elements,
.element-editor.is-fixed .nestable-elements {
padding: 2 * $default-padding $default-padding 2px;
Expand Down
24 changes: 24 additions & 0 deletions app/javascript/alchemy_admin/components/tinymce.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { AlchemyHTMLElement } from "./alchemy_html_element"
import { currentLocale } from "alchemy_admin/i18n"

const TOOLBAR_ROW_HEIGHT = 30
const TOOLBAR_BORDER_WIDTH = 1
const STATUSBAR_HEIGHT = 29.5
const EDITOR_BORDER_WIDTH = 2

class Tinymce extends AlchemyHTMLElement {
/**
* the observer will initialize Tinymce if the textarea becomes visible
Expand Down Expand Up @@ -53,6 +58,7 @@ class Tinymce extends AlchemyHTMLElement {
* hide the textarea until TinyMCE is ready to show the editor
*/
afterRender() {
this.style.minHeight = `${this.minHeight}px`
this.editor.style.display = "none"
}

Expand Down Expand Up @@ -117,6 +123,24 @@ class Tinymce extends AlchemyHTMLElement {
.getElementById(this.editorId)
.closest("alchemy-element-editor")
}

get minHeight() {
let minHeight = this.configuration.min_height || 0

if (Array.isArray(this.configuration.toolbar)) {
minHeight += this.configuration.toolbar.length * TOOLBAR_ROW_HEIGHT
minHeight += TOOLBAR_BORDER_WIDTH
} else if (this.configuration.toolbar) {
minHeight += TOOLBAR_ROW_HEIGHT
minHeight += TOOLBAR_BORDER_WIDTH
}
if (this.configuration.statusbar) {
minHeight += STATUSBAR_HEIGHT
}
minHeight += EDITOR_BORDER_WIDTH

return minHeight
}
}

customElements.define("alchemy-tinymce", Tinymce)
5 changes: 2 additions & 3 deletions lib/alchemy/tinymce.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ module Alchemy
module Tinymce
mattr_accessor :languages, :plugins

DEFAULT_PLUGINS = %w[anchor autoresize charmap code directionality fullscreen hr link lists paste tabfocus table]
DEFAULT_PLUGINS = %w[anchor charmap code directionality fullscreen hr link lists paste tabfocus table]

@@plugins = DEFAULT_PLUGINS + %w[alchemy_link]
@@init = {
skin: "alchemy",
width: "auto",
resize: true,
autoresize_min_height: "105",
autoresize_max_height: "480",
min_height: 220,
menubar: false,
statusbar: true,
toolbar: [
Expand Down
51 changes: 51 additions & 0 deletions spec/javascript/alchemy_admin/components/tinymce.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,55 @@ describe("alchemy-tinymce", () => {
expect(tinymceSettings.toolbar).toEqual("bold italic")
})
})

describe("minHeight", () => {
const html = `
<alchemy-tinymce>
<textarea id="tinymce-textarea"></textarea>
</alchemy-tinymce>
`

beforeEach(() => {
Alchemy.TinymceDefaults = {
toolbar: ["1", "2"],
statusbar: true,
min_height: 220
}
})

it("calculates with default config", () => {
const component = renderComponent("alchemy-tinymce", html)
expect(component.minHeight).toEqual(312.5)
})

it("calculates if toolbar is an array of 1", () => {
const component = renderComponent("alchemy-tinymce", html)
Alchemy.TinymceDefaults.toolbar = ["1"]
expect(component.minHeight).toEqual(282.5)
})

it("calculates if another min_height is set in config", () => {
const component = renderComponent("alchemy-tinymce", html)
Alchemy.TinymceDefaults.min_height = 123
expect(component.minHeight).toEqual(215.5)
})

it("calculates if toolbar is a string", () => {
const component = renderComponent("alchemy-tinymce", html)
Alchemy.TinymceDefaults.toolbar = "1|2"
expect(component.minHeight).toEqual(282.5)
})

it("calculates if toolbar is false", () => {
const component = renderComponent("alchemy-tinymce", html)
Alchemy.TinymceDefaults.toolbar = false
expect(component.minHeight).toEqual(251.5)
})

it("calculates if statusbar is false", () => {
const component = renderComponent("alchemy-tinymce", html)
Alchemy.TinymceDefaults.statusbar = false
expect(component.minHeight).toEqual(283)
})
})
})

0 comments on commit 6160be7

Please sign in to comment.