@@ -2,6 +2,8 @@ import BasicObject from "trix/core/basic_object"
2
2
3
3
import { findClosestElementFromNode , handleEvent , triggerEvent } from "trix/core/helpers"
4
4
5
+ import DOMPurify from "dompurify"
6
+
5
7
const attributeButtonSelector = "[data-trix-attribute]"
6
8
const actionButtonSelector = "[data-trix-action]"
7
9
const toolbarButtonSelector = `${ attributeButtonSelector } , ${ actionButtonSelector } `
@@ -205,7 +207,10 @@ export default class ToolbarController extends BasicObject {
205
207
setAttribute ( dialogElement ) {
206
208
const attributeName = getAttributeName ( dialogElement )
207
209
const input = getInputForDialog ( dialogElement , attributeName )
208
- if ( input . willValidate && ! input . checkValidity ( ) ) {
210
+
211
+ input . willValidate && input . setCustomValidity ( "" )
212
+ if ( input . willValidate && ! input . checkValidity ( ) || ! this . safeAttribute ( input ) ) {
213
+ input . setCustomValidity ( "Invalid value" )
209
214
input . setAttribute ( "data-trix-validate" , "" )
210
215
input . classList . add ( "trix-validate" )
211
216
return input . focus ( )
@@ -215,6 +220,14 @@ export default class ToolbarController extends BasicObject {
215
220
}
216
221
}
217
222
223
+ safeAttribute ( input ) {
224
+ if ( input . hasAttribute ( "data-trix-validate-href" ) ) {
225
+ return DOMPurify . isValidAttribute ( "a" , "href" , input . value )
226
+ } else {
227
+ return true
228
+ }
229
+ }
230
+
218
231
removeAttribute ( dialogElement ) {
219
232
const attributeName = getAttributeName ( dialogElement )
220
233
this . delegate ?. toolbarDidRemoveAttribute ( attributeName )
0 commit comments