AString get_string (in AString stri); => NS_IMETHOD get_string(const nsAString & stri, nsAString & _retval);
https://developer.mozilla.org/en/XPCOM_string_guide
Elexander, подскажи пожалуйста, как заставить правильно работать диалоговые окна TGeckoBrowser под делфей.
...
в какую сторону копать?
Хотел бы помочь, но не знаю как. TGeckoBrowser, к сожалению, никогда не использовал.
как правильно изменить путь к папке GRE\xpcom.dll?
пробовал вставочку сделать '\browser', но появляются побочные глюки, пропадают скролбары и поля ввода на страницах
Я не использовал встроенный Gecko в своих приложениях. При разработке XPCOM-компонентов для расширений не нужно ничего вручную инициализировать. Все уже приготовлено броузером, поэтому тут ничем помочь не могу.
Если стоит задача использовать в приложении на Delphi движок рендеринга HTML отличный от IE-шного, то советую посмотреть на WebKit.
http://code.google.com/p/delphichromiumembedded/
http://code.google.com/p/chromiumembedded/
привет Elexander, вопрос такой, у меня 1.7.12 gecko SDK портированный на Делфи, но встретился с такой проблемой, при отображении некоторых сайтов, мигает текст на странице, как будто стоит атрибут у текста blink, но его там нет. в новых версиях gecko такого нет. незнаеш как побороть глюк? может есть где скачать более свежую SDK ? никто не переводил 1.9.х ? незнаеш?
спасибо
Не понял вопрос. Если мигает текст, при чем здесь SDK?
Интерфейсы для новых версий Geckо генерируются с idl файлов. Компилятор я вам выслал.
IsokHtmlElement - это синоним IInterface. По сути это объект документной модели который поддерживает nsIDOMNode. В коде дальше у него просится этот интерфейс и работа ведется уже с ним.
IID_nsIDOMNSRange_190, IID_nsIDOMNSRange_181 - это TGUID-ы для соответствующих интерфейсов для разных версий Gecko (1.9.0 и 1.8.1). Mozilla делает одну странность: они в разных версиях меняют guid-ы своих интерфейсов, хотя сами интерфейсы оставляют без изменений. Иными словами, если вам нужно получить интерфейс у объекта по глобальному идентификатору, то нужно знать в какой версии gecko вы работаете (какая версия firefox). Если хотите, чтобы компонент работал в разных версиях gecko нужно делать вот такие некрасивые проверки, как в той функции.
NS_ERROR() - это функция которая проверяет NS_FAILED() и если результат положительный (nsResult <> 0) генерирует исключение.
К фреймовой структуре доступ получается приблизительно так:
[code]
element = document.getElementsByTagName('iframe')[0]
doc = el
Я при использовании Gecko за основу брал http://d-gecko.svn.sourceforge.net/viewvc/d-gecko/trunk/?pathrev=17.
Все интерфейсы, которые в нем не были описаны генерировал с idl файлов с помощью xpidl2pas компилятора. Его можно было когда-то найти в проекте Dino, который сейчас мертв. Если вам нужен только этот интерфейс, то вот:
nsIDOMNSRange = interface(nsISupports) ['{59188642-23B4-41D6-BDE1-302C3906D1F0}'] function CreateContextualFragment(const fragment: nsAString; var _retval: nsIDOMDocumentFragment): nsResult; stdcall; function IsPointInRange(parent: nsIDOMNode; offset: Integer; var _retval: LongBool): nsResult; stdcall; function ComparePoint(parent: nsIDOMNode; offset: Integer; var _retval: Smallint): nsResult; stdcall; end;
Если нужен компилятор xpidl2pas, могу выслать на почту.
…Пришлите исходники вашего XPCOM компонента мне на почту, я посмотрю на выходных. Только удалите все лишнее. Оставте только проблемное место. И еще pas-файлы вашего Gecko SDK, может быть в нем проблема.
elexander [at] ukr.net
GUID на 3.0.5 меняли? Я забыл указать ваш. Этот для 3.6
Интерфейс такой, проверте.
[code]nsIDOMNSElement = interface(nsISupports)
['{C9BA11BC-32D4-425E-A91F-7E0939C39251}']
function GetElementsByClassName(const classes: nsAString; var _retval: nsIDOMNodeList): HRESULT; stdcall;
function GetClientRects(var _retval: nsIDOMClientRectList): HRESULT; stdcall;
function GetBoundingClientRect(var _retval: nsIDOMClientRect): HRESULT; stdcall;
function GetScrollTop(out aScrollTop: Integer): HRESULT; stdcall;
function SetScrollTop(aScrollTop: Integer): HRESULT; stdcall;
function GetScrollLeft(out aScrollLeft: Integer): HRESULT; stdcall;
function SetScrollLeft(aScrollLeft: Integer): HRESULT; stdcall;
function GetScrollHeight(out aScrollHeight: Integer): HRESULT; stdcall;
function GetScrollWidth(out aScrollWidth: Integer): HRESULT; stdcall;
function GetClientTop(out aClientTop: Integer): HRESULT; stdcall;
function GetClientLeft(out aClientLeft: Integer): HRESULT; stdcall;
function GetClientHeight(out a
Может быть GUID неправильный. В 3.6 для nsIDOMNSElement {C9BA11BC-32D4-425E-A91F-7E0939C39251}
В 3.0.5 можно проверить с помощью XPCOMViewer.
В vr2 теперь поидее содержится массив объектов,но как с ним работаь, например, чтобы узнать размер массива?
Тут все аналогично.
length - свойство объекта-массива (получить можно через NPN_GetProperty)
items(i) - метод с одним параметром (через вызов NPN_Invoke)
Правильно ли я понимаю, что это будет совместимо только с ff ? Например, для Chrome работать не будет?
Нет. Все браузеры за исключением IE поддерживают технологию NPRuntime.
Приблизительный код на Delphi:
function GetElementByID(id: string): PNPObject; var window: PNPObject; vr1, vr2: TNPVariant; begin NPP_GetValue(Instance, NPNV_WINDOW_NPOBJECT, @window); NPN_GetProperty(Instance, window, NPN_GetStringIdentifier('document'), @vr1); STRINGZ_TO_NPVARIANT(id, vr2); NPN_Invoke(GetInstance, vr1.objectValue, NPN_GetStringIdentifier('getElementById'), @vr2, 1, vr1); Result := vr1.objectValue; end;
Только нужно не забыть освободить объект после использования.
…Elexander
Я так понимаю через createElement и innerHTML? Почему-то не выходит.
var script = "<script>alert('');</script>"; var range = document.createRange(); range.selectNode(document.getElementsByTagName("div").item(0)); var documentFragment = range.createContextualFragment(script); document.body.appendChild(documentFragment);
Посмотреть на nsIWebBrowser.contentDOMWindow.document.tagName, должен быть 'html'. Ну или еще по каким то свойствам пройтись.
Скажите возможно ли из расширения вызывать метод из JS, который находится на конкретной странице?
Возможно. Вставьте скрипт (<srcipt>...</script>) в страницу, он сразу исполнится.
Мне сложно что-то посоветовать, потому что я подключаю перехватчик прогресса по другому. Я передаю свой nsIWebProgressListener экземпляру nsIWebProgress. Это поле webProgress в browser. А browser получаю так:
browser = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsIDocShellTreeItem) .rootTreeItem .QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindow).getBrowser();
У меня были проблемы с получением browser в XPCOM, по этому я его получаю в JavaScript и передаю в бинарный компонент ссылку. У каждой вкладки свой browser. Нужно реагировать на открытие новой вкладки и каждый раз подключаться. При закрытии, соответственно, отключаться. У вас, я так понял, какой-то универсальный метод, но я так не пробовал. Посоветовать нечего.
…Объект должен реализовывать кроме nsIWebProgressListener еще nsISupportsWeakReference и nsIWeakReference, в методах которых возвращать себя же.
Вот, если интерестно, реализация InsertAdjacentHTML для Firefox. Правда на Delphi. Но вы, я думаю, разберетесь.
[code]
procedure InsertAdjacentHTML(Element: IsokHtmlElement; Where: TsokWhereInsert; Html: sokWideString);
var
doc: nsIDOMDocument;
docRange: nsIDOMDocumentRange;
range: nsIDOMRange;
nsRange: nsIDOMNSRange;
fragment: nsIDOMDocumentFragment;
node, parent, child, retval: nsIDOMNode;
rv: nsResult;
begin
try
if not Assigned(Element) then
Exit;
Element.QueryInterface(IID_nsIDOMNode, node);
if not Assigned(node) then
Exit;
NS_ERROR(node.GetOwnerDocument(doc));
if not Assigned(doc) then
Exit;
doc.QueryInterface(NS_IDOMDOCUMENTRANGE_IID, docRange);
if not Assigned(docRange) then
Exit;
range := docRange.CreateRange;
if not Assigned(range) then
Exit;
rv := range.SelectNode(node);
if NS_FAILED(rv) then
begin
NS_ERROR(node.GetParentNode(parent));
NS_ERROR(rv);
end;
if range.QueryInterface(IID_nsIDOMNSRange_
…Есть такой nsIDOMSerializer. Он принимает nsIDOMNode и возвращает в виде текста html-содержимое элемента. Попробуйте nsIDOMHTMLDocument привести к nsIDOMNode, ну или получить DocumentElement через nsIDOMDocument.
Скорей всего, нет. По причинам безопасности. Убедитесь: откройте консоль ошибок и кликните по такой ссылке.
У вас несколько выходов: можно реализовать поддержку своего протокола, можно воспользоваться описаным выше. Еще можно ставить ссылку, а в onclick javascript-ом передавать сообщение расширению. Или можно поставить перехватчик nsIWebProgressListener и для нужных ссылок обрывать навигацию и показывать диалог.
У ссылки (<a/>) убрать href, чтобы браузер не совершал лишних движений. И подписаться на mousedown. В обработчике показать xul-диалог или свой собственный через вызов XPCOM. Если ссылку добавляете вы, проблем быть не должно.
Мы с вами не знакомы, так что давайте "на вы".
Примера нет. Но если приведете минимальный код в котором наблюдается падение, может еще чем-то смогу помочь.
Вот еще: http://groups.google.ru/group/netscape. … um=3&pli=1. Там с примером и детально.
Вероятно, contentDocument - это XBL-свойство sidebar. В таком случае я бы вызывал JavaScript из XPCOM. Для этого нужно реализоть на JS объект со всем необходимым функционалом и передать ссылку на него в XPCOM-компонент.
JavaScript:
var CallbackObject = { getSidebarURL: function() { return sidebar.contentDocument.location.href; } } var Component = Components.classes["@example.com/component;1"] .createInstance().QueryInterface(Components.interfaces.IMyInterface); Component.setCallback(CallbackObject);
IDL:
[scriptable, uuid(8CECF414-495D-48FF-BEC4-F4ED2809AAEC)] interface ICallbackObject : nsISupports { AString getSidebarURL(); }; [scriptable, uuid(90758A97-A6F3-4ea4-8953-16BD2EE3A977)] interface IMyInterface : nsISupports { void setCallback(in ICallbackObject aCallback); };
После вызова setCallback в компоненте можна запоминать и использовать интерфейс ICallbackObject.
…Попробуйте через QueryInterface попросить у sidebar один из этих интерфейсов.
Только в них есть свойство contentDocument.
А что мешает явно запросить интерфейс в инициализации расширения и сохранить в глобальной переменной?