Click here to Skip to main content
15,885,953 members
Articles / Web Development / ASP.NET

OpenCollective -- The Requirements Management Wiki

Rate me:
Please Sign up or sign in to vote.
4.41/5 (16 votes)
9 Nov 20044 min read 261.4K   1.8K   111  
An article on building a project oriented wiki for software development requirements management
//** FreeTextBox Main Script ********************/
//   by John Dyer
//   http://www.freetextbox.com/
//***********************************************/

/** START:BROWSER DETECTION ********************/
_d=document;
_nv=navigator.appVersion.toLowerCase();
_f=false;_t=true;
ie4=(!_d.getElementById&&_d.all)?_t:_f;
ie5=(_nv.indexOf("msie 5.0")!=-1)?_t:_f;
ie55=(_nv.indexOf("msie 5.5")!=-1)?_t:_f;
ie6=(_nv.indexOf("msie 6.0")!=-1)?_t:_f;
isIE=(ie5||ie55||ie6)?_t:_f;
/** END:BROWSER DETECTION ********************/

/** START:MAIN FREETEXTBOX FUNCTIONS ********************/
function FTB_InitializeAll() {
	for (var i=0; i<FTB_StartUpArray.length; i++)
	FTB_Initialize(FTB_StartUpArray[i]);
}

function FTB_Initialize(ftbName) {
	
	startMode = eval(ftbName + "_StartMode");
	readOnly = eval(ftbName + "_ReadOnly");
	designModeCss = eval(ftbName + "_DesignModeCss");
	htmlModeCss = eval(ftbName + "_HtmlModeCss");

	hiddenHtml = FTB_GetHiddenField(ftbName);
	editor = FTB_GetIFrame(ftbName);
	
	if (readOnly) {
		editor.document.designMode = 'Off';
	} else {
		editor.document.designMode = 'On';
	}
	
	editor.document.open();
	//if (!isIE) editor.document.write("<html><body><style type='text/css'>body { direction: rtl; }</style>");
	editor.document.write(hiddenHtml.value);
	//if (!isIE) editor.document.write("</body><html>");
	editor.document.close();
		
	if (isIE) {
		if (htmlModeCss != "" || designModeCss != "" ) {
			editor.document.createStyleSheet(designModeCss);
			editor.document.createStyleSheet(htmlModeCss);
			editor.document.styleSheets[1].disabled = true;
		}
	} else {
		// turn off <span style="font-weight:bold">, use <b>
		editor.document.execCommand("useCSS", false, true); 
	}
	
	if (readOnly) {
		editor.document.contentEditable = 'False';
	} else {
		editor.document.contentEditable = 'True';
	}
	
	editor.document.body.style.border = '0';
	if (FTB_GetTextDirection(ftbName) == "RightToLeft")
		editor.document.body.style.direction = 'rtl';
	
	if (isIE) {
		editor.document.onkeydown = function() {
			return FTB_Event(ftbName);	
		};
		editor.document.onkeypress = function() {
			return FTB_Event(ftbName);	
		};	
		editor.document.onclick = function() {
			return FTB_Event(ftbName);	
		};	
		editor.document.onmousedown = function() {
			return FTB_Event(ftbName);	
		};		
	} else {
		editor.addEventListener("keydown", function() {
			return FTB_Event(ftbName);	
		}, true);	
		editor.addEventListener("keypress", function() {
			return FTB_Event(ftbName);	
		}, true);
		editor.addEventListener("click", function() {
			return FTB_Event(ftbName);	
		}, true);			
		editor.addEventListener("mousedown", function() {
			return FTB_Event(ftbName);	
		}, true);		
	}
	
	
	if (startMode != "DesignMode" && FTB_HideToolbar(ftbName)) {
		toolbar = FTB_GetToolbar(ftbName);
		if (toolbar != null) toolbar.style.display = 'none';
	}
	
	eval(ftbName + "_Initialized = true;");
}

function FTB_GetFtbName(ftb) {
	ftbName = ftb.name;
	underscore = ftbName.lastIndexOf("_");
	return ftbName.substring(0,underscore); 
}

