Pourquoi IE7 ne copie-t-il pas < pre > < code > blocs au presse-papiers correctement?

StackOverflow https://stackoverflow.com/questions/136443

  •  02-07-2019
  •  | 
  •  

Question

Nous avons remarqué que IE7 avait un comportement étrange avec des blocs de code publiés sur Stack Overflow. Par exemple, ce petit bloc de code:

public PageSizer(string href, int index)
{
    HRef = href;
    PageIndex = index;
}

Copié et collé depuis IE7, se termine comme ceci:

public PageSizer(string href, int index){    HRef = href;    PageIndex = index;    }

Ce n'est pas exactement ce que nous avions à l'esprit. La source HTML sous-jacente semble en fait bien; si vous affichez Source, vous verrez ceci:

<pre><code>public PageSizer(string href, int index)
{
    HRef = href;
    PageIndex = index;
}
</code></pre>

Alors, que faisons-nous de travers? Pourquoi IE7 ne peut-il pas copier et coller ce code HTML de manière rationnelle?

  

Mise à jour: cela concerne plus particulièrement les < pré > < code > blocs en cours de modification au moment de l'exécution via JavaScript. Le HTML natif rend et copie correctement; c'est la version modifiée par JavaScript de ce code HTML qui ne se comporte pas comme prévu. Notez que le copier-coller dans WordPad ou Word fonctionne car IE insère un contenu différent dans le Presse-papiers au format RTF par rapport au Presse-papiers au texte brut à partir duquel le Bloc-notes récupère ses données.

Était-ce utile?

La solution

Il semble que ce soit un bogue connu pour IE6 et prettify.js a une solution de contournement. Plus précisément, il remplace les balises BR par '\ r \ n'.

En modifiant la vérification pour autoriser IE6 ou 7, le copier-coller fonctionnera correctement à partir de IE7, mais le rendu sera effectué avec une nouvelle ligne suivie d'un espace . En vérifiant l'existence d'IE7 et en fournissant simplement un "\ r" au lieu d'un "\ r \ n", il continuera à couper-coller et à restituer correctement.

Ajoutez ce code à prettify.js:

function _pr_isIE7() {
  var isIE7 = navigator && navigator.userAgent &&
       /\bMSIE 7\./.test(navigator.userAgent);
  _pr_isIE7 = function () { return isIE7; };
  return isIE7;
}

