Skip to content

Commit 24652fe

Browse files
authored
Merge branch 'dev' into button-fix
2 parents 2480488 + 032972b commit 24652fe

3 files changed

Lines changed: 53 additions & 17 deletions

File tree

src/htmx.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,7 +1413,7 @@ var htmx = (function() {
14131413
* @param {Element} mergeFrom
14141414
*/
14151415
function cloneAttributes(mergeTo, mergeFrom) {
1416-
forEach(mergeTo.attributes, function(attr) {
1416+
forEach(Array.from(mergeTo.attributes), function(attr) {
14171417
if (!mergeFrom.hasAttribute(attr.name) && shouldSettleAttribute(attr.name)) {
14181418
mergeTo.removeAttribute(attr.name)
14191419
}
@@ -5062,12 +5062,14 @@ var htmx = (function() {
50625062
function insertIndicatorStyles() {
50635063
if (htmx.config.includeIndicatorStyles !== false) {
50645064
const nonceAttribute = htmx.config.inlineStyleNonce ? ` nonce="${htmx.config.inlineStyleNonce}"` : ''
5065+
const indicator = htmx.config.indicatorClass
5066+
const request = htmx.config.requestClass
50655067
getDocument().head.insertAdjacentHTML('beforeend',
5066-
'<style' + nonceAttribute + '>\
5067-
.' + htmx.config.indicatorClass + '{opacity:0}\
5068-
.' + htmx.config.requestClass + ' .' + htmx.config.indicatorClass + '{opacity:1; transition: opacity 200ms ease-in;}\
5069-
.' + htmx.config.requestClass + '.' + htmx.config.indicatorClass + '{opacity:1; transition: opacity 200ms ease-in;}\
5070-
</style>')
5068+
`<style${nonceAttribute}>` +
5069+
`.${indicator}{opacity:0;visibility: hidden} ` +
5070+
`.${request} .${indicator}, .${request}.${indicator}{opacity:1;visibility: visible;transition: opacity 200ms ease-in}` +
5071+
'</style>'
5072+
)
50715073
}
50725074
}
50735075

test/core/regressions.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,35 @@ describe('Core htmx Regression Tests', function() {
292292
byId('datefield').click()
293293
})
294294

295+
it('swap=outerHTML clears htmx-swapping class when old node has a style attribute and no class', function(done) {
296+
this.server.respondWith('GET', '/test', '<div id="test-div">Test</div>')
297+
298+
var btn = make('<button hx-get="/test" hx-target="#test-div" hx-swap="outerHTML">Click Me!</button>')
299+
var div = make('<div id="test-div" style></div>')
300+
btn.click()
301+
302+
this.server.respond()
303+
304+
var div = byId('test-div')
305+
const isSwappingClassStillThere = div.classList.contains('htmx-swapping')
306+
isSwappingClassStillThere.should.equal(false)
307+
done()
308+
})
309+
310+
it('swap=outerHTML won\'t carry over user-defined classes when old node has a style attribute before the class attribute', function(done) {
311+
this.server.respondWith('GET', '/test', '<div id="test-div">Test</div>')
312+
313+
var btn = make('<button hx-get="/test" hx-target="#test-div" hx-swap="outerHTML">Click Me!</button>')
314+
var div = make('<div id="test-div" style class="my-class"></div>')
315+
btn.click()
316+
317+
this.server.respond()
318+
319+
var div = byId('test-div')
320+
div.classList.length.should.equal(0)
321+
done()
322+
})
323+
295324
it('a button clicked inside an htmx enabled link will prevent the link from navigating on click', function(done) {
296325
var defaultPrevented = 'unset'
297326
var link = make('<a href="/foo" hx-get="/foo"><button>test</button></a>')
@@ -355,4 +384,5 @@ describe('Core htmx Regression Tests', function() {
355384

356385
span.click()
357386
})
387+
358388
})

www/content/attributes/hx-indicator.md

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,18 @@ image. The image also has the `htmx-indicator` class on it, which defines an op
4343
that will show the spinner:
4444

4545
```css
46-
.htmx-indicator{
47-
opacity:0;
48-
transition: opacity 500ms ease-in;
46+
.htmx-indicator {
47+
opacity: 0;
48+
visibility: hidden;
4949
}
50-
.htmx-request .htmx-indicator{
51-
opacity:1;
52-
}
53-
.htmx-request.htmx-indicator{
54-
opacity:1;
50+
.htmx-request .htmx-indicator,
51+
.htmx-request.htmx-indicator {
52+
opacity: 1;
53+
visibility: visible;
54+
transition: opacity 200ms ease-in;
5555
}
5656
```
57+
This default `htmx-indicator` CSS also sets the visibility to hidden for better screen reader accessibility and does a quick fade in of the opacity.
5758

5859
If you would prefer a different effect for showing the spinner you could define and use your own indicator
5960
CSS. Here is an example that uses `display` rather than opacity (Note that we use `my-indicator` instead of `htmx-indicator`):
@@ -62,9 +63,7 @@ CSS. Here is an example that uses `display` rather than opacity (Note that we u
6263
.my-indicator{
6364
display:none;
6465
}
65-
.htmx-request .my-indicator{
66-
display:inline;
67-
}
66+
.htmx-request .my-indicator,
6867
.htmx-request.my-indicator{
6968
display:inline;
7069
}
@@ -102,3 +101,8 @@ This simulates what a spinner might look like in that situation:
102101
```html
103102
<meta name="htmx-config" content='{"includeIndicatorStyles": false}'>
104103
```
104+
* the `htmx-indicator` CSS added when this config is not disabled uses an inline style tag which may need you to set `inlineStyleNonce` config if you have a strict nonce based CSP policy for `style-src`
105+
```html
106+
<meta name="htmx-config" content='{"inlineStyleNonce": "random-nonce"}'>
107+
```
108+
* If your CSP needs to block all inline style tags then disable `includeIndicatorStyles` and host your own CSS file with a copy of your preferred `htmx-indicator` style from above

0 commit comments

Comments
 (0)