1<!doctype html>
2<meta charset=gb18030>
3<script src=/resources/testharness.js></script>
4<script src=/resources/testharnessreport.js></script>
5<script src=resources/ranges.js></script>
6<script>
7 const encode = (input, output, desc) => {
8   test(function() {
9     const a = document.createElement("a"); // <a> uses document encoding for URL's query
10     a.href = "https://example.com/?" + input;
11     assert_equals(a.search.substr(1), output); // remove leading "?"
12   }, "gb18030 encoder: " + desc);
13 }
14
15 encode("s", "s", "very basic");
16 encode("\u20AC", "%A2%E3", "Euro");
17 encode("\u4E02", "%81@", "character");
18 encode("\uE4C6", "%A1@", "PUA");
19 encode("\uE4C5", "%FE%FE", "PUA #2");
20 encode("\uE5E5", "%26%2358853%3B", "PUA #3");
21 encode("\ud83d\udca9", "%949%DA3", "poo");
22 encode("\uE7C7", "%815%F47", "Ranges pointer special case");
23 encode("\uE7C8", "%836%C80", "legacy ICU special case 1");
24 encode("\u2026", "%A1%AD", "legacy ICU special case 2");
25 encode("\uFF5E", "%A1%AB", "legacy ICU special case 3");
26
27 const upperCaseNibble = x => {
28   return Math.floor(x).toString(16).toUpperCase();
29 }
30
31 const encodePointer = pointer => {
32   const firstByte = Math.floor(pointer / 12600) + 0x81;
33   const thirdByte = Math.floor((pointer % 1260) / 10) + 0x81;
34   return "%"
35     + upperCaseNibble(firstByte / 16)
36     + upperCaseNibble(firstByte % 16)
37     + String.fromCharCode(Math.floor((pointer % 12600) / 1260) + 0x30)
38     + "%"
39     + upperCaseNibble(thirdByte / 16)
40     + upperCaseNibble(thirdByte % 16)
41     + String.fromCharCode(pointer % 10 + 0x30);
42 }
43
44 let i = 0;
45 for (const range of ranges) {
46   encode(range[1], encodePointer(range[0]), "range " + i++);
47 }
48</script>
49