Удаление пробелов из выбора окна в js

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

Пример: в скрипке попробуйте выделить -- hi this is bob.справа налево, включая пробел в конце, затем нажмите Trim.

Это приводит к в:

Uncaught IndexSizeError: Failed to execute 'setEnd' on 'Range': The offset 24 is larger than or equal to the node's length (5).

Я думаю, это можно поймать с

 if (method == range.setEnd  && range.startOffset + ind >= range.endContainer.length)

но я не знаю, как с этим справиться.
Я также попытался заменить жесткие пространства с помощью

e2 = document.getElementById('e2');
e2.innerHTML = e2.innerHTML.replace(/ /gi, ' ');

Однако это делает выбор пустым.
Код:

function removeWsFromSelection(fromStart) {
  selection = window.getSelection();
  range = selection.getRangeAt(0);
  if (fromStart) {
    regex = /[^s]/;
    container = range.startContainer;
    method = range.setStart;
  } else {
    regex = /s+$/;
    container = range.endContainer;
    method = range.setEnd;
  }

  match = regex.exec(selection.toString());
  if (match) {
    ind = match.index;
    if (ind > 0) {
      // ind is the first non-ws char from the start or first ws char from the end,
      // hence (startOffset + ind)
      method.call(range, container, range.startOffset + ind);
      rng = range.cloneRange();
      selection.removeAllRanges();
      selection.addRange(rng);
    }
  }
}

Кстати, Selection.modifyу меня, к сожалению, не получилось, к тому же это считается нестандартным .

1 ответ

  1. Это очень некрасиво и не справляется с общим делом, но, кажется, работает:

    function removeWsFromSelection(fromStart) {
          selection = window.getSelection();
          range = selection.getRangeAt(0);
          if (fromStart) {
            regex = /[^\s]/;
            container = range.startContainer;
            method = range.setStart;
          }
          else {
            regex = /\s+$/;
            container = range.endContainer;
            method = range.setEnd;
          }
    
          match = regex.exec(selection.toString());
          if (match) {
            ind = match.index;
            if (ind > 0) {
                // ind is the first non-ws char from the start or first ws char from the end,
                // hence (startOffset + ind)
                if (method == range.setEnd  && range.startOffset + ind >= range.endContainer.length) {
                  match = regex.exec(range.endContainer.textContent);
                  if (match) {
                    range.setEnd(range.endContainer, match.index); 
                  }
                }
                else {
                  method.call(range, container, range.startOffset + ind);
                }
                rng = range.cloneRange();
                selection.removeAllRanges();
                selection.addRange(rng);
            }
          }
        }