635 строки
18 KiB
JavaScript
635 строки
18 KiB
JavaScript
/* -*- Mode: Java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla 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/MPL/
|
|
*
|
|
* 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 the Initial Developer are Copyright (C) 1998
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Robert John Churchill <rjc@netscape.com>
|
|
* Blake Ross <BlakeR1234@aol.com>
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
|
|
|
|
// global(s)
|
|
var gSearchBundle;
|
|
var promptService;
|
|
var pref = null;
|
|
var RDF = null;
|
|
var RDFC = null;
|
|
var RDFCUtils = null;
|
|
var catDS = null;
|
|
var internetSearchDS = null;
|
|
|
|
try
|
|
{
|
|
pref = Components.classes["@mozilla.org/preferences-service;1"]
|
|
.getService(Components.interfaces.nsIPrefBranch);
|
|
|
|
RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
|
|
|
|
RDFC = Components.classes["@mozilla.org/rdf/container;1"].createInstance(Components.interfaces.nsIRDFContainer);
|
|
|
|
RDFCUtils = Components.classes["@mozilla.org/rdf/container-utils;1"].getService(Components.interfaces.nsIRDFContainerUtils);
|
|
}
|
|
catch(e)
|
|
{
|
|
pref = null;
|
|
RDF = null;
|
|
RDFC = null;
|
|
RDFCUtils = null;
|
|
}
|
|
|
|
|
|
|
|
function debug(msg)
|
|
{
|
|
// uncomment for noise
|
|
// dump(msg+"\n");
|
|
}
|
|
|
|
|
|
|
|
function doLoad()
|
|
{
|
|
gSearchBundle = document.getElementById("searchBundle");
|
|
promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
|
.getService(Components.interfaces.nsIPromptService);
|
|
|
|
var categoryList = document.getElementById("categoryList");
|
|
// adjust category popup
|
|
var internetSearch = Components.classes["@mozilla.org/rdf/datasource;1?name=internetsearch"].getService();
|
|
if (internetSearch) internetSearch = internetSearch.QueryInterface(Components.interfaces.nsIInternetSearchService);
|
|
if (internetSearch)
|
|
{
|
|
internetSearchDS = internetSearch.QueryInterface(Components.interfaces.nsIRDFDataSource);
|
|
|
|
catDS = internetSearch.GetCategoryDataSource();
|
|
if (catDS) catDS = catDS.QueryInterface(Components.interfaces.nsIRDFDataSource);
|
|
if (catDS)
|
|
{
|
|
if (categoryList)
|
|
{
|
|
categoryList.database.AddDataSource(catDS);
|
|
categoryList.builder.rebuild();
|
|
}
|
|
var engineList = document.getElementById("engineList");
|
|
if (engineList)
|
|
{
|
|
engineList.database.AddDataSource(catDS);
|
|
engineList.builder.rebuild();
|
|
}
|
|
}
|
|
}
|
|
|
|
// try and determine last category name used
|
|
var lastCategoryName = "";
|
|
try
|
|
{
|
|
var pref = Components.classes["@mozilla.org/preferences-service;1"]
|
|
.getService(Components.interfaces.nsIPrefBranch);
|
|
lastCategoryName = pref.getCharPref( "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);
|
|
}
|
|
}
|
|
|
|
}
|
|
catch( e )
|
|
{
|
|
debug("Exception in SearchPanelStartup\n");
|
|
lastCategoryName = "";
|
|
}
|
|
debug("\nSearchPanelStartup: lastCategoryName = '" + lastCategoryName + "'\n");
|
|
|
|
// select the appropriate category
|
|
var categoryPopup = document.getElementById( "categoryPopup" );
|
|
if( categoryList && categoryPopup )
|
|
{
|
|
var found = false;
|
|
for( var i = 0; i < categoryPopup.childNodes.length; i++ )
|
|
{
|
|
if( ( lastCategoryName == "" && categoryPopup.childNodes[i].getAttribute("value") == "NC:SearchEngineRoot" ) ||
|
|
( categoryPopup.childNodes[i].getAttribute("id") == lastCategoryName ) )
|
|
{
|
|
categoryList.selectedItem = categoryPopup.childNodes[i];
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (categoryPopup.childNodes.length > 0)
|
|
{
|
|
if (found == false)
|
|
{
|
|
categoryList.selectedItem = categoryPopup.childNodes[0];
|
|
}
|
|
chooseCategory(categoryList.selectedItem);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function Commit()
|
|
{
|
|
// flush
|
|
if (catDS)
|
|
{
|
|
var flushableDS = catDS.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
|
|
if (flushableDS)
|
|
{
|
|
flushableDS.Flush();
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
function doUnload()
|
|
{
|
|
// Get the current window position/size.
|
|
var x = window.screenX;
|
|
var y = window.screenY;
|
|
var h = window.outerHeight;
|
|
var w = window.outerWidth;
|
|
|
|
// Store these into the window attributes (for persistence).
|
|
var win = document.getElementById( "search-editor-window" );
|
|
win.setAttribute( "x", x );
|
|
win.setAttribute( "y", y );
|
|
win.setAttribute( "height", h );
|
|
win.setAttribute( "width", w );
|
|
}
|
|
|
|
|
|
|
|
/* Note: doSort() does NOT support natural order sorting, unless naturalOrderResource is valid,
|
|
in which case we sort ascending on naturalOrderResource
|
|
*/
|
|
function doSort(sortColName, naturalOrderResource)
|
|
{
|
|
var node = document.getElementById(sortColName);
|
|
// determine column resource to sort on
|
|
var sortResource = node.getAttribute('resource');
|
|
if (!sortResource) return(false);
|
|
|
|
var sortDirection="ascending";
|
|
var isSortActive = node.getAttribute('sortActive');
|
|
if (isSortActive == "true")
|
|
{
|
|
sortDirection = "ascending";
|
|
|
|
var currentDirection = node.getAttribute('sortDirection');
|
|
if (currentDirection == "ascending")
|
|
{
|
|
if (sortResource != naturalOrderResource)
|
|
{
|
|
sortDirection = "descending";
|
|
}
|
|
}
|
|
else if (currentDirection == "descending")
|
|
{
|
|
if (naturalOrderResource != null && naturalOrderResource != "")
|
|
{
|
|
sortResource = naturalOrderResource;
|
|
}
|
|
}
|
|
}
|
|
|
|
var isupports = Components.classes["@mozilla.org/xul/xul-sort-service;1"].getService();
|
|
if (!isupports) return(false);
|
|
var xulSortService = isupports.QueryInterface(Components.interfaces.nsIXULSortService);
|
|
if (!xulSortService) return(false);
|
|
try
|
|
{
|
|
xulSortService.sort(node, sortResource, sortDirection);
|
|
}
|
|
catch(ex)
|
|
{
|
|
debug("Exception calling xulSortService.sort()");
|
|
}
|
|
return(true);
|
|
}
|
|
|
|
|
|
|
|
function chooseCategory( aNode )
|
|
{
|
|
var category = "NC:SearchCategory?category=" + aNode.getAttribute("id");
|
|
debug("chooseCategory: '" + category + "'\n");
|
|
|
|
var treeNode = document.getElementById("engineList");
|
|
if (treeNode)
|
|
{
|
|
dump("*** Set search engine list to category=" + category + "\n");
|
|
treeNode.setAttribute( "ref", category );
|
|
treeNode.builder.rebuild();
|
|
}
|
|
return(true);
|
|
}
|
|
|
|
|
|
|
|
function AddEngine()
|
|
{
|
|
var allenginesList = document.getElementById("allengines");
|
|
if (!allenginesList) return(false);
|
|
var select_list = allenginesList.selectedItems;
|
|
if (!select_list) return(false)
|
|
if (select_list.length < 1) return(false);
|
|
|
|
// make sure we have at least one category to add engine into
|
|
var categoryPopup = document.getElementById( "categoryPopup" );
|
|
if (!categoryPopup) return(false);
|
|
if (categoryPopup.childNodes.length < 1)
|
|
{
|
|
if (NewCategory() == false) return(false);
|
|
}
|
|
|
|
var engineList = document.getElementById("engineList");
|
|
if (!engineList) return(false);
|
|
|
|
var ref = engineList.getAttribute("ref");
|
|
if ((!ref) || (ref == "")) return(false);
|
|
|
|
var categoryRes = RDF.GetResource(ref);
|
|
if (!categoryRes) return(false);
|
|
|
|
RDFCUtils.MakeSeq(catDS, categoryRes);
|
|
|
|
RDFC.Init(catDS, categoryRes);
|
|
|
|
var urlRes = RDF.GetResource("http://home.netscape.com/NC-rdf#URL");
|
|
if (!urlRes) return(false);
|
|
var typeRes = RDF.GetResource("http://home.netscape.com/NC-rdf#searchtype");
|
|
if (!typeRes) return(false);
|
|
var engineRes = RDF.GetResource("http://home.netscape.com/NC-rdf#Engine");
|
|
if (!engineRes) return(false);
|
|
|
|
for (var x = 0; x < select_list.length; x++)
|
|
{
|
|
var id = select_list[x].getAttribute("id");
|
|
if ((!id) || (id == "")) return(false);
|
|
var idRes = RDF.GetResource(id);
|
|
if (!idRes) return(false);
|
|
|
|
// try and find/use alias to search engine
|
|
var privateEngineFlag = internetSearchDS.HasAssertion(idRes, typeRes, engineRes, true);
|
|
if (privateEngineFlag == true)
|
|
{
|
|
var node = internetSearchDS.GetTarget(idRes, urlRes, true);
|
|
if (node) node = node.QueryInterface(Components.interfaces.nsIRDFLiteral);
|
|
if (node)
|
|
{
|
|
if (node.Value)
|
|
{
|
|
id = node.Value;
|
|
idRes = RDF.GetResource(id);
|
|
if (!idRes) return(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
var nodeIndex = RDFC.IndexOf(idRes);
|
|
if (nodeIndex < 1)
|
|
{
|
|
RDFC.AppendElement(idRes);
|
|
}
|
|
}
|
|
|
|
return(true);
|
|
}
|
|
|
|
|
|
|
|
function RemoveEngine()
|
|
{
|
|
var engineList = document.getElementById("engineList");
|
|
if (!engineList) return(false);
|
|
var select_list = engineList.selectedItems;
|
|
if (!select_list) return(false)
|
|
if (select_list.length < 1) return(false);
|
|
|
|
var ref = engineList.getAttribute("ref");
|
|
if ((!ref) || (ref == "")) return(false);
|
|
var categoryRes = RDF.GetResource(ref);
|
|
if (!categoryRes) return(false);
|
|
|
|
RDFC.Init(catDS, categoryRes);
|
|
|
|
// Note: walk backwards to make deletion easier
|
|
for (var x = select_list.length - 1; x >= 0; x--)
|
|
{
|
|
var id = select_list[x].getAttribute("id");
|
|
if ((!id) || (id == "")) return(false);
|
|
var idRes = RDF.GetResource(id);
|
|
if (!idRes) return(false);
|
|
|
|
var nodeIndex = RDFC.IndexOf(idRes);
|
|
if (nodeIndex > 0)
|
|
{
|
|
RDFC.RemoveElementAt(nodeIndex, true, idRes);
|
|
}
|
|
}
|
|
|
|
return(true);
|
|
}
|
|
|
|
|
|
|
|
function MoveUp()
|
|
{
|
|
return MoveDelta(-1);
|
|
}
|
|
|
|
|
|
|
|
function MoveDown()
|
|
{
|
|
return MoveDelta(1);
|
|
}
|
|
|
|
|
|
|
|
function MoveDelta(delta)
|
|
{
|
|
var engineList = document.getElementById("engineList");
|
|
if (!engineList) return(false);
|
|
var select_list = engineList.selectedItems;
|
|
if (!select_list) return(false)
|
|
if (select_list.length != 1) return(false);
|
|
|
|
var ref = engineList.getAttribute("ref");
|
|
if (!ref) return(false);
|
|
var categoryRes = RDF.GetResource(ref);
|
|
if (!categoryRes) return(false);
|
|
|
|
var id = select_list[0].id;
|
|
if (!id) return(false);
|
|
var idRes = RDF.GetResource(id);
|
|
if (!idRes) return(false);
|
|
|
|
RDFC.Init(catDS, categoryRes);
|
|
|
|
var nodeIndex = RDFC.IndexOf(idRes);
|
|
if (nodeIndex < 1) return(false); // how did that happen?
|
|
|
|
var numItems = RDFC.GetCount();
|
|
|
|
var newPos = -1;
|
|
if (((delta == -1) && (nodeIndex > 1)) ||
|
|
((delta == 1) && (nodeIndex < numItems)))
|
|
{
|
|
newPos = nodeIndex + delta;
|
|
RDFC.RemoveElementAt(nodeIndex, true, idRes);
|
|
}
|
|
if (newPos > 0)
|
|
{
|
|
RDFC.InsertElementAt(idRes, newPos, true);
|
|
}
|
|
|
|
selectItems(engineList, ref, id);
|
|
|
|
return(true);
|
|
}
|
|
|
|
function doMoveDirectionEnabling()
|
|
{
|
|
var engineList = document.getElementById("engineList")
|
|
var selectedItems = engineList.selectedItems;
|
|
var nodeIndex = -1;
|
|
if (selectedItems && selectedItems.length == 1) {
|
|
var ref = engineList.getAttribute("ref");
|
|
var categoryResource = RDF.GetResource(ref);
|
|
var elementResource = RDF.GetResource(selectedItems[0].id);
|
|
RDFC.Init(catDS, categoryResource);
|
|
nodeIndex = RDFC.IndexOf(elementResource);
|
|
}
|
|
|
|
var moveUpButton = document.getElementById("up");
|
|
var moveDownButton = document.getElementById("down");
|
|
|
|
if (nodeIndex <= 1)
|
|
moveUpButton.setAttribute("disabled", "true");
|
|
else
|
|
moveUpButton.removeAttribute("disabled");
|
|
|
|
if (nodeIndex < 0 || nodeIndex >= RDFC.GetCount())
|
|
moveDownButton.setAttribute("disabled", "true");
|
|
else
|
|
moveDownButton.removeAttribute("disabled");
|
|
}
|
|
|
|
|
|
function NewCategory()
|
|
{
|
|
const promptStr = gSearchBundle.getString("NewCategoryPrompt");
|
|
const newTitle = gSearchBundle.getString("NewCategoryTitle");
|
|
var result = {value:null};
|
|
var confirmed = promptService.prompt(window, newTitle, promptStr, result, null, {value:0});
|
|
if (!confirmed || (!result.value) || result.value == "") return(false);
|
|
|
|
var newName = RDF.GetLiteral(result.value);
|
|
if (!newName) return(false);
|
|
|
|
var categoryRes = RDF.GetResource("NC:SearchCategoryRoot");
|
|
if (!categoryRes) return(false);
|
|
|
|
RDFC.Init(catDS, categoryRes);
|
|
|
|
var randomID = Math.random();
|
|
var categoryID = "NC:SearchCategory?category=urn:search:category:" + randomID.toString();
|
|
var currentCatRes = RDF.GetResource(categoryID);
|
|
if (!currentCatRes) return(false);
|
|
|
|
var titleRes = RDF.GetResource("http://home.netscape.com/NC-rdf#title");
|
|
if (!titleRes) return(false);
|
|
|
|
// set the category's name
|
|
catDS.Assert(currentCatRes, titleRes, newName, true);
|
|
|
|
// and insert the category
|
|
RDFC.AppendElement(currentCatRes);
|
|
|
|
RDFCUtils.MakeSeq(catDS, currentCatRes);
|
|
|
|
// try and select the new category
|
|
var categoryList = document.getElementById( "categoryList" );
|
|
var select_list = categoryList.getElementsByAttribute("id", categoryID);
|
|
if (select_list && select_list.item(0))
|
|
{
|
|
categoryList.selectedItem = select_list[0];
|
|
chooseCategory(categoryList.selectedItem);
|
|
}
|
|
return(true);
|
|
}
|
|
|
|
|
|
|
|
function RenameCategory()
|
|
{
|
|
// make sure we have at least one category
|
|
var categoryPopup = document.getElementById( "categoryPopup" );
|
|
if (!categoryPopup) return(false);
|
|
if (categoryPopup.childNodes.length < 1) return(false);
|
|
|
|
var categoryList = document.getElementById( "categoryList" );
|
|
var currentName = categoryList.selectedItem.getAttribute("label");
|
|
const promptStr = gSearchBundle.getString("RenameCategoryPrompt");
|
|
const renameTitle = gSearchBundle.getString("RenameCategoryTitle");
|
|
var result = {value:currentName};
|
|
var confirmed = promptService.prompt(window,renameTitle,promptStr,result,null,{value:0});
|
|
if (!confirmed || (!result.value) || (result.value == "") || result.value == currentName) return(false);
|
|
|
|
var currentCatID = categoryList.selectedItem.getAttribute("id");
|
|
var currentCatRes = RDF.GetResource(currentCatID);
|
|
if (!currentCatRes) return(false);
|
|
|
|
var titleRes = RDF.GetResource("http://home.netscape.com/NC-rdf#title");
|
|
if (!titleRes) return(false);
|
|
|
|
var newName = RDF.GetLiteral(result.value);
|
|
if (!newName) return(false);
|
|
|
|
var oldName = catDS.GetTarget(currentCatRes, titleRes, true);
|
|
if (oldName) oldName = oldName.QueryInterface(Components.interfaces.nsIRDFLiteral);
|
|
if (oldName)
|
|
{
|
|
catDS.Change(currentCatRes, titleRes, oldName, newName);
|
|
}
|
|
else
|
|
{
|
|
catDS.Assert(currentCatRes, titleRes, newName, true);
|
|
}
|
|
|
|
// force popup to update
|
|
chooseCategory(categoryList.selectedItem);
|
|
|
|
return(true);
|
|
}
|
|
|
|
|
|
|
|
function RemoveCategory()
|
|
{
|
|
// make sure we have at least one category
|
|
var categoryPopup = document.getElementById( "categoryPopup" );
|
|
if (!categoryPopup) return(false);
|
|
if (categoryPopup.childNodes.length < 1) return(false);
|
|
|
|
const titleStr = gSearchBundle.getString("RemoveCategoryTitle");
|
|
const promptStr = gSearchBundle.getString("RemoveCategoryPrompt");
|
|
const yesStr = gSearchBundle.getString("RemoveCategoryYes");
|
|
var flags = ((promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0) +
|
|
(promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_1) +
|
|
promptService.BUTTON_POS_1_DEFAULT);
|
|
if (promptService.confirmEx(window, titleStr, promptStr, flags, yesStr, null, null, null, {value:0}) == 1)
|
|
return false;
|
|
|
|
var categoryRes = RDF.GetResource("NC:SearchCategoryRoot");
|
|
if (!categoryRes) return(false);
|
|
|
|
var categoryList = document.getElementById( "categoryList" );
|
|
if (!categoryList) return(false);
|
|
|
|
var idNum = categoryList.selectedIndex;
|
|
|
|
var id = categoryList.selectedItem.getAttribute("id");
|
|
if ((!id) || (id == "")) return(false);
|
|
|
|
var idRes = RDF.GetResource(id);
|
|
if (!idRes) return(false);
|
|
|
|
RDFC.Init(catDS, categoryRes);
|
|
|
|
var nodeIndex = RDFC.IndexOf(idRes);
|
|
if (nodeIndex < 1) return(false); // how did that happen?
|
|
|
|
RDFC.RemoveElementAt(nodeIndex, true, idRes);
|
|
|
|
// try and select another category
|
|
if (idNum > 0) --idNum;
|
|
else idNum = 0;
|
|
|
|
if (categoryPopup.childNodes.length > 0)
|
|
{
|
|
categoryList.selectedItem = categoryPopup.childNodes[idNum];
|
|
chooseCategory(categoryList.selectedItem);
|
|
}
|
|
else
|
|
{
|
|
// last category was deleted, so empty out engine list
|
|
var treeNode = document.getElementById("engineList");
|
|
if (treeNode)
|
|
{
|
|
treeNode.setAttribute( "ref", "" );
|
|
}
|
|
}
|
|
return(true);
|
|
}
|
|
|
|
|
|
|
|
function selectItems(listbox, containerID, targetID)
|
|
{
|
|
var select_list = listbox.getElementsByAttribute("id", targetID);
|
|
for (var x=0; x<select_list.length; x++)
|
|
{
|
|
var node = select_list[x];
|
|
if (!node) continue;
|
|
|
|
var parent = node.parentNode;
|
|
if (!parent) continue;
|
|
|
|
var id = parent.getAttribute("ref");
|
|
if (!id || id=="")
|
|
{
|
|
id = parent.getAttribute("id");
|
|
}
|
|
if (!id || id=="") continue;
|
|
|
|
if (id == containerID)
|
|
{
|
|
listbox.selectItem(node);
|
|
break;
|
|
}
|
|
}
|
|
}
|