Add support for various ways of filtering search results... (accessable via context menus.)

This commit is contained in:
rjc%netscape.com 2000-03-19 08:52:18 +00:00
Родитель 165e8f083d
Коммит 61394fdeb2
3 изменённых файлов: 807 добавлений и 8 удалений

Просмотреть файл

@ -615,11 +615,11 @@ function openURL(event, treeitem, root)
// a "#URL" property, use it, otherwise default to using the id // a "#URL" property, use it, otherwise default to using the id
try try
{ {
var rootNode = document.getElementById(root); var theRootNode = document.getElementById(root);
var ds = null; var ds = null;
if (rootNode) if (rootNode)
{ {
ds = rootNode.database; ds = theRootNode.database;
} }
var rdf = Components.classes["component://netscape/rdf/rdf-service"].getService(); var rdf = Components.classes["component://netscape/rdf/rdf-service"].getService();
if (rdf) rdf = rdf.QueryInterface(Components.interfaces.nsIRDFService); if (rdf) rdf = rdf.QueryInterface(Components.interfaces.nsIRDFService);
@ -743,3 +743,227 @@ function switchTab( aPageIndex )
deck.setAttribute( "index", aPageIndex ); deck.setAttribute( "index", aPageIndex );
return(true); return(true);
} }
function fillContextMenu(name)
{
if (!name) return(false);
var popupNode = document.getElementById(name);
if (!popupNode) return(false);
// remove the menu node (which tosses all of its kids);
// do this in case any old command nodes are hanging around
while (popupNode.childNodes.length)
{
popupNode.removeChild(popupNode.childNodes[0]);
}
var treeNode = document.getElementById("Tree");
if (!treeNode) return(false);
var db = treeNode.database;
if (!db) return(false);
var compositeDB = db.QueryInterface(Components.interfaces.nsIRDFDataSource);
if (!compositeDB) return(false);
var isupports = Components.classes["component://netscape/rdf/rdf-service"].getService();
if (!isupports) return(false);
var rdf = isupports.QueryInterface(Components.interfaces.nsIRDFService);
if (!rdf) return(false);
var target_item = document.popupNode.parentNode.parentNode;
if (target_item && target_item.nodeName == "treeitem")
{
if (target_item.getAttribute('selected') != 'true') {
treeNode.selectItem(target_item);
}
}
var select_list = treeNode.selectedItems;
// perform intersection of commands over selected nodes
var cmdArray = new Array();
var selectLength = select_list.length;
if (selectLength == 0) selectLength = 1;
for (var nodeIndex=0; nodeIndex < selectLength; nodeIndex++)
{
var id = null;
// if nothing is selected, get commands for the "ref" of the tree root
if (select_list.length == 0)
{
id = treeNode.getAttribute("ref");
if (!id) break;
}
else
{
var node = select_list[nodeIndex];
if (!node) break;
id = node.getAttribute("id");
if (!id) break;
}
var rdfNode = rdf.GetResource(id);
if (!rdfNode) break;
var cmdEnum = db.GetAllCmds(rdfNode);
if (!cmdEnum) break;
var nextCmdArray = new Array();
while (cmdEnum.HasMoreElements())
{
var cmd = cmdEnum.GetNext();
if (!cmd) break;
if (nodeIndex == 0)
{
cmdArray[cmdArray.length] = cmd;
}
else
{
nextCmdArray[cmdArray.length] = cmd;
}
}
if (nodeIndex > 0)
{
// perform command intersection calculation
for (var cmdIndex = 0; cmdIndex < cmdArray.length; cmdIndex++)
{
var cmdFound = false;
for (var nextCmdIndex = 0; nextCmdIndex < nextCmdArray.length; nextCmdIndex++)
{
if (nextCmdArray[nextCmdIndex] == cmdArray[cmdIndex])
{
cmdFound = true;
break;
}
}
if (cmdFound == false)
{
cmdArray[cmdIndex] = null;
}
}
}
}
// need a resource to ask RDF for each command's name
var rdfNameResource = rdf.GetResource("http://home.netscape.com/NC-rdf#Name");
if (!rdfNameResource) return(false);
// build up menu items
if (cmdArray.length < 1) return(false);
for (var cmdIndex = 0; cmdIndex < cmdArray.length; cmdIndex++)
{
var cmd = cmdArray[cmdIndex];
if (!cmd) continue;
var cmdResource = cmd.QueryInterface(Components.interfaces.nsIRDFResource);
if (!cmdResource) break;
var cmdNameNode = compositeDB.GetTarget(cmdResource, rdfNameResource, true);
if (!cmdNameNode) break;
cmdNameLiteral = cmdNameNode.QueryInterface(Components.interfaces.nsIRDFLiteral);
if (!cmdNameLiteral) break;
cmdName = cmdNameLiteral.Value;
if (!cmdName) break;
var menuItem = document.createElement("menuitem");
menuItem.setAttribute("value", cmdName);
popupNode.appendChild(menuItem);
// work around bug # 26402 by setting "oncommand" attribute AFTER appending menuitem
menuItem.setAttribute("oncommand", "return doContextCmd('" + cmdResource.Value + "');");
}
return(true);
}
function doContextCmd(cmdName)
{
var treeNode = document.getElementById("Tree");
if (!treeNode) return(false);
var db = treeNode.database;
if (!db) return(false);
var compositeDB = db.QueryInterface(Components.interfaces.nsIRDFDataSource);
if (!compositeDB) return(false);
var isupports = Components.classes["component://netscape/rdf/rdf-service"].getService();
if (!isupports) return(false);
var rdf = isupports.QueryInterface(Components.interfaces.nsIRDFService);
if (!rdf) return(false);
// need a resource for the command
var cmdResource = rdf.GetResource(cmdName);
if (!cmdResource) return(false);
cmdResource = cmdResource.QueryInterface(Components.interfaces.nsIRDFResource);
if (!cmdResource) return(false);
// set up selection nsISupportsArray
var selectionInstance = Components.classes["component://netscape/supports-array"].createInstance();
var selectionArray = selectionInstance.QueryInterface(Components.interfaces.nsISupportsArray);
// set up arguments nsISupportsArray
var argumentsInstance = Components.classes["component://netscape/supports-array"].createInstance();
var argumentsArray = argumentsInstance.QueryInterface(Components.interfaces.nsISupportsArray);
// get argument (parent)
var parentArc = rdf.GetResource("http://home.netscape.com/NC-rdf#parent");
if (!parentArc) return(false);
var select_list = treeNode.selectedItems;
if (select_list.length < 1)
{
// if nothing is selected, default to using the "ref" on the root of the tree
var uri = treeNode.getAttribute("ref");
if (!uri || uri=="") return(false);
var rdfNode = rdf.GetResource(uri);
// add node into selection array
if (rdfNode)
{
selectionArray.AppendElement(rdfNode);
}
}
else for (var nodeIndex=0; nodeIndex<select_list.length; nodeIndex++)
{
var node = select_list[nodeIndex];
if (!node) break;
var uri = node.getAttribute("ref");
if ((uri) || (uri == ""))
{
uri = node.getAttribute("id");
}
if (!uri) return(false);
var rdfNode = rdf.GetResource(uri);
if (!rdfNode) break;
// add node into selection array
selectionArray.AppendElement(rdfNode);
// get the parent's URI
var parentURI="";
var theParent = node;
while (theParent)
{
theParent = theParent.parentNode;
parentURI = theParent.getAttribute("ref");
if ((!parentURI) || (parentURI == ""))
{
parentURI = theParent.getAttribute("id");
}
if (parentURI != "") break;
}
if (parentURI == "") return(false);
var parentNode = rdf.GetResource(parentURI, true);
if (!parentNode) return(false);
// add parent arc and node into arguments array
argumentsArray.AppendElement(parentArc);
argumentsArray.AppendElement(parentNode);
}
// do the command
compositeDB.DoCommand( selectionArray, cmdResource, argumentsArray );
return(true);
}

