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-autocomplete] Add support for prefetch attribute for prefetching remote data #31021

Merged
merged 6 commits into from Nov 10, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 12 additions & 8 deletions extensions/amp-autocomplete/0.1/amp-autocomplete.js
Expand Up @@ -220,14 +220,14 @@ export class AmpAutocomplete extends AMP.BaseElement {
this.viewport_ = null;

/** @private {boolean} */
this.interacted_ = false;
this.hasFetchedInitialData_ = false;

/**
* To ensure that we provide an accessible experience,
* the suggestion container must have a unique ID.
* In case the autocomplete doesn't have an ID we use a
* random number to ensure uniqueness.
@private {number|string}
@private {number|string}
*/
this.containerId_ = element.id
? element.id
Expand Down Expand Up @@ -499,6 +499,10 @@ export class AmpAutocomplete extends AMP.BaseElement {
// Disable autofill in browsers.
this.inputElement_.setAttribute('autocomplete', 'off');

if (this.element.hasAttribute('prefetch')) {
this.checkFirstInteractionAndMaybeFetchData_();
}

// Register event handlers.
this.inputElement_.addEventListener(
'touchstart',
Expand Down Expand Up @@ -687,19 +691,19 @@ export class AmpAutocomplete extends AMP.BaseElement {
*/
autocomplete_(data, opt_input = '') {
this.clearAllItems_();
if (opt_input.length < this.minChars_ || !data) {
if (!data || opt_input.length < this.minChars_) {
return Promise.resolve();
} else if (this.isSsr_) {
}
if (this.isSsr_) {
return hasOwn(data, 'html')
? this.renderResults_(
data,
dev().assertElement(this.container_),
opt_input
)
: Promise.resolve();
} else {
return this.filterDataAndRenderResults_(data, opt_input);
}
return this.filterDataAndRenderResults_(data, opt_input);
}

/**
Expand Down Expand Up @@ -990,10 +994,10 @@ export class AmpAutocomplete extends AMP.BaseElement {
* @private
*/
checkFirstInteractionAndMaybeFetchData_() {
if (this.interacted_ || !this.element.hasAttribute('src')) {
if (this.hasFetchedInitialData_ || !this.element.hasAttribute('src')) {
return Promise.resolve();
}
this.interacted_ = true;
this.hasFetchedInitialData_ = true;
return this.getRemoteData_().then(
(remoteData) => {
this.sourceData_ = remoteData;
Expand Down
21 changes: 21 additions & 0 deletions extensions/amp-autocomplete/0.1/test/test-amp-autocomplete-init.js
Expand Up @@ -318,6 +318,27 @@ describes.realWin(
});
});

it('should prefetch remote data if prefetch attribute is specified', () => {
let impl;
return getAutocomplete(
{
'prefetch': '', // boolean attribute, presence means prefetch is enabled.
'src': 'https://examples.com/json',
'filter': 'substring',
},
'{}',
false
)
.then((ampAutocomplete) => {
impl = ampAutocomplete.implementation_;
expect(impl.hasFetchedInitialData_).to.be.false;
return ampAutocomplete.layoutCallback();
})
.then(() => {
expect(impl.hasFetchedInitialData_).to.be.true;
});
});

it('should not fetch remote data when specified in src and using nested items property before first user interactino', () => {
const data = {
deeply: {
Expand Down
Expand Up @@ -588,5 +588,23 @@
<amp-autocomplete filter="prefix" query="q">
<input />
</amp-autocomplete>

<!-- Valid: amp-component with remote data, filter=prefix and prefetch attribute -->
<amp-autocomplete
filter="prefix"
src="https://data.com/articles.json?ref=CANONICAL_URL"
prefetch
>
<input />
</amp-autocomplete>

<!-- Invalid: prefetch is mistyped -->
<amp-autocomplete
filter="prefix"
src="https://data.com/articles.json?ref=CANONICAL_URL"
prefecth
>
<input />
</amp-autocomplete>
</body>
</html>
Expand Up @@ -609,5 +609,25 @@ amp-autocomplete/0.1/test/validator-amp-autocomplete.html:580:4 The attribute 'f
amp-autocomplete/0.1/test/validator-amp-autocomplete.html:588:4 The attribute 'src' in tag 'amp-autocomplete' is missing or incorrect, but required by attribute 'query'. (see https://amp.dev/documentation/components/amp-autocomplete/)
| <input />
| </amp-autocomplete>
|
| <!-- Valid: amp-component with remote data, filter=prefix and prefetch attribute -->
| <amp-autocomplete
| filter="prefix"
| src="https://data.com/articles.json?ref=CANONICAL_URL"
| prefetch
| >
| <input />
| </amp-autocomplete>
|
| <!-- Invalid: prefetch is mistyped -->
| <amp-autocomplete
>> ^~~~~~~~~
amp-autocomplete/0.1/test/validator-amp-autocomplete.html:602:4 The attribute 'prefecth' may not appear in tag 'amp-autocomplete'. (see https://amp.dev/documentation/components/amp-autocomplete/)
| filter="prefix"
| src="https://data.com/articles.json?ref=CANONICAL_URL"
| prefecth
| >
| <input />
| </amp-autocomplete>
| </body>
| </html>
4 changes: 4 additions & 0 deletions extensions/amp-autocomplete/amp-autocomplete.md
Expand Up @@ -198,6 +198,10 @@ Specifies the key to the data array within the JSON response. Nested keys can be

Whether the <code>amp-autocomplete</code> should autosuggest on the full user input or only a triggered substring of the user input. By default when the attribute is absent, suggestions will be based on the full user input. The attribute cannot have an empty value but must take a single character token, i.e. <code>@</code> which activates the autocomplete behavior. For example, if <code>inline="@"</code> then user input of <code>hello</code> will not retrieve suggestions but a user input of <code>hello @abc</code> might trigger options filtered on the substring <code>abc</code>. Currently triggered substrings are delimited on whitespace characters, however this is subject to change in the future.

### `prefetch`

Include the `prefetch` attribute to prefetch remote data to improve responsiveness for users. Requires `src` to be specified.

## Events

### `select`
Expand Down
Expand Up @@ -87,6 +87,7 @@ tags: { # <amp-autocomplete>
attrs: {
name: "[src]"
}
attrs: { name: "prefetch" }
dmanek marked this conversation as resolved.
Show resolved Hide resolved
attr_lists: "extended-amp-global"
spec_url: "https://amp.dev/documentation/components/amp-autocomplete/"
amp_layout: {
Expand Down Expand Up @@ -131,6 +132,7 @@ tags: { # <amp-autocomplete>
name: "template"
value_oneof_set: TEMPLATE_IDS
}
attrs: { name: "prefetch" }
dmanek marked this conversation as resolved.
Show resolved Hide resolved
attr_lists: "extended-amp-global"
amp_layout: {
supported_layouts: CONTAINER
Expand Down