Объединение сложенных элементов форматирования DOM - контент-доступный DIV

У меня есть контент-доступный DIV, который связан/синхронизирован обратно в текстовое поле.

Контекстно-зависимый DIV - это песочница бесплатно для всех, которая будет создавать элементы форматирования и т.д. при их вызове. Однако это часто приводит к беспорядочным сложным элементам.

Я хотел бы иметь возможность очистить код до того, как форма textarea будет отправлена ​​на сервер.

В результате можно сделать что-то вроде следующего:

<div>
  <b>
    <i>
        Hel
    </i>
    <i>
        l
    </i>
  </b>
  <i>
    <b>
       o World!
    </b>
  </i>
</div>

Что идеально было бы преобразовать в:

<div>
  <b>
    <i>
       Hello World!
    </i>
   </b>
</div>

Если бы я ходил (рекурсивно) через childNodes div, я мог бы, вероятно, отслеживать форматы (tagName.toUpperCase() == {'B','I' ....} )//или делать document.queryCommandState, в течение которых я мог бы сделать document.execCommand('removeFormat',false,null) на selectNode(thenode).

Тем не менее, я немного потерял то, как я могу отслеживать соседние узлы в форматах.

В качестве справочного материала я недавно сделал для разбора DOM, чтобы удалить форматирование из тегов IMG: http://jsfiddle.net/tjzGg/

NB: Это аналогичный вопроs > jquery - консолидировать сложные элементы DOM, но речь идет о консолидации строк стиля useCSS в один основной стиль. Причина этого другого вопроса заключается в том, что я хочу консолидировать текст с общим стилем, но искусственно разделять несколько элементов из-за того, как текст был отформатирован. Если вы используете контентный div и индивидуально жирный один символ за раз, вы получите один символ на элемент.

Ответ 1

У меня есть несколько решений, которые имеют свои плюсы и минусы.

Во-первых, во время игры в gmail я обнаружил, что контент-доступный DIV "поглотит" соседний node, если стиль форматирования находится в том же текущем выбранном режиме. Эта "халява" позволила мне просто попытаться реорганизовать заказ, в котором происходит форматирование, чтобы очистить большую часть супа html. Это не полное решение. Идеальное решение будет состоять в том, чтобы иметь самый большой режим форматирования, поскольку родительский элемент с текстами подмножества имел бы в уменьшающихся величинах дальнейшие вложенные режимы.

В приведенном выше искусственном примере результат по сути был бы преобразован в:

<div>
   <b>
     <i> 
        Hel
        l
     </i>
    </b> 
....

caveat: Это было протестировано только с текстом, без изображений. Я бы предположил, что есть ошибка или две проблемы, связанные с анализом node в решении 1 и использование textContent.length в решении 2.


Решение 1:

Первый работает в Chrome, но в Firefox, вызывающем execCommand, приведет к тому, что выбор node потеряет фокус и станет невыбранным. Это фатальный недостаток, который я, похоже, не понимаю и не программирую. Это было отменено, если я не могу понять, как повторно выделить/выбрать вновь отформатированный node.

http://jsfiddle.net/tjzGg/3/

Мне бы очень хотелось, чтобы это работало с Firefox. Любые предложения о том, где я ошибаюсь.


Решение 2:

Второй подход - попробовать придумать решение для Firefox, теряющего фокус. Единственный способ, с помощью которого я мог бы справиться, это игнорировать выбор целых узлов, но вместо этого выбирать один символ за раз, посмотреть его форматирование, ядерное оружие и повторное применение в определенном порядке. Это работает в обоих браузерах, но DOM затем разбивается на childNode для каждого символа. Я не уверен, что их можно комбинировать (textContent?).

http://jsfiddle.net/LDVpD/3/


[background: посмотрел на jsbeautifier, htmlsoup, html tidy, nokogiri, hpricot, jtidy..... Я действительно удивлен, что на этом уже нет решения. GMail также будет генерировать "уродливое" форматирование!]

Я знаю, что есть лучшие решения - мне бы хотелось услышать некоторые предложения.

Обновление

После тестирования очевидно, что решение 2 смехотворно медленное (было бы непросто оптимизировать его, отслеживая голову, поскольку это прогрессивный "поток", но все же он довольно медленный), и даже один может легко изменить его для обработки целых текстовых нодов, но решение 1 похоже на лучший подход, если он работает только в Firefox.


Решение 1 + 2 = 3:

Я выяснил, что если бы я применил форматирование как средство для переключения, он работал бы, как и прогнозировалось, что текстовые узлы будут расти/сокращаться на основе естественной консолидации соседнего согласованного форматирования. Поэтому мне стало приятно спать, что если бы я создал список текстовых узлов и пошел назад, мне было бы все равно, если бы внутри DOM (для Firefox!!!) рос/сокращался при форматировании. Сочетание списка 2-го списка решений 2 (а затем сбрасывание хвостовых узлов) отлично работает. Фактически повторение вместо рекурсивных текстовых узлов (исходный метод решения 1) еще быстрее.

http://jsfiddle.net/tjzGg/4/

Примечание: selectNodeContents vs selectNode