diff --git a/toolkit/components/places/src/nsLivemarkService.js b/toolkit/components/places/src/nsLivemarkService.js index c4a8aa8f624..2b09a297824 100644 --- a/toolkit/components/places/src/nsLivemarkService.js +++ b/toolkit/components/places/src/nsLivemarkService.js @@ -25,6 +25,7 @@ * Masayuki Nakano * Robert Sayre (JS port) * Phil Ringnalda + * Marco Bonardo * * Alternatively, the contents of this file may be used under the * terms of either the GNU General Public License Version 2 or later @@ -58,7 +59,6 @@ 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 LIVEMARK_TIMEOUT = 15000; // fire every 15 seconds const PLACES_BUNDLE_URI = "chrome://places/locale/places.properties"; const DEFAULT_LOAD_MSG = "Live Bookmark loading..."; const DEFAULT_FAIL_MSG = "Live Bookmark feed failed to load."; @@ -82,15 +82,19 @@ const IS_CONTRACTID = "@mozilla.org/widget/idleservice;1"; const SEC_FLAGS = Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL; const NS_BINDING_ABORTED = 0x804b0002; -// Check every hour by default +// Expire livemarks after 1 hour by default var gExpiration = 3600000; -// Check every 10 minutes on error +// Expire livemarks after 10 minutes on error const ERROR_EXPIRATION = 600000; -// Don't check when the user is idle for longer than half an hour: +// Don't check when the user is idle for longer than half an hour const IDLE_TIMELIMIT = 1800000; +// 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; + var gIoService = Cc[IO_CONTRACTID].getService(Ci.nsIIOService); var gStringBundle; function GetString(name) @@ -183,18 +187,24 @@ LivemarkService.prototype = { start: function LS_start() { if (this._updateTimer) return; - this._updateTimer = new G_Alarm(BindToObject(this._fireTimer, this), - LIVEMARK_TIMEOUT, true /* repeat */); + // 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(); + // the refresh time is calculated from the expiration time, but with a cap + var refresh_time = Math.min(Math.floor(gExpiration / 4), MAX_REFRESH_TIME); + this._updateTimer = new G_Alarm(BindToObject(this._checkAllLivemarks, this), + refresh_time, true /* repeat */); }, - // returns new length of _livemarks - _pushLivemark: function LS__pushLivemark(folderId, feedURI) { - return this._livemarks.push({folderId: folderId, feedURI: feedURI}); + _pushLivemark: function LS__pushLivemark(aFolderId, aFeedURI) { + // returns new length of _livemarks + return this._livemarks.push({folderId: aFolderId, feedURI: aFeedURI}); }, - _getLivemarkIndex: function LS__getLivemarkIndex(folderId) { - for (var i=0; i < this._livemarks.length; ++i) { - if (this._livemarks[i].folderId == folderId) + _getLivemarkIndex: function LS__getLivemarkIndex(aFolderId) { + for (var i = 0; i < this._livemarks.length; ++i) { + if (this._livemarks[i].folderId == aFolderId) return i; } throw Cr.NS_ERROR_INVALID_ARG; @@ -216,52 +226,54 @@ LivemarkService.prototype = { } }, - _fireTimer: function LS__fireTimer() { - for (var i=0; i < this._livemarks.length; ++i) { + _checkAllLivemarks: function LS__checkAllLivemarks() { + // check if livemarks are expired, update if needed + for (var i = 0; i < this._livemarks.length; ++i) { this._updateLivemarkChildren(i, false); } }, - deleteLivemarkChildren: function LS_deleteLivemarkChildren(folderId) { - this._bms.removeFolderChildren(folderId); + deleteLivemarkChildren: function LS_deleteLivemarkChildren(aFolderId) { + this._bms.removeFolderChildren(aFolderId); }, - insertLivemarkLoadingItem: function LS_insertLivemarkLoading(bms, livemark) { + insertLivemarkLoadingItem: function LS_insertLivemarkLoading(aBms, aLivemark) { var loadingURI = gIoService.newURI("about:livemark-loading", null, null); - if (!livemark.loadingId || livemark.loadingId == -1) - livemark.loadingId = bms.insertBookmark(livemark.folderId, loadingURI, + if (!aLivemark.loadingId || aLivemark.loadingId == -1) + aLivemark.loadingId = aBms.insertBookmark(aLivemark.folderId, loadingURI, 0, this._loading); }, _updateLivemarkChildren: - function LS__updateLivemarkChildren(index, forceUpdate) { - if (this._livemarks[index].locked) + function LS__updateLivemarkChildren(aIndex, aForceUpdate) { + if (this._livemarks[aIndex].locked) return false; - var livemark = this._livemarks[index]; + var livemark = this._livemarks[aIndex]; 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. - var exprTime = this._ans.getPageAnnotation(livemark.feedURI, - LMANNO_EXPIRATION); - if (!forceUpdate && exprTime > Date.now()) { + var expireTime = this._ans.getItemAnnotation(livemark.folderId, + LMANNO_EXPIRATION); + if (!aForceUpdate && expireTime > Date.now()) { // no need to refresh livemark.locked = false; return false; } - // Check the user idle time. If the user isn't using their computer, don't - // bother updating - save the internet some bandwidth. If we can't - // get the idle time, assume the user isn't idle. + // 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. var idleTime = 0; try { idleTime = this._idleService.idleTime; - } catch (ex) { /* We don't care */ } - if (idleTime > IDLE_TIMELIMIT) - { + } + catch (ex) { /* We don't care */ } + if (idleTime > IDLE_TIMELIMIT) { livemark.locked = false; return false; } @@ -303,115 +315,122 @@ LivemarkService.prototype = { return true; }, - createLivemark: function LS_createLivemark(folder, name, siteURI, - feedURI, index) { + createLivemark: function LS_createLivemark(aParentId, aName, aSiteURI, + aFeedURI, aIndex) { // Don't add livemarks to livemarks - if (this.isLivemark(folder)) + if (this.isLivemark(aParentId)) throw Cr.NS_ERROR_INVALID_ARG; - var livemarkID = this._createFolder(folder, name, siteURI, feedURI, index); - // kick off http fetch - this._updateLivemarkChildren( - this._pushLivemark(livemarkID, feedURI) - 1, - false - ); + var folderId = this._createFolder(aParentId, aName, aSiteURI, + aFeedURI, aIndex); - return livemarkID; + // do a first update of the livemark children + this._updateLivemarkChildren(this._pushLivemark(folderId, aFeedURI) - 1, + false); + + return folderId; }, createLivemarkFolderOnly: - function LS_createLivemarkFolderOnly(folder, name, siteURI, feedURI, index) { - var livemarkID = this._createFolder(folder, name, siteURI, feedURI, index); - this._pushLivemark(livemarkID, feedURI); - var livemarkIndex = this._getLivemarkIndex(livemarkID); + function LS_createLivemarkFolderOnly(aParentId, aName, aSiteURI, + aFeedURI, aIndex) { + // 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; var livemark = this._livemarks[livemarkIndex]; this.insertLivemarkLoadingItem(this._bms, livemark); - return livemarkID; + return folderId; }, _createFolder: - function LS__createFolder(folder, name, siteURI, feedURI, index) { - var livemarkID = this._bms.createFolder(folder, name, index); - this._bms.setFolderReadonly(livemarkID, true); + function LS__createFolder(aParentId, aName, aSiteURI, aFeedURI, aIndex) { + var folderId = this._bms.createFolder(aParentId, aName, aIndex); + this._bms.setFolderReadonly(folderId, true); // Add an annotation to map the folder id to the livemark feed URI - this._ans.setItemAnnotation(livemarkID, LMANNO_FEEDURI, feedURI.spec, 0, + this._ans.setItemAnnotation(folderId, LMANNO_FEEDURI, aFeedURI.spec, 0, this._ans.EXPIRE_NEVER); - if (siteURI) { + if (aSiteURI) { // Add an annotation to map the folder URI to the livemark site URI - this._setSiteURISecure(livemarkID, feedURI, siteURI); + this._setSiteURISecure(folderId, aFeedURI, aSiteURI); } - return livemarkID; + return folderId; }, - isLivemark: function LS_isLivemark(folder) { - return this._ans.itemHasAnnotation(folder, LMANNO_FEEDURI); + isLivemark: function LS_isLivemark(aFolderId) { + return this._ans.itemHasAnnotation(aFolderId, LMANNO_FEEDURI); }, - _ensureLivemark: function LS__ensureLivemark(container) { - if (!this.isLivemark(container)) + _ensureLivemark: function LS__ensureLivemark(aFolderId) { + if (!this.isLivemark(aFolderId)) throw Cr.NS_ERROR_INVALID_ARG; }, - getSiteURI: function LS_getSiteURI(container) { - this._ensureLivemark(container); + getSiteURI: function LS_getSiteURI(aFolderId) { + this._ensureLivemark(aFolderId); - if (this._ans.itemHasAnnotation(container, LMANNO_SITEURI)) { + if (this._ans.itemHasAnnotation(aFolderId, LMANNO_SITEURI)) { var siteURIString = - this._ans.getItemAnnotation(container, LMANNO_SITEURI); + this._ans.getItemAnnotation(aFolderId, LMANNO_SITEURI); return gIoService.newURI(siteURIString, null, null); } return null; }, - setSiteURI: function LS_setSiteURI(container, siteURI) { - this._ensureLivemark(container); + setSiteURI: function LS_setSiteURI(aFolderId, aSiteURI) { + this._ensureLivemark(aFolderId); - if (!siteURI) { - this._ans.removeItemAnnotation(container, LMANNO_SITEURI); + if (!aSiteURI) { + this._ans.removeItemAnnotation(aFolderId, LMANNO_SITEURI); return; } - var livemarkIndex = this._getLivemarkIndex(container); + var livemarkIndex = this._getLivemarkIndex(aFolderId); var livemark = this._livemarks[livemarkIndex]; - this._setSiteURISecure(container, livemark.feedURI, siteURI); + this._setSiteURISecure(aFolderId, livemark.feedURI, aSiteURI); }, - _setSiteURISecure: function LS__setSiteURISecure(container, feedURI, siteURI) { + _setSiteURISecure: + function LS__setSiteURISecure(aFolderId, aFeedURI, aSiteURI) { var secMan = Cc[SEC_CONTRACTID].getService(Ci.nsIScriptSecurityManager); - var feedPrincipal = secMan.getCodebasePrincipal(feedURI); + var feedPrincipal = secMan.getCodebasePrincipal(aFeedURI); try { - secMan.checkLoadURIWithPrincipal(feedPrincipal, siteURI, SEC_FLAGS); - } catch (e) { + secMan.checkLoadURIWithPrincipal(feedPrincipal, aSiteURI, SEC_FLAGS); + } + catch (e) { return; } - this._ans.setItemAnnotation(container, LMANNO_SITEURI, siteURI.spec, + this._ans.setItemAnnotation(aFolderId, LMANNO_SITEURI, aSiteURI.spec, 0, this._ans.EXPIRE_NEVER); }, - getFeedURI: function LS_getFeedURI(container) { - if (this._ans.itemHasAnnotation(container, LMANNO_FEEDURI)) - return gIoService.newURI(this._ans.getItemAnnotation(container, + getFeedURI: function LS_getFeedURI(aFolderId) { + if (this._ans.itemHasAnnotation(aFolderId, LMANNO_FEEDURI)) + return gIoService.newURI(this._ans.getItemAnnotation(aFolderId, LMANNO_FEEDURI), null, null); - return null; }, - setFeedURI: function LS_setFeedURI(container, feedURI) { - if (!feedURI) + setFeedURI: function LS_setFeedURI(aFolderId, aFeedURI) { + if (!aFeedURI) throw Cr.NS_ERROR_INVALID_ARG; - this._ans.setItemAnnotation(container, LMANNO_FEEDURI, feedURI.spec, 0, + this._ans.setItemAnnotation(aFolderId, LMANNO_FEEDURI, aFeedURI.spec, 0, this._ans.EXPIRE_NEVER); // now update our internal table - var livemarkIndex = this._getLivemarkIndex(container); - this._livemarks[livemarkIndex].feedURI = feedURI; + var livemarkIndex = this._getLivemarkIndex(aFolderId); + this._livemarks[livemarkIndex].feedURI = aFeedURI; }, reloadAllLivemarks: function LS_reloadAllLivemarks() { @@ -420,8 +439,8 @@ LivemarkService.prototype = { } }, - reloadLivemarkFolder: function LS_reloadLivemarkFolder(folderID) { - var livemarkIndex = this._getLivemarkIndex(folderID); + reloadLivemarkFolder: function LS_reloadLivemarkFolder(aFolderId) { + var livemarkIndex = this._getLivemarkIndex(aFolderId); this._updateLivemarkChildren(livemarkIndex, true); }, @@ -433,7 +452,9 @@ LivemarkService.prototype = { onItemVisited: function() { }, onItemMoved: function() { }, - onItemRemoved: function(aItemId, aParentFolder, aIndex) { + onItemRemoved: function(aItemId, aParentId, aIndex) { + // we don't need to remove annotations since itemAnnotations + // are already removed with the bookmark try { var livemarkIndex = this._getLivemarkIndex(aItemId); } @@ -446,38 +467,28 @@ LivemarkService.prototype = { // remove the livemark from the update array this._livemarks.splice(livemarkIndex, 1); - // check if we have more then one livemark for this address - // if exists we should not delete the annotation since it's still in use - var stillInUse = false; - stillInUse = this._livemarks.some( - function(mark) { return mark.feedURI.equals(livemark.feedURI) } - ); - if (!stillInUse) { - this._ans.removePageAnnotation(livemark.feedURI, LMANNO_EXPIRATION); - } - if (livemark.loadGroup) livemark.loadGroup.cancel(NS_BINDING_ABORTED); }, - createInstance: function LS_createInstance(outer, iid) { - if (outer != null) + createInstance: function LS_createInstance(aOuter, aIID) { + if (aOuter != null) throw Cr.NS_ERROR_NO_AGGREGATION; - return this.QueryInterface(iid); + return this.QueryInterface(aIID); }, - QueryInterface: function LS_QueryInterface(iid) { - if (iid.equals(Ci.nsILivemarkService) || - iid.equals(Ci.nsIFactory) || - iid.equals(Ci.nsINavBookmarkObserver) || - iid.equals(Ci.nsISupports)) + QueryInterface: function LS_QueryInterface(aIID) { + if (aIID.equals(Ci.nsILivemarkService) || + aIID.equals(Ci.nsIFactory) || + aIID.equals(Ci.nsINavBookmarkObserver) || + aIID.equals(Ci.nsISupports)) return this; throw Cr.NS_ERROR_NOT_IMPLEMENTED; } }; -function LivemarkLoadListener(livemark) { - this._livemark = livemark; +function LivemarkLoadListener(aLivemark) { + this._livemark = aLivemark; this._livemark.loadingId = -1; this._processor = null; this._isAborted = false; @@ -562,7 +573,7 @@ LivemarkLoadListener.prototype = { /** * See nsIFeedResultListener.idl */ - handleResult: function LLL_handleResult(result) { + handleResult: function LLL_handleResult(aResult) { if (this._isAborted) { if (this._livemark.loadingId != -1) { this._bms.removeItem(this._livemark.loadingId); @@ -574,7 +585,7 @@ LivemarkLoadListener.prototype = { } try { // The actual work is done in runBatched, see above. - this._bms.runInBatchMode(this, result); + this._bms.runInBatchMode(this, aResult); } finally { this._processor.listener = null; @@ -586,43 +597,42 @@ LivemarkLoadListener.prototype = { deleteLivemarkChildren: LivemarkService.prototype.deleteLivemarkChildren, insertLivemarkChild: - function LS_insertLivemarkChild(folderId, uri, title) { - var id = this._bms.insertBookmark(folderId, uri, this._bms.DEFAULT_INDEX, - title); + function LS_insertLivemarkChild(aFolderId, aUri, aTitle) { + this._bms.insertBookmark(aFolderId, aUri, this._bms.DEFAULT_INDEX, aTitle); }, /** * See nsIStreamListener.idl */ - onDataAvailable: function LLL_onDataAvailable(request, context, inputStream, - sourceOffset, count) { - this._processor.onDataAvailable(request, context, inputStream, - sourceOffset, count); + onDataAvailable: function LLL_onDataAvailable(aRequest, aContext, aInputStream, + aSourceOffset, aCount) { + this._processor.onDataAvailable(aRequest, aContext, aInputStream, + aSourceOffset, aCount); }, /** * See nsIRequestObserver.idl */ - onStartRequest: function LLL_onStartRequest(request, context) { + onStartRequest: function LLL_onStartRequest(aRequest, aContext) { if (this._isAborted) throw Cr.NS_ERROR_UNEXPECTED; - var channel = request.QueryInterface(Ci.nsIChannel); + var channel = aRequest.QueryInterface(Ci.nsIChannel); // 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); - this._processor.onStartRequest(request, context); + this._processor.onStartRequest(aRequest, aContext); }, /** * See nsIRequestObserver.idl */ - onStopRequest: function LLL_onStopRequest(request, context, status) { - if (!Components.isSuccessCode(status)) { - // Something went wrong; try to load again in a bit + onStopRequest: function LLL_onStopRequest(aRequest, aContext, aStatus) { + if (!Components.isSuccessCode(aStatus)) { + // Something went wrong, try to load again in a bit this._setResourceTTL(ERROR_EXPIRATION); this._isAborted = true; if (this._livemark.loadingId != -1) { @@ -635,21 +645,21 @@ LivemarkLoadListener.prototype = { } // Set an expiration on the livemark, for reloading the data try { - this._processor.onStopRequest(request, context, status); + this._processor.onStopRequest(aRequest, aContext, aStatus); // Calculate a new ttl - var channel = request.QueryInterface(Ci.nsICachingChannel); + var channel = aRequest.QueryInterface(Ci.nsICachingChannel); if (channel) { var entryInfo = channel.cacheToken.QueryInterface(Ci.nsICacheEntryInfo); if (entryInfo) { // nsICacheEntryInfo returns value as seconds, - // expiresTime stores as ms - var expiresTime = entryInfo.expirationTime * 1000; + // expireTime stores as milliseconds + var expireTime = entryInfo.expirationTime * 1000; var nowTime = Date.now(); - // note, expiresTime can be 0, see bug #383538 - if (expiresTime > nowTime) { - this._setResourceTTL(Math.max((expiresTime - nowTime), + // note, expireTime can be 0, see bug 383538 + if (expireTime > nowTime) { + this._setResourceTTL(Math.max((expireTime - nowTime), gExpiration)); return; } @@ -660,53 +670,53 @@ LivemarkLoadListener.prototype = { this._setResourceTTL(this._ttl); }, - _setResourceTTL: function LLL__setResourceTTL(milliseconds) { - var exptime = Date.now() + milliseconds; - this._ans.setPageAnnotation(this._livemark.feedURI, LMANNO_EXPIRATION, - exptime, 0, + _setResourceTTL: function LLL__setResourceTTL(aMilliseconds) { + var expireTime = Date.now() + aMilliseconds; + this._ans.setItemAnnotation(this._livemark.folderId, LMANNO_EXPIRATION, + expireTime, 0, Ci.nsIAnnotationService.EXPIRE_NEVER); }, /** * See nsIBadCertListener2 */ - notifyCertProblem: function LLL_certProblem(socketInfo, status, targetSite) { + notifyCertProblem: function LLL_certProblem(aSocketInfo, aStatus, aTargetSite) { return true; }, /** * See nsISSLErrorListener */ - notifySSLError: function LLL_SSLError(socketInfo, error, targetSite) { + notifySSLError: function LLL_SSLError(aSocketInfo, aError, aTargetSite) { return true; }, /** * See nsIInterfaceRequestor */ - getInterface: function LLL_getInterface(iid) { - return this.QueryInterface(iid); + getInterface: function LLL_getInterface(aIID) { + return this.QueryInterface(aIID); }, /** * See nsISupports.idl */ - QueryInterface: function LLL_QueryInterface(iid) { - if (iid.equals(Ci.nsIFeedResultListener) || - iid.equals(Ci.nsIStreamListener) || - iid.equals(Ci.nsIRequestObserver)|| - iid.equals(Ci.nsINavHistoryBatchCallback) || - iid.equals(Ci.nsIBadCertListener2) || - iid.equals(Ci.nsISSLErrorListener) || - iid.equals(Ci.nsIInterfaceRequestor) || - iid.equals(Ci.nsISupports)) + 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)) return this; throw Cr.NS_ERROR_NO_INTERFACE; }, } -function GenericComponentFactory(ctor) { - this._ctor = ctor; +function GenericComponentFactory(aCtor) { + this._ctor = aCtor; } GenericComponentFactory.prototype = { @@ -714,16 +724,16 @@ GenericComponentFactory.prototype = { _ctor: null, // nsIFactory - createInstance: function(outer, iid) { - if (outer != null) + createInstance: function(aOuter, aIID) { + if (aOuter != null) throw Cr.NS_ERROR_NO_AGGREGATION; - return (new this._ctor()).QueryInterface(iid); + return (new this._ctor()).QueryInterface(aIID); }, // nsISupports - QueryInterface: function(iid) { - if (iid.equals(Ci.nsIFactory) || - iid.equals(Ci.nsISupports)) + QueryInterface: function(aIID) { + if (aIID.equals(Ci.nsIFactory) || + aIID.equals(Ci.nsISupports)) return this; throw Cr.NS_ERROR_NO_INTERFACE; }, @@ -731,40 +741,40 @@ GenericComponentFactory.prototype = { }; var Module = { - QueryInterface: function(iid) { - if (iid.equals(Ci.nsIModule) || - iid.equals(Ci.nsISupports)) + QueryInterface: function(aIID) { + if (aIID.equals(Ci.nsIModule) || + aIID.equals(Ci.nsISupports)) return this; throw Cr.NS_ERROR_NO_INTERFACE; }, - getClassObject: function M_getClassObject(cm, cid, iid) { - if (!iid.equals(Ci.nsIFactory)) + getClassObject: function M_getClassObject(aCompMgr, aCID, aIID) { + if (!aIID.equals(Ci.nsIFactory)) throw Cr.NS_ERROR_NOT_IMPLEMENTED; - if (cid.equals(LS_CLASSID)) + if (aCID.equals(LS_CLASSID)) return new GenericComponentFactory(LivemarkService); throw Cr.NS_ERROR_NO_INTERFACE; }, - registerSelf: function(cm, file, location, type) { - var cr = cm.QueryInterface(Ci.nsIComponentRegistrar); + registerSelf: function(aCompMgr, aFile, aLocation, aType) { + var cr = aCompMgr.QueryInterface(Ci.nsIComponentRegistrar); cr.registerFactoryLocation(LS_CLASSID, LS_CLASSNAME, - LS_CONTRACTID, file, location, type); + LS_CONTRACTID, aFile, aLocation, aType); }, - unregisterSelf: function M_unregisterSelf(cm, location, type) { - var cr = cm.QueryInterface(Ci.nsIComponentRegistrar); - cr.unregisterFactoryLocation(LS_CLASSID, location); + unregisterSelf: function M_unregisterSelf(aCompMgr, aLocation, aType) { + var cr = aCompMgr.QueryInterface(Ci.nsIComponentRegistrar); + cr.unregisterFactoryLocation(LS_CLASSID, aLocation); }, - canUnload: function M_canUnload(cm) { + canUnload: function M_canUnload(aCompMgr) { return true; } }; -function NSGetModule(cm, file) { +function NSGetModule(aCompMgr, aFile) { return Module; } diff --git a/toolkit/components/places/src/nsNavHistory.cpp b/toolkit/components/places/src/nsNavHistory.cpp index 0af5cd36c62..5b2456d1e82 100644 --- a/toolkit/components/places/src/nsNavHistory.cpp +++ b/toolkit/components/places/src/nsNavHistory.cpp @@ -4422,6 +4422,17 @@ nsNavHistory::OnIdle() NS_ENSURE_SUCCESS(rv, rv); } + // Remove dangling livemark annotations + // we have moved expiration pageAnnotations to itemAnnotations + // we must remove pageAnnotations to allow expire do the cleanup + // see bug 388716 + // XXX REMOVE ME AFTER FINAL + rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( + "DELETE FROM moz_annos WHERE id IN (SELECT a.id FROM moz_annos a " + "JOIN moz_anno_attributes n ON a.anno_attribute_id = n.id " + "WHERE n.name = 'livemark/expiration')")); + NS_ENSURE_SUCCESS(rv, rv); + #if 0 // Currently commented out because vacuum is very slow // see bug #390244 for more details.