Ticket #10651: CKEditorControl.cs

File CKEditorControl.cs, 57.9 KB (added by Poornima Nookala, 6 years ago)

ModifiedCKEditorControl.cs

Line 
1/*
2 * Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
3 * For licensing, see LICENSE.html or http://ckeditor.com/license
4*/
5using System;
6using System.Collections.Generic;
7using System.ComponentModel;
8using System.Text;
9using System.Web;
10using System.Web.UI;
11using System.Web.UI.WebControls;
12using System.IO;
13using System.Text.RegularExpressions;
14using System.Globalization;
15using System.Runtime.InteropServices;
16using System.Collections.Specialized;
17
18namespace CKEditor.NET
19{
20        [DefaultProperty("Text")]
21        [ToolboxData("<{0}:CKEditorControl runat=server></{0}:CKEditorControl>")]
22        [ParseChildren(false)]
23        [Designer("CKEditor.NET.CKEditorControlDesigner")]
24        public class CKEditorControl : TextBox, IPostBackDataHandler
25        {
26                #region Changed TextBox Property
27
28                [Bindable(true)]
29                [Category("CKEditor Basic Settings")]
30                [DefaultValue("")]
31                public override string Text
32                {
33                        get
34                        {
35                                return base.Text;
36                        }
37                        set
38                        {
39                                base.Text = value;
40                        }
41                }
42
43        public event EventHandler TextChanged;
44
45                public override TextBoxMode TextMode { get { return base.TextMode; } }
46
47                [Description("If true, makes the editor start in read-only state. Otherwise, it will check if the linked <textarea> element has the disabled attribute.")]
48                [DefaultValue(false)]
49                public override bool ReadOnly
50                {
51                        get
52                        {
53                                return config.readOnly;
54                        }
55                        set
56                        {
57                                config.readOnly = base.ReadOnly = value;
58                        }
59                }
60
61                #endregion
62
63                #region Private Property
64
65                private string CKEditorJSFile
66                {
67                        get
68                        {
69                                return this.BasePath + "/ckeditor.js";
70                        }
71                }
72
73                private bool isChanged = false;
74
75                #endregion
76
77                #region CKEditor Other Settings Property
78
79                [Category("CKEditor Basic Settings")]
80                [DefaultValue("~/ckeditor")]
81                public string BasePath
82                {
83                        get
84                        {
85                                object obj = ViewState["BasePath"];
86                                if (obj == null)
87                                {
88                                        obj = System.Configuration.ConfigurationManager.AppSettings["CKeditor:BasePath"];
89                                        ViewState["BasePath"] = (obj == null ? "~/ckeditor" : (string)obj);
90                                }
91                                return (string)ViewState["BasePath"];
92                        }
93                        set
94                        {
95                                if (value.EndsWith("/"))
96                                        value = value.Remove(value.Length - 1);
97                                ViewState["BasePath"] = value;
98                        }
99                }
100
101                [Browsable(false)]
102                [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
103                [EditorBrowsable(EditorBrowsableState.Never)]
104                public CKEditorConfig config
105                {
106                        get
107                        {
108                                if (ViewState["CKEditorConfig"] == null)
109                                        ViewState["CKEditorConfig"] = new CKEditorConfig(this.BasePath.StartsWith("~") ? this.ResolveUrl(this.BasePath) : this.BasePath);
110                                return (CKEditorConfig)ViewState["CKEditorConfig"];
111                        }
112                        set { ViewState["CKEditorConfig"] = value; }
113                }
114
115                [Category("CKEditor Basic Settings")]
116                [Description("The height of editing area( content ), in relative or absolute, e.g. 30px, 5em. Note: Percentage unit is not supported yet.e.g. 30%.")]
117                [DefaultValue(typeof(System.Web.UI.WebControls.Unit), "200px")]
118                public override Unit Height
119                {
120                        get
121                        {
122                                System.Web.UI.WebControls.Unit result = new Unit(string.Empty);
123                                try
124                                {
125                                        result = System.Web.UI.WebControls.Unit.Parse(config.height);
126                                        base.Height = result;
127                                }
128                                catch { }
129                                return result;
130                        }
131                        set
132                        {
133                                System.Web.UI.WebControls.Unit result = new Unit(string.Empty);
134                                try
135                                {
136                                        result = value;
137                                        base.Height = result;
138                                }
139                                catch { }
140                                config.height = value.ToString().Replace("px", string.Empty);
141                        }
142                }
143
144                [Category("CKEditor Basic Settings")]
145                [Description("The editor width in CSS size format or pixel integer.")]
146                [DefaultValue(typeof(System.Web.UI.WebControls.Unit), "100%")]
147                public override Unit Width
148                {
149                        get
150                        {
151                                System.Web.UI.WebControls.Unit result = new Unit(string.Empty);
152                                try
153                                {
154                                        result = System.Web.UI.WebControls.Unit.Parse(config.width);
155                                        base.Width = result;
156                                }
157                                catch { }
158                                return result;
159                        }
160                        set
161                        {
162                                System.Web.UI.WebControls.Unit result = new Unit(string.Empty);
163                                try
164                                {
165                                        result = value;
166                                        base.Width = result;
167                                }
168                                catch { }
169                                config.width = value.ToString().Replace("px", string.Empty);
170                        }
171                }
172
173                [Category("CKEditor Other Settings")]
174                [Description("The editor tabindex value.")]
175                [DefaultValue(typeof(short), "0")]
176                public override short TabIndex { get { return (short)config.tabIndex; } set { config.tabIndex = value; } }
177
178                #region Encaspulate config
179
180                [Category("CKEditor Other Settings")]
181                [Description("Extra height in pixel to leave between the bottom boundary of content with document size when auto resizing.")]
182                [DefaultValue(0)]
183                public int AutoGrowBottomSpace { get { return config.autoGrow_bottomSpace; } set { config.autoGrow_bottomSpace = value; } }
184
185                [Category( "CKEditor Other Settings" )]
186                [Description( "Whether to have the auto grow happen on editor creation." )]
187                [DefaultValue(false)]
188                public bool AutoGrowOnStartup { get { return config.autoGrow_onStartup; } set { config.autoGrow_onStartup = value; } }
189
190                [Category("CKEditor Other Settings")]
191                [Description("The maximum height to which the editor can reach using AutoGrow. Zero means unlimited.")]
192                [DefaultValue(0)]
193                public int AutoGrowMaxHeight { get { return config.autoGrow_maxHeight; } set { config.autoGrow_maxHeight = value; } }
194
195                [Category("CKEditor Other Settings")]
196                [Description("The minimum height to which the editor can reach using AutoGrow.")]
197                [DefaultValue(200)]
198                public int AutoGrowMinHeight { get { return config.autoGrow_minHeight; } set { config.autoGrow_minHeight = value; } }
199
200                [Category("CKEditor Other Settings")]
201                [Description( "Whether automatically create wrapping blocks around inline contents inside document body, this helps to ensure the integrality of the block enter mode. Note: Changing the default value might introduce unpredictable usability issues." )]
202                [DefaultValue(true)]
203                public bool AutoParagraph { get { return config.autoParagraph; } set { config.autoParagraph = value; } }
204
205                [Category("CKEditor Other Settings")]
206                [Description("Whether the replaced element (usually a textarea) is to be updated automatically when posting the form containing the editor.")]
207                [DefaultValue(true)]
208                public bool AutoUpdateElement { get { return config.autoUpdateElement; } set { config.autoUpdateElement = value; } }
209
210                [Category("CKEditor Other Settings")]
211                [Description("Whether to escape basic HTML entities in the document, including: nbsp, gt, lt, amp.")]
212                [DefaultValue(true)]
213                public bool BasicEntities { get { return config.basicEntities; } set { config.basicEntities = value; } }
214
215                [Category("CKEditor Basic Settings")]
216                [Description("The base href URL used to resolve relative and absolute URLs in the editor content.")]
217                [DefaultValue("")]
218                public string BaseHref { get { return config.baseHref; } set { config.baseHref = value; } }
219
220                [Category("CKEditor Other Settings")]
221                [Description(@"Sets the ""class"" attribute to be used on the body element of the editing area. This can be useful when reusing the original CSS
222file you're using on your live website and you want to assing to the editor the same class name you're using for the region
223that'll hold the contents. In this way, class specific CSS rules will be enabled.")]
224                [DefaultValue("")]
225                public string BodyClass { get { return config.bodyClass; } set { config.bodyClass = value; } }
226
227                [Category("CKEditor Other Settings")]
228                [Description(@"Sets the ""id"" attribute to be used on the body element of the editing area. This can be useful when reusing the original CSS
229file you're using on your live website and you want to assing to the editor the same id you're using for the region
230that'll hold the contents. In this way, id specific CSS rules will be enabled.")]
231                [DefaultValue("")]
232                public string BodyId { get { return config.bodyId; } set { config.bodyId = value; } }
233
234                [Category("CKEditor Other Settings")]
235                [Description("Whether to show the browser native context menu when the CTRL or the META (Mac) key is pressed while opening the context menu.")]
236                [DefaultValue(true)]
237                public bool BrowserContextMenuOnCtrl { get { return config.browserContextMenuOnCtrl; } set { config.browserContextMenuOnCtrl = value; } }
238
239                [PersistenceMode(PersistenceMode.Attribute)]
240                [Category("CKEditor Basic Settings")]
241                [Description("The CSS file(s) to be used to apply style to the contents. It should reflect the CSS used in the final pages where the contents are to be used.")]
242                [DefaultValue("~/ckeditor/contents.css")]
243                [Editor(typeof(System.ComponentModel.Design.MultilineStringEditor), typeof(System.Drawing.Design.UITypeEditor))]
244                public string ContentsCss
245                {
246                        get
247                        {
248                                string retVal = string.Empty;
249                                foreach (string item in config.contentsCss) retVal += item + ",";
250                                if (retVal.EndsWith(",")) retVal = retVal.Remove(retVal.Length - 1);
251                                return retVal;
252                        }
253                        set { config.contentsCss = value.Replace("\t", string.Empty).Split(new char[] { ',', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); }
254                }
255
256                [Category("CKEditor Other Settings")]
257                [Description(@"The writing direction of the language used to write the editor contents. Allowed values are:
258'ui' - which indicate content direction will be the same with the user interface language direction;
259'ltr' - for Left-To-Right language (like English);
260'rtl' - for Right-To-Left languages (like Arabic).")]
261                [DefaultValue(typeof(contentsLangDirections), "Ui")]
262                public contentsLangDirections ContentsLangDirection { get { return config.contentsLangDirection; } set { config.contentsLangDirection = value; } }
263
264                [Category("CKEditor Other Settings")]
265                [Description("Language code of the writting language which is used to author the editor contents.")]
266                [DefaultValue("")]
267                public string ContentsLanguage { get { return config.contentsLanguage; } set { config.contentsLanguage = value; } }
268
269                [Category("CKEditor Basic Settings")]
270                [Description(@"The URL path for the custom configuration file to be loaded. If not overloaded with inline configurations, it defaults
271to the ""config.js"" file present in the root of the CKEditor installation directory.
272CKEditor will recursively load custom configuration files defined inside other custom configuration files.")]
273                [DefaultValue("config.js")]
274                public string CustomConfig { get { return config.customConfig; } set { config.customConfig = value; } }
275
276                [Category("CKEditor Basic Settings")]
277                [Description("The language to be used if CKEDITOR.config.language is left empty and it's not possible to localize the editor to the user language.")]
278                [DefaultValue("en")]
279                public string DefaultLanguage { get { return config.defaultLanguage; } set { config.defaultLanguage = value; } }
280
281                [Category("CKEditor Other Settings")]
282                [Description(@"The guideline to follow when generating the dialog buttons. There are 3 possible options:
283'OS' - the buttons will be displayed in the default order of the user's OS;
284'ltr' - for Left-To-Right order;
285'rtl' - for Right-To-Left order.")]
286                [DefaultValue(typeof(DialogButtonsOrder), "OS")]
287                public DialogButtonsOrder DialogButtonsOrder { get { return config.dialog_buttonsOrder; } set { config.dialog_buttonsOrder = value; } }
288
289                [Category("CKEditor Other Settings")]
290                [Description(@"Disables the built-in spell checker while typing natively available in the browser (currently Firefox and Safari only).
291Even if word suggestions will not appear in the CKEditor context menu, this feature is useful to help quickly identifying misspelled words.
292This setting is currently compatible with Firefox only due to limitations in other browsers.")]
293                [DefaultValue(true)]
294                public bool DisableNativeSpellChecker { get { return config.disableNativeSpellChecker; } set { config.disableNativeSpellChecker = value; } }
295
296                [Category("CKEditor Other Settings")]
297                [Description(@"Disables the ""table tools"" offered natively by the browser (currently Firefox only) to make quick table editing operations,
298like adding or deleting rows and columns.")]
299                [DefaultValue(true)]
300                public bool DisableNativeTableHandles { get { return config.disableNativeTableHandles; } set { config.disableNativeTableHandles = value; } }
301
302                [Category("CKEditor Other Settings")]
303                [Description("Disables the ability of resize objects (image and tables) in the editing area.")]
304                [DefaultValue(false)]
305                public bool DisableObjectResizing { get { return config.disableObjectResizing; } set { config.disableObjectResizing = value; } }
306
307                [Category("CKEditor Other Settings")]
308                [Description("Disables inline styling on read-only elements.")]
309                [DefaultValue(false)]
310                public bool DisableReadonlyStyling { get { return config.disableReadonlyStyling; } set { config.disableReadonlyStyling = value; } }
311
312                [Category("CKEditor Other Settings")]
313                [Description("Sets the doctype to be used when loading the editor content as HTML.")]
314                [DefaultValue(@"<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transitional//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"">")]
315                public string DocType { get { return config.docType; } set { config.docType = value; } }
316
317                [Category("CKEditor Other Settings")]
318                [Description("Whether to render or not the editing block area in the editor interface.")]
319                [DefaultValue(true)]
320                public bool EditingBlock { get { return config.editingBlock; } set { config.editingBlock = value; } }
321
322                [Category("CKEditor Other Settings")]
323                [Description(@"The e-mail address anti-spam protection option. The protection will be applied when creating or modifying e-mail links through the editor interface.
324Two methods of protection can be choosed:
325The e-mail parts (name, domain and any other query string) are assembled into a function call pattern. Such function must be provided by
326the developer in the pages that will use the contents.
327Only the e-mail address is obfuscated into a special string that has no meaning for humans or spam bots, but which is properly rendered and accepted by the browser.
328Both approaches require JavaScript to be enabled.")]
329                [DefaultValue("")]
330                public string EmailProtection { get { return config.emailProtection; } set { config.emailProtection = value; } }
331
332                [Category("CKEditor Other Settings")]
333                [Description(@"Allow context-sensitive tab key behaviors, including the following scenarios:
334When selection is anchored inside table cells:
335If TAB is pressed, select the contents of the ""next"" cell. If in the last cell in the table, add a new row to it and focus its first cell.
336If SHIFT+TAB is pressed, select the contents of the ""previous"" cell. Do nothing when it's in the first cell.")]
337                [DefaultValue(true)]
338                public bool EnableTabKeyTools { get { return config.enableTabKeyTools; } set { config.enableTabKeyTools = value; } }
339
340                [Category("CKEditor Other Settings")]
341                [Description(@"Sets the behavior for the ENTER key. It also dictates other behaviour rules in the editor, like whether the <br> element is to be used as a paragraph separator when indenting text.
342The allowed values are the following constants, and their relative behavior:
343CKEDITOR.ENTER_P (1): new <p> paragraphs are created;
344CKEDITOR.ENTER_BR (2): lines are broken with <br> elements;
345CKEDITOR.ENTER_DIV (3): new <div> blocks are created.
346Note: It's recommended to use the CKEDITOR.ENTER_P value because of its semantic value and correctness. The editor is optimized for this value.")]
347                [DefaultValue(typeof(EnterMode), "P")]
348                public EnterMode EnterMode { get { return config.enterMode; } set { config.enterMode = value; } }
349
350                [Category("CKEditor Basic Settings")]
351                [Description("Whether to use HTML entities in the output.")]
352                [DefaultValue(true)]
353                public bool Entities { get { return config.entities; } set { config.entities = value; } }
354
355                [Category("CKEditor Basic Settings")]
356                [Description(@"An additional list of entities to be used. It's a string containing each entry separated by a comma.
357Entities names or number must be used, exclusing the ""&"" preffix and the "";"" termination.")]
358                [DefaultValue("#39")]
359                public string EntitiesAdditional { get { return config.entities_additional; } set { config.entities_additional = value; } }
360
361                [Category("CKEditor Basic Settings")]
362                [Description(@"Whether to convert some symbols, mathematical symbols, and Greek letters to HTML entities. This may be more relevant for users typing text written in Greek.
363The list of entities can be found at the W3C HTML 4.01 Specification, section 24.3.1.")]
364                [DefaultValue(true)]
365                public bool EntitiesGreek { get { return config.entities_greek; } set { config.entities_greek = value; } }
366
367                [Category("CKEditor Basic Settings")]
368                [Description(@"Whether to convert some Latin characters (Latin alphabet No. 1, ISO 8859-1) to HTML entities.
369The list of entities can be found at the W3C HTML 4.01 Specification, section 24.2.1.")]
370                [DefaultValue(true)]
371                public bool EntitiesLatin { get { return config.entities_latin; } set { config.entities_latin = value; } }
372
373                [Category("CKEditor Basic Settings")]
374                [Description(@"List of additional plugins to be loaded.
375This is a tool setting which makes it easier to add new plugins, whithout having to touch and possibly breaking the CKEDITOR.config.plugins setting.")]
376                [DefaultValue("")]
377                public string ExtraPlugins { get { return config.extraPlugins; } set { config.extraPlugins = value; } }
378
379                [Category("CKEditor Basic Settings")]
380                [Description(@"The location of an external file browser, that should be launched when ""Browse Server"" button is pressed.
381If configured, the ""Browse Server"" button will appear in Link, Image and Flash dialogs.")]
382                [DefaultValue("")]
383                public string FilebrowserBrowseUrl { get { return config.filebrowserBrowseUrl; } set { config.filebrowserBrowseUrl = value; } }
384
385                [Category("CKEditor Basic Settings")]
386                [Description(@"The location of an external file browser, that should be launched when ""Browse Server"" button is pressed in the Flash dialog.
387If not set, CKEditor will use CKEDITOR.config.filebrowserBrowseUrl.")]
388                [DefaultValue("")]
389                public string FilebrowserFlashBrowseUrl { get { return config.filebrowserFlashBrowseUrl; } set { config.filebrowserFlashBrowseUrl = value; } }
390
391                [Category("CKEditor Basic Settings")]
392                [Description("The location of a script that handles file uploads in the Flash dialog. If not set, CKEditor will use CKEDITOR.config.filebrowserUploadUrl.")]
393                [DefaultValue("")]
394                public string FilebrowserFlashUploadUrl { get { return config.filebrowserFlashUploadUrl; } set { config.filebrowserFlashUploadUrl = value; } }
395
396                [Category("CKEditor Basic Settings")]
397                [Description(@"The location of an external file browser, that should be launched when ""Browse Server"" button is pressed in the Link tab of Image dialog.
398If not set, CKEditor will use CKEDITOR.config.filebrowserBrowseUrl.")]
399                [DefaultValue("")]
400                public string FilebrowserImageBrowseLinkUrl { get { return config.filebrowserImageBrowseLinkUrl; } set { config.filebrowserImageBrowseLinkUrl = value; } }
401
402                [Category("CKEditor Basic Settings")]
403                [Description(@"The location of an external file browser, that should be launched when ""Browse Server"" button is pressed in the Image dialog.
404If not set, CKEditor will use CKEDITOR.config.filebrowserBrowseUrl.")]
405                [DefaultValue("")]
406                public string FilebrowserImageBrowseUrl { get { return config.filebrowserImageBrowseUrl; } set { config.filebrowserImageBrowseUrl = value; } }
407
408                [Category("CKEditor Basic Settings")]
409                [Description("The location of a script that handles file uploads in the Image dialog. If not set, CKEditor will use CKEDITOR.config.filebrowserUploadUrl.")]
410                [DefaultValue("")]
411                public string FilebrowserImageUploadUrl { get { return config.filebrowserImageUploadUrl; } set { config.filebrowserImageUploadUrl = value; } }
412
413                [Category("CKEditor Basic Settings")]
414                [Description(@"The location of a script that handles file uploads. If set, the ""Upload"" tab will appear in ""Link"", ""Image"" and ""Flash"" dialogs.")]
415                [DefaultValue("")]
416                public string FilebrowserUploadUrl { get { return config.filebrowserUploadUrl; } set { config.filebrowserUploadUrl = value; } }
417
418                [Category("CKEditor Other Settings")]
419                [Description(@"The ""features"" to use in the file browser popup window.")]
420                [DefaultValue("location=no,menubar=no,toolbar=no,dependent=yes,minimizable=no,modal=yes,alwaysRaised=yes,resizable=yes,scrollbars=yes")]
421                [Editor(typeof(System.ComponentModel.Design.MultilineStringEditor), typeof(System.Drawing.Design.UITypeEditor))]
422                public string FilebrowserWindowFeatures { get { return config.filebrowserWindowFeatures; } set { config.filebrowserWindowFeatures = value; } }
423
424                [Category("CKEditor Other Settings")]
425                [Description(@"Whether a filler text (non-breaking space entity -  ) will be inserted into empty block elements in HTML output,
426this is used to render block elements properly with line-height; When a function is instead specified,
427it'll be passed a CKEDITOR.htmlParser.element to decide whether adding the filler text by expecting a boolean return value.")]
428                [DefaultValue(true)]
429                public bool FillEmptyBlocks { get { return config.fillEmptyBlocks; } set { config.fillEmptyBlocks = value; } }
430
431                [Category("CKEditor Other Settings")]
432                [Description("The text to be displayed in the Font combo is none of the available values matches the current cursor position or text selection.")]
433                [DefaultValue("")]
434                public string FontDefaultLabel { get { return config.font_defaultLabel; } set { config.font_defaultLabel = value; } }
435
436                [Category("CKEditor Basic Settings")]
437                [Description(@"The list of fonts names to be displayed in the Font combo in the toolbar. Entries are separated by semi-colons (;),
438while it's possible to have more than one font for each entry, in the HTML way (separated by comma).
439A display name may be optionally defined by prefixing the entries with the name and the slash character.")]
440                [DefaultValue(@"Arial/Arial, Helvetica, sans-serif;
441Comic Sans MS/Comic Sans MS, cursive;
442Courier New/Courier New, Courier, monospace;
443Georgia/Georgia, serif;
444Lucida Sans Unicode/Lucida Sans Unicode, Lucida Grande, sans-serif;
445Tahoma/Tahoma, Geneva, sans-serif;
446Times New Roman/Times New Roman, Times, serif;
447Trebuchet MS/Trebuchet MS, Helvetica, sans-serif;
448Verdana/Verdana, Geneva, sans-serif")]
449                [Editor(typeof(System.ComponentModel.Design.MultilineStringEditor), typeof(System.Drawing.Design.UITypeEditor))]
450                public string FontNames { get { return config.font_names; } set { config.font_names = value; } }
451
452                [Category("CKEditor Other Settings")]
453                [Description("The text to be displayed in the Font Size combo is none of the available values matches the current cursor position or text selection.")]
454                [DefaultValue("")]
455                public string FontSizeDefaultLabel { get { return config.fontSize_defaultLabel; } set { config.fontSize_defaultLabel = value; } }
456
457                [Category("CKEditor Basic Settings")]
458                [Description(@"The list of fonts size to be displayed in the Font Size combo in the toolbar. Entries are separated by semi-colons (;).
459Any kind of ""CSS like"" size can be used, like ""12px"", ""2.3em"", ""130%"", ""larger"" or ""x-small"".
460A display name may be optionally defined by prefixing the entries with the name and the slash character.")]
461                [DefaultValue("8/8px;9/9px;10/10px;11/11px;12/12px;14/14px;16/16px;18/18px;20/20px;22/22px;24/24px;26/26px;28/28px;36/36px;48/48px;72/72px")]
462                [Editor(typeof(System.ComponentModel.Design.MultilineStringEditor), typeof(System.Drawing.Design.UITypeEditor))]
463                public string FontSizeSizes { get { return config.fontSize_sizes; } set { config.fontSize_sizes = value; } }
464
465                [Category("CKEditor Other Settings")]
466                [Description(@"Force the respect of CKEDITOR.config.enterMode as line break regardless of the context,
467E.g. If CKEDITOR.config.enterMode is set to CKEDITOR.ENTER_P, press enter key inside a 'div' will create a new paragraph with 'p' instead of 'div'.")]
468                [DefaultValue(false)]
469                public bool ForceEnterMode { get { return config.forceEnterMode; } set { config.forceEnterMode = value; } }
470
471                [Category("CKEditor Basic Settings")]
472                [Description("Whether to force all pasting operations to insert on plain text into the editor, loosing any formatting information possibly available in the source text.")]
473                [DefaultValue(false)]
474                public bool ForcePasteAsPlainText { get { return config.forcePasteAsPlainText; } set { config.forcePasteAsPlainText = value; } }
475
476                [Category("CKEditor Basic Settings")]
477                [Description(@" Whether to force using ""&"" instead of ""&amp;"" in elements attributes values,
478it's not recommended to change this setting for compliance with the W3C XHTML 1.0 standards (C.12, XHTML 1.0).")]
479                [DefaultValue(false)]
480                public bool ForceSimpleAmpersand { get { return config.forceSimpleAmpersand; } set { config.forceSimpleAmpersand = value; } }
481
482                [Category("CKEditor Basic Settings")]
483                [Description(@" A list of semi colon separated style names (by default tags) representing the style definition for each entry to be displayed
484in the Format combo in the toolbar. Each entry must have its relative definition configuration in a setting named
485""format_(tagName)"". For example, the ""p"" entry has its definition taken from config.format_p.
486")]
487                [DefaultValue("p;h1;h2;h3;h4;h5;h6;pre;address;div")]
488                [Editor(typeof(System.ComponentModel.Design.MultilineStringEditor), typeof(System.Drawing.Design.UITypeEditor))]
489                public string FormatTags { get { return config.format_tags; } set { config.format_tags = value; } }
490
491                [Category("CKEditor Basic Settings")]
492                [Description(@"Indicates whether the contents to be edited are being inputted as a full HTML page.
493A full page includes the <html>, <head> and <body> tags.
494The final output will also reflect this setting, including the <body> contents only if this setting is disabled.")]
495                [DefaultValue(false)]
496                public bool FullPage { get { return config.fullPage; } set { config.fullPage = value; } }
497
498                [Category("CKEditor Other Settings")]
499                [Description("Whether escape HTML when editor update original input element.")]
500                [DefaultValue(true)]
501                public bool HtmlEncodeOutput { get { return config.htmlEncodeOutput; } set { config.htmlEncodeOutput = value; } }
502
503                [Category("CKEditor Other Settings")]
504                [Description(@"Whether the editor must output an empty value ("""") if it's contents is made by an empty paragraph only.")]
505                [DefaultValue(true)]
506                public bool IgnoreEmptyParagraph { get { return config.ignoreEmptyParagraph; } set { config.ignoreEmptyParagraph = value; } }
507
508                [Category("CKEditor Other Settings")]
509                [Description("Padding text to set off the image in preview area.")]
510                [DefaultValue("")]
511                public string ImagePreviewText { get { return config.image_previewText; } set { config.image_previewText = value; } }
512
513                [Category("CKEditor Other Settings")]
514                [Description("Whether to remove links when emptying the link URL field in the image dialog.")]
515                [DefaultValue(true)]
516                public bool ImageRemoveLinkByEmptyURL { get { return config.image_removeLinkByEmptyURL; } set { config.image_removeLinkByEmptyURL = value; } }
517
518                [TypeConverter(typeof(StringArrayConverter))]
519                [PersistenceMode(PersistenceMode.Attribute)]
520                [Category("CKEditor Other Settings")]
521                [Description("List of classes to use for indenting the contents. If it's null, no classes will be used and instead the #indentUnit and #indentOffset properties will be used.")]
522                [DefaultValue(typeof(Array), null)]
523                public string[] IndentClasses { get { return config.indentClasses; } set { config.indentClasses = value; } }
524
525                [Category("CKEditor Other Settings")]
526                [Description("Size of each indentation step")]
527                [DefaultValue(40)]
528                public int IndentOffset { get { return config.indentOffset; } set { config.indentOffset = value; } }
529
530                [Category("CKEditor Other Settings")]
531                [Description("Unit for the indentation style")]
532                [DefaultValue("px")]
533                public string IndentUnit { get { return config.indentUnit; } set { config.indentUnit = value; } }
534
535                [Category("CKEditor Basic Settings")]
536                [Description(@"The user interface language localization to use. If empty, the editor automatically localize the editor to the user language,
537if supported, otherwise the CKEDITOR.config.defaultLanguage language is used.")]
538                [DefaultValue("")]
539                public string Language { get { return config.language; } set { config.language = value; } }
540
541                [Category("CKEditor Other Settings")]
542                [Description("Whether to transform MS Word outline numbered headings into lists.")]
543                [DefaultValue(false)]
544                public bool PasteFromWordNumberedHeadingToList { get { return config.pasteFromWordNumberedHeadingToList; } set { config.pasteFromWordNumberedHeadingToList = value; } }
545
546                [Category("CKEditor Other Settings")]
547                [Description("Whether to prompt the user about the clean up of content being pasted from MS Word.")]
548                [DefaultValue(false)]
549                public bool PasteFromWordPromptCleanup { get { return config.pasteFromWordPromptCleanup; } set { config.pasteFromWordPromptCleanup = value; } }
550
551                [Category("CKEditor Other Settings")]
552                [Description(@"Whether to ignore all font related formatting styles, including:
553font size;
554font family;
555font foreground/background color.")]
556                [DefaultValue(true)]
557                public bool PasteFromWordRemoveFontStyles { get { return config.pasteFromWordRemoveFontStyles; } set { config.pasteFromWordRemoveFontStyles = value; } }
558
559                [Category("CKEditor Other Settings")]
560                [Description(@"Whether to remove element styles that can't be managed with the editor. Note that this doesn't handle the font specific styles,
561which depends on the CKEDITOR.config.pasteFromWordRemoveFontStyles setting instead.")]
562                [DefaultValue(false)]
563                public bool PasteFromWordRemoveStyles { get { return config.pasteFromWordRemoveStyles; } set { config.pasteFromWordRemoveStyles = value; } }
564
565                [TypeConverter(typeof(StringArrayConverter))]
566                [PersistenceMode(PersistenceMode.Attribute)]
567                [Category("CKEditor Other Settings")]
568                [Description("List of regular expressions to be executed over the input HTML, indicating HTML source code that matched must not present in WYSIWYG mode for editing.")]
569                [DefaultValue(typeof(Array), null)]
570                public string[] ProtectedSource { get { return config.protectedSource; } set { config.protectedSource = value; } }
571
572                [Category("CKEditor Other Settings")]
573                [Description(@"The dialog contents to removed. It's a string composed by dialog name and tab name with a colon between them.
574Separate each pair with semicolon (see example). Note: All names are case-sensitive.
575Note: Be cautious when specifying dialog tabs that are mandatory, like ""info"",
576dialog functionality might be broken because of this!")]
577                [DefaultValue("")]
578                public string RemoveDialogTabs { get { return config.removeDialogTabs; } set { config.removeDialogTabs = value; } }
579
580                [Category("CKEditor Other Settings")]
581                [Description(@"List of plugins that must not be loaded. This is a tool setting which makes it easier to avoid loading plugins definied
582in the CKEDITOR.config.plugins setting, whithout having to touch it and potentially breaking it.")]
583                [DefaultValue("")]
584                public string RemovePlugins { get { return config.removePlugins; } set { config.removePlugins = value; } }
585
586                [Category("CKEditor Other Settings")]
587                [Description(@"The directions to which the editor resizing is enabled. Possible values are ""both"", ""vertical"" and ""horizontal"".")]
588                [DefaultValue(typeof(ResizeDir), "Both")]
589                public ResizeDir ResizeDir { get { return config.resize_dir; } set { config.resize_dir = value; } }
590
591                [Category("CKEditor Other Settings")]
592                [Description("Whether to enable the resizing feature. If disabled the resize handler will not be visible.")]
593                [DefaultValue(true)]
594                public bool ResizeEnabled { get { return config.resize_enabled; } set { config.resize_enabled = value; } }
595
596                [Category("CKEditor Other Settings")]
597                [Description("The maximum editor height, in pixels, when resizing it with the resize handle.")]
598                [DefaultValue(3000)]
599                public int ResizeMaxHeight { get { return config.resize_maxHeight; } set { config.resize_maxHeight = value; } }
600
601                [Category("CKEditor Other Settings")]
602                [Description("The maximum editor width, in pixels, when resizing it with the resize handle.")]
603                [DefaultValue(3000)]
604                public int ResizeMaxWidth { get { return config.resize_maxWidth; } set { config.resize_maxWidth = value; } }
605
606                [Category("CKEditor Other Settings")]
607                [Description(@"The minimum editor height, in pixels, when resizing it with the resize handle.
608Note: It fallbacks to editor's actual height if that's smaller than the default value.")]
609                [DefaultValue(250)]
610                public int ResizeMinHeight { get { return config.resize_minHeight; } set { config.resize_minHeight = value; } }
611
612                [Category("CKEditor Other Settings")]
613                [Description(@"The minimum editor width, in pixels, when resizing it with the resize handle.
614Note: It fallbacks to editor's actual width if that's smaller than the default value.")]
615                [DefaultValue(750)]
616                public int ResizeMinWidth { get { return config.resize_minWidth; } set { config.resize_minWidth = value; } }
617
618                [Category("CKEditor Other Settings")]
619                [Description("If enabled (true), turns on SCAYT automatically after loading the editor.")]
620                [DefaultValue(false)]
621                public bool ScaytAutoStartup { get { return config.scayt_autoStartup; } set { config.scayt_autoStartup = value; } }
622
623                [Category("CKEditor Other Settings")]
624                [Description("ID of bottom cntrol's shared")]
625                [DefaultValue("")]
626                public string SharedSpacesBottom { get { return config.sharedSpacesBottom; } set { config.sharedSpacesBottom = value; } }
627
628                [Category("CKEditor Other Settings")]
629                [Description("ID of top cntrol's shared")]
630                [DefaultValue("")]
631                public string SharedSpacesTop { get { return config.sharedSpacesTop; } set { config.sharedSpacesTop = value; } }
632
633                [Category("CKEditor Other Settings")]
634                [Description(@"Just like the CKEDITOR.config.enterMode setting, it defines the behavior for the SHIFT+ENTER key.
635The allowed values are the following constants, and their relative behavior:
636CKEDITOR.ENTER_P (1): new <p> paragraphs are created;
637CKEDITOR.ENTER_BR (2): lines are broken with <br> elements;
638CKEDITOR.ENTER_DIV (3): new <div> blocks are created.")]
639                [DefaultValue(typeof(EnterMode), "P")]
640                public EnterMode ShiftEnterMode { get { return config.shiftEnterMode; } set { config.shiftEnterMode = value; } }
641
642                [Category("CKEditor Basic Settings")]
643                [Description("The skin to load. It may be the name of the skin folder inside the editor installation path, or the name and the path separated by a comma.")]
644                [DefaultValue("kama")]
645                public string Skin { get { return config.skin; } set { config.skin = value; } }
646
647                [Category("CKEditor Other Settings")]
648                [Description(@"The mode to load at the editor startup. It depends on the plugins loaded. By default, the ""wysiwyg"" and ""source"" modes are available.")]
649                [DefaultValue(typeof(StartupMode), "Wysiwyg")]
650                public StartupMode StartupMode { get { return config.startupMode; } set { config.startupMode = value; } }
651
652                [Category("CKEditor Other Settings")]
653                [Description(@"Whether to automaticaly enable the ""show block"" command when the editor loads. (StartupShowBlocks in FCKeditor)")]
654                [DefaultValue(false)]
655                public bool StartupOutlineBlocks { get { return config.startupOutlineBlocks; } set { config.startupOutlineBlocks = value; } }
656
657                [Category("CKEditor Other Settings")]
658                [Description(@"Whether to automatically enable the ""show borders"" command when the editor loads. (ShowBorders in FCKeditor)")]
659                [DefaultValue(true)]
660                public bool StartupShowBorders { get { return config.startupShowBorders; } set { config.startupShowBorders = value; } }
661
662                [PersistenceMode(PersistenceMode.Attribute)]
663                [Category("CKEditor Other Settings")]
664                [Description(@"The ""styles definition set"" to use in the editor. They will be used in the styles combo and the Style selector of the div container.
665The styles may be defined in the page containing the editor, or can be loaded on demand from an external file. In the second case,
666if this setting contains only a name, the styles definition file will be loaded from the ""styles"" folder inside the styles plugin folder.
667Otherwise, this setting has the ""name:url"" syntax, making it possible to set the URL from which loading the styles file.
668Previously this setting was available as config.stylesCombo_stylesSet")]
669                [DefaultValue("default")]
670                [Editor(typeof(System.ComponentModel.Design.MultilineStringEditor), typeof(System.Drawing.Design.UITypeEditor))]
671                public string StylesSet
672                {
673                        get
674                        {
675                                string retVal = string.Empty;
676                                foreach (string item in config.stylesSet) retVal += item + ",";
677                                if (retVal.EndsWith(",")) retVal = retVal.Remove(retVal.Length - 1);
678                                return retVal;
679                        }
680                        set
681                        {
682                                if (value.Contains("{") && value.Contains("}"))
683                                        config.stylesSet = new string[] { value };
684                                else
685                                        config.stylesSet = value.Replace("\t", string.Empty).Split(new char[] { ',', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
686                        }
687                }
688
689                [Category("CKEditor Other Settings")]
690                [Description(@"Intructs the editor to add a number of spaces (&nbsp;) to the text when hitting the TAB key.
691If set to zero, the TAB key will be used to move the cursor focus to the next element in the page, out of the editor focus.")]
692                [DefaultValue(0)]
693                public int TabSpaces { get { return config.tabSpaces; } set { config.tabSpaces = value; } }
694
695                [Category( "CKEditor Other Settings" )]
696                [Description( "The templates definition set to use. It accepts a list of names separated by comma. It must match definitions loaded with the templates_files setting." )]
697                [DefaultValue( "default" )]
698                public string Templates { get { return config.templates; } set { config.templates = value; } }
699
700                [PersistenceMode(PersistenceMode.Attribute)]
701                [Category("CKEditor Other Settings")]
702                [Description("The list of templates definition files to load.")]
703                [DefaultValue("~/ckeditor/plugins/templates/templates/default.js")]
704                [Editor(typeof(System.ComponentModel.Design.MultilineStringEditor), typeof(System.Drawing.Design.UITypeEditor))]
705                public string TemplatesFiles
706                {
707                        get
708                        {
709                                string retVal = string.Empty;
710                                foreach (string item in config.templates_files) retVal += item + ",";
711                                if (retVal.EndsWith(",")) retVal = retVal.Remove(retVal.Length - 1);
712                                return retVal;
713                        }
714                        set { config.templates_files = value.Replace("\t", string.Empty).Split(new char[] { ',', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); }
715                }
716
717                [Category("CKEditor Other Settings")]
718                [Description(@"Whether the ""Replace actual contents"" checkbox is checked by default in the Templates dialog.")]
719                [DefaultValue(true)]
720                public bool TemplatesReplaceContent { get { return config.templates_replaceContent; } set { config.templates_replaceContent = value; } }
721
722                [PersistenceMode(PersistenceMode.Attribute)]
723                [Category("CKEditor Basic Settings")]
724                [Description("The toolbox (alias toolbar) definition. It is a toolbar name or an array of toolbars (strips), each one being also an array, containing a list of UI items.")]
725                [DefaultValue("Full")]
726                [Editor(typeof(System.ComponentModel.Design.MultilineStringEditor), typeof(System.Drawing.Design.UITypeEditor))]
727                public string Toolbar
728                {
729                        get
730                        {
731                                if (config.toolbar is string) return (string)config.toolbar;
732                                string retVal = string.Empty;
733                                try
734                                {
735                                        string[] retValTab = new string[((object[])config.toolbar).Length];
736                                        object[] ob = (object[])config.toolbar;
737                                        for (int i = 0; i < ob.Length; i++)
738                                        {
739                                                object item = ob[i];
740                                                if (item is string) retValTab[i] = (string)item;
741                                                else
742                                                {
743                                                        object[] itemTab = (object[])item;
744                                                        string concatValue = string.Empty;
745                                                        for (int j = 0; j < itemTab.Length; j++)
746                                                                concatValue += (string)itemTab[j] + "|";
747                                                        if (!string.IsNullOrEmpty(concatValue))
748                                                                concatValue = concatValue.Remove(concatValue.Length - 1);
749                                                        retValTab[i] = concatValue;
750                                                }
751                                        }
752                                        foreach (string item in retValTab) retVal += item + "\r\n";
753                                        if (retVal.EndsWith("\r\n")) retVal = retVal.Remove(retVal.Length - 2);
754                                }
755                                catch { }
756                                return retVal;
757                        }
758                        set
759                        {
760                                value = value.Trim();
761                                if (value.StartsWith("[") && value.EndsWith("]"))
762                                {
763                                        config.toolbar = value.Replace("\t", string.Empty).Replace("\r", string.Empty).Replace("\n", string.Empty);
764                                        return;
765                                }
766                                string[] valueTab = value.Split(new string[] { "\r\n" }, int.MaxValue, StringSplitOptions.RemoveEmptyEntries);
767                                if (valueTab.Length == 1 && !valueTab[0].Contains("|"))
768                                {
769                                        config.toolbar = valueTab[0];
770                                        return;
771                                }
772                                object[] retVal = new object[valueTab.Length];
773                                try
774                                {
775                                        for (int i = 0; i < valueTab.Length; i++)
776                                        {
777                                                string[] item = valueTab[i].Split(new char[] { '|' });
778                                                for (int k = 0; k < item.Length; k++)
779                                                        item[k] = item[k].Trim();
780                                                if (item.Length == 1 && item[0] == "/") retVal[i] = item[0];
781                                                else retVal[i] = item;
782                                        }
783                                }
784                                catch { }
785                                config.toolbar = retVal;
786                        }
787                }
788
789                [PersistenceMode(PersistenceMode.Attribute)]
790                [Category("CKEditor Basic Settings")]
791                [Description(@"The toolbar definition. It is an array of toolbars (strips), each one being also an array, containing a list of UI items.
792Note that this setting is composed by ""toolbar_"" added by the toolbar name, which in this case is called ""Basic"".
793This second part of the setting name can be anything. You must use this name in the CKEDITOR.config.toolbar setting,
794so you instruct the editor which toolbar_(name) setting to you.")]
795                [DefaultValue("Bold|Italic|-|NumberedList|BulletedList|-|Link|Unlink|-|About")]
796                [Editor(typeof(System.ComponentModel.Design.MultilineStringEditor), typeof(System.Drawing.Design.UITypeEditor))]
797                public string ToolbarBasic
798                {
799                        get
800                        {
801                                string retVal = string.Empty;
802                                try
803                                {
804                                        string[] retValTab = new string[config.toolbar_Basic.Length];
805                                        object[] ob = config.toolbar_Basic;
806                                        for (int i = 0; i < ob.Length; i++)
807                                        {
808                                                object item = ob[i];
809                                                if (item is string) retValTab[i] = (string)item;
810                                                else
811                                                {
812                                                        object[] itemTab = (object[])item;
813                                                        string concatValue = string.Empty;
814                                                        for (int j = 0; j < itemTab.Length; j++)
815                                                                concatValue += (string)itemTab[j] + "|";
816                                                        if (!string.IsNullOrEmpty(concatValue))
817                                                                concatValue = concatValue.Remove(concatValue.Length - 1);
818                                                        retValTab[i] = concatValue;
819                                                }
820                                        }
821                                        foreach (string item in retValTab) retVal += item + "\r\n";
822                                        if (retVal.EndsWith("\r\n")) retVal = retVal.Remove(retVal.Length - 2);
823                                }
824                                catch { }
825                                return retVal;
826                        }
827                        set
828                        {
829                                value = value.Trim();
830                                if (value.StartsWith("[") && value.EndsWith("]"))
831                                {
832                                        config.toolbar_Basic = new object[] { value.Replace("\t", string.Empty).Replace("\r", string.Empty).Replace("\n", string.Empty) };
833                                        return;
834                                }
835                                string[] valueTab = value.Split(new string[] { "\r\n" }, int.MaxValue, StringSplitOptions.RemoveEmptyEntries);
836                                object[] retVal = new object[valueTab.Length];
837                                try
838                                {
839                                        for (int i = 0; i < valueTab.Length; i++)
840                                        {
841                                                string[] item = valueTab[i].Split(new char[] { '|' });
842                                                for (int k = 0; k < item.Length; k++)
843                                                        item[k] = item[k].Trim();
844                                                if (item.Length == 1 && item[0] == "/") retVal[i] = item[0];
845                                                else retVal[i] = item;
846                                        }
847                                }
848                                catch { }
849                                config.toolbar_Basic = retVal;
850                        }
851                }
852
853                [PersistenceMode(PersistenceMode.Attribute)]
854                [Category("CKEditor Basic Settings")]
855                [Description("This is the default toolbar definition used by the editor. It contains all editor features.")]
856                [DefaultValue(@"Source|-|Save|NewPage|Preview|-|Templates
857Cut|Copy|Paste|PasteText|PasteFromWord|-|Print|SpellChecker|Scayt
858Undo|Redo|-|Find|Replace|-|SelectAll|RemoveFormat
859Form|Checkbox|Radio|TextField|Textarea|Select|Button|ImageButton|HiddenField
860/
861Bold|Italic|Underline|Strike|-|Subscript|Superscript
862NumberedList|BulletedList|-|Outdent|Indent|Blockquote|CreateDiv
863JustifyLeft|JustifyCenter|JustifyRight|JustifyBlock
864BidiLtr|BidiRtl
865Link|Unlink|Anchor
866Image|Flash|Table|HorizontalRule|Smiley|SpecialChar|PageBreak|Iframe
867/
868Styles|Format|Font|FontSize
869TextColor|BGColor
870Maximize|ShowBlocks|-|About")]
871                [Editor(typeof(System.ComponentModel.Design.MultilineStringEditor), typeof(System.Drawing.Design.UITypeEditor))]
872                public string ToolbarFull
873                {
874                        get
875                        {
876                                string retVal = string.Empty;
877                                try
878                                {
879                                        string[] retValTab = new string[config.toolbar_Full.Length];
880                                        object[] ob = config.toolbar_Full;
881                                        for (int i = 0; i < ob.Length; i++)
882                                        {
883                                                object item = ob[i];
884                                                if (item is string) retValTab[i] = (string)item;
885                                                else
886                                                {
887                                                        object[] itemTab = (object[])item;
888                                                        string concatValue = string.Empty;
889                                                        for (int j = 0; j < itemTab.Length; j++)
890                                                                concatValue += (string)itemTab[j] + "|";
891                                                        if (!string.IsNullOrEmpty(concatValue))
892                                                                concatValue = concatValue.Remove(concatValue.Length - 1);
893                                                        retValTab[i] = concatValue;
894                                                }
895                                        }
896                                        foreach (string item in retValTab) retVal += item + "\r\n";
897                                        if (retVal.EndsWith("\r\n")) retVal = retVal.Remove(retVal.Length - 2);
898                                }
899                                catch { }
900                                return retVal;
901                        }
902                        set
903                        {
904                                value = value.Trim();
905                                if (value.StartsWith("[") && value.EndsWith("]"))
906                                {
907                                        config.toolbar_Full = new object[] { value.Replace("\t", string.Empty).Replace("\r", string.Empty).Replace("\n", string.Empty) };
908                                        return;
909                                }
910                                string[] valueTab = value.Split(new string[] { "\r\n" }, int.MaxValue, StringSplitOptions.RemoveEmptyEntries);
911                                object[] retVal = new object[valueTab.Length];
912                                try
913                                {
914                                        for (int i = 0; i < valueTab.Length; i++)
915                                        {
916                                                string[] item = valueTab[i].Split(new char[] { '|' });
917                                                for (int k = 0; k < item.Length; k++)
918                                                        item[k] = item[k].Trim();
919                                                if (item.Length == 1 && item[0] == "/") retVal[i] = item[0];
920                                                else retVal[i] = item;
921                                        }
922                                }
923                                catch { }
924                                config.toolbar_Full = retVal;
925                        }
926                }
927
928                [Category("CKEditor Other Settings")]
929                [Description("This is the default toolbar definition used by the editor. It contains all editor features.")]
930                [DefaultValue(true)]
931                public bool ToolbarCanCollapse { get { return config.toolbarCanCollapse; } set { config.toolbarCanCollapse = value; } }
932
933                [Category("CKEditor Other Settings")]
934                [Description(@"The ""theme space"" to which rendering the toolbar. For the default theme, the recommended options are ""top"" and ""bottom"".")]
935                [DefaultValue(typeof(ToolbarLocation), "Top")]
936                public ToolbarLocation ToolbarLocation { get { return config.toolbarLocation; } set { config.toolbarLocation = value; } }
937
938                [Category("CKEditor Other Settings")]
939                [Description("Whether the toolbar must start expanded when the editor is loaded.")]
940                [DefaultValue(true)]
941                public bool ToolbarStartupExpanded { get { return config.toolbarStartupExpanded; } set { config.toolbarStartupExpanded = value; } }
942
943                [Category("CKEditor Other Settings")]
944                [Description(@"Indicates that some of the editor features, like alignment and text direction, should used the ""computed value""
945of the featureto indicate it's on/off state, instead of using the ""real value"".
946If enabled, in a left to right written document, the ""Left Justify"" alignment button will show as active,
947even if the aligment style is not explicitly applied to the current paragraph in the editor.")]
948                [DefaultValue(true)]
949                public bool UseComputedState { get { return config.useComputedState; } set { config.useComputedState = value; } }
950
951                [TypeConverter(typeof(WebColorConverter))]
952                [Category("CKEditor Basic Settings")]
953                [Description("Specifies the color of the user interface. Works only with the Kama skin.")]
954                [DefaultValue(typeof(System.Drawing.Color), "LightGray")]
955                public System.Drawing.Color UIColor
956                {
957                        get
958                        {
959                                if (config.uiColor == "#D3D3D3") return System.Drawing.Color.FromName("LightGray");
960                                return System.Drawing.ColorTranslator.FromHtml(config.uiColor);
961                        }
962                        set { config.uiColor = "#" + value.R.ToString(@"x2") + value.G.ToString(@"x2") + value.B.ToString(@"x2"); }
963                }
964
965                [Category("CKEditor Other Settings")]
966                [Description("To attach a function to CKEditor events.")]
967                [DefaultValue(null)]
968                public List<object> CKEditorEventHandler { get { return config.CKEditorEventHandler; } set { config.CKEditorEventHandler = value; } }
969
970                [Category("CKEditor Other Settings")]
971                [Description("To attach a function to an event in a single editor instance")]
972                [DefaultValue(null)]
973                public List<object> CKEditorInstanceEventHandler { get { return config.CKEditorInstanceEventHandler; } set { config.CKEditorInstanceEventHandler = value; } }
974
975                #endregion
976
977                #endregion
978
979                #region Microsoft Ajax compatibility
980
981                private static bool? _HasMsAjax = null;
982                private static Type typScriptManager;
983                private static Type updatePanel;
984                private static System.Reflection.MethodInfo mtdRegisterClientScriptInclude;
985                private static System.Reflection.MethodInfo mtdRegisterStartupScript;
986                private static System.Reflection.MethodInfo mtdRegisterOnSubmitStatement;
987
988                private void RegisterClientScriptInclude(Type type, string key, string url)
989                {
990                        if (HasMsAjax)
991                        {
992                                if (mtdRegisterClientScriptInclude == null)
993                                        mtdRegisterClientScriptInclude = typScriptManager.GetMethod("RegisterClientScriptInclude", new Type[4] { typeof(Control), typeof(Type), typeof(string), typeof(string) });
994                                mtdRegisterClientScriptInclude.Invoke(null, new object[4] { this, type, key, url });
995                        }
996                        else
997                                Page.ClientScript.RegisterClientScriptInclude(type, key, url);
998                }
999
1000                private void RegisterStartupScript(Type type, string key, string script, bool addScriptTags)
1001                {
1002                        if (HasMsAjax)
1003                        {
1004                                if (mtdRegisterStartupScript == null)
1005                                        mtdRegisterStartupScript = typScriptManager.GetMethod("RegisterStartupScript", new Type[5] { typeof(Control), typeof(Type), typeof(string), typeof(string), typeof(bool) });
1006                                mtdRegisterStartupScript.Invoke(null, new object[5] { this, type, key, script, addScriptTags });
1007                        }
1008                        else
1009                                Page.ClientScript.RegisterStartupScript(type, key, script, addScriptTags);
1010                }
1011
1012                private void RegisterOnSubmitStatement(Type type, string key, string script)
1013                {
1014                        if (HasMsAjax)
1015                        {
1016                                if (mtdRegisterOnSubmitStatement == null)
1017                                        mtdRegisterOnSubmitStatement = typScriptManager.GetMethod("RegisterOnSubmitStatement", new Type[4] { typeof(Control), typeof(Type), typeof(string), typeof(string) });
1018                                mtdRegisterOnSubmitStatement.Invoke(null, new object[4] { this, type, key, script });
1019                        }
1020                        else
1021                                Page.ClientScript.RegisterOnSubmitStatement(type, key, script);
1022                }
1023
1024                private bool HasMsAjax
1025                {
1026                        get
1027                        {
1028                                if (_HasMsAjax == null)
1029                                {
1030                                        _HasMsAjax = false;
1031                                        System.Reflection.Assembly[] AppAssemblies = AppDomain.CurrentDomain.GetAssemblies();
1032                                        foreach (System.Reflection.Assembly asm in AppAssemblies)
1033                                        {
1034                                                if (asm.ManifestModule.Name == "System.Web.Extensions.dll")
1035                                                {
1036                                                        try
1037                                                        {
1038                                                                updatePanel = asm.GetType("System.Web.UI.UpdatePanel");
1039                                                                typScriptManager = asm.GetType("System.Web.UI.ScriptManager");
1040                                                                if (typScriptManager != null) _HasMsAjax = true;
1041                                                        }
1042                                                        catch { }
1043                                                        break;
1044                                                }
1045                                        }
1046                                }
1047
1048                                return _HasMsAjax ?? false;
1049                        }
1050                }
1051
1052                #endregion
1053
1054                #region Default Constructor
1055
1056                public CKEditorControl()
1057                {
1058                        base.TextMode = TextBoxMode.MultiLine;
1059                }
1060
1061                public override void Focus()
1062                {
1063                        base.Focus();
1064                        this.config.startupFocus = true;
1065                }
1066                #endregion
1067
1068                #region Override Method
1069                private string timestamp = "?t=C6HH5UF";
1070                protected override void OnPreRender(EventArgs e)
1071                {
1072                        base.OnPreRender(e);
1073                        this.RegisterStartupScript(this.GetType(), "CKEDITOR_BASEPATH", string.Format("window.CKEDITOR_BASEPATH = '{0}/';\n", (this.CKEditorJSFile.StartsWith("~") ? this.ResolveUrl(this.BasePath) : this.BasePath)), true);
1074                        this.RegisterStartupScript(this.GetType(), "ckeditor", "<script src=\"" + (this.CKEditorJSFile.StartsWith("~") ? this.ResolveUrl(this.CKEditorJSFile) : this.CKEditorJSFile) + timestamp + "\" type=\"text/javascript\"></script>", false);
1075                        string scriptInit = string.Empty;
1076                        string doPostBackScript = string.Empty;
1077                        if (this.AutoPostBack) doPostBackScript = string.Format(@"CKEDITOR.instances['{0}'].on('blur', function() {{if(this.checkDirty()){{javascript:setTimeout('__doPostBack(\'{0}\',\'\')',0); }}}});", this.ClientID);
1078                       
1079                        // Sys.Application.add_load does not work on browsers != IE
1080                        // http://msdn.microsoft.com/en-us/library/bb386417.aspx
1081                        // Check _dev/msajax.js for an uncompressed version (available in CKEditor.Net downloaded from SVN).
1082                        scriptInit += @"var CKEditor_Controls=[],CKEditor_Init=[];function CKEditor_TextBoxEncode(d,e){var f;if(typeof CKEDITOR=='undefined'||typeof CKEDITOR.instances[d]=='undefined'){f=document.getElementById(d);if(f)f.value=f.value.replace(/</g,'&lt;').replace(/>/g,'&gt;');}else{var g=CKEDITOR.instances[d];if(e&&(typeof Page_BlockSubmit=='undefined'||!Page_BlockSubmit)){g.destroy();f=document.getElementById(d);if(f)f.style.visibility='hidden';}else g.updateElement();}};(function(){if(typeof CKEDITOR!='undefined'){var d=document.getElementById('#this.ClientID#');if(d)d.style.visibility='hidden';}var e=function(){var f=CKEditor_Controls,g=CKEditor_Init,h=window.pageLoad,i=function(){for(var j=f.length;j--;){var k=document.getElementById(f[j]);if(k&&k.value&&(k.value.indexOf('<')==-1||k.value.indexOf('>')==-1))k.value=k.value.replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');}if(typeof CKEDITOR!='undefined')for(var j=0;j<g.length;j++)g[j].call(this);};window.pageLoad=function(j,k){if(k.get_isPartialLoad())setTimeout(i,0);if(h&&typeof h=='function')h.call(this,j,k);};if(typeof Page_ClientValidate=='function'&&typeof CKEDITOR!='undefined')Page_ClientValidate=CKEDITOR.tools.override(Page_ClientValidate,function(j){return function(){for(var k in CKEDITOR.instances){if(document.getElementById(k))CKEDITOR.instances[k].updateElement();}return j.apply(this,arguments);};});setTimeout(i,0);};if(typeof Sys!='undefined'&&typeof Sys.Application!='undefined')Sys.Application.add_load(e);if(window.addEventListener)window.addEventListener('load',e,false);else if(window.attachEvent)window.attachEvent('onload',e);})();";
1083                        scriptInit = scriptInit.Replace("#this.ClientID#", this.ClientID);
1084                        this.RegisterStartupScript(this.GetType(), "CKEditorForNet", scriptInit, true);
1085                        this.RegisterStartupScript(this.GetType(), this.ClientID + @"_addControl", string.Format(@"CKEditor_Controls.push('{0}');
1086", this.ClientID), true);
1087                        string script = string.Empty;
1088                        if (this.config.CKEditorEventHandler != null)
1089                                foreach (object[] item in this.config.CKEditorEventHandler)
1090                                {
1091                                        script += string.Format(@"CKEditor_Init.push(function(){{CKEDITOR.on('{0}',{1});}});
1092", item[0], item[1]);
1093                                }
1094                        if (this.config.protectedSource != null && this.config.protectedSource.Length > 0)
1095                        {
1096                                string proSour = string.Empty;
1097                                foreach (string item in this.config.protectedSource)
1098                                        proSour += @"
1099ckeditor.config.protectedSource.push( " + item + " );";
1100                                script += string.Format(@"CKEditor_Init.push(function(){{if(typeof CKEDITOR.instances['{0}']!='undefined' || !document.getElementById('{0}')) return;var ckeditor = CKEDITOR.replace('{0}',{1}); {2} {3}}});
1101", this.ClientID, prepareJSON(), proSour, doPostBackScript);
1102                        }
1103                        else
1104                                script += string.Format(@"CKEditor_Init.push(function(){{if(typeof CKEDITOR.instances['{0}']!='undefined' || !document.getElementById('{0}')) return;CKEDITOR.replace('{0}',{1}); {2}}});
1105", this.ClientID, prepareJSON(), doPostBackScript);
1106
1107                        bool isInUpdatePanel = false;
1108                        Control con = this.Parent;
1109                        if (updatePanel != null)
1110                                while (con != null)
1111                                {
1112                                        if (con.GetType() == updatePanel)
1113                                        {
1114                                                isInUpdatePanel = true;
1115                                                break;
1116                                        }
1117                                        con = con.Parent;
1118                                }
1119                        this.RegisterOnSubmitStatement(this.GetType(), "aspintegrator_Postback" + this.ClientID, string.Format("CKEditor_TextBoxEncode('{0}', {1}); ", this.ClientID, isInUpdatePanel ? 1 : 0));
1120                        this.RegisterStartupScript(this.GetType(), "aspintegratorInitial_" + this.ClientID, script, true);
1121                        //if (isChanged) OnTextChanged(e);
1122                }
1123
1124                protected override void OnLoad(EventArgs e)
1125                {
1126                        base.OnLoad(e);
1127                        if (ViewState["CKEditorConfig"] != null)
1128                                this.config = (CKEditorConfig)ViewState["CKEditorConfig"];
1129                        else
1130                                this.config = new CKEditorConfig(this.BasePath.StartsWith("~") ? this.ResolveUrl(this.BasePath) : this.BasePath);
1131                }
1132
1133        protected override void OnTextChanged(EventArgs e)
1134        {
1135            if (isChanged)
1136            {
1137                base.OnTextChanged(e);
1138                if (TextChanged != null)
1139                    TextChanged(this, e);
1140            }
1141        }
1142
1143                #endregion
1144
1145                #region Private Method
1146
1147                private string prepareJSON()
1148                {
1149                        return JSONSerializer.ToJavaScriptObjectNotation(this.config);
1150                }
1151
1152                #endregion
1153
1154                #region IPostBackDataHandler
1155
1156                bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection)
1157                {
1158                        if (this.config.htmlEncodeOutput)
1159                        {
1160                                string postedValue = HttpUtility.HtmlDecode(postCollection[postDataKey]);
1161                                if (this.Text != postedValue)
1162                                {
1163                                        isChanged = true;
1164                                        this.Text = postedValue;
1165                                        return true;
1166                                }
1167                        }
1168                        return false;
1169                }
1170
1171                void IPostBackDataHandler.RaisePostDataChangedEvent() 
1172        {
1173            OnTextChanged(EventArgs.Empty);
1174        }
1175
1176                #endregion
1177        }
1178
1179   
1180
1181        public class CKEditorControlDesigner : System.Web.UI.Design.ControlDesigner
1182        {
1183                public CKEditorControlDesigner()
1184                {
1185                }
1186
1187                public override string GetDesignTimeHtml()
1188                {
1189                        CKEditorControl control = (CKEditorControl)Component;
1190                        return String.Format(CultureInfo.InvariantCulture,
1191                                "<table width=\"{0}\" height=\"{1}\" bgcolor=\"#f5f5f5\" bordercolor=\"#c7c7c7\" cellpadding=\"0\" cellspacing=\"0\" border=\"1\"><tr><td valign=\"middle\" align=\"center\"><h3>CKEditor ASP.NET Control - <em>'{2}'</em></h3></td></tr></table>",
1192                                control.Width.Value == 0 ? "100%" : control.Width.ToString(),
1193                                control.Height,
1194                                control.ID);
1195                }
1196        }
1197}
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy