home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 April / CMCD0404.ISO / Software / Complet / thunderbird / chrome / mail.jar / content / editor / EdTableProps.js < prev    next >
Encoding:
JavaScript  |  2003-02-12  |  39.7 KB  |  1,299 lines

  1. /*
  2.  * The contents of this file are subject to the Netscape Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/NPL/
  6.  *
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  *
  12.  * The Original Code is Mozilla Communicator client code, released
  13.  * March 31, 1998.
  14.  *
  15.  * The Initial Developer of the Original Code is Netscape
  16.  * Communications Corporation. Portions created by Netscape are
  17.  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
  18.  * Rights Reserved.
  19.  *
  20.  * Contributor(s):
  21.  *    Ben Goodger
  22.  *    Charles Manske (cmanske@netscape.com)
  23.  *    Neil Rashbrook (neil@parkwaycc.co.uk)
  24.  */
  25.  
  26. //Cancel() is in EdDialogCommon.js
  27. var gTableElement;
  28. var gCellElement;
  29. var gTableCaptionElement;
  30. var globalCellElement;
  31. var globalTableElement
  32. var gValidateTab;
  33. const defHAlign =   "left";
  34. const centerStr =   "center";  //Index=1
  35. const rightStr =    "right";   // 2
  36. const justifyStr =  "justify"; // 3
  37. const charStr =     "char";    // 4
  38. const defVAlign =   "middle";
  39. const topStr =      "top";
  40. const bottomStr =   "bottom";
  41. const bgcolor = "bgcolor";
  42. var gTableColor;
  43. var gCellColor;
  44.  
  45. const cssBackgroundColorStr = "background-color";
  46.  
  47. var gRowCount = 1;
  48. var gColCount = 1;
  49. var gLastRowIndex;
  50. var gLastColIndex;
  51. var gNewRowCount;
  52. var gNewColCount;
  53. var gCurRowIndex;
  54. var gCurColIndex;
  55. var gCurColSpan;
  56. var gSelectedCellsType = 1;
  57. const SELECT_CELL = 1;
  58. const SELECT_ROW = 2;
  59. const SELECT_COLUMN = 3;
  60. const RESET_SELECTION = 0;
  61. var gCellData = { value:null, startRowIndex:0, startColIndex:0, rowSpan:0, colSpan:0,
  62.                  actualRowSpan:0, actualColSpan:0, isSelected:false
  63.                };
  64. var gAdvancedEditUsed;
  65. var gAlignWasChar = false;
  66.  
  67. /*
  68. From C++:
  69.  0 TABLESELECTION_TABLE
  70.  1 TABLESELECTION_CELL   There are 1 or more cells selected
  71.                           but complete rows or columns are not selected
  72.  2 TABLESELECTION_ROW    All cells are in 1 or more rows
  73.                           and in each row, all cells selected
  74.                           Note: This is the value if all rows (thus all cells) are selected
  75.  3 TABLESELECTION_COLUMN All cells are in 1 or more columns
  76. */
  77.  
  78. var gSelectedCellCount = 0;
  79. var gApplyUsed = false;
  80. var gSelection;
  81. var gCellDataChanged = false;
  82. var gCanDelete = false;
  83. var gPrefs = GetPrefs();
  84. var gUseCSS = true;
  85. var gActiveEditor;
  86.  
  87. // dialog initialization code
  88. function Startup()
  89. {
  90.   gActiveEditor = GetCurrentTableEditor();
  91.   if (!gActiveEditor)
  92.   {
  93.     window.close();
  94.     return;
  95.   }
  96.  
  97.   try {
  98.     gSelection = gActiveEditor.selection;
  99.   } catch (e) {}
  100.   if (!gSelection) return;
  101.  
  102.   // Get dialog widgets - Table Panel
  103.   gDialog.TableRowsInput = document.getElementById("TableRowsInput");
  104.   gDialog.TableColumnsInput = document.getElementById("TableColumnsInput");
  105.   gDialog.TableWidthInput = document.getElementById("TableWidthInput");
  106.   gDialog.TableWidthUnits = document.getElementById("TableWidthUnits");
  107.   gDialog.TableHeightInput = document.getElementById("TableHeightInput");
  108.   gDialog.TableHeightUnits = document.getElementById("TableHeightUnits");
  109.   try {
  110.     if (!gPrefs.getBoolPref("editor.use_css") || (gActiveEditor.flags & 1))
  111.     {
  112.       gUseCSS = false;
  113.       var tableHeightLabel = document.getElementById("TableHeightLabel");
  114.       tableHeightLabel.parentNode.removeChild(tableHeightLabel);
  115.       gDialog.TableHeightInput.parentNode.removeChild(gDialog.TableHeightInput);
  116.       gDialog.TableHeightUnits.parentNode.removeChild(gDialog.TableHeightUnits);
  117.     }
  118.   } catch (e) {}
  119.   gDialog.BorderWidthInput = document.getElementById("BorderWidthInput");
  120.   gDialog.SpacingInput = document.getElementById("SpacingInput");
  121.   gDialog.PaddingInput = document.getElementById("PaddingInput");
  122.   gDialog.TableAlignList = document.getElementById("TableAlignList");
  123.   gDialog.TableCaptionList = document.getElementById("TableCaptionList");
  124.   gDialog.TableInheritColor = document.getElementById("TableInheritColor");
  125.   gDialog.TabBox =  document.getElementById("TabBox");
  126.  
  127.   // Cell Panel
  128.   gDialog.SelectionList = document.getElementById("SelectionList");
  129.   gDialog.PreviousButton = document.getElementById("PreviousButton");
  130.   gDialog.NextButton = document.getElementById("NextButton");
  131.   // Currently, we always apply changes and load new attributes when changing selection
  132.   // (Let's keep this for possible future use)
  133.   //gDialog.ApplyBeforeMove =  document.getElementById("ApplyBeforeMove");
  134.   //gDialog.KeepCurrentData = document.getElementById("KeepCurrentData");
  135.  
  136.   gDialog.CellHeightInput = document.getElementById("CellHeightInput");
  137.   gDialog.CellHeightUnits = document.getElementById("CellHeightUnits");
  138.   gDialog.CellWidthInput = document.getElementById("CellWidthInput");
  139.   gDialog.CellWidthUnits = document.getElementById("CellWidthUnits");
  140.   gDialog.CellHAlignList = document.getElementById("CellHAlignList");
  141.   gDialog.CellVAlignList = document.getElementById("CellVAlignList");
  142.   gDialog.CellInheritColor = document.getElementById("CellInheritColor");
  143.   gDialog.CellStyleList = document.getElementById("CellStyleList");
  144.   gDialog.TextWrapList = document.getElementById("TextWrapList");
  145.  
  146.   // In cell panel, user must tell us which attributes to apply via checkboxes,
  147.   //  else we would apply values from one cell to ALL in selection
  148.   //  and that's probably not what they expect!
  149.   gDialog.CellHeightCheckbox = document.getElementById("CellHeightCheckbox");
  150.   gDialog.CellWidthCheckbox = document.getElementById("CellWidthCheckbox");
  151.   gDialog.CellHAlignCheckbox = document.getElementById("CellHAlignCheckbox");
  152.   gDialog.CellVAlignCheckbox = document.getElementById("CellVAlignCheckbox");
  153.   gDialog.CellStyleCheckbox = document.getElementById("CellStyleCheckbox");
  154.   gDialog.TextWrapCheckbox = document.getElementById("TextWrapCheckbox");
  155.   gDialog.CellColorCheckbox = document.getElementById("CellColorCheckbox");
  156.   gDialog.TableTab = document.getElementById("TableTab");
  157.   gDialog.CellTab = document.getElementById("CellTab");
  158.   gDialog.AdvancedEditCell = document.getElementById("AdvancedEditButton2");
  159.   // Save "normal" tooltip message for Advanced Edit button
  160.   gDialog.AdvancedEditCellToolTipText = gDialog.AdvancedEditCell.getAttribute("tooltiptext");
  161.  
  162.   try {
  163.     gTableElement = gActiveEditor.getElementOrParentByTagName("table", null);
  164.   } catch (e) {}
  165.   if(!gTableElement)
  166.   {
  167.     dump("Failed to get table element!\n");
  168.     window.close();
  169.     return;
  170.   }
  171.   globalTableElement = gTableElement.cloneNode(false);
  172.  
  173.   var tagNameObj = { value: "" };
  174.   var countObj = { value : 0 };
  175.   var tableOrCellElement;
  176.   try {
  177.    tableOrCellElement = gActiveEditor.getSelectedOrParentTableElement(tagNameObj, countObj);
  178.   } catch (e) {}
  179.  
  180.   if (tagNameObj.value == "td")
  181.   {
  182.     // We are in a cell
  183.     gSelectedCellCount = countObj.value;
  184.     gCellElement = tableOrCellElement;
  185.     globalCellElement = gCellElement.cloneNode(false);
  186.  
  187.     // Tells us whether cell, row, or column is selected
  188.     try {
  189.       gSelectedCellsType = gActiveEditor.getSelectedCellsType(gTableElement);
  190.     } catch (e) {}
  191.  
  192.     // Ignore types except Cell, Row, and Column
  193.     if (gSelectedCellsType < SELECT_CELL || gSelectedCellsType > SELECT_COLUMN)
  194.       gSelectedCellsType = SELECT_CELL;
  195.  
  196.     // Be sure at least 1 cell is selected.
  197.     // (If the count is 0, then we were inside the cell.)
  198.     if (gSelectedCellCount == 0)
  199.       DoCellSelection();
  200.  
  201.     // Get location in the cell map
  202.     var rowIndexObj = { value: 0 };
  203.     var colIndexObj = { value: 0 };
  204.     try {
  205.       gActiveEditor.getCellIndexes(gCellElement, rowIndexObj, colIndexObj);
  206.     } catch (e) {}
  207.     gCurRowIndex = rowIndexObj.value;
  208.     gCurColIndex = colIndexObj.value;
  209.  
  210.     // We save the current colspan to quickly
  211.     //  move selection from from cell to cell
  212.     if (GetCellData(gCurRowIndex, gCurColIndex))
  213.       gCurColSpan = gCellData.colSpan;
  214.  
  215.     // Starting TabPanel name is passed in
  216.     if (window.arguments[1] == "CellPanel")
  217.       gDialog.TabBox.selectedTab = gDialog.CellTab;
  218.   }
  219.  
  220.   if (gDialog.TabBox.selectedTab == gDialog.TableTab)
  221.   {
  222.     // We may call this with table selected, but no cell,
  223.     //  so disable the Cell Properties tab
  224.     if(!gCellElement)
  225.     {
  226.       // XXX: Disabling of tabs is currently broken, so for
  227.       //      now we'll just remove the tab completely.
  228.       //gDialog.CellTab.disabled = true;
  229.       gDialog.CellTab.parentNode.removeChild(gDialog.CellTab);
  230.     }
  231.   }
  232.  
  233.   // Note: we must use gTableElement, not globalTableElement for these,
  234.   //  thus we should not put this in InitDialog.
  235.   // Instead, monitor desired counts with separate globals
  236.   var rowCountObj = { value: 0 };
  237.   var colCountObj = { value: 0 };
  238.   try {
  239.     gActiveEditor.getTableSize(gTableElement, rowCountObj, colCountObj);
  240.   } catch (e) {}
  241.  
  242.   gRowCount = rowCountObj.value;
  243.   gLastRowIndex = gRowCount-1;
  244.   gColCount = colCountObj.value;
  245.   gLastColIndex = gColCount-1;
  246.  
  247.  
  248.   // Set appropriate icons and enable state for the Previous/Next buttons
  249.   SetSelectionButtons();
  250.  
  251.   // If only one cell in table, disable change-selection widgets
  252.   if (gRowCount == 1 && gColCount == 1)
  253.     gDialog.SelectionList.setAttribute("disabled", "true");
  254.  
  255.   // User can change these via textboxes
  256.   gNewRowCount = gRowCount;
  257.   gNewColCount = gColCount;
  258.  
  259.   // This flag is used to control whether set check state
  260.   //  on "set attribute" checkboxes
  261.   // (Advanced Edit dialog use calls  InitDialog when done)
  262.   gAdvancedEditUsed = false;
  263.   InitDialog();
  264.   gAdvancedEditUsed = true;
  265.  
  266.   // If first initializing, we really aren't changing anything
  267.   gCellDataChanged = false;
  268.  
  269.   if (gDialog.TabBox.selectedTab == gDialog.CellTab)
  270.     setTimeout("gDialog.SelectionList.focus()", 0);
  271.   else
  272.     SetTextboxFocus(gDialog.TableRowsInput);
  273.  
  274.   SetWindowLocation();
  275. }
  276.  
  277.  
  278. function InitDialog()
  279. {
  280. // turn on extra1 to be "apply"
  281.   var applyButton = document.documentElement.getButton("extra1");
  282.   if (applyButton)
  283.   {
  284.     applyButton.label = GetString("Apply");
  285.     applyButton.setAttribute("accesskey", GetString("ApplyAccessKey"));
  286.   }
  287.   
  288.   // Get Table attributes
  289.   gDialog.TableRowsInput.value = gRowCount;
  290.   gDialog.TableColumnsInput.value = gColCount;
  291.   gDialog.TableWidthInput.value = InitPixelOrPercentMenulist(globalTableElement, gTableElement, "width", "TableWidthUnits", gPercent);
  292.   if (gUseCSS) {
  293.     gDialog.TableHeightInput.value = InitPixelOrPercentMenulist(globalTableElement, gTableElement, "height",
  294.                                                                 "TableHeightUnits", gPercent);
  295.   }
  296.   gDialog.BorderWidthInput.value = globalTableElement.border;
  297.   gDialog.SpacingInput.value = globalTableElement.cellSpacing;
  298.   gDialog.PaddingInput.value = globalTableElement.cellPadding;
  299.  
  300.   var marginLeft  = GetHTMLOrCSSStyleValue(globalTableElement, "align", "margin-left");
  301.   var marginRight = GetHTMLOrCSSStyleValue(globalTableElement, "align", "margin-right");
  302.   var halign = marginLeft.toLowerCase() + " " + marginRight.toLowerCase();
  303.   if (halign == "center center" || halign == "auto auto")
  304.     gDialog.TableAlignList.value = "center";
  305.   else if (halign == "right right" || halign == "auto 0px")
  306.     gDialog.TableAlignList.value = "right";
  307.   else // Default = left
  308.     gDialog.TableAlignList.value = "left";
  309.  
  310.   // Be sure to get caption from table in doc, not the copied "globalTableElement"
  311.   gTableCaptionElement = gTableElement.caption;
  312.   if (gTableCaptionElement)
  313.   {
  314.     var align = GetHTMLOrCSSStyleValue(gTableCaptionElement, "align", "caption-side");
  315.     if (align != "bottom" && align != "left" && align != "right")
  316.       align = "top";
  317.     gDialog.TableCaptionList.value = align;
  318.   }
  319.  
  320.   gTableColor = GetHTMLOrCSSStyleValue(globalTableElement, bgcolor, cssBackgroundColorStr);
  321.   gTableColor = ConvertRGBColorIntoHEXColor(gTableColor);
  322.   SetColor("tableBackgroundCW", gTableColor);
  323.  
  324.   InitCellPanel();
  325. }
  326.  
  327. function InitCellPanel()
  328. {
  329.   // Get cell attributes
  330.   if (globalCellElement)
  331.   {
  332.     // This assumes order of items is Cell, Row, Column
  333.     gDialog.SelectionList.value = gSelectedCellsType;
  334.  
  335.     var previousValue = gDialog.CellHeightInput.value;
  336.     gDialog.CellHeightInput.value = InitPixelOrPercentMenulist(globalCellElement, gCellElement, "height", "CellHeightUnits", gPixel);
  337.     gDialog.CellHeightCheckbox.checked = gAdvancedEditUsed && previousValue != gDialog.CellHeightInput.value;
  338.  
  339.     previousValue= gDialog.CellWidthInput.value;
  340.     gDialog.CellWidthInput.value = InitPixelOrPercentMenulist(globalCellElement, gCellElement, "width", "CellWidthUnits", gPixel);
  341.     gDialog.CellWidthCheckbox.checked = gAdvancedEditUsed && previousValue != gDialog.CellWidthInput.value;
  342.  
  343.     var previousIndex = gDialog.CellVAlignList.selectedIndex;
  344.     var valign = GetHTMLOrCSSStyleValue(globalCellElement, "valign", "vertical-align").toLowerCase();
  345.     if (valign == topStr || valign == bottomStr)
  346.       gDialog.CellVAlignList.value = valign;
  347.     else // Default = middle
  348.       gDialog.CellVAlignList.value = defVAlign;
  349.  
  350.     gDialog.CellVAlignCheckbox.checked = gAdvancedEditUsed && previousIndex != gDialog.CellVAlignList.selectedIndex;
  351.  
  352.     previousIndex = gDialog.CellHAlignList.selectedIndex;
  353.  
  354.     gAlignWasChar = false;
  355.  
  356.     var halign = GetHTMLOrCSSStyleValue(globalCellElement, "align", "text-align").toLowerCase();
  357.     switch (halign)
  358.     {
  359.       case centerStr:
  360.       case rightStr:
  361.       case justifyStr:
  362.         gDialog.CellHAlignList.value = halign;
  363.         break;
  364.       case charStr:
  365.         // We don't support UI for this because layout doesn't work: bug 2212.
  366.         // Remember that's what they had so we don't change it
  367.         //  unless they change the alignment by using the menulist
  368.         gAlignWasChar = true;
  369.         // Fall through to use show default alignment in menu
  370.       default:
  371.         // Default depends on cell type (TH is "center", TD is "left")
  372.         gDialog.CellHAlignList.value =
  373.           (globalCellElement.nodeName.toLowerCase() == "th") ? "center" : "left";
  374.         break;
  375.     }
  376.  
  377.     gDialog.CellHAlignCheckbox.checked = gAdvancedEditUsed &&
  378.       previousIndex != gDialog.CellHAlignList.selectedIndex;
  379.  
  380.     previousIndex = gDialog.CellStyleList.selectedIndex;
  381.     gDialog.CellStyleList.value = globalCellElement.nodeName.toLowerCase();
  382.     gDialog.CellStyleCheckbox.checked = gAdvancedEditUsed && previousIndex != gDialog.CellStyleList.selectedIndex;
  383.  
  384.     previousIndex = gDialog.TextWrapList.selectedIndex;
  385.     if (GetHTMLOrCSSStyleValue(globalCellElement, "nowrap", "white-space") == "nowrap")
  386.       gDialog.TextWrapList.value = "nowrap";
  387.     else
  388.       gDialog.TextWrapList.value = "wrap";
  389.     gDialog.TextWrapCheckbox.checked = gAdvancedEditUsed && previousIndex != gDialog.TextWrapList.selectedIndex;
  390.  
  391.     previousValue = gCellColor;
  392.     gCellColor = GetHTMLOrCSSStyleValue(globalCellElement, bgcolor, cssBackgroundColorStr);
  393.     gCellColor = ConvertRGBColorIntoHEXColor(gCellColor);
  394.     SetColor("cellBackgroundCW", gCellColor);
  395.     gDialog.CellColorCheckbox.checked = gAdvancedEditUsed && previousValue != gCellColor;
  396.  
  397.     // We want to set this true in case changes came
  398.     //   from Advanced Edit dialog session (must assume something changed)
  399.     gCellDataChanged = true;
  400.   }
  401. }
  402.  
  403. function GetCellData(rowIndex, colIndex)
  404. {
  405.   // Get actual rowspan and colspan
  406.   var startRowIndexObj = { value: 0 };
  407.   var startColIndexObj = { value: 0 };
  408.   var rowSpanObj = { value: 0 };
  409.   var colSpanObj = { value: 0 };
  410.   var actualRowSpanObj = { value: 0 };
  411.   var actualColSpanObj = { value: 0 };
  412.   var isSelectedObj = { value: false };
  413.  
  414.   try {
  415.     gActiveEditor.getCellDataAt(gTableElement, rowIndex, colIndex,
  416.                          gCellData,
  417.                          startRowIndexObj, startColIndexObj,
  418.                          rowSpanObj, colSpanObj,
  419.                          actualRowSpanObj, actualColSpanObj, isSelectedObj);
  420.     // We didn't find a cell
  421.     if (!gCellData.value) return false;
  422.   }
  423.   catch(ex) {
  424.     return false;
  425.   }
  426.  
  427.   gCellData.startRowIndex = startRowIndexObj.value;
  428.   gCellData.startColIndex = startColIndexObj.value;
  429.   gCellData.rowSpan = rowSpanObj.value;
  430.   gCellData.colSpan = colSpanObj.value;
  431.   gCellData.actualRowSpan = actualRowSpanObj.value;
  432.   gCellData.actualColSpan = actualColSpanObj.value;
  433.   gCellData.isSelected = isSelectedObj.value;
  434.   return true;
  435. }
  436.  
  437. function SelectCellHAlign()
  438. {
  439.   SetCheckbox("CellHAlignCheckbox");
  440.   // Once user changes the alignment,
  441.   //  we loose their original "CharAt" alignment"
  442.   gAlignWasChar = false;
  443. }
  444.  
  445. function GetColorAndUpdate(ColorWellID)
  446. {
  447.   var colorWell = document.getElementById(ColorWellID);
  448.   if (!colorWell) return;
  449.  
  450.   var colorObj = { Type:"", TableColor:0, CellColor:0, NoDefault:false, Cancel:false, BackgroundColor:0 };
  451.  
  452.   switch( ColorWellID )
  453.   {
  454.     case "tableBackgroundCW":
  455.       colorObj.Type = "Table";
  456.       colorObj.TableColor = gTableColor;
  457.       break;
  458.     case "cellBackgroundCW":
  459.       colorObj.Type = "Cell";
  460.       colorObj.CellColor = gCellColor;
  461.       break;
  462.   }
  463.   window.openDialog("chrome://editor/content/EdColorPicker.xul", "_blank", "chrome,close,titlebar,modal", "", colorObj);
  464.  
  465.   // User canceled the dialog
  466.   if (colorObj.Cancel)
  467.     return;
  468.  
  469.   switch( ColorWellID )
  470.   {
  471.     case "tableBackgroundCW":
  472.       gTableColor = colorObj.BackgroundColor;
  473.       SetColor(ColorWellID, gTableColor);
  474.       break;
  475.     case "cellBackgroundCW":
  476.       gCellColor = colorObj.BackgroundColor;
  477.       SetColor(ColorWellID, gCellColor);
  478.       SetCheckbox('CellColorCheckbox');
  479.       break;
  480.   }
  481. }
  482.  
  483. function SetColor(ColorWellID, color)
  484. {
  485.   // Save the color
  486.   if (ColorWellID == "cellBackgroundCW")
  487.   {
  488.     if (color)
  489.     {
  490.       globalCellElement.setAttribute(bgcolor, color);
  491.       gDialog.CellInheritColor.collapsed = true;
  492.     }
  493.     else
  494.     {
  495.       try {
  496.         gActiveEditor.removeAttributeOrEquivalent(globalCellElement, bgcolor, true);
  497.       } catch(e) {}
  498.       // Reveal addition message explaining "default" color
  499.       gDialog.CellInheritColor.collapsed = false;
  500.     }
  501.   }
  502.   else
  503.   {
  504.     if (color)
  505.     {
  506.       globalTableElement.setAttribute(bgcolor, color);
  507.       gDialog.TableInheritColor.collapsed = true;
  508.     }
  509.     else
  510.     {
  511.       try {
  512.         gActiveEditor.removeAttributeOrEquivalent(globalTableElement, bgcolor, true);
  513.       } catch(e) {}
  514.       gDialog.TableInheritColor.collapsed = false;
  515.     }
  516.     SetCheckbox('CellColorCheckbox');
  517.   }
  518.  
  519.   setColorWell(ColorWellID, color);
  520. }
  521.  
  522. function ChangeSelectionToFirstCell()
  523. {
  524.   if (!GetCellData(0,0))
  525.   {
  526.     dump("Can't find first cell in table!\n");
  527.     return;
  528.   }
  529.   gCellElement = gCellData.value;
  530.   globalCellElement = gCellElement;
  531.  
  532.   gCurRowIndex = 0;
  533.   gCurColIndex = 0;
  534.   ChangeSelection(RESET_SELECTION);
  535. }
  536.  
  537. function ChangeSelection(newType)
  538. {
  539.   newType = Number(newType);
  540.  
  541.   if (gSelectedCellsType == newType)
  542.     return;
  543.  
  544.   if (newType == RESET_SELECTION)
  545.     // Restore selection to existing focus cell
  546.     gSelection.collapse(gCellElement,0);
  547.   else
  548.     gSelectedCellsType = newType;
  549.  
  550.   // Keep the same focus gCellElement, just change the type
  551.   DoCellSelection();
  552.   SetSelectionButtons();
  553.  
  554.   // Note: globalCellElement should still be a clone of gCellElement
  555. }
  556.  
  557. function MoveSelection(forward)
  558. {
  559.   var newRowIndex = gCurRowIndex;
  560.   var newColIndex = gCurColIndex;
  561.   var focusCell;
  562.   var inRow = false;
  563.  
  564.   if (gSelectedCellsType == SELECT_ROW)
  565.   {
  566.     newRowIndex += (forward ? 1 : -1);
  567.  
  568.     // Wrap around if before first or after last row
  569.     if (newRowIndex < 0)
  570.       newRowIndex = gLastRowIndex;
  571.     else if (newRowIndex > gLastRowIndex)
  572.       newRowIndex = 0;
  573.     inRow = true;
  574.  
  575.     // Use first cell in row for focus cell
  576.     newColIndex = 0;
  577.   }
  578.   else
  579.   {
  580.     // Cell or column:
  581.     if (!forward)
  582.       newColIndex--;
  583.  
  584.     if (gSelectedCellsType == SELECT_CELL)
  585.     {
  586.       // Skip to next cell
  587.       if (forward)
  588.         newColIndex += gCurColSpan;
  589.     }
  590.     else  // SELECT_COLUMN
  591.     {
  592.       // Use first cell in column for focus cell
  593.       newRowIndex = 0;
  594.  
  595.       // Don't skip by colspan,
  596.       //  but find first cell in next cellmap column
  597.       if (forward)
  598.         newColIndex++;
  599.     }
  600.  
  601.     if (newColIndex < 0)
  602.     {
  603.       // Request is before the first cell in column
  604.  
  605.       // Wrap to last cell in column
  606.       newColIndex = gLastColIndex;
  607.  
  608.       if (gSelectedCellsType == SELECT_CELL)
  609.       {
  610.         // If moving by cell, also wrap to previous...
  611.         if (newRowIndex > 0)
  612.           newRowIndex -= 1;
  613.         else
  614.           // ...or the last row
  615.           newRowIndex = gLastRowIndex;
  616.  
  617.         inRow = true;
  618.       }
  619.     }
  620.     else if (newColIndex > gLastColIndex)
  621.     {
  622.       // Request is after the last cell in column
  623.  
  624.       // Wrap to first cell in column
  625.       newColIndex = 0;
  626.  
  627.       if (gSelectedCellsType == SELECT_CELL)
  628.       {
  629.         // If moving by cell, also wrap to next...
  630.         if (newRowIndex < gLastRowIndex)
  631.           newRowIndex++;
  632.         else
  633.           // ...or the first row
  634.           newRowIndex = 0;
  635.  
  636.         inRow = true;
  637.       }
  638.     }
  639.   }
  640.  
  641.   // Get the cell at the new location
  642.   do {
  643.     if (!GetCellData(newRowIndex, newColIndex))
  644.     {
  645.       dump("MoveSelection: CELL NOT FOUND\n");
  646.       return;
  647.     }
  648.     if (inRow)
  649.     {
  650.       if (gCellData.startRowIndex == newRowIndex)
  651.         break;
  652.       else
  653.         // Cell spans from a row above, look for the next cell in row
  654.         newRowIndex += gCellData.actualRowSpan;
  655.     }
  656.     else
  657.     {
  658.       if (gCellData.startColIndex == newColIndex)
  659.         break;
  660.       else
  661.         // Cell spans from a Col above, look for the next cell in column
  662.         newColIndex += gCellData.actualColSpan;
  663.     }
  664.   }
  665.   while(true);
  666.  
  667.   // Save data for current selection before changing
  668.   if (gCellDataChanged) // && gDialog.ApplyBeforeMove.checked)
  669.   {
  670.     if (!ValidateCellData())
  671.       return;
  672.  
  673.     gActiveEditor.beginTransaction();
  674.     // Apply changes to all selected cells
  675.     ApplyCellAttributes();
  676.     gActiveEditor.endTransaction();
  677.  
  678.     SetCloseButton();
  679.   }
  680.  
  681.   // Set cell and other data for new selection
  682.   gCellElement = gCellData.value;
  683.  
  684.   // Save globals for new current cell
  685.   gCurRowIndex = gCellData.startRowIndex;
  686.   gCurColIndex = gCellData.startColIndex;
  687.   gCurColSpan = gCellData.actualColSpan;
  688.  
  689.   // Copy for new global cell
  690.   globalCellElement = gCellElement.cloneNode(false);
  691.  
  692.   // Change the selection
  693.   DoCellSelection();
  694.  
  695.   // Scroll page so new selection is visible
  696.   // Using SELECTION_ANCHOR_REGION makes the upper-left corner of first selected cell
  697.   //    the point to bring into view.
  698.   try {
  699.     var selectionController = gActiveEditor.selectionController;
  700.     selectionController.scrollSelectionIntoView(selectionController.SELECTION_NORMAL, selectionController.SELECTION_ANCHOR_REGION, true);
  701.   } catch (e) {}
  702.  
  703.   // Reinitialize dialog using new cell
  704. //  if (!gDialog.KeepCurrentData.checked)
  705.   // Setting this false unchecks all "set attributes" checkboxes
  706.   gAdvancedEditUsed = false;
  707.   InitCellPanel();
  708.   gAdvancedEditUsed = true;
  709. }
  710.  
  711.  
  712. function DoCellSelection()
  713. {
  714.   // Collapse selection into to the focus cell
  715.   //  so editor uses that as start cell
  716.   gSelection.collapse(gCellElement, 0);
  717.  
  718.   var tagNameObj = { value: "" };
  719.   var countObj = { value: 0 };
  720.   try {
  721.     switch (gSelectedCellsType)
  722.     {
  723.       case SELECT_CELL:
  724.         gActiveEditor.selectTableCell();
  725.         break
  726.       case SELECT_ROW:
  727.         gActiveEditor.selectTableRow();
  728.         break;
  729.       default:
  730.         gActiveEditor.selectTableColumn();
  731.         break;
  732.     }
  733.     // Get number of cells selected
  734.     var tableOrCellElement = gActiveEditor.getSelectedOrParentTableElement(tagNameObj, countObj);
  735.   } catch (e) {}
  736.  
  737.   if (tagNameObj.value == "td")
  738.     gSelectedCellCount = countObj.value;
  739.   else
  740.     gSelectedCellCount = 0;
  741.  
  742.   // Currently, we can only allow advanced editing on ONE cell element at a time
  743.   //   else we ignore CSS, JS, and HTML attributes not already in dialog
  744.   SetElementEnabled(gDialog.AdvancedEditCell, gSelectedCellCount == 1);
  745.  
  746.   gDialog.AdvancedEditCell.setAttribute("tooltiptext", 
  747.     gSelectedCellCount > 1 ? GetString("AdvancedEditForCellMsg") :
  748.                              gDialog.AdvancedEditCellToolTipText);
  749. }
  750.  
  751. function SetSelectionButtons()
  752. {
  753.   if (gSelectedCellsType == SELECT_ROW)
  754.   {
  755.     // Trigger CSS to set images of up and down arrows
  756.     gDialog.PreviousButton.setAttribute("type","row");
  757.     gDialog.NextButton.setAttribute("type","row");
  758.   }
  759.   else
  760.   {
  761.     // or images of left and right arrows
  762.     gDialog.PreviousButton.setAttribute("type","col");
  763.     gDialog.NextButton.setAttribute("type","col");
  764.   }
  765.   DisableSelectionButtons((gSelectedCellsType == SELECT_ROW && gRowCount == 1) ||
  766.                           (gSelectedCellsType == SELECT_COLUMN && gColCount == 1) ||
  767.                           (gRowCount == 1 && gColCount == 1));
  768. }
  769.  
  770. function DisableSelectionButtons( disable )
  771. {
  772.   gDialog.PreviousButton.setAttribute("disabled", disable ? "true" : "false");
  773.   gDialog.NextButton.setAttribute("disabled", disable ? "true" : "false");
  774. }
  775.  
  776. function SwitchToValidatePanel()
  777. {
  778.   if (gDialog.TabBox.selectedTab != gValidateTab)
  779.     gDialog.TabBox.selectedTab = gValidateTab;
  780. }
  781.  
  782. function SetAlign(listID, defaultValue, element, attName)
  783. {
  784.   var value = document.getElementById(listID).value;
  785.   if (value == defaultValue)
  786.   {
  787.     try {
  788.       gActiveEditor.removeAttributeOrEquivalent(element, attName, true);
  789.       } catch(e) {}
  790.   }
  791.   else
  792.     element.setAttribute(attName, value);
  793. }
  794.  
  795. function ValidateTableData()
  796. {
  797.   gValidateTab = gDialog.TableTab;
  798.   gNewRowCount = Number(ValidateNumber(gDialog.TableRowsInput, null, 1, gMaxRows, null, true, true));
  799.   if (gValidationError) return false;
  800.  
  801.   gNewColCount = Number(ValidateNumber(gDialog.TableColumnsInput, null, 1, gMaxColumns, null, true, true));
  802.   if (gValidationError) return false;
  803.  
  804.   // If user is deleting any cells, get confirmation
  805.   // (This is a global to the dialog and we ask only once per dialog session)
  806.   if ( !gCanDelete &&
  807.         (gNewRowCount < gRowCount ||
  808.          gNewColCount < gColCount) ) 
  809.   {
  810.     if (ConfirmWithTitle(GetString("DeleteTableTitle"), 
  811.                          GetString("DeleteTableMsg"),
  812.                          GetString("DeleteCells")) )
  813.     {
  814.       gCanDelete = true;
  815.     }
  816.     else
  817.     {
  818.       SetTextboxFocus(gNewRowCount < gRowCount ? gDialog.TableRowsInput : gDialog.TableColumnsInput);
  819.       return false;
  820.     }
  821.   }
  822.  
  823.   ValidateNumber(gDialog.TableWidthInput, gDialog.TableWidthUnits,
  824.                  1, gMaxTableSize, globalTableElement, "width");
  825.   if (gValidationError) return false;
  826.  
  827.   if (gUseCSS) {
  828.     ValidateNumber(gDialog.TableHeightInput, gDialog.TableHeightUnits,
  829.                    1, gMaxTableSize, globalTableElement, "height");
  830.     if (gValidationError) return false;
  831.   }
  832.  
  833.   var border = ValidateNumber(gDialog.BorderWidthInput, null, 0, gMaxPixels, globalTableElement, "border");
  834.   // TODO: Deal with "BORDER" without value issue
  835.   if (gValidationError) return false;
  836.  
  837.   ValidateNumber(gDialog.SpacingInput, null, 0, gMaxPixels, globalTableElement, "cellspacing");
  838.   if (gValidationError) return false;
  839.  
  840.   ValidateNumber(gDialog.PaddingInput, null, 0, gMaxPixels, globalTableElement, "cellpadding");
  841.   if (gValidationError) return false;
  842.  
  843.   SetAlign("TableAlignList", defHAlign, globalTableElement, "align");
  844.  
  845.   // Color is set on globalCellElement immediately
  846.   return true;
  847. }
  848.  
  849. function ValidateCellData()
  850. {
  851.  
  852.   gValidateTab = gDialog.CellTab;
  853.  
  854.   if (gDialog.CellHeightCheckbox.checked)
  855.   {
  856.     ValidateNumber(gDialog.CellHeightInput, gDialog.CellHeightUnits,
  857.                     1, gMaxTableSize, globalCellElement, "height");
  858.     if (gValidationError) return false;
  859.   }
  860.  
  861.   if (gDialog.CellWidthCheckbox.checked)
  862.   {
  863.     ValidateNumber(gDialog.CellWidthInput, gDialog.CellWidthUnits,
  864.                    1, gMaxTableSize, globalCellElement, "width");
  865.     if (gValidationError) return false;
  866.   }
  867.  
  868.   if (gDialog.CellHAlignCheckbox.checked)
  869.   {
  870.     var hAlign = gDialog.CellHAlignList.value;
  871.  
  872.     // Horizontal alignment is complicated by "char" type
  873.     // We don't change current values if user didn't edit alignment
  874.     if (!gAlignWasChar)
  875.     {
  876.       globalCellElement.removeAttribute(charStr);
  877.  
  878.       // Always set "align" attribute,
  879.       //  so the default "left" is effective in a cell
  880.       //  when parent row has align set.
  881.       globalCellElement.setAttribute("align", hAlign);
  882.     }
  883.   }
  884.  
  885.   if (gDialog.CellVAlignCheckbox.checked)
  886.   {
  887.     // Always set valign (no default in 2nd param) so
  888.     //  the default "middle" is effective in a cell
  889.     //  when parent row has valign set.
  890.     SetAlign("CellVAlignList", "", globalCellElement, "valign");
  891.   }
  892.  
  893.   if (gDialog.TextWrapCheckbox.checked)
  894.   {
  895.     if (gDialog.TextWrapList.value == "nowrap")
  896.       globalCellElement.setAttribute("nowrap","nowrap");
  897.     else
  898.       try {
  899.         gActiveEditor.removeAttributeOrEquivalent(globalCellElement, "nowrap", true);
  900.       } catch(e) {}
  901.   }
  902.  
  903.   return true;
  904. }
  905.  
  906. function ValidateData()
  907. {
  908.   var result;
  909.  
  910.   // Validate current panel first
  911.   if (gDialog.TabBox.selectedTab == gDialog.TableTab)
  912.   {
  913.     result = ValidateTableData();
  914.     if (result)
  915.       result = ValidateCellData();
  916.   } else {
  917.     result = ValidateCellData();
  918.     if (result)
  919.       result = ValidateTableData();
  920.   }
  921.   if(!result) return false;
  922.  
  923.   // Set global element for AdvancedEdit
  924.   if(gDialog.TabBox.selectedTab == gDialog.TableTab)
  925.     globalElement = globalTableElement;
  926.   else
  927.     globalElement = globalCellElement;
  928.  
  929.   return true;
  930. }
  931.  
  932. function ChangeCellTextbox(textboxID)
  933. {
  934.   // Filter input for just integers
  935.   forceInteger(textboxID);
  936.  
  937.   if (gDialog.TabBox.selectedTab == gDialog.CellTab)
  938.     gCellDataChanged = true;
  939. }
  940.  
  941. // Call this when a textbox or menulist is changed
  942. //   so the checkbox is automatically set
  943. function SetCheckbox(checkboxID)
  944. {
  945.   if (checkboxID && checkboxID.length > 0)
  946.   {
  947.     // Set associated checkbox
  948.     document.getElementById(checkboxID).checked = true;
  949.   }
  950.   gCellDataChanged = true;
  951. }
  952.  
  953. function ChangeIntTextbox(textboxID, checkboxID)
  954. {
  955.   // Filter input for just integers
  956.   forceInteger(textboxID);
  957.  
  958.   // Set associated checkbox
  959.   SetCheckbox(checkboxID);
  960. }
  961.  
  962. function CloneAttribute(destElement, srcElement, attr)
  963. {
  964.   var value = srcElement.getAttribute(attr);
  965.   // Use editor methods since we are always
  966.   //  modifying a table in the document and
  967.   //  we need transaction system for undo
  968.   try {
  969.     if (!value || value.length == 0)
  970.       gActiveEditor.removeAttributeOrEquivalent(destElement, attr, false);
  971.     else
  972.       gActiveEditor.setAttributeOrEquivalent(destElement, attr, value, false);
  973.   } catch(e) {}
  974. }
  975.  
  976. function ApplyTableAttributes()
  977. {
  978.   var newAlign = gDialog.TableCaptionList.value;
  979.   if (!newAlign) newAlign = "";
  980.  
  981.   if (gTableCaptionElement)
  982.   {
  983.     // Get current alignment
  984.     var align = GetHTMLOrCSSStyleValue(gTableCaptionElement, "align", "caption-side").toLowerCase();
  985.     // This is the default
  986.     if (!align) align = "top";
  987.  
  988.     if (newAlign == "")
  989.     {
  990.       // Remove existing caption
  991.       try {
  992.         gActiveEditor.deleteNode(gTableCaptionElement);
  993.       } catch(e) {}
  994.       gTableCaptionElement = null;
  995.     }
  996.     else if(newAlign != align)
  997.     {
  998.       try {
  999.         if (newAlign == "top") // This is default, so don't explicitly set it
  1000.           gActiveEditor.removeAttributeOrEquivalent(gTableCaptionElement, "align", false);
  1001.         else
  1002.           gActiveEditor.setAttributeOrEquivalent(gTableCaptionElement, "align", newAlign, false);
  1003.       } catch(e) {}
  1004.     }
  1005.   }
  1006.   else if (newAlign != "")
  1007.   {
  1008.     // Create and insert a caption:
  1009.     try {
  1010.       gTableCaptionElement = gActiveEditor.createElementWithDefaults("caption");
  1011.     } catch (e) {}
  1012.     if (gTableCaptionElement)
  1013.     {
  1014.       if (newAlign != "top")
  1015.         gTableCaptionElement.setAttribute("align", newAlign);
  1016.  
  1017.       // Insert it into the table - caption is always inserted as first child
  1018.       try {
  1019.         gActiveEditor.insertNode(gTableCaptionElement, gTableElement, 0);
  1020.       } catch(e) {}
  1021.  
  1022.       // Put selecton back where it was
  1023.       ChangeSelection(RESET_SELECTION);
  1024.     }
  1025.   }
  1026.  
  1027.   var countDelta;
  1028.   var foundcell;
  1029.   var i;
  1030.  
  1031.   if (gNewRowCount != gRowCount)
  1032.   {
  1033.     countDelta = gNewRowCount - gRowCount;
  1034.     if (gNewRowCount > gRowCount)
  1035.     {
  1036.       // Append new rows
  1037.       // Find first cell in last row
  1038.       if(GetCellData(gLastRowIndex, 0))
  1039.       {
  1040.         try {
  1041.           // Move selection to the last cell
  1042.           gSelection.collapse(gCellData.value,0);
  1043.           // Insert new rows after it
  1044.           gActiveEditor.insertTableRow(countDelta, true);
  1045.           gRowCount = gNewRowCount;
  1046.           gLastRowIndex = gRowCount - 1;
  1047.           // Put selecton back where it was
  1048.           ChangeSelection(RESET_SELECTION);
  1049.         }
  1050.         catch(ex) {
  1051.           dump("FAILED TO FIND FIRST CELL IN LAST ROW\n");
  1052.         }
  1053.       }
  1054.     }
  1055.     else
  1056.     {
  1057.       // Delete rows
  1058.       if (gCanDelete)
  1059.       {
  1060.         // Find first cell starting in first row we delete
  1061.         var firstDeleteRow = gRowCount + countDelta;
  1062.         foundCell = false;
  1063.         for ( i = 0; i <= gLastColIndex; i++)
  1064.         {
  1065.           if (!GetCellData(firstDeleteRow, i))
  1066.             break; // We failed to find a cell
  1067.  
  1068.           if (gCellData.startRowIndex == firstDeleteRow)
  1069.           {
  1070.             foundCell = true;
  1071.             break;
  1072.           }
  1073.         };
  1074.         if (foundCell)
  1075.         {
  1076.           try {
  1077.             // Move selection to the cell we found
  1078.             gSelection.collapse(gCellData.value, 0);
  1079.             gActiveEditor.deleteTableRow(-countDelta);
  1080.             gRowCount = gNewRowCount;
  1081.             gLastRowIndex = gRowCount - 1;
  1082.             if (gCurRowIndex > gLastRowIndex)
  1083.               // We are deleting our selection
  1084.               // move it to start of table
  1085.               ChangeSelectionToFirstCell()
  1086.             else
  1087.               // Put selecton back where it was
  1088.               ChangeSelection(RESET_SELECTION);
  1089.           }
  1090.           catch(ex) {
  1091.             dump("FAILED TO FIND FIRST CELL IN LAST ROW\n");
  1092.           }
  1093.         }
  1094.       }
  1095.     }
  1096.   }
  1097.  
  1098.   if (gNewColCount != gColCount)
  1099.   {
  1100.     countDelta = gNewColCount - gColCount;
  1101.  
  1102.     if (gNewColCount > gColCount)
  1103.     {
  1104.       // Append new columns
  1105.       // Find last cell in first column
  1106.       if(GetCellData(0, gLastColIndex))
  1107.       {
  1108.         try {
  1109.           // Move selection to the last cell
  1110.           gSelection.collapse(gCellData.value,0);
  1111.           gActiveEditor.insertTableColumn(countDelta, true);
  1112.           gColCount = gNewColCount;
  1113.           gLastColIndex = gColCount-1;
  1114.           // Restore selection
  1115.           ChangeSelection(RESET_SELECTION);
  1116.         }
  1117.         catch(ex) {
  1118.           dump("FAILED TO FIND FIRST CELL IN LAST COLUMN\n");
  1119.         }
  1120.       }
  1121.     }
  1122.     else
  1123.     {
  1124.       // Delete columns
  1125.       if (gCanDelete)
  1126.       {
  1127.         var firstDeleteCol = gColCount + countDelta;
  1128.         foundCell = false;
  1129.         for ( i = 0; i <= gLastRowIndex; i++)
  1130.         {
  1131.           // Find first cell starting in first column we delete
  1132.           if (!GetCellData(i, firstDeleteCol))
  1133.             break; // We failed to find a cell
  1134.  
  1135.           if (gCellData.startColIndex == firstDeleteCol)
  1136.           {
  1137.             foundCell = true;
  1138.             break;
  1139.           }
  1140.         };
  1141.         if (foundCell)
  1142.         {
  1143.           try {
  1144.             // Move selection to the cell we found
  1145.             gSelection.collapse(gCellData.value, 0);
  1146.             gActiveEditor.deleteTableColumn(-countDelta);
  1147.             gColCount = gNewColCount;
  1148.             gLastColIndex = gColCount-1;
  1149.             if (gCurColIndex > gLastColIndex)
  1150.               ChangeSelectionToFirstCell()
  1151.             else
  1152.               ChangeSelection(RESET_SELECTION);
  1153.           }
  1154.           catch(ex) {
  1155.             dump("FAILED TO FIND FIRST CELL IN LAST ROW\n");
  1156.           }
  1157.         }
  1158.       }
  1159.     }
  1160.   }
  1161.  
  1162.   // Clone all remaining attributes to pick up
  1163.   //  anything changed by Advanced Edit Dialog
  1164.   try {
  1165.     gActiveEditor.cloneAttributes(gTableElement, globalTableElement);
  1166.   } catch(e) {}
  1167. }
  1168.  
  1169. function ApplyCellAttributes()
  1170. {
  1171.   var rangeObj = { value: null };
  1172.   var selectedCell;
  1173.   try {
  1174.     selectedCell = gActiveEditor.getFirstSelectedCell(rangeObj);
  1175.   } catch(e) {}
  1176.  
  1177.   if (!selectedCell)
  1178.     return;
  1179.  
  1180.   if (gSelectedCellCount == 1)
  1181.   {
  1182.     // When only one cell is selected, simply clone entire element,
  1183.     //  thus CSS and JS from Advanced edit is copied
  1184.     try {
  1185.       gActiveEditor.cloneAttributes(selectedCell, globalCellElement);
  1186.     } catch(e) {}
  1187.  
  1188.     if (gDialog.CellStyleCheckbox.checked)
  1189.     {
  1190.       var currentStyleIndex = (selectedCell.nodeName.toLowerCase() == "th") ? 1 : 0;
  1191.       if (gDialog.CellStyleList.selectedIndex != currentStyleIndex)
  1192.       {
  1193.         // Switch cell types
  1194.         // (replaces with new cell and copies attributes and contents)
  1195.         try {
  1196.           selectedCell = gActiveEditor.switchTableCellHeaderType(selectedCell);
  1197.         } catch(e) {}
  1198.       }
  1199.     }
  1200.   }
  1201.   else
  1202.   {
  1203.     // Apply changes to all selected cells
  1204.     //XXX THIS DOESN'T COPY ADVANCED EDIT CHANGES!
  1205.     try {
  1206.       while (selectedCell)
  1207.       {
  1208.         ApplyAttributesToOneCell(selectedCell);
  1209.         selectedCell = gActiveEditor.getNextSelectedCell(rangeObj);
  1210.       }
  1211.     } catch(e) {}
  1212.   }
  1213.   gCellDataChanged = false;
  1214. }
  1215.  
  1216. function ApplyAttributesToOneCell(destElement)
  1217. {
  1218.   if (gDialog.CellHeightCheckbox.checked)
  1219.     CloneAttribute(destElement, globalCellElement, "height");
  1220.  
  1221.   if (gDialog.CellWidthCheckbox.checked)
  1222.     CloneAttribute(destElement, globalCellElement, "width");
  1223.  
  1224.   if (gDialog.CellHAlignCheckbox.checked)
  1225.   {
  1226.     CloneAttribute(destElement, globalCellElement, "align");
  1227.     CloneAttribute(destElement, globalCellElement, charStr);
  1228.   }
  1229.  
  1230.   if (gDialog.CellVAlignCheckbox.checked)
  1231.     CloneAttribute(destElement, globalCellElement, "valign");
  1232.  
  1233.   if (gDialog.TextWrapCheckbox.checked)
  1234.     CloneAttribute(destElement, globalCellElement, "nowrap");
  1235.  
  1236.   if (gDialog.CellStyleCheckbox.checked)
  1237.   {
  1238.     var newStyleIndex = gDialog.CellStyleList.selectedIndex;
  1239.     var currentStyleIndex = (destElement.nodeName.toLowerCase() == "th") ? 1 : 0;
  1240.  
  1241.     if (newStyleIndex != currentStyleIndex)
  1242.     {
  1243.       // Switch cell types
  1244.       // (replaces with new cell and copies attributes and contents)
  1245.       try {
  1246.         destElement = gActiveEditor.switchTableCellHeaderType(destElement);
  1247.       } catch(e) {}
  1248.     }
  1249.   }
  1250.  
  1251.   if (gDialog.CellColorCheckbox.checked)
  1252.     CloneAttribute(destElement, globalCellElement, "bgcolor");
  1253. }
  1254.  
  1255. function SetCloseButton()
  1256. {
  1257.   // Change text on "Cancel" button after Apply is used
  1258.   if (!gApplyUsed)
  1259.   {
  1260.     document.documentElement.getButton("cancel").setAttribute("label",GetString("Close"));
  1261.     gApplyUsed = true;
  1262.   }
  1263. }
  1264.  
  1265. function Apply()
  1266. {
  1267.   if (ValidateData())
  1268.   {
  1269.     gActiveEditor.beginTransaction();
  1270.  
  1271.     ApplyTableAttributes();
  1272.  
  1273.     // We may have just a table, so check for cell element
  1274.     if (globalCellElement)
  1275.       ApplyCellAttributes();
  1276.  
  1277.     gActiveEditor.endTransaction();
  1278.  
  1279.     SetCloseButton();
  1280.     return true;
  1281.   }
  1282.   return false;
  1283. }
  1284.  
  1285. function doHelpButton()
  1286. {
  1287.   openHelp("table_properties");
  1288. }
  1289.  
  1290. function onAccept()
  1291. {
  1292.   // Do same as Apply and close window if ValidateData succeeded
  1293.   var retVal = Apply();
  1294.   if (retVal)
  1295.     SaveWindowLocation();
  1296.  
  1297.   return retVal;
  1298. }
  1299.