diff --git a/suite/browser/public/nsISearchService.idl b/suite/browser/public/nsISearchService.idl index bf64fb85ae5..b10d13f2c09 100755 --- a/suite/browser/public/nsISearchService.idl +++ b/suite/browser/public/nsISearchService.idl @@ -27,6 +27,7 @@ */ #include "nsISupports.idl" +#include "nsIRDFDataSource.idl" [scriptable, uuid(1222e6f0-a5e3-11d2-8b7c-00805f8a7db6)] interface nsILocalSearchService : nsISupports @@ -36,7 +37,8 @@ interface nsILocalSearchService : nsISupports [scriptable, uuid(6bd1d803-1c67-11d3-9820-ed1b357eb3c4)] interface nsIInternetSearchService : nsISupports { - void ClearResultSearchSites(); + void ClearResultSearchSites(); + nsIRDFDataSource GetCategoryDataSource(); }; %{C++ diff --git a/suite/browser/src/nsInternetSearchService.cpp b/suite/browser/src/nsInternetSearchService.cpp index 926751325ab..580c0a7d0e4 100755 --- a/suite/browser/src/nsInternetSearchService.cpp +++ b/suite/browser/src/nsInternetSearchService.cpp @@ -86,11 +86,15 @@ static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID); static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); +static NS_DEFINE_CID(kRDFXMLDataSourceCID, NS_RDFXMLDATASOURCE_CID); -static const char kURINC_SearchRoot[] = "NC:SearchEngineRoot"; -static const char kURINC_SearchResultsSitesRoot[] = "NC:SearchResultsSitesRoot"; -static const char kURINC_LastSearchRoot[] = "NC:LastSearchRoot"; -static const char kURINC_SearchResultsAnonymous[] = "NC:SearchResultsAnonymous"; +static const char kURINC_SearchEngineRoot[] = "NC:SearchEngineRoot"; +static const char kURINC_SearchResultsSitesRoot[] = "NC:SearchResultsSitesRoot"; +static const char kURINC_LastSearchRoot[] = "NC:LastSearchRoot"; +static const char kURINC_SearchCategoryRoot[] = "NC:SearchCategoryRoot"; +static const char kURINC_SearchCategoryPrefix[] = "NC:SearchCategory?category="; +static const char kURINC_SearchCategoryEnginePrefix[] = "NC:SearchCategory?engine="; +static const char kURINC_SearchResultsAnonymous[] = "NC:SearchResultsAnonymous"; @@ -169,8 +173,9 @@ private: PRBool mEngineListBuilt; // pseudo-constants - static nsIRDFResource *kNC_SearchRoot; + static nsIRDFResource *kNC_SearchEngineRoot; static nsIRDFResource *kNC_LastSearchRoot; + static nsIRDFResource *kNC_SearchCategoryRoot; static nsIRDFResource *kNC_SearchResultsSitesRoot; static nsIRDFResource *kNC_Ref; static nsIRDFResource *kNC_Child; @@ -187,14 +192,20 @@ private: protected: static nsIRDFDataSource *mInner; + static nsCOMPtr categoryDataSource; + friend NS_IMETHODIMP NS_NewInternetSearchService(nsISupports* aOuter, REFNSIID aIID, void** aResult); // helper methods PRBool isEngineURI(nsIRDFResource* aResource); PRBool isSearchURI(nsIRDFResource* aResource); + PRBool isSearchCategoryURI(nsIRDFResource* aResource); + PRBool isSearchCategoryEngineURI(nsIRDFResource* aResource); + nsresult resolveSearchCategoryEngineURI(nsIRDFResource *source, nsIRDFResource **trueEngine); nsresult BeginSearchRequest(nsIRDFResource *source, PRBool doNetworkRequest); nsresult DoSearch(nsIRDFResource *source, nsIRDFResource *engine, nsString text); nsresult GetSearchEngineList(nsFileSpec spec); + nsresult GetCategoryList(); nsresult GetSearchFolder(nsFileSpec &spec); nsresult ReadFileContents(nsFileSpec baseFilename, nsString & sourceContents); static nsresult GetData(nsString data, char *sectionToFind, char *attribToFind, nsString &value); @@ -282,9 +293,11 @@ static InternetSearchDataSource *gInternetSearchDataSource = nsnull; PRInt32 InternetSearchDataSource::gRefCnt; nsIRDFDataSource *InternetSearchDataSource::mInner = nsnull; +nsCOMPtr InternetSearchDataSource::categoryDataSource; -nsIRDFResource *InternetSearchDataSource::kNC_SearchRoot; +nsIRDFResource *InternetSearchDataSource::kNC_SearchEngineRoot; nsIRDFResource *InternetSearchDataSource::kNC_LastSearchRoot; +nsIRDFResource *InternetSearchDataSource::kNC_SearchCategoryRoot; nsIRDFResource *InternetSearchDataSource::kNC_SearchResultsSitesRoot; nsIRDFResource *InternetSearchDataSource::kNC_Ref; nsIRDFResource *InternetSearchDataSource::kNC_Child; @@ -352,6 +365,65 @@ InternetSearchDataSource::isSearchURI(nsIRDFResource *r) +PRBool +InternetSearchDataSource::isSearchCategoryURI(nsIRDFResource *r) +{ + PRBool isSearchCategoryURIFlag = PR_FALSE; + const char *uri = nsnull; + + r->GetValueConst(&uri); + if ((uri) && (!strncmp(uri, kURINC_SearchCategoryPrefix, sizeof(kURINC_SearchCategoryPrefix) - 1))) + { + isSearchCategoryURIFlag = PR_TRUE; + } + return(isSearchCategoryURIFlag); +} + + + +PRBool +InternetSearchDataSource::isSearchCategoryEngineURI(nsIRDFResource *r) +{ + PRBool isSearchCategoryEngineURIFlag = PR_FALSE; + const char *uri = nsnull; + + r->GetValueConst(&uri); + if ((uri) && (!strncmp(uri, kURINC_SearchCategoryEnginePrefix, sizeof(kURINC_SearchCategoryEnginePrefix) - 1))) + { + isSearchCategoryEngineURIFlag = PR_TRUE; + } + return(isSearchCategoryEngineURIFlag); +} + + + +nsresult +InternetSearchDataSource::resolveSearchCategoryEngineURI(nsIRDFResource *engine, nsIRDFResource **trueEngine) +{ + *trueEngine = nsnull; + + if ((!categoryDataSource) || (!mInner)) return(NS_ERROR_UNEXPECTED); + + nsresult rv; + nsCOMPtr catNode; + rv = categoryDataSource->GetTarget(engine, kNC_Name, PR_TRUE, getter_AddRefs(catNode)); + if (NS_FAILED(rv)) return(rv); + + nsCOMPtr catName = do_QueryInterface(catNode); + if (!catName) return(NS_ERROR_UNEXPECTED); + + nsCOMPtr catSrc; + rv = mInner->GetSource(kNC_Name, catName, PR_TRUE, getter_AddRefs(catSrc)); + if (NS_FAILED(rv)) return(rv); + if (!catSrc) return(NS_ERROR_UNEXPECTED); + + *trueEngine = catSrc; + NS_IF_ADDREF(*trueEngine); + return(NS_OK); +} + + + InternetSearchDataSource::InternetSearchDataSource(void) { NS_INIT_REFCNT(); @@ -363,20 +435,21 @@ InternetSearchDataSource::InternetSearchDataSource(void) PR_ASSERT(NS_SUCCEEDED(rv)); - gRDFService->GetResource(kURINC_SearchRoot, &kNC_SearchRoot); - gRDFService->GetResource(kURINC_LastSearchRoot, &kNC_LastSearchRoot); - gRDFService->GetResource(kURINC_SearchResultsSitesRoot, &kNC_SearchResultsSitesRoot); - gRDFService->GetResource(NC_NAMESPACE_URI "ref", &kNC_Ref); - gRDFService->GetResource(NC_NAMESPACE_URI "child", &kNC_Child); - gRDFService->GetResource(NC_NAMESPACE_URI "data", &kNC_Data); - gRDFService->GetResource(NC_NAMESPACE_URI "Name", &kNC_Name); - gRDFService->GetResource(NC_NAMESPACE_URI "URL", &kNC_URL); - gRDFService->GetResource(RDF_NAMESPACE_URI "instanceOf", &kRDF_InstanceOf); - gRDFService->GetResource(RDF_NAMESPACE_URI "type", &kRDF_type); - gRDFService->GetResource(NC_NAMESPACE_URI "loading", &kNC_loading); - gRDFService->GetResource(NC_NAMESPACE_URI "HTML", &kNC_HTML); - gRDFService->GetResource(NC_NAMESPACE_URI "Icon", &kNC_Icon); - gRDFService->GetResource(NC_NAMESPACE_URI "StatusIcon", &kNC_StatusIcon); + gRDFService->GetResource(kURINC_SearchEngineRoot, &kNC_SearchEngineRoot); + gRDFService->GetResource(kURINC_LastSearchRoot, &kNC_LastSearchRoot); + gRDFService->GetResource(kURINC_SearchResultsSitesRoot, &kNC_SearchResultsSitesRoot); + gRDFService->GetResource(NC_NAMESPACE_URI "SearchCategoryRoot", &kNC_SearchCategoryRoot); + gRDFService->GetResource(NC_NAMESPACE_URI "ref", &kNC_Ref); + gRDFService->GetResource(NC_NAMESPACE_URI "child", &kNC_Child); + gRDFService->GetResource(NC_NAMESPACE_URI "data", &kNC_Data); + gRDFService->GetResource(NC_NAMESPACE_URI "Name", &kNC_Name); + gRDFService->GetResource(NC_NAMESPACE_URI "URL", &kNC_URL); + gRDFService->GetResource(RDF_NAMESPACE_URI "instanceOf", &kRDF_InstanceOf); + gRDFService->GetResource(RDF_NAMESPACE_URI "type", &kRDF_type); + gRDFService->GetResource(NC_NAMESPACE_URI "loading", &kNC_loading); + gRDFService->GetResource(NC_NAMESPACE_URI "HTML", &kNC_HTML); + gRDFService->GetResource(NC_NAMESPACE_URI "Icon", &kNC_Icon); + gRDFService->GetResource(NC_NAMESPACE_URI "StatusIcon", &kNC_StatusIcon); gInternetSearchDataSource = this; } @@ -388,8 +461,9 @@ InternetSearchDataSource::~InternetSearchDataSource (void) { if (--gRefCnt == 0) { - NS_IF_RELEASE(kNC_SearchRoot); + NS_IF_RELEASE(kNC_SearchEngineRoot); NS_IF_RELEASE(kNC_LastSearchRoot); + NS_IF_RELEASE(kNC_SearchCategoryRoot); NS_IF_RELEASE(kNC_SearchResultsSitesRoot); NS_IF_RELEASE(kNC_Ref); NS_IF_RELEASE(kNC_Child); @@ -515,7 +589,31 @@ InternetSearchDataSource::GetTarget(nsIRDFResource *source, // we only have positive assertions in the internet search data source. if (! tv) return(rv); - + + if ((isSearchCategoryURI(source)) && (categoryDataSource)) + { + const char *uri = nsnull; + source->GetValueConst(&uri); + if (!uri) return(NS_ERROR_UNEXPECTED); + nsAutoString catURI(uri); + + nsCOMPtr category; + if (NS_FAILED(rv = gRDFService->GetResource(nsCAutoString(catURI), + getter_AddRefs(category)))) + return(rv); + + rv = categoryDataSource->GetTarget(category, property, tv, target); + return(rv); + } + + if (isSearchCategoryEngineURI(source)) + { + nsCOMPtr trueEngine; + rv = resolveSearchCategoryEngineURI(source, getter_AddRefs(trueEngine)); + if (NS_FAILED(rv)) return(rv); + source = trueEngine; + } + if (mInner) { rv = mInner->GetTarget(source, property, tv, target); @@ -549,18 +647,47 @@ InternetSearchDataSource::GetTargets(nsIRDFResource *source, if (! tv) return(rv); + if ((isSearchCategoryURI(source)) && (categoryDataSource)) + { + const char *uri = nsnull; + source->GetValueConst(&uri); + if (!uri) return(NS_ERROR_UNEXPECTED); + nsAutoString catURI(uri); + + nsCOMPtr category; + if (NS_FAILED(rv = gRDFService->GetResource(nsCAutoString(catURI), + getter_AddRefs(category)))) + return(rv); + + rv = categoryDataSource->GetTargets(category, property, tv, targets); + return(rv); + } + + if (isSearchCategoryEngineURI(source)) + { + nsCOMPtr trueEngine; + rv = resolveSearchCategoryEngineURI(source, getter_AddRefs(trueEngine)); + if (NS_FAILED(rv)) return(rv); + source = trueEngine; + } + if (mInner) { // defer search engine discovery until needed; small startup time improvement - if (((source == kNC_SearchRoot) || isSearchURI(source)) && (property == kNC_Child) + if (((source == kNC_SearchEngineRoot) || isSearchURI(source)) && (property == kNC_Child) && (mEngineListBuilt == PR_FALSE)) { + mEngineListBuilt = PR_TRUE; + // get available search engines nsFileSpec nativeDir; if (NS_SUCCEEDED(rv = GetSearchFolder(nativeDir))) { rv = GetSearchEngineList(nativeDir); - mEngineListBuilt = PR_TRUE; + + // read in category list + rv = GetCategoryList(); + #ifdef XP_MAC // on Mac, use system's search files too nsSpecialSystemDirectory searchSitesDir(nsSpecialSystemDirectory::Mac_InternetSearchDirectory); @@ -596,6 +723,40 @@ InternetSearchDataSource::GetTargets(nsIRDFResource *source, +nsresult +InternetSearchDataSource::GetCategoryList() +{ + nsIRDFDataSource *ds = nsnull; + nsresult rv = nsComponentManager::CreateInstance(kRDFXMLDataSourceCID, + nsnull, NS_GET_IID(nsIRDFDataSource), (void**) &ds); + if (NS_FAILED(rv)) return(rv); + if (!ds) return(NS_ERROR_UNEXPECTED); + + categoryDataSource = do_QueryInterface(ds); + NS_RELEASE(ds); + ds = nsnull; + if (!categoryDataSource) return(NS_ERROR_UNEXPECTED); + + nsCOMPtr remoteCategoryDataSource = do_QueryInterface(categoryDataSource); + if (!remoteCategoryDataSource) return(NS_ERROR_UNEXPECTED); + + // XXX should check in user's profile directory first, + // and fallback to the default file + + nsFileSpec searchDir; + if (NS_FAILED(rv = GetSearchFolder(searchDir))) return(rv); + searchDir += "category.rdf"; + + nsFileURL fileURL(searchDir); + if (NS_FAILED(rv = remoteCategoryDataSource->Init(fileURL.GetURLString()))) return(rv); + + // synchronous read + rv = remoteCategoryDataSource->Refresh(PR_TRUE); + return(rv); +} + + + NS_IMETHODIMP InternetSearchDataSource::Assert(nsIRDFResource *source, nsIRDFResource *property, @@ -703,7 +864,7 @@ InternetSearchDataSource::ArcLabelsOut(nsIRDFResource *source, nsresult rv; - if ((source == kNC_SearchRoot) || (source == kNC_LastSearchRoot) || isSearchURI(source)) + if ((source == kNC_SearchEngineRoot) || (source == kNC_LastSearchRoot) || isSearchURI(source)) { nsCOMPtr array; rv = NS_NewISupportsArray(getter_AddRefs(array)); @@ -719,7 +880,31 @@ InternetSearchDataSource::ArcLabelsOut(nsIRDFResource *source, *labels = result; return(NS_OK); } - + + if ((isSearchCategoryURI(source)) && (categoryDataSource)) + { + const char *uri = nsnull; + source->GetValueConst(&uri); + if (!uri) return(NS_ERROR_UNEXPECTED); + nsAutoString catURI(uri); + + nsCOMPtr category; + if (NS_FAILED(rv = gRDFService->GetResource(nsCAutoString(catURI), + getter_AddRefs(category)))) + return(rv); + + rv = categoryDataSource->ArcLabelsOut(category, labels); + return(rv); + } + + if (isSearchCategoryEngineURI(source)) + { + nsCOMPtr trueEngine; + rv = resolveSearchCategoryEngineURI(source, getter_AddRefs(trueEngine)); + if (NS_FAILED(rv) || (!trueEngine)) return(rv); + source = trueEngine; + } + if (mInner) { rv = mInner->ArcLabelsOut(source, labels); @@ -877,6 +1062,31 @@ InternetSearchDataSource::ClearResultSearchSites(void) +NS_IMETHODIMP +InternetSearchDataSource::GetCategoryDataSource(nsIRDFDataSource **ds) +{ + nsresult rv; + + if (!categoryDataSource) + { + if (NS_FAILED(rv = GetCategoryList())) + { + *ds = nsnull; + return(rv); + } + } + if (categoryDataSource) + { + *ds = categoryDataSource.get(); + NS_IF_ADDREF(*ds); + return(NS_OK); + } + *ds = nsnull; + return(NS_ERROR_FAILURE); +} + + + nsresult InternetSearchDataSource::BeginSearchRequest(nsIRDFResource *source, PRBool doNetworkRequest) { @@ -1006,7 +1216,8 @@ InternetSearchDataSource::BeginSearchRequest(nsIRDFResource *source, PRBool doNe { if (attrib.EqualsIgnoreCase("engine")) { - if (value.Find(kEngineProtocol) == 0) + if ((value.Find(kEngineProtocol) == 0) || + (value.Find(kURINC_SearchCategoryEnginePrefix) == 0)) { char *val = value.ToNewCString(); if (val) @@ -1039,6 +1250,18 @@ InternetSearchDataSource::BeginSearchRequest(nsIRDFResource *source, PRBool doNe baseFilename = nsnull; if (!engine) continue; + // if its a engine from a search category, then get its "#Name", + // and map from that back to the real engine reference; if an + // error occurs, finish processing the rest of the engines, + // don't just break/return out + if (isSearchCategoryEngineURI(engine)) + { + nsCOMPtr trueEngine; + rv = resolveSearchCategoryEngineURI(engine, getter_AddRefs(trueEngine)); + if (NS_FAILED(rv) || (!trueEngine)) continue; + engine = trueEngine; + } + // mark this as a search site if (mInner) { @@ -1318,7 +1541,7 @@ InternetSearchDataSource::GetSearchEngineList(nsFileSpec nativeDir) uri.Left(temp, uri.Length()-4); temp += ".gif"; const nsFileSpec gifIconFile(temp); - if ((gifIconFile.Exists()) && (gifIconFile.IsFile())) + if (gifIconFile.IsFile()) { nsFileURL gifIconFileURL(gifIconFile); iconURL = gifIconFileURL.GetURLString(); @@ -1326,7 +1549,7 @@ InternetSearchDataSource::GetSearchEngineList(nsFileSpec nativeDir) uri.Left(temp, uri.Length()-4); temp += ".jpg"; const nsFileSpec jpgIconFile(temp); - if ((jpgIconFile.Exists()) && (jpgIconFile.IsFile())) + if (jpgIconFile.IsFile()) { nsFileURL jpgIconFileURL(jpgIconFile); iconURL = jpgIconFileURL.GetURLString(); @@ -1334,7 +1557,7 @@ InternetSearchDataSource::GetSearchEngineList(nsFileSpec nativeDir) uri.Left(temp, uri.Length()-4); temp += ".jpeg"; const nsFileSpec jpegIconFile(temp); - if ((jpegIconFile.Exists()) && (jpegIconFile.IsFile())) + if (jpegIconFile.IsFile()) { nsFileURL jpegIconFileURL(jpegIconFile); iconURL = jpegIconFileURL.GetURLString(); @@ -1342,7 +1565,7 @@ InternetSearchDataSource::GetSearchEngineList(nsFileSpec nativeDir) uri.Left(temp, uri.Length()-4); temp += ".png"; const nsFileSpec pngIconFile(temp); - if ((pngIconFile.Exists()) && (pngIconFile.IsFile())) + if (pngIconFile.IsFile()) { nsFileURL pngIconFileURL(pngIconFile); iconURL = pngIconFileURL.GetURLString(); @@ -1430,7 +1653,7 @@ InternetSearchDataSource::GetSearchEngineList(nsFileSpec nativeDir) } // Note: add the child relationship last - mInner->Assert(kNC_SearchRoot, kNC_Child, searchRes, PR_TRUE); + mInner->Assert(kNC_SearchEngineRoot, kNC_Child, searchRes, PR_TRUE); } nsCRT::free(searchURI); searchURI = nsnull; diff --git a/suite/common/search/internetresults.js b/suite/common/search/internetresults.js index 5f3e3c13c14..b6bca15ce13 100644 --- a/suite/common/search/internetresults.js +++ b/suite/common/search/internetresults.js @@ -12,6 +12,8 @@ function onLoadInternetResults() return(true); } + + function doEngineClick(node) { dump("doEngineClick entered.\n"); @@ -66,7 +68,7 @@ function doEngineClick(node) } } - if (html != "") + if ((html) && (html != "")) { var doc = window.frames[0].document; doc.open("text/html", "replace"); @@ -80,6 +82,8 @@ function doEngineClick(node) } + + function doResultClick(node) { var theID = node.getAttribute("id"); diff --git a/xpfe/components/search/datasets/MANIFEST b/xpfe/components/search/datasets/MANIFEST index 64aa84429b1..f2035953845 100644 --- a/xpfe/components/search/datasets/MANIFEST +++ b/xpfe/components/search/datasets/MANIFEST @@ -1,3 +1,4 @@ +category.rdf AOL_NetFind.gif AOL_NetFind.src Excite.gif diff --git a/xpfe/components/search/datasets/Makefile.in b/xpfe/components/search/datasets/Makefile.in index 5c0cca046c2..e40d099898b 100644 --- a/xpfe/components/search/datasets/Makefile.in +++ b/xpfe/components/search/datasets/Makefile.in @@ -27,6 +27,7 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk FILES = \ + category.rdf \ AOL_NetFind.gif \ AOL_NetFind.src \ Excite.gif \ diff --git a/xpfe/components/search/datasets/category.rdf b/xpfe/components/search/datasets/category.rdf new file mode 100755 index 00000000000..7bc3290cddb --- /dev/null +++ b/xpfe/components/search/datasets/category.rdf @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + Internet + + + + Shopping + + + + People + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AOL Netfind + + + + Excite + + + + Google! + + + + GoTo.com + + + + Hotbot + + + + LookSmart + + + + Lycos + + + + Netscape Open Directory + + + + Snap.com + + + + diff --git a/xpfe/components/search/datasets/makefile.win b/xpfe/components/search/datasets/makefile.win index 1ef751b840c..1fdaf3f18a5 100644 --- a/xpfe/components/search/datasets/makefile.win +++ b/xpfe/components/search/datasets/makefile.win @@ -24,6 +24,7 @@ DEPTH=..\..\..\.. include <$(DEPTH)\config\rules.mak> FILES=\ + category.rdf \ AOL_NetFind.gif \ AOL_NetFind.src \ Excite.gif \ diff --git a/xpfe/components/search/public/nsISearchService.idl b/xpfe/components/search/public/nsISearchService.idl index bf64fb85ae5..b10d13f2c09 100755 --- a/xpfe/components/search/public/nsISearchService.idl +++ b/xpfe/components/search/public/nsISearchService.idl @@ -27,6 +27,7 @@ */ #include "nsISupports.idl" +#include "nsIRDFDataSource.idl" [scriptable, uuid(1222e6f0-a5e3-11d2-8b7c-00805f8a7db6)] interface nsILocalSearchService : nsISupports @@ -36,7 +37,8 @@ interface nsILocalSearchService : nsISupports [scriptable, uuid(6bd1d803-1c67-11d3-9820-ed1b357eb3c4)] interface nsIInternetSearchService : nsISupports { - void ClearResultSearchSites(); + void ClearResultSearchSites(); + nsIRDFDataSource GetCategoryDataSource(); }; %{C++ diff --git a/xpfe/components/search/resources/internet.js b/xpfe/components/search/resources/internet.js index 9ec091f14ff..ebb9a049799 100644 --- a/xpfe/components/search/resources/internet.js +++ b/xpfe/components/search/resources/internet.js @@ -60,6 +60,27 @@ function loadPage() dump("\nloadPage(): Exception.\n"); } + var categoryList = document.getElementById("categoryList"); + if (categoryList) + { +// var internetSearch = Components.classes["component://netscape/browser/internetsearch-service"].getService(); + var internetSearch = Components.classes["component://netscape/rdf/datasource?name=internetsearch"].getService(); + if (internetSearch) internetSearch = internetSearch.QueryInterface(Components.interfaces.nsIInternetSearchService); + if (internetSearch) + { + var catDS = internetSearch.GetCategoryDataSource(); + if (catDS) catDS = catDS.QueryInterface(Components.interfaces.nsIRDFDataSource); + if (catDS) + { + categoryList.database.AddDataSource(catDS); + + // force contents to rebuild + var ref = categoryList.getAttribute("ref"); + if (ref) categoryList.setAttribute("ref", ref); + } + } + } + // check and see if we need to do an automatic search if (window.parent) { @@ -393,3 +414,22 @@ function saveSearch() return(true); } + + + +function chooseCategory(x) +{ + var val = x.options[x.selectedIndex].getAttribute("id"); + if (val) val = "NC:SearchCategory?category=" + val; + else val = "NC:SearchEngineRoot"; + + dump("You have chosen the category: " + val + "\n"); + + var treeNode = document.getElementById("searchengines"); + if (!treeNode) return(false); + treeNode.setAttribute("ref", val); + + dump("Set that as the ref attribute on the tree.\n"); + + return(true); +} diff --git a/xpfe/components/search/resources/internet.xul b/xpfe/components/search/resources/internet.xul index e76277e6e65..d10af3e6361 100644 --- a/xpfe/components/search/resources/internet.xul +++ b/xpfe/components/search/resources/internet.xul @@ -14,7 +14,30 @@ - + + + + + + + + &allengines.label; + + + + &search.button.label; diff --git a/xpfe/components/search/resources/internetresults.js b/xpfe/components/search/resources/internetresults.js index 5f3e3c13c14..b6bca15ce13 100644 --- a/xpfe/components/search/resources/internetresults.js +++ b/xpfe/components/search/resources/internetresults.js @@ -12,6 +12,8 @@ function onLoadInternetResults() return(true); } + + function doEngineClick(node) { dump("doEngineClick entered.\n"); @@ -66,7 +68,7 @@ function doEngineClick(node) } } - if (html != "") + if ((html) && (html != "")) { var doc = window.frames[0].document; doc.open("text/html", "replace"); @@ -80,6 +82,8 @@ function doEngineClick(node) } + + function doResultClick(node) { var theID = node.getAttribute("id"); diff --git a/xpfe/components/search/resources/locale/en-US/internet.dtd b/xpfe/components/search/resources/locale/en-US/internet.dtd index 6d97db4b9fb..82d10e8c315 100755 --- a/xpfe/components/search/resources/locale/en-US/internet.dtd +++ b/xpfe/components/search/resources/locale/en-US/internet.dtd @@ -19,7 +19,10 @@ - Contributor(s): --> - + + + + diff --git a/xpfe/components/search/src/nsInternetSearchService.cpp b/xpfe/components/search/src/nsInternetSearchService.cpp index 926751325ab..580c0a7d0e4 100755 --- a/xpfe/components/search/src/nsInternetSearchService.cpp +++ b/xpfe/components/search/src/nsInternetSearchService.cpp @@ -86,11 +86,15 @@ static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID); static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); +static NS_DEFINE_CID(kRDFXMLDataSourceCID, NS_RDFXMLDATASOURCE_CID); -static const char kURINC_SearchRoot[] = "NC:SearchEngineRoot"; -static const char kURINC_SearchResultsSitesRoot[] = "NC:SearchResultsSitesRoot"; -static const char kURINC_LastSearchRoot[] = "NC:LastSearchRoot"; -static const char kURINC_SearchResultsAnonymous[] = "NC:SearchResultsAnonymous"; +static const char kURINC_SearchEngineRoot[] = "NC:SearchEngineRoot"; +static const char kURINC_SearchResultsSitesRoot[] = "NC:SearchResultsSitesRoot"; +static const char kURINC_LastSearchRoot[] = "NC:LastSearchRoot"; +static const char kURINC_SearchCategoryRoot[] = "NC:SearchCategoryRoot"; +static const char kURINC_SearchCategoryPrefix[] = "NC:SearchCategory?category="; +static const char kURINC_SearchCategoryEnginePrefix[] = "NC:SearchCategory?engine="; +static const char kURINC_SearchResultsAnonymous[] = "NC:SearchResultsAnonymous"; @@ -169,8 +173,9 @@ private: PRBool mEngineListBuilt; // pseudo-constants - static nsIRDFResource *kNC_SearchRoot; + static nsIRDFResource *kNC_SearchEngineRoot; static nsIRDFResource *kNC_LastSearchRoot; + static nsIRDFResource *kNC_SearchCategoryRoot; static nsIRDFResource *kNC_SearchResultsSitesRoot; static nsIRDFResource *kNC_Ref; static nsIRDFResource *kNC_Child; @@ -187,14 +192,20 @@ private: protected: static nsIRDFDataSource *mInner; + static nsCOMPtr categoryDataSource; + friend NS_IMETHODIMP NS_NewInternetSearchService(nsISupports* aOuter, REFNSIID aIID, void** aResult); // helper methods PRBool isEngineURI(nsIRDFResource* aResource); PRBool isSearchURI(nsIRDFResource* aResource); + PRBool isSearchCategoryURI(nsIRDFResource* aResource); + PRBool isSearchCategoryEngineURI(nsIRDFResource* aResource); + nsresult resolveSearchCategoryEngineURI(nsIRDFResource *source, nsIRDFResource **trueEngine); nsresult BeginSearchRequest(nsIRDFResource *source, PRBool doNetworkRequest); nsresult DoSearch(nsIRDFResource *source, nsIRDFResource *engine, nsString text); nsresult GetSearchEngineList(nsFileSpec spec); + nsresult GetCategoryList(); nsresult GetSearchFolder(nsFileSpec &spec); nsresult ReadFileContents(nsFileSpec baseFilename, nsString & sourceContents); static nsresult GetData(nsString data, char *sectionToFind, char *attribToFind, nsString &value); @@ -282,9 +293,11 @@ static InternetSearchDataSource *gInternetSearchDataSource = nsnull; PRInt32 InternetSearchDataSource::gRefCnt; nsIRDFDataSource *InternetSearchDataSource::mInner = nsnull; +nsCOMPtr InternetSearchDataSource::categoryDataSource; -nsIRDFResource *InternetSearchDataSource::kNC_SearchRoot; +nsIRDFResource *InternetSearchDataSource::kNC_SearchEngineRoot; nsIRDFResource *InternetSearchDataSource::kNC_LastSearchRoot; +nsIRDFResource *InternetSearchDataSource::kNC_SearchCategoryRoot; nsIRDFResource *InternetSearchDataSource::kNC_SearchResultsSitesRoot; nsIRDFResource *InternetSearchDataSource::kNC_Ref; nsIRDFResource *InternetSearchDataSource::kNC_Child; @@ -352,6 +365,65 @@ InternetSearchDataSource::isSearchURI(nsIRDFResource *r) +PRBool +InternetSearchDataSource::isSearchCategoryURI(nsIRDFResource *r) +{ + PRBool isSearchCategoryURIFlag = PR_FALSE; + const char *uri = nsnull; + + r->GetValueConst(&uri); + if ((uri) && (!strncmp(uri, kURINC_SearchCategoryPrefix, sizeof(kURINC_SearchCategoryPrefix) - 1))) + { + isSearchCategoryURIFlag = PR_TRUE; + } + return(isSearchCategoryURIFlag); +} + + + +PRBool +InternetSearchDataSource::isSearchCategoryEngineURI(nsIRDFResource *r) +{ + PRBool isSearchCategoryEngineURIFlag = PR_FALSE; + const char *uri = nsnull; + + r->GetValueConst(&uri); + if ((uri) && (!strncmp(uri, kURINC_SearchCategoryEnginePrefix, sizeof(kURINC_SearchCategoryEnginePrefix) - 1))) + { + isSearchCategoryEngineURIFlag = PR_TRUE; + } + return(isSearchCategoryEngineURIFlag); +} + + + +nsresult +InternetSearchDataSource::resolveSearchCategoryEngineURI(nsIRDFResource *engine, nsIRDFResource **trueEngine) +{ + *trueEngine = nsnull; + + if ((!categoryDataSource) || (!mInner)) return(NS_ERROR_UNEXPECTED); + + nsresult rv; + nsCOMPtr catNode; + rv = categoryDataSource->GetTarget(engine, kNC_Name, PR_TRUE, getter_AddRefs(catNode)); + if (NS_FAILED(rv)) return(rv); + + nsCOMPtr catName = do_QueryInterface(catNode); + if (!catName) return(NS_ERROR_UNEXPECTED); + + nsCOMPtr catSrc; + rv = mInner->GetSource(kNC_Name, catName, PR_TRUE, getter_AddRefs(catSrc)); + if (NS_FAILED(rv)) return(rv); + if (!catSrc) return(NS_ERROR_UNEXPECTED); + + *trueEngine = catSrc; + NS_IF_ADDREF(*trueEngine); + return(NS_OK); +} + + + InternetSearchDataSource::InternetSearchDataSource(void) { NS_INIT_REFCNT(); @@ -363,20 +435,21 @@ InternetSearchDataSource::InternetSearchDataSource(void) PR_ASSERT(NS_SUCCEEDED(rv)); - gRDFService->GetResource(kURINC_SearchRoot, &kNC_SearchRoot); - gRDFService->GetResource(kURINC_LastSearchRoot, &kNC_LastSearchRoot); - gRDFService->GetResource(kURINC_SearchResultsSitesRoot, &kNC_SearchResultsSitesRoot); - gRDFService->GetResource(NC_NAMESPACE_URI "ref", &kNC_Ref); - gRDFService->GetResource(NC_NAMESPACE_URI "child", &kNC_Child); - gRDFService->GetResource(NC_NAMESPACE_URI "data", &kNC_Data); - gRDFService->GetResource(NC_NAMESPACE_URI "Name", &kNC_Name); - gRDFService->GetResource(NC_NAMESPACE_URI "URL", &kNC_URL); - gRDFService->GetResource(RDF_NAMESPACE_URI "instanceOf", &kRDF_InstanceOf); - gRDFService->GetResource(RDF_NAMESPACE_URI "type", &kRDF_type); - gRDFService->GetResource(NC_NAMESPACE_URI "loading", &kNC_loading); - gRDFService->GetResource(NC_NAMESPACE_URI "HTML", &kNC_HTML); - gRDFService->GetResource(NC_NAMESPACE_URI "Icon", &kNC_Icon); - gRDFService->GetResource(NC_NAMESPACE_URI "StatusIcon", &kNC_StatusIcon); + gRDFService->GetResource(kURINC_SearchEngineRoot, &kNC_SearchEngineRoot); + gRDFService->GetResource(kURINC_LastSearchRoot, &kNC_LastSearchRoot); + gRDFService->GetResource(kURINC_SearchResultsSitesRoot, &kNC_SearchResultsSitesRoot); + gRDFService->GetResource(NC_NAMESPACE_URI "SearchCategoryRoot", &kNC_SearchCategoryRoot); + gRDFService->GetResource(NC_NAMESPACE_URI "ref", &kNC_Ref); + gRDFService->GetResource(NC_NAMESPACE_URI "child", &kNC_Child); + gRDFService->GetResource(NC_NAMESPACE_URI "data", &kNC_Data); + gRDFService->GetResource(NC_NAMESPACE_URI "Name", &kNC_Name); + gRDFService->GetResource(NC_NAMESPACE_URI "URL", &kNC_URL); + gRDFService->GetResource(RDF_NAMESPACE_URI "instanceOf", &kRDF_InstanceOf); + gRDFService->GetResource(RDF_NAMESPACE_URI "type", &kRDF_type); + gRDFService->GetResource(NC_NAMESPACE_URI "loading", &kNC_loading); + gRDFService->GetResource(NC_NAMESPACE_URI "HTML", &kNC_HTML); + gRDFService->GetResource(NC_NAMESPACE_URI "Icon", &kNC_Icon); + gRDFService->GetResource(NC_NAMESPACE_URI "StatusIcon", &kNC_StatusIcon); gInternetSearchDataSource = this; } @@ -388,8 +461,9 @@ InternetSearchDataSource::~InternetSearchDataSource (void) { if (--gRefCnt == 0) { - NS_IF_RELEASE(kNC_SearchRoot); + NS_IF_RELEASE(kNC_SearchEngineRoot); NS_IF_RELEASE(kNC_LastSearchRoot); + NS_IF_RELEASE(kNC_SearchCategoryRoot); NS_IF_RELEASE(kNC_SearchResultsSitesRoot); NS_IF_RELEASE(kNC_Ref); NS_IF_RELEASE(kNC_Child); @@ -515,7 +589,31 @@ InternetSearchDataSource::GetTarget(nsIRDFResource *source, // we only have positive assertions in the internet search data source. if (! tv) return(rv); - + + if ((isSearchCategoryURI(source)) && (categoryDataSource)) + { + const char *uri = nsnull; + source->GetValueConst(&uri); + if (!uri) return(NS_ERROR_UNEXPECTED); + nsAutoString catURI(uri); + + nsCOMPtr category; + if (NS_FAILED(rv = gRDFService->GetResource(nsCAutoString(catURI), + getter_AddRefs(category)))) + return(rv); + + rv = categoryDataSource->GetTarget(category, property, tv, target); + return(rv); + } + + if (isSearchCategoryEngineURI(source)) + { + nsCOMPtr trueEngine; + rv = resolveSearchCategoryEngineURI(source, getter_AddRefs(trueEngine)); + if (NS_FAILED(rv)) return(rv); + source = trueEngine; + } + if (mInner) { rv = mInner->GetTarget(source, property, tv, target); @@ -549,18 +647,47 @@ InternetSearchDataSource::GetTargets(nsIRDFResource *source, if (! tv) return(rv); + if ((isSearchCategoryURI(source)) && (categoryDataSource)) + { + const char *uri = nsnull; + source->GetValueConst(&uri); + if (!uri) return(NS_ERROR_UNEXPECTED); + nsAutoString catURI(uri); + + nsCOMPtr category; + if (NS_FAILED(rv = gRDFService->GetResource(nsCAutoString(catURI), + getter_AddRefs(category)))) + return(rv); + + rv = categoryDataSource->GetTargets(category, property, tv, targets); + return(rv); + } + + if (isSearchCategoryEngineURI(source)) + { + nsCOMPtr trueEngine; + rv = resolveSearchCategoryEngineURI(source, getter_AddRefs(trueEngine)); + if (NS_FAILED(rv)) return(rv); + source = trueEngine; + } + if (mInner) { // defer search engine discovery until needed; small startup time improvement - if (((source == kNC_SearchRoot) || isSearchURI(source)) && (property == kNC_Child) + if (((source == kNC_SearchEngineRoot) || isSearchURI(source)) && (property == kNC_Child) && (mEngineListBuilt == PR_FALSE)) { + mEngineListBuilt = PR_TRUE; + // get available search engines nsFileSpec nativeDir; if (NS_SUCCEEDED(rv = GetSearchFolder(nativeDir))) { rv = GetSearchEngineList(nativeDir); - mEngineListBuilt = PR_TRUE; + + // read in category list + rv = GetCategoryList(); + #ifdef XP_MAC // on Mac, use system's search files too nsSpecialSystemDirectory searchSitesDir(nsSpecialSystemDirectory::Mac_InternetSearchDirectory); @@ -596,6 +723,40 @@ InternetSearchDataSource::GetTargets(nsIRDFResource *source, +nsresult +InternetSearchDataSource::GetCategoryList() +{ + nsIRDFDataSource *ds = nsnull; + nsresult rv = nsComponentManager::CreateInstance(kRDFXMLDataSourceCID, + nsnull, NS_GET_IID(nsIRDFDataSource), (void**) &ds); + if (NS_FAILED(rv)) return(rv); + if (!ds) return(NS_ERROR_UNEXPECTED); + + categoryDataSource = do_QueryInterface(ds); + NS_RELEASE(ds); + ds = nsnull; + if (!categoryDataSource) return(NS_ERROR_UNEXPECTED); + + nsCOMPtr remoteCategoryDataSource = do_QueryInterface(categoryDataSource); + if (!remoteCategoryDataSource) return(NS_ERROR_UNEXPECTED); + + // XXX should check in user's profile directory first, + // and fallback to the default file + + nsFileSpec searchDir; + if (NS_FAILED(rv = GetSearchFolder(searchDir))) return(rv); + searchDir += "category.rdf"; + + nsFileURL fileURL(searchDir); + if (NS_FAILED(rv = remoteCategoryDataSource->Init(fileURL.GetURLString()))) return(rv); + + // synchronous read + rv = remoteCategoryDataSource->Refresh(PR_TRUE); + return(rv); +} + + + NS_IMETHODIMP InternetSearchDataSource::Assert(nsIRDFResource *source, nsIRDFResource *property, @@ -703,7 +864,7 @@ InternetSearchDataSource::ArcLabelsOut(nsIRDFResource *source, nsresult rv; - if ((source == kNC_SearchRoot) || (source == kNC_LastSearchRoot) || isSearchURI(source)) + if ((source == kNC_SearchEngineRoot) || (source == kNC_LastSearchRoot) || isSearchURI(source)) { nsCOMPtr array; rv = NS_NewISupportsArray(getter_AddRefs(array)); @@ -719,7 +880,31 @@ InternetSearchDataSource::ArcLabelsOut(nsIRDFResource *source, *labels = result; return(NS_OK); } - + + if ((isSearchCategoryURI(source)) && (categoryDataSource)) + { + const char *uri = nsnull; + source->GetValueConst(&uri); + if (!uri) return(NS_ERROR_UNEXPECTED); + nsAutoString catURI(uri); + + nsCOMPtr category; + if (NS_FAILED(rv = gRDFService->GetResource(nsCAutoString(catURI), + getter_AddRefs(category)))) + return(rv); + + rv = categoryDataSource->ArcLabelsOut(category, labels); + return(rv); + } + + if (isSearchCategoryEngineURI(source)) + { + nsCOMPtr trueEngine; + rv = resolveSearchCategoryEngineURI(source, getter_AddRefs(trueEngine)); + if (NS_FAILED(rv) || (!trueEngine)) return(rv); + source = trueEngine; + } + if (mInner) { rv = mInner->ArcLabelsOut(source, labels); @@ -877,6 +1062,31 @@ InternetSearchDataSource::ClearResultSearchSites(void) +NS_IMETHODIMP +InternetSearchDataSource::GetCategoryDataSource(nsIRDFDataSource **ds) +{ + nsresult rv; + + if (!categoryDataSource) + { + if (NS_FAILED(rv = GetCategoryList())) + { + *ds = nsnull; + return(rv); + } + } + if (categoryDataSource) + { + *ds = categoryDataSource.get(); + NS_IF_ADDREF(*ds); + return(NS_OK); + } + *ds = nsnull; + return(NS_ERROR_FAILURE); +} + + + nsresult InternetSearchDataSource::BeginSearchRequest(nsIRDFResource *source, PRBool doNetworkRequest) { @@ -1006,7 +1216,8 @@ InternetSearchDataSource::BeginSearchRequest(nsIRDFResource *source, PRBool doNe { if (attrib.EqualsIgnoreCase("engine")) { - if (value.Find(kEngineProtocol) == 0) + if ((value.Find(kEngineProtocol) == 0) || + (value.Find(kURINC_SearchCategoryEnginePrefix) == 0)) { char *val = value.ToNewCString(); if (val) @@ -1039,6 +1250,18 @@ InternetSearchDataSource::BeginSearchRequest(nsIRDFResource *source, PRBool doNe baseFilename = nsnull; if (!engine) continue; + // if its a engine from a search category, then get its "#Name", + // and map from that back to the real engine reference; if an + // error occurs, finish processing the rest of the engines, + // don't just break/return out + if (isSearchCategoryEngineURI(engine)) + { + nsCOMPtr trueEngine; + rv = resolveSearchCategoryEngineURI(engine, getter_AddRefs(trueEngine)); + if (NS_FAILED(rv) || (!trueEngine)) continue; + engine = trueEngine; + } + // mark this as a search site if (mInner) { @@ -1318,7 +1541,7 @@ InternetSearchDataSource::GetSearchEngineList(nsFileSpec nativeDir) uri.Left(temp, uri.Length()-4); temp += ".gif"; const nsFileSpec gifIconFile(temp); - if ((gifIconFile.Exists()) && (gifIconFile.IsFile())) + if (gifIconFile.IsFile()) { nsFileURL gifIconFileURL(gifIconFile); iconURL = gifIconFileURL.GetURLString(); @@ -1326,7 +1549,7 @@ InternetSearchDataSource::GetSearchEngineList(nsFileSpec nativeDir) uri.Left(temp, uri.Length()-4); temp += ".jpg"; const nsFileSpec jpgIconFile(temp); - if ((jpgIconFile.Exists()) && (jpgIconFile.IsFile())) + if (jpgIconFile.IsFile()) { nsFileURL jpgIconFileURL(jpgIconFile); iconURL = jpgIconFileURL.GetURLString(); @@ -1334,7 +1557,7 @@ InternetSearchDataSource::GetSearchEngineList(nsFileSpec nativeDir) uri.Left(temp, uri.Length()-4); temp += ".jpeg"; const nsFileSpec jpegIconFile(temp); - if ((jpegIconFile.Exists()) && (jpegIconFile.IsFile())) + if (jpegIconFile.IsFile()) { nsFileURL jpegIconFileURL(jpegIconFile); iconURL = jpegIconFileURL.GetURLString(); @@ -1342,7 +1565,7 @@ InternetSearchDataSource::GetSearchEngineList(nsFileSpec nativeDir) uri.Left(temp, uri.Length()-4); temp += ".png"; const nsFileSpec pngIconFile(temp); - if ((pngIconFile.Exists()) && (pngIconFile.IsFile())) + if (pngIconFile.IsFile()) { nsFileURL pngIconFileURL(pngIconFile); iconURL = pngIconFileURL.GetURLString(); @@ -1430,7 +1653,7 @@ InternetSearchDataSource::GetSearchEngineList(nsFileSpec nativeDir) } // Note: add the child relationship last - mInner->Assert(kNC_SearchRoot, kNC_Child, searchRes, PR_TRUE); + mInner->Assert(kNC_SearchEngineRoot, kNC_Child, searchRes, PR_TRUE); } nsCRT::free(searchURI); searchURI = nsnull;