4,562,709 th visitor since 2017.2.1 ( Today : 160 )
Programming
No. 540
Name. swindler
Subject. Firefox extensions (xpi) 만들기
Main Cate. etc
Sub Cate.
Date. 2009-01-15 17:25
Hit. 5835 (211.43.206.101)
File.

목차


  1. Learn By Example
  2. Hello, world!
  3. Looking inside the XPI
  4. Re-configuring your extension’s installation
  5. Chrome is more than a shiny bumper
  6. Skin that cat
  7. Pack it up and try it out
  8. An easier way to re-build
  9. My Firefox got completely hosed up
  10. Ensure server compatibility
  11. Additonal help and information


Learn by example


누구나 한번쯤은 웹브라우저에 새로운 기능을 추가하는 것에 대해서 생각을 해 보았을 것입니다. 파이어팍스의 장점을 이용하면
쉽게 가능합니다. XUL 과 Javascript 를 대강 이해하는 것이 필요하지만 전문가가 될 필요는 없습니다. 실제로 저는
아무것도 모르고 시작했습니다. 여기 저기서 북마클릿을 보고 어떻게 작동하는지 연구하면서 제 첫번째 확장인 BugMeNot 을
만들게 되었습니다.


이 설명서는 여러분의 첫번째 확장을 어떻게 시작하는지 보여줄 것입니다. 모든 프로그래머가 항상 “Hello, world!” 예제부터 시작하므로 그것이 확장의 개발을 소개하는 좋은 방법이 될 것 같습니다.


Xul Planet 에 가시면 메뉴를 만드는 방법을 소개한 간단한 설명서를 볼 수 있습니다. Mozilla 에도 필요할 때 손쉽게 참고할 수 있는 DOM Window Interface 레퍼런스가 있습니다. 모두 프로그래밍에 부담이 없는 사람들을 위해 작성된 문서이므로, 전부 이해하지 않아도 이 설명서를 따라가는데는 문제가 없습니다.


Hello, world!


우리가 만드는 확장은 오른쪽 마우스 메뉴나 도구 메뉴에서 선택을 하면 ‘Hello, world!’ 가 표시되는 대화상자를 띄우는 간단한 것입니다. 두 메뉴 모두 널리 쓰이는 위치이므로 무엇인가를 추가하는 것이 상대적으로 쉽습니다.
어떤 방식의 확장이 될 것인지 감을 잡기 위해서 미리 결과를 살펴보도록 하겠습니다. 먼저 확장을 실행하는데는 두가지 방법이 있습니다.


오른쪽 클릭을 하면 다음과 같은 메뉴가 나옵니다.


right click


도구 메뉴는 다음과 같습니다.


tools


확장을 만드는 우리 노력의 최종 결과는 다음과 같습니다.


alert


확장 관리자에는 다음과 같이 나타납니다.


extensions


확장 관리자에서 “About…” 버튼을 누르면 다음과 같은 대화 상자를 볼 수 있습니다.


about


Looking inside the XPI


여기서는 미리 만들어 놓은 ‘Hello, world!’ 확장 예제를 이용하여 확장이 어떻게 구성되어 있는지 살펴보겠습니다. (예제는 여기서 내려받을 수 있습니다.)


helloworld.xpi 는 확장 꾸러미입니다. XPI 는 브라우저가 확장으로 인식하는 파일 형식이지만, 실제로는 zip으로 압축한 파일입니다. 그러므로 XPI 파일의 확장자를 ZIP 이나 JAR 로 바꾸고 나서 7-Zip 이나 WinRAR 같은 압축 프로그램으로 열어 볼 수 있습니다. 그러면 다음과 같은 하나의 폴더와 두개의 파일을 볼 수 있습니다.


  • chrome
  • install.js
  • install.rdf

원래 install.js 는 설치를 위해서 필요한 파일이었지만 Firefox 0.9 부터 바뀐 확장 관리자에서는
install.rdf 를 대신 사용합니다. 여기 install.js 는 Firefox/bird 이전 버전, Mozilla,
Netsacpe 를 위한 것입니다. Firefox 0.9 이상에만 쓰이는 확장을 만들고 있다면 install.js 를 빼도
상관이 없습니다. 작성하기가 어렵지도 않고 호환성을 보장하는데 도움이 되기 때문에 저는 빼지 않고 놔두는 편입니다. 하지만,
제가 만든 ListZilla 처럼 이전 버전에 대한 호환성이 전혀 없는 확장도 있습니다. 이는 ListZilla 가 0.9 버전의 확장 관리자에서 정보를 수집하기 때문입니다. 간단하게 “Hello, world!” 를 표시하는 것에는 당연히 그런 문제가 없을 것입니다.


