Bug 669390 - Allow setting a preference value from the menulist inline preferences; r=Unfocused
authorGeoff Lankow <geoff@darktrojan.net>
Sun, 14 Aug 2011 16:05:24 +1200
changeset 75268 6ece2d6ece8ee562ed17dd829090011a62fcb147
parent 75267 d7d667d640b2fd103682d1a5c9a008bc15062fad
child 75269 2de3cff973b2e4563bbf2d0abc4ee81e6eda587c
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
reviewersUnfocused
bugs669390
milestone8.0a1
Bug 669390 - Allow setting a preference value from the menulist inline preferences; r=Unfocused
toolkit/mozapps/extensions/content/extensions.css
toolkit/mozapps/extensions/content/setting.xml
toolkit/mozapps/extensions/test/browser/addons/browser_inlinesettings1/options.xul
toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
toolkit/mozapps/extensions/test/browser/more_options.xul
--- a/toolkit/mozapps/extensions/content/extensions.css
+++ b/toolkit/mozapps/extensions/content/extensions.css
@@ -128,19 +128,20 @@ 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"] {
+setting[type="radio"],
+setting[type="menulist"] {
   display: -moz-grid-line;
-  -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-radio");
+  -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-multi");
 }
 
 #addonitem-popup > menuitem[disabled="true"] {
   display: none;
 }
 
 #addonitem-popup[addontype="theme"] > #menuitem_enableItem,
 #addonitem-popup[addontype="theme"] > #menuitem_disableItem,
--- a/toolkit/mozapps/extensions/content/setting.xml
+++ b/toolkit/mozapps/extensions/content/setting.xml
@@ -307,17 +307,17 @@
     <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 anonid="input-container" class="setting-input">
-        <children includes="button|menulist"/>
+        <children includes="button"/>
       </xul:hbox>
     </content>
   </binding>
 
   <binding id="setting-string" 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"/>
@@ -468,33 +468,33 @@
           }
           return this.input.value = label;
        ]]>
         </setter>
       </property>
     </implementation>
   </binding>
 