function FTB_ChangeMode(ftb,goToHtmlMode) {
	editor = ftb;
		
	ftbName = FTB_GetFtbName(ftb);
	var toolbar = FTB_GetToolbar(ftbName);
	var hideToolbar = FTB_HideToolbar(ftbName);
	var editorContent;
	var iframe = document.getElementById(ftbName + "_Editor");
	
	editor.focus();
	
	if (goToHtmlMode) {
		if (isIE) {			
			if (editor.document.styleSheets.length > 0) {
				editor.document.styleSheets[0].disabled = true;
				editor.document.styleSheets[1].disabled = false;				
			}
			if (FTB_HtmlModeDefaultsToMonoSpaceFont(ftbName) && editor.document.styleSheets.length < 2) {						
				editor.document.body.style.fontFamily = 'Courier New, Courier New';
				editor.document.body.style.fontSize = '10pt';				
			}
						
			editorContent = editor.document.body.innerHTML;			
			//alert(editorContent);
			editor.document.body.innerText = editorContent;
		
		} else {			

			editorContent = document.createTextNode(editor.document.body.innerHTML);
			editor.document.body.innerHTML = "";
			editor.document.body.appendChild(editorContent);	
			
		}
		
		if (toolbar != null && hideToolbar ) {
			if (!isIE) iframe.style.height = '50%';
			toolbar.style.display = 'none';
			if (!isIE) setTimeout(function() { iframe.style.height = '100%'; }, 0);				
		}		
		return true;
	} else {
		// go to Design Mode
		if (isIE) {
			editorContent = editor.document.body.innerText;
			
			if (FTB_HtmlModeDefaultsToMonoSpaceFont(ftbName) && editor.document.styleSheets.length < 2) {					
				editor.document.body.style.fontFamily = '';
				editor.document.body.style.fontSize = '';
			}					
			if (editor.document.styleSheets.length > 0) {
				editor.document.styleSheets[0].disabled = false;
				editor.document.styleSheets[1].disabled = true;
			}
			
			editor.document.body.innerHTML = editorContent;
		} else {
						
			editorContent = editor.document.body.ownerDocument.createRange();
			editorContent.selectNodeContents(editor.document.body);
			editor.document.body.innerHTML = editorContent.toString();
		}

		if (toolbar != null && hideToolbar ) {
			if (!isIE) iframe.style.height = '50%';
			toolbar.style.display = '';
			if (!isIE) setTimeout(function() { iframe.style.height = '100%'; editor.focus();}, 0);				
		}
		
		editor.focus(); 
		return true;
	}
}

function FTB_CopyHtmlToHidden(ftbName) {
	
	if (!FTB_Initialized(ftbName)) return;
	

	hiddenHtml = FTB_GetHiddenField(ftbName);
	editor = FTB_GetIFrame(ftbName);
	
	if (isIE) {
		if (FTB_IsHtmlMode(ftbName)) {
			hiddenHtml.value = editor.document.body.innerText;  
		} else {
			hiddenHtml.value = editor.document.body.innerHTML;  
		}		
	} else {
		if (FTB_IsHtmlMode(ftbName)) {
			editorContent = editor.document.body.ownerDocument.createRange();
			editorContent.selectNodeContents(editor.document.body);
			hiddenHtml.value = editorContent.toString();
		} else {
			hiddenHtml.value = editor.document.body.innerHTML;  
		}	
	}
	if (hiddenHtml.value == '<P>&nbsp;</P>' || hiddenHtml.value == '<br>') {
		hiddenHtml.value = '';
	}
}

function FTB_Format(ftbName,commandName) {
	editor = FTB_GetIFrame(ftbName);

	if (FTB_IsHtmlMode(ftbName)) return;
	editor.focus();
	editor.document.execCommand(commandName,'',null);
	
	//FTB_Event(ftbName);
}

function FTB_SurroundTextDelDiv(ftbName,start,end) {
	if (FTB_IsHtmlMode(ftbName)) return;
	editor = FTB_GetIFrame(ftbName);
	editor.focus();
	
	if (isIE) {
		var sel = editor.document.selection.createRange();
		html = start + sel.htmlText + end;
		
		//added by Tyler
		//sel.htmlText = sel.htmlText.replace(/^(<DIV.*?>|<P>)/gi,'');
		//s/el.htmlText = sel.htmlText.replace(/(<\/DIV>|<\/P>)$/gi,'');
		//end add by Tyler		
		
		sel.pasteHTML(html);		
	} else {
        selection = editor.window.getSelection();
        editor.focus();
        if (selection) {
            range = selection.getRangeAt(0);
        } else {
            range = editor.document.createRange();
        } 
		//added by Tyler
		//range.htmlText = range.htmlText.replace(/^<DIV.*?>/gi,'');
		//range.htmlText = range.htmlText.replace(/<\/DIV>$/gi,'');
		//end add by Tyler
        
      FTB_InsertText(ftbName, start + selection + end);
	}	

}

function FTB_SurroundText(ftbName,start,end) {
	if (FTB_IsHtmlMode(ftbName)) return;
	editor = FTB_GetIFrame(ftbName);
	editor.focus();
	
	if (isIE) {
		var sel = editor.document.selection.createRange();
		html = start + sel.htmlText + end;
		sel.pasteHTML(html);		
	} else {
        selection = editor.window.getSelection();
        editor.focus();
        if (selection) {
            range = selection.getRangeAt(0);
        } else {
            range = editor.document.createRange();
        } 
      FTB_InsertText(ftbName, start + selection + end);
	}	

}

function FTB_InsertText(ftbName,insertion) {
	if (FTB_IsHtmlMode(ftbName)) return;
	editor = FTB_GetIFrame(ftbName);
	editor.focus();
	if (isIE) {
		sel = editor.document.selection.createRange();
		sel.pasteHTML(insertion);
	} else {
        editor.focus();
        selection = editor.window.getSelection();
		if (selection) {
			range = selection.getRangeAt(0);
		} else {
			range = editor.document.createRange();
		} 

        var fragment = editor.document.createDocumentFragment();
        var div = editor.document.createElement("div");
        div.innerHTML = insertion;

        while (div.firstChild) {
            fragment.appendChild(div.firstChild);
        }

        selection.removeAllRanges();
        range.deleteContents();

        var node = range.startContainer;
        var pos = range.startOffset;

        switch (node.nodeType) {
            case 3:
                if (fragment.nodeType == 3) {
                    node.insertData(pos, fragment.data);
                    range.setEnd(node, pos + fragment.length);
                    range.setStart(node, pos + fragment.length);
                } else {
                    node = node.splitText(pos);
                    node.parentNode.insertBefore(fragment, node);
                    range.setEnd(node, pos + fragment.length);
                    range.setStart(node, pos + fragment.length);
                }
                break;

            case 1:
                node = node.childNodes[pos];
                node.parentNode.insertBefore(fragment, node);
                range.setEnd(node, pos + fragment.length);
                range.setStart(node, pos + fragment.length);
                break;
        }
        selection.addRange(range);	
	}
}
function FTB_CheckTag(item,tagName) {
	if (item.tagName.search(tagName)!=-1) {
		return item;
	}
	if (item.tagName=='BODY') {
		return false;
	}
	item=item.parentElement;
	return FTB_CheckTag(item,tagName);
}
/** END:MAIN FREETEXTBOX FUNCTIONS ********************/

/** START:PROPERTIES ********************/
function FTB_IsHtmlMode(ftbName) {
	return (eval(ftbName + "_HtmlMode"));
}

function FTB_TabMode(ftbName) {
	return (eval(ftbName + "_TabMode"));
}

function FTB_BreakMode(ftbName) {
	return (eval(ftbName + "_BreakMode"));
}

function FTB_HtmlModeDefaultsToMonoSpaceFont(ftbName) {
	return (eval(ftbName + "_HtmlModeDefaultsToMonoSpaceFont"));
}

function FTB_HideToolbar(ftbName) {
	return (eval(ftbName + "_HideToolbar"));
}

function FTB_UpdateToolbar(ftbName) {
	return (eval(ftbName + "_UpdateToolbar"));
}

function FTB_ButtonRenderMode(ftbName) {
	return (eval(ftbName + "_ButtonRenderMode"));
}

function FTB_GetHiddenField(ftbName) {
	return document.getElementById(ftbName);
}

function FTB_GetTextDirection(ftbName) {
	return (eval(ftbName + "_TextDirection"));
}

function FTB_Initialized(ftbName) {
	return (eval(ftbName + "_Initialized"));
}

function FTB_GetIFrame(ftbName) {
	if (isIE) {
		return eval(ftbName + "_Editor");
		//return document.getElementById(ftbName + "_Editor");
	} else {
		return document.getElementById(ftbName + "_Editor").contentWindow;
	}
}

function FTB_GetToolbar(ftbName) {
	return document.getElementById(ftbName + "_Toolbar");
}
function FTB_GetToolbarArray(ftbName) {
	return eval(ftbName + "_ToolbarItems");
}
function FTB_GetCssID(ftbName) {
	cssID = ftbName;
	while (cssID.substring(0,1) == '_') {
		cssID = cssID.substring(1);
	}
	return cssID;
}

/** START: BUTTONS **************/

/** CSS BUTTON FUNCTIONS **************/
function FTB_SetButtonStyle(buttonTD,style,checkstyle) {
	if (buttonTD == null) return;
	if (buttonTD.className != checkstyle)
		buttonTD.className = style;
	
}
function FTB_GetClassSubName(className) {
	underscore = className.indexOf("_");
	if (underscore < 0) return className;
	return className.substring(underscore+1);
}

/** JS BUTTON FUNCTIONS **************/
function FTB_ButtonOver(theTD,ftbName,imageOver,imageDown) {
	FTB_SetButtonStyle(theTD,FTB_GetCssID(ftbName)+'_ButtonOver',null);
	
	//if (eval(ftbName+'_OverImage').src != '')
	//	theTD.style.backgroundImage = "url(" + eval(ftbName+'_OverImage').src + ")";
	
	if(imageOver == 1 & theTD.childNodes.length && theTD.childNodes[0].tagName == "IMG"){
		oldSrc = theTD.childNodes[0].src;
		if (oldSrc.indexOf('.over.') == -1) {
			theTD.childNodes[0].src=oldSrc.substring(0, oldSrc.length-4) + ".over.gif";
		}
	}
	
	//FTB_Event(ftbName);
}
function FTB_ButtonOut(theTD,ftbName,imageOver,imageDown) {
	FTB_SetButtonStyle(theTD,FTB_GetCssID(ftbName)+'_ButtonNormal',null);
	document.body.style.cursor = 'default';
	
	theTD.style.backgroundImage='';
	
	if(theTD.childNodes.length && theTD.childNodes[0].tagName == "IMG"){
		oldSrc = theTD.childNodes[0].src;
		if (oldSrc.indexOf('.over.') > 0) {
			theTD.childNodes[0].src=oldSrc.substring(0, oldSrc.length-9) + ".gif";
		}
		if (oldSrc.indexOf('.down.') > 0) {
			theTD.childNodes[0].src=oldSrc.substring(0, oldSrc.length-9) + ".gif";
		}
	}
	
	//FTB_Event(ftbName);
}
function FTB_ButtonDown(theTD,ftbName,imageOver,imageDown) {
	document.body.style.cursor = 'default';
	FTB_SetButtonStyle(theTD,FTB_GetCssID(ftbName)+'_ButtonDown',null);

	//if (eval(ftbName+'_DownImage').src != '') 
	//	theTD.style.backgroundImage = "url(" + eval(ftbName+'_DownImage').src + ")";
	
	if(imageDown == 1 && theTD.children.length && theTD.children[0].tagName == "IMG"){
		oldSrc = theTD.children[0].src;
		if (oldSrc.indexOf('.over.') > 0) {
			theTD.children[0].src=oldSrc.substring(0, oldSrc.length-9) + ".down.gif";
		}
	}
	
	//FTB_Event(ftbName);
}
function FTB_ButtonUp(theTD,ftbName,imageOver,imageDown) {
	document.body.style.cursor = 'auto';
	FTB_SetButtonStyle(theTD,FTB_GetCssID(ftbName)+'_ButtonOver',null);

	//if (eval(ftbName+'_OverImage').src != '')
	//	theTD.style.backgroundImage = "url(" + eval(ftbName+'_OverImage').src + ")";
	
	if(imageOver == 1 && theTD.children.length && theTD.children[0].tagName == "IMG"){
		oldSrc = theTD.children[0].src;
		if (oldSrc.indexOf('.over.') == -1) {
			theTD.children[0].src=oldSrc.substring(0, oldSrc.length-4) + ".over.gif";
		}
	}
	
	//FTB_Event(ftbName);
}

/** END:PROPERTIES ********************/

/** START:TABS ********************/
function FTB_SetActiveTab(theTD,ftbName) {
	parentTR = theTD.parentElement;
	parentTR = document.getElementById(ftbName + "_TabRow");

	selectedTab = 1;
	totalButtons = parentTR.cells.length-1;
	for (var i=1;i< totalButtons;i++) {
		parentTR.cells[i].className = FTB_GetCssID(ftbName) + "_TabOffRight";
		if (theTD == parentTR.cells[i]) { selectedTab = i; }
	}

	if (selectedTab==1) {
		parentTR.cells[0].className = FTB_GetCssID(ftbName) + "_StartTabOn";
	} else {
		parentTR.cells[0].className = FTB_GetCssID(ftbName) + "_StartTabOff";
		parentTR.cells[selectedTab-1].className = FTB_GetCssID(ftbName) + "_TabOffLeft";
	}

	theTD.className = FTB_GetCssID(ftbName) + "_TabOn";
}
function FTB_TabOver() {
	document.body.style.cursor='default';
}
function FTB_TabOut() {
	document.body.style.cursor='auto';
}
/** END:TABS ********************/

function FTB_Event(ftbName) {
	
	editor = FTB_GetIFrame(ftbName);
	htmlMode = FTB_IsHtmlMode(ftbName);
	var _TAB = 9;
	var _ENTER = 13;
	var _QUOTE = 222;
	var _OPENCURLY = '&#8220;';
	var _CLOSECURLY = '&#8221;';
	
	if (isIE) {
	// TAB Functions
		if (editor.event.keyCode == _TAB) {	

			var tabMode = FTB_TabMode(ftbName);

			if (tabMode == "Disabled") {
				editor.event.cancelBubble = true;
				editor.event.returnValue = false;
			}
			if (tabMode == "InsertSpaces") {
				FTB_InsertText(ftbName,"&nbsp;&nbsp;&nbsp;");
				editor.event.cancelBubble = true;
				editor.event.returnValue = false;
			}			
			if (tabMode == "NextControl") {
				// do nothing for TabMode.NextControl
			}	
		}

		// IE defaults to <p>, Mozilla to <br>
		if (editor.event.keyCode == _ENTER) {


			var breakMode = FTB_BreakMode(ftbName);			

			if (breakMode == "LineBreak" || editor.event.ctrlKey || htmlMode) {
				var sel = editor.document.selection;
				if (sel.type == 'Control') {
					return;
				}
				var r = sel.createRange();
				if ((!FTB_CheckTag(r.parentElement(),'LI'))&&(!FTB_CheckTag(r.parentElement(),'H'))) {
					r.pasteHTML('<br>');
					editor.event.cancelBubble = true; 
					editor.event.returnValue = false; 
					r.select();
					r.collapse(false);
					return false;
				}					
			}
		}
	}
	
	// update ToolbarItems only every 50 milliseconds b/c it is expensive
	if (!htmlMode && FTB_UpdateToolbar(ftbName)) {		
		if (editor.timerToolbar) {
			clearTimeout(editor.timerToolbar);
		}
		editor.timerToolbar = setTimeout(function() {
			FTB_SetToolbarItems(ftbName);
			editor.timerToolbar = null;
		}, 50);	
	}
}

function FTB_SetToolbarItems(ftbName) {
	editor = FTB_GetIFrame(ftbName);
	htmlMode = FTB_IsHtmlMode(ftbName);
	toolbarArray = 	FTB_GetToolbarArray(ftbName);
		
	//document.getElementById("Debug").value = "";
	
	if (toolbarArray) {
		for (var i=0; i<toolbarArray.length; i++) {
			toolbarItemID = toolbarArray[i][0];
			toolbarItem = document.getElementById(toolbarItemID);
			commandIdentifier = toolbarArray[i][1];

			state = "";
			try {
				if (toolbarItemID.indexOf("Button") > -1) {
					state = editor.document.queryCommandState(commandIdentifier);

					FTB_SetButtonState(toolbarItemID,ftbName,state);
				} else {
					state = editor.document.queryCommandValue(commandIdentifier);
					
					switch (commandIdentifier) {
						case "backcolor":
							if (isIE) {
								state = FTB_GetHexColor(state);
							} else {
								if (state == "") state = "#FFFFFF";
							}
							break;						
						case "forecolor":
							if (isIE) {
								state = FTB_GetHexColor(state);
							} else {
								if (state == "") state = "#000000";
							}
							break;
						case "formatBlock":
							//document.getElementById("Debug").value += "****: " + state + "\n";
							if (!isIE) {
								if (state == "p" || state == "" || state == "<x>") 
									state = "<body>";
								else 
									state = "<" + state + ">";							
							}
							break;					
					}
						
					//document.getElementById("Debug").value += commandIdentifier + ": " + state + "\n";
					
					FTB_SetDropDownListState(toolbarItemID,state);					
				}
			} catch(e) {
			}
		}
	}
}

function FTB_GetHexColor(intColor) {
	intColor = intColor.toString(16).toUpperCase();
	while (intColor.length < 6) {
		intColor = "0" + intColor;
	}
	return "#" + intColor.substring(4,6) + intColor.substring(2,4) + intColor.substring(0,2);
}

function FTB_SetDropDownListState(ddlName,value) {
	ddl = document.getElementById(ddlName);
	
	if (ddl) {
		for (var i=0; i<ddl.options.length; i++) {
			if (ddl.options[i].text == value || ddl.options[i].value == value) {
				ddl.options.selectedIndex = i;
				return;
			}	
		}
	}
}

function FTB_SetButtonState(buttonName,ftbName,value) {
	buttonTD = document.getElementById(buttonName);
	
	if (buttonTD) {
		if (value) {
			if (FTB_ButtonRenderMode(ftbName) == 'Css') 
				buttonTD.className = FTB_GetCssID(ftbName) + "_ButtonActive";
			else 
				FTB_ButtonOver(buttonTD,ftbName,0,0);
		} else {
			if (FTB_ButtonRenderMode(ftbName) == 'Css') 
				buttonTD.className = FTB_GetCssID(ftbName) + "_ButtonNormal";
			else 
				FTB_ButtonOut(buttonTD,ftbName,0,0);
		}
	}
}

// *******************************

function FTB_GetParentElement(ftbName) {
	editor = FTB_GetIFrame(ftbName);

	var sel = FTB_GetSelection(ftbName);
	var range = FTB_CreateRange(ftbName,sel);
	if (isIE) {
		switch (sel.type) {
		    case "Text":
		    case "None":
				// It seems that even for selection of type "None",
				// there _is_ a parent element and it's value is not
				// only correct, but very important to us.  MSIE is
				// certainly the buggiest browser in the world and I
				// wonder, God, how can Earth stand it?
				return range.parentElement();
		    case "Control":
				return range.item(0);
		    default:
				return editor.document.body;
		}
	} else try {
		var p = range.commonAncestorContainer;
		if (!range.collapsed && range.startContainer == range.endContainer &&
		    range.startOffset - range.endOffset <= 1 && range.startContainer.hasChildNodes())
			p = range.startContainer.childNodes[range.startOffset];
		/*
		alert(range.startContainer + ":" + range.startOffset + "\n" +
		      range.endContainer + ":" + range.endOffset);
		*/
		while (p.nodeType == 3) {
			p = p.parentNode;
		}
		return p;
	} catch (e) {
		return null;
	}
}

function FTB_InsertNodeAtSelection(ftbName,toBeInserted) {
	if (!isIE) {
		var editor = FTB_GetIFrame(ftbName);
		var sel = FTB_GetSelection(ftbName);
		var range = FTB_CreateRange(ftbName,sel);
		// remove the current selection
		sel.removeAllRanges();
		range.deleteContents();
		var node = range.startContainer;
		var pos = range.startOffset;
		switch (node.nodeType) {
		    case 3: // Node.TEXT_NODE
			// we have to split it at the caret position.
			if (toBeInserted.nodeType == 3) {
				// do optimized insertion
				node.insertData(pos, toBeInserted.data);
				range = this._createRange();
				range.setEnd(node, pos + toBeInserted.length);
				range.setStart(node, pos + toBeInserted.length);
				sel.addRange(range);
			} else {
				node = node.splitText(pos);
				var selnode = toBeInserted;
				if (toBeInserted.nodeType == 11 /* Node.DOCUMENT_FRAGMENT_NODE */) {
					selnode = selnode.firstChild;
				}
				node.parentNode.insertBefore(toBeInserted, node);
				editor.selectNodeContents(selnode);
			}
			break;
		    case 1: // Node.ELEMENT_NODE
			var selnode = toBeInserted;
			if (toBeInserted.nodeType == 11 /* Node.DOCUMENT_FRAGMENT_NODE */) {
				selnode = selnode.firstChild;
			}
			node.insertBefore(toBeInserted, node.childNodes[pos]);
			FTB_SelectNodeContents(editor,selnode);
			break;
		}
	}
}

// Selects the contents inside the given node
function FTB_SelectNodeContents(ftbName, node, pos) {
	

	editor = FTB_GetIFrame(ftbName);
	

	var range;
	var collapsed = (typeof pos != "undefined");
	if (isIE) {
		range = editor.document.body.createTextRange();
		range.moveToElementText(node);
		(collapsed) && range.collapse(pos);
		range.select();
	} else {
		var sel = FTB_GetSelection(ftbName);
		range = editor.document.createRange();
		range.selectNodeContents(node);
		(collapsed) && range.collapse(pos);
		sel.removeAllRanges();
		sel.addRange(range);
	}
};

// returns the current selection object
function FTB_GetSelection(ftbName) {
	editor = FTB_GetIFrame(ftbName);
	if (isIE) {
		return editor.document.selection;
	} else {
		return editor.getSelection();
	}
}

// returns a range for the current selection
function FTB_CreateRange(ftbName,sel) {
	editor = FTB_GetIFrame(ftbName);
	if (isIE) {
		return sel.createRange();
	} else {
		//TODO: this.focusEditor();
		if (typeof sel != "undefined") {
			try {
				return sel.getRangeAt(0);
			} catch(e) {
				return editor.document.createRange();
			}
		} else {
			return editor.document.createRange();
		}
	}
}

/* TABLE FUNCTIONS 
   MODIFIED FROM HtmlArea (thanks guys!)
**********************************************/

// helper function that clears the content in a table row
function FTB_ClearRow(tr) {
	var tds = tr.getElementsByTagName("td");
	for (var i = tds.length; --i >= 0;) {
		var td = tds[i];
		td.rowSpan = 1;
		td.innerHTML = (isIE) ? "" : "<br />";
	}
}

function FTB_SplitRow(td) {
	var n = parseInt("" + td.rowSpan);
	var nc = parseInt("" + td.colSpan);
	td.rowSpan = 1;
	tr = td.parentNode;
	var itr = tr.rowIndex;
	var trs = tr.parentNode.rows;
	var index = td.cellIndex;
	while (--n > 0) {
		tr = trs[++itr];
		var otd = editor._doc.createElement("td");
		otd.colSpan = td.colSpan;
		otd.innerHTML = mozbr;
		tr.insertBefore(otd, tr.cells[index]);
	}
	//editor.forceRedraw();
	//editor.updateToolbar();
}

function FTB_SplitCol(td) {
	var nc = parseInt("" + td.colSpan);
	td.colSpan = 1;
	tr = td.parentNode;
	var ref = td.nextSibling;
	while (--nc > 0) {
		var otd = editor._doc.createElement("td");
		otd.rowSpan = td.rowSpan;
		otd.innerHTML = mozbr;
		tr.insertBefore(otd, ref);
	}
	//editor.forceRedraw();
	//editor.updateToolbar();
}

function FTB_SplitCell(td) {
	var nc = parseInt("" + td.colSpan);
	splitCol(td);
	var items = td.parentNode.cells;
	var index = td.cellIndex;
	while (nc-- > 0) {
		FTB_SplitRow(items[index++]);
	}
}

function FTB_SelectNextNode(el) {
	var node = el.nextSibling;
	while (node && node.nodeType != 1) {
		node = node.nextSibling;
	}
	if (!node) {
		node = el.previousSibling;
		while (node && node.nodeType != 1) {
			node = node.previousSibling;
		}
	}
	if (!node) {
		node = el.parentNode;
	}
	//editor.selectNodeContents(node);
}

