Okay, I keep saying that I'll write a themes tutorial (even though I have yet to make a theme ;-) and then real life comes in and I have to work. Here's the current incarnation of the themes tutorial, along with the notes that Patrick Thompson (sailfish), the maintainer of Sky Pilot, has sent me on how he makes themes. If you want to make a splash in the mozilla documentation community, here's your chance. The need is there.
--------------------- Begin Themes Tutorial --------------------------- grayrest's guide to simple skinning Mozilla front end code (for the purposes of this tutorial) is the XUL, XBL, JavaScript, and CSS that make mozilla look like it does. Each has it's own role, JS and XBL defines behavior, XUL defines structure, and CSS defines apperance. To make a skin, you don't have to know all these, just the CSS. To do a proper job of it, Things you'll need to know: Using an image software package (optional) CSS Knowing CSS means really knowing CSS2, not just how to make your web page look like x. The most notable things to look for are the child operator (>), which will select the child of an object but not the grandchild e.g. .movie>.kungfu will select everything with class kungfu that is a direct decendant of an object of movie class, but won't select it's .kungfu's child .bad like a simple .movie .kungfu .bad or .movie .bad would (the space is the decendant selector and matches all decendants). The other construct that's used in moz but is uncommon elsewhere is the attribute selector .movie[kungfu] would match if the object of class movie had an attribute named kungfu while .movie[kungfu="bad"] would only match if the kungfu attribute were set to bad. Keep in mind that you're working with XUL and you can have all sorts of weird attribute names (though none I know of are kungfu ;^). I suggest you read up on the selectors, there are more unusual ones than just these two. Also, if you happen to run across a property that has a name like -moz-blah, then you can look up what it does at the xulplanet reference. Also, be sure to read the CSS chrome guidelines so your skin doesn't kill mozilla's performance. Things you'll need to have: Mozilla RC1+ (http://www.mozilla.org) Decent text editor (optional, but I recomment http://vim.sf.net) Image software package (optional, I use Photoshop) As you can see, the list isn't very long. The XUL and CSS for the mozilla front end are fairly easy to master, and you should be able to make some decent skins using only what is covered in this lesson. Step 1: PLAN! Don't make an ugly skin. Think about what you want it to look like before you go in and start painting. I was planning on making a skin a few months ago (http://grayrest.com/moz/resources/themes.shtml) but the underlying XUL was changing so fast that I couldn't keep up and decided to hold off till 1.0. The important thing to note is that I had the entire skin sketched out on paper before hand and went through three or four iterations till I got the look I wanted. You should be doing at least as much. If you don't then your skin won't be as good as it could have been had you put some planning into it and most likely it won't be any good and nobody will download or use it. If you're making skins for yourself, that's cool, but don't release them on the world and make us wade through forests of terrible design to grab a few good skins (witness winamp2, get off the most downloaded and you'll see what I mean). This lesson will focus on simpler modifications that are common up to this point. If you want to get more creative, you'll have to do your own digging. You'll be more satisfied in the end anyway. Step 2: Learn to use DOM Inspector. The DOM Inspector is a powerful tool for the skinner and the web page designer. You should use it to good affect. This is a simple example of just what you can do with it. 1. Open a browser window and hit ctrl+shift+i (alternatively go under Tools>Web Development>DOM Inspector). 2. When the window opens, go to File>Inspect Window>Your Window - Mozilla {BuildID:...} 3. Now, you click the "Find Node to Inspect By Clicking on It" 4. Alt+Tab (coolswitch, as microsoft calls it) back to the browser window you're inspecting and click on the back button, it should have a red box flash around it. **This will only work if you do it on a page with no back history. Otherwise the page will reload, reset the chrome, and you'll have to repeat steps 2 and 3. It works best if you start with a fresh window. Actually, it's behavior is erratic, it will work some of the time, but don't do it, it's just a pain. 5. Now you'll be *below* the actual back-button in the DOM tree, so move back up the tree to the item that has the back-button id. Now the interesting part begins. **Note that every time you click on a node in the tree, the corresponding chrome blinks. 6. In the right half of the DOM Inspector, you're currently on the DOM Node pane, this is useful for testing XUL changes, so is less interesting in our case. If you want to explore, follow the steps below. a.right click on the big white pane and choose insert. b.Type "class" and "toolbarbutton" in and poof, the button changes in the browser. c. Now right click on the class name you just added, click delete, the button disappears completely from the screen (but not from the browser window itself). d. Finally insert "class" and "toolbarbutton-1" (notice the -1 on the end) and you should have your back button normal once more. 7. Click on the Object button, and pick CSS Style Rules from the resulting menu. 8. �Caramba! I hear you say, "that's a lot of rules for just a button". I agree, it's one of the most visible and complex buttons so it serves us well. a. Scroll down to the end and click on the #back-button rule. b. Right click on the bottom pane where the style properties are listed ('-x-image-region...') and click New Property. c. Type "width" in the first popup box, and "30px" in the second. The back button is now squashed horizontally. d. Right click the rule you just added (it will be the bottommost) and pick delete. The rule is deleted and the back button restored. 9. One more thing you should notice, the top part of the right pane has the File the rule is defined in. It's all well and good to make temporary changes in chrome (yes, all the changes you just made are temporary), but once you figure out how to fix the problem by adding and deleting rules from the rules set, you need to go in and make those changes permanent. The trick with chrome is that you'll see stuff like chrome://navigator/skin/, which doesn't correspond to any apparent file. It corresponds to <chromedir>/modern.jar/skin/modern/navigator/navigator.css. You can preview the file (and extract/save it if you so desire) by typing the url that DOM Inspector shows into the location bar in navigator. This is actually the easiest way to pull a single file out of mozilla chrome jars. 10. Click on the Object button once more and choose Computed Style from the drop down list. You can't do anything in this view, but you should know about it because it's how you troubleshoot your chrome. e.g. You can't figure out why your buttons are shifted one pixel down and one over, then you go to this view to check out all the computed properties for the errant border-left, margin-top, or whatever then you use CSS Style Rules to find out where the errant rule is. That's about all there is to the DOM Inspector, the other views are nice on occasion, but nowhere near as useful to the skinner. Be wary of using the XBL Bindings, I've crashed mozilla many times by accidentally picking it on an object that didn't have XBL bindings. XBL is nifty because it allows you to change the behavior and functionality of chrome elements, learn it if that sounds interesting to you. Step 3: Get some Chrome You have two options here, download an existing Chrome or start with a default mozilla one. I recommend starting with the modern, because the classic skin gets parts of its style from the operating system theme, which can and probably will mess up your theme. I'm starting with the modern skin for this tutorial and I recommend you do the same. 1. Open up the chrome directory in your mozilla install folder. 2. Extract modern.jar into the chrome folder using your favorite gzip program. (winZip, winRAR in windows), place the extracted files in the chrome directory. This will give you <mozilla root>/chrome/skins/modern/... for your directory layout. 3. Change the name of the directory from modern to whatever you want, I'll use myskin. This will result in the directory structure being <mozillaroot>/chrome/skins/myskin/... 4. Now that we have the directories set up, we need to add the skin to the chrome files so that we can actually see the theme in mozilla. To do this we need to: a. add the following code block to the end of your <mozilla root>/chrome/chrome.rdf file (right above the </RDF:RDF> at the end). You edit this to correspond to your skin. <RDF:Description about="urn:mozilla:skin:skinTutorialSkin" c:description="This is what will show up when the user is choosing the skin from the preferences menu." c:image="resource:/chrome/skin/myskin/global/preview.gif" c:displayName="My First Skin" c:author="you" c:name="skinTutorialSkin/1.0" c:locType="install"> <c:packages resource="urn:mozilla:skin:skinTutorialSkin:packages"/> </RDF:Description> <RDF:Description about="urn:mozilla:skin:skinTutorialSkin:communicator" c:skinVersion="1.0" c:baseURL="resource:/chrome/skin/myskin/communicator/" c:allowScripts="false"> <c:package resource="urn:mozilla:package:communicator"/> </RDF:Description> <RDF:Description about="urn:mozilla:skin:skinTutorialSkin:editor" c:baseURL="resource:/chrome/skin/myskin/editor/" c:allowScripts="false" c:skinVersion="1.0"> <c:package resource="urn:mozilla:package:editor"/> </RDF:Description> <RDF:Description about="urn:mozilla:skin:skinTutorialSkin:global" c:baseURL="resource:/chrome/skin/myskin/global/" c:allowScripts="false" c:skinVersion="1.0"> <c:package resource="urn:mozilla:package:global"/> </RDF:Description> <RDF:Description about="urn:mozilla:skin:skinTutorialSkin:messenger" c:skinVersion="1.0" c:baseURL="resource:/chrome/skin/myskin/messenger/" c:allowScripts="false"> <c:package resource="urn:mozilla:package:messenger"/> </RDF:Description> <RDF:Description about="urn:mozilla:skin:skinTutorialSkin:navigator" c:baseURL="resource:/chrome/skin/myskin/navigator/" c:allowScripts="false" c:skinVersion="1.0"> <c:package resource="urn:mozilla:package:navigator"/> </RDF:Description> <RDF:Seq about="urn:mozilla:skin:skinTutorialSkin:packages"> <RDF:li resource="urn:mozilla:skin:skinTutorialSkin:communicator"/> <RDF:li resource="urn:mozilla:skin:skinTutorialSkin:editor"/> <RDF:li resource="urn:mozilla:skin:skinTutorialSkin:global"/> <RDF:li resource="urn:mozilla:skin:skinTutorialSkin:messenger"/> <RDF:li resource="urn:mozilla:skin:skinTutorialSkin:navigator"/> </RDF:Seq> b. Now you'll have to add the appropriate line to the urn:mozilla:skin:root RDF sequence. Search for "urn:mozilla:skin:root" and insert the following line in between the RDF:Seq tags (I found it on line 21). You should also see references for modern and classic. The line corresponding to the code in the last section is: <RDF:li resource="urn:mozilla:skin:skinTutorialSkin"/> Note that this corresponds to the first line of the code above. Change it if you changed the code above. 5. Close all open mozilla windows including quicklaunch and then reopen mozillla. Go to Edit>Preferences...>Debug>Networking and check "Disable XUL Cache". This will kill your new window performance, but will save you lots of time later. 6. Switch your skin to your new skin using either the View>Apply Theme or the preferences menu. 7. Restart moz again. When you come back you will be running from your brand new skin (though it looks just like modern, which it is). Congrats! Step 4: Hack that Chrome! We'll be doing some really simple chrome editing, this is the part that most of the Mozilla 0.9.4 era tutorials covered and that's why they don't work today. Basically all you need to know to start is that you can find the answers to your questions at http://www.xulpanet.com. Go there first, if that doesn't answer your question, hit #mozillazine on irc.mozilla.org (hit the chatzilla link, click on the moznet link on the first page, click on the #mozillazine link on the second) or the newsgroups. The plan for this tutorial is to change the forward/back/reload/stop to give you experience with image clipping, to change the throbber to the skypilot throbber because it looks cool, and to change the font for menu items to be bold so I can have three points. 1. Changing the font for menu items If you've ever done web development with CSS (if you haven't, you should), then you've probably set the font weight. It's no different in Mozilla Chrome, but you need to find out which of the many css files you need to change to get the effect you want. The tool we'll use for this is (your friend) the DOM Inspector. Now if you didn't read the intro to the DOM Inspector, shame on you. a. Fire up the DOM Inspector, hit the inspect by clicking button and then click the file menu, switch to CSS view and look for which file controls the menus. (It's <skinbase>/global/menu.css). Here's the slightly tricky part, which can save you lots of debugging time. b. Try to make the menus bold by adding the font-weight:bold rule to the menu stylesheets you've found using the DOM Inspector (refer to section 2). You will see that it does nothing. Now, it's much easier to find this out here than by typing the rule into a file, saving, and opening a new window. This is why I love the DOM Inspector. c. Expand the menu node in the node tree (click the little arrow, called a twisty, to the left of the menu node) and you'll see a node that says xul:label and is red. The red color means that the element is supplied by the XBL binding and not explicitly in the XUL source code (if this confuses you don't worry, it acts just like any other element for the purposes of CSS). This node is the actual text in the menu element, adding rules to the last rule in the chain will produce the desired affect. Unfortunately this has the affect of changing ALL the text that is a label (all the text that is chrome). This unexpected behavior is another reason it's nice to test using the DOM Inspector. d. I'd assume that the .menubar-text rule would add something, but I was unable to affect a change by editing it in the DOM Inspector, which forbodes evil minutes ahead... Time to check the XUL source. To do this, we'll have to use a mozilla web tool: LXR. LXR allows us to see the source of any file in the mozilla source tree. The one we're interested in is the one that controls the browser: navigator.xul (see the location bar in the DOM Inspector). Go to http://lxr.mozilla.org/seamonkey/ and enter navigator.xul in the file search menu. When you get to the page, you'll see that there are no tags corresponding to the menu bar items. (This is actually a really bad example to do this on, I realized this after I started, but it's about the worst you can get). The next place to turn is the overlays. Overlays are basically the same as Server Side Includes but for XUL instead of HTML. All the overlays in mozilla chrome are titled xxxOverlay.xul, which makes them easier to find. You can find a reference to navigatorOverlay.xul in the navigator.xul file. Change the name in the location bar from navigator.xul to navigatorOverlay.xul, and you'll be looking at the source for the menus. ---------------------------End Themes Tutorial ------------------------- A note here: the DOM Inspector section is the prototype version of the current DOM Inspector tutorial at http://grayrest.com/moz/evangelism/tutorials/dominspectortutorial.shtml, which may aid you in your editing of that section (you could, of course drop it completely and refer them to the tutorial). ----------------------Begin Sailfish Theme Notes------------------------ How I Did It ------------ 1. Create local theme folder structure. a. Add folders under Browsers, e.g., "skypilot/skin/skypilot" 2. Extract a template theme jar (using Winzip) into the folder structure in step 1. 3. Modify the contents.rdf file in theme root to reflect new theme structure and description. If either chatzilla or aim are being skinned then distinct contents.rdf file must be maintained for Mozilla and Netscape, excluding the IRC that doesn't apply and including the one that does. 4. Create RDF entries to allow local theme file access. a. Add entry to "installed-chrome.txt" to pull in skypilot theme structure. "skin,install,file,resource:/../skypilot/skin/skypilot/". This will allow both Mozilla AND Netscape to share the same development theme files assuming both are installed one directory level back. b. Delete installation chrome/chrome.rdf file. Browser will recreate from modified "installed-chrome.txt". 5. Modify existing template *.css and image files to desired theme. NOTE: For every changed ascii file (*.css, *.xml, *.rdf) renamed the original version to *.Ocss, *.Oxml, *.Ordf and enclose changes to the modified version with: Additions: /* ++B */ changes /* ++E */ Deletions: /* --B deletions --E */ Doing so will make it easier to debug during the creation process. ** Sky Pilot Specific Start: 6. Modified communicator/sidebar/sidebarBindings.xml file to place tab label on right side of tab Moved from line 12 14: <xul:label class="sidebar-tab-text" xbl:inherits="value=label" crop="right" flex="1"/> Added 58: <xul:hbox class="sidebarheader-internal-box" flex="1" autostretch="never"> 63: </xul:hbox> 7. To hide display of favicons on tabs: Added the following lines to global/global.css /* Added to remove favicon from tab (along with tabbox.xml). */ tab { -moz-binding: url(tabbox.xml#tab); } Created a global/tabbox.xml file to remove tab-icon inheritance only. 8. Triplicate folder following skin folder and rename to name1 and nameFULL. 9. Using Agent Ransack criteria file "Skypilot Pre-Delete Agent Ransack.srf" obtain list of image files referenced in .css and .rdf files in name1 folder. 10. Edit/reformat list (adding quotes and replacing /s with \s) to make a DOS batch file to delete these files in the name1 folder tree. 11. Using Agent Ransack criteria file "Skypilot Post-Delete Agent Ransack.srf" obtain list of remaining images left in name1 folder tree. 12. Edit/reformat list (adding quotes) to make a DOS batch file to delete these files in the original folder tree. Save this file in event that subsequent changes are need, thus saving steps 6-9 (see "Remove Surplus Images.bat"). ** Sky Pilot Specific End : 13. Delete all *.Ocss, *.Oxml and *.Ordf files from the skin folders. ** Sky Pilot Specific Start: 14. Using BK ReplaceEm fileset file "SkyPilot BK ReplaceEM.bkr" remove all comments added in step 5 from modified .css files. ** Sky Pilot Specific End : 15. Create theme.zip file using WinZip from the folder following the skin folder, rename to theme.jar. 16. Restore original chrome.rdf as explained in step 1. 17. Create install installation HTML (Install.html) and use it to do a local install of the theme to insure it works using the install process. 18. Place both the theme.jar and Install.html files on a web site. 19. Done! -----------------------End Sailfish Theme Notes------------------------- I hope someone out there can craft a good tutorial out of this. The entire thing is yours and you can do whatever you want with it (don't ask me about licensing, just do whatever). I ask that you do credit myself and Patrick somewhere in the thing, as credit is the coin of open source, but that's your perogative. -- grayrest http://grayrest.com/moz
