Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default click behaviour of portals #174

Closed
jakearchibald opened this issue Jan 24, 2020 · 15 comments · Fixed by #223
Closed

Default click behaviour of portals #174

jakearchibald opened this issue Jan 24, 2020 · 15 comments · Fixed by #223
Assignees
Labels
design work needed An acknowledged gap in the proposal that needs design work to resolve

Comments

@jakearchibald
Copy link
Collaborator

It feels like we have an opportunity to make these things useful even without JavaScript.

We could make their default click behaviour to activate. This means if the user clicks on a portal, and the site's JavaScript fails to call activate (eg, it throws an error, fails to load, or hasn't loaded yet), they still get to the site they clicked on.

This makes them behave kinda like links by default.


This also gives us an opportunity to provide defaults to shift+click, middle click etc. The complicating factor here is: What happens to a portal if it's opened in a new window?

I guess starting a fresh navigation in a new window is least destructive, but doesn't make use of the pre-loaded page.

Alternatively, we could activate the portal in the new window, and do 'something' with the portal in the page. I'm just not sure what.

@a4sriniv
Copy link
Contributor

We decided recently to make portals behave more like buttons instead. There are usually DOM changes/animations that need to be carried out before activation which would be skipped if we directly called activate on click.

We're making portals keyboard focusable by default, and making them simulate a click event/run click event handlers when they receive enter/space key events by default.

@jakearchibald
Copy link
Collaborator Author

There are usually DOM changes/animations that need to be carried out before activation which would be skipped if we directly called activate on click.

"Need to" or "should"? Is 'nothing happens' a better failure case than 'portal activates'?

@a4sriniv
Copy link
Contributor

In some scenarios, nothing happens is a better failure case (for example, some pages may want to limit activatation to some other gestures (like scrolling)). We could also have portals that authors never want to be activated.

@jakearchibald
Copy link
Collaborator Author

jakearchibald commented Jan 24, 2020

Right, but preventDefault() can be used to stop the default behaviour (just like links). The question is about which is the better failure case.

@a4sriniv
Copy link
Contributor

Hmm would preventDefault() work if the site's javascript throws an error/fails to load (going back to the inital premise here)?

I worry that authors may expect that they control exactly when a portal activates for the first time by default. Also I think if portals exist to enable seamless navigation (which differentiates them from links), we should have defaults that encourage authors to think about the transition, and not give a default behaviour that is abrupt.

But I think that the link behaviour is feasible, because we do intend to have browser triggered activations for back/forward navigations.

@jakearchibald
Copy link
Collaborator Author

Hmm would preventDefault() work if the site's javascript throws an error/fails to load (going back to the inital premise here)?

Only if it's called before the JS throws.

Also I think if portals exist to enable seamless navigation (which differentiates them from links), we should have defaults that encourage authors to think about the transition, and not give a default behaviour that is abrupt.

A link, or a button in a form, has a default action. Sometimes the default action isn't the best action, but the developer can prevent the default and do something different. But in both cases, the default is usually better than nothing happening.

I guess this comes down to how often "clicking leads to activation" is absolutely not what the developer would want. If it's often, then click-to-activate is a bad default and click-does-nothing is better.

@matthewp
Copy link

I guess this comes down to how often "clicking leads to activation" is absolutely not what the developer would want. If it's often, then click-to-activate is a bad default and click-does-nothing is better.

Right, exactly, the question is are developers going to be adding animations most of the time or are they just going to call activate()? If the former then "does nothing" is the way to go.

Is this data that can be collected from the origin trial?

@jakearchibald
Copy link
Collaborator Author

jakearchibald commented Jan 24, 2020

Right, exactly, the question is are developers going to be adding animations most of the time or are they just going to call activate()? If the former then "does nothing" is the way to go.

I don't think so. Consider this:

  1. User clicks portal.
  2. Developer's click listener fires.
  3. Developer looks at the state of the portal.
  4. Developer calls preventDefault.
  5. Developer transitions that portal in a particular way, depending on that state, and waits for the transition to complete.
  6. Developer calls activate().
  7. Portal activates.

If step 2 fails due to a lack of listener (JS fails to load, or an error is thrown before the listener is attacked), or an error is thrown in step 3, what would be a better result? Nothing happens, or portal activates?

Given that "Portal activates" is the eventual goal, I'd say that was the better fallback behaviour.

The cases we need to think about are the ones where the pattern isn't: Portal clicked . . . . . . . portal activates.

@jeremyroman
Copy link
Collaborator

We certainly could have a default action, but I would expect that in the majority of cases you do want an animation because suddenly cutting to another web page seems jarring to me. You also need to run script if you want to handle the activation result (reasonably likely), modify/remove the portal element after activation completes (also reasonably likely).

It also makes things a little weirder if we add, as is likely, an option to enable input, at which point clicks would go through to the portal browsing context and the default action is kinda meaningless.

@jeremyroman
Copy link
Collaborator

Somewhat relatedly: opening a portal in a new window/tab is something we've thought about doing in the future, but because it's a destructive operation on the existing page (insofar as it empties the <portal>) I doubt pages would be prepared to have their portals torn out into separate windows, so I think that would likely break applications in practice.

@jakearchibald
Copy link
Collaborator Author

but I would expect that in the majority of cases you do want an animation because suddenly cutting to another web page seems jarring to me

Sure, but cutting to another page (which is how pretty much all navigations happen on the web today) seems better than 'nothing happens', and that's the choice in the failure case.

You also need to run script if you want to handle the activation result (reasonably likely)

Which page is running this script, and what is it likely to do? Surely in an error-throwing/no-listener case, this isn't going to happen anyway.

modify/remove the portal element after activation completes

What would break if it isn't removed? In terms of breakage we need to compare to 'nothing happens'.

@matthewp
Copy link

Given that "Portal activates" is the eventual goal, I'd say that was the better fallback behaviour.

This forces all portal usage that wants to do animation to call preventDefault(). I don't think we should design an api where the failure case makes the normal case more difficult. <a> is different because preventDefault() is the exception, not the norm.

If you want to prioritize failure cases you can use inline javascript: <portal onclick="this.activate()"> ...

@jakearchibald
Copy link
Collaborator Author

This forces all portal usage that wants to do animation to call preventDefault(). I don't think we should design an api where the failure case makes the normal case more difficult.

The difficulty here is one line that developers are pretty used to writing with links and forms. As burdens go, it doesn't seem like much. On the other hand we see a lot of sites failing because their JS failed, and a thing that should have been a link was a button.

If you want to prioritize failure cases you can use inline javascript: <portal onclick="this.activate()"> ...

CSP would prevent that from working.

@domenic domenic added the design work needed An acknowledged gap in the proposal that needs design work to resolve label May 8, 2020
@domenic
Copy link
Collaborator

domenic commented May 8, 2020

For what it's worth, the more explainer material I write the more I'm convinced that this is a good idea.

@jeremyroman
Copy link
Collaborator

Good enough for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design work needed An acknowledged gap in the proposal that needs design work to resolve
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants