2017-08-02 16:06:56 -04:00
//
// htmlArea v2.03 - Copyright (c) 2002 interactivetools.com, inc.
// This copyright notice MUST stay intact for use (see license.txt).
//
// A free WYSIWYG editor replacement for <textarea> fields.
// For full source code and docs, visit http://www.interactivetools.com/
//
//if (typeof(_editor_url)==="undefined")
_editor _url = "/htmlarea/" ;
// write out styles for UI buttons
/ * d o c u m e n t . w r i t e ( ' < s t y l e t y p e = " t e x t / c s s " > \ n ' ) ;
document . write ( '.btn { width: 22px; height: 22px; border: 1px solid buttonface; margin: 0; padding: 0; }\n' ) ;
document . write ( '.btnOver { width: 22px; height: 22px; border: 1px outset; }\n' ) ;
document . write ( '.btnDown { width: 22px; height: 22px; border: 1px inset; background-color: buttonhighlight; }\n' ) ;
document . write ( '.btnNA { width: 22px; height: 22px; border: 1px solid buttonface; filter: alpha(opacity=25); }\n' ) ;
document . write ( '.cMenu { background-color: threedface; color: menutext; cursor: Default; font-family: MS Sans Serif; font-size: 8pt; padding: 2 12 2 16; }' ) ;
document . write ( '.cMenuOver { background-color: highlight; color: highlighttext; cursor: Default; font-family: MS Sans Serif; font-size: 8pt; padding: 2 12 2 16; }' ) ;
document . write ( '.cMenuDivOuter { background-color: threedface; height: 9 }' ) ;
document . write ( '.cMenuDivInner { margin: 0 4 0 4; border-width: 1; border-style: solid; border-color: threedshadow threedhighlight threedhighlight threedshadow; }' ) ;
document . write ( '</style>\n' ) ; * /
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * \
Function : editor _defaultConfig
Description : default configuration settings for wysiwyg editor
\ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
function editor _defaultConfig ( objname ) {
this . version = "2.03"
this . width = "auto" ;
this . height = "auto" ;
this . bodyStyle = 'background-color: #FFFFFF; font-family: "Verdana"; font-size: x-small;' ;
this . imgURL = _editor _url + 'images/' ;
this . debug = 0 ;
this . replaceNextlines = 0 ; // replace nextlines from spaces (on output)
this . plaintextInput = 0 ; // replace nextlines with breaks (on input)
this . toolbar = [
[ 'fontname' ] ,
[ 'fontsize' ] ,
// ['fontstyle'],
// ['linebreak'],
[ 'bold' , 'italic' , 'underline' , 'separator' ] ,
// ['strikethrough','subscript','superscript','separator'],
[ 'justifyleft' , 'justifycenter' , 'justifyright' , 'separator' ] ,
[ 'OrderedList' , 'UnOrderedList' , 'Outdent' , 'Indent' , 'separator' ] ,
[ 'forecolor' , 'backcolor' , 'separator' ] ,
[ 'HorizontalRule' , 'Createlink' , 'InsertImage' , 'InsertTable' , 'htmlmode' , 'separator' ] ,
// ['custom1','custom2','custom3','separator'],
[ 'popupeditor' , 'about' ] ] ;
this . fontnames = {
"Arial" : "arial, helvetica, sans-serif" ,
"Courier New" : "courier new, courier, mono" ,
"Georgia" : "Georgia, Times New Roman, Times, Serif" ,
"Tahoma" : "Tahoma, Arial, Helvetica, sans-serif" ,
"Times New Roman" : "times new roman, times, serif" ,
"Verdana" : "Verdana, Arial, Helvetica, sans-serif" ,
"impact" : "impact" ,
"WingDings" : "WingDings" } ;
this . fontsizes = {
"1 (8 pt)" : "1" ,
"2 (10 pt)" : "2" ,
"3 (12 pt)" : "3" ,
"4 (14 pt)" : "4" ,
"5 (18 pt)" : "5" ,
"6 (24 pt)" : "6" ,
"7 (36 pt)" : "7"
} ;
//this.stylesheet = "http://www.domain.com/sample.css"; // full URL to stylesheet
this . fontstyles = [ // make sure these exist in the header of page the content is being display as well in or they won't work!
// { name: "headline", className: "headline", classStyle: "font-family: arial black, arial; font-size: 28px; letter-spacing: -2px;" },
// { name: "arial red", className: "headline2", classStyle: "font-family: arial black, arial; font-size: 12px; letter-spacing: -2px; color:red" },
// { name: "verdana blue", className: "headline4", classStyle: "font-family: verdana; font-size: 18px; letter-spacing: -2px; color:blue" },
] ;
this . btnList = {
// buttonName: commandID, title, onclick, image,
"bold" : [ 'Bold' , 'Bold' , 'editor_action(this.id)' , 'ed_format_bold.gif' ] ,
"italic" : [ 'Italic' , 'Italic' , 'editor_action(this.id)' , 'ed_format_italic.gif' ] ,
"underline" : [ 'Underline' , 'Underline' , 'editor_action(this.id)' , 'ed_format_underline.gif' ] ,
"strikethrough" : [ 'StrikeThrough' , 'Strikethrough' , 'editor_action(this.id)' , 'ed_format_strike.gif' ] ,
"subscript" : [ 'SubScript' , 'Subscript' , 'editor_action(this.id)' , 'ed_format_sub.gif' ] ,
"superscript" : [ 'SuperScript' , 'Superscript' , 'editor_action(this.id)' , 'ed_format_sup.gif' ] ,
"justifyleft" : [ 'JustifyLeft' , 'Justify Left' , 'editor_action(this.id)' , 'ed_align_left.gif' ] ,
"justifycenter" : [ 'JustifyCenter' , 'Justify Center' , 'editor_action(this.id)' , 'ed_align_center.gif' ] ,
"justifyright" : [ 'JustifyRight' , 'Justify Right' , 'editor_action(this.id)' , 'ed_align_right.gif' ] ,
"orderedlist" : [ 'InsertOrderedList' , 'Ordered List' , 'editor_action(this.id)' , 'ed_list_num.gif' ] ,
"unorderedlist" : [ 'InsertUnorderedList' , 'Bulleted List' , 'editor_action(this.id)' , 'ed_list_bullet.gif' ] ,
"outdent" : [ 'Outdent' , 'Decrease Indent' , 'editor_action(this.id)' , 'ed_indent_less.gif' ] ,
"indent" : [ 'Indent' , 'Increase Indent' , 'editor_action(this.id)' , 'ed_indent_more.gif' ] ,
"forecolor" : [ 'ForeColor' , 'Font Color' , 'editor_action(this.id)' , 'ed_color_fg.gif' ] ,
"backcolor" : [ 'BackColor' , 'Background Color' , 'editor_action(this.id)' , 'ed_color_bg.gif' ] ,
"horizontalrule" : [ 'InsertHorizontalRule' , 'Horizontal Rule' , 'editor_action(this.id)' , 'ed_hr.gif' ] ,
"createlink" : [ 'CreateLink' , 'Insert Web Link' , 'editor_action(this.id)' , 'ed_link.gif' ] ,
"insertimage" : [ 'InsertImage' , 'Insert Image' , 'editor_action(this.id)' , 'ed_image.gif' ] ,
"inserttable" : [ 'InsertTable' , 'Insert Table' , 'editor_action(this.id)' , 'insert_table.gif' ] ,
"htmlmode" : [ 'HtmlMode' , 'View HTML Source' , 'editor_setmode(\'' + objname + '\')' , 'ed_html.gif' ] ,
"popupeditor" : [ 'popupeditor' , 'Enlarge Editor' , 'editor_action(this.id)' , 'fullscreen_maximize.gif' ] ,
"about" : [ 'about' , 'About this editor' , 'editor_about(\'' + objname + '\')' , 'ed_about.gif' ] ,
// Add custom buttons here:
"custom1" : [ 'custom1' , 'Purpose of button 1' , 'editor_action(this.id)' , 'ed_custom.gif' ] ,
"custom2" : [ 'custom2' , 'Purpose of button 2' , 'editor_action(this.id)' , 'ed_custom.gif' ] ,
"custom3" : [ 'custom3' , 'Purpose of button 3' , 'editor_action(this.id)' , 'ed_custom.gif' ] ,
// end: custom buttons
"help" : [ 'showhelp' , 'Help using editor' , 'editor_action(this.id)' , 'ed_help.gif' ] } ;
}
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * \
Function : editor _generate
Description : replace textarea with wysiwyg editor
Usage : editor _generate ( "textarea_id" , [ height ] , [ width ] ) ;
Arguments : objname - ID of textarea to replace
w - width of wysiwyg editor
h - height of wysiwyg editor
\ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
function editor _generate ( objname , userConfig ) {
// Default Settings
var config = new editor _defaultConfig ( objname ) ;
if ( userConfig ) {
for ( var thisName = 0 ; thisName < userConfig . length ; thisName ++ ) {
if ( userConfig [ thisName ] ) { config [ thisName ] = userConfig [ thisName ] ; }
}
}
document . getElementById ( objname ) . config = config ; // store config settings
// set size to specified size or size of original object
var obj = document . getElementById ( objname ) ;
if ( ! config . width || config . width == "auto" ) {
if ( obj . style . width ) { config . width = obj . style . width ; } // use css style
else if ( obj . cols ) { config . width = ( obj . cols * 8 ) + 22 ; } // col width + toolbar
else { config . width = '100%' ; } // default
}
if ( ! config . height || config . height == "auto" ) {
if ( obj . style . height ) { config . height = obj . style . height ; } // use css style
else if ( obj . rows ) { config . height = obj . rows * 17 } // row height
else { config . height = '200' ; } // default
}
var tblOpen = '<table border=0 cellspacing=0 cellpadding=0 style="float: left;" unselectable="on"><tr><td style="border: none; padding: 1 0 0 0"><nobr>' ;
var tblClose = '</nobr></td></tr></table>\n' ;
// build button toolbar
var toolbar = '' ;
var btnGroup , btnItem , aboutEditor ;
for ( var btnGroup = 0 ; btnGroup < config . toolbar . length ; btnGroup ++ ) {
// linebreak
if ( config . toolbar [ btnGroup ] . length == 1 &&
config . toolbar [ btnGroup ] [ 0 ] . toLowerCase ( ) == "linebreak" ) {
toolbar += '<br clear="all">' ;
continue ;
}
toolbar += tblOpen ;
for ( var btnItem = 0 ; btnItem < config . toolbar [ btnGroup ] . length ; btnItem ++ ) {
{
var btnName = config . toolbar [ btnGroup ] [ btnItem ] . toLowerCase ( ) ;
// fontname
if ( btnName == "fontname" ) {
toolbar += '<select id="_' + objname + '_FontName" onChange="editor_action(this.id)" unselectable="on" style="margin: 1 2 0 2; font-size: 12px;">' ;
for ( var fontname = 0 ; fontname < config . fontnames . length ; fontname ++ ) {
toolbar += '<option value="' + config . fontnames [ fontname ] + '">' + fontname + '</option>'
}
toolbar += '</select>' ;
continue ;
}
// fontsize
if ( btnName == "fontsize" ) {
toolbar += '<select id="_' + objname + '_FontSize" onChange="editor_action(this.id)" unselectable="on" style="margin: 1 2 0 0; font-size: 12px;">' ;
for ( var fontsize = 0 ; fontsize < config . fontsizes . length ; fontsize ++ ) {
toolbar += '<option value="' + config . fontsizes [ fontsize ] + '">' + fontsize + '</option>'
}
toolbar += '</select>\n' ;
continue ;
}
// font style
if ( btnName == "fontstyle" ) {
toolbar += '<select id="_' + objname + '_FontStyle" onChange="editor_action(this.id)" unselectable="on" style="margin: 1 2 0 0; font-size: 12px;">' ;
+ '<option value="">Font Style</option>' ;
for ( var i = 0 ; i < config . fontstyles . length ; i ++ ) {
var fontstyle = config . fontstyles [ i ] ;
toolbar += '<option value="' + fontstyle . className + '">' + fontstyle . name + '</option>'
}
toolbar += '</select>' ;
continue ;
}
// separator
if ( btnName == "separator" ) {
toolbar += '<span style="border: 1px inset; width: 1px; font-size: 16px; height: 16px; margin: 0 3 0 3"></span>' ;
continue ;
}
// buttons
var btnObj = config . btnList [ btnName ] ;
if ( btnName == 'linebreak' ) { alert ( "htmlArea error: 'linebreak' must be in a subgroup by itself, not with other buttons.\n\nhtmlArea wysiwyg editor not created." ) ; return ; }
if ( ! btnObj ) { alert ( "htmlArea error: button '" + btnName + "' not found in button list when creating the wysiwyg editor for '" + objname + "'.\nPlease make sure you entered the button name correctly.\n\nhtmlArea wysiwyg editor not created." ) ; return ; }
var btnCmdID = btnObj [ 0 ] ;
var btnTitle = btnObj [ 1 ] ;
var btnOnClick = btnObj [ 2 ] ;
var btnImage = btnObj [ 3 ] ;
toolbar += '<button title="' + btnTitle + '" id="_' + objname + '_' + btnCmdID + '" class="btn" onClick="' + btnOnClick + '" onmouseover="if(this.className==\'btn\'){this.className=\'btnOver\'}" onmouseout="if(this.className==\'btnOver\'){this.className=\'btn\'}" unselectable="on"><img src="' + config . imgURL + btnImage + '" border=0 unselectable="on"></button>' ;
}
} // end of button sub-group
toolbar += tblClose ;
} // end of entire button set
// build editor
var editor = '<span id="_editor_toolbar"><table border=0 cellspacing=0 cellpadding=0 bgcolor="buttonface" style="padding: 1 0 0 2" width=' + config . width + ' unselectable="on"><tr><td>\n'
+ toolbar
+ '</td></tr></table>\n'
+ '</td></tr></table></span>\n'
+ '<textarea ID="_' + objname + '_editor" style="width:' + config . width + '; height:' + config . height + '; margin-top: -1px; margin-bottom: -1px;" wrap=soft></textarea>' ;
// add context menu
editor += '<div id="_' + objname + '_cMenu" style="position: absolute; visibility: hidden;"></div>' ;
// hide original textarea and insert htmlarea after it
if ( ! config . debug ) { document . getElementById ( objname ) . style . display = "none" ; }
if ( config . plaintextInput ) { // replace nextlines with breaks
var contents = document . getElementById ( objname ) . value ;
contents = contents . replace ( /\r\n/g , '<br>' ) ;
contents = contents . replace ( /\n/g , '<br>' ) ;
contents = contents . replace ( /\r/g , '<br>' ) ;
document . getElementById ( objname ) . value = contents ;
}
// insert wysiwyg
//document.getElementById(objname).insertAdjacentHTML('afterEnd', editor)
insertHTMLAfterEnd ( document . getElementById ( objname ) , editor ) ;
// convert htmlarea from textarea to wysiwyg editor
editor _setmode ( objname , 'init' ) ;
// call filterOutput when user submits form
for ( var idx = 0 ; idx < document . forms . length ; idx ++ ) {
//var r = document.forms[idx].attachEvent('onsubmit', function() { editor_filterOutput(objname); });
leimnud . event . add ( document . forms [ idx ] , 'submit' , function ( ) { editor _filterOutput ( objname ) ; } ) ;
//var r = document.forms[idx].attachEvent('onsubmit', function() { editor_filterOutput(objname); });
//if (!r) { alert("Error attaching event to form!"); }
}
return true ;
}
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * \
Function : editor _action
Description : perform an editor command on selected editor content
Usage :
Arguments : button _id - button id string with editor and action name
\ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
function editor _action ( button _id ) {
// split up button name into "editorID" and "cmdID"
var BtnParts = Array ( ) ;
BtnParts = button _id . split ( "_" ) ;
var objname = button _id . replace ( /^_(.*)_[^_]*$/ , '$1' ) ;
var cmdID = BtnParts [ BtnParts . length - 1 ] ;
var button _obj = document . getElementById ( button _id ) ;
var editor _obj = document . getElementById ( "_" + objname + "_editor" ) ;
var config = document . getElementById ( objname ) . config ;
// help popup
if ( cmdID == 'showhelp' ) {
window . open ( _editor _url + "popups/editor_help.html" , 'EditorHelp' ) ;
return ;
}
// popup editor
if ( cmdID == 'popupeditor' ) {
window . open ( _editor _url + "popups/fullscreen.html?" + objname ,
'FullScreen' ,
'toolbar=no,location=no,directories=no,status=yes,menubar=no,scrollbars=yes,resizable=yes,width=640,height=480' ) ;
return ;
}
// check editor mode (don't perform actions in textedit mode)
if ( editor _obj . tagName . toLowerCase ( ) == 'textarea' ) { return ; }
var editdoc = editor _obj . contentWindow . document ;
editor _focus ( editor _obj ) ;
// get index and value for pulldowns
var idx = button _obj . selectedIndex ;
var val = ( idx != null ) ? button _obj [ idx ] . value : null ;
if ( 0 ) { } // use else if for easy cutting and pasting
//
// CUSTOM BUTTONS START HERE
//
// Custom1
else if ( cmdID == 'custom1' ) {
alert ( "Hello, I am custom button 1!" ) ;
}
// Custom2
else if ( cmdID == 'custom2' ) { // insert some text from a popup window
var myTitle = "This is a custom title" ;
var myText = showModalDialog ( _editor _url + "popups/custom2.html" ,
myTitle , // str or obj specified here can be read from dialog as "window.dialogArguments"
"resizable: yes; help: no; status: no; scroll: no; " ) ;
if ( myText ) { editor _insertHTML ( objname , myText ) ; }
}
// Custom3
else if ( cmdID == 'custom3' ) { // insert some text
editor _insertHTML ( objname , "It's easy to add buttons that insert text!" ) ;
}
//
// END OF CUSTOM BUTTONS
//
// FontName
else if ( cmdID == 'FontName' && val ) {
editdoc . execCommand ( cmdID , 0 , val ) ;
}
// FontSize
else if ( cmdID == 'FontSize' && val ) {
editdoc . execCommand ( cmdID , 0 , val ) ;
}
// FontStyle (change CSS className)
else if ( cmdID == 'FontStyle' && val ) {
editdoc . execCommand ( 'RemoveFormat' ) ;
editdoc . execCommand ( 'FontName' , 0 , '636c6173734e616d6520706c616365686f6c646572' ) ;
//var fontArray = editdoc.all.tags("FONT");
var fontArray = editdoc . getElementsByTagName ( "FONT" ) ;
for ( i = 0 ; i < fontArray . length ; i ++ ) {
if ( fontArray [ i ] . face == '636c6173734e616d6520706c616365686f6c646572' ) {
fontArray [ i ] . face = "" ;
fontArray [ i ] . className = val ;
fontArray [ i ] . outerHTML = fontArray [ i ] . outerHTML . replace ( /face=['"]+/ , "" ) ;
}
}
button _obj . selectedIndex = 0 ;
}
// fgColor and bgColor
else if ( cmdID == 'ForeColor' || cmdID == 'BackColor' ) {
var oldcolor = _dec _to _rgb ( editdoc . queryCommandValue ( cmdID ) ) ;
var newcolor = showModalDialog ( _editor _url + "popups/select_color.html" , oldcolor , "resizable: no; help: no; status: no; scroll: no;" ) ;
if ( newcolor != null ) { editdoc . execCommand ( cmdID , false , "#" + newcolor ) ; }
}
// execute command for buttons - if we didn't catch the cmdID by here we'll assume it's a
// commandID and pass it to execCommand(). See http://msdn.microsoft.com/workshop/author/dhtml/reference/commandids.asp
else {
// subscript & superscript, disable one before enabling the other
if ( cmdID . toLowerCase ( ) == 'subscript' && editdoc . queryCommandState ( 'superscript' ) ) { editdoc . execCommand ( 'superscript' ) ; }
if ( cmdID . toLowerCase ( ) == 'superscript' && editdoc . queryCommandState ( 'subscript' ) ) { editdoc . execCommand ( 'subscript' ) ; }
// insert link
if ( cmdID . toLowerCase ( ) == 'createlink' ) {
editdoc . execCommand ( cmdID , 1 ) ;
}
// insert image
else if ( cmdID . toLowerCase ( ) == 'insertimage' ) {
showModalDialog ( _editor _url + "popups/insert_image.html" , editdoc , "resizable: no; help: no; status: no; scroll: no; " ) ;
}
// insert table
else if ( cmdID . toLowerCase ( ) == 'inserttable' ) {
showModalDialog ( _editor _url + "popups/insert_table.html?" + objname ,
window ,
"resizable: yes; help: no; status: no; scroll: no; " ) ;
}
// all other commands microsoft Command Identifiers
else { editdoc . execCommand ( cmdID ) ; }
}
editor _event ( objname ) ;
}
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * \
Function : editor _event
Description : called everytime an editor event occurs
Usage : editor _event ( objname , runDelay , eventName )
Arguments : objname - ID of textarea to replace
runDelay : - 1 = run now , no matter what
0 = run now , if allowed
1000 = run in 1 sec , if allowed at that point
\ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
function editor _event ( objname , runDelay ) {
var config = document . getElementById ( objname ) . config ;
var editor _obj = document . getElementById ( "_" + objname + "_editor" ) ; // html editor object
if ( runDelay == null ) { runDelay = 0 ; }
var editdoc ;
var editEvent = editor _obj . contentWindow ? editor _obj . contentWindow . event : event ;
// catch keypress events
if ( editEvent && editEvent . keyCode ) {
var ord = editEvent . keyCode ; // ascii order of key pressed
var ctrlKey = editEvent . ctrlKey ;
var altKey = editEvent . altKey ;
var shiftKey = editEvent . shiftKey ;
if ( ord == 16 ) { return ; } // ignore shift key by itself
if ( ord == 17 ) { return ; } // ignore ctrl key by itself
if ( ord == 18 ) { return ; } // ignore alt key by itself
// cancel ENTER key and insert <BR> instead
// if (ord == 13 && editEvent.type == 'keypress') {
// editEvent.returnValue = false;
// editor_insertHTML(objname, "<br>");
// return;
// }
if ( ctrlKey && ( ord == 122 || ord == 90 ) ) { // catch ctrl-z (UNDO)
// TODO: Add our own undo/redo functionality
// editEvent.cancelBubble = true;
return ;
}
if ( ( ctrlKey && ( ord == 121 || ord == 89 ) ) ||
ctrlKey && shiftKey && ( ord == 122 || ord == 90 ) ) { // catch ctrl-y, ctrl-shift-z (REDO)
// TODO: Add our own undo/redo functionality
return ;
}
}
// setup timer for delayed updates (some events take time to complete)
if ( runDelay > 0 ) { return setTimeout ( function ( ) { editor _event ( objname ) ; } , runDelay ) ; }
// don't execute more than 3 times a second (eg: too soon after last execution)
if ( this . tooSoon == 1 && runDelay >= 0 ) { this . queue = 1 ; return ; } // queue all but urgent events
this . tooSoon = 1 ;
setTimeout ( function ( ) {
this . tooSoon = 0 ;
if ( this . queue ) { editor _event ( objname , - 1 ) ; } ;
this . queue = 0 ;
} , 333 ) ; // 1/3 second
editor _updateOutput ( objname ) ;
editor _updateToolbar ( objname ) ;
}
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * \
Function : editor _updateToolbar
Description : update toolbar state
Usage :
Arguments : objname - ID of textarea to replace
action - enable , disable , or update ( default action )
\ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
function editor _updateToolbar ( objname , action ) {
var config = document . getElementById ( objname ) . config ;
var editor _obj = document . getElementById ( "_" + objname + "_editor" ) ;
// disable or enable toolbar
if ( action == "enable" || action == "disable" ) {
var tbItems = new Array ( 'FontName' , 'FontSize' , 'FontStyle' ) ; // add pulldowns
for ( var btnName = 0 ; btnName < config . btnList . length ; btnName ++ ) { tbItems . push ( config . btnList [ btnName ] [ 0 ] ) ; } // add buttons
for ( var idxN = 0 ; idxN < tbItems . length ; idxN ++ ) {
if ( typeof ( tbItems [ idxN ] ) == 'undefined' ) alert ( idxN ) ;
var cmdID = tbItems [ idxN ] . toLowerCase ( ) ;
var tbObj = document . getElementById ( "_" + objname + "_" + tbItems [ idxN ] ) ;
if ( cmdID == "htmlmode" || cmdID == "about" || cmdID == "showhelp" || cmdID == "popupeditor" ) { continue ; } // don't change these buttons
if ( tbObj == null ) { continue ; }
var isBtn = ( tbObj . tagName . toLowerCase ( ) == "button" ) ? true : false ;
if ( action == "enable" ) { tbObj . disabled = false ; if ( isBtn ) { tbObj . className = 'btn' } }
if ( action == "disable" ) { tbObj . disabled = true ; if ( isBtn ) { tbObj . className = 'btnNA' } }
}
return ;
}
// update toolbar state
if ( editor _obj . tagName . toLowerCase ( ) == 'textarea' ) { return ; } // don't update state in textedit mode
var editdoc = editor _obj . contentWindow . document ;
// Set FontName pulldown
var fontname _obj = document . getElementById ( "_" + objname + "_FontName" ) ;
if ( fontname _obj ) {
var fontname = editdoc . queryCommandValue ( 'FontName' ) ;
if ( fontname == null ) { fontname _obj . value = null ; }
else {
var found = 0 ;
for ( i = 0 ; i < fontname _obj . length ; i ++ ) {
if ( fontname . toLowerCase ( ) == fontname _obj [ i ] . text . toLowerCase ( ) ) {
fontname _obj . selectedIndex = i ;
found = 1 ;
}
}
if ( found != 1 ) { fontname _obj . value = null ; } // for fonts not in list
}
}
// Set FontSize pulldown
var fontsize _obj = document . getElementById ( "_" + objname + "_FontSize" ) ;
if ( fontsize _obj ) {
var fontsize = editdoc . queryCommandValue ( 'FontSize' ) ;
if ( fontsize == null ) { fontsize _obj . value = null ; }
else {
var found = 0 ;
for ( i = 0 ; i < fontsize _obj . length ; i ++ ) {
if ( fontsize == fontsize _obj [ i ] . value ) { fontsize _obj . selectedIndex = i ; found = 1 ; }
}
if ( found != 1 ) { fontsize _obj . value = null ; } // for sizes not in list
}
}
// Set FontStyle pulldown
var classname _obj = document . getElementById ( "_" + objname + "_FontStyle" ) ;
if ( classname _obj ) {
var curRange = editdoc . selection . createRange ( ) ;
// check element and element parents for class names
var pElement ;
if ( curRange . length ) { pElement = curRange [ 0 ] ; } // control tange
else { pElement = curRange . parentElement ( ) ; } // text range
while ( pElement && ! pElement . className ) { pElement = pElement . parentElement ; } // keep going up
var thisClass = pElement ? pElement . className . toLowerCase ( ) : "" ;
if ( ! thisClass && classname _obj . value ) { classname _obj . value = null ; }
else {
var found = 0 ;
for ( i = 0 ; i < classname _obj . length ; i ++ ) {
if ( thisClass == classname _obj [ i ] . value . toLowerCase ( ) ) {
classname _obj . selectedIndex = i ;
found = 1 ;
}
}
if ( found != 1 ) { classname _obj . value = null ; } // for classes not in list
}
}
// update button states
var IDList = Array ( 'Bold' , 'Italic' , 'Underline' , 'StrikeThrough' , 'SubScript' , 'SuperScript' , 'JustifyLeft' , 'JustifyCenter' , 'JustifyRight' , 'InsertOrderedList' , 'InsertUnorderedList' ) ;
for ( i = 0 ; i < IDList . length ; i ++ ) {
var btnObj = document . getElementById ( "_" + objname + "_" + IDList [ i ] ) ;
if ( btnObj == null ) { continue ; }
var cmdActive = editdoc . queryCommandState ( IDList [ i ] ) ;
if ( ! cmdActive ) { // option is OK
if ( btnObj . className != 'btn' ) { btnObj . className = 'btn' ; }
if ( btnObj . disabled != false ) { btnObj . disabled = false ; }
} else if ( cmdActive ) { // option already applied or mixed content
if ( btnObj . className != 'btnDown' ) { btnObj . className = 'btnDown' ; }
if ( btnObj . disabled != false ) { btnObj . disabled = false ; }
}
}
}
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * \
Function : editor _updateOutput
Description : update hidden output field with data from wysiwg
\ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
function editor _updateOutput ( objname ) {
var config = document . getElementById ( objname ) . config ;
var editor _obj = document . getElementById ( "_" + objname + "_editor" ) ; // html editor object
//var editEvent = editor_obj.contentWindow ? editor_obj.contentWindow.event : event;
var isTextarea = ( editor _obj . tagName . toLowerCase ( ) == 'textarea' ) ;
var editdoc = isTextarea ? null : editor _obj . contentWindow . document ;
// get contents of edit field
var contents ;
if ( isTextarea ) { contents = editor _obj . value ; }
else { contents = editdoc . body . innerHTML ; }
// check if contents has changed since the last time we ran this routine
if ( config . lastUpdateOutput && config . lastUpdateOutput == contents ) { return ; }
else { config . lastUpdateOutput = contents ; }
// update hidden output field
document . getElementById ( objname ) . value = contents ;
}
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * \
Function : editor _filterOutput
Description :
\ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
function editor _filterOutput ( objname ) {
editor _updateOutput ( objname ) ;
var contents = document . getElementById ( objname ) . value ;
var config = document . getElementById ( objname ) . config ;
// ignore blank contents
if ( contents . toLowerCase ( ) == '<p> </p>' ) { contents = "" ; }
// filter tag - this code is run for each HTML tag matched
var filterTag = function ( tagBody , tagName , tagAttr ) {
tagName = tagName . toLowerCase ( ) ;
var closingTag = ( tagBody . match ( /^<\// ) ) ? true : false ;
// fix placeholder URLS - remove absolute paths that IE adds
if ( tagName == 'img' ) { tagBody = tagBody . replace ( /(src\s*=\s*.)[^*]*(\*\*\*)/ , "$1$2" ) ; }
if ( tagName == 'a' ) { tagBody = tagBody . replace ( /(href\s*=\s*.)[^*]*(\*\*\*)/ , "$1$2" ) ; }
// add additional tag filtering here
// convert to vbCode
// if (tagName == 'b' || tagName == 'strong') {
// if (closingTag) { tagBody = "[/b]"; } else { tagBody = "[b]"; }
// }
// else if (tagName == 'i' || tagName == 'em') {
// if (closingTag) { tagBody = "[/i]"; } else { tagBody = "[i]"; }
// }
// else if (tagName == 'u') {
// if (closingTag) { tagBody = "[/u]"; } else { tagBody = "[u]"; }
// }
// else {
// tagBody = ""; // disallow all other tags!
// }
return tagBody ;
} ;
// match tags and call filterTag
RegExp . lastIndex = 0 ;
var matchTag = /<\/?(\w+)((?:[^'">]*|'[^']*'|"[^"]*")*)>/g ; // this will match tags, but still doesn't handle container tags (textarea, comments, etc)
contents = contents . replace ( matchTag , filterTag ) ;
// remove nextlines from output (if requested)
if ( config . replaceNextlines ) {
contents = contents . replace ( /\r\n/g , ' ' ) ;
contents = contents . replace ( /\n/g , ' ' ) ;
contents = contents . replace ( /\r/g , ' ' ) ;
}
// update output with filtered content
document . getElementById ( objname ) . value = contents ;
}
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * \
Function : editor _setmode
Description : change mode between WYSIWYG and HTML editor
Usage : editor _setmode ( objname , mode ) ;
Arguments : objname - button id string with editor and action name
mode - init , textedit , or wysiwyg
\ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
function editor _setmode ( objname , mode ) {
var config = document . getElementById ( objname ) . config ;
var editor _obj = document . getElementById ( "_" + objname + "_editor" ) ;
// wait until document is fully loaded
if ( document . readyState != 'complete' ) {
setTimeout ( function ( ) { editor _setmode ( objname , mode ) } , 25 ) ;
return ;
}
// define different editors
var TextEdit = '<textarea ID="_' + objname + '_editor" style="width:' + editor _obj . style . width + '; height:' + editor _obj . style . height + '; margin-top: -1px; margin-bottom: -1px;"></textarea>' ;
var RichEdit = '<iframe ID="_' + objname + '_editor" style="width:' + editor _obj . style . width + '; height:' + editor _obj . style . height + ';"></iframe>' ;
// src="' +_editor_url+ 'popups/blank.html"
//
// Switch to TEXTEDIT mode
//
if ( mode == "textedit" || editor _obj . tagName . toLowerCase ( ) == 'iframe' ) {
config . mode = "textedit" ;
var editdoc = editor _obj . contentWindow . document ;
var contents = editdoc . body . createTextRange ( ) . htmlText ;
editor _obj . outerHTML = TextEdit ;
editor _obj = document . getElementById ( "_" + objname + "_editor" ) ;
editor _obj . value = contents ;
editor _event ( objname ) ;
editor _updateToolbar ( objname , "disable" ) ; // disable toolbar items
// set event handlers
editor _obj . onkeydown = function ( ) { editor _event ( objname ) ; }
editor _obj . onkeypress = function ( ) { editor _event ( objname ) ; }
editor _obj . onkeyup = function ( ) { editor _event ( objname ) ; }
editor _obj . onmouseup = function ( ) { editor _event ( objname ) ; }
editor _obj . ondrop = function ( ) { editor _event ( objname , 100 ) ; } // these events fire before they occur
editor _obj . oncut = function ( ) { editor _event ( objname , 100 ) ; }
editor _obj . onpaste = function ( ) { editor _event ( objname , 100 ) ; }
editor _obj . onblur = function ( ) { editor _event ( objname , - 1 ) ; }
editor _updateOutput ( objname ) ;
editor _focus ( editor _obj ) ;
}
//
// Switch to WYSIWYG mode
//
else {
config . mode = "wysiwyg" ;
var contents = editor _obj . value ;
if ( mode == 'init' ) { contents = document . getElementById ( objname ) . value ; } // on init use original textarea content
// create editor
editor _obj . outerHTML = RichEdit ;
editor _obj = document . getElementById ( "_" + objname + "_editor" ) ;
// get iframe document object
// create editor contents (and default styles for editor)
var html = "" ;
html += '<html><head>\n' ;
if ( config . stylesheet ) {
html += '<link href="' + config . stylesheet + '" rel="stylesheet" type="text/css">\n' ;
}
html += '<style>\n' ;
html += 'body {' + config . bodyStyle + '} \n' ;
for ( var i = 0 ; i < config . fontstyles . length ; i ++ ) {
var fontstyle = config . fontstyles [ i ] ;
if ( fontstyle . classStyle ) {
html += '.' + fontstyle . className + ' {' + fontstyle . classStyle + '}\n' ;
}
}
html += '</style>\n'
+ '</head>\n'
+ '<body contenteditable="true" topmargin=1 leftmargin=1'
// still working on this
// + ' oncontextmenu="parent.editor_cMenu_generate(window,\'' +objname+ '\');"'
+ '>'
+ contents
+ '</body>\n'
+ '</html>\n' ;
// write to editor window
if ( editor _obj . contentWindow )
var editdoc = editor _obj . contentWindow . document ;
else
var editdoc = editor _obj . contentDocument ;
editdoc . open ( ) ;
editdoc . write ( html ) ;
editdoc . close ( ) ;
editor _updateToolbar ( objname , "enable" ) ; // enable toolbar items
// store objname under editdoc
editdoc . objname = objname ;
// set event handlers
editdoc . onkeydown = function ( ) { editor _event ( objname ) ; }
editdoc . onkeypress = function ( ) { editor _event ( objname ) ; }
editdoc . onkeyup = function ( ) { editor _event ( objname ) ; }
editdoc . onmouseup = function ( ) { editor _event ( objname ) ; }
editdoc . body . ondrop = function ( ) { editor _event ( objname , 100 ) ; } // these events fire before they occur
editdoc . body . oncut = function ( ) { editor _event ( objname , 100 ) ; }
editdoc . body . onpaste = function ( ) { editor _event ( objname , 100 ) ; }
editdoc . body . onblur = function ( ) { editor _event ( objname , - 1 ) ; }
// bring focus to editor
if ( mode != 'init' ) { // don't focus on page load, only on mode switch
editor _focus ( editor _obj ) ;
}
}
// Call update UI
if ( mode != 'init' ) { // don't update UI on page load, only on mode switch
editor _event ( objname ) ;
}
}
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * \
Function : editor _focus
Description : bring focus to the editor
Usage : editor _focus ( editor _obj ) ;
Arguments : editor _obj - editor object
\ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
function editor _focus ( editor _obj ) {
// check editor mode
if ( editor _obj . tagName . toLowerCase ( ) == 'textarea' ) { // textarea
var myfunc = function ( ) { editor _obj . focus ( ) ; } ;
setTimeout ( myfunc , 100 ) ; // doesn't work all the time without delay
}
else { // wysiwyg
var editdoc = editor _obj . contentWindow . document ; // get iframe editor document object
var editorRange = editdoc . body . createTextRange ( ) ; // editor range
var curRange = editdoc . selection . createRange ( ) ; // selection range
if ( curRange . length == null && // make sure it's not a controlRange
! editorRange . inRange ( curRange ) ) { // is selection in editor range
editorRange . collapse ( ) ; // move to start of range
editorRange . select ( ) ; // select
curRange = editorRange ;
}
}
}
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * \
Function : editor _about
Description : display "about this editor" popup
\ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
function editor _about ( objname ) {
showModalDialog ( _editor _url + "popups/about.html" , window , "resizable: yes; help: no; status: no; scroll: no; " ) ;
}
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * \
Function : _dec _to _rgb
Description : convert dec color value to rgb hex
Usage : var hex = _dec _to _rgb ( '65535' ) ; // returns FFFF00
Arguments : value - dec value
\ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
function _dec _to _rgb ( 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 ( ) ;
}
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * \
Function : editor _insertHTML
Description : insert string at current cursor position in editor . If
two strings are specifed , surround selected text with them .
Usage : editor _insertHTML ( objname , str1 , [ str2 ] , reqSelection )
Arguments : objname - ID of textarea
str1 - HTML or text to insert
str2 - HTML or text to insert ( optional argument )
reqSelection - ( 1 or 0 ) give error if no text selected
\ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
function editor _insertHTML ( objname , str1 , str2 , reqSel ) {
var config = document . getElementById ( objname ) . config ;
var editor _obj = document . getElementById ( "_" + objname + "_editor" ) ; // editor object
if ( str1 == null ) { str1 = '' ; }
if ( str2 == null ) { str2 = '' ; }
// for non-wysiwyg capable browsers just add to end of textbox
if ( document . getElementById ( objname ) && editor _obj == null ) {
document . getElementById ( objname ) . focus ( ) ;
document . getElementById ( objname ) . value = document . getElementById ( objname ) . value + str1 + str2 ;
return ;
}
// error checking
if ( editor _obj == null ) { return alert ( "Unable to insert HTML. Invalid object name '" + objname + "'." ) ; }
editor _focus ( editor _obj ) ;
var tagname = editor _obj . tagName . toLowerCase ( ) ;
var sRange ;
// insertHTML for wysiwyg iframe
if ( tagname == 'iframe' ) {
var editdoc = editor _obj . contentWindow . document ;
sRange = editdoc . selection . createRange ( ) ;
var sHtml = sRange . htmlText ;
// check for control ranges
if ( sRange . length ) { return alert ( "Unable to insert HTML. Try highlighting content instead of selecting it." ) ; }
// insert HTML
var oldHandler = window . onerror ;
window . onerror = function ( ) { alert ( "Unable to insert HTML for current selection." ) ; return true ; } // partial table selections cause errors
if ( sHtml . length ) { // if content selected
if ( str2 ) { sRange . pasteHTML ( str1 + sHtml + str2 ) } // surround
else { sRange . pasteHTML ( str1 ) ; } // overwrite
} else { // if insertion point only
if ( reqSel ) { return alert ( "Unable to insert HTML. You must select something first." ) ; }
sRange . pasteHTML ( str1 + str2 ) ; // insert strings
}
window . onerror = oldHandler ;
}
// insertHTML for plaintext textarea
else if ( tagname == 'textarea' ) {
editor _obj . focus ( ) ;
sRange = document . selection . createRange ( ) ;
var sText = sRange . text ;
// insert HTML
if ( sText . length ) { // if content selected
if ( str2 ) { sRange . text = str1 + sText + str2 ; } // surround
else { sRange . text = str1 ; } // overwrite
} else { // if insertion point only
if ( reqSel ) { return alert ( "Unable to insert HTML. You must select something first." ) ; }
sRange . text = str1 + str2 ; // insert strings
}
}
else { alert ( "Unable to insert HTML. Unknown object tag type '" + tagname + "'." ) ; }
// move to end of new content
sRange . collapse ( false ) ; // move to end of range
sRange . select ( ) ; // re-select
}
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * \
Function : editor _getHTML
Description : return HTML contents of editor ( in either wywisyg or html mode )
Usage : var myHTML = editor _getHTML ( 'objname' ) ;
\ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
function editor _getHTML ( objname ) {
var editor _obj = document . getElementById ( "_" + objname + "_editor" ) ;
var isTextarea = ( editor _obj . tagName . toLowerCase ( ) == 'textarea' ) ;
if ( isTextarea ) { return editor _obj . value ; }
else { return editor _obj . contentWindow . document . body . innerHTML ; }
}
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * \
Function : editor _setHTML
Description : set HTML contents of editor ( in either wywisyg or html mode )
Usage : editor _setHTML ( 'objname' , "<b>html</b> <u>here</u>" ) ;
\ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
function editor _setHTML ( objname , html ) {
var editor _obj = document . getElementById ( "_" + objname + "_editor" ) ;
var isTextarea = ( editor _obj . tagName . toLowerCase ( ) == 'textarea' ) ;
if ( isTextarea ) { editor _obj . value = html ; }
else { editor _obj . contentWindow . document . body . innerHTML = html ; }
}
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * \
Function : editor _appendHTML
Description : append HTML contents to editor ( in either wywisyg or html mode )
Usage : editor _appendHTML ( 'objname' , "<b>html</b> <u>here</u>" ) ;
\ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
function editor _appendHTML ( objname , html ) {
var editor _obj = document . getElementById ( "_" + objname + "_editor" ) ;
var isTextarea = ( editor _obj . tagName . toLowerCase ( ) == 'textarea' ) ;
if ( isTextarea ) { editor _obj . value += html ; }
else { editor _obj . contentWindow . document . body . innerHTML += html ; }
}
/* ---------------------------------------------------------------- */
function _isMouseOver ( obj , event ) { // determine if mouse is over object
var mouseX = event . clientX ;
var mouseY = event . clientY ;
var objTop = obj . offsetTop ;
var objBottom = obj . offsetTop + obj . offsetHeight ;
var objLeft = obj . offsetLeft ;
var objRight = obj . offsetLeft + obj . offsetWidth ;
if ( mouseX >= objLeft && mouseX <= objRight &&
mouseY >= objTop && mouseY <= objBottom ) { return true ; }
return false ;
}
/* ---------------------------------------------------------------- */
function editor _cMenu _generate ( editorWin , objname ) {
var parentWin = window ;
editorWin . event . returnValue = false ; // cancel default context menu
// define content menu options
var cMenuOptions = [ // menu name, shortcut displayed, javascript code
[ 'Cut' , 'Ctrl-X' , function ( ) { } ] ,
[ 'Copy' , 'Ctrl-C' , function ( ) { } ] ,
[ 'Paste' , 'Ctrl-C' , function ( ) { } ] ,
[ 'Delete' , 'DEL' , function ( ) { } ] ,
[ '---' , null , null ] ,
[ 'Select All' , 'Ctrl-A' , function ( ) { } ] ,
[ 'Clear All' , '' , function ( ) { } ] ,
[ '---' , null , null ] ,
[ 'About this editor...' , '' , function ( ) {
alert ( "about this editor" ) ;
} ] ] ;
editor _cMenu . options = cMenuOptions ; // save options
// generate context menu
var cMenuHeader = ''
+ '<div id="_' + objname + '_cMenu" onblur="editor_cMenu(this);" oncontextmenu="return false;" onselectstart="return false"'
+ ' style="position: absolute; visibility: hidden; cursor: default; width: 167px; background-color: threedface;'
+ ' border: solid 1px; border-color: threedlightshadow threeddarkshadow threeddarkshadow threedlightshadow;">'
+ '<table border=0 cellspacing=0 cellpadding=0 width="100%" style="width: 167px; background-color: threedface; border: solid 1px; border-color: threedhighlight threedshadow threedshadow threedhighlight;">'
+ ' <tr><td colspan=2 height=1></td></tr>' ;
var cMenuList = '' ;
var cMenuFooter = ''
+ ' <tr><td colspan=2 height=1></td></tr>'
+ '</table></div>' ;
for ( var menuIdx = 0 ; menuIdx < editor _cMenu . options . length ; menuIdx ++ ) {
var menuName = editor _cMenu . options [ menuIdx ] [ 0 ] ;
var menuKey = editor _cMenu . options [ menuIdx ] [ 1 ] ;
var menuCode = editor _cMenu . options [ menuIdx ] [ 2 ] ;
// separator
if ( menuName == "---" || menuName == "separator" ) {
cMenuList += ' <tr><td colspan=2 class="cMenuDivOuter"><div class="cMenuDivInner"></div></td></tr>' ;
}
// menu option
else {
cMenuList += '<tr class="cMenu" onMouseOver="editor_cMenu(this)" onMouseOut="editor_cMenu(this)" onClick="editor_cMenu(this, \'' + menuIdx + '\',\'' + objname + '\')">' ;
if ( menuKey ) { cMenuList += ' <td align=left class="cMenu">' + menuName + '</td><td align=right class="cMenu">' + menuKey + '</td>' ; }
else { cMenuList += ' <td colspan=2 class="cMenu">' + menuName + '</td>' ; }
cMenuList += '</tr>' ;
}
}
var cMenuHTML = cMenuHeader + cMenuList + cMenuFooter ;
document . getElementById ( '_' + objname + '_cMenu' ) . outerHTML = cMenuHTML ;
editor _cMenu _setPosition ( parentWin , editorWin , objname ) ;
parentWin [ '_' + objname + '_cMenu' ] . style . visibility = 'visible' ;
parentWin [ '_' + objname + '_cMenu' ] . focus ( ) ;
}
/* ---------------------------------------------------------------- */
function editor _cMenu _setPosition ( parentWin , editorWin , objname ) { // set object position that won't overlap window edge
var event = editorWin . event ;
var cMenuObj = parentWin [ '_' + objname + '_cMenu' ] ;
var mouseX = event . clientX + parentWin . document . getElementById ( '_' + objname + '_editor' ) . offsetLeft ;
var mouseY = event . clientY + parentWin . document . getElementById ( '_' + objname + '_editor' ) . offsetTop ;
var cMenuH = cMenuObj . offsetHeight ;
var cMenuW = cMenuObj . offsetWidth ;
var pageH = document . body . clientHeight + document . body . scrollTop ;
var pageW = document . body . clientWidth + document . body . scrollLeft ;
// set horzontal position
if ( mouseX + 5 + cMenuW > pageW ) { var left = mouseX - cMenuW - 5 ; } // too far right
else { var left = mouseX + 5 ; }
// set vertical position
if ( mouseY + 5 + cMenuH > pageH ) { var top = mouseY - cMenuH + 5 ; } // too far down
else { var top = mouseY + 5 ; }
cMenuObj . style . top = top ;
cMenuObj . style . left = left ;
}
/* ---------------------------------------------------------------- */
function editor _cMenu ( obj , menuIdx , objname ) {
var action = event . type ;
if ( action == "mouseover" && ! obj . disabled && obj . tagName . toLowerCase ( ) == 'tr' ) {
obj . className = 'cMenuOver' ;
for ( var i = 0 ; i < obj . cells . length ; i ++ ) { obj . cells [ i ] . className = 'cMenuOver' ; }
}
else if ( action == "mouseout" && ! obj . disabled && obj . tagName . toLowerCase ( ) == 'tr' ) {
obj . className = 'cMenu' ;
for ( var i = 0 ; i < obj . cells . length ; i ++ ) { obj . cells [ i ] . className = 'cMenu' ; }
}
else if ( action == "click" && ! obj . disabled ) {
document . getElementById ( '_' + objname + '_cMenu' ) . style . visibility = "hidden" ;
var menucode = editor _cMenu . options [ menuIdx ] [ 2 ] ;
menucode ( ) ;
}
else if ( action == "blur" ) {
if ( ! _isMouseOver ( obj , event ) ) { obj . style . visibility = 'hidden' ; }
else {
if ( obj . style . visibility != "hidden" ) { obj . focus ( ) ; }
}
}
else { alert ( "editor_cMenu, unknown action: " + action ) ; }
}
/* ---------------------------------------------------------------------- */
/* -- For FireFox Compatibility -- */
function insertAfterEnd ( oElement , oNewNode )
{
oElement . parentNode . insertBefore ( oNewNode , oElement . nextSibling ) ;
}
function insertHTMLAfterEnd ( oElement , html )
{
var auxDiv = $dce ( 'div' ) ;
auxDiv . innerHTML = html ;
for ( var i = auxDiv . childNodes . length - 1 ; i >= 0 ; i -- )
{
insertAfterEnd ( oElement , auxDiv . childNodes [ i ] ) ;
}
}
2010-12-02 23:34:41 +00:00
/**/