b=380168. r=gavin, r=dietrich. Add FUEL 0.2 (bookmarks and browsers) to tree.

This commit is contained in:
mark.finkle@gmail.com 2007-06-27 05:58:29 -07:00
parent f62f60723e
commit 12710726de
11 changed files with 1649 additions and 65 deletions

View File

@ -1,7 +1,12 @@
#include "nsISupports.idl"
#include "nsIVariant.idl"
interface nsIVariant;
interface nsIURI;
interface nsIDOMHTMLDocument;
interface fuelIPreference;
interface fuelIBookmarkFolder;
interface fuelIBrowserTab;
/**
* Interface that gives simplified access to the console
@ -263,9 +268,9 @@ interface fuelISessionStorage : nsISupports
};
/**
* Interface representing an extension
*/
/**
* Interface representing an extension
*/
[scriptable, uuid(ea563b60-aa5a-11db-abbd-0800200c9a66)]
interface fuelIExtension : nsISupports
{
@ -339,6 +344,291 @@ interface fuelIExtensions : nsISupports
};
/**
* Interface representing a collection of annotations associated
* with a bookmark or bookmark folder.
*/
[scriptable, uuid(335c9292-91a1-4ca0-ad0b-07d5f63ed6cd)]
interface fuelIAnnotations : nsISupports
{
/**
* Array of the annotation names associated with the owning item
*/
readonly attribute nsIVariant names;
/**
* Determines if an annotation exists with the given name.
* @param aName
* The name of the annotation
* @returns true if an annotation exists with the given name,
* false otherwise.
*/
boolean has(in AString aName);
/**
* Gets the value of an annotation with the given name.
* @param aName
* The name of the annotation
* @returns A variant containing the value of the annotation. Supports
* string, boolean and number.
*/
nsIVariant get(in AString aName);
/**
* Sets the value of an annotation with the given name.
* @param aName
* The name of the annotation
* @param aValue
* The new value of the annotation. Supports string, boolean
* and number
* @param aExpiration
* The expiration policy for the annotation.
* See nsIAnnotationService.
*/
void set(in AString aName, in nsIVariant aValue, in PRInt32 aExpiration);
/**
* Removes the named annotation from the owner item.
* @param aName
* The name of annotation.
*/
void remove(in AString aName);
};
/**
* Interface representing a bookmark item.
*/
[scriptable, uuid(808585b6-7568-4b26-8c62-545221bf2b8c)]
interface fuelIBookmark : nsISupports
{
/**
* The id of the bookmark.
*/
readonly attribute long long id;
/**
* The title of the bookmark.
*/
attribute AString title;
/**
* The uri of the bookmark.
*/
attribute nsIURI uri;
/**
* The description of the bookmark.
*/
attribute AString description;
/**
* The keyword associated with the bookmark.
*/
attribute AString keyword;
/**
* The type of the bookmark.
* values: "bookmark", "separator"
*/
readonly attribute AString type;
/**
* The parent folder of the bookmark.
*/
attribute fuelIBookmarkFolder parent;
/**
* The annotations object for the bookmark.
*/
readonly attribute fuelIAnnotations annotations;
/**
* The events object for the bookmark.
* supports: "remove", "change", "visit", "move"
*/
readonly attribute fuelIEvents events;
/**
* Removes the item from the parent folder. Used to
* delete a bookmark or separator
*/
void remove();
};
/**
* Interface representing a bookmark folder. Folders
* can hold bookmarks, separators and other folders.
*/
[scriptable, uuid(9f42fe20-52de-4a55-8632-a459c7716aa0)]
interface fuelIBookmarkFolder : nsISupports
{
/**
* The id of the folder.
*/
readonly attribute long long id;
/**
* The title of the folder.
*/
attribute AString title;
/**
* The description of the folder.
*/
attribute AString description;
/**
* The type of the folder.
* values: "folder"
*/
readonly attribute AString type;
/**
* The parent folder of the folder.
*/
attribute fuelIBookmarkFolder parent;
/**
* The annotations object for the folder.
*/
readonly attribute fuelIAnnotations annotations;
/**
* The events object for the folder.
* supports: "add", "addchild", "remove", "removechild", "change", "move"
*/
readonly attribute fuelIEvents events;
/**
* Array of all bookmarks, separators and folders contained
* in this folder.
*/
readonly attribute nsIVariant children;
/**
* Adds a new child bookmark to this folder.
* @param aTitle
* The title of bookmark.
* @param aURI
* The uri of bookmark.
*/
fuelIBookmark addBookmark(in AString aTitle, in nsIURI aURI);
/**
* Adds a new child separator to this folder.
*/
fuelIBookmark addSeparator();
/**
* Adds a new child folder to this folder.
* @param aTitle
* The title of folder.
*/
fuelIBookmarkFolder addFolder(in AString aTitle);
/**
* Removes the folder from the parent folder.
*/
void remove();
};
/**
* Interface representing a browser window.
*/
[scriptable, uuid(207edb28-eb5e-424e-a862-b0e97C8de866)]
interface fuelIWindow : nsISupports
{
/**
* A collection of browser tabs within the browser window.
*/
readonly attribute nsIVariant tabs;
/**
* The currently-active tab within the browser window.
*/
readonly attribute fuelIBrowserTab activeTab;
/**
* Open a new browser tab, pointing to the specified URI.
* @param aURI
* The uri to open the browser tab to
*/
fuelIBrowserTab open(in nsIURI aURI);
/**
* The events object for the browser window.
* supports: "TabOpen", "TabClose", "TabMove", "TabSelect"
*/
readonly attribute fuelIEvents events;
};
/**
* Interface representing a browser tab.
*/
[scriptable, uuid(3073ceff-777c-41ce-9ace-ab37268147c1)]
interface fuelIBrowserTab : nsISupports
{
/**
* The current uri of this tab.
*/
readonly attribute nsIURI uri;
/**
* The current index of this tab in the browser window.
*/
readonly attribute PRInt32 index;
/**
* The browser window that is holding the tab.
*/
readonly attribute fuelIWindow window;
/**
* The content document of the browser tab.
*/
readonly attribute nsIDOMHTMLDocument document;
/**
* The events object for the browser tab.
* supports: "load"
*/
readonly attribute fuelIEvents events;
/**
* Load a new URI into this browser tab.
* @param aURI
* The uri to load into the browser tab
*/
void load(in nsIURI aURI);
/**
* Give focus to this browser tab, and bring it to the front.
*/
void focus();
/**
* Close the browser tab. This may not actually close the tab
* as script may abort the close operation.
*/
void close();
/**
* Moves this browser tab before another browser tab within the window.
* @param aBefore
* The tab before which the target tab will be moved
*/
void moveBefore(in fuelIBrowserTab aBefore);
/**
* Move this browser tab to the last tab within the window.
*/
void moveToEnd();
};
/**
* Interface for managing and accessing the applications systems
*/
@ -387,4 +677,19 @@ interface fuelIApplication : nsISupports
* supports: "load", "ready", "quit", "unload"
*/
readonly attribute fuelIEvents events;
/**
* The root bookmarks object for the application.
*/
readonly attribute fuelIBookmarkFolder bookmarks;
/**
* An array of browser windows within the application.
*/
readonly attribute nsIVariant windows;
/**
* The currently active browser window.
*/
readonly attribute fuelIWindow activeWindow;
};

