diff --git a/rdf/base/idl/nsIRDFRemoteDataSource.idl b/rdf/base/idl/nsIRDFRemoteDataSource.idl index 123b535b3376..691f1b7e7b71 100644 --- a/rdf/base/idl/nsIRDFRemoteDataSource.idl +++ b/rdf/base/idl/nsIRDFRemoteDataSource.idl @@ -71,5 +71,6 @@ interface nsIRDFRemoteDataSource : nsISupports * permanent storage, if applicable. */ void Flush(); + void FlushTo(in string aURI); }; diff --git a/rdf/base/src/nsRDFXMLDataSource.cpp b/rdf/base/src/nsRDFXMLDataSource.cpp index 381f754cfbdd..158384104675 100644 --- a/rdf/base/src/nsRDFXMLDataSource.cpp +++ b/rdf/base/src/nsRDFXMLDataSource.cpp @@ -242,6 +242,7 @@ protected: nsresult Init(); RDFXMLDataSourceImpl(void); virtual ~RDFXMLDataSourceImpl(void); + nsresult rdfXMLFlush(nsIURI *aURI); friend nsresult NS_NewRDFXMLDataSource(nsIRDFDataSource** aResult); @@ -429,6 +430,10 @@ protected: PRInt32 RDFXMLDataSourceImpl::gRefCnt = 0; nsIRDFService* RDFXMLDataSourceImpl::gRDFService; +static const char kFileURIPrefix[] = "file:"; +static const char kResourceURIPrefix[] = "resource:"; + + //---------------------------------------------------------------------- nsresult @@ -624,9 +629,6 @@ RDFXMLDataSourceImpl::GetLoaded(PRBool* _result) NS_IMETHODIMP RDFXMLDataSourceImpl::Init(const char* uri) { -static const char kFileURIPrefix[] = "file:"; -static const char kResourceURIPrefix[] = "resource:"; - NS_PRECONDITION(mInner != nsnull, "not initialized"); if (! mInner) return NS_ERROR_OUT_OF_MEMORY; @@ -781,18 +783,10 @@ RDFXMLDataSourceImpl::Move(nsIRDFResource* aOldSource, return rv; } -NS_IMETHODIMP -RDFXMLDataSourceImpl::Flush(void) + +nsresult +RDFXMLDataSourceImpl::rdfXMLFlush(nsIURI *aURI) { - if (!mIsWritable || !mIsDirty) - return NS_OK; - - NS_PRECONDITION(mOriginalURLSpec != nsnull, "not initialized"); - if (! mOriginalURLSpec) - return NS_ERROR_NOT_INITIALIZED; - - PR_LOG(gLog, PR_LOG_ALWAYS, - ("rdfxml[%p] flush(%s)", this, mOriginalURLSpec.get())); nsresult rv; @@ -810,7 +804,7 @@ RDFXMLDataSourceImpl::Flush(void) // Is it a file? If so, we can write to it. Some day, it'd be nice // if we didn't care what kind of stream this was... - nsCOMPtr fileURL = do_QueryInterface(mURL); + nsCOMPtr fileURL = do_QueryInterface(aURI); if (fileURL) { nsCOMPtr file; @@ -831,12 +825,57 @@ RDFXMLDataSourceImpl::Flush(void) } } - mIsDirty = PR_FALSE; - done: return NS_OK; } + +NS_IMETHODIMP +RDFXMLDataSourceImpl::FlushTo(const char *aURI) +{ + NS_PRECONDITION(aURI != nsnull, "not initialized"); + if (!aURI) + return NS_ERROR_NULL_POINTER; + + // XXX this is a hack: any "file:" URI is considered writable. All + // others are considered read-only. + if ((PL_strncmp(aURI, kFileURIPrefix, sizeof(kFileURIPrefix) - 1) != 0) && + (PL_strncmp(aURI, kResourceURIPrefix, sizeof(kResourceURIPrefix) - 1) != 0)) + { + return NS_ERROR_ILLEGAL_VALUE; + } + + nsCOMPtr url; + nsresult rv = NS_NewURI(getter_AddRefs(url), aURI); + if (NS_FAILED(rv)) + return rv; + rv = rdfXMLFlush(url); + return rv; +} + + +NS_IMETHODIMP +RDFXMLDataSourceImpl::Flush(void) +{ + if (!mIsWritable || !mIsDirty) + return NS_OK; + + NS_PRECONDITION(mOriginalURLSpec != nsnull, "not initialized"); + if (! mOriginalURLSpec) + return NS_ERROR_NOT_INITIALIZED; + + PR_LOG(gLog, PR_LOG_ALWAYS, + ("rdfxml[%p] flush(%s)", this, mOriginalURLSpec.get())); + + nsresult rv; + if (NS_SUCCEEDED(rv = rdfXMLFlush(mURL))) + { + mIsDirty = PR_FALSE; + } + return rv; +} + + //---------------------------------------------------------------------- // // nsIRDFXMLDataSource methods diff --git a/rdf/datasource/src/nsLocalStore.cpp b/rdf/datasource/src/nsLocalStore.cpp index 909d3f6bb099..2ec7d3f89f9c 100644 --- a/rdf/datasource/src/nsLocalStore.cpp +++ b/rdf/datasource/src/nsLocalStore.cpp @@ -217,6 +217,7 @@ public: NS_IMETHOD GetLoaded(PRBool* _result); NS_IMETHOD Init(const char *uri); NS_IMETHOD Flush(); + NS_IMETHOD FlushTo(const char *aURI); NS_IMETHOD Refresh(PRBool sync); // nsIObserver @@ -346,6 +347,13 @@ LocalStoreImpl::Flush() return remote->Flush(); } +NS_IMETHODIMP +LocalStoreImpl::FlushTo(const char *aURI) +{ + // Do not ever implement this (security) + return NS_ERROR_NOT_IMPLEMENTED; +} + NS_IMETHODIMP LocalStoreImpl::Refresh(PRBool sync) { diff --git a/xpfe/components/bookmarks/resources/bookmarks.xml b/xpfe/components/bookmarks/resources/bookmarks.xml index 26f5cf716cf5..ef3f9d039b66 100644 --- a/xpfe/components/bookmarks/resources/bookmarks.xml +++ b/xpfe/components/bookmarks/resources/bookmarks.xml @@ -1700,8 +1700,10 @@ const kFilePicker = Components.classes[kFilePickerContractID].createInstance(kFilePickerIID); const kTitle = this._bundle.GetStringFromName("EnterExport"); + const kRDFExportIndex = 2; kFilePicker.init(window, kTitle, kFilePickerIID["modeSave"]); kFilePicker.appendFilters(kFilePickerIID.filterHTML | kFilePickerIID.filterAll); + kFilePicker.appendFilter("RDF", "*.rdf"); // index 2: kRDFExportIndex kFilePicker.defaultString = "bookmarks.html"; var fileName; if (kFilePicker.show() != kFilePickerIID.returnCancel) { @@ -1720,7 +1722,9 @@ catch(ex) { seln = this.rdf.GetResource("NC:BookmarksRoot").Value; } - var args = [{ property: this.NC_NS + "URL", literal: fileName}]; + var args = [{ property: this.NC_NS + "URL", literal: fileName}, + { property: this.RDF_NS + "type", + literal: (kFilePicker.filterIndex == kRDFExportIndex) ? "RDF" : "HTML"}]; this.doBookmarksCommand(seln, this.NC_NS_CMD + "export", args); ]]> diff --git a/xpfe/components/bookmarks/src/nsBookmarksService.cpp b/xpfe/components/bookmarks/src/nsBookmarksService.cpp index 6045bf17a7f6..e2b03e1e1ac2 100644 --- a/xpfe/components/bookmarks/src/nsBookmarksService.cpp +++ b/xpfe/components/bookmarks/src/nsBookmarksService.cpp @@ -4493,13 +4493,39 @@ nsBookmarksService::exportBookmarks(nsISupportsArray *aArguments) pathLiteral->GetValueConst(&pathUni); if (!pathUni) return(NS_ERROR_NULL_POINTER); - nsAutoString fileName(pathUni); - nsFileURL fileURL(fileName); - nsFileSpec fileSpec(fileURL); + // determine file type to export; default to HTML unless told otherwise + nsAutoString formatStr; + if (NS_SUCCEEDED(rv = getArgumentN(aArguments, kRDF_type, 0, getter_AddRefs(aNode)))) + { + nsCOMPtr exportType = do_QueryInterface(aNode); + if (exportType) + { + const PRUnichar *exportUni = NULL; + exportType->GetValueConst(&exportUni); + if (exportUni) + { + formatStr = exportUni; + } + } + } - // write 'em out - rv = WriteBookmarks(&fileSpec, mInner, kNC_BookmarksRoot); + nsAutoString fileName(pathUni); + nsFileURL fileURL(fileName); + if (formatStr.EqualsIgnoreCase("RDF")) + { + nsCOMPtr remoteDS = do_QueryInterface(mInner); + if (remoteDS) + { + remoteDS->FlushTo(fileURL.GetURLString()); + } + } + else + { + nsFileSpec fileSpec(fileURL); + // write 'em out + rv = WriteBookmarks(&fileSpec, mInner, kNC_BookmarksRoot); + } return(rv); } @@ -4639,6 +4665,15 @@ nsBookmarksService::Flush() +NS_IMETHODIMP +nsBookmarksService::FlushTo(const char *aURI) +{ + // Do not ever implement this (security) + return(NS_ERROR_NOT_IMPLEMENTED); +} + + + //////////////////////////////////////////////////////////////////////// // Implementation methods @@ -4769,9 +4804,12 @@ nsBookmarksService::initDatasource() // so we need to forget about any previous bookmarks NS_IF_RELEASE(mInner); - rv = CallCreateInstance(kRDFInMemoryDataSourceCID, &mInner); - if (NS_FAILED(rv)) - return rv; + // create an xml-ds instead of an in-memory ds to allow for RDF serialization out + nsCOMPtr temp; + temp = do_CreateInstance(NS_RDF_DATASOURCE_CONTRACTID_PREFIX "xml-datasource", &rv); + if (NS_FAILED(rv)) return rv; + mInner = temp; + NS_ADDREF(mInner); rv = mInner->AddObserver(this); if (NS_FAILED(rv)) return rv; @@ -4800,6 +4838,11 @@ nsBookmarksService::LoadBookmarks() PRBool foundIERoot = PR_FALSE; + nsCOMPtr prefSvc(do_GetService(NS_PREF_CONTRACTID)); + nsCOMPtr bookmarksPrefs; + if (prefSvc) + prefSvc->GetBranch("browser.bookmarks.", getter_AddRefs(bookmarksPrefs)); + #ifdef DEBUG PRTime now; #ifdef XP_MAC @@ -4810,11 +4853,6 @@ nsBookmarksService::LoadBookmarks() printf("Start reading in bookmarks.html\n"); #endif - nsCOMPtr prefSvc(do_GetService(NS_PREF_CONTRACTID)); - nsCOMPtr bookmarksPrefs; - if (prefSvc) - prefSvc->GetBranch("browser.bookmarks.", getter_AddRefs(bookmarksPrefs)); - // System Bookmarks Strategy // // * By default, we do a one-off import of system bookmarks when the browser diff --git a/xpfe/components/history/src/nsGlobalHistory.cpp b/xpfe/components/history/src/nsGlobalHistory.cpp index f4516962e841..ca20b626cb5a 100644 --- a/xpfe/components/history/src/nsGlobalHistory.cpp +++ b/xpfe/components/history/src/nsGlobalHistory.cpp @@ -2209,6 +2209,13 @@ nsGlobalHistory::Flush() return Commit(kLargeCommit); } +NS_IMETHODIMP +nsGlobalHistory::FlushTo(const char *aURI) +{ + // Do not ever implement this (security) + return(NS_ERROR_NOT_IMPLEMENTED); +} + NS_IMETHODIMP nsGlobalHistory::StartBatchUpdate() {