HS: disable-scripting security attribute (+1 test)
Add hs-scripting-disabled? helper that walks the ancestor chain checking for the disable-scripting attribute. Guard hs-activate! with this check. Add disable-scripting to generator BOOL_ATTRS so the attribute is emitted in generated test setup code. Regen'd spec. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -99,6 +99,22 @@
|
|||||||
;; Called once at page load. Finds all elements with _ attribute,
|
;; Called once at page load. Finds all elements with _ attribute,
|
||||||
;; compiles their hyperscript, and activates them.
|
;; compiles their hyperscript, and activates them.
|
||||||
|
|
||||||
|
(define
|
||||||
|
hs-scripting-disabled?
|
||||||
|
(fn
|
||||||
|
(el)
|
||||||
|
(if
|
||||||
|
(= el nil)
|
||||||
|
false
|
||||||
|
(if
|
||||||
|
(dom-get-attr el "disable-scripting")
|
||||||
|
true
|
||||||
|
(hs-scripting-disabled? (dom-parent el))))))
|
||||||
|
|
||||||
|
;; ── Boot subtree: for dynamic content ───────────────────────────
|
||||||
|
;; Called after HTMX swaps or dynamic DOM insertion.
|
||||||
|
;; Only activates elements within the given root.
|
||||||
|
|
||||||
(define
|
(define
|
||||||
hs-activate!
|
hs-activate!
|
||||||
(fn
|
(fn
|
||||||
@@ -108,7 +124,7 @@
|
|||||||
(let
|
(let
|
||||||
((src (dom-get-attr el "_")) (prev (dom-get-data el "hs-script")))
|
((src (dom-get-attr el "_")) (prev (dom-get-data el "hs-script")))
|
||||||
(when
|
(when
|
||||||
(and src (not (= src prev)))
|
(and src (not (= src prev)) (not (hs-scripting-disabled? el)))
|
||||||
(when
|
(when
|
||||||
(dom-dispatch el "hyperscript:before:init" nil)
|
(dom-dispatch el "hyperscript:before:init" nil)
|
||||||
(hs-log-event! "hyperscript:init")
|
(hs-log-event! "hyperscript:init")
|
||||||
@@ -132,10 +148,6 @@
|
|||||||
(safe-handler el))))))
|
(safe-handler el))))))
|
||||||
(dom-dispatch el "hyperscript:after:init" nil)))))))
|
(dom-dispatch el "hyperscript:after:init" nil)))))))
|
||||||
|
|
||||||
;; ── Boot subtree: for dynamic content ───────────────────────────
|
|
||||||
;; Called after HTMX swaps or dynamic DOM insertion.
|
|
||||||
;; Only activates elements within the given root.
|
|
||||||
|
|
||||||
(define
|
(define
|
||||||
hs-deactivate!
|
hs-deactivate!
|
||||||
(fn
|
(fn
|
||||||
|
|||||||
@@ -2526,6 +2526,7 @@
|
|||||||
(deftest "on a single div"
|
(deftest "on a single div"
|
||||||
(hs-cleanup!)
|
(hs-cleanup!)
|
||||||
(let ((_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
|
(let ((_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
|
||||||
|
(dom-set-attr _el-div "disable-scripting" "")
|
||||||
(dom-set-attr _el-d1 "id" "d1")
|
(dom-set-attr _el-d1 "id" "d1")
|
||||||
(dom-set-attr _el-d1 "_" "on click add .foo")
|
(dom-set-attr _el-d1 "_" "on click add .foo")
|
||||||
(dom-append (dom-body) _el-div)
|
(dom-append (dom-body) _el-div)
|
||||||
|
|||||||
@@ -399,7 +399,8 @@ def parse_html(html):
|
|||||||
'children': [], 'parent_idx': None
|
'children': [], 'parent_idx': None
|
||||||
}
|
}
|
||||||
BOOL_ATTRS = {'checked', 'selected', 'disabled', 'multiple',
|
BOOL_ATTRS = {'checked', 'selected', 'disabled', 'multiple',
|
||||||
'required', 'readonly', 'autofocus', 'hidden', 'open'}
|
'required', 'readonly', 'autofocus', 'hidden', 'open',
|
||||||
|
'disable-scripting'}
|
||||||
for name, val in attrs:
|
for name, val in attrs:
|
||||||
if name == 'id': el['id'] = val
|
if name == 'id': el['id'] = val
|
||||||
elif name == 'class': el['classes'] = (val or '').split()
|
elif name == 'class': el['classes'] = (val or '').split()
|
||||||
|
|||||||
Reference in New Issue
Block a user