View File

@ -34,12 +34,9 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
const nsISupports = Components.interfaces.nsISupports;
const nsIClassInfo = Components.interfaces.nsIClassInfo;
const nsIObserver = Components.interfaces.nsIObserver;
const fuelIApplication = Components.interfaces.fuelIApplication;
const Ci = Components.interfaces;
const Cc = Components.classes;
//=================================================
// Shutdown - used to store cleanup functions which will
@ -50,7 +47,7 @@ var gShutdown = [];
// Console constructor
function Console() {
this._console = Components.classes["@mozilla.org/consoleservice;1"]
.getService(Components.interfaces.nsIConsoleService);
.getService(Ci.nsIConsoleService);
}
//=================================================
@ -62,11 +59,11 @@ Console.prototype = {
open : function cs_open() {
var wMediator = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
.getService(Ci.nsIWindowMediator);
var console = wMediator.getMostRecentWindow("global:console");
if (!console) {
var wWatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Components.interfaces.nsIWindowWatcher);
.getService(Ci.nsIWindowWatcher);
wWatch.openWindow(null, "chrome://global/content/console.xul", "_blank",
"chrome,dialog=no,all", cmdLine);
} else {
@ -148,13 +145,6 @@ Events.prototype = {
};
//=================================================
// Preferences constants
const nsIPrefService = Components.interfaces.nsIPrefService;
const nsIPrefBranch = Components.interfaces.nsIPrefBranch;
const nsIPrefBranch2 = Components.interfaces.nsIPrefBranch2;
const nsISupportsString = Components.interfaces.nsISupportsString;
//=================================================
// PreferenceBranch constructor
function PreferenceBranch(aBranch) {
@ -163,13 +153,13 @@ function PreferenceBranch(aBranch) {
this._root = aBranch;
this._prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(nsIPrefService);
.getService(Ci.nsIPrefService);
if (aBranch)
this._prefs = this._prefs.getBranch(aBranch);
this._prefs.QueryInterface(nsIPrefBranch);
this._prefs.QueryInterface(nsIPrefBranch2);
this._prefs.QueryInterface(Ci.nsIPrefBranch);
this._prefs.QueryInterface(Ci.nsIPrefBranch2);
this._prefs.addObserver(this._root, this, false);
this._events = new Events();
@ -225,7 +215,7 @@ PreferenceBranch.prototype = {
},
has : function prefs_has(aName) {
return (this._prefs.getPrefType(aName) != nsIPrefBranch.PREF_INVALID);
return (this._prefs.getPrefType(aName) != Ci.nsIPrefBranch.PREF_INVALID);
},
get : function prefs_get(aName) {
@ -236,13 +226,13 @@ PreferenceBranch.prototype = {
var type = this._prefs.getPrefType(aName);
switch (type) {
case nsIPrefBranch2.PREF_STRING:
aValue = this._prefs.getComplexValue(aName, nsISupportsString).data;
case Ci.nsIPrefBranch2.PREF_STRING:
aValue = this._prefs.getComplexValue(aName, Ci.nsISupportsString).data;
break;
case nsIPrefBranch2.PREF_BOOL:
case Ci.nsIPrefBranch2.PREF_BOOL:
aValue = this._prefs.getBoolPref(aName);
break;
case nsIPrefBranch2.PREF_INT:
case Ci.nsIPrefBranch2.PREF_INT:
aValue = this._prefs.getIntPref(aName);
break;
}
@ -256,9 +246,9 @@ PreferenceBranch.prototype = {
switch (type) {
case "String":
var str = Components.classes["@mozilla.org/supports-string;1"]
.createInstance(nsISupportsString);
.createInstance(Ci.nsISupportsString);
str.data = aValue;
this._prefs.setComplexValue(aName, nsISupportsString, str);
this._prefs.setComplexValue(aName, Ci.nsISupportsString, str);
break;
case "Boolean":
this._prefs.setBoolPref(aName, aValue);
@ -304,13 +294,13 @@ Preference.prototype = {
var type = this._prefs.getPrefType(name);
switch (type) {
case nsIPrefBranch2.PREF_STRING:
case Ci.nsIPrefBranch2.PREF_STRING:
value = "String";
break;
case nsIPrefBranch2.PREF_BOOL:
case Ci.nsIPrefBranch2.PREF_BOOL:
value = "Boolean";
break;
case nsIPrefBranch2.PREF_INT:
case Ci.nsIPrefBranch2.PREF_INT:
value = "Number";
break;
}
@ -381,10 +371,6 @@ SessionStorage.prototype = {
};
//=================================================
// Extension constants
const nsIUpdateItem = Components.interfaces.nsIUpdateItem;
//=================================================
// Extension constructor
function Extension(aItem) {
@ -401,7 +387,7 @@ function Extension(aItem) {
}
var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
.getService(Ci.nsIObserverService);
os.addObserver(this, "em-action-requested", false);
var self = this;
@ -409,12 +395,12 @@ function Extension(aItem) {
}
//=================================================
// Extensions implementation
// Extension implementation
Extension.prototype = {
// cleanup observer so we don't leak
_shutdown: function ext_shutdown() {
var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
.getService(Ci.nsIObserverService);
os.removeObserver(this, "em-action-requested");
this._prefs = null;
@ -426,7 +412,7 @@ Extension.prototype = {
observe: function ext_observe(aSubject, aTopic, aData)
{
if ((aData == "item-uninstalled") &&
(aSubject instanceof nsIUpdateItem) &&
(aSubject instanceof Ci.nsIUpdateItem) &&
(aSubject.id == this._item.id))
{
this._events.dispatch("uninstall", this._item.id);
@ -467,7 +453,7 @@ Extension.prototype = {
// Extensions constructor
function Extensions() {
this._extmgr = Components.classes["@mozilla.org/extensions/manager;1"]
.getService(Components.interfaces.nsIExtensionManager);
.getService(Ci.nsIExtensionManager);
var self = this;
gShutdown.push(function() { self._shutdown(); });
@ -492,7 +478,7 @@ Extensions.prototype = {
// maxVersion: "2.0"
find : function exts_find(aOptions) {
var retVal = [];
var items = this._extmgr.getItemList(nsIUpdateItem.TYPE_EXTENSION, {});
var items = this._extmgr.getItemList(Ci.nsIUpdateItem.TYPE_EXTENSION, {});
for (var i = 0; i < items.length; i++) {
retVal.push(new Extension(items[i]));
@ -513,6 +499,606 @@ Extensions.prototype = {
}
};
//=================================================
// Singleton that holds services and utilities
var Utilities = {
_bookmarks : null,
get bookmarks() {
if (!this._bookmarks) {
this._bookmarks = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
getService(Ci.nsINavBookmarksService);
}
return this._bookmarks;
},
_livemarks : null,
get livemarks() {
if (!this._livemarks) {
this._livemarks = Cc["@mozilla.org/browser/livemark-service;2"].
getService(Ci.nsILivemarkService);
}
return this._livemarks;
},
_annotations : null,
get annotations() {
if (!this._annotations) {
this._annotations = Cc["@mozilla.org/browser/annotation-service;1"].
getService(Ci.nsIAnnotationService);
}
return this._annotations;
},
_history : null,
get history() {
if (!this._history) {
this._history = Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsINavHistoryService);
}
return this._history;
},
_windowMediator : null,
get windowMediator() {
if (!this._windowMediator) {
this._windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
getService(Ci.nsIWindowMediator);
}
return this._windowMediator;
},
makeURI : function(aSpec) {
if (!aSpec)
return null;
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
return ios.newURI(aSpec, null, null);
},
free : function() {
this._bookmarks = null;
this._livemarks = null;
this._annotations = null;
this._history = null;
this._windowMediator = null;
}
};
//=================================================
// Window implementation
function Window(aWindow) {
this._window = aWindow;
this._tabbrowser = aWindow.getBrowser();
this._events = new Events();
this._cleanup = {};
this._watch("TabOpen");
this._watch("TabMove");
this._watch("TabClose");
this._watch("TabSelect");
var self = this;
gShutdown.push(function() { self._shutdown(); });
}
Window.prototype = {
get events() {
return this._events;
},
/*
* Helper used to setup event handlers on the XBL element. Note that the events
* are actually dispatched to tabs, so we capture them.
*/
_watch : function(aType) {
var self = this;
this._tabbrowser.addEventListener(aType,
this._cleanup[aType] = function(e){ self._event(e); },
true);
},
/*
* Helper event callback used to redirect events made on the XBL element
*/
_event : function(aEvent) {
this._events.dispatch(aEvent.type, "");
},
get tabs() {
var tabs = [];
var browsers = this._tabbrowser.browsers;
for (var i=0; i<browsers.length; i++)
tabs.push(new BrowserTab(this._window, browsers[i]));
return tabs;
},
get activeTab() {
return new BrowserTab(this._window, this._tabbrowser.selectedBrowser);
},
open : function(aURI) {
return new BrowserTab(this._window, this._tabbrowser.addTab(aURI.spec).linkedBrowser);
},
_shutdown : function() {
for (var type in this._cleanup)
this._tabbrowser.removeEventListener(type, this._cleanup[type]);
this._cleanup = null;
this._window = null;
this._tabbrowser = null;
this._events = null;
}
};
//=================================================
// BrowserTab implementation
function BrowserTab(aWindow, aBrowser) {
this._window = aWindow;
this._tabbrowser = aWindow.getBrowser();
this._browser = aBrowser;
this._events = new Events();
this._cleanup = {};
this._watch("load");
var self = this;
gShutdown.push(function() { self._shutdown(); });
}
BrowserTab.prototype = {
get uri() {
return this._browser.currentURI;
},
get index() {
var tabs = this._tabbrowser.mTabs;
for (var i=0; i<tabs.length; i++) {
if (tabs[i].linkedBrowser == this._browser)
return i;
}
return -1;
},
get events() {
return this._events;
},
get window() {
return this._window;
},
get document() {
return this._browser.contentDocument;
},
/*
* Helper used to setup event handlers on the XBL element
*/
_watch : function(aType) {
var self = this;
this._browser.addEventListener(aType,
this._cleanup[aType] = function(e){ self._event(e); },
true);
},
/*
* Helper event callback used to redirect events made on the XBL element
*/
_event : function(aEvent) {
if (aEvent.type == "load" && (!aEvent.originalTarget instanceof Ci.nsIDOMHTMLDocument ||
aEvent.originalTarget.defaultView.frameElement))
return;
this._events.dispatch(aEvent.type, "");
},
/*
* Helper used to determine the index offset of the browsertab
*/
_getTab : function() {
var tabs = this._tabbrowser.mTabs;
return tabs[this.index] || null;
},
load : function(aURI) {
this._browser.loadURI(aURI.spec, null, null);
},
focus : function() {
this._tabbrowser.selectedTab = this._getTab();
this._tabbrowser.focus();
},
close : function() {
this._tabbrowser.removeTab(this._getTab());
},
moveBefore : function(aBefore) {
this._tabbrowser.moveTabTo(this._getTab(), aBefore.index);
},
moveToEnd : function() {
this._tabbrowser.moveTabTo(this._getTab(), this._tabbrowser.browsers.length);
},
_shutdown : function() {
for (var type in this._cleanup)
this._browser.removeEventListener(type, this._cleanup[type]);
this._cleanup = null;
this._window = null;
this._tabbrowser = null;
this._browser = null;
this._events = null;
}
};
//=================================================
// Annotations implementation
function Annotations(aId) {
this._id = aId;
}
Annotations.prototype = {
get names() {
return Utilities.annotations.getItemAnnotationNames(this._id, {});
},
has : function(aName) {
return Utilities.annotations.itemHasAnnotation(this._id, aName);
},
get : function(aName) {
var value = null;
var type = Utilities.annotations.getItemAnnotationType(this._id, aName);
switch (type) {
case Ci.nsIAnnotationService.TYPE_INT32:
value = Utilities.annotations.getItemAnnotationInt32(this._id, aName);
break;
case Ci.nsIAnnotationService.TYPE_INT64:
value = Utilities.annotations.getItemAnnotationInt64(this._id, aName);
break;
case Ci.nsIAnnotationService.TYPE_DOUBLE:
value = Utilities.annotations.getItemAnnotationDouble(this._id, aName);
break;
case Ci.nsIAnnotationService.TYPE_STRING:
value = Utilities.annotations.getItemAnnotationString(this._id, aName);
break;
default:
throw("Unknown annotation type specified.");
}
return value;
},
set : function(aName, aValue, aExpiration) {
var type = aValue != null ? aValue.constructor.name : "";
switch (type) {
case "String":
Utilities.annotations.setItemAnnotationString(this._id, aName, aValue, 0, aExpiration);
break;
case "Boolean":
Utilities.annotations.setItemAnnotationInt32(this._id, aName, aValue, 0, aExpiration);
break;
case "Number":
Utilities.annotations.setItemAnnotationDouble(this._id, aName, aValue, 0, aExpiration);
break;
default:
throw("Unknown annotation value specified.");
}
},
remove : function(aName) {
if (aName)
Utilities.annotations.removeItemAnnotation(this._id, aName);
}
};
//=================================================
// Bookmark implementation
function Bookmark(aId, aParent, aType) {
this._id = aId;
this._parent = aParent;
this._type = aType || "bookmark";
this._annotations = new Annotations(this._id);
this._events = new Events();
Utilities.bookmarks.addObserver(this, false);
var self = this;
gShutdown.push(function() { self._shutdown(); });
}
Bookmark.prototype = {
_shutdown : function() {
this._annotations = null;
this._events = null;
Utilities.bookmarks.removeObserver(this);
},
get id() {
return this._id;
},
get title() {
return Utilities.bookmarks.getItemTitle(this._id);
},
set title(aTitle) {
Utilities.bookmarks.setItemTitle(this._id, aTitle);
},
get uri() {
return Utilities.bookmarks.getBookmarkURI(this._id);
},
set uri(aURI) {
return Utilities.bookmarks.changeBookmarkURI(this._id, aURI);
},
get description() {
return this._annotations.get("bookmarkProperties/description");
},
set description(aDesc) {
this._annotations.set("bookmarkProperties/description", aDesc, Ci.nsIAnnotationService.EXPIRE_NEVER);
},
get keyword() {
return Utilities.bookmarks.getKeywordForBookmark(this._id);
},
set keyword(aKeyword) {
Utilities.bookmarks.setKeywordForBookmark(this._id, aKeyword);
},
get type() {
return this._type;
},
get parent() {
return this._parent;
},
set parent(aFolder) {
Utilities.bookmarks.moveItem(this._id, aFolder.id, Utilities.bookmarks.DEFAULT_INDEX);
// this._parent is updated in onItemMoved
},
get annotations() {
return this._annotations;
},
get events() {
return this._events;
},
remove : function() {
Utilities.bookmarks.removeItem(this._id);
},
// observer
onBeginUpdateBatch : function() {
},
onEndUpdateBatch : function() {
},
onItemAdded : function(aId, aFolder, aIndex) {
// bookmark object doesn't exist at this point
},
onItemRemoved : function(aId, aFolder, aIndex) {
if (this._id == aId)
this._events.dispatch("remove", aId);
},
onItemChanged : function(aId, aProperty, aIsAnnotationProperty, aValue) {
if (this._id == aId)
this._events.dispatch("change", aProperty);
},
onItemVisited: function(aId, aVisitID, aTime) {
},
onItemMoved: function(aId, aOldParent, aOldIndex, aNewParent, aNewIndex) {
if (this._id == aId) {
this._parent = new BookmarkFolder(aNewParent, Utilities.bookmarks.getFolderIdForItem(aNewParent));
this._events.dispatch("move", aId);
}
},
QueryInterface: function(aIID) {
if (aIID.equals(Ci.fuelIBookmark) ||
aIID.equals(Ci.nsINavBookmarkObserver) ||
aIID.equals(Ci.nsISupports)) {
return this;
}
throw Component.result.NS_ERROR_NO_INTERFACE;
}
};
//=================================================
// BookmarkFolder implementation
function BookmarkFolder(aId, aParent) {
this._id = aId;
if (this._id == null)
this._id = Utilities.bookmarks.bookmarksRoot;
this._parent = aParent;
this._annotations = new Annotations(this._id);
this._events = new Events();
Utilities.bookmarks.addObserver(this, false);
var self = this;
gShutdown.push(function() { self._shutdown(); });
}
BookmarkFolder.prototype = {
_shutdown : function() {
this._annotations = null;
this._events = null;
Utilities.bookmarks.removeObserver(this);
},
get id() {
return this._id;
},
get title() {
return Utilities.bookmarks.getItemTitle(this._id);
},
set title(aTitle) {
Utilities.bookmarks.setItemTitle(this._id, aTitle);
},
get description() {
return this._annotations.get("bookmarkProperties/description");
},
set description(aDesc) {
this._annotations.set("bookmarkProperties/description", aDesc, Ci.nsIAnnotationService.EXPIRE_NEVER);
},
get type() {
return "folder";
},
get parent() {
return this._parent;
},
set parent(aFolder) {
Utilities.bookmarks.moveItem(this._id, aFolder.id, Utilities.bookmarks.DEFAULT_INDEX);
// this._parent is updated in onItemMoved
},
get annotations() {
return this._annotations;
},
get events() {
return this._events;
},
get children() {
var items = [];
var options = Utilities.history.getNewQueryOptions();
var query = Utilities.history.getNewQuery();
query.setFolders([this._id], 1);
var result = Utilities.history.executeQuery(query, options);
var rootNode = result.root;
rootNode.containerOpen = true;
var cc = rootNode.childCount;
for (var i=0; i<cc; ++i) {
var node = rootNode.getChild(i);
if (node.type == node.RESULT_TYPE_FOLDER) {
var folder = new BookmarkFolder(node.itemId, this._id);
items.push(folder);
}
else if (node.type == node.RESULT_TYPE_SEPARATOR) {
var separator = new Bookmark(node.itemId, this._id, "separator");
items.push(separator);
}
else {
var bookmark = new Bookmark(node.itemId, this._id, "bookmark");
items.push(bookmark);
}
}
rootNode.containerOpen = false;
return items;
},
addBookmark : function(aTitle, aUri) {
var newBookmarkID = Utilities.bookmarks.insertBookmark(this._id, aUri, Utilities.bookmarks.DEFAULT_INDEX, aTitle);
var newBookmark = new Bookmark(newBookmarkID, this, "bookmark");
return newBookmark;
},
addSeparator : function() {
var newBookmarkID = Utilities.bookmarks.insertSeparator(this._id, Utilities.bookmarks.DEFAULT_INDEX);
var newBookmark = new Bookmark(newBookmarkID, this, "separator");
return newBookmark;
},
addFolder : function(aTitle) {
var newFolderID = Utilities.bookmarks.createFolder(this._id, aTitle, Utilities.bookmarks.DEFAULT_INDEX);
var newFolder = new BookmarkFolder(newFolderID, this);
return newFolder;
},
remove : function() {
Utilities.bookmarks.removeFolder(this._id);
},
// observer
onBeginUpdateBatch : function() {
},
onEndUpdateBatch : function() {
},
onItemAdded : function(aId, aFolder, aIndex) {
// handle root folder events
if (!this._parent)
this._events.dispatch("add", aId);
// handle this folder events
if (this._id == aFolder)
this._events.dispatch("addchild", aId);
},
onItemRemoved : function(aId, aFolder, aIndex) {
// handle root folder events
if (!this._parent || this._id == aId)
this._events.dispatch("remove", aId);
// handle this folder events
if (this._id == aFolder)
this._events.dispatch("removechild", aId);
},
onItemChanged : function(aId, aProperty, aIsAnnotationProperty, aValue) {
// handle root folder and this folder events
if (!this._parent || this._id == aId)
this._events.dispatch("change", aProperty);
},
onItemVisited: function(aId, aVisitID, aTime) {
},
onItemMoved: function(aId, aOldParent, aOldIndex, aNewParent, aNewIndex) {
// handle this folder event, root folder cannot be moved
if (this._id == aId) {
this._parent = new BookmarkFolder(aNewParent, Utilities.bookmarks.getFolderIdForItem(aNewParent));
this._events.dispatch("move", aId);
}
},
QueryInterface: function(aIID) {
if (aIID.equals(Ci.fuelIBookmarkFolder) ||
aIID.equals(Ci.nsINavBookmarkObserver) ||
aIID.equals(Ci.nsISupports)) {
return this;
}
throw Component.result.NS_ERROR_NO_INTERFACE;
}
};
const CLASS_ID = Components.ID("fe74cf80-aa2d-11db-abbd-0800200c9a66");
const CLASS_NAME = "Application wrapper";
@ -525,12 +1111,13 @@ function Application() {
this._prefs = null;
this._storage = null;
this._events = null;
this._bookmarks = null;
this._info = Components.classes["@mozilla.org/xre/app-info;1"]
.getService(Components.interfaces.nsIXULAppInfo);
.getService(Ci.nsIXULAppInfo);
var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
.getService(Ci.nsIObserverService);
os.addObserver(this, "final-ui-startup", false);
os.addObserver(this, "quit-application-requested", false);
@ -578,7 +1165,7 @@ Application.prototype = {
// release our observers
var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
.getService(Ci.nsIObserverService);
os.removeObserver(this, "final-ui-startup");
@ -594,6 +1181,9 @@ Application.prototype = {
this._storage = null;
this._events = null;
this._extensions = null;
this._bookmarks = null;
Utilities.free();
}
},
@ -601,11 +1191,11 @@ Application.prototype = {
classDescription : "Application",
classID : CLASS_ID,
contractID : CONTRACT_ID,
flags : nsIClassInfo.SINGLETON,
implementationLanguage : Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
flags : Ci.nsIClassInfo.SINGLETON,
implementationLanguage : Ci.nsIProgrammingLanguage.JAVASCRIPT,
getInterfaces : function app_gi(aCount) {
var interfaces = [fuelIApplication, nsIObserver, nsIClassInfo];
var interfaces = [Ci.fuelIApplication, Ci.nsIObserver, Ci.nsIClassInfo];
aCount.value = interfaces.length;
return interfaces;
},
@ -617,10 +1207,10 @@ Application.prototype = {
// for nsISupports
QueryInterface: function app_qi(aIID) {
// add any other interfaces you support here
if (aIID.equals(fuelIApplication) ||
aIID.equals(nsIObserver) ||
aIID.equals(nsIClassInfo) ||
aIID.equals(nsISupports))
if (aIID.equals(Ci.fuelIApplication) ||
aIID.equals(Ci.nsIObserver) ||
aIID.equals(Ci.nsIClassInfo) ||
aIID.equals(Ci.nsISupports))
{
return this;
}
@ -657,14 +1247,34 @@ Application.prototype = {
this._events = new Events();
return this._events;
},
get bookmarks() {
if (this._bookmarks == null)
this._bookmarks = new BookmarkFolder(null, null);
return this._bookmarks;
},
get windows() {
var win = [];
var enum = Utilities.windowMediator.getEnumerator("navigator:browser");
while (enum.hasMoreElements())
win.push(new Window(enum.getNext()));
return win;
},
get activeWindow() {
return new Window(Utilities.windowMediator.getMostRecentWindow("navigator:browser"));
}
}
};
//=================================================
// Factory - Treat Application as a singleton
var gSingleton = null;
var ApplicationFactory = {
createInstance: function af_ci(aOuter, aIID) {
if (aOuter != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
@ -681,11 +1291,11 @@ var ApplicationFactory = {
// Module
var ApplicationModule = {
registerSelf: function am_rs(aCompMgr, aFileSpec, aLocation, aType) {
aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
aCompMgr = aCompMgr.QueryInterface(Ci.nsIComponentRegistrar);
aCompMgr.registerFactoryLocation(CLASS_ID, CLASS_NAME, CONTRACT_ID, aFileSpec, aLocation, aType);
var categoryManager = Components.classes["@mozilla.org/categorymanager;1"]
.getService(Components.interfaces.nsICategoryManager);
.getService(Ci.nsICategoryManager);
// make Application a startup observer
categoryManager.addCategoryEntry("app-startup", CLASS_NAME, "service," + CONTRACT_ID, true, true);
@ -694,18 +1304,18 @@ var ApplicationModule = {
},
unregisterSelf: function am_us(aCompMgr, aLocation, aType) {
aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
aCompMgr = aCompMgr.QueryInterface(Ci.nsIComponentRegistrar);
aCompMgr.unregisterFactoryLocation(CLASS_ID, aLocation);
// cleanup categories
var categoryManager = Components.classes["@mozilla.org/categorymanager;1"]
.getService(Components.interfaces.nsICategoryManager);
.getService(Ci.nsICategoryManager);
categoryManager.deleteCategoryEntry("app-startup", "service," + CONTRACT_ID, true);
categoryManager.deleteCategoryEntry("JavaScript global property", CONTRACT_ID, true);
},
getClassObject: function am_gco(aCompMgr, aCID, aIID) {
if (!aIID.equals(Components.interfaces.nsIFactory))
if (!aIID.equals(Ci.nsIFactory))
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
if (aCID.equals(CLASS_ID))

View File

@ -44,11 +44,15 @@ relativesrcdir = browser/fuel/test
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_TEST_FILES = test_Application.html \
test_ApplicationPrefs.html \
test_ApplicationStorage.html \
test_Extensions.html \
_CHROME_FILES = test_Application.xul \
test_ApplicationPrefs.xul \
test_ApplicationStorage.xul \
test_Extensions.xul \
test_Bookmarks.xul \
test_Browser.xul \
test_ContentA.html \
test_ContentB.html \
$(NULL)
libs:: $(_TEST_FILES)
$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
libs:: $(_CHROME_FILES)
$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)

View File

@ -0,0 +1,31 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Testing Application"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<body xmlns="http://www.w3.org/1999/xhtml" />
<script type="application/javascript">
<![CDATA[
test_Application();
function test_Application() {
ok(Application, "Check global access to Application");
// I'd test these against a specific value, but that is bound to flucuate
ok(Application.id, "Check to see if an ID exists for the Application");
ok(Application.name, "Check to see if a name exists for the Application");
ok(Application.version, "Check to see if a version exists for the Application");
}
]]>
</script>
</window>

View File

@ -0,0 +1,181 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Testing Application Prefs"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<body xmlns="http://www.w3.org/1999/xhtml" />
<script type="application/javascript">
<![CDATA[
// The various properties that we'll be testing
var test = {
missing: "fuel.fuel-test-missing",
dummy: "fuel.fuel-test",
string: "browser.active_color",
integer: "permissions.default.image",
boolean: "browser.blink_allowed"
};
test_Preferences();
function test_Preferences() {
// test getting non-existing values
var itemValue = Application.prefs.getValue(test.missing, "default");
is(itemValue, "default", "Check 'Application.prefs.getValue' for non-existing item");
is(Application.prefs.get(test.missing), null, "Check 'Application.prefs.get' for non-existing item");
// test setting and getting a value
Application.prefs.setValue(test.dummy, "dummy");
itemValue = Application.prefs.getValue(test.dummy, "default");
is(itemValue, "dummy", "Check 'Application.prefs.getValue' for existing item");
// test for overwriting an existing value
Application.prefs.setValue(test.dummy, "smarty");
itemValue = Application.prefs.getValue(test.dummy, "default");
is(itemValue, "smarty", "Check 'Application.prefs.getValue' for overwritten item");
// test setting and getting a value
Application.prefs.get(test.dummy).value = "dummy2";
itemValue = Application.prefs.get(test.dummy).value;
is(itemValue, "dummy2", "Check 'Application.prefs.get().value' for existing item");
// test resetting a pref [since there is no default value, the pref should disappear]
Application.prefs.get(test.dummy).reset();
var itemValue = Application.prefs.getValue(test.dummy, "default");
is(itemValue, "default", "Check 'Application.prefs.getValue' for reset pref");
// test to see if a non-existant property exists
ok(!Application.prefs.has(test.dummy), "Check non-existant property for existance");
// PREF: string browser.active_color == #EE0000
// test to see if an existing string property exists
ok(Application.prefs.has(test.string), "Check existing string property for existance");
// test accessing a non-existant string property
var val = Application.prefs.getValue(test.dummy, "default");
is(val, "default", "Check non-existant string property for expected value");
// test accessing an existing string property
var val = Application.prefs.getValue(test.string, "default");
is(val, "#EE0000", "Check existing string property for expected value");
// test manipulating an existing string property
Application.prefs.setValue(test.string, "#EF0000");
var val = Application.prefs.getValue(test.string, "default");
is(val, "#EF0000", "Set existing string property");
// test resetting an existing string property
Application.prefs.get(test.string).reset();
var val = Application.prefs.getValue(test.string, "default");
is(val, "#EE0000", "Reset existing string property");
// PREF: integer permissions.default.image == 1
// test to see if an existing integer property exists
ok(Application.prefs.has(test.integer), "Check existing integer property for existance");
// test accessing a non-existant integer property
var val = Application.prefs.getValue(test.dummy, 0);
is(val, 0, "Check non-existant integer property for expected value");
// test accessing an existing integer property
var val = Application.prefs.getValue(test.integer, 0);
is(val, 1, "Check existing integer property for expected value");
// test manipulating an existing integer property
Application.prefs.setValue(test.integer, 0);
var val = Application.prefs.getValue(test.integer, 1);
is(val, 0, "Set existing integer property");
// test resetting an existing integer property
Application.prefs.get(test.integer).reset();
var val = Application.prefs.getValue(test.integer, 0);
is(val, 1, "Reset existing integer property");
// PREF: boolean browser.blink_allowed == true
// test to see if an existing boolean property exists
ok(Application.prefs.has(test.boolean), "Check existing boolean property for existance");
// test accessing a non-existant boolean property
var val = Application.prefs.getValue(test.dummy, true);
ok(val, "Check non-existant boolean property for expected value");
// test accessing an existing boolean property
var val = Application.prefs.getValue(test.boolean, false);
ok(val, "Check existing boolean property for expected value");
// test manipulating an existing boolean property
Application.prefs.setValue(test.boolean, false);
var val = Application.prefs.getValue(test.boolean, true);
ok(!val, "Set existing boolean property");
// test resetting an existing boolean property
Application.prefs.get(test.boolean).reset();
var val = Application.prefs.getValue(test.boolean, false);
ok(val, "Reset existing string property for expected value");
// test getting all preferences
var allPrefs = Application.prefs.all;
ok(allPrefs.length >= 800, "Check 'Application.prefs.all' for the right number of preferences");
is(allPrefs[0].name, "capability.policy.default.Window.parent.get", "Check 'Application.prefs.all' for the right starting preference");
// test the value of the preference root
is(Application.prefs.root, "", "Check the Application preference root");
// test for user changed preferences
ok(Application.prefs.get("browser.shell.checkDefaultBrowser").modified, "A single preference is marked as modified.");
ok(!Application.prefs.get(test.string).modified, "A single preference is marked as not modified.");
// test for a locked preference
var pref = Application.prefs.get(test.string);
ok(!pref.locked, "A single preference should not be locked.");
pref.locked = true;
ok(pref.locked, "A single preference should be locked.");
try {
prev.value = "test value";
ok(false, "A locked preference should not be able to be modified.");
} catch(e){
ok(true, "A locked preference should not be able to be modified.");
}
pref.locked = false;
ok(!pref.locked, "A single preference should not be locked.");
// check for change event when setting a value
SimpleTest.waitForExplicitFinish();
Application.prefs.events.addListener("change", onPrefChange);
Application.prefs.setValue("fuel.fuel-test", "change event");
}
function onPrefChange(evt) {
is(evt.data, test.dummy, "Check 'Application.prefs.set' fired a change event");
Application.prefs.events.removeListener("change", onPrefChange);
Application.prefs.get("fuel.fuel-test").events.addListener("change", onPrefChange2);
Application.prefs.setValue("fuel.fuel-test", "change event2");
}
function onPrefChange2(evt) {
is(evt.data, test.dummy, "Check 'Application.prefs.set' fired a change event for a single preference");
Application.prefs.events.removeListener("change", onPrefChange2);
SimpleTest.finish();
}
]]>
</script>
</window>

View File

@ -0,0 +1,53 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Testing Application Storage"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<body xmlns="http://www.w3.org/1999/xhtml" />
<script type="application/javascript">
<![CDATA[
test_Storage();
function test_Storage() {
// test for existence of values
var hasItem = Application.storage.has("fuel-test-missing");
is(hasItem, false, "Check 'Application.storage.has' for non-existing item");
Application.storage.set("fuel-test", "dummy");
hasItem = Application.storage.has("fuel-test");
is(hasItem, true, "Check 'Application.storage.has' for existing item");
// test getting non-existing and existing values
var itemValue = Application.storage.get("fuel-test-missing", "default");
is(itemValue, "default", "Check 'Application.storage.get' for non-existing item");
itemValue = Application.storage.get("fuel-test", "default");
is(itemValue, "dummy", "Check 'Application.storage.get' for existing item");
// test for overwriting an existing value
Application.storage.set("fuel-test", "smarty");
itemValue = Application.storage.get("fuel-test", "default");
is(itemValue, "smarty", "Check 'Application.storage.get' for overwritten item");
// check for change event when setting a value
SimpleTest.waitForExplicitFinish();
Application.storage.events.addListener("change", onStorageChange);
Application.storage.set("fuel-test", "change event");
}
function onStorageChange(evt) {
is(evt.data, "fuel-test", "Check 'Application.storage.set' fired a change event");
Application.storage.events.removeListener("change", onStorageChange);
SimpleTest.finish();
}
]]>
</script>
</window>

View File

@ -0,0 +1,212 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Testing Bookmarks"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<body xmlns="http://www.w3.org/1999/xhtml" />
<script type="application/javascript">
<![CDATA[
const Ci = Components.interfaces;
const Cc = Components.classes;
var gLastFolderAction = "";
var gLastBookmarkAction = "";
test_Bookmarks();
function url(spec) {
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
return ios.newURI(spec, null, null);
}
function test_Bookmarks() {
var root = Application.bookmarks;
ok(root, "Check access to bookmark root");
ok(!root.parent, "Check root parent (should be null)");
var rootKidCount = root.children.length;
// test adding folders
var testFolder = root.addFolder("FUEL");
ok(testFolder, "Check folder creation");
is(testFolder.type, "folder", "Check 'folder.type' after creation");
ok(testFolder.parent, "Check parent after folder creation");
rootKidCount++;
is(root.children.length, rootKidCount, "Check root folder child count after adding a child folder");
// test modifying a folder
testFolder.events.addListener("change", onFolderChange);
testFolder.description = "FUEL folder";
is(testFolder.description, "FUEL folder", "Check setting 'folder.description'");
is(gLastFolderAction, "bookmarkProperties/description", "Check event handler for setting 'folder.description'");
testFolder.title = "fuel-is-cool";
is(testFolder.title, "fuel-is-cool", "Check setting 'folder.title'");
is(gLastFolderAction, "title", "Check event handler for setting 'folder.title'");
testFolder.annotations.set("testing/folder", "annotate-this", 0);
ok(testFolder.annotations.has("testing/folder"), "Checking existence of added annotation");
is(gLastFolderAction, "testing/folder", "Check event handler for setting annotation");
gLastFolderAction = "";
is(testFolder.annotations.get("testing/folder"), "annotate-this", "Checking existence of added annotation");
testFolder.annotations.remove("testing/folder");
ok(!testFolder.annotations.has("testing/folder"), "Checking existence of removed annotation");
is(gLastFolderAction, "testing/folder", "Check event handler for removing annotation");
testFolder.events.addListener("addchild", onFolderAddChild);
testFolder.events.addListener("removechild", onFolderRemoveChild);
// test adding a bookmark
var testBookmark = testFolder.addBookmark("Mozilla", url("http://www.mozilla.com/"));
ok(testBookmark, "Check bookmark creation");
ok(testBookmark.parent, "Check parent after bookmark creation");
is(gLastFolderAction, "addchild", "Check event handler for adding a child to a folder");
is(testBookmark.type, "bookmark", "Check 'bookmark.type' after creation");
is(testBookmark.title, "Mozilla", "Check 'bookmark.title' after creation");
is(testBookmark.uri.spec, "http://www.mozilla.com/", "Check 'bookmark.uri' after creation");
is(testFolder.children.length, 1, "Check test folder child count after adding a child bookmark");
// test modifying a bookmark
testBookmark.events.addListener("change", onBookmarkChange);
testBookmark.description = "mozcorp";
is(testBookmark.description, "mozcorp", "Check setting 'bookmark.description'");
is(gLastBookmarkAction, "bookmarkProperties/description", "Check event handler for setting 'bookmark.description'");
testBookmark.keyword = "moz"
is(testBookmark.keyword, "moz", "Check setting 'bookmark.keyword'");
is(gLastBookmarkAction, "keyword", "Check event handler for setting 'bookmark.keyword'");
testBookmark.title = "MozCorp"
is(testBookmark.title, "MozCorp", "Check setting 'bookmark.title'");
is(gLastBookmarkAction, "title", "Check event handler for setting 'bookmark.title'");
testBookmark.uri = url("http://www.mozilla.org/");
is(testBookmark.uri.spec, "http://www.mozilla.org/", "Check setting 'bookmark.uri'");
is(gLastBookmarkAction, "uri", "Check event handler for setting 'bookmark.uri'");
// test adding and removing a bookmark annotation
testBookmark.annotations.set("testing/bookmark", "annotate-this", 0);
ok(testBookmark.annotations.has("testing/bookmark"), "Checking existence of added annotation");
is(gLastBookmarkAction, "testing/bookmark", "Check event handler for setting annotation");
gLastBookmarkAction = "";
is(testBookmark.annotations.get("testing/bookmark"), "annotate-this", "Checking existence of added annotation");
testBookmark.annotations.remove("testing/bookmark");
ok(!testBookmark.annotations.has("testing/bookmark"), "Checking existence of removed annotation");
is(gLastBookmarkAction, "testing/bookmark", "Check event handler for removing annotation");
// quick annotation type tests
testBookmark.annotations.set("testing/bookmark/string", "annotate-this", 0);
ok(testBookmark.annotations.has("testing/bookmark/string"), "Checking existence of added string annotation");
is(testBookmark.annotations.get("testing/bookmark/string"), "annotate-this", "Checking value of added string annotation");
is(gLastBookmarkAction, "testing/bookmark/string", "Check event handler for setting annotation");
gLastBookmarkAction = "";
testBookmark.annotations.set("testing/bookmark/int", 100, 0);
ok(testBookmark.annotations.has("testing/bookmark/int"), "Checking existence of added integer annotation");
is(testBookmark.annotations.get("testing/bookmark/int"), 100, "Checking value of added integer annotation");
is(gLastBookmarkAction, "testing/bookmark/int", "Check event handler for setting annotation");
gLastBookmarkAction = "";
testBookmark.annotations.set("testing/bookmark/double", 3.333, 0);
ok(testBookmark.annotations.has("testing/bookmark/double"), "Checking existence of added double annotation");
is(testBookmark.annotations.get("testing/bookmark/double"), 3.333, "Checking value of added double annotation");
is(gLastBookmarkAction, "testing/bookmark/double", "Check event handler for setting annotation");
gLastBookmarkAction = "";
// test names array - NOTE: "bookmarkProperties/description" is an annotation too
var names = testBookmark.annotations.names;
is(names[1], "testing/bookmark/string", "Checking contents of annotation names array");
is(names.length, 4, "Checking the annotation names array after adding 3 annotations");
// test adding a separator
var testSeparator = testFolder.addSeparator();
ok(testSeparator, "Check bookmark creation");
ok(testSeparator.parent, "Check parent after separator creation");
is(gLastFolderAction, "addchild", "Check event handler for adding a child separator to a folder");
is(testSeparator.type, "separator", "Check 'bookmark.type' after separator creation");
is(testFolder.children.length, 2, "Check test folder child count after adding a child separator");
// test removing separator
testSeparator.events.addListener("remove", onBookmarkRemove);
testSeparator.remove();
is(gLastBookmarkAction, "remove", "Check event handler for removing separator");
is(gLastFolderAction, "removechild", "Check event handler for removing a child separator from a folder");
is(testFolder.children.length, 1, "Check test folder child count after removing a child separator");
// test removing bookmark
testBookmark.events.addListener("remove", onBookmarkRemove);
testBookmark.remove();
is(gLastBookmarkAction, "remove", "Check event handler for removing bookmark");
is(gLastFolderAction, "removechild", "Check event handler for removing a child from a folder");
is(testFolder.children.length, 0, "Check test folder child count after removing a child bookmark");
// test removing a folder
testFolder.events.addListener("remove", onFolderRemove);
testFolder.remove();
is(gLastFolderAction, "remove", "Check event handler for removing child folder");
rootKidCount--;
is(root.children.length, rootKidCount, "Check root folder child count after removing a child folder");
// test moving between folders
var testFolderA = root.addFolder("folder-a");
var testFolderB = root.addFolder("folder-b");
var testMove = testFolderA.addBookmark("Mozilla", url("http://www.mozilla.com/"));
testMove.events.addListener("move", onBookmarkMove);
is(testMove.parent.title, "folder-a", "Checking for new parent before moving bookmark");
testMove.parent = testFolderB;
is(testMove.parent.title, "folder-b", "Checking for new parent after moving bookmark");
is(gLastBookmarkAction, "move", "Checking for event handler after moving bookmark");
// test moving a folder
testFolderA.events.addListener("move", onFolderMove);
testFolderA.parent = testFolderB;
is(testFolderA.parent.title, "folder-b", "Checking for new parent after moving folder");
is(gLastFolderAction, "move", "Checking for event handler after moving folder");
}
function onFolderChange(evt) {
gLastFolderAction = evt.data;
}
function onFolderRemove(evt) {
gLastFolderAction = evt.type;
}
function onFolderAddChild(evt) {
gLastFolderAction = evt.type;
}
function onFolderRemoveChild(evt) {
gLastFolderAction = evt.type;
}
function onFolderMove(evt) {
gLastFolderAction = evt.type;
}
function onBookmarkChange(evt) {
gLastBookmarkAction = evt.data;
}
function onBookmarkRemove(evt) {
gLastBookmarkAction = evt.type;
}
function onBookmarkMove(evt) {
gLastBookmarkAction = evt.type;
}
]]>
</script>
</window>

View File

@ -0,0 +1,110 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Testing Browser"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<body xmlns="http://www.w3.org/1999/xhtml" />
<script type="application/javascript">
<![CDATA[
const Ci = Components.interfaces;
const Cc = Components.classes;
test_Browser();
function url(spec) {
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
return ios.newURI(spec, null, null);
}
var gTabOpenCount = 0;
var gTabCloseCount = 0;
var gTabMoveCount = 0;
function test_Browser() {
var windows = Application.windows;
ok(windows, "Check access to browser windows");
ok(windows.length, "There should be at least one browser window open");
var activeWin = Application.activeWindow;
activeWin.events.addListener("TabOpen", onTabOpen);
activeWin.events.addListener("TabClose", onTabClose);
activeWin.events.addListener("TabMove", onTabMove);
var pageA = activeWin.open(url("chrome://mochikit/content/chrome/browser/fuel/test/test_ContentA.html"));
var pageB = activeWin.open(url("chrome://mochikit/content/chrome/browser/fuel/test/test_ContentB.html"));
pageB.focus();
is(activeWin.tabs.length, 3, "Checking length of 'Browser.tabs' after opening 2 additional tabs");
is(activeWin.activeTab.index, pageB.index, "Checking 'Browser.activeTab' after setting focus");
SimpleTest.waitForExplicitFinish();
setTimeout(afterOpen, 1000);
// need to wait for the url's to be refreshed during the load
function afterOpen() {
is(pageA.uri.spec, "chrome://mochikit/content/chrome/browser/fuel/test/test_ContentA.html", "Checking 'BrowserTab.uri' after opening");
is(pageB.uri.spec, "chrome://mochikit/content/chrome/browser/fuel/test/test_ContentB.html", "Checking 'BrowserTab.uri' after opening");
// check event
todo_is(gTabOpenCount, 2, "Checking event handler for tab open");
// test document access
var test1 = pageA.document.getElementById("test1");
ok(test1, "Checking existence of element in content DOM");
is(test1.innerHTML, "A", "Checking content of element in content DOM");
// test moving tab
pageA.moveToEnd();
is(pageA.index, 2, "Checking index after moving tab");
// check event
is(gTabMoveCount, 1, "Checking event handler for tab move");
// test loading new content into a tab
// the event will be checked in afterClose
pageA.events.addListener("load", onPageLoad);
pageA.load(pageB.uri);
}
function onPageLoad(event) {
is(pageA.uri.spec, "chrome://mochikit/content/chrome/browser/fuel/test/test_ContentB.html", "Checking 'BrowserTab.uri' after loading new content");
// start testing closing tabs
pageA.close();
pageB.close();
setTimeout(afterClose, 1000);
}
function afterClose() {
// check event
is(gTabCloseCount, 2, "Checking event handler for tab close");
is(activeWin.tabs.length, 1, "Checking length of 'Browser.tabs' after closing 2 tabs");
SimpleTest.finish();
}
}
function onTabOpen(event) {
gTabOpenCount++;
}
function onTabClose(event) {
gTabCloseCount++;
}
function onTabMove(event) {
gTabMoveCount++;
}
]]>
</script>
</window>

View File

@ -0,0 +1,12 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Content Page A</title>
</head>
<body>
<h1>Content Page A</h1>
<div id="desc">This is a simple content page used for testing FUEL Browser API</div>
<div id="test1">A</div>
<div id="test2">B</div>
</body>
</html>

View File

@ -0,0 +1,12 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Content Page B</title>
</head>
<body>
<h1>Content Page B</h1>
<div id="desc">This is a simple content page used for testing FUEL Browser API</div>
<div id="test1">1</div>
<div id="test2">2</div>
</body>
</html>

View File

@ -0,0 +1,54 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Testing Extensions"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<body xmlns="http://www.w3.org/1999/xhtml" />
<script type="application/javascript">
<![CDATA[
// The various pieces that we'll be testing
var test = {
dummyid: "fuel-dummy-extension@mozilla.org",
dummyname: "Dummy Extension",
inspectorid: "inspector@mozilla.org",
inspectorname: "DOM Inspector"
};
test_Extensions();
function test_Extensions() {
// test to see if a non-existant extension exists
ok(!Application.extensions.has(test.dummyid), "Check non-existant extension for existance");
// test to see if an extension exists
ok(Application.extensions.has(test.inspectorid), "Check extension for existance");
var inspector = Application.extensions.get(test.inspectorid);
is(inspector.id, test.inspectorid, "Check 'Extension.id' for known extension");
is(inspector.name, test.inspectorname, "Check 'Extension.name' for known extension");
// The known version number changes too frequently to hardcode in
ok(inspector.version, "Check 'Extension.version' for known extension");
ok(inspector.firstRun, "Check 'Extension.firstRun' for known extension");
// test to see if extension find works
is(Application.extensions.all.length, 1, "Check a find for all extensions");
// test the value of the preference root
is(Application.extensions.all[0].prefs.root, "extensions.inspector@mozilla.org.", "Check an extension preference root");
// Reset the install event preference, so that we can test it again later
inspector.prefs.get("install-event-fired").reset();
}
]]>
</script>
</window>