通过 JavaScript 在 HTML 中正确编码变体选择器

Properly encoding Variation Selectors in HTML via JavaScript

在 Unicode 中,一个 variation selector 可以有多种用途。我使用 VS15 (︎) 来防止浏览器(所有 都有问题)将某些字符显示为表情符号。

我需要对 128 位及以上的 Unicode 字符进行编码,因为我们发现问题不仅与数据库有关,而且与浏览器错误有关。即使使用建议的修复,VS15(变体选择器 15:︎)也无​​法正确编码:

HTML,来自数据库,被呈现之前

😏︎

XML编码函数和用来取渲染的字符编码函数HTML:

function xml_encode(s)
{
 var r = '';
 var skip = 0;
 for (var i = 0; i < s.length; i++)
 {
  if (skip > 0) {skip--;}
  else if (character_code(s, i) > 127)
  {
   r += '&#' + character_code(s, i) + ';';
  }
  else {r += s.charAt(i);}
 }

 return r;
}

function character_code(s, i)
{
 i = i || 0;
 var c = s.charCodeAt(i), hi, low;

 if (0xD800 <= c && c <= 0xDBFF)
 {
  hi = c;
  low = s.charCodeAt(i + 1);
  if (isNaN(low)) {console.log('Error: high surrogate not followed by low surrogate in fixedCharCodeAt()');}
  c = ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
 }

 if (0xDC00 <= c && c <= 0xDFFF) {c = false;}

 return c;
}

此代码的一个使用示例是当用户从页面的可视化编辑切换到 XML 编辑时。 如何确保变体选择器被正确编码?

let s = 'a︎';
// U+0061 ‹a› \N{LATIN SMALL LETTER A}
// U+1F60F ‹› \N{SMIRKING FACE}
// U+FE0E ‹◌︎› \N{VARIATION SELECTOR-15}
Array.from(s).map(c => {
    const cp = c.codePointAt(0);
    return cp < 128 ? c : '&#' + cp + ';';
}).join('')
// 'a&#128527;&#65038;'