mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-15 04:00:12 +01:00
490 lines
16 KiB
JavaScript
490 lines
16 KiB
JavaScript
# ***** 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 the Browser Search Service.
|
|
#
|
|
# The Initial Developer of the Original Code is
|
|
# Google Inc.
|
|
# Portions created by the Initial Developer are Copyright (C) 2005
|
|
# the Initial Developer. All Rights Reserved.
|
|
#
|
|
# Contributor(s):
|
|
# Ben Goodger <beng@google.com> (Original author)
|
|
# Gavin Sharp <gavin@gavinsharp.com>
|
|
# Pamela Greene <pamg.bugs@gmail.com>
|
|
#
|
|
# Alternatively, the contents of this file may be used under the terms of
|
|
# either 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 *****
|
|
|
|
const Ci = Components.interfaces;
|
|
const Cc = Components.classes;
|
|
|
|
const ENGINE_FLAVOR = "text/x-moz-search-engine";
|
|
|
|
const BROWSER_SUGGEST_PREF = "browser.search.suggest.enabled";
|
|
|
|
var gEngineView = null;
|
|
|
|
var gEngineManagerDialog = {
|
|
init: function engineManager_init() {
|
|
gEngineView = new EngineView(new EngineStore());
|
|
|
|
var prefService = Cc["@mozilla.org/preferences-service;1"].
|
|
getService(Ci.nsIPrefBranch);
|
|
var suggestEnabled = prefService.getBoolPref(BROWSER_SUGGEST_PREF);
|
|
document.getElementById("enableSuggest").checked = suggestEnabled;
|
|
|
|
var tree = document.getElementById("engineList");
|
|
tree.view = gEngineView;
|
|
|
|
var os = Cc["@mozilla.org/observer-service;1"].
|
|
getService(Ci.nsIObserverService);
|
|
os.addObserver(this, "browser-search-engine-modified", false);
|
|
},
|
|
|
|
observe: function engineManager_observe(aEngine, aTopic, aVerb) {
|
|
if (aTopic == "browser-search-engine-modified") {
|
|
aEngine.QueryInterface(Ci.nsISearchEngine)
|
|
switch (aVerb) {
|
|
case "engine-added":
|
|
gEngineView._engineStore.addEngine(aEngine);
|
|
gEngineView.rowCountChanged(gEngineView.lastIndex, 1);
|
|
break;
|
|
case "engine-changed":
|
|
gEngineView._engineStore.reloadIcons();
|
|
break;
|
|
case "engine-removed":
|
|
case "engine-current":
|
|
// Not relevant
|
|
return;
|
|
}
|
|
gEngineView.invalidate();
|
|
}
|
|
},
|
|
|
|
onOK: function engineManager_onOK() {
|
|
// Remove the observer
|
|
var os = Cc["@mozilla.org/observer-service;1"].
|
|
getService(Ci.nsIObserverService);
|
|
os.removeObserver(this, "browser-search-engine-modified");
|
|
|
|
// Set the preference
|
|
var newSuggestEnabled = document.getElementById("enableSuggest").checked;
|
|
var prefService = Cc["@mozilla.org/preferences-service;1"].
|
|
getService(Ci.nsIPrefBranch);
|
|
prefService.setBoolPref(BROWSER_SUGGEST_PREF, newSuggestEnabled);
|
|
|
|
// Commit the changes
|
|
gEngineView._engineStore.commit();
|
|
},
|
|
|
|
onCancel: function engineManager_onCancel() {
|
|
// Remove the observer
|
|
var os = Cc["@mozilla.org/observer-service;1"].
|
|
getService(Ci.nsIObserverService);
|
|
os.removeObserver(this, "browser-search-engine-modified");
|
|
},
|
|
|
|
onRestoreDefaults: function engineManager_onRestoreDefaults() {
|
|
var num = gEngineView._engineStore.restoreDefaultEngines();
|
|
gEngineView.rowCountChanged(0, num);
|
|
gEngineView.invalidate();
|
|
},
|
|
|
|
showRestoreDefaults: function engineManager_showRestoreDefaults(val) {
|
|
document.documentElement.getButton("extra2").disabled = !val;
|
|
},
|
|
|
|
loadAddEngines: function engineManager_loadAddEngines() {
|
|
this.onOK();
|
|
window.opener.BrowserSearch.loadAddEngines();
|
|
window.close();
|
|
},
|
|
|
|
remove: function engineManager_remove() {
|
|
gEngineView._engineStore.removeEngine(gEngineView.selectedEngine);
|
|
var index = gEngineView.selectedIndex;
|
|
gEngineView.rowCountChanged(index, -1);
|
|
gEngineView.invalidate();
|
|
gEngineView.selection.select(Math.min(index, gEngineView.lastIndex));
|
|
gEngineView.ensureRowIsVisible(Math.min(index, gEngineView.lastIndex));
|
|
document.getElementById("engineList").focus();
|
|
},
|
|
|
|
/**
|
|
* Moves the selected engine either up or down in the engine list
|
|
* @param aDir
|
|
* -1 to move the selected engine down, +1 to move it up.
|
|
*/
|
|
bump: function engineManager_move(aDir) {
|
|
var selectedEngine = gEngineView.selectedEngine;
|
|
var newIndex = gEngineView.selectedIndex - aDir;
|
|
|
|
gEngineView._engineStore.moveEngine(selectedEngine, newIndex);
|
|
|
|
gEngineView.invalidate();
|
|
gEngineView.selection.select(newIndex);
|
|
gEngineView.ensureRowIsVisible(newIndex);
|
|
document.getElementById("engineList").focus();
|
|
},
|
|
|
|
onSelect: function engineManager_onSelect() {
|
|
// buttons only work if an engine is selected and it's not the last engine
|
|
var disableButtons = (gEngineView.selectedIndex == -1) ||
|
|
(gEngineView.lastIndex == 0);
|
|
var lastSelected = (gEngineView.selectedIndex == gEngineView.lastIndex);
|
|
var firstSelected = (gEngineView.selectedIndex == 0);
|
|
|
|
document.getElementById("cmd_remove").setAttribute("disabled",
|
|
disableButtons);
|
|
|
|
document.getElementById("cmd_moveup").setAttribute("disabled",
|
|
disableButtons || firstSelected);
|
|
|
|
document.getElementById("cmd_movedown").setAttribute("disabled",
|
|
disableButtons || lastSelected);
|
|
}
|
|
};
|
|
|
|
var gDragObserver = {
|
|
onDragStart: function (aEvent, aXferData, aDragAction) {
|
|
var selectedIndex = gEngineView.selectedIndex;
|
|
if (selectedIndex == -1)
|
|
return;
|
|
|
|
aXferData.data = new TransferData();
|
|
aXferData.data.addDataForFlavour(ENGINE_FLAVOR, selectedIndex.toString());
|
|
|
|
aDragAction.action = Ci.nsIDragService.DRAGDROP_ACTION_MOVE;
|
|
},
|
|
onDrop: function (aEvent, aXferData, aDragSession) { },
|
|
onDragExit: function (aEvent, aDragSession) { },
|
|
onDragOver: function (aEvent, aFlavour, aDragSession) { },
|
|
getSupportedFlavours: function() { return null; }
|
|
};
|
|
|
|
// "Operation" objects
|
|
function EngineMoveOp(aEngineClone, aNewIndex) {
|
|
if (!aEngineClone)
|
|
throw new Error("bad args to new EngineMoveOp!");
|
|
this._engine = aEngineClone.originalEngine;
|
|
this._newIndex = aNewIndex;
|
|
}
|
|
EngineMoveOp.prototype = {
|
|
_engine: null,
|
|
_newIndex: null,
|
|
commit: function EMO_commit() {
|
|
var searchService = Cc["@mozilla.org/browser/search-service;1"].
|
|
getService(Ci.nsIBrowserSearchService);
|
|
searchService.moveEngine(this._engine, this._newIndex);
|
|
}
|
|
}
|
|
|
|
function EngineRemoveOp(aEngineClone) {
|
|
if (!aEngineClone)
|
|
throw new Error("bad args to new EngineRemoveOp!");
|
|
this._engine = aEngineClone.originalEngine;
|
|
}
|
|
EngineRemoveOp.prototype = {
|
|
_engine: null,
|
|
commit: function ERO_commit() {
|
|
var searchService = Cc["@mozilla.org/browser/search-service;1"].
|
|
getService(Ci.nsIBrowserSearchService);
|
|
searchService.removeEngine(this._engine);
|
|
}
|
|
}
|
|
|
|
function EngineUnhideOp(aEngineClone, aNewIndex) {
|
|
if (!aEngineClone)
|
|
throw new Error("bad args to new EngineUnhideOp!");
|
|
this._engine = aEngineClone.originalEngine;
|
|
this._newIndex = aNewIndex;
|
|
}
|
|
EngineUnhideOp.prototype = {
|
|
_engine: null,
|
|
_newIndex: null,
|
|
commit: function EUO_commit() {
|
|
this._engine.hidden = false;
|
|
var searchService = Cc["@mozilla.org/browser/search-service;1"].
|
|
getService(Ci.nsIBrowserSearchService);
|
|
searchService.moveEngine(this._engine, this._newIndex);
|
|
}
|
|
}
|
|
|
|
function EngineStore() {
|
|
var searchService = Cc["@mozilla.org/browser/search-service;1"].
|
|
getService(Ci.nsIBrowserSearchService);
|
|
this._engines = searchService.getVisibleEngines({}).map(this._cloneEngine);
|
|
this._defaultEngines = searchService.getDefaultEngines({}).map(this._cloneEngine);
|
|
|
|
this._ops = [];
|
|
|
|
// check if we need to disable the restore defaults button
|
|
var someHidden = this._defaultEngines.some(function (e) {return e.hidden;});
|
|
gEngineManagerDialog.showRestoreDefaults(someHidden);
|
|
}
|
|
EngineStore.prototype = {
|
|
_engines: null,
|
|
_defaultEngines: null,
|
|
_ops: null,
|
|
|
|
get engines() {
|
|
return this._engines;
|
|
},
|
|
set engines(val) {
|
|
this._engines = val;
|
|
return val;
|
|
},
|
|
|
|
_getIndexForEngine: function ES_getIndexForEngine(aEngine) {
|
|
return this._engines.indexOf(aEngine);
|
|
},
|
|
|
|
_getEngineByName: function ES_getEngineByName(aName) {
|
|
for each (var engine in this._engines)
|
|
if (engine.name == aName)
|
|
return engine;
|
|
},
|
|
|
|
_cloneEngine: function ES_cloneObj(aEngine) {
|
|
var newO=[];
|
|
for (var i in aEngine)
|
|
newO[i] = aEngine[i];
|
|
newO.originalEngine = aEngine;
|
|
return newO;
|
|
},
|
|
|
|
// Callback for Array's some(). A thisObj must be passed to some()
|
|
_isSameEngine: function ES_isSameEngine(aEngineClone) {
|
|
return aEngineClone.originalEngine == this.originalEngine;
|
|
},
|
|
|
|
commit: function ES_commit() {
|
|
var searchService = Cc["@mozilla.org/browser/search-service;1"].
|
|
getService(Ci.nsIBrowserSearchService);
|
|
var currentEngine = this._cloneEngine(searchService.currentEngine);
|
|
for (var i = 0; i < this._ops.length; i++)
|
|
this._ops[i].commit();
|
|
|
|
// Restore currentEngine if it is a default engine that is still visible.
|
|
// Needed if the user deletes currentEngine and then restores it.
|
|
if (this._defaultEngines.some(this._isSameEngine, currentEngine) &&
|
|
!currentEngine.originalEngine.hidden)
|
|
searchService.currentEngine = currentEngine.originalEngine;
|
|
},
|
|
|
|
addEngine: function ES_addEngine(aEngine) {
|
|
this._engines.push(this._cloneEngine(aEngine));
|
|
},
|
|
|
|
moveEngine: function ES_moveEngine(aEngine, aNewIndex) {
|
|
if (aNewIndex < 0 || aNewIndex > this._engines.length - 1)
|
|
throw new Error("ES_moveEngine: invalid aNewIndex!");
|
|
var index = this._getIndexForEngine(aEngine);
|
|
if (index == -1)
|
|
throw new Error("ES_moveEngine: invalid engine?");
|
|
|
|
if (index == aNewIndex)
|
|
return; // nothing to do
|
|
|
|
// Move the engine in our internal store
|
|
var removedEngine = this._engines.splice(index, 1)[0];
|
|
this._engines.splice(aNewIndex, 0, removedEngine);
|
|
|
|
this._ops.push(new EngineMoveOp(aEngine, aNewIndex));
|
|
},
|
|
|
|
removeEngine: function ES_removeEngine(aEngine) {
|
|
var index = this._getIndexForEngine(aEngine);
|
|
if (index == -1)
|
|
throw new Error("invalid engine?");
|
|
|
|
this._engines.splice(index, 1);
|
|
this._ops.push(new EngineRemoveOp(aEngine));
|
|
if (this._defaultEngines.some(this._isSameEngine, aEngine))
|
|
gEngineManagerDialog.showRestoreDefaults(true);
|
|
},
|
|
|
|
restoreDefaultEngines: function ES_restoreDefaultEngines() {
|
|
var added = 0;
|
|
|
|
for (var i = 0; i < this._defaultEngines.length; ++i) {
|
|
var e = this._defaultEngines[i];
|
|
|
|
// If the engine is already in the list, just move it.
|
|
if (this._engines.some(this._isSameEngine, e)) {
|
|
this.moveEngine(this._getEngineByName(e.name), i);
|
|
} else {
|
|
// Otherwise, add it back to our internal store
|
|
this._engines.splice(i, 0, e);
|
|
this._ops.push(new EngineUnhideOp(e, i));
|
|
added++;
|
|
}
|
|
}
|
|
gEngineManagerDialog.showRestoreDefaults(false);
|
|
return added;
|
|
},
|
|
|
|
reloadIcons: function ES_reloadIcons() {
|
|
this._engines.forEach(function (e) {
|
|
e.uri = e.originalEngine.uri;
|
|
});
|
|
}
|
|
}
|
|
|
|
function EngineView(aEngineStore) {
|
|
this._engineStore = aEngineStore;
|
|
}
|
|
EngineView.prototype = {
|
|
_engineStore: null,
|
|
tree: null,
|
|
|
|
get lastIndex() {
|
|
return this.rowCount - 1;
|
|
},
|
|
get selectedIndex() {
|
|
var seln = this.selection;
|
|
if (seln.getRangeCount() > 0) {
|
|
var min = { };
|
|
seln.getRangeAt(0, min, { });
|
|
return min.value;
|
|
}
|
|
return -1;
|
|
},
|
|
get selectedEngine() {
|
|
return this._engineStore.engines[this.selectedIndex];
|
|
},
|
|
|
|
// Helpers
|
|
rowCountChanged: function (index, count) {
|
|
this.tree.rowCountChanged(index, count);
|
|
},
|
|
|
|
invalidate: function () {
|
|
this.tree.invalidate();
|
|
},
|
|
|
|
ensureRowIsVisible: function (index) {
|
|
this.tree.ensureRowIsVisible(index);
|
|
},
|
|
|
|
getSourceIndexFromDrag: function () {
|
|
var dragService = Cc["@mozilla.org/widget/dragservice;1"].
|
|
getService().QueryInterface(Ci.nsIDragService);
|
|
var dragSession = dragService.getCurrentSession();
|
|
var transfer = Cc["@mozilla.org/widget/transferable;1"].
|
|
createInstance(Ci.nsITransferable);
|
|
|
|
transfer.addDataFlavor(ENGINE_FLAVOR);
|
|
dragSession.getData(transfer, 0);
|
|
|
|
var dataObj = {};
|
|
var len = {};
|
|
var sourceIndex = -1;
|
|
try {
|
|
transfer.getAnyTransferData({}, dataObj, len);
|
|
} catch (ex) {}
|
|
|
|
if (dataObj.value) {
|
|
sourceIndex = dataObj.value.QueryInterface(Ci.nsISupportsString).data;
|
|
sourceIndex = parseInt(sourceIndex.substring(0, len.value));
|
|
}
|
|
|
|
return sourceIndex;
|
|
},
|
|
|
|
// nsITreeView
|
|
get rowCount() {
|
|
return this._engineStore.engines.length;
|
|
},
|
|
|
|
getImageSrc: function(index, column) {
|
|
if (column.id == "engineName" && this._engineStore.engines[index].iconURI)
|
|
return this._engineStore.engines[index].iconURI.spec;
|
|
return "";
|
|
},
|
|
|
|
getCellText: function(index, column) {
|
|
if (column.id == "engineName")
|
|
return this._engineStore.engines[index].name;
|
|
return "";
|
|
},
|
|
|
|
setTree: function(tree) {
|
|
this.tree = tree;
|
|
},
|
|
|
|
canDrop: function(targetIndex, orientation) {
|
|
var sourceIndex = this.getSourceIndexFromDrag();
|
|
return (sourceIndex != -1 &&
|
|
sourceIndex != targetIndex &&
|
|
sourceIndex != (targetIndex + orientation));
|
|
},
|
|
|
|
drop: function(dropIndex, orientation) {
|
|
var sourceIndex = this.getSourceIndexFromDrag();
|
|
var sourceEngine = this._engineStore.engines[sourceIndex];
|
|
|
|
if (dropIndex > sourceIndex) {
|
|
if (orientation == Ci.nsITreeView.DROP_BEFORE)
|
|
dropIndex--;
|
|
} else {
|
|
if (orientation == Ci.nsITreeView.DROP_AFTER)
|
|
dropIndex++;
|
|
}
|
|
|
|
this._engineStore.moveEngine(sourceEngine, dropIndex);
|
|
|
|
// Redraw, and adjust selection
|
|
this.invalidate();
|
|
this.selection.clearSelection();
|
|
this.selection.select(dropIndex);
|
|
},
|
|
|
|
selection: null,
|
|
getRowProperties: function(index, properties) { },
|
|
getCellProperties: function(index, column, properties) { },
|
|
getColumnProperties: function(column, properties) { },
|
|
isContainer: function(index) { return false; },
|
|
isContainerOpen: function(index) { return false; },
|
|
isContainerEmpty: function(index) { return false; },
|
|
isSeparator: function(index) { return false; },
|
|
isSorted: function(index) { return false; },
|
|
getParentIndex: function(index) { return -1; },
|
|
hasNextSibling: function(parentIndex, index) { return false; },
|
|
getLevel: function(index) { return 0; },
|
|
getProgressMode: function(index, column) { },
|
|
getCellValue: function(index, column) { },
|
|
toggleOpenState: function(index) { },
|
|
cycleHeader: function(column) { },
|
|
selectionChanged: function() { },
|
|
cycleCell: function(row, column) { },
|
|
isEditable: function(index, column) { return false; },
|
|
setCellValue: function(index, column, value) { },
|
|
setCellText: function(index, column, value) { },
|
|
performAction: function(action) { },
|
|
performActionOnRow: function(action, index) { },
|
|
performActionOnCell: function(action, index, column) { }
|
|
};
|