Thunderbird extensions

advertisement
Thunderbird extensions
Weishin Pan
2010/08/26
OutLine
•
•
•
•
Introduction
XPCOM
Demo
Reference
2
Introduction
• XUL (XML User Interface Language)
Mozilla以XML為基礎所發展的語言,用來描述用戶介面
• CSS (Cascading Style Sheets)
使用者自定規則來控制HTML/XUL/XML所產生的介面外觀,背景,字型
• DOM(Document Object Model)
給予HTML與XML所使用的API,可以用來連結JavaScript或其他的程式語言與網頁
3
• XPConnect
將XPCOM與JavaScript連接起來的技術
• XBL (Extensible Binding Language)
一種標記語言,應用於各個XUL應用程式當中
• RDF (Resource Definition Framework)
透過這個格式來存放Extension的註冊訊息與描述資訊
• JavaScript
開發extension的核心語言,這種腳本語言的特色為其原始碼在送到用戶端前不須經過編
譯,而是透過Browser來解釋其字元代碼並執行
• XPInstall
Mozilla 的跨平台安裝技術,提供了一個標準的方式將 XUL 應用程式的各個元件包裝成安
裝檔,讓 Mozilla users 可以下載並且安裝執行,以 XPI 格式為標準。XPI 的格式同 ZIP 及
JAR,為 PKZIP 壓縮後的檔案,只是內含可供管理安裝方式的腳本
4
XPCOM
(Cross-platform Component Object Model)
• 它是個用來撰寫跨平台與軟體模組化的一種架構,有自身的
API,定義著所提供的核心元件,介面與函式,與Microsoft所推
出的COM( Common Object Model)屬相同性質,透過介面
(Interface)的概念,來解決不同階段所開發的Components在
相容性問題以及系統的需求
• 透過XPIDL(Interface Description Language)的定義可使其
XPCOM物件可使用C、C++ 和 JavaScript 來創造,也可以在
C、C++、JavaScript、Python、與 Perl 擴充集的環境下來進
行開發
5
Mozilla application model
User Interface layer
Glue layer
XPCOM layer
6
XPconnect
• XPConnect 建立XPCOM物件 與 JavaScript 之
間的溝通
• XPConnect 允許 JavaScript 物件存取與運用
XPCOM 物件,也能使 JavaScript 物件可以表
示成 XPCOM 相容介面以供 XPCOM 物件呼
叫使用
7
http://m-alexandre.developpez.com/articles/xul/presentation/#note2
8
Environment
OS : Windows XP SP3
MUA : Thunderbird2 (v2.0.0.9)
(Win32) ftp://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/2.0.0.9/win32/en-US/Thunderbird%20Setup%202.0.0.9.exe
(Source) ftp://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/2.0.0.9/source/thunderbird-2.0.0.9-source.tar.bz2
SDK: gecko-sdk-i586-pc-msvc-1.8b1
http://ftp.mozilla.org/pub/mozilla.org/mozilla/releases/mozilla1.8b1/gecko-sdk-i586-pc-msvc-1.8b1.zip
Mozilla builder
http://ftp.mozilla.org/pub/mozilla.org/mozilla/libraries/win32/MozillaBuildSetup-Latest.exe
IDE:
Visual studio 2005
9
Hello world
•
helloworld/
chrome.manifest -> Tells thunderbird where your chrome files(UI) are and what to do with them
install.rdf
-> The description file for your extension ("Install manifest")
helloworld.xpi
-> Installing package
chrome/
helloworld.jar/
content/
contents.rdf
-> The information file for package and overlay
overlay.js
-> The file with scripts to run in the browser window
overlay.xul
-> The file describing UI elements to add to the browser window
10
Chrome.manifest
overlay
content
chrome://messenger/content/mailWindowOverlay.xul
chrome://helloworld/content/overlay.xul
helloworld
jar:chrome/helloworld.jar!/content/
11
Install.rdf
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>{241b5bc7-a8aa-44a6-a18d-3054dc6047cf}</em:id>
<em:name>Hello World</em:name>
<em:version>1.0</em:version>
<em:type>2</em:type>
<em:creator>Weishin Pan</em:creator>
<em:description>The classical demo with "Hello, world!"</em:description>
<em:homepageURL>http://kb.mozillazine.org/Getting_started_with_extension_development</em:homepa
geURL>
<em:targetApplication>
<!-- Thunderbird -->
<Description>
<em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
<em:minVersion>2.0</em:minVersion>
<em:maxVersion>2.0.0.*</em:maxVersion>
</Description>
</em:targetApplication>
<!-- This is not needed for Firefox 1.1 and later. Only include this
if you want to make your extension compatible with older versions -->
<em:file>
<Description about="urn:mozilla:extension:file:helloworld.jar">
<em:package>content/</em:package>
</Description>
</em:file>
</Description>
</RDF>
12
Contents.rdf
<?xml version="1.0"?>
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
<RDF:Seq about="urn:mozilla:package:root">
<RDF:li resource="urn:mozilla:package:helloworld"/>
</RDF:Seq>
<!-- package information -->
<RDF:Description RDF:about="urn:mozilla:package:helloworld"
chrome:name="helloworld"
chrome:extension="true"
chrome:displayName="Hello World"
chrome:author="Lewis Lv"
chrome:authorURL="http://kb.mozillazine.org/Getting_started_with_extension_development"
chrome:description="The Classical Demo With Hello World">
</RDF:Description>
<!-- overlay information -->
<RDF:Seq about="urn:mozilla:overlays">
<RDF:li resource="chrome://messenger/content/mailWindowOverlay.xul"/>
</RDF:Seq>
<RDF:Seq about="chrome://messenger/content/mailWindowOverlay.xul">
<RDF:li>chrome://helloworld/content/overlay.xul</RDF:li>
</RDF:Seq>
</RDF:RDF>
13
Overlay.js
// This is the main function
function helloWorld()
{
alert(“Hello world");
}
14
Overlay.xul
<?xml version="1.0"?>
<overlay id="helloworld-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript" src="overlay.js"/>
<menubar id="mail-menubar">
<menu id="MyAboutMenu" label="Test" insertbefore="tasksMenu">
<menupopup id="menu_TestAbout">
<menuitem id="helloworld-hello" label="Hello, world!"
oncommand="helloWorld();"/>
</menupopup>
</menu>
</menubar>
</overlay>
15
helloworld.xpi
• 壓縮 content資料夾成helloworld.zip,接著更改檔案類型為
.jar
• 接著將chrome資料夾以及chrome.manifest,install.rdf壓縮成
helloworld.zip,街著將檔案類型改成.xpi以進行後續的安裝
16
Installation
開啟thunderbird,”Tools” -> “Add-ons” -> “Install …” -> 選擇套件目錄 -> 選擇xxx.xpi來進行安裝
-> 安裝成功後,重新開啟thunderbird -> 在工作列上可以看到 “test”的項目 -> 點選執行
17
18
Hello world (2)
• Implantation an add() function for thunderbird
•
helloworld/
chrome.manifest -> Tells thunderbird where your chrome files(UI) are and what to do with
them
install.rdf
-> The description file for your extension ("Install manifest")
install.js
-> Register the package
helloworld.xpi
-> Installing package
chrome/
helloworld.jar/
content/
contents.rdf
-> The information file for package and overlay
overlay.js
-> The file with scripts to run in the browser window
overlay.xul
-> The file describing UI elements to add to the browser window
components/
helloworld.dll
-> C++ Source code contains add() function
IMycomponent.xpt -> IDL in binary code
19
開發環境設定
1.
Copy C:\mozilla-build\moztools-180compat\bin\ libIDL-0.6.dll and glib1.2.dll
2. To \gecko-sdk-i586-pc-msvc-1.8b1\gecko-sdk\bin
20
3. Create \gecko-sdk-i586-pc-msvc-1.8b1\gecko-sdk\bin\Imycomponent.idl
#include "nsISupports.idl"
[scriptable, uuid(b7b04070-45fc -4635- b219-7a172f806bee)]
interface IMyComponent : nsISupports
{
long Add(in long a, in long b);
};
4. Open visual studio 2005 -> “Tools” -> 建立GUID
21
XPCOM Component
22
• 在COM的IUnknown和XPCOM的nsISupports interface,它們的
基本目的是一樣的,要求所有的Component都應該實作
IUnknown/nsISupports interface, 接著user可以透過
QueryInterface()這個函式來得知這個Component是否支援”
某個版本的介面”的資訊
// For M$ COM
interface IUnknown
{
virtual HRESULT QueryInterface(REFIID riid, void **ppvObject) = 0;
virtual ULONG AddRef(void) = 0;
virtual ULONG Release(void) = 0;
};
// For XPCOM
interface nsISupports
{
void QueryInterface(in nsIIDRef uuid, out nsQIResult result);
nsrefcnt AddRef();
nsrefcnt Release();
};
23
5. Add Gecko-sdk path to windows PATH
PATH -> …;\gecko-sdk-i586-pc-msvc-1.8b1\gecko-sdk\bin;\gecko-sdk-i586-pc-msvc-1.8b1\geckosdk\idl;\gecko-sdk-i586-pc-msvc-1.8b1\gecko-sdk\include;
6. Execute Xpidl.exe in command line(CMD)
xpidl -m header -I ..\idl IMyComponent.idl
xpidl -m typelib -I ..\idl IMyComponent.idl
-> Create IMyComponent.h
-> Create IMyComponent.xpt
24
7.
Create a VC project for .dll (helloworld) and set the
properties
1. c/c++ -> General Additional Include Directories add ->
\gecko-sdk-i586-pc-msvc-1.8b1\gecko-sdk\include
2. c/c++ -> Preprocessor -> Preprocessor Definitions add ->
MYCOMPONENT_EXPORTS,XPCOM_GLUE
3. c/c++ -> Code Generation Runtime Library ->
Multi-threaded DLL (/MD)
4. Linker-> Additional Liberary Directoryse add ->
\gecko-sdk-i586-pc-msvc-1.8b1\gecko-sdk\lib
5. Linker-> Additional Depenendies add ->
nspr4.lib plds4.lib plc4.lib xpcomglue.lib
6. Build in “Release” mode
25
/* MyComponent.h*/
#pragma once
#ifndef _MY_COMPONENT_H_
#define _MY_COMPONENT_H_
#include "IMyComponent.h"
#define MY_COMPONENT_CONTRACTID
"@mydomain.com/XPCOMSample/MyComponent;1"
#define MY_COMPONENT_CLASSNAME "A Simple XPCOM Sample"
#define MY_COMPONENT_CID {0xb7b04070, 0x45fc, 0x4635,{ 0xb2, 0x19, 0x7a,
0x17, 0x2f, 0x80, 0x6b, 0xee } }
class MyComponent:public IMyComponent
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IMYCOMPONENT
MyComponent(void);
~MyComponent(void);
};
#endif
26
/* MyComponent.cpp*/
#include "StdAfx.h"
#include "MyComponent.h"
NS_IMPL_ISUPPORTS1(MyComponent, IMyComponent)
MyComponent::MyComponent(void)
{
}
MyComponent::~MyComponent(void)
{
}
NS_IMETHODIMP MyComponent::Add(PRInt32 a, PRInt32 b, PRInt32
*_retval)
{
*_retval = a + b;
return NS_OK;
}
27
/* MyComponentModule.cpp*/
#include "StdAfx.h"
#include "nsIGenericFactory.h"
#include "MyComponent.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(MyComponent)
static nsModuleComponentInfo components[] =
{
{
MY_COMPONENT_CLASSNAME,
MY_COMPONENT_CID,
MY_COMPONENT_CONTRACTID,
MyComponentConstructor,
}
};
NS_IMPL_NSGETMODULE("MyComponentsModule", components)
28
7.
Generate a helloworld.dll
8.
Add helloworld.dll and IMyComponent.xpi to
dictionary “components”
29
Install.js
// Install script for helloworld
var err;
const APP_VERSION="0.0.0.1";// Version
//Initiation
err = initInstall("helloworld"+APP_VERSION, // name for install UI
"/helloworld",
// registered name
APP_VERSION);
// package version
if(err!=0)
{// CancelInstall
cancelInstall(err);
}
//Standard dictionary
var fProgram = getFolder("Program");// root dictionary
var fChrome = getFolder("Chrome");//chrome dictionary
var fComponents = getFolder("Components");//components dictionary
// workaround for Mozilla 1.8a3 and newer, failing to register enigmime correctly
var delComps = [ "compreg.dat" ]; // Components registry
for (var j=0; j<delComps.length; j++)
{
var delFile = getFolder(fComponents, delComps[j]);
if (File.exists(delFile))
File.remove(delFile);
}
err = getLastError();
if (err == DOES_NOT_EXIST)
{
// error code: file does not exist
resetError();
}
else if (err != SUCCESS)
{
cancelInstall(err);
}
30
Install.js(2)
// addDirectory: blank, archive_dir, install_dir, install_subdir
addDirectory("", "components", fComponents, "");
addDirectory("", "chrome",
fChrome, "");
err = getLastError();
if (err == ACCESS_DENIED)
{
alert("Unable to write to components directory "+fComponents+".\n You will need to restart the browser
with administrator/root privileges to install this software. After installing as root (or administrator), you will
need to restart the browser one more time, as a privileged user, to register the installed software.\n After the
second restart, you can go back to running the browser without privileges!");
cancelInstall(ACCESS_DENIED);
}
else if (err != SUCCESS)
{
cancelInstall(err);
}
else
{
// Register chrome
registerChrome(PACKAGE | DELAYED_CHROME, getFolder("Chrome","helloworld.jar"),
"content/helloworld/");
err = getLastError();
if (err != SUCCESS)
{
cancelInstall(err);
}
else
{
performInstall();
}
}
31
overlay.js
const PHINECOS_C = Components;
const PHINECOS_HELLOWORLD_CONTRACTID = "@mydomain.com/XPCOMSample/MyComponent;1"
var gHelloWorldSvc = null;
// This is the main function
function helloWorld()
{
try
{
alert("Component Installing");
gHelloWorldSvc =
PHINECOS_C.classes[PHINECOS_HELLOWORLD_CONTRACTID].createInstance(PHINECOS_C.interfaces.IMyCo
mponent); //Instance
if(gHelloWorldSvc!=null)
{
alert("Success");
gHelloWorldSvc = gHelloWorldSvc.QueryInterface(PHINECOS_C.interfaces.IMyComponent);
}
else
{
alert("Fail");
return;
}
var res = gHelloWorldSvc.Add(6, 2);
alert('Performing 6+2. Returned ' + res + '.');
alert("Exit");
}
catch(ex)
{
alert("error");
}
}
32
helloworld.xpi
• 壓縮 content資料夾成helloworld.zip,接著更改檔案類型為.jar
• 接著將chrome和components資料夾以及
chrome.manifest,install.rdf,install.js壓縮成helloworld.zip,接著將檔案類
型改成.xpi以進行後續的安裝
33
•
•
•
•
•
•
•
•
•
•
•
•
•
•
Reference
http://www.cnblogs.com/phinecos/archive/2008/04/25/1171614.html Thunderbird extension(1)
http://www.cnblogs.com/phinecos/archive/2008/04/21/1164466.html Thunderbird extension(2)
https://developer.mozilla.org/zh_tw/XPCOM Mozilla.org XPCOM
https://developer.mozilla.org/en/building_an_extension#XPCOM_Components
Create a XPCOM
https://developer.mozilla.org/en/Extensions/Thunderbird/Building_a_Thunderbird_extension Build thunderbird
http://starkravingfinkle.org/blog/2006/10/mozilla-platform-xpcom-in-c/ XPCOM in c++
http://www.csie.ntu.edu.tw/~piaip/docs/CreateMozApp/index.html E Books for Mozilla developer
http://www.cnblogs.com/chio/archive/2007/09/26/907245.html XPIDL
http://rintarou.dyndns.org/2010/05/02/why-common-object-model-com/#more-441 XPCOM & COM
http://blog.csdn.net/SystemBug/archive/2006/02/28/612053.aspx XPIDL
https://developer.mozilla.org/zh_tw/The_Joy_of_XUL XUL
http://hi.baidu.com/kinsonhe/blog/item/b39dbcefd2ad454379f0555a.html XPCOM
http://kb.mozillazine.org/Getting_started_with_extension_development extension development
ftp://ftp.mozilla.org/pub/ Mozilla resource
34
Download