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