![]() |
|
Модераторы: Sardar, Aliance |
![]()
|
|
| 12345c |
|
|||
![]() Круглый ![]() ![]() ![]() ![]() Профиль Группа: Vingrad developer Сообщений: 2018 Регистрация: 26.12.2005 Где: наша не пропадала ? Репутация: 57 Всего: 101 |
Попытался сделать операцию средствами скриптов Винграда и наткнулся на баг 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 - 3.3.2008, 13:36 -------------------- Google Code Playground - онлайн-отладка своих примеров HTML+JS без регистрации, с сохранением по URL, без кириллицы. Go |
|||
|
||||
| 12345c |
|
||||
![]() Круглый ![]() ![]() ![]() ![]() Профиль Группа: Vingrad developer Сообщений: 2018 Регистрация: 26.12.2005 Где: наша не пропадала ? Репутация: 57 Всего: 101 |
Хуже того, как узнать, сколько мы выделили пустых переносов строки, как в следующем примере? (Длина выделения равна 0.) Проползанием с помощью moveStart()? А если переносов будет тысячи?
(Ещё не пропало желание сделать отличный редактор для Питона в IE? Интересно, какую длину займёт каждая из предположенных Girder-om пары строк кода? Правильно, настоящим джедаям любая длина не помеха.) То-то я регулярно замечал, что хорошо отлаженные скрипты вставки BB-кодов иногда выдают ошибку, выражающуюся в "слипании" двух соседних строк после вставки. Смотришь, думаешь, что неудачно выделил, вставляешь перенос и идёшь дальше. Вот где собака зарыта - IE не замечает ("проглатывает") любое количество переносов строк, стоящее на краях области выделения. И это остаётся после действия замены document.selection - перенос строки или несколько переносов перестают существовать. Задача, стало быть, заключается в том, чтобы вычислить (нащупать) то, сколько переносов строк находится на краях области выделения. Метод имеется единственный - moveStart/moveEnd. (При этом надо учитывать, что он понимает перенос как 1 символ, а выделение считает его внутри себя - как 2 (\d\n).) (Наверняка, задача с другими бр-рами в этом плане будет неизмеримо проще.) Это сообщение отредактировал(а) 12345c - 10.10.2006, 21:54 -------------------- Google Code Playground - онлайн-отладка своих примеров HTML+JS без регистрации, с сохранением по URL, без кириллицы. Go |
||||
|
|||||
| Zeroglif |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
Если перенос (\r\n) находится на правом краю текстового диапазона, то он не виден, не считается IE. Мне пришлось это вычислять, если ты видел, в своём скрипте. У тебя почти такая же байда, но под другим соусом. Когда курсор стоит в начале второй строки (перед A), то tR (также как и tR2) должны показать длину = 5 (1 плюс 2 плюс 3 плюс \r плюс \n), а мы имеем 3, перенос не учтён, т.к. он у обоих диапазонов с краю. Если же мы выделим A, то tR так и останется равным 3, а tR2 уже учтёт перенос правильно, т.к. он у этого диапазона уже не с краю, а вложен внутрь, и учтён IE. Получается разница в 2. |
|||
|
||||
| 12345c |
|
|||
![]() Круглый ![]() ![]() ![]() ![]() Профиль Группа: Vingrad developer Сообщений: 2018 Регистрация: 26.12.2005 Где: наша не пропадала ? Репутация: 57 Всего: 101 |
Zeroglif,
|
|||
|
||||
| Zeroglif |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
Диапазон отсекает правый крайний перенос, то есть условная правая граница диапазона с точки зрения TextRange.text стоит перед этим ближним переносом. Естесственно, не будет виден ни 2-ой, ни 3-ий, ни энный перенос справа, граница же уже установлена перед самым первым. Результаты твоего теста имхо не плавают, а как раз показывают это весёлое поведение IE. |
|||
|
||||
| Sardar |
|
|||
![]() Бегун ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6986 Регистрация: 19.4.2002 Где: Нидерланды, Groni ngen Репутация: 78 Всего: 317 |
Метод Zeroglif'а с "щупом" для начала и конца строки ИМХО самый действенный, вчера часа два убил что бы перенести на форумские скрипты
Споткнулся о селекцию, я её сохраняю как на была. При unindent'е если от курсора до начала строки меньше tab'а, то курсор должен остаться на начале строки и не прыгать на предидущую. Сейчас добью фишку и выложу с обильными коментариями. -------------------- Опыт - сын ошибок трудных © А. С. Пушкин Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik Оценить мои качества можно тут. |
|||
|
||||
| 12345c |
|
|||
![]() Круглый ![]() ![]() ![]() ![]() Профиль Группа: Vingrad developer Сообщений: 2018 Регистрация: 26.12.2005 Где: наша не пропадала ? Репутация: 57 Всего: 101 |
Я обошёл нащупывание в большинстве случаев через взятие разности длин двух TextRange, когда работает правильная левая граница. (Для примера, когда нужно взять длину выделенной строки.) В малом числе случаев, когда выделение происходит в сплошных переносах в конце поля ввода, такое простое решение перестаёт работать, и нужно нащупывание символа, отличного от переноса, через moveStart|moveEnd('character',-1). Это реализовано в примере http://javascript.aho.ru/example/JsPrimeryCode-97.htm (дополнил его сейчас) для выполнения вроде бы простенькой задачи - взять длину строки выделенных символов в Textarea. И оно стало работать. Теперь Ctrl+A не даёт чудеса в результате.
Подковавшись в методах определения длин строк, можно возвращаться к основной задаче :). Правда, тебе, Sardar, это сподручнее, а то я там наделаю своего кода. |
|||
|
||||
| 12345c |
|
|||
![]() Круглый ![]() ![]() ![]() ![]() Профиль Группа: Vingrad developer Сообщений: 2018 Регистрация: 26.12.2005 Где: наша не пропадала ? Репутация: 57 Всего: 101 |
Вот она, функция вычисления длины любой области TextRange, лежащей в поле textarea:
Дополнение: выставление и убирание пробелов сделано в IE с помощью написанной функции (конец строки не очень правильно обрабатывается), осталось выставлять выделение. Поскольку при работе с this.iesel появляется новый букет глюков, подумал, что проще будет работать с правильными вычисленными смещениями краёв выделения, но при выставлении выделения требуется перевести его снова в глючный формат (ожидается ради этого новая страница примера). Промежуточный результат в http://javascript.aho.ru/files/vingradScripts.rar , где для наглядности пробелы заменены на "@". Продолжение: По скрипту остался "последний вздох" - правильно вычислить положение конца области выделения (скрипт для IE). От идеи менять this.iesel, чтобы не переустанавливать границы выделения, пришлось отказаться, потому что глючность всоприятия им краевых переносов строки привела к тому, что сделать корректное изменение не представилось возможным. Вместо этого продолжил подход, сделанный в скрипте "Сборная солянка" (вставка текстов под курсором; её надо поправить тоже в соответствии с этой темой) - вычислить корректные заменители .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, доделывать ли дальше или ты сам сделаешь свой вариант? Для себя я задачу решил (могу подробно расписать процесс и полезные выводы здесь), дальше может интересовать, если только будет применяться. Если будет применяться, доделаю скрипт и подробно распишу процесс для всех браузеров. Это сообщение отредактировал(а) 12345c - 13.10.2006, 01:41 -------------------- Google Code Playground - онлайн-отладка своих примеров HTML+JS без регистрации, с сохранением по URL, без кириллицы. Go |
|||
|
||||
| pythonwin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2529 Регистрация: 18.4.2006 Где: за компом Репутация: 1 Всего: 36 |
потестировал - вроде нормально, но жаль что не работают клавиши (Ctrl+[ и Ctrl+])
+ хорошо бы сделать так чтобы при нажатии Enter в конце строки в новую строку добавлялось столько же пробелов как и у родительской строки. Это сообщение отредактировал(а) pythonwin - 7.11.2006, 07:01 |
|||
|
||||
| 12345c |
|
|||
![]() Круглый ![]() ![]() ![]() ![]() Профиль Группа: Vingrad developer Сообщений: 2018 Регистрация: 26.12.2005 Где: наша не пропадала ? Репутация: 57 Всего: 101 |
Сделана совместимость с остальными бр-рами, просьба проверить в http://forum.vingrad.ru/topic-124918.html . Имеется как файл с внедрённым в скрипты форума кодом, так и демонстрационный пример, который достаточно скопировать в файл для выполнения.
|
|||
|
||||
![]()
|
| Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | JavaScript: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |