/********************************************************************
* 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 = "popups/images/";
// Popups Directory
this.PopupsDir = "popups/";
// CSS Directory File
this.CSSFile = "styles/wysiwyg.css";
// Default WYSIWYG width and height (use px or %)
this.Width = "900px";
this.Height = "360px";
// Form name where WYSIWYG is attached to textarea
this.FormName = "edit";
// Page that opened the WYSIWYG (Used for the return command)
this.Opener = "admin.asp";
// 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 = 940;
this.PreviewHeight = 400;
// Action of the preview window
this.Preview = ""
// Confirmation message if you strip any HTML added by word
this.RemoveFormatConfMessage = "Clean HTML inserted by MS Word ?";
// Nofication if browser is not supported by openWYSIWYG, leave it blank for no message output.
this.NoValidBrowserMessage = "openWYSIWYG does not support your browser.";
// 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 =
, SHIFT + ENTER =
// Inverted: ENTER = , SHIFT + ENTER =
this.InvertIELineBreaks = false;
// Replace line breaks with 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(
"save",
"seperator",
"subscript",
"superscript",
"seperator",
"cut",
"copy",
"paste",
"removeformat",
"seperator",
"undo",
"redo",
"seperator",
"inserttable",
"insertimage",
"createlink",
"seperator",
"preview",
"print",
"seperator",
"viewSource"
);
// 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(element);}
if(this.Toolbar[toolbar-1] == null) {
this.Toolbar[toolbar-1] = new Array();
}
this.Toolbar[toolbar-1].splice(position+1, 1, element);
};
// Remove an element from the toolbar
this.removeToolbarElement = function(element) {
if(element == "seperator") {return;} // do not remove seperators
for(var i=0;i])*>( )*\s*<\/span>/gi, '');
str = str.replace(/]*>/gi, '');
str = str.replace(/<\/span[^>]*>/gi, '');
str = str.replace(/
]*>/ig, '');
str = str.replace (/<\/DIV>/gi, '');
str = str.replace (/<[\/\w?]+:[^>]*>/ig, '');
str = str.replace (/( ){2,}/ig, ' ');
str = str.replace (//ig, '');
str = str.replace (/<\/STRONG>/ig, '');
str = str.replace (//ig, '');
str = str.replace (/<\/TT>/ig, '');
str = str.replace (/]*>/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, '<$1$3');
str = str.replace(/width=([^ |>]*)([^>]*)/gi, '');
str = str.replace(/classname=([^ |>]*)([^>]*)/gi, '');
str = str.replace(/align=([^ |>]*)([^>]*)/gi, '');
str = str.replace(/valign=([^ |>]*)([^>]*)/gi, '');
str = str.replace(/<\\?\??xml[^>]>/gi, '');
str = str.replace(/<\/?\w+:[^>]*>/gi, '');
str = str.replace(//gi, '');
str = str.replace(/o:/gi, '');
str = str.replace(//gi, '');
str = str.replace(/<\/--[^>]*>/gi, '');
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.isBrowserCompatible()) {
if(this.config[n].NoValidBrowserMessage != "") { alert(this.config[n].NoValidBrowserMessage); }
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(/%/) == -1) {
ifrmWidth = currentWidth;
ifrmHeight = currentHeight;
}
// Create iframe which will be used for rich text editing
var iframe = '
\n'
+ '\n'
+ '
\n';
// Insert after the textArea both toolbar one and two
textarea.insertAdjacentHTML("afterEnd", iframe);
// Pass the textarea's existing text over to the content variable
var content = textarea.value;
var doc = this.getEditorWindow(n).document;
// Replace all \n with
if(this.config[n].ReplaceLineBreaks) {
content = content.replace(/(\r\n)|(\n)/ig, " ");
}
// 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(doc.body, "style", this.config[n].DefaultStyle);
},
/**
* 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.isBrowserCompatible()) {
if(this.config[n].NoValidBrowserMessage != "") { alert(this.config[n].NoValidBrowserMessage); }
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(/%/) == -1) {
toolbarWidth = currentWidth.replace(/px/gi, "");
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 += '
';
editor += '
';
// Output all command buttons that belong to toolbar one
for (var j = 0; j < this.config[n].Toolbar.length;j++) {
if(this.config[n].Toolbar[j] && this.config[n].Toolbar[j].length > 0) {
var toolbar = this.config[n].Toolbar[j];
// Generate WYSIWYG toolbar one
editor += '
';
editor += '
';
for (var i = 0; i < toolbar.length;i++) {
if (toolbar[i]) {
// Font selection
if (toolbar[i] == "font"){
editor += '
';
}
// Font size selection
else if (toolbar[i] == "fontsize"){
editor += '
';
}
// 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];
var buttonImageDown = this.config[n].ImagesDir + buttonObj[4];
if (toolbar[i] == "seperator") {
editor += '
\n';
// Create iframe which will be used for rich text editing
editor += '\n'
+ '
';
// Status bar HTML code
if(this.config[n].StatusBarEnabled) {
editor += '
';
}
editor += '
\n';
// Insert the editor after the textarea
textarea.insertAdjacentHTML("afterEnd", editor);
// 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).document;
// Replace all \n with
if(this.config[n].ReplaceLineBreaks) {
content = content.replace(/\n\r|\n/ig, " ");
}
// 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(doc.body, "style", this.config[n].DefaultStyle);
// 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(document.forms[idx], "submit", function xxx_aa() { WYSIWYG.updateTextArea(n); });
}
// close font selection if mouse moves over the editor window
WYSIWYG_Core.addEvent(doc, "mouseover", function xxx_bb() { WYSIWYG.hideFonts(n); WYSIWYG.hideFontSizes(n); });
// If it's true invert the line break capability of IE
if(this.config[n].InvertIELineBreaks) {
WYSIWYG_Core.addEvent(doc, "keypress", function xxx_cc() { WYSIWYG.invertIELineBreakCapability(n); });
}
// status bar update
if(this.config[n].StatusBarEnabled) {
WYSIWYG_Core.addEvent(doc, "mouseup", function xxx_dd() { WYSIWYG.updateStatusBar(n); });
}
// custom context menu
if(this.config[n].ContextMenu) {
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.contentEditable) {
editor.document.body.contentEditable = false;
}
else {
editor.document.designMode = "Off";
}
// change the style of the body
WYSIWYG_Core.setAttribute(editor.document.body, "style", this.config[n].DisabledStyle);
// 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.contentEditable){
editor.document.body.contentEditable = true;
}
else {
editor.document.designMode = "On";
}
// change the style of the body
WYSIWYG_Core.setAttribute(editor.document.body, "style", this.config[n].DefaultStyle);
// 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(childNodes[i], tag);
// 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.removeChild(parent); }
}
// 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 += '' + nodeTree[i].nodeName + '';
}
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(e, n);
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).document;
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).focus();
// When in Text Mode these execCommands are disabled
var formatIDs = new Array("FontSize","FontName","Bold","Italic","Underline","Subscript","Superscript","Strikethrough","Justifyleft","Justifyright","Justifycenter","InsertUnorderedList","InsertOrderedList","Indent","Outdent","ForeColor","BackColor","InsertImage","InsertTable","CreateLink", "Preview", "RemoveFormat");
// 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.availWidth / 8), top: parseInt(window.screen.availHeight / 4)};
// 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 = 215;
if(typeof this.config[n].ImagePopupFile != "undefined" && this.config[n].ImagePopupFile != "") {
imagePopupFile = this.config[n].ImagePopupFile;
}
if(typeof this.config[n].ImagePopupWidth && this.config[n].ImagePopupWidth > 0) {
imagePopupWidth = this.config[n].ImagePopupWidth;
}
if(typeof this.config[n].ImagePopupHeight && this.config[n].ImagePopupHeight > 0) {
imagePopupHeight = this.config[n].ImagePopupHeight;
}
// switch which action have to do
switch(cmd) {
// Font size
case "FontSize":
this.getEditorWindow(n).document.execCommand("FontSize", false, selected);
break;
// FontName
case "FontName":
this.getEditorWindow(n).document.execCommand("FontName", false, selected);
break;
// ForeColor and
case "ForeColor":
var rgb = this.getEditorWindow(n).document.queryCommandValue(cmd);
var currentColor = rgb != '' ? toHexColor(this.getEditorWindow(n).document.queryCommandValue(cmd)) : "000000";
window.open(this.config[n].PopupsDir + 'select_color.html?color=' + currentColor + '&command=' + cmd + '&wysiwyg=' + n, 'popup', 'location=0,status=0,scrollbars=0,width=210,height=165,top=' + popupPosition.top + ',left=' + popupPosition.left).focus();
break;
// BackColor
case "BackColor":
var currentColor = toHexColor(this.getEditorWindow(n).document.queryCommandValue(cmd));
window.open(this.config[n].PopupsDir + 'select_color.html?color=' + currentColor + '&command=' + cmd + '&wysiwyg=' + n, 'popup', 'location=0,status=0,scrollbars=0,width=210,height=165,top=' + popupPosition.top + ',left=' + popupPosition.left).focus();
break;
// InsertImage
case "InsertImage":
window.open(imagePopupFile + '?wysiwyg=' + n, 'popup', 'location=0,status=0,scrollbars=0,resizable=0,width=' + imagePopupWidth + ',height=' + imagePopupHeight + ',top=' + popupPosition.top + ',left=' + popupPosition.left).focus();
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].PopupsDir + 'insert_hyperlink.html?wysiwyg=' + n, 'popup', 'location=0,status=0,scrollbars=0,resizable=0,width=350,height=160,top=' + popupPosition.top + ',left=' + popupPosition.left).focus();
break;
// InsertTable
case "InsertTable":
window.open(this.config[n].PopupsDir + 'create_table.html?wysiwyg=' + n, 'popup', 'location=0,status=0,scrollbars=0,resizable=0,width=400,height=360,top=' + popupPosition.top + ',left=' + popupPosition.left).focus();
break;
// ViewSource
case "ViewSource":
this.viewSource(n);
break;
// ViewText
case "ViewText":
this.viewText(n);
break;
// Help
case "Help":
window.open(this.config[n].PopupsDir + 'about.html?wysiwyg=' + n, 'popup', 'location=0,status=0,scrollbars=0,resizable=0,width=400,height=350,top=' + popupPosition.top + ',left=' + popupPosition.left).focus();
break;
// Strip any HTML added by word
case "RemoveFormat":
this.removeFormat(n);
break;
// Preview thx to Korvo
case "Preview":
window.open(this.config[n].PopupsDir + 'preview.html?wysiwyg=' + n + '&preview=' + this.config[n].Preview,'popup', 'location=0,status=0,scrollbars=1,resizable=1,width=' + this.config[n].PreviewWidth + ',height=' + this.config[n].PreviewHeight + ',top=' + popupPosition.top + ',left=' + popupPosition.left).focus();
break;
// Print
case "Print":
this.print(n);
break;
// Save
case "Save":
WYSIWYG.updateTextArea(n);
document.getElementById(this.config[n].FormName).submit();
break;
// Save and close
case "Saveclose":
WYSIWYG.updateTextArea(n);
document.getElementById(this.config[n].FormName).submit();
break;
// Return
case "Return":
history.go(-1);
break;
default:
WYSIWYG_Core.execCommand(n, cmd);
}
// 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("hello", "textareaID")
Arguments : html - The HTML being inserted (e.g. hello)
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).document.selection.createRange().pasteHTML(html);
}
else {
var span = this.getEditorWindow(n).document.createElement("span");
span.innerHTML = html;
this.insertNodeAtSelection(span, n);
}
},
/* ---------------------------------------------------------------------- *\
Function : insertNodeAtSelection()
Description : insert HTML into WYSIWYG in rich text (mozilla)
Usage : WYSIWYG.insertNodeAtSelection(insertNode, n)
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).document;
// 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(textBefore);
afterNode = document.createTextNode(textAfter);
// insert the 3 new nodes before the old one
container.insertBefore(afterNode, textNode);
container.insertBefore(insertNode, afterNode);
container.insertBefore(beforeNode, insertNode);
// remove the old node
container.removeChild(textNode);
}
else {
// else simply insert the node
afterNode = container.childNodes[pos];
container.insertBefore(insertNode, afterNode);
}
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.substring(22,23)==4) {
var doc = this.getEditorWindow(n).document;
doc.focus();
var OLECMDID_PRINT = 6;
var OLECMDEXECOPT_DONTPROMPTUSER = 2;
var OLECMDEXECOPT_PROMPTUSER = 1;
var WebBrowser = '';
doc.body.insertAdjacentHTML('beforeEnd',WebBrowser);
WebBrowser.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER);
WebBrowser.outerHTML = '';
} else {
this.getEditorWindow(n).print();
}
},
/* ---------------------------------------------------------------------- *\
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['selectfont'];
var FontSelect = this.config[n].ImagesDir + FontSelectObj[2];
var FontSelectOn = this.config[n].ImagesDir + FontSelectObj[3];
fonts.sort();
var FontSelectDropDown = new Array;
FontSelectDropDown[n] = '
';
FontSelectDropDown[n] += '';
for (var i = 0; i < fonts.length;i++) {
if (fonts[i]) {
FontSelectDropDown[n] += ' ';
}
}
FontSelectDropDown[n] += '
';
fontDiv.insertAdjacentHTML("afterBegin", FontSelectDropDown[n]);
},
/* ---------------------------------------------------------------------- *\
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['selectsize'];
var FontSize = this.config[n].ImagesDir + FontSizeObj[2];
var FontSizeOn = this.config[n].ImagesDir + FontSizeObj[3];
fontSize.sort();
var FontSizesDropDown = new Array;
FontSizesDropDown[n] = '
';
FontSizesDropDown[n] += '';
for (var i = 0; i < fontSize.length;i++) {
if (fontSize[i]) {
FontSizesDropDown[n] += ' ';
}
}
FontSizesDropDown[n] += '
';
fontSizeDiv.insertAdjacentHTML("afterBegin", FontSizesDropDown[n]);
},
/* ---------------------------------------------------------------------- *\
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).document;
// 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.replaceRGBWithHexColor(iHTML);
doc.body.innerText = iHTML;
}
// View Source for Mozilla/Netscape
else {
// replace all decimal color strings with hex decimal color strings
var html = WYSIWYG_Core.replaceRGBWithHexColor(doc.body.innerHTML);
html = document.createTextNode(html);
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).document;
// 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.replaceRGBWithHexColor(iText);
doc.body.innerHTML = iText;
}
// View Text for Mozilla/Netscape
else {
var html = doc.body.ownerDocument.createRange();
html.selectNodeContents(doc.body);
// replace all decimal color strings with hex decimal color strings
html = WYSIWYG_Core.replaceRGBWithHexColor(html.toString());
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(doc.body, "style", this.config[n].DefaultStyle);
this.viewTextMode[n] = false;
},
/* ---------------------------------------------------------------------- *\
Function : getDocumentPath()
Description : Get the path of the given document
Usage : WYSIWYG.getDocumentPath(doc)
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, "file:///");
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, "file:///");
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(content)
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].AnchorPathToStrip == "auto") {
stripAnchorUrl = this.getDocumentUrl(document);
}
else if(this.config[n].AnchorPathToStrip != "") {
stripAnchorUrl = this.config[n].AnchorPathToStrip;
}
// add strip url of images to array
if(this.config[n].ImagePathToStrip == "auto") {
stripImgageUrl = this.getDocumentUrl(document);
}
else if(this.config[n].ImagePathToStrip != "") {
stripImgageUrl = this.config[n].ImagePathToStrip;
}
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(this.getDocumentPathOfUrl(stripImgageUrl));
// exact replacing of url. regex: src=""
if(exact) {
regex = eval("/(src=\")(" + url + ")([^\"]*)/gi");
content = content.replace(regex, "$1$3");
}
// not exect replacing of url. regex:
else {
regex = eval("/(" + url + ")(.+)/gi");
content = content.replace(regex, "$2");
}
// strip absolute urls without a heading slash ("images/print.gif")
result = this.getDocumentPathOfUrl(stripImgageUrl).match(/.+[\/]{2,3}[^\/]*/,"");
if(result) {
url = WYSIWYG_Core.stringToRegex(result[0]);
// exact replacing of url. regex: src=""
if(exact) {
regex = eval("/(src=\")(" + url + ")([^\"]*)/gi");
content = content.replace(regex, "$1$3");
}
// not exect replacing of url. regex:
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(this.getDocumentPathOfUrl(stripAnchorUrl));
// strip absolute urls with a heading slash ("/product/index.html")
// exact replacing of url. regex: src=""
if(exact) {
regex = eval("/(href=\")(" + url + ")([^\"]*)/gi");
content = content.replace(regex, "$1$3");
}
// not exect replacing of url. regex:
else {
regex = eval("/(" + url + ")(.+)/gi");
content = content.replace(regex, "$2");
}
// strip absolute urls without a heading slash ("product/index.html")
result = this.getDocumentPathOfUrl(stripAnchorUrl).match(/.+[\/]{2,3}[^\/]*/,"");
if(result) {
url = WYSIWYG_Core.stringToRegex(result[0]);
// exact replacing of url. regex: src=""
if(exact) {
regex = eval("/(href=\")(" + url + ")([^\"]*)/gi");
content = content.replace(regex, "$1$3");
}
// not exect replacing of url. regex:
else {
regex = eval("/(" + url + ")(.+)/gi");
content = content.replace(regex, "$2");
}
}
// stip off anchor links with #name
url = WYSIWYG_Core.stringToRegex(stripAnchorUrl);
// exact replacing of url. regex: src=""
if(exact) {
regex = eval("/(href=\")(" + url + ")(#[^\"]*)/gi");
content = content.replace(regex, "$1$3");
}
// not exect replacing of url. regex:
else {
regex = eval("/(" + url + ")(.+)/gi");
content = content.replace(regex, "$2");
}
// stip off anchor links with #name (only for local system)
url = this.getDocumentUrl(document);
var pos = url.lastIndexOf("/");
if(pos != -1) {
url = url.substring(pos + 1, url.length);
url = WYSIWYG_Core.stringToRegex(url);
// exact replacing of url. regex: src=""
if(exact) {
regex = eval("/(href=\")(" + url + ")(#[^\"]*)/gi");
content = content.replace(regex, "$1$3");
}
// not exect replacing of url. regex:
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).document.body.innerHTML;
// strip off defined URLs on IE
content = this.stripURLPath(n, content);
// replace all decimal color strings with hex color strings
content = WYSIWYG_Core.replaceRGBWithHexColor(content);
// remove line breaks before content will be updated
if(this.config[n].ReplaceLineBreaks) { content = content.replace(/(\r\n)|(\n)/ig, ""); }
// 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 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("character", 1);
if (rangeWorking.text.length>0) {
while (rangeWorking.compareEndPoints("EndToEnd", range) < 0){
rangeWorking.move("Character");
if (null != this.findParentTag(parentTagName, rangeWorking)){
return this.findParentTag(parentTagName, rangeWorking);
}
}
}
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(element)
Arguments : element - An element of which you get the text range object
\* ---------------------------------------------------------------------- */
getTextRange: function(element){
var range = element.parentTextEdit.createTextRange();
range.moveToElementText(element);
return range;
},
/* ---------------------------------------------------------------------- *\
Function : invertIELineBreakCapability()
Description : Inverts the line break capability of IE (Thx to richyrich)
Normal: ENTER =
, SHIFT + ENTER =
Inverted: ENTER = , SHIFT + ENTER =
Usage : WYSIWYG.invertIELineBreakCapability(n)
Arguments : n - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
invertIELineBreakCapability: function(n) {
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.getSelection(n));
sel.pasteHTML(" ");
editor.event.cancelBubble = true;
editor.event.returnValue = false;
sel.select();
sel.moveEnd("character", 1);
sel.moveStart("character", 1);
sel.collapse(false);
return false;
}
else {
sel = this.getRange(this.getSelection(n));
sel.pasteHTML("
");
editor.event.cancelBubble = true;
editor.event.returnValue = false;
sel.select();
sel.moveEnd("character", 1);
sel.moveStart("character", 1);
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).document;
var sel = this.getSelection(n);
var range = this.getRange(sel);
if(!WYSIWYG_Core.isMSIE) {
if (node.nodeName == "BODY") {
range.selectNodeContents(node);
} 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.createControlRange();
range.addElement(node);
range.select();
}
catch(e) { }
}
else {
range = doc.body.createTextRange();
if (range) {
range.collapse();
if (range.moveToElementText) {
try {
range.moveToElementText(node);
range.select();
} catch(e) {
try {
range = doc.body.createTextRange();
range.moveToElementText(node);
range.select();
}
catch(e) {}
}
} else {
try {
range = doc.body.createTextRange();
range.moveToElementText(node);
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.indexOf('Safari') != -1 ) || !document.getElementById || !document.designMode){
//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>= 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';
// 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 += '';
this.contextMenuDiv.innerHTML = this.html;
},
/**
* Close the context menu
*/
close: function() {
this.contextMenuDiv.style.visibility = "hidden";
this.contextMenuDiv.style.display = "none";
},
/**
* Clear context menu
*/
clear: function() {
this.contextMenuDiv.innerHTML = "";
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 += '