63 votes

CSS: la transformation de texte ne fonctionne pas correctement pour les caractères turcs

La mise en œuvre des principaux navigateurs semblent avoir des problèmes avec text-transform: uppercase avec des caractères turcs. Autant que je sache (je ne suis pas turc.) il existe quatre différents i caractères: ı i I İ , où les deux derniers sont des majuscules dans les représentations de l'ancien deux.

Cependant l'application de text-transform:uppercase de ı i, les navigateurs (vérifié IE, Firefox, Chrome et Safari) résultats en I I qui n'est pas correct et peut changer le sens des mots, de sorte que beaucoup de sorte qu'ils deviennent des insultes. (C'est ce que j'ai dit)

Ma recherche de solutions n'a pas révélé de ma question est: existe-il des solutions de contournement pour ce problème? La première solution pourrait être de supprimer text-transform: uppercase , mais c'est une sorte de dernier recours.

Drôle de chose, le W3C a des tests pour ce problème sur leur site, mais l'absence de plus d'informations sur cette question. http://www.w3.org/International/tests/tests-html-css/tests-text-transform/generate?test=5

J'apprécie toute l'aide et au plaisir de vos réponses :-)

112voto

Hakan Aktaş Points 136

<html lang="tr"> est la solution.

15voto

alex Points 196

Voici un exemple de solution rapide et sale - c'est plus rapide que je ne le pensais (testé dans un document avec 2400 balises -> pas de retard). Mais je vois que les solutions de contournement js ne sont pas la meilleure solution

 <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>
 

7voto

gtd Points 7062

Voici ma version améliorée de alex de code que j'utilise dans la production:

(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);

Notez que je suis en utilisant jQuery ici uniquement pour l' ready() fonction. Le jQuery compatibilité wrapper est aussi un moyen pratique pour l'espace de noms les fonctions. Autre que cela, les deux fonctions ne comptez pas sur jQuery à tous, de sorte que vous pourrait les sortir.

Par rapport à alex de la version originale de celui-ci résout quelques problèmes:

  • Il garde la trace de l'attribut lang car elle se répète, parce que si vous avez mélangé le turc et l'autre latine contenu, vous obtiendrez une mauvaise transforme sur la non-turque sans elle. Conformément à ce que je passe dans la base html élément, de ne pas l' body. Vous pouvez coller lang="en" sur toutes les balises qui n'est pas le turc pour éviter une mauvaise utilisation des majuscules.

  • Il s'applique à la transformation d' TEXT_NODES car la précédente innerHTML méthode ne fonctionne pas avec un mélange de texte/nœuds d'éléments tels que des étiquettes avec le texte et les cases à l'intérieur d'eux.

Tout en ayant quelques exemples de lacunes par rapport à une solution côté serveur, il a aussi quelques grands avantages, dont le principal est la garantie de la couverture sans le côté serveur avoir à être conscients de ce que les styles sont appliqués à ce contenu. Si le contenu est indexé et affichées dans Google résumés (par exemple), il est beaucoup mieux si elle reste en minuscules quand ils sont servis.

4voto

teoli Points 78

La prochaine version de Firefox Nightly (qui devrait devenir Firefox 14) est un correctif pour ce problème et doit gérer le cas sans aucun hack (comme le CSS3 spécifications de la demande).

Les détails techniques sont disponibles dans le bug : https://bugzilla.mozilla.org/show_bug.cgi?id=231162

Ils ont également résolu le problème de la propriété font-variant, je crois (Pour ceux ne sachant pas ce que font-variant, voir https://developer.mozilla.org/en/CSS/font-variant n'est pas encore à jour avec le changement, mais la doc est un navigateur agnostique et un wiki, donc...)

0voto

BarsMonster Points 3484

La cause première de ce problème doit être une gestion incorrecte de ces caractères turcs par la bibliothèque Unicode utilisée dans tous ces navigateurs. Je doute donc qu'il existe une solution frontale pour cela.

Quelqu'un doit signaler ce problème aux développeurs de ces bibliothèques unicode, et il serait corrigé dans quelques semaines / mois.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X