function FTB_GetClosest(ftbName,tagName) {
	var editor = FTB_GetIFrame(ftbName);
	var ancestors = FTB_GetAllAncestors(ftbName);
	var ret = null;
	tagName = ("" + tagName).toLowerCase();
	for (var i in ancestors) {
		var el = ancestors[i];
		if (el.tagName.toLowerCase() == tagName) {
			ret = el;
			break;
		}
	}
	return ret;
}
function FTB_GetAllAncestors(ftbName) {
	editor = FTB_GetIFrame(ftbName);
	var p = FTB_GetParentElement(ftbName);
	var a = [];
	while (p && (p.nodeType == 1) && (p.tagName.toLowerCase() != 'body')) {
		a.push(p);
		p = p.parentNode;
	}
	a.push(editor.document.body);
	return a;
}
function FTB_InsertColumn(ftbName,after) {
   editor = FTB_GetIFrame(ftbName);
   var td = FTB_GetClosest(ftbName,"td");
   if (!td) {
      return;
   }
   var rows = td.parentNode.parentNode.rows;
   var index = td.cellIndex;
   for (var i = rows.length; --i >= 0;) {
      var tr = rows[i];
      var otd = editor.document.createElement("td");
      otd.innerHTML = (isIE) ? "" : "<br />";

      //if last column and insert column after is select append child
      if (index==tr.cells.length-1 && after) {
         tr.appendChild(otd);
      } else {
         var ref = tr.cells[index + ((after) ? 1 : 0)]; // 0 
         tr.insertBefore(otd, ref);
      } 
   }
}
function FTB_InsertTableRow(ftbName,after) { 
	if (FTB_IsHtmlMode(ftbName)) return;	
	var tr = FTB_GetClosest(ftbName,"tr");
	if (!tr) {
		return;
	}
	var otr = tr.cloneNode(true);
	FTB_ClearRow(otr);
	tr.parentNode.insertBefore(otr, ((after) ? tr.nextSibling : tr));
}
function FTB_CreateTable(ftbName,cols,rows,width,widthUnit,align,cellpadding,cellspacing,border) {
	var editor = FTB_GetIFrame(ftbName);
	var sel = FTB_GetSelection(ftbName);
	var range = FTB_CreateRange(ftbName,sel);	
	
	var doc = editor.document;
	// create the table element
	var table = doc.createElement("<table class=ctable>");
	

	// assign the given arguments
	table.style.width 	= width + widthUnit;
	table.align	 		= align;
	table.border	 	= border;
	table.cellspacing 	= cellspacing;
	table.cellpadding 	= cellpadding;

	
	var tbody = doc.createElement("tbody");
	table.appendChild(tbody);	

	for (var i = 0; i < rows; ++i) {
		var tr = doc.createElement("tr");
		tbody.appendChild(tr);
		for (var j = 0; j < cols; ++j) {
			var td = null;
			//doc.createElement("td");		 //cellhead, celldata, cellfoot
			
			if(rows > 2 && i == rows - 1)
				td = doc.createElement("<td class=cellfoot>");
			else if (rows > 1 && i == 0)
				td = doc.createElement("<td class=cellhead>");
			else
				td = doc.createElement("<td class=celldata>");
			
			tr.appendChild(td);
			// Mozilla likes to see something inside the cell.
			if (!isIE) td.appendChild(doc.createElement("br"));
		}
	}
	
	if (isIE) {
		range.pasteHTML(table.outerHTML);
	} else {
		FTB_InsertNodeAtSelection(ftbName,table);
	}
	
	return true;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
Since 2001 I've been writing .NET applications in C# and architecting n-tier applications in the enterprise. Before that I worked as a tech writer for nine years. Don't bother doing the math. I'm old. Ever since I laid eyes on my first Commodore PET, I've been a technologist. I've worked in the software world for fifteen years. I started as a technical writer and learned to code from the best engineers as I worked with them in creating technical documentation. It was then that I learned that writing code was more fun and frankly easier than writing about code. I've been doing both ever since. You can visit my blog at http://www.tsjensen.com/blog.

Comments and Discussions