install.js 를 열어보시면, 설치 스크립트를 작성하기 위하여 고쳐야 할 부분이 간단하다는 것을 알 수 있습니다.

// --- Editable items begin ---
extFullName: 'Hello, world!', // The name displayed to the user (don't include the version)
extShortName: 'helloworld', // The leafname of the JAR file (without the .jar part)
extVersion: '0.1',
extAuthor: 'Eric Hamiter',
extLocaleNames: null, // e.g. ['en-US', 'en-GB']
extSkinNames: null, // e.g. ['classic', 'modern']
extPostInstallMessage: 'Success! Please restart your browser to finish the installation.'
// Set to null for no post-install message
// --- Editable items end ---


복잡한 부분은 여러분을 위하여 벌써 마무리되어 있습니다. 나머지 코드를 소개하지는 않겠지만, 상당히 많은 양의 작업이 이미 자동화 되어있다는 것을 알 수 있습니다.


이제 install.rdf 를 열어보시면 다음 내용을 볼 수 있습니다.

<?xml version="1.0"?>
 
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
    <Description about="urn:mozilla:install-manifest">
        <em:id>{9AA46F4F-4DC7-4c06-97AF-5035170633FE}</em:id>
        <em:name>Hello, world!</em:name>
        <em:version>0.1</em:version>
        <em:description>Displays an alert message via right-click or Tools menu.</em:description>
        <em:creator>Eric Hamiter</em:creator>
        <em:homepageURL>http://extensions.roachfiend.com</em:homepageURL>
        <em:iconURL>chrome://helloworld/skin/helloworld.png</em:iconURL>
        <em:aboutURL>chrome://helloworld/content/about.xul</em:aboutURL>
        <em:file>
            <Description about="urn:mozilla:extension:file:helloworld.jar">
                <em:package>content/helloworld/</em:package>
                <em:skin>skin/classic/helloworld/</em:skin>
            </Description>
        </em:file>
        <em:targetApplication>
            <Description>
                <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
                <em:minVersion>0.7</em:minVersion>
                <em:maxVersion>0.9+</em:maxVersion>
            </Description>
        </em:targetApplication>
    </Description>
</RDF>


Re-configuring your extension’s installation


도대체 이 복잡한 것이 무엇일까요? 처음 보게 되는 것은 <em :id> 태그입니다. 이것은 여러분의 확장을 다른 확장과 구별할 수 있도록 직접 생성하는 아이디입니다. 아이디를 생성하기 위해서는 온라인 펄 스크립트 를 쓰거나 윈도우 사용자들은 마이크로소프트가 제공하는 guidgen 이라는 프로그램을 쓰면 됩니다. 재미있는 일이죠? 재미있다는 말이 어색한가요? 어쨌든, 프로그램을 받아서 실행하면 다음과 같은 대화상자가 나타납니다.


여기서 4. Registry Format 을 선택하고 New GUID 버튼을 몇 번 누른후에 Copy 버튼을 누릅니다. 그럼 잘 생긴 아이디 하나가 클립보드에 들어 있습니다. 예전 아이디를 그 아이디로 바꿔주시면 되는 겁니다.
Name,
version, description, creator, homepageURL 은 이름을 보면 쉽게 알 수 있습니다.
IconURL 과 aboutURL 은 확장 관리자에서 마우스 오른쪽 버튼을 누르고 “About Extension…” 을 선택할
때 화면에 나타납니다. 꼭 적을 필요 없이 그냥 비워두셔도 되지만, 가끔 살짝 멋을 내보는 것도 나쁘지는 않습니다.


File 안쪽은 일반적인 사항들을 담고 있습니다. “helloworld” 를 전부 여러분의 확장 이름으로 바꾸십시오. 설치
프로그램이 그 위치에서 여러분의 파일과 폴더를 찾게 됩니다. 아이콘이 있을 때는 skin 폴더를 포함해야 하지만, 꼭 필요한
것은 아닙니다.


