home *** CD-ROM | disk | FTP | other *** search
/ Freelog 112 / FreelogNo112-NovembreDecembre2012.iso / Multimedia / Songbird / Songbird_2.0.0-2311_windows-i686-msvc8.exe / jsmodules / WindowUtils.jsm < prev   
Text File  |  2012-06-08  |  20KB  |  604 lines

  1. /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* vim: set sw=2 :miv */
  3. /*
  4. //
  5. // BEGIN SONGBIRD GPL
  6. //
  7. // This file is part of the Songbird web player.
  8. //
  9. // Copyright(c) 2005-2009 POTI, Inc.
  10. // http://songbirdnest.com
  11. //
  12. // This file may be licensed under the terms of of the
  13. // GNU General Public License Version 2 (the "GPL").
  14. //
  15. // Software distributed under the License is distributed
  16. // on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
  17. // express or implied. See the GPL for the specific language
  18. // governing rights and limitations.
  19. //
  20. // You should have received a copy of the GPL along with this
  21. // program. If not, go to http://www.gnu.org/licenses/gpl.html
  22. // or write to the Free Software Foundation, Inc.,
  23. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  24. //
  25. // END SONGBIRD GPL
  26. //
  27. */
  28.  
  29. /**
  30.  * \file  WindowUtils.jsm
  31.  * \brief Javascript source for the window utility services.
  32.  */
  33.  
  34. //------------------------------------------------------------------------------
  35. //
  36. // Window utility JSM configuration.
  37. //
  38. //------------------------------------------------------------------------------
  39.  
  40. EXPORTED_SYMBOLS = ["WindowUtils"];
  41.  
  42.  
  43. //------------------------------------------------------------------------------
  44. //
  45. // Window utility imported services.
  46. //
  47. //------------------------------------------------------------------------------
  48.  
  49. Components.utils.import("resource://app/jsmodules/DOMUtils.jsm");
  50. Components.utils.import("resource://app/jsmodules/SBDataRemoteUtils.jsm");
  51. Components.utils.import("resource://app/jsmodules/SBUtils.jsm");
  52. Components.utils.import("resource://app/jsmodules/StringUtils.jsm");
  53.  
  54.  
  55. //------------------------------------------------------------------------------
  56. //
  57. // Window utility defs.
  58. //
  59. //------------------------------------------------------------------------------
  60.  
  61. const Cc = Components.classes;
  62. const Ci = Components.interfaces;
  63. const Cr = Components.results
  64.  
  65.  
  66. //------------------------------------------------------------------------------
  67. //
  68. // Window utility services.
  69. //
  70. //------------------------------------------------------------------------------
  71.  
  72. var WindowUtils = {
  73.   /**
  74.    * \brief Open the modal dialog specified by aURL.  The parent window of the
  75.    *        dialog is specified by aParent.  The name of the dialog is specified
  76.    *        by aName.  The dialog options are specified by aOptions.  Pass the
  77.    *        arguments specified by the array aInArgs in an nsIDialogParamBlock
  78.    *        to the dialog.  The arguments may be strings or nsISupports.
  79.    *        Strings may be specified as locale string bundle keys.  In addition,
  80.    *        if an array of strings is specified as an argument, the first string
  81.    *        is the locale key for a formatted string, and the remaining strings
  82.    *        are the format arguments.  Strings are interpreted as locale keys if
  83.    *        they're wrapped in "&;" (e.g., "&local.string;"); otherwise, they're
  84.    *        interpreted as literal strings.
  85.    *        Set the value field of the objects within the array aOutArgs to the
  86.    *        arguments returned by the dialog.
  87.    *        A locale string bundle may be optionally specified by aLocale.  If
  88.    *        one is not specified, the Songbird locale bundle is used.
  89.    *        Return true if the dialog was accepted.
  90.    *
  91.    * \param aParent             Dialog parent window.
  92.    * \param aURL                URL of dialog chrome.
  93.    * \param aName               Dialog name.
  94.    * \param aOptions            Dialog options.
  95.    * \param aInArgs             Array of arguments passed into dialog.
  96.    * \param aOutArgs            Array of argments returned from dialog.
  97.    * \param aLocale             Optional locale string bundle.
  98.    *
  99.    * \return                    True if dialog accepted.
  100.    */
  101.  
  102.   openModalDialog: function WindowUtils_openModalDialog(aParent,
  103.                                                         aURL,
  104.                                                         aName,
  105.                                                         aOptions,
  106.                                                         aInArgs,
  107.                                                         aOutArgs,
  108.                                                         aLocale) {
  109.     return this.openDialog(aParent,
  110.                            aURL,
  111.                            aName,
  112.                            aOptions,
  113.                            true,
  114.                            aInArgs,
  115.                            aOutArgs,
  116.                            aLocale);
  117.   },
  118.  
  119.  
  120.   /**
  121.    * \brief Open the dialog specified by aURL.  The parent window of the
  122.    *        dialog is specified by aParent.  The name of the dialog is specified
  123.    *        by aName.  The dialog options are specified by aOptions.  Pass the
  124.    *        arguments specified by the array aInArgs in an nsIDialogParamBlock
  125.    *        to the dialog.  The arguments may be strings or nsISupports.
  126.    *        Strings may be specified as locale string bundle keys.  In addition,
  127.    *        if an array of strings is specified as an argument, the first string
  128.    *        is the locale key for a formatted string, and the remaining strings
  129.    *        are the format arguments.  Strings are interpreted as locale keys if
  130.    *        they're wrapped in "&;" (e.g., "&local.string;"); otherwise, they're
  131.    *        interpreted as literal strings.
  132.    *        Set the value field of the objects within the array aOutArgs to the
  133.    *        arguments returned by the dialog.
  134.    *        A locale string bundle may be optionally specified by aLocale.  If
  135.    *        one is not specified, the Songbird locale bundle is used.
  136.    *        Return true if the dialog was accepted.
  137.    *
  138.    * \param aParent             Dialog parent window.
  139.    * \param aURL                URL of dialog chrome.
  140.    * \param aName               Dialog name.
  141.    * \param aOptions            Dialog options.
  142.    * \param aModal              True if the dialog should be modal
  143.    * \param aInArgs             Array of arguments passed into dialog.
  144.    * \param aOutArgs            Array of argments returned from dialog.
  145.    * \param aLocale             Optional locale string bundle.
  146.    *
  147.    * \return                    True if dialog accepted.
  148.    */
  149.  
  150.   openDialog: function WindowUtils_openDialog(aParent,
  151.                                               aURL,
  152.                                               aName,
  153.                                               aOptions,
  154.                                               aModal,
  155.                                               aInArgs,
  156.                                               aOutArgs,
  157.                                               aLocale) {
  158.     // Set the dialog arguments.
  159.     var dialogPB = null;
  160.     if (aInArgs)
  161.       dialogPB = this._setArgs(aInArgs, aLocale);
  162.  
  163.     // Get the options.
  164.     var options = aOptions.split(",");
  165.  
  166.     // Add options for a dialog.
  167.     options.push("dialog");
  168.     if (aModal) {
  169.       options.push("modal=yes");
  170.     }
  171.     options.push("resizable=no");
  172.  
  173.     // Set accessibility options.
  174.     if (SBDataGetBoolValue("accessibility.enabled"))
  175.       options.push("titlebar=yes");
  176.     else
  177.       options.push("titlebar=no");
  178.  
  179.     // Convert options back to a string.
  180.     options = options.join(",");
  181.  
  182.     // Create a dialog watcher.
  183.     var dialogWatcher = new sbDialogWatcher();
  184.  
  185.     // Open the dialog and check for acceptance.
  186.     var prompter = Cc["@songbirdnest.com/Songbird/Prompter;1"]
  187.                      .createInstance(Ci.sbIPrompter);
  188.     var window = prompter.openDialog(aParent, aURL, aName, options, dialogPB);
  189.     var accepted = dialogWatcher.getAccepted(window);
  190.  
  191.     // Finalize the dialog watcher.
  192.     dialogWatcher.finalize();
  193.  
  194.     // Get the dialog arguments.
  195.     if (aOutArgs)
  196.       this._getArgs(dialogPB, aOutArgs);
  197.  
  198.     return accepted;
  199.   },
  200.  
  201.  
  202.   /**
  203.    * Invoke sizeToContent on the window specified by aWindow with workarounds
  204.    * for the following bugs:
  205.    *
  206.    *   https://bugzilla.mozilla.org/show_bug.cgi?id=230959
  207.    *   http://bugzilla.songbirdnest.com/show_bug.cgi?id=20969.
  208.    *
  209.    * \param aWindow             Window to size to content.
  210.    */
  211.  
  212.   sizeToContent: function WindowUtils_sizeToContent(aWindow) {
  213.     // Don't resize if not needed.
  214.     // See https://bugzilla.mozilla.org/show_bug.cgi?id=230959
  215.     if ((aWindow.innerHeight >= 10) &&
  216.         (aWindow.innerHeight ==
  217.          aWindow.document.documentElement.boxObject.height)) {
  218.       return;
  219.     }
  220.  
  221.     // Defer resizing until after the current event completes.
  222.     // See http://bugzilla.songbirdnest.com/show_bug.cgi?id=20969.
  223.     SBUtils.deferFunction(function() { aWindow.sizeToContent(); });
  224.   },
  225.  
  226.  
  227.   /**
  228.    * \brief Attempt to restart the application.
  229.    */
  230.  
  231.   restartApp: function WindowUtils_restartApp() {
  232.     // Notify all windows that an application quit has been requested.
  233.     var os = Cc["@mozilla.org/observer-service;1"]
  234.                .getService(Ci.nsIObserverService);
  235.     var cancelQuit = Cc["@mozilla.org/supports-PRBool;1"]
  236.                        .createInstance(Ci.nsISupportsPRBool);
  237.     os.notifyObservers(cancelQuit, "quit-application-requested", "restart");
  238.  
  239.     // Something aborted the quit process.
  240.     if (cancelQuit.data)
  241.       return;
  242.  
  243.     // attempt to restart
  244.     var as = Cc["@mozilla.org/toolkit/app-startup;1"]
  245.                .getService(Ci.nsIAppStartup);
  246.     as.quit(Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eAttemptQuit);
  247.   },
  248.  
  249.  
  250.   /**
  251.    * \brief Create and return a dialog parameter block set with the arguments
  252.    *        contained in the array specified by aArgs.  Look up string arguments
  253.    *        as keys in the locale string bundle specified by aLocale; use the
  254.    *        Songbird locale string bundle if aLocale is not specified.
  255.    *
  256.    * \param aArgs               Array of dialog arguments to set.
  257.    * \param aLocale             Optional locale string bundle.
  258.    */
  259.  
  260.   _setArgs: function WindowUtils__setArgs(aArgs, aLocale) {
  261.     // If |aArgs| is already a |nsIArray|, just use it instead.
  262.     if (aArgs instanceof Ci.nsIArray) {
  263.       return aArgs;
  264.     }
  265.     
  266.     // Get a dialog param block.
  267.     var dialogPB = Cc["@mozilla.org/embedcomp/dialogparam;1"]
  268.                      .createInstance(Ci.nsIDialogParamBlock);
  269.  
  270.     /* Put arguments into param block. */
  271.     var stringArgNum = 0;
  272.     for (var i = 0; i < aArgs.length; i++) {
  273.       // Get the next argument.
  274.       var arg = aArgs[i];
  275.  
  276.       // If arg is an nsISupports, add it to the objects field.  Otherwise, add
  277.       // it to the string list.
  278.       if (arg instanceof Ci.nsISupports) {
  279.         if (!dialogPB.objects) {
  280.           dialogPB.objects = Cc["@songbirdnest.com/moz/xpcom/threadsafe-array;1"]
  281.                                .createInstance(Ci.nsIMutableArray);
  282.         }
  283.         dialogPB.objects.appendElement(arg, false);
  284.       } else {
  285.         dialogPB.SetString(stringArgNum, this._getArgString(arg, aLocale));
  286.         stringArgNum++;
  287.       }
  288.     }
  289.  
  290.     return dialogPB;
  291.   },
  292.  
  293.  
  294.   /**
  295.    * \brief Get the dialog arguments from the parameter block specified by
  296.    *        aDialogPB and return them in the value field of the objects within
  297.    *        the array specified by aArgs.
  298.    *
  299.    * \param aDialogPB           Dialog parameter block.
  300.    * \param aArgs               Array of dialog arguments to get.
  301.    */
  302.  
  303.   _getArgs: function WindowUtils__getArgs(aDialogPB, aArgs) {
  304.     // Get arguments from param block.
  305.     for (var i = 0; i < aArgs.length; i++)
  306.         aArgs[i].value = aDialogPB.GetString(i);
  307.   },
  308.  
  309.  
  310.   /**
  311.    * \brief Parse the argument specified by aArg and return a formatted,
  312.    *        localized string using the locale string bundle specified by
  313.    *        aLocale.  If aLocale is not specified, use the Songbird locale
  314.    *        string bundle.
  315.    *
  316.    * \param aArg                Argument to parse.
  317.    * \param aLocale             Optional locale string bundle.
  318.    *
  319.    * \return                    Formatted, localized string.
  320.    */
  321.  
  322.   _getArgString: function WindowUtils__getArgString(aArg, aLocale) {
  323.     if (aArg instanceof Array) {
  324.       var localeKeyMatch = aArg[0].match(/^&(.*);$/);
  325.       return SBFormattedString(localeKeyMatch[1], aArg.slice(1), null, aLocale);
  326.     }
  327.     else {
  328.       var localeKeyMatch = aArg.match(/^&(.*);$/);
  329.       if (localeKeyMatch)
  330.         return SBString(localeKeyMatch[1], null, aLocale);
  331.       else
  332.         return aArg;
  333.     }
  334.   }
  335. };
  336.  
  337.  
  338. //------------------------------------------------------------------------------
  339. //------------------------------------------------------------------------------
  340. //
  341. // Dialog watcher services.
  342. //
  343. //   These service provide support for watching dialog windows and determining
  344. // whether a dialog was accepted.
  345. //
  346. //------------------------------------------------------------------------------
  347. //------------------------------------------------------------------------------
  348.  
  349. /**
  350.  * Construct a dialog watcher object.
  351.  */
  352.  
  353. function sbDialogWatcher() {
  354.   this.initialize();
  355. }
  356.  
  357. // Define the object.
  358. sbDialogWatcher.prototype = {
  359.   // Set the constructor.
  360.   constructor: sbDialogWatcher,
  361.  
  362.   //
  363.   // Dialog watcher fields.
  364.   //
  365.   //   _windowInfoList          List of information about windows being watched.
  366.   //   _windowWatcher           Window watcher services.
  367.   //
  368.  
  369.   _windowInfoList: null,
  370.   _windowWatcher: null,
  371.  
  372.  
  373.   //----------------------------------------------------------------------------
  374.   //
  375.   // Dialog watcher services.
  376.   //
  377.   //----------------------------------------------------------------------------
  378.  
  379.   /**
  380.    * Initialize the dialog watcher services.  This is called automatically from
  381.    * the dialog watcher constructor.
  382.    */
  383.  
  384.   initialize: function sbDialogWatcher_initialize() {
  385.     // Initialize the watched window info list.
  386.     this._windowInfoList = [];
  387.  
  388.     // Register for window notifications.
  389.     this._windowWatcher = Cc["@mozilla.org/embedcomp/window-watcher;1"]
  390.                             .getService(Ci.nsIWindowWatcher);
  391.     this._windowWatcher.registerNotification(this);
  392.   },
  393.  
  394.  
  395.   /**
  396.    * Finalize the dialog watcher services.
  397.    */
  398.  
  399.   finalize: function sbDialogWatcher_finalize() {
  400.     // Unregister for window notifications.
  401.     this._windowWatcher.unregisterNotification(this);
  402.  
  403.     // Remove all windows.
  404.     this._removeAllWindows();
  405.  
  406.     // Clear object fields.
  407.     this._windowWatcher = null;
  408.   },
  409.  
  410.  
  411.   /**
  412.    * Return true if the dialog with the window specified by aWindow was
  413.    * accepted.
  414.    *
  415.    * \param aWindow             Window for which to check for acceptance.
  416.    *
  417.    * \return                    True if the dialog was accepted.
  418.    */
  419.  
  420.   getAccepted: function sbDialogWatcher_getAccepted(aWindow) {
  421.     // Get the window info.
  422.     var windowInfo = this._getWindowInfo(aWindow);
  423.  
  424.     return windowInfo ? windowInfo.accepted : false;
  425.   },
  426.  
  427.  
  428.   //----------------------------------------------------------------------------
  429.   //
  430.   // Dialog watcher nsIObserver services.
  431.   //
  432.   //----------------------------------------------------------------------------
  433.  
  434.   /**
  435.    * Handle the observed event specified by aSubject, aTopic, and aData.
  436.    *
  437.    * \param aSubject            Event subject.
  438.    * \param aTopic              Event topic.
  439.    * \param aData               Event data.
  440.    */
  441.  
  442.   observe: function sbDialogWatcher_observe(aSubject, aTopic, aData) {
  443.     switch (aTopic) {
  444.       case "domwindowopened" :
  445.         this._addWindow(aSubject);
  446.         break;
  447.  
  448.       case "domwindowclosed" :
  449.         this._doWindowClosed(aSubject);
  450.         break;
  451.  
  452.       default :
  453.         break;
  454.     }
  455.   },
  456.  
  457.  
  458.   //----------------------------------------------------------------------------
  459.   //
  460.   // Dialog watcher event services.
  461.   //
  462.   //----------------------------------------------------------------------------
  463.  
  464.   /**
  465.    * Handle the load event for the window specified by aWindowInfo.
  466.    *
  467.    * \param aWindowInfo         Window info pertaining to the load event.
  468.    */
  469.  
  470.   _doLoad: function sbDialogWatcher__doLoad(aWindowInfo) {
  471.     var _this = this;
  472.     var func;
  473.  
  474.     // Listen for accept and cancel events.
  475.     var documentElement = aWindowInfo.window.document.documentElement;
  476.     func = function() { _this._doAccept(aWindowInfo); };
  477.     aWindowInfo.domEventListenerSet.add(documentElement,
  478.                                         "dialogaccept",
  479.                                         func,
  480.                                         false);
  481.     func = function() { _this._doCancel(aWindowInfo); };
  482.     aWindowInfo.domEventListenerSet.add(documentElement,
  483.                                         "dialogcancel",
  484.                                         func,
  485.                                         false);
  486.   },
  487.  
  488.  
  489.   /**
  490.    * Handle the window closed event for the window specified by aWindow.
  491.    *
  492.    * \param aWindow             Window pertaining to the closed event.
  493.    */
  494.  
  495.   _doWindowClosed: function sbDialogWatcher__doWindowClosed(aWindow) {
  496.     // Get the window info.  Do nothing if no window info.
  497.     var windowInfo = this._getWindowInfo(aWindow);
  498.     if (!windowInfo)
  499.       return;
  500.  
  501.     // Remove DOM event listeners.
  502.     windowInfo.domEventListenerSet.removeAll();
  503.     windowInfo.domEventListenerSet = null;
  504.   },
  505.  
  506.  
  507.   /**
  508.    * Handle the accept event for the window specified by aWindowInfo.
  509.    *
  510.    * \param aWindowInfo         Window info pertaining to the accept event.
  511.    */
  512.  
  513.   _doAccept: function sbDialogWatcher__doAccept(aWindowInfo) {
  514.     // Set the window as accepted.
  515.     aWindowInfo.accepted = true;
  516.   },
  517.  
  518.  
  519.   /**
  520.    * Handle the cancel event for the window specified by aWindowInfo.
  521.    *
  522.    * \param aWindowInfo         Window info pertaining to the cancel event.
  523.    */
  524.  
  525.   _doCancel: function sbDialogWatcher__doCancel(aWindowInfo) {
  526.     // Set the window as not accepted.
  527.     aWindowInfo.accepted = false;
  528.   },
  529.  
  530.  
  531.   //----------------------------------------------------------------------------
  532.   //
  533.   // Internal dialog watcher services.
  534.   //
  535.   //----------------------------------------------------------------------------
  536.  
  537.   /**
  538.    * Add the window specified by aWindow to the list of windows being watched.
  539.    *
  540.    * \param aWindow             Window to add.
  541.    */
  542.  
  543.   _addWindow: function sbDialogWatcher__addWindow(aWindow) {
  544.     // Do nothing if window has already been added.
  545.     if (this._getWindowInfo(aWindow))
  546.       return;
  547.  
  548.     // Add window to window list.
  549.     var windowInfo = { window: aWindow, accepted: false };
  550.     this._windowInfoList.push(windowInfo);
  551.  
  552.     // Create a window DOM event listener set.
  553.     windowInfo.domEventListenerSet = new DOMEventListenerSet();
  554.  
  555.     // Listen once for window load events.
  556.     var _this = this;
  557.     var func = function() { _this._doLoad(windowInfo); };
  558.     windowInfo.domEventListenerSet.add(aWindow, "load", func, false, true);
  559.   },
  560.  
  561.  
  562.   /**
  563.    * Remove all windows from the list of windows being watched.
  564.    */
  565.  
  566.   _removeAllWindows: function sbDialogWatcher__removeAllWindows() {
  567.     // Remove all windows.
  568.     for (var i = 0; i < this._windowInfoList.length; i++) {
  569.       // Get the window info.
  570.       var windowInfo = this._windowInfoList[i];
  571.  
  572.       // Remove window DOM event listeners.
  573.       if (windowInfo.domEventListenerSet) {
  574.         windowInfo.domEventListenerSet.removeAll();
  575.         windowInfo.domEventListenerSet = null;
  576.       }
  577.     }
  578.     this._windowInfoList = null;
  579.   },
  580.  
  581.  
  582.   /**
  583.    * Return the window info for the window specified by aWindow.
  584.    *
  585.    * \param aWindow             Window for which to return information.
  586.    *
  587.    * \retrurn                   Window information object.
  588.    */
  589.  
  590.   _getWindowInfo: function sbDialogWatcher__getWindowInfo(aWindow) {
  591.     // Find the window information.
  592.     var windowInfo = null;
  593.     for (var i = 0; i < this._windowInfoList.length; i++) {
  594.       if (this._windowInfoList[i].window == aWindow) {
  595.         windowInfo = this._windowInfoList[i];
  596.         break;
  597.       }
  598.     }
  599.  
  600.     return windowInfo;
  601.   }
  602. };
  603.  
  604.