blob: a757c115149518ddd47668db21da018fdf911cd0 [file] [log] [blame]
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
var editorId;
var editorCSS;
var baseHREF;
var supportRichTextEditing = true;
var editorDoc;
var selection;
var selectionRange;
var readOnly = false;
var initialized = false;
var modified = false;
var STATUS_INITIALIZED = 1;
var STATUS_MODIFIED = 2;
var STATUS_GET_TEXT = 3;
var STATUS_KEY_DOWN = 4;
var STATUS_KEY_UP = 5;
var STATUS_SELECT_TEXT = 6;
var STATUS_SELECT_CONTROL = 7;
var STATUS_SELECT_NONE = 8;
var STATUS_EXEC_CMD = 9;
var KEY_ARROW_DOWN = 40;
var KEY_ARROW_LEFT = 37;
var KEY_ARROW_RIGHT = 39;
var KEY_ARROW_UP = 38;
var KEY_END = 35;
var KEY_HOME = 36;
var KEY_PAGE_DOWN = 34;
var KEY_PAGE_UP = 33;
var KEY_TAB = 9;
var KEY_C = 67;
var KEY_F = 70;
var KEY_V = 86;
var CMD_FIND_TEXT = "findText";
var CMD_PASTE = "paste";
var TABLE_HEADERS_NONE = 0;
var TABLE_HEADERS_COLS = 1;
var TABLE_HEADERS_ROWS = 2;
var TABLE_HEADERS_BOTH = 3;
// Initializes the editor.
function initEditor(id, css, baseURL, html) {
editorId = id;
editorCSS = css;
baseHREF = baseURL;
try {
document.getElementById(editorId).contentWindow.document.designMode = "on";
setContent(html);
initialized = true;
setStatus(STATUS_INITIALIZED, null);
}
catch (e) {
supportRichTextEditing = false;
}
}
// Sets the editor content.
function setContent(html) {
var htmlSrc = '<html><head><title></title>';
if (editorCSS != null && editorCSS != '') {
htmlSrc += '<link rel="StyleSheet" href="' + editorCSS + '" type="text/css"/>';
}
if (baseHREF != null && baseHREF != '') {
htmlSrc += '<base href="' + baseHREF + '"/>';
}
if (html != null && html != '') {
html = html.replace(/%sq%/g, "'");
}
if (html != null && html != '') {
htmlSrc += '</head><body>' + html + '</body></html>';
}
else {
htmlSrc += '</head><body></body></html>';
}
doc = document.getElementById(editorId).contentWindow.document;
doc.open();
doc.write(htmlSrc);
doc.close();
modified = false;
doc.onkeydown = function(event) {
var keyCode = doc.parentWindow.event.keyCode;
var ctrlKeyPressed = doc.parentWindow.event.ctrlKey;
if (readOnly) {
switch (keyCode) {
case KEY_ARROW_DOWN:
case KEY_ARROW_LEFT:
case KEY_ARROW_RIGHT:
case KEY_ARROW_UP:
case KEY_END:
case KEY_HOME:
case KEY_PAGE_DOWN:
case KEY_PAGE_UP:
case KEY_TAB:
return;
case KEY_C:
if (ctrlKeyPressed) {
return;
}
break;
case KEY_F:
if (ctrlKeyPressed) {
setStatus(STATUS_KEY_DOWN, CMD_FIND_TEXT);
doc.parentWindow.event.keyCode = -1;
}
break;
}
doc.parentWindow.event.returnValue = false;
return;
}
if (ctrlKeyPressed) {
if (keyCode == KEY_F) {
doc.parentWindow.event.keyCode = -1;
doc.parentWindow.event.returnValue = false;
setStatus(STATUS_KEY_DOWN, CMD_FIND_TEXT);
return;
}
else if (keyCode == KEY_V) {
doc.parentWindow.event.keyCode = -1;
doc.parentWindow.event.returnValue = false;
setStatus(STATUS_KEY_DOWN, CMD_PASTE);
return;
}
}
}
doc.onkeyup = function(event) {
if (updateSelection()) {
if (document.all) {
setStatus(STATUS_KEY_UP, doc.parentWindow.event.keyCode);
}
}
}
doc.ondragstart = function() {
if (readOnly) {
doc.parentWindow.event.returnValue = false;
}
}
}
// Sets the status.
function setStatus(type, value) {
var status = '$$$' + type;
if (value != null && value != '') {
status += ('$' + value);
}
window.status = status;
}
// Returns the HTML source.
function getText() {
var html = document.getElementById(editorId).contentWindow.document.body.innerHTML;
if (html == "<P>&nbsp;</P>") {
html = "";
}
setStatus(STATUS_GET_TEXT, html);
return html;
}
// Sets the HTML source.
function setText(html) {
setContent(html);
setStatus(STATUS_EXEC_CMD, 1);
}
// Updates the current selection and selection range.
function updateSelection() {
if (!supportRichTextEditing) {
return false;
}
contentWindow = document.getElementById(editorId).contentWindow;
editorDoc = contentWindow.document;
editorDoc.body.focus();
if (document.all) {
selection = editorDoc.selection;
if (selection != null) {
selectionRange = selection.createRange();
reformatElementLinks();
}
}
else {
selection = contentWindow.getSelection();
if (selection != null) {
selectionRange = selection.getRangeAt(selection.rangeCount - 1).cloneRange();
}
}
return true;
}
// Sets focus to this editor.
function setFocus() {
if (updateSelection()) {
setStatus(STATUS_EXEC_CMD, 1);
}
}
// Gets the selected text.
function getSelectedText() {
if (updateSelection()) {
if (document.all) {
if (selection != null) {
if (selection.type == 'Text' && selectionRange != null && selectionRange.text != '') {
setStatus(STATUS_SELECT_TEXT, selectionRange.text);
return;
}
else if (selection.type == 'Control') {
setStatus(STATUS_SELECT_CONTROL, null);
return;
}
}
setStatus(STATUS_SELECT_NONE, null);
}
}
}
// Reformats element links created via drag & drop.
function reformatElementLinks() {
var linksReformatted = 0;
var elements = editorDoc.getElementsByTagName('A');
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if (element.className.toLowerCase() == 'elementlinkwithtype') {
if (element.firstChild != null && element.firstChild.firstChild != null &&
element.firstChild.firstChild.firstChild != null) {
var linkText = element.firstChild.firstChild.firstChild.nodeValue;
element.removeChild(element.firstChild);
element.appendChild(editorDoc.createTextNode(linkText));
linksReformatted++;
}
}
}
if (linksReformatted > 0) {
setStatus(STATUS_MODIFIED, null);
}
}
// Formats the selected text.
function formatText(command, option) {
if (!readOnly && updateSelection()) {
if (editorDoc.execCommand(command, false, option)) {
setStatus(STATUS_EXEC_CMD, 1);
setStatus(STATUS_MODIFIED, null);
}
}
}
// Adds HTML.
function addHTML(html) {
if (!readOnly && html != "") {
html = html.replace(/%sq%/g, "'");
if (updateSelection()) {
if (document.all) {
if (selectionRange.text != null) {
selectionRange.pasteHTML(html);
setStatus(STATUS_EXEC_CMD, 1);
setStatus(STATUS_MODIFIED, null);
}
}
}
}
}
// Adds an image.
function addImage(url, height, width, alt) {
if (url != null && url != '') {
formatText('insertimage', url);
}
if (updateSelection()) {
if (selection != null && selection.type == 'Control' && selectionRange != null) {
if (height != null && height != '') selectionRange.item().height = height;
if (width != null && width != '') selectionRange.item().width = width;
if (alt != null) selectionRange.item().alt = alt;
}
}
}
// Adds a horizontal line.
function addLine() {
formatText('inserthorizontalrule', null);
}
// Adds a link.
function addLink(url) {
if (!readOnly && url != null && url != '' && updateSelection()) {
if (document.all) {
if (selectionRange.text == null || selectionRange.text == '') {
selectionRange.text = url;
setStatus(STATUS_EXEC_CMD, 1);
setStatus(STATUS_MODIFIED, null);
}
else if (selectionRange.execCommand('createlink', false, url)) {
setStatus(STATUS_EXEC_CMD, 1);
setStatus(STATUS_MODIFIED, null);
}
}
else {
if (selection == null || selection == "") {
var urlTextNode = editorDoc.createTextNode(url);
insertNodeAtSelection(document.getElementById(editorFrameId).contentWindow, urlTextNode);
}
if (editorDoc.execCommand('createlink', false, url)) {
setStatus(STATUS_EXEC_CMD, 1);
setStatus(STATUS_MODIFIED, null);
}
}
}
}
// Adds an ordered list.
function addOrderedList() {
formatText('insertorderedlist', null);
}
// Adds a table.
function addTable(rows, cols, width, summary, caption, tableheaders) {
if (readOnly) return;
if (rows == 0) rows = 2;
if (cols == 0) cols = 2;
if (width == 0) width = 200;
if (updateSelection()) {
var tableElement;
var table;
if (document.all) {
tableElement = editorDoc.createElement('TABLE');
table = selectionRange.parentElement().appendChild(tableElement);
table.cellPadding = "2";
table.cellSpacing = "2";
table.border = "1";
table.width = width;
if (summary != null && summary != '') {
table.summary = summary;
}
if (caption != null && caption != '') {
table.createCaption();
table.caption.innerText = caption;
}
for (var i = 0; i < rows; i++) {
var newRow = table.insertRow();
for (var j = 0; j < cols; j++) {
if (i == 0 && (tableheaders == TABLE_HEADERS_COLS || tableheaders == TABLE_HEADERS_BOTH)) {
tableHeader = editorDoc.createElement('TH');
tableHeader.scope = "col";
newRow.appendChild(tableHeader);
}
else if (j == 0 && (tableheaders == TABLE_HEADERS_ROWS || tableheaders == TABLE_HEADERS_BOTH)) {
tableHeader = editorDoc.createElement('TH');
tableHeader.scope = "row";
newRow.appendChild(tableHeader);
}
else {
table.rows[i].insertCell();
}
}
}
setStatus(STATUS_EXEC_CMD, 1);
setStatus(STATUS_MODIFIED, null);
}
}
}
// Adds an unordered list.
function addUnorderedList() {
formatText('insertunorderedlist', null);
}
// Sets the background color of the selected text.
function backColor(color) {
if (color != null && color != '') {
formatText('backcolor', color);
}
}
// Toggles the 'bold' attribute of the selected text.
function bold() {
formatText('bold', null);
}
// Copies the selected text to the clipboard.
function copy() {
if (updateSelection()) {
if (editorDoc.execCommand('copy', false, null)) {
setStatus(STATUS_EXEC_CMD, 1);
}
}
}
// Cuts the selected text to the clipboard.
function cut() {
formatText('cut', null);
}
// Deletes the selected text.
function deleteText() {
formatText('delete', null);
}
// Finds text.
function findText(findText, dir, options) {
if (readOnly || findText == null || findText == "") {
return;
}
else {
findText = findText.replace(/%sq%/g, "'");
}
if (updateSelection()) {
selectionRange.collapse(dir < 0);
if (selectionRange.findText(findText, dir, options)) {
selectionRange.scrollIntoView();
selectionRange.select();
selectionRange.collapse(dir < 0);
setStatus(STATUS_EXEC_CMD, 1);
}
}
}
// Sets the foreground color of the selected text.
function foreColor(color) {
if (color != null && color != '') {
formatText('forecolor', color);
}
}
// Formats the selected text using the given HTML heading tag.
function formatBlock(tag) {
if (tag != null && tag != '') {
formatText('formatblock', tag);
}
}
// Indents the selected text.
function indent() {
formatText('indent', null);
}
// Toggles the 'italic' attribute of the selected text.
function italic() {
formatText('italic', null);
}
// Center justifies the selected text.
function justifyCenter() {
formatText('justifycenter', null);
}
// Fully justifies the selected text.
function justifyFull() {
formatText('justifyfull', null);
}
// Left justifies the selected text.
function justifyLeft() {
formatText('justifyleft', null);
}
// Right justifies the selected text.
function justifyRight() {
formatText('justifyright', null);
}
// Outdents the selected text.
function outdent() {
formatText('outdent', null);
}
// Pastes text from the clipboard.
function paste() {
formatText('paste', null);
}
// Redo the previous command.
function redo() {
formatText('redo', null);
}
// Redo the previous command.
function removeFormat() {
formatText('removeformat', null);
}
// Replaces all text.
function replaceAllText(findText, replaceText, options) {
if (readOnly || findText == null || findText == "") {
return;
}
else {
findText = findText.replace(/%sq%/g, "'");
}
if (replaceText == null) {
replaceText = "";
}
else {
replaceText = replaceText.replace(/%sq%/g, "'");
}
var html = document.getElementById(editorId).contentWindow.document.body.innerHTML;
var optionStr = "/g";
if ((options & 4) == 0) {
optionStr += "i";
}
var regExp = eval("/" + findText + optionStr);
html = html.replace(regExp, replaceText);
setText(html);
setStatus(STATUS_EXEC_CMD, 1);
}
// Replaces text.
function replaceText(replaceText, dir, options) {
if (readOnly || !updateSelection()) {
return;
}
if (replaceText == null) {
replaceText = "";
}
else {
replaceText = replaceText.replace(/%sq%/g, "'");
}
selectionRange.text = replaceText;
if (replaceText != "") {
selectionRange.moveStart("word", -1);
selectionRange.select();
selectionRange.collapse(dir < 0);
}
setStatus(STATUS_EXEC_CMD, 1);
}
// Selects all text.
function selectAll() {
if (updateSelection()) {
if (editorDoc.execCommand('selectall', false, null)) {
setStatus(STATUS_EXEC_CMD, 1);
}
}
}
// Sets the font name for the selected text.
function setFontName(name) {
if (name != null && name != '') {
formatText('fontname', name);
}
}
// Sets the font size for the selected text.
function setFontSize(size) {
if (size != null && size != '') {
formatText('fontsize', size);
}
}
// Sets the font style for the selected text.
function setFontStyle(style) {
if (!readOnly && style != null && style != '' && updateSelection()) {
try {
selectionRange.execCommand("removeformat");
selectionRange.parentElement().removeAttribute("className");
}
catch (e) {
}
if (style == "<quote>") {
formatText('formatblock', '<p>');
selectionRange.parentElement().className = "quote";
}
else if (style == "<code>") {
formatText('formatblock', '<p>');
selectionRange.parentElement().className = "codeSample";
}
else {
formatText('formatblock', style);
}
}
}
// Sets whether the content can be edited.
function setEditable(editable) {
if (editable != null && editable == 'true') {
readOnly = false;
}
else {
readOnly = true;
}
setStatus(STATUS_EXEC_CMD, 1);
}
// Toggles the 'strike-through' attribute of the selected text.
function strikeThrough() {
formatText('strikethrough', size);
}
// Toggles the 'subscript' attribute of the selected text.
function subscript() {
formatText('subscript', null);
}
// Toggles the 'superscript' attribute of the selected text.
function superscript() {
formatText('superscript', null);
}
// Toggles the 'underline' attribute of the selected text.
function underline() {
formatText('underline', null);
}
// Converts a link to normal text.
function unlink() {
formatText('unlink', null);
}