Просмотреть файл

@ -36,6 +36,12 @@
<html:script src="chrome://global/content/strres.js"/> <html:script src="chrome://global/content/strres.js"/>
<html:script src="chrome://search/content/search-panel.js" /> <html:script src="chrome://search/content/search-panel.js" />
<popupset>
<popup id="contextual" oncreate="return fillContextMenu('contextual');" >
<menu />
</popup>
</popupset>
<box align="vertical"> <box align="vertical">
<box align="horizontal" class="spaced"> <box align="horizontal" class="spaced">
<html:input id="sidebar-search-text" flex="1" onkeyup="if (event.which == 13) { return doSearch(); }" /> <html:input id="sidebar-search-text" flex="1" onkeyup="if (event.which == 13) { return doSearch(); }" />
@ -74,7 +80,7 @@
</box> </box>
<spring style="height: 2px;"/> <spring style="height: 2px;"/>
<tree id="Tree" ref="NC:LastSearchRoot" <tree id="Tree" ref="NC:LastSearchRoot" context="contextual"
rdf:resource="http://home.netscape.com/NC-rdf#PageRank" rdf:resource="http://home.netscape.com/NC-rdf#PageRank"
rdf:resource2="http://home.netscape.com/NC-rdf#Name" rdf:resource2="http://home.netscape.com/NC-rdf#Name"
sortDirection="ascending" sortActive="true" sortDirection="ascending" sortActive="true"

Просмотреть файл

