| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > JavaScript: Общие вопросы > 4 пробела для Python-а (продолжение) + баги IE |
| Автор: 12345c 10.10.2006, 07:32 |
| Попытался сделать операцию средствами скриптов Винграда и наткнулся на баг TextRange в IE, не позволяющий это сделать (простыми методами, в 2-10 строчек). Суть в том, что если выделение текста в Textarea начинается с 1-го символа не 1-й строки, то выделение (selection) "проглатывает" символ переноса строки, и анализом состыкованных объектов Textrange нельзя узнать, стоит ли между ними перенос. Из этого немедленно следует, что таким способом нельзя выполнить сдвиг группы строк - мы не будем знать, сделано выделение в середине или в начале строки. Конечно, другим способом анализа (пересчётом суммы символов) узнать это можно. Но глюк интересен теоретически сам по себе, поэтому вынес его в новую тему. Заодно, несколько развита тема сдвига строк. В настоящий момент в архиве лежит скрипт, имеющий 2 кнопки - Ctrl+[, Ctrl+] над Textarea, срабатывающий по клавишам, т.е. совместимый по управлению с Винградом. Но действие наблюдается только в IE, и то неправильное, но уже более-менее локализованное, имеющее наглядность. Вся функция лежит в MyLib.js архива под именем TextAreaSelectionHelper.prototype.move4p . Часть, относящаяся к Опере и FF не затрагивалась вследствие таких интересных событий с IE. Если кто желает переписать или поотладить - архив в http://js2.ru/files/vingradScripts.rar (29 К). Правила, которые достигались и достигаются пока что - * Если курсора в поле нет, реакции на Ctrl+[ нет; * Если курсор есть, но нет выделения текста или выделение в пределах строки, ставится/удаляется до 4 пробелов в начале строки; * Если есть выделение, охватывающее переносы строк, ставится/удаляется группа пробелов в каждом начале строки в выделении и в строке в начале выделения; * позиции выделения или курсора сохраняются относительно существовавшего текста. Добавлено @ 07:34 Исходная тема: http://forum.vingrad.ru/index.php?showtopic=113416 - "вставка/удаление 4-х пробелов при нажатии "Ctrl+]"/"Ctrl+[" " |
| Автор: 12345c 10.10.2006, 20:37 | ||||
Хуже того, как узнать, сколько мы выделили пустых переносов строки, как в следующем примере? (Длина выделения равна 0.) Проползанием с помощью moveStart()? А если переносов будет тысячи?
(Ещё не пропало желание сделать отличный редактор для Питона в IE? Интересно, какую длину займёт каждая из предположенных Girder-om пары строк кода? Правильно, настоящим джедаям любая длина не помеха.) То-то я регулярно замечал, что хорошо отлаженные скрипты вставки BB-кодов иногда выдают ошибку, выражающуюся в "слипании" двух соседних строк после вставки. Смотришь, думаешь, что неудачно выделил, вставляешь перенос и идёшь дальше. Вот где собака зарыта - IE не замечает ("проглатывает") любое количество переносов строк, стоящее на краях области выделения. И это остаётся после действия замены document.selection - перенос строки или несколько переносов перестают существовать. Задача, стало быть, заключается в том, чтобы вычислить (нащупать) то, сколько переносов строк находится на краях области выделения. Метод имеется единственный - moveStart/moveEnd. (При этом надо учитывать, что он понимает перенос как 1 символ, а выделение считает его внутри себя - как 2 (\d\n).) (Наверняка, задача с другими бр-рами в этом плане будет неизмеримо проще.) |
| Автор: 12345c 11.10.2006, 01:59 | ||
Zeroglif,
|
| Автор: Zeroglif 11.10.2006, 09:36 | ||
Диапазон отсекает правый крайний перенос, то есть условная правая граница диапазона с точки зрения TextRange.text стоит перед этим ближним переносом. Естесственно, не будет виден ни 2-ой, ни 3-ий, ни энный перенос справа, граница же уже установлена перед самым первым. Результаты твоего теста имхо не плавают, а как раз показывают это весёлое поведение IE. |
| Автор: Sardar 11.10.2006, 16:00 |
| Метод Zeroglif'а с "щупом" для начала и конца строки ИМХО самый действенный, вчера часа два убил что бы перенести на форумские скрипты Споткнулся о селекцию, я её сохраняю как на была. При unindent'е если от курсора до начала строки меньше tab'а, то курсор должен остаться на начале строки и не прыгать на предидущую. Сейчас добью фишку и выложу с обильными коментариями. |
| Автор: 12345c 11.10.2006, 20:19 |
| Я обошёл нащупывание в большинстве случаев через взятие разности длин двух TextRange, когда работает правильная левая граница. (Для примера, когда нужно взять длину выделенной строки.) В малом числе случаев, когда выделение происходит в сплошных переносах в конце поля ввода, такое простое решение перестаёт работать, и нужно нащупывание символа, отличного от переноса, через moveStart|moveEnd('character',-1). Это реализовано в примере http://javascript.aho.ru/example/JsPrimeryCode-97.htm (дополнил его сейчас) для выполнения вроде бы простенькой задачи - взять длину строки выделенных символов в Textarea. И оно стало работать. Теперь Ctrl+A не даёт чудеса в результате. Подковавшись в методах определения длин строк, можно возвращаться к основной задаче :). Правда, тебе, Sardar, это сподручнее, а то я там наделаю своего кода. |
| Автор: 12345c 12.10.2006, 22:37 | ||
Вот она, функция вычисления длины любой области TextRange, лежащей в поле textarea:
Дополнение: выставление и убирание пробелов сделано в IE с помощью написанной функции (конец строки не очень правильно обрабатывается), осталось выставлять выделение. Поскольку при работе с this.iesel появляется новый букет глюков, подумал, что проще будет работать с правильными вычисленными смещениями краёв выделения, но при выставлении выделения требуется перевести его снова в глючный формат (ожидается ради этого новая страница примера). Промежуточный результат в http://javascript.aho.ru/files/vingradScripts.rar , где для наглядности пробелы заменены на "@". Продолжение: По скрипту остался "последний вздох" - правильно вычислить положение конца области выделения (скрипт для IE). От идеи менять this.iesel, чтобы не переустанавливать границы выделения, пришлось отказаться, потому что глючность всоприятия им краевых переносов строки привела к тому, что сделать корректное изменение не представилось возможным. Вместо этого продолжил подход, сделанный в скрипте "http://forum.vingrad.ru/index.php?showtopic=107024" (вставка текстов под курсором; её надо поправить тоже в соответствии с этой темой) - вычислить корректные заменители .selectionStart, .selectionEnd в IE и пользоваться реальными строками из .value . При выставлении выделения нужно было учесть очередной глюк (или нестыковку) TextRange, когда он считает, что move() через перенос строки - это 1 символ, когда в коде Textarea их 2 (\r\n). В http://javascript.aho.ru/files/vingradScripts.rar - обновлённая версия и комметарий того, что функция TextAreaSelectionHelper.prototype.move4p делает. Ещё 1 день - и можно проверять практичность работы. Окончание для IE: функция для IE работает, можно тестировать юзабельность. Специально проработал начала и концы выделений в разных случаях. Срабатывает по кнопкам в конце списка кнопок над полем ввода под названием Ctrl_[ и Ctrl+], но сочетания клавиш не работают - что-то сломал в скриптах, потому что вначале работали. Вероятно, переустановить в скрипты не должно составить проблемы. Sardar, доделывать ли дальше или ты сам сделаешь свой вариант? Для себя я задачу решил (могу подробно расписать процесс и полезные выводы здесь), дальше может интересовать, если только будет применяться. Если будет применяться, доделаю скрипт и подробно распишу процесс для всех браузеров. |
| Автор: pythonwin 7.11.2006, 06:58 |
| потестировал - вроде нормально, но жаль что не работают клавиши (Ctrl+[ и Ctrl+]) + хорошо бы сделать так чтобы при нажатии Enter в конце строки в новую строку добавлялось столько же пробелов как и у родительской строки. |
| Автор: 12345c 2.12.2006, 20:59 |
| Сделана совместимость с остальными бр-рами, просьба проверить в http://forum.vingrad.ru/topic-124918.html . Имеется как файл с внедрённым в скрипты форума кодом, так и демонстрационный пример, который достаточно скопировать в файл для выполнения. |