Target application 은 확장이 추가될 프로그램입니다. ec8030f7… 는 Firefox 의 고유
아이디이므로 고치지 마십시오. minversion 과 maxversion 은 확장이 호환 가능한 Firefox 의 버전입니다.
이에 관하여 한가지 큰 문제가 있었는데, 개발자들이 maxversion 을 0.9 로 지정해야 한다고 한 후 바로 0.9.1 을
출시한 것입니다. 이는 일리가 있는 것이 아닙니다. 그래서 최근에 제 확장에서는 maxversion을 1.2 로 바꾸었고 그래서
몇 차례의 새로운 파이어팍스 버전에서 호환성이 있게 됩니다. 이것이 정식으로 지원하는 것은 아니며 모질라에서는
maxveresion 에 현재 버전을 입력하기를 권장합니다. 하지만 이렇게 하면 몇 주 마다 여러분의 확장을 업데이트하는 수고를
덜 수 있습니다.


Chrome is more than a shiny bumper


이제 chrome 폴더를 열어보십시오. 폴더에서 helloworld.jar 라는 압축 파일을 찾을 수 있습니다. 그 파일을
열어서 압축을 풀면 content 와 skin 폴더가 생깁니다. 먼저 content 폴더를 살펴보면 helloworld 라는
폴더가 있고 그 안에 다음과 같은 파일이 있습니다.


  • about.xul
  • contents.rdf
  • helloworldOverlay.js
  • helloworldOverlay.xul

about.xul 은 확장 메뉴에서 “About Hello, world!…” 를 선택했을 때 나타나는 페이지입니다. 내용을
보면 쉽게 이해가 가능하며, Jed Brown 이라는 사람이 여러분을 위하여 template을 작성해 놓았다는 것을 알 수
있습니다. 역시 필요한 정보만 채우면 됩니다.


helloworldOverlay.xul 은 helloworldOverlay.js 확장이 작동할 수 있도록 하는 파일입니다.
말하자면 드러나는 모습 뒤에 있는 핵심입니다. helloworldOverlay.xul 의 내용은 여러분이 놀랄만큼 단순합니다.

< ?xml version="1.0"?>
<overlay id="helloworldOverlay"  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<!-- This imports our javascript. -->
<script type="application/x-javascript" src="chrome://helloworld/content/helloworldOverlay.js">
</script>
<!-- This is for the right click menu. -->
<popup id="contentAreaContextMenu">
  <menuitem id="helloworld" label="Hello, world!" accesskey="H"  insertafter="context-stop" oncommand="hello();"/>
</popup>
<!-- This is for the Tools menu. -->
<menupopup id="menu_ToolsPopup">
    <menuitem insertafter="devToolsSeparator" label="Hello, world!" accesskey="H" oncommand="hello();" />
</menupopup>
</overlay>


코드가 가리키는 것은 helloworldOverlay.js 라는 자바스크립트 파일을 삽입하고 Hello, world! 라는
컨텍스트 메뉴 항목을 생성하라는 것이 전부입니다. accesskey=”H” 는 다른 메뉴 항목이 사용하지 않는 첫번째 글자인 H
에 밑줄을 칩니다. insertafter=”context-stop” 은 메뉴 항목이 Stop 아래에 나오게 합니다.
oncommand 는 앞서 불러온 자바스크립트 파일에 포한된 hello() 함수를 호출하여 윈도우를 띄웁니다. overlay 의
두번째 부분은 메뉴 항목을 도구 메뉴에도 추가하도록 합니다. 붙어있는 위치를 빼고는 컨텍스트 메뉴와 똑같습니다.
helloworldOverlay.js 는 다음과 같습니다.

// This is our javascript, which will pop up our message
// in an alert box.
 
function hello(){
    alert("Hello, world!");
}


이제 contents.rdf 를 살펴보겠습니다. 이 파일은 브라우저에게 overlay 정보가 저장된 장소를 알려줍니다.

<?xml version="1.0"?>
 
<rdf :RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
 
    <rdf:Seq RDF:about="urn:mozilla:package:root">
        <rdf:li RDF:resource="urn:mozilla:package:helloworld"/>
    </rdf:Seq>
 
    <rdf:Seq RDF:about="urn:mozilla:overlays">
        <rdf:li RDF:resource="chrome://browser/content/browser.xul"/>
        <rdf:li RDF:resource="chrome://navigator/content/navigator.xul"/>
    </rdf:Seq>
 
    <rdf :Seq RDF:about="chrome://browser/content/browser.xul">
        <rdf :li>chrome://helloworld/content/helloworldOverlay.xul</rdf>
    </rdf:Seq>
 
    <rdf :Seq about="chrome://navigator/content/navigator.xul">
        <rdf :li>chrome://helloworld/content/helloworldOverlay.xul</rdf>
    </rdf:Seq>
 
    <rdf :Description RDF:about="urn:mozilla:package:helloworld"
        chrome:displayName="Hello, world! 0.1"
        chrome:author="Eric Hamiter"
        chrome:authorURL="mailto:ehamiter@gmail.com"
        chrome:name="helloworld"
        chrome:extension="true"
        chrome:description="Displays an alert message via right-click or Tools menu.">
    </rdf>
 


에서 chrome://browser/content/browser.xul 라는 주소를 볼 수 있는데, 이것은 모질라에서 참조를
하는 내부 방식입니다. browser 는 Firefox 이며 navigator 는 넷스케이프나 모질라에서 작동합니다. 여러분이
바꿀 필요가 있는 부분은 description 부분입니다. 나머지는 그냥 확장을 브라우저에 추가하기 위한 부분입니다.


Skin that cat


이제 skin 폴더로 돌아가 보겠습니다. 그 안에서 class 과 helloworld 라는 폴더를 볼 수 있습니다. 이것이
일반적인 배치이므로 잘 작동하면 고칠 필요가 없습니다. helloworld 안에서는 세 개의 파일 -
helloworld.png, helloworldb.png, contents.rdf - 을 찾을 수 있습니다.


helloworld.png:
helloworld
helloworldb.png:
helloworldb


이 파일들은 앞서 말씀드린 about.xul에서 확장 메뉴와 about 메뉴에서 사용하기 위하여 부르는 파일입니다.
content.rdf 는 단순히 경로를 스킨 파일에 맞추는 역할을 하므로, 여러분의 확장을 위하여 helloworld 를
가리키는 마지막 줄만 바꾸면 됩니다.


Pack it up and try it out


이제 여러분은 각 파일이 어떻게 작동하고 어디에 들어있는지 알게 되었으므로, 새로운 것을 만들기 위해서 고칠 수 있습니다.
일단 고치고 나서는 반대의 순서로 다시 넣어주면 됩니다. 압축 프로그램을 사용하여 chrome 폴더로 올라간 후에 압축 파일에
content 와 skin 을 추가하고 이름을 extension.jar 로 바꾸어 줍니다. 그리고 나서 다른 폴더에서
chrome, install.rdf, install.js 을 압축한 후 이름을 extension.xpi 로 바꿉니다.


이제 브라우저에서 테스트 할 준비가 되었습니다. Firefox 를 열고 Ctrl-O 를 누르거나 Open File 을
선택합니다. 여러분이 작성한 xpi 파일을 불러들여 설치합니다. Firefox 를 재시작하면 메뉴에서 새로운 확장을 볼 수
있으며, 그것은 여러분이 바랬던 일을 하게 될 것입니다.


An easier way to re-build


얼마 지나지 않아서 파일과 폴더를 선택하여 압축하고, 이름을 바꾸고, 옮기고, 삭제하고, 이름을 바꾸고… 하는 일이 귀찮아 질 것입니다. 7-Zip 이 설치되어 있으면 명령행을 이용하여 이 과정을 자동화 할 수 있습니다.


C:\Program Files\7-Zip\ 에 있는 7z.exe 파일을 C:\WINDOWS\system32 로 복사합니다. 그러면 7z.exe를 명령행에서 실행할 수 있습니다.


아무런 파일이나 널려있는 폴더가 아닌 곳에서 확장을 만드는 것이 좋은 습관이므로, 여러분이 작성하는 확장과 같은 이름의 새
폴더를 만듭니다. 그 이름은 install.rdf 파일에서 지정한 jar 파일의 이름과 같아야 합니다. xpi 파일의 이름은
나중에 복잡한 것으로 바꿀 수도 있지만 간단한 이름이 더 좋습니다.


아래 스크립트를 복사하여 편집기에 붙여 넣은 후에 새로 만든 폴더에 build.bat 으로 저장합니다.

set x=%cd%
md build\chrome
cd chrome
7z a -tzip "%x%.jar" * -r -mx=0
move "%x%.jar" ..\build\chrome
cd ..
copy install.* build
cd build
7z a -tzip "%x%.xpi" * -r -mx=9
move "%x%.xpi" ..\
cd ..
rd build /s/q


이제 여러분의 확장을 쉽게 변경할 수 있습니다. 새로운 폴더를 확장 작성을 위한 기본 폴더로 간주하여 모든 설치 파일과
chrome 폴더를 보관합니다. 언제든지 새로운 확장 파일을 만들어야 할 때는 단지 build.bat 을 두번 누르면 같은
폴더에 새로운 파일이 생깁니다. 여러분이 build.bat 을 사용할 때마다 기존 파일을 삭제하고 새 파일을 만듭니다.


My Firefox just got completely hosed up


최악의 경우에는 Firefox 를 재시작할 때, “Firefox is still installing an
extension, this may take a minute…” 라는 메시지와 함께 멈춰버립니다. 당황하지 마십시오. 나머지
부분을 망치지 않고 확장을 삭제하는 가장 쉬운 방법은 다음과 같습니다.
Start » Program Files » Mozilla Firefox » Mozilla Firefox (Safe Mode)
Tools » Extensions » [right-click on your extension] » Uninstall
그리고 Firefox 를 재실행 하면 에러가 사라질 것입니다. 그러면 여러분의 파일을 수정한 후에 다시 시도해 보십시오.


Ensure server compatibility


제대로 작동해서 웹 서버에 올려놓고 싶지만, 브라우저에서 설치가 되지 않고 “Save File As..” 가 뜨는 것을 발견하게 됩니다. 그러면 .htaccess 수정해야 합니다. 자세한 정보는 여기 를 참고하십시오. 간단하게 말하자면, 아파치 서버에서 다음과 같은 설정을 .htaccess 에 추가해야 합니다.


AddType application/x-xpinstall xpi


그러면 제대로 작동할 것입니다.


Additional help and information


제가 작성한 파일을 보고 싶으면 제 확장 페이지 를 참고하십시오. 여러분의 편의를 위해서 여기에도 나열하겠습니다.



모든 페이지에 대해서 자바스크립트 코드를 실행하고 싶으면 Allow Right-Click 이나 Always Remember
Password 를 살펴보십시오. Alt-Text for Links 는 툴팁을 제어하기 위해서 자바스크립트를 사용하고 있습니다.
새로운 링크 메뉴를 작성하는 것은 Goon Menu 에서 배울 수 있습니다. BugMeNot 에서는 복잡한 정규표현식을 사용하고
ListZilla 는 설정 옵션과 확장 관리자를 다루고 있으며 WordCount 는 bookmarklet 을 확장으로 사용하는
방법을 보여줍니다.


모질라 확장 포럼은 확장 제작에 대해서 배울 수 있는 좋은 장소입니다. 부하가 심해서 이 글을 읽는 동안에 다운되었을지도 모르지만, 그렇더라도 유용한 정보가 많이 있으니 꼭 다시 시도해 보십시오.


다른 유용한 확장은 Mozilla Update 에서 찾을 수 있으며 게시판과 여러가지 확장이 있는 My Extensions Mirror 라는 곳도 있습니다.


이상입니다. 이 글이 확장을 어떻게 만드는지 알고 싶은 사람들이나 확장을 직접 만들고자 하는 야심찬 개발자들에게 도움이 되기를 바랍니다. 이제 쓸모있는 확장을 직접 만들어 보십시오!




[바로가기 링크] : http://coolx.net/cboard/develop/540


Name
Password
Comment
Copyright © 1999-2017, swindler. All rights reserved. 367,611 visitor ( 1999.1.8-2004.5.26 ), 2,405,771 ( -2017.01.31)

  2HLAB   2HLAB_Blog   RedToolBox   Omil   Omil_Blog