@ -66,6 +66,7 @@
#include "nsIInputStream.h" #include "nsIInputStream.h"
#include "nsIStreamListener.h" #include "nsIStreamListener.h"
#include "nsISearchService.h" #include "nsISearchService.h"
#include "nsIBookmarksService.h"
#ifdef XP_MAC #ifdef XP_MAC
#include "Files.h" #include "Files.h"
@ -99,6 +100,11 @@ static const char kURINC_LastSearchRoot[] = "NC:LastSearchRoot";
static const char kURINC_SearchCategoryRoot[] = "NC:SearchCategoryRoot"; static const char kURINC_SearchCategoryRoot[] = "NC:SearchCategoryRoot";
static const char kURINC_SearchCategoryPrefix[] = "NC:SearchCategory?category="; static const char kURINC_SearchCategoryPrefix[] = "NC:SearchCategory?category=";
static const char kURINC_SearchCategoryEnginePrefix[] = "NC:SearchCategory?engine="; static const char kURINC_SearchCategoryEnginePrefix[] = "NC:SearchCategory?engine=";
static const char kURINC_FilterSearchURLsRoot[] = "NC:FilterSearchURLsRoot";
static const char kURINC_FilterSearchSitesRoot[] = "NC:FilterSearchSitesRoot";
static const char kSearchCommand[] = "http://home.netscape.com/NC-rdf#command?";
@ -246,10 +252,13 @@ static PRBool mEngineListBuilt;
static nsCOMPtr<nsILoadGroup> mLoadGroup; static nsCOMPtr<nsILoadGroup> mLoadGroup;
// pseudo-constants // pseudo-constants
static nsIRDFResource *kNC_SearchResult;
static nsIRDFResource *kNC_SearchEngineRoot; static nsIRDFResource *kNC_SearchEngineRoot;
static nsIRDFResource *kNC_LastSearchRoot; static nsIRDFResource *kNC_LastSearchRoot;
static nsIRDFResource *kNC_SearchCategoryRoot; static nsIRDFResource *kNC_SearchCategoryRoot;
static nsIRDFResource *kNC_SearchResultsSitesRoot; static nsIRDFResource *kNC_SearchResultsSitesRoot;
static nsIRDFResource *kNC_FilterSearchURLsRoot;
static nsIRDFResource *kNC_FilterSearchSitesRoot;
static nsIRDFResource *kNC_Ref; static nsIRDFResource *kNC_Ref;
static nsIRDFResource *kNC_Child; static nsIRDFResource *kNC_Child;
static nsIRDFResource *kNC_Data; static nsIRDFResource *kNC_Data;
@ -273,6 +282,11 @@ static nsCOMPtr<nsILoadGroup> mLoadGroup;
static nsIRDFResource *kNC_PriceSort; static nsIRDFResource *kNC_PriceSort;
static nsIRDFResource *kNC_Availability; static nsIRDFResource *kNC_Availability;
static nsIRDFResource *kNC_SearchCommand_AddToBookmarks;
static nsIRDFResource *kNC_SearchCommand_FilterResult;
static nsIRDFResource *kNC_SearchCommand_FilterSite;
static nsIRDFResource *kNC_SearchCommand_ClearFilters;
protected: protected:
static nsIRDFDataSource *mInner; static nsIRDFDataSource *mInner;
@ -285,6 +299,7 @@ friend NS_IMETHODIMP NS_NewInternetSearchService(nsISupports* aOuter, REFNSIID a
PRBool isSearchURI(nsIRDFResource* aResource); PRBool isSearchURI(nsIRDFResource* aResource);
PRBool isSearchCategoryURI(nsIRDFResource* aResource); PRBool isSearchCategoryURI(nsIRDFResource* aResource);
PRBool isSearchCategoryEngineURI(nsIRDFResource* aResource); PRBool isSearchCategoryEngineURI(nsIRDFResource* aResource);
PRBool isSearchCommand(nsIRDFResource* aResource);
nsresult resolveSearchCategoryEngineURI(nsIRDFResource *source, nsIRDFResource **trueEngine); nsresult resolveSearchCategoryEngineURI(nsIRDFResource *source, nsIRDFResource **trueEngine);
nsresult BeginSearchRequest(nsIRDFResource *source, PRBool doNetworkRequest); nsresult BeginSearchRequest(nsIRDFResource *source, PRBool doNetworkRequest);
nsresult FindData(nsIRDFResource *engine, nsString &data); nsresult FindData(nsIRDFResource *engine, nsString &data);
@ -301,6 +316,13 @@ static nsresult GetData(nsString &data, const char *sectionToFind, const char *a
nsresult SetHint(nsIRDFResource *mParent, nsIRDFResource *hintRes); nsresult SetHint(nsIRDFResource *mParent, nsIRDFResource *hintRes);
nsresult ConvertEntities(nsString &str, PRBool removeHTMLFlag = PR_TRUE, PRBool removeCRLFsFlag = PR_TRUE, PRBool trimWhiteSpaceFlag = PR_TRUE); nsresult ConvertEntities(nsString &str, PRBool removeHTMLFlag = PR_TRUE, PRBool removeCRLFsFlag = PR_TRUE, PRBool trimWhiteSpaceFlag = PR_TRUE);
char * getSearchURI(nsIRDFResource *src);
nsresult addToBookmarks(nsIRDFResource *src);
nsresult filterResult(nsIRDFResource *src);
nsresult filterSite(nsIRDFResource *src);
nsresult clearFilters(void);
PRBool isSearchResultFiltered(const nsString &href);
InternetSearchDataSource(void); InternetSearchDataSource(void);
virtual ~InternetSearchDataSource(void); virtual ~InternetSearchDataSource(void);
NS_METHOD Init(); NS_METHOD Init();
@ -332,10 +354,13 @@ nsCOMPtr<nsIRDFDataSource> InternetSearchDataSource::categoryDataSource;
PRBool InternetSearchDataSource::mEngineListBuilt; PRBool InternetSearchDataSource::mEngineListBuilt;
nsCOMPtr<nsILoadGroup> InternetSearchDataSource::mLoadGroup; nsCOMPtr<nsILoadGroup> InternetSearchDataSource::mLoadGroup;
nsIRDFResource *InternetSearchDataSource::kNC_SearchResult;
nsIRDFResource *InternetSearchDataSource::kNC_SearchEngineRoot; nsIRDFResource *InternetSearchDataSource::kNC_SearchEngineRoot;
nsIRDFResource *InternetSearchDataSource::kNC_LastSearchRoot; nsIRDFResource *InternetSearchDataSource::kNC_LastSearchRoot;
nsIRDFResource *InternetSearchDataSource::kNC_SearchCategoryRoot; nsIRDFResource *InternetSearchDataSource::kNC_SearchCategoryRoot;
nsIRDFResource *InternetSearchDataSource::kNC_SearchResultsSitesRoot; nsIRDFResource *InternetSearchDataSource::kNC_SearchResultsSitesRoot;
nsIRDFResource *InternetSearchDataSource::kNC_FilterSearchURLsRoot;
nsIRDFResource *InternetSearchDataSource::kNC_FilterSearchSitesRoot;
nsIRDFResource *InternetSearchDataSource::kNC_Ref; nsIRDFResource *InternetSearchDataSource::kNC_Ref;
nsIRDFResource *InternetSearchDataSource::kNC_Child; nsIRDFResource *InternetSearchDataSource::kNC_Child;
nsIRDFResource *InternetSearchDataSource::kNC_Data; nsIRDFResource *InternetSearchDataSource::kNC_Data;
@ -359,6 +384,10 @@ nsIRDFResource *InternetSearchDataSource::kNC_Price;
nsIRDFResource *InternetSearchDataSource::kNC_PriceSort; nsIRDFResource *InternetSearchDataSource::kNC_PriceSort;
nsIRDFResource *InternetSearchDataSource::kNC_Availability; nsIRDFResource *InternetSearchDataSource::kNC_Availability;
nsIRDFResource *InternetSearchDataSource::kNC_SearchCommand_AddToBookmarks;
nsIRDFResource *InternetSearchDataSource::kNC_SearchCommand_FilterResult;
nsIRDFResource *InternetSearchDataSource::kNC_SearchCommand_FilterSite;
nsIRDFResource *InternetSearchDataSource::kNC_SearchCommand_ClearFilters;
static const char kEngineProtocol[] = "engine://"; static const char kEngineProtocol[] = "engine://";
static const char kSearchProtocol[] = "internetsearch:"; static const char kSearchProtocol[] = "internetsearch:";
@ -381,6 +410,9 @@ InternetSearchDataSource::InternetSearchDataSource(void)
gRDFService->GetResource(kURINC_SearchEngineRoot, &kNC_SearchEngineRoot); gRDFService->GetResource(kURINC_SearchEngineRoot, &kNC_SearchEngineRoot);
gRDFService->GetResource(kURINC_LastSearchRoot, &kNC_LastSearchRoot); gRDFService->GetResource(kURINC_LastSearchRoot, &kNC_LastSearchRoot);
gRDFService->GetResource(kURINC_SearchResultsSitesRoot, &kNC_SearchResultsSitesRoot); gRDFService->GetResource(kURINC_SearchResultsSitesRoot, &kNC_SearchResultsSitesRoot);
gRDFService->GetResource(kURINC_FilterSearchURLsRoot, &kNC_FilterSearchURLsRoot);
gRDFService->GetResource(kURINC_FilterSearchSitesRoot, &kNC_FilterSearchSitesRoot);
gRDFService->GetResource(NC_NAMESPACE_URI "SearchResult", &kNC_SearchResult);
gRDFService->GetResource(NC_NAMESPACE_URI "SearchCategoryRoot", &kNC_SearchCategoryRoot); gRDFService->GetResource(NC_NAMESPACE_URI "SearchCategoryRoot", &kNC_SearchCategoryRoot);
gRDFService->GetResource(NC_NAMESPACE_URI "ref", &kNC_Ref); gRDFService->GetResource(NC_NAMESPACE_URI "ref", &kNC_Ref);
gRDFService->GetResource(NC_NAMESPACE_URI "child", &kNC_Child); gRDFService->GetResource(NC_NAMESPACE_URI "child", &kNC_Child);
@ -404,6 +436,11 @@ InternetSearchDataSource::InternetSearchDataSource(void)
gRDFService->GetResource(NC_NAMESPACE_URI "Price", &kNC_Price); gRDFService->GetResource(NC_NAMESPACE_URI "Price", &kNC_Price);
gRDFService->GetResource(NC_NAMESPACE_URI "Price?sort=true", &kNC_PriceSort); gRDFService->GetResource(NC_NAMESPACE_URI "Price?sort=true", &kNC_PriceSort);
gRDFService->GetResource(NC_NAMESPACE_URI "Availability", &kNC_Availability); gRDFService->GetResource(NC_NAMESPACE_URI "Availability", &kNC_Availability);
gRDFService->GetResource(NC_NAMESPACE_URI "command?cmd=addtobookmarks", &kNC_SearchCommand_AddToBookmarks);
gRDFService->GetResource(NC_NAMESPACE_URI "command?cmd=filterresult", &kNC_SearchCommand_FilterResult);
gRDFService->GetResource(NC_NAMESPACE_URI "command?cmd=filtersite", &kNC_SearchCommand_FilterSite);
gRDFService->GetResource(NC_NAMESPACE_URI "command?cmd=clearfilters", &kNC_SearchCommand_ClearFilters);
} }
} }
@ -413,10 +450,13 @@ InternetSearchDataSource::~InternetSearchDataSource (void)
{ {
if (--gRefCnt == 0) if (--gRefCnt == 0)
{ {
NS_IF_RELEASE(kNC_SearchResult);
NS_IF_RELEASE(kNC_SearchEngineRoot); NS_IF_RELEASE(kNC_SearchEngineRoot);
NS_IF_RELEASE(kNC_LastSearchRoot); NS_IF_RELEASE(kNC_LastSearchRoot);
NS_IF_RELEASE(kNC_SearchCategoryRoot); NS_IF_RELEASE(kNC_SearchCategoryRoot);
NS_IF_RELEASE(kNC_SearchResultsSitesRoot); NS_IF_RELEASE(kNC_SearchResultsSitesRoot);
NS_IF_RELEASE(kNC_FilterSearchURLsRoot);
NS_IF_RELEASE(kNC_FilterSearchSitesRoot);
NS_IF_RELEASE(kNC_Ref); NS_IF_RELEASE(kNC_Ref);
NS_IF_RELEASE(kNC_Child); NS_IF_RELEASE(kNC_Child);
NS_IF_RELEASE(kNC_Data); NS_IF_RELEASE(kNC_Data);
@ -440,6 +480,11 @@ InternetSearchDataSource::~InternetSearchDataSource (void)
NS_IF_RELEASE(kNC_PriceSort); NS_IF_RELEASE(kNC_PriceSort);
NS_IF_RELEASE(kNC_Availability); NS_IF_RELEASE(kNC_Availability);
NS_IF_RELEASE(kNC_SearchCommand_AddToBookmarks);
NS_IF_RELEASE(kNC_SearchCommand_FilterResult);
NS_IF_RELEASE(kNC_SearchCommand_FilterSite);
NS_IF_RELEASE(kNC_SearchCommand_ClearFilters);
NS_IF_RELEASE(mInner); NS_IF_RELEASE(mInner);
if (gRDFService) if (gRDFService)
@ -517,6 +562,24 @@ InternetSearchDataSource::isSearchCategoryEngineURI(nsIRDFResource *r)
PRBool
InternetSearchDataSource::isSearchCommand(nsIRDFResource *r)
{
PRBool isSearchCommandFlag = PR_FALSE;
const char *uri = nsnull;
if (NS_SUCCEEDED(r->GetValueConst( &uri )) && (uri))
{
if (!strncmp(uri, kSearchCommand, sizeof(kSearchCommand) - 1))
{
isSearchCommandFlag = PR_TRUE;
}
}
return(isSearchCommandFlag);
}
nsresult nsresult
InternetSearchDataSource::resolveSearchCategoryEngineURI(nsIRDFResource *engine, nsIRDFResource **trueEngine) InternetSearchDataSource::resolveSearchCategoryEngineURI(nsIRDFResource *engine, nsIRDFResource **trueEngine)
{ {
@ -721,6 +784,31 @@ InternetSearchDataSource::GetTarget(nsIRDFResource *source,
return(NS_OK); return(NS_OK);
} }
if (isSearchCommand(source) && (property == kNC_Name))
{
// XXX localize: put static strings into a string bundle
nsAutoString name;
if (source == kNC_SearchCommand_AddToBookmarks)
name = "Add to bookmarks";
else if (source == kNC_SearchCommand_FilterResult)
name = "Filter out this URL from all search results";
else if (source == kNC_SearchCommand_FilterSite)
name = "Filter out this web site from all search results";
else if (source == kNC_SearchCommand_ClearFilters)
name = "Clear all search filters";
if (name.Length() > 0)
{
*target = nsnull;
nsCOMPtr<nsIRDFLiteral> literal;
if (NS_FAILED(rv = gRDFService->GetLiteral(name.GetUnicode(), getter_AddRefs(literal))))
return(rv);
*target = literal;
NS_IF_ADDREF(*target);
return(rv);
}
}
if (mInner) if (mInner)
{ {
rv = mInner->GetTarget(source, property, tv, target); rv = mInner->GetTarget(source, property, tv, target);
@ -1102,7 +1190,49 @@ NS_IMETHODIMP
InternetSearchDataSource::GetAllCmds(nsIRDFResource* source, InternetSearchDataSource::GetAllCmds(nsIRDFResource* source,
nsISimpleEnumerator/*<nsIRDFResource>*/** commands) nsISimpleEnumerator/*<nsIRDFResource>*/** commands)
{ {
return(NS_NewEmptyEnumerator(commands)); nsCOMPtr<nsISupportsArray> cmdArray;
nsresult rv;
rv = NS_NewISupportsArray(getter_AddRefs(cmdArray));
if (NS_FAILED(rv)) return(rv);
PRBool isSearchResult = PR_FALSE;
if (NS_SUCCEEDED(rv = mInner->HasAssertion(source, kRDF_type, kNC_SearchResult,
PR_TRUE, &isSearchResult)) && (isSearchResult == PR_TRUE))
{
nsCOMPtr<nsIRDFDataSource> datasource;
if (NS_SUCCEEDED(rv = gRDFService->GetDataSource("rdf:bookmarks", getter_AddRefs(datasource))))
{
nsCOMPtr<nsIBookmarksService> bookmarks = do_QueryInterface(datasource);
if (bookmarks)
{
char *uri = getSearchURI(source);
if (uri)
{
PRBool isBookmarkedFlag = PR_FALSE;
if (NS_SUCCEEDED(rv = bookmarks->IsBookmarked(uri, &isBookmarkedFlag))
&& (isBookmarkedFlag == PR_FALSE))
{
cmdArray->AppendElement(kNC_SearchCommand_AddToBookmarks);
}
Recycle(uri);
}
}
}
cmdArray->AppendElement(kNC_SearchCommand_FilterResult);
cmdArray->AppendElement(kNC_SearchCommand_FilterSite);
cmdArray->AppendElement(kNC_SearchCommand_ClearFilters);
}
else if (isSearchURI(source) || (source == kNC_LastSearchRoot))
{
cmdArray->AppendElement(kNC_SearchCommand_ClearFilters);
}
nsISimpleEnumerator *result = new nsArrayEnumerator(cmdArray);
if (!result)
return(NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(result);
*commands = result;
return(NS_OK);
} }
@ -1118,12 +1248,434 @@ InternetSearchDataSource::IsCommandEnabled(nsISupportsArray/*<nsIRDFResource>*/*
char *
InternetSearchDataSource::getSearchURI(nsIRDFResource *src)
{
char *uri = nsnull;
if (src)
{
nsresult rv;
nsCOMPtr<nsIRDFNode> srcNode;
if (NS_SUCCEEDED(rv = mInner->GetTarget(src, kNC_URL, PR_TRUE, getter_AddRefs(srcNode))))
{
nsCOMPtr<nsIRDFLiteral> urlLiteral = do_QueryInterface(srcNode);
if (urlLiteral)
{
const PRUnichar *uriUni = nsnull;
urlLiteral->GetValueConst(&uriUni);
if (uriUni)
{
nsAutoString uriString(uriUni);
uri = uriString.ToNewUTF8String();
}
}
}
}
return(uri);
}
nsresult
InternetSearchDataSource::addToBookmarks(nsIRDFResource *src)
{
if (!src) return(NS_ERROR_UNEXPECTED);
if (!mInner) return(NS_ERROR_UNEXPECTED);
nsresult rv;
nsCOMPtr<nsIRDFNode> nameNode;
// Note: nameLiteral needs to stay in scope for the life of "name"
nsCOMPtr<nsIRDFLiteral> nameLiteral;
const PRUnichar *name = nsnull;
if (NS_SUCCEEDED(rv = mInner->GetTarget(src, kNC_Name, PR_TRUE, getter_AddRefs(nameNode))))
{
nameLiteral = do_QueryInterface(nameNode);
if (nameLiteral)
{
nameLiteral->GetValueConst(&name);
}
}
nsCOMPtr<nsIRDFDataSource> datasource;
if (NS_SUCCEEDED(rv = gRDFService->GetDataSource("rdf:bookmarks", getter_AddRefs(datasource))))
{
nsCOMPtr<nsIBookmarksService> bookmarks = do_QueryInterface(datasource);
if (bookmarks)
{
char *uri = getSearchURI(src);
if (uri)
{
rv = bookmarks->AddBookmark(uri, name );
Recycle(uri);
}
}
}
return(NS_OK);
}
nsresult
InternetSearchDataSource::filterResult(nsIRDFResource *aResource)
{
if (!aResource) return(NS_ERROR_UNEXPECTED);
if (!mInner) return(NS_ERROR_UNEXPECTED);
// remove all anonymous resources which have this as a #URL
char *uri = getSearchURI(aResource);
if (!uri) return(NS_ERROR_UNEXPECTED);
nsAutoString url(uri);
Recycle(uri);
nsresult rv;
nsCOMPtr<nsIRDFLiteral> urlLiteral;
if (NS_FAILED(rv = gRDFService->GetLiteral(url.GetUnicode(), getter_AddRefs(urlLiteral)))
|| (urlLiteral == nsnull)) return(NS_ERROR_UNEXPECTED);
// add aResource into a list of nodes to filter out
nsCOMPtr<nsIRDFDataSource> localstore;
rv = gRDFService->GetDataSource("rdf:local-store", getter_AddRefs(localstore));
if (NS_FAILED(rv)) return(rv);
PRBool alreadyFiltered = PR_FALSE;
if (NS_SUCCEEDED(rv = localstore->HasAssertion(kNC_FilterSearchURLsRoot, kNC_Child, urlLiteral,
PR_TRUE, &alreadyFiltered)) && (alreadyFiltered == PR_TRUE))
{
// already filtered, nothing to do
return(rv);
}
// filter this URL out
localstore->Assert(kNC_FilterSearchURLsRoot, kNC_Child, urlLiteral, PR_TRUE);
// flush localstore
nsCOMPtr<nsIRDFRemoteDataSource> remoteLocalStore = do_QueryInterface(localstore);
if (remoteLocalStore)
{
remoteLocalStore->Flush();
}
nsCOMPtr<nsISimpleEnumerator> anonArcs;
if (NS_SUCCEEDED(rv = mInner->GetSources(kNC_URL, urlLiteral, PR_TRUE,
getter_AddRefs(anonArcs))))
{
PRBool hasMoreAnonArcs = PR_TRUE;
while (hasMoreAnonArcs == PR_TRUE)
{
if (NS_FAILED(anonArcs->HasMoreElements(&hasMoreAnonArcs)) ||
(hasMoreAnonArcs == PR_FALSE)) break;
nsCOMPtr<nsISupports> anonArc;
if (NS_FAILED(anonArcs->GetNext(getter_AddRefs(anonArc))))
break;
nsCOMPtr<nsIRDFResource> anonChild = do_QueryInterface(anonArc);
if (!anonChild) continue;
PRBool isSearchResult = PR_FALSE;
if (NS_FAILED(rv = mInner->HasAssertion(anonChild, kRDF_type, kNC_SearchResult,
PR_TRUE, &isSearchResult)) || (isSearchResult == PR_FALSE))
continue;
nsCOMPtr<nsIRDFResource> anonParent;
if (NS_FAILED(rv = mInner->GetSource(kNC_Child, anonChild, PR_TRUE,
getter_AddRefs(anonParent)))) continue;
if (!anonParent) continue;
mInner->Unassert(anonParent, kNC_Child, anonChild);
}
}
return(NS_OK);
}
nsresult
InternetSearchDataSource::filterSite(nsIRDFResource *aResource)
{
if (!aResource) return(NS_ERROR_UNEXPECTED);
if (!mInner) return(NS_ERROR_UNEXPECTED);
char *uri = getSearchURI(aResource);
if (!uri) return(NS_ERROR_UNEXPECTED);
nsAutoString host(uri);
Recycle(uri);
// determine site (host name)
PRInt32 slashOffset1 = host.Find("://");
if (slashOffset1 < 1) return(NS_ERROR_UNEXPECTED);
PRInt32 slashOffset2 = host.FindChar(PRUnichar('/'), PR_FALSE, slashOffset1 + 3);
if (slashOffset2 <= slashOffset1) return(NS_ERROR_UNEXPECTED);
host.Truncate(slashOffset2 + 1);
nsresult rv;
nsCOMPtr<nsIRDFLiteral> urlLiteral;
if (NS_FAILED(rv = gRDFService->GetLiteral(host.GetUnicode(), getter_AddRefs(urlLiteral)))
|| (urlLiteral == nsnull)) return(NS_ERROR_UNEXPECTED);
// add aResource into a list of nodes to filter out
nsCOMPtr<nsIRDFDataSource> localstore;
rv = gRDFService->GetDataSource("rdf:local-store", getter_AddRefs(localstore));
if (NS_FAILED(rv)) return(rv);
PRBool alreadyFiltered = PR_FALSE;
if (NS_SUCCEEDED(rv = localstore->HasAssertion(kNC_FilterSearchSitesRoot, kNC_Child, urlLiteral,
PR_TRUE, &alreadyFiltered)) && (alreadyFiltered == PR_TRUE))
{
// already filtered, nothing to do
return(rv);
}
// filter this site out
localstore->Assert(kNC_FilterSearchSitesRoot, kNC_Child, urlLiteral, PR_TRUE);
// flush localstore
nsCOMPtr<nsIRDFRemoteDataSource> remoteLocalStore = do_QueryInterface(localstore);
if (remoteLocalStore)
{
remoteLocalStore->Flush();
}
// remove all anonymous resources which have this as a site
nsCOMPtr<nsISupportsArray> array;
nsCOMPtr<nsIRDFResource> aRes;
nsCOMPtr<nsISimpleEnumerator> cursor;
PRBool hasMore;
rv = NS_NewISupportsArray(getter_AddRefs(array));
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv = GetAllResources(getter_AddRefs(cursor)))) return(rv);
if (!cursor) return(NS_ERROR_UNEXPECTED);
hasMore = PR_TRUE;
while (hasMore == PR_TRUE)
{
if (NS_FAILED(rv = cursor->HasMoreElements(&hasMore))) return(rv);
if (hasMore == PR_FALSE) break;
nsCOMPtr<nsISupports> isupports;
if (NS_FAILED(rv = cursor->GetNext(getter_AddRefs(isupports))))
return(rv);
if (!isupports) return(NS_ERROR_UNEXPECTED);
aRes = do_QueryInterface(isupports);
if (!aRes) return(NS_ERROR_UNEXPECTED);
if ((aRes == kNC_LastSearchRoot) || (isSearchURI(aRes)))
{
array->AppendElement(aRes);
}
}
//crap
PRUint32 count;
if (NS_FAILED(rv = array->Count(&count))) return(rv);
for (PRUint32 loop=0; loop<count; loop++)
{
nsCOMPtr<nsISupports> element = array->ElementAt(loop);
if (!element) break;
nsCOMPtr<nsIRDFResource> aSearchRoot = do_QueryInterface(element);
if (!aSearchRoot) break;
if (NS_SUCCEEDED(rv = mInner->GetTargets(aSearchRoot, kNC_Child,
PR_TRUE, getter_AddRefs(cursor))))
{
hasMore = PR_TRUE;
while (hasMore == PR_TRUE)
{
if (NS_FAILED(cursor->HasMoreElements(&hasMore)) ||
(hasMore == PR_FALSE)) break;
nsCOMPtr<nsISupports> arc;
if (NS_FAILED(cursor->GetNext(getter_AddRefs(arc))))
break;
aRes = do_QueryInterface(arc);
if (!aRes) break;
uri = getSearchURI(aRes);
if (!uri) return(NS_ERROR_UNEXPECTED);
nsAutoString site(uri);
Recycle(uri);
// determine site (host name)
PRInt32 slashOffset1 = site.Find("://");
if (slashOffset1 < 1) return(NS_ERROR_UNEXPECTED);
PRInt32 slashOffset2 = site.FindChar(PRUnichar('/'), PR_FALSE, slashOffset1 + 3);
if (slashOffset2 <= slashOffset1) return(NS_ERROR_UNEXPECTED);
site.Truncate(slashOffset2 + 1);
if (site.EqualsIgnoreCase(host))
{
mInner->Unassert(aSearchRoot, kNC_Child, aRes);
}
}
}
}
return(NS_OK);
}
nsresult
InternetSearchDataSource::clearFilters(void)
{
if (!mInner) return(NS_ERROR_UNEXPECTED);
nsresult rv;
nsCOMPtr<nsIRDFDataSource> localstore;
rv = gRDFService->GetDataSource("rdf:local-store", getter_AddRefs(localstore));
if (NS_FAILED(rv)) return(rv);
nsCOMPtr<nsISimpleEnumerator> arcs;
PRBool hasMore = PR_TRUE;
nsCOMPtr<nsISupports> arc;
// remove all filtered URLs
if (NS_SUCCEEDED(rv = localstore->GetTargets(kNC_FilterSearchURLsRoot, kNC_Child,
PR_TRUE, getter_AddRefs(arcs))))
{
hasMore = PR_TRUE;
while (hasMore == PR_TRUE)
{
if (NS_FAILED(arcs->HasMoreElements(&hasMore)) || (hasMore == PR_FALSE))
break;
if (NS_FAILED(arcs->GetNext(getter_AddRefs(arc))))
break;
nsCOMPtr<nsIRDFLiteral> filterURL = do_QueryInterface(arc);
if (!filterURL) continue;
localstore->Unassert(kNC_FilterSearchURLsRoot, kNC_Child, filterURL);
}
}
// remove all filtered sites
if (NS_SUCCEEDED(rv = localstore->GetTargets(kNC_FilterSearchSitesRoot, kNC_Child,
PR_TRUE, getter_AddRefs(arcs))))
{
hasMore = PR_TRUE;
while (hasMore == PR_TRUE)
{
if (NS_FAILED(arcs->HasMoreElements(&hasMore)) || (hasMore == PR_FALSE))
break;
if (NS_FAILED(arcs->GetNext(getter_AddRefs(arc))))
break;
nsCOMPtr<nsIRDFLiteral> filterSite = do_QueryInterface(arc);
if (!filterSite) continue;
localstore->Unassert(kNC_FilterSearchSitesRoot, kNC_Child, filterSite);
}
}
// flush localstore
nsCOMPtr<nsIRDFRemoteDataSource> remoteLocalStore = do_QueryInterface(localstore);
if (remoteLocalStore)
{
remoteLocalStore->Flush();
}
return(NS_OK);
}
PRBool
InternetSearchDataSource::isSearchResultFiltered(const nsString &hrefStr)
{
PRBool filterStatus = PR_FALSE;
nsresult rv;
nsCOMPtr<nsIRDFDataSource> localstore;
rv = gRDFService->GetDataSource("rdf:local-store", getter_AddRefs(localstore));
if (NS_FAILED(rv)) return(filterStatus);
const PRUnichar *hrefUni = hrefStr.GetUnicode();
if (!hrefUni) return(filterStatus);
// check if this specific URL is to be filtered out
nsCOMPtr<nsIRDFLiteral> hrefLiteral;
if (NS_SUCCEEDED(rv = gRDFService->GetLiteral(hrefUni, getter_AddRefs(hrefLiteral))))
{
if (NS_SUCCEEDED(rv = localstore->HasAssertion(kNC_FilterSearchURLsRoot,
kNC_Child, hrefLiteral, PR_TRUE, &filterStatus)))
{
if (filterStatus == PR_TRUE)
{
return(filterStatus);
}
}
}
// check if this specific Site is to be filtered out
// determine site (host name)
nsAutoString host(hrefStr);
PRInt32 slashOffset1 = host.Find("://");
if (slashOffset1 < 1) return(NS_ERROR_UNEXPECTED);
PRInt32 slashOffset2 = host.FindChar(PRUnichar('/'), PR_FALSE, slashOffset1 + 3);
if (slashOffset2 <= slashOffset1) return(NS_ERROR_UNEXPECTED);
host.Truncate(slashOffset2 + 1);
nsCOMPtr<nsIRDFLiteral> urlLiteral;
if (NS_FAILED(rv = gRDFService->GetLiteral(host.GetUnicode(), getter_AddRefs(urlLiteral)))
|| (urlLiteral == nsnull)) return(NS_ERROR_UNEXPECTED);
rv = localstore->HasAssertion(kNC_FilterSearchSitesRoot, kNC_Child, urlLiteral,
PR_TRUE, &filterStatus);
return(filterStatus);
}
NS_IMETHODIMP NS_IMETHODIMP
InternetSearchDataSource::DoCommand(nsISupportsArray/*<nsIRDFResource>*/* aSources, InternetSearchDataSource::DoCommand(nsISupportsArray/*<nsIRDFResource>*/* aSources,
nsIRDFResource* aCommand, nsIRDFResource* aCommand,
nsISupportsArray/*<nsIRDFResource>*/* aArguments) nsISupportsArray/*<nsIRDFResource>*/* aArguments)
{ {
return(NS_ERROR_NOT_IMPLEMENTED); nsresult rv = NS_OK;
PRInt32 loop;
PRUint32 numSources;
if (NS_FAILED(rv = aSources->Count(&numSources))) return(rv);
if (numSources < 1)
{
return(NS_ERROR_ILLEGAL_VALUE);
}
for (loop=((PRInt32)numSources)-1; loop>=0; loop--)
{
nsCOMPtr<nsISupports> aSource = aSources->ElementAt(loop);
if (!aSource) return(NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIRDFResource> src = do_QueryInterface(aSource);
if (!src) return(NS_ERROR_NO_INTERFACE);
if (aCommand == kNC_SearchCommand_AddToBookmarks)
{
if (NS_FAILED(rv = addToBookmarks(src)))
return(rv);
}
else if (aCommand == kNC_SearchCommand_FilterResult)
{
if (NS_FAILED(rv = filterResult(src)))
return(rv);
}
else if (aCommand == kNC_SearchCommand_FilterSite)
{
if (NS_FAILED(rv = filterSite(src)))
return(rv);
}
else if (aCommand == kNC_SearchCommand_ClearFilters)
{
if (NS_FAILED(rv = clearFilters()))
return(rv);
}
}
return(NS_OK);
} }
@ -1789,7 +2341,7 @@ struct encodings
nsresult nsresult
InternetSearchDataSource::MapEncoding(const nsString &numericEncoding, nsString &stringEncoding) InternetSearchDataSource::MapEncoding(const nsString &numericEncoding, nsString &stringEncoding)
{ {
// XXX we need to have a fully table of numeric --> string conversions // XXX we need to have a full table of numeric --> string conversions
struct encodings encodingList[] = struct encodings encodingList[] =
{ {
@ -2293,11 +2845,21 @@ InternetSearchDataSource::GetData(nsString &data, const char *sectionToFind, con
len = value.Length(); len = value.Length();
if ((len > 0) && (foundQuoteChar == PR_TRUE)) if ((len > 0) && (foundQuoteChar == PR_TRUE))
{ {
if (value[len-1] == quoteChar) PRInt32 quoteEnd = value.FindChar(quoteChar, PR_TRUE);
if (quoteEnd >= 0)
{ {
value.SetLength(len-1); value.Truncate(quoteEnd);
} }
} }
else
{
PRInt32 commentOffset = value.FindCharInSet("# \t", 0);
if (commentOffset >= 0)
{
value.Truncate(commentOffset);
}
value = value.Trim(" \t");
}
rv = NS_OK; rv = NS_OK;
break; break;
} }
@ -2973,6 +3535,10 @@ InternetSearchDataSource::ParseHTML(nsIURI *aURL, nsIRDFResource *mParent, nsIRD
} }
} }
// if this result is to be filtered out, notice it now
if (isSearchResultFiltered(hrefStr) == PR_TRUE)
continue;
nsAutoString site(hrefStr); nsAutoString site(hrefStr);
#ifdef DEBUG_SEARCH_OUTPUT #ifdef DEBUG_SEARCH_OUTPUT
@ -3322,6 +3888,9 @@ InternetSearchDataSource::ParseHTML(nsIURI *aURL, nsIRDFResource *mParent, nsIRD
rv = mInner->Assert(res, kNC_PageRank, pageRankLiteral, PR_TRUE); rv = mInner->Assert(res, kNC_PageRank, pageRankLiteral, PR_TRUE);
} }
// set the type
rv = mInner->Assert(res, kRDF_type, kNC_SearchResult, PR_TRUE);
#ifdef OLDWAY #ifdef OLDWAY
// Note: always add in parent-child relationship last! (if it isn't already set) // Note: always add in parent-child relationship last! (if it isn't already set)
PRBool parentHasChildFlag = PR_FALSE; PRBool parentHasChildFlag = PR_FALSE;