/* 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/. */
"use strict";
// This is loaded into all XUL windows. Wrap in a block to prevent
// leaking to window scope.
{
class MozSettingBase extends MozXULElement {
connectedCallback() {
if (this.delayConnectedCallback()) {
return;
}
this._observer = {
_self: this,
QueryInterface(aIID) {
const Ci = Components.interfaces;
if (aIID.equals(Ci.nsIObserver) ||
aIID.equals(Ci.nsISupportsWeakReference) ||
aIID.equals(Ci.nsISupports))
return this;
throw Components.Exception("No interface", Components.results.NS_ERROR_NO_INTERFACE);
},
observe(aSubject, aTopic, aPrefName) {
if (aTopic != "nsPref:changed")
return;
if (this._self.pref == aPrefName)
this._self.preferenceChanged();
}
};
this._updatingInput = false;
this.input = document.getAnonymousElementByAttribute(this, "anonid", "input");
this.settings = this.parentNode.localName == "settings" ? this.parentNode : null;
this.preferenceChanged();
this.addEventListener("keypress", function(event) {
event.stopPropagation();
});
if (this.usePref)
Services.prefs.addObserver(this.pref, this._observer, true);
}
get usePref() {
return this.hasAttribute('pref');
}
get pref() {
return this.getAttribute('pref');
}
get type() {
return this.getAttribute('type');
}
set value(val) {
return this.input.value = val;
}
get value() {
return this.input.value;
}
fireEvent(eventName, funcStr) {
let body = funcStr || this.getAttribute(eventName);
if (!body)
return;
try {
let event = document.createEvent("Events");
event.initEvent(eventName, true, true);
let f = new Function("event", body);
f.call(this, event);
} catch (e) {
Cu.reportError(e);
}
}
valueFromPreference() {
// Should be code to set the from the preference input.value
throw Components.Exception("No valueFromPreference implementation",
Components.results.NS_ERROR_NOT_IMPLEMENTED);
}
valueToPreference() {
// Should be code to set the input.value from the preference
throw Components.Exception("No valueToPreference implementation",
Components.results.NS_ERROR_NOT_IMPLEMENTED);
}
inputChanged() {
if (this.usePref && !this._updatingInput) {
this.valueToPreference();
this.fireEvent("oninputchanged");
}
}
preferenceChanged() {
if (this.usePref) {
this._updatingInput = true;
try {
this.valueFromPreference();
this.fireEvent("onpreferencechanged");
} catch (e) {}
this._updatingInput = false;
}
}
}
customElements.define("setting-base", MozSettingBase);
}
/* 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/. */
"use strict";
// This is loaded into all XUL windows. Wrap in a block to prevent
// leaking to window scope.
{
class MozSettingBool extends MozSettingBase {
connectedCallback() {
if (this.delayConnectedCallback()) {
return;
}
this.textContent = "";
this.appendChild(MozXULElement.parseXULToFragment(`
<vbox>
<hbox class="preferences-alignment">
<label class="preferences-title" flex="1" inherits="text=title"></label>
</hbox>
<description class="preferences-description" flex="1" inherits="text=desc"></description>
<label class="preferences-learnmore text-link" onclick="document.getBindingParent(this).openLearnMore()"></label>
</vbox>
<hbox class="preferences-alignment">
<checkbox anonid="input" inherits="disabled,onlabel,offlabel,label=checkboxlabel" oncommand="inputChanged();"></checkbox>
</hbox>
`));
// XXX: Implement `this.inheritAttribute()` for the [inherits] attribute in the markup above!
}
set value(val) {
return this.input.setChecked(val);
}
get value() {
return this.input.checked;
}
get inverted() {
return this.getAttribute('inverted');
}
valueFromPreference() {
let val = Services.prefs.getBoolPref(this.pref);
this.value = this.inverted ? !val : val;
}
valueToPreference() {
let val = this.value;
Services.prefs.setBoolPref(this.pref, this.inverted ? !val : val);
}
openLearnMore() {
window.open(this.getAttribute("learnmore"), "_blank");
}
}
customElements.define("setting-bool", MozSettingBool);
}
/* 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/. */
"use strict";
// This is loaded into all XUL windows. Wrap in a block to prevent
// leaking to window scope.
{
class MozSettingBoolint extends MozSettingBool {
connectedCallback() {
if (this.delayConnectedCallback()) {
return;
}
}
valueFromPreference() {
let val = Services.prefs.getIntPref(this.pref);
this.value = (val == this.getAttribute("on"));
}
valueToPreference() {
Services.prefs.setIntPref(this.pref, this.getAttribute(this.value ? "on" : "off"));
}
}
customElements.define("setting-boolint", MozSettingBoolint);
}
/* 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/. */
"use strict";
// This is loaded into all XUL windows. Wrap in a block to prevent
// leaking to window scope.
{
class MozSettingLocalizedBool extends MozSettingBool {
connectedCallback() {
if (this.delayConnectedCallback()) {
return;
}
}
valueFromPreference() {
let val = Services.prefs.getComplexValue(this.pref, Components.interfaces.nsIPrefLocalizedString).data;
if (this.inverted) val = !val;
this.value = (val == "true");
}
valueToPreference() {
let val = this.value;
if (this.inverted) val = !val;
let pref = Components.classes["@mozilla.org/pref-localizedstring;1"].createInstance(Components.interfaces.nsIPrefLocalizedString);
pref.data = this.inverted ? (!val).toString() : val.toString();
Services.prefs.setComplexValue(this.pref, Components.interfaces.nsIPrefLocalizedString, pref);
}
}
customElements.define("setting-localized-bool", MozSettingLocalizedBool);
}
/* 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/. */
"use strict";
// This is loaded into all XUL windows. Wrap in a block to prevent
// leaking to window scope.
{
class MozSettingInteger extends MozSettingBase {
connectedCallback() {
if (this.delayConnectedCallback()) {
return;
}
this.textContent = "";
this.appendChild(MozXULElement.parseXULToFragment(`
<vbox>
<hbox class="preferences-alignment">
<label class="preferences-title" flex="1" inherits="text=title"></label>
</hbox>
<description class="preferences-description" flex="1" inherits="text=desc"></description>
</vbox>
<hbox class="preferences-alignment">
<textbox type="number" anonid="input" oninput="inputChanged();" onchange="inputChanged();" inherits="disabled,emptytext,min,max,increment,hidespinbuttons,wraparound,size"></textbox>
</hbox>
`));
// XXX: Implement `this.inheritAttribute()` for the [inherits] attribute in the markup above!
}
valueFromPreference() {
let val = Services.prefs.getIntPref(this.pref);
this.value = val;
}
valueToPreference() {
Services.prefs.setIntPref(this.pref, this.value);
}
}
customElements.define("setting-integer", MozSettingInteger);
}
/* 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/. */
"use strict";
// This is loaded into all XUL windows. Wrap in a block to prevent
// leaking to window scope.
{
class MozSettingControl extends MozSettingBase {
connectedCallback() {
if (this.delayConnectedCallback()) {
return;
}
this.textContent = "";
this.appendChild(MozXULElement.parseXULToFragment(`
<vbox>
<hbox class="preferences-alignment">
<label class="preferences-title" flex="1" inherits="text=title"></label>
</hbox>
<description class="preferences-description" flex="1" inherits="text=desc"></description>
</vbox>
<hbox class="preferences-alignment">
<children></children>
</hbox>
`));
// XXX: Implement `this.inheritAttribute()` for the [inherits] attribute in the markup above!
}
}
customElements.define("setting-control", MozSettingControl);
}
/* 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/. */
"use strict";
// This is loaded into all XUL windows. Wrap in a block to prevent
// leaking to window scope.
{
class MozSettingString extends MozSettingBase {
connectedCallback() {
if (this.delayConnectedCallback()) {
return;
}
this.textContent = "";
this.appendChild(MozXULElement.parseXULToFragment(`
<vbox>
<hbox class="preferences-alignment">
<label class="preferences-title" flex="1" inherits="text=title"></label>
</hbox>
<description class="preferences-description" flex="1" inherits="text=desc"></description>
</vbox>
<hbox class="preferences-alignment">
<textbox anonid="input" flex="1" oninput="inputChanged();" inherits="disabled,emptytext,type=inputtype,min,max,increment,hidespinbuttons,decimalplaces,wraparound"></textbox>
</hbox>
`));
// XXX: Implement `this.inheritAttribute()` for the [inherits] attribute in the markup above!
}
valueFromPreference() {
this.value = Preferences.get(this.pref, "");
}
valueToPreference() {
Preferences.set(this.pref, this.value);
}
}
customElements.define("setting-string", MozSettingString);
}
/* 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/. */
"use strict";
// This is loaded into all XUL windows. Wrap in a block to prevent
// leaking to window scope.
{
class MozSettingColor extends MozSettingBase {
connectedCallback() {
if (this.delayConnectedCallback()) {
return;
}
this.textContent = "";
this.appendChild(MozXULElement.parseXULToFragment(`
<vbox>
<hbox class="preferences-alignment">
<label class="preferences-title" flex="1" inherits="text=title"></label>
</hbox>
<description class="preferences-description" flex="1" inherits="text=desc"></description>
</vbox>
<hbox class="preferences-alignment">
<colorpicker type="button" anonid="input" inherits="disabled" onchange="document.getBindingParent(this).inputChanged();"></colorpicker>
</hbox>
`));
// XXX: Implement `this.inheritAttribute()` for the [inherits] attribute in the markup above!
}
set value(val) {
return this.input.color = val;
}
get value() {
return this.input.color;
}
valueFromPreference() {
// We must wait for the colorpicker's binding to be applied before setting the value
if (!this.input.color)
this.input.initialize();
this.value = Services.prefs.getCharPref(this.pref);
}
valueToPreference() {
Services.prefs.setCharPref(this.pref, this.value);
}
}
customElements.define("setting-color", MozSettingColor);
}
/* 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/. */
"use strict";
// This is loaded into all XUL windows. Wrap in a block to prevent
// leaking to window scope.
{
class MozSettingPath extends MozSettingBase {
connectedCallback() {
if (this.delayConnectedCallback()) {
return;
}
this.textContent = "";
this.appendChild(MozXULElement.parseXULToFragment(`
<vbox>
<hbox class="preferences-alignment">
<label class="preferences-title" flex="1" inherits="text=title"></label>
</hbox>
<description class="preferences-description" flex="1" inherits="text=desc"></description>
</vbox>
<hbox class="preferences-alignment">
<button type="button" anonid="button" label="FROM-DTD.settings.path.button.label;" inherits="disabled" oncommand="showPicker();"></button>
<label anonid="input" flex="1" crop="center" inherits="disabled"></label>
</hbox>
`));
// XXX: Implement `this.inheritAttribute()` for the [inherits] attribute in the markup above!
this._value = "";
}
set value(val) {
this._value = val;
let label = "";
if (val) {
try {
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.initWithPath(val);
label = this.hasAttribute("fullpath") ? file.path : file.leafName;
} catch (e) {}
}
this.input.tooltipText = val;
return this.input.value = label;
}
get value() {
return this._value;
}
showPicker() {
var filePicker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
filePicker.init(window, this.getAttribute("title"),
this.type == "file" ? Ci.nsIFilePicker.modeOpen : Ci.nsIFilePicker.modeGetFolder);
if (this.value) {
try {
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.initWithPath(this.value);
filePicker.displayDirectory = this.type == "file" ? file.parent : file;
if (this.type == "file") {
filePicker.defaultString = file.leafName;
}
} catch (e) {}
}
filePicker.open(rv => {
if (rv != Ci.nsIFilePicker.returnCancel && filePicker.file) {
this.value = filePicker.file.path;
this.inputChanged();
}
});
}
valueFromPreference() {
this.value = Preferences.get(this.pref, "");
}
valueToPreference() {
Preferences.set(this.pref, this.value);
}
}
customElements.define("setting-path", MozSettingPath);
}
/* 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/. */
"use strict";
// This is loaded into all XUL windows. Wrap in a block to prevent
// leaking to window scope.
{
class MozSettingMulti extends MozSettingBase {
connectedCallback() {
if (this.delayConnectedCallback()) {
return;
}
this.textContent = "";
this.appendChild(MozXULElement.parseXULToFragment(`
<vbox>
<hbox class="preferences-alignment">
<label class="preferences-title" flex="1" inherits="text=title"></label>
</hbox>
<description class="preferences-description" flex="1" inherits="text=desc"></description>
</vbox>
<hbox class="preferences-alignment">
<children includes="radiogroup|menulist"></children>
</hbox>
`));
// XXX: Implement `this.inheritAttribute()` for the [inherits] attribute in the markup above!
this.control = this.getElementsByTagName(this.getAttribute("type") == "radio" ? "radiogroup" : "menulist")[0];
this.control.addEventListener("command", this.inputChanged.bind(this));
}
valueFromPreference() {
let val = Preferences.get(this.pref, "").toString();
if ("itemCount" in this.control) {
for (let i = 0; i < this.control.itemCount; i++) {
if (this.control.getItemAtIndex(i).value == val) {
this.control.selectedIndex = i;
break;
}
}
} else {
this.control.setAttribute("value", val);
}
}
valueToPreference() {
// We might not have a pref already set, so we guess the type from the value attribute
let val = this.control.selectedItem.value;
if (val == "true" || val == "false") {
val = val == "true";
} else if (/^-?\d+$/.test(val)) {
val = parseInt(val, 10);
}
Preferences.set(this.pref, val);
}
}
customElements.define("setting-multi", MozSettingMulti);
}