зеркало из https://github.com/mozilla/gecko-dev.git
Bug 540009 - revise about:config screen design for touch use [r=mark.finkle]
This commit is contained in:
Родитель
4a80897005
Коммит
d0b1111af9
|
@ -357,6 +357,14 @@
|
|||
|
||||
<binding id="place-base">
|
||||
<content/>
|
||||
|
||||
<handlers>
|
||||
<handler event="click" button="0">
|
||||
if (this.control)
|
||||
this.control._fireOpen(event, this);
|
||||
</handler>
|
||||
</handlers>
|
||||
|
||||
<implementation>
|
||||
<field name="_uri">null</field>
|
||||
<field name="_control">null</field>
|
||||
|
@ -637,6 +645,15 @@
|
|||
</binding>
|
||||
|
||||
<binding id="place-label" extends="chrome://browser/content/bindings.xml#place-base">
|
||||
<handlers>
|
||||
<handler event="click" button="0">
|
||||
<![CDATA[
|
||||
if (this.control)
|
||||
this.control.openFolder(this.previousSibling.itemId);
|
||||
]]>
|
||||
</handler>
|
||||
</handlers>
|
||||
|
||||
<content align="center">
|
||||
<xul:spacer xbl:inherits="width=indent"/>
|
||||
<xul:image anonid="favicon" class="bookmark-folder-image"/>
|
||||
|
@ -647,7 +664,7 @@
|
|||
<binding id="place-list">
|
||||
<content orient="vertical" flex="1">
|
||||
<xul:vbox anonid="parent-items" class="place-list-parents" />
|
||||
<xul:richlistbox anonid="child-items" class="place-list-children" flex="1"/>
|
||||
<xul:richlistbox anonid="child-items" class="place-list-children" flex="1" batch="25"/>
|
||||
</content>
|
||||
<implementation>
|
||||
<constructor>
|
||||
|
@ -709,12 +726,6 @@
|
|||
</field>
|
||||
|
||||
<field name="scrollBoxObject">this._children.scrollBoxObject</field>
|
||||
<!-- This won't be updated when the window size changes, but that's OK,
|
||||
since we don't need an exact value - we just use it to get an
|
||||
approximate scroll position for deciding whether to append additional
|
||||
items (see batchSize/_insertItems()).
|
||||
-->
|
||||
<field name="_childrenHeight">this.scrollBoxObject.height;</field>
|
||||
|
||||
<property name="items" readonly="true" onget="return this._children.childNodes"/>
|
||||
|
||||
|
@ -861,14 +872,6 @@
|
|||
</body>
|
||||
</method>
|
||||
|
||||
<!-- Number of elements to add to the list initially. If there are more
|
||||
than this many bookmarks to display, only add them to the list once
|
||||
the user has scrolled towards them. This is a performance
|
||||
optimization to avoid locking up while attempting to append hundreds
|
||||
of bookmarks to our richlistbox.
|
||||
-->
|
||||
<field name="batchSize">25</field>
|
||||
|
||||
<method name="openFolder">
|
||||
<parameter name="aRootFolder"/>
|
||||
<body>
|
||||
|
@ -899,9 +902,6 @@
|
|||
parent.setAttribute("title", title);
|
||||
parents.insertBefore(parent, parents.firstChild);
|
||||
|
||||
// XXX Fix me - use <handler>?
|
||||
parent.addEventListener("click", function(e) { self.openFolder(e.target.previousSibling.itemId); }, false);
|
||||
|
||||
folderId = this._folderParents[folderId] || PlacesUtils.bookmarks.getFolderIdForItem(folderId);
|
||||
} while (folderId != PlacesUtils.bookmarks.placesRoot)
|
||||
|
||||
|
@ -911,95 +911,13 @@
|
|||
|
||||
children.scrollBoxObject.scrollTo(0, 0);
|
||||
|
||||
this._childItems = (aRootFolder == this._fakeDesktopFolderId) ? this._desktopChildren.concat()
|
||||
: this._getChildren(aRootFolder);
|
||||
let items = (aRootFolder == this._fakeDesktopFolderId) ? this._desktopChildren.concat()
|
||||
: this._getChildren(aRootFolder);
|
||||
|
||||
if (aRootFolder == this.mobileRoot && !this.isDesktopFolderEmpty())
|
||||
this._childItems.unshift(this._desktopFolder);
|
||||
items.unshift(this._desktopFolder);
|
||||
|
||||
this._insertItems();
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="close">
|
||||
<body>
|
||||
<![CDATA[
|
||||
// Clear out references to child items, and remove event listener
|
||||
// if needed
|
||||
this._childItems = null;
|
||||
if (this._scrollListenerAdded) {
|
||||
this._children.removeEventListener("scroll", this._scrollListener, false);
|
||||
this._scrollListenerAdded = false;
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="_insertItems">
|
||||
<body>
|
||||
<![CDATA[
|
||||
let items = this._childItems.splice(0, this.batchSize);
|
||||
|
||||
if (!items.length)
|
||||
return; // no items to insert
|
||||
|
||||
let children = this._children;
|
||||
let itemsRemaining = this._childItems.length > 0;
|
||||
if (itemsRemaining && !this._scrollListenerAdded) {
|
||||
// We're not going to insert all items, so add a scroll listener
|
||||
// to know when to add them.
|
||||
this._children.addEventListener("scroll", this._scrollListener, false);
|
||||
this._scrollListenerAdded = true;
|
||||
}
|
||||
|
||||
if (!itemsRemaining && this._scrollListenerAdded) {
|
||||
// Can get rid of the scroll listener now that all items are added.
|
||||
this._children.removeEventListener("scroll", this._scrollListener, false);
|
||||
this._scrollListenerAdded = false;
|
||||
}
|
||||
|
||||
let fragment = document.createDocumentFragment();
|
||||
let count = items.length;
|
||||
for (let i=0; i<count; i++)
|
||||
fragment.appendChild(this.createItem(items[i]));
|
||||
children.appendChild(fragment);
|
||||
|
||||
// make sure we recalculate the scrollHeight of the children
|
||||
this._childrenScrollHeight = -1;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<field name="_scrollListener"><![CDATA[
|
||||
({
|
||||
self: this,
|
||||
handleEvent: function () {
|
||||
this.self._checkForInsert();
|
||||
}
|
||||
})
|
||||
]]></field>
|
||||
|
||||
<method name="_checkForInsert">
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (this._childrenScrollHeight == -1) {
|
||||
// Need to force a reflow to get the right value here since we may
|
||||
// have just added children.
|
||||
Browser.forceChromeReflow();
|
||||
let scrollheight = {};
|
||||
this.scrollBoxObject.getScrolledSize({}, scrollheight);
|
||||
this._childrenScrollHeight = scrollheight.value;
|
||||
}
|
||||
|
||||
let y = {};
|
||||
this.scrollBoxObject.getPosition({}, y);
|
||||
let scrollRatio = (y.value + this._childrenHeight) / this._childrenScrollHeight;
|
||||
|
||||
// If we're scrolled 80% to the bottom of the list, append the next
|
||||
// set of items
|
||||
if (scrollRatio > 0.8)
|
||||
this._insertItems();
|
||||
children.setItems(items.map(this.createItem));
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
@ -1021,10 +939,6 @@
|
|||
else
|
||||
child.setAttribute("src", aItem.icon);
|
||||
|
||||
// XXX make a <handler>
|
||||
let self = this;
|
||||
child.addEventListener("click", function(e) { self._fireOpen(e, child); }, false);
|
||||
|
||||
return child;
|
||||
]]>
|
||||
</body>
|
||||
|
@ -1073,6 +987,69 @@
|
|||
</implementation>
|
||||
</binding>
|
||||
|
||||
<binding id="richlistbox-batch" extends="chrome://global/content/bindings/richlistbox.xml#richlistbox">
|
||||
<handlers>
|
||||
<handler event="scroll">
|
||||
<![CDATA[
|
||||
// if there no more items to insert, just return early
|
||||
if (this._items.length == 0)
|
||||
return;
|
||||
|
||||
if (this._contentScrollHeight == -1) {
|
||||
let scrollheight = {};
|
||||
this.scrollBoxObject.getScrolledSize({}, scrollheight);
|
||||
this._contentScrollHeight = scrollheight.value;
|
||||
}
|
||||
|
||||
let y = {};
|
||||
this.scrollBoxObject.getPosition({}, y);
|
||||
let scrollRatio = (y.value + this._childrenHeight) / this._contentScrollHeight;
|
||||
|
||||
// If we're scrolled 80% to the bottom of the list, append the next
|
||||
// set of items
|
||||
if (scrollRatio > 0.8)
|
||||
this._insertItems();
|
||||
]]>
|
||||
</handler>
|
||||
</handlers>
|
||||
<implementation>
|
||||
<!-- Number of elements to add to the list initially. If there are more
|
||||
than this many elements to display, only add them to the list once
|
||||
the user has scrolled towards them. This is a performance
|
||||
optimization to avoid locking up while attempting to append hundreds
|
||||
of nodes to our richlistbox.
|
||||
-->
|
||||
<property name="batchSize" readonly="true" onget="return this.getAttribute('batch')"/>
|
||||
|
||||
<field name="_childrenHeight">this.scrollBoxObject.height;</field>
|
||||
<field name="_items">[]</field>
|
||||
|
||||
<method name="setItems">
|
||||
<parameter name="aItems"/>
|
||||
<body><![CDATA[
|
||||
this._items = aItems;
|
||||
this._insertItems();
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_insertItems">
|
||||
<body><![CDATA[
|
||||
let items = this._items.splice(0, this.batchSize);
|
||||
if (!items.length)
|
||||
return; // no items to insert
|
||||
|
||||
let count = items.length;
|
||||
for (let i = 0; i<count; i++)
|
||||
this.appendChild(items[i]);
|
||||
|
||||
|
||||
// make sure we recalculate the scrollHeight of the content
|
||||
this._contentScrollHeight = -1;
|
||||
]]></body>
|
||||
</method>
|
||||
</implementation>
|
||||
</binding>
|
||||
|
||||
<binding id="richlistitem" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
|
||||
<handlers>
|
||||
<handler event="mousedown" phase="capturing">
|
||||
|
|
|
@ -184,7 +184,7 @@
|
|||
</xul:label>
|
||||
</xul:vbox>
|
||||
<xul:hbox anonid="input-container">
|
||||
<xul:checkbox anonid="input" xbl:inherits="disabled" oncommand="inputChanged();"/>
|
||||
<xul:checkbox anonid="input" xbl:inherits="disabled,onlabel,offlabel" oncommand="inputChanged();"/>
|
||||
</xul:hbox>
|
||||
</xul:box>
|
||||
</content>
|
||||
|
@ -337,7 +337,6 @@
|
|||
let iss = Components.classes["@mozilla.org/supports-string;1"]
|
||||
.createInstance(Components.interfaces.nsISupportsString);
|
||||
iss.data = this.value;
|
||||
Components.reportError(this.value)
|
||||
this._prefs
|
||||
.setComplexValue(this.pref, Components.interfaces.nsISupportsString, iss);
|
||||
]]>
|
||||
|
|
|
@ -1049,8 +1049,6 @@ var BookmarkList = {
|
|||
close: function() {
|
||||
BrowserUI.updateStar();
|
||||
|
||||
this._bookmarks.close();
|
||||
|
||||
if (this._bookmarks.manageUI)
|
||||
this.toggleManage();
|
||||
this._bookmarks.blur();
|
||||
|
|
|
@ -98,6 +98,10 @@ menulist {
|
|||
}
|
||||
|
||||
/* richlist defaults ------------------------------------------------------- */
|
||||
richlistbox[batch] {
|
||||
-moz-binding: url("chrome://browser/content/bindings.xml#richlistbox-batch");
|
||||
}
|
||||
|
||||
richlistitem {
|
||||
-moz-binding: url("chrome://browser/content/bindings.xml#richlistitem");
|
||||
}
|
||||
|
|
|
@ -1355,8 +1355,10 @@ Browser.MainDragger.prototype = {
|
|||
let panOffset = this._panControlsAwayOffset(doffset);
|
||||
|
||||
// do HTML overflow or XUL panning
|
||||
if (this.contentScrollbox && !doffset.isZero())
|
||||
if (this.contentScrollbox && !doffset.isZero()) {
|
||||
this._panScrollbox(this.contentScrollbox, doffset);
|
||||
render = true;
|
||||
}
|
||||
|
||||
// Do all iframe panning
|
||||
if (elem) {
|
||||
|
|
|
@ -0,0 +1,410 @@
|
|||
/* ***** 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) 2008
|
||||
* 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 Cc = Components.classes;
|
||||
let Ci = Components.interfaces;
|
||||
|
||||
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("");
|
||||
},
|
||||
|
||||
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 nameField = document.getElementById("editor-name");
|
||||
nameField.value = "";
|
||||
|
||||
let shouldFocus = false;
|
||||
let setting = document.getElementById("editor-setting");
|
||||
switch (aType) {
|
||||
case Ci.nsIPrefBranch.PREF_INT:
|
||||
setting.setAttribute("type", "integer");
|
||||
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);
|
||||
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").value;
|
||||
if (name != "") {
|
||||
let setting = document.getElementById("editor-setting");
|
||||
setting.setAttribute("pref", name);
|
||||
setting.valueToPreference();
|
||||
}
|
||||
}
|
||||
document.getElementById("editor-container").appendChild(this._editor);
|
||||
},
|
||||
|
||||
_currentItem: null,
|
||||
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));
|
||||
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.outerHeight - 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;
|
||||
}
|
||||
|
||||
// add 1 because of the new pref row
|
||||
let item = this._container.childNodes[aIndex + 1];
|
||||
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("default", aPref.default);
|
||||
|
||||
let label = document.createElement("label");
|
||||
label.setAttribute("class", "preftitle");
|
||||
label.setAttribute("value", aPref.name);
|
||||
label.setAttribute("crop", "end");
|
||||
row.appendChild(label);
|
||||
|
||||
label = document.createElement("label");
|
||||
label.setAttribute("class", "prefvalue");
|
||||
label.setAttribute("value", aPref.value);
|
||||
label.setAttribute("crop", "end");
|
||||
row.appendChild(label);
|
||||
|
||||
return row;
|
||||
},
|
||||
|
||||
getIncrementForValue: function getIncrementForValue(aValue) {
|
||||
let count = 0;
|
||||
while (aValue > 10) {
|
||||
aValue /= 10;
|
||||
count++;
|
||||
}
|
||||
|
||||
return Math.max(1, count * 10);
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
let prefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService);
|
||||
this._branch = prefService.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");
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
<?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) 2008
|
||||
- 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.edit(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(Components.interfaces.nsIPrefBranch.PREF_INT)"/>
|
||||
<button label="&boolean.label;" oncommand="ViewConfig.open(Components.interfaces.nsIPrefBranch.PREF_BOOL)"/>
|
||||
<button label="&string.label;" oncommand="ViewConfig.open(Components.interfaces.nsIPrefBranch.PREF_STRING)"/>
|
||||
</hbox>
|
||||
</hbox>
|
||||
|
||||
<vbox id="editor" hidden="true">
|
||||
<hbox align="center">
|
||||
<textbox id="editor-name" flex="1"/>
|
||||
<setting id="editor-setting" 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>
|
||||
|
|
@ -3,6 +3,8 @@
|
|||
chrome.jar:
|
||||
% content browser %content/
|
||||
* content/about.xhtml (content/about.xhtml)
|
||||
content/config.xul (content/config.xul)
|
||||
content/config.js (content/config.js)
|
||||
content/aboutCertError.xhtml (content/aboutCertError.xhtml)
|
||||
content/aboutCertError.css (content/aboutCertError.css)
|
||||
content/languages.properties (content/languages.properties)
|
||||
|
@ -43,3 +45,5 @@ chrome.jar:
|
|||
content/prompt/promptPassword.xul (content/prompt/promptPassword.xul)
|
||||
content/prompt/select.xul (content/prompt/select.xul)
|
||||
content/prompt/prompt.js (content/prompt/prompt.js)
|
||||
|
||||
% override chrome://global/content/config.xul chrome://browser/content/config.xul
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<!ENTITY empty.label "Search">
|
||||
<!ENTITY newpref.label "Add a new preference">
|
||||
|
||||
<!ENTITY cancel.label "Cancel">
|
||||
<!ENTITY reset.label "Reset">
|
||||
<!ENTITY done.label "Done">
|
||||
|
||||
<!ENTITY integer.label "Integer">
|
||||
<!ENTITY string.label "String">
|
||||
<!ENTITY boolean.label "Boolean">
|
|
@ -6,6 +6,7 @@
|
|||
locale/@AB_CD@/browser/aboutCertError.dtd (%chrome/aboutCertError.dtd)
|
||||
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/firstrun.dtd (%chrome/firstrun.dtd)
|
||||
locale/@AB_CD@/browser/region.properties (%chrome/region.properties)
|
||||
locale/@AB_CD@/browser/preferences.dtd (%chrome/preferences.dtd)
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/* ***** 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) 2008
|
||||
* 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 ***** */
|
||||
|
||||
richlistitem {
|
||||
-moz-box-align: center;
|
||||
}
|
||||
|
||||
richlistitem .preftitle {
|
||||
min-width: 200px;
|
||||
-moz-box-flex: 1;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
/* XXX look + sync */
|
||||
richlistitem[default="false"] .preftitle {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
richlistitem .prefvalue {
|
||||
min-width: 200px;
|
||||
-moz-box-flex: 4;
|
||||
text-align: right;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
/* Editor */
|
||||
#editor-row {
|
||||
padding: 0;
|
||||
background: #E9E9E9;
|
||||
}
|
||||
|
||||
#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: block;
|
||||
}
|
||||
|
||||
#editor-container > #editor > hbox > #editor-reset {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#editor + richlistitem {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#editor[default="false"] .preftitle {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#editor-setting .prefbox {
|
||||
border-color: transparent !important;
|
||||
}
|
||||
|
||||
#editor-setting[type="string"] [anonid="input-container"] {
|
||||
-moz-box-flex: 4;
|
||||
}
|
||||
|
||||
#editor-setting[type="string"] [anonid="input-container"] > textbox {
|
||||
-moz-box-flex: 1;
|
||||
}
|
||||
|
||||
#editor-buttons {
|
||||
margin: 2px;
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ chrome.jar:
|
|||
aboutCertError.css (aboutCertError.css)
|
||||
aboutPage.css (aboutPage.css)
|
||||
about.css (about.css)
|
||||
config.css (config.css)
|
||||
firstRun.css (firstRun.css)
|
||||
header.css (header.css)
|
||||
platform.css (platform.css)
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/* ***** 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) 2008
|
||||
* 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 ***** */
|
||||
|
||||
richlistitem {
|
||||
-moz-box-align: center;
|
||||
}
|
||||
|
||||
richlistitem .preftitle {
|
||||
min-width: 100px;
|
||||
-moz-box-flex: 1;
|
||||
margin-right: 1.1mm;
|
||||
}
|
||||
|
||||
/* XXX look + sync */
|
||||
richlistitem[default="false"] .preftitle {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
richlistitem .prefvalue {
|
||||
min-width: 100px;
|
||||
-moz-box-flex: 4;
|
||||
text-align: right;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
/* Editor */
|
||||
#editor-row {
|
||||
padding: 0;
|
||||
background: #E9E9E9;
|
||||
}
|
||||
|
||||
#editor {
|
||||
border-bottom: 0.05mm 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: block;
|
||||
}
|
||||
|
||||
#editor-container > #editor > hbox > #editor-reset {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#editor + richlistitem {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#editor[default="false"] .preftitle {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#editor-setting .prefbox {
|
||||
border-bottom: 0 solid transparent !important;
|
||||
}
|
||||
|
||||
#editor-setting[type="string"] [anonid="input-container"] {
|
||||
-moz-box-flex: 4;
|
||||
}
|
||||
|
||||
#editor-setting[type="string"] [anonid="input-container"] > textbox {
|
||||
-moz-box-flex: 1;
|
||||
}
|
||||
|
||||
#editor-buttons {
|
||||
margin: 0.5mm;
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ chrome.jar:
|
|||
% skin browser classic/1.0 %
|
||||
aboutCertError.css (aboutCertError.css)
|
||||
aboutPage.css (aboutPage.css)
|
||||
config.css (config.css)
|
||||
firstRun.css (firstRun.css)
|
||||
header.css (header.css)
|
||||
platform.css (platform.css)
|
||||
|
|
Загрузка…
Ссылка в новой задаче