Bug 669345 - Add support for radio button elements for inline preferences; r=Unfocused
authorGeoff Lankow <geoff@darktrojan.net>
Sun, 14 Aug 2011 15:53:49 +1200
changeset 75265 d7d667d640b2fd103682d1a5c9a008bc15062fad
parent 75264 7e6ca29cfa7cb0532f68b2756e6963f7320dda52
child 75266 6ece2d6ece8ee562ed17dd829090011a62fcb147
push id20986
push userkhuey@mozilla.com
push dateSun, 14 Aug 2011 11:45:15 +0000
treeherdermozilla-central@2de3cff973b2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersUnfocused
bugs669345
milestone8.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 669345 - Add support for radio button elements for inline preferences; r=Unfocused
toolkit/mozapps/extensions/content/extensions.css
toolkit/mozapps/extensions/content/setting.xml
toolkit/mozapps/extensions/test/browser/Makefile.in
toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
toolkit/mozapps/extensions/test/browser/more_options.xul
toolkit/themes/gnomestripe/mozapps/extensions/extensions.css
toolkit/themes/pinstripe/mozapps/extensions/extensions.css
toolkit/themes/winstripe/mozapps/extensions/extensions.css
--- a/toolkit/mozapps/extensions/content/extensions.css
+++ b/toolkit/mozapps/extensions/content/extensions.css
@@ -128,16 +128,21 @@ setting[type="color"] {
 }
 
 setting[type="file"],
 setting[type="directory"] {
   display: -moz-grid-line;
   -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-path");
 }
 
+setting[type="radio"] {
+  display: -moz-grid-line;
+  -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-radio");
+}
+
 #addonitem-popup > menuitem[disabled="true"] {
   display: none;
 }
 
 #addonitem-popup[addontype="theme"] > #menuitem_enableItem,
 #addonitem-popup[addontype="theme"] > #menuitem_disableItem,
 #addonitem-popup:not([addontype="theme"]) > #menuitem_enableTheme,
 #addonitem-popup:not([addontype="theme"]) > #menuitem_disableTheme {
--- a/toolkit/mozapps/extensions/content/setting.xml
+++ b/toolkit/mozapps/extensions/content/setting.xml
@@ -17,16 +17,17 @@
    - 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):
    -   Daniel Brooks <db48x@yahoo.com>
    -   Mark Finkle <mfinkle@mozilla.com>
+   -   Geoff Lankow <geoff@darktrojan.net>
    -
    - 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
@@ -466,9 +467,76 @@
             } catch (e) {}
           }
           return this.input.value = label;
        ]]>
         </setter>
       </property>
     </implementation>
   </binding>
+
+  <binding id="setting-radio" extends="chrome://mozapps/content/extensions/setting.xml#setting-base">
+    <content>
+      <xul:vbox class="setting-label">
+        <xul:label class="preferences-title" xbl:inherits="value=title" crop="end" flex="1"/>
+        <xul:label class="preferences-description" xbl:inherits="value=desc" crop="end" flex="1">
+          <children/>
+        </xul:label>
+      </xul:vbox>
+      <xul:hbox class="setting-input">
+        <children includes="radiogroup" />
+      </xul:hbox>
+    </content>
+
+    <implementation>
+      <constructor>
+      <![CDATA[
+        this.radioGroup.addEventListener("command", this.valueToPreference.bind(this), false);
+      ]]>
+      </constructor>
+
+      <method name="valueFromPreference">
+        <body>
+        <![CDATA[
+          let val;
+          switch (Services.prefs.getPrefType(this.pref)) {
+            case Ci.nsIPrefBranch.PREF_STRING:
+              val = Services.prefs.getCharPref(this.pref);
+              break;
+            case Ci.nsIPrefBranch.PREF_INT:
+              val = Services.prefs.getIntPref(this.pref);
+              break;
+            case Ci.nsIPrefBranch.PREF_BOOL:
+              val = Services.prefs.getBoolPref(this.pref).toString();
+              break;
+            default:
+              return;
+          }
+
+          for (let i = 0; i < this.radioGroup.itemCount; i++) {
+            if (this.radioGroup.getItemAtIndex(i).value == val) {
+              this.radioGroup.selectedIndex = i;
+              break;
+            }
+          }
+        ]]>
+        </body>
+      </method>
+
+      <method name="valueToPreference">
+        <body>
+        <![CDATA[
+          // We might not have a pref already set, so we guess the type from the value attribute
+          let val = this.radioGroup.selectedItem.value;
+          if (val == "true" || val == "false")
+            Services.prefs.setBoolPref(this.pref, val == "true");
+          else if (/^-?\d+$/.test(val))
+            Services.prefs.setIntPref(this.pref, val);
+          else
+            Services.prefs.setCharPref(this.pref, val);
+        ]]>
+        </body>
+      </method>
+
+      <field name="radioGroup">this.getElementsByTagName("radiogroup")[0];</field>
+    </implementation>
+  </binding>
 </bindings>
