home *** CD-ROM | disk | FTP | other *** search
/ ftp.swcp.com / ftp.swcp.com.zip / ftp.swcp.com / mac / mozilla-macos9-1.3.1.sea.bin / Mozilla1.3.1 / Chrome / comm.jar / content / communicator / pref / pref-languages.js < prev    next >
Text File  |  2003-06-08  |  15KB  |  579 lines

  1. /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2. *
  3. * The contents of this file are subject to the Mozilla Public
  4. * License Version 1.1 (the "License"); you may not use this file
  5. * except in compliance with the License. You may obtain a copy of
  6. * the License at http://www.mozilla.org/MPL/
  7. *
  8. * Software distributed under the License is distributed on an "AS
  9. * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  10. * implied. See the License for the specific language governing
  11. * rights and limitations under the License.
  12. *
  13. * The Original Code is mozilla.org code.
  14. *
  15. * The Initial Developer of the Original Code is Netscape Communications
  16. * Corporation.  Portions created by Netscape are
  17. * Copyright (C) 2000 Netscape Communications Corporation. All
  18. * Rights Reserved.
  19. *
  20. * Contributor(s):
  21. *   Adrian Havill <havill@redhat.com>
  22. */
  23.  
  24. //GLOBALS
  25.  
  26.  
  27. //locale bundles
  28. var regionsBundle;
  29. var languagesBundle;
  30. var acceptedBundle;
  31. var prefLangBundle;
  32.  
  33. //dictionary of all supported locales
  34. var availLanguageDict;
  35.  
  36. //XUL listbox handles
  37. var available_languages;
  38. var active_languages;
  39.  
  40. //XUL window pref window interface object
  41. var pref_string = new String();
  42.  
  43. //Reg expression for splitting multiple pref values
  44. var separatorRe = /\s*,\s*/;
  45.  
  46. function GetBundles()
  47. {
  48.   if (!regionsBundle)    regionsBundle   = srGetStrBundle("chrome://global/locale/regionNames.properties");
  49.   if (!languagesBundle)  languagesBundle = srGetStrBundle("chrome://global/locale/languageNames.properties");
  50.   if (!prefLangBundle)  prefLangBundle = srGetStrBundle("chrome://communicator/locale/pref/pref-languages.properties");
  51.   if (!acceptedBundle)   acceptedBundle  = srGetStrBundle("resource:/res/language.properties");
  52. }
  53.  
  54.  
  55. function Init()
  56. {
  57.   try {
  58.     GetBundles();
  59.   }
  60.  
  61.   catch(ex) {
  62.   }
  63.  
  64.   ReadAvailableLanguages();
  65.  
  66.   if (!("arguments" in window)) {
  67.  
  68.     //no caller arguments - load base window
  69.  
  70.     try {
  71.       active_languages              = document.getElementById('active_languages');
  72.     } //try
  73.  
  74.     catch(ex) {
  75.     } //catch
  76.  
  77.     try {
  78.       parent.initPanel('chrome://communicator/content/pref/pref-languages.xul');
  79.     }
  80.  
  81.     catch(ex) {
  82.       //pref service backup
  83.     } //catch
  84.  
  85.     pref_string = active_languages.getAttribute("prefvalue");
  86.     LoadActiveLanguages();
  87.     SelectLanguage();
  88.  
  89.   } else {
  90.  
  91.     //load available languages popup
  92.     try {
  93.  
  94.       //add language popup
  95.       available_languages           = document.getElementById('available_languages');
  96.       active_languages              = window.opener.document.getElementById('active_languages');
  97.       pref_string                   = window.opener.document.getElementById('intlAcceptLanguages').label;
  98.  
  99.     } //try
  100.  
  101.     catch(ex) {
  102.     } //catch
  103.  
  104.     LoadAvailableLanguages();
  105.   }
  106. }
  107.  
  108.  
  109. function AddLanguage()
  110. {
  111.     //cludge: make pref string available from the popup
  112.     document.getElementById('intlAcceptLanguages').label = pref_string;
  113.     window.openDialog("chrome://communicator/content/pref/pref-languages-add.xul","_blank","modal,chrome,centerscreen,resizable=yes,titlebar", "addlangwindow");
  114.     UpdateSavePrefString();
  115.     SelectLanguage();
  116. }
  117.  
  118.  
  119. function ReadAvailableLanguages()
  120. {
  121.  
  122.     availLanguageDict   = new Array();
  123.     var visible = new String();
  124.     var str = new String();
  125.     var i =0;
  126.  
  127.     var acceptedBundleEnum = acceptedBundle.getSimpleEnumeration();
  128.  
  129.     var curItem;
  130.   var stringName;
  131.   var stringNameProperty;
  132.  
  133.     while (acceptedBundleEnum.hasMoreElements()) {
  134.  
  135.        //progress through the bundle
  136.        curItem = acceptedBundleEnum.getNext();
  137.  
  138.        //"unpack" the item, nsIPropertyElement is now partially scriptable
  139.        curItem = curItem.QueryInterface(Components.interfaces.nsIPropertyElement);
  140.  
  141.        //dump string name (key)
  142.        stringName = curItem.key;
  143.        stringNameProperty = stringName.split('.');
  144.  
  145.        if (stringNameProperty[1] == 'accept') {
  146.  
  147.           //dump the UI string (value)
  148.            visible   = curItem.value;
  149.  
  150.           //if (visible == 'true') {
  151.  
  152.              str = stringNameProperty[0];
  153.              var stringLangRegion = stringNameProperty[0].split('-');
  154.  
  155.              if (stringLangRegion[0]) {
  156.                  var tit;
  157.                  try {
  158.                     tit = languagesBundle.GetStringFromName(stringLangRegion[0]);
  159.                  }
  160.  
  161.                  catch (ex) {
  162.                     tit = "";
  163.                  }
  164.  
  165.  
  166.                  if (stringLangRegion.length > 1) {
  167.  
  168.                    try {
  169.                     tit += "/" + regionsBundle.GetStringFromName(stringLangRegion[1]);
  170.                    }
  171.  
  172.                    catch (ex) {
  173.           tit += "["+str+"]";
  174.                    }
  175.  
  176.                  } //if region
  177.  
  178.                  tit = tit + "  [" + str + "]";
  179.  
  180.              } //if language
  181.  
  182.              if (str && tit) {
  183.  
  184.           availLanguageDict[i] = new Array(3);
  185.           availLanguageDict[i][0] = tit;
  186.           availLanguageDict[i][1] = str;
  187.           availLanguageDict[i][2] = visible;
  188.                 i++;
  189.  
  190.              } // if str&tit
  191.             //} //if visible
  192.       } //if accepted
  193.     } //while
  194.     availLanguageDict.sort( // sort on first element
  195.       function (a, b) {
  196.         if (a[0] < b[0]) return -1;
  197.         if (a[0] > b[0]) return  1;
  198.         return 0;
  199.     });
  200. }
  201.  
  202.  
  203. function LoadAvailableLanguages()
  204. {
  205.   if (availLanguageDict)
  206.     for (var i = 0; i < availLanguageDict.length; i++) {
  207.  
  208.     if (availLanguageDict[i][2] == 'true') {
  209.  
  210.         AddListItem(document, available_languages, availLanguageDict[i][1], availLanguageDict[i][0]);
  211.  
  212.       } //if
  213.  
  214.     } //for
  215. }
  216.  
  217.  
  218. function LoadActiveLanguages()
  219. {
  220.   if (pref_string) {
  221.     var arrayOfPrefs = pref_string.split(separatorRe);
  222.  
  223.     for (var i = 0; i < arrayOfPrefs.length; i++) {
  224.       var str = arrayOfPrefs[i];
  225.       var tit = GetLanguageTitle(str);
  226.  
  227.       if (str) {
  228.         if (!tit)
  229.            tit = '[' + str + ']';
  230.         AddListItem(document, active_languages, str, tit);
  231.  
  232.       } //if
  233.     } //for
  234.   }
  235. }
  236.  
  237.  
  238. function LangAlreadyActive(langId)
  239. {
  240.   var found = false;
  241.   try {
  242.     var arrayOfPrefs = pref_string.split(separatorRe);
  243.  
  244.     if (arrayOfPrefs)
  245.       for (var i = 0; i < arrayOfPrefs.length; i++) {
  246.       if (arrayOfPrefs[i] == langId) {
  247.          found = true;
  248.          break;
  249.       }
  250.     }
  251.  
  252.     return found;
  253.   }
  254.  
  255.   catch(ex){
  256.      return false;
  257.   }
  258. }
  259.  
  260. function isAlpha(mixedCase) {
  261.   var allCaps = mixedCase.toUpperCase();
  262.   for (var i = allCaps.length - 1; i >= 0; i--) {
  263.     var c = allCaps.charAt(i);
  264.     if (c < 'A' || c > 'Z') return false;
  265.   }
  266.   return true;
  267. }
  268.  
  269. function isAlphaNum(mixedCase) {
  270.   var allCaps = mixedCase.toUpperCase();
  271.   for (var i = allCaps.length - 1; i >= 0; i--) {
  272.     var c = allCaps.charAt(i);
  273.     if ((c < 'A' || c > 'Z') && (c < '0' || c > '9')) return false;
  274.   }
  275.   return true;
  276. }
  277.  
  278. function IsRFC1766LangTag(candidate) {
  279.   /* Valid language codes examples:
  280.      i.e. ja-JP-kansai (Kansai dialect of Japanese)
  281.           en-US-texas (Texas dialect)
  282.           i-klingon-tng (did TOS Klingons speak in non-English?)
  283.           sgn-US-MA (Martha Vineyard's Sign Language)
  284.   */
  285.   var tags = candidate.split('-');
  286.  
  287.   /* if not IANA "i" or a private "x" extension, the primary
  288.      tag should be a ISO 639 country code, two or three letters long.
  289.      we don't check if the country code is bogus or not.
  290.   */
  291.   var checkedTags = 0;
  292.   if (tags[0].toLowerCase() != "x" && tags[0].toLowerCase() != "i") {
  293.     if (tags[0].length != 2 && tags[0].length != 3) return false;
  294.     if (!isAlpha(tags[0])) return false;
  295.     checkedTags++;
  296.  
  297.     /* the first subtag can be either a 2 letter ISO 3166 country code,
  298.        or an IANA registered tag from 3 to 8 characters.
  299.     */
  300.     if (tags.length > 1) {
  301.       if (tags[1].length < 2 || tags[1].length > 3) return false;
  302.       if (!isAlphaNum(tags[1])) return false;
  303.  
  304.       /* do not allow user-assigned ISO 3166 country codes */
  305.       if (tags[1].length == 2 && isAlpha(tags[1])) {
  306.         var countryCode = tags[1].toUpperCase();
  307.         if (countryCode == "AA" || countryCode == "ZZ") return false;
  308.         if (countryCode[0] == 'X') return false;
  309.         if (countryCode[0] == 'Q' && countryCode[1] > 'L') return false;
  310.       }
  311.       checkedTags++;
  312.     }
  313.   }
  314.   else if (tags.length < 2) return false;
  315.   else {
  316.     if ((tags[1].length < 1) || (tags[1].length > 8)) return false;
  317.     if (!isAlphaNum(tags[1])) return false;
  318.     checkedTags++;
  319.   }
  320.  
  321.   /* any remaining subtags must be one to eight alphabetic characters */
  322.  
  323.   for (var i = checkedTags; i < tags.length; i++) {
  324.     if ((tags[1].length < 1) || (tags[i].length > 8)) return false;
  325.     if (!isAlphaNum(tags[i])) return false;
  326.     checkedTags++;
  327.   }
  328.   return true;
  329. }
  330.  
  331. function AddAvailableLanguage()
  332. {
  333.   var Languagename = new String();
  334.   var Languageid = new String();
  335.  
  336.  
  337.   //selected languages
  338.   for (var nodeIndex=0; nodeIndex < available_languages.selectedItems.length; nodeIndex++) {
  339.  
  340.     var selItem =  available_languages.selectedItems[nodeIndex];
  341.  
  342.     Languagename    = selItem.getAttribute('label');
  343.     Languageid      = selItem.getAttribute('id');
  344.  
  345.     if (!LangAlreadyActive(Languageid)) {
  346.  
  347.       AddListItem(window.opener.document, active_languages, Languageid, Languagename);
  348.  
  349.     }//if
  350.  
  351.   } //loop selected languages
  352.  
  353.  
  354.   //user-defined languages
  355.   var otherField = document.getElementById( "languages.other" );
  356.  
  357.   if (otherField.value) {
  358.  
  359.     /* reject bogus lang strings, INCLUDING those with HTTP "q"
  360.        values kludged on the end of them
  361.     */
  362.     if (!IsRFC1766LangTag(otherField.value)) {
  363.       window.alert(prefLangBundle.GetStringFromName("illegalOtherLanguage"));
  364.       return false;
  365.     }
  366.  
  367.     Languageid      = otherField.value;
  368.     Languageid      = Languageid.toLowerCase();
  369.     Languagename    = GetLanguageTitle(Languageid);
  370.     if (!Languagename)
  371.        Languagename = '[' + Languageid + ']';
  372.  
  373.     if (!LangAlreadyActive(Languageid)) {
  374.  
  375.       AddListItem(window.opener.document, active_languages, Languageid, Languagename);
  376.  
  377.     }//if
  378.   }
  379.  
  380.   available_languages.clearSelection();
  381.   return true;
  382. } //AddAvailableLanguage
  383.  
  384. function HandleDoubleClick(node)
  385. {
  386.   var languageId    = node.id;
  387.   var languageName  = node.getAttribute('label');
  388.  
  389.   if (languageName && languageName.length > 0)
  390.   {
  391.     if (!LangAlreadyActive(languageId)) {
  392.       AddListItem(window.opener.document, active_languages, languageId, languageName);
  393.     }
  394.     window.close();
  395.   }//if
  396. } //HandleDoubleClick
  397.  
  398. function RemoveActiveLanguage()
  399. {
  400.  
  401.   var nextNode = null;
  402.   var numSelected = active_languages.selectedItems.length;
  403.   var deleted_all = false;
  404.  
  405.   while (active_languages.selectedItems.length > 0) {
  406.  
  407.   var selectedNode = active_languages.selectedItems[0];
  408.     nextNode = selectedNode.nextSibling;
  409.  
  410.   if (!nextNode)
  411.  
  412.     if (selectedNode.previousSibling)
  413.     nextNode = selectedNode.previousSibling;
  414.  
  415.     active_languages.removeChild(selectedNode);
  416.    } //while
  417.  
  418.   if (nextNode) {
  419.     active_languages.selectItem(nextNode)
  420.   } else {
  421.     //active_languages.clearSelection();
  422.   }
  423.  
  424.   UpdateSavePrefString();
  425.  
  426. } //RemoveActiveLanguage
  427.  
  428.  
  429. function GetLanguageTitle(id)
  430. {
  431.  
  432.   if (availLanguageDict)
  433.     for (var j = 0; j < availLanguageDict.length; j++) {
  434.  
  435.       if ( availLanguageDict[j][1] == id) {
  436.       //title =
  437.   return availLanguageDict[j][0];
  438.       }
  439.     }
  440.   return '';
  441. }
  442.  
  443.  
  444. function AddListItem(doc, listbox, langID, langTitle)
  445. {
  446.   try {  //let's beef up our error handling for languages without label / title
  447.  
  448.       // Create a listitem for the new Language
  449.       var item = doc.createElement('listitem');
  450.  
  451.       // Copy over the attributes
  452.       item.setAttribute('label', langTitle);
  453.       item.setAttribute('id', langID);
  454.  
  455.       listbox.appendChild(item);
  456.  
  457.   } //try
  458.  
  459.   catch (ex) {
  460.   } //catch
  461.  
  462. }
  463.  
  464.  
  465. function UpdateSavePrefString()
  466. {
  467.   var num_languages = 0;
  468.   pref_string = "";
  469.  
  470.   for (var item = active_languages.firstChild; item != null; item = item.nextSibling) {
  471.  
  472.     var languageid = item.getAttribute('id');
  473.  
  474.     if (languageid.length > 1) {
  475.  
  476.           num_languages++;
  477.  
  478.       //separate >1 languages by commas
  479.       if (num_languages > 1) {
  480.         pref_string = pref_string + "," + " " + languageid;
  481.       } else {
  482.         pref_string = languageid;
  483.       } //if
  484.     } //if
  485.   }//for
  486.  
  487.   active_languages.setAttribute("prefvalue", pref_string);
  488. }
  489.  
  490.  
  491. function MoveUp() {
  492.  
  493.   if (active_languages.selectedItems.length == 1) {
  494.     var selected = active_languages.selectedItems[0];
  495.     var before = selected.previousSibling
  496.     if (before) {
  497.       before.parentNode.insertBefore(selected, before);
  498.       active_languages.selectItem(selected);
  499.       active_languages.ensureElementIsVisible(selected);
  500.     }
  501.   }
  502.   
  503.   if (active_languages.selectedIndex == 0)
  504.   {
  505.     // selected item is first
  506.     var moveUp = document.getElementById("up");
  507.     moveUp.disabled = true;
  508.   }
  509.  
  510.   if (active_languages.childNodes.length > 1)
  511.   {
  512.     // more than one item so we can move selected item back down
  513.     var moveDown = document.getElementById("down");
  514.     moveDown.disabled = false;
  515.   }
  516.  
  517.   UpdateSavePrefString();
  518.  
  519. } //MoveUp
  520.  
  521.  
  522. function MoveDown() {
  523.  
  524.   if (active_languages.selectedItems.length == 1) {
  525.     var selected = active_languages.selectedItems[0];
  526.     if (selected.nextSibling) {
  527.       if (selected.nextSibling.nextSibling) {
  528.         active_languages.insertBefore(selected, selected.nextSibling.nextSibling);
  529.       }
  530.       else {
  531.         active_languages.appendChild(selected);
  532.       }
  533.       active_languages.selectItem(selected);
  534.     }
  535.   }
  536.  
  537.   if (active_languages.selectedIndex == active_languages.childNodes.length - 1)
  538.   {
  539.     // selected item is last
  540.     var moveDown = document.getElementById("down");
  541.     moveDown.disabled = true;
  542.   }
  543.  
  544.   if (active_languages.childNodes.length > 1)
  545.   {
  546.     // more than one item so we can move selected item back up 
  547.     var moveUp = document.getElementById("up");
  548.     moveUp.disabled = false;
  549.   }
  550.  
  551.   UpdateSavePrefString();
  552.  
  553. } //MoveDown
  554.  
  555.  
  556. function SelectLanguage() {
  557.   if (active_languages.selectedItems.length) {
  558.     document.getElementById("remove").disabled = false;
  559.     var selected = active_languages.selectedItems[0];
  560.     document.getElementById("down").disabled = !selected.nextSibling;
  561.  
  562.     document.getElementById("up").disabled = !selected.previousSibling;
  563.   }
  564.   else {
  565.     document.getElementById("remove").disabled = true;
  566.     document.getElementById("down").disabled = true;
  567.     document.getElementById("up").disabled = true;
  568.   }
  569.  
  570.   if (parent.hPrefWindow.getPrefIsLocked(document.getElementById("up").getAttribute("prefstring")))
  571.     document.getElementById("up").disabled = true;
  572.   if (parent.hPrefWindow.getPrefIsLocked(document.getElementById("down").getAttribute("prefstring")))
  573.     document.getElementById("down").disabled = true;
  574.   if (parent.hPrefWindow.getPrefIsLocked(document.getElementById("add").getAttribute("prefstring")))
  575.     document.getElementById("add").disabled = true;
  576.   if (parent.hPrefWindow.getPrefIsLocked(document.getElementById("remove").getAttribute("prefstring")))
  577.     document.getElementById("remove").disabled = true;
  578. } // SelectLanguage
  579.