Skip to content
This repository has been archived by the owner on Feb 26, 2022. It is now read-only.

Bug 710107 - Support radio type for simple-prefs #597

Merged
merged 7 commits into from
Oct 17, 2012
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/dev-guide-source/tutorials/l10n.md
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,10 @@ When the browser's locale is set to "fr-FR", they see this:

<img class="image-center" src="static-files/media/screenshots/preference-french.png" alt="screenshot of French preference localization">

The `menulist` and the `radio` preference types have options.
The `label` attribute of each option is displayed to the user.
If the locale file has a entry with the value of the `label` attribute as its key, its value is used as a localized label.

## Using Identifiers ##

If the localization system can't find an entry for a particular identifier
Expand Down
69 changes: 67 additions & 2 deletions packages/addon-kit/docs/simple-prefs.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,7 @@ They are documented along with the

The setting types map to the
[inline settings types](https://developer.mozilla.org/en/Extensions/Inline_Options)
used by the Add-on Manager. All the inline settings are supported except
for `radio` and `menulist`.
used by the Add-on Manager. All the inline settings are supported.

<table>
<tr>
Expand Down Expand Up @@ -226,6 +225,72 @@ for `radio` and `menulist`.
"title": "Select a directory"
}</pre></td>
</tr>
<tr>
<td><code>menulist</code></td>
<td><p>Displayed as a drop-down list.
The type of the stored value depends on the default value.</p>
<p>The options are specified by a mandatory "options" attribute,
that is an array of objects with mandatory attributes
"label" and "value"<p>
<p>The values of the "value" attributes must be supplied as strings.</p>
<p>The values of the "label" attributes are used as localization keys,
or used verbatim as labels if no matching entries are exist in
locale file.</p></td>
<td><pre>
{
"name": "typeOfBreath",
"type": "menulist",
"title": "Type of breath",
"value": 0,
"options": [
{
"value": "0",
"label": "Fire"
},
{
"value": "1",
"label": "Cold"
},
{
"value": "2",
"label": "Disintegration"
}
]
}<pre></td>
</tr>
<tr>
<td><code>radio</code></td>
<td><p>Displayed as radio buttons.
The type of the stored value depends on the default value.</p>
<p>The options are specified by a mandatory "options" attribute,
that is an array of objects with mandatory attributes
"label" and "value"<p>
<p>The values of the "value" attributes must be supplied as strings.</p>
<p>The values of the "label" attributes are used as localization keys,
or used verbatim as labels if no matching entries are exist in
locale file.</p></td>
<td><pre>
{
"name": "alignment",
"type": "radio",
"title": "Alignment",
"value": "N",
"options": [
{
"value": "L",
"label": "Lawful"
},
{
"value": "N",
"label": "Neutral"
},
{
"value": "C",
"label": "Chaotic"
}
]
}<pre></td>
</tr>
<tr>
<td><code>control</code></td>
<td><p>Displays a button.</p>
Expand Down
6 changes: 6 additions & 0 deletions packages/api-utils/lib/l10n/prefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ function onOptionsDisplayed(document, addonId) {
let title = core.get(name + "_title");
if (title)
node.setAttribute("title", title);

for (let item of node.querySelectorAll("menuitem, radio")) {
let label = core.get(item.getAttribute("label"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use core.get(name + "_options." + item.getAttribute("label")) to stick to the convention already started.

if (label)
item.setAttribute("label", label);
}
}
else if (node.tagName == "button") {
let label = core.get(name + "_label");
Expand Down
32 changes: 31 additions & 1 deletion python-lib/cuddlefish/options_xul.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from xml.dom.minidom import Document

VALID_PREF_TYPES = ['bool', 'boolint', 'integer', 'string', 'color', 'file',
'directory', 'control']
'directory', 'control', 'menulist', 'radio']

class Error(Exception):
pass
Expand All @@ -31,6 +31,18 @@ def validate_prefs(options):
if ("label" not in pref):
raise MissingPrefAttr("The 'control' inline pref type requires a 'label'")

# Make sure the 'menulist' type has a 'menulist'
if (pref["type"] == "menulist" or pref["type"] == "radio"):
if ("options" not in pref):
raise MissingPrefAttr("The 'menulist' and the 'radio' inline pref types requires a 'options'")

# Make sure each option has a 'value' and a 'label'
for item in pref["options"]:
if ("value" not in item):
raise MissingPrefAttr("'options' requires a 'value'")
if ("label" not in item):
raise MissingPrefAttr("'options' requires a 'label'")

# TODO: Check that pref["type"] matches default value type

def parse_options(options, jetpack_id):
Expand Down Expand Up @@ -62,6 +74,24 @@ def parse_options(options, jetpack_id):
elif (pref["type"] == "boolint"):
setting.setAttribute("on", pref["on"])
setting.setAttribute("off", pref["off"])
elif (pref["type"] == "menulist"):
menulist = doc.createElement("menulist")
menupopup = doc.createElement("menupopup")
for item in pref["options"]:
menuitem = doc.createElement("menuitem")
menuitem.setAttribute("value", item["value"])
menuitem.setAttribute("label", item["label"])
menupopup.appendChild(menuitem)
menulist.appendChild(menupopup)
setting.appendChild(menulist)
elif (pref["type"] == "radio"):
radiogroup = doc.createElement("radiogroup")
for item in pref["options"]:
radio = doc.createElement("radio")
radio.setAttribute("value", item["value"])
radio.setAttribute("label", item["label"])
radiogroup.appendChild(radio)
setting.appendChild(radiogroup)

root.appendChild(setting)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,38 @@
"type": "string",
"title": "tëst",
"value": "ünicødé"
},
{
"name": "test3",
"type": "menulist",
"title": "\"><test",
"value": "1",
"options": [
{
"value": "0",
"label": "label1"
},
{
"value": "1",
"label": "label2"
}
]
},
{
"name": "test4",
"type": "radio",
"title": "tëst",
"value": "red",
"options": [
{
"value": "red",
"label": "rouge"
},
{
"value": "blue",
"label": "bleu"
}
]
}],
"loader": "lib/main.js"
}
44 changes: 40 additions & 4 deletions python-lib/cuddlefish/tests/test_xpi.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from cuddlefish.tests import test_packaging
from test_linker import up

