Bug 699418 - Implement about:config in html. r=mfinkle

This commit is contained in:
Margaret Leibovic 2011-11-18 15:41:42 -08:00
parent 7e4f1abf6e
commit 05032189d6
8 changed files with 353 additions and 615 deletions

View File

@ -1,423 +0,0 @@
/* ***** 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 Mobile Browser.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 ***** */
let Ci = Components.interfaces;
Components.utils.import("resource://gre/modules/Services.jsm");
var ViewConfig = {
get _container() {
delete this._container;
return this._container = document.getElementById("prefs-container");
},
get _editor() {
delete this._editor;
return this._editor = document.getElementById("editor");
},
init: function init() {
window.addEventListener("resize", this, false);
window.addEventListener("prefchange", this, false);
window.addEventListener("prefnew", this, false);
this._handleWindowResize();
this.filter("");
document.getElementById("textbox").focus();
},
uninit: function uninit() {
window.removeEventListener("resize", this, false);
window.removeEventListener("prefchange", this, false);
window.removeEventListener("prefnew", this, false);
},
filter: function filter(aValue) {
let row = document.getElementById("editor-row");
row.setAttribute("hidden", aValue != "");
let container = this._container;
container.scrollBoxObject.scrollTo(0, 0);
// Clear the list by replacing with a shallow copy
let empty = container.cloneNode(false);
empty.appendChild(row);
container.parentNode.replaceChild(empty, container);
this._container = empty;
let result = Utils.getPrefs(aValue);
this._container.setItems(result.map(this._createItem, this));
},
open: function open(aType) {
let buttons = document.getElementById("editor-buttons-add");
buttons.setAttribute("hidden", "true");
let shouldFocus = false;
let setting = document.getElementById("editor-setting");
switch (aType) {
case Ci.nsIPrefBranch.PREF_INT:
setting.setAttribute("type", "integer");
setting.setAttribute("min", -Infinity);
break;
case Ci.nsIPrefBranch.PREF_BOOL:
setting.setAttribute("type", "bool");
break;
case Ci.nsIPrefBranch.PREF_STRING:
setting.setAttribute("type", "string");
break;
}
setting.removeAttribute("title");
setting.removeAttribute("pref");
if (setting.input)
setting.input.value = "";
document.getElementById("editor-container").appendChild(this._editor);
let nameField = document.getElementById("editor-name");
nameField.value = "";
this._editor.setAttribute("hidden", "false");
this._currentItem = null;
nameField.focus();
},
close: function close(aValid) {
this._editor.setAttribute("hidden", "true");
let buttons = document.getElementById("editor-buttons-add");
buttons.setAttribute("hidden", "false");
if (aValid) {
let name = document.getElementById("editor-name").inputField.value;
if (name != "") {
let setting = document.getElementById("editor-setting");
setting.setAttribute("pref", name);
setting.valueToPreference();
}
}
document.getElementById("editor-container").appendChild(this._editor);
},
_currentItem: null,
delayEdit: function(aItem) {
setTimeout(this.edit.bind(this), 0, aItem);
},
edit: function(aItem) {
if (!aItem)
return;
let pref = Utils.getPref(aItem.getAttribute("name"));
if (pref.lock || !pref.name || aItem == this._currentItem)
return;
this.close(false);
this._currentItem = aItem;
let setting = document.getElementById("editor-setting");
let shouldFocus = false;
switch (pref.type) {
case Ci.nsIPrefBranch.PREF_BOOL:
setting.setAttribute("type", "bool");
break;
case Ci.nsIPrefBranch.PREF_INT:
setting.setAttribute("type", "integer");
setting.setAttribute("increment", this.getIncrementForValue(pref.value));
setting.setAttribute("min", -Infinity);
shouldFocus = true;
break;
case Ci.nsIPrefBranch.PREF_STRING:
setting.setAttribute("type", "string");
shouldFocus = true;
break;
}
setting.setAttribute("title", pref.name);
setting.setAttribute("pref", pref.name);
this._container.insertBefore(this._editor, aItem);
let resetButton = document.getElementById("editor-reset");
resetButton.setAttribute("disabled", pref.default);
this._editor.setAttribute("default", pref.default);
this._editor.setAttribute("hidden", "false");
if (shouldFocus && setting.input)
setting.input.focus();
},
reset: function reset(aItem) {
let setting = document.getElementById("editor-setting");
let pref = Utils.getPref(setting.getAttribute("pref"));
if (!pref.default)
Utils.resetPref(pref.name);
},
handleEvent: function handleEvent(aEvent) {
switch (aEvent.type) {
case "resize":
this._handleWindowResize();
break;
case "prefchange":
case "prefnew":
this._handlePrefChange(aEvent.detail, aEvent.type == "prefnew");
break;
}
},
_handleWindowResize: function _handleWindowResize() {
let mainBox = document.getElementById("main-container");
let textbox = document.getElementById("textbox");
let height = window.innerHeight - textbox.getBoundingClientRect().height;
mainBox.setAttribute("height", height);
},
_handlePrefChange: function _handlePrefChange(aIndex, aNew) {
let isEditing = !this._editor.hidden;
let shouldUpdateEditor = false;
if (isEditing) {
let setting = document.getElementById("editor-setting");
let editorIndex = Utils.getPrefIndex(setting.getAttribute("pref"));
shouldUpdateEditor = (aIndex == editorIndex);
if(shouldUpdateEditor || aIndex > editorIndex)
aIndex += 1;
}
// XXX An item display value will probably fail if a pref is changed in the
// background while there is a filter on the pref
let item = shouldUpdateEditor ? this._editor.nextSibling
: this._container.childNodes[aIndex + 1];// add 1 because of the new pref row
if (!item) // the pref is not viewable
return;
if (aNew) {
let pref = Utils.getPrefByIndex(aIndex);
let row = this._createItem(pref);
this._container.insertBefore(row, item);
return;
}
let pref = Utils.getPref(item.getAttribute("name"));
if (shouldUpdateEditor) {
this._editor.setAttribute("default", pref.default);
let resetButton = document.getElementById("editor-reset");
resetButton.disabled = pref.default;
}
item.setAttribute("default", pref.default);
item.lastChild.setAttribute("value", pref.value);
},
_createItem: function _createItem(aPref) {
let row = document.createElement("richlistitem");
row.setAttribute("name", aPref.name);
row.setAttribute("type", aPref.type);
row.setAttribute("role", "button");
row.setAttribute("default", aPref.default);
let label = document.createElement("label");
label.setAttribute("class", "preferences-title");
label.setAttribute("value", aPref.name);
label.setAttribute("crop", "end");
row.appendChild(label);
label = document.createElement("label");
label.setAttribute("class", "preferences-value");
label.setAttribute("value", aPref.value);
label.setAttribute("crop", "end");
row.appendChild(label);
return row;
},
getIncrementForValue: function getIncrementForValue(aValue) {
let count = 1;
while (aValue >= 100) {
aValue /= 10;
count *= 10;
}
return count;
}
};
var Utils = {
QueryInterface: function(aIID) {
if (!aIID.equals(Ci.nsIObserver) && !aIID.equals(Ci.nsISupportsWeakReference))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
},
get _branch() {
delete this._branch;
this._branch = Services.prefs.getBranch(null).QueryInterface(Ci.nsIPrefBranch2);
this._branch.addObserver("", this, true);
return this._branch;
},
get _preferences() {
delete this._preferences;
let list = this._branch.getChildList("", {}).filter(function(element) {
return !(/^capability\./.test(element));
});
return this._preferences = list.sort().map(this.getPref, this);
},
getPrefs: function getPrefs(aValue) {
let result = this._preferences.slice();;
if (aValue != "") {
let reg = this._generateRegexp(aValue);
if (!reg)
return [];
result = this._preferences.filter(function(element, index, array) {
return reg.test(element.name + ";" + element.value);
});
}
return result;
},
getPref: function getPref(aPrefName) {
let branch = this._branch;
let pref = {
name: aPrefName,
value: "",
default: !branch.prefHasUserValue(aPrefName),
lock: branch.prefIsLocked(aPrefName),
type: branch.getPrefType(aPrefName)
};
try {
switch (pref.type) {
case Ci.nsIPrefBranch.PREF_BOOL:
pref.value = branch.getBoolPref(aPrefName).toString();
break;
case Ci.nsIPrefBranch.PREF_INT:
pref.value = branch.getIntPref(aPrefName).toString();
break;
default:
case Ci.nsIPrefBranch.PREF_STRING:
pref.value = branch.getComplexValue(aPrefName, Ci.nsISupportsString).data;
// Try in case it's a localized string (will throw an exception if not)
if (pref.default && /^chrome:\/\/.+\/locale\/.+\.properties/.test(pref.value))
pref.value = branch.getComplexValue(aPrefName, Ci.nsIPrefLocalizedString).data;
break;
}
} catch (e) {}
return pref;
},
getPrefByIndex: function getPrefByIndex(aIndex) {
return this._preferences[aIndex];
},
getPrefIndex: function getPrefIndex(aPrefName) {
let prefs = this._preferences;
let high = prefs.length - 1;
let low = 0, middle, element;
while (low <= high) {
middle = parseInt((low + high) / 2);
element = prefs[middle];
if (element.name > aPrefName)
high = middle - 1;
else if (element.name < aPrefName)
low = middle + 1;
else
return middle;
}
return -1;
},
resetPref: function resetPref(aPrefName) {
this._branch.clearUserPref(aPrefName);
},
observe: function observe(aSubject, aTopic, aPrefName) {
if (aTopic != "nsPref:changed" || /^capability\./.test(aPrefName)) // avoid displaying "private" preferences
return;
let type = "prefchange";
let index = this.getPrefIndex(aPrefName);
if (index != - 1) {
// update the inner array
let pref = this.getPref(aPrefName);
this._preferences[index].value = pref.value;
}
else {
// XXX we could do better here
let list = this._branch.getChildList("", {}).filter(function(element, index, array) {
return !(/^capability\./.test(element));
});
this._preferences = list.sort().map(this.getPref, this);
type = "prefnew";
index = this.getPrefIndex(aPrefName);
}
let evt = document.createEvent("UIEvents");
evt.initUIEvent(type, true, true, window, index);
window.dispatchEvent(evt);
},
_generateRegexp: function _generateRegexp(aValue) {
if (aValue.charAt(0) == "/") {
try {
let rv = aValue.match(/^\/(.*)\/(i?)$/);
return RegExp(rv[1], rv[2]);
}
catch (e) {
return null; // Do nothing on incomplete or bad RegExp
}
}
return RegExp(aValue.replace(/([^* \w])/g, "\\$1").replace(/^\*+/, "")
.replace(/\*+/g, ".*"), "i");
}
};

View File

@ -0,0 +1,315 @@
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" [
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd" >
%globalDTD;
<!ENTITY % configDTD SYSTEM "chrome://browser/locale/config.dtd">
%configDTD;
]>
<!-- ***** 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 Mobile Browser.
-
- The Initial Developer of the Original Code is
- Mozilla Corporation.
- Portions created by the Initial Developer are Copyright (C) 2011
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- 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 LGPL or the GPL. 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 ***** -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=480; initial-scale=.6667; user-scalable=0" />
<link rel="stylesheet" href="chrome://browser/skin/config.css" type="text/css"/>
</head>
<body dir="&locale.dir;" onload="AboutConfig.init();" onunload="AboutConfig.uninit();">
<div id="filter-container">
<input id="filter-input" type="text" placeholder="&filter.placeholder;"/>
<button onclick="AboutConfig.filter();">&filter.label;</button>
</div>
<div id="new-pref-container">
<button id="new-pref-button" onclick="AboutConfig.addNewPref();">&newpref.label;</button>
</div>
<div id="prefs-container"/>
<script type="application/javascript;version=1.8"><![CDATA[
const {classes: Cc, interfaces: Ci, manager: Cm, utils: Cu} = Components;
Cu.import("resource://gre/modules/Services.jsm");
let gStringBundle = Services.strings.createBundle("chrome://browser/locale/config.properties");
function dump(a) {
Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).logStringMessage(a);
}
let AboutConfig = {
_container: null,
_filterInput: null,
init: function AC_init() {
this._container = document.getElementById("prefs-container");
this._filterInput = document.getElementById("filter-input");
this.filter();
Services.prefs.addObserver("", this, false);
},
uninit: function AC_uninit() {
Services.prefs.removeObserver("", this);
},
filter: function AC_filter(aValue) {
if (!aValue)
aValue = this._filterInput.value;
// Replace pref container with a new empty one
let empty = this._container.cloneNode(false);
this._container.parentNode.replaceChild(empty, this._container);
this._container = empty;
let prefs = this._getPrefs(aValue);
let fragment = document.createDocumentFragment();
for (let i = 0; i < prefs.length; i++) {
let item = this._createItem(prefs[i]);
fragment.appendChild(item);
}
this._container.appendChild(fragment);
},
addNewPref: function AC_addNewPref() {
let title = gStringBundle.GetStringFromName("addPref.title");
// Prompt for pref type
let typeString = gStringBundle.GetStringFromName("addPref.selectType");
let typeArray = [gStringBundle.GetStringFromName("addPref.type.string"),
gStringBundle.GetStringFromName("addPref.type.integer"),
gStringBundle.GetStringFromName("addPref.type.boolean")];
let typeResult = { value: null };
if (!Services.prompt.select(window, title, typeString, 3, typeArray, typeResult))
return;
// Prompt for pref name
let nameString = gStringBundle.GetStringFromName("addPref.enterName");
let nameResult = { value: "" };
if (!Services.prompt.prompt(window, title, nameString, nameResult, null, {}))
return;
// Make a stub pref item to send to modifyPref
let pref = {
name: nameResult.value,
lock: false,
type: [Ci.nsIPrefBranch.PREF_STRING,
Ci.nsIPrefBranch.PREF_INT,
Ci.nsIPrefBranch.PREF_BOOL][typeResult.value],
value: ""
}
this.modifyPref(pref);
},
// Mostly copied from toolkit config.js
modifyPref: function AC_modifyPref(aPref) {
if (aPref.locked)
return;
let title = gStringBundle.GetStringFromName("modifyPref.label");
let result = { value: aPref.value };
if (aPref.type == Ci.nsIPrefBranch.PREF_BOOL) {
let text = gStringBundle.formatStringFromName("modifyPref.selectText", [aPref.name], 1);
if (!Services.prompt.select(window, title, text, 2, [false, true], result))
return;
Services.prefs.setBoolPref(aPref.name, result.value);
} else {
let text = gStringBundle.formatStringFromName("modifyPref.promptText", [aPref.name], 1);
if (!Services.prompt.prompt(window, title, text, result, null, {}))
return;
if (aPref.type == Ci.nsIPrefBranch.PREF_INT) {
// | 0 converts to integer or 0; - 0 to float or NaN.
// Thus, this check should catch all cases.
let val = result.value | 0;
if (val != result.value - 0) {
let errorTitle = gStringBundle.GetStringFromName("modifyPref.numberErrorTitle");
let errorText = gStringBundle.GetStringFromName("modifyPref.numberErrorText");
Services.prompt.alert(window, errorTitle, errorText);
return;
}
Services.prefs.setIntPref(aPref.name, val);
} else {
let supportsString = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
supportsString.data = result.value;
Services.prefs.setComplexValue(aPref.name, Ci.nsISupportsString, supportsString);
}
}
Services.prefs.savePrefFile(null);
},
resetPref: function AC_resetPref(aPref) {
Services.prefs.clearUserPref(aPref.name);
},
observe: function AC_observe(aSubject, aTopic, aPrefName) {
if (aTopic != "nsPref:changed" || /^capability\./.test(aPrefName))
return;
// Get the updated pref
let pref = this._getPref(aPrefName);
let item = document.querySelector(".pref-item[name=\"" + aPrefName + "\"]");
// If a new pref was added, make a new item for it
if (!item) {
let item = this._createItem(pref);
// Just stick the item at the beginning of the list so that we don't
// need to scroll to it
this._container.insertBefore(item, this._container.firstChild);
return;
}
// Check to see if the pref was removed
if (pref.type = Ci.nsIPrefBranch.PREF_INVALID) {
this._container.removeChild(item);
return;
}
// Otherwise, just replace the item with an updated item
this._container.replaceChild(this._createItem(pref), item);
},
// Gets prefs, optionally filtered for aValue
_getPrefs: function AC_getPrefs(aValue) {
let list = Services.prefs.getChildList("", {}).filter(function(element) {
// Avoid displaying "private" preferences
return !(/^capability\./.test(element));
});
let prefs = list.sort().map(this._getPref, this);
if (!aValue)
return prefs;
let reg = this._generateRegExp(aValue);
if (!reg)
return [];
return prefs.filter(function(element, index, array) {
return reg.test(element.name + ";" + element.value);
});
},
// Copied from old mobile config.js
_generateRegExp: function AC_generateRegExp(aValue) {
if (aValue.charAt(0) == "/") {
try {
let rv = aValue.match(/^\/(.*)\/(i?)$/);
return RegExp(rv[1], rv[2]);
} catch (e) {
return null; // Do nothing on incomplete or bad RegExp
}
}
return RegExp(aValue.replace(/([^* \w])/g, "\\$1").replace(/^\*+/, "")
.replace(/\*+/g, ".*"), "i");
},
_getPref: function AC_getPref(aPrefName) {
let pref = {
name: aPrefName,
value: "",
default: !Services.prefs.prefHasUserValue(aPrefName),
lock: Services.prefs.prefIsLocked(aPrefName),
type: Services.prefs.getPrefType(aPrefName)
};
try {
switch (pref.type) {
case Ci.nsIPrefBranch.PREF_BOOL:
pref.value = Services.prefs.getBoolPref(aPrefName).toString();
break;
case Ci.nsIPrefBranch.PREF_INT:
pref.value = Services.prefs.getIntPref(aPrefName).toString();
break;
default:
case Ci.nsIPrefBranch.PREF_STRING:
pref.value = Services.prefs.getComplexValue(aPrefName, Ci.nsISupportsString).data;
// Try in case it's a localized string (will throw an exception if not)
if (pref.default && /^chrome:\/\/.+\/locale\/.+\.properties/.test(pref.value))
pref.value = Services.prefs.getComplexValue(aPrefName, Ci.nsIPrefLocalizedString).data;
break;
}
} catch (e) {}
return pref;
},
_createItem: function AC_createItem(aPref) {
let name = document.createElement("div");
name.className = "pref-name";
name.textContent = aPref.name;
let value = document.createElement("div");
value.className = "pref-value";
value.textContent = aPref.value;
let modifyButton = document.createElement("button");
modifyButton.className = "modify-pref-button";
modifyButton.textContent = gStringBundle.GetStringFromName("modifyPref.label");
modifyButton.addEventListener("click", function(event) {
this.modifyPref(aPref);
}.bind(this), false);
let resetButton = document.createElement("button");
resetButton.className = "reset-pref-button";
resetButton.textContent = gStringBundle.GetStringFromName("resetPref.label");
resetButton.addEventListener("click", function(event) {
this.resetPref(aPref);
}.bind(this), false);
let item = document.createElement("div");
item.className = "pref-item";
item.appendChild(name);
item.appendChild(value);
item.appendChild(modifyButton);
item.appendChild(resetButton);
item.setAttribute("name", aPref.name);
item.setAttribute("value", aPref.value);
item.setAttribute("default", aPref.default);
return item;
}
}
]]></script>
</body>
</html>

