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

amp-script: Interop with [on] actions #24763

Open
sebastianbenz opened this issue Sep 26, 2019 · 11 comments
Open

amp-script: Interop with [on] actions #24763

sebastianbenz opened this issue Sep 26, 2019 · 11 comments

Comments

@sebastianbenz
Copy link
Contributor

sebastianbenz commented Sep 26, 2019

Overview

Bidirectional interoperation has two parts:

  1. amp-script can define custom actions and other elements can call them.
  2. amp-script can call actions on other elements.

(1) Actions calling into amp-script

It'd be great if amp-script had the ability to define custom actions. The advantages are:

  • less need to wrap everything with an amp-script element as components outside the amp-script element can still trigger functionality implemented in amp-script.
  • better operability with existing AMP components
  • less cases were amp-bind is needed

For example:

<amp-script id="data" actions="fetch, update">
</amp-script>

<button on="tap:data.fetch">Click</button>

Inside the script you could implement a handler:

AMP.addEventListener('fetch', () => { // do stuff })
AMP.addEventListener('update', (data) => { AMP.setState({result: update(data) })

Alternative

The same thing could be accomplished with AMP.setState(...) and a counter:

<button on="tap:AMP.setState({fetch: fetch + 1})">Click</button>

where the amp-script listens to state changes to the fetch variable. However, this is hacky and always requires using amp-bind.

(2) amp-script calling actions on other elements

It'd be useful to be able to trigger AMP Actions from within an amp-script. Use cases would be:

  • open an amp-lightbox from a script
  • submit a form from a script
  • trigger closeOrNavigateTo or navigateTo actions from a script

A positive side-effect would be that scripts can target elements outside the amp-script element's scope.

@dreamofabear dreamofabear changed the title amp-script: allow defining custom actions amp-script: Interop with [on] actions Nov 21, 2019
@dreamofabear
Copy link

/cc @samouri

@samouri
Copy link
Member

samouri commented Jan 16, 2020

@sebastianbenz, can you help me understand the use case for: "(1) Actions calling into amp-script
"?

Specifically I'm trying to figure out what kind of amp-script behaviors a publisher would want to call via [on] handlers, and is it more ergonomic than alternatives. In which situations would this remove the need for amp-bind?

I'm probably missing something, but all the situations I'm thinking of either still require amp-state (which depends on amp-bind), or are better solved purely in amp-script.

@dreamofabear
Copy link

or are better solved purely in amp-script.

Could be helpful to augment preexisting pages with a little "amp-script magic". Also composing AMP components with [on] actions might be easier than writing code depending on the developer's expertise.

@sebastianbenz
Copy link
Contributor Author

Use cases:

  • trigger an action in the backend that's not possible via amp-form
  • add a todo item to a todo list (this makes it possible for the todo list to be rendered without any of the amp-script layout constraints
  • Use amp-script to implement complex domain logic that's used by the whole page (

Not requiring amp-state is not the main use case, but a positive side-effect in a few cases.

@samouri
Copy link
Member

samouri commented Jan 16, 2020

Thank you both for the replies!

I'm still struggling to understand the use cases, so I'm going to think-out-loud through the three use cases to try an understand how the alternative implementations would stack up.


trigger an action in the backend that's not possible via amp-form

So this would involve creating a new action via amp-script js, and then calling it via [on] actions. Seems to me like it would be more concise (and involve no new APIs) to do this purely with amp-script. e.g.:

<script id="example" type="text/plain" target="amp-script">
  const elements = document.querySelectorAll('...');
  elements.forEach(el => {
    el.addEventListener(() => triggerBackendAction());
  })
</script>

add a todo item to a todo list (this makes it possible for the todo list to be rendered without any of the amp-script layout constraints

Unless the amp-script function were modifying amp-state, how could this work? And if we were assuming amp-state is used in this case, then I think amp-script alone may still be simpler. From what I can tell, the benefit to [on] actions would be how it automatically handles registering the per-element listeners.

re. the layout constraints: now that AMP.setState() from amp-script can trigger modifications anywhere in the page during the user interaction activation window (regardless of layout), is that still relevant? (#24862).


Use amp-script to implement complex domain logic that's used by the whole page

Ah. Is this because an amp-script can only attach event listeners to elements within its own subtree? Even though it would feel funny, is there anything wrong with basically wrapping the whole body with amp-script?

@sebastianbenz
Copy link
Contributor Author

So this would involve creating a new action via amp-script js, and then calling it via [on] actions. Seems to me like it would be more concise (and involve no new APIs) to do this purely with amp-script. e.g.: ...

There's a subtree/nesting problem (more below). You might want to be able to fire the same action from different elements on the page.

re. the layout constraints: now that AMP.setState() from amp-script can trigger modifications anywhere in the page during the user interaction activation window (regardless of layout), is that still relevant? (#24862).

How would you fire a repeatable action using amp-state? E.g. send out a request every time a button is clicked?

Ah. Is this because an amp-script can only attach event listeners to elements within its own subtree? Even though it would feel funny, is there anything wrong with basically wrapping the whole body with amp-script?

This could work in some cases, but would mean that you couldn't have a small self-updating amp-script on the same page.

@chasefinch
Copy link

Adding access to other AMP actions from amp-script, such as AMP.scrollTo, AMP.navigateTo, AMP.print, etc. would be a simple first step that would make a big difference here IMO.

@stale
Copy link

stale bot commented Jan 13, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the Stale Inactive for one year or more label Jan 13, 2022
@sebastianbenz
Copy link
Contributor Author

sebastianbenz commented Jan 14, 2022 via email

@stale stale bot closed this as completed Jan 22, 2022
@samouri samouri reopened this Jan 23, 2022
@stale stale bot closed this as completed Feb 20, 2022
@westonruter
Copy link
Member

Stale bot shouldn't have closed this.

daysUntilStale: 540 # 1.5Y - 7d

@westonruter westonruter reopened this Feb 24, 2022
@stale stale bot removed the Stale Inactive for one year or more label Feb 24, 2022
@stale
Copy link

stale bot commented Mar 19, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the Stale Inactive for one year or more label Mar 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants