JSFiddle - React, Tailwind, and code Playground
HTML
Original
<input type="text" id="foo" value="Olá ́ 𝒞͆!">
Exemplos:
<select id="options">
<option>Texto simples ASCII</option>
<option>Olá 𝒞</option>
<option>Olá 𝒞͆!</option>
<option>𝄞 ♫ 🎵 𝄪</option>
<option>͆Começa com combinante</option>
</select>
<button id="lone">Testar lone surrogates</button>
<br/>
<br/>
Restrito:
<div id="strict"></div>
Completar combinantes isolados
<div id="complete"></div>
Permissivo:
<div id="simple"></div>
Errado:
<div id="wrong"></div>
(Nem todos os caracteres estão disponíveis em todos os tipos de letra)
CSS
div, input {
margin: 5px;
margin-left: 15px;
padding: 10px;
}
input#foo {
display: block;
}
#strict, #complete {
background-color: #ccffcc;
}
#simple, #wrong {
background-color: #ffcccc;
}
JavaScript
"use strict";
// Procurei na norma do Unicode e não encontrei informação
// suficiente sobre como lidar com strings que comecem em
// combining code points.
var ReversalMode = {
//Assume uma string "normal"
'PERMISSIVE': 0,
// Substitui um caracter pelo <?> (U+FFFD REPLACEMENT CHARACTER)
// quando não o reconhece.
'STRICT': 1,
// Por defeito, usar o modo STRICT.
'DEFAULT': 1,
// Semelhante a STRICT, mas pode acrescentar code points ao inicio
// de uma string se esta começar por um combining.
'COMPLETE_COMBINING': 3,
// Semelhante a COMPLETE_COMBINING, mas sem substituir caracteres
// inválidos pelo <?>
'PERMISSIVE_COMPLETE_COMBINING': 2
};
String.prototype.isHighSurrogate = function () {
var charCode = this.charCodeAt(0);
return charCode >= 0xD800 && charCode <= 0xDBFF;
}
String.prototype.isLowSurrogate = function () {
var charCode = this.charCodeAt(0);
return charCode >= 0xDC00 && charCode <= 0xDFFF;
};
String.prototype.isCombining = function () {
if (this.length != 1) {
//Todos os caracteres de combinação estão no BMP
return false;
}
var codePoint = this.charCodeAt(0);
//Combining Diacritical Marks
if (codePoint >= 0x0300 && codePoint <= 0x036F)
return true;
//Combining Diacritical Marks Supplement
if (codePoint >= 0x1DC0 && codePoint <= 0x1DFF)
return true;
//Combining Diacritical Marks for Symbols
if (codePoint >= 0x20D0 && codePoint <= 0x20FF)
return true;
//Combining Half Marks
if (codePoint >= 0xFE20 && codePoint <= 0xFE2F)
return true;
return false;
}
String.prototype.codePoints = function (strictMode) {
var codePoints = [];
var currentPoint = '';
for (var i = 0; i < this.length; ++i) {
var currentUnit = this[i];
if (currentUnit.isHighSurrogate()) {
if (currentPoint.length !== 0 && strictMode) {
...