5 changed files with 0 additions and 1186 deletions
@ -1,822 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public |
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this |
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const Ci = Components.interfaces; |
||||
const Cc = Components.classes; |
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); |
||||
XPCOMUtils.defineLazyModuleGetter(this, "Deprecated", |
||||
"resource://gre/modules/Deprecated.jsm"); |
||||
|
||||
const APPLICATION_CID = Components.ID("fe74cf80-aa2d-11db-abbd-0800200c9a66"); |
||||
const APPLICATION_CONTRACTID = "@mozilla.org/fuel/application;1"; |
||||
|
||||
//=================================================
|
||||
// Singleton that holds services and utilities
|
||||
var Utilities = { |
||||
get bookmarks() { |
||||
let bookmarks = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]. |
||||
getService(Ci.nsINavBookmarksService); |
||||
this.__defineGetter__("bookmarks", function() bookmarks); |
||||
return this.bookmarks; |
||||
}, |
||||
|
||||
get bookmarksObserver() { |
||||
let bookmarksObserver = new BookmarksObserver(); |
||||
this.__defineGetter__("bookmarksObserver", function() bookmarksObserver); |
||||
return this.bookmarksObserver; |
||||
}, |
||||
|
||||
get annotations() { |
||||
let annotations = Cc["@mozilla.org/browser/annotation-service;1"]. |
||||
getService(Ci.nsIAnnotationService); |
||||
this.__defineGetter__("annotations", function() annotations); |
||||
return this.annotations; |
||||
}, |
||||
|
||||
get history() { |
||||
let history = Cc["@mozilla.org/browser/nav-history-service;1"]. |
||||
getService(Ci.nsINavHistoryService); |
||||
this.__defineGetter__("history", function() history); |
||||
return this.history; |
||||
}, |
||||
|
||||
get windowMediator() { |
||||
let windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"]. |
||||
getService(Ci.nsIWindowMediator); |
||||
this.__defineGetter__("windowMediator", function() windowMediator); |
||||
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() { |
||||
delete this.bookmarks; |
||||
delete this.bookmarksObserver; |
||||
delete this.annotations; |
||||
delete this.history; |
||||
delete this.windowMediator; |
||||
} |
||||
}; |
||||
|
||||
|
||||
//=================================================
|
||||
// Window implementation
|
||||
|
||||
var fuelWindowMap = new WeakMap(); |
||||
function getWindow(aWindow) { |
||||
let fuelWindow = fuelWindowMap.get(aWindow); |
||||
if (!fuelWindow) { |
||||
fuelWindow = new Window(aWindow); |
||||
fuelWindowMap.set(aWindow, fuelWindow); |
||||
} |
||||
return fuelWindow; |
||||
} |
||||
|
||||
// Don't call new Window() directly; use getWindow instead.
|
||||
function Window(aWindow) { |
||||
this._window = aWindow; |
||||
this._events = new Events(); |
||||
|
||||
this._watch("TabOpen"); |
||||
this._watch("TabMove"); |
||||
this._watch("TabClose"); |
||||
this._watch("TabSelect"); |
||||
} |
||||
|
||||
Window.prototype = { |
||||
get events() { |
||||
return this._events; |
||||
}, |
||||
|
||||
get _tabbrowser() { |
||||
return this._window.getBrowser(); |
||||
}, |
||||
|
||||
/* |
||||
* 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) { |
||||
this._tabbrowser.tabContainer.addEventListener(aType, this, |
||||
/* useCapture = */ true); |
||||
}, |
||||
|
||||
handleEvent: function(aEvent) { |
||||
this._events.dispatch(aEvent.type, getBrowserTab(this, aEvent.originalTarget.linkedBrowser)); |
||||
}, |
||||
|
||||
get tabs() { |
||||
var tabs = []; |
||||
var browsers = this._tabbrowser.browsers; |
||||
for (var i=0; i<browsers.length; i++) |
||||
tabs.push(getBrowserTab(this, browsers[i])); |
||||
return tabs; |
||||
}, |
||||
|
||||
get activeTab() { |
||||
return getBrowserTab(this, this._tabbrowser.selectedBrowser); |
||||
}, |
||||
|
||||
open: function(aURI) { |
||||
return getBrowserTab(this, this._tabbrowser.addTab(aURI.spec).linkedBrowser); |
||||
}, |
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.fuelIWindow]) |
||||
}; |
||||
|
||||
//=================================================
|
||||
// BrowserTab implementation
|
||||
|
||||
var fuelBrowserTabMap = new WeakMap(); |
||||
function getBrowserTab(aFUELWindow, aBrowser) { |
||||
let fuelBrowserTab = fuelBrowserTabMap.get(aBrowser); |
||||
if (!fuelBrowserTab) { |
||||
fuelBrowserTab = new BrowserTab(aFUELWindow, aBrowser); |
||||
fuelBrowserTabMap.set(aBrowser, fuelBrowserTab); |
||||
} |
||||
else { |
||||
// This tab may have moved to another window, so make sure its cached
|
||||
// window is up-to-date.
|
||||
fuelBrowserTab._window = aFUELWindow; |
||||
} |
||||
|
||||
return fuelBrowserTab; |
||||
} |
||||
|
||||
// Don't call new BrowserTab() directly; call getBrowserTab instead.
|
||||
function BrowserTab(aFUELWindow, aBrowser) { |
||||
this._window = aFUELWindow; |
||||
this._browser = aBrowser; |
||||
this._events = new Events(); |
||||
|
||||
this._watch("load"); |
||||
} |
||||
|
||||
BrowserTab.prototype = { |
||||
get _tabbrowser() { |
||||
return this._window._tabbrowser; |
||||
}, |
||||
|
||||
get uri() { |
||||
return this._browser.currentURI; |
||||
}, |
||||
|
||||
get index() { |
||||
var tabs = this._tabbrowser.tabs; |
||||
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) { |
||||
this._browser.addEventListener(aType, this, |
||||
/* useCapture = */ true); |
||||
}, |
||||
|
||||
handleEvent: function(aEvent) { |
||||
if (aEvent.type == "load") { |
||||
if (!(aEvent.originalTarget instanceof Ci.nsIDOMDocument)) |
||||
return; |
||||
|
||||
if (aEvent.originalTarget.defaultView instanceof Ci.nsIDOMWindow && |
||||
aEvent.originalTarget.defaultView.frameElement) |
||||
return; |
||||
} |
||||
this._events.dispatch(aEvent.type, this); |
||||
}, |
||||
/* |
||||
* Helper used to determine the index offset of the browsertab |
||||
*/ |
||||
_getTab: function() { |
||||
var tabs = this._tabbrowser.tabs; |
||||
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); |
||||
}, |
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.fuelIBrowserTab]) |
||||
}; |
||||
|
||||
|
||||
//=================================================
|
||||
// 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) { |
||||
if (this.has(aName)) |
||||
return Utilities.annotations.getItemAnnotation(this._id, aName); |
||||
return null; |
||||
}, |
||||
|
||||
set: function(aName, aValue, aExpiration) { |
||||
Utilities.annotations.setItemAnnotation(this._id, aName, aValue, 0, aExpiration); |
||||
}, |
||||
|
||||
remove: function(aName) { |
||||
if (aName) |
||||
Utilities.annotations.removeItemAnnotation(this._id, aName); |
||||
}, |
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.fuelIAnnotations]) |
||||
}; |
||||
|
||||
|
||||
//=================================================
|
||||
// BookmarksObserver implementation (internal class)
|
||||
//
|
||||
// BookmarksObserver is a global singleton which watches the browser's
|
||||
// bookmarks and sends you events when things change.
|
||||
//
|
||||
// You can register three different kinds of event listeners on
|
||||
// BookmarksObserver, using addListener, addFolderListener, and
|
||||
// addRootlistener.
|
||||
//
|
||||
// - addListener(aId, aEvent, aListener) lets you listen to a specific
|
||||
// bookmark. You can listen to the "change", "move", and "remove" events.
|
||||
//
|
||||
// - addFolderListener(aId, aEvent, aListener) lets you listen to a specific
|
||||
// bookmark folder. You can listen to "addchild" and "removechild".
|
||||
//
|
||||
// - addRootListener(aEvent, aListener) lets you listen to the root bookmark
|
||||
// node. This lets you hear "add", "remove", and "change" events on all
|
||||
// bookmarks.
|
||||
//
|
||||
|
||||
function BookmarksObserver() { |
||||
this._eventsDict = {}; |
||||
this._folderEventsDict = {}; |
||||
this._rootEvents = new Events(); |
||||
Utilities.bookmarks.addObserver(this, /* ownsWeak = */ true); |
||||
} |
||||
|
||||
BookmarksObserver.prototype = { |
||||
onBeginUpdateBatch: function() {}, |
||||
onEndUpdateBatch: function() {}, |
||||
onItemVisited: function() {}, |
||||
|
||||
onItemAdded: function(aId, aFolder, aIndex, aItemType, aURI) { |
||||
this._rootEvents.dispatch("add", aId); |
||||
this._dispatchToEvents("addchild", aId, this._folderEventsDict[aFolder]); |
||||
}, |
||||
|
||||
onItemRemoved: function(aId, aFolder, aIndex) { |
||||
this._rootEvents.dispatch("remove", aId); |
||||
this._dispatchToEvents("remove", aId, this._eventsDict[aId]); |
||||
this._dispatchToEvents("removechild", aId, this._folderEventsDict[aFolder]); |
||||
}, |
||||
|
||||
onItemChanged: function(aId, aProperty, aIsAnnotationProperty, aValue) { |
||||
this._rootEvents.dispatch("change", aProperty); |
||||
this._dispatchToEvents("change", aProperty, this._eventsDict[aId]); |
||||
}, |
||||
|
||||
onItemMoved: function(aId, aOldParent, aOldIndex, aNewParent, aNewIndex) { |
||||
this._dispatchToEvents("move", aId, this._eventsDict[aId]); |
||||
}, |
||||
|
||||
_dispatchToEvents: function(aEvent, aData, aEvents) { |
||||
if (aEvents) { |
||||
aEvents.dispatch(aEvent, aData); |
||||
} |
||||
}, |
||||
|
||||
_addListenerToDict: function(aId, aEvent, aListener, aDict) { |
||||
var events = aDict[aId]; |
||||
if (!events) { |
||||
events = new Events(); |
||||
aDict[aId] = events; |
||||
} |
||||
events.addListener(aEvent, aListener); |
||||
}, |
||||
|
||||
_removeListenerFromDict: function(aId, aEvent, aListener, aDict) { |
||||
var events = aDict[aId]; |
||||
if (!events) { |
||||
return; |
||||
} |
||||
events.removeListener(aEvent, aListener); |
||||
if (events._listeners.length == 0) { |
||||
delete aDict[aId]; |
||||
} |
||||
}, |
||||
|
||||
addListener: function(aId, aEvent, aListener) { |
||||
this._addListenerToDict(aId, aEvent, aListener, this._eventsDict); |
||||
}, |
||||
|
||||
removeListener: function(aId, aEvent, aListener) { |
||||
this._removeListenerFromDict(aId, aEvent, aListener, this._eventsDict); |
||||
}, |
||||
|
||||
addFolderListener: function(aId, aEvent, aListener) { |
||||
this._addListenerToDict(aId, aEvent, aListener, this._folderEventsDict); |
||||
}, |
||||
|
||||
removeFolderListener: function(aId, aEvent, aListener) { |
||||
this._removeListenerFromDict(aId, aEvent, aListener, this._folderEventsDict); |
||||
}, |
||||
|
||||
addRootListener: function(aEvent, aListener) { |
||||
this._rootEvents.addListener(aEvent, aListener); |
||||
}, |
||||
|
||||
removeRootListener: function(aEvent, aListener) { |
||||
this._rootEvents.removeListener(aEvent, aListener); |
||||
}, |
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsINavBookmarksObserver, |
||||
Ci.nsISupportsWeakReference]) |
||||
}; |
||||
|
||||
//=================================================
|
||||
// Bookmark implementation
|
||||
//
|
||||
// Bookmark event listeners are stored in BookmarksObserver, not in the
|
||||
// Bookmark objects themselves. Thus, you don't have to hold on to a Bookmark
|
||||
// object in order for your event listener to stay valid, and Bookmark objects
|
||||
// not kept alive by the extension can be GC'ed.
|
||||
//
|
||||
// A consequence of this is that if you have two different Bookmark objects x
|
||||
// and y for the same bookmark (i.e., x != y but x.id == y.id), and you do
|
||||
//
|
||||
// x.addListener("foo", fun);
|
||||
// y.removeListener("foo", fun);
|
||||
//
|
||||
// the second line will in fact remove the listener added in the first line.
|
||||
//
|
||||
|
||||
function Bookmark(aId, aParent, aType) { |
||||
this._id = aId; |
||||
this._parent = aParent; |
||||
this._type = aType || "bookmark"; |
||||
this._annotations = new Annotations(this._id); |
||||
|
||||
// Our _events object forwards to bookmarksObserver.
|
||||
var self = this; |
||||
this._events = { |
||||
addListener: function(aEvent, aListener) { |
||||
Utilities.bookmarksObserver.addListener(self._id, aEvent, aListener); |
||||
}, |
||||
removeListener: function(aEvent, aListener) { |
||||
Utilities.bookmarksObserver.removeListener(self._id, aEvent, aListener); |
||||
}, |
||||
QueryInterface: XPCOMUtils.generateQI([Ci.extIEvents]) |
||||
}; |
||||
|
||||
// For our onItemMoved listener, which updates this._parent.
|
||||
Utilities.bookmarks.addObserver(this, /* ownsWeak = */ true); |
||||
} |
||||
|
||||
Bookmark.prototype = { |
||||
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); |
||||
}, |
||||
|
||||
onBeginUpdateBatch: function() {}, |
||||
onEndUpdateBatch: function() {}, |
||||
onItemAdded: function() {}, |
||||
onItemVisited: function() {}, |
||||
onItemRemoved: function() {}, |
||||
onItemChanged: function() {}, |
||||
|
||||
onItemMoved: function(aId, aOldParent, aOldIndex, aNewParent, aNewIndex) { |
||||
if (aId == this._id) { |
||||
this._parent = new BookmarkFolder(aNewParent, Utilities.bookmarks.getFolderIdForItem(aNewParent)); |
||||
} |
||||
}, |
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.fuelIBookmark, |
||||
Ci.nsINavBookmarksObserver, |
||||
Ci.nsISupportsWeakReference]) |
||||
}; |
||||
|
||||
|
||||
//=================================================
|
||||
// BookmarkFolder implementation
|
||||
//
|
||||
// As with Bookmark, events on BookmarkFolder are handled by the
|
||||
// BookmarksObserver singleton.
|
||||
//
|
||||
|
||||
function BookmarkFolder(aId, aParent) { |
||||
this._id = aId; |
||||
this._parent = aParent; |
||||
this._annotations = new Annotations(this._id); |
||||
|
||||
// Our event listeners are handled by the BookmarksObserver singleton. This
|
||||
// is a bit complicated because there are three different kinds of events we
|
||||
// might want to listen to here:
|
||||
//
|
||||
// - If this._parent is null, we're the root bookmark folder, and all our
|
||||
// listeners should be root listeners.
|
||||
//
|
||||
// - Otherwise, events ending with "child" (addchild, removechild) are
|
||||
// handled by a folder listener.
|
||||
//
|
||||
// - Other events are handled by a vanilla bookmark listener.
|
||||
|
||||
var self = this; |
||||
this._events = { |
||||
addListener: function(aEvent, aListener) { |
||||
if (self._parent) { |
||||
if (/child$/.test(aEvent)) { |
||||
Utilities.bookmarksObserver.addFolderListener(self._id, aEvent, aListener); |
||||
} |
||||
else { |
||||
Utilities.bookmarksObserver.addListener(self._id, aEvent, aListener); |
||||
} |
||||
} |
||||
else { |
||||
Utilities.bookmarksObserver.addRootListener(aEvent, aListener); |
||||
} |
||||
}, |
||||
removeListener: function(aEvent, aListener) { |
||||
if (self._parent) { |
||||
if (/child$/.test(aEvent)) { |
||||
Utilities.bookmarksObserver.removeFolderListener(self._id, aEvent, aListener); |
||||
} |
||||
else { |
||||
Utilities.bookmarksObserver.removeListener(self._id, aEvent, aListener); |
||||
} |
||||
} |
||||
else { |
||||
Utilities.bookmarksObserver.removeRootListener(aEvent, aListener); |
||||
} |
||||
}, |
||||
QueryInterface: XPCOMUtils.generateQI([Ci.extIEvents]) |
||||
}; |
||||
|
||||
// For our onItemMoved listener, which updates this._parent.
|
||||
Utilities.bookmarks.addObserver(this, /* ownsWeak = */ true); |
||||
} |
||||
|
||||
BookmarkFolder.prototype = { |
||||
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.removeItem(this._id); |
||||
}, |
||||
|
||||
// observer
|
||||
onBeginUpdateBatch: function() {}, |
||||
onEndUpdateBatch : function() {}, |
||||
onItemAdded : function() {}, |
||||
onItemRemoved : function() {}, |
||||
onItemChanged : function() {}, |
||||
|
||||
onItemMoved: function(aId, aOldParent, aOldIndex, aNewParent, aNewIndex) { |
||||
if (this._id == aId) { |
||||
this._parent = new BookmarkFolder(aNewParent, Utilities.bookmarks.getFolderIdForItem(aNewParent)); |
||||
} |
||||
}, |
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.fuelIBookmarkFolder, |
||||
Ci.nsINavBookmarksObserver, |
||||
Ci.nsISupportsWeakReference]) |
||||
}; |
||||
|
||||
//=================================================
|
||||
// BookmarkRoots implementation
|
||||
function BookmarkRoots() { |
||||
} |
||||
|
||||
BookmarkRoots.prototype = { |
||||
get menu() { |
||||
if (!this._menu) |
||||
this._menu = new BookmarkFolder(Utilities.bookmarks.bookmarksMenuFolder, null); |
||||
|
||||
return this._menu; |
||||
}, |
||||
|
||||
get toolbar() { |
||||
if (!this._toolbar) |
||||
this._toolbar = new BookmarkFolder(Utilities.bookmarks.toolbarFolder, null); |
||||
|
||||
return this._toolbar; |
||||
}, |
||||
|
||||
get tags() { |
||||
if (!this._tags) |
||||
this._tags = new BookmarkFolder(Utilities.bookmarks.tagsFolder, null); |
||||
|
||||
return this._tags; |
||||
}, |
||||
|
||||
get unfiled() { |
||||
if (!this._unfiled) |
||||
this._unfiled = new BookmarkFolder(Utilities.bookmarks.unfiledBookmarksFolder, null); |
||||
|
||||
return this._unfiled; |
||||
}, |
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.fuelIBookmarkRoots]) |
||||
}; |
||||
|
||||
|
||||
//=================================================
|
||||
// Factory - Treat Application as a singleton
|
||||
// XXX This is required, because we're registered for the 'JavaScript global
|
||||
// privileged property' category, whose handler always calls createInstance.
|
||||
// See bug 386535.
|
||||
var gSingleton = null; |
||||
var ApplicationFactory = { |
||||
createInstance: function(aOuter, aIID) { |
||||
if (aOuter != null) |
||||
throw Components.results.NS_ERROR_NO_AGGREGATION; |
||||
|
||||
if (gSingleton == null) { |
||||
gSingleton = new Application(); |
||||
} |
||||
|
||||
return gSingleton.QueryInterface(aIID); |
||||
} |
||||
}; |
||||
|
||||
|
||||
#include ../../../platform/toolkit/components/exthelper/extApplication.js |
||||
|
||||
//=================================================
|
||||
// Application constructor
|
||||
function Application() { |
||||
Deprecated.warning("FUEL is deprecated, you should use the standard Toolkit API instead.", |
||||
"https://github.com/MoonchildProductions/UXP/issues/1083"); |
||||
this.initToolkitHelpers(); |
||||
} |
||||
|
||||
//=================================================
|
||||
// Application implementation
|
||||
function ApplicationPrototype() { |
||||
// for nsIClassInfo + XPCOMUtils
|
||||
this.classID = APPLICATION_CID; |
||||
|
||||
// redefine the default factory for XPCOMUtils
|
||||
this._xpcom_factory = ApplicationFactory; |
||||
|
||||
// for nsISupports
|
||||
this.QueryInterface = XPCOMUtils.generateQI([ |
||||
Ci.fuelIApplication, |
||||
Ci.extIApplication, |
||||
Ci.nsIObserver, |
||||
Ci.nsISupportsWeakReference |
||||
]); |
||||
|
||||
// for nsIClassInfo
|
||||
this.classInfo = XPCOMUtils.generateCI({ |
||||
classID: APPLICATION_CID, |
||||
contractID: APPLICATION_CONTRACTID, |
||||
interfaces: [ |
||||
Ci.fuelIApplication, |
||||
Ci.extIApplication, |
||||
Ci.nsIObserver |
||||
], |
||||
flags: Ci.nsIClassInfo.SINGLETON |
||||
}); |
||||
|
||||
// for nsIObserver
|
||||
this.observe = function(aSubject, aTopic, aData) { |
||||
// Call the extApplication version of this function first
|
||||
var superPrototype = Object.getPrototypeOf(Object.getPrototypeOf(this)); |
||||
superPrototype.observe.call(this, aSubject, aTopic, aData); |
||||
if (aTopic == "xpcom-shutdown") { |
||||
this._obs.removeObserver(this, "xpcom-shutdown"); |
||||
Utilities.free(); |
||||
} |
||||
}; |
||||
|
||||
Object.defineProperty(this, "bookmarks", { |
||||
get: function bookmarks () { |
||||
let bookmarks = new BookmarkRoots(); |
||||
Object.defineProperty(this, "bookmarks", { value: bookmarks }); |
||||
return this.bookmarks; |
||||
}, |
||||
enumerable: true, |
||||
configurable: true |
||||
}); |
||||
|
||||
Object.defineProperty(this, "windows", { |
||||
get: function windows() { |
||||
var win = []; |
||||
var browserEnum = Utilities.windowMediator.getEnumerator("navigator:browser"); |
||||
|
||||
while (browserEnum.hasMoreElements()) |
||||
win.push(getWindow(browserEnum.getNext())); |
||||
|
||||
return win; |
||||
}, |
||||
enumerable: true, |
||||
configurable: true |
||||
}); |
||||
|
||||
Object.defineProperty(this, "activeWindow", { |
||||
get: () => getWindow(Utilities.windowMediator.getMostRecentWindow("navigator:browser")), |
||||
enumerable: true, |
||||
configurable: true |
||||
}); |
||||
|
||||
}; |
||||
|
||||
// set the proto, defined in extApplication.js
|
||||
ApplicationPrototype.prototype = extApplication.prototype; |
||||
|
||||
Application.prototype = new ApplicationPrototype(); |
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([Application]); |
||||
|
@ -1,3 +0,0 @@
|
||||
component {fe74cf80-aa2d-11db-abbd-0800200c9a66} fuelApplication.js |
||||
contract @mozilla.org/fuel/application;1 {fe74cf80-aa2d-11db-abbd-0800200c9a66} |
||||
category JavaScript-global-privileged-property Application @mozilla.org/fuel/application;1 |
@ -1,347 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public |
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this |
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
||||
|
||||
#include "nsISupports.idl" |
||||
#include "extIApplication.idl" |
||||
|
||||
interface nsIVariant; |
||||
interface nsIURI; |
||||
interface nsIDOMHTMLDocument; |
||||
|
||||
interface fuelIBookmarkFolder; |
||||
interface fuelIBrowserTab; |
||||
|
||||
/** |
||||
* 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 int32_t 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 extIEvents 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 extIEvents 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 container for bookmark roots. Roots |
||||
* are the top level parents for the various types of bookmarks in the system. |
||||
*/ |
||||
[scriptable, uuid(c9a80870-eb3c-11dc-95ff-0800200c9a66)] |
||||
interface fuelIBookmarkRoots : nsISupports |
||||
{ |
||||
/** |
||||
* The folder for the 'bookmarks menu' root. |
||||
*/ |
||||
readonly attribute fuelIBookmarkFolder menu; |
||||
|
||||
/** |
||||
* The folder for the 'personal toolbar' root. |
||||
*/ |
||||
readonly attribute fuelIBookmarkFolder toolbar; |
||||
|
||||
/** |
||||
* The folder for the 'tags' root. |
||||
*/ |
||||
readonly attribute fuelIBookmarkFolder tags; |
||||
|
||||
/** |
||||
* The folder for the 'unfiled bookmarks' root. |
||||
*/ |
||||
readonly attribute fuelIBookmarkFolder unfiled; |
||||
}; |
||||
|
||||
/** |
||||
* 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 extIEvents 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 int32_t 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 extIEvents 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 |
||||
*/ |
||||
[scriptable, uuid(fe74cf80-aa2d-11db-abbd-0800200c9a66)] |
||||
interface fuelIApplication : extIApplication |
||||
{ |
||||
/** |
||||
* The root bookmarks object for the application. |
||||
* Contains all the bookmark roots in the system. |
||||
*/ |
||||
readonly attribute fuelIBookmarkRoots bookmarks; |
||||
|
||||
/** |
||||
* An array of browser windows within the application. |
||||
*/ |
||||
readonly attribute nsIVariant windows; |
||||
|
||||
/** |
||||
* The currently active browser window. |
||||
*/ |
||||
readonly attribute fuelIWindow activeWindow; |
||||
}; |
@ -1,13 +0,0 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- |
||||
# This Source Code Form is subject to the terms of the Mozilla Public |
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this |
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/. |
||||
|
||||
XPIDL_SOURCES += ['fuelIApplication.idl'] |
||||
|
||||
XPIDL_MODULE = 'fuel' |
||||
|
||||
EXTRA_COMPONENTS += ['fuelApplication.manifest'] |
||||
|
||||
EXTRA_PP_COMPONENTS += ['fuelApplication.js'] |
||||
|
Loading…
Reference in new issue