📄 zpeditor-core.js
字号:
/** *$Id: zpeditor-core.js 7622 2007-07-30 17:43:09Z vkulov $ * @fileoverview Basic Rich Text editor (see Midas specification) * This file provides functionality to create a new editor out of a given * container id and adjust various styles and actual behavior in design mode * * @link http://www.mozilla.org/editor/midas-spec.html * * <pre> * Copyright (c) 2004-2006 by Zapatec, Inc. * http://www.zapatec.com * 1700 MLK Way, Berkeley, California, * 94709, U.S.A. * All rights reserved. * </pre> *//** * Zapatec.MinimalEditor constructor. Creates a new editor object with given * parameters. * * @constructor * @extends Zapatec.Widget * @param {object} objArgs Editor configuration * * Constructor recognizes the following properties of the config object * \code * property name | description *------------------------------------------------------------------------------------------------- * field | [string or object] Reference to DOM element to be used as * | prototype for the editor. The editor pane will be created right * | after this element and will take its size. * toolbarElements | [array] Array of strings representing toolbar buttons to * | be added to the editor toolbar. The buttons will be added to * | the toolbar in the order they are specified in this array. * maximizedBorder | [number] A margin between the editor and the browser window * | border when in maximized mode (pixels) * enableTooltips | [boolean] Specifies if toolbar button tooltips are to appear * dumpHtml | [boolean] Specifies the way html source is obtained from iframe. * | If set to false innerHtml will be used to get html from design mode. * | If set to true. the html is achieved by manually dumping the root DOM element. * | Default is false. * generateXhtml | [boolean] If this option is true the editor will produce * | valid xhtml 1.0 strict * customUndo | [boolean] Specifies the way undo works. If this option is true * | a custom JavaScript undo stack will be maintained. Otherwise execCommand * | will be used. Default is true. * preserveImgSrc | [boolean] Under IE relative image paths are * | automatically converted to absolute paths. Set this * | option to true in order to pre-process the html every time the * | user switches from HTML to WYSIWYG mode and vice versa. Default is * | true for IE and false otherwise. * preserveAnchorHref | [boolean] Under IE relative anchor hrefs are * | automatically converted to absolute href URLs. Set this * | option to true in order to pre-process the html every time the * | user switches from HTML to WYSIWYG mode and vice versa. Default is * | true for IE and false otherwise. * \endcode * * Constructor recognizes the following strings as elements of toolbarElements * array * \code * toolbar element name | description *------------------------------------------------------------------------------------------------- * maximize | A toggle button for maximizing/restoring the editor to full page boundaries * fontName | A font name select field * fontSize | A font size select field * foreColor | A font color picker button * backColor | A background color picker button * insertLink | A button for inserting hyperlinks * insertImage | A button for inserting images * insertTable | A button for inserting tables * insertHorizontalRule | A button for inserting horizontal rules * insertSpecialChar | A button for showing a character map window for selecting a special character to insert * bold | A button for toggling bold style on selected text * italic | A button for toggling italic style on selected text * underline | A button for toggling underline style on selected text * justifyLeft | A button for making paragraphs left justified * justifyCenter | A button for making paragraphs centered * justifyRight | A button for making paragraphs right justified * justifyFull | A button for making paragraphs full justified * insertOrderedList | A button for inserting ordered numbered lists * insertUnorderedList | A button for inserting unordered bulleted lists * selectAll | A button for selecting all editor content * copy | A copy button * cut | A cut button * paste | A paste button * outdent | A button for decreasing indentation * indent | A button for increasing indentation * undo | An undo button * redo | A redo button * about | About this editor button * browser | A button for previewing editor html content in a new browser window * switcher | A toggle button to switch between HTML and WYSIWYG mode * fetch | A button for loading editor html content from a remote location * save | A button for sending editor html content to a remote location * newPanel | This element will make the next button appear in * | a new toolbar panel * newRow | This element will make the next button appear in * | a new row * \endcode * */Zapatec.MinimalEditor = function(objArgs) { if (arguments.length == 0) { objArgs = {}; } // Call constructor of superclass Zapatec.MinimalEditor.SUPERconstructor.call(this, objArgs);}/** * Unique static id of the widget class. Gives ability for Zapatec#inherit to * determine and store path to this file correctly when it is included using * Zapatec#include. When this file is included using Zapatec#include or path * to this file is gotten using Zapatec#getPath, this value must be specified * as script id. * @private */Zapatec.MinimalEditor.id = 'Zapatec.MinimalEditor';// Inherit Zapatec.WidgetZapatec.inherit(Zapatec.MinimalEditor, Zapatec.Widget);/** * Initializes object. * * @param {object} objArgs User configuration */Zapatec.MinimalEditor.prototype.init = function(objArgs) { // processing Widget functionality Zapatec.MinimalEditor.SUPERclass.init.call(this, objArgs); this.createEditor(); this.initEditor();}/** * Creates editor DOM elements * @private */Zapatec.MinimalEditor.prototype.createEditor = function() { this.createProperty(this, 'container', null); this.createProperty(this, 'editorPanel', null); // Holds all created toolbar buttons this.createProperty(this, 'buttons', []); // Hides native controls that are under the editor when it is maximized this.createProperty(this, 'wch', null); this.createProperty(this, 'undo', new Zapatec.MinimalEditor.Undo(this)); if (Zapatec.is_webkit) { this.fillWebKitMap(); } // Get original textarea field dimensions var fieldWidth = this.config.field.clientWidth; var fieldHeight = this.config.field.clientHeight; // Creare a container element this.container = Zapatec.Utils.createElement("div"); this.container.id = 'zpEditor' + this.id + 'Container'; // Add container element after the original textarea Zapatec.Utils.insertAfter(this.config.field, this.container); // Copy styles from textarea to our main container if (!Zapatec.is_opera) { this.container.style.cssText = this.config.field.style.cssText; } else { for (var i in this.config.field.style) { try { this.container.style[i] = this.config.field.style[i]; } catch (e) { } } } this.config.field.style.position = "static"; this.config.field.style.left = ""; this.config.field.style.top = ""; this.config.field.style.margin = "0"; // Creare an editor panel element this.editorPanel = document.createElement("div"); this.editorPanel.id = 'zpEditor' + this.id + 'EditorPanel'; // Add editor panel to the container this.container.appendChild(this.editorPanel); // Set editor panel style class this.editorPanel.className = this.getClassName({prefix: "zpEditor", suffix: "EditorPanel" }); // Remove textarea this.config.field.parentNode.removeChild(this.config.field); // Add textarea inside our container this.editorPanel.appendChild(this.config.field); // Set textfield style class this.config.field.className = this.getClassName({prefix: "zpEditor", suffix: "Textarea" }); // Create WCH this.wch = Zapatec.Utils.createWCH(this.editorPanel); // Put WCH under container if (this.wch) { this.wch.style.zIndex = -1; } // Add toolbar buttons this.addButtons(); // Get iframe pane dimensions var paneSize = this.getPaneSize(fieldWidth, fieldHeight); // Create editor pane this.pane = new Zapatec.Pane({ containerType: 'iframe', width: paneSize.width, height: paneSize.height, showLoadingIndicator: false }) // Remove iframe border this.pane.removeBorder(); // Set editor pane style class this.pane.getContainer().className = this.getClassName({prefix: "zpEditor", suffix: "Pane" }); // Set editor dimenisons this.setSize(fieldWidth, fieldHeight); // Move iframe to the editor panel just after our text area this.pane.getContainer().parentNode.removeChild(this.pane.getContainer()); Zapatec.Utils.insertAfter(this.config.field, this.pane.getContainer()); // Hide html text area this.config.field.style.display = "none"; // set current mode to WYSIWYG(visual formatting) this.mode = "WYSIWYG"; // Disable toolbar buttons this.toggleButtons(false);}/** * Configures the widget. Gets called from init and reconfigure methods of * superclass. * * @private * @param {object} objArgs User configuration */Zapatec.MinimalEditor.prototype.configure = function(objArgs) { this.defineConfigOption('field'); this.defineConfigOption('asyncTheme', true); this.defineConfigOption('maximizedBorder', 6); this.defineConfigOption('toolbarElements', [ 'fontName', 'fontSize', 'newPanel', 'bold', 'italic', 'underline', 'newPanel', 'foreColor', 'backColor', 'insertLink', 'insertImage', 'insertTable', 'insertHorizontalRule', 'newRow', 'justifyLeft', 'justifyCenter', 'justifyRight', 'newPanel', 'insertOrderedList', 'insertUnorderedList', 'newPanel', 'selectall', 'copy', 'cut', 'paste', 'newPanel', 'outdent', 'indent', 'newPanel', 'undo', 'redo', 'newPanel', 'switcher', 'newPanel', 'about' ]); this.defineConfigOption('langId', Zapatec.MinimalEditor.id); this.defineConfigOption('lang', "eng"); this.defineConfigOption('persistKey', null); this.defineConfigOption('persistPath', null); this.defineConfigOption('externalBrowserWidth', 450); this.defineConfigOption('externalBrowserHeight', 350); this.defineConfigOption('enableTooltips', false); this.defineConfigOption('dumpHtml', false); this.defineConfigOption('generateXhtml', false); this.defineConfigOption('customUndo', true); // Maximum key strikes before an undo step is stored this.defineConfigOption('maxUndoTypes', 25); this.defineConfigOption('maxUndoLevels', 100); // Foreground and background colors this.defineConfigOption('foreColor', ""); this.defineConfigOption('backColor', ""); this.defineConfigOption('preserveImgSrc', Zapatec.is_ie); this.defineConfigOption('preserveAnchorHref', Zapatec.is_ie); // If set to true toolbar dimensions won't be taken into account // when calculating editor size this.defineConfigOption('excludeToolbar', false); // Call parent method Zapatec.MinimalEditor.SUPERclass.configure.call(this, objArgs); // Change all toobar element names to lower case for (var ii = 0; ii < this.config.toolbarElements.length; ii++) { this.config.toolbarElements[ii] = this.config.toolbarElements[ii].toLowerCase(); } // Check if required param "field" is defined if (typeof(this.config.field) == "undefined") { Zapatec.Log({description: this.getMessage('noTextareaError')}); return false; } // if required param "field" is a string if (typeof(this.config.field) == "string") { // Get DOM element with specified id this.config.field = document.getElementById(this.config.field); } // Check if a DOM element was found for "field" and it's text area if (this.config.field == null || this.config.field.nodeType != 1 || this.config.field.nodeName.toLowerCase() != "textarea") { Zapatec.Log({description: this.getMessage('fieldIsNotTextareaError')}) return false; } // Disable tooltips if they are not defined if (typeof Zapatec.Tooltip == 'undefined') { this.config.enableTooltips = false; }};/** * Turn on design mode for the editor iframe pane * @private */Zapatec.MinimalEditor.prototype.initEditor = function() { var self = this; if (!this.pane.isReady()) { setTimeout(function() { self.initEditor() }, 50); return null; } // Revalidate editor size self.setSize(); // Handly Enter key manually in IE to write <br> instead of <p> if (Zapatec.is_ie) { this.pane.getContentElement().onbeforedeactivate = function() { var sel = self.pane.getContainer().contentWindow.document.selection; if (sel) { try { // Focus editor var range = sel.createRange(); self.oldSelectionRange = range; } catch(e) { } } } } // on each keydown event write value to original field Zapatec.Utils.addEvent(this.pane.getIframeDocument(), "keydown", function(e) { if (!e) { e = self.pane.getIframeDocument().event; } // Notify undo manager that a key is pressed self.undo.onKeyDown(); switch (e.keyCode) { case 13: if (Zapatec.is_ie && !(e.ctrlKey || e.altKey || e.shiftKey)) { // Handle enter key var isHandled = self.onEnterPressed(); if (isHandled) { // Prevent default handling e.cancelBubble = true; e.returnValue = false; return false; } }; break; } }); // on each keyup event write value to original field Zapatec.Utils.addEvent(this.pane.getIframeDocument(), "keyup", function() { self.saveContentToField(); self.invokeUpdateToolbar(); }); // on each click event update toolbar icon states Zapatec.Utils.addEvent(this.pane.getIframeDocument(), "click", function() { self.invokeUpdateToolbar(); }); // on each contextmenu event update toolbar icon states Zapatec.Utils.addEvent(this.pane.getIframeDocument(), "contextmenu", function() { self.invokeUpdateToolbar(); }); // Enable design mode this.toggleDesignMode(true); // copy value from field to editor pane this.loadContentFromField(); // Store an undo step this.undo.saveUndo(); // Enable all toolbar buttons this.toggleButtons(true); this.fireEvent("onInit");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -