Hacking Firefox - part 33 pptx

10 119 0
Hacking Firefox - part 33 pptx

Đang tải... (xem toàn văn)

Thông tin tài liệu

322 Part VI — Creating Extensions and Themes Most text editors won’t recognize XUL files as XML by default. You should look for an editor that can highlight XML and in which you can specify that XUL files are actually XML files. Ⅲ Automatic indentation: If you want to create readable XML documents, JavaScript pro- grams, or any other structured text files, you should use indentation to emphasize the hierarchical structure of the document elements. For example, in XML files, the child elements should have greater indentation than their parent element: <box> <button label=”one”/> <button label=”two”/> </box> Editors with an autoindentation feature automatically indent the elements of your docu- ment according to its type. Ⅲ Parentheses matching: A good text editor warns you if you forget to close a previously opened parenthesis. This can save you a lot of debugging time further along the way. Some editors also allow you to see the correspondence between the opening and the closing parentheses, which can be a great troubleshooting tool. Ⅲ Line numbering: If there are problems or errors in your document, the browser (or a validation program) typically reports them along with the line number on which the error was encountered. A good text editor will display the current cursor position within the document and allows jumping directly to any given line number. There are many excellent freeware text editors available: Ⅲ JEdit: A multiplatform programmer’s text editor Ⅲ VIM: A flexible text editor that works on many operating systems Ⅲ Crimson Editor: Source editor for Windows Ⅲ Nedit: A multipurpose text editor for the X Window System Dozens of additional text editors are available on the Web. ZIP Format Compression Tool Extensions are packaged using the ZIP compression format. There are a lot of great ZIP com- pression tools, many of which are free. If you are on Windows, you might want to look at one of the following programs: Ⅲ 7-Zip Ⅲ WinZip Ⅲ WinRar 25_596500 ch17.qxd 6/30/05 3:13 PM Page 322 323 Chapter 17 — Creating Extensions If you want to automate the packaging process, you should get a ZIP tool with a command-line interface. For example, the free 7-Zip file archiver has a command-line utility called 7z.exe. You will see an example of how it can be used to automatically package your extension later in the chapter. Graphics Editor If you want your user interface to have icons, images, or any other graphic elements, you need to create them using a graphics editor. Similar to the other software tools mentioned, a great variety of graphics editors is available, starting with simple and lightweight utilities and going all the way to full-featured applications. You will want your graphics editor to have several features. First, it should be able to handle GIF, PNG, and JPG image formats.The program should also be able to save transparent GIF and PNG files and give you some control over the saved format parameters, such as the num- ber of colors in the GIF image palette. For creating more elaborate graphics, you might want an application that supports special effects such as drop shadow, emboss, and so on. Some of the most popular graphics editor applications are as follows: Ⅲ GIMP: An advanced, free, multiplatform image editor Ⅲ Adobe Photoshop: A professional image editing application Ⅲ Adobe Photoshop Elements: A simplified (and much more affordable) version of Photoshop with most of the needed functionality Ⅲ Corel Paint Shop Pro: An advanced image editing application for Windows Building Your First Extension This section is a tutorial for creating, packaging, and deploying Firefox extensions. You will learn how to create a fully functional extension, how to test and troubleshoot it, and finally, how to deploy it by publishing it on your web page and on other extension-related sites. The extension we will create in this section is called SiteLeds. The idea is to have an icon, or a status led, on your Firefox status bar that displays the state of a given web page — whether it is available or not and, if so, whether it was recently changed. Such an extension has several uses: You can monitor your own website and make sure the server is up and running, or alternatively, you can watch some web page for changes and get a notification whenever the page is updated. Introduction to Chrome As you should know by now, the process of building applications with Mozilla is very similar to building dynamic web pages. Typically, a web page is an HTML document that defines the page contents, a JavaScript program that adds some functionality to the page, and a CSS style sheet that determines its appearance. Building applications with Mozilla is very similar. The XUL document defines the user interface, the JavaScript makes it dynamic, and a style sheet specifies its presentation. Figure 17-1 demonstrates this concept. 25_596500 ch17.qxd 6/30/05 3:13 PM Page 323 324 Part VI — Creating Extensions and Themes F IGURE 17-1: A comparison between a web page and a XUL application To specify the address of any specific web resource, an HTML page, a CSS file, and so on, you use a Uniform Resource Locator (URL). For example, if you want to specify the official Firefox page, you can use its URL, http://www.mozilla.org/products/firefox/index. html . The http part means that the page should be fetched from the Web using the HTTP protocol. Similarly, when specifying application resources (XUL documents, CSS style sheets, and many other components of our application), you will use a chrome URL. The Web is the place where all the web pages are found. Similarly, the chrome contains all the elements of our application user interface. Figure 17-2 further clarifies this concept. One example of a chrome resource is the Firefox Options dialog, which can be found at the following address: chrome://browser/content/pref/pref.xul. F IGURE 17-2: Web versus chrome resources As mentioned in the previous chapter, XUL applications can be run directly from the Web. We will be using the regular HTTP URLs to reference such applications. Chrome addresses are used to reference the components of the locally installed application, such as the browser itself or any of its extensions. Because XUL applications that are run directly from the Web can be potentially malicious, they have some security restrictions imposed on them by the browser. Installed com- ponents accessed through the chrome URL do not have such restrictions. Chrome Browser Web HTTP URL Chrome URL HTML JavaScript CSS XUL Dynamic Web Page XUL Application JavaScript CSS 25_596500 ch17.qxd 6/30/05 3:13 PM Page 324 325 Chapter 17 — Creating Extensions Let’s use our web address analogy to introduce some additional concepts. For the browser to be able to find a web page using its URL, the page domain ( mozilla.org in our previous exam- ple) must be first registered in a domain registry. Similarly, for Mozilla to locate the files that define a XUL application, the packages that contain these files must be first registered in the chrome registry. When a browser receives a chrome URL, it looks into the chrome registry, obtains the installation locations of the needed files, and then loads the documents from these locations. Using this method for accessing our application resources allows us to be indepen- dent of the physical location of the files, as long as the chrome registry contains the correct information. A typical chrome URL looks like this: chrome://<package name>/<type>/<filename> Take a closer look at the different parts of the chrome URL: Ⅲ chrome:: This means that we want a chrome resource. Ⅲ package name: The package of the wanted file. Typically, every Mozilla application is split into several packages. For example, Firefox consists of browser, mozapps, help, and so on. An extension is usually a separate package with its own package name. Ⅲ type: There are three chrome resource types: ■ content: XUL and JavaScript documents are located in the content part of the package. This part contains the definition of the user interface and its behavior. ■ skin: This part contains the files that determine the appearance of the user inter- face, typically CSS style sheets and images. Separating this part from the content allows having several skins in the same package. The browser can determine which skin to display based on the user’s current browser theme. ■ locale: All user interface strings and messages should be located in this part of the chrome package. Separating them from the content part allows the package to con- tain several sets of strings, each translated into a different language. The browser determines which translation to use based on its current user interface language. The string resources are usually specified in XML Document Type Definition (DTD) and JavaScript property files (more on this later in this chapter). Figure 17-3 demonstrates the structure of a typical chrome package. You don’t have to keep the content, locale, and skin parts packaged in the same physical file. While this is often the case, a logical package specified in the chrome URL can actually be com- posed of several physical chrome package files. For example, you can add a translation to an existing logical package by installing and registering a separate locale package file. Some examples of chrome URLs follow: Ⅲ chrome://browser/content/browser.xul: The browser.xul file defines the user interface of the main browser window. As you can see, it is a part of the browser package and located in the content part of this package, as expected. 25_596500 ch17.qxd 6/30/05 3:13 PM Page 325 326 Part VI — Creating Extensions and Themes Ⅲ chrome://inspector/content/inspector.xul: The main window of the DOM inspector extension is defined in the inspector.xul file.This file is a part of the inspector package. Ⅲ chrome://browser/skin/browser.css: This is the main browser style sheet. If there are several sets of skins in the browser package, each containing a different browser.css file, the correct one will be used, according to the current browser theme. Ⅲ chrome://browser/locale/browser.dtd: This is the address of the main browser string table. Note that nothing specifies the specific language or locale in the URL. If the locale part of the browser package contains several browser.dtd files (each in a different language), the URL is resolved to the string table file that contains the strings in the user’s language. F IGURE 17-3: The structure of a typical chrome package Creating the SiteLeds Extension In this section, we create the first fully functioning version of our extension. We create the vari- ous components of the extension: its XUL user interface definition, its functionality written in JavaScript, and its CSS style sheet. Then you see how to package these components and create the final installable extension file. Building the User Interface The user interface of our first extension is extremely simple. Because we want to add an icon to the status bar, our user interface consists of a single statusbarpanel element: <statusbarpanel class=”statusbarpanel-iconic” id=”siteleds-statusbar-panel”/> tooltiptext=”SiteLeds Status Icon” sitestate=”unknown”/> - XUL - JavaScript - CSS - Images classic modern English Spanish - DTD - Properties content skin Chrome Package locale 25_596500 ch17.qxd 6/30/05 3:13 PM Page 326 327 Chapter 17 — Creating Extensions We are using the statusbarpanel-iconic class to specify that the status panel will display an icon. Also, we gave our status bar panel a unique id so we can find it later, using the DOM methods from JavaScript, and apply different styles to it, using CSS. The tooltiptext attribute specifies the text that will appear on the panel tooltip. We have added a new private attribute called sitestate to our panel. This attribute specifies the current site status and is useful in applying different styles to our panel widget. Integrating the New Element into Firefox Now that we have created our user interface element, how do we let the browser know that we want this new element to appear on the status bar? Mozilla has a mechanism called dynamic overlays that allows the user interface to be modified dynamically without changing the actual document that defines it. In our example, we add an element to the Firefox status bar without modifying the browser XUL definition file. The procedure for creating a dynamic overlay is straightforward: 1. Create a separate XUL document that specifies all the needed additions and modifica- tions to the original user interface. 2. The root element of the new XUL document is overlay. This specifies that the chil- dren of this element are inserted into a target document (or are overlaid on top of it). Define any number of child elements under the overlay. The id attribute of these ele- ments will be matched against the ids of the elements in the document being overlaid, and if there is a match, the two elements will be merged. 3. You need to perform one additional step to let Mozilla know which XUL documents are overlays and what their target documents are. The following sections explore how this is done. Let’s modify our XUL definition to specify that we want our status bar panel to appear on the main browser status bar: <overlay id=”siteleds-overlay” xmlns=”http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul”> <statusbar id=”status-bar”> <statusbarpanel class=”statusbarpanel-iconic” id=”siteleds-statusbar-panel” tooltiptext=”SiteLeds Status Icon” sitestate=”unknown” insertbefore=”statusbar-display”/> </statusbar> </overlay> Let’s see exactly what we have done: Ⅲ We have defined an overlay element. Its id attribute uniquely identifies it, and the value of the xmlns attribute specifies that the default name space of our XML docu- ment is XUL, meaning that all its children are XUL elements. 25_596500 ch17.qxd 6/30/05 3:13 PM Page 327 328 Part VI — Creating Extensions and Themes Ⅲ We have created a child statusbar element in the overlay node. Its id is status- bar , which is identical to the id of the main Firefox statusbar element. This means that our status bar is overlaid on top of the Firefox status bar. Ⅲ Because our status bar element is merged into the Firefox status bar, all the child ele- ments of our status bar — in this case, a single statusbarpanel element — are added to the child elements of the Firefox status bar. We can use the insertbefore attribute to specify the exact position at which the new status bar panel is inserted. In this case, we want it to be inserted just before the element with the statusbar-display id, which is the element that displays the current browser status. Figure 17-4 shows the position of the new status bar panel. F IGURE 17-4: The position of the new status bar panel Dynamic overlays can be used not only to add new elements to existing ones but also to modify the attributes of the existing elements and to add new top-level elements to the target window. Defining the Appearance We want our status bar panel to display different icons, depending on the current state of the monitored site. Table 17-1 specifies the various icons that are displayed according to the sitestate attribute of our statusbarpanel element. The SiteLeds status panel 25_596500 ch17.qxd 6/30/05 3:13 PM Page 328 329 Chapter 17 — Creating Extensions Table 17-1 Displayed Icons State Icon Icon Filename Meaning unknown state-unknown.png The site state is unknown. ok state-ok.png The page is reachable and hasn’t been modified. error state-error.png There was an error connecting to the site. modified state-modified.png The monitored page has been modified. Our style sheet document, siteledsOverlay.css, will therefore look like this: #siteleds-statusbar-panel[sitestate=”unknown”] { list-style-image: url(“chrome://siteleds/skin/state-unknown.png”); } #siteleds-statusbar-panel[sitestate=”ok”] { list-style-image: url(“chrome://siteleds/skin/state-ok.png”); } #siteleds-statusbar-panel[sitestate=”error”] { list-style-image: url(“chrome://siteleds/skin/state-error.png”); } #siteleds-statusbar-panel[sitestate=”modified”] { list-style-image: url(“chrome://siteleds/skin/state-modified.png”); } As you can see, we are selecting our status bar panel by its id attribute (siteleds-statusbar- panel ), and specifying which icon to display by defining different rules for different values of the sitestate attribute. The icon we want to appear on the status bar is specified using the CSS list-style-image attribute. Adding the Functionality We want our extension to try to load a given web page. If this load operation succeeds, the extension checks whether the page was modified by comparing its content with the one saved during the previous request. Our JavaScript code then sets the value of the sitestate attribute of our status panel according to the result of this operation. We will create the JavaScript implementation file named siteledsOverlay.js. First, let’s define some global variables: var gSiteLedsLastRequest = null; var gSiteLedsLastContent = null; 25_596500 ch17.qxd 6/30/05 3:13 PM Page 329 330 Part VI — Creating Extensions and Themes These variables contain the last HTTP request object and the contents of the last loaded page. The main function that initiates the page load request is called siteLedsCheckPage: function siteLedsCheckPage() { var pageURL = ‘http://www.iosart.com/firefox/siteleds/index.html’; gSiteLedsLastRequest = new XMLHttpRequest(); gSiteLedsLastRequest.onload = siteLedsPageLoaded; gSiteLedsLastRequest.onerror = siteLedsPageError; gSiteLedsLastRequest.open(‘GET’, pageURL); gSiteLedsLastRequest.send(null); } This function does the following: 1. Creates a new XMLHttpRequest object. This object is used to perform HTTP requests. 2. Adds two event handlers. The siteLedsPageLoaded function is called when the server responds to our query, and the siteLedsPageError function is executed in case an error occurs during the HTTP request. 3. Initializes and sends an HTTP Get request for the specified web page. Our error handling function looks like this: function siteLedsPageError() { var ledElement = document.getElementById(‘siteleds-statusbar-panel’); ledElement.setAttribute(‘sitestate’, ‘error’); setTimeout(siteLedsCheckPage, 900000); } This function is called if there is an error during the attempt to load the monitored web page (for example, if the network connection is down). We first find our status panel element using the DOM getElementById method. Then we set the value of the sitestate attribute to error. This, along with our style sheet definitions, will make the error icon appear on the sta- tus bar. Finally, we call the setTimeout function to try to perform the same test again after 900,000 milliseconds (15 minutes). If the server responds to our HTTP request, the siteLedsPageLoaded function is called: function siteLedsPageLoaded() { var ledElement = document.getElementById(‘siteleds-statusbar-panel’); if (gSiteLedsLastRequest.status == 200) { var prevContent = gSiteLedsLastContent; gSiteLedsLastContent = gSiteLedsLastRequest.responseText; if ((prevContent != null) && (prevContent != gSiteLedsLastContent)) { ledElement.setAttribute(‘sitestate’, ‘modified’); } else { ledElement.setAttribute(‘sitestate’, ‘ok’); setTimeout(siteLedsCheckPage, 900000); } 25_596500 ch17.qxd 6/30/05 3:13 PM Page 330 331 Chapter 17 — Creating Extensions } else { ledElement.setAttribute(‘sitestate’, ‘error’); setTimeout(siteLedsCheckPage, 900000); } } First, we check whether the server returned HTTP status code 200 (OK). If so, the page was loaded correctly, and we can check whether it has changed since the last time we successfully loaded it. We compare the contents of the current and the previously loaded pages and, depending on the outcome of this comparison, set the current state to either ok or modified. If the server returned a status code other than 200, we set the state of our panel to error. Also, if the page wasn’t modified, we schedule a new test to 15 minutes from now by calling the setTimeout function. After defining all the needed functions, we must tell Firefox to start the site checking cycle when it loads by adding the following line at the top level of our JavaScript file: window.addEventListener(“load”, siteLedsCheckPage, false); This adds an event handler for the window load event, meaning that our siteLedsCheckPage function will be called after the main Firefox window is first opened and initialized. The JavaScript functions and global variables we have defined are evaluated in the global names- pace along with the other Firefox JavaScript code. This means that if one of our functions or vari- ables has the same name as an existing identifier, we will have a name collision. To avoid this situation, you should always create a unique string (“siteLeds” in our case) and use it as a prefix for all your global identifiers. The following sections describe another technique for avoid- ing such conflicts. The final siteledsOverlay.js file is as follows: var gSiteLedsLastRequest = null; var gSiteLedsLastContent = null; function siteLedsCheckPage() { var pageURL = ‘http://www.iosart.com/firefox/siteleds/index.html’; gSiteLedsLastRequest = new XMLHttpRequest(); gSiteLedsLastRequest.onload = siteLedsPageLoaded; gSiteLedsLastRequest.onerror = siteLedsPageError; gSiteLedsLastRequest.open(‘GET’, pageURL); gSiteLedsLastRequest.send(null); } function siteLedsPageError() { var ledElement = document.getElementById(‘siteleds-statusbar-panel’); ledElement.setAttribute(‘sitestate’, ‘error’); setTimeout(siteLedsCheckPage, 900000); } 25_596500 ch17.qxd 6/30/05 3:13 PM Page 331 . url(“chrome://siteleds/skin/state-unknown.png”); } #siteleds-statusbar-panel[sitestate=”ok”] { list-style-image: url(“chrome://siteleds/skin/state-ok.png”); } #siteleds-statusbar-panel[sitestate=”error”] { list-style-image:. class=”statusbarpanel-iconic” id=”siteleds-statusbar-panel”/> tooltiptext=”SiteLeds Status Icon” sitestate=”unknown”/> - XUL - JavaScript - CSS - Images classic modern English Spanish - DTD - Properties content skin Chrome. { list-style-image: url(“chrome://siteleds/skin/state-error.png”); } #siteleds-statusbar-panel[sitestate=”modified”] { list-style-image: url(“chrome://siteleds/skin/state-modified.png”); } As you can see, we

Ngày đăng: 04/07/2014, 17:20

Tài liệu cùng người dùng

Tài liệu liên quan