Здравствуйте. Я только начинаю разбираться с расширениями для firefox, и прошу совета.
Есть такая задача: нужно из расширения открыть в нескольких табах страницы, подождать пока они загрузятся, обработать (получить url по которому загрузилось) и начать грузить следующую порцию страниц. Как отловить событие окончания загрузики страницы для конктерного таба? Как поставить каждому табу в соответствие event listener, таким образом чтобы из него можно было узнать в каком табе страница загрузилась?
Какие классы и методы надо использовать чтобы решить задачку?
Большое спасибо.

Elena пишет

Здравствуйте. Я только начинаю разбираться с расширениями для firefox, и прошу совета.
Есть такая задача: нужно из расширения открыть в нескольких табах страницы, подождать пока они загрузятся, обработать (получить url по которому загрузилось) и начать грузить следующую порцию страниц. Как отловить событие окончания загрузики страницы для конктерного таба? Как поставить каждому табу в соответствие event listener, таким образом чтобы из него можно было узнать в каком табе страница загрузилась?
Какие классы и методы надо использовать чтобы решить задачку?
Большое спасибо.

Выделить код

Код:

var progressListener=
{
    QueryInterface: function (aIID)
    {
        if (aIID. equals (Components. interfaces. nsIWebProgressListener) ||
            aIID. equals (Components. interfaces. nsISupportsWeakReference) ||
            aIID. equals (Components. interfaces. nsIXULBrowserWindow) ||
            aIID. equals (Components. interfaces. nsISupports))
            return this;
        throw Components. results. NS_NOINTERFACE;
    },
onLocationChange:function (a,b,c){},
onProgressChange:function(a,b,c,d,e,f){},
onSecurityChange:function(a,b,c){},
onStateChange:function(a,b,c,d){},
onStatusChange:function(a,b,c,d){}
};
var res = "http://ya.ru";
var tab = getBrowser().addTab(res);
var br = window.getBrowser().getBrowserForTab(tab);
br.addProgressListener(progressListener);

Copyright © Anton :)

для того, чтобы узнать об окончании загрузки нужно проверять флаги в OnStateChange (3й аргумент).
По окончании загрузки приходят флаги STOP и NETWORK:

Выделить код

Код:

const STATE_STOP = Components. interfaces. nsIWebProgressListener.STATE_STOP;
const STATE_NETWORK = Components.interfaces.nsIWebProgressListener.STATE_IS_NETWORK;
.......................

onStateChange:function(a,b,stateFlags,d){

var STOP = (stateFlags & STATE_STOP) != 0;
var NETWORK = (stateFlags & STATE_NETWORK) != 0;

  if (STOP && NETWORK)
  {
     //загрузка закончена
  }
}

но эти же флаги приходят когда загрузка остановлена (польз-ль нажал на стоп, дисконнект). Чтобы узнать, загрузилась ли страница полностью, можно проверять значения 3го и 4го аргумента метода OnProgressChange (curSelfProgress и maxSelfProgress). Если равны - страница загружена полностью :)

Ну вот, пока писал ответ, уже ответить успели... :sick:

Большое спасибо. Работает.
Можно ли как-нибудь из обработчика события узнать в каком табе загрузилась страница?
Т.е. если делать так:

Выделить код

Код:

for(var i=1; i<=10; i++){
           var tab = getBrowser().addTab(res);
           var br = window.getBrowser().getBrowserForTab(tab);
           br.addProgressListener(progressListener);
}

то ведь обработчик будет зарегистрирован только для последнего таба. можно ли какнибудь соотнести обработчик и таб из которого пришло событие?

Elena пишет

...можно ли какнибудь соотнести обработчик и таб из которого пришло событие?

Что если соорудить класс

Выделить код

Код:

function progressListener (id)
{
    this. id = id;
}
progressListener. prototype. QueryInterface = function (aIID)
{
    ...

...

    br. addProgressListener (new progressListener (i))
...

?


cesspit пишет

...Copyright © Anton...

не, не мой, это из расширения extended statusbar

Что если соорудить класс

Попробовала написать так:

Выделить код

Код:

function progressListener (id)
{
    this. id = id;
}
progressListener. prototype.QueryInterface=function(aIID)
{
	
 	if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
	    aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
	    aIID.equals(Components.interfaces.nsIXULBrowserWindow) ||
	    aIID.equals(Components.interfaces.nsISupports))
		return this;
	throw Components.results.NS_NOINTERFACE;
}

progressListener.prototype={
	onStateChange: function(...){...},
...
}

Скорее всего где-то не правильно из-за моего слабого знания javascript, т.к. не работает и похоже из-за ошибки:

Выделить код

Код:

Error: [Exception... "Component returned failure code: 0x80070057 (NS_ERROR_ILLEGAL_VALUE) [nsIWebProgress.addProgressListener]"  nsresult: "0x80070057 (NS_ERROR_ILLEGAL_VALUE)"  location: "JS frame :: chrome://global/content/bindings/browser.xml :: addProgressListener :: line 346"  data: no]
Source File: chrome://global/content/bindings/browser.xml
Line: 346

Elena

...
Попробовала написать так:
...

Сначала вы определяете в прототипе функцию QueryInterface, а потом полностью "перекрываете" прототип конструкцией

Выделить код

Код:

progressListener.prototype={
	onStateChange: function(...){...},
...
}

после чего в прототипе progressListener'а уже нет определения QueryInterface, отсюда и ошибка.
Используйте один метод для определения функций - т. е., или

Выделить код

Код:

function progressListener (arglist) { ... }
progressListener. prototype. QueryInterface = function (aIID) { ... }
progressListener. prototype. onStateChange = function (arglist) { ... }
...

или

Выделить код

Код:

function progressListener (arglist) { ... }
progressListener. prototype = {
    QueryInterface: function (arglist) { ... },
    onStateChange: function (arglist) { ... },
    ...
}

или (без prototype)

Выделить код

Код:

function progressListener (id)
{
    this. id = id;
    this. QueryInterface = function (aIID) { ... }
    this. onStateChange = function (arglist) { ... }
    ...
}

Сначала вы определяете в прототипе функцию QueryInterface, а потом полностью "перекрываете" прототип конструкцией

Большое спасибо за разъяснения! Буду делать.
Еще такой вопрос: можно ли как-нибудь связать nsIHTTPChannel с табом? мне надо чтобы можно было поймать ответ от сервера предназначенный конкретному табу...

А кто мне пояснит, почему для text/html onProgressChange вызывается, а для "text/plain" нет?
А также для "application/x-unknown-content-type" тоже не вызывается, что не позволяет мерять размер картинки, загруженной из кеша?
Второе, что мне непонятно: для html страницы onProgressChange вызывается даже если она грузится из кеша...
Extended Status Bar не показывет точный размер страницы и всех ее изображений.
Более-менее справляется lori, но тоже как-то странно.