Skip to content

Commit

Permalink
Migrate Link Dialog from CoffeeScript to Javascript
Browse files Browse the repository at this point in the history
Migrate the Link Dialog from CoffeeScript to Javascript. This will also trim the internal class structure a bit to be better readable.
  • Loading branch information
sascha-karnatz committed Mar 28, 2024
1 parent f8e6b36 commit ed8e6ca
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 84 deletions.
1 change: 0 additions & 1 deletion app/assets/javascripts/alchemy/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@
//= require alchemy/alchemy.confirm_dialog
//= require alchemy/alchemy.fixed_elements
//= require alchemy/alchemy.image_overlay
//= require alchemy/alchemy.link_dialog
83 changes: 0 additions & 83 deletions app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee

This file was deleted.

2 changes: 2 additions & 0 deletions app/javascript/alchemy_admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import IngredientAnchorLink from "alchemy_admin/ingredient_anchor_link"
import ImageLoader from "alchemy_admin/image_loader"
import ImageCropper from "alchemy_admin/image_cropper"
import Initializer from "alchemy_admin/initializer"
import { LinkDialog } from "alchemy_admin/link_dialog"
import pictureSelector from "alchemy_admin/picture_selector"
import pleaseWaitOverlay from "alchemy_admin/please_wait_overlay"
import Sitemap from "alchemy_admin/sitemap"
Expand Down Expand Up @@ -60,6 +61,7 @@ Object.assign(Alchemy, {
ImageCropper,
Initializer,
IngredientAnchorLink,
LinkDialog,
pictureSelector,
pleaseWaitOverlay,
Sitemap,
Expand Down
118 changes: 118 additions & 0 deletions app/javascript/alchemy_admin/link_dialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// Represents the link Dialog that appears, if a user clicks the link buttons
// in TinyMCE or on an Ingredient that has links enabled (e.g. Picture)
//
export class LinkDialog extends Alchemy.Dialog {
constructor(link) {
const url = new URL(Alchemy.routes.link_admin_pages_path, window.location)
const parameterMapping = {
url: link.url,
selected_tab: link.type,
link_title: link.title,
link_target: link.target
}

// searchParams.set would also add undefined values
Object.keys(parameterMapping).forEach((key) => {
if (parameterMapping[key]) {
url.searchParams.set(key, parameterMapping[key])
}
})

super(url.href, {
size: "600x320",
title: "Link"
})
}

/**
* Called from Dialog class after the url was loaded
*/
replace(data) {
// let Dialog class handle the content replacement
super.replace(data)
// Store some jQuery objects for further reference
this.$internal_link = $("#internal_link", this.dialog_body)
this.$element_anchor = $("#element_anchor", this.dialog_body)
this.linkForm = document.querySelector('[data-link-form-type="internal"]')

// attach events we handle
this.attachEvents()
}

/**
* make the open method a promise
* maybe in a future version the whole Dialog will respond with a promise result if the dialog is closing
* @returns {Promise<unknown>}
*/
open() {
super.open(...arguments)
return new Promise((resolve) => (this.resolve = resolve))
}

updatePage(page) {
this.$internal_link.val(page != null ? page.url_path : undefined)(
(this.linkForm.querySelector("alchemy-anchor-select").page =
page != null ? page.id : undefined)
)
}

// Attaches click events to forms in the link dialog.
attachEvents() {
// enable the dom selection in internal link tab
this.linkForm.addEventListener("Alchemy.PageSelect.ItemRemoved", (e) =>
this.updatePage()
)
this.linkForm.addEventListener("Alchemy.PageSelect.ItemAdded", (e) =>
this.updatePage(e.detail)
)

$("[data-link-form-type]", this.dialog_body).on("submit", (e) => {
e.preventDefault()
this.link_type = e.target.dataset.linkFormType
// get url and remove a possible hash fragment
let url = $(`#${this.link_type}_link`).val().replace(/#\w+$/, "")
if (this.link_type === "internal" && this.$element_anchor.val() !== "") {
url += "#" + this.$element_anchor.val()
}

// Create the link
this.createLink({
url,
title: $(`#${this.link_type}_link_title`).val(),
target: $(`#${this.link_type}_link_target`).val()
})
})
}

// Creates a link if no validation errors are present.
// Otherwise shows an error notice.
createLink(options) {
if (
this.link_type === "external" &&
!options.url.match(Alchemy.link_url_regexp)
) {
this.showValidationError()
} else {
this.setLink(options)
this.close()
}
}

// Sets the link either in TinyMCE or on an Ingredient.
setLink(options) {
this.resolve({
url: options.url.trim(),
title: options.title,
target: options.target,
type: this.link_type
})
}

// Shows validation errors
showValidationError() {
$("#errors ul", this.dialog_body).html(
`<li>${Alchemy.t("url_validation_failed")}</li>`
)
return $("#errors", this.dialog_body).show()
}
}

0 comments on commit ed8e6ca

Please sign in to comment.