]> git.donarmstrong.com Git - dactyl.git/blob - common/tests/functional/shared-modules/prefs.js
Initial import of 1.0~b6
[dactyl.git] / common / tests / functional / shared-modules / prefs.js
1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code is MozMill Test code.
15  *
16  * The Initial Developer of the Original Code is Mozilla Foundation.
17  * Portions created by the Initial Developer are Copyright (C) 2009
18  * the Initial Developer. All Rights Reserved.
19  *
20  * Contributor(s):
21  *   Henrik Skupin <hskupin@mozilla.com>
22  *   Clint Talbert <ctalbert@mozilla.com>
23  *
24  * Alternatively, the contents of this file may be used under the terms of
25  * either the GNU General Public License Version 2 or later (the "GPL"), or
26  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27  * in which case the provisions of the GPL or the LGPL are applicable instead
28  * of those above. If you wish to allow use of your version of this file only
29  * under the terms of either the GPL or the LGPL, and not to allow others to
30  * use your version of this file under the terms of the MPL, indicate your
31  * decision by deleting the provisions above and replace them with the notice
32  * and other provisions required by the GPL or the LGPL. If you do not delete
33  * the provisions above, a recipient may use your version of this file under
34  * the terms of any one of the MPL, the GPL or the LGPL.
35  *
36  * ***** END LICENSE BLOCK ***** */
37
38 /**
39  * @fileoverview
40  * The PrefsAPI adds support for preferences related functions. It gives access
41  * to the preferences system and allows to handle the preferences dialog
42  *
43  * @version 1.0.1
44  */
45
46 // Include required modules
47 var modalDialog = require("modal-dialog");
48 var utils = require("utils");
49
50
51 const gTimeout = 5000;
52
53 // Preferences dialog element templates
54 const PREF_DIALOG_BUTTONS  = '/{"type":"prefwindow"}/anon({"anonid":"dlg-buttons"})';
55 const PREF_DIALOG_DECK     = '/{"type":"prefwindow"}/anon({"class":"paneDeckContainer"})/anon({"anonid":"paneDeck"})';
56 const PREF_DIALOG_SELECTOR = '/{"type":"prefwindow"}/anon({"orient":"vertical"})/anon({"anonid":"selector"})';
57
58
59 /**
60  * Constructor
61  *
62  * @param {MozMillController} controller
63  *        MozMill controller of the browser window to operate on.
64  */
65 function preferencesDialog(controller) {
66   this._controller = controller;
67 }
68
69 /**
70  * Preferences dialog object to simplify the access to this dialog
71  */
72 preferencesDialog.prototype = {
73   /**
74    * Returns the MozMill controller
75    *
76    * @returns Mozmill controller
77    * @type {MozMillController}
78    */
79   get controller() {
80     return this._controller;
81   },
82
83   /**
84    * Retrieve the currently selected panel
85    *
86    * @returns The panel element
87    * @type {ElemBase}
88    */
89   get selectedPane() {
90     return this.getElement({type: "deck_pane"});
91   },
92
93   /**
94    * Get the given pane id
95    */
96   get paneId() {
97     // Check if the selector and the pane are consistent
98     var selector = this.getElement({type: "selector"});
99
100     this._controller.waitForEval("subject.selector.getAttribute('pane') == subject.dlg.selectedPane.getNode().id", gTimeout, 100,
101                                  {selector: selector.getNode().selectedItem, dlg: this});
102
103     return this.selectedPane.getNode().id;
104   },
105
106   /**
107    * Set the given pane by id
108    *
109    * @param {string} id of the pane
110    */
111   set paneId(id) {
112     var button = this.getElement({type: "selector_button", value: id});
113     this._controller.waitThenClick(button, gTimeout);
114
115     // Check if the correct selector is selected
116     var selector = this.getElement({type: "selector"});
117     this._controller.waitForEval("subject.selector.getAttribute('pane') == subject.newPane", gTimeout, 100,
118                                  {selector: selector.getNode().selectedItem, newPane: id});
119     return this.paneId;
120   },
121
122   /**
123    * Close the preferences dialog
124    *
125    * @param {MozMillController} controller
126    *        MozMillController of the window to operate on
127    * @param {boolean} saveChanges
128    *        (Optional) If true the OK button is clicked on Windows which saves
129    *        the changes. On OS X and Linux changes are applied immediately
130    */
131   close : function preferencesDialog_close(saveChanges) {
132     saveChanges = (saveChanges == undefined) ? false : saveChanges;
133
134     if (mozmill.isWindows) {
135       var button = this.getElement({type: "button", subtype: (saveChanges ? "accept" : "cancel")});
136       this._controller.click(button);
137     } else {
138       this._controller.keypress(null, 'w', {accelKey: true});
139     }
140   },
141
142   /**
143    * Gets all the needed external DTD urls as an array
144    *
145    * @returns Array of external DTD urls
146    * @type [string]
147    */
148   getDtds : function preferencesDialog_getDtds() {
149     return null;
150   },
151
152   /**
153    * Retrieve an UI element based on the given spec
154    *
155    * @param {object} spec
156    *        Information of the UI element which should be retrieved
157    *        type: General type information
158    *        subtype: Specific element or property
159    *        value: Value of the element or property
160    * @returns Element which has been created
161    * @type {ElemBase}
162    */
163   getElement : function aboutSessionRestore_getElement(spec) {
164     var elem = null;
165
166     switch(spec.type) {
167       case "button":
168         elem = new elementslib.Lookup(this._controller.window.document, PREF_DIALOG_BUTTONS +
169                                       '/{"dlgtype":"' + spec.subtype + '"}');
170         break;
171       case "deck":
172         elem = new elementslib.Lookup(this._controller.window.document, PREF_DIALOG_DECK);
173         break;
174       case "deck_pane":
175         var deck = this.getElement({type: "deck"}).getNode();
176
177         // XXX: Bug 390724 - selectedPane is broken. So iterate through all elements
178         var panel = deck.boxObject.firstChild;
179         for (var ii = 0; ii < deck.selectedIndex; ii++)
180           panel = panel.nextSibling;
181
182         elem = new elementslib.Elem(panel);
183         break;
184       case "selector":
185         elem = new elementslib.Lookup(this._controller.window.document, PREF_DIALOG_SELECTOR);
186         break;
187       case "selector_button":
188         elem = new elementslib.Lookup(this._controller.window.document, PREF_DIALOG_SELECTOR +
189                                       '/{"pane":"' + spec.value + '"}');
190         break;
191       default:
192         throw new Error(arguments.callee.name + ": Unknown element type - " + spec.type);
193     }
194
195     return elem;
196   }
197 };
198
199 /**
200  * Preferences object to simplify the access to the nsIPrefBranch.
201  */
202 var preferences = {
203   _prefService : Cc["@mozilla.org/preferences-service;1"].
204                  getService(Ci.nsIPrefService),
205
206   /**
207    * Use branch to access low level functions of nsIPrefBranch
208    *
209    * @return Instance of the preferences branch
210    * @type nsIPrefBranch
211    */
212   get prefBranch() {
213     return this._prefService.QueryInterface(Ci.nsIPrefBranch);
214   },
215
216   /**
217    * Use defaultPrefBranch to access low level functions of the default branch
218    *
219    * @return Instance of the preferences branch
220    * @type nsIPrefBranch
221    */
222   get defaultPrefBranch() {
223     return this._prefService.getDefaultBranch("");
224   },
225
226   /**
227    * Use prefService to access low level functions of nsIPrefService
228    *
229    * @return Instance of the pref service
230    * @type nsIPrefService
231    */
232   get prefService() {
233     return this._prefService;
234   },
235
236   /**
237    * Clear a user set preference
238    *
239    * @param {string} prefName
240    *        The user-set preference to clear
241    * @return False if the preference had the default value
242    * @type boolean
243    **/
244   clearUserPref : function preferences_clearUserPref(prefName) {
245     try {
246       this.prefBranch.clearUserPref(prefName);
247       return true;
248     } catch (e) {
249       return false;
250     }
251   },
252
253   /**
254    * Retrieve the value of an individual preference.
255    *
256    * @param {string} prefName
257    *        The preference to get the value of.
258    * @param {boolean/number/string} defaultValue
259    *        The default value if preference cannot be found.
260    * @param {boolean/number/string} defaultBranch
261    *        If true the value will be read from the default branch (optional)
262    * @param {string} interfaceType
263    *        Interface to use for the complex value (optional)
264    *        (nsILocalFile, nsISupportsString, nsIPrefLocalizedString)
265    *
266    * @return The value of the requested preference
267    * @type boolean/int/string/complex
268    */
269   getPref : function preferences_getPref(prefName, defaultValue, defaultBranch,
270                                          interfaceType) {
271     try {
272       branch = defaultBranch ? this.defaultPrefBranch : this.prefBranch;
273
274       // If interfaceType has been set, handle it differently
275       if (interfaceType != undefined) {
276         return branch.getComplexValue(prefName, interfaceType);
277       }
278
279       switch (typeof defaultValue) {
280         case ('boolean'):
281           return branch.getBoolPref(prefName);
282         case ('string'):
283           return branch.getCharPref(prefName);
284         case ('number'):
285           return branch.getIntPref(prefName);
286         default:
287           return undefined;
288       }
289     } catch(e) {
290       return defaultValue;
291     }
292   },
293
294   /**
295    * Set the value of an individual preference.
296    *
297    * @param {string} prefName
298    *        The preference to set the value of.
299    * @param {boolean/number/string/complex} value
300    *        The value to set the preference to.
301    * @param {string} interfaceType
302    *        Interface to use for the complex value
303    *        (nsILocalFile, nsISupportsString, nsIPrefLocalizedString)
304    *
305    * @return Returns if the value was successfully set.
306    * @type boolean
307    */
308   setPref : function preferences_setPref(prefName, value, interfaceType) {
309     try {
310       switch (typeof value) {
311         case ('boolean'):
312           this.prefBranch.setBoolPref(prefName, value);
313           break;
314         case ('string'):
315           this.prefBranch.setCharPref(prefName, value);
316           break;
317         case ('number'):
318           this.prefBranch.setIntPref(prefName, value);
319           break;
320         default:
321           this.prefBranch.setComplexValue(prefName, interfaceType, value);
322       }
323     } catch(e) {
324       return false;
325     }
326
327     return true;
328   }
329 };
330
331 /**
332  * Open the preferences dialog and call the given handler
333  *
334  * @param {MozMillController} controller
335  *        MozMillController which is the opener of the preferences dialog
336  * @param {function} callback
337  *        The callback handler to use to interact with the preference dialog
338  * @param {function} launcher
339  *        (Optional) A callback handler to launch the preference dialog
340  */
341 function openPreferencesDialog(controller, callback, launcher) {
342   if (!controller)
343     throw new Error("No controller given for Preferences Dialog");
344   if (typeof callback != "function")
345     throw new Error("No callback given for Preferences Dialog");
346
347   if (mozmill.isWindows) {
348     // Preference dialog is modal on windows, set up our callback
349     var prefModal = new modalDialog.modalDialog(controller.window);
350     prefModal.start(callback);
351   }
352
353   // Launch the preference dialog
354   if (launcher) {
355     launcher();
356   } else {
357     mozmill.getPreferencesController();
358   }
359
360   if (mozmill.isWindows) {
361     prefModal.waitForDialog();
362   } else {
363     // Get the window type of the preferences window depending on the application
364     var prefWindowType = null;
365     switch (mozmill.Application) {
366       case "Thunderbird":
367         prefWindowType = "Mail:Preferences";
368         break;
369       default:
370         prefWindowType = "Browser:Preferences";
371     }
372
373     utils.handleWindow("type", prefWindowType, callback);
374   }
375 }
376
377 // Export of variables
378 exports.preferences = preferences;
379
380 // Export of functions
381 exports.openPreferencesDialog = openPreferencesDialog;
382
383 // Export of classes
384 exports.preferencesDialog = preferencesDialog;