mozilla firefox extension development course 2: advanced
TRANSCRIPT
![Page 1: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/1.jpg)
Mozilla Firefox Extension Development
Course 2: Advanced
LittlebtcOSSF Workshop / MozTW Acitivity
The text of the slide is under CC-BY-SA-3.0.Most photos are under CC-BY-SA compatible license,while screenshots / logos are under Fair Use.Code is under MIT license.
![Page 2: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/2.jpg)
Review
• Do you remember…?– XUL and controls?– Some JavaScript technique?– install.rdf and chrome.manifest?– Some XPCOM introduction?
![Page 3: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/3.jpg)
Preference SystemMake options for your extension
![Page 4: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/4.jpg)
Why preferences?
• Provide options to user– Which can be set in an option window– Or in the program operation
• Record user's choice
![Page 5: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/5.jpg)
about:config
![Page 6: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/6.jpg)
Available types
• String• Integer• Boolean: true / false
![Page 7: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/7.jpg)
Default Preferences
• Can be included in the Extension Dir / XPI file• Will be loaded as default value of preferences• Place .js files in [ext-dir]/defaults/preferences/• Example of .js file content of default
preferences : pref("extensions.extensionname.preferencename", false);– Name: has a widely used naming convention– Value: Boolean / Integer / String
![Page 8: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/8.jpg)
Take an example
• See defaults/preferences/ tutorial.js
pref("extensions.tutorial.option1", false);pref("extensions.tutorial.option2", "");pref("extensions.tutorial.option3", 32);pref("extensions.tutorial.default_editor", "");
![Page 9: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/9.jpg)
See about:config
![Page 10: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/10.jpg)
Preference System:<prefwindow>
• Way to make a "option window"• It is XUL, again• But it has a special system, in that system,
you don't need to write too much JavaScript/XPCOM to support changing preferences.
![Page 11: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/11.jpg)
Set install.rdf, again
<em:optionsURL>chrome://tutorial/content/options.xul</em:optionsURL>
• This will point the "Options" button of your extension to the corresponding XUL pages:
![Page 12: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/12.jpg)
<prefpane>
• Must be a child of <prefwindow>• Reprensent a pane (tab) in the prefwindow• Attributes: – label– image– onpaneload: a onload-like on this panel– src: Content can be external XUL
<prefpane id="paneGeneral" label="General" src="chrome://path/to/paneOverlay.xul"/>
![Page 13: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/13.jpg)
<preferences> <preference>
• <preferences>: Container• <preference>: "Magic Attribute" to hold the
actual preference, attributes:– id– name: Corresponding preference name– type: bool/string/unichar/int/file
• In controls, use preference="id" to connect the magic!
![Page 14: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/14.jpg)
Example: options.xul<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="chrome://global/skin/" type="text/css"?><?xml-stylesheet href="chrome://mozapps/content/preferences/preferences.css"?><?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css"?>
<prefwindow xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <prefpane id="panel1" label="panel1"> <preferences> <preference name="extensions.tutorial.option1" id="extensions.tutorial.option1" type="bool" /> <preference name="extensions.tutorial.option2" id="extensions.tutorial.option2" type="unichar" /> </preferences> <checkbox id="option1" preference="extensions.tutorial.option1" label="Check me!" /> <hbox> <label value="Type Your Name:" accesskey="N" control="option2" /> <textbox id="option2" preference="extensions.tutorial.option2" /> </hbox> </prefpane> <prefpane id="panel2" label="panel2" src="chrome://tutorial/content/panel2.xul"/></prefwindow>
![Page 15: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/15.jpg)
Example: panel2.xul<?xml version="1.0" encoding="UTF-8"?>
<overlay id="Pane2Overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <prefpane id="panel2"> <preferences> <preference name="extensions.tutorial.option3" id="extensions.tutorial.option3"
type="int" /> </preferences> <hbox> <label value="Type a Integer:" accesskey="I" control="option3" /> <textbox id="option3" preference="extensions.tutorial.option3" type="number" /> </hbox> </prefpane></overlay>
![Page 16: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/16.jpg)
Result
![Page 17: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/17.jpg)
Part 2: Read/Write in XPCOM
• XPCOM: nsIPrefService / nsIPrefBranch• Changes Preferences in JavaScript• First step: Read branch// Get the root branchvar prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
// Get the "extensions.tutorial." branchvar prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService); prefs = prefs.getBranch("extensions.tutorial.");
![Page 18: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/18.jpg)
Part 2: Read/Write in XPCOM
• Then, read/write• getBoolPref(), setBoolPref()• getCharPref(), setCharPref()– BEWARE: Not Unicode Compatible!
• getIntPref() and setIntPref()
![Page 19: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/19.jpg)
Part 2: Read/Write in XPCOM
Examples to run in JavaScript Shell:// Get the "extensions.tutorial." branchvar prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService); prefs = prefs.getBranch("extensions.tutorial.");
// Get the value of option3 (a number)var option3 = prefs.getIntPref('option3');alert(option3);// Set the value of option1 (a boolean) to trueprefs.setBoolPref('option1', true);var option1 = prefs.getBoolPref('option1');alert(option1);
![Page 20: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/20.jpg)
Part 2: Read/Write in XPCOM
• Read/Write Unicode Strings:(from https://developer.mozilla.org/en/Code_snippets/Preferences)// Example 1: getting Unicode valuevar option2 = prefs.getComplexValue("option2",
Components.interfaces.nsISupportsString).data;alert(option2);
// Example 2: setting Unicode valuevar str = Components.classes["@mozilla.org/supports-string;1"] .createInstance(Components.interfaces.nsISupportsString);str.data = "火狐 ";prefs.setComplexValue("option2", Components.interfaces.nsISupportsString, str);
![Page 21: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/21.jpg)
When you should use XPCOM
• First run:– Make a default pref to detect first run
(Change it after first run processing is ended)
• Dialog to remember something:– Like "Exit Firefox":
![Page 22: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/22.jpg)
File ProcessingAccess local fileshttps://developer.mozilla.org/en/Code_snippets/File_I%2f%2fO
![Page 23: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/23.jpg)
The nsIFile / nsILocalFile• nsIFile: Cross-platform File I/O interface• nsILocalFile: extends nsIFile, can access local
filesystem• It is a "LOCATION INDICATOR"• What can nsILocalFile object do?– Check whether the file exists– Copy / Delete / Move files– Create files / folders– Work as a parameter to a lot of function
• Saving webpage into files, etc…
![Page 24: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/24.jpg)
"Create" a nsILocalFile
• With a absolute path:var file = Components.classes["@mozilla.org/file/local;1"] .createInstance(Components.interfaces.nsILocalFile);file.initWithPath("C:\\");
• "Path" should be in a "native" waylike /home/littlebtc in Linux, C:\ in Windows
• file:// URI? Explained later
![Page 25: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/25.jpg)
"Create" nsIFile pointing to special folders
• Get an object located to Profile Directory:// get profile directoryvar file = Components.classes["@mozilla.org/file/directory_service;1"] .getService(Components.interfaces.nsIProperties) .get("ProfD", Components.interfaces.nsIFile);
• You can replace the ProfD with:With… Where With… Where
CurProcD (Firefox) Installation Dir
Desk DesktopC:\Users\Littlebtc\Desktop
Home User's DirC:\Users\Littlebtc/home/littlebtc/
Progs "Programs" directory inWindows Start Menu
resource:app XULRunner App Directory
![Page 26: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/26.jpg)
How to…
Assuming we have a nsIFile object file, how to• Get the native path representation of a nsIFile?
– file.path
• Know whether the path refers to a existed thing?– file.exists()
– Return true or false• Distinguish the path which this file object refers
to from a folder, a file, or a link, or others?– Use file.isFile() file.isFolder() file.isSymlink() file.isSpecial()
![Page 27: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/27.jpg)
How to…
• Whether the path is readable/writable/executable/hidden?• Use file.isWritable() file.isReadable()
file.isExecutable() file.isHidden()
• Know the filesize (if it is a file)?– file.fileSize
• The file name without path?– file.leafName
• The parent of the path?– file.parent (It is a nsIFile object, and can be null!)
![Page 28: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/28.jpg)
How to…
• "Open the file" by the OS?• file.launch();
• Do something like "Open containing folder" in download manager?• file.reveal();
• Both of them are not work on Unix-like!
![Page 29: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/29.jpg)
How to…
• Delete the path?– file.remove();
– For folder, you can only remove empty folder
• Copy path?– file.copyTo(file2, 'newname');– file2 represents the parent path for the target item,
if it is null, it will be copied to the same parent of file• Move path?
– file.moveTo(file2, 'newname');
– file2 is the same as above– You can only move empty folder
![Page 30: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/30.jpg)
How to…
• How to "run the file" if it is a executable?– file.launch(); (Not recommended)– Use nsIProcess:
https://developer.mozilla.org/En/Code_snippets/Running_applications
– nsIProcess cannot accept Unicode parameters on Windows…
![Page 31: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/31.jpg)
How to…Assuming file is a nsIFile object refering to a folder path, how to:• Access a file in this directory?
– file.append('filename');Then file will be changed, will refer to this file, not the original folder!
• Access multiple files? Clone object, then append– var file1 = file.clone(); // Clone file object
file1.append('filename');
• How to create a subfolder?– file.append("DIR"); // Still, append first
if( !file.exists() || !file.isDirectory() ) { // if it doesn't exist, create file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777);}
![Page 32: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/32.jpg)
File contents read/write
• https://developer.mozilla.org/en/Code_snippets/File_I%2f%2fO
• A little complex, why? When it comes to the encoding, it will be complex
![Page 33: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/33.jpg)
File Picker / <filefield>
• File Open / File Save / Select Folder Dialog• See
https://developer.mozilla.org/en/nsIFilePicker• <filefield> in the <prefwindow>, like Firefox
options (UNDOCUMENTED):http://www.xuldev.org/blog/?p=142
• We will have a small demo!
![Page 34: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/34.jpg)
File I/O demo 1
• A run dialog like Windows, use undocumented <filefield>
![Page 35: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/35.jpg)
run.xul<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<dialog title="Run application" buttons="accept,cancel" ondialogaccept="runApp.go();"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"><script type="application/x-javascript" src="chrome://tutorial/content/run.js"/><hbox><label value="Select an file:" accesskey="F" /> <filefield id="file" /><button label="Browse..." oncommand="runApp.browse();" /></hbox><grid><columns> <column flex="1" /> <column flex="2" /></columns><rows> <row> <label value="File name:" /><label value="" id="file_name" /> </row><row> <label value="File size:" /><label value="" id="file_size" /> </row></rows></grid></dialog>
![Page 36: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/36.jpg)
run.js (partial) browse: function() { // Initialize file picker var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); fp.init(window, 'Select a file', Ci.nsIFilePicker.modeOpen);
// Set Filter: file types fp.appendFilter('Windows executable', '*.exe'); fp.appendFilter('All Files', '*.*');
// Show the dialog var result = fp.show(); if (result == Ci.nsIFilePicker.returnOK) { this.file = fp.file; // This should not be happened, but this is a demo :P if (!this.file.exists() || !this.file.isFile()) { return; } // Include it into filefield document.getElementById('file').file = this.file; // Load file infos document.getElementById('file_name').value = this.file.leafName; document.getElementById('file_size').value = this.file.fileSize + ' bytes'; }},
![Page 37: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/37.jpg)
run.js (partial 2) go: function() { if (this.file && this.file.exists() &&
this.file.isFile()) { this.file.launch(); } }
![Page 38: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/38.jpg)
URI Problem• In XPCOM, nsIURI is a common interface to represent
an URI (It can handle all types of URI)• nsIURI <-> String URL: Use nsIIOService
– var uri = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService).newURI('http://moztw.org/', null, null);
– uri.spec will contain the string representation of the URI• nsIURI <-> nsIFile
– var file_uri = Components.classes["@mozilla.org/network/io-service;1"] .getService(Components.interfaces.nsIIOService).newFileURI(file); // Assuming file is a nsIFIle
– var file = file_uri.QueryInterface(Components.interfaces.nsIFileURL).file;
![Page 39: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/39.jpg)
When you will need nsIURI / nsIFile• Downloading files
https://developer.mozilla.org/en/Code_snippets/Downloading_Files (Basic)http://www.xuldev.org/blog/?p=163 (Advanced, by Gomita, a good intro to nsIWebBrowserPersist)
• Use Places API (Bookmarks, Tags, History)https://developer.mozilla.org/en/Places
• Progress listenershttps://developer.mozilla.org/en/Code_snippets/Progress_Listeners
• And much more…
![Page 40: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/40.jpg)
TreeA somehow complex XUL structure
![Page 41: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/41.jpg)
What is a tree?
• A complex item lists• An item may have some childs
![Page 42: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/42.jpg)
Why is it so complex• There are A LOT OF way to implement• But none of them are NOT trivial • Some is easier but not so easy to be extended• Some is harder, but fully functional
![Page 43: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/43.jpg)
The easiest: Content Tree• (Try XUL Editor!)• From https://developer.mozilla.org/En/XUL/Tree
<tree flex="1" rows="2"> <treecols> <treecol id="sender" label="Sender" flex="1"/> <treecol id="subject" label="Subject" flex="2"/> </treecols> <treechildren> <treeitem> <treerow> <treecell label="[email protected]"/> <treecell label="Top secret plans"/> </treerow> </treeitem> <treeitem> <treerow> <treecell label="[email protected]"/> <treecell label="Let's do lunch"/> </treerow> </treeitem> </treechildren></tree>
![Page 44: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/44.jpg)
The easiest: Content Tree
• <tree>: Sent a row number as rows attribute is recommended?
• <treecols>, <treecol>: Define the columns– Use flex to modify column width in <treecol>– Use id to build an identifier of the column
• <treeitem>, <treerow>: Represents a row• <treecell>: Represents a cell– Attribute: label
![Page 45: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/45.jpg)
A tree with nested itemsFrom https://developer.mozilla.org/En/XUL/Tree
<tree id="myTree" flex="1" hidecolumnpicker="false" seltype="single" class="tree" rows="5"> <treecols id="myTree2-treeCols"> <treecol id="myTree2-treeCol0" primary="true" flex="2" label="Column A" persist="width" ordinal="1"/> <splitter class="tree-splitter" ordinal="2"/> <treecol id="myTree2-treeCol1" flex="1" label="Column B" persist="width" ordinal="3"/> </treecols> <treechildren> <treeitem> <treerow> <treecell label="1"/> <treecell label="a"/> </treerow> </treeitem> <!-- Make sure to set container="true" --> <treeitem container="true" open="true"> <treerow> <treecell label="2"/> <treecell label="b"/> </treerow> <treechildren> <treeitem> <treerow> <treecell label="2a"/> <treecell label="ba"/> </treerow> </treeitem> </treechildren> </treeitem> </treechildren></tree>
![Page 46: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/46.jpg)
Wait, a lot of new thing…?
• <splitter>: Between columns, to make them resizable
• Nested items: <treechildren> under <treeitem>• hidecolumnpicker="false"– Whether to hide the column picker on the right– seltype="single": you can select only one item
or seltype="multiple" for multiple selection support• persist="attributename1 attributename2"– Make Firefox "remember" user's settings on specific
attribute
![Page 47: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/47.jpg)
OK, now, what is wrong?
• Though we can multiply the tree with DOM, but it will the code will be somehow complex due to the bad XUL structure
• So DOM way is not a popular way if it comes to dynamic content trees
![Page 48: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/48.jpg)
The most common: Custom TreeView
• Implements nsITreeView to create a tree• Set custom tree view into view property• It can be fully functional and dynamic
– …But somehow hard: poorly documented and buggy if having bad implementation
– You should check Firefox's code to understand – It takes me almost 20 hours to make <tree> on NicoFox works
and another 20 hours to fix bugs…• Are you ready? :Dhttps://developer.mozilla.org/en/XUL_Tutorial/
Custom_Tree_Viewshttp://www.xuldev.org/blog/?p=127 (Thank you again,
Gomita!)
![Page 49: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/49.jpg)
Tree Selection / Box Object
• Tree Selection: Get currently selected itemshttps://developer.mozilla.org/en/XUL_Tutorial/Tree_Selection– A little like text selection we had mentioned at the
previous lecture (?)• Box Objects: Handle Tree's display
Needed, for example, if you need to know the which cell the cursor is athttps://developer.mozilla.org/en/XUL_Tutorial/Tree_Box_Objects
![Page 50: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/50.jpg)
LUNCH TIME AGAIN!Take a break, there is a final boss: SQLite!
![Page 51: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/51.jpg)
Storage: SQLiteGreat storage choice
![Page 52: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/52.jpg)
What is SQLite?
• A lightweight relational database management system
• Its C/C++ library is very small (418KB in Firefox 3.5) and very easy-to-use
• Can use most of the SQL command• Resulting database is a single file• PUBLIC DOMAIN!(No any copyright restriction)• Used by a lot of software / framework
![Page 53: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/53.jpg)
SQLite is in …
• Firefox, Safari, Google Chrome• Google Gears• Photoshop lightroom, Adobe AIR• Skype, McAfee, Songbird• PHP, Python…• iPhone, Symbian, Android…• Almost everywhere!!!!
![Page 54: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/54.jpg)
Now, make a new database!
![Page 55: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/55.jpg)
Now, make a new database!
• Find your profile dir and copy the path Orz
![Page 56: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/56.jpg)
Now, make a new database!
• Close SQLite manager and restart:
![Page 57: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/57.jpg)
Create a table
![Page 58: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/58.jpg)
Table is ready!
![Page 59: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/59.jpg)
Add a record
![Page 60: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/60.jpg)
Simple way to display SQLite DB
• Use templatehttps://developer.mozilla.org/en/XUL/Template_Guide/SQLite_Templates
• Simple, but useful for our demo! :D• We will use the template technique and
<tree> in the following demo
![Page 61: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/61.jpg)
students.xul
<tree flex="1"> <treecols> <treecol id="col-no" label="No" flex="1"/> <treecol id="col-name" label="Name" flex="1"/> <treecol id="col-score" label="Score" flex="1"/> </treecols> <treechildren datasources="profile:tutorial.sqlite" ref="*" querytype="storage"> <template> <query> SELECT * FROM students ORDER BY score DESC </query> <action> <treeitem uri="?"> <treerow> <treecell label="?no"/> <treecell label="?name"/> <treecell label="?score"/> </treerow> </treeitem> </action> </template> </treechildren></tree>
![Page 62: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/62.jpg)
Explain
• <treechildren datasources="profile:tutorial.sqlite" ref="*" querytype="storage">
• Use SQLite database as a template datasources• <template>: <query> and <action>– <query>: SQL command
• SELECT * FROM students: Select all fields from students table• ORDER BY score DESC: Order by score field in descendant order
– <action>: Applied template• uri="?": (?)• Read score field from ?score
![Page 63: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/63.jpg)
mozStorage API
• Mozilla's way to multiply SQLite database• So it is XPCOM again … • But it is not so difficult!
• I don't want to talk in detail, so go straight to examples!
![Page 64: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/64.jpg)
Final Demo:"Add a record" function
![Page 65: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/65.jpg)
A SQL preview
• INSERT INTO students (name, score) VALUES ("Littlebtc", 30)
• Insert a data into students table• Two fields: name and score• Their values: Littlebtc and 30
![Page 66: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/66.jpg)
students.xul, again<hbox><label value="Student Name:" accesskey="N" control="new_name" /><textbox id="new_name" style="width: 8em;"/>
<label value="Score:" accesskey="S" control="new_score" /><textbox id="new_score" type="number" style="width: 4em;"
max="100" min="0"/>
<button label="Add" oncommand="students.add();"/></hbox>
![Page 67: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/67.jpg)
student.js: student.add();/* use nsIPromptService to alert */ /*
https://developer.mozilla.org/en/Code_snippets/Dialogs_and_Prompts */
var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"] .getService(Ci.nsIPromptService);
/* Record user's choice */ var name = document.getElementById('new-name').value; var score = document.getElementById('new-score').value;
/* Required to enter a name */ if (!name) { prompts.alert(null, 'Error', 'Please Enter a Name.'); return; }
![Page 68: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/68.jpg)
…continued try { // try-catch exception handling
/* We will see here later */ } catch(e) { // There may be some error in XPCOM, we can handle it prompts.alert(null, 'Error', 'Database/XPCOM Error:' + e); }
• XPCOM Will throw exception when error• So we need a good way to handle it• …Or it will be displayed in the error console
![Page 69: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/69.jpg)
Connect to DB/* Find the tutorial.sqlite */var file = Components.classes["@mozilla.org/file/directory_service;1"] .getService(Components.interfaces.nsIProperties) .get("ProfD", Components.interfaces.nsIFile);
file.append("tutorial.sqlite");
/* Open database */var storageService = Cc["@mozilla.org/storage/service;1"] .getService(Ci.mozIStorageService);var db = storageService.openDatabase(file);
![Page 70: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/70.jpg)
Execute a "statement"var sql = "INSERT INTO students (name, score) VALUES (?
1, ?2)";var statement = db.createStatement(sql);statement.bindUTF8StringParameter(0, name);statement.bindInt32Parameter(1, score);/* Execute the statement */statement.execute();/* Finallize */statement.finalize();
• "Statement" is a SQL command in mozStorage• Why we should use the "binding" way?
Prevent SQL injection, make database safe• https://developer.mozilla.org/en/
mozIStorageStatement#Binding_Functions
![Page 71: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/71.jpg)
Finally…
• Don't forget to close your DB!
db.close();
![Page 72: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/72.jpg)
After try{…} catch{…}
• We should update the tree and show a message
/* Update the tree */document.getElementById('students-treechildren').builder.rebuild();
/* Prompt the user */
prompts.alert(null, 'OK', 'Thank you!');
![Page 73: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/73.jpg)
Working Example
![Page 74: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/74.jpg)
How to do for you later
• Understand how to CRUD (Create, Read, Update, Delete) in SQLite– SQL commands: INSERT, SELECT, UPDATE, DELETE
• Remember: Always Binding, NEVER directly apply variables into SQL command strings– Google "SQL Injection" for details
• SQLite is simple but powerful – have fun!
![Page 75: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/75.jpg)
This is the basic!• Actually, SQLite storage access with <tree> is
usually implemented in Custom Tree View way, both in Firefox and NicoFox
• That is another reason that I had spent 40 hours on a tree
• Edit / Remove may be a very hard work
![Page 76: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/76.jpg)
THANK YOU!It is 5:34am, I had finished my slide
![Page 77: Mozilla Firefox Extension Development Course 2: Advanced](https://reader034.vdocuments.mx/reader034/viewer/2022050817/5559fff5d8b42ad00a8b4e25/html5/thumbnails/77.jpg)
…….NOT YET!!!