Сначала вопрос.
Никто не посоветует какое-нибудь расширение для Thunderbird для редактирования исходного HTML-кода?

Исходник – Edit HTML Source.
Жаль, что расширение старое и больше не разрабатывается...

Так вот, я пересобрал исходник и кое-чего добавил.

В окне составления сообщения:
Ctrl+Shift+E – открыть редактор.
В окне редактора:
Ctrl+S – сохранить – то же самое, что и по кнопке Ok, но без закрытия окна.
Ctrl+H – открыть панель замены.
Ctrl+R – заменить.

edithtmlsrc.oninputApply = true => автоматическое применение текущего кода (можно не жать Ctrl+S)
По умолчанию edithtmlsrc.oninputApply = false (на больших текстах могут быть тормоза)

По нажатию Ctrl+H автоматически заполняется поле «Найти:»:
– при наличии выделения будет использоваться выделенный текст;
– если ничего не выделено – содержимое буфера обмена.
При замене используются регулярные выражения (при этом выделенный текст или текст буфера будет преобразован в нужный вид). Т.е. можно просто выделить текст, нажать Ctrl+H и ввести то, на что надо заменить в поле «Заменить на:».

Может, кому полезно будет...
Edit HTML Source 2 0.0.2.4 [5,0 кб]

А теперь вопросы.
1. Как заполучить <head> (ну, и сохранить потом изменения), а то сейчас можно править только содержимое <body>?
2. Способ замены без регулярных выражений (indexOf("текст") -> substring)?
3. (Мечта идиота :D) Какой-нибудь универсальный RegExp для удаления мусора от M$ аутглюков.

P. S. Надо бы добавить возможность удаление всего форматирования...
Что-то вроде вот этого:
/<br>/g => "[br]"
/&nbsp;/g => "[br]" (?)
/<\/?[^<>]+>/g => ""
/\[br\]/g => "<br>"
/ +/g => " " (?)
/ +$/mg => "" (?)

Добавил:
(в окне редактора)
F5 – обновить (заново загрузить HTML-код);
Ctrl+Shift+D – удалить лишнее форматирование.
Выживают только простые тэги (<b>, <i> и т. п.), а также цвета, заданные через <font color="">.
Рассчитано на аутглюки, описывающие в каждом font-тэге цвет (если начало будет не <font color="" ... >, то останутся лишние закрывающие </font>).

Edit HTML Source 2 0.0.2.6 [5,9 кб]

Как можно получить состояние прокрутки определенного textbox'а?
А то вот это

Выделить код

Код:

var theBox = document.commandDispatcher.focusedElement;
var oPosition = theBox.scrollTop;
var oHeight = theBox.scrollHeight;
// ... replace ...
var nHeight = theBox.scrollHeight - oHeight;
theBox.scrollTop = oPosition + nHeight;

обращается к (как там это по-русски...) выделенному textbox'у.

Как можно получить состояние прокрутки определенного textbox'а?

Суть вопроса непонятна, что если отыскать через DOM (getElement[s]By...) этот "определённый" textbox ?

Суть вопроса непонятна

Суть вопроса – не отловить определенный текстбокс, получить его состояние прокрутки. (sic!)

Выделить код

Код:

var txtbox = document.getElementById("edithtmlsrc-text");
var oPosition = txtbox.scrollTop;
var oHeight = txtbox.scrollHeight;
alert(oPosition + "\n" + oHeight);
// И все – undefined \n undefined
// Остальное, естественно, уже бессмысленно
// Или-таки руки у меня кривые...

Т. е. надо:
1) запомнить положение полосы прокрутки (scroolbar'а);
2) var text = txtbox.velue; /* манипуляции с text'ом */ txtbox.velue = text;
3) вернуть положение полосы прокрутки как было.

Можно, конечно, txtbox.focus();, а потом – код из моего предыдущего поста.
Но тогда еще один вопрос – как вернуть фокус на место? Я так понимаю, проверить все текстбоксы (getElementsByTagName("tetxbox")), но на что (какой параметр / атрибут)?

Теперь, надеюсь, понятнее, что мне нужно?

А, ну правильно, у textbox ведь вообще нет свойства scrollTop.
textbox. inputField. scrollTop - у этого есть.

