gecko-dev/xpfe/components/search/resources/search-panel.js
matt%netscape.com 4190e86cc1 r=law
sr=ben
adding focus to search panel when opened
2001-02-06 23:13:37 +00:00

755 lines
24 KiB
JavaScript

/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Robert John Churchill <rjc@netscape.com> (Original Author)
* Peter Annema <disttsc@bart.nl>
* Blake Ross <blakeross@telocity.com>
* Ben Goodger <ben@netscape.com>
* Rob Ginda <rginda@netscape.com>
* Steve Lamm <slamm@netscape.com>
*/
const WMEDIATOR_CONTRACTID = "@mozilla.org/rdf/datasource;1?name=window-mediator";
const ISEARCH_CONTRACTID = "@mozilla.org/rdf/datasource;1?name=internetsearch";
const RDFSERVICE_CONTRACTID = "@mozilla.org/rdf/rdf-service;1";
const BMARKS_CONTRACTID = "@mozilla.org/browser/bookmarks-service;1";
const nsIBookmarksService = Components.interfaces.nsIBookmarksService;
const nsIWindowMediator = Components.interfaces.nsIWindowMediator;
const nsIRDFService = Components.interfaces.nsIRDFService;
const nsIRDFLiteral = Components.interfaces.nsIRDFLiteral;
const nsIRDFDataSource = Components.interfaces.nsIRDFDataSource;
const nsIRDFRemoteDataSource = Components.interfaces.nsIRDFRemoteDataSource;
const nsIInternetSearchService = Components.interfaces.nsIInternetSearchService;
var rootNode;
var textArc;
var modeArc;
var searchBundle;
var RDF_observer =
{
onAssert : function(ds, src, prop, target)
{
if (src == rootNode) {
if (prop == textArc)
rememberSearchText(target);
else if (prop == modeArc)
updateSearchMode();
}
},
onUnassert : function(ds, src, prop, target)
{
},
onChange : function(ds, src, prop, old_target, new_target)
{
if (src == rootNode) {
if (prop == textArc)
rememberSearchText(new_target);
else if (prop == modeArc)
updateSearchMode();
}
},
onMove : function(ds, old_src, new_src, prop, target)
{
},
beginUpdateBatch : function(ds)
{
},
endUpdateBatch : function(ds)
{
}
}
function rememberSearchText(target)
{
if (target) {
target = target.QueryInterface(nsIRDFLiteral).Value;
if (target) {
// convert plusses (+) back to spaces
target = target.replace(/+/i, " ");
var textNode = document.getElementById("sidebar-search-text");
textNode.value = unescape(target);
doEnabling();
}
}
// show the results tab
switchTab(0);
}
function updateSearchMode()
{
var searchMode = nsPreferences.getIntPref("browser.search.mode", 0);
var categoryBox = document.getElementById("categoryBox");
if (!searchMode) {
categoryBox.setAttribute("collapsed", "true");
switchTab(0);
}
else {
categoryBox.removeAttribute("collapsed");
switchTab(1);
}
return searchMode;
}
// Initialize the Search panel:
// 1) init the category list
// 2) load the search engines associated with this category
// 3) initialize the checked state of said engines
function SearchPanelStartup()
{
searchBundle = document.getElementById("searchBundle");
var rdf = Components.classes[RDFSERVICE_CONTRACTID].getService(nsIRDFService);
rootNode = rdf.GetResource("NC:LastSearchRoot", true);
textArc = rdf.GetResource("http://home.netscape.com/NC-rdf#LastText", true);
modeArc = rdf.GetResource("http://home.netscape.com/NC-rdf#SearchMode", true);
var tree = document.getElementById("Tree");
tree.database.AddObserver(RDF_observer);
var categoryList = document.getElementById("categoryList");
var internetSearch = Components.classes[ISEARCH_CONTRACTID].getService(nsIInternetSearchService);
var catDS = internetSearch.GetCategoryDataSource();
if (catDS) {
catDS = catDS.QueryInterface(nsIRDFDataSource);
categoryList.database.AddDataSource(catDS);
var ref = categoryList.getAttribute("ref");
if (ref)
categoryList.setAttribute("ref", ref);
var engineTree = document.getElementById("searchengines");
engineTree.database.AddDataSource(catDS);
ref = engineTree.getAttribute("ref");
if (ref)
engineTree.setAttribute("ref", ref);
}
// try and determine last category name used
var lastCategoryName = nsPreferences.copyUnicharPref("browser.search.last_search_category", "");
if (lastCategoryName) {
// strip off the prefix if necessary
var prefix = "NC:SearchCategory?category=";
if (lastCategoryName.indexOf(prefix) == 0)
lastCategoryName = lastCategoryName.substr(prefix.length);
}
// select the appropriate category
var categoryPopup = document.getElementById("categoryPopup");
var found = false;
for (var i = 0; i < categoryPopup.childNodes.length; ++i) {
if (lastCategoryName == "" &&
categoryPopup.childNodes[i].getAttribute("data") == "NC:SearchEngineRoot" ||
categoryPopup.childNodes[i].getAttribute("id") == lastCategoryName)
{
categoryList.selectedItem = categoryPopup.childNodes[i];
found = true;
break;
}
}
if (!found)
categoryList.selectedItem = categoryPopup.childNodes[0];
if (!lastCategoryName)
lastCategoryName = "NC:SearchEngineRoot";
else if (lastCategoryName != "NC:SearchEngineRoot")
lastCategoryName = "NC:SearchCategory?category=" + lastCategoryName;
var treeNode = document.getElementById("searchengines");
treeNode.setAttribute("ref", lastCategoryName);
loadEngines(lastCategoryName);
// if we have search results, show them, otherwise show engines
if (haveSearchResults() || updateSearchMode() == 0)
switchTab(0);
else
switchTab(1);
focusTextField();
}
function haveSearchResults()
{
var ds = document.getElementById("Tree").database;
if (!ds)
return false;
var rdf = Components.classes[RDFSERVICE_CONTRACTID].getService(nsIRDFService);
var source = rdf.GetResource("NC:LastSearchRoot", true);
var childProperty = rdf.GetResource("http://home.netscape.com/NC-rdf#LastText", true);
var target = ds.GetTarget(source, childProperty, true);
if (target) {
target = target.QueryInterface(nsIRDFLiteral).Value;
if (target) {
// convert plusses (+) back to spaces
target = target.replace(/+/i, " ");
var textNode = document.getElementById("sidebar-search-text");
textNode.value = unescape(target);
return true;
}
}
return false;
}
function getNumEngines()
{
var treeChildrenNode = document.getElementById("engineKids");
return treeChildrenNode.childNodes.length;
}
function chooseCategory(aNode)
{
var category = !aNode.id ? "NC:SearchEngineRoot" :
"NC:SearchCategory?category=" + aNode.getAttribute("id");
nsPreferences.setUnicharPref("browser.search.last_search_category", category);
var treeNode = document.getElementById("searchengines");
treeNode.setAttribute("ref", category);
loadEngines(category);
}
function saveEngines()
{
var categoryList = document.getElementById("categoryList");
var category = categoryList.selectedItem.getAttribute("id");
if (category)
category = "NC:SearchCategory?category=" + category;
else
category = "NC:SearchEngineRoot";
var rdf = Components.classes[RDFSERVICE_CONTRACTID].getService(nsIRDFService);
var localStore = rdf.GetDataSource("rdf:local-store");
if (!localStore)
return;
var engineBox = document.getElementById("engineKids");
var checkedProperty = rdf.GetResource("http://home.netscape.com/NC-rdf#checked", true);
var categorySRC = rdf.GetResource(category, true);
for (var x = 0; x < engineBox.childNodes.length; ++x) {
var treeitemNode = engineBox.childNodes[x];
var checkboxNode = treeitemNode.firstChild.firstChild.firstChild;
if (checkboxNode) {
var engineURI = treeitemNode.getAttribute("id");
var engineSRC = rdf.GetResource(engineURI, true);
if (checkboxNode.checked)
localStore.Assert(categorySRC, checkedProperty, engineSRC, true);
else
localStore.Unassert(categorySRC, checkedProperty, engineSRC, true);
}
}
// save changes; flush out the localstore
try {
var flushableStore = localStore.QueryInterface(nsIRDFRemoteDataSource);
flushableStore.Flush();
}
catch (ex) {}
}
// initialize the appropriate engine list, and the checked state of the engines
function loadEngines(aCategory)
{
var rdf = Components.classes[RDFSERVICE_CONTRACTID].getService(nsIRDFService);
var localStore = rdf.GetDataSource("rdf:local-store");
if (localStore) {
var engineBox = document.getElementById("engineKids");
var numEngines = engineBox.childNodes.length;
var checkedProperty = rdf.GetResource("http://home.netscape.com/NC-rdf#checked", true);
var categorySRC = rdf.GetResource(aCategory, true);
for (var x = 0; x < numEngines; ++x) {
var treeitemNode = engineBox.childNodes[x];
var engineURI = treeitemNode.getAttribute("id");
var engineSRC = rdf.GetResource(engineURI, true);
var checkboxNode = treeitemNode.firstChild.firstChild.firstChild;
if (checkboxNode) {
var hasAssertion = localStore.HasAssertion(categorySRC, checkedProperty, engineSRC, true);
if (hasAssertion)
checkboxNode.checked = true;
}
}
}
}
function focusTextField()
{
var textField = document.getElementById("sidebar-search-text");
textField.focus();
}
function SearchPanelShutdown()
{
var tree = document.getElementById("Tree");
tree.database.RemoveObserver(RDF_observer);
}
function doStop()
{
var stopButtonNode = document.getElementById("stopButton");
stopButtonNode.setAttribute("hidden", "true");
var searchButtonNode = document.getElementById("searchButton");
searchButtonNode.removeAttribute("hidden");
// should stop button press also stop the load of the page in the browser? I think so.
var progressNode = parent.document.getElementById("statusbar-icon");
if (progressNode)
progressNode.setAttribute("mode", "normal");
// stop any network connections
var internetSearchService = Components.classes[ISEARCH_CONTRACTID].getService(nsIInternetSearchService);
internetSearchService.Stop();
// show appropriate column(s)
var navWindow = getNavigatorWindow(false);
var resultsTree = navWindow ? navWindow._content.document.getElementById("internetresultstree") : null;
if (!resultsTree)
return;
var searchURL = resultsTree.getAttribute("ref");
if (!searchURL)
return;
var internetSearch = internetSearchService.QueryInterface(nsIRDFDataSource);
// get various services
var rdf = Components.classes[RDFSERVICE_CONTRACTID].getService(nsIRDFService);
var searchResource = rdf.GetResource(searchURL, true);
var priceProperty = rdf.GetResource("http://home.netscape.com/NC-rdf#Price", true);
var availabilityProperty = rdf.GetResource("http://home.netscape.com/NC-rdf#Availability", true);
var relevanceProperty = rdf.GetResource("http://home.netscape.com/NC-rdf#Relevance", true);
var dateProperty = rdf.GetResource("http://home.netscape.com/NC-rdf#Date", true);
var trueProperty = rdf.GetLiteral("true");
var hasPriceFlag = internetSearch.HasAssertion(searchResource, priceProperty, trueProperty, true);
var hasAvailabilityFlag = internetSearch.HasAssertion(searchResource, availabilityProperty, trueProperty, true);
var hasRelevanceFlag = internetSearch.HasAssertion(searchResource, relevanceProperty, trueProperty, true);
var hasDateFlag = internetSearch.HasAssertion(searchResource, dateProperty, trueProperty, true);
var colNode;
var sortSetFlag = false;
if (hasPriceFlag) {
colNode = navWindow._content.document.getElementById("PriceColumn");
if (colNode) {
colNode.removeAttribute("hidden");
if (!sortSetFlag) {
top._content.setInitialSort(colNode, "ascending");
sortSetFlag = true;
}
}
}
if (hasAvailabilityFlag) {
colNode = navWindow._content.document.getElementById("AvailabilityColumn");
if (colNode)
colNode.removeAttribute("hidden");
}
if (hasDateFlag) {
colNode = navWindow._content.document.getElementById("DateColumn");
if (colNode)
colNode.removeAttribute("hidden");
}
if (hasRelevanceFlag) {
colNode = navWindow._content.document.getElementById("RelevanceColumn");
if (colNode) {
colNode.removeAttribute("hidden");
if (!sortSetFlag) {
navWindow._content.setInitialSort(colNode, "descending");
sortSetFlag = true;
}
}
}
if (!sortSetFlag) {
colNode = navWindow._content.document.getElementById("PageRankColumn");
if (colNode)
navWindow._content.setInitialSort(colNode, "ascending");
}
switchTab(0);
}
function doSearch()
{
var searchMode = nsPreferences.getIntPref("browser.search.mode", 0);
// hide various columns
var navWindow = getNavigatorWindow(false);
if (navWindow && "_content" in navWindow && "isMozillaSearchWindow" in navWindow._content) {
colNode = navWindow._content.document.getElementById("RelevanceColumn");
if (colNode)
colNode.setAttribute("hidden", "true");
colNode = navWindow._content.document.getElementById("PriceColumn");
if (colNode)
colNode.setAttribute("hidden", "true");
colNode = navWindow._content.document.getElementById("AvailabilityColumn");
if (colNode)
colNode.setAttribute("hidden", "true");
}
// get user text to find
var textNode = document.getElementById("sidebar-search-text");
if (!textNode.value) {
alert(searchBundle.getString("enterstringandlocation"));
return;
}
if (searchMode > 0) {
var foundEngine = false;
var engineURIs = [];
var treeitemNode;
var engineBox = document.getElementById("engineKids");
// in advanced search mode, get selected search engines
// (for the current search category)
for (var x = 0; x < engineBox.childNodes.length; x++) {
treeitemNode = engineBox.childNodes[x];
if (treeitemNode) {
var checkboxNode = treeitemNode.firstChild.firstChild.firstChild;
if (checkboxNode && checkboxNode.checked) {
var engineURI = treeitemNode.id;
if (engineURI) {
engineURIs[engineURIs.length] = engineURI;
foundEngine = true;
}
}
}
}
if (!foundEngine) {
if (getNumEngines() == 1) {
// only one engine in this category, check it
treeitemNode = engineBox.firstChild;
engineURIs[engineURIs.length] = treeitemNode.id;
}
else {
for (var i = 0; i < engineBox.childNodes.length; ++i) {
treeitemNode = engineBox.childNodes[i];
var theID = treeitemNode.id;
if (theID.indexOf("NetscapeSearch.src") != -1) {
engineURIs[engineURIs.length] = theID;
foundEngine = true;
break;
}
}
if (!foundEngine) {
alert(searchBundle.getString("enterstringandlocation"));
return;
}
}
}
}
// hide search button
var searchButtonNode = document.getElementById("searchButton");
searchButtonNode.setAttribute("hidden", "true");
// show stop button
var stopButtonNode = document.getElementById("stopButton");
stopButtonNode.removeAttribute("hidden");
var progressNode = top.document.getElementById("statusbar-icon");
if (progressNode)
progressNode.setAttribute("mode", "undetermined");
// run the search
OpenSearch(textNode.value, engineURIs);
switchTab(0);
}
function checkSearchProgress()
{
var activeSearchFlag = false;
var navWindow = getNavigatorWindow(false);
if (navWindow) {
var resultsTree = navWindow._content.document.getElementById("internetresultstree");
if (resultsTree) {
var treeref = resultsTree.getAttribute("ref");
var ds = resultsTree.database;
if (ds && treeref) {
try {
var rdf = Components.classes[RDFSERVICE_CONTRACTID].getService(nsIRDFService);
var source = rdf.GetResource(treeref, true);
var loadingProperty = rdf.GetResource("http://home.netscape.com/NC-rdf#loading", true);
var target = ds.GetTarget(source, loadingProperty, true);
if (target)
target = target.QueryInterface(nsIRDFLiteral).Value;
activeSearchFlag = target == "true" ? true : false;
}
catch (ex) {
activeSearchFlag = false;
}
}
}
}
if (activeSearchFlag)
setTimeout("checkSearchProgress()", 1000);
else
doStop();
return activeSearchFlag;
}
function sidebarOpenURL(treeitem)
{
if (treeitem.getAttribute("container") == "true" ||
treeitem.getAttribute("type") == "http://home.netscape.com/NC-rdf#BookmarkSeparator") {
return;
}
var id = treeitem.id;
if (!id)
return;
// rjc: add support for anonymous resources; if the node has
// a "#URL" property, use it, otherwise default to using the id
try {
var ds = document.getElementById("Tree").database;
if (ds) {
var rdf = Components.classes[RDFSERVICE_CONTRACTID].getService(nsIRDFService);
var src = rdf.GetResource(id, true);
var prop = rdf.GetResource("http://home.netscape.com/NC-rdf#URL", true);
var target = ds.GetTarget(src, prop, true);
if (target) {
target = target.QueryInterface(nsIRDFLiteral).Value;
if (target)
id = target;
}
}
} catch (ex) {
}
loadURLInContent(id);
}
function OpenSearch(aSearchStr, engineURIs)
{
var searchEngineURI = nsPreferences.copyUnicharPref("browser.search.defaultengine", null);
var defaultSearchURL = nsPreferences.getLocalizedUnicharPref("browser.search.defaulturl", null);
if (!defaultSearchURL)
defaultSearchURL = searchBundle.getString("defaultSearchURL");
var searchDS = Components.classes[ISEARCH_CONTRACTID].getService(nsIInternetSearchService);
var escapedSearchStr = escape(aSearchStr);
searchDS.RememberLastSearchText(escapedSearchStr);
var gURL;
try {
if (!engineURIs || engineURIs.length <= 1) {
// not called from sidebar or only one engine selected
if (engineURIs && engineURIs.length == 1) {
searchEngineURI = engineURIs[0];
gURL = "internetsearch:engine=" + searchEngineURI + "&text=" + escapedSearchStr;
}
if (!searchEngineURI)
searchEngineURI = searchBundle.getString("defaultSearchURL");
// look up the correct search URL format for the given engine
try {
var searchURL = searchDS.GetInternetSearchURL(searchEngineURI, escapedSearchStr);
}
catch (ex) {
searchURL = "";
}
defaultSearchURL = searchURL ? searchURL : defaultSearchURL + escapedSearchStr;
if (!searchURL)
gURL = "";
// load the results page of selected or default engine in the content area
if (defaultSearchURL)
loadURLInContent(defaultSearchURL);
}
else {
// multiple providers
searchURL = "";
for (var i = 0; i < engineURIs.length; ++i) {
searchURL += !searchURL ? "internetsearch:" : "&";
searchURL += "engine=" + engineURIs[i];
}
searchURL += ("&text=" + escapedSearchStr);
gURL = searchURL;
loadURLInContent("chrome://communicator/content/search/internetresults.xul?" + escape(searchURL));
}
}
catch (ex) {}
setTimeout("checkSearchProgress()", 1000);
}
function switchTab(aPageIndex)
{
var deck = document.getElementById("advancedDeck");
deck.setAttribute("index", aPageIndex);
// decide whether to show/hide/enable/disable save search query button
if (aPageIndex != 0)
return;
var ds = document.getElementById("Tree").database;
if (!ds)
return;
var haveSearchRef = false;
var rdf = Components.classes[RDFSERVICE_CONTRACTID].getService(nsIRDFService);
// look for last search URI
var source = rdf.GetResource("NC:LastSearchRoot", true);
var childProperty = rdf.GetResource("http://home.netscape.com/NC-rdf#ref", true);
var target = ds.GetTarget(source, childProperty, true);
if (target) {
target = target.QueryInterface(nsIRDFLiteral).Value;
if (target)
haveSearchRef = true;
}
var saveQueryButton = document.getElementById("saveQueryButton");
saveQueryButton.disabled = !haveSearchRef;
}
function saveSearch()
{
var ds = document.getElementById("Tree").database;
if (!ds)
return;
var lastSearchURI = "";
var lastSearchText = "";
var rdf = Components.classes[RDFSERVICE_CONTRACTID].getService(nsIRDFService);
// look for last search URI
var source = rdf.GetResource("NC:LastSearchRoot", true);
var childProperty = rdf.GetResource("http://home.netscape.com/NC-rdf#ref", true);
var target = ds.GetTarget(source, childProperty, true);
if (target) {
target = target.QueryInterface(nsIRDFLiteral).Value;
if (target)
lastSearchURI = target;
}
// look for last search text
childProperty = rdf.GetResource("http://home.netscape.com/NC-rdf#LastText", true);
target = ds.GetTarget(source, childProperty, true);
if (target) {
target = target.QueryInterface(nsIRDFLiteral).Value;
if (target) {
// convert plusses (+) back to spaces
target = target.replace(/+/i, " ");
lastSearchText = unescape(target);
}
}
if (!lastSearchURI)
return;
// rjc says: if lastSearchText is empty/null, that's still OK, synthesize the text
if (!lastSearchText) {
lastSearchText = lastSearchURI;
var siteOffset = lastSearchText.indexOf("://");
if (siteOffset > 0) {
siteOffset += 3;
var endOffset = lastSearchText.indexOf("/", siteOffset);
if (endOffset > 0)
lastSearchText = lastSearchText.substr(0, endOffset+1);
}
}
var searchTitle = "Search: '" + lastSearchText + "'"; // using " + gSites;
var bmks = Components.classes[BMARKS_CONTRACTID].getService(nsIBookmarksService);
bmks.AddBookmark(lastSearchURI, searchTitle, bmks.BOOKMARK_SEARCH_TYPE, null);
}
function doCustomize()
{
//Switching from Edit Categories back to All Engines then launching customize window
var category = document.getElementById("categoryList");
category.selectedIndex = 0;
window.openDialog("chrome://communicator/content/search/search-editor.xul", "internetsearch:editor", "centerscreen,chrome,resizable");
}
function loadURLInContent(url)
{
var navigatorWindow = getNavigatorWindow(true);
navigatorWindow.loadURI(url);
}
// retrieves the most recent navigator window
function getNavigatorWindow(aOpenFlag)
{
var navigatorWindow;
// if this is a browser window, just use it
if ("document" in top) {
var possibleNavigator = top.document.getElementById("main-window");
if (possibleNavigator &&
possibleNavigator.getAttribute("windowtype") == "navigator:browser")
navigatorWindow = top;
}
// if not, get the most recently used browser window
if (!navigatorWindow) {
var wm = Components.classes[WMEDIATOR_CONTRACTID].getService(nsIWindowMediator);
navigatorWindow = wm.getMostRecentWindow("navigator:browser");
}
// if no browser window available and it's ok to open a new one, do so
if (!navigatorWindow && aOpenFlag) {
var navigatorChromeURL = search_getBrowserURL();
navigatorWindow = openDialog(navigatorChromeURL, "_blank", "chrome,all,dialog=no");
}
return navigatorWindow;
}
function search_getBrowserURL()
{
return nsPreferences.copyUnicharPref("browser.chromeURL", "chrome://navigator/content/navigator.xul");
}
function doEnabling()
{
var searchButton = document.getElementById("searchButton");
var sidebarSearchText = document.getElementById("sidebar-search-text");
searchButton.disabled = !sidebarSearchText.value;
}