personalizado etiqueta estilo ejemplos ejemplo editar con cambiar atributo html css internationalization uppercase lang

html - etiqueta - CSS: la transformación de texto no funciona correctamente para los caracteres turcos



title html personalizado (8)

Las implementaciones de los principales navegadores parecen tener problemas con text-transform: uppercase con caracteres turcos. Por lo que sé (no soy turco), hay cuatro caracteres i diferentes: ı i I İ donde los dos últimos son las representaciones en mayúsculas de los dos anteriores.

Sin embargo, al aplicar text-transform:uppercase a ı i , los navegadores (verificados IE, Firefox, Chrome y Safari) dan como resultado II que no es correcto y puede cambiar el significado de las palabras hasta el punto de que se conviertan en insultos. (Eso es lo que me han dicho)

Como mi investigación de soluciones no reveló ninguna, mi pregunta es: ¿Existen soluciones para este problema? La primera solución podría ser eliminar text-transform: uppercase completo, pero es un último recurso.

Lo curioso es que el W3C tiene pruebas para este problema en su sitio, pero no tiene más información sobre este problema. http://www.w3.org/International/tests/tests-html-css/tests-text-transform/generate?test=5

Agradezco cualquier ayuda y espero sus respuestas :-)

Aquí hay un codepen


Aquí está mi versión mejorada del código de alex que estoy usando en producción:

