| //------------------------------------------------------------------------------ |
| // 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> </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); |
| } |