View File

@ -1,97 +0,0 @@
<?xml version="1.0"?>
<!-- ***** 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 Mobile Browser.
-
- The Initial Developer of the Original Code is
- Mozilla Corporation.
- Portions created by the Initial Developer are Copyright (C) 2010
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- 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 LGPL or the GPL. 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 ***** -->
<?xml-stylesheet href="chrome://browser/skin/platform.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/browser.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/browser.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/config.css" type="text/css"?>
<!DOCTYPE window [
<!ENTITY % configDTD SYSTEM "chrome://browser/locale/config.dtd">
%configDTD;
]>
<window id="about:config"
onload="ViewConfig.init();"
onunload="ViewConfig.uninit();"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript" src="chrome://browser/content/config.js"/>
<vbox class="panel-dark" flex="1">
<textbox id="textbox"
oncommand="ViewConfig.filter(this.value)"
type="search"
timeout="400"
emptytext="&empty.label;"/>
<hbox id="main-container" class="panel-dark">
<richlistbox id="prefs-container" flex="1" onselect="ViewConfig.delayEdit(this.selectedItem)" batch="25">
<richlistitem id="editor-row">
<vbox id="editor-container" flex="1">
<hbox align="center" flex="1">
<label value="&newpref.label;" flex="1"/>
<spacer flex="1" />
<hbox id="editor-buttons-add">
<button label="&integer.label;" oncommand="ViewConfig.open(Ci.nsIPrefBranch.PREF_INT)"/>
<button label="&boolean.label;" oncommand="ViewConfig.open(Ci.nsIPrefBranch.PREF_BOOL)"/>
<button label="&string.label;" oncommand="ViewConfig.open(Ci.nsIPrefBranch.PREF_STRING)"/>
</hbox>
</hbox>
<vbox id="editor" hidden="true">
<hbox align="center">
<textbox id="editor-name" emptytext="&addpref.name;" flex="1"/>
<setting id="editor-setting" emptytext="&addpref.value;" onlabel="true" offlabel="false" flex="1"/>
</hbox>
<hbox id="editor-buttons">
<button id="editor-cancel" label="&cancel.label;" oncommand="ViewConfig.close(false)"/>
<spacer flex="1"/>
<button id="editor-reset" label="&reset.label;" oncommand="ViewConfig.reset(this.parentNode.parentNode.nextSibling)"/>
<button id="editor-done" label="&done.label;" oncommand="ViewConfig.close(true)"/>
</hbox>
</vbox>
</vbox>
</richlistitem>
</richlistbox>
</hbox>
</vbox>
</window>

