2007-03-22 10:30:00 -07:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
* ***** BEGIN LICENSE BLOCK *****
|
|
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Mozilla Public License
|
|
|
|
* Version 1.1 (the "License"); you may not use this file except in
|
|
|
|
* compliance with the License. You may obtain a copy of the License
|
|
|
|
* at http://www.mozilla.org/MPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an "AS IS"
|
|
|
|
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
|
|
|
* the License for the specific language governing rights and
|
|
|
|
* limitations under the License.
|
|
|
|
*
|
|
|
|
* The Original Code is the Places JS Livemark Service.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Mozilla Corporation.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 2006
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
* Annie Sullivan <annie.sullivan@gmail.com> (C++ author)
|
|
|
|
* Joe Hughes <joe@retrovirus.com>
|
|
|
|
* Vladimir Vukicevic <vladimir@pobox.com>
|
|
|
|
* Masayuki Nakano <masayuki@d-toybox.com>
|
|
|
|
* Robert Sayre <sayrer@gmail.com> (JS port)
|
2008-01-05 20:45:01 -08:00
|
|
|
* Phil Ringnalda <philringnalda@gmail.com>
|
2008-09-25 03:30:33 -07:00
|
|
|
* Marco Bonardo <mak77@bonardo.net>
|
2008-09-27 04:05:28 -07:00
|
|
|
* Takeshi Ichimaru <ayakawa.m@gmail.com>
|
2007-03-22 10:30:00 -07:00
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the
|
|
|
|
* terms of either the GNU General Public License Version 2 or later
|
|
|
|
* (the "GPL"), or the GNU Lesser General Public License Version 2.1
|
|
|
|
* or later (the "LGPL"), in which case the provisions of the GPL or
|
|
|
|
* the LGPL are applicable instead of those above. If you wish to
|
|
|
|
* allow use of your version of this file only under the terms of
|
|
|
|
* either the GPL or the LGPL, and not to allow others to use your
|
|
|
|
* version of this file under the terms of the MPL, indicate your
|
|
|
|
* decision by deleting the provisions above and replace them with the
|
|
|
|
* notice and other provisions required by the GPL or the LGPL. If you
|
|
|
|
* do not delete the provisions above, a recipient may use your
|
|
|
|
* version of this file under the terms of any one of the MPL, the GPL
|
|
|
|
* or the LGPL.
|
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
|
|
|
|
const Cc = Components.classes;
|
|
|
|
const Ci = Components.interfaces;
|
|
|
|
const Cr = Components.results;
|
|
|
|
|
|
|
|
#include ../../url-classifier/content/moz/lang.js
|
|
|
|
#include ../../url-classifier/content/moz/observer.js
|
|
|
|
#include ../../url-classifier/content/moz/alarm.js
|
|
|
|
|
|
|
|
const LS_CLASSID = Components.ID("{dca61eb5-c7cd-4df1-b0fb-d0722baba251}");
|
|
|
|
const LS_CLASSNAME = "Livemark Service";
|
|
|
|
const LS_CONTRACTID = "@mozilla.org/browser/livemark-service;2";
|
|
|
|
|
|
|
|
const LMANNO_FEEDURI = "livemark/feedURI";
|
|
|
|
const LMANNO_SITEURI = "livemark/siteURI";
|
|
|
|
const LMANNO_EXPIRATION = "livemark/expiration";
|
2007-12-04 21:02:06 -08:00
|
|
|
const LMANNO_LOADFAILED = "livemark/loadfailed";
|
2008-09-25 03:30:33 -07:00
|
|
|
const LMANNO_LOADING = "livemark/loading";
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2007-06-12 08:56:36 -07:00
|
|
|
const PS_CONTRACTID = "@mozilla.org/preferences-service;1";
|
2007-03-22 10:30:00 -07:00
|
|
|
const NH_CONTRACTID = "@mozilla.org/browser/nav-history-service;1";
|
|
|
|
const AS_CONTRACTID = "@mozilla.org/browser/annotation-service;1";
|
|
|
|
const OS_CONTRACTID = "@mozilla.org/observer-service;1";
|
|
|
|
const SB_CONTRACTID = "@mozilla.org/intl/stringbundle;1";
|
|
|
|
const IO_CONTRACTID = "@mozilla.org/network/io-service;1";
|
|
|
|
const BMS_CONTRACTID = "@mozilla.org/browser/nav-bookmarks-service;1";
|
|
|
|
const FAV_CONTRACTID = "@mozilla.org/browser/favicon-service;1";
|
|
|
|
const LG_CONTRACTID = "@mozilla.org/network/load-group;1";
|
|
|
|
const FP_CONTRACTID = "@mozilla.org/feed-processor;1";
|
|
|
|
const SEC_CONTRACTID = "@mozilla.org/scriptsecuritymanager;1";
|
2007-08-31 13:33:54 -07:00
|
|
|
const IS_CONTRACTID = "@mozilla.org/widget/idleservice;1";
|
2007-03-22 10:30:00 -07:00
|
|
|
const SEC_FLAGS = Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL;
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
// Expire livemarks after 1 hour by default
|
2007-06-12 08:56:36 -07:00
|
|
|
var gExpiration = 3600000;
|
|
|
|
|
2008-09-27 04:05:28 -07:00
|
|
|
// Number of livemarks that are read at once
|
|
|
|
var gLimitCount = 1;
|
|
|
|
|
|
|
|
// Interval when livemarks are loaded
|
|
|
|
var gDelayTime = 3;
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
// Expire livemarks after 10 minutes on error
|
2007-03-22 10:30:00 -07:00
|
|
|
const ERROR_EXPIRATION = 600000;
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
// Don't check when the user is idle for longer than half an hour
|
2007-08-31 13:33:54 -07:00
|
|
|
const IDLE_TIMELIMIT = 1800000;
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
// We should check for expiration _at least_ every hour
|
|
|
|
// This cap is used only if the user sets a very high expiration time (>4h)
|
|
|
|
const MAX_REFRESH_TIME = 3600000;
|
|
|
|
|
2007-12-04 21:02:06 -08:00
|
|
|
function MarkLivemarkLoadFailed(aFolderId) {
|
|
|
|
var ans = Cc[AS_CONTRACTID].getService(Ci.nsIAnnotationService);
|
2008-09-25 03:30:33 -07:00
|
|
|
// if it failed before, nothing more to do
|
2007-12-04 21:02:06 -08:00
|
|
|
if (ans.itemHasAnnotation(aFolderId, LMANNO_LOADFAILED))
|
|
|
|
return;
|
|
|
|
|
2008-09-25 03:30:33 -07:00
|
|
|
// removeItemAnnotation can safely be used even when the anno isn't set
|
|
|
|
ans.removeItemAnnotation(aFolderId, LMANNO_LOADING);
|
|
|
|
ans.setItemAnnotation(aFolderId, LMANNO_LOADFAILED, true,
|
|
|
|
0, ans.EXPIRE_NEVER);
|
2007-12-13 22:04:49 -08:00
|
|
|
}
|
2007-12-04 21:02:06 -08:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
function LivemarkService() {
|
2007-06-12 08:56:36 -07:00
|
|
|
|
|
|
|
try {
|
|
|
|
var prefs = Cc[PS_CONTRACTID].getService(Ci.nsIPrefBranch);
|
2007-12-13 22:04:49 -08:00
|
|
|
var livemarkRefresh =
|
2007-06-12 08:56:36 -07:00
|
|
|
prefs.getIntPref("browser.bookmarks.livemark_refresh_seconds");
|
|
|
|
// Reset global expiration variable to reflect hidden pref (in ms)
|
|
|
|
// with a lower limit of 1 minute (60000 ms)
|
|
|
|
gExpiration = Math.max(livemarkRefresh * 1000, 60000);
|
2007-12-13 22:04:49 -08:00
|
|
|
}
|
2007-06-12 08:56:36 -07:00
|
|
|
catch (ex) { }
|
2007-08-10 12:23:58 -07:00
|
|
|
|
2008-09-27 04:05:28 -07:00
|
|
|
try {
|
|
|
|
gLimitCount = prefs.getIntPref("browser.bookmarks.livemark_refresh_limit_count");
|
|
|
|
if ( gLimitCount < 1 ) gLimitCount = 1;
|
|
|
|
}
|
|
|
|
catch (ex) { }
|
|
|
|
|
|
|
|
try {
|
|
|
|
gDelayTime = prefs.getIntPref("browser.bookmarks.livemark_refresh_delay_time");
|
|
|
|
if ( gDelayTime < 1 ) gDelayTime = 1;
|
|
|
|
}
|
|
|
|
catch (ex) { }
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// [ {folderId:, folderURI:, feedURI:, loadGroup:, locked: } ];
|
|
|
|
this._livemarks = [];
|
|
|
|
|
|
|
|
this._observerServiceObserver =
|
|
|
|
new G_ObserverServiceObserver('xpcom-shutdown',
|
|
|
|
BindToObject(this._shutdown, this),
|
|
|
|
true /*only once*/);
|
|
|
|
|
2007-05-10 01:05:19 -07:00
|
|
|
var livemarks = this._ans.getItemsWithAnnotation(LMANNO_FEEDURI, {});
|
2007-03-22 10:30:00 -07:00
|
|
|
for (var i = 0; i < livemarks.length; i++) {
|
2008-09-25 03:30:33 -07:00
|
|
|
var feedURI = this._ios.newURI(this._ans.getItemAnnotation(livemarks[i],
|
|
|
|
LMANNO_FEEDURI),
|
|
|
|
null, null);
|
2007-05-10 01:05:19 -07:00
|
|
|
this._pushLivemark(livemarks[i], feedURI);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2007-08-02 13:19:44 -07:00
|
|
|
|
|
|
|
this._bms.addObserver(this, false);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
LivemarkService.prototype = {
|
|
|
|
|
|
|
|
get _bms() {
|
2009-06-12 15:39:42 -07:00
|
|
|
var svc = Cc[BMS_CONTRACTID].getService(Ci.nsINavBookmarksService);
|
|
|
|
this.__defineGetter__("_bms", function() svc);
|
|
|
|
return this._bms;
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
get _history() {
|
2009-06-12 15:39:42 -07:00
|
|
|
var svc = Cc[NH_CONTRACTID].getService(Ci.nsINavHistoryService);
|
|
|
|
this.__defineGetter__("_history", function() svc);
|
|
|
|
return this._history;
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
|
|
|
|
2008-09-25 03:30:33 -07:00
|
|
|
get _ans() {
|
2009-06-12 15:39:42 -07:00
|
|
|
var svc = Cc[AS_CONTRACTID].getService(Ci.nsIAnnotationService);
|
|
|
|
this.__defineGetter__("_ans", function() svc);
|
|
|
|
return this._ans;
|
2008-09-25 03:30:33 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
get _ios() {
|
2009-06-12 15:39:42 -07:00
|
|
|
var svc = Cc[IO_CONTRACTID].getService(Ci.nsIIOService);
|
|
|
|
this.__defineGetter__("_ios", function() svc);
|
|
|
|
return this._ios;
|
2008-09-25 03:30:33 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
get _idleService() {
|
2009-06-12 15:39:42 -07:00
|
|
|
if (!(IS_CONTRACTID in Cc))
|
|
|
|
return null;
|
|
|
|
var svc = Cc[IS_CONTRACTID].getService(Ci.nsIIdleService);
|
|
|
|
this.__defineGetter__("_idleService", function() svc);
|
|
|
|
return this._idleService;
|
2008-09-25 03:30:33 -07:00
|
|
|
},
|
|
|
|
|
2008-01-17 22:58:52 -08:00
|
|
|
_updateTimer: null,
|
|
|
|
start: function LS_start() {
|
|
|
|
if (this._updateTimer)
|
|
|
|
return;
|
2008-03-07 10:35:29 -08:00
|
|
|
// start is called in delayed startup, 5s after browser startup
|
|
|
|
// we do a first check of the livemarks here, next checks will be on timer
|
|
|
|
// browser start => 5s => this.start() => check => refresh_time => check
|
|
|
|
this._checkAllLivemarks();
|
2008-09-27 04:05:28 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
stopUpdateLivemarks: function LS_stopUpdateLivemarks() {
|
|
|
|
for (var livemark in this._livemarks) {
|
|
|
|
if (livemark.loadGroup)
|
|
|
|
livemark.loadGroup.cancel(Components.results.NS_BINDING_ABORTED);
|
|
|
|
}
|
|
|
|
// kill timer
|
|
|
|
if (this._updateTimer) {
|
|
|
|
this._updateTimer.cancel();
|
|
|
|
this._updateTimer = null;
|
|
|
|
}
|
2008-01-17 22:58:52 -08:00
|
|
|
},
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
_pushLivemark: function LS__pushLivemark(aFolderId, aFeedURI) {
|
|
|
|
// returns new length of _livemarks
|
2008-09-25 03:30:33 -07:00
|
|
|
return this._livemarks.push({folderId: aFolderId, feedURI: aFeedURI});
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
_getLivemarkIndex: function LS__getLivemarkIndex(aFolderId) {
|
|
|
|
for (var i = 0; i < this._livemarks.length; ++i) {
|
|
|
|
if (this._livemarks[i].folderId == aFolderId)
|
2007-03-22 10:30:00 -07:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
throw Cr.NS_ERROR_INVALID_ARG;
|
|
|
|
},
|
|
|
|
|
|
|
|
_shutdown: function LS__shutdown() {
|
2007-08-02 18:04:01 -07:00
|
|
|
// remove bookmarks observer
|
|
|
|
this._bms.removeObserver(this);
|
|
|
|
|
2008-09-27 04:05:28 -07:00
|
|
|
// stop to update livemarks
|
|
|
|
this.stopUpdateLivemarks();
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
|
|
|
|
2008-09-27 04:05:28 -07:00
|
|
|
// We try to distribute the load of the livemark update.
|
|
|
|
// load gLimitCount Livemarks per gDelayTime sec.
|
|
|
|
_nextUpdateStartIndex : 0,
|
2008-03-07 10:35:29 -08:00
|
|
|
_checkAllLivemarks: function LS__checkAllLivemarks() {
|
2008-09-27 04:05:28 -07:00
|
|
|
var startNo = this._nextUpdateStartIndex;
|
|
|
|
var count = 0;
|
|
|
|
for (var i = startNo; (i < this._livemarks.length) && (count < gLimitCount); ++i ) {
|
|
|
|
// check if livemarks are expired, update if needed
|
|
|
|
try {
|
|
|
|
if (this._updateLivemarkChildren(i, false)) count++;
|
|
|
|
}
|
|
|
|
catch (ex) { }
|
|
|
|
this._nextUpdateStartIndex = i+1;
|
|
|
|
}
|
|
|
|
if ( this._nextUpdateStartIndex >= this._livemarks.length ) {
|
|
|
|
// all livemarks are checked, sleeping until next period
|
|
|
|
this._nextUpdateStartIndex = 0;
|
|
|
|
var refresh_time = Math.min(Math.floor(gExpiration / 4), MAX_REFRESH_TIME);
|
|
|
|
this._updateTimer = new G_Alarm(BindToObject(this._checkAllLivemarks, this),
|
|
|
|
refresh_time);
|
|
|
|
} else {
|
|
|
|
// wait gDelayTime sec.
|
|
|
|
this._updateTimer = new G_Alarm(BindToObject(this._checkAllLivemarks, this),
|
|
|
|
gDelayTime*1000);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
deleteLivemarkChildren: function LS_deleteLivemarkChildren(aFolderId) {
|
|
|
|
this._bms.removeFolderChildren(aFolderId);
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
_updateLivemarkChildren:
|
2008-03-07 10:35:29 -08:00
|
|
|
function LS__updateLivemarkChildren(aIndex, aForceUpdate) {
|
|
|
|
if (this._livemarks[aIndex].locked)
|
2008-03-04 03:30:35 -08:00
|
|
|
return false;
|
2007-12-04 21:02:06 -08:00
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
var livemark = this._livemarks[aIndex];
|
2007-03-22 10:30:00 -07:00
|
|
|
livemark.locked = true;
|
|
|
|
try {
|
|
|
|
// Check the TTL/expiration on this. If there isn't one,
|
|
|
|
// then we assume it's never been loaded. We perform this
|
|
|
|
// check even when the update is being forced, in case the
|
|
|
|
// livemark has somehow never been loaded.
|
2008-03-07 10:35:29 -08:00
|
|
|
var expireTime = this._ans.getItemAnnotation(livemark.folderId,
|
|
|
|
LMANNO_EXPIRATION);
|
|
|
|
if (!aForceUpdate && expireTime > Date.now()) {
|
2007-04-12 21:17:12 -07:00
|
|
|
// no need to refresh
|
|
|
|
livemark.locked = false;
|
2008-03-04 03:30:35 -08:00
|
|
|
return false;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2007-08-31 13:33:54 -07:00
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
// Check the user idle time.
|
|
|
|
// If the user is away from the computer, don't bother updating,
|
|
|
|
// so we save some bandwidth.
|
|
|
|
// If we can't get the idle time, assume the user is not idle.
|
2007-08-31 13:33:54 -07:00
|
|
|
var idleTime = 0;
|
|
|
|
try {
|
|
|
|
idleTime = this._idleService.idleTime;
|
2008-03-07 10:35:29 -08:00
|
|
|
}
|
|
|
|
catch (ex) { /* We don't care */ }
|
|
|
|
if (idleTime > IDLE_TIMELIMIT) {
|
2007-08-31 13:33:54 -07:00
|
|
|
livemark.locked = false;
|
2008-03-04 03:30:35 -08:00
|
|
|
return false;
|
2007-08-31 13:33:54 -07:00
|
|
|
}
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
catch (ex) {
|
|
|
|
// This livemark has never been loaded, since it has no expire time.
|
|
|
|
}
|
|
|
|
|
|
|
|
var loadgroup;
|
|
|
|
try {
|
|
|
|
// Create a load group for the request. This will allow us to
|
|
|
|
// automatically keep track of redirects, so we can always
|
|
|
|
// cancel the channel.
|
|
|
|
loadgroup = Cc[LG_CONTRACTID].createInstance(Ci.nsILoadGroup);
|
2008-09-25 03:30:33 -07:00
|
|
|
var uriChannel = this._ios.newChannel(livemark.feedURI.spec, null, null);
|
2007-03-22 10:30:00 -07:00
|
|
|
uriChannel.loadGroup = loadgroup;
|
2007-12-13 22:04:49 -08:00
|
|
|
uriChannel.loadFlags |= Ci.nsIRequest.LOAD_BACKGROUND |
|
2007-03-22 10:30:00 -07:00
|
|
|
Ci.nsIRequest.VALIDATE_ALWAYS;
|
|
|
|
var httpChannel = uriChannel.QueryInterface(Ci.nsIHttpChannel);
|
|
|
|
httpChannel.requestMethod = "GET";
|
|
|
|
httpChannel.setRequestHeader("X-Moz", "livebookmarks", false);
|
|
|
|
|
|
|
|
// Stream the result to the feed parser with this listener
|
|
|
|
var listener = new LivemarkLoadListener(livemark);
|
2008-09-25 03:30:33 -07:00
|
|
|
// removeItemAnnotation can safely be used even when the anno isn't set
|
|
|
|
this._ans.removeItemAnnotation(livemark.folderId, LMANNO_LOADFAILED);
|
|
|
|
this._ans.setItemAnnotation(livemark.folderId, LMANNO_LOADING, true,
|
|
|
|
0, this._ans.EXPIRE_NEVER);
|
2008-01-15 07:06:34 -08:00
|
|
|
httpChannel.notificationCallbacks = listener;
|
2007-03-22 10:30:00 -07:00
|
|
|
httpChannel.asyncOpen(listener, null);
|
|
|
|
}
|
|
|
|
catch (ex) {
|
2007-12-13 22:04:49 -08:00
|
|
|
MarkLivemarkLoadFailed(livemark.folderId);
|
2007-03-22 10:30:00 -07:00
|
|
|
livemark.locked = false;
|
2008-03-04 03:30:35 -08:00
|
|
|
return false;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
livemark.loadGroup = loadgroup;
|
2008-03-04 03:30:35 -08:00
|
|
|
return true;
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
createLivemark: function LS_createLivemark(aParentId, aName, aSiteURI,
|
|
|
|
aFeedURI, aIndex) {
|
2009-06-12 00:34:35 -07:00
|
|
|
if (!aParentId || !aFeedURI)
|
|
|
|
throw Cr.NS_ERROR_INVALID_ARG;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// Don't add livemarks to livemarks
|
2008-03-07 10:35:29 -08:00
|
|
|
if (this.isLivemark(aParentId))
|
2007-03-22 10:30:00 -07:00
|
|
|
throw Cr.NS_ERROR_INVALID_ARG;
|
2007-12-13 22:04:49 -08:00
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
var folderId = this._createFolder(aParentId, aName, aSiteURI,
|
|
|
|
aFeedURI, aIndex);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
// do a first update of the livemark children
|
|
|
|
this._updateLivemarkChildren(this._pushLivemark(folderId, aFeedURI) - 1,
|
|
|
|
false);
|
|
|
|
|
|
|
|
return folderId;
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
createLivemarkFolderOnly:
|
2008-03-07 10:35:29 -08:00
|
|
|
function LS_createLivemarkFolderOnly(aParentId, aName, aSiteURI,
|
|
|
|
aFeedURI, aIndex) {
|
2009-06-12 00:34:35 -07:00
|
|
|
if (aParentId < 1 || !aFeedURI)
|
|
|
|
throw Cr.NS_ERROR_INVALID_ARG;
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
// Don't add livemarks to livemarks
|
|
|
|
if (this.isLivemark(aParentId))
|
|
|
|
throw Cr.NS_ERROR_INVALID_ARG;
|
|
|
|
|
|
|
|
var folderId = this._createFolder(aParentId, aName, aSiteURI,
|
|
|
|
aFeedURI, aIndex);
|
|
|
|
|
|
|
|
var livemarkIndex = this._pushLivemark(folderId, aFeedURI) - 1;
|
2007-08-10 12:23:58 -07:00
|
|
|
var livemark = this._livemarks[livemarkIndex];
|
2008-03-07 10:35:29 -08:00
|
|
|
return folderId;
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
_createFolder:
|
2008-03-07 10:35:29 -08:00
|
|
|
function LS__createFolder(aParentId, aName, aSiteURI, aFeedURI, aIndex) {
|
|
|
|
var folderId = this._bms.createFolder(aParentId, aName, aIndex);
|
|
|
|
this._bms.setFolderReadonly(folderId, true);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2007-11-19 18:01:53 -08:00
|
|
|
// Add an annotation to map the folder id to the livemark feed URI
|
2008-09-25 03:30:33 -07:00
|
|
|
this._ans.setItemAnnotation(folderId, LMANNO_FEEDURI, aFeedURI.spec,
|
|
|
|
0, this._ans.EXPIRE_NEVER);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
if (aSiteURI) {
|
2007-03-22 10:30:00 -07:00
|
|
|
// Add an annotation to map the folder URI to the livemark site URI
|
2008-03-07 10:35:29 -08:00
|
|
|
this._setSiteURISecure(folderId, aFeedURI, aSiteURI);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
return folderId;
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
isLivemark: function LS_isLivemark(aFolderId) {
|
2009-06-12 00:34:35 -07:00
|
|
|
if (aFolderId < 1)
|
|
|
|
throw Cr.NS_ERROR_INVALID_ARG;
|
2009-06-12 15:39:42 -07:00
|
|
|
try {
|
|
|
|
this._getLivemarkIndex(aFolderId);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
catch (ex) {}
|
|
|
|
return false;
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
|
|
|
|
2009-06-22 16:00:51 -07:00
|
|
|
getLivemarkIdForFeedURI: function LS_getLivemarkIdForFeedURI(aFeedURI) {
|
|
|
|
if (!(aFeedURI instanceof Ci.nsIURI))
|
|
|
|
throw Cr.NS_ERROR_INVALID_ARG;
|
|
|
|
|
|
|
|
for (var i = 0; i < this._livemarks.length; ++i) {
|
|
|
|
if (this._livemarks[i].feedURI.equals(aFeedURI))
|
|
|
|
return this._livemarks[i].folderId;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
},
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
_ensureLivemark: function LS__ensureLivemark(aFolderId) {
|
|
|
|
if (!this.isLivemark(aFolderId))
|
2007-03-22 10:30:00 -07:00
|
|
|
throw Cr.NS_ERROR_INVALID_ARG;
|
|
|
|
},
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
getSiteURI: function LS_getSiteURI(aFolderId) {
|
|
|
|
this._ensureLivemark(aFolderId);
|
2007-10-13 13:50:57 -07:00
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
if (this._ans.itemHasAnnotation(aFolderId, LMANNO_SITEURI)) {
|
2007-05-27 20:50:34 -07:00
|
|
|
var siteURIString =
|
2008-03-07 10:35:29 -08:00
|
|
|
this._ans.getItemAnnotation(aFolderId, LMANNO_SITEURI);
|
2007-05-27 20:50:34 -07:00
|
|
|
|
2008-09-25 03:30:33 -07:00
|
|
|
return this._ios.newURI(siteURIString, null, null);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2007-05-27 20:50:34 -07:00
|
|
|
return null;
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
setSiteURI: function LS_setSiteURI(aFolderId, aSiteURI) {
|
|
|
|
this._ensureLivemark(aFolderId);
|
2007-12-13 22:04:49 -08:00
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
if (!aSiteURI) {
|
|
|
|
this._ans.removeItemAnnotation(aFolderId, LMANNO_SITEURI);
|
2007-03-22 10:30:00 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
var livemarkIndex = this._getLivemarkIndex(aFolderId);
|
2007-12-27 19:00:07 -08:00
|
|
|
var livemark = this._livemarks[livemarkIndex];
|
2008-03-07 10:35:29 -08:00
|
|
|
this._setSiteURISecure(aFolderId, livemark.feedURI, aSiteURI);
|
2007-12-27 19:00:07 -08:00
|
|
|
},
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
_setSiteURISecure:
|
|
|
|
function LS__setSiteURISecure(aFolderId, aFeedURI, aSiteURI) {
|
2007-12-27 19:00:07 -08:00
|
|
|
var secMan = Cc[SEC_CONTRACTID].getService(Ci.nsIScriptSecurityManager);
|
2008-03-07 10:35:29 -08:00
|
|
|
var feedPrincipal = secMan.getCodebasePrincipal(aFeedURI);
|
2007-12-27 19:00:07 -08:00
|
|
|
try {
|
2008-03-07 10:35:29 -08:00
|
|
|
secMan.checkLoadURIWithPrincipal(feedPrincipal, aSiteURI, SEC_FLAGS);
|
|
|
|
}
|
|
|
|
catch (e) {
|
2007-12-27 19:00:07 -08:00
|
|
|
return;
|
|
|
|
}
|
2008-03-07 10:35:29 -08:00
|
|
|
this._ans.setItemAnnotation(aFolderId, LMANNO_SITEURI, aSiteURI.spec,
|
2007-12-27 19:00:07 -08:00
|
|
|
0, this._ans.EXPIRE_NEVER);
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
getFeedURI: function LS_getFeedURI(aFolderId) {
|
|
|
|
if (this._ans.itemHasAnnotation(aFolderId, LMANNO_FEEDURI))
|
2008-09-25 03:30:33 -07:00
|
|
|
return this._ios.newURI(this._ans.getItemAnnotation(aFolderId,
|
|
|
|
LMANNO_FEEDURI),
|
|
|
|
null, null);
|
2007-05-27 20:50:34 -07:00
|
|
|
return null;
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
setFeedURI: function LS_setFeedURI(aFolderId, aFeedURI) {
|
|
|
|
if (!aFeedURI)
|
2007-03-22 10:30:00 -07:00
|
|
|
throw Cr.NS_ERROR_INVALID_ARG;
|
2007-05-10 01:05:19 -07:00
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
this._ans.setItemAnnotation(aFolderId, LMANNO_FEEDURI, aFeedURI.spec, 0,
|
2007-07-11 02:57:59 -07:00
|
|
|
this._ans.EXPIRE_NEVER);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// now update our internal table
|
2008-03-07 10:35:29 -08:00
|
|
|
var livemarkIndex = this._getLivemarkIndex(aFolderId);
|
|
|
|
this._livemarks[livemarkIndex].feedURI = aFeedURI;
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
reloadAllLivemarks: function LS_reloadAllLivemarks() {
|
|
|
|
for (var i = 0; i < this._livemarks.length; ++i) {
|
|
|
|
this._updateLivemarkChildren(i, true);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
reloadLivemarkFolder: function LS_reloadLivemarkFolder(aFolderId) {
|
|
|
|
var livemarkIndex = this._getLivemarkIndex(aFolderId);
|
2007-03-22 10:30:00 -07:00
|
|
|
this._updateLivemarkChildren(livemarkIndex, true);
|
|
|
|
},
|
|
|
|
|
2007-08-02 13:19:44 -07:00
|
|
|
// nsINavBookmarkObserver
|
|
|
|
onBeginUpdateBatch: function() { },
|
|
|
|
onEndUpdateBatch: function() { },
|
|
|
|
onItemAdded: function() { },
|
|
|
|
onItemChanged: function() { },
|
|
|
|
onItemVisited: function() { },
|
|
|
|
onItemMoved: function() { },
|
2009-03-19 12:56:51 -07:00
|
|
|
onBeforeItemRemoved: function() { },
|
2007-08-02 13:19:44 -07:00
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
onItemRemoved: function(aItemId, aParentId, aIndex) {
|
|
|
|
// we don't need to remove annotations since itemAnnotations
|
|
|
|
// are already removed with the bookmark
|
2007-08-02 13:19:44 -07:00
|
|
|
try {
|
|
|
|
var livemarkIndex = this._getLivemarkIndex(aItemId);
|
|
|
|
}
|
|
|
|
catch(ex) {
|
|
|
|
// not a livemark
|
|
|
|
return;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
var livemark = this._livemarks[livemarkIndex];
|
2007-05-10 01:05:19 -07:00
|
|
|
|
2008-02-23 01:38:39 -08:00
|
|
|
// remove the livemark from the update array
|
|
|
|
this._livemarks.splice(livemarkIndex, 1);
|
|
|
|
|
2007-12-13 22:04:49 -08:00
|
|
|
if (livemark.loadGroup)
|
2008-09-09 21:33:27 -07:00
|
|
|
livemark.loadGroup.cancel(Components.results.NS_BINDING_ABORTED);
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
createInstance: function LS_createInstance(aOuter, aIID) {
|
|
|
|
if (aOuter != null)
|
2007-03-22 10:30:00 -07:00
|
|
|
throw Cr.NS_ERROR_NO_AGGREGATION;
|
2008-03-07 10:35:29 -08:00
|
|
|
return this.QueryInterface(aIID);
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
2007-12-13 22:04:49 -08:00
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
QueryInterface: function LS_QueryInterface(aIID) {
|
|
|
|
if (aIID.equals(Ci.nsILivemarkService) ||
|
|
|
|
aIID.equals(Ci.nsIFactory) ||
|
|
|
|
aIID.equals(Ci.nsINavBookmarkObserver) ||
|
|
|
|
aIID.equals(Ci.nsISupports))
|
2007-03-22 10:30:00 -07:00
|
|
|
return this;
|
|
|
|
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
2007-08-02 13:19:44 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
};
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
function LivemarkLoadListener(aLivemark) {
|
|
|
|
this._livemark = aLivemark;
|
2007-03-22 10:30:00 -07:00
|
|
|
this._processor = null;
|
|
|
|
this._isAborted = false;
|
2007-06-12 08:56:36 -07:00
|
|
|
this._ttl = gExpiration;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
LivemarkLoadListener.prototype = {
|
|
|
|
|
|
|
|
abort: function LLL_abort() {
|
|
|
|
this._isAborted = true;
|
|
|
|
},
|
|
|
|
|
|
|
|
get _bms() {
|
|
|
|
if (!this.__bms)
|
|
|
|
this.__bms = Cc[BMS_CONTRACTID].getService(Ci.nsINavBookmarksService);
|
|
|
|
return this.__bms;
|
|
|
|
},
|
|
|
|
|
|
|
|
get _history() {
|
|
|
|
if (!this.__history)
|
|
|
|
this.__history = Cc[NH_CONTRACTID].getService(Ci.nsINavHistoryService);
|
|
|
|
return this.__history;
|
|
|
|
},
|
|
|
|
|
2008-09-25 03:30:33 -07:00
|
|
|
get _ans() {
|
|
|
|
if (!this.__ans)
|
|
|
|
this.__ans = Cc[AS_CONTRACTID].getService(Ci.nsIAnnotationService);
|
|
|
|
return this.__ans;
|
|
|
|
},
|
|
|
|
|
2007-05-31 17:44:43 -07:00
|
|
|
// called back from handleResult
|
|
|
|
runBatched: function LLL_runBatched(aUserData) {
|
|
|
|
var result = aUserData.QueryInterface(Ci.nsIFeedResult);
|
|
|
|
|
|
|
|
// We need this to make sure the item links are safe
|
|
|
|
var secMan = Cc[SEC_CONTRACTID].getService(Ci.nsIScriptSecurityManager);
|
2007-12-13 20:01:05 -08:00
|
|
|
var feedPrincipal = secMan.getCodebasePrincipal(this._livemark.feedURI);
|
|
|
|
|
2007-05-31 17:44:43 -07:00
|
|
|
var lmService = Cc[LS_CONTRACTID].getService(Ci.nsILivemarkService);
|
|
|
|
|
|
|
|
// Enforce well-formedness because the existing code does
|
|
|
|
if (!result || !result.doc || result.bozo) {
|
2007-12-04 21:02:06 -08:00
|
|
|
MarkLivemarkLoadFailed(this._livemark.folderId);
|
2007-06-12 08:56:36 -07:00
|
|
|
this._ttl = gExpiration;
|
2007-05-31 17:44:43 -07:00
|
|
|
throw Cr.NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2007-12-13 22:04:49 -08:00
|
|
|
// Clear out any child nodes of the livemark folder, since
|
|
|
|
// they're about to be replaced.
|
2007-08-10 12:23:58 -07:00
|
|
|
this.deleteLivemarkChildren(this._livemark.folderId);
|
2007-05-31 17:44:43 -07:00
|
|
|
var feed = result.doc.QueryInterface(Ci.nsIFeed);
|
2008-01-05 20:45:01 -08:00
|
|
|
if (feed.link) {
|
|
|
|
var oldSiteURI = lmService.getSiteURI(this._livemark.folderId);
|
|
|
|
if (!oldSiteURI || !feed.link.equals(oldSiteURI))
|
|
|
|
lmService.setSiteURI(this._livemark.folderId, feed.link);
|
|
|
|
}
|
2007-05-31 17:44:43 -07:00
|
|
|
// Loop through and check for a link and a title
|
|
|
|
// as the old code did
|
|
|
|
for (var i = 0; i < feed.items.length; ++i) {
|
2007-09-16 18:46:27 -07:00
|
|
|
let entry = feed.items.queryElementAt(i, Ci.nsIFeedEntry);
|
|
|
|
let href = entry.link;
|
|
|
|
if (!href)
|
|
|
|
continue;
|
|
|
|
|
2008-09-04 10:00:18 -07:00
|
|
|
let title = entry.title ? entry.title.plainText() : "";
|
2007-09-16 18:46:27 -07:00
|
|
|
|
|
|
|
try {
|
2007-12-13 20:01:05 -08:00
|
|
|
secMan.checkLoadURIWithPrincipal(feedPrincipal, href, SEC_FLAGS);
|
2007-09-16 18:46:27 -07:00
|
|
|
}
|
|
|
|
catch(ex) {
|
|
|
|
continue;
|
2007-05-31 17:44:43 -07:00
|
|
|
}
|
|
|
|
|
2007-09-16 18:46:27 -07:00
|
|
|
this.insertLivemarkChild(this._livemark.folderId, href, title);
|
2007-05-31 17:44:43 -07:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
/**
|
|
|
|
* See nsIFeedResultListener.idl
|
|
|
|
*/
|
2008-03-07 10:35:29 -08:00
|
|
|
handleResult: function LLL_handleResult(aResult) {
|
2007-03-22 10:30:00 -07:00
|
|
|
if (this._isAborted) {
|
2007-12-04 21:02:06 -08:00
|
|
|
MarkLivemarkLoadFailed(this._livemark.folderId);
|
2007-03-22 10:30:00 -07:00
|
|
|
this._livemark.locked = false;
|
|
|
|
return;
|
|
|
|
}
|
2007-05-31 17:44:43 -07:00
|
|
|
try {
|
|
|
|
// The actual work is done in runBatched, see above.
|
2008-03-07 10:35:29 -08:00
|
|
|
this._bms.runInBatchMode(this, aResult);
|
2007-05-31 17:44:43 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
finally {
|
|
|
|
this._processor.listener = null;
|
|
|
|
this._processor = null;
|
|
|
|
this._livemark.locked = false;
|
2008-09-25 03:30:33 -07:00
|
|
|
this._ans.removeItemAnnotation(this._livemark.folderId, LMANNO_LOADING);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
},
|
2007-12-13 22:04:49 -08:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
deleteLivemarkChildren: LivemarkService.prototype.deleteLivemarkChildren,
|
|
|
|
|
|
|
|
insertLivemarkChild:
|
2008-03-07 10:35:29 -08:00
|
|
|
function LS_insertLivemarkChild(aFolderId, aUri, aTitle) {
|
|
|
|
this._bms.insertBookmark(aFolderId, aUri, this._bms.DEFAULT_INDEX, aTitle);
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* See nsIStreamListener.idl
|
|
|
|
*/
|
2008-03-07 10:35:29 -08:00
|
|
|
onDataAvailable: function LLL_onDataAvailable(aRequest, aContext, aInputStream,
|
|
|
|
aSourceOffset, aCount) {
|
2009-05-01 22:17:07 -07:00
|
|
|
if (this._processor)
|
|
|
|
this._processor.onDataAvailable(aRequest, aContext, aInputStream,
|
|
|
|
aSourceOffset, aCount);
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
2007-12-13 22:04:49 -08:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
/**
|
|
|
|
* See nsIRequestObserver.idl
|
|
|
|
*/
|
2008-03-07 10:35:29 -08:00
|
|
|
onStartRequest: function LLL_onStartRequest(aRequest, aContext) {
|
2007-03-22 10:30:00 -07:00
|
|
|
if (this._isAborted)
|
|
|
|
throw Cr.NS_ERROR_UNEXPECTED;
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
var channel = aRequest.QueryInterface(Ci.nsIChannel);
|
2007-12-13 22:04:49 -08:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// Parse feed data as it comes in
|
|
|
|
this._processor = Cc[FP_CONTRACTID].createInstance(Ci.nsIFeedProcessor);
|
|
|
|
this._processor.listener = this;
|
|
|
|
this._processor.parseAsync(null, channel.URI);
|
2007-12-13 22:04:49 -08:00
|
|
|
|
2009-07-07 03:41:23 -07:00
|
|
|
try {
|
|
|
|
this._processor.onStartRequest(aRequest, aContext);
|
|
|
|
}
|
|
|
|
catch (ex) {
|
|
|
|
Components.utils.reportError("Livemark Service: feed processor received an invalid channel for " + channel.URI.spec);
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
2007-12-13 22:04:49 -08:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
/**
|
|
|
|
* See nsIRequestObserver.idl
|
|
|
|
*/
|
2008-03-07 10:35:29 -08:00
|
|
|
onStopRequest: function LLL_onStopRequest(aRequest, aContext, aStatus) {
|
|
|
|
if (!Components.isSuccessCode(aStatus)) {
|
2007-03-22 10:30:00 -07:00
|
|
|
this._isAborted = true;
|
2007-12-04 21:02:06 -08:00
|
|
|
this._livemark.locked = false;
|
2009-07-07 03:41:23 -07:00
|
|
|
var lmService = Cc[LS_CONTRACTID].getService(Ci.nsILivemarkService);
|
|
|
|
// One of the reasons we could abort a request is when a livemark is
|
|
|
|
// removed, in such a case the livemark itemId would already be invalid.
|
|
|
|
if (lmService.isLivemark(this._livemark.folderId)) {
|
|
|
|
// Something went wrong, try to load again in a bit
|
|
|
|
this._setResourceTTL(ERROR_EXPIRATION);
|
|
|
|
MarkLivemarkLoadFailed(this._livemark.folderId);
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Set an expiration on the livemark, for reloading the data
|
2007-12-13 22:04:49 -08:00
|
|
|
try {
|
2009-05-01 22:17:07 -07:00
|
|
|
if (this._processor)
|
|
|
|
this._processor.onStopRequest(aRequest, aContext, aStatus);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// Calculate a new ttl
|
2008-03-07 10:35:29 -08:00
|
|
|
var channel = aRequest.QueryInterface(Ci.nsICachingChannel);
|
2007-03-22 10:30:00 -07:00
|
|
|
if (channel) {
|
|
|
|
var entryInfo = channel.cacheToken.QueryInterface(Ci.nsICacheEntryInfo);
|
|
|
|
if (entryInfo) {
|
2007-12-13 22:04:49 -08:00
|
|
|
// nsICacheEntryInfo returns value as seconds,
|
2008-03-07 10:35:29 -08:00
|
|
|
// expireTime stores as milliseconds
|
|
|
|
var expireTime = entryInfo.expirationTime * 1000;
|
2007-06-12 08:56:36 -07:00
|
|
|
var nowTime = Date.now();
|
2007-12-13 22:04:49 -08:00
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
// note, expireTime can be 0, see bug 383538
|
|
|
|
if (expireTime > nowTime) {
|
|
|
|
this._setResourceTTL(Math.max((expireTime - nowTime),
|
2007-06-12 08:56:36 -07:00
|
|
|
gExpiration));
|
|
|
|
return;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-06-12 08:56:36 -07:00
|
|
|
catch (ex) { }
|
|
|
|
this._setResourceTTL(this._ttl);
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
_setResourceTTL: function LLL__setResourceTTL(aMilliseconds) {
|
|
|
|
var expireTime = Date.now() + aMilliseconds;
|
|
|
|
this._ans.setItemAnnotation(this._livemark.folderId, LMANNO_EXPIRATION,
|
|
|
|
expireTime, 0,
|
2007-07-11 02:57:59 -07:00
|
|
|
Ci.nsIAnnotationService.EXPIRE_NEVER);
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
2007-12-13 22:04:49 -08:00
|
|
|
|
2008-01-15 07:06:34 -08:00
|
|
|
/**
|
|
|
|
* See nsIBadCertListener2
|
|
|
|
*/
|
2008-03-07 10:35:29 -08:00
|
|
|
notifyCertProblem: function LLL_certProblem(aSocketInfo, aStatus, aTargetSite) {
|
2008-01-15 07:06:34 -08:00
|
|
|
return true;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* See nsISSLErrorListener
|
|
|
|
*/
|
2008-03-07 10:35:29 -08:00
|
|
|
notifySSLError: function LLL_SSLError(aSocketInfo, aError, aTargetSite) {
|
2008-01-15 07:06:34 -08:00
|
|
|
return true;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* See nsIInterfaceRequestor
|
|
|
|
*/
|
2008-03-07 10:35:29 -08:00
|
|
|
getInterface: function LLL_getInterface(aIID) {
|
|
|
|
return this.QueryInterface(aIID);
|
2008-01-15 07:06:34 -08:00
|
|
|
},
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
/**
|
|
|
|
* See nsISupports.idl
|
|
|
|
*/
|
2008-03-07 10:35:29 -08:00
|
|
|
QueryInterface: function LLL_QueryInterface(aIID) {
|
|
|
|
if (aIID.equals(Ci.nsIFeedResultListener) ||
|
|
|
|
aIID.equals(Ci.nsIStreamListener) ||
|
|
|
|
aIID.equals(Ci.nsIRequestObserver)||
|
|
|
|
aIID.equals(Ci.nsINavHistoryBatchCallback) ||
|
|
|
|
aIID.equals(Ci.nsIBadCertListener2) ||
|
|
|
|
aIID.equals(Ci.nsISSLErrorListener) ||
|
|
|
|
aIID.equals(Ci.nsIInterfaceRequestor) ||
|
|
|
|
aIID.equals(Ci.nsISupports))
|
2007-03-22 10:30:00 -07:00
|
|
|
return this;
|
|
|
|
throw Cr.NS_ERROR_NO_INTERFACE;
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
function GenericComponentFactory(aCtor) {
|
|
|
|
this._ctor = aCtor;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
GenericComponentFactory.prototype = {
|
|
|
|
|
|
|
|
_ctor: null,
|
|
|
|
|
|
|
|
// nsIFactory
|
2008-03-07 10:35:29 -08:00
|
|
|
createInstance: function(aOuter, aIID) {
|
|
|
|
if (aOuter != null)
|
2007-03-22 10:30:00 -07:00
|
|
|
throw Cr.NS_ERROR_NO_AGGREGATION;
|
2008-03-07 10:35:29 -08:00
|
|
|
return (new this._ctor()).QueryInterface(aIID);
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
// nsISupports
|
2008-03-07 10:35:29 -08:00
|
|
|
QueryInterface: function(aIID) {
|
|
|
|
if (aIID.equals(Ci.nsIFactory) ||
|
|
|
|
aIID.equals(Ci.nsISupports))
|
2007-03-22 10:30:00 -07:00
|
|
|
return this;
|
|
|
|
throw Cr.NS_ERROR_NO_INTERFACE;
|
|
|
|
},
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
var Module = {
|
2008-03-07 10:35:29 -08:00
|
|
|
QueryInterface: function(aIID) {
|
|
|
|
if (aIID.equals(Ci.nsIModule) ||
|
|
|
|
aIID.equals(Ci.nsISupports))
|
2007-03-22 10:30:00 -07:00
|
|
|
return this;
|
|
|
|
|
|
|
|
throw Cr.NS_ERROR_NO_INTERFACE;
|
|
|
|
},
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
getClassObject: function M_getClassObject(aCompMgr, aCID, aIID) {
|
|
|
|
if (!aIID.equals(Ci.nsIFactory))
|
2007-03-22 10:30:00 -07:00
|
|
|
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
2008-03-07 10:35:29 -08:00
|
|
|
if (aCID.equals(LS_CLASSID))
|
2007-03-22 10:30:00 -07:00
|
|
|
return new GenericComponentFactory(LivemarkService);
|
|
|
|
|
|
|
|
throw Cr.NS_ERROR_NO_INTERFACE;
|
|
|
|
},
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
registerSelf: function(aCompMgr, aFile, aLocation, aType) {
|
|
|
|
var cr = aCompMgr.QueryInterface(Ci.nsIComponentRegistrar);
|
2007-12-13 22:04:49 -08:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
cr.registerFactoryLocation(LS_CLASSID, LS_CLASSNAME,
|
2008-03-07 10:35:29 -08:00
|
|
|
LS_CONTRACTID, aFile, aLocation, aType);
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
unregisterSelf: function M_unregisterSelf(aCompMgr, aLocation, aType) {
|
|
|
|
var cr = aCompMgr.QueryInterface(Ci.nsIComponentRegistrar);
|
|
|
|
cr.unregisterFactoryLocation(LS_CLASSID, aLocation);
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
2007-12-13 22:04:49 -08:00
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
canUnload: function M_canUnload(aCompMgr) {
|
2007-03-22 10:30:00 -07:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2008-03-07 10:35:29 -08:00
|
|
|
function NSGetModule(aCompMgr, aFile) {
|
2007-03-22 10:30:00 -07:00
|
|
|
return Module;
|
|
|
|
}
|