Bug 1106559
- Improve the search preference UI, r=felipe,dao.
|
@ -45,7 +45,6 @@ browser.jar:
|
|||
content/browser/preferences/sync.js
|
||||
#endif
|
||||
content/browser/preferences/search.xul
|
||||
content/browser/preferences/search.css
|
||||
content/browser/preferences/search.js
|
||||
* content/browser/preferences/tabs.xul
|
||||
* content/browser/preferences/tabs.js
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
-->
|
||||
<?xml-stylesheet href="chrome://browser/content/preferences/handlers.css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/preferences/applications.css"?>
|
||||
<?xml-stylesheet href="chrome://browser/content/preferences/search.css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/preferences/search.css"?>
|
||||
|
||||
<!DOCTYPE prefwindow [
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#oneClickProvidersList richlistitem {
|
||||
-moz-binding: url("chrome://global/content/bindings/checkbox.xml#checkbox");
|
||||
-moz-padding-start: 5px;
|
||||
height: 22px; /* setting the height of checkboxes is required to let the
|
||||
window auto-sizing code work. */
|
||||
}
|
||||
|
||||
#oneClickProvidersList {
|
||||
height: 178px;
|
||||
}
|
||||
|
||||
.searchengine-menuitem > .menu-iconic-left {
|
||||
display: -moz-box
|
||||
}
|
||||
|
||||
.checkbox-label-box {
|
||||
-moz-box-align: center;
|
||||
-moz-appearance: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.checkbox-icon {
|
||||
margin: 3px 3px;
|
||||
max-width: 16px;
|
||||
}
|
|
@ -4,13 +4,45 @@
|
|||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const ENGINE_FLAVOR = "text/x-moz-search-engine";
|
||||
|
||||
var gEngineView = null;
|
||||
|
||||
var gSearchPane = {
|
||||
|
||||
init: function ()
|
||||
{
|
||||
gEngineView = new EngineView(new EngineStore());
|
||||
document.getElementById("engineList").view = gEngineView;
|
||||
this.buildDefaultEngineDropDown();
|
||||
|
||||
Services.obs.addObserver(this, "browser-search-engine-modified", false);
|
||||
window.addEventListener("unload", () => {
|
||||
Services.obs.removeObserver(this, "browser-search-engine-modified", false);
|
||||
});
|
||||
},
|
||||
|
||||
buildDefaultEngineDropDown: function() {
|
||||
// This is called each time something affects the list of engines.
|
||||
let list = document.getElementById("defaultEngine");
|
||||
let currentEngine = Services.search.currentEngine.name;
|
||||
Services.search.getVisibleEngines().forEach(e => {
|
||||
let currentEngine;
|
||||
|
||||
// First, try to preserve the current selection.
|
||||
if (list.selectedItem)
|
||||
currentEngine = list.selectedItem.label;
|
||||
|
||||
// If there's no current selection, use the current default engine.
|
||||
if (!currentEngine)
|
||||
currentEngine = Services.search.currentEngine.name;
|
||||
|
||||
// If the current engine isn't in the list any more, select the first item.
|
||||
let engines = gEngineView._engineStore._engines;
|
||||
if (!engines.some(e => e.name == currentEngine))
|
||||
currentEngine = engines[0].name;
|
||||
|
||||
// Now clean-up and rebuild the list.
|
||||
list.removeAllItems();
|
||||
gEngineView._engineStore._engines.forEach(e => {
|
||||
let item = list.appendItem(e.name);
|
||||
item.setAttribute("class", "menuitem-iconic searchengine-menuitem menuitem-with-favicon");
|
||||
if (e.iconURI)
|
||||
|
@ -19,50 +51,472 @@ var gSearchPane = {
|
|||
if (e.name == currentEngine)
|
||||
list.selectedItem = item;
|
||||
});
|
||||
|
||||
this.displayOneClickEnginesList();
|
||||
|
||||
document.getElementById("oneClickProvidersList")
|
||||
.addEventListener("CheckboxStateChange", gSearchPane.saveOneClickEnginesList);
|
||||
},
|
||||
|
||||
displayOneClickEnginesList: function () {
|
||||
let richlistbox = document.getElementById("oneClickProvidersList");
|
||||
let pref = document.getElementById("browser.search.hiddenOneOffs").value;
|
||||
let hiddenList = pref ? pref.split(",") : [];
|
||||
observe: function(aEngine, aTopic, aVerb) {
|
||||
if (aTopic == "browser-search-engine-modified") {
|
||||
aEngine.QueryInterface(Components.interfaces.nsISearchEngine);
|
||||
switch (aVerb) {
|
||||
case "engine-added":
|
||||
gEngineView._engineStore.addEngine(aEngine);
|
||||
gEngineView.rowCountChanged(gEngineView.lastIndex, 1);
|
||||
gSearchPane.buildDefaultEngineDropDown();
|
||||
break;
|
||||
case "engine-changed":
|
||||
gEngineView._engineStore.reloadIcons();
|
||||
gEngineView.invalidate();
|
||||
break;
|
||||
case "engine-removed":
|
||||
case "engine-current":
|
||||
case "engine-default":
|
||||
// Not relevant
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
while (richlistbox.firstChild)
|
||||
richlistbox.firstChild.remove();
|
||||
onTreeSelect: function() {
|
||||
document.getElementById("removeEngineButton").disabled =
|
||||
gEngineView.selectedIndex == -1 || gEngineView.lastIndex == 0;
|
||||
},
|
||||
|
||||
let currentEngine = Services.search.currentEngine.name;
|
||||
Services.search.getVisibleEngines().forEach(e => {
|
||||
if (e.name == currentEngine)
|
||||
return;
|
||||
onTreeKeyPress: function(aEvent) {
|
||||
let index = gEngineView.selectedIndex;
|
||||
let tree = document.getElementById("engineList");
|
||||
if (aEvent.charCode == KeyEvent.DOM_VK_SPACE) {
|
||||
// Space toggles the checkbox.
|
||||
let newValue = !gEngineView._engineStore.engines[index].shown;
|
||||
gEngineView.setCellValue(index, tree.columns.getFirstColumn(),
|
||||
newValue.toString());
|
||||
}
|
||||
else {
|
||||
let isMac = Services.appinfo.OS == "Darwin";
|
||||
if ((isMac && aEvent.keyCode == KeyEvent.DOM_VK_RETURN) ||
|
||||
(!isMac && aEvent.keyCode == KeyEvent.DOM_VK_F2))
|
||||
tree.startEditing(index, tree.columns.getLastColumn());
|
||||
}
|
||||
},
|
||||
|
||||
let item = document.createElement("richlistitem");
|
||||
item.setAttribute("label", e.name);
|
||||
if (hiddenList.indexOf(e.name) == -1)
|
||||
item.setAttribute("checked", "true");
|
||||
if (e.iconURI)
|
||||
item.setAttribute("src", e.iconURI.spec);
|
||||
richlistbox.appendChild(item);
|
||||
});
|
||||
onRestoreDefaults: function() {
|
||||
let num = gEngineView._engineStore.restoreDefaultEngines();
|
||||
gEngineView.rowCountChanged(0, num);
|
||||
gEngineView.invalidate();
|
||||
},
|
||||
|
||||
showRestoreDefaults: function(aEnable) {
|
||||
document.getElementById("restoreDefaultSearchEngines").disabled = !aEnable;
|
||||
},
|
||||
|
||||
remove: function() {
|
||||
gEngineView._engineStore.removeEngine(gEngineView.selectedEngine);
|
||||
let index = gEngineView.selectedIndex;
|
||||
gEngineView.rowCountChanged(index, -1);
|
||||
gEngineView.invalidate();
|
||||
gEngineView.selection.select(Math.min(index, gEngineView.lastIndex));
|
||||
gEngineView.ensureRowIsVisible(gEngineView.currentIndex);
|
||||
document.getElementById("engineList").focus();
|
||||
},
|
||||
|
||||
editKeyword: function(aEngine, aNewKeyword) {
|
||||
if (aNewKeyword) {
|
||||
let bduplicate = false;
|
||||
let eduplicate = false;
|
||||
let dupName = "";
|
||||
|
||||
try {
|
||||
let bmserv =
|
||||
Components.classes["@mozilla.org/browser/nav-bookmarks-service;1"]
|
||||
.getService(Components.interfaces.nsINavBookmarksService);
|
||||
if (bmserv.getURIForKeyword(aNewKeyword))
|
||||
bduplicate = true;
|
||||
} catch(ex) {}
|
||||
|
||||
// Check for duplicates in changes we haven't committed yet
|
||||
let engines = gEngineView._engineStore.engines;
|
||||
for each (let engine in engines) {
|
||||
if (engine.alias == aNewKeyword &&
|
||||
engine.name != aEngine.name) {
|
||||
eduplicate = true;
|
||||
dupName = engine.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Notify the user if they have chosen an existing engine/bookmark keyword
|
||||
if (eduplicate || bduplicate) {
|
||||
let strings = document.getElementById("engineManagerBundle");
|
||||
let dtitle = strings.getString("duplicateTitle");
|
||||
let bmsg = strings.getString("duplicateBookmarkMsg");
|
||||
let emsg = strings.getFormattedString("duplicateEngineMsg", [dupName]);
|
||||
|
||||
Services.prompt.alert(window, dtitle, eduplicate ? emsg : bmsg);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
gEngineView._engineStore.changeEngine(aEngine, "alias", aNewKeyword);
|
||||
gEngineView.invalidate();
|
||||
return true;
|
||||
},
|
||||
|
||||
saveOneClickEnginesList: function () {
|
||||
let richlistbox = document.getElementById("oneClickProvidersList");
|
||||
let hiddenList = [];
|
||||
for (let child of richlistbox.childNodes) {
|
||||
if (!child.checked)
|
||||
hiddenList.push(child.getAttribute("label"));
|
||||
for (let engine of gEngineView._engineStore.engines) {
|
||||
if (!engine.shown)
|
||||
hiddenList.push(engine.name);
|
||||
}
|
||||
document.getElementById("browser.search.hiddenOneOffs").value =
|
||||
hiddenList.join(",");
|
||||
},
|
||||
|
||||
setDefaultEngine: function () {
|
||||
if (document.documentElement.instantApply) {
|
||||
Services.search.currentEngine =
|
||||
document.getElementById("defaultEngine").selectedItem.engine;
|
||||
this.displayOneClickEnginesList();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function onDragEngineStart(event) {
|
||||
var selectedIndex = gEngineView.selectedIndex;
|
||||
if (selectedIndex >= 0) {
|
||||
event.dataTransfer.setData(ENGINE_FLAVOR, selectedIndex.toString());
|
||||
event.dataTransfer.effectAllowed = "move";
|
||||
}
|
||||
}
|
||||
|
||||
// "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() {
|
||||
Services.search.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() {
|
||||
Services.search.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;
|
||||
Services.search.moveEngine(this._engine, this._newIndex);
|
||||
}
|
||||
};
|
||||
|
||||
function EngineChangeOp(aEngineClone, aProp, aValue) {
|
||||
if (!aEngineClone)
|
||||
throw new Error("bad args to new EngineChangeOp!");
|
||||
|
||||
this._engine = aEngineClone.originalEngine;
|
||||
this._prop = aProp;
|
||||
this._newValue = aValue;
|
||||
}
|
||||
EngineChangeOp.prototype = {
|
||||
_engine: null,
|
||||
_prop: null,
|
||||
_newValue: null,
|
||||
commit: function ECO_commit() {
|
||||
this._engine[this._prop] = this._newValue;
|
||||
}
|
||||
};
|
||||
|
||||
function EngineStore() {
|
||||
let pref = document.getElementById("browser.search.hiddenOneOffs").value;
|
||||
this.hiddenList = pref ? pref.split(",") : [];
|
||||
|
||||
this._engines = Services.search.getVisibleEngines().map(this._cloneEngine, this);
|
||||
this._defaultEngines = Services.search.getDefaultEngines().map(this._cloneEngine, this);
|
||||
|
||||
if (document.documentElement.instantApply) {
|
||||
this._ops = {
|
||||
push: function(op) { op.commit(); }
|
||||
};
|
||||
}
|
||||
else {
|
||||
this._ops = [];
|
||||
document.documentElement.addEventListener("beforeaccept", () => {
|
||||
gEngineView._engineStore.commit();
|
||||
});
|
||||
}
|
||||
|
||||
// check if we need to disable the restore defaults button
|
||||
var someHidden = this._defaultEngines.some(function (e) e.hidden);
|
||||
gSearchPane.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;
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
_cloneEngine: function ES_cloneEngine(aEngine) {
|
||||
var clonedObj={};
|
||||
for (var i in aEngine)
|
||||
clonedObj[i] = aEngine[i];
|
||||
clonedObj.originalEngine = aEngine;
|
||||
clonedObj.shown = this.hiddenList.indexOf(clonedObj.name) == -1;
|
||||
return clonedObj;
|
||||
},
|
||||
|
||||
// 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() {
|
||||
for (op of this._ops)
|
||||
op.commit();
|
||||
|
||||
Services.search.currentEngine =
|
||||
document.getElementById("defaultEngine").selectedItem.engine;
|
||||
},
|
||||
|
||||
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))
|
||||
gSearchPane.showRestoreDefaults(true);
|
||||
gSearchPane.buildDefaultEngineDropDown();
|
||||
},
|
||||
|
||||
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++;
|
||||
}
|
||||
}
|
||||
gSearchPane.showRestoreDefaults(false);
|
||||
gSearchPane.buildDefaultEngineDropDown();
|
||||
return added;
|
||||
},
|
||||
|
||||
changeEngine: function ES_changeEngine(aEngine, aProp, aNewValue) {
|
||||
var index = this._getIndexForEngine(aEngine);
|
||||
if (index == -1)
|
||||
throw new Error("invalid engine?");
|
||||
|
||||
this._engines[index][aProp] = aNewValue;
|
||||
this._ops.push(new EngineChangeOp(aEngine, aProp, aNewValue));
|
||||
},
|
||||
|
||||
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 (dataTransfer) {
|
||||
return parseInt(dataTransfer.getData(ENGINE_FLAVOR));
|
||||
},
|
||||
|
||||
// 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;
|
||||
else if (column.id == "engineKeyword")
|
||||
return this._engineStore.engines[index].alias;
|
||||
return "";
|
||||
},
|
||||
|
||||
setTree: function(tree) {
|
||||
this.tree = tree;
|
||||
},
|
||||
|
||||
canDrop: function(targetIndex, orientation, dataTransfer) {
|
||||
var sourceIndex = this.getSourceIndexFromDrag(dataTransfer);
|
||||
return (sourceIndex != -1 &&
|
||||
sourceIndex != targetIndex &&
|
||||
sourceIndex != targetIndex + orientation);
|
||||
},
|
||||
|
||||
drop: function(dropIndex, orientation, dataTransfer) {
|
||||
var sourceIndex = this.getSourceIndexFromDrag(dataTransfer);
|
||||
var sourceEngine = this._engineStore.engines[sourceIndex];
|
||||
|
||||
const nsITreeView = Components.interfaces.nsITreeView;
|
||||
if (dropIndex > sourceIndex) {
|
||||
if (orientation == nsITreeView.DROP_BEFORE)
|
||||
dropIndex--;
|
||||
} else {
|
||||
if (orientation == nsITreeView.DROP_AFTER)
|
||||
dropIndex++;
|
||||
}
|
||||
|
||||
this._engineStore.moveEngine(sourceEngine, dropIndex);
|
||||
gSearchPane.showRestoreDefaults(true);
|
||||
gSearchPane.buildDefaultEngineDropDown();
|
||||
|
||||
// Redraw, and adjust selection
|
||||
this.invalidate();
|
||||
this.selection.select(dropIndex);
|
||||
},
|
||||
|
||||
selection: null,
|
||||
getRowProperties: function(index) { return ""; },
|
||||
getCellProperties: function(index, column) { return ""; },
|
||||
getColumnProperties: function(column) { return ""; },
|
||||
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) {
|
||||
if (column.id == "engineShown")
|
||||
return this._engineStore.engines[index].shown;
|
||||
return undefined;
|
||||
},
|
||||
toggleOpenState: function(index) { },
|
||||
cycleHeader: function(column) { },
|
||||
selectionChanged: function() { },
|
||||
cycleCell: function(row, column) { },
|
||||
isEditable: function(index, column) { return column.id != "engineName"; },
|
||||
isSelectable: function(index, column) { return false; },
|
||||
setCellValue: function(index, column, value) {
|
||||
if (column.id == "engineShown") {
|
||||
this._engineStore.engines[index].shown = value == "true";
|
||||
gEngineView.invalidate();
|
||||
gSearchPane.saveOneClickEnginesList();
|
||||
}
|
||||
},
|
||||
setCellText: function(index, column, value) {
|
||||
if (column.id == "engineKeyword") {
|
||||
if (!gSearchPane.editKeyword(this._engineStore.engines[index], value)) {
|
||||
setTimeout(() => {
|
||||
document.getElementById("engineList").startEditing(index, column);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
},
|
||||
performAction: function(action) { },
|
||||
performActionOnRow: function(action, index) { },
|
||||
performActionOnCell: function(action, index, column) { }
|
||||
};
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
|
||||
<script type="application/javascript" src="chrome://browser/content/preferences/search.js"/>
|
||||
|
||||
<stringbundle id="engineManagerBundle" src="chrome://browser/locale/engineManager.properties"/>
|
||||
|
||||
<!-- Default Search Engine -->
|
||||
<groupbox id="defaultEngineGroup" align="start">
|
||||
<caption label="&defaultSearchEngine.label;"/>
|
||||
|
@ -51,8 +53,34 @@
|
|||
<caption label="&oneClickSearchEngines.label;"/>
|
||||
<label>&chooseWhichOneToDisplay.label;</label>
|
||||
|
||||
<richlistbox id="oneClickProvidersList"/>
|
||||
<hbox pack="end" style="margin-bottom: 1em">
|
||||
<tree id="engineList" flex="1" rows="8" hidecolumnpicker="true" editable="true"
|
||||
seltype="single" onselect="gSearchPane.onTreeSelect();"
|
||||
onkeypress="gSearchPane.onTreeKeyPress(event);">
|
||||
<treechildren id="engineChildren" flex="1"
|
||||
ondragstart="onDragEngineStart(event);"/>
|
||||
<treecols>
|
||||
<treecol id="engineShown" type="checkbox" style="min-width: 26px;" editable="true"/>
|
||||
<treecol id="engineName" flex="4" label="&engineNameColumn.label;"/>
|
||||
<treecol id="engineKeyword" flex="1" label="&engineKeywordColumn.label;" editable="true"/>
|
||||
</treecols>
|
||||
</tree>
|
||||
|
||||
<hbox>
|
||||
<button id="restoreDefaultSearchEngines"
|
||||
label="&restoreDefaultSearchEngines.label;"
|
||||
accesskey="&restoreDefaultSearchEngines.accesskey;"
|
||||
oncommand="gSearchPane.onRestoreDefaults();"/>
|
||||
<spacer flex="1"/>
|
||||
<button id="removeEngineButton"
|
||||
label="&removeEngine.label;"
|
||||
accesskey="&removeEngine.accesskey;"
|
||||
disabled="true"
|
||||
oncommand="gSearchPane.remove();"/>
|
||||
</hbox>
|
||||
|
||||
<separator class="thin"/>
|
||||
|
||||
<hbox pack="start" style="margin-bottom: 1em">
|
||||
<label id="addEngines" class="text-link" value="&addMoreSearchEngines.label;"
|
||||
onclick="if (event.button == 0) { Services.wm.getMostRecentWindow('navigator:browser').BrowserSearch.loadAddEngines(); }"/>
|
||||
</hbox>
|
||||
|
|
|
@ -169,6 +169,7 @@ browser.jar:
|
|||
skin/classic/browser/preferences/in-content/icons@2x.png (../shared/incontentprefs/icons@2x.png)
|
||||
skin/classic/browser/preferences/applications.css (preferences/applications.css)
|
||||
skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/browser/preferences/search.css (preferences/search.css)
|
||||
skin/classic/browser/social/services-16.png (social/services-16.png)
|
||||
skin/classic/browser/social/services-64.png (social/services-64.png)
|
||||
skin/classic/browser/social/share-button.png (social/share-button.png)
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#defaultEngine > .menulist-label-box > .menulist-icon {
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
/* work around a display: none in Linux's menu.css, see bug 1112310 */
|
||||
.searchengine-menuitem > .menu-iconic-left {
|
||||
display: -moz-box;
|
||||
}
|
||||
|
||||
#engineList {
|
||||
margin: .5em 6px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-checkbox(checked) {
|
||||
list-style-image: url("chrome://global/skin/checkbox/cbox-check.gif");
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-image(engineName) {
|
||||
-moz-margin-end: 4px;
|
||||
-moz-margin-start: 0;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-row {
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-drop-feedback {
|
||||
background-color: Highlight;
|
||||
width: 10000px; /* 100% doesn't work; 10k is hopefully larger than any window
|
||||
we may have, overflow isn't visible. */
|
||||
height: 2px;
|
||||
-moz-margin-start: 0;
|
||||
}
|
|
@ -273,6 +273,11 @@ browser.jar:
|
|||
skin/classic/browser/preferences/in-content/icons@2x.png (../shared/incontentprefs/icons@2x.png)
|
||||
skin/classic/browser/preferences/applications.css (preferences/applications.css)
|
||||
skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/browser/preferences/search.css (preferences/search.css)
|
||||
skin/classic/browser/preferences/checkbox.png (preferences/checkbox.png)
|
||||
skin/classic/browser/preferences/checkbox@2x.png (preferences/checkbox@2x.png)
|
||||
skin/classic/browser/yosemite/preferences/checkbox.png (preferences/checkbox-yosemite.png)
|
||||
skin/classic/browser/yosemite/preferences/checkbox@2x.png (preferences/checkbox-yosemite@2x.png)
|
||||
skin/classic/browser/social/services-16.png (social/services-16.png)
|
||||
skin/classic/browser/social/services-16@2x.png (social/services-16@2x.png)
|
||||
skin/classic/browser/social/services-64.png (social/services-64.png)
|
||||
|
@ -588,6 +593,8 @@ browser.jar:
|
|||
% override chrome://browser/skin/menuPanel-help@2x.png chrome://browser/skin/yosemite/menuPanel-help@2x.png os=Darwin osversion>=10.10
|
||||
% override chrome://browser/skin/menuPanel-small.png chrome://browser/skin/yosemite/menuPanel-small.png os=Darwin osversion>=10.10
|
||||
% override chrome://browser/skin/menuPanel-small@2x.png chrome://browser/skin/yosemite/menuPanel-small@2x.png os=Darwin osversion>=10.10
|
||||
% override chrome://browser/skin/preferences/checkbox.png chrome://browser/skin/yosemite/preferences/checkbox.png os=Darwin osversion>=10.10
|
||||
% override chrome://browser/skin/preferences/checkbox@2x.png chrome://browser/skin/yosemite/preferences/checkbox@2x.png os=Darwin osversion>=10.10
|
||||
% override chrome://browser/skin/reload-stop-go.png chrome://browser/skin/yosemite/reload-stop-go.png os=Darwin osversion>=10.10
|
||||
% override chrome://browser/skin/reload-stop-go@2x.png chrome://browser/skin/yosemite/reload-stop-go@2x.png os=Darwin osversion>=10.10
|
||||
% override chrome://browser/skin/sync-horizontalbar.png chrome://browser/skin/yosemite/sync-horizontalbar.png os=Darwin osversion>=10.10
|
||||
|
|
После Ширина: | Высота: | Размер: 1.0 KiB |
После Ширина: | Высота: | Размер: 2.4 KiB |
После Ширина: | Высота: | Размер: 1.6 KiB |
После Ширина: | Высота: | Размер: 3.6 KiB |
|
@ -0,0 +1,54 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#defaultEngine > .menulist-label-box > .menulist-icon {
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
#engineList {
|
||||
margin: .5em 6px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-image(engineShown) {
|
||||
list-style-image: url("chrome://browser/skin/preferences/checkbox.png");
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
-moz-margin-start: 4px;
|
||||
-moz-margin-end: 1px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-image(engineShown, checked) {
|
||||
-moz-image-region: rect(0, 48px, 16px, 32px);
|
||||
}
|
||||
|
||||
@media (min-resolution: 2dppx) {
|
||||
#engineList treechildren::-moz-tree-image(engineShown) {
|
||||
list-style-image: url("chrome://browser/skin/preferences/checkbox@2x.png");
|
||||
-moz-image-region: rect(0, 32px, 32px, 0);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-image(engineShown, checked) {
|
||||
-moz-image-region: rect(0, 96px, 32px, 64px);
|
||||
}
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-image(engineName) {
|
||||
-moz-margin-end: 4px;
|
||||
-moz-margin-start: 1px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-row {
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-drop-feedback {
|
||||
background-color: Highlight;
|
||||
width: 10000px; /* 100% doesn't work; 10k is hopefully larger than any window
|
||||
we may have, overflow isn't visible. */
|
||||
height: 2px;
|
||||
-moz-margin-start: 0;
|
||||
}
|
|
@ -197,6 +197,9 @@ browser.jar:
|
|||
skin/classic/browser/preferences/in-content/icons@2x.png (../shared/incontentprefs/icons@2x.png)
|
||||
skin/classic/browser/preferences/applications.css (preferences/applications.css)
|
||||
skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/browser/preferences/search.css (preferences/search.css)
|
||||
skin/classic/browser/preferences/checkbox.png (preferences/checkbox-xp.png)
|
||||
skin/classic/browser/preferences/checkbox-classic.png (preferences/checkbox-classic.png)
|
||||
skin/classic/browser/social/services-16.png (social/services-16.png)
|
||||
skin/classic/browser/social/services-64.png (social/services-64.png)
|
||||
skin/classic/browser/social/chat-icons.svg (../shared/social/chat-icons.svg)
|
||||
|
@ -645,6 +648,10 @@ browser.jar:
|
|||
skin/classic/aero/browser/preferences/in-content/icons@2x.png (../shared/incontentprefs/icons@2x.png)
|
||||
skin/classic/aero/browser/preferences/applications.css (preferences/applications.css)
|
||||
skin/classic/aero/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/aero/browser/preferences/search.css (preferences/search.css)
|
||||
skin/classic/aero/browser/preferences/checkbox.png (preferences/checkbox-8.png)
|
||||
skin/classic/aero/browser/preferences/checkbox-aero.png (preferences/checkbox-aero.png)
|
||||
skin/classic/aero/browser/preferences/checkbox-classic.png (preferences/checkbox-classic.png)
|
||||
skin/classic/aero/browser/social/services-16.png (social/services-16.png)
|
||||
skin/classic/aero/browser/social/services-64.png (social/services-64.png)
|
||||
skin/classic/aero/browser/social/chat-icons.svg (../shared/social/chat-icons.svg)
|
||||
|
@ -902,6 +909,9 @@ browser.jar:
|
|||
% override chrome://browser/skin/menuPanel-small.png chrome://browser/skin/menuPanel-small-aero.png os=WINNT osversion=6
|
||||
% override chrome://browser/skin/menuPanel-small.png chrome://browser/skin/menuPanel-small-aero.png os=WINNT osversion=6.1
|
||||
|
||||
% override chrome://browser/skin/preferences/checkbox.png chrome://browser/skin/preferences/checkbox-aero.png os=WINNT osversion=6
|
||||
% override chrome://browser/skin/preferences/checkbox.png chrome://browser/skin/preferences/checkbox-aero.png os=WINNT osversion=6.1
|
||||
|
||||
% override chrome://browser/skin/theme-switcher-icon.png chrome://browser/skin/theme-switcher-icon-aero.png os=WINNT osversion=6
|
||||
% override chrome://browser/skin/theme-switcher-icon.png chrome://browser/skin/theme-switcher-icon-aero.png os=WINNT osversion=6.1
|
||||
|
||||
|
|
После Ширина: | Высота: | Размер: 705 B |
После Ширина: | Высота: | Размер: 1.5 KiB |
После Ширина: | Высота: | Размер: 284 B |
После Ширина: | Высота: | Размер: 1.4 KiB |
|
@ -0,0 +1,59 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#defaultEngine > .menulist-label-box > .menulist-icon {
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
#engineList {
|
||||
margin: .5em 6px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-checkbox {
|
||||
list-style-image: url("chrome://browser/skin/preferences/checkbox.png");
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-checkbox(checked) {
|
||||
-moz-image-region: rect(0, 64px, 16px, 48px);
|
||||
}
|
||||
|
||||
@media (-moz-windows-classic) {
|
||||
#engineList treechildren::-moz-tree-checkbox {
|
||||
list-style-image: url("chrome://browser/skin/preferences/checkbox-classic.png");
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-checkbox(checked) {
|
||||
-moz-image-region: rect(0, 48px, 16px, 32px);
|
||||
}
|
||||
}
|
||||
|
||||
@media not all and (-moz-windows-classic) {
|
||||
#engineList treechildren::-moz-tree-checkbox(hover) {
|
||||
-moz-image-region: rect(0, 48px, 16px, 32px);
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-checkbox(checked, hover) {
|
||||
-moz-image-region: rect(0, 80px, 16px, 64px);
|
||||
}
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-image(engineName) {
|
||||
-moz-margin-end: 4px;
|
||||
-moz-margin-start: 0;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-row {
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-drop-feedback {
|
||||
background-color: Highlight;
|
||||
width: 10000px; /* 100% doesn't work; 10k is hopefully larger than any window
|
||||
we may have, overflow isn't visible. */
|
||||
height: 2px;
|
||||
-moz-margin-start: 0;
|
||||
}
|