2个好用的js(实现树型菜单&&页面中展现word)
2007-11-20 09:57
651 查看
1.editor.js
// <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
// 需要IE5.5以上的版本支持
// write out styles for UI buttons
document.write('<style type="text/css"> ');
document.write('.btn { width: 22px; height: 22px; border: 1px solid buttonface; margin: 0; padding: 0; } ');
document.write('.btnOver { width: 22px; height: 22px; border: 1px outset; } ');
document.write('.btnDown { width: 22px; height: 22px; border: 1px inset; background-color: buttonhighlight; } ');
document.write('.btnNA { width: 22px; height: 22px; border: 1px solid buttonface; filter: alpha(opacity=25); } ');
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> ');
/**//* ---------------------------------------------------------------------- *
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', '加粗', 'editor_action(this.id)', 'ed_format_bold.gif'],
"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', '关于当前编辑器', '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 in userConfig) ...{
if (userConfig[thisName]) ...{
config[thisName] = userConfig[thisName];
}
}
}
document.all[objname].config = config; // store config settings
// set size to specified size or size of original object
var obj = document.all[objname];
if (!config.width || config.width == "auto") ...{
if (obj.style.width) ...{ // use css style
config.width = obj.style.width;
}else if (obj.cols)...{ // col width + toolbar
config.width = (obj.cols * 8) + 22;
}else ...{ // default
config.width = '100%';
}
}
if (!config.height || config.height == "auto") ...{
if(obj.style.height)...{ // use css style
config.height = obj.style.height;
}else if (obj.rows)...{ // row height
config.height = obj.rows * 17
}else...{ // default
config.height = '200';
}
}
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> ';
// build button toolbar
var toolbar = '';
var btnGroup, btnItem, aboutEditor;
for (var btnGroup in config.toolbar) ...{
// linebreak
if (config.toolbar[btnGroup].length == 1 &&
config.toolbar[btnGroup][0].toLowerCase() == "linebreak") ...{
toolbar += '<br clear="all">';
continue;
}
toolbar += tblOpen;
for (var btnItem in config.toolbar[btnGroup]) ...{
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 in config.fontnames) ...{
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 in config.fontsizes) ...{
toolbar += '<option value="' +config.fontsizes[fontsize]+ '">' +fontsize+ '</option>'
}
toolbar += '</select> ';
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 in config.fontstyles) ...{
var fontstyle = config.fontstyles;
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. htmlArea wysiwyg editor not created."); return; }
if (!btnObj) ...{ alert("htmlArea error: button '" +btnName+ "' not found in button list when creating the wysiwyg editor for '"+objname+"'. Please make sure you entered the button name correctly. htmlArea 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> '
+ toolbar
+ '</td></tr></table> '
+ '</td></tr></table></span> '
+ '<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.all[objname].style.display = "none"; }
if (config.plaintextInput) ...{ // replace nextlines with breaks
var contents = document.all[objname].value;
contents = contents.replace(/ /g, '<br>');
contents = contents.replace(/ /g, '<br>');
contents = contents.replace(/ /g, '<br>');
document.all[objname].value = contents;
}
// insert wysiwyg
document.all[objname].insertAdjacentHTML('afterEnd', 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); });
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.all[button_id];
var editor_obj = document.all["_" +objname + "_editor"];
var config = document.all[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");
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.all[objname].config;
var editor_obj = document.all["_" +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.all[objname].config;
var editor_obj = document.all["_" +objname+ "_editor"];
// disable or enable toolbar
if (action == "enable" || action == "disable") ...{
var tbItems = new Array('FontName','FontSize','FontStyle'); // add pulldowns
for (var btnName in config.btnList) ...{ tbItems.push(config.btnList[btnName][0]); } // add buttons
for (var idxN in tbItems) ...{
var cmdID = tbItems[idxN].toLowerCase();
var tbObj = document.all["_" +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.all["_" +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.all["_" +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.all["_" +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.all["_" +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.all[objname].config;
var editor_obj = document.all["_" +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.all[objname].value = contents;
}
/**//* ---------------------------------------------------------------------- *
Function : editor_filterOutput
Description :
* ---------------------------------------------------------------------- */
function editor_filterOutput(objname) ...{
editor_updateOutput(objname);
var contents = document.all[objname].value;
var config = document.all[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(/(srcs*=s*.)[^*]*(***)/, "$1$2"); }
if (tagName == 'a') ...{ tagBody = tagBody.replace(/(hrefs*=s*.)[^*]*(***)/, "$1$2"); }
// add additional tag filtering here
// convert to vbCode
// if (tagName == 'b' || tagName == 'strong') {
// if (closingTag) { tagBody = "[/b]"; } else { tagBody = ""; }
// }
// else if (tagName == 'i' || tagName == 'em') {
// if (closingTag) { tagBody = ""; } 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(/ /g, ' ');
contents = contents.replace(/ /g, ' ');
contents = contents.replace(/ /g, ' ');
}
// update output with filtered content
document.all[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.all[objname].config;
var editor_obj = document.all["_" +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.all["_" +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.all[objname].value; } // on init use original textarea content
// create editor
editor_obj.outerHTML = RichEdit;
editor_obj = document.all["_" +objname + "_editor"];
// get iframe document object
// create editor contents (and default styles for editor)
var html = "";
html += '<html><head> ';
if (config.stylesheet) {
html += '<link href="' +config.stylesheet+ '" rel="stylesheet" type="text/css"> ';
}
html += '<style> ';
html += 'body {' +config.bodyStyle+ '} ';
for (var i in config.fontstyles) {
var fontstyle = config.fontstyles[i];
if (fontstyle.classStyle) {
html += '.' +fontstyle.className+ ' {' +fontstyle.classStyle+ '} ';
}
}
html += '</style> '
+ '</head> '
+ '<body contenteditable="true" topmargin=1 leftmargin=1'
// still working on this
// + ' oncontextmenu="parent.editor_cMenu_generate(window,'' +objname+ '');"'
+'>'
+ contents
+ '</body> '
+ '</html> ';
// write to editor window
var editdoc = editor_obj.contentWindow.document;
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.all[objname].config;
var editor_obj = document.all["_" +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.all[objname] && editor_obj == null) ...{
document.all[objname].focus();
document.all[objname].value = document.all[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.all["_" +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.all["_" +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.all["_" +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 in editor_cMenu.options) ...{
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.all['_'+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.all['_'+objname+'_editor'].offsetLeft;
var mouseY = event.clientY + parentWin.document.all['_'+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.all['_'+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); }
}
/**//* ---------------------------------------------------------------------- */
//创建以新的配置的对象
function newConfig(contentName)
...{
var config = new Object(); // 创建一个新的配置对象
config.width = "800px";
config.height = "400px";
config.bodyStyle = 'background-color: white; font-family: "Verdana"; font-size: x-small;';
config.debug = 0;
// NOTE: You can remove any of these blocks and use the default config!
config.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','htmlmode','separator'],
// ['about','help','popupeditor'],
];
// 配置对象的字体
config.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"
};
// 配置字体的大小
config.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"
};
// 配置字体的样式
//// config.stylesheet = "http://www.domain.com/sample.css";
// 配置字体的样式
config.fontstyles = [ // make sure classNames are defined in the 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" }
// leave classStyle blank if it's defined in config.stylesheet (above), like this:
// { name: "verdana blue", className: "headline4", classStyle: "" }
];
// 设置对象,和对象的样式
editor_generate(contentName,config); // 指定输入区域的样式
}
//创建以新的配置的对象:信息修改部分
function update_newConfig()
...{
var config = new Object(); // 创建一个新的配置对象
config.width = "800px";
config.height = "400px";
config.bodyStyle = 'background-color: white; font-family: "Verdana"; font-size: x-small;';
config.debug = 0;
// NOTE: You can remove any of these blocks and use the default config!
config.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','htmlmode','separator'],
['about','help','popupeditor'],
];
// 配置对象的字体
config.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"
};
// 配置字体的大小
config.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"
};
// 配置字体的样式
//// config.stylesheet = "http://www.domain.com/sample.css";
// 配置字体的样式
config.fontstyles = [ // make sure classNames are defined in the 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" }
// leave classStyle blank if it's defined in config.stylesheet (above), like this:
// { name: "verdana blue", className: "headline4", classStyle: "" }
];
// 设置对象,和对象的样式
editor_generate('content',config); // 指定中文输入区域的样式
}
//浏览器版本的控制
function browserControl()
...{
_editor_url = ""; // 当前文件的绝对的路径
var win_ie_ver = parseFloat(navigator.appVersion.split("MSIE")[1]); // 获得IE浏览器的版本号
/**//*
* 判断其他浏览器的方式
*/
if (navigator.userAgent.indexOf('Mac') >= 0) ...{ win_ie_ver = 0; }
if (navigator.userAgent.indexOf('Windows CE') >= 0) ...{ win_ie_ver = 0; }
if (navigator.userAgent.indexOf('Opera') >= 0) ...{ win_ie_ver = 0; }
// 这里是判断浏览器,需要IE5.5以上的版本支持
if (win_ie_ver >= 5.5) ...{
// document.write('<scr'+'ipt src="' +_editor_url+ 'js/editor.js" language="Javascript1.2"></scr'+'ipt>');
} else ...{
alert("不支持当前浏览器的版本");
document.write('<scr'+'ipt>function editor_generate() { return false; }</scr'+'ipt>');
}
// -->
}
使用该js只需要三个步骤:
1.通过<script language="javascript" src="js/editor.js" type="text/javascript""></script>引入该控件所在的文件;
2 调用browserControl()函数来判断客户端的浏览器类型,对不同的浏览器作不同的操作;
3. 调用newConfig()函数,将指定的textarea域设定为文本编辑区域.
经过该编辑器格式化的文字内容提交到数据库以后,从数据库中直接以字符串的格式取出来放在jsp页面中,就可以显示出原来发布时的 格式效果,这是因为javascirpt脚本已经对格式化文本做了特殊处理,比如加粗文字"[b]加粗"实际上存储的是"<b>加粗</b>"字符串。因此,显示页面无需作特殊处理,就可以恢复原文字的格式信息了。
2.tree.js && tree_tpl.js
这两个js主要实现了树型结构的展现,构造出树型菜单。
tree_tpl.js:
/**//*
Feel free to use your custom images for the tree. Make sure they are all of the same size.
User images collections are welcome, we'll publish them giving all regards.
*/
var tree_tpl = ...{
'target' : 'mainFrame', // name of the frame links will be opened in
// other possible values are: _blank, _parent, _search, _self and _top
'icon_e' : 'images/empty.gif', // empty image
'icon_l' : 'images/line.gif', // vertical line
'icon_32' : 'images/base.gif', // root icon normal
'icon_36' : 'images/base.gif', // root icon normal
'icon_48' : 'images/base.gif', // root icon normal
'icon_52' : 'images/base.gif', // root icon selected
'icon_56' : 'images/base.gif', // root icon opened
'icon_60' : 'images/base.gif', // root icon selected
'icon_16' : 'images/folder.gif', // node icon normal
'icon_20' : 'images/folderopen.gif', // node icon selected
'icon_24' : 'images/folder.gif', // node icon opened
'icon_28' : 'images/folderopen.gif', // node icon selected opened
'icon_0' : 'images/page.gif', // leaf icon normal
'icon_4' : 'images/page.gif', // leaf icon selected
'icon_8' : 'images/page.gif', // leaf icon opened
'icon_12' : 'images/page.gif', // leaf icon selected
'icon_2' : 'images/joinbottom.gif', // junction for leaf
'icon_3' : 'images/join.gif', // junction for last leaf
'icon_18' : 'images/plusbottom.gif', // junction for closed node
'icon_19' : 'images/plus.gif', // junctioin for last closed node
'icon_26' : 'images/minusbottom.gif',// junction for opened node
'icon_27' : 'images/minus.gif' // junctioin for last opended node
};
tree.js:
// Title: Tigra Tree
// Description: See the demo at url
// URL: http://www.softcomplex.com/products/tigra_menu_tree/
// Version: 1.0
// Date: 07-20-2002 (mm-dd-yyyy)
// Contact: feedback@softcomplex.com (specify product title in the subject)
// Notes: Registration needed to use this script on your web site.
// Registration for this version (1.0) is free of charge.
// Visit official site for details
function tree (a_items, a_template) ...{
this.a_tpl = a_template;
this.a_config = a_items;
this.o_root = this;
this.a_index = [];
this.o_selected = null;
this.n_depth = -1;
var o_icone = new Image(),
o_iconl = new Image();
o_icone.src = a_template['icon_e'];
o_iconl.src = a_template['icon_l'];
a_template['im_e'] = o_icone;
a_template['im_l'] = o_iconl;
for (var i = 0; i < 64; i++)
if (a_template['icon_' + i]) ...{
var o_icon = new Image();
a_template['im_' + i] = o_icon;
o_icon.src = a_template['icon_' + i];
}
this.toggle = function (n_id) ...{ var o_item = this.a_index[n_id]; o_item.open(o_item.b_opened) };
this.select = function (n_id) ...{ return this.a_index[n_id].select(); };
this.mout = function (n_id) ...{ this.a_index[n_id].upstatus(true) };
this.mover = function (n_id) ...{ this.a_index[n_id].upstatus() };
this.a_children = [];
for (var i = 0; i < a_items.length; i++)
new tree_item(this, i);
this.n_id = trees.length;
trees[this.n_id] = this;
for (var i = 0; i < this.a_children.length; i++) ...{
document.write(this.a_children[i].init());
this.a_children[i].open();
}
}
function tree_item (o_parent, n_order) ...{
this.n_depth = o_parent.n_depth + 1;
this.a_config = o_parent.a_config[n_order + (this.n_depth ? 2 : 0)];
if (!this.a_config) return;
this.o_root = o_parent.o_root;
this.o_parent = o_parent;
this.n_order = n_order;
this.b_opened = !this.n_depth;
this.n_id = this.o_root.a_index.length;
this.o_root.a_index[this.n_id] = this;
o_parent.a_children[n_order] = this;
this.a_children = [];
for (var i = 0; i < this.a_config.length - 2; i++)
new tree_item(this, i);
this.get_icon = item_get_icon;
this.open = item_open;
this.select = item_select;
this.init = item_init;
this.upstatus = item_upstatus;
this.is_last = function () ...{ return this.n_order == this.o_parent.a_children.length - 1 };
}
function item_open (b_close) ...{
var o_idiv = get_element('i_div' + this.n_id);
if (!o_idiv) return;
if (!o_idiv.innerHTML) ...{
var a_children = [];
for (var i = 0; i < this.a_children.length; i++)
a_children[i]= this.a_children[i].init();
o_idiv.innerHTML = a_children.join('');
}
o_idiv.style.display = (b_close ? 'none' : 'block');
this.b_opened = !b_close;
var o_jicon = document.images['j_img' + this.n_id],
o_iicon = document.images['i_img' + this.n_id];
if (o_jicon) o_jicon.src = this.get_icon(true);
if (o_iicon) o_iicon.src = this.get_icon();
this.upstatus();
}
function item_select (b_deselect) ...{
if (!b_deselect) ...{
var o_olditem = this.o_root.o_selected;
this.o_root.o_selected = this;
if (o_olditem) o_olditem.select(true);
}
var o_iicon = document.images['i_img' + this.n_id];
if (o_iicon) o_iicon.src = this.get_icon();
get_element('i_txt' + this.n_id).style.fontWeight = b_deselect ? 'normal' : 'bold';
this.upstatus();
return Boolean(this.a_config[1]);
}
function item_upstatus (b_clear) ...{
window.setTimeout('window.status="' + (b_clear ? '' : this.a_config[0] + (this.a_config[1] ? ' ('+ this.a_config[1] + ')' : '')) + '"', 10);
}
function item_init () ...{
var a_offset = [],
o_current_item = this.o_parent;
for (var i = this.n_depth; i > 1; i--) ...{
a_offset[i] = '<img src="' + this.o_root.a_tpl[o_current_item.is_last() ? 'icon_e' : 'icon_l'] + '" border="0" align="absbottom">';
o_current_item = o_current_item.o_parent;
}
return '<table cellpadding="0" cellspacing="0" border="0"><tr><td nowrap>' + (this.n_depth ? a_offset.join('') + (this.a_children.length ? '<a href="javascript: trees[' + this.o_root.n_id + '].toggle(' + this.n_id + ')" onmouseover="trees[' + this.o_root.n_id + '].mover(' + this.n_id + ')" onmouseout="trees[' + this.o_root.n_id + '].mout(' + this.n_id + ')"><img src="' + this.get_icon(true) + '" border="0" align="absbottom" name="j_img' + this.n_id + '"></a>' : '<img src="' + this.get_icon(true) + '" border="0" align="absbottom">') : '') + '<a href="' + this.a_config[1] + '" target="' + this.o_root.a_tpl['target'] + '" onclick="return trees[' + this.o_root.n_id + '].select(' + this.n_id + ')" ondblclick="trees[' + this.o_root.n_id + '].toggle(' + this.n_id + ')" onmouseover="trees[' + this.o_root.n_id + '].mover(' + this.n_id + ')" onmouseout="trees[' + this.o_root.n_id + '].mout(' + this.n_id + ')" class="t' + this.o_root.n_id + 'i" id="i_txt' + this.n_id + '"><img src="' + this.get_icon() + '" border="0" align="absbottom" name="i_img' + this.n_id + '" class="t' + this.o_root.n_id + 'im">' + this.a_config[0] + '</a></td></tr></table>' + (this.a_children.length ? '<div id="i_div' + this.n_id + '" style="display:none"></div>' : '');
}
function item_get_icon (b_junction) ...{
// alert('icon_' + ((this.n_depth ? 0 : 32) + (this.a_children.length ? 16 : 0) + (this.a_children.length && this.b_opened ? 8 : 0) + (!b_junction && this.o_root.o_selected == this ? 4 : 0) + (b_junction ? 2 : 0) + (b_junction && this.is_last() ? 1 : 0)));
return this.o_root.a_tpl['icon_' + ((this.n_depth ? 0 : 32) + (this.a_children.length ? 16 : 0) + (this.a_children.length && this.b_opened ? 8 : 0) + (!b_junction && this.o_root.o_selected == this ? 4 : 0) + (b_junction ? 2 : 0) + (b_junction && this.is_last() ? 1 : 0))];
}
var trees = [];
get_element = document.all ?
function (s_id) ...{ return document.all[s_id] } :
function (s_id) ...{ return document.getElementById(s_id) };
这是一次测试:
<%...@page contentType="text/html; charset=GBK" language="java" %>
<%...
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<script language="javascript1.2" src="./js/editor.js" type="text/javascript"></script>
<script language="Javascript1.2">...browserControl()</script>
<textarea name="content" style="width:100%; height:80"></textarea>
<script language="javascript1.2">...newConfig('content')</script>
<%...StringBuffer strBuf = new StringBuffer(); //构造字符串
strBuf.append("['根','some/path/to/my/url?column=1',"+" "+
"['根-叶结点1','some/path/to/my/url?column=2']],"+
"['根','some/path/to/my/url?column=3',"+" "+
"['根-叶结点2','some/path/to/my/url?column=4']],");
%>
<script language="JavaScript" src="./js/tree.js"></script> <script language="JavaScript">...
var TREE_ITEMS = [
<%=strBuf.toString()%>
];
</script> <script language="JavaScript" src="./js/tree_tpl.js"></script> <script language="JavaScript">...
new tree (TREE_ITEMS, tree_tpl);
</script>
test!
</body>
</html>
// <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
// 需要IE5.5以上的版本支持
// write out styles for UI buttons
document.write('<style type="text/css"> ');
document.write('.btn { width: 22px; height: 22px; border: 1px solid buttonface; margin: 0; padding: 0; } ');
document.write('.btnOver { width: 22px; height: 22px; border: 1px outset; } ');
document.write('.btnDown { width: 22px; height: 22px; border: 1px inset; background-color: buttonhighlight; } ');
document.write('.btnNA { width: 22px; height: 22px; border: 1px solid buttonface; filter: alpha(opacity=25); } ');
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> ');
/**//* ---------------------------------------------------------------------- *
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', '加粗', 'editor_action(this.id)', 'ed_format_bold.gif'],
"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', '关于当前编辑器', '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 in userConfig) ...{
if (userConfig[thisName]) ...{
config[thisName] = userConfig[thisName];
}
}
}
document.all[objname].config = config; // store config settings
// set size to specified size or size of original object
var obj = document.all[objname];
if (!config.width || config.width == "auto") ...{
if (obj.style.width) ...{ // use css style
config.width = obj.style.width;
}else if (obj.cols)...{ // col width + toolbar
config.width = (obj.cols * 8) + 22;
}else ...{ // default
config.width = '100%';
}
}
if (!config.height || config.height == "auto") ...{
if(obj.style.height)...{ // use css style
config.height = obj.style.height;
}else if (obj.rows)...{ // row height
config.height = obj.rows * 17
}else...{ // default
config.height = '200';
}
}
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> ';
// build button toolbar
var toolbar = '';
var btnGroup, btnItem, aboutEditor;
for (var btnGroup in config.toolbar) ...{
// linebreak
if (config.toolbar[btnGroup].length == 1 &&
config.toolbar[btnGroup][0].toLowerCase() == "linebreak") ...{
toolbar += '<br clear="all">';
continue;
}
toolbar += tblOpen;
for (var btnItem in config.toolbar[btnGroup]) ...{
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 in config.fontnames) ...{
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 in config.fontsizes) ...{
toolbar += '<option value="' +config.fontsizes[fontsize]+ '">' +fontsize+ '</option>'
}
toolbar += '</select> ';
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 in config.fontstyles) ...{
var fontstyle = config.fontstyles;
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. htmlArea wysiwyg editor not created."); return; }
if (!btnObj) ...{ alert("htmlArea error: button '" +btnName+ "' not found in button list when creating the wysiwyg editor for '"+objname+"'. Please make sure you entered the button name correctly. htmlArea 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> '
+ toolbar
+ '</td></tr></table> '
+ '</td></tr></table></span> '
+ '<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.all[objname].style.display = "none"; }
if (config.plaintextInput) ...{ // replace nextlines with breaks
var contents = document.all[objname].value;
contents = contents.replace(/ /g, '<br>');
contents = contents.replace(/ /g, '<br>');
contents = contents.replace(/ /g, '<br>');
document.all[objname].value = contents;
}
// insert wysiwyg
document.all[objname].insertAdjacentHTML('afterEnd', 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); });
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.all[button_id];
var editor_obj = document.all["_" +objname + "_editor"];
var config = document.all[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");
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.all[objname].config;
var editor_obj = document.all["_" +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.all[objname].config;
var editor_obj = document.all["_" +objname+ "_editor"];
// disable or enable toolbar
if (action == "enable" || action == "disable") ...{
var tbItems = new Array('FontName','FontSize','FontStyle'); // add pulldowns
for (var btnName in config.btnList) ...{ tbItems.push(config.btnList[btnName][0]); } // add buttons
for (var idxN in tbItems) ...{
var cmdID = tbItems[idxN].toLowerCase();
var tbObj = document.all["_" +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.all["_" +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.all["_" +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.all["_" +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.all["_" +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.all[objname].config;
var editor_obj = document.all["_" +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.all[objname].value = contents;
}
/**//* ---------------------------------------------------------------------- *
Function : editor_filterOutput
Description :
* ---------------------------------------------------------------------- */
function editor_filterOutput(objname) ...{
editor_updateOutput(objname);
var contents = document.all[objname].value;
var config = document.all[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(/(srcs*=s*.)[^*]*(***)/, "$1$2"); }
if (tagName == 'a') ...{ tagBody = tagBody.replace(/(hrefs*=s*.)[^*]*(***)/, "$1$2"); }
// add additional tag filtering here
// convert to vbCode
// if (tagName == 'b' || tagName == 'strong') {
// if (closingTag) { tagBody = "[/b]"; } else { tagBody = ""; }
// }
// else if (tagName == 'i' || tagName == 'em') {
// if (closingTag) { tagBody = ""; } 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(/ /g, ' ');
contents = contents.replace(/ /g, ' ');
contents = contents.replace(/ /g, ' ');
}
// update output with filtered content
document.all[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.all[objname].config;
var editor_obj = document.all["_" +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.all["_" +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.all[objname].value; } // on init use original textarea content
// create editor
editor_obj.outerHTML = RichEdit;
editor_obj = document.all["_" +objname + "_editor"];
// get iframe document object
// create editor contents (and default styles for editor)
var html = "";
html += '<html><head> ';
if (config.stylesheet) {
html += '<link href="' +config.stylesheet+ '" rel="stylesheet" type="text/css"> ';
}
html += '<style> ';
html += 'body {' +config.bodyStyle+ '} ';
for (var i in config.fontstyles) {
var fontstyle = config.fontstyles[i];
if (fontstyle.classStyle) {
html += '.' +fontstyle.className+ ' {' +fontstyle.classStyle+ '} ';
}
}
html += '</style> '
+ '</head> '
+ '<body contenteditable="true" topmargin=1 leftmargin=1'
// still working on this
// + ' oncontextmenu="parent.editor_cMenu_generate(window,'' +objname+ '');"'
+'>'
+ contents
+ '</body> '
+ '</html> ';
// write to editor window
var editdoc = editor_obj.contentWindow.document;
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.all[objname].config;
var editor_obj = document.all["_" +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.all[objname] && editor_obj == null) ...{
document.all[objname].focus();
document.all[objname].value = document.all[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.all["_" +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.all["_" +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.all["_" +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 in editor_cMenu.options) ...{
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.all['_'+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.all['_'+objname+'_editor'].offsetLeft;
var mouseY = event.clientY + parentWin.document.all['_'+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.all['_'+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); }
}
/**//* ---------------------------------------------------------------------- */
//创建以新的配置的对象
function newConfig(contentName)
...{
var config = new Object(); // 创建一个新的配置对象
config.width = "800px";
config.height = "400px";
config.bodyStyle = 'background-color: white; font-family: "Verdana"; font-size: x-small;';
config.debug = 0;
// NOTE: You can remove any of these blocks and use the default config!
config.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','htmlmode','separator'],
// ['about','help','popupeditor'],
];
// 配置对象的字体
config.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"
};
// 配置字体的大小
config.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"
};
// 配置字体的样式
//// config.stylesheet = "http://www.domain.com/sample.css";
// 配置字体的样式
config.fontstyles = [ // make sure classNames are defined in the 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" }
// leave classStyle blank if it's defined in config.stylesheet (above), like this:
// { name: "verdana blue", className: "headline4", classStyle: "" }
];
// 设置对象,和对象的样式
editor_generate(contentName,config); // 指定输入区域的样式
}
//创建以新的配置的对象:信息修改部分
function update_newConfig()
...{
var config = new Object(); // 创建一个新的配置对象
config.width = "800px";
config.height = "400px";
config.bodyStyle = 'background-color: white; font-family: "Verdana"; font-size: x-small;';
config.debug = 0;
// NOTE: You can remove any of these blocks and use the default config!
config.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','htmlmode','separator'],
['about','help','popupeditor'],
];
// 配置对象的字体
config.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"
};
// 配置字体的大小
config.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"
};
// 配置字体的样式
//// config.stylesheet = "http://www.domain.com/sample.css";
// 配置字体的样式
config.fontstyles = [ // make sure classNames are defined in the 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" }
// leave classStyle blank if it's defined in config.stylesheet (above), like this:
// { name: "verdana blue", className: "headline4", classStyle: "" }
];
// 设置对象,和对象的样式
editor_generate('content',config); // 指定中文输入区域的样式
}
//浏览器版本的控制
function browserControl()
...{
_editor_url = ""; // 当前文件的绝对的路径
var win_ie_ver = parseFloat(navigator.appVersion.split("MSIE")[1]); // 获得IE浏览器的版本号
/**//*
* 判断其他浏览器的方式
*/
if (navigator.userAgent.indexOf('Mac') >= 0) ...{ win_ie_ver = 0; }
if (navigator.userAgent.indexOf('Windows CE') >= 0) ...{ win_ie_ver = 0; }
if (navigator.userAgent.indexOf('Opera') >= 0) ...{ win_ie_ver = 0; }
// 这里是判断浏览器,需要IE5.5以上的版本支持
if (win_ie_ver >= 5.5) ...{
// document.write('<scr'+'ipt src="' +_editor_url+ 'js/editor.js" language="Javascript1.2"></scr'+'ipt>');
} else ...{
alert("不支持当前浏览器的版本");
document.write('<scr'+'ipt>function editor_generate() { return false; }</scr'+'ipt>');
}
// -->
}
使用该js只需要三个步骤:
1.通过<script language="javascript" src="js/editor.js" type="text/javascript""></script>引入该控件所在的文件;
2 调用browserControl()函数来判断客户端的浏览器类型,对不同的浏览器作不同的操作;
3. 调用newConfig()函数,将指定的textarea域设定为文本编辑区域.
经过该编辑器格式化的文字内容提交到数据库以后,从数据库中直接以字符串的格式取出来放在jsp页面中,就可以显示出原来发布时的 格式效果,这是因为javascirpt脚本已经对格式化文本做了特殊处理,比如加粗文字"[b]加粗"实际上存储的是"<b>加粗</b>"字符串。因此,显示页面无需作特殊处理,就可以恢复原文字的格式信息了。
2.tree.js && tree_tpl.js
这两个js主要实现了树型结构的展现,构造出树型菜单。
tree_tpl.js:
/**//*
Feel free to use your custom images for the tree. Make sure they are all of the same size.
User images collections are welcome, we'll publish them giving all regards.
*/
var tree_tpl = ...{
'target' : 'mainFrame', // name of the frame links will be opened in
// other possible values are: _blank, _parent, _search, _self and _top
'icon_e' : 'images/empty.gif', // empty image
'icon_l' : 'images/line.gif', // vertical line
'icon_32' : 'images/base.gif', // root icon normal
'icon_36' : 'images/base.gif', // root icon normal
'icon_48' : 'images/base.gif', // root icon normal
'icon_52' : 'images/base.gif', // root icon selected
'icon_56' : 'images/base.gif', // root icon opened
'icon_60' : 'images/base.gif', // root icon selected
'icon_16' : 'images/folder.gif', // node icon normal
'icon_20' : 'images/folderopen.gif', // node icon selected
'icon_24' : 'images/folder.gif', // node icon opened
'icon_28' : 'images/folderopen.gif', // node icon selected opened
'icon_0' : 'images/page.gif', // leaf icon normal
'icon_4' : 'images/page.gif', // leaf icon selected
'icon_8' : 'images/page.gif', // leaf icon opened
'icon_12' : 'images/page.gif', // leaf icon selected
'icon_2' : 'images/joinbottom.gif', // junction for leaf
'icon_3' : 'images/join.gif', // junction for last leaf
'icon_18' : 'images/plusbottom.gif', // junction for closed node
'icon_19' : 'images/plus.gif', // junctioin for last closed node
'icon_26' : 'images/minusbottom.gif',// junction for opened node
'icon_27' : 'images/minus.gif' // junctioin for last opended node
};
tree.js:
// Title: Tigra Tree
// Description: See the demo at url
// URL: http://www.softcomplex.com/products/tigra_menu_tree/
// Version: 1.0
// Date: 07-20-2002 (mm-dd-yyyy)
// Contact: feedback@softcomplex.com (specify product title in the subject)
// Notes: Registration needed to use this script on your web site.
// Registration for this version (1.0) is free of charge.
// Visit official site for details
function tree (a_items, a_template) ...{
this.a_tpl = a_template;
this.a_config = a_items;
this.o_root = this;
this.a_index = [];
this.o_selected = null;
this.n_depth = -1;
var o_icone = new Image(),
o_iconl = new Image();
o_icone.src = a_template['icon_e'];
o_iconl.src = a_template['icon_l'];
a_template['im_e'] = o_icone;
a_template['im_l'] = o_iconl;
for (var i = 0; i < 64; i++)
if (a_template['icon_' + i]) ...{
var o_icon = new Image();
a_template['im_' + i] = o_icon;
o_icon.src = a_template['icon_' + i];
}
this.toggle = function (n_id) ...{ var o_item = this.a_index[n_id]; o_item.open(o_item.b_opened) };
this.select = function (n_id) ...{ return this.a_index[n_id].select(); };
this.mout = function (n_id) ...{ this.a_index[n_id].upstatus(true) };
this.mover = function (n_id) ...{ this.a_index[n_id].upstatus() };
this.a_children = [];
for (var i = 0; i < a_items.length; i++)
new tree_item(this, i);
this.n_id = trees.length;
trees[this.n_id] = this;
for (var i = 0; i < this.a_children.length; i++) ...{
document.write(this.a_children[i].init());
this.a_children[i].open();
}
}
function tree_item (o_parent, n_order) ...{
this.n_depth = o_parent.n_depth + 1;
this.a_config = o_parent.a_config[n_order + (this.n_depth ? 2 : 0)];
if (!this.a_config) return;
this.o_root = o_parent.o_root;
this.o_parent = o_parent;
this.n_order = n_order;
this.b_opened = !this.n_depth;
this.n_id = this.o_root.a_index.length;
this.o_root.a_index[this.n_id] = this;
o_parent.a_children[n_order] = this;
this.a_children = [];
for (var i = 0; i < this.a_config.length - 2; i++)
new tree_item(this, i);
this.get_icon = item_get_icon;
this.open = item_open;
this.select = item_select;
this.init = item_init;
this.upstatus = item_upstatus;
this.is_last = function () ...{ return this.n_order == this.o_parent.a_children.length - 1 };
}
function item_open (b_close) ...{
var o_idiv = get_element('i_div' + this.n_id);
if (!o_idiv) return;
if (!o_idiv.innerHTML) ...{
var a_children = [];
for (var i = 0; i < this.a_children.length; i++)
a_children[i]= this.a_children[i].init();
o_idiv.innerHTML = a_children.join('');
}
o_idiv.style.display = (b_close ? 'none' : 'block');
this.b_opened = !b_close;
var o_jicon = document.images['j_img' + this.n_id],
o_iicon = document.images['i_img' + this.n_id];
if (o_jicon) o_jicon.src = this.get_icon(true);
if (o_iicon) o_iicon.src = this.get_icon();
this.upstatus();
}
function item_select (b_deselect) ...{
if (!b_deselect) ...{
var o_olditem = this.o_root.o_selected;
this.o_root.o_selected = this;
if (o_olditem) o_olditem.select(true);
}
var o_iicon = document.images['i_img' + this.n_id];
if (o_iicon) o_iicon.src = this.get_icon();
get_element('i_txt' + this.n_id).style.fontWeight = b_deselect ? 'normal' : 'bold';
this.upstatus();
return Boolean(this.a_config[1]);
}
function item_upstatus (b_clear) ...{
window.setTimeout('window.status="' + (b_clear ? '' : this.a_config[0] + (this.a_config[1] ? ' ('+ this.a_config[1] + ')' : '')) + '"', 10);
}
function item_init () ...{
var a_offset = [],
o_current_item = this.o_parent;
for (var i = this.n_depth; i > 1; i--) ...{
a_offset[i] = '<img src="' + this.o_root.a_tpl[o_current_item.is_last() ? 'icon_e' : 'icon_l'] + '" border="0" align="absbottom">';
o_current_item = o_current_item.o_parent;
}
return '<table cellpadding="0" cellspacing="0" border="0"><tr><td nowrap>' + (this.n_depth ? a_offset.join('') + (this.a_children.length ? '<a href="javascript: trees[' + this.o_root.n_id + '].toggle(' + this.n_id + ')" onmouseover="trees[' + this.o_root.n_id + '].mover(' + this.n_id + ')" onmouseout="trees[' + this.o_root.n_id + '].mout(' + this.n_id + ')"><img src="' + this.get_icon(true) + '" border="0" align="absbottom" name="j_img' + this.n_id + '"></a>' : '<img src="' + this.get_icon(true) + '" border="0" align="absbottom">') : '') + '<a href="' + this.a_config[1] + '" target="' + this.o_root.a_tpl['target'] + '" onclick="return trees[' + this.o_root.n_id + '].select(' + this.n_id + ')" ondblclick="trees[' + this.o_root.n_id + '].toggle(' + this.n_id + ')" onmouseover="trees[' + this.o_root.n_id + '].mover(' + this.n_id + ')" onmouseout="trees[' + this.o_root.n_id + '].mout(' + this.n_id + ')" class="t' + this.o_root.n_id + 'i" id="i_txt' + this.n_id + '"><img src="' + this.get_icon() + '" border="0" align="absbottom" name="i_img' + this.n_id + '" class="t' + this.o_root.n_id + 'im">' + this.a_config[0] + '</a></td></tr></table>' + (this.a_children.length ? '<div id="i_div' + this.n_id + '" style="display:none"></div>' : '');
}
function item_get_icon (b_junction) ...{
// alert('icon_' + ((this.n_depth ? 0 : 32) + (this.a_children.length ? 16 : 0) + (this.a_children.length && this.b_opened ? 8 : 0) + (!b_junction && this.o_root.o_selected == this ? 4 : 0) + (b_junction ? 2 : 0) + (b_junction && this.is_last() ? 1 : 0)));
return this.o_root.a_tpl['icon_' + ((this.n_depth ? 0 : 32) + (this.a_children.length ? 16 : 0) + (this.a_children.length && this.b_opened ? 8 : 0) + (!b_junction && this.o_root.o_selected == this ? 4 : 0) + (b_junction ? 2 : 0) + (b_junction && this.is_last() ? 1 : 0))];
}
var trees = [];
get_element = document.all ?
function (s_id) ...{ return document.all[s_id] } :
function (s_id) ...{ return document.getElementById(s_id) };
这是一次测试:
<%...@page contentType="text/html; charset=GBK" language="java" %>
<%...
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<script language="javascript1.2" src="./js/editor.js" type="text/javascript"></script>
<script language="Javascript1.2">...browserControl()</script>
<textarea name="content" style="width:100%; height:80"></textarea>
<script language="javascript1.2">...newConfig('content')</script>
<%...StringBuffer strBuf = new StringBuffer(); //构造字符串
strBuf.append("['根','some/path/to/my/url?column=1',"+" "+
"['根-叶结点1','some/path/to/my/url?column=2']],"+
"['根','some/path/to/my/url?column=3',"+" "+
"['根-叶结点2','some/path/to/my/url?column=4']],");
%>
<script language="JavaScript" src="./js/tree.js"></script> <script language="JavaScript">...
var TREE_ITEMS = [
<%=strBuf.toString()%>
];
</script> <script language="JavaScript" src="./js/tree_tpl.js"></script> <script language="JavaScript">...
new tree (TREE_ITEMS, tree_tpl);
</script>
test!
</body>
</html>
相关文章推荐
- js树型菜单的实现原理
- JS实现获取word文档内容并输出显示到html页面示例
- JS如何实现点击页面其他地方隐藏菜单?
- 使用"函数递归"实现基于php和MySQL的动态树型菜单
- js树型菜单的实现原理
- js关闭当前页面不弹出提示的方法 js实现浏览器的各种菜单命令
- 使用"函数递归"实现的树型菜单 (转)
- JS+CSS实现类似QQ好友及黑名单效果的树型菜单
- 使用js实现页面导出到word文档
- JS+CSS实现类似QQ好友及黑名单效果的树型菜单
- js实现页面跳转菜单选中
- js+css实现页面右键菜单
- JS巧妙实现多级菜单中当前菜单不随页面跳转样式而发生变化
- JS组件dtree轻松实现树型菜单
- [JS&Jquery]实现页面表格中相同内容的行或列合并
- JSP+mssql+tomcat 实现jsp页面读取数据库目录信息,以树型菜单显示
- js+css实现页面右键菜单
- JS组件dtree轻松实现树型菜单
- JS实现多级菜单中当前菜单不随页面跳转样式而发生变化
- js实现 菜单iframe与主页面iframe 重叠 防止互相遮挡 代码参考