-
Notifications
You must be signed in to change notification settings - Fork 107
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
Implement speculative loading of the search form #1297
base: trunk
Are you sure you want to change the base?
Changes from all commits
67a9c39
bd22cbb
0493b67
d45eb1c
ace2aef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { | ||
store, | ||
getConfig, | ||
getContext, | ||
getElement, | ||
} from '@wordpress/interactivity'; | ||
|
||
const { actions } = store( 'speculationRules', { | ||
callbacks: { | ||
doSpeculativeLoad: () => { | ||
/** | ||
* @type {Object} | ||
* @property {string} [speculativeLoadUrl] Speculative load URL. | ||
*/ | ||
const context = getContext(); | ||
const scriptId = 'speculation-rules-search-form'; | ||
const existingScript = document.getElementById( scriptId ); | ||
if ( ! context.speculativeLoadUrl ) { | ||
if ( existingScript ) { | ||
existingScript.remove(); | ||
} | ||
} else { | ||
const script = document.createElement( 'script' ); | ||
script.type = 'speculationrules'; | ||
script.id = scriptId; | ||
const rules = { | ||
[ getConfig().mode ]: [ | ||
{ | ||
source: 'list', | ||
urls: [ context.speculativeLoadUrl ], | ||
}, | ||
], | ||
}; | ||
script.textContent = JSON.stringify( rules ); | ||
|
||
if ( existingScript ) { | ||
existingScript.replaceWith( script ); | ||
} else { | ||
document.body.appendChild( script ); | ||
} | ||
} | ||
}, | ||
}, | ||
actions: { | ||
// TODO: Is this really actually callback? | ||
updateSpeculativeLoadUrl: () => { | ||
const context = getContext(); | ||
const { ref } = getElement(); | ||
const form = ref.closest( 'form' ); | ||
const formData = new FormData( form ); | ||
if ( ! formData.get( 's' ) ) { | ||
context.speculativeLoadUrl = null; | ||
} else { | ||
const url = new URL( form.action ); | ||
url.search = new URLSearchParams( formData ).toString(); | ||
context.speculativeLoadUrl = url.href; | ||
} | ||
}, | ||
handleInputKeydown: ( event ) => { | ||
// Eke out a few milliseconds when hitting enter on the input to submit. | ||
if ( event.key === 'Enter' ) { | ||
actions.updateSpeculativeLoadUrl(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An action calling another action. Is this bad? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's fine. Even expected 🙂 |
||
} | ||
}, | ||
handleFormSubmit: ( event ) => { | ||
event.preventDefault(); | ||
const form = event.target; | ||
const formData = new FormData( form ); | ||
const url = new URL( form.action ); | ||
url.search = new URLSearchParams( formData ).toString(); | ||
location.href = url.href; | ||
}, | ||
}, | ||
} ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See
wp_interactivity_data_wp_context()
which has a$store_namepace
argument. The logic in that function could be replicated here. However, it seems this would conflict when there is already adata-wp-context
attribute present.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have created a discussion to see how we can solve that problem in a general way for all the directives: