| <!DOCTYPE html> |
| <title>Prerender activation by form submission</title> |
| <meta name="variant" content="?target_hint=_self"> |
| <meta name="variant" content="?target_hint=_blank"> |
| <meta name="variant" content="?rule=prerender_until_script&target_hint=_self"> |
| <meta name="variant" content="?rule=prerender_until_script&target_hint=_blank"> |
| <meta name="timeout" content="long"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="/common/utils.js"></script> |
| <script src="/common/dispatcher/dispatcher.js"></script> |
| <script src="/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js"></script> |
| <script src="../resources/utils.js"></script> |
| <script src="resources/utils.js"></script> |
| |
| <body> |
| <script> |
| setup(() => assertSpeculationRulesIsSupported('prerender')); |
| |
| promise_test(async t => { |
| const rcHelper = new PrerenderingRemoteContextHelper(); |
| const referrerRC = await rcHelper.addWindow(undefined, { features: 'noopener' }); |
| const params = new URLSearchParams(window.location.search); |
| const rule = params.get('rule') || 'prerender'; |
| const target_hint = getTargetHint(); |
| const uid = token(); |
| const prerenderedRC = await referrerRC.addPreload(rule, { |
| extrasInSpeculationRule: { form_submission: true, target_hint }, |
| scripts: [`/speculation-rules/prerender/resources/key-value-store.py?key=${uid}&value=ok`] |
| }); |
| |
| await referrerRC.executeScript((hint) => { |
| window.target_hint = hint; |
| }, [target_hint]); |
| |
| const navigateFn = (url) => { |
| const form = document.createElement('form'); |
| const urlObj = new URL(url); |
| form.action = urlObj.origin + urlObj.pathname; |
| form.method = 'GET'; |
| form.target = window.target_hint; |
| if (window.target_hint === '_blank') { |
| form.setAttribute('rel', 'noopener'); |
| } |
| |
| // Add parameters as hidden inputs dynamically |
| const extraParams = new URLSearchParams(urlObj.search); |
| for (const [key, value] of extraParams.entries()) { |
| const input = document.createElement('input'); |
| input.type = 'hidden'; |
| input.name = key; |
| input.value = value; |
| form.appendChild(input); |
| } |
| |
| document.body.appendChild(form); |
| form.submit(); |
| }; |
| |
| if (rule === 'prerender_until_script') { |
| // For prerender_until_script, we cannot execute scripts before activation. |
| // So we wait until the prerendered page fetches the key-value-store script. |
| while (true) { |
| const response = await fetch(`/speculation-rules/prerender/resources/key-value-store.py?key=${uid}`); |
| const text = await response.text(); |
| if (text === 'ok') { |
| break; |
| } |
| await new Promise(r => t.step_timeout(r, 100)); |
| } |
| |
| await referrerRC.executeScript(navigateFn, [prerenderedRC.url]); |
| |
| // Check it was a prerender activation. |
| const is_prerender = await prerenderedRC.executeScript(() => { |
| const entries = performance.getEntriesByType('navigation'); |
| return entries.length > 0 && entries[0].activationStart > 0; |
| }); |
| assert_true(is_prerender, 'The document was not activated from a prerender'); |
| } else { |
| await referrerRC.navigateExpectingPrerenderingActivation(prerenderedRC, navigateFn); |
| } |
| }, "Prerender activation by form submission"); |
| </script> |