| <!DOCTYPE html> |
| <title>Percent-encoding in a text directive</title> |
| <meta charset=utf-8> |
| <link rel="help" href="https://wicg.github.io/ScrollToTextFragment/"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="/resources/testdriver.js"></script> |
| <script src="/resources/testdriver-vendor.js"></script> |
| <script src="resources/util.js"></script> |
| <style> |
| .target { |
| margin-top: 2000px; |
| margin-bottom: 2000px; |
| } |
| </style> |
| <script> |
| |
| function determineResult() { |
| if (window.scrollY == 0) |
| return 'noscroll'; |
| |
| for (let target of document.querySelectorAll('.target')) { |
| if (isInViewport(target)) { |
| return target.id; |
| } |
| } |
| return 'UNEXPECTED'; |
| } |
| |
| let test_cases = [ |
| { |
| fragment: '#:~:text=%25', |
| expect: 'singlepercent', |
| description: 'Percent-encoded "%" char.' |
| }, |
| { |
| fragment: '#:~:text=%', |
| expect: 'singlepercent', |
| description: 'Percent char without hex digits is invalid.' |
| }, |
| { |
| fragment: '#:~:text=%%', |
| expect: 'doublepercent', |
| description: 'Percent char followed by percent char is invalid.' |
| }, |
| { |
| fragment: '#:~:text=%F', |
| expect: 'percentf', |
| description: 'Single digit percent-encoding is invalid.' |
| }, |
| { |
| fragment: '#:~:text=%25F', |
| expect: 'percentf', |
| description: 'Percent-encoding limited to two digits.' |
| }, |
| { |
| fragment: '#:~:text=%25%25F', |
| expect: 'doublepercentf', |
| description: 'Percent-encoded "%%F"' |
| }, |
| { |
| fragment: '#:~:text=%E2%9C%85', |
| expect: 'checkmark', |
| description: 'Percent-encoding multibyte codepoint (CHECKMARK).' |
| }, |
| ]; |
| |
| function runTests() { |
| for (const test_case of test_cases) { |
| promise_test(t => new Promise(resolve => { |
| // Clear the fragment and reset the scroll offset to prepare for the next |
| // test case. |
| location = `${location.pathname}#`; |
| scrollTo(0, 0); |
| |
| location = `${location.pathname}${test_case.fragment}`; |
| requestAnimationFrame( () => requestAnimationFrame(resolve) ); |
| }).then(() => { |
| assert_equals(determineResult(), test_case.expect); |
| }), `Test navigation with fragment: ${test_case.description}.`); |
| } |
| } |
| </script> |
| <body onload="runTests()"> |
| <p class="target" id="singlepercent"> |
| % |
| </p> |
| <p class="target" id="doublepercent"> |
| %% |
| </p> |
| <p class="target" id="percentf"> |
| %F |
| </p> |
| <p class="target" id="doublepercentf"> |
| %%f |
| </p> |
| <p class="target" id="checkmark"> |
| <!-- U+2705 WHITE HEAVY CHECK MARK - UTF-8 percent encoding: %E2%9C%85 --> |
| ✅ |
| </p> |
| <p class="target" id="helloworld"> |
| Hello world |
| </p> |
| |
| </body> |