Open rik opened 2 years ago
That seems like a pretty reasonable addition. This information is similar to event.userInitiated
and it would just be a matter of hooking up the actual element instead of making it just a boolean.
Any thumbs-up on the issue from community members would be appreciated, to weigh this versus other additions.
Other libraries in the same space that might be interested by this new API and/or this issue: htmx (cc @benpate) and Unpoly (cc @triskweline).
What is the current status of this API? From this page, it seems like a proposal that hasn't yet been implemented by W3C or major browsers. It certainly looks interesting, and I'll keep an eye on it as it develops!
Also -- thanks for the mention! @1cg is the rockstar behind htmx. I'm just a groupie with a pair of drumsticks :)
What is the current status of this API? From this page, it seems like a proposal that hasn't yet been implemented by W3C or major browsers.
We are preparing to ship this in Chromium, after having run an origin trial for a while. You can find out some details on other browsers' engagement on that link. The W3C does not implement APIs so I don't know what you mean by that.
Thanks for the mention @rik.
Confirming that this would be relevant for Unpoly, as we're trying to update a minimal fragment around the triggering element (link, submit button) that causes a navigation.
In Unpoly the triggering element is called { origin }
, but since you're already using { destination }
it wouldn't work well here.
For a use case of where having the element triggering the navigation event would be needed checkout the duplicate issue I previously created: https://github.com/WICG/navigation-api/issues/238 .
function visit(params) {
// ...
navigation.addEventListener('navigate', (e) => {
const element = e.targetElement; // <- Element or null
if (!element || !element.hasAttribute('data-visit')) {
return;
}
e.transitionWhile(
fetch({
url: element.getAttribute('data-visit-url') || determineUrlToUseFromElement(element),
method: element.getAttribute('data-visit-method') || determineMethodToUseFromElement(element),
// ...
})
.then(response => response.text())
.then(html => swapDom(html))
);
});
}
A few design questions that came up:
triggeringElement
in my prototype, but I'm not hung up on it. sourceElement
? srcElement
? element
? initiator
? Something else?<form>
. Is that ok?initiatingElement
since this is a type of userInitiated
? Just thinking about other precedents, when you have an event, the triggering element is event.target
, but I don't think target
is a clear word here.<form>
?
initiatingElement
since this is a type ofuserInitiated
? Just thinking about other precedents, when you have an event, the triggering element isevent.target
, but I don't thinktarget
is a clear word here.
It is often-but-not-always user initiataed, fwiw. At least the way I prototyped it, a form submission will populate the triggering element, even if it was submitted via form.submit()
without any user action.
I agree that target
isn't really the right word here. initiatingElement
is clear, but longer than I was hoping for.
- I think the use cases for this are typically not cross-document, and so it would be better to leave this same-document.
Just to clarify: This will be available for cross-document navigations, but not cross-window initiation. <a href="some-other-document.html>
will populate the triggering element, but <a href="some-other-document.html target="myIframe">
will not
- I think that's okay. What other options could you imagine besides the
<form>
?
The submitting <input>
, if one exists? Idk.
In my prototype, when submitting a form, the triggering element is the
<form>
. Is that ok?
I think it should be the SubmitEvent.submitter
. Turbo checks a data-turbo
attribute on the submitter to decide wether or not to intercept the navigation.
<form>
<button type="submit">Intercepts the submission</button>
<button type="submit" data-turbo="false">Let the browser navigate as usual</button>
</form>
Oh and I suppose link.click()
would also trigger it.
Just some options:
triggering
activating
originating
initiating
I don't have strong opinions I think most of these would be clear.
Ack with cross-window initiation, that was my understanding as well.
+1 to submitter
, that does seem useful, especially if there are multiple ways of submitting. If you call form.submit()
would you expect the element to be form
?
If you call
form.submit()
would you expect the element to beform
?
Yes. Same if you call form.requestSubmit()
.
Trying to settle on the final naming:
We don't like anything involving "initiate" (initiator, initiating element, etc.) because it's too close to userInitiated
. userInitiated
and this proposal are almost orthogonal, e.g. if you do aElement.click()
then navigateEvent.thisThing === aElement
but navigateEvent.userInitiated === false
.
We don't like anything involving "activate" (initiator, activating element, etc.) because it's too close to navigator.userActivation
, which is orthogonal for similar reasons.
This leaves "trigger", "source", and "originate" as the main stem concepts to use. Of these "originate" is a bit more unusual and long.
We tend to think this would benefit from the Element
suffix, but don't feel strongly.
So our current front-runners are things like triggeringElement
, triggerElement
, and sourceElement
.
Thoughts welcome. This is a pretty simple addition so let's nail down the name soon.
Some thoughts:
- Should this return something useful when it's not an element?
My instinct is no. Between this and userInitiated
and navigationType
, I think you should have the information you need. E.g.:
e.userInitiated && (e.navigationType === "traverse" || e.navigationType === "reload")
=> browser UIe.userInitiated && !(e.navigationType === "traverse" || e.navigationType === "reload")
=> API methods were used!e.userInitiated && (e.navigationType === "push" || e.navigationType === "replace") && !e.sourceElement
=> API methods were used!e.userInitiated && (e.navigationType === "push" || e.navigationType === "replace") && e.sourceElement
=> an element was .click()
ed or similarThe only extra thing we could consider giving you is the ability to know exactly which API method was used, e.g. location.reload()
vs. navigation.reload()
, or history.go(-1)
vs. history.back()
. I don't think that should be necessary?
- What elements do you get to know about? Same-document only, same-origin within same top-level navigable only (though what about A -> B -> A), something else?
Great point. I think Nate implemented a same-document restriction, but forgot to mention that in https://github.com/WICG/navigation-api/pull/264. That seems like the right conservative starting point. Although I guess it kind of belies my above breakdown; if a cross-document <a>
or <form>
navigates you, you'll get incorrect results from those kind of boolean expressions. Hmm.
- Speaking of, could this partially replace sourceDocument?
Yes. We haven't written the spec yet, but I think the way to do things will be to convert sourceDocument into sourceNode, extract out sourceDocument (always non-null) and sourceElement (sometimes non-null) from it early in the navigate algorithm, and pass sourceDocument on to the rest of the algorithm while passing sourceElement on to the specific parts concerned with firing the navigate
event.
Fine with sourceElement
.
Re: booleans, I suppose you would have to check e.sameDocument
as well.
I also think sourceElement
is clearest among those listed.
I'm not seeing this in the merged version within the HTML spec. Are there any blockers to do so?
Nope, @natechapin is working on it :)
I can see that this has been "Implemented behind the NavigateEventSourceElement flag" in Chromium
How do we enable that flag to try it out? Under what circumstances would it be un-flagged?
To give it a try, launch Chrome with this extra argument: --enable-blink-features=NavigateEventSourceElement
.
Is there any movement on when this will be unflagged in Blink? Also, do we know whether sourceElement
is being included in the other browsers alongside their new Navigation API implementations?
It's immensely useful to be able to toggle an aria-busy
on form submission (and use this for user feedback) without having to add additional submit
event listeners.
It's hard to understand the status on https://github.com/w3ctag/design-reviews/issues/867 – for clarity: was this closed because TAG don't need to review and therefore it's just automatically accepted as an addition?
I apologize for the lack of progress in shipping sourceElement. It fell through the cracks in a bit of a team transition. I'll try to bump shipping it higher on the priority queue.
This would be very helpful for View Transitions, so that one can capture the correct element – by adding a view-transition-name
to it – from within the pageswap
event.
Sorry to bump this again, but with the unflagged release of Cross Document View Transitions in Chrome 126, this really needs releasing for the exact use-case that @bramus outlined.
I think this new API could be very interesting for a library like Hotwire Turbo. The Turbo Frame concept would need to know if the navigation was triggered by an element or not and if that element was configured to do a Turbo navigation or not. As far as I can tell, this information is not available at the moment.
(cc @seanpdoyle from the Turbo community)