import xml.etree.ElementTree as ElementTree

xpi_template_path = os.path.join(test_packaging.static_files_path,
'xpi-template')

Expand Down Expand Up @@ -40,15 +42,49 @@ def testPackageWithSimplePrefs(self):
self.makexpi('simple-prefs')
self.failUnless('options.xul' in self.xpi.namelist())
optsxul = self.xpi.read('options.xul').decode("utf-8")
self.failUnless('pref="extensions.jid1-fZHqN9JfrDBa8A@jetpack.test"'
in optsxul, optsxul)
self.failUnless('type="bool"' in optsxul, optsxul)
self.failUnless(u'title="t\u00EBst"' in optsxul, repr(optsxul))
self.failUnlessEqual(self.xpi_harness_options["jetpackID"],
"jid1-fZHqN9JfrDBa8A@jetpack")

root = ElementTree.XML(optsxul.encode('utf-8'))

xulNamespacePrefix = \
"{http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul}"

settings = root.findall(xulNamespacePrefix + 'setting')

def assertPref(setting, name, prefType, title):
packageName = 'jid1-fZHqN9JfrDBa8A@jetpack'
self.failUnlessEqual(setting.get('data-jetpack-id'), packageName)
self.failUnlessEqual(setting.get('pref'),
'extensions.' + packageName + '.' + name)
self.failUnlessEqual(setting.get('pref-name'), name)
self.failUnlessEqual(setting.get('type'), prefType)
self.failUnlessEqual(setting.get('title'), title)

assertPref(settings[0], 'test', 'bool', u't\u00EBst')
assertPref(settings[1], 'test2', 'string', u't\u00EBst')
assertPref(settings[2], 'test3', 'menulist', '"><test')
assertPref(settings[3], 'test4', 'radio', u't\u00EBst')

menuItems = settings[2].findall(
'{0}menulist/{0}menupopup/{0}menuitem'.format(xulNamespacePrefix))
radios = settings[3].findall(
'{0}radiogroup/{0}radio'.format(xulNamespacePrefix))

def assertOption(option, value, label):
self.failUnlessEqual(option.get('value'), value)
self.failUnlessEqual(option.get('label'), label)

assertOption(menuItems[0], "0", "label1")
assertOption(menuItems[1], "1", "label2")
assertOption(radios[0], "red", "rouge")
assertOption(radios[1], "blue", "bleu")

prefsjs = self.xpi.read('defaults/preferences/prefs.js').decode("utf-8")
exp = [u'pref("extensions.jid1-fZHqN9JfrDBa8A@jetpack.test", false);',
u'pref("extensions.jid1-fZHqN9JfrDBa8A@jetpack.test2", "\u00FCnic\u00F8d\u00E9");',
u'pref("extensions.jid1-fZHqN9JfrDBa8A@jetpack.test3", "1");',
u'pref("extensions.jid1-fZHqN9JfrDBa8A@jetpack.test4", "red");',
]
self.failUnlessEqual(prefsjs, "\n".join(exp)+"\n")

Expand Down