View File

@ -4,8 +4,7 @@ chrome.jar:
% content browser %content/
* content/about.xhtml (content/about.xhtml)
content/config.xul (content/config.xul)
content/config.js (content/config.js)
content/config.xhtml (content/config.xhtml)
content/aboutCertError.xhtml (content/aboutCertError.xhtml)
content/aboutHome.xhtml (content/aboutHome.xhtml)
content/aboutDougt.xhtml (content/aboutDougt.xhtml)
@ -86,5 +85,5 @@ chrome.jar:
content/CaptureDialog.js (content/CaptureDialog.js)
content/CaptureDialog.xul (content/CaptureDialog.xul)
% override chrome://global/content/config.xul chrome://browser/content/config.xul
% override chrome://global/content/config.xul chrome://browser/content/config.xhtml
% override chrome://global/content/netError.xhtml chrome://browser/content/netError.xhtml

View File

@ -1,12 +1,3 @@
<!ENTITY empty.label "Search">
<!ENTITY filter.placeholder "Filter Preferences">
<!ENTITY filter.label "Filter">
<!ENTITY newpref.label "Add a New Preference">
<!ENTITY addpref.name "Name">
<!ENTITY addpref.value "Value">
<!ENTITY cancel.label "Cancel">
<!ENTITY reset.label "Reset">
<!ENTITY done.label "Done">
<!ENTITY integer.label "Integer">
<!ENTITY string.label "String">
<!ENTITY boolean.label "Boolean">

