home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Freeware / Miro 1.0 / Miro_Installer.exe / xulrunner / chrome / toolkit.jar / content / global / widgetStateManager.js < prev    next >
Encoding:
JavaScript  |  2005-02-01  |  17.3 KB  |  465 lines

  1. /* -*- Mode: Java; tab-width: 2; c-basic-offset: 2; -*-
  2.  * 
  3.  * ***** BEGIN LICENSE BLOCK *****
  4.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  5.  *
  6.  * The contents of this file are subject to the Mozilla Public License Version
  7.  * 1.1 (the "License"); you may not use this file except in compliance with
  8.  * the License. You may obtain a copy of the License at
  9.  * http://www.mozilla.org/MPL/
  10.  *
  11.  * Software distributed under the License is distributed on an "AS IS" basis,
  12.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13.  * for the specific language governing rights and limitations under the
  14.  * License.
  15.  *
  16.  * The Original Code is mozilla.org Code.
  17.  *
  18.  * The Initial Developer of the Original Code is
  19.  * Netscape Communications Corporation.
  20.  * Portions created by the Initial Developer are Copyright (C) 1998
  21.  * the Initial Developer. All Rights Reserved.
  22.  *
  23.  * Contributor(s):
  24.  *   Ben "Count XULula" Goodger <rgoodger@ihug.co.nz>
  25.  *   Alec Flett <alecf@netscape.com>
  26.  *
  27.  * Alternatively, the contents of this file may be used under the terms of
  28.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  29.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  30.  * in which case the provisions of the GPL or the LGPL are applicable instead
  31.  * of those above. If you wish to allow use of your version of this file only
  32.  * under the terms of either the GPL or the LGPL, and not to allow others to
  33.  * use your version of this file under the terms of the MPL, indicate your
  34.  * decision by deleting the provisions above and replace them with the notice
  35.  * and other provisions required by the GPL or the LGPL. If you do not delete
  36.  * the provisions above, a recipient may use your version of this file under
  37.  * the terms of any one of the MPL, the GPL or the LGPL.
  38.  *
  39.  * ***** END LICENSE BLOCK ***** */
  40.  
  41.  
  42. /** class WizardStateManager ( string frame_id, object pageMap )
  43.  *  - purpose: object for managing data in iframe multi-panel dialogs.
  44.  *  - in: string frame id/name set of iframe, pageMap showing navigation of wizard
  45.  *  - out: nothing (object)
  46.  **/
  47. function WidgetStateManager( frame_id, panelPrefix, panelSuffix )
  48. {
  49.   // data members
  50.   /**
  51.    *  hash table for data values:
  52.    *    page1  =>  id1  =>  value1
  53.    *    page1  =>  id2  =>  value2
  54.    *    page2  =>  id1  =>  value1
  55.    *    page2  =>  id2  =>  value2
  56.    **/
  57.   this.PageData          = [];
  58.   this.content_frame     = window.frames[frame_id];
  59.  
  60.   this.panelPrefix       = ( panelPrefix ) ? panelPrefix : null;
  61.   this.panelSuffix       = ( panelSuffix ) ? panelSuffix : null;
  62.   
  63.   // member functions
  64.   this.SavePageData      = WSM_SavePageData;
  65.   this.SetPageData       = WSM_SetPageData;
  66.   this.PageIsValid       = WSM_PageIsValid;
  67.   this.GetTagFromURL     = WSM_GetTagFromURL;
  68.   this.GetURLFromTag     = WSM_GetURLFromTag;
  69.   this.toString          = WSM_toString;
  70.   this.AddAttributes     = WSM_AddAttributes;
  71.   this.ElementIsIgnored  = WSM_ElementIsIgnored;
  72.   this.HasValidElements  = WSM_HasValidElements;
  73.   this.LookupElement     = WSM_LookupElement;
  74.   this.GetDataForTag     = WSM_GetDataForTag;
  75.   this.SetDataForTag     = WSM_SetDataForTag;
  76. }
  77.  
  78. /** void SavePageData() ;
  79.  *  - purpose: retrieves form/widget data from a generic page stored in a frame.
  80.  *  -          useful for retrieving and persisting wizard/prefs page data that
  81.  *  -          has not been added to permanent storage. 
  82.  *  -          for full reference, please refer to user manual at:
  83.  *  -            http://www.mozilla.org/xpapps/ui/wizards.html
  84.  *  - in:  nothing
  85.  *  - out: nothing
  86.  **/               
  87. function WSM_SavePageData( currentPageTag, optAttributes, exclElements, inclElements )
  88. {
  89.   // 11/26/99: changing this to support the saving of an optional number of extra
  90.   // attributes other than the default value. these attributes are specified as 
  91.   // strings in an array passed in as the second parameter. these values are stored
  92.   // in the table associated with the element:
  93.   // 
  94.   // this.wsm.PageData[pageTag][element][id]    - id of element       (default)
  95.   // this.wsm.PageData[pageTag][element][value] - value of element    (default)
  96.   // this.wsm.PageData[pageTag][element][foo]   - optional attribute  (default)
  97.   // 11/27/99: changing this to support the exclusion of specified elements.
  98.   // typically this is includes fieldsets, legends and labels. These are default
  99.   // and do not need to be passed. 
  100.   
  101.   if( !currentPageTag )
  102.     currentPageTag = this.GetTagFromURL( this.content_frame.location.href, this.panelPrefix, this.panelSuffix, true );
  103.   
  104.   var doc = this.content_frame.document;
  105.   var thisTagData = this.GetDataForTag(currentPageTag);
  106.  
  107.   if( this.content_frame.GetFields ) {
  108.     // user GetFields function
  109.     this.SetDataForTag(currentPageTag, this.content_frame.GetFields());
  110.     var string = "";
  111.     for( var i in thisTagData )
  112.     {
  113.       string += "element: " + i + "\n";
  114.     }
  115.   }
  116.   else if (doc && doc.controls) {
  117.     var fields = doc.controls;
  118.     var data = [];
  119.     for( i = 0; i < fields.length; i++ ) 
  120.     { 
  121.       data[i] = []; 
  122.       var formElement = fields[i];
  123.       var elementEntry = thisTagData[formElement.id] = [];
  124.  
  125.       // check to see if element is excluded
  126.       if( !this.ElementIsIgnored( formElement, exclElements ) )
  127.         elementEntry.excluded = false;
  128.       else 
  129.         elementEntry.excluded = true;
  130.  
  131.       if( formElement.localName.toLowerCase() == "select" ) { // select & combo
  132.         /* commenting out until select fields work properly, or someone tells me how
  133.            to do this (also, is it better to store .value, or .text?):*/
  134.           if( formElement.getAttribute("multiple") ) {
  135.             // multiple selections
  136.             for( var j = 0, idx = 0; j < formElement.options.length; j++ )
  137.             {
  138.               if( formElement.options[j].selected ) {
  139.                 elementEntry.value[idx] = formElement.options[j].value;
  140.                 idx++;
  141.               }
  142.             }
  143.           }
  144.           else {
  145.               // single selections
  146.               if (formElement.options[formElement.selectedIndex]) {
  147.                   var value = formElement.options[formElement.selectedIndex].value;
  148.                   dump("*** VALUE=" + value + "\n");
  149.                   formElement.arbitraryvalue = value;
  150.                   this.AddAttributes( formElement, elementEntry, "arbitraryvalue", optAttributes );
  151.                   this.AddAttributes( formElement, elementEntry, "value", optAttributes);
  152.               }
  153.           }
  154.       }
  155.       else if( formElement.getAttribute("type") &&
  156.                ( formElement.type.toLowerCase() == "checkbox" ||
  157.                  formElement.type.toLowerCase() == "radio" ) ) {
  158.         // XXX 11/04/99
  159.         this.AddAttributes( formElement, elementEntry, "checked", optAttributes );
  160.       }
  161.       else if( formElement.type == "text" &&
  162.                formElement.getAttribute( "datatype" ) == "nsIFileSpec" &&
  163.                formElement.value ) {
  164.         try {
  165.           var filespec = Components.classes["@mozilla.org/filespec;1"].createInstance();
  166.           filespec = filespec.QueryInterface( Components.interfaces.nsIFileSpec );
  167.         }
  168.         catch(e) {
  169.           dump("*** Failed to create filespec object\n");
  170.         }
  171.         filespec.nativePath = formElement.value;
  172.         this.AddAttributes( formElement, elementEntry, "filespec", optAttributes )
  173.       }
  174.       else
  175.         this.AddAttributes( formElement, elementEntry, "value", optAttributes );  // generic
  176.  
  177.       elementEntry.id       = formElement.id;
  178.       elementEntry.localName = formElement.localName;
  179.       // save the type attribute on the element if one is present
  180.       elementEntry.elType   = ( formElement.type ) ? formElement.type : null;
  181.     }
  182.   }
  183.   if( !this.HasValidElements( thisTagData ) )
  184.     thisTagData.noData = true; // page has no (valid) elements
  185. }
  186.  
  187. /** void SetPageData() ;
  188.  *  - purpose: populates the loaded page with appropriate data from the data 
  189.  *  -          table.
  190.  *  -          for full reference, please refer to user manual at:
  191.  *  -            http://www.mozilla.org/xpapps/ui/wizards.html
  192.  *  - in:  nothing.
  193.  *  - out: nothing.
  194.  **/
  195. function WSM_SetPageData( currentPageTag, hasExtraAttributes )
  196. {
  197.   if( !currentPageTag )
  198.     currentPageTag = this.GetTagFromURL( this.content_frame.location.href, this.panelPrefix, this.panelSuffix, true );
  199.   
  200.     var doc = this.content_frame.document;
  201.   var thisTagData = this.GetDataForTag(currentPageTag);
  202.   if ( thisTagData && !thisTagData.nodata) {
  203.       for( var i in thisTagData ) {
  204.       if( thisTagData[i].excluded || !i )
  205.         continue;     // element is excluded, goto next
  206.      
  207.       var id    = thisTagData[i].id;
  208.       var value = thisTagData[i].value;
  209.  
  210.       dump("*** id & value: " + id + " : " + value + "\n");
  211.       
  212.       if( this.content_frame.SetFields && !hasExtraAttributes )
  213.         this.content_frame.SetFields( id, value );  // user provided setfields
  214.       else if( this.content_frame.SetFields && hasExtraAttributes )
  215.         this.content_frame.SetFields( id, value, thisTagData[i]); // SetFields + attrs
  216.       else {                              // automated data provision
  217.         var formElement = doc.getElementById( i );
  218.         
  219.         if( formElement && hasExtraAttributes ) {        // if extra attributes are set, set them
  220.           for( var attName in thisTagData[i] ) 
  221.           {
  222.             // for each attribute set for this element
  223.             if( attName == "value" || attName == "id" )
  224.               continue;                   // don't set value/id (value = default, id = dangerous)
  225.             var attValue  = thisTagData[i][attName];
  226.             formElement.setAttribute( attName, attValue );
  227.           }
  228.         }
  229.         
  230.         // default "value" attributes        
  231.         if( formElement && formElement.localName.toLowerCase() == "input" ) {
  232.           if( formElement.type.toLowerCase() == "checkbox" ||
  233.               formElement.type.toLowerCase() == "radio" ) {
  234.             if( value == undefined )
  235.               formElement.checked = formElement.defaultChecked;
  236.             else 
  237.               formElement.checked = value;
  238. /*            oops.. appears we've reimplemented 'reversed'. this will be why its not working for alecf. 
  239.               if( formElement.getAttribute( "reversed" ) )
  240.                 formElement.checked = !value;
  241.               else
  242.                 formElement.checked = value;
  243.                 */
  244.           }
  245.           else if( formElement.type.toLowerCase() == "text" &&
  246.                formElement.getAttribute( "datatype" ) == "nsIFileSpec" ) {
  247.             // formElement has something to do with fileSpec. looked important
  248.             if( value ) {
  249.               var filespec = value.QueryInterface( Components.interfaces.nsIFileSpec );
  250.               try {
  251.                 formElement.value = filespec.nativePath;
  252.               } 
  253.               catch( ex ) {
  254.                 dump("Still need to fix uninitialized filespec problem!\n");
  255.               }
  256.             } 
  257.             else
  258.               formElement.value = formElement.defaultValue;
  259.           }
  260.           else {                          // some other type of form element
  261.             if( value == undefined )
  262.               formElement.value = formElement.defaultValue;
  263.             else
  264.               formElement.value = value;
  265.           }
  266.         } 
  267.         else if( formElement && formElement.localName.toLowerCase() == "select" ) {
  268.           /* commenting this out until select widgets work properly */
  269.             if( formElement.getAttribute("multiple") &&
  270.                 typeof(value) == "object" ) {
  271.               // multiple selected items
  272.               for( var j = 0; j < value.length; j++ )
  273.               {
  274.                 for ( var k = 0; k < formElement.options.length; k++ )
  275.                 {
  276.                   if( formElement.options[k].value == value[j] )
  277.                     formElement.options[k].selected = true;
  278.                 }
  279.               }
  280.             }
  281.             else {
  282.               // single selected item
  283.               for ( k = 0; k < formElement.options.length; k++ )
  284.               {
  285.                 dump("*** value=" + value + "; options[k].value=" + formElement.options[k].value + "\n");
  286.                 if( formElement.options[k].value == value )
  287.                   formElement.options[k].selected = true;
  288.               }
  289.             }            
  290.         }
  291.         else if( formElement && formElement.localName.toLowerCase() == "textarea" )
  292.           formElement.value = value;
  293.       }
  294.     }
  295.   }
  296.   // initialize the pane
  297.   if (this.content_frame.onInit) {
  298.     dump("Calling custom onInit()\n");
  299.     this.content_frame.onInit();
  300.   }
  301.     
  302. }   
  303.  
  304. /** boolean PageIsValid()
  305.  * - purpose: returns whether the given page is in a valid state
  306.  * - in:
  307.  * - out: 
  308.  */
  309. function WSM_PageIsValid()
  310. {
  311.   if( this.content_frame.validate )
  312.     return this.content_frame.validate();
  313.  
  314.   // page is valid by default
  315.   return true;
  316. }
  317.  
  318.  
  319. /** string GetTagFromURL( string tag, string prefix, string postfix ) ;
  320.  *  - purpose: fetches a tag from a URL
  321.  *  - in:   string url representing the complete location of the page.
  322.  *  - out:  string tag representing the specific page to be loaded
  323.  **/               
  324. function WSM_GetTagFromURL( url, prefix, suffix, mode )
  325. {
  326.   // NOTE TO SELF: this is an accident WAITING to happen
  327.   if (!prefix) return undefined;
  328.   if( mode )
  329.     return url.substring( prefix.length, url.lastIndexOf(suffix) );
  330.   else
  331.     return url.substring( url.lastIndexOf(prefix) + 1, url.lastIndexOf(suffix) );
  332. }
  333.  
  334. /** string GetUrlFromTag( string tag, string prefix, string postfix ) ;
  335.  *  - purpose: creates a complete URL based on a tag.
  336.  *  - in:  string tag representing the specific page to be loaded
  337.  *  - out: string url representing the complete location of the page.
  338.  **/               
  339. function WSM_GetURLFromTag( tag, prefix, postfix ) 
  340. {
  341.   return prefix + tag + postfix;
  342. }
  343.  
  344. /** string toString() ;
  345.  *  - purpose: returns a string representation of the object
  346.  *  - in: nothing;
  347.  *  - out: nothing;
  348.  **/
  349. function WSM_toString()
  350. {
  351.   var string = "";
  352.   for( var i in this.PageData ) {
  353.     for( var j in this.PageData[i] ) {
  354.       for( var k in this.PageData[i][j] ) {
  355.         string += "WSM.PageData[" + i + "][" + j + "][" + k + "] : " + this.PageData[i][j][k] + ";\n";
  356.       }
  357.     }
  358.   }
  359.   return string;
  360. }
  361.  
  362. /** void AddAttributes( DOMElement formElement, AssocArray elementEntry, 
  363.                         String valueAttribute, StringArray optAttributes ) ;
  364.  *  - purpose: adds name/value entries to associative array.
  365.  *  - in:       formElement - element to add attributes from
  366.  *  -           elementEntry - the associative array to add data to
  367.  *  -           valueAttribute - string representing which attribute represents 
  368.  *  -               value (e.g. "value", "checked")
  369.  *  -           optAttributes - array of extra attributes to store. 
  370.  *  - out: nothing;
  371.  **/
  372. function WSM_AddAttributes( formElement, elementEntry, valueAttribute, optAttributes )
  373. {
  374.   // 07/01/00 adding in a reversed thing here for alecf's ultra picky mail prefs :P:P
  375.   if( formElement.getAttribute("reversed") )
  376.     elementEntry.value = !formElement[valueAttribute]; // get the value (e.g. "checked")
  377.   else
  378.     elementEntry.value = formElement[valueAttribute]; // get the value (e.g. "checked")
  379.   
  380.   if( optAttributes ) {   // if we've got optional attributes, add em
  381.     for(var k = 0; k < optAttributes.length; k++ ) 
  382.     {
  383.       attValue = formElement.getAttribute( optAttributes[k] );
  384.       if( attValue )
  385.         elementEntry[optAttributes[k]] = attValue;
  386.     }
  387.   }
  388. }
  389.  
  390. /** string ElementIsIgnored( DOMElement element, StringArray exclElements ) ;
  391.  *  - purpose: check to see if the current element is one of the ignored elements
  392.  *  - in:       element - element to check, 
  393.  *  -           exclElements - array of string ignored attribute localNames;
  394.  *  - out:      boolean if element is ignored (true) or not (false);
  395.  **/
  396. function WSM_ElementIsIgnored( element, exclElements )
  397. {
  398.   if (!exclElements) return false;
  399.   for( var i = 0; i < exclElements.length; i++ )
  400.   {
  401.     if( element.localName.toLowerCase() == exclElements[i] )
  402.       return true;
  403.   }
  404.   return false;
  405. }
  406.  
  407. /** string HasValidElements( AssocArray dataStore ) ;
  408.  *  - purpose:  checks to see if there are any elements on this page that are 
  409.  *  -           valid.
  410.  *  - in:       associative array representing the page;
  411.  *  - out:      boolean whether or not valid elements are present (true) or not (false);
  412.  **/
  413. function WSM_HasValidElements( dataStore )
  414. {
  415.   for( var i in dataStore ) 
  416.   {
  417.     if( !dataStore[i].excluded )
  418.       return true;
  419.   }
  420.   return false;
  421. }
  422.  
  423.  
  424. function WSM_LookupElement( element, lookby, property )
  425. {
  426.   for(var i in this.PageData )
  427.   {
  428.     for( var j in this.PageData[i] )
  429.     {
  430.       if(!lookby) 
  431.         lookby = "id";    // search by id by default
  432.       if( j[lookby] == element && !property )
  433.         return j;
  434.       else if( j[lookby] == element ) {
  435.         var container = [];
  436.         for( var k = 0; k < property.length; k++ )
  437.         {
  438.           container[k] = this.PageData[i][k][property[k]];
  439.         }
  440.         return container; // only support one single match per hash just now
  441.       }
  442.     }
  443.   }
  444.   return undefined;
  445. }
  446.  
  447. /**
  448.  * array GetDataForTag(string tag)
  449.  * - purpose: to get the array associated with this tag
  450.  *            creates the array if one doesn't already exist
  451.  * - in:      tag
  452.  * - out:     the associative array for this page
  453.  */
  454. function WSM_GetDataForTag(tag) {
  455.   if (!this.PageData[tag])
  456.     this.PageData[tag] = [];
  457.   return this.PageData[tag];
  458. }
  459.  
  460. function WSM_SetDataForTag(tag, data) {
  461.   this.PageData[tag] = data;
  462. }
  463.  
  464. /* it will be dark soon */
  465.