Почему IE7 не копирует блоки в буфер обмена правильно?

мы заметили, что IE7 имеет нечетное поведение с блоками кода, размещенными на переполнении стека. Например, этот маленький блок кода:

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

копировать и вставлять из IE7, заканчивается так:

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

не совсем то, что мы имели в виду.. базовый источник HTML на самом деле выглядит нормально; если вы просматриваете Источник, вы увидите следующее:

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

так что мы делаем неправильно? Почему ИЕ7 скопируйте и вставьте этот HTML рационально?

обновление: это конкретно связано с <pre> <code> блоки, которые изменяются во время выполнения с помощью JavaScript. родной HTML делает рендеринг и копирование правильно; это модифицированная версия JavaScript этого HTML, которая не ведет себя так, как ожидалось. Обратите внимание, что копирование и вставка в WordPad или Word работает, потому что IE помещает различное содержимое в буфер обмена rich text по сравнению с обычным текстовым буфером обмена, из которого Блокнот получает свои данные.

7 ответов


кажется, что это известная ошибка для IE6 и prettify.у js есть обходной путь для этого. В частности, он заменяет теги BR на "\r\n".

путем изменения проверки, чтобы разрешить IE6 или 7, то вырезать и вставить будет работать правильно из IE7, но он будет отображаться с newline затем пробел. Проверяя IE7 и предоставляя только "\r "вместо" \r\n", он будет продолжать вырезать и вставлять и отображать правильно.

добавить код для приукрашивания.js:

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

а затем измените функцию prettyPrint следующим образом:

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

вы можете увидеть рабочий пример здесь.

Примечание: я не тестировал исходный обходной путь в IE6, поэтому я предполагаю, что он отображает без пространства, вызванного "\n", которое видно в IE7, в противном случае исправление проще.


отсюда вопрос:

ваш скрипт раскрашивания кода заменяет разрывы строк тегами
. При копировании / вставке IE7, по-видимому, не переводит тег
в linebreak, как это происходит для экрана.

другими словами, ваш код будет такой:

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

но вы хотите, чтобы это стало так:


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

в последней версии prettify.js в коде Google, ответственная строка-строка 1001 (часть recombineTagsAndDecorations):


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

отредактировано, на основе комментариев:
Для IE7 это то, что строка, вероятно, должна быть изменена на:


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

(предполагая newlineRe заполнитель).

это исправление также выполняется в Chrome и FFX3... Я не уверен, какие (если есть) браузеры нуждаются в тегах
.

обновление: Более подробная информация в моем втором ответе:
почему IE7 не копирует блоки

 в буфер обмена правильно?


Это похоже на ошибку в IE, BR теги внутри PRE или код не преобразуются в новые строки в буфере копирования обычного текста. Буфер копирования богатого текста в порядке, поэтому вставка работает так, как ожидалось для таких приложений, как wordpad.

скрипт prettify, который окрашивает код, удаляет все пробел и заменяет его тегами HTML для пробелов и новых строк. Сгенерированный код выглядит что-то вроде этого:--10-->

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

на PRE и код теги отображаются по умолчанию со стилем CSS {пробел: pre}. В этом случае IE не удается включить BR теги в строку. Он будет работать на вашем исходном HTML, потому что IE успешно превратит фактические новые строки в новые строки.

чтобы исправить это, у вас есть 3 варианта. (Я предполагаю, что вы хотите хороший HTML и возможность хорошо работать с javascript и без него включена на клиенте):

  1. вы можете поместить код внутри обычного div и использовать CSS для его рендеринга с помощью {пробел: pre}. Это простое решение, хотя может не понравиться пуристу разметки HTML.

  2. у вас может быть две копии кода, одна из которых использует proper PRE / код теги и еще один в a обычный div. В вашем CSS вы скрываете обычный div. Используя javascript, вы улучшаете обычный div и скрываете версию pre/code.

  3. измените сценарий prettify, чтобы признать, что он действует на PRE или код элемент и не заменять пробелы в этом случае.


Примечания:

  • что важно, это не HTML в вашем источнике, а HTML как приукрасить скрипт запускал на нем.

  • эта ошибка все еще присутствует, даже если режим пробела PRE изменено на нормальный использование CSS.


этот сайт решил проблему:http://www.developerfusion.com/tools/convert/csharp-to-vb/

Я предлагаю кнопку "Копировать в буфер обмена" как часть окна отображения кода. Эта кнопка будет копировать версию отображаемой информации в виде обычного текста. Простой текст может храниться как внутреннее свойство страницы.


плохие новости: ни один из предложенных исправлений не работает. Модификация prettify.js вокруг линии 1000

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

это вызывает двойной интервал в других браузерах и еще не решает проблему копирования IE7 в блокнот! Поэтому, даже если я выборочно обнаружил IE7, это "исправление" ничего не исправляет.

Я думаю, может быть, это просто ошибка в IE7, связанная с перестройкой JavaScript <pre> element -- независимо от того, сколько \ N новых строк я положил туда, ничего не меняется без / r/t к поведению вставки в блокнот.


@Jeff Atwood Это правильная идея, но реализация все еще нуждается в работе. Думаю, мой воздушный код просто не разрезал его:)

Я подозреваю, что исправление, о котором я упоминал ранее, не работает, потому что prettify выполняет дополнительную обработку текста после вызова строки ~1000.

пытаясь отслеживать содержимое назад от того, когда оно добавлено на страницу, я наткнулся на этот комментарий вокруг строки 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.

когда я снял условие isIE6 с код, он в основном работал в IE7 (был дополнительный разрыв строки вверху и внизу) и Firefox 3... Но я бы предположил, что это вызывает проблемы со старыми версиями FFX.

по крайней мере, кажется, что IE7 потребует \r\n, а не только \n. Выяснить, что именно будет работать, с какими браузерами будет проходить более обширная тестовая настройка, чем у меня есть на данный момент.

в любом случае, вставка \r\n для IE7 кажется в основном тем, что должно произойти. Я продолжайте шарить вокруг, чтобы увидеть, могу ли я сузить его дальше.

обновление: IE7, похоже, удаляет символы новой строки (\r или \n) из строк, назначенных свойству innerHTML. Похоже, их нужно добавить обратно в строку 1227.

правильное решение, вероятно, означает вставку тега-заполнителя вокруг строки 1000, а затем замену его вокруг строки 1227.


снимите внутреннюю <code>. Поведение копирования/вставки IE может видеть это как встроенный тег и забывать о видимых пробелах.