htmx icon indicating copy to clipboard operation
htmx copied to clipboard

Allow removing extension inheritance with this-only: option

Open MichaelWest22 opened this issue 1 year ago • 5 comments

Description

Allow hx-ext extension inheritance to be disabled on an element with a new this-only: prefix instead of having to use ignore: on all children.

It works by setting isParentScan to track when scanning parent nodes recursively and then ignoring recursive calls that have ignore: prefix. Otherwise it strips the ignore: prefix.

Also improved readability/performance/minification by: removing un-needed explicit undefined checks moving replace => trim moving slice => indexOf

Corresponding issue: #3016

Testing

Added test to confirm extension with this-only: prefix does not get inherited as expected.

Checklist

  • [x] I have read the contribution guidelines
  • [x] I have targeted this PR against the correct branch (master for website changes, dev for source changes)
  • [x] This is either a bugfix, a documentation update, or a new feature that has been explicitly approved via an issue
  • [x] I ran the test suite locally (npm run test) and verified that it succeeded

MichaelWest22 avatar Nov 14 '24 02:11 MichaelWest22

Not a change request at all, just throwing out alternative naming ideas for the prefix itself in case you think they sound good ; self:, isolate:, or isolated: came to mind while answering on the issue

Telroshan avatar Nov 15 '24 08:11 Telroshan

Yeah local: is not the perfect word for this but I've struggled to find a better word that fits as well. local brings to mind things like local vs global scope which is well understood but in a way the current extension default behavior is already locally scoped to the form element! it just also applies to the form elements children because they are in the same scope normally. But in this use case we want to just break inheritance to the children which makes self: make more sense. isolate: and isolated: have the issue that is not obvious what you are isolating without reading the documentation as i think these are less self explaining than 'local:'.

What i like about local: is that how it reads in your head when looking at hx-ext="local:my-exetnsion" as it makes you think "my-extension is a local extension that only applies locally". But something like self: while possibly more accurate you have to think hx-ext="self:my-extension" means "my-extension is an extension that only applies to itself where itself refers to the local element it is tagged on".

There are other more complex options that are even more accurate and descriptive like disinherit: (mirror hx-disinherit attribute) or noninheritable: or nonheritable: . But the disinherit one feels more like the ignore: case and not for setting the extension up situation. The other two *heritable ones seem to be too long and complicated to use to me.

MichaelWest22 avatar Nov 17 '24 22:11 MichaelWest22

@Telroshan I just tried updating this change to use this-only: instead of local: to see if this improves the readability and understandability of this feature proposal. asked for some advice on discord and had suggestions for using self-only or this as good options. I like this because it has existing meaning and use in htmx like in hx-target to refer to the element itself. self is also good but its not as obvious if the subject of the self is the element or the extension so I think this is probably more accurate. Adding the -only makes it much more obvious and human readable I think as it now reads like apply this extension to this element only

MichaelWest22 avatar Dec 05 '24 21:12 MichaelWest22

Sounds like a good name to me!

Telroshan avatar Dec 06 '24 08:12 Telroshan

As I said before, I'm not a big fan of these prefixes. Introducing attributes such as hx-ext-ignore and hx-ext-disinherit are the better choice in my opinion. We still have the choice now, once this change is in, it will be hard to change it.

<form action="/action" hx-ext="ext1,ext2" hx-ext-disinherit="ext1"> <!-- disable inheritance for ext1 -->
  <a href="#" hx-delete="/delete"></a>
</form>
<form action="/action" hx-ext="ext1,ext2">
  <a href="#" hx-get="/get" hx-ext-ignore="ext1,ext2"></a> <!-- ignore ext1,ext2 only on this element -->
  <a href="#" hx-delete="/delete"></a>
</form>

xhaggi avatar Dec 12 '24 07:12 xhaggi

closing as too niche

1cg avatar Jul 15 '25 01:07 1cg