puis modifiez la fonction prettyPrint comme suit:

   function prettyPrint(opt_whenDone) {
     var isIE6 = _pr_isIE6();
+    var isIE7 = _pr_isIE7();

...

-        if (isIE6 && cs.tagName === 'PRE') {
+        if ((isIE6 || isIE7) && cs.tagName === 'PRE') {
          var lineBreaks = cs.getElementsByTagName('br');
+         var newline;
+         if (isIE6) {
+           newline = '\r\n';
+         } else {
+           newline = '\r';
+         }
          for (var j = lineBreaks.length; --j >= 0;) {
            var lineBreak = lineBreaks[j];
            lineBreak.parentNode.replaceChild(
-               document.createTextNode('\r\n'), lineBreak);
+               document.createTextNode(newline), lineBreak);
          }

Vous pouvez voir un exemple de travail ici .

Remarque: Je n'ai pas testé la solution de contournement d'origine dans IE6. Par conséquent, je suppose qu'elle restitue sans l'espace créé par le '\ n' affiché dans IE7. Sinon, le correctif est le suivant. plus simple.

Autres conseils

Voici le problème:

Votre script de colorisation de code remplace les sauts de ligne par < br / > Mots clés. Lors du copier / coller, IE7 ne traduit apparemment pas le texte < br / > marquez un saut de ligne comme il le fait pour l'écran.

En d'autres termes, votre code devient ceci:

public PageSizer(string href, int index)<br />{<br />    HRef = href;<br />    PageIndex = index;<br />    }

Mais vous voulez que cela devienne ceci:


public PageSizer(string href, int index)<br />
{<br />
    HRef = href;<br />
    PageIndex = index;<br />
}<br />

Dans la dernière version de prettify.js sur Google Code, la ligne responsable est la ligne 1001 (appartenant à recombineTagsAndDecorations):


html.push(htmlChunk.replace(newlineRe, '<br />'));

Edité en fonction des commentaires:
Pour IE7, voici ce à quoi la ligne devrait probablement être remplacée par:


html.push(htmlChunk.replace(newlineRe, '\n'));

(En supposant que newlineRe soit un espace réservé).

Ce correctif s'applique également à Chrome et à FFX3 ... Je ne sais pas quel navigateur (le cas échéant) a besoin de la < br / > tags.

Mise à jour: Plus d'informations dans ma deuxième réponse:
Pourquoi IE7 ne copie-t-il pas < pre > < code > se bloque correctement dans le presse-papiers?

Cela ressemble à un bogue dans IE, les balises BR à l'intérieur du PRE ou du CODE ne sont pas converties en nouvelles lignes dans la copie en texte brut. tampon. Le tampon de copie en texte enrichi convient parfaitement. Par conséquent, le collage fonctionne comme prévu pour des applications telles que WordPad .

Le script prettify, qui colore le code, supprime tous les espaces et les remplace par des balises HTML pour les espaces et les nouvelles lignes. Le code généré ressemble à ceci:

<pre><code>code<br/>&nbsp;&nbsp;code<br/>&nbsp;&nbsp;code<br/>code</code></pre>

Les balises PRE et CODE sont restituées par défaut avec le style CSS de {whitespace: pre} . Dans ce cas, Internet Explorer ne parvient pas à transformer les balises BR en nouvelles lignes. Cela fonctionnerait avec votre code HTML d'origine, car Internet Explorer transforme avec succès les nouvelles lignes réelles en nouvelles lignes.

Pour y remédier, vous avez 3 options. (Je suppose que vous voulez du HTML agréable et une capacité de bien fonctionner avec et sans javascript activé sur le client):

  1. Vous pouvez placer le code dans une div normale et utiliser CSS pour le rendre à l'aide de {whitespace: pre} . C’est une solution simple, mais qui ne plaira peut-être pas à un puriste des balises HTML.

  2. Vous pouvez avoir deux copies du code, l’une utilisant les balises PRE / CODE appropriées et l’autre dans un div normal. Dans votre CSS, vous cachez la div normale. En utilisant javascript, vous épurez la div normale et cachez la version pré / code.

  3. Modifiez le script prettify pour reconnaître qu'il agit sur un élément PRE ou CODE et pour ne pas remplacer les espaces dans cet événement.

Remarques:

  • L'important n'est pas le code HTML de votre source, mais le code HTML généré après l'exécution du script prettify.

  • Ce bogue est toujours présent même si le mode espace blanc du PRE est remplacé par normal à l'aide de CSS.

Ce site a résolu le problème suivant: http: //www.developerfusion. com / tools / convert / csharp-to-vb /

Je suggère un " Copier dans le presse-papiers " bouton faisant partie de la zone d'affichage du code. Ce bouton copierait la version des informations affichées sous forme de texte brut. Le texte brut peut être stocké en tant que propriété de page interne.

mauvaise nouvelle: aucune des corrections proposées ne fonctionne. Modification de prettify.js autour de la ligne 1000

html.push(htmlChunk.replace(newlineRe, '\n'));

Cela provoque un double espacement dans les autres navigateurs et toujours ne résout pas le problème de la copie IE7 dans le bloc-notes! Ainsi, même si je détectais sélectivement IE7, ce "correctif" ne répare rien.

Je suppose qu’il s’agit peut-être simplement d’un bogue dans IE7 lié à la reconstruction par JavaScript de l’élément < pre > . Quel que soit le nombre de nouvelles lignes \ n que j’y ai insérées, rien ne change. r / t au comportement coller au bloc-notes.

@Jeff Atwood C'est la bonne idée, mais la mise en œuvre a encore besoin de travail. Je suppose que mon code aérien ne l’a pas coupé:)

Je soupçonne que le correctif mentionné précédemment ne fonctionne pas car prettify effectue un traitement supplémentaire sur le texte après l'appel de la ligne ~ 1000.

En essayant de suivre le contenu à l'envers depuis son ajout à la page, je suis tombé sur ce commentaire autour de la ligne 1227:


// Replace <br>s with line-feeds so that copying and pasting works
// on IE 6.
// Doing this on other browsers breaks lots of stuff since \r\n is
// treated as two newlines on Firefox, and doing this also slows
// down rendering.

Lorsque j'ai retiré la condition isIE6 du code, cela fonctionnait principalement dans IE7 (il y avait un saut de ligne supplémentaire en haut et en bas) et dans Firefox 3 ... Mais je suppose que cela pose des problèmes avec les versions antérieures. versions de FFX.

À tout le moins, il semble que IE7 nécessitera \ r \ n au lieu de \ n. Déterminer exactement ce qui fonctionnera avec quels navigateurs prendra une configuration de test plus étendue que celle que j’ai pu pour le moment.

Quoi qu’il en soit, l’insertion de \ r \ n pour IE7 semble être ce qu’il faut faire. Je vais continuer à fouiller pour savoir si je peux la réduire davantage.

UPDATE: IE7 semble supprimer les caractères de nouvelle ligne (\ r ou \ n) des chaînes affectées à une propriété innerHTML. Il semble qu’ils doivent être rajoutés autour de la ligne 1227.

Une solution correcte consisterait probablement à insérer une balise fictive autour de la ligne 1000, puis à la remplacer autour de la ligne 1227.

Supprimez le < code > interne. Le comportement copier / coller d'IE peut le voir comme une balise en ligne et oublier les espaces visibles.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top