Объект Range: различия между браузерами на основе Webkit и Mozilla

В настоящее время у меня возникают проблемы с написанием слоя абстракции для браузеров на основе Mozilla и Webkit для использования объекта диапазона DOM (получение и обработка пользовательских выборок).

Я также попытался взглянуть на фреймворки, такие как Rangy, но это кажется слишком сложным для моей задачи (я не знаю, где именно в коде найти нужную мне информацию. Если кто-то может дать мне подсказку, я был бы благодарен !).

Что я хочу, так это просто:

получить ссылку на текстовый узел, в котором начинается выделение, и его смещениеполучить ссылку на текстовый узел, на котором заканчивается выделение, и его смещение

Пока что мой слой выглядит так:

var SEL_ABSTR = {
get_selection: function(window_object) {
    return window_object.getSelection();
},
get_range: function(selection) {
    return (selection.getRangeAt) ? selection.getRangeAt(0) : selection.createRange();
},
get_range_info: function(range, div_ele) {
    var first_node, start_offset;
    var last_node, end_offset;

    if (range.startContainer == div_ele) {
        // selections affects the containing div
        first_node = div_ele.childNodes[0];
        last_node = first_node;
        start_offset = 0;
        end_offset = first_node.nodeValue.length;
    } else if (range.startOffset == range.startContainer.nodeValue.length && range.endOffset == 0) {
        // known bug in Firefox
        alert('firefox bug');
        first_node = range.startContainer.nextSibling.childNodes[0];
        last_node = first_node;
        start_offset = 0;
        end_offset = first_node.nodeValue.length;
    } else {
        first_node = range.startContainer;
        last_node = range.endContainer;
        start_offset = range.startOffset;
        end_offset = range.endOffset;
    }

    return {
        first_node: first_node,
        start_offset: start_offset,
        last_node: last_node,
        end_offset: end_offset,
        orig_diff: end_offset - start_offset
    };
},
};

На данный момент я определил две ошибки Mozilla:

Иногда, когда весь содержащий текстовый узел (если он единственный) выбран внутри содержащего div, я получаю ссылку на этот div вместо ссылки на текстовый узел. Теперь я могу справиться с этим и вернуть ссылку на дочерний элемент div, который является текстовым узлом

Иногда я возвращаю ссылку на предыдущего родного брата со смещением == prevSibling.length и ссылку на следующий брата со смещением == 0. Но правильная ссылка будет в середине. Я также могу справиться с этим.

Так что еще есть для Мозиллы? Webkit работает отлично!

Следует предположить, что объект DOM-диапазона является стандартным (и я не говорю о IE, это еще одна задача ...)

приветствует!

более конкретные детали здесь:

Это не было критикой Рейнджи. Поэтому извините, если это звучало так. Я могу себе представить, что обработка этих различных API не легка сама по себе.

Вы правы, я не уточнил задачу, которую пытаюсь выполнить. Моя структура довольно проста: у меня есть div (с атрибутом contenteditable = true) и текст внутри этого div (один текстовый узел в начале).

Начиная с этой структуры, теперь можно выделять текст мышью и добавлять к нему свойство; это свойство затем выражается диапазоном, охватывающим выделенный текст, и классом, назначенным этому диапазону, представляющему выбранное свойство. Теперь можно снова выбрать текст и свойство. Если это тот же текст и другое свойство, этому классу будет присвоен другой класс или он будет удален, если свойство уже существует. Если выбран текст, охватывающий несколько интервалов, он будет разделен для того, чтобы выразить эту структуру (возможно, вы помните мой пост за июль).

<div contenteditable="true">
hello I am 
<span class="red">text but I am also <span class="underline">underlined</span></span>
<span class="underline"> also without color</span>
</div>

Алгоритм теперь отлично работает для «симметричных» случаев: я могу построить сложную структуру и затем отменить ее в обратном направлении. Он отлично работает для Safari и Chrome. Теперь я, конечно, должен развивать алгоритм дальше.

Но сейчас у меня проблемы с Mozilla, потому что я не понимаю систему для объектов диапазона DOM: startContainer, endContainer, startOffset, endOffset

В моем восприятии моего конкретного случая с div, содержащим только текстовые узлы и промежутки, я предполагаю:

что startContainer и endContainer всегда указывают на текстовый узел, на который влияет выделение мыши (нет пустых промежутков, они всегда содержат либо другие промежутки, либо текстовый узел), отмечая начало и конец всего выделениячто startOffset и endOffset указывают позицию выделения в текстовом узле в начале и в конце

В приведенном выше коде я выделил два случая, когда Mozilla действует не так, как webkit.

Поэтому, если бы я знал правила DOM-диапазона Mozilla, я мог бы интегрировать это в свой слой, чтобы поведение было одинаковым для webkit и Mozilla.

Большое спасибо за ответ.

Ответы на вопрос(2)

Ваш ответ на вопрос