View File

@ -0,0 +1,14 @@
addPref.title=Add
addPref.selectType=Select type:
addPref.type.string=String
addPref.type.integer=Integer
addPref.type.boolean=Boolean
addPref.enterName=Enter name:
modifyPref.label=Modify
modifyPref.selectText=Select value for %1$S:
modifyPref.promptText=Enter value for %1$S:
modifyPref.numberErrorTitle=Invalid Value
modifyPref.numberErrorText=The text you entered was not a number
resetPref.label=Reset

View File

@ -8,6 +8,7 @@
locale/@AB_CD@/browser/browser.dtd (%chrome/browser.dtd)
locale/@AB_CD@/browser/browser.properties (%chrome/browser.properties)
locale/@AB_CD@/browser/config.dtd (%chrome/config.dtd)
locale/@AB_CD@/browser/config.properties (%chrome/config.properties)
locale/@AB_CD@/browser/localepicker.properties (%chrome/localepicker.properties)
locale/@AB_CD@/browser/region.properties (%chrome/region.properties)
locale/@AB_CD@/browser/preferences.dtd (%chrome/preferences.dtd)

View File

@ -34,96 +34,34 @@
*
* ***** END LICENSE BLOCK ***** */
@media (max-width: 499px) {
#editor-container > hbox {
-moz-box-orient: vertical;
}
html {
font-size: 24px;
}
richlistitem {
-moz-box-align: center;
input,
button {
font-size: 28px;
padding: 5px;
}
richlistitem .preferences-title {
pointer-events: none;
min-width: 200px;
-moz-box-flex: 1;
margin-right: 8px;
#filter-container,
#new-pref-container {
margin-bottom: 10px;
}
/* XXX look + sync */
richlistitem[default="false"] .preferences-title {
.pref-item {
padding-top: 10px;
border-top: 1px solid #ccc;
}
.pref-item[default="false"] {
font-weight: bold;
}
richlistitem .preferences-value {
min-width: 200px;
pointer-events: none;
-moz-box-flex: 4;
text-align: end;
color: grey;
.pref-item > * {
margin-bottom: 10px;
}
/* Editor */
#editor-row {
padding: 0;
background: #E9E9E9;
.modify-pref-button {
margin-right: 10px;
}
#editor {
border-bottom: 1px solid rgb(207,207,207);
}
#editor > hbox > #editor-name,
#editor > hbox > #editor-cancel,
#editor > hbox > #editor-done {
display: none;
}
#editor-container > #editor > hbox > #editor-name,
#editor-container > #editor > hbox > #editor-cancel,
#editor-container > #editor > hbox > #editor-done {
display: -moz-box;
}
#editor-container > #editor > hbox > #editor-reset {
display: none;
}
#editor-container > hbox > label {
pointer-events: none;
color: black;
}
#editor + richlistitem {
display: none;
}
#editor[default="false"] .preferences-title {
font-weight: bold;
}
#editor-setting setting {
border-color: transparent !important;
}
#editor-setting[type="string"] .setting-input {
-moz-box-flex: 4;
}
#editor-setting[type="string"] .setting-input > textbox {
-moz-box-flex: 1;
}
/* bug 647650: keep 'text-align: right' here instead of using start/end since
* the field should looks like ltr as much as possible
*/
#editor-setting[type="string"] .setting-input > textbox:-moz-locale-dir(rtl) {
direction: ltr;
text-align: right;
}
#editor-buttons {
margin: 2px;
}