Skip to content

Commit 06ade69

Browse files
committed
Inherit keyword in hx-include / hx-indicator
1 parent 9fcb5c5 commit 06ade69

File tree

3 files changed

+158
-0
lines changed

3 files changed

+158
-0
lines changed

src/htmx.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,6 +1350,16 @@ var htmx = (function() {
13501350
return [findThisElement(elt, attrName)]
13511351
} else {
13521352
const result = querySelectorAllExt(elt, attrTarget)
1353+
// find `inherit` whole word in value, make sure it's surrounded by commas or is at the start/end of string
1354+
const shouldInherit = /(^|,)(\s*)inherit(\s*)($|,)/.test(attrTarget)
1355+
if (shouldInherit) {
1356+
const eltToInheritFrom = asElement(getClosestMatch(elt, function(parent) {
1357+
return parent !== elt && hasAttribute(asElement(parent), attrName)
1358+
}))
1359+
if (eltToInheritFrom) {
1360+
result.push(...findAttributeTargets(eltToInheritFrom, attrName))
1361+
}
1362+
}
13531363
if (result.length === 0) {
13541364
logError('The selector "' + attrTarget + '" on ' + attrName + ' returned no matches!')
13551365
return [DUMMY_ELT]

test/attributes/hx-include.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,4 +336,88 @@ describe('hx-include attribute', function() {
336336
this.server.respond()
337337
btn.innerHTML.should.equal('Clicked!')
338338
})
339+
340+
it('`inherit` can be used to expand parent hx-include', function() {
341+
this.server.respondWith('POST', '/include', function(xhr) {
342+
var params = getParameters(xhr)
343+
params.i1.should.equal('test1')
344+
params.i2.should.equal('test2')
345+
xhr.respond(200, {}, 'Clicked!')
346+
})
347+
make('<div hx-include="#i1">' +
348+
' <button id="btn" hx-include="inherit, #i2" hx-post="/include"></button>' +
349+
'</div>' +
350+
'<input id="i1" name="i1" value="test1"/>' +
351+
'<input id="i2" name="i2" value="test2"/>')
352+
var btn = byId('btn')
353+
btn.click()
354+
this.server.respond()
355+
btn.innerHTML.should.equal('Clicked!')
356+
})
357+
358+
it('`inherit` can be used to expand multiple parents hx-include', function() {
359+
this.server.respondWith('POST', '/include', function(xhr) {
360+
var params = getParameters(xhr)
361+
params.i1.should.equal('test1')
362+
params.i2.should.equal('test2')
363+
params.i3.should.equal('test3')
364+
xhr.respond(200, {}, 'Clicked!')
365+
})
366+
make('<div hx-include="#i1">' +
367+
' <div hx-include="inherit, #i2">' +
368+
' <button id="btn" hx-include="inherit, #i3" hx-post="/include"></button>' +
369+
' </div>' +
370+
'</div>' +
371+
'<input id="i1" name="i1" value="test1"/>' +
372+
'<input id="i2" name="i2" value="test2"/>' +
373+
'<input id="i3" name="i3" value="test3"/>')
374+
var btn = byId('btn')
375+
btn.click()
376+
this.server.respond()
377+
btn.innerHTML.should.equal('Clicked!')
378+
})
379+
380+
it('`inherit` chain breaks properly', function() {
381+
this.server.respondWith('POST', '/include', function(xhr) {
382+
var params = getParameters(xhr)
383+
should.not.exist(params.i1)
384+
params.i2.should.equal('test2')
385+
params.i3.should.equal('test3')
386+
xhr.respond(200, {}, 'Clicked!')
387+
})
388+
make('<div hx-include="#i1">' +
389+
' <div hx-include="#i2">' +
390+
' <button id="btn" hx-include="inherit, #i3" hx-post="/include"></button>' +
391+
' </div>' +
392+
'</div>' +
393+
'<input id="i1" name="i1" value="test1"/>' +
394+
'<input id="i2" name="i2" value="test2"/>' +
395+
'<input id="i3" name="i3" value="test3"/>')
396+
var btn = byId('btn')
397+
btn.click()
398+
this.server.respond()
399+
btn.innerHTML.should.equal('Clicked!')
400+
})
401+
402+
it('`inherit` syntax regex properly catches keyword', function() {
403+
this.server.respondWith('POST', '/include', function(xhr) {
404+
var params = getParameters(xhr)
405+
params.i1.should.equal('test1')
406+
params.i2.should.equal('test2')
407+
params.i3.should.equal('test3')
408+
xhr.respond(200, {}, 'Clicked!')
409+
})
410+
make('<div hx-include="#i1">' +
411+
' <div hx-include="#i2, inherit,.nonexistent-class">' +
412+
' <button id="btn" hx-include="customtag,inherit , #i3" hx-post="/include"></button>' +
413+
' </div>' +
414+
'</div>' +
415+
'<input id="i1" name="i1" value="test1"/>' +
416+
'<input id="i2" name="i2" value="test2"/>' +
417+
'<input id="i3" name="i3" value="test3"/>')
418+
var btn = byId('btn')
419+
btn.click()
420+
this.server.respond()
421+
btn.innerHTML.should.equal('Clicked!')
422+
})
339423
})

test/attributes/hx-indicator.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,68 @@ describe('hx-indicator attribute', function() {
123123
b2.classList.contains('htmx-request').should.equal(false)
124124
a1.classList.contains('htmx-request').should.equal(false)
125125
})
126+
127+
it('`inherit` can be used to expand parent hx-indicator', function() {
128+
this.server.respondWith('GET', '/test', 'Clicked!')
129+
make('<div hx-indicator="#a1">' +
130+
' <button id="btn" hx-get="/test" hx-indicator="inherit, #a2">Click Me!</button>' +
131+
'</div>')
132+
var btn = byId('btn')
133+
var a1 = make('<a id="a1"></a>')
134+
var a2 = make('<a id="a2"></a>')
135+
btn.click()
136+
btn.classList.contains('htmx-request').should.equal(false)
137+
a1.classList.contains('htmx-request').should.equal(true)
138+
a2.classList.contains('htmx-request').should.equal(true)
139+
this.server.respond()
140+
btn.classList.contains('htmx-request').should.equal(false)
141+
a1.classList.contains('htmx-request').should.equal(false)
142+
a2.classList.contains('htmx-request').should.equal(false)
143+
})
144+
145+
it('`inherit` can be used to expand multiple parents hx-indicator', function() {
146+
this.server.respondWith('GET', '/test', 'Clicked!')
147+
make('<div hx-indicator="#a1">' +
148+
' <div hx-indicator="inherit, #a2">' +
149+
' <button id="btn" hx-get="/test" hx-indicator="inherit, #a3">Click Me!</button>' +
150+
' </div>' +
151+
'</div>')
152+
var btn = byId('btn')
153+
var a1 = make('<a id="a1"></a>')
154+
var a2 = make('<a id="a2"></a>')
155+
var a3 = make('<a id="a3"></a>')
156+
btn.click()
157+
btn.classList.contains('htmx-request').should.equal(false)
158+
a1.classList.contains('htmx-request').should.equal(true)
159+
a2.classList.contains('htmx-request').should.equal(true)
160+
a3.classList.contains('htmx-request').should.equal(true)
161+
this.server.respond()
162+
btn.classList.contains('htmx-request').should.equal(false)
163+
a1.classList.contains('htmx-request').should.equal(false)
164+
a2.classList.contains('htmx-request').should.equal(false)
165+
a3.classList.contains('htmx-request').should.equal(false)
166+
})
167+
168+
it('`inherit` chain breaks properly', function() {
169+
this.server.respondWith('GET', '/test', 'Clicked!')
170+
make('<div hx-indicator="#a1">' +
171+
' <div hx-indicator="#a2">' +
172+
' <button id="btn" hx-get="/test" hx-indicator="inherit, #a3">Click Me!</button>' +
173+
' </div>' +
174+
'</div>')
175+
var btn = byId('btn')
176+
var a1 = make('<a id="a1"></a>')
177+
var a2 = make('<a id="a2"></a>')
178+
var a3 = make('<a id="a3"></a>')
179+
btn.click()
180+
btn.classList.contains('htmx-request').should.equal(false)
181+
a1.classList.contains('htmx-request').should.equal(false)
182+
a2.classList.contains('htmx-request').should.equal(true)
183+
a3.classList.contains('htmx-request').should.equal(true)
184+
this.server.respond()
185+
btn.classList.contains('htmx-request').should.equal(false)
186+
a1.classList.contains('htmx-request').should.equal(false)
187+
a2.classList.contains('htmx-request').should.equal(false)
188+
a3.classList.contains('htmx-request').should.equal(false)
189+
})
126190
})

0 commit comments

Comments
 (0)