(function($) { function getStyle(element, style) { var result; if (document.defaultView && document.defaultView.getComputedStyle) { result = document.defaultView.getComputedStyle(element, '''').getPropertyValue(style); } else if(element.currentStyle) { style = style.replace(//-(/w)/g, function (strMatch, p1) { return p1.toUpperCase(); }); result = element.currentStyle[style]; } return result; } function replaceRecursive(element, lang) { if(element.lang) { lang = element.lang; // Maintain language context } if (element && element.style && getStyle(element, ''text-transform'') == ''uppercase'') { if (lang == ''tr'' && element.value) { element.value = element.value.replace(/ı/g, ''I''); element.value = element.value.replace(/i/g, ''İ''); } for (var i = 0; i < element.childNodes.length; ++i) { if (lang == ''tr'' && element.childNodes[i].nodeType == Node.TEXT_NODE) { element.childNodes[i].textContent = element.childNodes[i].textContent.replace(/ı/g, ''I''); element.childNodes[i].textContent = element.childNodes[i].textContent.replace(/i/g, ''İ''); } else { replaceRecursive(element.childNodes[i], lang); } } } else { if (!element.childNodes || element.childNodes.length == 0) return; for (var i = 0; i < element.childNodes.length; ++i) { replaceRecursive(element.childNodes[i], lang); } } } $(document).ready(function(){ replaceRecursive(document.getElementsByTagName(''html'')[0], ''''); }) })(jQuery);

Tenga en cuenta que estoy usando jQuery aquí solo para la función ready() . El envoltorio de compatibilidad de jQuery también es una forma conveniente de ubicar las funciones en el espacio de nombres. Aparte de eso, las dos funciones no se basan en jQuery en absoluto, por lo que podría sacarlas.

Comparado con la versión original de alex, éste resuelve un par de problemas:

  • Realiza un seguimiento del atributo lang a medida que recurre, ya que si ha mezclado el contenido turco y el otro contenido latino, obtendrá transformaciones incorrectas en el no turco sin él. De acuerdo con esto paso en el elemento html base, no en el body . Puede pegar lang="en" en cualquier etiqueta que no sea turca para evitar el uso indebido de mayúsculas.

  • Aplica la transformación solo a TEXT_NODES porque el método innerHTML anterior no funcionaba con nodos de elementos / texto mixtos, como etiquetas con texto y casillas de verificación dentro de ellos.

Si bien tiene algunas deficiencias notables en comparación con una solución del lado del servidor, también tiene algunas ventajas importantes, el principal de los cuales es la cobertura garantizada sin que el lado del servidor tenga que conocer qué estilos se aplican a qué contenido. Si alguno de los contenidos se indexa y se muestra en los resúmenes de Google (por ejemplo), es mucho mejor si se mantiene en minúsculas cuando se sirve.


Aquí hay un ejemplo de solución rápida y sucia: es más rápido de lo que pensaba (probado en un documento con 2400 etiquetas -> sin demora). Pero veo que las soluciones js no son la mejor solución

<html> <head> <meta http-equiv="content-type" content="text/html; charset=ISO-8859-3"> </head> <body> <div style="text-transform:uppercase">a b c ç d e f g ğ h ı i j k l m n o ö p r s ş t u ü v y z (source)</div> <div>A B C Ç D E F G Ğ H I İ J K L M N O Ö P R S Ş T U Ü V Y Z (should be like this)</div> <script> function getStyle(element, style) { var result; if (document.defaultView && document.defaultView.getComputedStyle) { result = document.defaultView.getComputedStyle(element, '''').getPropertyValue(style); } else if(element.currentStyle) { style = style.replace(//-(/w)/g, function (strMatch, p1) { return p1.toUpperCase(); }); result = element.currentStyle[style]; } return result; } function replaceRecursive(element) { if (element && element.style && getStyle(element, ''text-transform'') == ''uppercase'') { element.innerHTML = element.innerHTML.replace(/ı/g, ''I''); element.innerHTML = element.innerHTML.replace(/i/g, ''İ''); // replaces ''i'' in tags too, regular expression should be extended if necessary } if (!element.childNodes || element.childNodes.length == 0) return; for (var n in element.childNodes) { replaceRecursive(element.childNodes[n]); } } window.onload = function() { // as appropriate ''ondomready'' alert(''before...''); replaceRecursive(document.getElementsByTagName(''body'')[0]); alert(''...after''); } </script> </body> </html>


Esta solución requiere un poco de Javascript. Si no quieres hacer eso, pero tienes algo del lado del servidor que puede preprocesar el texto, esta idea también funcionará allí (creo).

Primero, detecta si estás ejecutando en turco. Si es así, escanee lo que vaya a mayúsculas para ver si contiene los caracteres problemáticos. Si lo hacen, reemplaza todos esos caracteres con la versión mayúscula de ellos. A continuación, aplique el CSS en mayúsculas. Dado que los caracteres problemáticos ya están en mayúsculas, debería ser una solución totalmente correcta (ghetto). Para Javascript, imagino tener que lidiar con algunos .innerHTML en sus elementos impactados.

Déjeme saber si necesita algún detalle de implementación, tengo una buena idea de cómo hacerlo en Javascript usando métodos de manipulación de cadenas de Javascript. Esta idea general debería llevarte la mayor parte del camino (¡y con suerte conseguirme una recompensa!)

-Brian J. Stinar-


La causa raíz de este problema debe ser el manejo incorrecto de estos caracteres turcos por parte de la biblioteca Unicode utilizada en todos estos navegadores. Así que dudo que haya una solución de front-end-side para eso.

Alguien tiene que informar este problema a los desarrolladores de estas librerías Unicode, y se solucionará en pocas semanas / meses.


La próxima versión de Firefox Nightly (que debería convertirse en Firefox 14) tiene una solución para este problema y debe manejar el caso sin ningún tipo de piratería (como lo solicitan las especificaciones de CSS3).

Los detalles sangrientos están disponibles en ese error: https://bugzilla.mozilla.org/show_bug.cgi?id=231162

También solucionaron el problema de la variante de la fuente, creo (para aquellos que no saben qué es la variante de la fuente, consulte https://developer.mozilla.org/en/CSS/font-variant , que aún no está actualizado con el cambiar pero el documento es un navegador agnóstico y un wiki, así que ...)



Puedes resolver esto con javascript nativo también:

Aquí también está su esencia.

String.prototype.turkishToLower = function(){ var string = this; var letters = { "İ": "i", "I": "ı", "Ş": "ş", "Ğ": "ğ", "Ü": "ü", "Ö": "ö", "Ç": "ç" }; string = string.replace(/(([İIŞĞÜÇÖ]))/g, function(letter){ return letters[letter]; }) return string.toLowerCase(); } String.prototype.turkishToUpper = function(){ var string = this; var letters = { "i": "İ", "ş": "Ş", "ğ": "Ğ", "ü": "Ü", "ö": "Ö", "ç": "Ç", "ı": "I" }; string = string.replace(/(([iışğüçö]))/g, function(letter){ return letters[letter]; }) return string.toUpperCase(); } var text = ''iii''; text = text.turkishToUpper(); console.log(text);


Si no puedes confiar en la transformación de texto y en los navegadores, tendrás que renderizar tu texto en mayúsculas en el servidor (espero que no estés haciendo mayúsculas en el texto a medida que el usuario lo escribe). Deberías tener un mejor soporte para la internacionalización allí.