Comments are available to members only. Sign up or Log in to view these comments.
Main Topics
Browse All TopicsI cant get a value from this via the ID...
<script>
WYSIWYG.attach('whythis', small);
</script>
<textarea id="whythis" name="test1" style="width:500px;height:
<img src="" onclick="doit();">
<script>
function doit(){
var blah = document.getElementById('w
alert(blah);
}
</script>
CODE:
====================
/*************************
* openWYSIWYG v1.46c Copyright (c) 2006 openWebWare.com
* Contact us at devs@openwebware.com
* This copyright notice MUST stay intact for use.
*
* $Id: wysiwyg.js,v 1.10 2006/12/25 09:17:07 xhaggi Exp $
*
* An open source WYSIWYG editor for use in web based applications.
* For full source code and docs, visit http://www.openwebware.com
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with this library; if not, write to the Free Software Foundation, Inc., 59
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
**************************
var WYSIWYG = {
/**
* Settings class, holds all customizeable properties
*/
Settings: function() {
// Images Directory
this.ImagesDir = "/common/js/wysiwyg2/image
// Popups Directory
this.PopupsDir = "/common/js/wysiwyg2/popup
// CSS Directory File
this.CSSFile = "/common/js/wysiwyg2/style
// Default WYSIWYG width and height (use px or %)
this.Width = "500px";
this.Height = "200px";
// Default stylesheet of the WYSIWYG editor window
this.DefaultStyle = "font-family: Arial; font-size: 12px; background-color: #FFFFFF";
// Stylesheet if editor is disabled
this.DisabledStyle = "font-family: Arial; font-size: 12px; background-color: #EEEEEE";
// Width + Height of the preview window
this.PreviewWidth = 500;
this.PreviewHeight = 400;
// Confirmation message if you strip any HTML added by word
this.RemoveFormatConfMessa
// Nofication if browser is not supported by openWYSIWYG, leave it blank for no message output.
this.NoValidBrowserMessage
// Anchor path to strip, leave it blank to ignore
// or define auto to strip the path where the editor is placed
// (only IE)
this.AnchorPathToStrip = "auto";
// Image path to strip, leave it blank to ignore
// or define auto to strip the path where the editor is placed
// (only IE)
this.ImagePathToStrip = "auto";
// Enable / Disable the custom context menu
this.ContextMenu = true;
// Enabled the status bar update. Within the status bar
// node tree of the actually selected element will build
this.StatusBarEnabled = true;
// If enabled than the capability of the IE inserting line breaks will be inverted.
// Normal: ENTER = <p> , SHIFT + ENTER = <br>
// Inverted: ENTER = <br>, SHIFT + ENTER = <p>
this.InvertIELineBreaks = false;
// Replace line breaks with <br> tags
this.ReplaceLineBreaks = false;
// Insert image implementation
this.ImagePopupFile = "";
this.ImagePopupWidth = 0;
this.ImagePopupHeight = 0;
// Holds the available buttons displayed
// on the toolbar of the editor
this.Toolbar = new Array();
this.Toolbar[0] = new Array(
"font",
"fontsize",
"bold",
"italic",
"underline",
"strikethrough",
"seperator",
"forecolor",
"backcolor",
"seperator",
"justifyleft",
"justifycenter",
"justifyright",
"seperator",
"unorderedlist",
"orderedlist",
"outdent",
"indent"
);
this.Toolbar[1] = new Array(
"subscript",
"superscript",
"seperator",
"cut",
"copy",
"paste",
"removeformat",
"seperator",
"undo",
"redo",
"seperator",
"inserttable",
"insertimage",
"createlink",
"seperator",
"preview",
"print",
"seperator",
"viewSource",
"seperator",
"help"
);
// List of available font types
this.Fonts = new Array(
"Arial",
"Sans Serif",
"Tahoma",
"Verdana",
"Courier New",
"Georgia",
"Times New Roman",
"Impact",
"Comic Sans MS"
);
// List of available font sizes
this.Fontsizes = new Array(
"1",
"2",
"3",
"4",
"5",
"6",
"7"
);
// Add the given element to the defined toolbar
// on the defined position
this.addToolbarElement = function(element, toolbar, position) {
if(element != "seperator") {this.removeToolbarElement
if(this.Toolbar[toolbar-1]
this.Toolbar[toolbar-1] = new Array();
}
this.Toolbar[toolbar-1].sp
};
// Remove an element from the toolbar
this.removeToolbarElement = function(element) {
if(element == "seperator") {return;} // do not remove seperators
for(var i=0;i<this.Toolbar.length;
if(this.Toolbar[i]) {
var toolbar = this.Toolbar[i];
for(var j=0;j<toolbar.length;j++) {
if(toolbar[j] != null && toolbar[j] == element) {
this.Toolbar[i].splice(j,1
}
}
}
}
};
// clear all or a given toolbar
this.clearToolbar = function(toolbar) {
if(typeof toolbar == "undefined") {
this.Toolbar = new Array();
}
else {
this.Toolbar[toolbar+1] = new Array();
}
};
},
/* --------------------------
!! Do not change something below or you know what you are doning !!
\* --------------------------
// List of available block formats (not in use)
//BlockFormats: new Array("Address", "Bulleted List", "Definition", "Definition Term", "Directory List", "Formatted", "Heading 1", "Heading 2", "Heading 3", "Heading 4", "Heading 5", "Heading 6", "Menu List", "Normal", "Numbered List"),
// List of available actions and their respective ID and images
ToolbarList: {
//Name buttonID buttonTitle buttonImage buttonImageRollover
"bold": ['Bold', 'Bold', 'bold.gif', 'bold_on.gif'],
"italic": ['Italic', 'Italic', 'italics.gif', 'italics_on.gif'],
"underline": ['Underline', 'Underline', 'underline.gif', 'underline_on.gif'],
"strikethrough": ['Strikethrough', 'Strikethrough', 'strikethrough.gif', 'strikethrough_on.gif'],
"seperator": ['', '', 'seperator.gif', 'seperator.gif'],
"subscript": ['Subscript', 'Subscript', 'subscript.gif', 'subscript_on.gif'],
"superscript": ['Superscript', 'Superscript', 'superscript.gif', 'superscript_on.gif'],
"justifyleft": ['Justifyleft', 'Justifyleft', 'justify_left.gif', 'justify_left_on.gif'],
"justifycenter": ['Justifycenter', 'Justifycenter', 'justify_center.gif', 'justify_center_on.gif'],
"justifyright": ['Justifyright', 'Justifyright', 'justify_right.gif', 'justify_right_on.gif'],
"unorderedlist": ['InsertUnorderedList', 'Insert Unordered List', 'list_unordered.gif', 'list_unordered_on.gif'],
"orderedlist": ['InsertOrderedList', 'Insert Ordered List', 'list_ordered.gif', 'list_ordered_on.gif'],
"outdent": ['Outdent', 'Outdent', 'indent_left.gif', 'indent_left_on.gif'],
"indent": ['Indent', 'Indent', 'indent_right.gif', 'indent_right_on.gif'],
"cut": ['Cut', 'Cut', 'cut.gif', 'cut_on.gif'],
"copy": ['Copy', 'Copy', 'copy.gif', 'copy_on.gif'],
"paste": ['Paste', 'Paste', 'paste.gif', 'paste_on.gif'],
"forecolor": ['ForeColor', 'Fore Color', 'forecolor.gif', 'forecolor_on.gif'],
"backcolor": ['BackColor', 'Back Color', 'backcolor.gif', 'backcolor_on.gif'],
"undo": ['Undo', 'Undo', 'undo.gif', 'undo_on.gif'],
"redo": ['Redo', 'Redo', 'redo.gif', 'redo_on.gif'],
"inserttable": ['InsertTable', 'Insert Table', 'insert_table.gif', 'insert_table_on.gif'],
"insertimage": ['InsertImage', 'Insert Image', 'insert_picture.gif', 'insert_picture_on.gif'],
"createlink": ['CreateLink', 'Create Link', 'insert_hyperlink.gif', 'insert_hyperlink_on.gif']
"viewSource": ['ViewSource', 'View Source', 'view_source.gif', 'view_source_on.gif'],
"viewText": ['ViewText', 'View Text', 'view_text.gif', 'view_text_on.gif'],
"help": ['Help', 'Help', 'help.gif', 'help_on.gif'],
"selectfont": ['SelectFont', 'Select Font', 'select_font.gif', 'select_font_on.gif'],
"selectsize": ['SelectSize', 'Select Size', 'select_size.gif', 'select_size_on.gif'],
"preview": ['Preview', 'Preview', 'preview.gif', 'preview_on.gif'],
"print": ['Print', 'Print', 'print.gif', 'print_on.gif'],
"removeformat": ['RemoveFormat', 'Strip Word HTML', 'remove_format.gif', 'remove_format_on.gif'],
"delete": ['Delete', 'Delete', 'delete.gif', 'delete_on.gif']
},
// stores the different settings for each textarea
// the textarea identifier is used to store the settings object
config: new Array(),
// Create viewTextMode global variable and set to 0
// enabling all toolbar commands while in HTML mode
viewTextMode: new Array(),
/**
* Get the range of the given selection
*
* @param {Selection} sel Selection object
* @return {Range} Range object
*/
getRange: function(sel) {
return sel.createRange ? sel.createRange() : sel.getRangeAt(0);
},
/**
* Get the iframe object of the WYSIWYG editor
*
* @param {String} n Editor identifier
* @return {HtmlIframeObject} Iframe object
*/
getEditor: function(n) {
return $("wysiwyg" + n);
},
/**
* Get editors window element
*
* @param {String} n Editor identifier
* @return {Object} Html window object
*/
getEditorWindow: function(n) {
return this.getEditor(n).contentW
},
/**
* Attach the WYSIWYG editor to the given textarea element
*
* @param {String} id Textarea identifier (all = all textareas)
* @param {Settings} settings the settings which will be applied to the textarea
*/
attach: function(id, settings) {
if(id != "all") {
this.setSettings(id, settings);
WYSIWYG_Core.includeCSS(th
WYSIWYG_Core.addEvent(wind
}
else {
WYSIWYG_Core.addEvent(wind
}
},
/**
* Attach the WYSIWYG editor to all textarea elements
*
* @param {Settings} settings Settings to customize the look and feel
*/
attachAll: function(settings) {
var areas = document.getElementsByTagN
for(var i=0;i<areas.length;i++) {
var id = areas[i].getAttribute("id"
if(id == null || id == "") continue;
this.setSettings(id, settings);
WYSIWYG_Core.includeCSS(th
WYSIWYG._generate(id, settings);
}
},
/**
* Display an iframe instead of the textarea.
* It's used as textarea replacement to display HTML.
*
* @param id Textarea identifier (all = all textareas)
* @param settings the settings which will be applied to the textarea
*/
display: function(id, settings) {
if(id != "all") {
this.setSettings(id, settings);
WYSIWYG_Core.includeCSS(th
WYSIWYG_Core.addEvent(wind
}
else {
WYSIWYG_Core.addEvent(wind
}
},
/**
* Display an iframe instead of the textarea.
* It's apply the iframe to all textareas found in the current document.
*
* @param settings Settings to customize the look and feel
*/
displayAll: function(settings) {
var areas = document.getElementsByTagN
for(var i=0;i<areas.length;i++) {
var id = areas[i].getAttribute("id"
if(id == null || id == "") continue;
this.setSettings(id, settings);
WYSIWYG_Core.includeCSS(th
WYSIWYG._display(id, settings);
}
},
/**
* Set settings in config array, use the textarea id as identifier
*
* @param n Textarea identifier (all = all textareas)
* @param settings the settings which will be applied to the textarea
*/
setSettings: function(n, settings) {
if(typeof(settings) != "object") {
this.config[n] = new this.Settings();
}
else {
this.config[n] = settings;
}
},
/* --------------------------
Function : insertImage()
Description : insert an image into WYSIWYG in rich text
Usage : WYSIWYG.insertImage("test.
Arguments : src - Source of the image
width - Width
height - Height
align - Alignment of the image
border - border
alt - Alternativ Text
hspace - Horizontal Space
vspace - Vertical Space
n - The editor identifier (the textarea's ID)
\* --------------------------
insertImage: function(src, width, height, align, border, alt, hspace, vspace, n) {
// get editor
var doc = this.getEditorWindow(n).do
// get selection and range
var sel = this.getSelection(n);
var range = this.getRange(sel);
// the current tag of range
var img = this.findParentTag("img", range);
// element is not a link
var update = (img == null) ? false : true;
if(!update) {
img = doc.createElement("img");
}
// set the attributes
WYSIWYG_Core.setAttribute(
WYSIWYG_Core.setAttribute(
if(align != "") { WYSIWYG_Core.setAttribute(
WYSIWYG_Core.setAttribute(
WYSIWYG_Core.setAttribute(
WYSIWYG_Core.setAttribute(
WYSIWYG_Core.setAttribute(
img.removeAttribute("width
img.removeAttribute("heigh
// on update exit here
if(update) { return; }
// Check if IE or Mozilla (other)
if (WYSIWYG_Core.isMSIE) {
range.pasteHTML(img.outerH
}
else {
this.insertNodeAtSelection
}
},
/* --------------------------
Function : insertLink()
Description : insert a link into WYSIWYG in rich text
Usage : WYSIWYG.insertLink("http:/
Arguments : href - The link url
target - Target of the link
style - Stylesheet of the link
styleClass - Stylesheet class of the link
name - Name attribute of the link
n - The editor identifier (the textarea's ID)
\* --------------------------
insertLink: function(href, target, style, styleClass, name, n) {
// get editor
var doc = this.getEditorWindow(n).do
// get selection and range
var sel = this.getSelection(n);
var range = this.getRange(sel);
var lin = null;
// get element from selection
if(WYSIWYG_Core.isMSIE) {
if(sel.type == "Control" && range.length == 1) {
range = this.getTextRange(range(0)
range.select();
}
}
// find a as parent element
lin = this.findParentTag("a", range);
// check if parent is found
var update = (lin == null) ? false : true;
if(!update) {
lin = doc.createElement("a");
}
// set the attributes
WYSIWYG_Core.setAttribute(
WYSIWYG_Core.setAttribute(
WYSIWYG_Core.setAttribute(
WYSIWYG_Core.setAttribute(
WYSIWYG_Core.setAttribute(
WYSIWYG_Core.setAttribute(
// on update exit here
if(update) { return; }
// Check if IE or Mozilla (other)
if (WYSIWYG_Core.isMSIE) {
range.select();
lin.innerHTML = range.htmlText;
range.pasteHTML(lin.outerH
}
else {
var node = range.startContainer;
var pos = range.startOffset;
if(node.nodeType != 3) { node = node.childNodes[pos]; }
if(node.tagName)
lin.appendChild(node);
else
lin.innerHTML = sel;
this.insertNodeAtSelection
}
},
/* --------------------------
Function : removeFormat()
Description : Strip any HTML added by word
Usage : removeFormat(n)
Arguments : n - The editor identifier (the textarea's ID)
\* --------------------------
removeFormat: function(n) {
if ( !confirm(this.config[n].Re
var doc = this.getEditorWindow(n).do
var str = doc.body.innerHTML;
str = str.replace(/<span([^>])*>
str = str.replace(/<span[^>]*>/g
str = str.replace(/<\/span[^>]*>
str = str.replace(/<p([^>])*>(&n
str = str.replace(/<p[^>]*>/gi, '');
str = str.replace(/<\/p[^>]*>/gi
str = str.replace(/<h([^>])[0-9]
str = str.replace(/<h[^>][0-9]>/
str = str.replace(/<\/h[^>][0-9]
str = str.replace (/<B [^>]*>/ig, '<b>');
// var repl_i1 = /<I[^>]*>/ig;
// str = str.replace (repl_i1, '<i>');
str = str.replace (/<DIV[^>]*>/ig, '');
str = str.replace (/<\/DIV>/gi, '');
str = str.replace (/<[\/\w?]+:[^>]*>/ig, '');
str = str.replace (/( ){2,}/ig, ' ');
str = str.replace (/<STRONG>/ig, '');
str = str.replace (/<\/STRONG>/ig, '');
str = str.replace (/<TT>/ig, '');
str = str.replace (/<\/TT>/ig, '');
str = str.replace (/<FONT [^>]*>/ig, '');
str = str.replace (/<\/FONT>/ig, '');
str = str.replace (/STYLE=\"[^\"]*\"/ig, '');
str = str.replace(/<([\w]+) class=([^ |>]*)([^>]*)/gi, '<$1$3');
str = str.replace(/<([\w]+) style="([^"]*)"([^>]*)/gi,
str = str.replace(/width=([^ |>]*)([^>]*)/gi, '');
str = str.replace(/classname=([^
str = str.replace(/align=([^ |>]*)([^>]*)/gi, '');
str = str.replace(/valign=([^ |>]*)([^>]*)/gi, '');
str = str.replace(/<\\?\??xml[^>
str = str.replace(/<\/?\w+:[^>]*
str = str.replace(/<st1:.*?>/gi,
str = str.replace(/o:/gi, '');
str = str.replace(/<!--([^>])*>(
str = str.replace(/<!--[^>]*>/gi
str = str.replace(/<\/--[^>]*>/g
doc.body.innerHTML = str;
},
/**
* Display an iframe instead of the textarea.
*
* @param n - ID of textarea to replace
* @param settings - object which holds the settings
*/
_display: function(n, settings) {
// Get the textarea element
var textarea = $(n);
// Validate if textarea exists
if(textarea == null) {
alert("No textarea found with the given identifier (ID: " + n + ").");
return;
}
// Validate browser compatiblity
if(!WYSIWYG_Core.isBrowser
if(this.config[n].NoValidB
return;
}
// Load settings in config array, use the textarea id as identifier
if(typeof(settings) != "object") {
this.config[n] = new this.Settings();
}
else {
this.config[n] = settings;
}
// Hide the textarea
textarea.style.display = "none";
// Override the width and height of the editor with the
// size given by the style attributes width and height
if(textarea.style.width) {
this.config[n].Width = textarea.style.width;
}
if(textarea.style.height) {
this.config[n].Height = textarea.style.height
}
// determine the width + height
var currentWidth = this.config[n].Width;
var currentHeight = this.config[n].Height;
// Calculate the width + height of the editor
var ifrmWidth = "100%";
var ifrmHeight = "100%";
if(currentWidth.search(/%/
ifrmWidth = currentWidth;
ifrmHeight = currentHeight;
}
// Create iframe which will be used for rich text editing
var iframe = '<table cellpadding="0" cellspacing="0" border="0" style="width:' + currentWidth + '; height:' + currentHeight + ';" class="tableTextareaEditor
+ '<iframe frameborder="0" id="wysiwyg' + n + '" class="iframeText" style="width:' + ifrmWidth + ';height:' + ifrmHeight + ';"></iframe>\n'
+ '</td></tr></table>\n';
// Insert after the textArea both toolbar one and two
textarea.insertAdjacentHTM
// Pass the textarea's existing text over to the content variable
var content = textarea.value;
var doc = this.getEditorWindow(n).do
// Replace all \n with <br>
if(this.config[n].ReplaceL
content = content.replace(/(\r\n)|(\
}
// Write the textarea's content into the iframe
doc.open();
doc.write(content);
doc.close();
// Set default style of the editor window
WYSIWYG_Core.setAttribute(
},
/**
* Replace the given textarea with wysiwyg editor
*
* @param n - ID of textarea to replace
* @param settings - object which holds the settings
*/
_generate: function(n, settings) {
// Get the textarea element
var textarea = $(n);
// Validate if textarea exists
if(textarea == null) {
alert("No textarea found with the given identifier (ID: " + n + ").");
return;
}
// Validate browser compatiblity
if(!WYSIWYG_Core.isBrowser
if(this.config[n].NoValidB
return;
}
// Hide the textarea
textarea.style.display = 'none';
// Override the width and height of the editor with the
// size given by the style attributes width and height
if(textarea.style.width) {
this.config[n].Width = textarea.style.width;
}
if(textarea.style.height) {
this.config[n].Height = textarea.style.height
}
// determine the width + height
var currentWidth = this.config[n].Width;
var currentHeight = this.config[n].Height;
// Calculate the width + height of the editor
var toolbarWidth = currentWidth;
var ifrmWidth = "100%";
var ifrmHeight = "100%";
if(currentWidth.search(/%/
toolbarWidth = currentWidth.replace(/px/g
toolbarWidth = (parseFloat(toolbarWidth) + 2) + "px";
ifrmWidth = currentWidth;
ifrmHeight = currentHeight;
}
// Generate the WYSIWYG Table
// This table holds the toolbars and the iframe as the editor
var editor = "";
editor += '<table border="0" cellpadding="0" cellspacing="0" class="tableTextareaEditor
editor += '<tr><td>';
// Output all command buttons that belong to toolbar one
for (var j = 0; j < this.config[n].Toolbar.len
if(this.config[n].Toolbar[
var toolbar = this.config[n].Toolbar[j];
// Generate WYSIWYG toolbar one
editor += '<table border="0" cellpadding="0" cellspacing="0" class="toolbar1" style="width:100%;" id="toolbar' + j + '_' + n + '">';
editor += '<tr><td style="width: 6px;"><img src="' + this.config[n].ImagesDir + 'seperator2.gif" alt="" hspace="3"></td>';
for (var i = 0; i < toolbar.length;i++) {
if (toolbar[i]) {
// Font selection
if (toolbar[i] == "font"){
editor += '<td style="width: 90px;"><span id="FontSelect' + n + '"></span></td>';
}
// Font size selection
else if (toolbar[i] == "fontsize"){
editor += '<td style="width: 60px;"><span id="FontSizes' + n + '"></span></td>';
}
// Button print out
else {
// Get the values of the Button from the global ToolbarList object
var buttonObj = this.ToolbarList[toolbar[i
var buttonID = buttonObj[0];
var buttonTitle = buttonObj[1];
var buttonImage = this.config[n].ImagesDir + buttonObj[2];
var buttonImageRollover = this.config[n].ImagesDir + buttonObj[3];
if (toolbar[i] == "seperator") {
editor += '<td style="width: 12px;" align="center">';
editor += '<img src="' + buttonImage + '" border=0 unselectable="on" width="2" height="18" hspace="2" unselectable="on">';
editor += '</td>';
}
// View Source button
else if (toolbar[i] == "viewSource"){
editor += '<td style="width: 22px;">';
editor += '<span id="HTMLMode' + n + '"><img src="' + buttonImage + '" border="0" unselectable="on" title="' + buttonTitle + '" id="' + buttonID + '" class="buttonEditor" onmouseover="this.classNam
editor += '<span id="textMode' + n + '"><img src="' + this.config[n].ImagesDir + 'view_text.gif" border="0" unselectable="on" title="viewText" id="ViewText" class="buttonEditor" onmouseover="this.classNam
editor += '</td>';
}
else {
editor += '<td style="width: 22px;">';
editor += '<img src="' + buttonImage + '" border=0 unselectable="on" title="' + buttonTitle + '" id="' + buttonID + '" class="buttonEditor" onmouseover="this.classNam
editor += '</td>';
}
}
}
}
editor += '<td> </td></tr></tab
}
}
editor += '</td></tr><tr><td valign="top">\n';
// Create iframe which will be used for rich text editing
editor += '<iframe frameborder="0" id="wysiwyg' + n + '" class="iframeText" style="width:100%;height:'
+ '</td></tr>';
// Status bar HTML code
if(this.config[n].StatusBa
editor += '<tr><td class="wysiwyg-statusbar" style="height:10px;" id="wysiwyg_statusbar_' + n + '"> </td></tr>';
}
editor += '</table>\n';
// Insert the editor after the textarea
textarea.insertAdjacentHTM
// Insert the Font Type and Size drop downs into the toolbar
// Hide the dynamic drop down lists for the Font Types and Sizes
this.outputFontSelect(n);
this.outputFontSizes(n);
this.hideFonts(n);
this.hideFontSizes(n);
// Hide the "Text Mode" button
// Validate if textMode Elements are prensent
if($("textMode" + n)) {
$("textMode" + n).style.display = 'none';
}
// Pass the textarea's existing text over to the content variable
var content = textarea.value;
var doc = this.getEditorWindow(n).do
// Replace all \n with <br>
if(this.config[n].ReplaceL
content = content.replace(/\n\r|\n/i
}
// Write the textarea's content into the iframe
doc.open();
doc.write(content);
doc.close();
// Make the iframe editable in both Mozilla and IE
// Improve compatiblity for IE + Mozilla
if (doc.body.contentEditable)
doc.body.contentEditable = true;
}
else {
doc.designMode = "on";
}
// Set default font style
WYSIWYG_Core.setAttribute(
// Event Handling
// Update the textarea with content in WYSIWYG when user submits form
for (var idx=0; idx < document.forms.length; idx++) {
WYSIWYG_Core.addEvent(docu
}
// close font selection if mouse moves over the editor window
WYSIWYG_Core.addEvent(doc,
// If it's true invert the line break capability of IE
if(this.config[n].InvertIE
WYSIWYG_Core.addEvent(doc,
}
// status bar update
if(this.config[n].StatusBa
WYSIWYG_Core.addEvent(doc,
}
// custom context menu
if(this.config[n].ContextM
WYSIWYG_ContextMenu.init(n
}
// init viewTextMode var
this.viewTextMode[n] = false;
},
/* --------------------------
Function : disable()
Description : Disable the given WYSIWYG Editor Box
Usage : WYSIWYG.disable(textareaID
Arguments : textareaID - The editor identifier (the textarea's ID)
\* --------------------------
disable: function(textareaID) {
// set n to textareaID
var n = textareaID;
// get the editor window
var editor = this.getEditorWindow(n);
// Validate if editor exists
if(editor == null) {
alert("No editor found with the given identifier (ID: " + n + ").");
return;
}
if(editor) {
// disable design mode or content editable feature
if(editor.document.body.co
editor.document.body.conte
}
else {
editor.document.designMode
}
// change the style of the body
WYSIWYG_Core.setAttribute(
// hide the status bar
this.hideStatusBar(n);
// hide all toolbars
this.hideToolbars(n);
}
},
/* --------------------------
Function : enable()
Description : Enables the given WYSIWYG Editor Box
Usage : WYSIWYG.enable(textareaID)
Arguments : textareaID - The editor identifier (the textarea's ID)
\* --------------------------
enable: function(textareaID) {
// set n to textareaID
var n = textareaID;
// get the editor window
var editor = this.getEditorWindow(n);
// Validate if editor exists
if(editor == null) {
alert("No editor found with the given identifier (ID: " + n + ").");
return;
}
if(editor) {
// disable design mode or content editable feature
if(editor.document.body.co
editor.document.body.conte
}
else {
editor.document.designMode
}
// change the style of the body
WYSIWYG_Core.setAttribute(
// hide the status bar
this.showStatusBar(n);
// hide all toolbars
this.showToolbars(n);
}
},
/* --------------------------
Function : getNodeTree()
Description : Returns the node structure of the current selection as array
Usage : WYSIWYG.getNodeTree(n);
Arguments : n - The editor identifier (the textarea's ID)
\* --------------------------
getNodeTree: function(n) {
var sel = this.getSelection(n);
var range = this.getRange(sel);
// get element of range
var tag = this.getTag(range);
if(tag == null) { return; }
// get parent of element
var node = this.getParent(tag);
// init the tree as array with the current selected element
var nodeTree = new Array(tag);
// get all parent nodes
var ii = 1;
while(node != null && node.nodeName != "#document") {
nodeTree[ii] = node;
node = this.getParent(node);
ii++;
}
return nodeTree;
},
/**
* Removes the current node of the selection
*
* @param {String} n The editor identifier (the textarea's ID)
*/
removeNode: function(n) {
// get selection and range
var sel = this.getSelection(n);
var range = this.getRange(sel);
// the current tag of range
var tag = this.getTag(range);
var parent = tag.parentNode;
if(tag == null || parent == null) { return; }
if(tag.nodeName == "HTML" || tag.nodeName == "BODY") { return; }
// copy child elements of the node to the parent element before remove the node
//var childNodes = new Array();
//for(var i=0; i < tag.childNodes.length;i++)
// childNodes[i] = tag.childNodes[i];
//for(var i=0; i < childNodes.length;i++)
// parent.insertBefore(childN
// remove node
parent.removeChild(tag);
// validate if parent is a link and the node is only
// surrounded by the link, then remove the link too
if(parent.nodeName == "A" && !parent.hasChildNodes()) {
if(parent.parentNode) { parent.parentNode.removeCh
}
// update the status bar
this.updateStatusBar(n);
},
/**
* Get the selection of the given editor
*
* @param n The editor identifier (the textarea's ID)
*/
getSelection: function(n) {
var ifrm = this.getEditorWindow(n);
var doc = ifrm.document;
var sel = null;
if(ifrm.getSelection){
sel = ifrm.getSelection();
}
else if (doc.getSelection) {
sel = doc.getSelection();
}
else if (doc.selection) {
sel = doc.selection;
}
return sel;
},
/* --------------------------
Function : updateStatusBar()
Description : Updates the status bar with the current node tree
Usage : WYSIWYG.updateStatusBar(n)
Arguments : n - The editor identifier (the textarea's ID)
\* --------------------------
updateStatusBar: function(n) {
// get the node structure
var nodeTree = this.getNodeTree(n);
if(nodeTree == null) { return; }
// format the output
var outputTree = "";
var max = nodeTree.length - 1;
for(var i=max;i>=0;i--) {
if(nodeTree[i].nodeName != "HTML" && nodeTree[i].nodeName != "BODY") {
outputTree += '<a class="wysiwyg-statusbar" href="javascript:WYSIWYG.s
}
else {
outputTree += nodeTree[i].nodeName;
}
if(i > 0) { outputTree += " > "; }
}
// update the status bar
var statusbar = $("wysiwyg_statusbar_" + n);
if(statusbar){
statusbar.innerHTML = outputTree;
}
},
/* --------------------------
Function : disableDesignMode()
Description : Disable the design mode if right mouse button is pressed.
It's needed for custom context menus on mozilla (firefox),
because if design mode is on then you can`t diabled the browser
context menu.
Usage : WYSIWYG.disableDesignMode(
Arguments : event - browser event (like which button pressed)
n - The editor identifier (the textarea's ID)
\* --------------------------
disableDesignMode: function(event, n) {
var doc = this.getEditorWindow(n).do
if(event.which == 3) {
doc.designMode = "off";
return false;
}
else if(event.which != 3 && doc.designMode == "off") {
doc.designMode = "on";
return true;
}
},
/* --------------------------
Function : formatText() (changed)
Description : Format the content within the WYSIWYG Editor
Usage : WYSIWYG.formatText(id, n, selected);
Arguments : cmd - The execCommand (e.g. Bold)
n - The editor identifier that the command affects (the textarea's ID)
selected - The selected value when applicable (e.g. Arial)
\* --------------------------
formatText: function(cmd, n, selected) {
// When user clicks toolbar button make sure it always targets its respective WYSIWYG
this.getEditorWindow(n).fo
// When in Text Mode these execCommands are disabled
var formatIDs = new Array("FontSize","FontName
// Check if button clicked is in disabled list
for (var i = 0; i < formatIDs.length; i++) {
if (formatIDs[i] == cmd) {
var disabled_id = 1;
}
}
// rbg to hex convertion implementation dependents on browser
var toHexColor = WYSIWYG_Core.isMSIE ? WYSIWYG_Core._dec_to_rgb : WYSIWYG_Core.toHexColor;
// popup screen positions
var popupPosition = {left: parseInt(window.screen.ava
// Check if in Text Mode and disabled button was clicked
if (this.viewTextMode[n] == true && disabled_id == 1) {
alert("You are in TEXT Mode. This feature has been disabled.");
return;
}
// Check the insert image popup implementation
var imagePopupFile = this.config[n].PopupsDir + 'insert_image.html';
var imagePopupWidth = 400;
var imagePopupHeight = 210;
if(typeof this.config[n].ImagePopupF
imagePopupFile = this.config[n].ImagePopupF
}
if(typeof this.config[n].ImagePopupW
imagePopupWidth = this.config[n].ImagePopupW
}
if(typeof this.config[n].ImagePopupH
imagePopupHeight = this.config[n].ImagePopupH
}
// switch which action have to do
switch(cmd) {
// Font size
case "FontSize":
this.getEditorWindow(n).do
break;
// FontName
case "FontName":
this.getEditorWindow(n).do
break;
// ForeColor and
case "ForeColor":
var rgb = this.getEditorWindow(n).do
var currentColor = rgb != '' ? toHexColor(this.getEditorW
window.open(this.config[n]
break;
// BackColor
case "BackColor":
var currentColor = toHexColor(this.getEditorW
window.open(this.config[n]
break;
// InsertImage
case "InsertImage":
window.open(imagePopupFile
break;
// Remove Image
case "RemoveImage":
this.removeImage(n);
break;
// Remove Link
case "RemoveLink":
this.removeLink(n);
break;
// Remove a Node
case "RemoveNode":
this.removeNode(n);
break;
// Create Link
case "CreateLink":
window.open(this.config[n]
break;
// InsertTable
case "InsertTable":
window.open(this.config[n]
break;
// ViewSource
case "ViewSource":
this.viewSource(n);
break;
// ViewText
case "ViewText":
this.viewText(n);
break;
// Help
case "Help":
window.open(this.config[n]
break;
// Strip any HTML added by word
case "RemoveFormat":
this.removeFormat(n);
break;
// Preview thx to Korvo
case "Preview":
window.open(this.config[n]
break;
// Print
case "Print":
this.print(n);
break;
default:
WYSIWYG_Core.execCommand(n
}
// hide node the font + font size selection
this.hideFonts(n);
this.hideFontSizes(n);
},
/* --------------------------
Function : insertHTML()
Description : Insert HTML into WYSIWYG in rich text
Usage : WYSIWYG.insertHTML("<b>hel
Arguments : html - The HTML being inserted (e.g. <b>hello</b>)
n - The editor identifier that the HTML
will be inserted into (the textarea's ID)
\* --------------------------
insertHTML: function(html, n) {
if (WYSIWYG_Core.isMSIE) {
this.getEditorWindow(n).do
}
else {
var span = this.getEditorWindow(n).do
span.innerHTML = html;
this.insertNodeAtSelection
}
},
/* --------------------------
Function : insertNodeAtSelection()
Description : insert HTML into WYSIWYG in rich text (mozilla)
Usage : WYSIWYG.insertNodeAtSelect
Arguments : insertNode - The HTML being inserted (must be innerHTML inserted within a div element)
n - The editor identifier that the HTML will be inserted into (the textarea's ID)
\* --------------------------
insertNodeAtSelection: function(insertNode, n) {
// get editor document
var doc = this.getEditorWindow(n).do
// get current selection
var sel = this.getSelection(n);
// get the first range of the selection
// (there's almost always only one range)
var range = sel.getRangeAt(0);
// deselect everything
sel.removeAllRanges();
// remove content of current selection from document
range.deleteContents();
// get location of current selection
var container = range.startContainer;
var pos = range.startOffset;
// make a new range for the new selection
range = doc.createRange();
if (container.nodeType==3 && insertNode.nodeType==3) {
// if we insert text in a textnode, do optimized insertion
container.insertData(pos, insertNode.data);
// put cursor after inserted text
range.setEnd(container, pos+insertNode.length);
range.setStart(container, pos+insertNode.length);
}
else {
var afterNode;
var beforeNode;
if (container.nodeType==3) {
// when inserting into a textnode
// we create 2 new textnodes
// and put the insertNode in between
var textNode = container;
container = textNode.parentNode;
var text = textNode.nodeValue;
// text before the split
var textBefore = text.substr(0,pos);
// text after the split
var textAfter = text.substr(pos);
beforeNode = document.createTextNode(te
afterNode = document.createTextNode(te
// insert the 3 new nodes before the old one
container.insertBefore(aft
container.insertBefore(ins
container.insertBefore(bef
// remove the old node
container.removeChild(text
}
else {
// else simply insert the node
afterNode = container.childNodes[pos];
container.insertBefore(ins
}
range.setEnd(afterNode, 0);
range.setStart(afterNode, 0);
}
sel.addRange(range);
},
/* --------------------------
Function : print()
Description : Print out the content of the WYSIWYG editor area
Usage : WYSIWYG.print(n)
Arguments : n - The editor identifier (textarea ID)
\* --------------------------
print: function(n) {
if(document.all && navigator.appVersion.subst
var doc = this.getEditorWindow(n).do
doc.focus();
var OLECMDID_PRINT = 6;
var OLECMDEXECOPT_DONTPROMPTUS
var OLECMDEXECOPT_PROMPTUSER = 1;
var WebBrowser = '<object id="WebBrowser1" width="0" height="0" classid="CLSID:8856F961-34
doc.body.insertAdjacentHTM
WebBrowser.ExecWB(OLECMDID
WebBrowser.outerHTML = '';
} else {
this.getEditorWindow(n).pr
}
},
/* --------------------------
Function : outputFontSelect()
Description : creates the Font Select drop down and inserts it into the toolbar
Usage : WYSIWYG.outputFontSelect(n
Arguments : n - The editor identifier that the Font Select will update
when making font changes (the textarea's ID)
\* --------------------------
outputFontSelect: function(n) {
var fontDiv = $('FontSelect' + n);
if(fontDiv == null) { return; }
var fonts = this.config[n].Fonts;
var FontSelectObj = this.ToolbarList['selectfo
var FontSelect = this.config[n].ImagesDir + FontSelectObj[2];
var FontSelectOn = this.config[n].ImagesDir + FontSelectObj[3];
fonts.sort();
var FontSelectDropDown = new Array;
FontSelectDropDown[n] = '<table border="0" cellpadding="0" cellspacing="0"><tr><td onMouseOver="$(\'selectFon
FontSelectDropDown[n] += '<span id="Fonts' + n + '" class="dropdown" style="width: 145px;">';
for (var i = 0; i < fonts.length;i++) {
if (fonts[i]) {
FontSelectDropDown[n] += '<button type="button" onClick="WYSIWYG.formatTex
}
}
FontSelectDropDown[n] += '</span></td></tr></table>
fontDiv.insertAdjacentHTML
},
/* --------------------------
Function : outputFontSizes()
Description : creates the Font Sizes drop down and inserts it into the toolbar
Usage : WYSIWYG.outputFontSelect(n
Arguments : n - The editor identifier that the Font Sizes will update
when making font changes (the textarea's ID)
\* --------------------------
outputFontSizes: function(n) {
var fontSizeDiv = $('FontSizes' + n);
if(fontSizeDiv == null) { return; }
var fontSize = this.config[n].Fontsizes;
var FontSizeObj = this.ToolbarList['selectsi
var FontSize = this.config[n].ImagesDir + FontSizeObj[2];
var FontSizeOn = this.config[n].ImagesDir + FontSizeObj[3];
fontSize.sort();
var FontSizesDropDown = new Array;
FontSizesDropDown[n] = '<table border="0" cellpadding="0" cellspacing="0"><tr><td onMouseOver="$(\'selectSiz
FontSizesDropDown[n] += '<span id="Sizes' + n + '" class="dropdown" style="width: 170px;">';
for (var i = 0; i < fontSize.length;i++) {
if (fontSize[i]) {
FontSizesDropDown[n] += '<button type="button" onClick="WYSIWYG.formatTex
}
}
FontSizesDropDown[n] += '</span></td></tr></table>
fontSizeDiv.insertAdjacent
},
/* --------------------------
Function : hideFonts()
Description : Hides the list of font names in the font select drop down
Usage : WYSIWYG.hideFonts(n)
Arguments : n - The editor identifier (the textarea's ID)
\* --------------------------
hideFonts: function(n) {
if($('Fonts' + n)) { $('Fonts' + n).style.display = 'none'; }
},
/* --------------------------
Function : hideFontSizes()
Description : Hides the list of font sizes in the font sizes drop down
Usage : WYSIWYG.hideFontSizes(n)
Arguments : n - The editor identifier (the textarea's ID)
\* --------------------------
hideFontSizes: function(n) {
if($('Sizes' + n)) { $('Sizes' + n).style.display = 'none'; }
},
/* --------------------------
Function : showFonts()
Description : Shows the list of font names in the font select drop down
Usage : WYSIWYG.showFonts(n)
Arguments : n - The editor identifier (the textarea's ID)
\* --------------------------
showFonts: function(n) {
if($('Fonts' + n) == null) { return; }
if ($('Fonts' + n).style.display == 'block') {
$('Fonts' + n).style.display = 'none';
}
else {
$('Fonts' + n).style.display = 'block';
$('Fonts' + n).style.position = 'absolute';
}
// hide font size selection
this.hideFontSizes(n);
},
/* --------------------------
Function : showFontSizes()
Description : Shows the list of font sizes in the font sizes drop down
Usage : WYSIWYG.showFonts(n)
Arguments : n - The editor identifier (the textarea's ID)
\* --------------------------
showFontSizes: function(n) {
if($('Sizes' + n) == null) { return; }
if ($('Sizes' + n).style.display == 'block') {
$('Sizes' + n).style.display = 'none';
}
else {
$('Sizes' + n).style.display = 'block';
$('Sizes' + n).style.position = 'absolute';
}
// hide font size selection
this.hideFonts(n);
},
/* --------------------------
Function : viewSource()
Description : Shows the HTML source code generated by the WYSIWYG editor
Usage : WYSIWYG.showFonts(n)
Arguments : n - The editor identifier (the textarea's ID)
\* --------------------------
viewSource: function(n) {
// document
var doc = this.getEditorWindow(n).do
// View Source for IE
if (WYSIWYG_Core.isMSIE) {
var iHTML = doc.body.innerHTML;
// strip off the absolute urls
iHTML = this.stripURLPath(n, iHTML);
// replace all decimal color strings with hex decimal color strings
iHTML = WYSIWYG_Core.replaceRGBWit
doc.body.innerText = iHTML;
}
// View Source for Mozilla/Netscape
else {
// replace all decimal color strings with hex decimal color strings
var html = WYSIWYG_Core.replaceRGBWit
html = document.createTextNode(ht
doc.body.innerHTML = "";
doc.body.appendChild(html)
}
// Hide the HTML Mode button and show the Text Mode button
// Validate if Elements are present
if($('HTMLMode' + n)) {
$('HTMLMode' + n).style.display = 'none';
}
if($('textMode' + n)) {
$('textMode' + n).style.display = 'block';
}
// set the font values for displaying HTML source
doc.body.style.fontSize = "12px";
doc.body.style.fontFamily = "Courier New";
this.viewTextMode[n] = true;
},
/* --------------------------
Function : viewSource()
Description : Shows the HTML source code generated by the WYSIWYG editor
Usage : WYSIWYG.showFonts(n)
Arguments : n - The editor identifier (the textarea's ID)
\* --------------------------
viewText: function(n) {
// get document
var doc = this.getEditorWindow(n).do
// View Text for IE
if (WYSIWYG_Core.isMSIE) {
var iText = doc.body.innerText;
// strip off the absolute urls
iText = this.stripURLPath(n, iText);
// replace all decimal color strings with hex decimal color strings
iText = WYSIWYG_Core.replaceRGBWit
doc.body.innerHTML = iText;
}
// View Text for Mozilla/Netscape
else {
var html = doc.body.ownerDocument.cre
html.selectNodeContents(do
// replace all decimal color strings with hex decimal color strings
html = WYSIWYG_Core.replaceRGBWit
doc.body.innerHTML = html;
}
// Hide the Text Mode button and show the HTML Mode button
// Validate if Elements are present
if($('textMode' + n)) {
$('textMode' + n).style.display = 'none';
}
if($('HTMLMode' + n)) {
$('HTMLMode' + n).style.display = 'block';
}
// reset the font values (changed)
WYSIWYG_Core.setAttribute(
this.viewTextMode[n] = false;
},
/* --------------------------
Function : getDocumentPath()
Description : Get the path of the given document
Usage : WYSIWYG.getDocumentPath(do
Arguments : doc - Document of which you get the the path
\* --------------------------
getDocumentPathOfUrl: function(url) {
var path = null;
// if local file system, convert local url into web url
url = url.replace(/file:\/\//gi,
url = url.replace(/\\/gi, "\/");
var pos = url.lastIndexOf("/");
if(pos != -1) {
path = url.substring(0, pos + 1);
}
return path;
},
/* --------------------------
Function : getDocumentUrl()
Description : Get the documents url, convert local urls to web urls
Usage : WYSIWYG.getDocumentUrl(doc
Arguments : doc - Document of which you get the the path
\* --------------------------
getDocumentUrl: function(doc) {
// if local file system, convert local url into web url
var url = doc.URL;
url = url.replace(/file:\/\//gi,
url = url.replace(/\\/gi, "\/");
return url;
},
/* --------------------------
Function : stripURLPath()
Description : Strips off the defined image and the anchor urls of the given content.
It also can strip the document URL automatically if you define auto.
Usage : WYSIWYG.stripURLPath(conte
Arguments : content - Content on which the stripping applies
\* --------------------------
stripURLPath: function(n, content, exact) {
// parameter exact is optional
if(typeof exact == "undefined") {
exact = true;
}
var stripImgageUrl = null;
var stripAnchorUrl = null;
// add url to strip of anchors to array
if(this.config[n].AnchorPa
stripAnchorUrl = this.getDocumentUrl(docume
}
else if(this.config[n].AnchorPa
stripAnchorUrl = this.config[n].AnchorPathT
}
// add strip url of images to array
if(this.config[n].ImagePat
stripImgageUrl = this.getDocumentUrl(docume
}
else if(this.config[n].ImagePat
stripImgageUrl = this.config[n].ImagePathTo
}
var url;
var regex;
var result;
// strip url of image path
if(stripImgageUrl) {
// escape reserved characters to be a valid regex
url = WYSIWYG_Core.stringToRegex
// exact replacing of url. regex: src="<url>"
if(exact) {
regex = eval("/(src=\")(" + url + ")([^\"]*)/gi");
content = content.replace(regex, "$1$3");
}
// not exect replacing of url. regex: <url>
else {
regex = eval("/(" + url + ")(.+)/gi");
content = content.replace(regex, "$2");
}
// strip absolute urls without a heading slash ("images/print.gif")
result = this.getDocumentPathOfUrl(
if(result) {
url = WYSIWYG_Core.stringToRegex
// exact replacing of url. regex: src="<url>"
if(exact) {
regex = eval("/(src=\")(" + url + ")([^\"]*)/gi");
content = content.replace(regex, "$1$3");
}
// not exect replacing of url. regex: <url>
else {
regex = eval("/(" + url + ")(.+)/gi");
content = content.replace(regex, "$2");
}
}
}
// strip url of image path
if(stripAnchorUrl) {
// escape reserved characters to be a valid regex
url = WYSIWYG_Core.stringToRegex
// strip absolute urls with a heading slash ("/product/index.html")
// exact replacing of url. regex: src="<url>"
if(exact) {
regex = eval("/(href=\")(" + url + ")([^\"]*)/gi");
content = content.replace(regex, "$1$3");
}
// not exect replacing of url. regex: <url>
else {
regex = eval("/(" + url + ")(.+)/gi");
content = content.replace(regex, "$2");
}
// strip absolute urls without a heading slash ("product/index.html")
result = this.getDocumentPathOfUrl(
if(result) {
url = WYSIWYG_Core.stringToRegex
// exact replacing of url. regex: src="<url>"
if(exact) {
regex = eval("/(href=\")(" + url + ")([^\"]*)/gi");
content = content.replace(regex, "$1$3");
}
// not exect replacing of url. regex: <url>
else {
regex = eval("/(" + url + ")(.+)/gi");
content = content.replace(regex, "$2");
}
}
// stip off anchor links with #name
url = WYSIWYG_Core.stringToRegex
// exact replacing of url. regex: src="<url>"
if(exact) {
regex = eval("/(href=\")(" + url + ")(#[^\"]*)/gi");
content = content.replace(regex, "$1$3");
}
// not exect replacing of url. regex: <url>
else {
regex = eval("/(" + url + ")(.+)/gi");
content = content.replace(regex, "$2");
}
// stip off anchor links with #name (only for local system)
url = this.getDocumentUrl(docume
var pos = url.lastIndexOf("/");
if(pos != -1) {
url = url.substring(pos + 1, url.length);
url = WYSIWYG_Core.stringToRegex
// exact replacing of url. regex: src="<url>"
if(exact) {
regex = eval("/(href=\")(" + url + ")(#[^\"]*)/gi");
content = content.replace(regex, "$1$3");
}
// not exect replacing of url. regex: <url>
else {
regex = eval("/(" + url + ")(.+)/gi");
content = content.replace(regex, "$2");
}
}
}
return content;
},
/* --------------------------
Function : updateTextArea()
Description : Updates the text area value with the HTML source of the WYSIWYG
Arguments : n - The editor identifier (the textarea's ID)
\* --------------------------
updateTextArea: function(n) {
// on update switch editor back to html mode
if(this.viewTextMode[n]) { this.viewText(n); }
// get inner HTML
var content = this.getEditorWindow(n).do
// strip off defined URLs on IE
content = this.stripURLPath(n, content);
// replace all decimal color strings with hex color strings
content = WYSIWYG_Core.replaceRGBWit
// remove line breaks before content will be updated
if(this.config[n].ReplaceL
// set content back in textarea
$(n).value = content;
},
/* --------------------------
Function : hideToolbars()
Description : Hide all toolbars
Usage : WYSIWYG.hideToolbars(n)
Arguments : n - The editor identifier (the textarea's ID)
\* --------------------------
hideToolbars: function(n) {
for(var i=0;i<this.config[n].Toolb
var toolbar = $("toolbar" + i + "_" + n);
if(toolbar) { toolbar.style.display = "none"; }
}
},
/* --------------------------
Function : showToolbars()
Description : Display all toolbars
Usage : WYSIWYG.showToolbars(n)
Arguments : n - The editor identifier (the textarea's ID)
\* --------------------------
showToolbars: function(n) {
for(var i=0;i<this.config[n].Toolb
var toolbar = $("toolbar" + i + "_" + n);
if(toolbar) { toolbar.style.display = ""; }
}
},
/* --------------------------
Function : hideStatusBar()
Description : Hide the status bar
Usage : WYSIWYG.hideStatusBar(n)
Arguments : n - The editor identifier (the textarea's ID)
\* --------------------------
hideStatusBar: function(n) {
var statusbar = $('wysiwyg_statusbar_' + n);
if(statusbar) { statusbar.style.display = "none"; }
},
/* --------------------------
Function : showStatusBar()
Description : Display the status bar
Usage : WYSIWYG.showStatusBar(n)
Arguments : n - The editor identifier (the textarea's ID)
\* --------------------------
showStatusBar: function(n) {
var statusbar = $('wysiwyg_statusbar_' + n);
if(statusbar) { statusbar.style.display = ""; }
},
/* --------------------------
Function : findParentTag()
Description : Get the given parent tag of a range
Usage : WYSIWYG.findParentTag(pare
Arguments : parentTagName - Parent tag to find
range - Range
\* --------------------------
findParentTag: function(parentTagName, range){
parentTagName = parentTagName.toUpperCase(
var rangeWorking;
var elmWorking = null;
try {
if(!WYSIWYG_Core.isMSIE) {
var node = range.startContainer;
var pos = range.startOffset;
if(node.nodeType != 3) { node = node.childNodes[pos]; }
elmWorking = node;
while (elmWorking.tagName != "HTML") {
if (elmWorking.tagName == parentTagName){
return elmWorking;
}
elmWorking = elmWorking.parentNode;
}
return null;
}
else {
if(range.length > 0) {
elmWorking = range.item(0);
}
else {
elmWorking = range.parentElement();
}
while (elmWorking.tagName != "HTML") {
if (elmWorking.tagName == parentTagName){
return elmWorking;
} else {
elmWorking = elmWorking.parentElement;
}
}
rangeWorking = range.duplicate();
rangeWorking.collapse(true
rangeWorking.moveEnd("char
if (rangeWorking.text.length>
while (rangeWorking.compareEndPo
rangeWorking.move("Charact
if (null != this.findParentTag(parentT
return this.findParentTag(parentT
}
}
}
return null;
}
}
catch(e) {
return null;
}
},
/* --------------------------
Function : getTag()
Description : Get the acutally tag of the given range
Usage : WYSIWYG.getTag(range)
Arguments : range - Range
\* --------------------------
getTag: function(range) {
try {
if(!WYSIWYG_Core.isMSIE) {
var node = range.startContainer;
var pos = range.startOffset;
if(node.nodeType != 3) { node = node.childNodes[pos]; }
if(node.nodeName && node.nodeName.search(/#/) != -1) {
return node.parentNode;
}
return node;
}
else {
if(range.length > 0) {
return range.item(0);
}
else if(range.parentElement()) {
return range.parentElement();
}
}
return null;
}
catch(e) {
return null;
}
},
/* --------------------------
Function : getParent()
Description : Get the parent node of an node
Usage : WYSIWYG.getParent(node)
Arguments : element - Element which parent will be returned
\* --------------------------
getParent: function(element) {
if(element.parentNode) {
return element.parentNode;
}
return null;
},
/* --------------------------
Function : getTextRange()
Description : Get the text range object of the given element
Usage : WYSIWYG.getTextRange(eleme
Arguments : element - An element of which you get the text range object
\* --------------------------
getTextRange: function(element){
var range = element.parentTextEdit.cre
range.moveToElementText(el
return range;
},
/* --------------------------
Function : invertIELineBreakCapabilit
Description : Inverts the line break capability of IE (Thx to richyrich)
Normal: ENTER = <p> , SHIFT + ENTER = <br>
Inverted: ENTER = <br>, SHIFT + ENTER = <p>
Usage : WYSIWYG.invertIELineBreakC
Arguments : n - The editor identifier (the textarea's ID)
\* --------------------------
invertIELineBreakCapabilit
var editor = this.getEditorWindow(n);
var sel;
// validate if the press key is the carriage return key
if (editor.event.keyCode==13)
if (!editor.event.shiftKey) {
sel = this.getRange(this.getSele
sel.pasteHTML("<br>");
editor.event.cancelBubble = true;
editor.event.returnValue = false;
sel.select();
sel.moveEnd("character", 1);
sel.moveStart("character",
sel.collapse(false);
return false;
}
else {
sel = this.getRange(this.getSele
sel.pasteHTML("<p>");
editor.event.cancelBubble = true;
editor.event.returnValue = false;
sel.select();
sel.moveEnd("character", 1);
sel.moveStart("character",
sel.collapse(false);
return false;
}
}
},
/* --------------------------
Function : selectNode()
Description : Select a node within the current editor
Usage : WYSIWYG.selectNode(n, level)
Arguments : n - The editor identifier (the textarea's ID)
level - identifies the level of the element which will be selected
\* --------------------------
selectNode: function(n, level) {
var sel = this.getSelection(n);
var range = this.getRange(sel);
var parentnode = this.getTag(range);
var i = 0;
for (var node=parentnode; (node && (node.nodeType == 1)); node=node.parentNode) {
if (i == level) {
this.nodeSelection(n, node);
}
i++;
}
this.updateStatusBar(n);
},
/* --------------------------
Function : nodeSelection()
Description : Do the node selection
Usage : WYSIWYG.nodeSelection(n, node)
Arguments : n - The editor identifier (the textarea's ID)
node - The node which will be selected
\* --------------------------
nodeSelection: function(n, node) {
var doc = this.getEditorWindow(n).do
var sel = this.getSelection(n);
var range = this.getRange(sel);
if(!WYSIWYG_Core.isMSIE) {
if (node.nodeName == "BODY") {
range.selectNodeContents(n
} else {
range.selectNode(node);
}
/*
if (endNode) {
try {
range.setStart(node, startOffset);
range.setEnd(endNode, endOffset);
} catch(e) {
}
}
*/
if (sel) { sel.removeAllRanges(); }
if (sel) { sel.addRange(range); }
}
else {
// MSIE may not select everything when BODY is selected -
// start may be set to first text node instead of first non-text node -
// no known workaround
if ((node.nodeName == "TABLE") || (node.nodeName == "IMG") || (node.nodeName == "INPUT") || (node.nodeName == "SELECT") || (node.nodeName == "TEXTAREA")) {
try {
range = doc.body.createControlRang
range.addElement(node);
range.select();
}
catch(e) { }
}
else {
range = doc.body.createTextRange()
if (range) {
range.collapse();
if (range.moveToElementText) {
try {
range.moveToElementText(no
range.select();
} catch(e) {
try {
range = doc.body.createTextRange()
range.moveToElementText(no
range.select();
}
catch(e) {}
}
} else {
try {
range = doc.body.createTextRange()
range.moveToElementText(no
range.select();
}
catch(e) {}
}
}
}
}
}
}
/*************************
* openWYSIWYG core functions Copyright (c) 2006 openWebWare.com
* Contact us at devs@openwebware.com
* This copyright notice MUST stay intact for use.
*
* $Id: wysiwyg.js,v 1.10 2006/12/25 09:17:07 xhaggi Exp $
**************************
var WYSIWYG_Core = {
/**
* Holds true if browser is MSIE, otherwise false
*/
isMSIE: navigator.appName == "Microsoft Internet Explorer" ? true : false,
/**
* Holds true if browser is Firefox (Mozilla)
*/
isFF: !document.all && document.getElementById && !this.isOpera,
/**
* Holds true if browser is Opera, otherwise false
*/
isOpera: navigator.appName == "Opera" ? true : false,
/**
* Trims whitespaces of the given string
*
* @param str String
* @return Trimmed string
*/
trim: function(str) {
return str.replace(/^\s*|\s*$/g,"
},
/**
* Determine if the given parameter is defined
*
* @param p Parameter
* @return true/false dependents on definition of the parameter
*/
defined: function(p) {
return typeof p == "undefined" ? false : true;
},
/**
* Determine if the browser version is compatible
*
* @return true/false depending on compatiblity of the browser
*/
isBrowserCompatible: function() {
// Validate browser and compatiblity
if ((navigator.userAgent.inde
//no designMode (Safari lies)
return false;
}
return true;
},
/**
* Set the style attribute of the given element.
* Private method to solve the IE bug while setting the style attribute.
*
* @param element The element on which the style attribute will affect
* @param style Stylesheet which will be set
*/
_setStyleAttribute: function(element, style) {
var styles = style.split(";");
var pos;
for(var i=0;i<styles.length;i++) {
var attributes = styles[i].split(":");
if(attributes.length == 2) {
try {
var attr = WYSIWYG_Core.trim(attribut
while((pos = attr.search(/-/)) != -1) {
var strBefore = attr.substring(0, pos);
var strToUpperCase = attr.substring(pos + 1, pos + 2);
var strAfter = attr.substring(pos + 2, attr.length);
attr = strBefore + strToUpperCase.toUpperCase
}
var value = WYSIWYG_Core.trim(attribut
element.style[attr] = value;
}
catch (e) {
//alert(e);
}
}
}
},
/**
* Set an attribute's value on the given node element.
*
* @param node Node element
* @param attr Attribute which is set
* @param value Value of the attribute
*/
setAttribute: function(node, attr, value) {
if(value == "") {return;}
if(attr.toLowerCase() == "style") {
this._setStyleAttribute(no
}
else {
node.setAttribute(attr, value);
}
},
/**
* Cancel the given event.
*
* @param e Event which will be canceled
*/
cancelEvent: function(e) {
if (!e) return false;
if (this.isMSIE) {
e.returnValue = false;
e.cancelBubble = true;
} else {
e.preventDefault();
e.stopPropagation && e.stopPropagation();
}
return false;
},
/**
* Converts a RGB color string to hex color string.
*
* @param color RGB color string
* @param Hex color string
*/
toHexColor: function(color) {
color = color.replace(/^rgb/g,'');
color = color.replace(/\(/g,'');
color = color.replace(/\)/g,'');
color = color.replace(/ /g,'');
color = color.split(',');
var r = parseFloat(color[0]).toStr
var g = parseFloat(color[1]).toStr
var b = parseFloat(color[2]).toStr
if (r.length<2) { r='0'+r; }
if (g.length<2) { g='0'+g; }
if (b.length<2) { b='0'+b; }
return r + g + b;
},
/**
* Converts a decimal color to hex color string.
*
* @param Decimal color
* @param Hex color string
*/
_dec_to_rgb: function(value) {
var hex_string = "";
for (var hexpair = 0; hexpair < 3; hexpair++) {
var myByte = value & 0xFF; // get low byte
value >>= 8; // drop low byte
var nybble2 = myByte & 0x0F; // get low nybble (4 bits)
var nybble1 = (myByte >> 4) & 0x0F; // get high nybble
hex_string += nybble1.toString(16); // convert nybble to hex
hex_string += nybble2.toString(16); // convert nybble to hex
}
return hex_string.toUpperCase();
},
/**
* Replace RGB color strings with hex color strings within a string.
*
* @param {String} str RGB String
* @param {String} Hex color string
*/
replaceRGBWithHexColor: function(str) {
// find all decimal color strings
var matcher = str.match(/rgb\([0-9 ]+,[0-9 ]+,[0-9 ]+\)/gi);
if(matcher) {
for(var j=0; j<matcher.length;j++) {
var regex = eval("/" + WYSIWYG_Core.stringToRegex
// replace the decimal color strings with hex color strings
str = str.replace(regex, "#" + this.toHexColor(matcher[j]
}
}
return str;
},
/**
* Execute the given command on the given editor
*
* @param n The editor's identifier
* @param cmd Command which is execute
*/
execCommand: function(n, cmd, value) {
if(typeof(value) == "undefined") value = null;
// firefox BackColor problem fixed
if(cmd == 'BackColor' && WYSIWYG_Core.isFF) cmd = 'HiliteColor';
// firefox cut, paste and copy
if(WYSIWYG_Core.isFF && (cmd == "Cut" || cmd == "Paste" || cmd == "Copy")) {
try {
WYSIWYG.getEditorWindow(n)
}
catch(e) {
if(confirm("Copy/Cut/Paste
window.open('http://www.mo
}
}
}
else {
WYSIWYG.getEditorWindow(n)
}
},
/**
* Parse a given string to a valid regular expression
*
* @param {String} string String to be parsed
* @return {RegEx} Valid regular expression
*/
stringToRegex: function(string) {
string = string.replace(/\//gi, "\\/");
string = string.replace(/\(/gi, "\\(");
string = string.replace(/\)/gi, "\\)");
string = string.replace(/\[/gi, "\\[");
string = string.replace(/\]/gi, "\\]");
string = string.replace(/\+/gi, "\\+");
string = string.replace(/\$/gi, "\\$");
string = string.replace(/\*/gi, "\\*");
string = string.replace(/\?/gi, "\\?");
string = string.replace(/\^/gi, "\\^");
string = string.replace(/\\b/gi, "\\\\b");
string = string.replace(/\\B/gi, "\\\\B");
string = string.replace(/\\d/gi, "\\\\d");
string = string.replace(/\\B/gi, "\\\\B");
string = string.replace(/\\D/gi, "\\\\D");
string = string.replace(/\\f/gi, "\\\\f");
string = string.replace(/\\n/gi, "\\\\n");
string = string.replace(/\\r/gi, "\\\\r");
string = string.replace(/\\t/gi, "\\\\t");
string = string.replace(/\\v/gi, "\\\\v");
string = string.replace(/\\s/gi, "\\\\s");
string = string.replace(/\\S/gi, "\\\\S");
string = string.replace(/\\w/gi, "\\\\w");
string = string.replace(/\\W/gi, "\\\\W");
return string;
},
/**
* Add an event listener
*
* @param obj Object on which the event will be attached
* @param ev Kind of event
* @param fu Function which is execute on the event
*/
addEvent: function(obj, ev, fu) {
if (obj.attachEvent)
obj.attachEvent("on" + ev, fu);
else
obj.addEventListener(ev, fu, false);
},
/**
* Remove an event listener
*
* @param obj Object on which the event will be attached
* @param ev Kind of event
* @param fu Function which is execute on the event
*/
removeEvent: function(obj, ev, fu) {
if (obj.attachEvent)
obj.detachEvent("on" + ev, fu);
else
obj.removeEventListener(ev
},
/**
* Includes a javascript file
*
* @param file Javascript file path and name
*/
includeJS: function(file) {
var script = document.createElement("sc
this.setAttribute(script, "type", "text/javascript");
this.setAttribute(script, "src", file);
var heads = document.getElementsByTagN
for(var i=0;i<heads.length;i++) {
heads[i].appendChild(scrip
}
},
/**
* Includes a stylesheet file
*
* @param file Stylesheet file path and name
*/
includeCSS: function(path) {
var link = document.createElement("li
this.setAttribute(link, "rel", "stylesheet");
this.setAttribute(link, "type", "text/css");
this.setAttribute(link, "href", path);
var heads = document.getElementsByTagN
for(var i=0;i<heads.length;i++) {
heads[i].appendChild(link)
}
},
/**
* Get the screen position of the given element.
*
* @param {HTMLObject} elm1 Element which position will be calculate
* @param {HTMLObject} elm2 Element which is the last one before calculation stops
* @param {Object} Left and top position of the given element
*/
getElementPosition: function(elm1, elm2) {
var top = 0, left = 0;
while (elm1 && elm1 != elm2) {
left += elm1.offsetLeft;
top += elm1.offsetTop;
elm1 = elm1.offsetParent;
}
return {left : left, top : top};
}
}
/**
* Context menu object
*/
var WYSIWYG_ContextMenu = {
html: "",
contextMenuDiv: null,
/**
* Init function
*
* @param {String} n Editor identifier
*/
init: function(n) {
var doc = WYSIWYG.getEditorWindow(n)
// create context menu div
this.contextMenuDiv = document.createElement("di
this.contextMenuDiv.classN
this.contextMenuDiv.setAtt
this.contextMenuDiv.style.
this.contextMenuDiv.style.
this.contextMenuDiv.style.
this.contextMenuDiv.style.
this.contextMenuDiv.style.
this.contextMenuDiv.unsele
document.body.insertBefore
// bind event listeners
WYSIWYG_Core.addEvent(doc,
WYSIWYG_Core.addEvent(doc,
WYSIWYG_Core.addEvent(doc,
WYSIWYG_Core.addEvent(docu
},
/**
* Show the context menu
*
* @param e Event
* @param n Editor identifier
*/
show: function(e, n) {
if(this.contextMenuDiv == null) return false;
var ifrm = WYSIWYG.getEditor(n);
var doc = WYSIWYG.getEditorWindow(n)
// set the context menu position
var pos = WYSIWYG_Core.getElementPos
var x = WYSIWYG_Core.isMSIE ? pos.left + e.clientX : pos.left + (e.pageX - doc.body.scrollLeft);
var y = WYSIWYG_Core.isMSIE ? pos.top + e.clientY : pos.top + (e.pageY - doc.body.scrollTop);
this.contextMenuDiv.style.
this.contextMenuDiv.style.
this.contextMenuDiv.style.
this.contextMenuDiv.style.
// call the context menu, mozilla needs some time
window.setTimeout("WYSIWYG
WYSIWYG_Core.cancelEvent(e
return false;
},
/**
* Output the context menu items
*
* @param n Editor identifier
*/
output: function (n) {
// get selection
var sel = WYSIWYG.getSelection(n);
var range = WYSIWYG.getRange(sel);
// get current selected node
var tag = WYSIWYG.getTag(range);
if(tag == null) { return; }
// clear context menu
this.clear();
// Determine kind of nodes
var isImg = (tag.nodeName == "IMG") ? true : false;
var isLink = (tag.nodeName == "A") ? true : false;
// Selection is an image or selection is a text with length greater 0
var len = 0;
if(WYSIWYG_Core.isMSIE)
len = (document.selection && range.text) ? range.text.length : 0;
else
len = range.toString().length;
var sel = len != 0 || isImg;
// Icons
var iconLink = { enabled: WYSIWYG.config[n].ImagesDi
var iconImage = { enabled: WYSIWYG.config[n].ImagesDi
var iconDelete = { enabled: WYSIWYG.config[n].ImagesDi
var iconCopy = { enabled: WYSIWYG.config[n].ImagesDi
var iconCut = { enabled: WYSIWYG.config[n].ImagesDi
var iconPaste = { enabled: WYSIWYG.config[n].ImagesDi
// Create context menu html
this.html += '<table class="wysiwyg-context-men
// Add items
this.addItem(n, 'Copy', iconCopy, 'Copy', sel);
this.addItem(n, 'Cut', iconCut, 'Cut', sel);
this.addItem(n, 'Paste', iconPaste, 'Paste', true);
this.addSeperator();
this.addItem(n, 'InsertImage', iconImage, 'Modify Image Properties...', isImg);
this.addItem(n, 'CreateLink', iconLink, 'Create or Modify Link...', sel || isLink);
this.addItem(n, 'RemoveNode', iconDelete, 'Remove', true);
this.html += '</table>';
this.contextMenuDiv.innerH
},
/**
* Close the context menu
*/
close: function() {
this.contextMenuDiv.style.
this.contextMenuDiv.style.
},
/**
* Clear context menu
*/
clear: function() {
this.contextMenuDiv.innerH
this.html = "";
},
/**
* Add context menu item
*
* @param n editor identifier
* @param cmd Command
* @param icon Icon which is diabled
* @param title Title of the item
* @param disabled If item is diabled
*/
addItem: function(n, cmd, icon, title, disabled) {
var item = '';
if(disabled) {
item += '<tr>';
item += '<td class="icon"><a href="javascript:WYSIWYG.f
item += '<td onmouseover="this.classNam
item += '</tr>';
}
else {
item += '<tr>';
item += '<td class="icon"><img src="' + icon.disabled + '" border="0"></td>';
item += '<td onmouseover="this.classNam
item += '</tr>';
}
this.html += item;
},
/**
* Add seperator to context menu
*/
addSeperator: function() {
var output = '';
output += '<tr>';
output += '<td colspan="2" style="text-align:center;"
output += '</tr>';
this.html += output;
}
}
/**
* Get an element by it's identifier
*
* @param id Element identifier
*/
function $(id) {
return document.getElementById(id
}
/**
* Emulates insertAdjacentHTML(), insertAdjacentText() and
* insertAdjacentElement() three functions so they work with Netscape 6/Mozilla
* by Thor Larholm me@jscript.dk
*/
if(typeof HTMLElement!="undefined" && !HTMLElement.prototype.ins
HTMLElement.prototype.inse
switch (where){
case 'beforeBegin':
this.parentNode.insertBefo
break;
case 'afterBegin':
this.insertBefore(parsedNo
break;
case 'beforeEnd':
this.appendChild(parsedNod
break;
case 'afterEnd':
if (this.nextSibling) {
this.parentNode.insertBefo
}
else {
this.parentNode.appendChil
}
break;
}
};
HTMLElement.prototype.inse
var r = this.ownerDocument.createR
r.setStartBefore(this);
var parsedHTML = r.createContextualFragment
this.insertAdjacentElement
};
HTMLElement.prototype.inse
var parsedText = document.createTextNode(tx
this.insertAdjacentElement
};
}
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
Business Accounts
Answer for Membership
by: mplungjanPosted on 2007-05-30 at 23:34:22ID: 19185867
Comments are available to members only. Sign up or Log in to view these comments.