if(!dojo._hasResource["dijit._editor.RichText"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. dojo._hasResource["dijit._editor.RichText"] = true; dojo.provide("dijit._editor.RichText"); dojo.require("dijit._Widget"); dojo.require("dijit._editor.selection"); dojo.require("dijit._editor.html"); dojo.require("dojo.i18n"); dojo.requireLocalization("dijit.form", "Textarea", null, "zh,pt,da,tr,ru,de,ROOT,sv,ja,he,fi,nb,el,ar,pt-pt,cs,fr,es,ko,nl,zh-tw,pl,it,hu"); // used to restore content when user leaves this page then comes back // but do not try doing dojo.doc.write if we are using xd loading. // dojo.doc.write will only work if RichText.js is included in the dojo.js // file. If it is included in dojo.js and you want to allow rich text saving // for back/forward actions, then set dojo.config.allowXdRichTextSave = true. if(!dojo.config["useXDomain"] || dojo.config["allowXdRichTextSave"]){ if(dojo._postLoad){ (function(){ var savetextarea = dojo.doc.createElement('textarea'); savetextarea.id = dijit._scopeName + "._editor.RichText.savedContent"; var s = savetextarea.style; s.display='none'; s.position='absolute'; s.top="-100px"; s.left="-100px"; s.height="3px"; s.width="3px"; dojo.body().appendChild(savetextarea); })(); }else{ //dojo.body() is not available before onLoad is fired try{ dojo.doc.write(''); }catch(e){ } } } dojo.declare("dijit._editor.RichText", dijit._Widget, { constructor: function(){ // summary: // dijit._editor.RichText is the core of the WYSIWYG editor in dojo, which // provides the basic editing features. It also encapsulates the differences // of different js engines for various browsers // // contentPreFilters: Array // pre content filter function register array. // these filters will be executed before the actual // editing area get the html content this.contentPreFilters = []; // contentPostFilters: Array // post content filter function register array. // these will be used on the resulting html // from contentDomPostFilters. The resuling // content is the final html (returned by getValue()) this.contentPostFilters = []; // contentDomPreFilters: Array // pre content dom filter function register array. // these filters are applied after the result from // contentPreFilters are set to the editing area this.contentDomPreFilters = []; // contentDomPostFilters: Array // post content dom filter function register array. // these filters are executed on the editing area dom // the result from these will be passed to contentPostFilters this.contentDomPostFilters = []; // editingAreaStyleSheets: Array // array to store all the stylesheets applied to the editing area this.editingAreaStyleSheets=[]; this._keyHandlers = {}; this.contentPreFilters.push(dojo.hitch(this, "_preFixUrlAttributes")); if(dojo.isMoz){ this.contentPreFilters.push(this._fixContentForMoz); this.contentPostFilters.push(this._removeMozBogus); }else if(dojo.isSafari){ this.contentPostFilters.push(this._removeSafariBogus); } //this.contentDomPostFilters.push(this._postDomFixUrlAttributes); this.onLoadDeferred = new dojo.Deferred(); }, // inheritWidth: Boolean // whether to inherit the parent's width or simply use 100% inheritWidth: false, // focusOnLoad: Boolean // whether focusing into this instance of richtext when page onload focusOnLoad: false, // name: String // If a save name is specified the content is saved and restored when the user // leave this page can come back, or if the editor is not properly closed after // editing has started. name: "", // styleSheets: String // semicolon (";") separated list of css files for the editing area styleSheets: "", // _content: String // temporary content storage _content: "", // height: String // set height to fix the editor at a specific height, with scrolling. // By default, this is 300px. If you want to have the editor always // resizes to accommodate the content, use AlwaysShowToolbar plugin // and set height="" height: "300px", // minHeight: String // The minimum height that the editor should have minHeight: "1em", // isClosed: Boolean isClosed: true, // isLoaded: Boolean isLoaded: false, // _SEPARATOR: String // used to concat contents from multiple textareas into a single string _SEPARATOR: "@@**%%__RICHTEXTBOUNDRY__%%**@@", // onLoadDeferred: dojo.Deferred // deferred which is fired when the editor finishes loading onLoadDeferred: null, postCreate: function(){ // summary: init dojo.publish(dijit._scopeName + "._editor.RichText::init", [this]); this.open(); this.setupDefaultShortcuts(); }, setupDefaultShortcuts: function(){ // summary: add some default key handlers // description: // Overwrite this to setup your own handlers. The default // implementation does not use Editor commands, but directly // executes the builtin commands within the underlying browser // support. var exec = function(cmd, arg){ return arguments.length == 1 ? function(){ this.execCommand(cmd); } : function(){ this.execCommand(cmd, arg); }; }; var ctrlKeyHandlers = { b: exec("bold"), i: exec("italic"), u: exec("underline"), a: exec("selectall"), s: function(){ this.save(true); }, "1": exec("formatblock", "h1"), "2": exec("formatblock", "h2"), "3": exec("formatblock", "h3"), "4": exec("formatblock", "h4"), "\\": exec("insertunorderedlist") }; if(!dojo.isIE){ ctrlKeyHandlers.Z = exec("redo"); //FIXME: undo? } for(var key in ctrlKeyHandlers){ this.addKeyHandler(key, this.KEY_CTRL, ctrlKeyHandlers[key]); } }, // events: Array // events which should be connected to the underlying editing area events: ["onKeyPress", "onKeyDown", "onKeyUp", "onClick"], // events: Array // events which should be connected to the underlying editing // area, events in this array will be addListener with // capture=true captureEvents: [], _editorCommandsLocalized: false, _localizeEditorCommands: function(){ if(this._editorCommandsLocalized){ return; } this._editorCommandsLocalized = true; //in IE, names for blockformat is locale dependent, so we cache the values here //if the normal way fails, we try the hard way to get the list //do not use _cacheLocalBlockFormatNames here, as it will //trigger security warning in IE7 //in the array below, ul can not come directly after ol, //otherwise the queryCommandValue returns Normal for it var formats = ['p', 'pre', 'address', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'div', 'ul']; var localhtml = "", format, i=0; while((format=formats[i++])){ if(format.charAt(1) != 'l'){ localhtml += "<"+format+">content"; }else{ localhtml += "<"+format+">
  • content
  • "; } } //queryCommandValue returns empty if we hide editNode, so move it out of screen temporary var div=dojo.doc.createElement('div'); div.style.position = "absolute"; div.style.left = "-2000px"; div.style.top = "-2000px"; dojo.doc.body.appendChild(div); div.innerHTML = localhtml; var node = div.firstChild; while(node){ dijit._editor.selection.selectElement(node.firstChild); dojo.withGlobal(this.window, "selectElement", dijit._editor.selection, [node.firstChild]); var nativename = node.tagName.toLowerCase(); this._local2NativeFormatNames[nativename] = dojo.doc.queryCommandValue("formatblock");//this.queryCommandValue("formatblock"); this._native2LocalFormatNames[this._local2NativeFormatNames[nativename]] = nativename; node = node.nextSibling; } dojo.doc.body.removeChild(div); }, open: function(/*DomNode?*/element){ // summary: // Transforms the node referenced in this.domNode into a rich text editing // node. This will result in the creation and replacement with an