--- a/toolkit/mozapps/extensions/test/browser/Makefile.in
+++ b/toolkit/mozapps/extensions/test/browser/Makefile.in
@@ -118,16 +118,17 @@ include $(DEPTH)/config/autoconf.mk
   browser_updatessl.rdf^headers^ \
   browser_install.rdf \
   browser_install.rdf^headers^ \
   browser_install.xml \
   browser_install1_3.xpi \
   browser_eula.xml \
   browser_purchase.xml \
   discovery.html \
+  more_options.xul \
   options.xul \
   redirect.sjs \
   releaseNotes.xhtml \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 libs:: $(_MAIN_TEST_FILES)
--- a/toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
@@ -37,16 +37,23 @@ function test() {
 
   gProvider.createAddons([{
     id: "inlinesettings2@tests.mozilla.org",
     name: "Inline Settings (Regular)",
     version: "1",
     optionsURL: CHROMEROOT + "options.xul",
     optionsType: AddonManager.OPTIONS_TYPE_INLINE
   },{
+    id: "inlinesettings3@tests.mozilla.org",
+    name: "Inline Settings (More Options)",
+    description: "Tests for option types introduced after Mozilla 7.0",
+    version: "1",
+    optionsURL: CHROMEROOT + "more_options.xul",
+    optionsType: AddonManager.OPTIONS_TYPE_INLINE
+  },{
     id: "noninlinesettings@tests.mozilla.org",
     name: "Non-Inline Settings",
     version: "1",
     optionsURL: CHROMEROOT + "addon_prefs.xul"
   }]);
 
   installAddon(function () {
     open_manager("addons://list/extension", function(aWindow) {
@@ -65,16 +72,19 @@ function end_test() {
 
   Services.prefs.clearUserPref("extensions.inlinesettings1.bool");
   Services.prefs.clearUserPref("extensions.inlinesettings1.boolint");
   Services.prefs.clearUserPref("extensions.inlinesettings1.integer");
   Services.prefs.clearUserPref("extensions.inlinesettings1.string");
   Services.prefs.clearUserPref("extensions.inlinesettings1.color");
   Services.prefs.clearUserPref("extensions.inlinesettings1.file");
   Services.prefs.clearUserPref("extensions.inlinesettings1.directory");
+  Services.prefs.clearUserPref("extensions.inlinesettings3.radioBool");
+  Services.prefs.clearUserPref("extensions.inlinesettings3.radioInt");
+  Services.prefs.clearUserPref("extensions.inlinesettings3.radioString");
 
   close_manager(gManagerWindow, function() {
     AddonManager.getAddonByID("inlinesettings1@tests.mozilla.org", function(aAddon) {
       aAddon.uninstall();
       finish();
     });
   });
 }
@@ -250,16 +260,73 @@ add_test(function() {
       button = gManagerWindow.document.getElementById("detail-prefs-btn");
       is_element_hidden(button, "Preferences button should not be visible");
 
       gCategoryUtilities.openType("extension", run_next_test);
     }
   });
 });
 
+// Tests for the setting.xml bindings introduced after Mozilla 7
+add_test(function() {
+  var addon = get_addon_element(gManagerWindow, "inlinesettings3@tests.mozilla.org");
+  addon.parentNode.ensureElementIsVisible(addon);
+
+  var button = gManagerWindow.document.getAnonymousElementByAttribute(addon, "anonid", "preferences-btn");
+  EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
+
+  wait_for_view_load(gManagerWindow, function() {
+    is(observer.lastData, "inlinesettings3@tests.mozilla.org", "Observer notification should have fired");
+
+    var grid = gManagerWindow.document.getElementById("detail-grid");
+    var settings = grid.querySelectorAll("rows > setting");
+    is(settings.length, 3, "Grid should have settings children");
+
+    // Force bindings to apply
+    settings[0].clientTop;
+
+    ok(settings[0].hasAttribute("first-row"), "First visible row should have first-row attribute");
+    Services.prefs.setBoolPref("extensions.inlinesettings3.radioBool", false);
+    var radios = settings[0].getElementsByTagName("radio");
+    isnot(radios[0].selected, true, "Correct radio button should be selected");
+    is(radios[1].selected, true, "Correct radio button should be selected");
+    EventUtils.synthesizeMouseAtCenter(radios[0], { clickCount: 1 }, gManagerWindow);
+    is(Services.prefs.getBoolPref("extensions.inlinesettings3.radioBool"), true, "Radio pref should have been updated");
+    EventUtils.synthesizeMouseAtCenter(radios[1], { clickCount: 1 }, gManagerWindow);
+    is(Services.prefs.getBoolPref("extensions.inlinesettings3.radioBool"), false, "Radio pref should have been updated");
+
+    ok(!settings[1].hasAttribute("first-row"), "Not the first row");
+    Services.prefs.setIntPref("extensions.inlinesettings3.radioInt", 5);
+    var radios = settings[1].getElementsByTagName("radio");
+    isnot(radios[0].selected, true, "Correct radio button should be selected");
+    is(radios[1].selected, true, "Correct radio button should be selected");
+    isnot(radios[2].selected, true, "Correct radio button should be selected");
+    EventUtils.synthesizeMouseAtCenter(radios[0], { clickCount: 1 }, gManagerWindow);
+    is(Services.prefs.getIntPref("extensions.inlinesettings3.radioInt"), 4, "Radio pref should have been updated");
+    EventUtils.synthesizeMouseAtCenter(radios[2], { clickCount: 1 }, gManagerWindow);
+    is(Services.prefs.getIntPref("extensions.inlinesettings3.radioInt"), 6, "Radio pref should have been updated");
+
+    ok(!settings[2].hasAttribute("first-row"), "Not the first row");
+    Services.prefs.setCharPref("extensions.inlinesettings3.radioString", "juliet");
+    var radios = settings[2].getElementsByTagName("radio");
+    isnot(radios[0].selected, true, "Correct radio button should be selected");
+    is(radios[1].selected, true, "Correct radio button should be selected");
+    isnot(radios[2].selected, true, "Correct radio button should be selected");
+    EventUtils.synthesizeMouseAtCenter(radios[0], { clickCount: 1 }, gManagerWindow);
+    is(Services.prefs.getCharPref("extensions.inlinesettings3.radioString"), "india", "Radio pref should have been updated");
+    EventUtils.synthesizeMouseAtCenter(radios[2], { clickCount: 1 }, gManagerWindow);
+    is(Services.prefs.getCharPref("extensions.inlinesettings3.radioString"), "kilo", "Radio pref should have been updated");
+
+    button = gManagerWindow.document.getElementById("detail-prefs-btn");
+    is_element_hidden(button, "Preferences button should not be visible");
+
+    gCategoryUtilities.openType("extension", run_next_test);
+  });
+});
+
 // Addon with inline preferences as optionsURL
 add_test(function() {
   var addon = get_addon_element(gManagerWindow, "inlinesettings2@tests.mozilla.org");
   addon.parentNode.ensureElementIsVisible(addon);
 
   var button = gManagerWindow.document.getAnonymousElementByAttribute(addon, "anonid", "preferences-btn");
   EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
 
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/browser/more_options.xul
@@ -0,0 +1,23 @@
+<?xml version="1.0" ?>
+<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <setting pref="extensions.inlinesettings3.radioBool" type="radio" title="Radio">
+    <radiogroup>
+      <radio label="Delta" value="true" />
+      <radio label="Echo" value="false" />
+    </radiogroup>
+  </setting>
+  <setting pref="extensions.inlinesettings3.radioInt" type="radio" title="Radio">
+    <radiogroup>
+      <radio label="Foxtrot" value="4" />
+      <radio label="Golf" value="5" />
+      <radio label="Hotel" value="6" />
+    </radiogroup>
+  </setting>
+  <setting pref="extensions.inlinesettings3.radioString" type="radio" title="Radio">
+    <radiogroup>
+      <radio label="India" value="india" />
+      <radio label="Juliet" value="juliet" />
+      <radio label="Kilo" value="kilo" />
+    </radiogroup>
+  </setting>
+</vbox>
--- a/toolkit/themes/gnomestripe/mozapps/extensions/extensions.css
+++ b/toolkit/themes/gnomestripe/mozapps/extensions/extensions.css
@@ -746,16 +746,20 @@ menulist { /* Fixes some styling inconsi
   margin: 1px 5px 2px 5px;
 }
 
 colorpicker[type="button"] { /* Fixes some styling inconsistencies */
   height: 29px;
   margin: 1px 5px 2px 5px;
 }
 
+setting[type="radio"] > radiogroup {
+  -moz-box-orient: horizontal;
+}
+
 /*** creator ***/
 
 .creator > label {
   -moz-margin-start: 0;
   -moz-margin-end: 0;
 }
 
 .creator > .text-link {
--- a/toolkit/themes/pinstripe/mozapps/extensions/extensions.css
+++ b/toolkit/themes/pinstripe/mozapps/extensions/extensions.css
@@ -915,16 +915,20 @@ setting[first-row="true"] {
   margin-top: -2px;
   -moz-margin-start: 2em;
 }
 
 setting[type="string"] > .setting-input > textbox {
   -moz-box-flex: 1;
 }
 
+setting[type="radio"] > radiogroup {
+  -moz-box-orient: horizontal;
+}
+
 
 /*** creator ***/
 
 .creator > label {
   -moz-margin-start: 0;
   -moz-margin-end: 0;
 }
 
--- a/toolkit/themes/winstripe/mozapps/extensions/extensions.css
+++ b/toolkit/themes/winstripe/mozapps/extensions/extensions.css
@@ -894,16 +894,20 @@ setting[first-row="true"] {
   margin-top: -2px;
   -moz-margin-start: 2em;
 }
 
 setting[type="string"] > .setting-input > textbox {
   -moz-box-flex: 1;
 }
 
+setting[type="radio"] > radiogroup {
+  -moz-box-orient: horizontal;
+}
+
 menulist { /* Fixes some styling inconsistencies */
   margin: 1px 5px 2px 5px;
 }
 
 /*** creator ***/
 
 .creator > label {
   -moz-margin-start: 0;