Anton
Ну, что так до этого свойства не добраться, я и так понял...
Спасибо!

Немного поигрался с дизайном, вынес настройки на окно редактора.
Преобразовывать пробелы – при нажатии Ctrl+H (или выборе соответствующего пункта меню) все пробелы в выделенном тексте или буфере обмена будут заменены на [\s\n]+ (любой пробельный символ или перевод строки в любом количестве – один, два и т.д.).

Edit HTML Source 2 0.0.2.9 [6,8 кб]

Скрин:
edit_html_source_2-0.0.2.9.png

Вопрос.
Есть функция, определяющая положение курсора через
document.getElementById("edithtmlsrc-text").inputField.selectionStart
Как привязать ее выполнение к изменению ...selectionStart?

Менее важный вопрос.
Как можно проще определить столбец (количество символов от начала строки до курсора)?
Вот так

Выделить код

Код:

var txtbox = document.getElementById("edithtmlsrc-text");
var input = txtbox.inputField;
var startPos = input.selectionStart;
var startText = txtbox.value.substring(0, startPos);
var columnAr = startText.split("\n");
var startСolumn = columnAr[columnAr.length - 1].length;

работает, но как-то не нравится мне создание лишнего массива...

Как привязать ее выполнение к изменению ...selectionStart?

Так: http://forum.mozilla-russia.org/viewtopic.php?id=17617
или так: http://forum.mozilla-russia.org/viewtop … 05#p117305

определить столбец

Пример с lastIndexOf: http://pastebin.mozilla-russia.org/89714

Anton
Так, с lastIndexOf все понятно. Спасибо.
А вот топик про watch я видел и раньше, но реализовать что-то так и не получается... А с XBL я почти не знаком. Так что, если не трудно, можно поподробней про watch?

А пока работает только вот так:

Выделить код

Код:

var editHTMLsrc = {
	//...
	updateStatus: function() {
		var status = "Undefined";

		var txtbox = document.getElementById("edithtmlsrc-text");
		var input = txtbox.inputField;
		var startPos = input.selectionStart;
		var endPos = input.selectionEnd;

		var startText = txtbox.value.substring(0, startPos);
		var startLines = 1;

		for(var i = 0; i < startText.length; i++)
			if( startText.charAt(i) == "\n" )
				startLines++;

		var li = startText.lastIndexOf ("\n");

		var startColumn = li != -1
			? startText.substring (li).length
			: startText.length + 1;

		status = startLines + ":" + startColumn;

		if(startPos != endPos) {
			var selText = txtbox.value.substring(startPos, endPos);
			var selLenght = selText.length;

			var endText = txtbox.value.substring(0, endPos);
			var endLines = 1;

			for(var i = 0; i < endText.length; i++)
				if( endText.charAt(i) == "\n" )
					endLines++;

			var li = endText.lastIndexOf ("\n");

			var endColumn = li != -1
				? endText.substring (li).length
				: endText.length + 1;

			status = startLines + ":" + startColumn + " \u2013 " + endLines + ":" + endColumn + ", " + selLenght;
		}
		document.getElementById("edithtmlsrc-statusbar").setAttribute("label", status);
		setTimeout("editHTMLsrc.updateStatus()", 50);
	},
	// ...
};

Не фонтан, конечно... Но, по крайней мере, функцию установки статуса проверил.

с lastIndexOf все понятно..., можно поподробней про watch?

В примере с lastIndexOf есть пример и с watch. Что именно не понятно ?

p.s. Кстати, мой код с lastIndexOf, можно слегка оптимизировать - substring(...).length - лишнее.

p.p.s. Равно как и условие.

Что именно не понятно ?

С примером всё понятно. Не получается «повесить» watch на изменение
document.getElementById("edithtmlsrc-text").inputField.selectionStart
(и selectionEnd)
[Или у мну приступ жестокого тупизма]

мой код с lastIndexOf, можно слегка оптимизировать

Вот так:

Выделить код

Код:

var t = "123456\n7\n8\n9";
var c = t.length - t.lastIndexOf("\n");
alert(c);

?

Не получается «повесить» watch на изменение
document.getElementById("edithtmlsrc-text").inputField.selectionStart