-  <binding id="setting-radio" extends="chrome://mozapps/content/extensions/setting.xml#setting-base">
+  <binding id="setting-multi" 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" />
+        <children includes="radiogroup|menulist" />
       </xul:hbox>
     </content>
 
     <implementation>
       <constructor>
       <![CDATA[
-        this.radioGroup.addEventListener("command", this.valueToPreference.bind(this), false);
+        this.control.addEventListener("command", this.valueToPreference.bind(this), false);
       ]]>
       </constructor>
 
       <method name="valueFromPreference">
         <body>
         <![CDATA[
           let val;
           switch (Services.prefs.getPrefType(this.pref)) {
@@ -506,37 +506,37 @@
               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;
+          for (let i = 0; i < this.control.itemCount; i++) {
+            if (this.control.getItemAtIndex(i).value == val) {
+              this.control.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;
+          let val = this.control.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>
+      <field name="control">this.getElementsByTagName(this.getAttribute("type") == "radio" ? "radiogroup" : "menulist")[0];</field>
     </implementation>
   </binding>
 </bindings>
--- a/toolkit/mozapps/extensions/test/browser/addons/browser_inlinesettings1/options.xul
+++ b/toolkit/mozapps/extensions/test/browser/addons/browser_inlinesettings1/options.xul
@@ -1,19 +1,10 @@
 <?xml version="1.0" ?>
 <vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   <setting pref="extensions.inlinesettings1.bool" type="bool" title="Bool"/>
   <setting pref="extensions.inlinesettings1.boolint" type="boolint" on="1" off="2" title="BoolInt"/>
   <setting pref="extensions.inlinesettings1.integer" type="integer" title="Integer"/>
   <setting pref="extensions.inlinesettings1.string" type="string" title="String"/>
-  <setting type="control" title="Menulist">
-    <menulist sizetopopup="always" oncommand="window._testValue = this.value;">
-      <menupopup>
-        <menuitem label="Alpha" value="1" />
-        <menuitem label="Bravo" value="2" />
-        <menuitem label="Charlie" value="3" />
-      </menupopup>
-    </menulist>
-  </setting>
   <setting pref="extensions.inlinesettings1.color" type="color" title="Color"/>
   <setting pref="extensions.inlinesettings1.file" type="file" title="File"/>
   <setting pref="extensions.inlinesettings1.directory" type="directory" title="Directory"/>
 </vbox>
--- a/toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
@@ -3,17 +3,17 @@
  */
 
 // Tests various aspects of the details view
 
 var gManagerWindow;
 var gCategoryUtilities;
 var gProvider;
 
-const SETTINGS_ROWS = 8;
+const SETTINGS_ROWS = 7;
 
 var observer = {
   lastData: null,
   observe: function(aSubject, aTopic, aData) {
     if (aTopic == "addon-options-displayed")
       this.lastData = aData;
   }
 };
@@ -75,16 +75,17 @@ function end_test() {
   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");
+  Services.prefs.clearUserPref("extensions.inlinesettings3.menulist");
 
   close_manager(gManagerWindow, function() {
     AddonManager.getAddonByID("inlinesettings1@tests.mozilla.org", function(aAddon) {
       aAddon.uninstall();
       finish();
     });
   });
 }
@@ -185,42 +186,33 @@ add_test(function() {
     input.select();
     EventUtils.synthesizeKey("b", {}, gManagerWindow);
     EventUtils.synthesizeKey("a", {}, gManagerWindow);
     EventUtils.synthesizeKey("r", {}, gManagerWindow);
     is(input.value, "bar", "Text box should have updated value");
     is(Services.prefs.getCharPref("extensions.inlinesettings1.string"), "bar", "String pref should have been updated");
 
     ok(!settings[4].hasAttribute("first-row"), "Not the first row");
-    var input = settings[4].firstElementChild;
-    is(input.value, "1", "Menulist should have initial value");
-    input.focus();
-    EventUtils.synthesizeKey("b", {}, gManagerWindow);
-    is(input.value, "2", "Menulist should have updated value");
-    is(gManagerWindow._testValue, "2", "Menulist oncommand handler should've updated the test value");
-    delete gManagerWindow._testValue;
-
-    ok(!settings[5].hasAttribute("first-row"), "Not the first row");
     Services.prefs.setCharPref("extensions.inlinesettings1.color", "#FF0000");
-    input = gManagerWindow.document.getAnonymousElementByAttribute(settings[5], "anonid", "input");
+    input = gManagerWindow.document.getAnonymousElementByAttribute(settings[4], "anonid", "input");
     is(input.color, "#FF0000", "Color picker should have initial value");
     input.focus();
     EventUtils.synthesizeKey("VK_RIGHT", {}, gManagerWindow);
     EventUtils.synthesizeKey("VK_RIGHT", {}, gManagerWindow);
     EventUtils.synthesizeKey("VK_RETURN", {}, gManagerWindow);
     input.hidePopup();
     is(input.color, "#FF9900", "Color picker should have updated value");
     is(Services.prefs.getCharPref("extensions.inlinesettings1.color"), "#FF9900", "Color pref should have been updated");
 
     try {
       mockFilePickerFactory.register();
 
-      ok(!settings[6].hasAttribute("first-row"), "Not the first row");
-      var button = gManagerWindow.document.getAnonymousElementByAttribute(settings[6], "anonid", "button");
-      input = gManagerWindow.document.getAnonymousElementByAttribute(settings[6], "anonid", "input");
+      ok(!settings[5].hasAttribute("first-row"), "Not the first row");
+      var button = gManagerWindow.document.getAnonymousElementByAttribute(settings[5], "anonid", "button");
+      input = gManagerWindow.document.getAnonymousElementByAttribute(settings[5], "anonid", "input");
       is(input.value, "", "Label value should be empty");
 
       var profD = Services.dirsvc.get("ProfD", Ci.nsIFile);
       var curProcD = Services.dirsvc.get("CurProcD", Ci.nsIFile);
 
       _returnFile = profD;
       _returnValue = Ci.nsIFilePicker.returnOK;
       EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
@@ -230,19 +222,19 @@ add_test(function() {
 
       _returnFile = curProcD;
       _returnValue = Ci.nsIFilePicker.returnCancel;
       EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
       is(_mode, Ci.nsIFilePicker.modeOpen, "File picker mode should be open file");
       is(input.value, profD.path, "Label value should not have changed");
       is(Services.prefs.getCharPref("extensions.inlinesettings1.file"), profD.path, "File pref should not have changed");
 
-      ok(!settings[7].hasAttribute("first-row"), "Not the first row");
-      button = gManagerWindow.document.getAnonymousElementByAttribute(settings[7], "anonid", "button");
-      input = gManagerWindow.document.getAnonymousElementByAttribute(settings[7], "anonid", "input");
+      ok(!settings[6].hasAttribute("first-row"), "Not the first row");
+      button = gManagerWindow.document.getAnonymousElementByAttribute(settings[6], "anonid", "button");
+      input = gManagerWindow.document.getAnonymousElementByAttribute(settings[6], "anonid", "input");
       is(input.value, "", "Label value should be empty");
 
       _returnFile = profD;
       _returnValue = Ci.nsIFilePicker.returnOK;
       EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
       is(_mode, Ci.nsIFilePicker.modeGetFolder, "File picker mode should be directory");
       is(input.value, profD.path, "Label value should match file chosen");
       is(Services.prefs.getCharPref("extensions.inlinesettings1.directory"), profD.path, "Directory pref should match file chosen");
@@ -273,17 +265,17 @@ add_test(function() {
   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");
+    is(settings.length, 4, "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");
@@ -310,16 +302,25 @@ add_test(function() {
     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");
 
+    ok(!settings[3].hasAttribute("first-row"), "Not the first row");
+    Services.prefs.setIntPref("extensions.inlinesettings3.menulist", 8);
+    var input = settings[3].firstElementChild;
+    is(input.value, "8", "Menulist should have initial value");
+    input.focus();
+    EventUtils.synthesizeKey("n", {}, gManagerWindow);
+    is(input.value, "9", "Menulist should have updated value");
+    is(Services.prefs.getIntPref("extensions.inlinesettings3.menulist"), 9, "Menulist 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
--- a/toolkit/mozapps/extensions/test/browser/more_options.xul
+++ b/toolkit/mozapps/extensions/test/browser/more_options.xul
@@ -15,9 +15,18 @@
   </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>
+  <setting pref="extensions.inlinesettings3.menulist" type="menulist" title="Menulist">
+    <menulist sizetopopup="always">
+      <menupopup>
+        <menuitem label="Lima" value="7" />
+        <menuitem label="Mike" value="8" />
+        <menuitem label="November" value="9" />
+      </menupopup>
+    </menulist>
+  </setting>
 </vbox>