-
+
diff --git a/src/trix/controllers/toolbar_controller.js b/src/trix/controllers/toolbar_controller.js
index a1178fea7..7b1b4ebcb 100644
--- a/src/trix/controllers/toolbar_controller.js
+++ b/src/trix/controllers/toolbar_controller.js
@@ -2,6 +2,8 @@ import BasicObject from "trix/core/basic_object"
import { findClosestElementFromNode, handleEvent, triggerEvent } from "trix/core/helpers"
+import DOMPurify from "dompurify"
+
const attributeButtonSelector = "[data-trix-attribute]"
const actionButtonSelector = "[data-trix-action]"
const toolbarButtonSelector = `${attributeButtonSelector}, ${actionButtonSelector}`
@@ -205,7 +207,10 @@ export default class ToolbarController extends BasicObject {
setAttribute(dialogElement) {
const attributeName = getAttributeName(dialogElement)
const input = getInputForDialog(dialogElement, attributeName)
- if (input.willValidate && !input.checkValidity()) {
+
+ input.willValidate && input.setCustomValidity("")
+ if (input.willValidate && !input.checkValidity() || !this.safeAttribute(input)) {
+ input.setCustomValidity("Invalid value")
input.setAttribute("data-trix-validate", "")
input.classList.add("trix-validate")
return input.focus()
@@ -215,6 +220,14 @@ export default class ToolbarController extends BasicObject {
}
}
+ safeAttribute(input) {
+ if (input.hasAttribute("data-trix-validate-href")) {
+ return DOMPurify.isValidAttribute("a", "href", input.value)
+ } else {
+ return true
+ }
+ }
+
removeAttribute(dialogElement) {
const attributeName = getAttributeName(dialogElement)
this.delegate?.toolbarDidRemoveAttribute(attributeName)