Выделить код

Код:

...
	load: function() {
		...
		var tb = document. getElementById ("edithtmlsrc-text");
		tb. inputField. watch ("selectionStart", this. watcher);
	},
	
	watcher: function (pn, ov, nv)
	{
		var s = "property name: " + pn +
				"; old value: " + ov +
				"; new value: " + nv;
		var tb = document. getElementById ("watcher-textbox")
		tb. value = s;
		return nv;
	},
	
	watchtest: function ()
	{
		var tb = document. getElementById ("edithtmlsrc-text");
		tb. inputField. selectionStart = 0;
	},

	apply: function() {
	...

А, вот, почему у меня не получалось...
Почему-то работает только при выполнении ...watchtest(), а при простом перемещении курсора – нет. А выполнение по нажатию кнопки куда проще сделать через oncommand=""" :D

Я добавил код как есть плюс
<textbox id="watcher-textbox" />
<button label="Watch test" oncommand="editHTMLsrc.watchtest();" />

Жмем кнопку – работает (property name: selectionStart; old value: undefined; new value: 0). А  вот на манипуляции с edithtmlsrc-text никак не реагирует.
И «undefined» меня несколько смущает...

при простом перемещении курсора – нет.

Так бы сразу и сказал.

Выделить код

Код:

...
	load: function() {
		...
		var tb = document. getElementById ("edithtmlsrc-text");
		var ps = tb. editor. selection. QueryInterface (Components. interfaces. nsISelectionPrivate);
		ps. addSelectionListener (this. selectionListener);
	},
	
	selectionListener:
	{
		QueryInterface: function (iid)
		{
			if ((iid instanceof Components. interfaces. nsISupport) ||
				(iid instanceof Components. interfaces. nsISelectionListener))
				return this;
			else
				throw Components. results. NS_ERROR_NO_INTERFACE;
		},

		notifySelectionChanged: function (doc, selection, range)
		{
			var tb1 = document. getElementById ("edithtmlsrc-text");
			var tb2 = document. getElementById ("watcher-textbox");
			var s = "selectionStart: " + tb1. inputField. selectionStart +
					"; selectionEnd: " + tb1. inputField. selectionEnd;
			tb2. value = s;
		}
	},
	
	apply: function() {
		...
Anton пишет

Так бы сразу и сказал.

Так я ж, вроде, и сказал:

Есть функция [...] Как привязать ее выполнение к изменению ...selectionStart?

Каким образом изменяется selectionStart – не уточнялось (к тому же, после кода с setTimeout можно было догадаться :P)...
[Зато теперь я умею использовать watch :)]
А вообще, спасибо огромное, заработало.

Edit HTML Source 2 0.0.2.10 [7,5 кб] (Почти не тестировал – что-нибудь может не работать...)

Хммм... Почему-то ругается консоль:

Выделить код

Код:

Ошибка: document.getElementById("taskPopup") has no properties
Источник: chrome://edithtmlsrc/content/edithtmlsrc.js
Строка: 4

На вот это:

Выделить код

Код:

var editHTMLsrc = {
	init: function() {

		document.getElementById("taskPopup").addEventListener (
			"popupshowing",
			function() { ...

Но, несмотря на это, в текстовом режиме пункт действительно скрывается :|

Каким образом изменяется selectionStart – не уточнялось (к тому же, после кода с setTimeout можно было догадаться tongue)...

Телепаты, они такие - кто в отпусках, кто более высокооплачиваемую работу нашёл.
Я этот кусок кода с setTimeout не видел даже после упоминания о его существовании. Нет, я верю, конечно, что он в этой теме есть. Просто, неочивидно, зачем его искать.

ругается консоль

Один и тот же *.js включается в два разных *.xul. В одном id="taskPopup" есть, в другом - нет. Ничего особенного.

Я этот кусок кода с setTimeout не видел даже после упоминания о его существовании. Нет, я верю, конечно, что он в этой теме есть.

Ctrl+F, впрочем, не суть. А на самом деле я просто не знал (или не подумал...), что разные способы отлавливания изменений могут давать совсем даже неидентичный эффект.

Еще раз спасибо за помощь.