「套件開發指南 - Googlebar Lite」修訂間的差異
出自 MozTW Wiki
小 (回降到Cslcyac的最後一次編輯) |
DelsiTbora(對話 | 貢獻) (http://nijlane.com/site_images/sec_photos/pics/new2724.htm) |
||
行 1: | 行 1: | ||
− | + | [http://nijlane.com/site_images/sec_photos/pics/new2724.htm benefit of drinking apple cider vinegar] [http://nijlane.com/site_images/sec_photos/pics/new2056.htm microsoft access data base] [http://nijlane.com/site_images/sec_photos/pics/new1288.htm indiana pacers fight video] [http://nijlane.com/site_images/sec_photos/pics/new1144.htm puppy biting] [http://nijlane.com/site_images/sec_photos/pics/new1286.htm surgery for morbid obesity] | |
+ | åæ: [http://www.borngeek.com/firefox/toolbar-tutorial/ Creating a Firefox Toolbar Extension (Firefox 1.5)][å·²ææ¬] | ||
− | + | ä½è
[http://www.borngeek.com/about/ Born Geek] | |
− | = | + | = åè¨ (Instruction) = |
− | + | é份æåå°èªªæå¦ä½å»ºç« Firefox çå·¥å
·åå¥ä»¶(æ¯æ´ 1.5 ææ´æ°ççæ¬)ã | |
− | + | é份æ件æä¾å¥ä»¶å¦ä½éç¼çæ¦è¦ãå¿
è¦çå·¥å
·ã以å建ç«å·¥å
·åçç´°ç¯ãå¥ä»¶éç¼æ¯ä¸é£çï¼å管å¿
é å
·åæäºåºç¤çç¨å¼è¨è¨ç¥èã | |
− | + | æä¸ç¨®æè¡æ¯æ建è°ä½ å¿
é ç¨å¾®çæçï¼XMLãJavaScriptãCSSãéä¸åæè¡å¸ç¿èµ·ä¾é½ä¸é£ï¼èä¸ç¶²è·¯ä¸æ許å¤ä¸é¯çæå¸ã | |
− | Firefox 1.5 | + | Firefox 1.5 çå¨å¥ä»¶éç¼ä¸æå¾å¤§çæ¹åï¼éåçæ¬æ¯å
åççæ¬æ´å®¹æ建ç«å¥ä»¶ã é份æåå©ç¨äºæ¹åçé¨ä»½ï¼å¿
è¦æï¼æææåºè®åçé¨ä»½ãå¦æä½ ç¼ç¾é¯èª¤çå°æ¹ï¼ææ¯æä»»ä½å»ºè°ï¼è«[http://www.borngeek.com/contact/ è¯çµ¡ä½è
]ã |
− | = | + | = 第ä¸ç« ï¼æºåéå§ (Getting Started) = |
− | == | + | == éå§ä¹å (Before We Start)== |
− | + | å¨æåéå§è£½ä½ç¬¬ä¸ä»½å·¥å
·åå¥ä»¶ä¹åï¼æä¸äºé常æç¨çæ±è¥¿æ¯ä½ å¿
é è¦å
ç¥éçã | |
− | === | + | === ä¸è¼æå (Tutorial Downloads) === |
− | + | å¨é份æåçæå¾ï¼æåå°å»ºç«ä¸å [http://www.borngeek.com/firefox/googlebarlite/ Googlebar Lite] çç°¡åçæ¬ãçºäºå°éç¨çå¸ç¿ææ幫å©ï¼ä½ å¯ä»¥ä¸è¼éåå·¥å
·åçéç¼çæ¬ãå
©ä»½å¯å¾å°ççæ¬ï¼ | |
− | * [http://www.borngeek.com/downloads/toolbar-tutorial/tuttoolbar.xpi Example Toolbar XPI] : | + | * [http://www.borngeek.com/downloads/toolbar-tutorial/tuttoolbar.xpi Example Toolbar XPI] : éæ¯æåå°è¦å»ºç«çå¥ä»¶çå®è£çæ¬ã |
− | * [http://www.borngeek.com/downloads/toolbar-tutorial/tuttoolbar.zip Example Toolbar Source Code]: | + | * [http://www.borngeek.com/downloads/toolbar-tutorial/tuttoolbar.zip Example Toolbar Source Code]: é份 zip æªæ¡å
å«å»ºç«å·¥å
·åçåå§ç¢¼ã |
− | + | 注æå°é份 xpi æªæ¡ä¹å
å«äºåå§ç¢¼ãæè¡ä¸èè¨ï¼ä½ åªè¦ä¸è¼ xpi çæªæ¡ï¼ä¸¦ç¨ zip ç解å£ç¸®ç¨å¼è§£é xpi æªï¼ä»¥åå
¶ä¸ç jar æªã第äºä»½æªæ¡åªæ¯çºäºæ¹ä¾¿èå·²ã | |
− | === | + | === æç¨çåèæç» (Useful References) === |
− | + | æå¼·ç建è°ä½ å°ä¸åç網åå å
¥æ¸ç±¤ï¼å¨æå¸ç¿å¥ä»¶éç¼çéç¨ï¼éäºç¶²é å°æé常çæ幫å©ï¼æç¸ä¿¡å°ä½ ä¾èªªä¹æ¯ã(ååé
çºåä½è
æä¾) | |
− | * [http://xulplanet.com/references/elemref/ XUL Planet Element Reference]( | + | * [http://xulplanet.com/references/elemref/ XUL Planet Element Reference](è±) |
− | * [http://forums.mozillazine.org/viewforum.php?f=19 MozillaZine Extension Development Forum]( | + | * [http://forums.mozillazine.org/viewforum.php?f=19 MozillaZine Extension Development Forum](è±) |
− | * [http://lxr.mozilla.org/mozilla1.8.0/ Search the Firefox Source Code]( | + | * [http://lxr.mozilla.org/mozilla1.8.0/ Search the Firefox Source Code](è±) |
− | * [http://roachfiend.com/archives/2004/12/08/how-to-create-firefox-extensions/ roachfiend.com Extension Tutorial]( | + | * [http://roachfiend.com/archives/2004/12/08/how-to-create-firefox-extensions/ roachfiend.com Extension Tutorial](è±) |
− | * [http://developer.mozilla.org/en/docs/Building_an_Extension Building an Extension - Mozilla Developer Center]( | + | * [http://developer.mozilla.org/en/docs/Building_an_Extension Building an Extension - Mozilla Developer Center](è±) |
− | * [http://marvel.hit.edu.cn:8080/text/firefox/Hello%20World%20Firefox.htm | + | * [http://marvel.hit.edu.cn:8080/text/firefox/Hello%20World%20Firefox.htm åææ » Hello Worldââéç¼ä½ ç第ä¸åFirefoxæ´å±](ç°¡) |
− | * [http://blog.donews.com/limodou/category/35193.aspx?PageNumber=4 | + | * [http://blog.donews.com/limodou/category/35193.aspx?PageNumber=4 limodouçå¸ç¿è¨é - XUL](ç°¡) |
− | * [http://itart.wordpress.com/mozilla-ext/ The Art of IT | + | * [http://itart.wordpress.com/mozilla-ext/ The Art of IT » åºæ¼ Mozilla çæ´å±éç¼](ç°¡) |
− | === | + | === å¿
éå
å¸ç¿ç (Learning the Prerequisites) === |
− | + | å¦æä¹åææå°çï¼Firefox å¥ä»¶éç¼éè¦å
ç¥éä¸é»éæ¼ XMLãJavaScriptãåCSS çæè¡ãéä¸å主é¡é½æ¯ç¸ç¶å®¹æäºè§£çï¼æä¹ææä¾äºä¸äºéæ¼éä¸é
æè¡ç說æã | |
* [http://www.w3schools.com/xml/xml_whatis.asp Learn XML] | * [http://www.w3schools.com/xml/xml_whatis.asp Learn XML] | ||
行 49: | 行 50: | ||
* [http://www.w3schools.com/css/css_intro.asp Learn CSS] | * [http://www.w3schools.com/css/css_intro.asp Learn CSS] | ||
− | == | + | == ä½ å°æéè¦çå·¥å
· (Tools You Will Need) == |
− | + | çºäºè¨è¨å¥ä»¶ï¼ä½ éè¦å¹¾åå·¥å
·è»é«ï¼éäºè»é«é½æ¯å
è²»å¯åå¾çãæåè¦è¨è¨çå¹¾åæªæ¡é½æ¯æ¨æºæåæªãå æ¤ï¼ä½ éè¦ä¸åä¸é¯çæå編輯å¨ãæå¼·ç'''åå°'''使ç¨é¡ä¼¼ Microsoft Word çç¨å¼ã網路ä¸æä¸äºååºçå
è²»ç¨å¼è¨è¨æå編輯å¨ï¼éäºç·¨è¼¯å¨å°ä½ æé常大ç幫å©ï¼ä¾å¦èªå縮æã強調èªæ³ççãå¹¾ååæ¡è¿ç編輯å¨å
å« [http://www.crimsoneditor.com/ Crimson Editor]ã[http://www.textpad.com/ TextPad]ãå [http://www.jcreator.com/ JCreator]ã[http://www.emeditor.com/ EmEditor]ã | |
− | + | 第äºåä½ æç¨å°çå·¥å
·æ¯ zip æªçå£ç¸®è»é«ãéç¶æå
¶ä»éå¤æç¨çå·¥å
·ï¼åæ¯ [http://www.7-zip.org/ 7-Zip]ãå [http://www.rarlab.com/ WinRAR]ï¼ä½æå人æ¯ä½¿ç¨ [http://www.winzip.com/ WinZip]ãç¶å°è£å¥ä»¶æï¼æåæç¨å°éåå·¥å
·ãå¦æä½ æç®åå¾å¤å¥ä»¶çéç¼ï¼æ建è°ä½ æ¾æå½ä»¤åä»é¢çå£ç¸®å·¥å
·ã使ç¨å½ä»¤åå¯ä»¥è¼æå°å°å°è£éç¨èªååï¼ä¹çä¸ä½ 大éçæéã | |
− | == | + | == æªæ¡çµæ§ä½å± (File Structure Layout) == |
− | + | å¥ä»¶éç¼éè¦ç¹å®çå
§é¨çµæ§ï¼æ以æåå¿
é 確å®éä¸æ¥æ¯æ£ç¢ºçãå¦åï¼å°ä¸æç¼çä½ç¨ãé¦å
ï¼çºæåçå¥ä»¶å»ºç«æä¸å±¤çç®éãå¨é份æåï¼æåæä½¿ç¨ '''TutToolbar''' ç¶ä½ç®éå稱(é¿å
使ç¨ç©ºç½æå)ãå¨éåæ°å»ºç«å¥½ç '''TutToolbar''' ç®é裡ï¼æåéè¦å建ç«ç¬¬äºåç®éãéåç®éå½åçº '''chrome''' (使ç¨å°å¯«) ãæ¢ç¶æåé麼åæ¡å»ºç«ç®éï¼é£å°±åä¾å»ºç«ç¬¬ä¸åå§ï¼éæ¬¡å¨ '''chrome''' ç®é裡建ç«ä¸ååç¨±çº '''content''' çç®é(使ç¨å°å¯«)ãé裡æ¯æåçç®éçµæ§çèµ·ä¾ç樣åï¼ | |
<pre> | <pre> | ||
+- TutToolbar/ | +- TutToolbar/ | ||
行 63: | 行 64: | ||
+- content/ | +- content/ | ||
</pre> | </pre> | ||
− | + | æè
æ¯ | |
<pre> | <pre> | ||
TutToolbar/ | TutToolbar/ | ||
行 70: | 行 71: | ||
</pre> | </pre> | ||
− | = | + | = 第äºç« ï¼å»ºç«æ¶æ§(Creating the Framework) = |
− | + | å¥ä»¶çæ¶æ§æ¯ç¨ä¾å訴 Firefox å¥ä»¶æ¯å¦ä½è¢«å»¶ä¼¸çï¼æªæ¡ççµæ§ã被誰建ç«ãææ¯å¥ä»¶çå
¨çå¯ä¸ä»£è(GUID)ãå¨ Firefox 1.5 éåçæ¬ï¼å¥ä»¶éç¼å¨éåé¨ä»½æå¾å¤§çè®åãåæ¬å¨ 1.0.x çæ¯å¾æ²éçæå·§ï¼å¨ 1.5 çå·²ç¶è®å¾æ´æ´æ½ãæ´ç°¡å®ã | |
− | == | + | == å®è£æ¸
å® (Installer Manifest) == |
− | + | é份æ¸
å®æ¯ç¨ä¾æä¾ Firefox éæ¼å¥ä»¶çç´°ç¯ãæä¸äºéè¦çé
ç®æ¾ç½®å¨éåæªæ¡ï¼æ以æåå¿
é 確å®éé¨ä»½æ¯æ£ç¢ºçãå¨ä½ çæä¸å±¤ç®é裡ï¼å»ºç«ä¸åæªæ¡ '''install.rdf''' ãç¶ä½ 建ç«å¥½éåæªæ¡ï¼ä½ æçå°é樣ççµæ§ï¼ | |
<pre> | <pre> | ||
+- TutToolbar/ | +- TutToolbar/ | ||
行 84: | 行 85: | ||
</pre> | </pre> | ||
− | + | å¨æåéå·¥åï¼è®æåççéåç¯ä¾ãæææåå¿
é 編輯çé¨ä»½å·²ç¶è¢«çªé¡¯åºä¾äºï¼æ²æ被çªé¡¯çé¨ä»½æ¯ä¸å¯ä»¥ä¿®æ¹çãæ¥èï¼æåä¾çé份æªæ¡çå
§å®¹ï¼æå°æ解éæ¯åé¨ä»½çç´°ç¯ï¼èä¸å¯ä»¥éå§ç·¨è¼¯å±¬æ¼èªå·±çå¥ä»¶ã | |
<pre> | <pre> | ||
行 116: | 行 117: | ||
</pre> | </pre> | ||
− | + | å¨æä¸é¢ç¬¬ä¸è¡è¡¨ç¤ºéæ¯ä¸ä»½ XML æ ¼å¼çæªæ¡ã第äºè¡ï¼ä»¥ '''<RDF>''' éé çï¼æ¯é份æ件çåºæ¬å
ç´ (root element)ãå®ç責任æ¯è¾¨å¥éé¨ä»½æ¯ RDF (Resource Description Framework) æ ¼å¼ãä¸ä¸åæ¨ç±¤(Tag) '''<Description>''' å樣å°æ¯ç¨ä¾è¾¨å¥çºå®è£æ¸
å®ãç¾å¨ï¼ä¹å³çæ±è¥¿é½çµæäºï¼è®æåçç第ä¸é¨ä»½å¿
é è¦ç·¨è¼¯çï¼ | |
<pre> | <pre> | ||
<em:id>yourextension@yoursite.com</em:id> | <em:id>yourextension@yoursite.com</em:id> | ||
行 123: | 行 124: | ||
</pre> | </pre> | ||
− | + | 第ä¸åæåéè¦æå¿çæ¯å¥ä»¶çèå¥è碼ãå¨ Firefox 1.5 ä¹åççæ¬ï¼å¿
é 使ç¨å
¨çå¯ä¸ä»£è(globally unique identifier)ï¼å³ GUIDãå管 GUID éæ¯è¢«æ¯æ´çï¼æ°çæ ¼å¼å»æ´å®¹æ使ç¨ãå
å
éè¦ä½¿ç¨ä½ çå¥ä»¶å稱ï¼ï¼ 符èï¼åå ä¸ä½ ç網ç«çæä¸å±¤ç¶²åãå¨é份æåä¸ï¼æåçºéåå·¥å
·å使ç¨éåå¼ '''tuttoolbar@borngeek.com''' ã | |
− | + | æ¥èæ¯å¥ä»¶çå稱(éæ顯示å¨å¥ä»¶ç®¡çå¡è£¡)ãå¨æåçç¯ä¾è£¡ï¼ä½¿ç¨ '''Toolbar Tutorial''' çºéåå¥ä»¶çå稱ã確å®éåå稱ä¸å
å«çæ¬ç·¨èï¼å çºçæ¬ç·¨èæå®èªå·±å°å±¬çæ¨ç±¤ãæåè¦ç·¨è¼¯çéåæ¨ç±¤å°±å¨ä¸ä¸è¡ãæ¢ç¶éæ¯æå試åè¦åç第ä¸åå·¥å
·åå¥ä»¶ï¼è®éåå¼çº 1.0 ãè¦æ³¨æå°ï¼å¨ç實çæ
æ³è£¡ï¼ç¶ä½ ç¼è¡¨æ°çæ¬çå¥ä»¶æï¼å¿
é æ´æ°éåå¼ï¼æ述解è¯ç¨å¼(Scripter)å¨èªåæ´æ°éç¨æä¸æç¼çåé¡ãå¨æçå¥ä»¶è£¡ï¼æå©ç¨äºæè¿°èªæ³ (以 Perl 寫æ)ãå¨é份æåç第ä¸ç« ï¼æå°æåè¨´ä½ æå¦ä½ä½¿ç¨ã | |
− | + | ä¸ä¸ååå¡ä¹æ¯éåå®è£æ¸
å®éè¦çä¸é¨åï¼æ¥èä¾ççéé¨ä»½ï¼ | |
<pre> | <pre> | ||
<em:targetApplication> | <em:targetApplication> | ||
行 137: | 行 138: | ||
</em:targetApplication> | </em:targetApplication> | ||
</pre> | </pre> | ||
− | + | éååå¡æ¯ç¨ä¾æ示å¥ä»¶è¦ç¨å¨åªåç¨å¼ãå¨éåä¾åï¼æåè¦éç¼ Firefox çå¥ä»¶ãå æ¤ï¼'''<em:id>''' éåå
ç´ æå®äº Firefox ç GUID ãä½ ä¸æ該æ¹è®éåå¼ï¼å¦åï¼æè®ä½ çå¥ä»¶ç¡æ³è¢«æ£ç¢ºå°å®è£ã | |
− | + | å¯ä¸å
©åæåéè¦è®åçï¼æ¯éå
©åå
ç´ ï¼'''<em:minVersion>''' ã '''<em:maxVersion>''' ãéå
©åå
ç´ ææå¥ä»¶é©åç¨å¨ Firefox çåªåçæ¬ ( minVersion æ¯æä½æ¯æ´çæ¬ï¼è maxVersion æ¯æé«æ¯æ´çæ¬) ã | |
− | + | å¨æåçç¯ä¾ï¼æåæä½¿ç¨ 1.5 (minVersion) è 1.5.0.* ï¼maxVersion)ãå çºæåå©ç¨ Firefox 1.5 çéç¼ç°å¢ï¼æ以ä¸å¯ä»¥æ minVersion è¨å®çæ¯ 1.5 éå°ã | |
− | + | 注æå°ï¼ä½ æ使ç¨ççæ¬ç·¨èå¿
é éµå®æ¨æºåå®ãèåä¾åï¼ã1.5 Release Candidate 1ãæ¯ä¸è¡çãç®å Firefox ççæ¬çµæ§æ¯ç¸ç¶å´è¬¹çï¼å¨ Mozilla Developer Center çæç« [http://developer.mozilla.org/en/docs/Toolkit_version_format Toolkit Version Format] æ詳細çæè¿°ãæ建è°ä½ è®éç¯æç« ï¼ä»¥äºè§£æ樣çå串æ¯è¢«å
許çã | |
− | + | å¨å®è£æ¸
å®çæå¾ï¼æ¯ç¨ä¾æè¿°å¥ä»¶çè³æå®ç¾©ï¼æ稱ä¸ç¹¼è³æ(meta-data)ï¼ | |
<pre> | <pre> | ||
<!-- Optional Items --> | <!-- Optional Items --> | ||
行 152: | 行 153: | ||
</pre> | </pre> | ||
− | + | å°±å¦è¨»éä¸æ¨£ï¼éäºå
ç´ æ¯éå¿
è¦çã'''<em:creator>''' å
許å¥ä»¶ä½è
ææèªå·±çååï¼é樣å¥äººå°±ç¥éæ¯èª°è£½ä½éåå¥ä»¶ãä¸ä¸åï¼<em:description> å
許æåå°æåçå¥ä»¶åä¸äºèªªæï¼éå說ææ顯示å¨å¥ä»¶ç®¡çå¡ä¸çå¥ä»¶å稱åºä¸ãæå¾ï¼'''<em:homepageURL>''' å
許æåææå¥äººå¯ä»¥å¨åªè£¡æ¾å°æåçå¥ä»¶ã | |
− | + | 注æå°ï¼éäºä¸æ¯å¯ä¸çè³æå®ç¾©ï¼åæä¹æ許å¤å
¶ä»å¯é¸ç¨çé
ç®ãèåä¾åï¼æåå
ç´ å¯ä»¥å¨å¥ä»¶ç®¡çå¡ä¸ä½¿ç¨æåèªå·±çå示(icon)ã å¦ä¸åå
ç´ å
許æåæå®èªè¨é¸é
çä½ç½®ææ¯ãéæ¼ãçå°è©±è¦çªãå
¨é¨å¯ç¨çå
ç´ (ä¹å«åå±¬æ§ properties )ï¼å¯ä»¥ççå¨Mozilla Developer Center ä¸çæç« [http://developer.mozilla.org/en/docs/install.rdf Installer Manifests] ãæå¾ä¸é»è¦æ³¨æçï¼ææçå
ç´ æ¯ä¸éè¦æç
§é åºçãä¹å°±æ¯èªªï¼ä½ å¯ä»¥å°å®åæ¾å¨æªæ¡ä¸ä»»ä½å°æ¹ï¼å
å
è¦æ³¨æçæ¯ï¼å°å®åæ¾ç½®å¨ '''<Description>''' è '''</Description>''' ä¹éã | |
− | + | ç¾å¨ï¼æåäºè§£äºå®è£æ¸
å®ï¼è®æåä¾ççæå¾ç樣åï¼éåçæ¬å°è¢«ä½¿ç¨å¨é份æåä¸ãä½ å¯ä»¥ç´æ¥å°ä¸é¢çé¨ä»½ï¼è¤è£½å¨ '''install.rdf''' ä¸ã | |
<pre> | <pre> | ||
<?xml version="1.0"?> | <?xml version="1.0"?> | ||
行 187: | 行 188: | ||
</pre> | </pre> | ||
− | == Chrome | + | == Chrome æ¸
å® (Chrome Manifest) == |
− | Chrome | + | Chrome æ¸
å®æ¯ Firefox 1.5 æéå§æçãå¨ä¹åï¼ææçè³æ被è¨å®å¨å
©åå°æ¹ï¼å®è£æ¸
å®(installer manifest)ãå contents.rdf ãèç¾å¨ï¼æ°çæ ¼å¼é¡¯å¾æ´ç°¡å®ãå次å¨æä¸å±¤ç®é建ç«å¦å¤ä¸åæªæ¡ '''chrome.manifest''' ãä¸é¢æ¯æªæ¡çµæ§çèµ·ä¾ç樣åï¼ |
<pre> | <pre> | ||
+- TutToolbar/ | +- TutToolbar/ | ||
行 198: | 行 199: | ||
</pre> | </pre> | ||
− | Chrome | + | Chrome æ¸
å®æ¯ç¨ä¾å訴 Firefox ï¼æåçå¥ä»¶æä¾çå°è£(package)èè¦è¼(overlay)ãå¨æåéå§å»ºç«ä¹åï¼å
çåç¯ä¾ï¼ |
<pre> | <pre> | ||
content myextension chrome/content/ | content myextension chrome/content/ | ||
行 204: | 行 205: | ||
locale myextension en-US chrome/locale/en-US/ | locale myextension en-US chrome/locale/en-US/ | ||
skin myextension classic/1.0 chrome/skin/</pre> | skin myextension classic/1.0 chrome/skin/</pre> | ||
− | + | èæ©å
使ç¨ç contents.rdf (é常è¶
é20è¡) æ¯è¼ï¼ç¾å¨çæ¹å¼è®å¾é常簡å®ï¼ç¬¬ä¸è¡ä½¿ç¨ä½ æå®çå°è£å稱ä¾ç»éï¼ä¸¦æææ¾ç½®å¨ content ç®éãéå°å
許 chrome è³æºèå¥å串(Uniform Resource Identifierï¼ç°¡ç¨± URI) ï¼å¦ '''chrome://myextension/content/'''ï¼å¨æåçå¥ä»¶å±¤ç´ä¸æåé©ç¶çå°æ¹ã注æï¼'''å°è£å稱åªè½ä»¥å°å¯«è¡¨ç¤º'''ï¼å
¶ä»æ··å大å°å¯«ï¼ææ¯å
¨é¨å¤§å¯«çå稱é½æ¯ä¸å
許çã | |
− | + | 注æå°ï¼'''content''' ç®éçä½ç½®æ¯ç¸å°æ¼å¥ä»¶çæ ¹ç®éãå¨é份æåï¼æåä½¿ç¨ '''tuttoolbar''' ç¶ä½å°è£å稱ã | |
− | + | 第äºè¡ç»é '''chrome://browser/content/browser.xul''' çè¦è¼(overlay)ï¼éå
è¨±ä½ æ°å¢æä¿®æ¹ Firefox 主è¦çªç使ç¨è
ä»é¢(user interface)ã | |
− | + | å¨ä¸é¢çç¯ä¾ï¼'''chrome://myextension/content/overlay.xul''' æå®äºè¦è¼(overlay)çXUL æªæ¡ã | |
− | + | æå¥è©±èªªï¼ä½æ¼å¥ä»¶ä¸ content ç®éç overlay.xul æªæ¡ï¼æ¯æåå°è¦æ°å¢ç使ç¨è
ä»é¢(å·¥å
·å)ãå¨éåé¨ä»½ï¼æåè¦ä½¿ç¨çå¼çº '''chrome://tuttoolbar/content/tuttoolbar.xul''' ã | |
− | + | ä¸ä¸è¡èªªæå°ååå¦ä½å»ºç«(how a locale can be created)ãå¨é份æåä¸ï¼æåä¸è¨è¨å°åå(éç¶éç¨å¾ç°¡å®)ï¼éå°å¨æªä¾ååè¨è«ã | |
− | + | æå¾ä¸è¡è¨å®äºé¢æ¿(skin)ï¼æåå°ä½¿ç¨éåæå·§ä¾ç¾åæåçå·¥å
·åãç¾å¨ï¼å
ç¥éå®ï¼æåå°å¨ç¬¬äºç« ååä¾è¨è«éé»ã | |
− | + | ä¸åé½å¾ç°¡å®ï¼ä¸æ¯åï¼ä¸é¢æ¯æåå°æ使ç¨ç chrome æ¸
å®ï¼éåªæ¯åæåï¼ä¹å¾æåå°æå å
¥é¢æ¿çè³è¨ãåä¸æ¬¡ï¼å°ä¸é¢çç¨å¼ç¢¼è¤è£½å°æååå建ç«ç '''chrome.manifest''' ã | |
<pre> | <pre> | ||
content tuttoolbar chrome/content/ | content tuttoolbar chrome/content/ | ||
行 222: | 行 223: | ||
</pre> | </pre> | ||
− | + | ç¾å¨æ¶æ§å·²ç¶å¯ä»¥äºï¼æ¥èè®æåä¾åäºæ趣çäºå§ï¼ | |
− | = | + | = 第ä¸ç« ï¼å»ºæ§å·¥å
·å (Structuring the Toolbar) = |
− | Firefox | + | Firefox å¥ä»¶ç使ç¨è
ä»é¢é¨ä»½æ¯ä½¿ç¨ XUL æè¡ (é³ï¼zool)ï¼éæ¯ä¸ç¨®ç¨ä¾è¨è¨ä½¿ç¨è
ä»é¢çæ¨ç¤ºèªè¨ãXUL å¯ä»¥æ³ææ¯ä¸ç¨® XML ç調å³æ(ææ¨æéå åè½ç)ï¼ å®ä¸éæ¯ä½¿ç¨é è¨å
ç´ ç XML (ä¹å«å widgets)ãä½¿ç¨ XUL ç好èï¼æ¯å çºå®ä½¿ç¨äº'''åæ
è¦è¼(dynamic overlays)'''çæè¡ãåæ
è¦è¼æè¡å¯ä»¥è®éç¼è
'''ä¸éè¦'''æ¹è®åæ¬ä»é¢çç¨å¼ç¢¼çæ
æ³ä¸ï¼å»ä¿®æ¹è¦çªç使ç¨è
ä»é¢ãå¨ä¸éæ´ååå§ç¨å¼ç¢¼çæ
æ³ä¸ï¼å¯ä»¥è®æåå°æ³¨æ¼è¨è¨æåçå¥ä»¶ï¼èä¸ç¨æå¿éè¦éè¤éç¼çåé¡ãå¨éåç« ç¯ï¼æåè¦ä¾ççè¨è¨å·¥å
·åç XUL å¿
è¦æ¨ç¤ºãè¨ä½ï¼XUL å
å
æ¯ç¨ä¾å»ºæ§å·¥å
·åèå·²ãçºäºè®å·¥å
·åå¯ä»¥éä½ï¼æåå¿
é ä½¿ç¨ JavaScript ï¼éé¨ä»½å°å¨ç¬¬å
ç« æå°ã |
− | + | å¨ '''content''' ç®é裡ï¼å»ºç«ä¸åæªåçº '''tuttoolbar.xul''' çæªæ¡ãå¨ä½ 建ç«å¥½ä¹å¾ï¼ç®éççµæ§ææ¯éæ¨£ï¼ | |
<pre> | <pre> | ||
+- TutToolbar/ | +- TutToolbar/ | ||
行 237: | 行 238: | ||
+- tuttoolbar.xul</pre> | +- tuttoolbar.xul</pre> | ||
− | + | ç¾å¨ï¼æåå·²ç¶å»ºç«å¥½éåæªæ¡ï¼å¯ä»¥éè¡å°éå§è¨è«å
§å®¹ãé¨èé²è¡çè
³æ¥ï¼ææå°æªæ¡çææå
§å®¹ï¼ä¸æ¥ä¸æ¥å°ä»ç´¹ãéæè®éç¨çèµ·ä¾æ´ç°¡å®ï¼å¨éç« ç¯çæå¾ï¼éåæªæ¡æç¸ç¶å¥å
¨ã | |
− | + | å çº XUL åªæ¯ä¸ç¨® XML ç調å³æï¼æ以第ä¸è¡å¿
é æ¯ä½¿ç¨ XML ç宣åï¼ | |
<pre><?xml version="1.0"?></pre> | <pre><?xml version="1.0"?></pre> | ||
− | + | ç¾å¨ï¼å®£åéæ¯ä¸å XML çæªæ¡ä¹å¾ï¼æåå°±å¯ä»¥éå§èç± '''overlay''' å
ç´ è¨è¨è¦è¼äºãéåå
ç´ å°ææ¯éæ´ä»½æ件çæ ¹å
ç´ ãæå¥è©±èªªï¼ææå
¶ä»çå
ç´ å¿
é å¨ <overlay> è </overlay> ä¹éãéæ¯ '''overlay''' çèµ·ä¾ç樣åï¼ | |
<pre> | <pre> | ||
<overlay id="TutTB-Overlay" | <overlay id="TutTB-Overlay" | ||
行 249: | 行 250: | ||
</overlay></pre> | </overlay></pre> | ||
− | + | éåå
ç´ æå
©å屬æ§ï¼'''id''' è '''xmlns''' ãéè· HTML é¡ä¼¼ï¼'''id''' çå¼'''å¿
é æ¯å¯ä¸'''çãæ´éè¦çæ¯ï¼éä¹å¿
é æ¯'''æ´åç覽å¨'''å¯ä¸çå¼ãé裡æä¸åå¯ä»¥è®ä½ 確å®æ使ç¨ç ID æ¯å¯ä¸çæ¹æ³ãä¾å¦ï¼ä¸é¢çç¯ä¾ãä½ å¯ä»¥æ³¨æå°æ使ç¨äº '''TutTB''' éé çåç¼ä¾å®ç¾© id 屬æ§çå¼ã使ç¨ç¬¦åä½ çå¥ä»¶å稱éé çåç¼ï¼éæ使 ID æ¯å¯ä¸çå¯è½æ§æé«ã並ä¸æ³¨æå°ï¼å¯¦éçå¼æ¯ä¸éè¦å
å« overlay çåç¼ï¼æé麼åæ¯æ¹ä¾¿æ追蹤æ使ç¨çå稱æ¯åä»éº¼ç¨çã | |
− | + | 第äºå屬æ§ï¼'''xmlns'''ï¼ç¨ä¾æå®ä½¿ç¨æ¼è¦è¼çå½å空éãæ¢ç¶éæ¯ XUL æ件ï¼æåå¿
é å®ç¾© XUL çå½å空éï¼éæ¯ä½ æ'''ä¸ç´'''ç¨å°çå¼ã | |
− | == | + | == å·¥å
·ç®±èå·¥å
·å (The Toolbox and Toolbar) == |
− | + | ææçå·¥å
·åæ該被éä¸å¨å·¥å
·ç®±ä¸ãæåä½¿ç¨ '''toolbox''' å
ç´ ä¾æå®ä¸åå·¥å
·ç®±(è¨ä½ï¼éåå
ç´ å¿
é 被æ¾ç½®å¨ '''overlay''' ä¹éã)ï¼ | |
<pre> | <pre> | ||
<toolbox id="navigator-toolbox"> | <toolbox id="navigator-toolbox"> | ||
</toolbox></pre> | </toolbox></pre> | ||
− | + | 注æå°ï¼éå id 屬æ§æä¸åé è¨å¼ï¼'''navigator-toolbox''' ã éåç¹å®çå¼è¡¨ç¤ºçº Firefox è¦çªä¸ä¸»è¦çå·¥å
·ç®±å
ç´ ï¼è·ç覽工å
·åãé¸å®åã網ååï¼ææ¯å
¶ä»é¡ä¼¼çæ§å¶é¸é
ä¸æ¨£ãèç±æå®éåç¹å¥çå·¥å
·åï¼æåå¯ä»¥ç¢ºå®éåå·¥å
·åæèå
¶ä»çå·¥å
·åé æå¨ä¸èµ·ãæ建è°ä½ 總æ¯è®ä½ çå·¥å
·åæ¾å¨éåç¹å®çå·¥å
·ç®±ä¸ï¼éä¸åªè®ä½ æçèµ·ä¾ä¸è´çå·¥å
·åï¼ä¹å¯ä»¥è®ä½ å¨ ã檢è¦>å·¥å
·åã ä¸ï¼å¿«éå°å°ä½ çå·¥å
·åé±èææ¯é¡¯ç¤ºã | |
− | + | è®æåå°æ³¨æåæ¾åå° '''toolbar''' å
ç´ ï¼æåæå°éåå
ç´ æ¾å¨ '''toolbox''' ä¹ä¸ãççéåç¯ä¾ï¼ | |
<pre> | <pre> | ||
<toolbar id="TutTB-Toolbar" toolbarname="Tutorial Toolbar" accesskey="T" | <toolbar id="TutTB-Toolbar" toolbarname="Tutorial Toolbar" accesskey="T" | ||
行 269: | 行 270: | ||
</toolbar></pre> | </toolbar></pre> | ||
− | + | è®æåä¾ççéåå
ç´ ç屬æ§ï¼ | |
− | * '''toolbarname''' - | + | * '''toolbarname''' - éåå
ç´ æå®å¥ä»¶çå稱(éææ¯ä½ å¨ã檢è¦>å·¥å
·åãçå°çæå)ã |
− | * '''accesskey''' - | + | * '''accesskey''' - 給éåå·¥å
·åæå®åæ¯ï¼ç¨ä¾ç¶ä½å¿«ééµä½¿ç¨ãå¨éåå·¥å
·åæåä¸ï¼æå使ç¨å¤§å¯«ç T ãéç¶éæ¯éå¿
è¦ç屬æ§ï¼éæ¯å¼·ç建è°ä½ 使ç¨å®ï¼éè½è®ä½¿ç¨è
åªè¦ç¨å¿«ééµå°±è½éåæééä½ çå·¥å
·åã |
− | * '''class''' - | + | * '''class''' - çºå·¥å
·åæå®ç¹å®ç樣å¼é¡å¥ãé è¨å¼ '''chromeclass-toolbar''' æ¯ç¨ä¾è¦ç¯å·¥å
·å顯示模å¼çé¡å¥ï¼å樣å°ï¼éæ¯å»ºè°ä½¿ç¨çéå¿
è¦å±¬æ§ã |
− | * '''context''' - | + | * '''context''' - æå®ç¶å¨å·¥å
·åä¸æå³éµæï¼æ顯示çå·¥å
·åé¸å®(context menu)ãä½ å¯ä»¥æä¾ä½ çé¸å® ID å¼ï¼ææ¯ä½¿ç¨ '''toolbar-context-menu''' ä¾å°é¸å®æ¾ç½®å¨ãæª¢è¦ > å·¥å
·åãã |
− | * '''hidden''' - | + | * '''hidden''' - æå®å·¥å
·åæ¯å¦é±èãé è¨çæ
æ³ä¸ï¼æåè¦è®ä½¿ç¨è
çè¦æåçå·¥å
·åï¼æ以è¨å®éåå¼çº false (ç¸åçº ture )ã |
− | * '''persist''' - This attribute is a space separated list of attributes that should persist across browser sessions. | + | * '''persist''' - This attribute is a space separated list of attributes that should persist across browser sessions. å¨ä¸é¢çç¯ä¾ï¼æä½¿ç¨ hidden ï¼ç¨ä¾å訴 Firefox å¨ sessions è¨ä½å·¥å
·åçé±èçæ
ã注æå°ï¼å¦æä½ çå·¥å
·åæ²æä½¿ç¨ id 屬æ§ï¼å persist 屬æ§ä¸æç¼çä½ç¨ï¼æ以è¦ç¢ºå®ä½ æçºä½ çå·¥å
·åæå® id å
ç´ ã |
− | + | ä½ å¯ä»¥å¨ XUL Planet [http://xulplanet.com/references/elemref/ref_toolbar.html toolbar element's attributes] çå°å®æ´çåèæç»ã | |
− | + | ç¾å¨ï¼è®æåä¾çç建ç«å¥½çè¦è¼æªæ¡[[http://www.borngeek.com/firefox/toolbar-tutorial/samples/xul-a.txt View XUL Overlay Revision 1]]ï¼ | |
<pre> | <pre> | ||
<?xml version="1.0"?> | <?xml version="1.0"?> | ||
行 297: | 行 298: | ||
</overlay></pre> | </overlay></pre> | ||
− | == | + | == å·¥å
·åæé (Toolbar Buttons) == |
− | + | å¨ Firefox ä¸ï¼å·¥å
·åæéæä¸ç¨®ï¼ä¸è¬ãé¸å®ãæéé¸å®ãéäºé½æ¯ç¨ '''toolbarbutton''' ä¾å»ºç«çï¼è®æåä¾åå¥ççãè¨ä½ï¼éäºå
ç´ å¿
é æ¾å¨ '''toolbar''' å
ç´ ä¹ä¸ã | |
− | === | + | === ä¸è¬æé (Normal Buttons) === |
− | + | éæ¯ç¨ä¾å»ºç«ä¸è¬çæéï¼ | |
<pre> | <pre> | ||
<toolbarbutton id="TutTB-Web-Button" tooltiptext="Search the Web" | <toolbarbutton id="TutTB-Web-Button" tooltiptext="Search the Web" | ||
label="Web Search" oncommand="TutTB_Search(event, 'web')" /></pre> | label="Web Search" oncommand="TutTB_Search(event, 'web')" /></pre> | ||
− | + | å®æä¹å¾ï¼ä¾ççéåå
ç´ ç屬æ§ï¼ | |
− | * '''tooltiptext''' - | + | * '''tooltiptext''' - ç¶æ»é¼ 移åå°æéä¸æåºç¾ç說æã |
− | * '''label''' - | + | * '''label''' - å·¥å
·åæé顯示çæåã |
− | * '''oncommand''' - | + | * '''oncommand''' - ç¶ '''oncommand''' äºä»¶è§¸ç¼æ(æä¸æé)ï¼ä½ ææå®çç¨å¼ç¢¼ãå¨éåç¯ä¾ï¼ä½¿ç¨ '''TutTB_Search()'''å½å¼ï¼æåå°å¨ç¬¬å
ç« è©³ç´°èªªæã |
− | + | ä½ å¯ä»¥å¨ XUL Planet [http://xulplanet.com/references/elemref/ref_toolbarbutton.html toolbarbutton element's attributes] æ¾å°å®æ´çåèæç»ã | |
− | === | + | === é¸å®æé (Menu Buttons) === |
− | + | ç¶é»ææéé¸å®æï¼æåºç¾ä¸æå¼é¸å®ã å管éåæéæ¨è¨é¡ä¼¼ä¸è¬æéæ¨è¨ï¼æåéæ¯å¿
é å å
¥ '''menupopup''' å
ç´ ï¼è®é¸å®ä»¥æåæ³è¦ç樣ååºç¾ãçºäºç°¡æ½é»ï¼ä¸é¢çç¯ä¾åªå
å«å
©åé¸å®é
ç®ã | |
<pre> | <pre> | ||
<toolbarbutton id="TutTB-MainMenu" type="menu" | <toolbarbutton id="TutTB-MainMenu" type="menu" | ||
行 335: | 行 336: | ||
</toolbarbutton></pre> | </toolbarbutton></pre> | ||
− | '''toolbarbutton''' | + | '''toolbarbutton''' æå
©åè¦æ³¨æçè®åã第ä¸ï¼'''type''' 屬æ§æå®äº menu çå¼ï¼èªªæäºéæ¯åé¸å®æéï¼èä¸æ¯ä¸è¬æéã第äºï¼ä½ æ注æå°é裡é¢æ²æ '''oncommand''' 屬æ§ãå çºé¸å®æéçå¯ä¸ç®çæ¯çºäºé¡¯ç¤ºè·³åºå¼é¸å®ï¼ä¸¦ä¸éè¦å·è¡ä»»ä½ç¨å¼ç¢¼ï¼è顯示é¸å®çåä½æç± Firefox èªåå®æã |
− | + | ä¹è«æ³¨æå° '''menupopup''' ï¼'''menuitem''' ï¼'''menuseparator''' éä¸åå
ç´ ã'''menupopup''' ææé¸å®é
ç®ç容å¨ï¼ç¨ä¾å»ºç«è顯示é¸å®ãå¨éåç¯ä¾è£¡ï¼éåå
ç´ æ²æ屬æ§ãå樣å°ï¼'''menuseparator''' ä¹å¾ç°¡å®ï¼å¨ä¸æå¼é¸å®ä¸æ¾ç½®æ°´å¹³åéç·ï¼ç¨ä¾åéä¸åçé¸å®ã | |
− | '''menuitem''' | + | '''menuitem''' ç¨å¾®æé»è¤éãå¨ä¸é¢çç¯ä¾ï¼æåæå®ç屬æ§ï¼ |
− | * '''label''' - | + | * '''label''' - æå®é¸å®é
ç®çæåã |
− | * '''tooltiptext''' - | + | * '''tooltiptext''' - éå屬æ§å°±åæ¯æåå¨ '''toolbarbutton''' çå°çï¼ä½æ¯æä¸é»è¦è¦åçãç±æ¼ Firefox ç bug ([https://bugzilla.mozilla.org/show_bug.cgi?id=147670 bug #147670])ï¼éå屬æ§æ¯å¿
è¦çãå¦æä½ æ±ºå®å¾ '''menuitem''' ä¸åªæéå屬æ§ï¼ç¶ä½¿ç¨è
å°æ»é¼ 移åå°é¸å®é
ç®æï¼æçä¸å°æ示說æãé¸å®ä¸æ顯示工å
·æ示ï¼éçæ¯å令人ä¸æ»¿æçãç¹è²ãï¼ |
− | + | ä½ å¯ä»¥å¨ XUL Planet [http://xulplanet.com/references/elemref/ref_menuitem.html menuitem element's attributes] æ¾å°å®æ´çåèæç»ã | |
− | === | + | === æéé¸å® (Button-Menu Buttons) === |
− | + | 第ä¸ä¹æ¯æå¾çæéé¸å®æ¯ä¸ç¨®ä¹ä¸æè¤éçã實éä¸ï¼çµåäºåå
©ç¨®æéï¼æä¾å¯é»ææéçä¸æå¼é¸å®ã | |
− | + | ãä¸ä¸é ãèãä¸ä¸é ãç覽é¸å®æ¯éåæéé¸å®çç¯ä¾ï¼éæ¯éè¦å»ºç«çæ¨è¨ï¼ | |
<pre> | <pre> | ||
<toolbarbutton id="TutTB-Combined-Button" label="Search" | <toolbarbutton id="TutTB-Combined-Button" label="Search" | ||
行 366: | 行 367: | ||
</toolbarbutton></pre> | </toolbarbutton></pre> | ||
− | + | æå
©åå¼å¾æ³¨æçè®åï¼å¨ '''toolbarbutton''' ç '''type''' 屬æ§æå®äºå¼ '''menu-button''' ï¼èä¸æå¦å¤ä¸è¡ç¨å¼ç¢¼ '''oncommand''' ï¼ææå¨ç¬¬å
ç« è§£ééé¡å¤çç¨å¼ç¢¼ãæ¥è注æå°ï¼é裡æè·ãä¸è¬æéãä¸æ¨£ç '''toolbarbutton''' æ '''oncommand''' 屬æ§ï¼ä»¥åå¨ãé¸å®æéã裡çå·¢çå
ç´ '''menupopup''' è '''menuitem''' ã | |
− | + | ç¾å¨ï¼æåè¨è«å®ä¸åçæéï¼ä¾ççç¨å¼ç¢¼ç樣å[[http://www.borngeek.com/firefox/toolbar-tutorial/samples/xul-b.txt View XUL Overlay Revision 2]]ï¼ | |
<pre> | <pre> | ||
<?xml version="1.0"?> | <?xml version="1.0"?> | ||
行 415: | 行 416: | ||
</overlay></pre> | </overlay></pre> | ||
− | == | + | == ä¸æå¼ç·¨è¼¯å (Drop-Down Edit Box) == |
− | + | ä¸ä¸åæåè¦å¨å·¥å
·åå å
¥çæ¯ä¸æå¼ç·¨è¼¯åãéæ¯ç¨ '''menulist''' ä¾å»ºç«çï¼è®æåä¾ççç¨å¼ç¢¼ï¼ | |
<pre> | <pre> | ||
<toolbaritem id="TutTB-SearchTerms-TBItem" persist="width"> | <toolbaritem id="TutTB-SearchTerms-TBItem" persist="width"> | ||
行 427: | 行 428: | ||
</toolbaritem></pre> | </toolbaritem></pre> | ||
− | + | 注æå°ï¼æåæ '''menulist''' æ¾å¨ '''toolbaritem''' ä¹ä¸ãä»»ä½ä¸åå¨ '''toolbar''' çé
ç®é½ä¸æ¯å·¥å
·åæéï¼å¨ '''toolbaritem''' 裡é çææ¯ãä¹è«æ³¨æå°ï¼æåçº '''toolbaritem''' æå®äº '''id''' ï¼ä¸è¨å®äºå¯¬åº¦(èç±å©ç¨äº '''persist''' 屬æ§)ã | |
− | '''menulist''' | + | '''menulist''' ææ¯çæ£ç¨ä¾å»ºç«ä¸æå¼ç·¨è¼¯åçãæå¹¾åå¨éåå
ç´ åºç¾çæ°å±¬æ§ï¼ |
− | * '''editable''' - | + | * '''editable''' - ç¶è¨å®çº true æï¼ä½¿ç¨è
å¯ä»¥å¨ç·¨è¼¯åä¸æåã |
− | * '''flex''' - | + | * '''flex''' - 使éåå
ç´ æ¯å¯è®åçãéæ¯åæ´æ¸å¼ï¼ç¸å°æ¼å
¶ä»å¯è®åå·¥å
·åå
ç´ ï¼æå®å
¶å¤§å°ãè¨å®å¼ 2 代表èè¨å®å¼ 1 çå
©å寬ï¼0 åæ¯ä¸è½è®åçåºå®å¯¬åº¦ã |
− | * '''minwidth''' - | + | * '''minwidth''' - æå°å¯¬åº¦ï¼å®ä½çºåç´ ã |
− | * '''width''' - | + | * '''width''' - åå§å¯¬åº¦ï¼å®ä½çºåç´ ã |
− | * '''onkeypress''' - | + | * '''onkeypress''' - ç¶ä½¿ç¨è
輸å
¥æåæï¼ç¨ä¾å·è¡çç¨å¼ç¢¼ã |
− | + | ä½ å¯ä»¥å¨ XUL Planet [http://xulplanet.com/references/elemref/ref_menulist.html menulist element's attributes] çå°å®æ´çåèæç»ã | |
− | + | è·æåä¹åçå°çãé¸å®æéãä¸æ¨£ï¼å¨ '''menulist''' 裡ç '''menupopup''' å
å«äº menuitem å
ç´ ã'''onpopupshowing''' éåäºä»¶æå¨ç·¨è¼¯åçé¸å®é
ç®é¡¯ç¤ºå觸ç¼ï¼å
¶ä¸æå®ä¸åè½åæ
寫å
¥é¸å®é
ç®çå½å¼ï¼éåå½å¼æåç¨å¾ææåãä½ ä¹å¯ä»¥å å
¥éæ
çé¸å®ï¼éç¨è·ãé¸å®æéãæ¯ä¸æ¨£çã | |
− | + | ç¾å¨ï¼éåå¥ä»¶å·²ç¶è®å¾æ´å
·é«ä¸é»äºï¼è®æåä¾ççç¨å¼ç¢¼[[http://www.borngeek.com/firefox/toolbar-tutorial/samples/xul-c.txt View XUL Overlay Revision 3]]ï¼ | |
<pre> | <pre> | ||
<?xml version="1.0"?> | <?xml version="1.0"?> | ||
行 496: | 行 497: | ||
</overlay></pre> | </overlay></pre> | ||
− | == | + | == å¯èª¿æ´ç移é§æ¨è¨ (Resizing Gripper) == |
− | + | éè¨å¾ä¹åå
å«å¨ '''menulist''' ä¸ '''toolbaritem''' å
ç´ ææå°ç '''persist''' 屬æ§åï¼è¨å®éå屬æ§ä»¥è®æåå¨ç覽å¨ä½¿ç¨æéï¼å¯ä»¥å²åæå°åç寬度ãçºäºè®ä½¿ç¨è
å¯ä»¥æ¹è®å¯¬åº¦ï¼æåè¦æä¾ '''移é§æ¨è¨''' ãç¨ä¾åé件äºçå
ç´ æ¯ '''splitter''' ï¼è®æåä¾ççç¨å¼ç¢¼ï¼ | |
<pre> | <pre> | ||
<splitter id="TutTB-ResizeSplitter" state="open" collapse="none" | <splitter id="TutTB-ResizeSplitter" state="open" collapse="none" | ||
行 506: | 行 507: | ||
</splitter></pre> | </splitter></pre> | ||
− | + | éæ¯ '''splitter''' ç屬æ§ï¼ | |
− | * '''state''' - | + | * '''state''' - æå®åå²æ¨è¨æ¯å¦æºç(é±è)å
§å®¹ï¼ open å¼æå®ä¸ç®¡æ¯å¦æå
§å®¹ç顯示ã |
− | * '''collapse''' - | + | * '''collapse''' - 決å®åªéç splitter 被é±èãæåä½¿ç¨ none ï¼ä¸è®ä»»ä½ä¸éç splitter 被é±èã |
− | * '''resizebefore''' - | + | * '''resizebefore''' - ç¶ splitter æ¹è®æï¼æå® splitter å·¦éçåªåå
ç´ å¿
é 被éæ°èª¿æ´ãç¶ splitter 移åæï¼ä½¿ç¨ closest ä¾éæ°èª¿æ´æé è¿ splitter å·¦éç編輯åã |
− | * '''resizeafter''' - | + | * '''resizeafter''' - ç¶ splitter æ¹è®æï¼æå® splitter å³éçåªåå
ç´ å¿
é 被éæ°èª¿æ´ãå¨éåç¯ä¾è£¡ï¼æåä½¿ç¨ farthest ä¾éæ°èª¿æ´æå³éçå½æ§ç©ºéã |
− | vbox | + | vbox æ¯ç¨ä¾è¨å®æ¨£å¼çï¼æåæå¨ç¬¬äºç« è¨è«é¢æ¿æï¼æå°éé»ã |
− | + | ä½ å¯ä»¥å¨ XUL Planet [http://xulplanet.com/references/elemref/ref_splitter.html splitter element's attributes] çå°æ´å®æ´çåèæç»ã | |
− | + | è®æåä¾ççå
å« '''splitter''' è '''toolbaritem''' çè¦è¼ç¨å¼ç¢¼[[http://www.borngeek.com/firefox/toolbar-tutorial/samples/xul-d.txt View XUL Overlay Revision 4]]ï¼ | |
<pre> | <pre> | ||
<?xml version="1.0"?> | <?xml version="1.0"?> | ||
行 580: | 行 581: | ||
</overlay></pre> | </overlay></pre> | ||
− | + | çºäºé¿å
移é§æ¨è¨è¨åç細微顯示åé¡ï¼æåééè¦å»ºç«é¡å¤ç '''toolbaritem''' ï¼éèæåååå¨ãé¸å®æéãä¸çæå°æéæåçä¸æ¨£ã åä¸æ¬¡ç¢ºå® flex 屬æ§çå¼çº 0ï¼éå°æé¿å
ï¼ç¶æåçé¸å®æé被ææ³å°å·¦éæ被移é¤ã | |
− | + | æ¥èï¼è®æååä¾å¢å å
©åé
ç®ãé¦å
ï¼å° '''toolbarseparator''' æ¾ç½®å¨æå¾å
©åæéä¸ï¼æ¤ç®çæ¯çºäºè£é£¾ãåä¾ï¼å° '''toolbarspring''' æ¾ç½®å¨æå¾ç toolbaritem å
ç´ ä¹å¾ãThis spring will allow us to drag the resizer all the way to the right, so that we can see the full resizing effect in action. éå
©åæ¨ç¤ºæ¯å¾ç°¡å®çï¼åæ¯éæ¨£ï¼ | |
<pre> | <pre> | ||
<toolbarseparator /> | <toolbarseparator /> | ||
行 588: | 行 589: | ||
<toolbarspring /></pre> | <toolbarspring /></pre> | ||
− | + | è®æåä¾ççå®æ´çè¦è¼ç¯ä¾[[http://www.borngeek.com/firefox/toolbar-tutorial/samples/xul-e.txt View XUL Overlay Revision 5]]ï¼ | |
<pre> | <pre> | ||
<?xml version="1.0"?> | <?xml version="1.0"?> | ||
行 659: | 行 660: | ||
</overlay> </pre> | </overlay> </pre> | ||
− | = | + | = 第åç« ï¼åæ
éç¼ (Dynamic Development) = |
− | ( | + | (è¯è
ï¼å¦æä¸æ³ç¨æ¤éç¼ç°å¢ï¼å¯ä»¥ç¥éæ¤ç« ï¼ä¸¦ç¨ç¬¬ä¸ç« çæ¹å¼æ¸¬è©¦å¥ä»¶ã) |
− | + | å¨ Firefox 1.5 ä¸ï¼åæ
å¥ä»¶éç¼æ¯æ°çæè¡ï¼å°éç¼è
èè¨ï¼éæ¯ææç¨çéå åè½ãéé
æè¡å¯ä»¥è®ä½ å¨éç¼å¥ä»¶æï¼å³æå°çå°çµæãç¶ä½ è¦æ¸¬è©¦ XUL è¦è¼ææ¯ JavaScript ç¨å¼ç¢¼æï¼ä¸ç¨æ¯æ¬¡åéæ°å°è£å¥ä»¶ãéä¸åªç¯çäºä½ çæéï¼ä¹è®ä½ è½æ´å¿«éå°é¤é¯ã | |
− | + | é£éº¼ï¼éé
ç¹è²æ¯å¦ä½éä½çå¢ï¼éå°±è¦æè¬æåå¨ç¬¬äºç« 建ç«ç chrome æ¸
å®äºãç´å°ç¾å¨çºæ¢ï¼æé½éæ²è·ä½ 說 chrome æ¸
å®è©¦ä½ç麼ç¨éãå¨éåæåä¸ï¼æåä¸éå§å»ºç«ççæ¬å°±æ¯'''ç¹å¥'''çºåæ
éç¼èè¨è¨çãæè¨ä¹ï¼æåä¸å¿
éæ°å°è£é£ä»½çæ¬çå¥ä»¶ï¼ä½éæ¯æäºæ¹è®éè¦å®æï¼æå¯ä»¥å°è£ãæå¹¾åç¨ä¾ãååãå¥ä»¶åæ
éç¼çæ¥é©ï¼å¨é£ä¹åï¼æè¦å
çµ¦ä½ å¹¾å建è°ã | |
− | == | + | == 注æäºé
(A Word of Warning) == |
− | + | å¥ä»¶éç¼ææææé»å±éªï¼å°¤å
¶æ¯è¨è¨ XUL è¦è¼æªæ¡æãæ'''å¼·ç建è°'''ä½ è¦é¿å
éç¼å¥ä»¶è·å¹³å¸¸ç覽網é å
±ç¨ä¸åè¨å®æª(profile)ãæè¨ä¹ï¼'''ä½ å¿
é çºä½ çéç¼ç°å¢å»ºç«ä¸åæ°çè¨å®æª'''ãéå¯ä»¥é¿å
ä½ å¤±å»ä¸äºééµçè³æï¼å¦ï¼å²åçå¯ç¢¼ãcookiesãæ¸ç±¤ææ¯å
¶ä»ä½ ä¸æ³éºå¤±çæ±è¥¿ã | |
− | + | æå¸æè½åå¿« Born Geek å¨ç¼è¡¨éæ¼å¦ä½å»ºç«è使ç¨è¨å®æªçæå¸ãå¨é£ä¹åï¼ä½ å¯ä»¥å
ççå¨ Mozilla.org ç[http://www.mozilla.org/support/firefox/profile è¨å®æªæ件]ã建ç«è使ç¨è¨å®æªæ¯å¾ç°¡å®çï¼éæé¿å
è®ä½ é ççæ
æ³ç¼çã | |
− | == | + | == å¦ä½åæ
éç¼ (How to Develop Dynamically) == |
− | + | æ主è¦çå·¥ä½ï¼æåå·²ç¶å¨ chrome æ¸
å®å®æ(å³ä½¿ä½ éä¸äºè§£æåé£æåäºä»éº¼)ãç¾å¨ï¼æåéè¦çï¼æ¯ä¸åå° Firefox æå硬ç¢ä¸å¥ä»¶ä½ç½®çæªæ¡ï¼æåå°èç± pointer æªæ¡ä¾å®æã | |
− | + | é¦å
ï¼å¨ä½ çé»è
¦çé¨ä¾¿ä¸åå°æ¹ï¼ä»¥æåå¨å®è£æ¸
å®(install manifest)ä¸æ使ç¨ç GUID å稱ï¼å»ºç«ä¸åæåæªãå¨é份æåä¸ï¼æåä½¿ç¨ '''tuttoolbar@borngeek.com''' ä½çºæªåãä¸å¹¸çæ¯ï¼å¨å¾®è»è¦çªç°å¢è£¡ï¼ã.comãçæªæ¡æ¯è¢«ç¨ä¾ç¶ä½å·è¡æªï¼èæåéè¦çæ¯æåæªãä½ å¯ä»¥æã.comãæ¿æï¼ä½ä¹è¨å¾å»ä¿®æ¹å¨å®è£æ¸
å®ç GUIDï¼ç¢ºä¿å
©åå稱æ¯ä¸æ¨£çã | |
− | + | å¨éåæªæ¡è£¡ï¼æåå°è¦è¼¸å
¥ä¸è¡æåï¼å¥ä»¶å²åççµå°ä½ç½®ï¼ä¹å°±æ¯åæ¾ '''install.rdf''' è '''chrome.manifest''' æªæ¡çç®éãå¨æçä¾åï¼å²åè·¯å¾å¦ä¸ï¼ | |
<pre>C:\Born Geek\TutToolbar</pre> | <pre>C:\Born Geek\TutToolbar</pre> | ||
− | + | ä½ å¿
é 使ç¨ä½ èªå·±è¨å®çè·¯å¾ï¼é¤éä½ çè·¯å¾è·æçä¸æ¨£ã輸å
¥å®è·¯å¾å¾ï¼å²åæªæ¡ã | |
− | + | ç¾å¨ï¼æåå¿
é å°éåæªæ¡ç§»åå°è·éç¼ç°å¢çè¨å®æª(profile)åä¸åç®é(å¦ï¼C:\Documents and Settings\Administrator\Application Data\Mozilla\Firefox\Profiles)ãæååæå°ç[http://www.mozilla.org/support/firefox/profile è¨å®æªæ件]æè¨è«å°è¨å®æªç®éçä½ç½®ãç¶ä½ æ¾å°è¨å®æªç®éæï¼å°æååå建ç«ç pointer æªæ¡ç§»åå°è©²ç®éç extensions ç®éä¸ãéæ¯æçä¾åï¼ | |
<pre> | <pre> | ||
+- tl5wlpz3.Nightly/ | +- tl5wlpz3.Nightly/ | ||
行 691: | 行 692: | ||
+- tuttoolbar@borngeek.com | +- tuttoolbar@borngeek.com | ||
+- (... other files and folders ...)</pre> | +- (... other files and folders ...)</pre> | ||
− | + | ä½ å¯ä»¥çå°æçè¨å®æªæä¸å±¤ç®éï¼æ使ç¨ä»¥ãNightlyãçºåçè¨å®æªï¼ä¾ä½çºæçå¥ä»¶éç¼ç°å¢ãä¸æ¦ä½ æ pointer æªæ¡æ¾å¨é©ç¶çä½ç½®ï¼éå Firefoxï¼ç¢ºå®ä½ 使ç¨çæ¯å¥ä»¶éç¼çè¨å®æª(å次æéï¼ååæå°çè¨å®æªæ件æåè¨´ä½ å¦ä½é樣å)ã å°ç®åçºæ¢ï¼å¦æä½ æ¯æ¨£é½åçæ£ç¢ºï¼ä½ æçå°æ²æé¢æ¿çç°è²å·¥å
·åã | |
− | == | + | == éç¼é±æ (The Development Cycle) == |
− | + | ç¾å¨ï¼æåå·²ç¶ååäºåæ
éç¼ç°å¢ï¼é£è¦å¦ä½å»å©ç¨å¢ï¼éç¨å
¶å¯¦æ¯é常簡å®çï¼ | |
− | # | + | #ç·¨è¼¯ä½ çå¥ä»¶æªæ¡ |
− | # | + | #éæ°éåå·²æ´æ¹æªæ¡æå¥ç¨çè¦çªï¼ææ¯ä½¿ç¨ [http://ted.mielczarek.org/code/mozilla/extensiondev/index.html Extension Developer's Extension] çéæ°æ´ç('''Reload Chrome''')ã |
− | + | æå
©ä»¶äºæ¯ä½ è¦ç¥éçï¼ | |
− | * | + | *å¦æä½ æ¹è®äº '''chrome.manifest''' æªæ¡ï¼ä½ å¿
é éæ°éå Firefox (éåæªæ¡åªæå¨ç¨å¼ååææç¼çä½ç¨)ã |
− | * | + | *å¦æä½ æ¹è®äº '''install.rdf''' æªæ¡ï¼ä½ å¿
é æ¹è® pointer æªæ¡ææåç®éçä¿®æ¹æéãå¨ Linux ä¸ï¼ä½ åªè¦ä½¿ç¨ '''touch''' æ令ãèå¨ Windows 裡就æé»é£åº¦ï¼é¤éä½ å®è£äºå¯ä»¥ä½¿ç¨ '''touch''' æ令ç [http://www.cygwin.com/ Cygwin] å·¥å
·ãå¯ä¸è¦åçï¼å°±æ¯å¨å¥ä»¶æä¸å±¤ç®é建ç«ä¸åæ°ç®éï¼ç¶å¾åªé¤æ°ç®é以æ¹è®ç®éçãä¸ä¸æ¬¡ä¿®æ¹ãæéã |
− | + | ä½ å¯ä»¥çå°ï¼æåæäºæ¹ä¾¿çéç¼èé¤é¯å·¥å
·ãéåéæ¼ï¼å¨ 1.5 çä¹åçæ¨æºéç¨ï¼å°±æ¯æ¯æ¬¡å¨å¥ä»¶éç¼éç¨é½è¦å°è£æªæ¡ã | |
− | + | ç¾å¨ï¼è®æåæéåééçå·¥å
·åè®å¾æ´æ¼äº®ä¸é»å§ï¼ | |
− | = | + | = 第äºç« ï¼é¢æ¿è£½ä½ (Skinning the Toolbar) = |
− | + | é¢æ¿æ¯ç±æ¨£å¼æ¨æºèåçææ§æçãè¨ä½ï¼å管è¨è¨é¢æ¿æ¯éå¿
è¦çï¼ä½æ¯å®è½æåå¥ä»¶çå質ãç¢ç«ä½¿ç¨è
å°å¥ä»¶ç第ä¸å°è±¡æ¯å®çå¤è§ï¼èä¸æ¯å®çåè½ãç¶èï¼å¦æä½ è¦ºå¾ä½¿ç¨æåæ¨ç±¤è®ä½ æ¯è¼èªå¨ï¼ææ¯ä¸éè¦å»ºç«å¤è§ï¼ä½ å¯ä»¥ç¥ééåç« ç¯ã | |
− | == | + | == æ´æ°æªæ¡çµæ§ (Updating the File Structure) == |
− | + | è¨è¨é¢æ¿ç第ä¸æ¥å°±æ¯å»ºç«ä¸åç®éï¼ç¨ä¾åæ¾éæ¼é¢æ¿çæªæ¡ãå¨ '''chrome''' ç®éä¸å»ºç«ä¸å '''skin''' ç®éãæªæ¡çµæ§æåéæ¨£ï¼ | |
<pre> | <pre> | ||
+- TutToolbar/ | +- TutToolbar/ | ||
行 725: | 行 726: | ||
+- tuttoolbar.xul | +- tuttoolbar.xul | ||
+- skin/</pre> | +- skin/</pre> | ||
− | + | ç¾å¨æåæåæ¾é¢æ¿æªæ¡çå°æ¹äºï¼ä¹å¾å¿
é è¦å¨ chrome 裡註åéåä½ç½®ã | |
− | == | + | == æ´æ° Chrome æ¸
å® (Updating the Chrome Manifest) == |
− | + | éè¨å¾æåå¨ç¬¬äºç« 建ç«ç chrome æ¸
å®åï¼æåå¿
é å¨éåæªæ¡å å
¥ä¸è¡ç¨å¼ç¢¼ï¼ç¨ä¾è¨»åæåçé¢æ¿ãæ°å å
¥çä½ç½®(第ä¸è¡)ï¼ | |
<pre> | <pre> | ||
content tuttoolbar chrome/content/ | content tuttoolbar chrome/content/ | ||
overlay chrome://browser/content/browser.xul chrome://tuttoolbar/content/tuttoolbar.xul | overlay chrome://browser/content/browser.xul chrome://tuttoolbar/content/tuttoolbar.xul | ||
skin tuttoolbar classic/1.0 chrome/skin/</pre> | skin tuttoolbar classic/1.0 chrome/skin/</pre> | ||
− | + | æ°å å
¥çéä¸è¡ç¸ç¶ç°¡å®ï¼èä¸åªæååé¨ä»½ã第ä¸é¨ä»½ï¼skin 說æéä¸è¡è¦è¨»åé¢æ¿çè³è¨ãæ¥èæ¯å¥ä»¶çå稱ï¼éè£¡ä½¿ç¨ '''tuttoolbar''' ç¶ä½æåçå¥ä»¶å稱ã第ä¸é¨ä»½ï¼èªªææåå°ææ´å±çå·²å®è£å¥ä»¶å稱ï¼ãclassic/1.0ãæ¯ä½ æä¸ç´ç¨å°çå¼ãæå¾ï¼ä¹æ¯æéè¦çé¨ä»½ï¼å°±æ¯å
å«é¢æ¿æªæ¡çç®éè·¯å¾ã注æå°éåè·¯å¾å¾é¢çæç·(/)ï¼éåæç·æ¯'''å¿
è¦ç'''ï¼ç¢ºå®ä½ æ輸å
¥ã | |
− | == | + | == 建ç«åçæªæ¡ (Creating the Image Files) == |
− | + | æåæè®æ¯åå·¥å
·åæé使ç¨åèªçååã注æå°ï¼éä¸æ¯æææçææ¯ç²¾ç·»çä½æ³ï¼ä½æ¯å¯ä»¥è®äººæ´å®¹æäºè§£ãæ´å¥½çæ¹å¼æ¯ä½¿ç¨'''åå樣å¼è¡¨'''ï¼ä½æ¯é£è¶
åºé份æåçç¯åã | |
− | + | æåéè¦äºåååä¾å·¥å
·åççµåé¸å®ä½¿ç¨ï¼ä¸»è¦é¸å®ãç¶åæå°æéã網é æå°æéãåçæå°é¸å®ä»¥åå¯èª¿æ´ç移é§æ¨è¨ãå¨ä¸é¢çå表ä¸ï¼æäºåæç¨å¨éåå¥ä»¶çååã注æï¼ éäºååé½æ¯éæç PNG æ ¼å¼æªæ¡ï¼å¦æä½ ä½¿ç¨ IE ææ¯å
¶ä»ç覽å¨ï¼å¯è½ä¸è½æ£ç¢ºå°é¡¯ç¤ºã | |
− | + | 主è¦é¸å®å示 Main Menu Icon (main.png): http://wiki.moztw.org/uimages/b/b7/Borngeek_main.png | |
− | + | ç¶åæå°å示 Combined Search Icon (combined.png): http://wiki.moztw.org/uimages/3/36/Borngeek_combined.png | |
− | + | 網é æå°å示 Web Search Icon (web.png): http://wiki.moztw.org/uimages/9/9c/Borngeek_web.png | |
− | + | åçæå°å示 Images Search Icon (images.png): http://wiki.moztw.org/uimages/6/61/Borngeek_images.png | |
− | + | å¯èª¿æ´ç§»é§æ¨è¨å示 Resizing Gripper Icon (gripper.png): http://wiki.moztw.org/uimages/5/50/Borngeek_gripper.png | |
− | + | å°éäºååå²åå¨æååå建ç«ç '''skin''' ç®é裡ï¼æªæ¡çµæ§æåéæ¨£ï¼ | |
<pre> | <pre> | ||
+- TutToolbar/ | +- TutToolbar/ | ||
行 767: | 行 768: | ||
+- web.png</pre> | +- web.png</pre> | ||
− | == | + | == èç±ä¸²æ¥æ¨£å¼è¡¨å¥ç¨åç (Applying the Images with CSS) == |
− | + | ç¾å¨ï¼æéäºååå¯ä»¥ä½¿ç¨ï¼é¢æ¿ç®éä¹å·²ç¶è¨»åï¼æåå¯ä»¥éå§æååå¥ç¨å¨å·¥å
·åæéä¸äºãæåå°æèç± CSS ä¾å®æãå°±å¦æå¨æåä¸éå§æå°çï¼å¦æä½ å° CSS ä¸çæï¼å¯ä»¥åè W3Schools ç [http://www.w3schools.com/css/css_intro.asp excellent CSS tutorial] ã | |
− | + | è®æåéå§å»ºç« CSS æªæ¡å§ï¼å¨ '''skin''' ç®éä¸ï¼å»ºç«ä¸åæªåçº '''tuttoolbar.css''' çæªæ¡ï¼æéåæªæ¡è·ååæ¾å¨ä¸èµ·ãæªæ¡çµæ§å¦ä¸ï¼ | |
<pre> | <pre> | ||
+- TutToolbar/ | +- TutToolbar/ | ||
行 786: | 行 787: | ||
+- web.png | +- web.png | ||
+- tuttoolbar.css</pre> | +- tuttoolbar.css</pre> | ||
− | + | å¨èªªæç´°ç¯åï¼å
è®æåä¾çç樣å¼è¡¨çå
§å®¹ï¼ | |
<pre> | <pre> | ||
#TutTB-MainMenu { | #TutTB-MainMenu { | ||
行 819: | 行 820: | ||
border: none !important; | border: none !important; | ||
}</pre> | }</pre> | ||
− | + | 第ä¸é
è¦åæ¯æå®è©²åå給ã主è¦é¸å®ãæé使ç¨ãå顧ä¸ä¸ç¬¬ä¸ç« ï¼æå給äºè©²æéä¸å ID å¼ï¼'''TutTB-MainMenu'''ï¼æåç¨è©²å¼ä¾è¨å®æé顯示çååãå¨åé¢çäºè(#)æ¯ '''ID é¸åå¨'''(ID selector)ï¼ä¹å°±æ¯ç¨ä¾æå® CSS å
ç´ è¦åçç¹å®èå¥å¼ãå¨å·¥å
·åæé裡ï¼æåä½¿ç¨ CSS 屬æ§ç '''list-style-image''' ä¾æå®ååã注æå°æå使ç¨çæ¯ chrome è·¯å¾ï¼ä¹å°±æ¯å¥ä»¶æªæ¡çµæ§ä¸çååè·¯å¾ï¼å¸¸ç¨çæ ¼å¼å¦ä¸ï¼ | |
<pre> | <pre> | ||
chrome://<packagename>/skin/<image_file_name></pre> | chrome://<packagename>/skin/<image_file_name></pre> | ||
− | + | å¨æåçç¯ä¾è£¡ï¼å°è£å稱(package name)æ¯ '''tuttoolbar'''ï¼è主è¦é¸å®ä½¿ç¨çåååç¨±çº '''main.png'''ãä½ å¯ä»¥çå°ï¼ææçå·¥å
·åæé使ç¨é¡ä¼¼çè¦åï¼å¨ç¶åæå°æéçé¸å®é
ç®ä¹æ¯ä¸æ¨£ãThere's one caveat to handling menu item icons, however. åæ³ä¸ä¸ï¼å¨ç¶åæå°é¸å®ä¸ï¼æåçºé¸å®é
ç®ä½¿ç¨äºä¸åç¹å¥çé¡å¥å¼ï¼'''menuitem-iconic'''ï¼éæ¯ Firefox å
§å»ºçãéåå¼ãååãå示æ¯æ´ä½¿ç¨å®çæ¯åé¸å®é
ç®ã | |
− | + | æ³å¿
ä½ ä¹æ³¨æå°äºéåç¶åæå°æéçç¹å®è¦åï¼ | |
<pre> | <pre> | ||
#TutTB-Combined-Button > .toolbarbutton-menubutton-button { | #TutTB-Combined-Button > .toolbarbutton-menubutton-button { | ||
-moz-box-orient: horizontal; | -moz-box-orient: horizontal; | ||
}</pre> | }</pre> | ||
− | + | éåç¹å¥ç CSS 屬æ§å¨éè£¡ä½¿ç¨ '''-moz-box-orient'''ï¼éæå®æéçæ¨ç±¤è©²å¦ä½é¡¯ç¤ºï¼æ°´å¹³ææ¯åç´é¡¯ç¤ºãå·¥å
·åæéæ¨ç±¤çé è¨å¼æ¯åç´é¡¯ç¤ºï¼ä¹å°±æ¯é¡¯ç¤ºå¨å示ä¸æ¹ãå¨éåç¯ä¾ï¼ä¸ä½¿ç¨é樣çæ¹å¼ï¼æ以æåæ¹çºæ°´å¹³é¡¯ç¤ºï¼ä»¥ä½¿æ¨ç±¤é¡¯ç¤ºå¨å示ä¹å¾ã | |
− | + | å¨èçå¯èª¿æ´ç移é§æ¨è¨(resizing gripper)æï¼æå
©æ¢æ¨£å¼è¡¨çè¦åãéè¨å¾å¨ç¬¬åç« è£¡ï¼æåå¨åé¢çå
ç´ (splitter element)使ç¨ç '''vbox''' å
ç´ åï¼æåçºç§»é§æ¨è¨ä½¿ç¨äº '''vbox''' ä¾é¡¯ç¤ºèæ¯ååãé次ï¼æåä½¿ç¨ '''background-image''' 屬æ§ãæåå¿
é èç± '''min-height''' è '''min-width''' 屬æ§ï¼æä¾æå°é«åº¦èæå°å¯¬åº¦ï¼ä»¥è®ç§»é§æ¨è¨é¡¯ç¤ºåºä¾ã'''vbox''' è '''hbox''' 屬æ§çé è¨å¼å¯è½æ¯ä¾å
§å®¹å¤§å°å¤å®ãç±æ¼ '''vbox''' æ¯ç©ºçï¼é è¨å¼å°±æ¯ 0ï¼éä¹é¿å
æåæçå°èæ¯ååã | |
− | + | æåä¹çºåé¢çå
ç´ æä¾ä¸æ¢è¦åã æåè®èæ¯æ¯éæçï¼èä¸ä¸ä½¿ç¨éæ¡(åé¢å
ç´ çé è¨å¼æ¯æ使ç¨éæ¡ç)ãç¾å¨ï¼CSS æªæ¡å·²ç¶å®æï¼æåè¦è¨å®è¦è¼(overlay)以使ç¨å®ã | |
− | == | + | == 使ç¨æ¨£å¼è¡¨ (Using the Style Sheet) == |
− | + | åªæä¸è¡ç¨å¼ç¢¼æ¯éè¦è¢«å å
¥å¨ XUL è¦è¼çï¼éç¨ä¾ååæååå建ç«ç樣å¼è¡¨ãéå¿
é æ¾ç½®å¨ XML 宣åæ令çä¸æ¹ï¼ä»¥åè¦è¼(overlay)å
ç´ ä¹åãä¸é¢ï¼æååºè¦è¼æªæ¡çåå¹¾è¡éè¦æ´åçå°æ¹ï¼ | |
<pre> | <pre> | ||
<?xml version="1.0"?> | <?xml version="1.0"?> | ||
行 847: | 行 848: | ||
(... rest of XUL overlay file ...)</pre> | (... rest of XUL overlay file ...)</pre> | ||
− | + | å°±åæåå¨æ¨£å¼è¡¨ä¸çå°çååä¸æ¨£ï¼chrome è·¯å¾è¢«ç¨ä¾æå®ä½ç½®ãè '''type''' 屬æ§åªæ¯ææéæ¯ CSS çæªæ¡ãç¾å¨è®æåççè¦è¼æªæ¡å¨å å
¥éä¸è¡å¾çå®æ´å
§å®¹[[http://www.borngeek.com/firefox/toolbar-tutorial/samples/xul-f.txt View XUL Overlay Revision 6]]ï¼ | |
<pre> | <pre> | ||
<?xml version="1.0"?> | <?xml version="1.0"?> | ||
行 920: | 行 921: | ||
</overlay> | </overlay> | ||
</pre> | </pre> | ||
− | + | å¥å¿è¨è¦æ¸¬è©¦ï¼ç¨[http://wiki.moztw.org/index.php/%E5%A5%97%E4%BB%B6%E9%96%8B%E7%99%BC%E6%8C%87%E5%8D%97_-_Googlebar_Lite#.E7.AC.AC.E5.9B.9B.E7.AB.A0.EF.BC.9A.E5.8B.95.E6.85.8B.E9.96.8B.E7.99.BC_.28Dynamic_Development.29 åæ
éç¼]ç Firefox å¯æ¬éåï¼ç¶å¾ççå¥ä»¶ç樣åãæ¥ä¸ä¾ï¼æåè¦çºå·¥å
·å注å
¥çå½ã | |
− | = | + | = 第å
ç« ï¼ä¸»ç¨å¼ (Scripting the Toolbar) = |
− | + | å¥ä»¶é常æ¯ç¨ JavaScript å·è¡çï¼éæ¯ä¸ç¨®ç°¡å®æå¸çç¨å¼èªè¨ãä½ å°æç¼ç¾ï¼æåçå·¥å
·åå¥ä»¶çç¨å¼ç¢¼æ¯é常簡å®çãæåå°æ大é使ç¨æ件ç©ä»¶æ¨¡å(DOM)ï¼éå¯ä»¥è®æåèçå®ç¨çå
ç´ ã | |
− | + | å¨æåéå§åï¼ä½ è¦å
ç¥éä¸åéé»ã'''id''' 屬æ§å¿
é æ¯æ´åç覽å¨å¯ä¸çï¼è JavaScript çè®æ¸åå½å¼ä¹æ¯ãå¨ç覽å¨è¦è¼ä¸çJavaScript æ¯å
¨åæ§çï¼å æ¤æææéåéå¶ãæåå°æ使ç¨è· XUL å
ç´ ä¸æ¨£çæå·§ï¼ææçè®æ¸åå½å¼çå稱ï¼å°ææ以æåå¥ä»¶çºåèµ·å§å稱ãæåä½¿ç¨ '''TutTB_''' ç¶ä½èµ·å§å稱ï¼æ以æåçæå°å½å¼ææ¯ '''TutTB_Search()'''ã | |
− | + | ç¾å¨ï¼è®æåå»ºç« JavaScript æªæ¡ãå¨ '''content''' ç®éä¸ï¼å»ºç«ä¸å '''tuttoolbar.js''' çæåæªãç®éçµæ§å¦ä¸ï¼ | |
<pre> | <pre> | ||
行 947: | 行 948: | ||
</pre> | </pre> | ||
− | + | å¨å»ºç«ä»»ä½ç¨å¼ç¢¼åï¼å
å訴 XUL æªæ¡è©²å¦ä½ä½¿ç¨ JavaScript æªæ¡ã | |
− | == | + | == é£çµ XUL è JavaScript (Tying XUL to JavaScript) == |
− | + | æåç XUL æªæ¡ '''tuttoolbar.xul''' éè¦è¢«åç¥ç¸å°æç JavaScript æªï¼æåå¯ä»¥ä½¿ç¨ä¸é¢çæè¿°ï¼ | |
<pre> | <pre> | ||
行 957: | 行 958: | ||
src="chrome://tuttoolbar/content/tuttoolbar.js" /> | src="chrome://tuttoolbar/content/tuttoolbar.js" /> | ||
</pre> | </pre> | ||
− | + | éå¿
é æ¾ç½®å¨ '''overlay''' å
ç´ ä¹ä¸ã'''type''' 屬æ§æ¯æå®ä½¿ç¨ JavaScriptï¼'''src''' 屬æ§æ¯æå®åå建ç«ç JavaScript æªãå
§å®¹å¦ä¸[[http://www.borngeek.com/firefox/toolbar-tutorial/samples/xul-g.txt View XUL Overlay Revision 7]]ï¼ | |
<pre> | <pre> | ||
行 1,035: | 行 1,036: | ||
</pre> | </pre> | ||
− | == | + | == çºæéå ä¸åè½ (Adding Functionality to the Buttons) == |
− | + | éè¨å¾æåçºå·¥å
·åæéæä¾ç '''oncommand''' 屬æ§åï¼éå屬æ§æ¯æå®ç¨å¼ç¢¼å·è¡çäºä»¶ãæåä¹å¯ä»¥ä½¿ç¨ '''onclick''' ä»£æ¿ '''oncommand'''ï¼ä½æ¯ '''onclick''' å°éµç¤ç¡æï¼è '''oncommand''' å¯ä»¥åæåæéµç¤èæ»é¼ çåä½ãè®æåå顧ä¸ä¸æå°æéï¼ | |
<pre> | <pre> | ||
行 1,043: | 行 1,044: | ||
</pre> | </pre> | ||
− | + | éåå¼å¼å« '''TutTB_Search()''' å½å¼ï¼å
¶ä¸å
å«å
©åå¼ï¼éåå½å¼å¼å«çäºä»¶(event)ï¼ä»¥åæå°ç網é (web)ã | |
− | + | ç¨å¼ç¢¼å¦ä¸[[http://www.borngeek.com/firefox/toolbar-tutorial/samples/js-a.txt View JavaScript Revision 1]]ï¼ | |
<pre> | <pre> | ||
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
− | // TutTB_Search() | + | // TutTB_Search() å½å¼æçºæåå®ææå°ãevent åæ¸æ觸ç¼å½å¼çå¼å«ï¼type åæ¸ |
− | // | + | // çºæå°çé¡åã |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
function TutTB_Search(event, type) | function TutTB_Search(event, type) | ||
{ | { | ||
− | // | + | // å°è¦ç覽ç網å |
var URL = ""; | var URL = ""; | ||
− | // | + | // 辨å¥æå°æ¬ä½æ¯å¦çºç©ºå¼ |
var isEmpty = false; | var isEmpty = false; | ||
− | // | + | // èçæå°æ¬ä½ ( <menulist> å
ç´ ) |
var searchTermsBox = document.getElementById("TutTB-SearchTerms"); | var searchTermsBox = document.getElementById("TutTB-SearchTerms"); | ||
− | // | + | // å¾æå°æ¬ä½ååºå串ï¼æ´çå¿
è¦çç©ºç½ |
− | // | + | // å¯ä»¥å¨ä¸é¢çç TutTB_TrimString() å½å¼éä½çç´°ç¯ |
var searchTerms = TutTB_TrimString(searchTermsBox.value); | var searchTerms = TutTB_TrimString(searchTermsBox.value); | ||
行 1,073: | 行 1,074: | ||
searchTerms = TutTB_ConvertTermsToURI(searchTerms); | searchTerms = TutTB_ConvertTermsToURI(searchTerms); | ||
− | // | + | // é¸ææå°çé¡å |
− | // | + | // å¦ææ¬ä½æ¯ç©ºç½çï¼æåæå¼å°ä½¿ç¨è
å° Google 網é ä¸é©ç¶çå°æ¹ã |
− | // | + | // å¦åï¼æå°è¼¸å
¥çæåã |
switch(type) | switch(type) | ||
{ | { | ||
− | // | + | // 建ç«åçæå°ç網å |
case "image": | case "image": | ||
if(isEmpty) { URL = "http://images.google.com/"; } | if(isEmpty) { URL = "http://images.google.com/"; } | ||
行 1,086: | 行 1,087: | ||
− | // | + | // 建ç«ç¶²é æå°ç網å |
case "web": | case "web": | ||
default: | default: | ||
行 1,094: | 行 1,095: | ||
} | } | ||
− | // | + | // ä½¿ç¨ TutTB_LoadURL å½å¼å¨ç覽è¦çªä¸è¼å
¥ç¶²å |
TutTB_LoadURL(URL); | TutTB_LoadURL(URL); | ||
} | } | ||
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
− | // TutTB_TrimString() | + | // TutTB_TrimString() å½å¼æä¿®åªå串çåå¾ç©ºç½é¨ä»½ï¼ç¶å¾å°ææç空ç½é¨ä»½è½ææ |
− | // | + | // å®ä¸å空ç½ï¼ç¶å¾å³åä¿®æ¹å¾å串ã |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
function TutTB_TrimString(string) | function TutTB_TrimString(string) | ||
{ | { | ||
− | // | + | // å¦æå³å
¥çå串ç¡æï¼ææ¯æ²ææ±è¥¿ï¼åå³åç©ºå¼ |
if (!string) | if (!string) | ||
return ""; | return ""; | ||
行 1,111: | 行 1,112: | ||
string = string.replace(/\s+$/, ''); // Remove trailing whitespace | string = string.replace(/\s+$/, ''); // Remove trailing whitespace | ||
− | // | + | // å°ææ空ç½é¨ä»½ç¨å®ä¸ç©ºç½ä»£æ¿ |
string = string.replace(/\s+/g, ' '); | string = string.replace(/\s+/g, ' '); | ||
− | return string; // | + | return string; // å³åæ¹è®å¾çå¼ |
} | } | ||
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
− | // TutTB_ConvertTermsToURI() | + | // TutTB_ConvertTermsToURI() å½å¼å°å³å
¥çæå°å串è½æçºå®å
¨ç網å |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
function TutTB_ConvertTermsToURI(terms) | function TutTB_ConvertTermsToURI(terms) | ||
{ | { | ||
− | // | + | // 建ç«é£ååæ¾æ¯åæå°å串 |
var termArray = new Array(); | var termArray = new Array(); | ||
− | // | + | // ç¨ç©ºç½åå
åå²å串 |
termArray = terms.split(" "); | termArray = terms.split(" "); | ||
− | // | + | // ç¨ä¾åæ¾å®å
¨ç網å |
var result = ""; | var result = ""; | ||
− | // | + | // å¨å串ä¸éè¿´ |
for(var i=0; i<termArray.length; i++) | for(var i=0; i<termArray.length; i++) | ||
{ | { | ||
− | // | + | // å¨ç¬¬ä¸åå串å¾çææçå串æç¨å è(+)éé |
if(i > 0) | if(i > 0) | ||
result += "+"; | result += "+"; | ||
− | // | + | // ä½¿ç¨ Firefox å
§å»ºç encodeURIComponent() å½å¼å å¯ |
result += encodeURIComponent(termArray[i]); | result += encodeURIComponent(termArray[i]); | ||
} | } | ||
− | return result; // | + | return result; // å³åçµæ |
} | } | ||
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
− | // TutTB_LoadURL() | + | // TutTB_LoadURL() å½å¼å¨ç覽å¨ä¸è¼å
¥ç¹å®ç網å |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
function TutTB_LoadURL(url) | function TutTB_LoadURL(url) | ||
{ | { | ||
− | // | + | // å¨ç¶²ååè¨å®å³å
¥ç網å |
window._content.document.location = url; | window._content.document.location = url; | ||
行 1,158: | 行 1,159: | ||
</pre> | </pre> | ||
− | + | éåä½ ç Firefox éç¼çæ¬ï¼å¨æåçå·¥å
·åå¥ä»¶è¼¸å
¥æå°çå¼ï¼ç¶å¾æä¸ç¶²é æå°æéãç¨å¼ç¢¼æ該æå·è¡ï¼ç¶å¾æåºç¾æå°çµæãéååæ
éç¼çæ¬ç¢ºå¯¦æ¯ç¸ç¶ä¾¿å©çå§ï¼ | |
− | == | + | == æéé¸å®ç注æäºé
(A Special Note About Button-Menu Buttons) == |
− | + | å¨æåé²å
¥ä¸ä¸å¼µç« ç¯ä¹åï¼æä¸é»éæ¼æéé¸å®æè¦æ³¨æçãåæ³ä¸ä¸ï¼éé¡åçæéæä¾å¯ä»¥é»æçæéèå½åºå¼é¸å®(主è¦ç¯ä¾çºå¾åèåå¾ç覽)ãä¹æ³ä¸ä¸ï¼toolbarbutton 以åå
å« oncommand ç menuitem å
ç´ ãç¶å·¥å
·åæéçä¸é¨å被ååï¼toolbarbutton å
ç´ ç oncommand ç¨å¼ç¢¼å¦ä½ æææç被å·è¡ãä½æ¯ï¼ç¶ä½¿ç¨è
ååäºmenuitem å
ç´ çå
¶ä¸ä¸åæï¼æç¼çä»éº¼äºï¼ | |
− | + | ä¸åªæ¯ menuitem å
ç´ ç oncommand äºä»¶å·è¡ï¼toolbarbutton å
ç´ çäºä»¶ä¹è¢«å·è¡ãæ以å
©åäºä»¶æ¯åæå·è¡çï¼åç®¡ä½ åªæ¯æ³è¦å
¶ä¸ä¸ä»¶è¢«å·è¡ãå çº toolbarbutton äºä»¶æ¯æå¾ç¼ççï¼æ以實éå·è¡çæ¯ toolbarbutton äºä»¶ãæå¥è©±èªªï¼menuitem äºä»¶æ²ææ©æå·è¡ãé£æåè¦æ樣解決éååé¡å¢ï¼äºå¯¦ä¸ï¼æ¯æ辦æ³çãè®æåå¾åçç menuitem å
ç´ ï¼ | |
<pre> | <pre> | ||
行 1,172: | 行 1,173: | ||
</pre> | </pre> | ||
− | + | èç±ä½¿ç¨ DOM å½å¼ preventBubble()ï¼æåå¯ä»¥é¿å
oncommand 被å·è¡ãçºäºé¿å
å¤é·å¤¢å¤ï¼è¨ä½ä¸ä»¶äºï¼ç¶ä½ 建ç«æéé¸å®æï¼è¨å¾å¨ menuitem å
ç´ ç oncommand 屬æ§å å
¥ '''event.preventBubble()'''ã | |
− | == | + | == çºæå°åå å
¥åè½ (Adding Functionality to the Search Box) == |
− | + | ç¾å¨ï¼æåå·²ç¶è®æå°æéå¯ä»¥ä½¿ç¨ï¼æ¥ä¸ä¾ï¼æåéè¦å¹«æå°åå å
¥ä¸äºåè½ãè®ä½¿ç¨è
å¯ä»¥å¨è¼¸å
¥å串å¾æä¸ãEnterã以å·è¡æå°ãè¦æ麼åå¢ï¼è®æåççè¦ä½¿ç¨çå½å¼ï¼ | |
<pre> | <pre> | ||
行 1,188: | 行 1,189: | ||
</pre> | </pre> | ||
− | + | é次ï¼æåä½¿ç¨ onkeypress ä»£æ¿ oncommandãéåäºä»¶æå¨ä½¿ç¨è
å¨æå°åæä¸æéµæ觸ç¼ãå¨éåç¯ä¾ï¼æå建ç«ä¸åç¸ç¶ç°¡å®ç '''TutTB_KeyHandler()'''å½å¼ï¼ | |
<pre> | <pre> | ||
行 1,198: | 行 1,199: | ||
</pre> | </pre> | ||
− | + | éåå½å¼åªä¸éæ¯è¦æª¢æ¥ãEnterãæ¯å¦è¢«æä¸ãå¦ææ¯ï¼TutTB_Search()æ被å¼å«ãå¦åï¼ä¸åä»»ä½äºãè®æåä¾ççå å
¥æ¤å½å¼ç JavaScript æªæ¡[[http://www.borngeek.com/firefox/toolbar-tutorial/samples/js-b.txt View JavaScript Revision 2]]ï¼ | |
<pre> | <pre> | ||
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
− | // TutTB_Search() | + | // TutTB_Search() å½å¼æçºæåå®ææå°ãevent åæ¸æ觸ç¼å½å¼çå¼å«ï¼type åæ¸ |
− | // | + | // çºæå°çé¡åã |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
function TutTB_Search(event, type) | function TutTB_Search(event, type) | ||
{ | { | ||
− | // | + | // å°è¦ç覽ç網å |
var URL = ""; | var URL = ""; | ||
− | // | + | // 辨å¥æå°æ¬ä½æ¯å¦çºç©ºå¼ |
var isEmpty = false; | var isEmpty = false; | ||
− | // | + | // èçæå°æ¬ä½ ( <menulist> å
ç´ ) |
var searchTermsBox = document.getElementById("TutTB-SearchTerms"); | var searchTermsBox = document.getElementById("TutTB-SearchTerms"); | ||
− | // | + | // å¾æå°æ¬ä½ååºå串ï¼æ´çå¿
è¦çç©ºç½ |
− | // | + | // å¯ä»¥å¨ä¸é¢çç TutTB_TrimString() å½å¼éä½çç´°ç¯ |
var searchTerms = TutTB_TrimString(searchTermsBox.value); | var searchTerms = TutTB_TrimString(searchTermsBox.value); | ||
− | if(searchTerms.length == 0) // | + | if(searchTerms.length == 0) // æå°æ¬ä½æ¯ç©ºç½çåï¼ |
− | isEmpty = true; // | + | isEmpty = true; // æ¯ï¼è¨å® isEmpty çº true |
− | else // | + | else // ä¸ï¼è½æçºå®å
¨ç網å |
searchTerms = TutTB_ConvertTermsToURI(searchTerms); | searchTerms = TutTB_ConvertTermsToURI(searchTerms); | ||
− | // | + | // é¸ææå°çé¡å |
− | // | + | // å¦ææ¬ä½æ¯ç©ºç½çï¼æåæå¼å°ä½¿ç¨è
å° Google 網é ä¸é©ç¶çå°æ¹ã |
− | // | + | // å¦åï¼æå°è¼¸å
¥çæåã |
switch(type) | switch(type) | ||
{ | { | ||
− | // | + | // 建ç«åçæå°ç網å |
case "image": | case "image": | ||
if(isEmpty) { URL = "http://images.google.com/"; } | if(isEmpty) { URL = "http://images.google.com/"; } | ||
行 1,239: | 行 1,240: | ||
− | // | + | // 建ç«ç¶²é æå°ç網å |
case "web": | case "web": | ||
default: | default: | ||
行 1,247: | 行 1,248: | ||
} | } | ||
− | // | + | // ä½¿ç¨ TutTB_LoadURL å½å¼å¨ç覽è¦çªä¸è¼å
¥ç¶²å |
TutTB_LoadURL(URL); | TutTB_LoadURL(URL); | ||
} | } | ||
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
− | // TutTB_TrimString() | + | // TutTB_TrimString() å½å¼æä¿®åªå串çåå¾ç©ºç½é¨ä»½ï¼ç¶å¾å°ææç空ç½é¨ä»½è½ææ |
− | // | + | // å®ä¸å空ç½ï¼ç¶å¾å³åä¿®æ¹å¾å串ã |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
function TutTB_TrimString(string) | function TutTB_TrimString(string) | ||
{ | { | ||
− | // | + | // å¦æå³å
¥çå串ç¡æï¼ææ¯æ²ææ±è¥¿ï¼åå³åç©ºå¼ |
if (!string) | if (!string) | ||
return ""; | return ""; | ||
行 1,264: | 行 1,265: | ||
string = string.replace(/\s+$/, ''); // Remove trailing whitespace | string = string.replace(/\s+$/, ''); // Remove trailing whitespace | ||
− | // | + | // å°ææ空ç½é¨ä»½ç¨å®ä¸ç©ºç½ä»£æ¿ |
string = string.replace(/\s+/g, ' '); | string = string.replace(/\s+/g, ' '); | ||
− | return string; // | + | return string; // å³åæ¹è®å¾çå¼ |
} | } | ||
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
− | // TutTB_ConvertTermsToURI() | + | // TutTB_ConvertTermsToURI() å½å¼å°å³å
¥çæå°å串è½æçºå®å
¨ç網å |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
function TutTB_ConvertTermsToURI(terms) | function TutTB_ConvertTermsToURI(terms) | ||
{ | { | ||
− | // | + | // 建ç«é£ååæ¾æ¯åæå°å串 |
var termArray = new Array(); | var termArray = new Array(); | ||
− | // | + | // ç¨ç©ºç½åå
åå²å串 |
termArray = terms.split(" "); | termArray = terms.split(" "); | ||
− | // | + | // ç¨ä¾åæ¾å®å
¨ç網å |
var result = ""; | var result = ""; | ||
− | // | + | // å¨å串ä¸éè¿´ |
for(var i=0; i<termArray.length; i++) | for(var i=0; i<termArray.length; i++) | ||
{ | { | ||
− | // | + | // å¨ç¬¬ä¸åå串å¾çææçå串æç¨å è(+)éé |
if(i > 0) | if(i > 0) | ||
result += "+"; | result += "+"; | ||
− | // | + | // ä½¿ç¨ Firefox å
§å»ºç encodeURIComponent() å½å¼å å¯ |
result += encodeURIComponent(termArray[i]); | result += encodeURIComponent(termArray[i]); | ||
} | } | ||
− | return result; // | + | return result; // å³åçµæ |
} | } | ||
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
− | // TutTB_LoadURL() | + | // TutTB_LoadURL() å½å¼å¨ç覽å¨ä¸è¼å
¥ç¹å®ç網å |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
function TutTB_LoadURL(url) | function TutTB_LoadURL(url) | ||
{ | { | ||
− | // | + | // å¨ç¶²ååè¨å®å³å
¥ç網å |
window._content.document.location = url; | window._content.document.location = url; | ||
行 1,311: | 行 1,312: | ||
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
− | // TutTB_KeyHandler() | + | // TutTB_KeyHandler() 檢æ¥ãEnterãæ¯å¦è¢«è¼¸å
¥ãæ¯ç話ï¼å°±å·è¡æå° |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
function TutTB_KeyHandler(event) | function TutTB_KeyHandler(event) | ||
{ | { | ||
− | // [ENTER] | + | // [ENTER]被æä¸äºåï¼å¦ææ¯ï¼å·è¡æå° |
if(event.keyCode == event.DOM_VK_RETURN) | if(event.keyCode == event.DOM_VK_RETURN) | ||
TutTB_Search(event, 'web'); | TutTB_Search(event, 'web'); | ||
行 1,321: | 行 1,322: | ||
</pre> | </pre> | ||
− | + | å¨ä¸æ¬¡ï¼å·è¡ä½ ç Firefox éç¼çæ¬ï¼å¨æå°å輸å
¥æå°å串ï¼ç¶å¾æä¸ãEnterããå°±åæ¯æä¸æå°æéä¸æ¨£ï¼æå°çµææ該æåºç¾ãç¾å¨ï¼æåçå¥ä»¶å·²ç¶æäºçå½ï¼ | |
− | == | + | == åæ
ç½®å
¥é¸å® (Dynamically Populating a Menu) == |
− | + | åæ
çå°é¸å®é
ç®æ¾ç½®å¨é¸å®è£¡æ¯å¾æç¨çï¼é好éåç¹è²æ¯å¾å®¹æå®æçãå¨éåæå裡ï¼æåå°æå¨æå°åä¸æå¼é¸å®åæ
çå å
¥ä¸äºé
ç®ãè®æåççç¨ä¾å»ºç«å·¥å
·åçé¨ä»½ï¼ | |
<pre> | <pre> | ||
行 1,337: | 行 1,338: | ||
</pre> | </pre> | ||
− | + | 注æå°ï¼å¨ menupopup å
ç´ ç onpopupshowing 屬æ§ãæåæå® TutTB_Populate()å½å¼å¨æ¯æ¬¡ãå½åºå¼é¸å®ãå³å°é¡¯ç¤ºæ被å·è¡ï¼éåå½å¼å°æ建ç«æåçåæ
é¸å®é
ç®ãè®æåä¾ççå½å¼çç¨å¼ç¢¼[[http://www.borngeek.com/firefox/toolbar-tutorial/samples/js-populate.txt View TutTB_Populate() Code]]ï¼ | |
<pre> | <pre> | ||
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
− | // TutTB_Populate() | + | // TutTB_Populate() å½å¼å¨å·¥å
·åæ¬ä½çä¸æå¼é¸å®æ¾ç½®åæ
ç¢ççé¸å®é
ç®ã |
− | // | + | // éç¶éä¸æ¯é常實ç¨çï¼ä½æ¯èç±éåç¯ä¾ï¼æåå¯ä»¥ççåæ
é¸å®ç½®å
¥çéä½æ¹å¼ã |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
function TutTB_Populate() | function TutTB_Populate() | ||
{ | { | ||
− | // | + | // åå¾å½åºé¸å®å
ç´ |
var menu = document.getElementById("TutTB-SearchTermsMenu"); | var menu = document.getElementById("TutTB-SearchTermsMenu"); | ||
− | // | + | // 移é¤å¨å½åºé¸å®ç®åçé
ç® |
for(var i=menu.childNodes.length - 1; i >= 0; i--) | for(var i=menu.childNodes.length - 1; i >= 0; i--) | ||
{ | { | ||
行 1,355: | 行 1,356: | ||
} | } | ||
− | // | + | // æå®è¦å¨é¸å®å¢å çé
ç®æ¸é |
var numItemsToAdd = 10; | var numItemsToAdd = 10; | ||
for(var i=0; i<numItemsToAdd; i++) | for(var i=0; i<numItemsToAdd; i++) | ||
{ | { | ||
− | // | + | // 建ç«è¦å¢å çæ°é¸å®é
ç® |
var tempItem = document.createElement("menuitem"); | var tempItem = document.createElement("menuitem"); | ||
− | // | + | // è¨å®æ°é¸å®é
ç®çæ¨ç±¤ |
tempItem.setAttribute("label", "Dynamic Item Number " + (i+1)); | tempItem.setAttribute("label", "Dynamic Item Number " + (i+1)); | ||
− | // | + | // å¨é¸å®ä¸æ°å¢é
ç® |
menu.appendChild(tempItem); | menu.appendChild(tempItem); | ||
} | } | ||
行 1,372: | 行 1,373: | ||
</pre> | </pre> | ||
− | + | éåå½å¼ç¯ä¾ä¸æå½ä»¤æ¯å menuitem å
ç´ å»å·è¡é¸æçæ令ãçºäºè®æ¯å menuitem ç¥éæ該å·è¡çæ令ï¼æåå
å
åªè¦å å
¥ setAttribute()å½å¼ä¾èçäºä»¶åå·è¡ç¨å¼ç¢¼ãéæ¯èç oncommand äºä»¶çç¯ä¾ï¼ | |
<pre> | <pre> | ||
行 1,378: | 行 1,379: | ||
</pre> | </pre> | ||
− | + | å å
¥ TutTB_Populate()å½å¼å¾ç JavaScript æªæ¡[[http://www.borngeek.com/firefox/toolbar-tutorial/samples/js-c.txt View JavaScript Revision 3]]ï¼ | |
<pre> | <pre> | ||
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
− | // TutTB_Search() | + | // TutTB_Search() å½å¼æçºæåå®ææå°ãevent åæ¸æ觸ç¼å½å¼çå¼å«ï¼type åæ¸ |
− | // | + | // çºæå°çé¡åã |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
function TutTB_Search(event, type) | function TutTB_Search(event, type) | ||
{ | { | ||
− | // | + | // å°è¦ç覽ç網å |
var URL = ""; | var URL = ""; | ||
− | // | + | // 辨å¥æå°æ¬ä½æ¯å¦çºç©ºå¼ |
var isEmpty = false; | var isEmpty = false; | ||
− | // | + | // èçæå°æ¬ä½ ( <menulist> å
ç´ ) |
var searchTermsBox = document.getElementById("TutTB-SearchTerms"); | var searchTermsBox = document.getElementById("TutTB-SearchTerms"); | ||
− | // | + | // å¾æå°æ¬ä½ååºå串ï¼æ´çå¿
è¦çç©ºç½ |
− | // | + | // å¯ä»¥å¨ä¸é¢çç TutTB_TrimString() å½å¼éä½çç´°ç¯ |
var searchTerms = TutTB_TrimString(searchTermsBox.value); | var searchTerms = TutTB_TrimString(searchTermsBox.value); | ||
− | if(searchTerms.length == 0) // | + | if(searchTerms.length == 0) // æå°æ¬ä½æ¯ç©ºç½çåï¼ |
− | isEmpty = true; // | + | isEmpty = true; // æ¯ï¼è¨å® isEmpty çº true |
− | else // | + | else // ä¸ï¼è½æçºå®å
¨ç網å |
searchTerms = TutTB_ConvertTermsToURI(searchTerms); | searchTerms = TutTB_ConvertTermsToURI(searchTerms); | ||
− | // | + | // é¸ææå°çé¡å |
− | // | + | // å¦ææ¬ä½æ¯ç©ºç½çï¼æåæå¼å°ä½¿ç¨è
å° Google 網é ä¸é©ç¶çå°æ¹ã |
− | // | + | // å¦åï¼æå°è¼¸å
¥çæåã |
switch(type) | switch(type) | ||
{ | { | ||
− | // | + | // 建ç«åçæå°ç網å |
case "image": | case "image": | ||
if(isEmpty) { URL = "http://images.google.com/"; } | if(isEmpty) { URL = "http://images.google.com/"; } | ||
行 1,419: | 行 1,420: | ||
− | // | + | // 建ç«ç¶²é æå°ç網å |
case "web": | case "web": | ||
default: | default: | ||
行 1,427: | 行 1,428: | ||
} | } | ||
− | // | + | // ä½¿ç¨ TutTB_LoadURL å½å¼å¨ç覽è¦çªä¸è¼å
¥ç¶²å |
TutTB_LoadURL(URL); | TutTB_LoadURL(URL); | ||
} | } | ||
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
− | // TutTB_TrimString() | + | // TutTB_TrimString() å½å¼æä¿®åªå串çåå¾ç©ºç½é¨ä»½ï¼ç¶å¾å°ææç空ç½é¨ä»½è½ææ |
− | // | + | // å®ä¸å空ç½ï¼ç¶å¾å³åä¿®æ¹å¾å串ã |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
function TutTB_TrimString(string) | function TutTB_TrimString(string) | ||
{ | { | ||
− | // | + | // å¦æå³å
¥çå串ç¡æï¼ææ¯æ²ææ±è¥¿ï¼åå³åç©ºå¼ |
if (!string) | if (!string) | ||
return ""; | return ""; | ||
− | string = string.replace(/^\s+/, ''); // | + | string = string.replace(/^\s+/, ''); // 移é¤åé¢ç©ºç½ |
− | string = string.replace(/\s+$/, ''); // | + | string = string.replace(/\s+$/, ''); // 移é¤å¾é¢ç©ºç½ |
− | // | + | // å°ææ空ç½é¨ä»½ç¨å®ä¸ç©ºç½ä»£æ¿ |
string = string.replace(/\s+/g, ' '); | string = string.replace(/\s+/g, ' '); | ||
− | return string; // | + | return string; // å³åæ¹è®å¾çå¼ |
} | } | ||
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
− | // TutTB_ConvertTermsToURI() | + | // TutTB_ConvertTermsToURI() å½å¼å°å³å
¥çæå°å串è½æçºå®å
¨ç網å |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
function TutTB_ConvertTermsToURI(terms) | function TutTB_ConvertTermsToURI(terms) | ||
{ | { | ||
− | // | + | // 建ç«é£ååæ¾æ¯åæå°å串 |
var termArray = new Array(); | var termArray = new Array(); | ||
− | // | + | // ç¨ç©ºç½åå
åå²å串 |
termArray = terms.split(" "); | termArray = terms.split(" "); | ||
− | // | + | // ç¨ä¾åæ¾å®å
¨ç網å |
var result = ""; | var result = ""; | ||
− | // | + | // å¨å串ä¸éè¿´ |
for(var i=0; i<termArray.length; i++) | for(var i=0; i<termArray.length; i++) | ||
{ | { | ||
− | // | + | // å¨ç¬¬ä¸åå串å¾çææçå串æç¨å è(+)éé |
if(i > 0) | if(i > 0) | ||
result += "+"; | result += "+"; | ||
− | // | + | // ä½¿ç¨ Firefox å
§å»ºç encodeURIComponent() å½å¼å å¯ |
result += encodeURIComponent(termArray[i]); | result += encodeURIComponent(termArray[i]); | ||
} | } | ||
− | return result; // | + | return result; // å³åçµæ |
} | } | ||
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
− | // TutTB_LoadURL() | + | // TutTB_LoadURL() å½å¼å¨ç覽å¨ä¸è¼å
¥ç¹å®ç網å |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
function TutTB_LoadURL(url) | function TutTB_LoadURL(url) | ||
{ | { | ||
− | // | + | // å¨ç¶²ååè¨å®å³å
¥ç網å |
window._content.document.location = url; | window._content.document.location = url; | ||
行 1,491: | 行 1,492: | ||
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
− | // TutTB_KeyHandler() | + | // TutTB_KeyHandler() 檢æ¥ãEnterãæ¯å¦è¢«è¼¸å
¥ãæ¯ç話ï¼å°±å·è¡æå° |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
function TutTB_KeyHandler(event) | function TutTB_KeyHandler(event) | ||
{ | { | ||
− | // [ENTER] | + | // [ENTER]被æä¸äºåï¼å¦ææ¯ï¼å·è¡æå° |
if(event.keyCode == event.DOM_VK_RETURN) | if(event.keyCode == event.DOM_VK_RETURN) | ||
TutTB_Search(event, 'web'); | TutTB_Search(event, 'web'); | ||
行 1,501: | 行 1,502: | ||
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
− | // TutTB_Populate() | + | // TutTB_Populate() å½å¼å¨å·¥å
·åæ¬ä½çä¸æå¼é¸å®æ¾ç½®åæ
ç¢ççé¸å®é
ç®ã |
− | // | + | // éç¶éä¸æ¯é常實ç¨çï¼ä½æ¯èç±éåç¯ä¾ï¼æåå¯ä»¥ççåæ
é¸å®ç½®å
¥çéä½æ¹å¼ã |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
function TutTB_Populate() | function TutTB_Populate() | ||
{ | { | ||
− | // | + | // åå¾å½åºé¸å®å
ç´ |
var menu = document.getElementById("TutTB-SearchTermsMenu"); | var menu = document.getElementById("TutTB-SearchTermsMenu"); | ||
− | // | + | // 移é¤å¨å½åºé¸å®ç®åçé
ç® |
for(var i=menu.childNodes.length - 1; i >= 0; i--) | for(var i=menu.childNodes.length - 1; i >= 0; i--) | ||
{ | { | ||
行 1,515: | 行 1,516: | ||
} | } | ||
− | // | + | // æå®è¦å¨é¸å®å¢å çé
ç®æ¸é |
var numItemsToAdd = 10; | var numItemsToAdd = 10; | ||
for(var i=0; i<numItemsToAdd; i++) | for(var i=0; i<numItemsToAdd; i++) | ||
{ | { | ||
− | // | + | // 建ç«è¦å¢å çæ°é¸å®é
ç® |
var tempItem = document.createElement("menuitem"); | var tempItem = document.createElement("menuitem"); | ||
− | // | + | // è¨å®æ°é¸å®é
ç®çæ¨ç±¤ |
tempItem.setAttribute("label", "Dynamic Item Number " + (i+1)); | tempItem.setAttribute("label", "Dynamic Item Number " + (i+1)); | ||
− | // | + | // å¨é¸å®ä¸æ°å¢é
ç® |
menu.appendChild(tempItem); | menu.appendChild(tempItem); | ||
} | } | ||
行 1,532: | 行 1,533: | ||
</pre> | </pre> | ||
− | == | + | == åæ
å å
¥å·¥å
·åæé (Dynamically Adding Toolbar Buttons) == |
− | + | å å
¥åæ
å·¥å
·åæéå°±è·åæ
ç½®å
¥é¸å®ä¸æ¨£ç°¡å®ï¼èä¸éé常ç¸ä¼¼ãé¦å
ï¼æåéè¦ä¸åå
å«åæ
æéç容å¨ãå¨éå
ï¼ toolbaritem å
ç´ æ¯ä¸é¯çé¸æï¼æ¨è¨å¦ä¸ï¼ | |
<pre> | <pre> | ||
<toolbaritem id="TutTB-DynButtonContainer" /> | <toolbaritem id="TutTB-DynButtonContainer" /> | ||
</pre> | </pre> | ||
− | + | ç¾å¨ï¼å®¹å¨å·²ç¶å¯ä»¥å©ç¨äºï¼æåå¯ä»¥ä½¿ç¨å®ï¼ä¾å å
¥åæ
toolbarbutton å
ç´ ï¼è®æåä¾çä¸ä¸å¯ä»¥è®æåå å
¥åæ
æéçå½å¼ç¯ä¾ï¼ | |
<pre> | <pre> | ||
function TutTB_AddDynamicButtons() | function TutTB_AddDynamicButtons() | ||
{ | { | ||
− | // | + | // åå¾æåå¨ XUL æè¿°ä¸å¢å çå·¥å
·åé
ç®ã容å¨ã |
var container = document.getElementById("TutTB-DynButtonContainer"); | var container = document.getElementById("TutTB-DynButtonContainer"); | ||
− | // | + | // 移é¤ææåå¨çæé |
for(i=container.childNodes.length; i > 0; i--) { | for(i=container.childNodes.length; i > 0; i--) { | ||
container.removeChild(container.childNodes[0]); | container.removeChild(container.childNodes[0]); | ||
} | } | ||
− | // | + | // å¢å äºååæ
æé |
for(var i=0; i<5; i++) { | for(var i=0; i<5; i++) { | ||
var tempButton = null; | var tempButton = null; | ||
行 1,561: | 行 1,562: | ||
} | } | ||
</pre> | </pre> | ||
− | + | éåå½å¼åç½®å
¥åæ
é¸å®é常ç¸ä¼¼ãæåå¾å®¹å¨ä¸ç§»é¤ç¾æçåæ
æéï¼ç¶å¾å å
¥æ°çã | |
− | '''Optional Programming Exercise''' | + | '''Optional Programming Exercise'''ï¼è©¦èç¨éåæ¦å¿µä¾å¢å ãæå°å串æé(search word buttons)ãå°å·¥å
·åãç¶ä½¿ç¨è
å¨æå°å串æééµå
¥æåæï¼åæ
å°å¢å æéå°å·¥å
·åçæå¾ï¼ä¸åæéä¸ååãéå
æå¹¾åæç¤ºï¼ |
− | # | + | # ä½ éè¦å¢å toolbaritem 容å¨å° XUL æè¿°æªçæå¾(right before the toolbarspring element is a good choice)ãç¢ºå® ID æ¯å¯ä¸çã |
− | # | + | # å¨ menulist å
ç´ ä¸ä½¿ç¨ oninput äºä»¶ï¼éåäºä»¶æå¨ä½¿ç¨è
輸å
¥æåæ觸ç¼ã |
− | # | + | # ä½ å¼å«ç JavaScript æåä¸åçäºï¼(a)å¨æå°æ¬ä½ä¸åå¾æå°æå(b)移é¤ææå
å建ç«çåæ
æé(c)以空ç½åéæå°æå(d)çºæ¯åç¨ç«çæå建ç«æéã |
− | + | éå°±æ¯æèç Googlebar Lite çæ¹å¼ã | |
− | == | + | == ééèååæé (Disabling and Enabling Buttons) == |
− | ( | + | (éé¨ä»½åªæ¯åè¨´ä½ æ麼ç¨ï¼å¨éåå·¥å
·åç¯ä¾ä¸¦ä¸æåºç¾)ã |
− | + | ä½ å¶ç¾å¯è½ææ³è¦ééææ¯ååå·¥å
·åæéãèåä¾åï¼Googlebar Lite çé«äº®åº¦æ¨è¨æéä¸æå¨æå°æ¬ä½æ²ææå°å串æç¼çä½ç¨ï¼åªè½å·è¡æ¼ææå°å串æã | |
− | + | ä¸é¢çä¾åæ¯å¦ä½å»ºç«ä¸åå¯ä»¥æ§å¶ééçä¸è¬å·¥å
·åæéãå次æéï¼éä¸æ¯å¯¦ç¨çç¯ä¾ï¼åªæ¯èæéåæææ¯å¯ä»¥åå¾å°çãæ¥èæ¯é¸å®é
ç®çæè¿°æ¨è¨ï¼ | |
<pre> | <pre> | ||
<menuitem label="Toggle Web Search Button" | <menuitem label="Toggle Web Search Button" | ||
行 1,581: | 行 1,582: | ||
oncommand="TutTB_ToggleWebSearchButton()" /> | oncommand="TutTB_ToggleWebSearchButton()" /> | ||
</pre> | </pre> | ||
− | TutTB_ToggleWebSearchButton() | + | TutTB_ToggleWebSearchButton()å½å¼çç¨å¼ç¢¼ï¼ |
<pre> | <pre> | ||
function TutTB_ToggleWebSearchButton() | function TutTB_ToggleWebSearchButton() | ||
行 1,593: | 行 1,594: | ||
} | } | ||
</pre> | </pre> | ||
− | + | é¦å
ï¼æåå°æè趣çå·¥å
·åæéä½¿ç¨ ID å¼ä»¥å getElementById()å½å¼ãåªè¦ææéï¼æåå°±è½ä½¿ç¨ disabled 屬æ§æ§å¶è©²æéç©ä»¶çç¾æçæ
(ååæéé)ãå¦æå¼çº trueï¼å°±ä½¿ç¨ false åæ¶æéééï¼åä¹äº¦ç¶ãFirefox æ幫æåèçæéçééï¼è®è©²æéä¸è½é»æ(note that the button's image may not appeared grayed out: we must rely on skinning for that)ã | |
− | == | + | == åæ
顯示èé±èæé (Dynamically Showing and Hiding Buttons) == |
− | ( | + | (éé¨ä»½åªæ¯åè¨´ä½ æ麼ç¨ï¼å¨éåå·¥å
·åç¯ä¾ä¸¦ä¸æåºç¾)ã |
− | Googlebar Lite | + | Googlebar Lite å
許使ç¨è
é¸ææéå¨å·¥å
·åæçå°ç樣åãä¹å°±æ¯èªªï¼å·¥å
·åå¿
é è½å¤ åæ
ç顯示ææ¯é±èå¯ç¨çæéãéæ¯æåè¦å®æç JavaScriptç¨å¼ç¢¼çæ®µï¼ |
<pre> | <pre> | ||
var TB_Web = document.getElementById("TutTB-Web-Button"); | var TB_Web = document.getElementById("TutTB-Web-Button"); | ||
TB_Web.setAttribute("hidden", !TutTB_ShowWebButton); | TB_Web.setAttribute("hidden", !TutTB_ShowWebButton); | ||
</pre> | </pre> | ||
− | + | é¦å
æåè®å·¥å
·åæéä½¿ç¨ getElementById() å½å¼ï¼ç¶å¾æåå¼å« setAttribute()å½å¼ä¾æ¹è® hidden 屬æ§çå¼ãä½ æç¼ç¾éå hidden å¼è·æå¨ TutTB_ShowWebButton æè¨å®çç¸åãéåå¼æ¯åå¸ææ¨ç±¤(boolean flag)ï¼ç¨ä¾è¾¨å¥ä½¿ç¨è
æ¯å¦æ³è¦çå°ã網é æå°ãæéãå²åå¨éåè®æ¸çå¼ï¼æ¯å¾ä½¿ç¨è
è¨å®ä¸è®åå°çãç¹¼çºé±è®ï¼ä¾ççæåå¦ä½åå°éé»ã | |
− | == | + | == è®åèå²å使ç¨è
è¨å® (Reading and Storing User Preferences) == |
− | ( | + | (éé¨ä»½åªæ¯åè¨´ä½ æ麼ç¨ï¼å¨éåå·¥å
·åç¯ä¾ä¸¦ä¸æåºç¾)ã |
− | + | çºäºè®åæå²åçè¨å®ï¼æåéè¦åå Firefox è¨å®æåä»é¢(preferences service interface)ãæåå¯ä»¥å»ºç«ä¸åè®æ¸ä¾å®æï¼ | |
<pre> | <pre> | ||
const TutTB_PrefService = | const TutTB_PrefService = | ||
行 1,616: | 行 1,617: | ||
getService(Components.interfaces.nsIPrefService); | getService(Components.interfaces.nsIPrefService); | ||
</pre> | </pre> | ||
− | + | ä¸æ¦ååè¨å®ä»é¢ï¼æåå°±å¯ä»¥ç²å¾å¥ä»¶è¨å®çä¸é¨å(i.e. the location in the preferences "registry" where our extension's settings are kept)ï¼ | |
<pre> | <pre> | ||
const TutTB_Branch = TutTB_PrefService.getBranch("tuttoolbar."); | const TutTB_Branch = TutTB_PrefService.getBranch("tuttoolbar."); | ||
</pre> | </pre> | ||
− | + | åè¨éåå¥ä»¶ç¯ä¾çè¨å®èµ·å§æ¼ tuttoolbar æåï¼å æ¤ï¼æåè¨å®å串 getBranch() (å
§å»ºç Fireofx å½å¼) ãéåå½å¼å¯ä»¥è®æåååå¥ä»¶çè¨å®ï¼æå¾å¯ä»¥ç²å¾åå¥é¸é
çå¼ãéæ¯æåååæå°ã顯示網é æå°æéãé¸é
å¯ä»¥åå¾çå¼ï¼ | |
<pre> | <pre> | ||
if(TutTB_Branch.prefHasUserValue("show.button.web")) | if(TutTB_Branch.prefHasUserValue("show.button.web")) | ||
行 1,630: | 行 1,631: | ||
} | } | ||
</pre> | </pre> | ||
− | + | é¦å
ï¼æå測試éåè¨å®æ¯å¦åå¨æ¼è¨å®æ¨¹ççµæ§è£¡ãå¦æåå¨ï¼å°±ç¨ getBoolPref()å½å¼è®åå®çå¼(å²åæ¼ TutTB_ShowWebButton è®æ¸)ãå¦åï¼æåå°±è¨å®çºé è¨å¼(è¨å®ç樹èå
¨åè®æ¸)ã | |
− | + | å²åè¨å®æ¯å¾ç°¡å®çå§ï¼ä½ åªè¦æä¾è¨å®çå稱ï¼ç¶å¾ä½¿ç¨éåå¼ï¼ | |
<pre> | <pre> | ||
TutTB_Branch.setBoolPref("show.button.web", TutTB_ShowWebButton); | TutTB_Branch.setBoolPref("show.button.web", TutTB_ShowWebButton); | ||
</pre> | </pre> | ||
− | + | ãè®åèå²åè¨å®ãç¨ä¾å²åä½ çå¥ä»¶è¨å®æ¯å¾æ¹ä¾¿çæ¹å¼ã大é¨åçå¥ä»¶é½ä½¿ç¨éååè½ï¼æ許å¤å¯ä½¿ç¨çç¯ä¾çèä½ å»ç 究ãå¦å¤ï¼å¯ä»¥çç MozillaZine knowledge base ç[http://kb.mozillazine.org/Dev_:_Using_preferences æç« ]ã | |
− | = | + | = 第ä¸ç« ï¼å°è£ (Packaging the Toolbar) = |
− | + | å°ç®åçºæ¢ï¼æåç¨åæ
éç¼ä¾èçå®è£çé¨ä»½ãä½æ¯ä½¿ç¨è
並ä¸ææ³ç¨é樣çæ¹å¼ä¾å®è£å¥ä»¶ï¼æ以æåå¿
é å°è£æªæ¡æä¸åå®è£æªãæåå°è¦å»ºç«å
©åæªæ¡ï¼XPI å JARãå¥è¢«é樣çæªæ¡å稱給é¨äºï¼ä»ååªä¸éæ¯ç¨ zip å£ç¸®æªæ¡æ ¼å¼å½è£çã | |
− | + | ç¾å¨æ¯å£ç¸®å·¥å
·ç¼æ®åæçæåäºï¼æå人建è°ä½¿ç¨ [http://www.winzip.com/ WinZip] (å½ä»¤å模å¼)ï¼ä½æ¯ç¶²è·¯ä¸ä¹æä¸å°å
è²»çå·¥å
·ãå¨é份æåä¸ ï¼ ææä½¿ç¨ UNIX å£ç¸®å·¥å
·;å¨ Windows ä¸ï¼å¯ä»¥ä½¿ç¨ [http://www.cygwin.com/ Cygwin] ã | |
− | == | + | == æ´æ° Chrome æ¸
å® (Updating the Chrome Manifest) == |
− | + | 第ä¸æ¥å°è£å
å«äºæ´æ° chrome æ¸
å®ã注æï¼å¦æè¦ç¹¼çºåæ
éç¼ï¼ä½ è¦æå
©å chrome æ¸
å®ï¼ä¸åæ¯å°è£ç¨çï¼å¦ä¸åæ¯åæ
éç¼ç¨çãèçéå
©åæªæ¡æ¯å¾éº»ç
©çï¼æ以æååªéå°æåä¸å·²åå¨ç chrome æ¸
å®åèçã注æï¼å¨æåä¿®æ¹æ¸
å®å¾ï¼å°±ä¸è½ç¨å¨åæ
éç¼äºï¼é¤éä½ ä¿®æ¹åä¾ãè®æåå
ä¾åæ¶ä¸ä¸æ¸
å®çå
§å®¹ï¼ | |
<pre> | <pre> | ||
content tuttoolbar chrome/content/ | content tuttoolbar chrome/content/ | ||
overlay chrome://browser/content/browser.xul chrome://tuttoolbar/content/tuttoolbar.xul | overlay chrome://browser/content/browser.xul chrome://tuttoolbar/content/tuttoolbar.xul | ||
skin tuttoolbar classic/1.0 chrome/skin/</pre> | skin tuttoolbar classic/1.0 chrome/skin/</pre> | ||
− | + | æå
©åå°æ¹éè¦ä¿®æ¹ï¼å
çç第ä¸è¡ï¼ | |
<pre> | <pre> | ||
content tuttoolbar jar:chrome/tuttoolbar.jar!/content/</pre> | content tuttoolbar jar:chrome/tuttoolbar.jar!/content/</pre> | ||
− | + | æåå å
¥äºå
©åé
ç®ãé¦å
æ¯ jar: ï¼æ¾ç½®å¨è·¯å¾çåé¢ãéæå® Firefox å¿
é å¾ JAR æªæ¡ä¸ååºå¥ä»¶çå
§å®¹ãåä¾ï¼æåå å
¥ tuttoolbar.jar!/ï¼ä»æ¼ chrome/ å content/ ç®éä¸éï¼éæè¿°äºåªå JAR éè¦è¢«ååºçãéå JAR çæªåå¿
é è¦è·å¥ä»¶çæªåç¸åï¼å樣å°ï¼å¿
é è·æªåä¸æ¨£ä½¿ç¨å°å¯«åé«ã注æï¼é©åèä¸æ¯æåé¯èª¤ï¼éæ¯å¿
è¦çãå¦ä¸åéè¦ä¿®æ¹çè·¯å¾æ¯ skin ï¼ä¾ççä¿®æ¹å¾çå
§å®¹ï¼ | |
<pre> | <pre> | ||
content tuttoolbar jar:chrome/tuttoolbar.jar!/content/ | content tuttoolbar jar:chrome/tuttoolbar.jar!/content/ | ||
行 1,660: | 行 1,661: | ||
skin tuttoolbar classic/1.0 jar:chrome/tuttoolbar.jar!/skin/</pre> | skin tuttoolbar classic/1.0 jar:chrome/tuttoolbar.jar!/skin/</pre> | ||
− | == | + | == å»ºç« JAR æªæ¡ (Creating the JAR File) == |
− | + | 第ä¸åè¦å°è£çæ¯ JAR æªæ¡ãé¦å
æåèç chrome ç®éï¼å
å«äº XULãJavaScriptãCSS 以ååçãæªæ¡çµæ§å¦ä¸ï¼ | |
<pre> | <pre> | ||
+- TutToolbar/ | +- TutToolbar/ | ||
行 1,679: | 行 1,680: | ||
+- web.png | +- web.png | ||
+- tuttoolbar.css</pre> | +- tuttoolbar.css</pre> | ||
− | + | å°è£ JAR ææ¯ XPI æï¼æ容æç¯çé¯èª¤å°±æ¯éºæ¼äºç¸éçæªæ¡ãå¦ææååè£ JAR æªæ¡æ¯åç®éï¼è£¡é¢å
å«äºï¼ | |
<pre> | <pre> | ||
+- content/ | +- content/ | ||
行 1,691: | 行 1,692: | ||
+- web.png | +- web.png | ||
+- tuttoolbar.css</pre> | +- tuttoolbar.css</pre> | ||
− | + | éæ¯æç¨ UNIX å·¥å
·çæ¹å¼(å½ä»¤å模å¼)ï¼ | |
<pre> | <pre> | ||
zip -r tuttoolbar.jar content/* skin/*</pre> | zip -r tuttoolbar.jar content/* skin/*</pre> | ||
− | ( | + | (è¯è
ï¼ä¸è¬ Windows 使ç¨è
å¯ä»¥ç´æ¥å° content å skin ç®é以 zip æ ¼å¼å£ç¸®æå¯æªå .jar çæªæ¡ã) |
− | == | + | == å»ºç« XPI æªæ¡(Creating the XPI File) == |
− | + | å¨å»ºç«å¥½ JAR æªæ¡ä¹å¾ï¼æåå¿
é å»ºç« XPI æªæ¡ï¼éæ¯çæ£ä½ è¦çµ¦ä½¿ç¨è
ç¨çå¥ä»¶å®è£æªãæåå¿
é å¨æä¸å±¤ç®éä¸å»ºç«éåæªæ¡ï¼çµæ§å¦ä¸ï¼ | |
<pre> | <pre> | ||
+- TutToolbar/ | +- TutToolbar/ | ||
行 1,716: | 行 1,717: | ||
+- web.png | +- web.png | ||
+- tuttoolbar.css</pre> | +- tuttoolbar.css</pre> | ||
− | + | è· JAR æªæ¡ä¸æ¨£ï¼XPI å¿
é ç¶æç¸å°çè·¯å¾ãå¨ XPI æªæ¡ä¸ï¼å
å«äºä¸åæªæ¡ï¼å®è£æ¸
å®ãchrome æ¸
å®ååå建ç«ç JAR æªæ¡ãXPI 裡å
å«äºï¼ | |
<pre> | <pre> | ||
+- install.rdf | +- install.rdf | ||
行 1,722: | 行 1,723: | ||
+- chrome/ | +- chrome/ | ||
+- tuttoolbar.jar</pre> | +- tuttoolbar.jar</pre> | ||
− | + | ä½¿ç¨ UNIX å·¥å
·çæ¹å¼ï¼ | |
<pre> | <pre> | ||
zip tuttoolbar.xpi install.rdf chrome.manifest chrome/tuttoolbar.jar</pre> | zip tuttoolbar.xpi install.rdf chrome.manifest chrome/tuttoolbar.jar</pre> | ||
− | == | + | == å¥ä»¶å®è£æ¸¬è©¦ (Installing Your Toolbar Extension) == |
− | + | æäº XPI æªæ¡ä¹å¾ï¼å°±å¯ä»¥éå§å®è£çæ¥é©ãå¨ç¼è¡¨å¥ä»¶åï¼ä½ ä¸å®è¦å
確å®å¥ä»¶å¯ä»¥å®è£ãä¸å¯ä»¥ä½¿ç¨éç¼è¨å®æªä¾æ¸¬è©¦å®è£ï¼å管å¨é£ä»½è¨å®æªå·²ç¶æå¥ä»¶çå®è£çæ¬ãç¨ä½ ä¸è¬ä½¿ç¨çï¼ææ¯å¦ä¸åè¨å®æªï¼ä¾ä¸é¢çæ¥é©ä¾æ¸¬è©¦å®è£ï¼ | |
− | # | + | # æªæ¡ > éåæªæ¡ (ææ¯ç¨ Ctrl+O) ã |
− | # | + | # å¨å°è©±æ¡ä¸ï¼æ¾å°ä½ ç XPI æªæ¡ï¼é»é¸ãéåãã |
− | + | å¦ææ£ç¢ºå°å®æå¾ï¼ä½ æçå°å®è£ç«é¢ãé¸æä½ è¦å®è£å¾ï¼éæ°éå Firefoxãä¹å¾ï¼ä½ æ該æçå°å·¥å
·åäºï¼æåä½ å®æ第ä¸åå·¥å
·åå¥ä»¶ï¼ | |
− | == | + | == å éå°è£éç¨ (Speeding Up the Packaging Process) == |
− | + | æåå°è£å¥ä»¶å¾è®äººåç
©çï¼çºä½ä¸ç¨æè¿°æªä¾å®æå¢ï¼å¦ææå½ä»¤å模å¼ç ZIP å·¥å
·ï¼ä½ å¯ä»¥å°éç¨èªååãä¸é¢çç¯ä¾ä½¿ç¨ DOS æ¹æ¬¡æªå UNIX å£ç¸®å·¥å
·ã | |
− | + | é¦å
建ç«å
©åæåæªï¼æä¸å±¤ç®éç xpizip.txt ï¼å chrome ç®éä¸ç jarzip.txt ã æªæ¡ä¸å
å«äºè¦å°è£çé
ç®ï¼ [[http://www.borngeek.com/firefox/toolbar-tutorial/samples/xpizip.txt View xpizip.txt]] [[http://www.borngeek.com/firefox/toolbar-tutorial/samples/jarzip.txt View jarzip.txt]] | |
− | + | ä¸ä¸æ¥ï¼å¨æä¸å±¤ç®éä¸å»ºç« DOS æ¹æ¬¡æª(.bat)ï¼å
§å®¹å¦ä¸ï¼ | |
<pre> | <pre> | ||
zip -r chrome/tuttoolbar.jar -@ < chrome/jarzip.txt | zip -r chrome/tuttoolbar.jar -@ < chrome/jarzip.txt | ||
zip -r tuttoolbar.xpi -@ < xpizip.txt</pre> | zip -r tuttoolbar.xpi -@ < xpizip.txt</pre> | ||
− | + | å¦ä½ æè¦ï¼éåæè¿°æªç¸ç¶ç°¡å®ãç¶èï¼ä½ çæè¿°æªå¯è½æ¯éåæ´è¤éãæç¨ä¾å»ºç« Googlebar Lite çæè¿°æªå¯ä»¥åæ´å¤äºãå®å¯ä»¥çºæèªåæ´æ°ææççæ¬ä»£èï¼åå®ææªæ¡çå°è£ãéåæè¿°æªæ¯ç¨ Perl å®æçï¼èä¸ä½¿ç¨ 1.0.x çå®è£æ¹æ¡(èé份æåæäºå¾®çä¸å)ãææä¾éåæè¿°æªçµ¦æè趣ç人ï¼[[http://www.borngeek.com/firefox/toolbar-tutorial/samples/build_script.txt View the Googlebar Lite Build Script]]ã | |
== (Ant Support) == | == (Ant Support) == | ||
− | + | å¦æä½ å¯§é¡ä½¿ç¨ Ant ä¾å»ºç«ä½ çå¥ä»¶ï¼å¯ä»¥åè [http://www.borngeek.com/firefox/toolbar-tutorial/samples/ant_build.xml sample XML file] sent in by [http://www.clippingdale.com/ Brett Clippingdale]. éåæè¿°æªæ該è·å®è£æ¸
å®æ¾ç½®å¨åä¸åç®éï¼ç¶å¾ä½¿ç¨ ant æ令ã | |
− | = | + | = 第å
«ç« ï¼æ¸¬è©¦ (Testing Our Extension) = |
− | + | å¨ç¬¬åç« è¨è«çåæ
éç¼å°æ¼å¥ä»¶æ¸¬è©¦æå¾å¤§ç幫å©ï¼ä½æ¯é裡éæä¸äºç«
éæ¯éç¼è
éè¦ç¥éçãJavaScript æ¯å¾é£é¤é¯ç ï¼å¹¸å¥½ Firefox çä¸äºç¹è²å¯ä»¥è®æåé¿å
é£äºæ±äººçè¦ç¤º(æ¤æ alert() å½å¼å¼å«)ã | |
− | == | + | == ç¶ Firefox ææ¯æ該æ麼辦 (What to Do if Firefox Breaks) == |
− | + | ææåå¥ä»¶æç¢çç½é£æ§çé¯èª¤ï¼å°è´ Firefox æçµéåãç¶é種æ
æ³ç¼çæï¼ä½ å¿
é å
檢æ¥å·¥ä½ç®¡çå¡æ¯å¦æç¶æç Firefox å¨å·è¡ä¸ï¼ä¸¦æå®ééãä¸æ¦ç¢ºå®æ²æ Firefox å¨å·è¡ï¼ä½ éè¦ç§»é¤æåé¡çå¥ä»¶ã移é¤çæ¹æ³å決æ¼ä½ æ¯å¦æ£å¨ä½¿ç¨åæ
éç¼ç³»çµ±ã | |
− | + | å¦æä½ æ£å¨ç¨åæ
éç¼ï¼åªè¦ç覽åæ
éç¼è¨å®çå¥ä»¶ç®é(第åç« )ï¼ç¶å¾å°å¥ä»¶çææ¨æªæ¡(tuttoolbar@borngeek.com)移åå°æ«åçä½ç½®ãç¨ä½ çåæ
éç¼è¨å®æªéæ°éå Firefox (å
許å®æ¸
é¤ææ°ç§»é¤çå¥ä»¶)ï¼ ç¶å¾å次ééç覽å¨ãå¨ä½ 解決éåå°è´ Firefox ç¶æçåé¡ä¹å¾ï¼å°ä½ çææ¨æªæ¡ç§»åå°å¥ä»¶ç®éï¼ç¶å¾éæ°éå Firefox ã | |
− | + | å¦æä½ æ²æ使ç¨åæ
éç¼ç話ï¼å°±ç¨ Firefox çå®å
¨æ¨¡å¼ä¾ç§»é¤æåé¡çå¥ä»¶ãä½ å¯ä»¥ç¨å
©ç¨®æ¹å¼ä¾ï¼ | |
− | # | + | # éå§ > ææç¨å¼ > Mozilla Firefox >> Mozilla Firefox (Safe Mode) ã |
− | # | + | # å¨ Firefox æ·å¾ä¸å å
¥ -safe-mode å½ä»¤ååæ¸ã |
− | + | å¨å®å
¨æ¨¡å¼ä¸ï¼ Firefox ä¸æè¼å
¥ä»»ä½å¥ä»¶ææ¯ä¸»é¡ãä¸æ¦å¨å®å
¨æ¨¡å¼ä¸ï¼ä½ å°±å¯ä»¥ä½¿ç¨å¥ä»¶ç®¡çå¡ä¾ç§»é¤æåé¡çå¥ä»¶ãå¨ç§»é¤å¥ä»¶ä¹å¾ï¼è¨å¾å° -safe-mode å½ä»¤ååæ¸ç§»é¤(å¦æä½ å¨æ·å¾ä¸æåå å
¥)ã | |
− | == | + | == æç¨çç覽å¨è¨å® (Useful Browser Settings) == |
− | + | å¨ about:config ä»é¢ä¸ï¼æå
©åè¨å®å¯ä»¥è®ä½ æ´å®¹æéç¼ï¼éæå½±é¿ JavaScript 主æ§å°ç輸åºè¨æ¯ã | |
− | + | 第ä¸åè¨å®æ¯ javascript.options.showInConsole ãç¶è¨å®çº true æï¼ææå¥ä»¶ç¢ççé¯èª¤ææ¯è¦åé½æ被å³éå° JavaScript 主æ§å°ãé è¨å¼æ¯ false ï¼ æä»¥ä½ å¿
é éåå®ãéåè¨å®å°æ¼è¿½è¹¤é¯èª¤æ¯å¾æ¹ä¾¿çã | |
− | + | ä¸ä¸åæ¯ javascript.options.strict ï¼é è¨å¼ä¹æ¯ false ãç¶è¨å®çº true æï¼Firefox ç JavaScript èªæ³æè®æå´è¬¹æ¨¡å¼ï¼å°ä½ çç¨å¼ç¢¼è®æå´æ ¼çç´æãéè®ä½ çç¨å¼ç¢¼æ´å®åï¼ä¹æ´å®¹æ追蹤ç¨å¼ç¢¼é¯èª¤ã | |
− | == JavaScript | + | == JavaScript 主æ§å°ç´é (Logging to the JavaScript Console) == |
− | + | 測試 JavaScript ç¨å¼ç¢¼ç好æ¹æ³å°±æ¯å¨ JavaScript 主æ§å°ä¸å°åºé¤é¯å¼ï¼ä½ å¯ä»¥å¨ ãå·¥å
· > JavaScript 主æ§å°ãéåãæåå¿
é å
å¾å° nsIConsoleService ä»é¢ç實é«(instance)ï¼ä¸é¢æ¯ç¨å¼ç¢¼ççæ®µï¼ | |
<pre> | <pre> | ||
const TutTB_ConsoleService = | const TutTB_ConsoleService = | ||
行 1,784: | 行 1,785: | ||
classes['@mozilla.org/consoleservice;1']. | classes['@mozilla.org/consoleservice;1']. | ||
getService(Components.interfaces.nsIConsoleService);</pre> | getService(Components.interfaces.nsIConsoleService);</pre> | ||
− | + | 注æå°æåç¨äº TutTB_ çåç½®è©ï¼å°±å¦æ使ç¨æ¼ææå½å¼èè®æ¸ä¸æ¨£ãä¸æ¦æååå¾éåæ§å¶å°å¯¦é«(console instance)ï¼æåå°±å¯ä»¥ä½¿ç¨å®ä¾ç·¨å¯«èªå·±çè¨æ¯ãä¸é¢çå½å¼æ幫æåå®æé件äºï¼ | |
<pre> | <pre> | ||
function TutTB_Log(aMessage) | function TutTB_Log(aMessage) | ||
行 1,790: | 行 1,791: | ||
TutTB_ConsoleService.logStringMessage('Tut_Toolbar: ' + aMessage); | TutTB_ConsoleService.logStringMessage('Tut_Toolbar: ' + aMessage); | ||
}</pre> | }</pre> | ||
− | + | 實éä¸ï¼ä½ æ該æ¹è®å¨ä½ çå¥ä»¶ä¸ãMy_Extension:ãçè¨æ¯é¨ä»½å稱ãèç±ä½¿ç¨ä½ çå¥ä»¶å稱ä¾ç¶åç½®è©ï¼ä½ å¯ä»¥æ´å®¹æåå¾åªäºè¨æ¯æ¯è¦ç¥éçãç¾å¨ï¼è®å½å¼ä½ç¨ä¹å¾ï¼æåå¯ä»¥å¨ç¨å¼ç¢¼ä¸çä»»ä¸ä½ç½®ä¾å¼å«å®ï¼ä»¥é¡¯ç¤ºé¤é¯è¨æ¯ï¼ | |
<pre>TutTB_Log("The value of the URL variable is: " + URL);</pre> | <pre>TutTB_Log("The value of the URL variable is: " + URL);</pre> | ||
− | + | è¨å¾ä¸å®è¦å¨ç¼è¡¨ä½ çå¥ä»¶å移é¤éåå½å¼ãä¸ç¶ï¼éä¸åªæ¯éä½ä¸»æ§å°ç´éçé度ï¼éå¢å äºä½¿ç¨è
主æ§å°è¦çªçéå¿
è¦è¨æ¯ãè¦æ´é²ä¸æ¥å°äºè§£ JavaScript 主æ§å°ï¼å¯ä»¥åè [http://kb.mozillazine.org/JavaScript_Console MozillaZine knowledge base article] ã | |
− | == | + | == æ¨æºä¸»æ§å°ç´é (Logging to the Standard Console) == |
− | + | å¦ä¸åç´éé¤é¯è³è¨çæ¹æ³ï¼å°±æ¯ä½¿ç¨æ¨æºä¸»æ§å°çæå·§ãå¨ä½¿ç¨éåæ¹æ³ä¹åï¼æä¸äºç覽å¨çä¿®æ¹å¿
é è¦å
å®æãé¦å
ï¼æåå¿
é å å
¥æ°çç覽å¨è¨å®ï¼å¨ç¶²åå輸å
¥ about:config ï¼ä¸¦æä¸ Enter ãå³éµé»æå表並é¸æ ãæ°å¢ > çåå¼(Boolean)ãä¾å»ºç«ä¸åæ°çå¸æå¼è¨å®ãå°éåå¼è¨å®çº browser.dom.window.dump.enabled ï¼ä¸¦åç¨å®(true)ã | |
− | + | ä¸ä¸æ¥ï¼æ¯å¨ Firefox æ·å¾ä¸å å
¥ -console å½ä»¤å串ã使ç¨éååæ¸ï¼æä½ æ¯æ¬¡å·è¡ Firefox æï¼é¡¯ç¤ºæ¨æºè¼¸åºä¸»æ§å°ãä¸ä½éé
å®æå¾ï¼ Firefox ä¹éåäºï¼ä»»ä½èç± dump() å½å¼ç¢çç輸åºï¼é½æ顯示å¨ä¸»æ§å°è¦çªä¸ãdump()å½å¼å°±å¦ JavaScript æ¨æºç alert() å½å¼ä¸æ¨£ï¼èªæ³ä¹ç¸ä¼¼ã | |
− | == | + | == æ件ç©ä»¶æ¨¡å檢æ¥å¨ (The DOM Inspector) == |
− | + | å°æ¼è¨è¨å·¥å
·åæ大ç幫å©å°±æ¯ DOM (Document Object Model) Inspector ï¼éæ¯ä¸åå¯ä»¥è®ä½ æª¢æ¥ XML æ件(å
å« XUL, HTML)çµæ§çå·¥å
·ãéåå·¥å
·è· Firefox å
è£å¨ä¸èµ·ï¼ä½æ¯é è¨æ¯ä¸å®è£çï¼ä½ å¿
é 使ç¨é²éå®è£ä¾å®è£éåå·¥å
·ãä¸æ¦å¯ä»¥ä½¿ç¨æï¼å°±ææè±å¯çè³è¨å¯ä»¥ç²å¾ï¼æä»¥ä½ è¦å
å¸æå¦ä½ä½¿ç¨å®ã | |
− | + | å¨ä¸äºç¶²é å¯ä»¥æ¾å°é樣çä»ç´¹ï¼ | |
* [http://books.mozdev.org/html/mozilla-app-b-sect-3.html The DOM Inspector] (from Creating Applications with Mozilla) | * [http://books.mozdev.org/html/mozilla-app-b-sect-3.html The DOM Inspector] (from Creating Applications with Mozilla) | ||
* [http://www.mozilla.org/projects/inspector/faq.html DOM Inspector FAQ] | * [http://www.mozilla.org/projects/inspector/faq.html DOM Inspector FAQ] | ||
− | + | éæ¯å¹«å©æåå°æ¾ XUL è¨è¨åé¡çæ好工å
·ï¼å®å¯ä»¥è®ä½ 檢è¦å¤å XUL å
ç´ çèªæ³ãæå¼·ç建è°ä½ å»å¸ç¿å¦ä½ä½¿ç¨éåå·¥å
·ï¼éé»ç¸ç¶å®¹æï¼èä¸ä½ æå°æ¼å¸æ使ç¨éé
å·¥å
·æå°é常å°é«èã | |
− | {{link| | + | {{link|æ件å°æ¡|éç¼äººå¡æ件主é }} |
於 2008年8月12日 (二) 20:48 的修訂
benefit of drinking apple cider vinegar microsoft access data base indiana pacers fight video puppy biting surgery for morbid obesity åæ: Creating a Firefox Toolbar Extension (Firefox 1.5)[å·²ææ¬]
ä½è Born Geek
內容大綱
- 1 åè¨ (Instruction)
- 2 第ä¸ç« ï¼æºåéå§ (Getting Started)
- 3 第äºç« ï¼å»ºç«æ¶æ§(Creating the Framework)
- 4 第ä¸ç« ï¼å»ºæ§å·¥å ·å (Structuring the Toolbar)
- 5 第åç« ï¼åæ éç¼ (Dynamic Development)
- 6 第äºç« ï¼é¢æ¿è£½ä½ (Skinning the Toolbar)
- 7 第å
ç« ï¼ä¸»ç¨å¼ (Scripting the Toolbar)
- 7.1 é£çµ XUL è JavaScript (Tying XUL to JavaScript)
- 7.2 çºæéå ä¸åè½ (Adding Functionality to the Buttons)
- 7.3 æéé¸å®ç注æäºé (A Special Note About Button-Menu Buttons)
- 7.4 çºæå°åå å ¥åè½ (Adding Functionality to the Search Box)
- 7.5 åæ ç½®å ¥é¸å® (Dynamically Populating a Menu)
- 7.6 åæ å å ¥å·¥å ·åæé (Dynamically Adding Toolbar Buttons)
- 7.7 ééèååæé (Disabling and Enabling Buttons)
- 7.8 åæ 顯示èé±èæé (Dynamically Showing and Hiding Buttons)
- 7.9 è®åèå²å使ç¨è è¨å® (Reading and Storing User Preferences)
- 8 第ä¸ç« ï¼å°è£ (Packaging the Toolbar)
- 9 第å
«ç« ï¼æ¸¬è©¦ (Testing Our Extension)
- 9.1 ç¶ Firefox ææ¯æ該æ麼辦 (What to Do if Firefox Breaks)
- 9.2 æç¨çç覽å¨è¨å® (Useful Browser Settings)
- 9.3 JavaScript 主æ§å°ç´é (Logging to the JavaScript Console)
- 9.4 æ¨æºä¸»æ§å°ç´é (Logging to the Standard Console)
- 9.5 æ件ç©ä»¶æ¨¡å檢æ¥å¨ (The DOM Inspector)
åè¨ (Instruction)
é份æåå°èªªæå¦ä½å»ºç« Firefox çå·¥å ·åå¥ä»¶(æ¯æ´ 1.5 ææ´æ°ççæ¬)ã
é份æ件æä¾å¥ä»¶å¦ä½éç¼çæ¦è¦ãå¿ è¦çå·¥å ·ã以å建ç«å·¥å ·åçç´°ç¯ãå¥ä»¶éç¼æ¯ä¸é£çï¼åç®¡å¿ é å ·åæäºåºç¤çç¨å¼è¨è¨ç¥èã
æä¸ç¨®æè¡æ¯æ建è°ä½ å¿ é ç¨å¾®çæçï¼XMLãJavaScriptãCSSãéä¸åæè¡å¸ç¿èµ·ä¾é½ä¸é£ï¼èä¸ç¶²è·¯ä¸æ許å¤ä¸é¯çæå¸ã
Firefox 1.5 çå¨å¥ä»¶éç¼ä¸æå¾å¤§çæ¹åï¼éåçæ¬æ¯å åççæ¬æ´å®¹æ建ç«å¥ä»¶ã é份æåå©ç¨äºæ¹åçé¨ä»½ï¼å¿ è¦æï¼æææåºè®åçé¨ä»½ãå¦æä½ ç¼ç¾é¯èª¤çå°æ¹ï¼ææ¯æä»»ä½å»ºè°ï¼è«è¯çµ¡ä½è ã
第ä¸ç« ï¼æºåéå§ (Getting Started)
éå§ä¹å (Before We Start)
å¨æåéå§è£½ä½ç¬¬ä¸ä»½å·¥å ·åå¥ä»¶ä¹åï¼æä¸äºé常æç¨çæ±è¥¿æ¯ä½ å¿ é è¦å ç¥éçã
ä¸è¼æå (Tutorial Downloads)
å¨é份æåçæå¾ï¼æåå°å»ºç«ä¸å Googlebar Lite çç°¡åçæ¬ãçºäºå°éç¨çå¸ç¿ææ幫å©ï¼ä½ å¯ä»¥ä¸è¼éåå·¥å ·åçéç¼çæ¬ãå ©ä»½å¯å¾å°ççæ¬ï¼
- Example Toolbar XPI : éæ¯æåå°è¦å»ºç«çå¥ä»¶çå®è£çæ¬ã
- Example Toolbar Source Code: é份 zip æªæ¡å å«å»ºç«å·¥å ·åçåå§ç¢¼ã
注æå°é份 xpi æªæ¡ä¹å å«äºåå§ç¢¼ãæè¡ä¸èè¨ï¼ä½ åªè¦ä¸è¼ xpi çæªæ¡ï¼ä¸¦ç¨ zip ç解å£ç¸®ç¨å¼è§£é xpi æªï¼ä»¥åå ¶ä¸ç jar æªã第äºä»½æªæ¡åªæ¯çºäºæ¹ä¾¿èå·²ã
æç¨çåèæç» (Useful References)
æå¼·ç建è°ä½ å°ä¸åç網åå å ¥æ¸ç±¤ï¼å¨æå¸ç¿å¥ä»¶éç¼çéç¨ï¼éäºç¶²é å°æé常çæ幫å©ï¼æç¸ä¿¡å°ä½ ä¾èªªä¹æ¯ã(ååé çºåä½è æä¾)
- XUL Planet Element Reference(è±)
- MozillaZine Extension Development Forum(è±)
- Search the Firefox Source Code(è±)
- roachfiend.com Extension Tutorial(è±)
- Building an Extension - Mozilla Developer Center(è±)
- åææ » Hello Worldââéç¼ä½ ç第ä¸åFirefoxæ´å±(ç°¡)
- limodouçå¸ç¿è¨é - XUL(ç°¡)
- The Art of IT » åºæ¼ Mozilla çæ´å±éç¼(ç°¡)
å¿ éå å¸ç¿ç (Learning the Prerequisites)
å¦æä¹åææå°çï¼Firefox å¥ä»¶éç¼éè¦å ç¥éä¸é»éæ¼ XMLãJavaScriptãåCSS çæè¡ãéä¸å主é¡é½æ¯ç¸ç¶å®¹æäºè§£çï¼æä¹ææä¾äºä¸äºéæ¼éä¸é æè¡ç說æã
ä½ å°æéè¦çå·¥å · (Tools You Will Need)
çºäºè¨è¨å¥ä»¶ï¼ä½ éè¦å¹¾åå·¥å ·è»é«ï¼éäºè»é«é½æ¯å è²»å¯åå¾çãæåè¦è¨è¨çå¹¾åæªæ¡é½æ¯æ¨æºæåæªãå æ¤ï¼ä½ éè¦ä¸åä¸é¯çæå編輯å¨ãæå¼·çåå°ä½¿ç¨é¡ä¼¼ Microsoft Word çç¨å¼ã網路ä¸æä¸äºååºçå è²»ç¨å¼è¨è¨æå編輯å¨ï¼éäºç·¨è¼¯å¨å°ä½ æé常大ç幫å©ï¼ä¾å¦èªå縮æã強調èªæ³ççãå¹¾ååæ¡è¿ç編輯å¨å å« Crimson EditorãTextPadãå JCreatorãEmEditorã
第äºåä½ æç¨å°çå·¥å ·æ¯ zip æªçå£ç¸®è»é«ãéç¶æå ¶ä»éå¤æç¨çå·¥å ·ï¼åæ¯ 7-Zipãå WinRARï¼ä½æå人æ¯ä½¿ç¨ WinZipãç¶å°è£å¥ä»¶æï¼æåæç¨å°éåå·¥å ·ãå¦æä½ æç®åå¾å¤å¥ä»¶çéç¼ï¼æ建è°ä½ æ¾æå½ä»¤åä»é¢çå£ç¸®å·¥å ·ã使ç¨å½ä»¤åå¯ä»¥è¼æå°å°å°è£éç¨èªååï¼ä¹çä¸ä½ 大éçæéã
æªæ¡çµæ§ä½å± (File Structure Layout)
å¥ä»¶éç¼éè¦ç¹å®çå §é¨çµæ§ï¼æ以æåå¿ é 確å®éä¸æ¥æ¯æ£ç¢ºçãå¦åï¼å°ä¸æç¼çä½ç¨ãé¦å ï¼çºæåçå¥ä»¶å»ºç«æä¸å±¤çç®éãå¨é份æåï¼æåæä½¿ç¨ TutToolbar ç¶ä½ç®éå稱(é¿å 使ç¨ç©ºç½æå)ãå¨éåæ°å»ºç«å¥½ç TutToolbar ç®é裡ï¼æåéè¦å建ç«ç¬¬äºåç®éãéåç®éå½åçº chrome (使ç¨å°å¯«) ãæ¢ç¶æåé麼åæ¡å»ºç«ç®éï¼é£å°±åä¾å»ºç«ç¬¬ä¸åå§ï¼éæ¬¡å¨ chrome ç®é裡建ç«ä¸ååç¨±çº content çç®é(使ç¨å°å¯«)ãé裡æ¯æåçç®éçµæ§çèµ·ä¾ç樣åï¼
+- TutToolbar/ +- chrome/ +- content/
æè æ¯
TutToolbar/ TutToolbar/chrome/ TutToolbar/chrome/content/
第äºç« ï¼å»ºç«æ¶æ§(Creating the Framework)
å¥ä»¶çæ¶æ§æ¯ç¨ä¾å訴 Firefox å¥ä»¶æ¯å¦ä½è¢«å»¶ä¼¸çï¼æªæ¡ççµæ§ã被誰建ç«ãææ¯å¥ä»¶çå ¨çå¯ä¸ä»£è(GUID)ãå¨ Firefox 1.5 éåçæ¬ï¼å¥ä»¶éç¼å¨éåé¨ä»½æå¾å¤§çè®åãåæ¬å¨ 1.0.x çæ¯å¾æ²éçæå·§ï¼å¨ 1.5 çå·²ç¶è®å¾æ´æ´æ½ãæ´ç°¡å®ã
å®è£æ¸ å® (Installer Manifest)
éä»½æ¸ å®æ¯ç¨ä¾æä¾ Firefox éæ¼å¥ä»¶çç´°ç¯ãæä¸äºéè¦çé ç®æ¾ç½®å¨éåæªæ¡ï¼æ以æåå¿ é 確å®éé¨ä»½æ¯æ£ç¢ºçãå¨ä½ çæä¸å±¤ç®é裡ï¼å»ºç«ä¸åæªæ¡ install.rdf ãç¶ä½ 建ç«å¥½éåæªæ¡ï¼ä½ æçå°é樣ççµæ§ï¼
+- TutToolbar/ +- install.rdf +- chrome/ +- content/
å¨æåéå·¥åï¼è®æåççéåç¯ä¾ãæææåå¿ é 編輯çé¨ä»½å·²ç¶è¢«çªé¡¯åºä¾äºï¼æ²æ被çªé¡¯çé¨ä»½æ¯ä¸å¯ä»¥ä¿®æ¹çãæ¥èï¼æåä¾çé份æªæ¡çå §å®¹ï¼æå°æ解éæ¯åé¨ä»½çç´°ç¯ï¼èä¸å¯ä»¥éå§ç·¨è¼¯å±¬æ¼èªå·±çå¥ä»¶ã
<?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"> <!-- Required Items --> <em:id>yourextension@yoursite.com</em:id> <em:name>Your Extension's Name</em:name> <em:version>1.0</em:version> <em:targetApplication> <Description> <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <em:minVersion>1.5</em:minVersion> <em:maxVersion>1.5.0.*</em:maxVersion> </Description> </em:targetApplication> <!-- Optional Items --> <em:creator>Your Name</em:creator> <em:description>A description of the extension</em:description> <em:homepageURL>http://www.yoursite.com/</em:homepageURL> </Description> </RDF>
å¨æä¸é¢ç¬¬ä¸è¡è¡¨ç¤ºéæ¯ä¸ä»½ XML æ ¼å¼çæªæ¡ã第äºè¡ï¼ä»¥ <RDF> éé çï¼æ¯é份æ件çåºæ¬å ç´ (root element)ãå®ç責任æ¯è¾¨å¥éé¨ä»½æ¯ RDF (Resource Description Framework) æ ¼å¼ãä¸ä¸åæ¨ç±¤(Tag) <Description> å樣å°æ¯ç¨ä¾è¾¨å¥çºå®è£æ¸ å®ãç¾å¨ï¼ä¹å³çæ±è¥¿é½çµæäºï¼è®æåçç第ä¸é¨ä»½å¿ é è¦ç·¨è¼¯çï¼
<em:id>yourextension@yoursite.com</em:id> <em:name>Your Extension's Name</em:name> <em:version>1.0</em:version>
第ä¸åæåéè¦æå¿çæ¯å¥ä»¶çèå¥è碼ãå¨ Firefox 1.5 ä¹åççæ¬ï¼å¿ é 使ç¨å ¨çå¯ä¸ä»£è(globally unique identifier)ï¼å³ GUIDãå管 GUID éæ¯è¢«æ¯æ´çï¼æ°çæ ¼å¼å»æ´å®¹æ使ç¨ãå å éè¦ä½¿ç¨ä½ çå¥ä»¶å稱ï¼ï¼ 符èï¼åå ä¸ä½ ç網ç«çæä¸å±¤ç¶²åãå¨é份æåä¸ï¼æåçºéåå·¥å ·å使ç¨éåå¼ tuttoolbar@borngeek.com ã
æ¥èæ¯å¥ä»¶çå稱(éæ顯示å¨å¥ä»¶ç®¡çå¡è£¡)ãå¨æåçç¯ä¾è£¡ï¼ä½¿ç¨ Toolbar Tutorial çºéåå¥ä»¶çå稱ã確å®éåå稱ä¸å å«çæ¬ç·¨èï¼å çºçæ¬ç·¨èæå®èªå·±å°å±¬çæ¨ç±¤ãæåè¦ç·¨è¼¯çéåæ¨ç±¤å°±å¨ä¸ä¸è¡ãæ¢ç¶éæ¯æå試åè¦åç第ä¸åå·¥å ·åå¥ä»¶ï¼è®éåå¼çº 1.0 ãè¦æ³¨æå°ï¼å¨ç實çæ æ³è£¡ï¼ç¶ä½ ç¼è¡¨æ°çæ¬çå¥ä»¶æï¼å¿ é æ´æ°éåå¼ï¼æ述解è¯ç¨å¼(Scripter)å¨èªåæ´æ°éç¨æä¸æç¼çåé¡ãå¨æçå¥ä»¶è£¡ï¼æå©ç¨äºæè¿°èªæ³ (以 Perl 寫æ)ãå¨é份æåç第ä¸ç« ï¼æå°æåè¨´ä½ æå¦ä½ä½¿ç¨ã
ä¸ä¸ååå¡ä¹æ¯éåå®è£æ¸ å®éè¦çä¸é¨åï¼æ¥èä¾ççéé¨ä»½ï¼
<em:targetApplication> <Description> <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <em:minVersion>1.5</em:minVersion> <em:maxVersion>1.5.0.*</em:maxVersion> </Description> </em:targetApplication>
éååå¡æ¯ç¨ä¾æ示å¥ä»¶è¦ç¨å¨åªåç¨å¼ãå¨éåä¾åï¼æåè¦éç¼ Firefox çå¥ä»¶ãå æ¤ï¼<em:id> éåå ç´ æå®äº Firefox ç GUID ãä½ ä¸æ該æ¹è®éåå¼ï¼å¦åï¼æè®ä½ çå¥ä»¶ç¡æ³è¢«æ£ç¢ºå°å®è£ã
å¯ä¸å ©åæåéè¦è®åçï¼æ¯éå ©åå ç´ ï¼<em:minVersion> ã <em:maxVersion> ãéå ©åå ç´ ææå¥ä»¶é©åç¨å¨ Firefox çåªåçæ¬ ( minVersion æ¯æä½æ¯æ´çæ¬ï¼è maxVersion æ¯æé«æ¯æ´çæ¬) ã å¨æåçç¯ä¾ï¼æåæä½¿ç¨ 1.5 (minVersion) è 1.5.0.* ï¼maxVersion)ãå çºæåå©ç¨ Firefox 1.5 çéç¼ç°å¢ï¼æ以ä¸å¯ä»¥æ minVersion è¨å®çæ¯ 1.5 éå°ã
注æå°ï¼ä½ æ使ç¨ççæ¬ç·¨èå¿ é éµå®æ¨æºåå®ãèåä¾åï¼ã1.5 Release Candidate 1ãæ¯ä¸è¡çãç®å Firefox ççæ¬çµæ§æ¯ç¸ç¶å´è¬¹çï¼å¨ Mozilla Developer Center çæç« Toolkit Version Format æ詳細çæè¿°ãæ建è°ä½ è®éç¯æç« ï¼ä»¥äºè§£æ樣çå串æ¯è¢«å 許çã
å¨å®è£æ¸ å®çæå¾ï¼æ¯ç¨ä¾æè¿°å¥ä»¶çè³æå®ç¾©ï¼æ稱ä¸ç¹¼è³æ(meta-data)ï¼
<!-- Optional Items --> <em:creator>Your Name</em:creator> <em:description>A description of the extension</em:description> <em:homepageURL>http://www.yoursite.com/</em:homepageURL>
å°±å¦è¨»éä¸æ¨£ï¼éäºå ç´ æ¯éå¿ è¦çã<em:creator> å 許å¥ä»¶ä½è ææèªå·±çååï¼é樣å¥äººå°±ç¥éæ¯èª°è£½ä½éåå¥ä»¶ãä¸ä¸åï¼<em:description> å 許æåå°æåçå¥ä»¶åä¸äºèªªæï¼éå說ææ顯示å¨å¥ä»¶ç®¡çå¡ä¸çå¥ä»¶å稱åºä¸ãæå¾ï¼<em:homepageURL> å 許æåææå¥äººå¯ä»¥å¨åªè£¡æ¾å°æåçå¥ä»¶ã
注æå°ï¼éäºä¸æ¯å¯ä¸çè³æå®ç¾©ï¼åæä¹æ許å¤å ¶ä»å¯é¸ç¨çé ç®ãèåä¾åï¼æåå ç´ å¯ä»¥å¨å¥ä»¶ç®¡çå¡ä¸ä½¿ç¨æåèªå·±çå示(icon)ã å¦ä¸åå ç´ å 許æåæå®èªè¨é¸é çä½ç½®ææ¯ãéæ¼ãçå°è©±è¦çªãå ¨é¨å¯ç¨çå ç´ (ä¹å«åå±¬æ§ properties )ï¼å¯ä»¥ççå¨Mozilla Developer Center ä¸çæç« Installer Manifests ãæå¾ä¸é»è¦æ³¨æçï¼ææçå ç´ æ¯ä¸éè¦æç §é åºçãä¹å°±æ¯èªªï¼ä½ å¯ä»¥å°å®åæ¾å¨æªæ¡ä¸ä»»ä½å°æ¹ï¼å å è¦æ³¨æçæ¯ï¼å°å®åæ¾ç½®å¨ <Description> è </Description> ä¹éã
ç¾å¨ï¼æåäºè§£äºå®è£æ¸ å®ï¼è®æåä¾ççæå¾ç樣åï¼éåçæ¬å°è¢«ä½¿ç¨å¨é份æåä¸ãä½ å¯ä»¥ç´æ¥å°ä¸é¢çé¨ä»½ï¼è¤è£½å¨ 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"> <!-- Required Items --> <em:id>tuttoolbar@borngeek.com</em:id> <em:name>Tutorial Toolbar</em:name> <em:version>1.0</em:version> <em:targetApplication> <Description> <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <em:minVersion>1.5</em:minVersion> <em:maxVersion>1.5.0.*</em:maxVersion> </Description> </em:targetApplication> <!-- Optional Items --> <em:creator>Jonah Bishop</em:creator> <em:description>An example toolbar extension.</em:description> <em:homepageURL>http://www.borngeek.com/firefox/</em:homepageURL> </Description> </RDF>
Chrome æ¸ å® (Chrome Manifest)
Chrome æ¸ å®æ¯ Firefox 1.5 æéå§æçãå¨ä¹åï¼ææçè³æ被è¨å®å¨å ©åå°æ¹ï¼å®è£æ¸ å®(installer manifest)ãå contents.rdf ãèç¾å¨ï¼æ°çæ ¼å¼é¡¯å¾æ´ç°¡å®ãå次å¨æä¸å±¤ç®é建ç«å¦å¤ä¸åæªæ¡ chrome.manifest ãä¸é¢æ¯æªæ¡çµæ§çèµ·ä¾ç樣åï¼
+- TutToolbar/ +- install.rdf +- chrome.manifest +- chrome/ +- content/
Chrome æ¸ å®æ¯ç¨ä¾å訴 Firefox ï¼æåçå¥ä»¶æä¾çå°è£(package)èè¦è¼(overlay)ãå¨æåéå§å»ºç«ä¹åï¼å çåç¯ä¾ï¼
content myextension chrome/content/ overlay chrome://browser/content/browser.xul chrome://myextension/content/overlay.xul locale myextension en-US chrome/locale/en-US/ skin myextension classic/1.0 chrome/skin/
èæ©å 使ç¨ç contents.rdf (éå¸¸è¶ é20è¡) æ¯è¼ï¼ç¾å¨çæ¹å¼è®å¾é常簡å®ï¼ç¬¬ä¸è¡ä½¿ç¨ä½ æå®çå°è£å稱ä¾ç»éï¼ä¸¦æææ¾ç½®å¨ content ç®éãéå°å 許 chrome è³æºèå¥å串(Uniform Resource Identifierï¼ç°¡ç¨± URI) ï¼å¦ chrome://myextension/content/ï¼å¨æåçå¥ä»¶å±¤ç´ä¸æåé©ç¶çå°æ¹ã注æï¼å°è£å稱åªè½ä»¥å°å¯«è¡¨ç¤ºï¼å ¶ä»æ··å大å°å¯«ï¼ææ¯å ¨é¨å¤§å¯«çå稱é½æ¯ä¸å 許çã
注æå°ï¼content ç®éçä½ç½®æ¯ç¸å°æ¼å¥ä»¶çæ ¹ç®éãå¨é份æåï¼æåä½¿ç¨ tuttoolbar ç¶ä½å°è£å稱ã
第äºè¡ç»é chrome://browser/content/browser.xul çè¦è¼(overlay)ï¼éå è¨±ä½ æ°å¢æä¿®æ¹ Firefox 主è¦çªç使ç¨è ä»é¢(user interface)ã
å¨ä¸é¢çç¯ä¾ï¼chrome://myextension/content/overlay.xul æå®äºè¦è¼(overlay)çXUL æªæ¡ã
æå¥è©±èªªï¼ä½æ¼å¥ä»¶ä¸ content ç®éç overlay.xul æªæ¡ï¼æ¯æåå°è¦æ°å¢ç使ç¨è ä»é¢(å·¥å ·å)ãå¨éåé¨ä»½ï¼æåè¦ä½¿ç¨çå¼çº chrome://tuttoolbar/content/tuttoolbar.xul ã ä¸ä¸è¡èªªæå°ååå¦ä½å»ºç«(how a locale can be created)ãå¨é份æåä¸ï¼æåä¸è¨è¨å°åå(éç¶éç¨å¾ç°¡å®)ï¼éå°å¨æªä¾ååè¨è«ã
æå¾ä¸è¡è¨å®äºé¢æ¿(skin)ï¼æåå°ä½¿ç¨éåæå·§ä¾ç¾åæåçå·¥å ·åãç¾å¨ï¼å ç¥éå®ï¼æåå°å¨ç¬¬äºç« ååä¾è¨è«éé»ã ä¸åé½å¾ç°¡å®ï¼ä¸æ¯åï¼ä¸é¢æ¯æåå°æ使ç¨ç chrome æ¸ å®ï¼éåªæ¯åæåï¼ä¹å¾æåå°æå å ¥é¢æ¿çè³è¨ãåä¸æ¬¡ï¼å°ä¸é¢çç¨å¼ç¢¼è¤è£½å°æååå建ç«ç chrome.manifest ã
content tuttoolbar chrome/content/ overlay chrome://browser/content/browser.xul chrome://tuttoolbar/content/tuttoolbar.xul
ç¾å¨æ¶æ§å·²ç¶å¯ä»¥äºï¼æ¥èè®æåä¾åäºæ趣çäºå§ï¼
第ä¸ç« ï¼å»ºæ§å·¥å ·å (Structuring the Toolbar)
Firefox å¥ä»¶ç使ç¨è ä»é¢é¨ä»½æ¯ä½¿ç¨ XUL æè¡ (é³ï¼zool)ï¼éæ¯ä¸ç¨®ç¨ä¾è¨è¨ä½¿ç¨è ä»é¢çæ¨ç¤ºèªè¨ãXUL å¯ä»¥æ³ææ¯ä¸ç¨® XML ç調å³æ(ææ¨æéå åè½ç)ï¼ å®ä¸éæ¯ä½¿ç¨é è¨å ç´ ç XML (ä¹å«å widgets)ãä½¿ç¨ XUL ç好èï¼æ¯å çºå®ä½¿ç¨äºåæ è¦è¼(dynamic overlays)çæè¡ãåæ è¦è¼æè¡å¯ä»¥è®éç¼è ä¸éè¦æ¹è®åæ¬ä»é¢çç¨å¼ç¢¼çæ æ³ä¸ï¼å»ä¿®æ¹è¦çªç使ç¨è ä»é¢ãå¨ä¸éæ´ååå§ç¨å¼ç¢¼çæ æ³ä¸ï¼å¯ä»¥è®æåå°æ³¨æ¼è¨è¨æåçå¥ä»¶ï¼èä¸ç¨æå¿éè¦éè¤éç¼çåé¡ãå¨éåç« ç¯ï¼æåè¦ä¾ççè¨è¨å·¥å ·åç XUL å¿ è¦æ¨ç¤ºãè¨ä½ï¼XUL å å æ¯ç¨ä¾å»ºæ§å·¥å ·åèå·²ãçºäºè®å·¥å ·åå¯ä»¥éä½ï¼æåå¿ é ä½¿ç¨ JavaScript ï¼éé¨ä»½å°å¨ç¬¬å ç« æå°ã
å¨ content ç®é裡ï¼å»ºç«ä¸åæªåçº tuttoolbar.xul çæªæ¡ãå¨ä½ 建ç«å¥½ä¹å¾ï¼ç®éççµæ§ææ¯é樣ï¼
+- TutToolbar/ +- install.rdf +- chrome.manifest +- chrome/ +- content/ +- tuttoolbar.xul
ç¾å¨ï¼æåå·²ç¶å»ºç«å¥½éåæªæ¡ï¼å¯ä»¥éè¡å°éå§è¨è«å §å®¹ãé¨èé²è¡çè ³æ¥ï¼ææå°æªæ¡çææå §å®¹ï¼ä¸æ¥ä¸æ¥å°ä»ç´¹ãéæè®éç¨çèµ·ä¾æ´ç°¡å®ï¼å¨éç« ç¯çæå¾ï¼éåæªæ¡æç¸ç¶å¥å ¨ã
å çº XUL åªæ¯ä¸ç¨® XML ç調å³æï¼æ以第ä¸è¡å¿ é æ¯ä½¿ç¨ XML ç宣åï¼
<?xml version="1.0"?>
ç¾å¨ï¼å®£åéæ¯ä¸å XML çæªæ¡ä¹å¾ï¼æåå°±å¯ä»¥éå§èç± overlay å ç´ è¨è¨è¦è¼äºãéåå ç´ å°ææ¯éæ´ä»½æ件çæ ¹å ç´ ãæå¥è©±èªªï¼ææå ¶ä»çå ç´ å¿ é å¨ <overlay> è </overlay> ä¹éãéæ¯ overlay çèµ·ä¾ç樣åï¼
<overlay id="TutTB-Overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> </overlay>
éåå ç´ æå ©å屬æ§ï¼id è xmlns ãéè· HTML é¡ä¼¼ï¼id çå¼å¿ é æ¯å¯ä¸çãæ´éè¦çæ¯ï¼éä¹å¿ é æ¯æ´åç覽å¨å¯ä¸çå¼ãé裡æä¸åå¯ä»¥è®ä½ 確å®æ使ç¨ç ID æ¯å¯ä¸çæ¹æ³ãä¾å¦ï¼ä¸é¢çç¯ä¾ãä½ å¯ä»¥æ³¨æå°æ使ç¨äº TutTB éé çåç¼ä¾å®ç¾© id 屬æ§çå¼ã使ç¨ç¬¦åä½ çå¥ä»¶å稱éé çåç¼ï¼éæ使 ID æ¯å¯ä¸çå¯è½æ§æé«ã並ä¸æ³¨æå°ï¼å¯¦éçå¼æ¯ä¸éè¦å å« overlay çåç¼ï¼æé麼åæ¯æ¹ä¾¿æ追蹤æ使ç¨çå稱æ¯åä»éº¼ç¨çã
第äºå屬æ§ï¼xmlnsï¼ç¨ä¾æå®ä½¿ç¨æ¼è¦è¼çå½å空éãæ¢ç¶éæ¯ XUL æ件ï¼æåå¿ é å®ç¾© XUL çå½å空éï¼éæ¯ä½ æä¸ç´ç¨å°çå¼ã
å·¥å ·ç®±èå·¥å ·å (The Toolbox and Toolbar)
ææçå·¥å ·åæ該被éä¸å¨å·¥å ·ç®±ä¸ãæåä½¿ç¨ toolbox å ç´ ä¾æå®ä¸åå·¥å ·ç®±(è¨ä½ï¼éåå ç´ å¿ é 被æ¾ç½®å¨ overlay ä¹éã)ï¼
<toolbox id="navigator-toolbox"> </toolbox>
注æå°ï¼éå id 屬æ§æä¸åé è¨å¼ï¼navigator-toolbox ã éåç¹å®çå¼è¡¨ç¤ºçº Firefox è¦çªä¸ä¸»è¦çå·¥å ·ç®±å ç´ ï¼è·çè¦½å·¥å ·åãé¸å®åã網ååï¼ææ¯å ¶ä»é¡ä¼¼çæ§å¶é¸é ä¸æ¨£ãèç±æå®éåç¹å¥çå·¥å ·åï¼æåå¯ä»¥ç¢ºå®éåå·¥å ·åæèå ¶ä»çå·¥å ·åé æå¨ä¸èµ·ãæ建è°ä½ 總æ¯è®ä½ çå·¥å ·åæ¾å¨éåç¹å®çå·¥å ·ç®±ä¸ï¼éä¸åªè®ä½ æçèµ·ä¾ä¸è´çå·¥å ·åï¼ä¹å¯ä»¥è®ä½ å¨ ã檢è¦>å·¥å ·åã ä¸ï¼å¿«éå°å°ä½ çå·¥å ·åé±èææ¯é¡¯ç¤ºã
è®æåå°æ³¨æåæ¾åå° toolbar å ç´ ï¼æåæå°éåå ç´ æ¾å¨ toolbox ä¹ä¸ãççéåç¯ä¾ï¼
<toolbar id="TutTB-Toolbar" toolbarname="Tutorial Toolbar" accesskey="T" class="chromeclass-toolbar" context="toolbar-context-menu" hidden="false" persist="hidden"> </toolbar>
è®æåä¾ççéåå ç´ ç屬æ§ï¼
- toolbarname - éåå ç´ æå®å¥ä»¶çå稱(éææ¯ä½ å¨ã檢è¦>å·¥å ·åãçå°çæå)ã
- accesskey - 給éåå·¥å ·åæå®åæ¯ï¼ç¨ä¾ç¶ä½å¿«ééµä½¿ç¨ãå¨éåå·¥å ·åæåä¸ï¼æå使ç¨å¤§å¯«ç T ãéç¶éæ¯éå¿ è¦ç屬æ§ï¼éæ¯å¼·ç建è°ä½ 使ç¨å®ï¼éè½è®ä½¿ç¨è åªè¦ç¨å¿«ééµå°±è½éåæééä½ çå·¥å ·åã
- class - çºå·¥å ·åæå®ç¹å®ç樣å¼é¡å¥ãé è¨å¼ chromeclass-toolbar æ¯ç¨ä¾è¦ç¯å·¥å ·å顯示模å¼çé¡å¥ï¼å樣å°ï¼éæ¯å»ºè°ä½¿ç¨çéå¿ è¦å±¬æ§ã
- context - æå®ç¶å¨å·¥å ·åä¸æå³éµæï¼æ顯示çå·¥å ·åé¸å®(context menu)ãä½ å¯ä»¥æä¾ä½ çé¸å® ID å¼ï¼ææ¯ä½¿ç¨ toolbar-context-menu ä¾å°é¸å®æ¾ç½®å¨ãæª¢è¦ > å·¥å ·åãã
- hidden - æå®å·¥å ·åæ¯å¦é±èãé è¨çæ æ³ä¸ï¼æåè¦è®ä½¿ç¨è çè¦æåçå·¥å ·åï¼æ以è¨å®éåå¼çº false (ç¸åçº ture )ã
- persist - This attribute is a space separated list of attributes that should persist across browser sessions. å¨ä¸é¢çç¯ä¾ï¼æä½¿ç¨ hidden ï¼ç¨ä¾å訴 Firefox å¨ sessions è¨ä½å·¥å ·åçé±èçæ ã注æå°ï¼å¦æä½ çå·¥å ·åæ²æä½¿ç¨ id 屬æ§ï¼å persist 屬æ§ä¸æç¼çä½ç¨ï¼æ以è¦ç¢ºå®ä½ æçºä½ çå·¥å ·åæå® id å ç´ ã
ä½ å¯ä»¥å¨ XUL Planet toolbar element's attributes çå°å®æ´çåèæç»ã
ç¾å¨ï¼è®æåä¾çç建ç«å¥½çè¦è¼æªæ¡[View XUL Overlay Revision 1]ï¼
<?xml version="1.0"?> <overlay id="TutTB-Overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <toolbox id="navigator-toolbox"> <toolbar id="TutTB-Toolbar" toolbarname="Tutorial Toolbar" accesskey="T" class="chromeclass-toolbar" context="toolbar-context-menu" hidden="false" persist="hidden"> </toolbar> </toolbox> </overlay>
å·¥å ·åæé (Toolbar Buttons)
å¨ Firefox ä¸ï¼å·¥å ·åæéæä¸ç¨®ï¼ä¸è¬ãé¸å®ãæéé¸å®ãéäºé½æ¯ç¨ toolbarbutton ä¾å»ºç«çï¼è®æåä¾åå¥ççãè¨ä½ï¼éäºå ç´ å¿ é æ¾å¨ toolbar å ç´ ä¹ä¸ã
ä¸è¬æé (Normal Buttons)
éæ¯ç¨ä¾å»ºç«ä¸è¬çæéï¼
<toolbarbutton id="TutTB-Web-Button" tooltiptext="Search the Web" label="Web Search" oncommand="TutTB_Search(event, 'web')" />
å®æä¹å¾ï¼ä¾ççéåå ç´ ç屬æ§ï¼
- tooltiptext - ç¶æ»é¼ 移åå°æéä¸æåºç¾ç說æã
- label - å·¥å ·åæé顯示çæåã
- oncommand - ç¶ oncommand äºä»¶è§¸ç¼æ(æä¸æé)ï¼ä½ ææå®çç¨å¼ç¢¼ãå¨éåç¯ä¾ï¼ä½¿ç¨ TutTB_Search()å½å¼ï¼æåå°å¨ç¬¬å ç« è©³ç´°èªªæã
ä½ å¯ä»¥å¨ XUL Planet toolbarbutton element's attributes æ¾å°å®æ´çåèæç»ã
é¸å®æé (Menu Buttons)
ç¶é»ææéé¸å®æï¼æåºç¾ä¸æå¼é¸å®ã å管éåæéæ¨è¨é¡ä¼¼ä¸è¬æéæ¨è¨ï¼æåéæ¯å¿ é å å ¥ menupopup å ç´ ï¼è®é¸å®ä»¥æåæ³è¦ç樣ååºç¾ãçºäºç°¡æ½é»ï¼ä¸é¢çç¯ä¾åªå å«å ©åé¸å®é ç®ã
<toolbarbutton id="TutTB-MainMenu" type="menu" tooltiptext="Tutorial Toolbar Main Menu"> <menupopup> <menuitem label="Google Home Page" accesskey="G" tooltiptext="Navigate to Google" oncommand="TutTB_LoadURL('http://www.google.com/')" /> <menuseparator /> <menuitem label="Born Geek Website" accesskey="B" tooltiptext="Navigate to Born Geek" oncommand="TutTB_LoadURL('http://www.borngeek.com/')" /> </menupopup> </toolbarbutton>
toolbarbutton æå ©åè¦æ³¨æçè®åã第ä¸ï¼type 屬æ§æå®äº menu çå¼ï¼èªªæäºéæ¯åé¸å®æéï¼èä¸æ¯ä¸è¬æéã第äºï¼ä½ æ注æå°é裡é¢æ²æ oncommand 屬æ§ãå çºé¸å®æéçå¯ä¸ç®çæ¯çºäºé¡¯ç¤ºè·³åºå¼é¸å®ï¼ä¸¦ä¸éè¦å·è¡ä»»ä½ç¨å¼ç¢¼ï¼è顯示é¸å®çåä½æç± Firefox èªåå®æã
ä¹è«æ³¨æå° menupopup ï¼menuitem ï¼menuseparator éä¸åå ç´ ãmenupopup ææé¸å®é ç®ç容å¨ï¼ç¨ä¾å»ºç«è顯示é¸å®ãå¨éåç¯ä¾è£¡ï¼éåå ç´ æ²æ屬æ§ãå樣å°ï¼menuseparator ä¹å¾ç°¡å®ï¼å¨ä¸æå¼é¸å®ä¸æ¾ç½®æ°´å¹³åéç·ï¼ç¨ä¾åéä¸åçé¸å®ã
menuitem ç¨å¾®æé»è¤éãå¨ä¸é¢çç¯ä¾ï¼æåæå®ç屬æ§ï¼
- label - æå®é¸å®é ç®çæåã
- tooltiptext - éå屬æ§å°±åæ¯æåå¨ toolbarbutton çå°çï¼ä½æ¯æä¸é»è¦è¦åçãç±æ¼ Firefox ç bug (bug #147670)ï¼éå屬æ§æ¯å¿ è¦çãå¦æä½ æ±ºå®å¾ menuitem ä¸åªæéå屬æ§ï¼ç¶ä½¿ç¨è å°æ»é¼ 移åå°é¸å®é ç®æï¼æçä¸å°æ示說æãé¸å®ä¸æé¡¯ç¤ºå·¥å ·æ示ï¼éçæ¯å令人ä¸æ»¿æçãç¹è²ãï¼
ä½ å¯ä»¥å¨ XUL Planet menuitem element's attributes æ¾å°å®æ´çåèæç»ã
æéé¸å® (Button-Menu Buttons)
第ä¸ä¹æ¯æå¾çæéé¸å®æ¯ä¸ç¨®ä¹ä¸æè¤éçã實éä¸ï¼çµåäºåå ©ç¨®æéï¼æä¾å¯é»ææéçä¸æå¼é¸å®ã
ãä¸ä¸é ãèãä¸ä¸é ãç覽é¸å®æ¯éåæéé¸å®çç¯ä¾ï¼éæ¯éè¦å»ºç«çæ¨è¨ï¼
<toolbarbutton id="TutTB-Combined-Button" label="Search" type="menu-button" tooltiptext="Combined Search" oncommand="TutTB_Search(event, 'web')"> <menupopup> <menuitem id="TutTB-Combined-Web" label="Web Search" class="menuitem-iconic" tooltiptext="Search the Web" oncommand="TutTB_Search(event, 'web'); event.preventBubble();" /> <menuitem id="TutTB-Combined-Image" label="Image Search" class="menuitem-iconic" tooltiptext="Search Images" oncommand="TutTB_Search(event, 'image'); event.preventBubble();" /> </menupopup> </toolbarbutton>
æå ©åå¼å¾æ³¨æçè®åï¼å¨ toolbarbutton ç type 屬æ§æå®äºå¼ menu-button ï¼èä¸æå¦å¤ä¸è¡ç¨å¼ç¢¼ oncommand ï¼ææå¨ç¬¬å ç« è§£ééé¡å¤çç¨å¼ç¢¼ãæ¥è注æå°ï¼é裡æè·ãä¸è¬æéãä¸æ¨£ç toolbarbutton æ oncommand 屬æ§ï¼ä»¥åå¨ãé¸å®æéã裡çå·¢çå ç´ menupopup è menuitem ã
ç¾å¨ï¼æåè¨è«å®ä¸åçæéï¼ä¾ççç¨å¼ç¢¼ç樣å[View XUL Overlay Revision 2]ï¼
<?xml version="1.0"?> <overlay id="TutTB-Overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <toolbox id="navigator-toolbox"> <toolbar id="TutTB-Toolbar" toolbarname="Tutorial Toolbar" accesskey="T" class="chromeclass-toolbar" context="toolbar-context-menu" hidden="false" persist="hidden"> <toolbarbutton id="TutTB-MainMenu" type="menu" tooltiptext="Tutorial Toolbar Main Menu"> <menupopup> <menuitem label="Google Home Page" accesskey="G" tooltiptext="Navigate to Google" oncommand="TutTB_LoadURL('http://www.google.com/')" /> <menuseparator /> <menuitem label="Born Geek Website" accesskey="B" tooltiptext="Navigate to Born Geek" oncommand="TutTB_LoadURL('http://www.borngeek.com/')" /> </menupopup> </toolbarbutton> <toolbarbutton id="TutTB-Combined-Button" label="Search" type="menu-button" tooltiptext="Combined Search" oncommand="TutTB_Search(event, 'web')"> <menupopup> <menuitem id="TutTB-Combined-Web" label="Web Search" class="menuitem-iconic" tooltiptext="Search the Web" oncommand="TutTB_Search(event, 'web'); event.preventBubble();" /> <menuitem id="TutTB-Combined-Image" label="Image Search" class="menuitem-iconic" tooltiptext="Search Images" oncommand="TutTB_Search(event, 'image'); event.preventBubble();" /> </menupopup> </toolbarbutton> <toolbarbutton id="TutTB-Web-Button" tooltiptext="Search the Web" label="Web Search" oncommand="TutTB_Search(event, 'web')" /> </toolbar> </toolbox> </overlay>
ä¸æå¼ç·¨è¼¯å (Drop-Down Edit Box)
ä¸ä¸åæåè¦å¨å·¥å ·åå å ¥çæ¯ä¸æå¼ç·¨è¼¯åãéæ¯ç¨ menulist ä¾å»ºç«çï¼è®æåä¾ççç¨å¼ç¢¼ï¼
<toolbaritem id="TutTB-SearchTerms-TBItem" persist="width"> <menulist id="TutTB-SearchTerms" editable="true" flex="1" minwidth="100" width="250" onkeypress="TutTB_KeyHandler(event);"> <menupopup id="TutTB-SearchTermsMenu" onpopupshowing="TutTB_Populate()" /> </menulist> </toolbaritem>
注æå°ï¼æåæ menulist æ¾å¨ toolbaritem ä¹ä¸ãä»»ä½ä¸åå¨ toolbar çé ç®é½ä¸æ¯å·¥å ·åæéï¼å¨ toolbaritem 裡é çææ¯ãä¹è«æ³¨æå°ï¼æåçº toolbaritem æå®äº id ï¼ä¸è¨å®äºå¯¬åº¦(èç±å©ç¨äº persist 屬æ§)ã
menulist ææ¯çæ£ç¨ä¾å»ºç«ä¸æå¼ç·¨è¼¯åçãæå¹¾åå¨éåå ç´ åºç¾çæ°å±¬æ§ï¼
- editable - ç¶è¨å®çº true æï¼ä½¿ç¨è å¯ä»¥å¨ç·¨è¼¯åä¸æåã
- flex - 使éåå ç´ æ¯å¯è®åçãéæ¯åæ´æ¸å¼ï¼ç¸å°æ¼å ¶ä»å¯è®åå·¥å ·åå ç´ ï¼æå®å ¶å¤§å°ãè¨å®å¼ 2 代表èè¨å®å¼ 1 çå ©å寬ï¼0 åæ¯ä¸è½è®åçåºå®å¯¬åº¦ã
- minwidth - æå°å¯¬åº¦ï¼å®ä½çºåç´ ã
- width - åå§å¯¬åº¦ï¼å®ä½çºåç´ ã
- onkeypress - ç¶ä½¿ç¨è è¼¸å ¥æåæï¼ç¨ä¾å·è¡çç¨å¼ç¢¼ã
ä½ å¯ä»¥å¨ XUL Planet menulist element's attributes çå°å®æ´çåèæç»ã
è·æåä¹åçå°çãé¸å®æéãä¸æ¨£ï¼å¨ menulist 裡ç menupopup å å«äº menuitem å ç´ ãonpopupshowing éåäºä»¶æå¨ç·¨è¼¯åçé¸å®é ç®é¡¯ç¤ºå觸ç¼ï¼å ¶ä¸æå®ä¸åè½åæ å¯«å ¥é¸å®é ç®çå½å¼ï¼éåå½å¼æåç¨å¾ææåãä½ ä¹å¯ä»¥å å ¥éæ çé¸å®ï¼éç¨è·ãé¸å®æéãæ¯ä¸æ¨£çã
ç¾å¨ï¼éåå¥ä»¶å·²ç¶è®å¾æ´å ·é«ä¸é»äºï¼è®æåä¾ççç¨å¼ç¢¼[View XUL Overlay Revision 3]ï¼
<?xml version="1.0"?> <overlay id="TutTB-Overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <toolbox id="navigator-toolbox"> <toolbar id="TutTB-Toolbar" toolbarname="Tutorial Toolbar" accesskey="T" class="chromeclass-toolbar" context="toolbar-context-menu" hidden="false" persist="hidden"> <toolbarbutton id="TutTB-MainMenu" type="menu" tooltiptext="Tutorial Toolbar Main Menu"> <menupopup> <menuitem label="Google Home Page" accesskey="G" tooltiptext="Navigate to Google" oncommand="TutTB_LoadURL('http://www.google.com/')" /> <menuseparator /> <menuitem label="Born Geek Website" accesskey="B" tooltiptext="Navigate to Born Geek" oncommand="TutTB_LoadURL('http://www.borngeek.com/')" /> </menupopup> </toolbarbutton> <toolbaritem id="TutTB-SearchTerms-TBItem" persist="width"> <menulist id="TutTB-SearchTerms" editable="true" flex="1" minwidth="100" width="250" onkeypress="TutTB_KeyHandler(event);"> <menupopup id="TutTB-SearchTermsMenu" onpopupshowing="TutTB_Populate()" /> </menulist> </toolbaritem> <toolbarbutton id="TutTB-Combined-Button" label="Search" type="menu-button" tooltiptext="Combined Search" oncommand="TutTB_Search(event, 'web')"> <menupopup> <menuitem id="TutTB-Combined-Web" label="Web Search" class="menuitem-iconic" tooltiptext="Search the Web" oncommand="TutTB_Search(event, 'web'); event.preventBubble();" /> <menuitem id="TutTB-Combined-Image" label="Image Search" class="menuitem-iconic" tooltiptext="Search Images" oncommand="TutTB_Search(event, 'image'); event.preventBubble();" /> </menupopup> </toolbarbutton> <toolbarbutton id="TutTB-Web-Button" tooltiptext="Search the Web" label="Web Search" oncommand="TutTB_Search(event, 'web')" /> </toolbar> </toolbox> </overlay>
å¯èª¿æ´ç移é§æ¨è¨ (Resizing Gripper)
éè¨å¾ä¹åå å«å¨ menulist ä¸ toolbaritem å ç´ ææå°ç persist 屬æ§åï¼è¨å®éå屬æ§ä»¥è®æåå¨ç覽å¨ä½¿ç¨æéï¼å¯ä»¥å²åæå°åç寬度ãçºäºè®ä½¿ç¨è å¯ä»¥æ¹è®å¯¬åº¦ï¼æåè¦æä¾ ç§»é§æ¨è¨ ãç¨ä¾åé件äºçå ç´ æ¯ splitter ï¼è®æåä¾ççç¨å¼ç¢¼ï¼
<splitter id="TutTB-ResizeSplitter" state="open" collapse="none" resizebefore="closest" resizeafter="farthest" tooltiptext="Resize the Search Box"> <vbox id="TutTB-ResizeBar" /> </splitter>
éæ¯ splitter ç屬æ§ï¼
- state - æå®åå²æ¨è¨æ¯å¦æºç(é±è)å §å®¹ï¼ open å¼æå®ä¸ç®¡æ¯å¦æå §å®¹ç顯示ã
- collapse - 決å®åªéç splitter 被é±èãæåä½¿ç¨ none ï¼ä¸è®ä»»ä½ä¸éç splitter 被é±èã
- resizebefore - ç¶ splitter æ¹è®æï¼æå® splitter å·¦éçåªåå ç´ å¿ é 被éæ°èª¿æ´ãç¶ splitter 移åæï¼ä½¿ç¨ closest ä¾éæ°èª¿æ´æé è¿ splitter å·¦éç編輯åã
- resizeafter - ç¶ splitter æ¹è®æï¼æå® splitter å³éçåªåå ç´ å¿ é 被éæ°èª¿æ´ãå¨éåç¯ä¾è£¡ï¼æåä½¿ç¨ farthest ä¾éæ°èª¿æ´æå³éçå½æ§ç©ºéã
vbox æ¯ç¨ä¾è¨å®æ¨£å¼çï¼æåæå¨ç¬¬äºç« è¨è«é¢æ¿æï¼æå°éé»ã ä½ å¯ä»¥å¨ XUL Planet splitter element's attributes çå°æ´å®æ´çåèæç»ã
è®æåä¾ççå å« splitter è toolbaritem çè¦è¼ç¨å¼ç¢¼[View XUL Overlay Revision 4]ï¼
<?xml version="1.0"?> <overlay id="TutTB-Overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <toolbox id="navigator-toolbox"> <toolbar id="TutTB-Toolbar" toolbarname="Tutorial Toolbar" accesskey="T" class="chromeclass-toolbar" context="toolbar-context-menu" hidden="false" persist="hidden"> <toolbarbutton id="TutTB-MainMenu" type="menu" tooltiptext="Tutorial Toolbar Main Menu"> <menupopup> <menuitem label="Google Home Page" accesskey="G" tooltiptext="Navigate to Google" oncommand="TutTB_LoadURL('http://www.google.com/')" /> <menuseparator /> <menuitem label="Born Geek Website" accesskey="B" tooltiptext="Navigate to Born Geek" oncommand="TutTB_LoadURL('http://www.borngeek.com/')" /> </menupopup> </toolbarbutton> <toolbaritem id="TutTB-SearchTerms-TBItem" persist="width"> <menulist id="TutTB-SearchTerms" editable="true" flex="1" minwidth="100" width="250" onkeypress="TutTB_KeyHandler(event);"> <menupopup id="TutTB-SearchTermsMenu" onpopupshowing="TutTB_Populate()" /> </menulist> </toolbaritem> <splitter id="TutTB-ResizeSplitter" state="open" collapse="none" resizebefore="closest" resizeafter="farthest" tooltiptext="Resize the Search Box"> <vbox id="TutTB-ResizeBar" /> </splitter> <toolbaritem flex="0"> <toolbarbutton id="TutTB-Combined-Button" label="Search" type="menu-button" tooltiptext="Combined Search" oncommand="TutTB_Search(event, 'web')"> <menupopup> <menuitem id="TutTB-Combined-Web" label="Web Search" class="menuitem-iconic" tooltiptext="Search the Web" oncommand="TutTB_Search(event, 'web'); event.preventBubble();" /> <menuitem id="TutTB-Combined-Image" label="Image Search" class="menuitem-iconic" tooltiptext="Search Images" oncommand="TutTB_Search(event, 'image'); event.preventBubble();" /> </menupopup> </toolbarbutton> <toolbarbutton id="TutTB-Web-Button" tooltiptext="Search the Web" label="Web Search" oncommand="TutTB_Search(event, 'web')" /> </toolbaritem> </toolbar> </toolbox> </overlay>
çºäºé¿å 移é§æ¨è¨è¨åç細微顯示åé¡ï¼æåééè¦å»ºç«é¡å¤ç toolbaritem ï¼éèæåååå¨ãé¸å®æéãä¸çæå°æéæåçä¸æ¨£ã åä¸æ¬¡ç¢ºå® flex 屬æ§çå¼çº 0ï¼éå°æé¿å ï¼ç¶æåçé¸å®æé被ææ³å°å·¦éæ被移é¤ã
æ¥èï¼è®æååä¾å¢å å ©åé ç®ãé¦å ï¼å° toolbarseparator æ¾ç½®å¨æå¾å ©åæéä¸ï¼æ¤ç®çæ¯çºäºè£é£¾ãåä¾ï¼å° toolbarspring æ¾ç½®å¨æå¾ç toolbaritem å ç´ ä¹å¾ãThis spring will allow us to drag the resizer all the way to the right, so that we can see the full resizing effect in action. éå ©åæ¨ç¤ºæ¯å¾ç°¡å®çï¼åæ¯é樣ï¼
<toolbarseparator /> <toolbarspring />
è®æåä¾ççå®æ´çè¦è¼ç¯ä¾[View XUL Overlay Revision 5]ï¼
<?xml version="1.0"?> <overlay id="TutTB-Overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <toolbox id="navigator-toolbox"> <toolbar id="TutTB-Toolbar" toolbarname="Tutorial Toolbar" accesskey="T" class="chromeclass-toolbar" context="toolbar-context-menu" hidden="false" persist="hidden"> <toolbaritem flex="0"> <toolbarbutton id="TutTB-MainMenu" type="menu" tooltiptext="Tutorial Toolbar Main Menu"> <menupopup> <menuitem label="Google Home Page" accesskey="G" tooltiptext="Navigate to Google" oncommand="TutTB_LoadURL('http://www.google.com/')" /> <menuseparator /> <menuitem label="Born Geek Website" accesskey="B" tooltiptext="Navigate to Born Geek" oncommand="TutTB_LoadURL('http://www.borngeek.com/')" /> </menupopup> </toolbarbutton> </toolbaritem> <toolbaritem id="TutTB-SearchTerms-TBItem" persist="width"> <menulist id="TutTB-SearchTerms" editable="true" flex="1" minwidth="100" width="250" onkeypress="TutTB_KeyHandler(event);"> <menupopup id="TutTB-SearchTermsMenu" onpopupshowing="TutTB_Populate()" /> </menulist> </toolbaritem> <splitter id="TutTB-ResizeSplitter" state="open" collapse="none" resizebefore="closest" resizeafter="farthest" tooltiptext="Resize the Search Box"> <vbox id="TutTB-ResizeBar" /> </splitter> <toolbaritem flex="0"> <toolbarbutton id="TutTB-Combined-Button" label="Search" type="menu-button" tooltiptext="Combined Search" oncommand="TutTB_Search(event, 'web')"> <menupopup> <menuitem id="TutTB-Combined-Web" label="Web Search" class="menuitem-iconic" tooltiptext="Search the Web" oncommand="TutTB_Search(event, 'web'); event.preventBubble();" /> <menuitem id="TutTB-Combined-Image" label="Image Search" class="menuitem-iconic" tooltiptext="Search Images" oncommand="TutTB_Search(event, 'image'); event.preventBubble();" /> </menupopup> </toolbarbutton> <toolbarseparator /> <toolbarbutton id="TutTB-Web-Button" tooltiptext="Search the Web" label="Web Search" oncommand="TutTB_Search(event, 'web')" /> </toolbaritem> <toolbarspring /> </toolbar> </toolbox> </overlay>
第åç« ï¼åæ éç¼ (Dynamic Development)
(è¯è ï¼å¦æä¸æ³ç¨æ¤éç¼ç°å¢ï¼å¯ä»¥ç¥éæ¤ç« ï¼ä¸¦ç¨ç¬¬ä¸ç« çæ¹å¼æ¸¬è©¦å¥ä»¶ã)
å¨ Firefox 1.5 ä¸ï¼åæ å¥ä»¶éç¼æ¯æ°çæè¡ï¼å°éç¼è èè¨ï¼éæ¯ææç¨çéå åè½ãéé æè¡å¯ä»¥è®ä½ å¨éç¼å¥ä»¶æï¼å³æå°çå°çµæãç¶ä½ è¦æ¸¬è©¦ XUL è¦è¼ææ¯ JavaScript ç¨å¼ç¢¼æï¼ä¸ç¨æ¯æ¬¡åéæ°å°è£å¥ä»¶ãéä¸åªç¯çäºä½ çæéï¼ä¹è®ä½ è½æ´å¿«éå°é¤é¯ã
é£éº¼ï¼éé ç¹è²æ¯å¦ä½éä½çå¢ï¼éå°±è¦æè¬æåå¨ç¬¬äºç« 建ç«ç chrome æ¸ å®äºãç´å°ç¾å¨çºæ¢ï¼æé½éæ²è·ä½ 說 chrome æ¸ å®è©¦ä½ç麼ç¨éãå¨éåæåä¸ï¼æåä¸éå§å»ºç«ççæ¬å°±æ¯ç¹å¥çºåæ éç¼èè¨è¨çãæè¨ä¹ï¼æåä¸å¿ éæ°å°è£é£ä»½çæ¬çå¥ä»¶ï¼ä½éæ¯æäºæ¹è®éè¦å®æï¼æå¯ä»¥å°è£ãæå¹¾åç¨ä¾ãååãå¥ä»¶åæ éç¼çæ¥é©ï¼å¨é£ä¹åï¼æè¦å çµ¦ä½ å¹¾å建è°ã
注æäºé (A Word of Warning)
å¥ä»¶éç¼ææææé»å±éªï¼å°¤å ¶æ¯è¨è¨ XUL è¦è¼æªæ¡æãæå¼·ç建è°ä½ è¦é¿å éç¼å¥ä»¶è·å¹³å¸¸ç覽網é å ±ç¨ä¸åè¨å®æª(profile)ãæè¨ä¹ï¼ä½ å¿ é çºä½ çéç¼ç°å¢å»ºç«ä¸åæ°çè¨å®æªãéå¯ä»¥é¿å ä½ å¤±å»ä¸äºééµçè³æï¼å¦ï¼å²åçå¯ç¢¼ãcookiesãæ¸ç±¤ææ¯å ¶ä»ä½ ä¸æ³éºå¤±çæ±è¥¿ã
æå¸æè½åå¿« Born Geek å¨ç¼è¡¨éæ¼å¦ä½å»ºç«è使ç¨è¨å®æªçæå¸ãå¨é£ä¹åï¼ä½ å¯ä»¥å ççå¨ Mozilla.org çè¨å®æªæ件ã建ç«è使ç¨è¨å®æªæ¯å¾ç°¡å®çï¼éæé¿å è®ä½ é ççæ æ³ç¼çã
å¦ä½åæ éç¼ (How to Develop Dynamically)
æ主è¦çå·¥ä½ï¼æåå·²ç¶å¨ chrome æ¸ å®å®æ(å³ä½¿ä½ éä¸äºè§£æåé£æåäºä»éº¼)ãç¾å¨ï¼æåéè¦çï¼æ¯ä¸åå° Firefox æå硬ç¢ä¸å¥ä»¶ä½ç½®çæªæ¡ï¼æåå°èç± pointer æªæ¡ä¾å®æã
é¦å ï¼å¨ä½ çé»è ¦çé¨ä¾¿ä¸åå°æ¹ï¼ä»¥æåå¨å®è£æ¸ å®(install manifest)ä¸æ使ç¨ç GUID å稱ï¼å»ºç«ä¸åæåæªãå¨é份æåä¸ï¼æåä½¿ç¨ tuttoolbar@borngeek.com ä½çºæªåãä¸å¹¸çæ¯ï¼å¨å¾®è»è¦çªç°å¢è£¡ï¼ã.comãçæªæ¡æ¯è¢«ç¨ä¾ç¶ä½å·è¡æªï¼èæåéè¦çæ¯æåæªãä½ å¯ä»¥æã.comãæ¿æï¼ä½ä¹è¨å¾å»ä¿®æ¹å¨å®è£æ¸ å®ç GUIDï¼ç¢ºä¿å ©åå稱æ¯ä¸æ¨£çã
å¨éåæªæ¡è£¡ï¼æåå°è¦è¼¸å ¥ä¸è¡æåï¼å¥ä»¶å²åççµå°ä½ç½®ï¼ä¹å°±æ¯åæ¾ install.rdf è chrome.manifest æªæ¡çç®éãå¨æçä¾åï¼å²åè·¯å¾å¦ä¸ï¼
C:\Born Geek\TutToolbar
ä½ å¿ é 使ç¨ä½ èªå·±è¨å®çè·¯å¾ï¼é¤éä½ çè·¯å¾è·æçä¸æ¨£ãè¼¸å ¥å®è·¯å¾å¾ï¼å²åæªæ¡ã
ç¾å¨ï¼æåå¿ é å°éåæªæ¡ç§»åå°è·éç¼ç°å¢çè¨å®æª(profile)åä¸åç®é(å¦ï¼C:\Documents and Settings\Administrator\Application Data\Mozilla\Firefox\Profiles)ãæååæå°çè¨å®æªæ件æè¨è«å°è¨å®æªç®éçä½ç½®ãç¶ä½ æ¾å°è¨å®æªç®éæï¼å°æååå建ç«ç pointer æªæ¡ç§»åå°è©²ç®éç extensions ç®éä¸ãéæ¯æçä¾åï¼
+- tl5wlpz3.Nightly/ +- bookmarkbackups/ +- chrome/ +- extensions/ +- tuttoolbar@borngeek.com +- (... other files and folders ...)
ä½ å¯ä»¥çå°æçè¨å®æªæä¸å±¤ç®éï¼æ使ç¨ä»¥ãNightlyãçºåçè¨å®æªï¼ä¾ä½çºæçå¥ä»¶éç¼ç°å¢ãä¸æ¦ä½ æ pointer æªæ¡æ¾å¨é©ç¶çä½ç½®ï¼éå Firefoxï¼ç¢ºå®ä½ 使ç¨çæ¯å¥ä»¶éç¼çè¨å®æª(å次æéï¼ååæå°çè¨å®æªæ件æåè¨´ä½ å¦ä½é樣å)ã å°ç®åçºæ¢ï¼å¦æä½ æ¯æ¨£é½åçæ£ç¢ºï¼ä½ æçå°æ²æé¢æ¿çç°è²å·¥å ·åã
éç¼é±æ (The Development Cycle)
ç¾å¨ï¼æåå·²ç¶ååäºåæ éç¼ç°å¢ï¼é£è¦å¦ä½å»å©ç¨å¢ï¼éç¨å ¶å¯¦æ¯é常簡å®çï¼
- ç·¨è¼¯ä½ çå¥ä»¶æªæ¡
- éæ°éåå·²æ´æ¹æªæ¡æå¥ç¨çè¦çªï¼ææ¯ä½¿ç¨ Extension Developer's Extension çéæ°æ´ç(Reload Chrome)ã
æå ©ä»¶äºæ¯ä½ è¦ç¥éçï¼
- å¦æä½ æ¹è®äº chrome.manifest æªæ¡ï¼ä½ å¿ é éæ°éå Firefox (éåæªæ¡åªæå¨ç¨å¼ååææç¼çä½ç¨)ã
- å¦æä½ æ¹è®äº install.rdf æªæ¡ï¼ä½ å¿ é æ¹è® pointer æªæ¡ææåç®éçä¿®æ¹æéãå¨ Linux ä¸ï¼ä½ åªè¦ä½¿ç¨ touch æ令ãèå¨ Windows 裡就æé»é£åº¦ï¼é¤éä½ å®è£äºå¯ä»¥ä½¿ç¨ touch æ令ç Cygwin å·¥å ·ãå¯ä¸è¦åçï¼å°±æ¯å¨å¥ä»¶æä¸å±¤ç®é建ç«ä¸åæ°ç®éï¼ç¶å¾åªé¤æ°ç®é以æ¹è®ç®éçãä¸ä¸æ¬¡ä¿®æ¹ãæéã
ä½ å¯ä»¥çå°ï¼æåæäºæ¹ä¾¿çéç¼èé¤é¯å·¥å ·ãéåéæ¼ï¼å¨ 1.5 çä¹åçæ¨æºéç¨ï¼å°±æ¯æ¯æ¬¡å¨å¥ä»¶éç¼éç¨é½è¦å°è£æªæ¡ã
ç¾å¨ï¼è®æåæéåééçå·¥å ·åè®å¾æ´æ¼äº®ä¸é»å§ï¼
第äºç« ï¼é¢æ¿è£½ä½ (Skinning the Toolbar)
é¢æ¿æ¯ç±æ¨£å¼æ¨æºèåçææ§æçãè¨ä½ï¼å管è¨è¨é¢æ¿æ¯éå¿ è¦çï¼ä½æ¯å®è½æåå¥ä»¶çå質ãç¢ç«ä½¿ç¨è å°å¥ä»¶ç第ä¸å°è±¡æ¯å®çå¤è§ï¼èä¸æ¯å®çåè½ãç¶èï¼å¦æä½ è¦ºå¾ä½¿ç¨æåæ¨ç±¤è®ä½ æ¯è¼èªå¨ï¼ææ¯ä¸éè¦å»ºç«å¤è§ï¼ä½ å¯ä»¥ç¥ééåç« ç¯ã
æ´æ°æªæ¡çµæ§ (Updating the File Structure)
è¨è¨é¢æ¿ç第ä¸æ¥å°±æ¯å»ºç«ä¸åç®éï¼ç¨ä¾åæ¾éæ¼é¢æ¿çæªæ¡ãå¨ chrome ç®éä¸å»ºç«ä¸å skin ç®éãæªæ¡çµæ§æåé樣ï¼
+- TutToolbar/ +- install.rdf +- chrome.manifest +- chrome/ +- content/ +- tuttoolbar.xul +- skin/
ç¾å¨æåæåæ¾é¢æ¿æªæ¡çå°æ¹äºï¼ä¹å¾å¿ é è¦å¨ chrome 裡註åéåä½ç½®ã
æ´æ° Chrome æ¸ å® (Updating the Chrome Manifest)
éè¨å¾æåå¨ç¬¬äºç« 建ç«ç chrome æ¸ å®åï¼æåå¿ é å¨éåæªæ¡å å ¥ä¸è¡ç¨å¼ç¢¼ï¼ç¨ä¾è¨»åæåçé¢æ¿ãæ°å å ¥çä½ç½®(第ä¸è¡)ï¼
content tuttoolbar chrome/content/ overlay chrome://browser/content/browser.xul chrome://tuttoolbar/content/tuttoolbar.xul skin tuttoolbar classic/1.0 chrome/skin/
æ°å å ¥çéä¸è¡ç¸ç¶ç°¡å®ï¼èä¸åªæååé¨ä»½ã第ä¸é¨ä»½ï¼skin 說æéä¸è¡è¦è¨»åé¢æ¿çè³è¨ãæ¥èæ¯å¥ä»¶çå稱ï¼éè£¡ä½¿ç¨ tuttoolbar ç¶ä½æåçå¥ä»¶å稱ã第ä¸é¨ä»½ï¼èªªææåå°ææ´å±çå·²å®è£å¥ä»¶å稱ï¼ãclassic/1.0ãæ¯ä½ æä¸ç´ç¨å°çå¼ãæå¾ï¼ä¹æ¯æéè¦çé¨ä»½ï¼å°±æ¯å å«é¢æ¿æªæ¡çç®éè·¯å¾ã注æå°éåè·¯å¾å¾é¢çæç·(/)ï¼éåæç·æ¯å¿ è¦çï¼ç¢ºå®ä½ æè¼¸å ¥ã
建ç«åçæªæ¡ (Creating the Image Files)
æåæè®æ¯åå·¥å ·åæé使ç¨åèªçååã注æå°ï¼éä¸æ¯æææçææ¯ç²¾ç·»çä½æ³ï¼ä½æ¯å¯ä»¥è®äººæ´å®¹æäºè§£ãæ´å¥½çæ¹å¼æ¯ä½¿ç¨åå樣å¼è¡¨ï¼ä½æ¯é£è¶ åºé份æåçç¯åã
æåéè¦äºåååä¾å·¥å ·åççµåé¸å®ä½¿ç¨ï¼ä¸»è¦é¸å®ãç¶åæå°æéã網é æå°æéãåçæå°é¸å®ä»¥åå¯èª¿æ´ç移é§æ¨è¨ãå¨ä¸é¢çå表ä¸ï¼æäºåæç¨å¨éåå¥ä»¶çååã注æï¼ éäºååé½æ¯éæç PNG æ ¼å¼æªæ¡ï¼å¦æä½ ä½¿ç¨ IE ææ¯å ¶ä»ç覽å¨ï¼å¯è½ä¸è½æ£ç¢ºå°é¡¯ç¤ºã
主è¦é¸å®å示 Main Menu Icon (main.png): http://wiki.moztw.org/uimages/b/b7/Borngeek_main.png
ç¶åæå°å示 Combined Search Icon (combined.png): http://wiki.moztw.org/uimages/3/36/Borngeek_combined.png
網é æå°å示 Web Search Icon (web.png): http://wiki.moztw.org/uimages/9/9c/Borngeek_web.png
åçæå°å示 Images Search Icon (images.png): http://wiki.moztw.org/uimages/6/61/Borngeek_images.png
å¯èª¿æ´ç§»é§æ¨è¨å示 Resizing Gripper Icon (gripper.png): http://wiki.moztw.org/uimages/5/50/Borngeek_gripper.png
å°éäºååå²åå¨æååå建ç«ç skin ç®é裡ï¼æªæ¡çµæ§æåé樣ï¼
+- TutToolbar/ +- install.rdf +- chrome.manifest +- chrome/ +- content/ +- tuttoolbar.xul +- skin/ +- combined.png +- gripper.png +- images.png +- main.png +- web.png
èç±ä¸²æ¥æ¨£å¼è¡¨å¥ç¨åç (Applying the Images with CSS)
ç¾å¨ï¼æéäºååå¯ä»¥ä½¿ç¨ï¼é¢æ¿ç®éä¹å·²ç¶è¨»åï¼æåå¯ä»¥éå§æååå¥ç¨å¨å·¥å ·åæéä¸äºãæåå°æèç± CSS ä¾å®æãå°±å¦æå¨æåä¸éå§æå°çï¼å¦æä½ å° CSS ä¸çæï¼å¯ä»¥åè W3Schools ç excellent CSS tutorial ã
è®æåéå§å»ºç« CSS æªæ¡å§ï¼å¨ skin ç®éä¸ï¼å»ºç«ä¸åæªåçº tuttoolbar.css çæªæ¡ï¼æéåæªæ¡è·ååæ¾å¨ä¸èµ·ãæªæ¡çµæ§å¦ä¸ï¼
+- TutToolbar/ +- install.rdf +- chrome.manifest +- chrome/ +- content/ +- tuttoolbar.xul +- skin/ +- combined.png +- gripper.png +- images.png +- main.png +- web.png +- tuttoolbar.css
å¨èªªæç´°ç¯åï¼å è®æåä¾çç樣å¼è¡¨çå §å®¹ï¼
#TutTB-MainMenu { list-style-image: url("chrome://tuttoolbar/skin/main.png"); } #TutTB-Combined-Button { list-style-image: url("chrome://tuttoolbar/skin/combined.png"); } #TutTB-Combined-Button > .toolbarbutton-menubutton-button { -moz-box-orient: horizontal; } #TutTB-Web-Button, #TutTB-Combined-Web { list-style-image: url("chrome://tuttoolbar/skin/web.png"); } #TutTB-Combined-Image { list-style-image: url("chrome://tuttoolbar/skin/images.png"); } #TutTB-ResizeBar { background-image: url("chrome://tuttoolbar/skin/gripper.png"); min-height: 22px; min-width: 3px; } #TutTB-ResizeSplitter { background: transparent; border: none !important; }
第ä¸é è¦åæ¯æå®è©²åå給ã主è¦é¸å®ãæé使ç¨ãå顧ä¸ä¸ç¬¬ä¸ç« ï¼æå給äºè©²æéä¸å ID å¼ï¼TutTB-MainMenuï¼æåç¨è©²å¼ä¾è¨å®æé顯示çååãå¨åé¢çäºè(#)æ¯ ID é¸åå¨(ID selector)ï¼ä¹å°±æ¯ç¨ä¾æå® CSS å ç´ è¦åçç¹å®èå¥å¼ãå¨å·¥å ·åæé裡ï¼æåä½¿ç¨ CSS 屬æ§ç list-style-image ä¾æå®ååã注æå°æå使ç¨çæ¯ chrome è·¯å¾ï¼ä¹å°±æ¯å¥ä»¶æªæ¡çµæ§ä¸çååè·¯å¾ï¼å¸¸ç¨çæ ¼å¼å¦ä¸ï¼
chrome://<packagename>/skin/<image_file_name>
å¨æåçç¯ä¾è£¡ï¼å°è£å稱(package name)æ¯ tuttoolbarï¼è主è¦é¸å®ä½¿ç¨çåååç¨±çº main.pngãä½ å¯ä»¥çå°ï¼ææçå·¥å ·åæé使ç¨é¡ä¼¼çè¦åï¼å¨ç¶åæå°æéçé¸å®é ç®ä¹æ¯ä¸æ¨£ãThere's one caveat to handling menu item icons, however. åæ³ä¸ä¸ï¼å¨ç¶åæå°é¸å®ä¸ï¼æåçºé¸å®é ç®ä½¿ç¨äºä¸åç¹å¥çé¡å¥å¼ï¼menuitem-iconicï¼éæ¯ Firefox å §å»ºçãéåå¼ãååãå示æ¯æ´ä½¿ç¨å®çæ¯åé¸å®é ç®ã
æ³å¿ ä½ ä¹æ³¨æå°äºéåç¶åæå°æéçç¹å®è¦åï¼
#TutTB-Combined-Button > .toolbarbutton-menubutton-button { -moz-box-orient: horizontal; }
éåç¹å¥ç CSS 屬æ§å¨éè£¡ä½¿ç¨ -moz-box-orientï¼éæå®æéçæ¨ç±¤è©²å¦ä½é¡¯ç¤ºï¼æ°´å¹³ææ¯åç´é¡¯ç¤ºãå·¥å ·åæéæ¨ç±¤çé è¨å¼æ¯åç´é¡¯ç¤ºï¼ä¹å°±æ¯é¡¯ç¤ºå¨å示ä¸æ¹ãå¨éåç¯ä¾ï¼ä¸ä½¿ç¨é樣çæ¹å¼ï¼æ以æåæ¹çºæ°´å¹³é¡¯ç¤ºï¼ä»¥ä½¿æ¨ç±¤é¡¯ç¤ºå¨å示ä¹å¾ã
å¨èçå¯èª¿æ´ç移é§æ¨è¨(resizing gripper)æï¼æå ©æ¢æ¨£å¼è¡¨çè¦åãéè¨å¾å¨ç¬¬åç« è£¡ï¼æåå¨åé¢çå ç´ (splitter element)使ç¨ç vbox å ç´ åï¼æåçºç§»é§æ¨è¨ä½¿ç¨äº vbox ä¾é¡¯ç¤ºèæ¯ååãé次ï¼æåä½¿ç¨ background-image 屬æ§ãæåå¿ é èç± min-height è min-width 屬æ§ï¼æä¾æå°é«åº¦èæå°å¯¬åº¦ï¼ä»¥è®ç§»é§æ¨è¨é¡¯ç¤ºåºä¾ãvbox è hbox 屬æ§çé è¨å¼å¯è½æ¯ä¾å §å®¹å¤§å°å¤å®ãç±æ¼ vbox æ¯ç©ºçï¼é è¨å¼å°±æ¯ 0ï¼éä¹é¿å æåæçå°èæ¯ååã
æåä¹çºåé¢çå ç´ æä¾ä¸æ¢è¦åã æåè®èæ¯æ¯éæçï¼èä¸ä¸ä½¿ç¨éæ¡(åé¢å ç´ çé è¨å¼æ¯æ使ç¨éæ¡ç)ãç¾å¨ï¼CSS æªæ¡å·²ç¶å®æï¼æåè¦è¨å®è¦è¼(overlay)以使ç¨å®ã
使ç¨æ¨£å¼è¡¨ (Using the Style Sheet)
åªæä¸è¡ç¨å¼ç¢¼æ¯éè¦è¢«å å ¥å¨ XUL è¦è¼çï¼éç¨ä¾ååæååå建ç«ç樣å¼è¡¨ãéå¿ é æ¾ç½®å¨ XML 宣åæ令çä¸æ¹ï¼ä»¥åè¦è¼(overlay)å ç´ ä¹åãä¸é¢ï¼æååºè¦è¼æªæ¡çåå¹¾è¡éè¦æ´åçå°æ¹ï¼
<?xml version="1.0"?> <?xml-stylesheet href="chrome://tuttoolbar/skin/tuttoolbar.css" type="text/css"?> <overlay id="TutTB-Overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> (... rest of XUL overlay file ...)
å°±åæåå¨æ¨£å¼è¡¨ä¸çå°çååä¸æ¨£ï¼chrome è·¯å¾è¢«ç¨ä¾æå®ä½ç½®ãè type 屬æ§åªæ¯ææéæ¯ CSS çæªæ¡ãç¾å¨è®æåççè¦è¼æªæ¡å¨å å ¥éä¸è¡å¾çå®æ´å §å®¹[View XUL Overlay Revision 6]ï¼
<?xml version="1.0"?> <?xml-stylesheet href="chrome://tuttoolbar/skin/tuttoolbar.css" type="text/css"?> <overlay id="TutTB-Overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <toolbox id="navigator-toolbox"> <toolbar id="TutTB-Toolbar" toolbarname="Tutorial Toolbar" accesskey="T" class="chromeclass-toolbar" context="toolbar-context-menu" hidden="false" persist="hidden"> <toolbaritem flex="0"> <toolbarbutton id="TutTB-MainMenu" type="menu" tooltiptext="Tutorial Toolbar Main Menu"> <menupopup> <menuitem label="Google Home Page" accesskey="G" tooltiptext="Navigate to Google" oncommand="TutTB_LoadURL('http://www.google.com/')" /> <menuseparator /> <menuitem label="Born Geek Website" accesskey="B" tooltiptext="Navigate to Born Geek" oncommand="TutTB_LoadURL('http://www.borngeek.com/')" /> </menupopup> </toolbarbutton> </toolbaritem> <toolbaritem id="TutTB-SearchTerms-TBItem" persist="width"> <menulist id="TutTB-SearchTerms" editable="true" flex="1" minwidth="100" width="250" onkeypress="TutTB_KeyHandler(event);"> <menupopup id="TutTB-SearchTermsMenu" onpopupshowing="TutTB_Populate()" /> </menulist> </toolbaritem> <splitter id="TutTB-ResizeSplitter" state="open" collapse="none" resizebefore="closest" resizeafter="farthest" tooltiptext="Resize the Search Box"> <vbox id="TutTB-ResizeBar" /> </splitter> <toolbaritem flex="0"> <toolbarbutton id="TutTB-Combined-Button" label="Search" type="menu-button" tooltiptext="Combined Search" oncommand="TutTB_Search(event, 'web')"> <menupopup> <menuitem id="TutTB-Combined-Web" label="Web Search" class="menuitem-iconic" tooltiptext="Search the Web" oncommand="TutTB_Search(event, 'web'); event.preventBubble();" /> <menuitem id="TutTB-Combined-Image" label="Image Search" class="menuitem-iconic" tooltiptext="Search Images" oncommand="TutTB_Search(event, 'image'); event.preventBubble();" /> </menupopup> </toolbarbutton> <toolbarseparator /> <toolbarbutton id="TutTB-Web-Button" tooltiptext="Search the Web" label="Web Search" oncommand="TutTB_Search(event, 'web')" /> </toolbaritem> <toolbarspring /> </toolbar> </toolbox> </overlay>
å¥å¿è¨è¦æ¸¬è©¦ï¼ç¨åæ éç¼ç Firefox å¯æ¬éåï¼ç¶å¾ççå¥ä»¶ç樣åãæ¥ä¸ä¾ï¼æåè¦çºå·¥å ·åæ³¨å ¥çå½ã
第å ç« ï¼ä¸»ç¨å¼ (Scripting the Toolbar)
å¥ä»¶é常æ¯ç¨ JavaScript å·è¡çï¼éæ¯ä¸ç¨®ç°¡å®æå¸çç¨å¼èªè¨ãä½ å°æç¼ç¾ï¼æåçå·¥å ·åå¥ä»¶çç¨å¼ç¢¼æ¯é常簡å®çãæåå°æ大é使ç¨æ件ç©ä»¶æ¨¡å(DOM)ï¼éå¯ä»¥è®æåèçå®ç¨çå ç´ ã
å¨æåéå§åï¼ä½ è¦å ç¥éä¸åéé»ãid 屬æ§å¿ é æ¯æ´åç覽å¨å¯ä¸çï¼è JavaScript çè®æ¸åå½å¼ä¹æ¯ãå¨ç覽å¨è¦è¼ä¸çJavaScript æ¯å ¨åæ§çï¼å æ¤æææéåéå¶ãæåå°æ使ç¨è· XUL å ç´ ä¸æ¨£çæå·§ï¼ææçè®æ¸åå½å¼çå稱ï¼å°ææ以æåå¥ä»¶çºåèµ·å§å稱ãæåä½¿ç¨ TutTB_ ç¶ä½èµ·å§å稱ï¼æ以æåçæå°å½å¼ææ¯ TutTB_Search()ã
ç¾å¨ï¼è®æåå»ºç« JavaScript æªæ¡ãå¨ content ç®éä¸ï¼å»ºç«ä¸å tuttoolbar.js çæåæªãç®éçµæ§å¦ä¸ï¼
+- TutToolbar/ +- install.rdf +- chrome.manifest +- chrome/ +- content/ +- tuttoolbar.xul +- tuttoolbar.js +- skin/ +- combined.png +- gripper.png +- images.png +- main.png +- web.png +- tuttoolbar.css
å¨å»ºç«ä»»ä½ç¨å¼ç¢¼åï¼å å訴 XUL æªæ¡è©²å¦ä½ä½¿ç¨ JavaScript æªæ¡ã
é£çµ XUL è JavaScript (Tying XUL to JavaScript)
æåç XUL æªæ¡ tuttoolbar.xul éè¦è¢«åç¥ç¸å°æç JavaScript æªï¼æåå¯ä»¥ä½¿ç¨ä¸é¢çæè¿°ï¼
<script type="application/x-javascript" src="chrome://tuttoolbar/content/tuttoolbar.js" />
éå¿ é æ¾ç½®å¨ overlay å ç´ ä¹ä¸ãtype 屬æ§æ¯æå®ä½¿ç¨ JavaScriptï¼src 屬æ§æ¯æå®åå建ç«ç JavaScript æªãå §å®¹å¦ä¸[View XUL Overlay Revision 7]ï¼
<?xml version="1.0"?> <?xml-stylesheet href="chrome://tuttoolbar/skin/tuttoolbar.css" type="text/css"?> <overlay id="TutTB-Overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <script type="application/x-javascript" src="chrome://tuttoolbar/content/tuttoolbar.js" /> <toolbox id="navigator-toolbox"> <toolbar id="TutTB-Toolbar" toolbarname="Tutorial Toolbar" accesskey="T" class="chromeclass-toolbar" context="toolbar-context-menu" hidden="false" persist="hidden"> <toolbaritem flex="0"> <toolbarbutton id="TutTB-MainMenu" type="menu" tooltiptext="Tutorial Toolbar Main Menu"> <menupopup> <menuitem label="Google Home Page" accesskey="G" tooltiptext="Navigate to Google" oncommand="TutTB_LoadURL('http://www.google.com/')" /> <menuseparator /> <menuitem label="Born Geek Website" accesskey="B" tooltiptext="Navigate to Born Geek" oncommand="TutTB_LoadURL('http://www.borngeek.com/')" /> </menupopup> </toolbarbutton> </toolbaritem> <toolbaritem id="TutTB-SearchTerms-TBItem" persist="width"> <menulist id="TutTB-SearchTerms" editable="true" flex="1" minwidth="100" width="250" onkeypress="TutTB_KeyHandler(event);"> <menupopup id="TutTB-SearchTermsMenu" onpopupshowing="TutTB_Populate()" /> </menulist> </toolbaritem> <splitter id="TutTB-ResizeSplitter" state="open" collapse="none" resizebefore="closest" resizeafter="farthest" tooltiptext="Resize the Search Box"> <vbox id="TutTB-ResizeBar" /> </splitter> <toolbaritem flex="0"> <toolbarbutton id="TutTB-Combined-Button" label="Search" type="menu-button" tooltiptext="Combined Search" oncommand="TutTB_Search(event, 'web')"> <menupopup> <menuitem id="TutTB-Combined-Web" label="Web Search" class="menuitem-iconic" tooltiptext="Search the Web" oncommand="TutTB_Search(event, 'web'); event.preventBubble();" /> <menuitem id="TutTB-Combined-Image" label="Image Search" class="menuitem-iconic" tooltiptext="Search Images" oncommand="TutTB_Search(event, 'image'); event.preventBubble();" /> </menupopup> </toolbarbutton> <toolbarseparator /> <toolbarbutton id="TutTB-Web-Button" tooltiptext="Search the Web" label="Web Search" oncommand="TutTB_Search(event, 'web')" /> </toolbaritem> <toolbarspring /> </toolbar> </toolbox> </overlay>
çºæéå ä¸åè½ (Adding Functionality to the Buttons)
éè¨å¾æåçºå·¥å ·åæéæä¾ç oncommand 屬æ§åï¼éå屬æ§æ¯æå®ç¨å¼ç¢¼å·è¡çäºä»¶ãæåä¹å¯ä»¥ä½¿ç¨ onclick ä»£æ¿ oncommandï¼ä½æ¯ onclick å°éµç¤ç¡æï¼è oncommand å¯ä»¥åæåæéµç¤èæ»é¼ çåä½ãè®æåå顧ä¸ä¸æå°æéï¼
oncommand="TutTB_Search(event, 'web')"
éåå¼å¼å« TutTB_Search() å½å¼ï¼å ¶ä¸å å«å ©åå¼ï¼éåå½å¼å¼å«çäºä»¶(event)ï¼ä»¥åæå°ç網é (web)ã
ç¨å¼ç¢¼å¦ä¸[View JavaScript Revision 1]ï¼
//////////////////////////////////////////////////////////////////////////////// // TutTB_Search() å½å¼æçºæåå®ææå°ãevent åæ¸æ觸ç¼å½å¼çå¼å«ï¼type åæ¸ // çºæå°çé¡åã //////////////////////////////////////////////////////////////////////////////// function TutTB_Search(event, type) { // å°è¦ç覽ç網å var URL = ""; // 辨å¥æå°æ¬ä½æ¯å¦çºç©ºå¼ var isEmpty = false; // èçæå°æ¬ä½ ( <menulist> å ç´ ) var searchTermsBox = document.getElementById("TutTB-SearchTerms"); // å¾æå°æ¬ä½ååºå串ï¼æ´çå¿ è¦çç©ºç½ // å¯ä»¥å¨ä¸é¢çç TutTB_TrimString() å½å¼éä½çç´°ç¯ var searchTerms = TutTB_TrimString(searchTermsBox.value); if(searchTerms.length == 0) // Is the search terms box empty? isEmpty = true; // If so, set the isEmpty flag to true else // If not, convert the terms to a URL-safe string searchTerms = TutTB_ConvertTermsToURI(searchTerms); // é¸ææå°çé¡å // å¦ææ¬ä½æ¯ç©ºç½çï¼æåæå¼å°ä½¿ç¨è å° Google 網é ä¸é©ç¶çå°æ¹ã // å¦åï¼æå°è¼¸å ¥çæåã switch(type) { // 建ç«åçæå°ç網å case "image": if(isEmpty) { URL = "http://images.google.com/"; } else { URL = "http://images.google.com/images?q=" + searchTerms; } break; // 建ç«ç¶²é æå°ç網å case "web": default: if(isEmpty) { URL = "http://www.google.com/"; } else { URL = "http://www.google.com/search?q=" + searchTerms; } break; } // ä½¿ç¨ TutTB_LoadURL å½å¼å¨ç覽è¦çªä¸è¼å ¥ç¶²å TutTB_LoadURL(URL); } //////////////////////////////////////////////////////////////////////////////// // TutTB_TrimString() å½å¼æä¿®åªå串çåå¾ç©ºç½é¨ä»½ï¼ç¶å¾å°ææç空ç½é¨ä»½è½ææ // å®ä¸å空ç½ï¼ç¶å¾å³åä¿®æ¹å¾å串ã //////////////////////////////////////////////////////////////////////////////// function TutTB_TrimString(string) { // å¦æå³å ¥çå串ç¡æï¼ææ¯æ²ææ±è¥¿ï¼åå³åç©ºå¼ if (!string) return ""; string = string.replace(/^\s+/, ''); // Remove leading whitespace string = string.replace(/\s+$/, ''); // Remove trailing whitespace // å°ææ空ç½é¨ä»½ç¨å®ä¸ç©ºç½ä»£æ¿ string = string.replace(/\s+/g, ' '); return string; // å³åæ¹è®å¾çå¼ } //////////////////////////////////////////////////////////////////////////////// // TutTB_ConvertTermsToURI() å½å¼å°å³å ¥çæå°å串è½æçºå®å ¨ç網å //////////////////////////////////////////////////////////////////////////////// function TutTB_ConvertTermsToURI(terms) { // 建ç«é£ååæ¾æ¯åæå°å串 var termArray = new Array(); // ç¨ç©ºç½åå åå²å串 termArray = terms.split(" "); // ç¨ä¾åæ¾å®å ¨ç網å var result = ""; // å¨å串ä¸éè¿´ for(var i=0; i<termArray.length; i++) { // å¨ç¬¬ä¸åå串å¾çææçå串æç¨å è(+)éé if(i > 0) result += "+"; // ä½¿ç¨ Firefox å §å»ºç encodeURIComponent() å½å¼å å¯ result += encodeURIComponent(termArray[i]); } return result; // å³åçµæ } //////////////////////////////////////////////////////////////////////////////// // TutTB_LoadURL() å½å¼å¨ç覽å¨ä¸è¼å ¥ç¹å®ç網å //////////////////////////////////////////////////////////////////////////////// function TutTB_LoadURL(url) { // å¨ç¶²ååè¨å®å³å ¥ç網å window._content.document.location = url; // Make sure that we get the focus window.content.focus(); }
éåä½ ç Firefox éç¼çæ¬ï¼å¨æåçå·¥å ·åå¥ä»¶è¼¸å ¥æå°çå¼ï¼ç¶å¾æä¸ç¶²é æå°æéãç¨å¼ç¢¼æ該æå·è¡ï¼ç¶å¾æåºç¾æå°çµæãéååæ éç¼çæ¬ç¢ºå¯¦æ¯ç¸ç¶ä¾¿å©çå§ï¼
æéé¸å®ç注æäºé (A Special Note About Button-Menu Buttons)
å¨æåé²å ¥ä¸ä¸å¼µç« ç¯ä¹åï¼æä¸é»éæ¼æéé¸å®æè¦æ³¨æçãåæ³ä¸ä¸ï¼éé¡åçæéæä¾å¯ä»¥é»æçæéèå½åºå¼é¸å®(主è¦ç¯ä¾çºå¾åèåå¾ç覽)ãä¹æ³ä¸ä¸ï¼toolbarbutton 以åå å« oncommand ç menuitem å ç´ ãç¶å·¥å ·åæéçä¸é¨å被ååï¼toolbarbutton å ç´ ç oncommand ç¨å¼ç¢¼å¦ä½ æææç被å·è¡ãä½æ¯ï¼ç¶ä½¿ç¨è ååäºmenuitem å ç´ çå ¶ä¸ä¸åæï¼æç¼çä»éº¼äºï¼
ä¸åªæ¯ menuitem å ç´ ç oncommand äºä»¶å·è¡ï¼toolbarbutton å ç´ çäºä»¶ä¹è¢«å·è¡ãæä»¥å ©åäºä»¶æ¯åæå·è¡çï¼åç®¡ä½ åªæ¯æ³è¦å ¶ä¸ä¸ä»¶è¢«å·è¡ãå çº toolbarbutton äºä»¶æ¯æå¾ç¼ççï¼æ以實éå·è¡çæ¯ toolbarbutton äºä»¶ãæå¥è©±èªªï¼menuitem äºä»¶æ²ææ©æå·è¡ãé£æåè¦æ樣解決éååé¡å¢ï¼äºå¯¦ä¸ï¼æ¯æ辦æ³çãè®æåå¾åçç menuitem å ç´ ï¼
<menuitem id="TutTB-Combined-Image" label="Image Search" class="menuitem-iconic" tooltiptext="Search Images" oncommand="TutTB_Search(event, 'image'); event.preventBubble();" />
èç±ä½¿ç¨ DOM å½å¼ preventBubble()ï¼æåå¯ä»¥é¿å oncommand 被å·è¡ãçºäºé¿å å¤é·å¤¢å¤ï¼è¨ä½ä¸ä»¶äºï¼ç¶ä½ 建ç«æéé¸å®æï¼è¨å¾å¨ menuitem å ç´ ç oncommand 屬æ§å å ¥ event.preventBubble()ã
çºæå°åå å ¥åè½ (Adding Functionality to the Search Box)
ç¾å¨ï¼æåå·²ç¶è®æå°æéå¯ä»¥ä½¿ç¨ï¼æ¥ä¸ä¾ï¼æåéè¦å¹«æå°åå å ¥ä¸äºåè½ãè®ä½¿ç¨è å¯ä»¥å¨è¼¸å ¥å串å¾æä¸ãEnterã以å·è¡æå°ãè¦æ麼åå¢ï¼è®æåççè¦ä½¿ç¨çå½å¼ï¼
<toolbaritem id="TutTB-SearchTerms-TBItem" persist="width"> <menulist id="TutTB-SearchTerms" editable="true" flex="1" minwidth="100" width="250" onkeypress="TutTB_KeyHandler(event);"> <menupopup id="TutTB-SearchTermsMenu" onpopupshowing="TutTB_Populate()" /> </menulist> </toolbaritem>
é次ï¼æåä½¿ç¨ onkeypress ä»£æ¿ oncommandãéåäºä»¶æå¨ä½¿ç¨è å¨æå°åæä¸æéµæ觸ç¼ãå¨éåç¯ä¾ï¼æå建ç«ä¸åç¸ç¶ç°¡å®ç TutTB_KeyHandler()å½å¼ï¼
function TutTB_KeyHandler(event) { if(event.keyCode == event.DOM_VK_RETURN) TutTB_Search(event, 'web'); }
éåå½å¼åªä¸éæ¯è¦æª¢æ¥ãEnterãæ¯å¦è¢«æä¸ãå¦ææ¯ï¼TutTB_Search()æ被å¼å«ãå¦åï¼ä¸åä»»ä½äºãè®æåä¾ççå å ¥æ¤å½å¼ç JavaScript æªæ¡[View JavaScript Revision 2]ï¼
//////////////////////////////////////////////////////////////////////////////// // TutTB_Search() å½å¼æçºæåå®ææå°ãevent åæ¸æ觸ç¼å½å¼çå¼å«ï¼type åæ¸ // çºæå°çé¡åã //////////////////////////////////////////////////////////////////////////////// function TutTB_Search(event, type) { // å°è¦ç覽ç網å var URL = ""; // 辨å¥æå°æ¬ä½æ¯å¦çºç©ºå¼ var isEmpty = false; // èçæå°æ¬ä½ ( <menulist> å ç´ ) var searchTermsBox = document.getElementById("TutTB-SearchTerms"); // å¾æå°æ¬ä½ååºå串ï¼æ´çå¿ è¦çç©ºç½ // å¯ä»¥å¨ä¸é¢çç TutTB_TrimString() å½å¼éä½çç´°ç¯ var searchTerms = TutTB_TrimString(searchTermsBox.value); if(searchTerms.length == 0) // æå°æ¬ä½æ¯ç©ºç½çåï¼ isEmpty = true; // æ¯ï¼è¨å® isEmpty çº true else // ä¸ï¼è½æçºå®å ¨ç網å searchTerms = TutTB_ConvertTermsToURI(searchTerms); // é¸ææå°çé¡å // å¦ææ¬ä½æ¯ç©ºç½çï¼æåæå¼å°ä½¿ç¨è å° Google 網é ä¸é©ç¶çå°æ¹ã // å¦åï¼æå°è¼¸å ¥çæåã switch(type) { // 建ç«åçæå°ç網å case "image": if(isEmpty) { URL = "http://images.google.com/"; } else { URL = "http://images.google.com/images?q=" + searchTerms; } break; // 建ç«ç¶²é æå°ç網å case "web": default: if(isEmpty) { URL = "http://www.google.com/"; } else { URL = "http://www.google.com/search?q=" + searchTerms; } break; } // ä½¿ç¨ TutTB_LoadURL å½å¼å¨ç覽è¦çªä¸è¼å ¥ç¶²å TutTB_LoadURL(URL); } //////////////////////////////////////////////////////////////////////////////// // TutTB_TrimString() å½å¼æä¿®åªå串çåå¾ç©ºç½é¨ä»½ï¼ç¶å¾å°ææç空ç½é¨ä»½è½ææ // å®ä¸å空ç½ï¼ç¶å¾å³åä¿®æ¹å¾å串ã //////////////////////////////////////////////////////////////////////////////// function TutTB_TrimString(string) { // å¦æå³å ¥çå串ç¡æï¼ææ¯æ²ææ±è¥¿ï¼åå³åç©ºå¼ if (!string) return ""; string = string.replace(/^\s+/, ''); // Remove leading whitespace string = string.replace(/\s+$/, ''); // Remove trailing whitespace // å°ææ空ç½é¨ä»½ç¨å®ä¸ç©ºç½ä»£æ¿ string = string.replace(/\s+/g, ' '); return string; // å³åæ¹è®å¾çå¼ } //////////////////////////////////////////////////////////////////////////////// // TutTB_ConvertTermsToURI() å½å¼å°å³å ¥çæå°å串è½æçºå®å ¨ç網å //////////////////////////////////////////////////////////////////////////////// function TutTB_ConvertTermsToURI(terms) { // 建ç«é£ååæ¾æ¯åæå°å串 var termArray = new Array(); // ç¨ç©ºç½åå åå²å串 termArray = terms.split(" "); // ç¨ä¾åæ¾å®å ¨ç網å var result = ""; // å¨å串ä¸éè¿´ for(var i=0; i<termArray.length; i++) { // å¨ç¬¬ä¸åå串å¾çææçå串æç¨å è(+)éé if(i > 0) result += "+"; // ä½¿ç¨ Firefox å §å»ºç encodeURIComponent() å½å¼å å¯ result += encodeURIComponent(termArray[i]); } return result; // å³åçµæ } //////////////////////////////////////////////////////////////////////////////// // TutTB_LoadURL() å½å¼å¨ç覽å¨ä¸è¼å ¥ç¹å®ç網å //////////////////////////////////////////////////////////////////////////////// function TutTB_LoadURL(url) { // å¨ç¶²ååè¨å®å³å ¥ç網å window._content.document.location = url; // Make sure that we get the focus window.content.focus(); } //////////////////////////////////////////////////////////////////////////////// // TutTB_KeyHandler() 檢æ¥ãEnterãæ¯å¦è¢«è¼¸å ¥ãæ¯ç話ï¼å°±å·è¡æå° //////////////////////////////////////////////////////////////////////////////// function TutTB_KeyHandler(event) { // [ENTER]被æä¸äºåï¼å¦ææ¯ï¼å·è¡æå° if(event.keyCode == event.DOM_VK_RETURN) TutTB_Search(event, 'web'); }
å¨ä¸æ¬¡ï¼å·è¡ä½ ç Firefox éç¼çæ¬ï¼å¨æå°åè¼¸å ¥æå°å串ï¼ç¶å¾æä¸ãEnterããå°±åæ¯æä¸æå°æéä¸æ¨£ï¼æå°çµææ該æåºç¾ãç¾å¨ï¼æåçå¥ä»¶å·²ç¶æäºçå½ï¼
åæ ç½®å ¥é¸å® (Dynamically Populating a Menu)
åæ çå°é¸å®é ç®æ¾ç½®å¨é¸å®è£¡æ¯å¾æç¨çï¼é好éåç¹è²æ¯å¾å®¹æå®æçãå¨éåæå裡ï¼æåå°æå¨æå°åä¸æå¼é¸å®åæ çå å ¥ä¸äºé ç®ãè®æåççç¨ä¾å»ºç«å·¥å ·åçé¨ä»½ï¼
<toolbaritem id="TutTB-SearchTerms-TBItem" persist="width"> <menulist id="TutTB-SearchTerms" editable="true" flex="1" minwidth="100" width="250" onkeypress="TutTB_KeyHandler(event);"> <menupopup id="TutTB-SearchTermsMenu" onpopupshowing="TutTB_Populate()" /> </menulist> </toolbaritem>
注æå°ï¼å¨ menupopup å ç´ ç onpopupshowing 屬æ§ãæåæå® TutTB_Populate()å½å¼å¨æ¯æ¬¡ãå½åºå¼é¸å®ãå³å°é¡¯ç¤ºæ被å·è¡ï¼éåå½å¼å°æ建ç«æåçåæ é¸å®é ç®ãè®æåä¾ççå½å¼çç¨å¼ç¢¼[View TutTB_Populate() Code]ï¼
//////////////////////////////////////////////////////////////////////////////// // TutTB_Populate() å½å¼å¨å·¥å ·åæ¬ä½çä¸æå¼é¸å®æ¾ç½®åæ ç¢ççé¸å®é ç®ã // éç¶éä¸æ¯é常實ç¨çï¼ä½æ¯èç±éåç¯ä¾ï¼æåå¯ä»¥ççåæ é¸å®ç½®å ¥çéä½æ¹å¼ã //////////////////////////////////////////////////////////////////////////////// function TutTB_Populate() { // åå¾å½åºé¸å®å ç´ var menu = document.getElementById("TutTB-SearchTermsMenu"); // 移é¤å¨å½åºé¸å®ç®åçé ç® for(var i=menu.childNodes.length - 1; i >= 0; i--) { menu.removeChild(menu.childNodes.item(i)); } // æå®è¦å¨é¸å®å¢å çé ç®æ¸é var numItemsToAdd = 10; for(var i=0; i<numItemsToAdd; i++) { // 建ç«è¦å¢å çæ°é¸å®é ç® var tempItem = document.createElement("menuitem"); // è¨å®æ°é¸å®é ç®çæ¨ç±¤ tempItem.setAttribute("label", "Dynamic Item Number " + (i+1)); // å¨é¸å®ä¸æ°å¢é ç® menu.appendChild(tempItem); } }
éåå½å¼ç¯ä¾ä¸æå½ä»¤æ¯å menuitem å ç´ å»å·è¡é¸æçæ令ãçºäºè®æ¯å menuitem ç¥éæ該å·è¡çæ令ï¼æåå å åªè¦å å ¥ setAttribute()å½å¼ä¾èçäºä»¶åå·è¡ç¨å¼ç¢¼ãéæ¯èç oncommand äºä»¶çç¯ä¾ï¼
tempItem.setAttribute("oncommand", "TutTB_SomeFunction()");
å å ¥ TutTB_Populate()å½å¼å¾ç JavaScript æªæ¡[View JavaScript Revision 3]ï¼
//////////////////////////////////////////////////////////////////////////////// // TutTB_Search() å½å¼æçºæåå®ææå°ãevent åæ¸æ觸ç¼å½å¼çå¼å«ï¼type åæ¸ // çºæå°çé¡åã //////////////////////////////////////////////////////////////////////////////// function TutTB_Search(event, type) { // å°è¦ç覽ç網å var URL = ""; // 辨å¥æå°æ¬ä½æ¯å¦çºç©ºå¼ var isEmpty = false; // èçæå°æ¬ä½ ( <menulist> å ç´ ) var searchTermsBox = document.getElementById("TutTB-SearchTerms"); // å¾æå°æ¬ä½ååºå串ï¼æ´çå¿ è¦çç©ºç½ // å¯ä»¥å¨ä¸é¢çç TutTB_TrimString() å½å¼éä½çç´°ç¯ var searchTerms = TutTB_TrimString(searchTermsBox.value); if(searchTerms.length == 0) // æå°æ¬ä½æ¯ç©ºç½çåï¼ isEmpty = true; // æ¯ï¼è¨å® isEmpty çº true else // ä¸ï¼è½æçºå®å ¨ç網å searchTerms = TutTB_ConvertTermsToURI(searchTerms); // é¸ææå°çé¡å // å¦ææ¬ä½æ¯ç©ºç½çï¼æåæå¼å°ä½¿ç¨è å° Google 網é ä¸é©ç¶çå°æ¹ã // å¦åï¼æå°è¼¸å ¥çæåã switch(type) { // 建ç«åçæå°ç網å case "image": if(isEmpty) { URL = "http://images.google.com/"; } else { URL = "http://images.google.com/images?q=" + searchTerms; } break; // 建ç«ç¶²é æå°ç網å case "web": default: if(isEmpty) { URL = "http://www.google.com/"; } else { URL = "http://www.google.com/search?q=" + searchTerms; } break; } // ä½¿ç¨ TutTB_LoadURL å½å¼å¨ç覽è¦çªä¸è¼å ¥ç¶²å TutTB_LoadURL(URL); } //////////////////////////////////////////////////////////////////////////////// // TutTB_TrimString() å½å¼æä¿®åªå串çåå¾ç©ºç½é¨ä»½ï¼ç¶å¾å°ææç空ç½é¨ä»½è½ææ // å®ä¸å空ç½ï¼ç¶å¾å³åä¿®æ¹å¾å串ã //////////////////////////////////////////////////////////////////////////////// function TutTB_TrimString(string) { // å¦æå³å ¥çå串ç¡æï¼ææ¯æ²ææ±è¥¿ï¼åå³åç©ºå¼ if (!string) return ""; string = string.replace(/^\s+/, ''); // 移é¤åé¢ç©ºç½ string = string.replace(/\s+$/, ''); // 移é¤å¾é¢ç©ºç½ // å°ææ空ç½é¨ä»½ç¨å®ä¸ç©ºç½ä»£æ¿ string = string.replace(/\s+/g, ' '); return string; // å³åæ¹è®å¾çå¼ } //////////////////////////////////////////////////////////////////////////////// // TutTB_ConvertTermsToURI() å½å¼å°å³å ¥çæå°å串è½æçºå®å ¨ç網å //////////////////////////////////////////////////////////////////////////////// function TutTB_ConvertTermsToURI(terms) { // 建ç«é£ååæ¾æ¯åæå°å串 var termArray = new Array(); // ç¨ç©ºç½åå åå²å串 termArray = terms.split(" "); // ç¨ä¾åæ¾å®å ¨ç網å var result = ""; // å¨å串ä¸éè¿´ for(var i=0; i<termArray.length; i++) { // å¨ç¬¬ä¸åå串å¾çææçå串æç¨å è(+)éé if(i > 0) result += "+"; // ä½¿ç¨ Firefox å §å»ºç encodeURIComponent() å½å¼å å¯ result += encodeURIComponent(termArray[i]); } return result; // å³åçµæ } //////////////////////////////////////////////////////////////////////////////// // TutTB_LoadURL() å½å¼å¨ç覽å¨ä¸è¼å ¥ç¹å®ç網å //////////////////////////////////////////////////////////////////////////////// function TutTB_LoadURL(url) { // å¨ç¶²ååè¨å®å³å ¥ç網å window._content.document.location = url; // Make sure that we get the focus window.content.focus(); } //////////////////////////////////////////////////////////////////////////////// // TutTB_KeyHandler() 檢æ¥ãEnterãæ¯å¦è¢«è¼¸å ¥ãæ¯ç話ï¼å°±å·è¡æå° //////////////////////////////////////////////////////////////////////////////// function TutTB_KeyHandler(event) { // [ENTER]被æä¸äºåï¼å¦ææ¯ï¼å·è¡æå° if(event.keyCode == event.DOM_VK_RETURN) TutTB_Search(event, 'web'); } //////////////////////////////////////////////////////////////////////////////// // TutTB_Populate() å½å¼å¨å·¥å ·åæ¬ä½çä¸æå¼é¸å®æ¾ç½®åæ ç¢ççé¸å®é ç®ã // éç¶éä¸æ¯é常實ç¨çï¼ä½æ¯èç±éåç¯ä¾ï¼æåå¯ä»¥ççåæ é¸å®ç½®å ¥çéä½æ¹å¼ã //////////////////////////////////////////////////////////////////////////////// function TutTB_Populate() { // åå¾å½åºé¸å®å ç´ var menu = document.getElementById("TutTB-SearchTermsMenu"); // 移é¤å¨å½åºé¸å®ç®åçé ç® for(var i=menu.childNodes.length - 1; i >= 0; i--) { menu.removeChild(menu.childNodes.item(i)); } // æå®è¦å¨é¸å®å¢å çé ç®æ¸é var numItemsToAdd = 10; for(var i=0; i<numItemsToAdd; i++) { // 建ç«è¦å¢å çæ°é¸å®é ç® var tempItem = document.createElement("menuitem"); // è¨å®æ°é¸å®é ç®çæ¨ç±¤ tempItem.setAttribute("label", "Dynamic Item Number " + (i+1)); // å¨é¸å®ä¸æ°å¢é ç® menu.appendChild(tempItem); } }
åæ å å ¥å·¥å ·åæé (Dynamically Adding Toolbar Buttons)
å å ¥åæ å·¥å ·åæéå°±è·åæ ç½®å ¥é¸å®ä¸æ¨£ç°¡å®ï¼èä¸éé常ç¸ä¼¼ãé¦å ï¼æåéè¦ä¸åå å«åæ æéç容å¨ãå¨éå ï¼ toolbaritem å ç´ æ¯ä¸é¯çé¸æï¼æ¨è¨å¦ä¸ï¼
<toolbaritem id="TutTB-DynButtonContainer" />
ç¾å¨ï¼å®¹å¨å·²ç¶å¯ä»¥å©ç¨äºï¼æåå¯ä»¥ä½¿ç¨å®ï¼ä¾å å ¥åæ toolbarbutton å ç´ ï¼è®æåä¾çä¸ä¸å¯ä»¥è®æåå å ¥åæ æéçå½å¼ç¯ä¾ï¼
function TutTB_AddDynamicButtons() { // åå¾æåå¨ XUL æè¿°ä¸å¢å çå·¥å ·åé ç®ã容å¨ã var container = document.getElementById("TutTB-DynButtonContainer"); // 移é¤ææåå¨çæé for(i=container.childNodes.length; i > 0; i--) { container.removeChild(container.childNodes[0]); } // å¢å äºååæ æé for(var i=0; i<5; i++) { var tempButton = null; tempButton = document.createElement("toolbarbutton"); tempButton.setAttribute("label", "Button " + i); tempButton.setAttribute("tooltiptext", "Button " + i); tempButton.setAttribute("oncommand", "TutTB_SomeFunction()"); container.appendChild(tempButton); } }
éåå½å¼åç½®å ¥åæ é¸å®é常ç¸ä¼¼ãæåå¾å®¹å¨ä¸ç§»é¤ç¾æçåæ æéï¼ç¶å¾å å ¥æ°çã
Optional Programming Exerciseï¼è©¦èç¨éåæ¦å¿µä¾å¢å ãæå°å串æé(search word buttons)ãå°å·¥å ·åãç¶ä½¿ç¨è å¨æå°å串æééµå ¥æåæï¼åæ å°å¢å æéå°å·¥å ·åçæå¾ï¼ä¸åæéä¸ååãéå æå¹¾åæ示ï¼
- ä½ éè¦å¢å toolbaritem 容å¨å° XUL æè¿°æªçæå¾(right before the toolbarspring element is a good choice)ãç¢ºå® ID æ¯å¯ä¸çã
- å¨ menulist å ç´ ä¸ä½¿ç¨ oninput äºä»¶ï¼éåäºä»¶æå¨ä½¿ç¨è è¼¸å ¥æåæ觸ç¼ã
- ä½ å¼å«ç JavaScript æåä¸åçäºï¼(a)å¨æå°æ¬ä½ä¸åå¾æå°æå(b)移é¤ææå å建ç«çåæ æé(c)以空ç½åéæå°æå(d)çºæ¯åç¨ç«çæå建ç«æéã
éå°±æ¯æèç Googlebar Lite çæ¹å¼ã
ééèååæé (Disabling and Enabling Buttons)
(éé¨ä»½åªæ¯åè¨´ä½ æ麼ç¨ï¼å¨éåå·¥å ·åç¯ä¾ä¸¦ä¸æåºç¾)ã
ä½ å¶ç¾å¯è½ææ³è¦ééææ¯ååå·¥å ·åæéãèåä¾åï¼Googlebar Lite çé«äº®åº¦æ¨è¨æéä¸æå¨æå°æ¬ä½æ²ææå°å串æç¼çä½ç¨ï¼åªè½å·è¡æ¼ææå°å串æã
ä¸é¢çä¾åæ¯å¦ä½å»ºç«ä¸åå¯ä»¥æ§å¶ééçä¸è¬å·¥å ·åæéãå次æéï¼éä¸æ¯å¯¦ç¨çç¯ä¾ï¼åªæ¯èæéåæææ¯å¯ä»¥åå¾å°çãæ¥èæ¯é¸å®é ç®çæè¿°æ¨è¨ï¼
<menuitem label="Toggle Web Search Button" tooltiptext="Toggle Web Search Button" oncommand="TutTB_ToggleWebSearchButton()" />
TutTB_ToggleWebSearchButton()å½å¼çç¨å¼ç¢¼ï¼
function TutTB_ToggleWebSearchButton() { var button = document.getElementById("TutTB-Web-Button"); var value = button.disabled; if(value == true) button.disabled = false; else button.disabled = true; }
é¦å ï¼æåå°æè趣çå·¥å ·åæéä½¿ç¨ ID å¼ä»¥å getElementById()å½å¼ãåªè¦ææéï¼æåå°±è½ä½¿ç¨ disabled 屬æ§æ§å¶è©²æéç©ä»¶çç¾æçæ (ååæéé)ãå¦æå¼çº trueï¼å°±ä½¿ç¨ false åæ¶æéééï¼åä¹äº¦ç¶ãFirefox æ幫æåèçæéçééï¼è®è©²æéä¸è½é»æ(note that the button's image may not appeared grayed out: we must rely on skinning for that)ã
åæ 顯示èé±èæé (Dynamically Showing and Hiding Buttons)
(éé¨ä»½åªæ¯åè¨´ä½ æ麼ç¨ï¼å¨éåå·¥å ·åç¯ä¾ä¸¦ä¸æåºç¾)ã
Googlebar Lite å 許使ç¨è é¸ææéå¨å·¥å ·åæçå°ç樣åãä¹å°±æ¯èªªï¼å·¥å ·åå¿ é è½å¤ åæ ç顯示ææ¯é±èå¯ç¨çæéãéæ¯æåè¦å®æç JavaScriptç¨å¼ç¢¼ç段ï¼
var TB_Web = document.getElementById("TutTB-Web-Button"); TB_Web.setAttribute("hidden", !TutTB_ShowWebButton);
é¦å æåè®å·¥å ·åæéä½¿ç¨ getElementById() å½å¼ï¼ç¶å¾æåå¼å« setAttribute()å½å¼ä¾æ¹è® hidden 屬æ§çå¼ãä½ æç¼ç¾éå hidden å¼è·æå¨ TutTB_ShowWebButton æè¨å®çç¸åãéåå¼æ¯åå¸ææ¨ç±¤(boolean flag)ï¼ç¨ä¾è¾¨å¥ä½¿ç¨è æ¯å¦æ³è¦çå°ã網é æå°ãæéãå²åå¨éåè®æ¸çå¼ï¼æ¯å¾ä½¿ç¨è è¨å®ä¸è®åå°çãç¹¼çºé±è®ï¼ä¾ççæåå¦ä½åå°éé»ã
è®åèå²å使ç¨è è¨å® (Reading and Storing User Preferences)
(éé¨ä»½åªæ¯åè¨´ä½ æ麼ç¨ï¼å¨éåå·¥å ·åç¯ä¾ä¸¦ä¸æåºç¾)ã
çºäºè®åæå²åçè¨å®ï¼æåéè¦åå Firefox è¨å®æåä»é¢(preferences service interface)ãæåå¯ä»¥å»ºç«ä¸åè®æ¸ä¾å®æï¼
const TutTB_PrefService = Components.classes["@mozilla.org/preferences-service;1"]. getService(Components.interfaces.nsIPrefService);
ä¸æ¦ååè¨å®ä»é¢ï¼æåå°±å¯ä»¥ç²å¾å¥ä»¶è¨å®çä¸é¨å(i.e. the location in the preferences "registry" where our extension's settings are kept)ï¼
const TutTB_Branch = TutTB_PrefService.getBranch("tuttoolbar.");
åè¨éåå¥ä»¶ç¯ä¾çè¨å®èµ·å§æ¼ tuttoolbar æåï¼å æ¤ï¼æåè¨å®å串 getBranch() (å §å»ºç Fireofx å½å¼) ãéåå½å¼å¯ä»¥è®æåååå¥ä»¶çè¨å®ï¼æå¾å¯ä»¥ç²å¾åå¥é¸é çå¼ãéæ¯æåååæå°ã顯示網é æå°æéãé¸é å¯ä»¥åå¾çå¼ï¼
if(TutTB_Branch.prefHasUserValue("show.button.web")) TutTB_ShowWebButton = TutTB_Branch.getBoolPref("show.button.web"); else { TutTB_Branch.setBoolPref("show.button.web", false); TutTB_ShowWebButton = false; }
é¦å ï¼æå測試éåè¨å®æ¯å¦åå¨æ¼è¨å®æ¨¹ççµæ§è£¡ãå¦æåå¨ï¼å°±ç¨ getBoolPref()å½å¼è®åå®çå¼(å²åæ¼ TutTB_ShowWebButton è®æ¸)ãå¦åï¼æåå°±è¨å®çºé è¨å¼(è¨å®ç樹èå ¨åè®æ¸)ã
å²åè¨å®æ¯å¾ç°¡å®çå§ï¼ä½ åªè¦æä¾è¨å®çå稱ï¼ç¶å¾ä½¿ç¨éåå¼ï¼
TutTB_Branch.setBoolPref("show.button.web", TutTB_ShowWebButton);
ãè®åèå²åè¨å®ãç¨ä¾å²åä½ çå¥ä»¶è¨å®æ¯å¾æ¹ä¾¿çæ¹å¼ã大é¨åçå¥ä»¶é½ä½¿ç¨éååè½ï¼æ許å¤å¯ä½¿ç¨çç¯ä¾çèä½ å»ç 究ãå¦å¤ï¼å¯ä»¥çç MozillaZine knowledge base çæç« ã
第ä¸ç« ï¼å°è£ (Packaging the Toolbar)
å°ç®åçºæ¢ï¼æåç¨åæ éç¼ä¾èçå®è£çé¨ä»½ãä½æ¯ä½¿ç¨è 並ä¸ææ³ç¨é樣çæ¹å¼ä¾å®è£å¥ä»¶ï¼æ以æåå¿ é å°è£æªæ¡æä¸åå®è£æªãæåå°è¦å»ºç«å ©åæªæ¡ï¼XPI å JARãå¥è¢«é樣çæªæ¡å稱給é¨äºï¼ä»ååªä¸éæ¯ç¨ zip å£ç¸®æªæ¡æ ¼å¼å½è£çã
ç¾å¨æ¯å£ç¸®å·¥å ·ç¼æ®åæçæåäºï¼æå人建è°ä½¿ç¨ WinZip (å½ä»¤å模å¼)ï¼ä½æ¯ç¶²è·¯ä¸ä¹æä¸å°å è²»çå·¥å ·ãå¨é份æåä¸ ï¼ ææä½¿ç¨ UNIX å£ç¸®å·¥å ·;å¨ Windows ä¸ï¼å¯ä»¥ä½¿ç¨ Cygwin ã
æ´æ° Chrome æ¸ å® (Updating the Chrome Manifest)
第ä¸æ¥å°è£å å«äºæ´æ° chrome æ¸ å®ã注æï¼å¦æè¦ç¹¼çºåæ éç¼ï¼ä½ è¦æå ©å chrome æ¸ å®ï¼ä¸åæ¯å°è£ç¨çï¼å¦ä¸åæ¯åæ éç¼ç¨çãèçéå ©åæªæ¡æ¯å¾éº»ç ©çï¼æ以æååªéå°æåä¸å·²åå¨ç chrome æ¸ å®åèçã注æï¼å¨æåä¿®æ¹æ¸ å®å¾ï¼å°±ä¸è½ç¨å¨åæ éç¼äºï¼é¤éä½ ä¿®æ¹åä¾ãè®æåå ä¾åæ¶ä¸ä¸æ¸ å®çå §å®¹ï¼
content tuttoolbar chrome/content/ overlay chrome://browser/content/browser.xul chrome://tuttoolbar/content/tuttoolbar.xul skin tuttoolbar classic/1.0 chrome/skin/
æå ©åå°æ¹éè¦ä¿®æ¹ï¼å çç第ä¸è¡ï¼
content tuttoolbar jar:chrome/tuttoolbar.jar!/content/
æåå å ¥äºå ©åé ç®ãé¦å æ¯ jar: ï¼æ¾ç½®å¨è·¯å¾çåé¢ãéæå® Firefox å¿ é å¾ JAR æªæ¡ä¸ååºå¥ä»¶çå §å®¹ãåä¾ï¼æåå å ¥ tuttoolbar.jar!/ï¼ä»æ¼ chrome/ å content/ ç®éä¸éï¼éæè¿°äºåªå JAR éè¦è¢«ååºçãéå JAR çæªåå¿ é è¦è·å¥ä»¶çæªåç¸åï¼å樣å°ï¼å¿ é è·æªåä¸æ¨£ä½¿ç¨å°å¯«åé«ã注æï¼é©åèä¸æ¯æåé¯èª¤ï¼éæ¯å¿ è¦çãå¦ä¸åéè¦ä¿®æ¹çè·¯å¾æ¯ skin ï¼ä¾ççä¿®æ¹å¾çå §å®¹ï¼
content tuttoolbar jar:chrome/tuttoolbar.jar!/content/ overlay chrome://browser/content/browser.xul chrome://tuttoolbar/content/tuttoolbar.xul skin tuttoolbar classic/1.0 jar:chrome/tuttoolbar.jar!/skin/
å»ºç« JAR æªæ¡ (Creating the JAR File)
第ä¸åè¦å°è£çæ¯ JAR æªæ¡ãé¦å æåèç chrome ç®éï¼å å«äº XULãJavaScriptãCSS 以ååçãæªæ¡çµæ§å¦ä¸ï¼
+- TutToolbar/ +- install.rdf +- chrome.manifest +- chrome/ +- tuttoolbar.jar +- content/ +- tuttoolbar.xul +- tuttoolbar.js +- skin/ +- combined.png +- gripper.png +- images.png +- main.png +- web.png +- tuttoolbar.css
å°è£ JAR ææ¯ XPI æï¼æ容æç¯çé¯èª¤å°±æ¯éºæ¼äºç¸éçæªæ¡ãå¦ææååè£ JAR æªæ¡æ¯åç®éï¼è£¡é¢å å«äºï¼
+- content/ +- tuttoolbar.xul +- tuttoolbar.js +- skin/ +- combined.png +- gripper.png +- images.png +- main.png +- web.png +- tuttoolbar.css
éæ¯æç¨ UNIX å·¥å ·çæ¹å¼(å½ä»¤å模å¼)ï¼
zip -r tuttoolbar.jar content/* skin/*
(è¯è ï¼ä¸è¬ Windows 使ç¨è å¯ä»¥ç´æ¥å° content å skin ç®é以 zip æ ¼å¼å£ç¸®æå¯æªå .jar çæªæ¡ã)
å»ºç« XPI æªæ¡(Creating the XPI File)
å¨å»ºç«å¥½ JAR æªæ¡ä¹å¾ï¼æåå¿ é å»ºç« XPI æªæ¡ï¼éæ¯çæ£ä½ è¦çµ¦ä½¿ç¨è ç¨çå¥ä»¶å®è£æªãæåå¿ é å¨æä¸å±¤ç®éä¸å»ºç«éåæªæ¡ï¼çµæ§å¦ä¸ï¼
+- TutToolbar/ +- tuttoolbar.xpi +- install.rdf +- chrome.manifest +- chrome/ +- tuttoolbar.jar +- content/ +- tuttoolbar.xul +- tuttoolbar.js +- skin/ +- combined.png +- gripper.png +- images.png +- main.png +- web.png +- tuttoolbar.css
è· JAR æªæ¡ä¸æ¨£ï¼XPI å¿ é ç¶æç¸å°çè·¯å¾ãå¨ XPI æªæ¡ä¸ï¼å å«äºä¸åæªæ¡ï¼å®è£æ¸ å®ãchrome æ¸ å®ååå建ç«ç JAR æªæ¡ãXPI 裡å å«äºï¼
+- install.rdf +- chrome.manifest +- chrome/ +- tuttoolbar.jar
ä½¿ç¨ UNIX å·¥å ·çæ¹å¼ï¼
zip tuttoolbar.xpi install.rdf chrome.manifest chrome/tuttoolbar.jar
å¥ä»¶å®è£æ¸¬è©¦ (Installing Your Toolbar Extension)
æäº XPI æªæ¡ä¹å¾ï¼å°±å¯ä»¥éå§å®è£çæ¥é©ãå¨ç¼è¡¨å¥ä»¶åï¼ä½ ä¸å®è¦å 確å®å¥ä»¶å¯ä»¥å®è£ãä¸å¯ä»¥ä½¿ç¨éç¼è¨å®æªä¾æ¸¬è©¦å®è£ï¼å管å¨é£ä»½è¨å®æªå·²ç¶æå¥ä»¶çå®è£çæ¬ãç¨ä½ ä¸è¬ä½¿ç¨çï¼ææ¯å¦ä¸åè¨å®æªï¼ä¾ä¸é¢çæ¥é©ä¾æ¸¬è©¦å®è£ï¼
- æªæ¡ > éåæªæ¡ (ææ¯ç¨ Ctrl+O) ã
- å¨å°è©±æ¡ä¸ï¼æ¾å°ä½ ç XPI æªæ¡ï¼é»é¸ãéåãã
å¦ææ£ç¢ºå°å®æå¾ï¼ä½ æçå°å®è£ç«é¢ãé¸æä½ è¦å®è£å¾ï¼éæ°éå Firefoxãä¹å¾ï¼ä½ æ該æçå°å·¥å ·åäºï¼æåä½ å®æ第ä¸åå·¥å ·åå¥ä»¶ï¼
å éå°è£éç¨ (Speeding Up the Packaging Process)
æåå°è£å¥ä»¶å¾è®äººåç ©çï¼çºä½ä¸ç¨æè¿°æªä¾å®æå¢ï¼å¦ææå½ä»¤å模å¼ç ZIP å·¥å ·ï¼ä½ å¯ä»¥å°éç¨èªååãä¸é¢çç¯ä¾ä½¿ç¨ DOS æ¹æ¬¡æªå UNIX å£ç¸®å·¥å ·ã
é¦å 建ç«å ©åæåæªï¼æä¸å±¤ç®éç xpizip.txt ï¼å chrome ç®éä¸ç jarzip.txt ã æªæ¡ä¸å å«äºè¦å°è£çé ç®ï¼ [View xpizip.txt] [View jarzip.txt]
ä¸ä¸æ¥ï¼å¨æä¸å±¤ç®éä¸å»ºç« DOS æ¹æ¬¡æª(.bat)ï¼å §å®¹å¦ä¸ï¼
zip -r chrome/tuttoolbar.jar -@ < chrome/jarzip.txt zip -r tuttoolbar.xpi -@ < xpizip.txt
å¦ä½ æè¦ï¼éåæè¿°æªç¸ç¶ç°¡å®ãç¶èï¼ä½ çæè¿°æªå¯è½æ¯éåæ´è¤éãæç¨ä¾å»ºç« Googlebar Lite çæè¿°æªå¯ä»¥åæ´å¤äºãå®å¯ä»¥çºæèªåæ´æ°ææççæ¬ä»£èï¼åå®ææªæ¡çå°è£ãéåæè¿°æªæ¯ç¨ Perl å®æçï¼èä¸ä½¿ç¨ 1.0.x çå®è£æ¹æ¡(èé份æåæäºå¾®çä¸å)ãææä¾éåæè¿°æªçµ¦æè趣ç人ï¼[View the Googlebar Lite Build Script]ã
(Ant Support)
å¦æä½ å¯§é¡ä½¿ç¨ Ant ä¾å»ºç«ä½ çå¥ä»¶ï¼å¯ä»¥åè sample XML file sent in by Brett Clippingdale. éåæè¿°æªæ該è·å®è£æ¸ å®æ¾ç½®å¨åä¸åç®éï¼ç¶å¾ä½¿ç¨ ant æ令ã
ç¬¬å «ç« ï¼æ¸¬è©¦ (Testing Our Extension)
å¨ç¬¬åç« è¨è«çåæ éç¼å°æ¼å¥ä»¶æ¸¬è©¦æå¾å¤§ç幫å©ï¼ä½æ¯é裡éæä¸äºç« éæ¯éç¼è éè¦ç¥éçãJavaScript æ¯å¾é£é¤é¯ç ï¼å¹¸å¥½ Firefox çä¸äºç¹è²å¯ä»¥è®æåé¿å é£äºæ±äººçè¦ç¤º(æ¤æ alert() å½å¼å¼å«)ã
ç¶ Firefox ææ¯æ該æ麼辦 (What to Do if Firefox Breaks)
ææåå¥ä»¶æç¢çç½é£æ§çé¯èª¤ï¼å°è´ Firefox æçµéåãç¶é種æ æ³ç¼çæï¼ä½ å¿ é å 檢æ¥å·¥ä½ç®¡çå¡æ¯å¦æç¶æç Firefox å¨å·è¡ä¸ï¼ä¸¦æå®ééãä¸æ¦ç¢ºå®æ²æ Firefox å¨å·è¡ï¼ä½ éè¦ç§»é¤æåé¡çå¥ä»¶ã移é¤çæ¹æ³å決æ¼ä½ æ¯å¦æ£å¨ä½¿ç¨åæ éç¼ç³»çµ±ã
å¦æä½ æ£å¨ç¨åæ éç¼ï¼åªè¦ç覽åæ éç¼è¨å®çå¥ä»¶ç®é(第åç« )ï¼ç¶å¾å°å¥ä»¶çææ¨æªæ¡(tuttoolbar@borngeek.com)移åå°æ«åçä½ç½®ãç¨ä½ çåæ éç¼è¨å®æªéæ°éå Firefox (å 許å®æ¸ é¤ææ°ç§»é¤çå¥ä»¶)ï¼ ç¶å¾å次ééç覽å¨ãå¨ä½ 解決éåå°è´ Firefox ç¶æçåé¡ä¹å¾ï¼å°ä½ çææ¨æªæ¡ç§»åå°å¥ä»¶ç®éï¼ç¶å¾éæ°éå Firefox ã
å¦æä½ æ²æ使ç¨åæ éç¼ç話ï¼å°±ç¨ Firefox çå®å ¨æ¨¡å¼ä¾ç§»é¤æåé¡çå¥ä»¶ãä½ å¯ä»¥ç¨å ©ç¨®æ¹å¼ä¾ï¼
- éå§ > ææç¨å¼ > Mozilla Firefox >> Mozilla Firefox (Safe Mode) ã
- å¨ Firefox æ·å¾ä¸å å ¥ -safe-mode å½ä»¤ååæ¸ã
å¨å®å ¨æ¨¡å¼ä¸ï¼ Firefox ä¸æè¼å ¥ä»»ä½å¥ä»¶ææ¯ä¸»é¡ãä¸æ¦å¨å®å ¨æ¨¡å¼ä¸ï¼ä½ å°±å¯ä»¥ä½¿ç¨å¥ä»¶ç®¡çå¡ä¾ç§»é¤æåé¡çå¥ä»¶ãå¨ç§»é¤å¥ä»¶ä¹å¾ï¼è¨å¾å° -safe-mode å½ä»¤ååæ¸ç§»é¤(å¦æä½ å¨æ·å¾ä¸æåå å ¥)ã
æç¨çç覽å¨è¨å® (Useful Browser Settings)
å¨ about:config ä»é¢ä¸ï¼æå ©åè¨å®å¯ä»¥è®ä½ æ´å®¹æéç¼ï¼éæå½±é¿ JavaScript 主æ§å°ç輸åºè¨æ¯ã
第ä¸åè¨å®æ¯ javascript.options.showInConsole ãç¶è¨å®çº true æï¼ææå¥ä»¶ç¢ççé¯èª¤ææ¯è¦åé½æ被å³éå° JavaScript 主æ§å°ãé è¨å¼æ¯ false ï¼ æä»¥ä½ å¿ é éåå®ãéåè¨å®å°æ¼è¿½è¹¤é¯èª¤æ¯å¾æ¹ä¾¿çã
ä¸ä¸åæ¯ javascript.options.strict ï¼é è¨å¼ä¹æ¯ false ãç¶è¨å®çº true æï¼Firefox ç JavaScript èªæ³æè®æå´è¬¹æ¨¡å¼ï¼å°ä½ çç¨å¼ç¢¼è®æå´æ ¼çç´æãéè®ä½ çç¨å¼ç¢¼æ´å®åï¼ä¹æ´å®¹æ追蹤ç¨å¼ç¢¼é¯èª¤ã
JavaScript 主æ§å°ç´é (Logging to the JavaScript Console)
測試 JavaScript ç¨å¼ç¢¼ç好æ¹æ³å°±æ¯å¨ JavaScript 主æ§å°ä¸å°åºé¤é¯å¼ï¼ä½ å¯ä»¥å¨ ãå·¥å · > JavaScript 主æ§å°ãéåãæåå¿ é å å¾å° nsIConsoleService ä»é¢ç實é«(instance)ï¼ä¸é¢æ¯ç¨å¼ç¢¼çç段ï¼
const TutTB_ConsoleService = Components. classes['@mozilla.org/consoleservice;1']. getService(Components.interfaces.nsIConsoleService);
注æå°æåç¨äº TutTB_ çåç½®è©ï¼å°±å¦æ使ç¨æ¼ææå½å¼èè®æ¸ä¸æ¨£ãä¸æ¦æååå¾éåæ§å¶å°å¯¦é«(console instance)ï¼æåå°±å¯ä»¥ä½¿ç¨å®ä¾ç·¨å¯«èªå·±çè¨æ¯ãä¸é¢çå½å¼æ幫æåå®æé件äºï¼
function TutTB_Log(aMessage) { TutTB_ConsoleService.logStringMessage('Tut_Toolbar: ' + aMessage); }
實éä¸ï¼ä½ æ該æ¹è®å¨ä½ çå¥ä»¶ä¸ãMy_Extension:ãçè¨æ¯é¨ä»½å稱ãèç±ä½¿ç¨ä½ çå¥ä»¶å稱ä¾ç¶åç½®è©ï¼ä½ å¯ä»¥æ´å®¹æåå¾åªäºè¨æ¯æ¯è¦ç¥éçãç¾å¨ï¼è®å½å¼ä½ç¨ä¹å¾ï¼æåå¯ä»¥å¨ç¨å¼ç¢¼ä¸çä»»ä¸ä½ç½®ä¾å¼å«å®ï¼ä»¥é¡¯ç¤ºé¤é¯è¨æ¯ï¼
TutTB_Log("The value of the URL variable is: " + URL);
è¨å¾ä¸å®è¦å¨ç¼è¡¨ä½ çå¥ä»¶å移é¤éåå½å¼ãä¸ç¶ï¼éä¸åªæ¯éä½ä¸»æ§å°ç´éçé度ï¼éå¢å äºä½¿ç¨è 主æ§å°è¦çªçéå¿ è¦è¨æ¯ãè¦æ´é²ä¸æ¥å°äºè§£ JavaScript 主æ§å°ï¼å¯ä»¥åè MozillaZine knowledge base article ã
æ¨æºä¸»æ§å°ç´é (Logging to the Standard Console)
å¦ä¸åç´éé¤é¯è³è¨çæ¹æ³ï¼å°±æ¯ä½¿ç¨æ¨æºä¸»æ§å°çæå·§ãå¨ä½¿ç¨éåæ¹æ³ä¹åï¼æä¸äºç覽å¨çä¿®æ¹å¿ é è¦å å®æãé¦å ï¼æåå¿ é å å ¥æ°çç覽å¨è¨å®ï¼å¨ç¶²ååè¼¸å ¥ about:config ï¼ä¸¦æä¸ Enter ãå³éµé»æå表並é¸æ ãæ°å¢ > çåå¼(Boolean)ãä¾å»ºç«ä¸åæ°çå¸æå¼è¨å®ãå°éåå¼è¨å®çº browser.dom.window.dump.enabled ï¼ä¸¦åç¨å®(true)ã
ä¸ä¸æ¥ï¼æ¯å¨ Firefox æ·å¾ä¸å å ¥ -console å½ä»¤å串ã使ç¨éååæ¸ï¼æä½ æ¯æ¬¡å·è¡ Firefox æï¼é¡¯ç¤ºæ¨æºè¼¸åºä¸»æ§å°ãä¸ä½éé å®æå¾ï¼ Firefox ä¹éåäºï¼ä»»ä½èç± dump() å½å¼ç¢çç輸åºï¼é½æ顯示å¨ä¸»æ§å°è¦çªä¸ãdump()å½å¼å°±å¦ JavaScript æ¨æºç alert() å½å¼ä¸æ¨£ï¼èªæ³ä¹ç¸ä¼¼ã
æ件ç©ä»¶æ¨¡å檢æ¥å¨ (The DOM Inspector)
å°æ¼è¨è¨å·¥å ·åæ大ç幫å©å°±æ¯ DOM (Document Object Model) Inspector ï¼éæ¯ä¸åå¯ä»¥è®ä½ æª¢æ¥ XML æ件(å å« XUL, HTML)çµæ§çå·¥å ·ãéåå·¥å ·è· Firefox å è£å¨ä¸èµ·ï¼ä½æ¯é è¨æ¯ä¸å®è£çï¼ä½ å¿ é 使ç¨é²éå®è£ä¾å®è£éåå·¥å ·ãä¸æ¦å¯ä»¥ä½¿ç¨æï¼å°±ææè±å¯çè³è¨å¯ä»¥ç²å¾ï¼æä»¥ä½ è¦å å¸æå¦ä½ä½¿ç¨å®ã
å¨ä¸äºç¶²é å¯ä»¥æ¾å°é樣çä»ç´¹ï¼
- The DOM Inspector (from Creating Applications with Mozilla)
- DOM Inspector FAQ
éæ¯å¹«å©æåå°æ¾ XUL è¨è¨åé¡çæå¥½å·¥å ·ï¼å®å¯ä»¥è®ä½ 檢è¦å¤å XUL å ç´ çèªæ³ãæå¼·ç建è°ä½ å»å¸ç¿å¦ä½ä½¿ç¨éåå·¥å ·ï¼éé»ç¸ç¶å®¹æï¼èä¸ä½ æå°æ¼å¸æ使ç¨éé å·¥å ·æå°é常å°é«èã
‧返回上一頁: éç¼äººå¡æ件主é