Панели
XUL-элемент panel можно использовать и как диалоговое окно и как окно сообщений. Панель может содержать любой XUL-код и таким образом в ней можно реализовать любой интерфейс. Для тех, кто хорошо знаком с компановкой XUL-интерфейсов в принципе больше ничего и не надо, поскольку тут имеются полноценные элементы управления практически на любой вкус. Единственное чего не получится реализовать с помощью панелей - это модальные окна, поскольку они должны быть полноценными окнами.Об использовании панелей можно почитать здесь
Panels - Mozilla | MDN
и здесь
Floating Panels - Mozilla | MDN
В двух словах: панель - это разновидность popup-элемента, наряду с menupopup, то есть она появляется "где скажут" и исчезает при потере фокуса. Но это поведение можно изменить, установив значение атрибута noautohide="true". Так же, установив значения других атрибутов можно настроить другие аспекты поведения панели: задать ей титлбар(зделав ее подобием окна), разместить на титлбаре кнопку закрытия, сделать так, чтобы панель можно было передвигать мышкой и т. д. В простейшем случае панель можно привязать к какому-то элементу интерфейса (кнопке, меню) и она будет появляться также, как появляется menupopup в районе этого элемента (где именно тоже можно указать явно). Можно также открывать панель программно с помощью методов openPopup и openPopupAtScreen.
Теперь для наглядности создадим простейшую панель. Создавать ее будем с помощью оверлея следующего содержания.
Код xml | Выделить |
<?xml version="1.0"
encoding="utf-8"
?>
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript">
<![CDATA[
function showValues()
{
var tb1 = document.getElementById("tb1");
var tb2 = document.getElementById("tb2");
alert("Text1 = " + tb1.value + ";\nText2 = " + tb2.value + ";");
}
]]>
</script>
<popupset id="mainPopupSet">
<panel id="myTestPanel">
<hbox>
<label>Text1</label>
<textbox id="tb1"/>
</hbox>
<hbox>
<label>Text2</label>
<textbox id="tb2"/>
</hbox>
<button label="Показать
значения" id="showValues"
oncommand="showValues();"/>
</panel>
</popupset>
</overlay>
Код javascript | Выделить |
this.setAttribute("popup", "myTestPanel");
Если нужно, чтобы панель появлялась в произвольном месте экрана, тогда в коде кнопки надо на вкладке Код поместить примерно такой код
Код javascript | Выделить |
document.getElementById("myTestPanel").openPopupAtScreen(300, 200, false);
Вывод данных в виде HTML-документа
Пример, в котором может понадобиться собрать какую-то информацию на странице и представить ее совсем в другом виде можно посмотреть здесь. Наиболее очевидным решением этой задачи является сохранение сгенерированного содержимого во временный файл с последующим открытием его с помощью функции open. Как-то так
Код javascript | Выделить |
function saveTextToTempFile(text)
{
Components.utils.import("resource://gre/modules/FileUtils.jsm");
var file = FileUtils.getFile("TmpD",
["temp_html_file.html"]);
file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].
createInstance(Components.interfaces.nsIFileOutputStream);
foStream.init(file, 0x02 | 0x08 | 0x20, 0666, 0);
var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"].
createInstance(Components.interfaces.nsIConverterOutputStream);
converter.init(foStream, "UTF-8", 0, 0);
converter.writeString(text);
converter.close();
return file.path;
}
var html = "<meta charset='utf-8'/><marquee style='color:red;font-size:30px;'>Привет</marquee>";
open("file:///" + saveTextToTempFile(html));
В примере со скачиванием медиафайлов из вконтактика сохранение во временный файл вообще было невозможно, поскольку делалось это в GreaseMonkey, там такой возможности нет (ну, или я о ней не знаю). Там открывалась пустая страница about:blank и в нее добавлялось содержимое программно. Проблема здесь в том, что если написать что-то-вроде
Код javascript | Выделить |
var newwin = open("about:blank");
newwin.document.body.innerHTML = htmlCode;
Код javascript | Выделить |
var newwin = open("about:blank");
newwin.onload = function (evt)
{
newwin.document.body.innerHTML = htmlCode;
}
Код javascript | Выделить |
var newwin = open("about:blank");
newwin.addEventListener("load", function (evt)
{
newwin.document.body.innerHTML = htmlCode;
}, false);
Код javascript | Выделить |
var newwin = open("about:blank");
newwin.document.write(htmlCode);
newwin.document.close();
Модальные диалоги и наблюдатели
Открытие нового окна в режиме диалога осуществляется либо с помощью функции openDialog, либо open, но в параметрах надо указать, что это диалог. Для того, чтобы сделать окно модальным, следует в параметрах указать modal. Подробно о параметрах open можно прочитать здесь
Window.open() - Web APIs | MDN
Для того, чтобы загрузить окно из файловой системы, можно так же как и с окном вывода данных просто сохранить его код во временный файл и загрузить оттуда. Делается это так же, только окно открывается как модальный диалог.
Код javascript | Выделить |
openDialog(tempFileName, dialogName, "chrome,centerscreen,modal,width=500,height=300");
А вот для того, чтобы сделать то же самое, ничего не сохраняя в файловую систему, а просто загрузив about:blank и сформировав содержимое в уже открытом окне, придется немножко "поколдовать". Проблема модального окна в том, что весь код, написанный после вызова open или openDialog, выполняться не будет пока окно не будет закрыто, а стало быть в этой области нет никакого смысла писать код, генерирующий содержимое окна.
Пролить свет на то, как можно генерировать содержимое модального окна "на лету" нам помогут следующие топики документации
nsIObserverService - Mozilla | MDN
nsIObserver - Mozilla | MDN
Observer Notifications | MDN
Для того, чтобы выполнить код во вновь появившемся окне мы создадим наблюдателя. Наблюдатель - это объект, содержащий метод observe, как описано здесь
nsIObserver - Mozilla | MDN. Кроме того, как показано в примере, полезно добавить в него методы для регистрации и разрегистрации наблюдателя. Регистрация заключается в создании экземпляра службы наблюдателей и передаче экземпляра наблюдателя
методу addOserver этой службы. Разрегистрация - в передаче этого же объекта методу removeObserver. Кроме того, нам потребуется передать аргумент параметру aTopic, это строка, указывающая какое именно глобальное событие мы хотим отслеживать. Список системных событий можно найти здесь Observer Notifications | MDN. Нас интересует toplevel-window-ready из этого списка. Таким образом шаблон нашего наблюдателя будет выглядеть так
Код javascript | Выделить |
var observer =
{
observe: function (subject, topic, data)
{
// Здесь код
обработки
},
register: function ()
{
var observerService = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
observerService.addObserver(this, "toplevel-window-ready",
false);
},
unregister: function ()
{
var observerService = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
observerService.removeObserver(this, "toplevel-window-ready");
}
}
Теперь создадим код нашего диалогового окна.
Код HTML | Выделить |
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8"
/>
<title>Пример
модального диалога</title>
</head>
<body>
<table>
<tr>
<td>Текст
1</td>
<td><input
type="text" id="txt1"
/></td>
</tr>
<tr>
<td>Текст
2</td>
<td><input
type="text" id="txt2"
/></td>
</tr>
</table>
<button id="btnReady">Готово</button>
<script>
var args = window.arguments[0];
document.getElementById("txt1").value = args.text1;
document.getElementById("txt2").value = args.text2;
document.getElementById("btnReady").addEventListener("click",
function (evt)
{
args.text1 = document.getElementById("txt1").value;
args.text2 = document.getElementById("txt2").value;
close();
}, false);
</script>
</body>
</html>
Код javascript | Выделить |
gClipboard.write(JSON.stringify(gClipboard.read()));
Функция преобразования текста в js-строку есть в некоторых редакторах кода или расширениях к ним, так что можно просто воспользоваться готовым инструментом.
Теперь собственно код кнопки, использующей это окно
Код javascript | Выделить |
/*CODE*/
var dlg = "<!DOCTYPE html>\n\n<html lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n <meta charset=\"utf-8\" />\n <title>Пример модального диалога</title>\n</head>\n<body>\n <table>\n <tr>\n <td>Текст 1</td>\n
<td><input type=\"text\" id=\"txt1\" /></td>\n </tr>\n <tr>\n <td>Текст 2</td>\n <td><input type=\"text\" id=\"txt2\" /></td>\n </tr>\n </table>\n <button id=\"btnReady\">Готово</button>\n <script>\n var args = window.arguments[0];\n document.getElementById(\"txt1\").value =
args.text1;\n document.getElementById(\"txt2\").value = args.text2;\n document.getElementById(\"btnReady\").addEventListener(\"click\", function (evt)\n {\n args.text1 = document.getElementById(\"txt1\").value;\n args.text2 = document.getElementById(\"txt2\").value;\n close();\n }, false);\n\n </script>\n</body>\n</html>";
var observer =
{
observe: function (subject, topic, data)
{
if (subject.name == "myTestDialog")
{
subject.document.write(dlg);
subject.document.close();
}
},
register: function ()
{
var observerService = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
observerService.addObserver(this, "toplevel-window-ready",
false);
},
unregister: function ()
{
var observerService = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
observerService.removeObserver(this, "toplevel-window-ready");
}
}
observer.register();
var args = { text1: "Текст
первого поля", text2:
"Текст второго
поля" };
openDialog("about:blank", "myTestDialog",
"chrome,centerscreen,modal,width=300,height=200", args);
observer.unregister();
alert("Текст 1: " + args.text1 + "\nТекст 2: " + args.text2);
Учитывая предварительные объяснения, думаю, разобраться в этом коде будет несложно.
Вопросы работы с окнами из хром-кода неплохо освещены в следующей статье документации
Working with windows in chrome code | MDN
Комментариев нет :
Отправить комментарий