Rangy: индексы, возвращаемые range.selectCharacters (), зависят от структуры HTML - PullRequest
0 голосов
/ 22 июня 2019

Мне нужно выделить несколько запятых в тексте.Для этого я сначала получаю индексы всех запятых:

for (let i = 0; i < text.length; i++) {
      if (text[i] == ',')
          commaIndexes.push(i);
}

In Ну, я думаю, что пропущено несколько запятых, верно? , эти индексы 4 и 42.

Затем этот текст переносится в промежутки, которые я получаю из алгоритма сравнения:

<span>Well</span>
<span>,</span>
<span> I guess there's a few commas missing</span>
<span>,</span>
<span> right?</span>

Я хочу выбрать запятые по их индексу, используя Rangy :

// Create a Rangy range at the index that should contain a comma
let range = rangy.createRange();

// I'd expect the range to include the comma and only the comma.
range.selectCharacters(fragment, index, index + 1);

Работает только для первой запятой в тексте.Обтекание текста в промежутки, кажется, сдвигает индекс, и я мог бы выяснить систему: для каждой предыдущей запятой мне нужно добавить 2 к индексу каждой другой запятой:

for (let i = 0; i < text.length; i++) {
    if (text[i] == ',')
        commaIndexes.push(i + 2 * commaIndexes.length);
}

Мой код работает сейчас,но я хотел бы понять, что происходит.Насколько я понимаю, метод range.selectCharacters Рэнги должен выбирать символы на основе индексов видимого текста, не должно иметь значения, если текст обернут в промежутки.

Редактировать: в моем разрыве строкВторой пример кода.Я скопировал это из инструментов разработчика Chrome.Разрыв строки может вызвать мою проблему, однако я не уверен, являются ли они частью DOM или просто отображаются в инструментах разработчика.Это все, что я делаю, чтобы обернуть текст в промежутки:

// Create new span to host the segment
let span = document.createElement('span');

// Set text and append span
span.innerText = 'some text';
fragment.appendChild(span); 

Второе редактирование: фрагмент кода

rangy.init();

// A sample text. Commas should be at (zero-based) indexes 4 and 42.
let text = "Well, I guess there's a few commas missing, right?";

// Store zero-based comma indexes
let commaIndexes = [];

for (let i = 0; i < text.length; i++) {
      if (text[i] == ',')
          commaIndexes.push(i);
}

// Simulate diff output
let substrings = [
  'Well',
  ',',
  " I guess there's a few commas missing",
  ',',
  ' right?'
];

// Create a DOM fragment to hold all spans created in the next step
let fragment = document.createDocumentFragment();

// Create new span for each substring
substrings.forEach(substring => {
    let span = document.createElement('span');

    // Set text and append span
    span.innerText = substring;
    fragment.appendChild(span);
});

commaIndexes.forEach(index => {
    // Create a Rangy range
    let range = rangy.createRange();

    // I guess selectCharacters is one-based, left index including, right index excluding?
    range.selectCharacters(fragment, index + 1, index + 2);

    // I get the first comma and the 'g' preceding the second one
    console.log(range.text());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rangy/1.3.0/rangy-core.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/rangy/1.3.0/rangy-selectionsaverestore.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/rangy/1.3.0/rangy-textrange.js"></script>
...