2001-09-20 04:02:59 +04:00
|
|
|
/*
|
|
|
|
* The contents of this file are subject to the Netscape Public
|
2001-05-09 09:23:37 +04:00
|
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
2001-09-20 04:02:59 +04:00
|
|
|
* the License at http://www.mozilla.org/NPL/
|
|
|
|
*
|
2001-05-09 09:23:37 +04:00
|
|
|
* Software distributed under the License is distributed on an "AS
|
|
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
|
|
* implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
2001-09-20 04:02:59 +04:00
|
|
|
*
|
|
|
|
* The Original Code is Mozilla Communicator client code, released
|
|
|
|
* March 31, 1998.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape
|
|
|
|
* Communications Corporation. Portions created by Netscape are
|
2001-05-09 09:23:37 +04:00
|
|
|
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
|
|
|
|
* Rights Reserved.
|
2001-09-20 04:02:59 +04:00
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
*/
|
2001-05-09 09:23:37 +04:00
|
|
|
|
|
|
|
var gIndex;
|
|
|
|
var gCommaIndex = "0";
|
|
|
|
var gSpaceIndex = "1";
|
|
|
|
var gOtherIndex = "2";
|
|
|
|
|
|
|
|
// dialog initialization code
|
|
|
|
function Startup()
|
|
|
|
{
|
|
|
|
if (!InitEditorShell())
|
|
|
|
return;
|
|
|
|
|
2001-10-11 00:07:06 +04:00
|
|
|
gDialog.sepRadioGroup = document.getElementById("SepRadioGroup");
|
|
|
|
gDialog.sepCharacterInput = document.getElementById("SepCharacterInput");
|
|
|
|
gDialog.deleteSepCharacter = document.getElementById("DeleteSepCharacter");
|
|
|
|
gDialog.collapseSpaces = document.getElementById("CollapseSpaces");
|
2001-08-31 08:09:23 +04:00
|
|
|
|
2001-05-09 09:23:37 +04:00
|
|
|
// We persist the user's separator character
|
2001-10-11 00:07:06 +04:00
|
|
|
gDialog.sepCharacterInput.value = gDialog.sepRadioGroup.getAttribute("character");
|
2001-05-09 09:23:37 +04:00
|
|
|
|
2001-10-11 00:07:06 +04:00
|
|
|
gIndex = gDialog.sepRadioGroup.getAttribute("index");
|
2001-05-09 09:23:37 +04:00
|
|
|
|
|
|
|
switch (gIndex)
|
|
|
|
{
|
|
|
|
case gCommaIndex:
|
|
|
|
default:
|
2001-11-07 08:42:41 +03:00
|
|
|
gDialog.sepRadioGroup.selectedItem = document.getElementById("comma");
|
2001-05-09 09:23:37 +04:00
|
|
|
break;
|
|
|
|
case gSpaceIndex:
|
2001-11-07 08:42:41 +03:00
|
|
|
gDialog.sepRadioGroup.selectedItem = document.getElementById("space");
|
2001-05-09 09:23:37 +04:00
|
|
|
break;
|
|
|
|
case gOtherIndex:
|
2001-11-07 08:42:41 +03:00
|
|
|
gDialog.sepRadioGroup.selectedItem = document.getElementById("other");
|
2001-05-09 09:23:37 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2001-08-31 08:09:23 +04:00
|
|
|
// Set initial enable state on character input and "collapse" checkbox
|
2001-05-09 09:23:37 +04:00
|
|
|
SelectCharacter(gIndex);
|
|
|
|
|
2001-10-11 00:07:06 +04:00
|
|
|
SetTextboxFocus(gDialog.sepRadioGroup);
|
2001-05-09 09:23:37 +04:00
|
|
|
|
|
|
|
SetWindowLocation();
|
|
|
|
}
|
|
|
|
|
2001-05-19 04:49:26 +04:00
|
|
|
function InputSepCharacter()
|
|
|
|
{
|
2001-10-11 00:07:06 +04:00
|
|
|
var str = gDialog.sepCharacterInput.value;
|
2001-05-19 04:49:26 +04:00
|
|
|
|
|
|
|
// Limit input to 1 character
|
|
|
|
if (str.length > 1)
|
2001-10-20 01:47:04 +04:00
|
|
|
str = str.slice(0,1);
|
2001-05-19 04:49:26 +04:00
|
|
|
|
2001-12-24 02:23:41 +03:00
|
|
|
// We can never allow tag or entity delimiters for separator character
|
2001-08-31 08:09:23 +04:00
|
|
|
if (str == "<" || str == ">" || str == "&" || str == ";" || str == " ")
|
2001-05-19 04:49:26 +04:00
|
|
|
str = "";
|
|
|
|
|
2001-10-11 00:07:06 +04:00
|
|
|
gDialog.sepCharacterInput.value = str;
|
2001-05-19 04:49:26 +04:00
|
|
|
}
|
|
|
|
|
2001-05-09 09:23:37 +04:00
|
|
|
function SelectCharacter(radioGroupIndex)
|
|
|
|
{
|
|
|
|
gIndex = radioGroupIndex;
|
|
|
|
SetElementEnabledById("SepCharacterInput", gIndex == gOtherIndex);
|
2001-08-31 08:09:23 +04:00
|
|
|
SetElementEnabledById("CollapseSpaces", gIndex == gSpaceIndex);
|
2001-05-09 09:23:37 +04:00
|
|
|
}
|
|
|
|
|
2001-12-07 07:38:52 +03:00
|
|
|
function onAccept()
|
2001-05-09 09:23:37 +04:00
|
|
|
{
|
|
|
|
var sepCharacter = "";
|
|
|
|
switch ( gIndex )
|
|
|
|
{
|
|
|
|
case gCommaIndex:
|
|
|
|
sepCharacter = ",";
|
|
|
|
break;
|
|
|
|
case gSpaceIndex:
|
|
|
|
sepCharacter = " ";
|
|
|
|
break;
|
|
|
|
case gOtherIndex:
|
2001-10-11 00:07:06 +04:00
|
|
|
sepCharacter = gDialog.sepCharacterInput.value.slice(0,1);
|
2001-05-09 09:23:37 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2001-05-19 04:49:26 +04:00
|
|
|
// 1 = OutputSelectionOnly, 1024 = OutputLFLineBreak
|
|
|
|
// 256 = OutputEncodeEntities
|
|
|
|
var str = editorShell.GetContentsAs("text/html", 1+1024);
|
|
|
|
|
|
|
|
// Replace nbsp with spaces:
|
|
|
|
str = str.replace(/\u00a0/g, " ");
|
|
|
|
|
|
|
|
// Strip out </p> completely
|
|
|
|
str = str.replace(/\s*<\/p>\s*/g, "");
|
|
|
|
|
|
|
|
// Trim whitespace adjacent to <p> and <br> tags
|
|
|
|
// and replace <p> with <br>
|
|
|
|
// (which will be replaced with </tr> below)
|
|
|
|
str = str.replace(/\s*<p>\s*|\s*<br>\s*/g, "<br>");
|
|
|
|
|
|
|
|
// Trim leading <br>s
|
|
|
|
str = str.replace(/^(<br>)+/, "");
|
|
|
|
|
|
|
|
// Trim trailing <br>s
|
|
|
|
str = str.replace(/(<br>)+$/, "");
|
|
|
|
|
|
|
|
// Reduce multiple internal <br> to just 1
|
2001-08-31 08:09:23 +04:00
|
|
|
// TODO: Maybe add a checkbox to let user decide
|
|
|
|
//str = str.replace(/(<br>)+/g, "<br>");
|
2001-05-19 04:49:26 +04:00
|
|
|
|
|
|
|
// Trim leading and trailing spaces
|
|
|
|
str = str.replace(/^\s+|\s+$/, "");
|
|
|
|
|
|
|
|
// Remove all tag contents so we don't replace
|
|
|
|
// separator character within tags
|
|
|
|
// Also converts lists to something usefull
|
|
|
|
var stack = [];
|
|
|
|
var start;
|
|
|
|
var end;
|
|
|
|
var searchStart = 0;
|
|
|
|
var listSeparator = "";
|
|
|
|
var listItemSeparator = "";
|
|
|
|
var endList = false;
|
|
|
|
|
|
|
|
do {
|
|
|
|
start = str.indexOf("<", searchStart);
|
|
|
|
|
|
|
|
if (start >= 0)
|
|
|
|
{
|
2002-01-03 04:01:13 +03:00
|
|
|
end = str.indexOf(">", start+1);
|
2001-05-19 04:49:26 +04:00
|
|
|
if (end > start)
|
|
|
|
{
|
|
|
|
var tagContent = TrimString(str.slice(start+1, end));
|
|
|
|
|
|
|
|
if ( tagContent.match(/^ol|^ul|^dl/) )
|
|
|
|
{
|
|
|
|
// Replace list tag with <BR> to start new row
|
|
|
|
// at begining of second or greater list tag
|
|
|
|
str = str.slice(0, start) + listSeparator + str.slice(end+1);
|
|
|
|
if (listSeparator == "")
|
|
|
|
listSeparator = "<br>";
|
|
|
|
|
|
|
|
// Reset for list item separation into cells
|
|
|
|
listItemSeparator = "";
|
|
|
|
}
|
|
|
|
else if ( tagContent.match(/^li|^dt|^dd/) )
|
|
|
|
{
|
|
|
|
// Start a new row if this is first item after the ending the last list
|
|
|
|
if (endList)
|
|
|
|
listItemSeparator = "<br>";
|
|
|
|
|
|
|
|
// Start new cell at begining of second or greater list items
|
|
|
|
str = str.slice(0, start) + listItemSeparator + str.slice(end+1);
|
|
|
|
|
|
|
|
if (endList || listItemSeparator == "")
|
|
|
|
listItemSeparator = sepCharacter;
|
|
|
|
|
|
|
|
endList = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Find end tags
|
|
|
|
endList = tagContent.match(/^\/ol|^\/ul|^\/dl/);
|
|
|
|
if ( endList || tagContent.match(/^\/li|^\/dt|^\/dd/) )
|
|
|
|
{
|
|
|
|
// Strip out tag
|
|
|
|
str = str.slice(0, start) + str.slice(end+1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Not a list-related tag: Store tag contents in an array
|
|
|
|
stack.push(tagContent);
|
|
|
|
|
|
|
|
// Keep the "<" and ">" while removing from source string
|
|
|
|
start++;
|
|
|
|
str = str.slice(0, start) + str.slice(end);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
searchStart = start + 1;
|
|
|
|
}
|
|
|
|
} while (start >= 0);
|
2001-05-09 09:23:37 +04:00
|
|
|
|
|
|
|
// Replace separator characters with table cells
|
|
|
|
var replaceString;
|
2001-10-11 00:07:06 +04:00
|
|
|
if (gDialog.deleteSepCharacter.checked)
|
2001-05-09 09:23:37 +04:00
|
|
|
{
|
|
|
|
replaceString = "";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Don't delete separator character,
|
|
|
|
// so include it at start of string to replace
|
|
|
|
replaceString = sepCharacter;
|
|
|
|
}
|
2001-08-31 08:09:23 +04:00
|
|
|
|
2001-05-19 04:49:26 +04:00
|
|
|
replaceString += "<td>";
|
2001-05-09 09:23:37 +04:00
|
|
|
|
2001-05-19 04:49:26 +04:00
|
|
|
if (sepCharacter.length > 0)
|
|
|
|
{
|
2001-08-31 08:09:23 +04:00
|
|
|
var tempStr = sepCharacter;
|
2001-10-10 00:39:03 +04:00
|
|
|
var regExpChars = ".!@#$%^&*-+[]{}()\|\\\/";
|
2001-08-31 08:09:23 +04:00
|
|
|
if (regExpChars.indexOf(sepCharacter) >= 0)
|
|
|
|
tempStr = "\\" + sepCharacter;
|
|
|
|
|
|
|
|
if (gIndex == gSpaceIndex)
|
|
|
|
{
|
|
|
|
// If checkbox is checked,
|
|
|
|
// one or more adjacent spaces are one separator
|
2001-10-11 00:07:06 +04:00
|
|
|
if (gDialog.collapseSpaces.checked)
|
2001-08-31 08:09:23 +04:00
|
|
|
tempStr = "\\s+"
|
|
|
|
else
|
|
|
|
tempStr = "\\s";
|
|
|
|
}
|
|
|
|
var pattern = new RegExp(tempStr, "g");
|
2001-05-19 04:49:26 +04:00
|
|
|
str = str.replace(pattern, replaceString);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Put back tag contents that we removed above
|
|
|
|
searchStart = 0;
|
|
|
|
var stackIndex = 0;
|
|
|
|
do {
|
|
|
|
start = str.indexOf("<", searchStart);
|
|
|
|
end = start + 1;
|
|
|
|
if (start >= 0 && str.charAt(end) == ">")
|
|
|
|
{
|
|
|
|
// We really need a FIFO stack!
|
|
|
|
str = str.slice(0, end) + stack[stackIndex++] + str.slice(end);
|
|
|
|
}
|
|
|
|
searchStart = end;
|
|
|
|
|
|
|
|
} while (start >= 0);
|
2001-05-09 09:23:37 +04:00
|
|
|
|
|
|
|
// End table row and start another for each br or p
|
|
|
|
str = str.replace(/\s*<br>\s*/g, "</tr>\n<tr><td>");
|
|
|
|
|
|
|
|
// Add the table tags and the opening and closing tr/td tags
|
2001-05-19 04:49:26 +04:00
|
|
|
// Default table attributes should be same as those used in nsHTMLEditor::CreateElementWithDefaults()
|
|
|
|
// (Default width="100%" is used in EdInsertTable.js)
|
|
|
|
str = "<table border=\"1\" width=\"100%\" cellpadding=\"2\" cellspacing=\"2\">\n<tr><td>" + str + "</tr>\n</table>\n";
|
2001-05-09 09:23:37 +04:00
|
|
|
|
|
|
|
editorShell.BeginBatchChanges();
|
|
|
|
|
2001-05-19 04:49:26 +04:00
|
|
|
// Delete the selection -- makes it easier to find where table will insert
|
|
|
|
editorShell.DeleteSelection(0);
|
|
|
|
|
|
|
|
var anchorNodeBeforeInsert = editorShell.editorSelection.anchorNode;
|
|
|
|
var offset = editorShell.editorSelection.anchorOffset;
|
|
|
|
var nodeBeforeTable = null;
|
|
|
|
var nodeAfterTable = null;
|
|
|
|
if (anchorNodeBeforeInsert.nodeType == Node.TEXT_NODE)
|
|
|
|
{
|
|
|
|
// Text was split. Table should be right after the first or before
|
|
|
|
nodeBeforeTable = anchorNodeBeforeInsert.previousSibling;
|
|
|
|
nodeAfterTable = anchorNodeBeforeInsert;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Table should be inserted right after node pointed to by selection
|
|
|
|
if (offset > 0)
|
|
|
|
nodeBeforeTable = anchorNodeBeforeInsert.childNodes.item(offset - 1);
|
|
|
|
|
|
|
|
nodeAfterTable = anchorNodeBeforeInsert.childNodes.item(offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
editorShell.InsertSource(str);
|
|
|
|
|
|
|
|
var table = null;
|
|
|
|
if (nodeAfterTable)
|
|
|
|
{
|
|
|
|
var previous = nodeAfterTable.previousSibling;
|
|
|
|
if (previous && previous.nodeName.toLowerCase() == "table")
|
|
|
|
table = previous;
|
|
|
|
}
|
|
|
|
if (!table && nodeBeforeTable)
|
|
|
|
{
|
|
|
|
var next = nodeBeforeTable.nextSibling;
|
|
|
|
if (next && next.nodeName.toLowerCase() == "table")
|
|
|
|
table = next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (table)
|
|
|
|
{
|
|
|
|
// Fixup table only if pref is set
|
|
|
|
var prefs = GetPrefs();
|
|
|
|
try {
|
2001-10-27 09:39:25 +04:00
|
|
|
if (prefs && prefs.getBoolPref("editor.table.maintain_structure") )
|
2001-05-19 04:49:26 +04:00
|
|
|
editorShell.NormalizeTable(table);
|
|
|
|
} catch(ex) {
|
|
|
|
dump(ex);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Put caret in first cell
|
|
|
|
var firstRow = editorShell.GetFirstRow(table);
|
|
|
|
if (firstRow)
|
|
|
|
{
|
|
|
|
var node2 = firstRow.firstChild;
|
|
|
|
do {
|
|
|
|
if (node2.nodeName.toLowerCase() == "td" ||
|
|
|
|
node2.nodeName.toLowerCase() == "th")
|
|
|
|
{
|
|
|
|
editorShell.editorSelection.collapse(node2, 0);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
node2 = node.nextSibling;
|
|
|
|
} while (node2);
|
|
|
|
}
|
|
|
|
}
|
2001-05-09 09:23:37 +04:00
|
|
|
|
|
|
|
editorShell.EndBatchChanges();
|
|
|
|
|
|
|
|
// Save persisted attributes
|
2001-10-11 00:07:06 +04:00
|
|
|
gDialog.sepRadioGroup.setAttribute("index", gIndex);
|
2001-05-09 09:23:37 +04:00
|
|
|
if (gIndex == gOtherIndex)
|
2001-10-11 00:07:06 +04:00
|
|
|
gDialog.sepRadioGroup.setAttribute("character", sepCharacter);
|
2001-05-09 09:23:37 +04:00
|
|
|
|
|
|
|
SaveWindowLocation();
|
|
|
|
return true;
|
|
|
|
}
|