File "editor.js"
Full Path: /home/analogde/www/private/templates/common/editor.js
File size: 37.61 KB
MIME-type: text/plain
Charset: utf-8
/*
* =================================================================
* HTML Editor - A wysiwyg web based editor for Mozilla V1.4+
* Website : http://gossamer-threads.com/
* Revision : $Id: editor.js,v 1.20 2004/04/08 17:40:46 bao Exp $
*
* Copyright (c) 2004 Gossamer Threads Inc. All Rights Reserved.
* Redistribution in part or in whole strictly prohibited. Please
* see LICENSE file for full details.
* =================================================================
*
* Description: Common functions needed to display the toolbar for an
* HTML-editing iframe, as used in Gossamer Forum.
*/
/* -- Javascript needed to write a post -- */
var iframe, editor, inner_content, outerdoc, main_form;
var pressedInterval, initializing, initialized, editorWidth, windowResized;
var inner_content_loaded = false;
var controlRange; // selection is a ControlRange collection
window.onresize = window_resize;
var unStack = new Array();
var reStack = new Array();
var unPress = false;
var input = parent.load_param();
var baseURL = input[0];
var extraURL = input[1];
var imageURL = input[2];
var mainForm = input[3];
var contentObj = input[4];
var formTools = input[5];
var temp_id = input[6];
var attachments = input[7];
var dialogWindow = new Object();
var is_ie = <%if is_ie%>true<%else%>false<%endif%>;
var doc_attr = is_ie ? 'document' : 'contentDocument';
function window_resize () {
windowResized = true;
}
var initOuterIFrameCalled = false;
function initOuterIFrame () {
if (initOuterIFrameCalled) return;
else initOuterIFrameCalled = true;
if (is_ie)
outerdoc = parent.document.frames.editor_iframe.document;
else
outerdoc = parent.document.getElementById('editor_iframe').contentDocument;
setTimeout("initInnerIFrame()", 100);
}
// Somehow, initInnerIFrame is sometimes called simultaneously; this lock
// variable locks out any subsequent calls
var initInnerIFrameLocked = false;
function initInnerIFrame () {
if (initInnerIFrameLocked) return;
initInnerIFrameLocked = true;
var varsOkay = false;
if (is_ie) iframe = outerdoc.frames.editor_iframe;
else iframe = outerdoc.getElementById('editor_iframe');
if ((is_ie || inner_content_loaded) && iframe) {
main_form = parent.document[mainForm];
if (main_form) {
editor = iframe[doc_attr];
if (editor) {
inner_content = editor.getElementById('inner_content');
if (inner_content) {
if (is_ie) inner_content.contentEditable = true;
else editor.designMode = "on";
varsOkay = true;
}
}
}
}
if (!varsOkay) {
setTimeout("initInnerIFrame()", 100);
initInnerIFrameLocked = false;
return;
}
try {
editor.execCommand("Undo", false, null);
} catch (e) {
alert("The HTML editor does not appear to be supported by your browser: " + e);
}
//if (!is_ie) editor.execCommand("useCSS", false, null);
initHTML();
setTimeout("toolbarInit()", 100);
main_form.onsubmit = retrieveHTML;
if (!pressedInterval) pressedInterval = setInterval("calcPressed()", 150);
}
var pressLoopInit = false;
var pressButtons = {};
var pressLoop = [];
function calcPressed () {
if (windowResized) {
tb_layout();
windowResized = false;
}
if (is_ie) controlRange = (editor.selection.type == "Control") ? true : false;
if (!pressLoopInit) {
pressLoop[pressLoop.length] = 'Bold';
pressButtons['Bold'] = [outerdoc.getElementById('bold'), outerdoc.getElementById('boldImage')];
pressLoop[pressLoop.length] = 'Italic';
pressButtons['Italic'] = [outerdoc.getElementById('italic'), outerdoc.getElementById('italicImage')];
pressLoop[pressLoop.length] = 'Underline';
pressButtons['Underline'] = [outerdoc.getElementById('underline'), outerdoc.getElementById('underlineImage')];
pressLoop[pressLoop.length] = 'JustifyLeft';
pressButtons['JustifyLeft'] = [outerdoc.getElementById('jleft'), outerdoc.getElementById('jleftImage')];
pressLoop[pressLoop.length] = 'JustifyCenter';
pressButtons['JustifyCenter'] = [outerdoc.getElementById('jcenter'), outerdoc.getElementById('jcenterImage')];
pressLoop[pressLoop.length] = 'JustifyRight';
pressButtons['JustifyRight'] = [outerdoc.getElementById('jright'), outerdoc.getElementById('jrightImage')];
pressLoop[pressLoop.length] = 'InsertOrderedList';
pressButtons['InsertOrderedList'] = [outerdoc.getElementById('ol'), outerdoc.getElementById('olImage')];
pressLoop[pressLoop.length] = 'InsertUnorderedList';
pressButtons['InsertUnorderedList'] = [outerdoc.getElementById('ul'), outerdoc.getElementById('ulImage')];
pressLoopInit = true;
}
for (var i = 0; i < pressLoop.length; i++) {
var pressed = editor.queryCommandState(pressLoop[i]);
var span = pressButtons[pressLoop[i]][0];
var image = pressButtons[pressLoop[i]][1];
if (pressed && !span.isPressed) press(span, image);
else if (!pressed && span.isPressed) unpress(span, image);
else if (span.isPressed == null) span.isPressed = false;
}
var buttons = {
'link' : 'CreateLink',
'bold' : 'Bold',
'italic' : 'Italic',
'underline' : 'Underline',
'ol' : 'InsertOrderedList',
'ul' : 'InsertUnorderedList',
'od' : 'Outdent',
'id' : 'Indent',
'font' : 'FontName',
'fcolor' : 'ForeColor',
'horRule' : 'InsertHorizontalRule',
'insImage' : 'InsertImage'
};
if (is_ie) {
buttons['cut'] = 'Cut';
buttons['copy'] = 'Copy';
buttons['paste'] = 'Paste';
}
if (formTools) {
buttons['form'] = 'Bold';
buttons['text'] = 'Bold';
buttons['textarea'] = 'Bold';
buttons['checkbox'] = 'Bold';
buttons['radio'] = 'Bold';
buttons['select'] = 'Bold';
buttons['button'] = 'Bold';
}
for (var i in buttons) {
var querycommand = buttons[i];
var button = outerdoc.getElementById(i);
var possible = false;
try {
possible = editor.queryCommandEnabled(querycommand);
} catch (e) { }
if ( possible && button.disabled)
enable(button);
else if (!possible && !button.disabled)
disable(button);
}
if (!is_ie) return;
var bool_table = check_env();
if ( bool_table ) {
if (outerdoc.all.insCell.disabled) enable (outerdoc.all.insCell);
if (outerdoc.all.insRow.disabled) enable (outerdoc.all.insRow);
if (outerdoc.all.insCol.disabled) enable (outerdoc.all.insCol);
if (outerdoc.all.delCell.disabled) enable (outerdoc.all.delCell);
if (outerdoc.all.delRow.disabled) enable (outerdoc.all.delRow);
if (outerdoc.all.delCol.disabled) enable (outerdoc.all.delCol);
if (outerdoc.all.split.disabled) enable (outerdoc.all.split);
}
else {
if (!outerdoc.all.insCell.disabled) disable (outerdoc.all.insCell);
if (!outerdoc.all.insRow.disabled) disable (outerdoc.all.insRow);
if (!outerdoc.all.insCol.disabled) disable (outerdoc.all.insCol);
if (!outerdoc.all.delCell.disabled) disable (outerdoc.all.delCell);
if (!outerdoc.all.delRow.disabled) disable (outerdoc.all.delRow);
if (!outerdoc.all.delCol.disabled) disable (outerdoc.all.delCol);
if (!outerdoc.all.split.disabled) disable (outerdoc.all.split);
}
if (check_merge()) {
if (outerdoc.all.merge.disabled) enable(outerdoc.all.merge);
}
else {
disable(outerdoc.all.merge);
}
}
function initHTML(type) {
var initValue = main_form.pre_content.value;
var epos = initValue.search('<BODY');
if (epos == -1) epos = initValue.search('<body');
var head = initValue.substr(0,epos);
head = head.replace('<html>','');
parent.document[mainForm].header.value = head;
initValue = initValue.replace(head,'');
initValue = initValue.replace('</html>','');
if (type) {
inner_content.innerHTML = '';
iframe.focus();
var selection = editor.selection.createRange();
var html = htmlUNESCAPE(initValue);
selection.pasteHTML(html);
iframe.focus();
}
else {
inner_content.innerHTML = initValue;
}
}
function htmlESCAPE(content) {
content = content.replace(/\&/gi,'&');
content = content.replace(/\</gi,'<');
content = content.replace(/\>/gi,'>');
content = content.replace(/\"/gi,'"');
return content;
}
function htmlUNESCAPE(content) {
content = content.replace(/(\<\;)/gi,'<');
content = content.replace(/(\>\;)/gi,'>');
content = content.replace(/(\"\;)/gi,'"');
content = content.replace(/(\&\;)/gi,'&');
return content;
}
function press (button, image) { // Takes a span from the outer iframe and "presses" it.
button.isPressed = true;
button.className = "menu_item_mouseoverdown";
image.className = "icon_down";
}
function unpress (button, image) { // Takes one of the spans from the editor_iframe page and unpresses the button
button.isPressed = false;
button.className = "tb_menu_item";
image.className = "tb_icon";
}
function disable (button) { // Disables a span
button.className = "tb_menu_item";
button.disabled = true;
if (is_ie)
button.style.filter = "progid:DXImageTransform.Microsoft.Alpha(style=0, opacity=25)";
else {
var agent = navigator.userAgent;
var ver = /Mozilla\/5\.0\s*\(X11; [^)]*; rv:(\d\.\d+)([ab]?)\)/.exec(agent);
// GTK2 Mozilla/Firebird/etc. builds do not properly support the -moz-opacity style. This
// is mozilla bug 201209, which was fixed in the 1.6 trunk on 2003-11-01. Therefore, if
// on X11, we require >= 1.6b in order to enable the mozopacity style.
if (!ver || (ver.index >= 0 && (ver[1] > 1.6 || (ver[1] == 1.6 && (!ver[2] || ver[2] >= 'b')))))
button.style.MozOpacity = 0.25;
}
}
function enable (button) { // Enables a span
button.disabled = false;
if (is_ie)
button.style.filter = null;
else
button.style.MozOpacity = 1;
}
var pressLoopInit = false;
var pressButtons = {};
var pressLoop = [];
function retrieveHTML () {
var body = inner_content.innerHTML;
var head = main_form.header.value
if (body){
var style = /style="BORDER-RIGHT: red 1px dotted; PADDING-RIGHT: 2px; BORDER-TOP: red 1px dotted; PADDING-LEFT: 2px; PADDING-BOTTOM: 2px; BORDER-LEFT: red 1px dotted; PADDING-TOP: 2px; BORDER-BOTTOM: red 1px dotted"/gi;
body = body.replace(style,'');
body = body.replace('id=inner_content contentEditable=true','');
var html = '<html>' + head + body + '\n</html>';
html = html.replace(/\n\s/gi,'');
main_form.content.value = html;
}
}
function command (cmd) {
setFocus();
editor.execCommand(cmd, false, null);
}
var colorCmd = 'ForeColor';
function colorDialog (id, cmd) {
setFocus();
if (cmd != 'ForeColor' && is_ie ) {
colorCmd = 'BackColor';
}
else {
colorCmd = cmd;
}
if (!is_ie) dialogWindow.currentColor = editor.queryCommandValue(cmd);
showDialog('editor_color', 345, 193, returnColor);
}
function fontLoad(fontSelect, styleSelect, sizeSelect, underlineCheckbox) {
if (typeof(editor) == 'undefined') return;
var name = editor.queryCommandValue('FontName').toLowerCase();
var size = editor.queryCommandValue('FontSize');
var bold = editor.queryCommandState('Bold');
var italic = editor.queryCommandState('Italic');
var underline = editor.queryCommandState('Underline');
if (name != '') {
for (i=0; i < fontSelect.length; i++) {
if (fontSelect.options[i].text.toLowerCase() == name) {
fontSelect.selectedIndex = i;
break;
}
}
}
if (size) {
for (i=0; i < sizeSelect.length; i++) {
if (sizeSelect.options[i].value == size) {
sizeSelect.selectedIndex = i;
break;
}
}
}
styleSelect.value = bold && italic ? 'bi' : bold ? 'b' : italic ? 'i' : 'r';
underlineCheckbox.checked = underline;
}
function returnFont (font, size, color, bold, italic, underline) {
var nowB = editor.queryCommandState('Bold');
var nowI = editor.queryCommandState('Italic');
var nowU = editor.queryCommandState('Underline');
setFocus();
if (font) editor.execCommand('FontName', false, font);
if (size) editor.execCommand('FontSize', false, size);
if (color) editor.execCommand('ForeColor', false, color);
if (bold && !nowB || !bold && nowB) editor.execCommand('Bold', false, null);
if (italic && !nowI || !italic && nowI) editor.execCommand('Italic', false, null);
if (underline && !nowU || !underline && nowU) editor.execCommand('Underline', false, null);
}
function returnColor (color) {
setFocus();
if (!color) return;
if ( colorCmd == 'ForeColor' ) {
editor.execCommand(colorCmd, false, color);
return;
}
if (is_ie) {
if (controlRange) {
var oControlRange = editor.selection.createRange();
for (i = 0; i < oControlRange.length; i++) {
if (oControlRange(i).tagName.toUpperCase() == "TABLE")
oControlRange(i).bgColor = color;
}
}
else {
if (getSelection()) {
editor.execCommand(colorCmd, false, color);
}
else inner_content.bgColor = color;
}
}
else if ( getSelection() ) {
editor.execCommand(colorCmd, false, color);
}
else inner_content.bgColor = color;
}
function returnLink (url) {
if (url == '' || url == 'http://')
return;
setFocus();
editor.execCommand('CreateLink', false, url);
}
function returnImage (object) {
if (typeof(object) == 'undefined')
return;
setFocus();
insertNodeAtSelection(object);
}
function setFocus () {
var obj;
if (is_ie)
obj = inner_content;
else
obj = document.getElementById("editor_iframe").contentWindow;
obj.focus();
}
function showDialog (do_equals, width, height, dialogReturn) {
/*------------------------------------------------------------
* show dialog window
*/
var url = baseURL + ';page=' + do_equals + '.html;' + extraURL;
if (dialogWindow.win && !dialogWindow.win.closed && dialogWindow.url == url) {
dialogWindow.win.focus();
}
else {
if (dialogWindow.win && !dialogWindow.win.closed) dialogWindow.win.close();
dialogWindow.returnFunc = dialogReturn;
dialogWindow.url = url;
dialogWindow.width = width;
dialogWindow.height = height;
dialogWindow.name = Math.random().toString().replace(/\./, "");
dialogWindow.left = (screen.width - width) / 2;
dialogWindow.top = (screen.height - height) / 2;
dialogWindow.attribs = 'left=' + dialogWindow.left + ',' +
'top=' + dialogWindow.top + ',' +
'resizable=no,statusbar=no,' +
'width=' + dialogWindow.width + ',' +
'height=' + dialogWindow.height;
dialogWindow.win = window.open(dialogWindow.url, dialogWindow.name, dialogWindow.attribs);
dialogWindow.win.focus();
}
}
function getSelection () {
var ret;
if (is_ie) {
ret = editor.selection.createRange().htmlText;
}
else {
var span = document.createElement("span");
var sel = document.getElementById('editor_iframe').contentWindow.getSelection();
span.appendChild(sel.getRangeAt(sel.rangeCount-1).cloneContents());
ret = span.innerHTML;
}
return ret;
}
/* Table's feature: insert table, insert/delete/merge cell, insert row/col */
function returnTable(rows, cols, width, padding, spacing, border) {
var table = editor.createElement("TABLE");
var tbody = editor.createElement("tbody");
var cols = cols || 3;
var rows = rows || 3;
table.width = width || '100%';
table.border = border || 1;
table.cellPadding = padding || 1;
table.cellspacing = spacing || 1;
//create rows and cells
if (cols > 0 && rows >0) {
for (var i=0; i < rows; i++) {
var tr = editor.createElement("tr");
for (var j=0; j < cols; j++) {
var td = editor.createElement("td");
td.innerHTML = ' ';
tr.appendChild(td);
}
tbody.appendChild(tr);
}
table.appendChild(tbody);
}
setFocus();
insertNodeAtSelection(table);
}
function insert_row() {
/* ------------------------------------------------------------
* Insert new row
*/
var mytable = selected_table();
if (mytable) {
var currentRow = selected_tr(mytable);
var cols = mytable.rows[currentRow].cells.length;
var oRow = mytable.insertRow(currentRow);
for (var i=0; i<cols ;i++ ) oRow.insertCell();
}
}
function insert_col() {
/* ------------------------------------------------------------
* Insert a column
*/
var mytable = selected_table();
if (mytable) {
var rows = mytable.rows.length;
for (var i=0; i<rows; i++) insert_cell(i);
}
}
function insert_cell(nrow,ncol) {
/* ------------------------------------------------------------
* Insert a cell
*/
var mytable = selected_table();
if (mytable) {
var currentRow = (nrow >=0) ? nrow : selected_tr(mytable);
var currentCol = (ncol >=0) ? ncol : selected_td(mytable,currentRow);
mytable.rows[currentRow].insertCell(currentCol);
}
}
function delete_row() {
/* ------------------------------------------------------------
* Delete a row
*/
var mytable = selected_table();
if (mytable) mytable.deleteRow(selected_tr(mytable));
}
function delete_col() {
/* ------------------------------------------------------------
* Delete a column
*/
var mytable = selected_table();
if (mytable) {
var currentRow = selected_tr(mytable);
var currentCol = selected_td(mytable,currentRow);
var rows = mytable.rows.length;
for (var i=0; i<rows; i++) delete_cell(i,currentCol);
}
}
function delete_cell(nrow,ncol) {
/* ------------------------------------------------------------
* Delete a cell
*/
var mytable = selected_table();
if (mytable) {
var currentRow = (nrow >=0)? nrow : selected_tr(mytable);
var currentCol = (ncol >=0)? ncol : selected_td(mytable,currentRow);
if (currentCol < mytable.rows[currentRow].cells.length) mytable.rows[currentRow].deleteCell(currentCol);
if (mytable.rows[currentRow].cells.length == 0) mytable.deleteRow(currentRow);
}
}
function split_cell() {
/* ------------------------------------------------------------
* Split a cell
*/
var mytable = selected_table();
if (!mytable) return
var currentRow = selected_tr(mytable);
var currentCol = selected_td(mytable,currentRow);
var rows = mytable.rows.length;
var cols = mytable.rows[currentRow].cells.length;
var span = mytable.rows[currentRow].cells[currentCol].colSpan;
for (var i=0; i<rows; i++) {
if ( i == currentRow) {
if (mytable.rows[i].cells[currentCol].colSpan > 1) mytable.rows[i].cells[currentCol].colSpan--;
insert_cell(currentRow,currentCol);
}
else {
var ncol;
var nlen = mytable.rows[i].cells.length;
if ( span == 1) {
var jspan = 0;
for (var j=0; j<nlen ; j++) {
jspan += mytable.rows[i].cells[j].colSpan;
if (jspan - 1 >= currentCol) { ncol = j; break; }
}
mytable.rows[i].cells[ncol].colSpan++;
}
else {
if (currentCol > 0 ) {
var jmax = 0;
var jcol = (currentCol >= nlen - 1) ? nlen - 1 : currentCol-1;
for (var j=0; j<rows ; j++) {
var mlen = mytable.rows[j].cells.length
var mcol = (currentCol >= mlen-1) ? mlen - 1 : currentCol-1;
if (mytable.rows[j].cells[mcol].colSpan > jmax) jmax = mytable.rows[j].cells[mcol].colSpan;
}
if (mytable.rows[i].cells[jcol].colSpan == jmax) { ncol = currentCol; }
else {
var jspan = 0;
for (var j=0; j<jmax ; j++ ) {
jspan += mytable.rows[i].cells[j].colSpan;
if (jspan == jmax) ncol = (j == jmax - 1) ? jmax : j;
}
}
}
}
}
}
}
function merge_cell() {
/* ------------------------------------------------------------
* Split a cell
*/
var mytable = selected_table();
if (!mytable)
return
rows = mytable.rows.length;
//mark TD id
for (var i=0; i<rows ; i++) {
cols = mytable.rows[i].cells.length;
for (var j=0; j<cols ; j++) mytable.rows[i].cells[j].ch = i + '-' + j;
}
htmlText = editor.selection.createRange().htmlText;
htmlText.toUpperCase();
if (htmlText.search('<TR') != -1) return;
var pos = pre_merge(htmlText);
currentRow = parseInt(pos[0]); begCol = parseInt(pos[1]); endCol = parseInt(pos[2])
if ( begCol <= endCol && currentRow >= 0) {
var data = '';
var html = '';
var count = 0;
var nspan = 0;
for (var i=begCol; i<=endCol; i++) {
if (mytable.rows[currentRow].cells[i].hasChildNodes()) {
if (mytable.rows[currentRow].cells[i].innerHTML) html += mytable.rows[currentRow].cells[i].innerHTML;
data += mytable.rows[currentRow].cells[i].childNodes.item(0).data + ' ';
}
nspan += mytable.rows[currentRow].cells[i].colSpan;
count++;
}
for (var i=begCol; i<endCol ; i++ ) { delete_cell(currentRow,begCol); }
mytable.rows[currentRow].cells[begCol].colSpan = nspan;
mytable.rows[currentRow].cells[begCol].childNodes.item(0).data = data;
if (html) mytable.rows[currentRow].cells[begCol].innerHTML = html;
}
}
function pre_merge(htmlText) {
/* ----------------------------------
* Define currentRow, begCol, endCol in merge cell
*/
items = htmlText.split("</TD>");
var currentRow,begCol,endCol;
for (i=0; i<items.length ;i++) {
if ( items[i] != '' && items[i].search('<TR') == -1) {
pos1 = items[i].indexOf(">");
pos2 = items[i].indexOf("ch=");
tmp = items[i].substr(pos2+3,pos1-pos2-3)
elem = tmp.split('-');
if (i==0) {
currentRow = elem[0];
begCol = elem[1];
}
endCol = elem[1];
}
}
return [currentRow,begCol,endCol];
}
function selected_table () {
/* ------------------------------------------------------------
* Return a current table object
*/
if (!editor) return;
var table = inner_content.getElementsByTagName("table");
for (var i=table.length-1; i >= 0; i-- )
if (isChild(table(i))) return table(i);
}
function selected_tr (mytable) {
/*------------------------------------------------------------
* Return a number of current row
*/
var rows = mytable.rows;
for (var i=0; i < rows.length; i++)
if (isChild(rows(i))) return i;
}
function selected_td (mytable,currentRow) {
/* ------------------------------------------------------------
* Return a number of current column
*/
var cols = mytable.rows[currentRow].cells;
for (var i=0; i < cols.length; i++)
if (isChild(cols(i))) return i;
}
function isChild(obj) {
/* ------------------------------------------------------------
* Return 1: if the cursor is in an object area
*/
if (!controlRange) {
// selection is a TextRange
var rcts = obj.getClientRects();
var selection = editor.selection.createRange();
var sel_rcts = selection.getClientRects();
var keyCount=0;
if ( (sel_rcts[keyCount].top >= rcts[keyCount].top) && (sel_rcts[keyCount].bottom <= rcts[keyCount].bottom) && (sel_rcts[keyCount].left >= rcts[keyCount].left) && (sel_rcts[keyCount].right <= rcts[keyCount].right) )
return 1;
}
}
function check_env() {
var mytable = selected_table();
if (!mytable) return;
if ( selected_tr(mytable) >=0 ) return true;
}
function check_merge(type) {
if (controlRange) return false;
htmlText = editor.selection.createRange().htmlText;
htmlText.toUpperCase();
var ret = (type) ? ((htmlText.search('<TR') != -1 || htmlText.search('<TD') != -1) && htmlText != '') : (htmlText.search('<TR') == -1 && htmlText != '' && htmlText.search('<TD') != -1);
return ret;
}
/* Forms features */
function returnForm(html) {
var span = editor.createElement("SPAN");
span.innerHTML = html;
setFocus();
insertNodeAtSelection(span);
}
/* -- Toolbar initialization is below -- */
var initInterval, toolbars, tb;
// Keep track of number of images loaded.
//var imagesLoaded = 0;
function toolbarInit () {
/* ---------------------------------------------------------
* Should be called after the outerdoc has loaded.
* Initializes the Toolbar for display.
*/
if (initialized || initializing) return;
initializing = true;
if (!outerdoc) {
initializing = false;
setTimeout("toolbarInit()", 100);
return initOuterIFrame();
}
var tbs = outerdoc.getElementsByTagName("DIV");
var imgs = outerdoc.getElementsByTagName("IMG");
// There are 3 <div>'s on Mozilla, 4 on IE, containing 20 <img>'s on
// Mozilla, 23 on IE. If anything is added or removed, this numbers MUST be
// updated added, this number should be incremented.
if (tbs.length < 3 || imgs.length < 19) {
initializing = false;
setTimeout("toolbarInit()", 100);
return;
}
if (parent.document.getElementById('load_bar')) {
parent.document.getElementById('load_bar').innerHTML = '';
}
parent.document.getElementById('editor_iframe').style.visibility = "visible";
tb = {};
// 'toolbars' contains all the div tags
toolbars = [];
// Go through the outerdoc and get the toolbar classes
for (var i = 0; i < tbs.length; i++) {
var toolbar = tbs[i];
tb[toolbar.title] = toolbar;
toolbars[toolbars.length] = toolbar;
toolbar.TB_INDEX = toolbars.length;
// Initialize the toolbar
tb_init(toolbar);
}
tb_layout();
initialized = true;
}
function tb_init (toolbar) {
/* ---------------------------------------------------------
* Called for each toolbar DIV. Populates the toolbar and
* sets the width.
*/
toolbar.TBWidth = 1;
tb_populate(toolbar)
toolbar.style.posWidth = toolbar.TBWidth;
return true;
}
function tb_populate (toolbar) {
/* ---------------------------------------------------------
* Moves all of toolbar 'toolbar's icons to the proper location on
* the screen and sets the correct size for the toolbars.
*/
var elements = toolbar.childNodes;
if (!elements) return;
// Loop through all the toolbars children.
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if (element.tagName == "SCRIPT" || element.tagName == "!") continue;
// Switch to see what element we are workin with.
switch (element.className) {
case "tb_menu_item": // A button
if (!element.INITIALIZED)
tb_init_button(element)
element.style.left = toolbar.TBWidth;
toolbar.TBWidth += element.offsetWidth + 1;
break;
case "tb_general": // Not a button - most likely a form field
case "tb_menu_text":
element.style.left = toolbar.TBWidth;
toolbar.TBWidth += element.offsetWidth + 5;
break;
case "tb_sep": // Seperator
element.style.left = toolbar.TBWidth + 2;
toolbar.TBWidth += 5;
break;
case "tb_handle": // Toolbar handle
element.style.left = 2;
toolbar.TBWidth += element.offsetWidth + 7;
break;
default: // No action
}
}
toolbar.TBWidth++; // Add 1 in case the width is zero
return true;
}
function tb_init_button (element) {
/* ---------------------------------------------------------
* Sets up all the defaults for a button DIV. Saves any
* onclick and detaches the event. OnClick events are called
* onMouseDown.
*/
if (element.className == "tb_general") return true;
// Set events
element.onmouseover = tb_mouseover;
element.onmouseout = tb_mouseout;
element.onmousedown = tb_mousedown;
element.onmouseup = tb_mouseup;
// Save onClick event for onMouseDown
element.YUSERONCLICK = element.onclick;
// So we don't re-initialize
element.INITIALIZED = true;
return true;
}
function tb_layout () {
/* ---------------------------------------------------------
* Layouts the toolbar on the screen based on the screen
* width and the widths built in tb_populate().
*/
if (!initializing && !initialized) return toolbarInit();
var num_tb = toolbars.length;
// No toolbars
if (num_tb == 0) return;
var i;
// Get the screen width minus the width of the scrollbar
var sbar = outerdoc.body.clientWidth - outerdoc.body.offsetWidth;
editorWidth = outerdoc.body.offsetWidth;
var ScrWid = (outerdoc.body.offsetWidth - sbar) + (is_ie ? -6 : 7);
var ScrHit = (parent.document.getElementById('editor_iframe').offsetHeight - sbar) - (is_ie ? 6 : 5);
// Go through the toolbars and find the width of the widest one.
var TotalLen = ScrWid;
var tb = [];
var e = 0;
for (i = 0; i < num_tb; i++) {
tb[e] = toolbars[i];
if (tb[e].TBWidth > TotalLen) TotalLen = tb[e].TBWidth;
e++;
}
e--;
if (!tb.length) { return; }
var PrevTB;
var LastStart = 0;
var RelTop = 0;
var LastWid, CurrWid;
// Position the top toolbar to the top of the screen
var TB = tb[0];
TB.style.top = 0;
TB.style.left = 0;
var rows = 1;
// Go through the toolbars and update their width and position.
var Start = TB.TBWidth;
var wExtra = 0
var hExtra = 0;
for (i = 1; i < tb.length; i++) {
PrevTB = TB;
TB = tb[i];
CurrWid = TB.TBWidth;
// Reached the end of the screen, reset to the start
if ((Start + CurrWid) > ScrWid) {
Start = 0;
rows++;
LastWid = TotalLen - LastStart + hExtra;
}
else {
LastWid = PrevTB.TBWidth;
RelTop -= TB.offsetHeight;
}
TB.style.top = RelTop;
TB.style.left = Start;
PrevTB.style.width = LastWid;
LastStart = Start;
Start += CurrWid;
}
outerdoc.getElementById('editor_iframe').style.top = rows * (is_ie ? 25 : 27);
outerdoc.getElementById('editor_iframe').style.height = ScrHit - rows * (is_ie ? 25 : 27) + wExtra;
outerdoc.getElementById('editor_iframe').style.width = ScrWid + wExtra;
outerdoc.getElementById('editor_iframe').style.visibility = 'visible';
// Set the total width
TB.style.width = TotalLen - LastStart + hExtra;
// Move the rest of the toolbars down
TB = tb[--i];
var TBInd = TB.sourceIndex;
var A = TB.childNodes;
for (var i in A) {
var item = A.item(i);
if (item && item.style && item.sourceIndex > TBInd && tb[item.title])
item.style.posTop = RelTop;
}
}
function tb_mouseover (event) {
/* ---------------------------------------------------------
* OnMouseOver event handler function for toolbar buttons.
*/
var image, element;
if ( is_ie ) {
event = parent.document.frames.editor_iframe.event;
if (event.srcElement.tagName.toUpperCase() != "IMG") return cancel_event(event);
image = event.srcElement;
element = image.parentElement;
// If we are in text mode and the button is disables for
// text mode. cancel the mouseover.
}
else {
image = outerdoc.getElementById(this.id + 'Image');
element = this;
}
if (element.disabled) return cancel_event(event);
// If the image in normal state put it in mouseover state
if (image.className == "tb_icon") {
element.className = "menu_item_mouseoverup";
}
// else if it is in down state put it in mouseover
// for down states.
else if (image.className == "icon_down") {
element.className = "menu_item_mouseoverdown";
}
return cancel_event(event);
}
function tb_mouseout (event) {
/* ---------------------------------------------------------
* MouseOut event handler function for toolbar buttons
*/
// The source tag must be an image.
var image, element;
if ( is_ie ) {
event = parent.document.frames.editor_iframe.event;
if (event.srcElement.tagName != "IMG") return cancel_event(event);
var image = event.srcElement;
var element = image.parentElement;
if (element.disabled) return cancel_event(event);
}
else {
image = outerdoc.getElementById(this.id + 'Image');
element = this;
}
// If the button is a toggle update it's state.
if (element.isPressed) {
element.className = "menu_item_mouseoverdown"
image.className = 'icon_down';
}
// else put the image back to it's normal state.
else {
element.className = "tb_menu_item";
image.className = "tb_icon";
}
return cancel_event(event);
}
function tb_mousedown () {
/* ---------------------------------------------------------
* MouseDown event handler for toolbar buttons.
*/
this.className = 'menu_item_mouseoverdown';
}
function tb_mouseup () {
/* ---------------------------------------------------------
* MouseUp event handler function for toolbar buttons.
*/
this.className = 'menu_item_mouseoverup';
}
function isChanged() {
/*---------------------------------------------
Return boolean, True if it's changed
*/
var body = inner_content.innerHTML;
if (unStack.length == 0 || !body) return false;
else if (body != unStack[unStack.length-1]) return true;
}
function getOffsetTop(elm) {
var mOffsetTop = elm.offsetTop;
var mOffsetParent = elm.offsetParent;
while(mOffsetParent){
mOffsetTop += mOffsetParent.offsetTop;
mOffsetParent = mOffsetParent.offsetParent;
}
return mOffsetTop;
}
function getOffsetLeft(elm) {
var mOffsetLeft = elm.offsetLeft;
var mOffsetParent = elm.offsetParent;
while(mOffsetParent){
mOffsetLeft += mOffsetParent.offsetLeft;
mOffsetParent = mOffsetParent.offsetParent;
}
return mOffsetLeft;
}
function insertNodeAtSelection (insertNode) {
if (is_ie) {
editor.selection.createRange().pasteHTML(insertNode.outerHTML)
return;
}
var win = document.getElementById("editor_iframe").contentWindow;
var sel = win.getSelection();
var range = sel.getRangeAt(0);
// deselect everything
if (sel != '')
sel.removeAllRanges();
// remove content of current selection from document
range.deleteContents();
// get location of current selection
var container = range.startContainer;
var pos = range.startOffset;
// make a new range for the new selection
range = document.createRange();
if (container.nodeType==3 && insertNode.nodeType==3) {
// if we insert text in a textnode, do optimized insertion
container.insertData(pos, insertNode.nodeValue);
// put cursor after inserted text
range.setEnd(container, pos+insertNode.length);
range.setStart(container, pos+insertNode.length);
}
else {
var afterNode;
if (container.nodeType==3) {
var textNode = container;
container = textNode.parentNode;
var text = textNode.nodeValue;
// text before the split
var textBefore = text.substr(0,pos);
// text after the split
var textAfter = text.substr(pos);
var beforeNode = document.createTextNode(textBefore);
var afterNode = document.createTextNode(textAfter);
// insert the 3 new nodes before the old one
container.insertBefore(afterNode, textNode);
container.insertBefore(insertNode, afterNode);
container.insertBefore(beforeNode, insertNode);
// remove the old node
container.removeChild(textNode);
}
else {
// else simply insert the node
afterNode = container.childNodes[pos];
container.insertBefore(insertNode, afterNode);
}
if (afterNode) {
range.setEnd(afterNode, 0);
range.setStart(afterNode, 0);
}
}
if (typeof(afterNode) != 'undefined')
sel.addRange(range);
}
function cancel_event (event) {
/* ---------------------------------------------------------
* General function to cancel an event.
*/
if (!event) return false;
event.returnValue = false;
event.cancelBubble = true;
return false;
}