{***************************************************************************}
{ TMS IntraWeb Component Pack Pro                                           }
{ for Delphi & C++Builder                                                   }
{                                                                           }
{ written by TMS Software                                                   }
{            copyright © 2002 - 2014                                        }
{            Email : info@tmssoftware.com                                   }
{            Web : http://www.tmssoftware.com                               }
{                                                                           }
{ The source code is given as is. The author is not responsible             }
{ for any possible damage done due to the use of this code.                 }
{ The component can be freely used in any application. The complete         }
{ source code remains property of the author and may not be distributed,    }
{ published, given or sold in any form as such. No parts of the source      }
{ code can be included in any other component or application without        }
{ written authorization of the author.                                      }
{***************************************************************************}
unit IWHTMLEdit;

{$I TMSDEFS.INC}

interface
{$R tmsiwhtmled.res}

uses
  Controls, Windows, Graphics, IWPicCntnr,
  {$IFDEF DELPHI6_LVL}
  Types,
  {$ENDIF}
  Classes,
  IWControl, IWTypes, SysUtils, IWHTMLTag,
  IWCompEdit, IWCompLabel, IWCompCheckbox,
  IWTMSBase, IWTMSImg, IWFont,IWRenderContext, IWColor
  {$IFDEF TMSIW121}
  ,IWCompExtCtrls
  {$ELSE}
  ,IWExtCtrls
  {$ENDIF}
  ;

type

  TTIWComboboxes = class(TPersistent)
  private
    FOwner: TComponent;
    FBackColors: Boolean;
    FParagraph: Boolean;
    FFontNames: Boolean;
    FFontSizes: Boolean;
    FFontColors: Boolean;
    procedure SetBackColors(const Value: Boolean);    
    procedure SetParagraph(const Value: Boolean);
    procedure SetFontNames(const Value: Boolean);
    procedure SetFontSizes(const Value: Boolean);
    procedure SetFontColors(const Value: Boolean);
  public
    constructor Create(AOwner: TComponent);
    destructor Destroy; override;
  published
    property BackColors: Boolean read FBackColors write SetBackColors;
    property Paragraph: Boolean read FParagraph write SetParagraph;
    property FontNames: Boolean read FFontNames write SetFontNames;
    property FontSizes: Boolean read FFontSizes write SetFontSizes;
    property FontColors: Boolean read FFontColors write SetFontColors;
  end;

  TTIWHTMLEdHints = class(TPersistent)
  private
    FOwner: TComponent;
    FBold: string;
    FItalic: string;
    FUnderline: string;
    FStrike: string;
    FSubscript: string;
    FSuperscript: string;
    FLeft: string;
    FCenter: string;
    FRight: string;
    FUnorderedList: string;
    FOrderedList: string;
    FIndent: string;
    FUnIndent: string;
    FCut: string;
    FCopy: string;
    FPaste: string;
    FNew: string;
    FLink: string;
    FInsertImage : string;
    FInsertHorizontalRule: string;
    procedure SetBold(const Value: string);
    procedure SetItalic(const Value: string);
    procedure SetUnderline(const Value: string);
    procedure SetStrike(const Value: string);
    procedure SetSubscript(const Value: string);
    procedure SetSuperscript(const Value: string);
    procedure SetLeft(const Value: string);
    procedure SetCenter(const Value: string);
    procedure SetRight(const Value: string);
    procedure SetUnorderedList(const Value: string);
    procedure SetOrderedList(const Value: string);
    procedure SetIndent(const Value: string);
    procedure SetUnindent(const Value: string);
    procedure SetCut(const Value: string);
    procedure SetCopy(const Value: string);
    procedure SetNew(const Value: string);
    procedure SetPaste(const Value: string);
    procedure SetLink(const Value: string);
    procedure SetInsertImage(const Value : string);
    procedure SetInsertHorizontalRule(const Value : string);
  public
    constructor Create(AOwner: TComponent);
    destructor Destroy; override;
  published
    property Bold: string read FBold write SetBold;
    property Center: string read FCenter write SetCenter;
    property Copy: string read FCopy write SetCopy;
    property Cut: string read FCut write SetCut;
    property Indent: string read FIndent write SetIndent;
    property InsertImage : string read FInsertImage write SetInsertImage;
    property InsertHorizontalRule : string read FInsertHorizontalRule write SetInsertHorizontalRule;
    property Italic: string read FItalic write SetItalic;
    property Left: string read FLeft write SetLeft;
    property Link: string read FLink write SetLink;
    property New: string read FNew write SetNew;
    property OrderedList: string read FOrderedList write SetOrderedList;
    property Paste: string read FPaste write SetPaste;
    property Right: string read FRight write SetRight;
    property Strike: string read FStrike write SetStrike;
    property Subscript: string read FSubscript write SetSubscript;
    property Superscript: string read FSuperscript write SetSuperscript;
    property Underline: string read FUnderline write SetUnderline;
    property Unindent: string read FUnindent write SetUnindent;
    property UnorderedList: string read FUnorderedList write SetUnorderedList;
  end;

  TTIWHTMLEdGlyphs = class(TPersistent)
  private
    FOwner: TComponent;
    FBold: Boolean;
    FItalic: Boolean;
    FUnderline: Boolean;
    FStrike: Boolean;
    FSubscript: Boolean;
    FSuperscript: Boolean;
    FLeft: Boolean;
    FCenter: Boolean;
    FRight: Boolean;
    FUnorderedList: Boolean;
    FOrderedList: Boolean;
    FIndent: Boolean;
    FUnIndent: Boolean;
    FCut: Boolean;
    FCopy: Boolean;
    FPaste: Boolean;
    FNew: Boolean;
    FLink: Boolean;
    FInsertImage : Boolean;
    FInsertHorizontalRule: Boolean;
    procedure SetBold(const Value: Boolean);
    procedure SetItalic(const Value: Boolean);
    procedure SetUnderline(const Value: Boolean);
    procedure SetStrike(const Value: Boolean);
    procedure SetSubscript(const Value: Boolean);
    procedure SetSuperscript(const Value: Boolean);
    procedure SetLeft(const Value: Boolean);
    procedure SetCenter(const Value: Boolean);
    procedure SetRight(const Value: Boolean);
    procedure SetUnorderedList(const Value: Boolean);
    procedure SetOrderedList(const Value: Boolean);
    procedure SetIndent(const Value: Boolean);
    procedure SetUnindent(const Value: Boolean);
    procedure SetCut(const Value: Boolean);
    procedure SetCopy(const Value: Boolean);
    procedure SetNew(const Value: Boolean);
    procedure SetPaste(const Value: Boolean);
    procedure SetLink(const Value: Boolean);
    procedure SetInsertImage(const Value : Boolean);
    procedure SetInsertHorizontalRule(const Value : Boolean);
  public
    constructor Create(AOwner: TComponent);
    destructor Destroy; override;
  published
    property Bold: Boolean read FBold write SetBold default true;
    property Center: Boolean read FCenter write SetCenter default true;
    property Copy: Boolean read FCopy write SetCopy default true;
    property Cut: Boolean read FCut write SetCut default true;
    property Indent: Boolean read FIndent write SetIndent default true;
    property InsertImage : Boolean read FInsertImage write SetInsertImage default true;
    property InsertHorizontalRule : Boolean read FInsertHorizontalRule write SetInsertHorizontalRule default true;
    property Italic: Boolean read FItalic write SetItalic default true;
    property Left: Boolean read FLeft write SetLeft default true;
    property Link: Boolean read FLink write SetLink default true;
    property New: Boolean read FNew write SetNew default true;
    property OrderedList: Boolean read FOrderedList write SetOrderedList default true;
    property Paste: Boolean read FPaste write SetPaste default true;
    property Right: Boolean read FRight write SetRight default true;
    property Strike: Boolean read FStrike write SetStrike default true;
    property Subscript: Boolean read FSubscript write SetSubscript default true;
    property Superscript: Boolean read FSuperscript write SetSuperscript default true;
    property Underline: Boolean read FUnderline write SetUnderline default true;
    property Unindent: Boolean read FUnindent write SetUnindent default true;
    property UnorderedList: Boolean read FUnorderedList write SetUnorderedList default true;
  end;

  TTIWScrollType = (stAuto, stShow, stHidden);

  TTIWCustomHTMLEdit = class(TIWControl)
  private
    FBackground: TColor;
    FComboboxes: TTIWComboboxes;
    FContentEditable: boolean;
    FFont: TIWFont;
    FFontList: TStrings;
    FGlyphs: TTIWHTMLEdGlyphs;
    FHints: TTIWHTMLEdHints;
    FLines: TStrings;
    FShowToolBar: Boolean;
    FShowComboboxes: Boolean;
    FViewHTML: boolean;
    FScroll: TTIWScrollType;
    procedure HTMLEditFontChanged(Sender: TObject);
    procedure SetBackground(const AValue: TColor);
    procedure SetComboboxes(const AValue: TTIWComboboxes);
    procedure SetContentEditable(const AValue: boolean);
    procedure SetFont(const AValue: TIWFont);
    procedure SetFontList(const AValue: TStrings);
    procedure SetGlyphs(const Value: TTIWHTMLEdGlyphs);
    procedure SetHints(const Value: TTIWHTMLEdHints);
    procedure SetLines(const AValue: TStrings);
    procedure SetShowToolBar(const AValue: Boolean);
    procedure SetShowComboboxes(const AValue: Boolean);
  protected
    procedure SetValue(const AValue: string); override;
    function HTMLClr(color: TColor): string;
    function GetFonts(fonts: TStrings): string;
  public
    procedure IWPaint; override;
    function RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag; override;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    property BackgroundColor: TColor read FBackground write SetBackground;
    property ComboBoxes: TTIWComboboxes read FComboboxes write SetComboboxes;
    property ContentEditable: Boolean read FContentEditable write SetContentEditable;
    property Font: TIWFont read FFont write SetFont;
    property FontList: TStrings read FFontList write SetFontList;
    property Glyphs: TTIWHTMLEdGlyphs read FGlyphs write SetGlyphs;
    property Hints: TTIWHTMLEdHints read FHints write SetHints;
    property Lines: TStrings read FLines write SetLines;
    property ShowComboBoxes: Boolean read FShowComboboxes write SetShowComboboxes default true;
    property ShowToolBar: Boolean read FShowToolBar write SetShowToolbar default true;
    property ViewHtml: boolean read FViewHTML write FViewHTML;
    property Scroll: TTIWScrollType read FScroll write FScroll default stAuto;
  end;

  TTIWHTMLEdit = class(TTIWCustomHTMLEdit)
  published
    property BackgroundColor;
    property ComboBoxes;
    property ContentEditable;
    property Font;
    property FontList;
    property Glyphs;
    property Hints;
    property Lines;
    property ShowComboBoxes;
    property ShowToolBar;
    property Scroll;
  end;

implementation

uses
  ImgList, ShellAPI, CommCtrl,
  IWApplication, IWServerControllerBase, TMSIWStrings, TMSIWSystem,
  IWAppForm, IWBaseHTMLControl, IWMarkupLanguageTag;

{ TTIWHTMLEdGlyphs }

constructor TTIWHTMLEdGlyphs.Create(AOwner: TComponent);
begin
  inherited Create;
  FOwner := AOwner;
  FBold := true;
  FItalic := true;
  FUnderline := true;
  FStrike := true;
  FSubscript := true;
  FSuperscript := true;
  FLeft := true;
  FCenter := true;
  FRight := true;
  FUnorderedList := true;
  FOrderedList := true;
  FIndent := true;
  FUnindent := true;
  FCut := true;
  FCopy := true;
  FPaste := true;
  FNew := true;
  FLink := true;
  FInsertImage := true;
  FInsertHorizontalRule := true;
end;

destructor TTIWHTMLEdGlyphs.Destroy;
begin
  inherited;
end;

procedure TTIWHTMLEdGlyphs.SetBold(const Value: Boolean);
begin
  FBold := Value;
end;

procedure TTIWHTMLEdGlyphs.SetCenter(const Value: Boolean);
begin
  FCenter := Value;
end;

procedure TTIWHTMLEdGlyphs.SetCopy(const Value: Boolean);
begin
  FCopy := Value;
end;

procedure TTIWHTMLEdGlyphs.SetCut(const Value: Boolean);
begin
  FCut := Value;
end;

procedure TTIWHTMLEdGlyphs.SetIndent(const Value: Boolean);
begin
  FIndent := Value;
end;

procedure TTIWHTMLEdGlyphs.SetInsertImage(const Value : Boolean);
begin
  FInsertImage := Value;
end;

procedure TTIWHTMLEdGlyphs.SetInsertHorizontalRule(const Value : Boolean);
begin
  FInsertHorizontalRule := Value;
end;

procedure TTIWHTMLEdGlyphs.SetItalic(const Value: Boolean);
begin
  FItalic := Value;
end;
                                  
procedure TTIWHTMLEdGlyphs.SetLeft(const Value: Boolean);
begin
  FLeft := Value;
end;

procedure TTIWHTMLEdGlyphs.SetLink(const Value: Boolean);
begin
  FLink := Value;
end;

procedure TTIWHTMLEdGlyphs.SetNew(const Value: Boolean);
begin
  FNew := Value;
end;

procedure TTIWHTMLEdGlyphs.SetOrderedList(const Value: Boolean);
begin
  FOrderedList := Value;
end;

procedure TTIWHTMLEdGlyphs.SetPaste(const Value: Boolean);
begin
  FPaste := Value;
end;

procedure TTIWHTMLEdGlyphs.SetRight(const Value: Boolean);
begin
  FRight := Value;
end;

procedure TTIWHTMLEdGlyphs.SetStrike(const Value: Boolean);
begin
  FStrike := Value;
end;

procedure TTIWHTMLEdGlyphs.SetSubscript(const Value: Boolean);
begin
  FSubscript := Value;
end;

procedure TTIWHTMLEdGlyphs.SetSuperscript(const Value: Boolean);
begin
  FSuperscript := Value;
end;

procedure TTIWHTMLEdGlyphs.SetUnderline(const Value: Boolean);
begin
  FUnderline := Value;
end;

procedure TTIWHTMLEdGlyphs.SetUnindent(const Value: Boolean);
begin
  FUnindent := Value;
end;

procedure TTIWHTMLEdGlyphs.SetUnorderedList(const Value: Boolean);
begin
  FUnorderedList := Value;
end;

{ TTIWCustomHTMLEdit }

constructor TTIWCustomHTMLEdit.Create(AOwner: TComponent);
begin
  inherited;
  FComboboxes := TTIWComboboxes.Create(Self);
  FGlyphs := TTIWHTMLEdGlyphs.Create(Self);
  FHints := TTIWHTMLEdHints.Create(Self);
  FLines := TStringList.Create;
  FFontList := TStringList.Create;
  {$IFNDEF TMSIW121}
  SetRenderSize(true);
  {$ENDIF}
//  FRenderSize := True;
//  FSupportsInput := True;
//  FSupportsSubmit := True;
//  FEditable := True;
//  FDesignMode := True;
  FFont := TIWFont.Create;
  FFont.OnChange := HTMLEditFontChanged;
  Font.Color := clBlack;
  FBackground := clWhite;
  Font.FontName := 'Arial';
  Font.Size := 12;
  FLines.Add('This is an example of a HTML editor.');
  FViewHtml := false;
  FContentEditable := true;
  FFontList.Add('Arial');
  FFontList.Add('Comic Sans MS');
  FFontList.Add('Courier New');
  FFontList.Add('Lucida Console');
  FFontList.Add('Tahoma');
  FFontList.Add('Times New Roman');
  FFontList.Add('Trebuchet MS');
  FFontList.Add('Verdana');
  Height := 400;
  Width := 600;
  FShowToolBar := true;
  FShowComboBoxes := true;
  FScroll := stAuto;
end;

destructor TTIWCustomHTMLEdit.Destroy;
begin
  FComboboxes.Free;
  FGlyphs.Free;
  FHints.Free;
  FreeAndNil(FFont);
  FreeAndNil(FLines);
  FreeAndNil(FFontList);
  inherited;
end;

procedure TTIWCustomHTMLEdit.HTMLEditFontChanged(Sender: TObject);
begin
  Invalidate;
end;

procedure TTIWCustomHTMLEdit.SetShowToolBar(const AValue: Boolean);
begin
  FShowToolBar := AValue;
  Invalidate;
end;

procedure TTIWCustomHTMLEdit.SetShowComboboxes(const AValue: Boolean);
begin
  FShowComboboxes := AValue;
  Invalidate;
end;

procedure TTIWCustomHTMLEdit.SetContentEditable(const AValue: boolean);
begin
  FContentEditable := AValue;
end;

procedure TTIWCustomHTMLEdit.IWPaint;
var
  r: TRect;
  down,i: integer;
begin
  Canvas.Font.Name := Font.FontName;
  Canvas.Font.Size := Font.Size;
  Canvas.Font.Color := Font.Color;
  Canvas.Font.Style := Font.Style;

  with Canvas do
  begin
    r := GetClientRect;
    Brush.Color := FBackground;
    Rectangle(r);
    if (FShowToolBar) then
    begin
      TextOut(r.Left+5, r.Top+10,'Toolbar');
      r.top := r.top + 40;
    end;
    MoveTo(r.Left,r.Top);
    LineTo(r.Right,r.Top);
    if (FShowComboboxes) then
    begin
      TextOut(r.Left+5, r.Top+10,'Comboboxes');
      r.top := r.top + 40;
    end;
    MoveTo(r.Left,r.Top);
    LineTo(r.Right,r.Top);
    TextOut(r.Left+5, r.Top+10,'HTMLEditor:');
    if (FLines.Count > 0) then
    begin
      down := 50;
      i := 0;
      while (i < FLines.Count) do
      begin
        TextOut(r.Left + 25, r.Top + down, FLines.Strings[i]);
        down := down + 20;
        i := i + 1;
      end;
    end;
  end;
end;

function TTIWCustomHTMLEdit.HTMLClr(color: TColor):string;
begin
  Result := ColorToRGBString(color);
end;

function TTIWCustomHTMLEdit.GetFonts(fonts: TStrings): string;
var
  i: integer;
begin
  for i:=0 to fonts.Count-1 do
  begin
    if not (fonts.Strings[i] = '') then
      Result := Result + '<option value="' + fonts.Strings[i] + '">' + fonts.Strings[i] + '</option>';
  end;
end;

procedure TTIWCustomHTMLEdit.SetLines(const AValue:TStrings);
begin
  FLines.Assign(AValue);
  Invalidate;
end;

procedure TTIWCustomHTMLEdit.SetFont(const AValue: TIWFont);
begin
  FFont.Assign(AValue);
  Invalidate;
end;

procedure TTIWCustomHTMLEdit.SetFontList(const AValue: TStrings);
begin
  FFontList.Assign(AValue);
end;

procedure TTIWCustomHtmlEdit.SetComboboxes(const Avalue: TTIWComboboxes);
begin
  FComboboxes.Assign(AValue);
end;

procedure TTIWCustomHTMLEdit.SetBackground(const AValue: TColor);
begin
  FBackground := AValue;
  Invalidate;
end;

procedure TTIWCustomHTMLEdit.SetValue(const AValue:string);
begin
  //FLines.Text := StringReplace(AValue,'<BR>',#13,[rfReplaceAll,rfIgnoreCase]);
  //FLines.Text := StringReplace(AValue,'<BR>','',[rfReplaceAll,rfIgnoreCase]);
  FLines.Text := AValue;

end;

function JSAdapt(s:string):string;
var
  i: integer;
begin
  Result := '';
  for i := 1 to length(s) do
  begin
    case s[i] of
    #39:Result := Result + '\'#39;
    '"':Result := Result + '\"';
    '\':Result := Result + '\\'
    else
      Result := Result + s[i];
    end

    {
    if s[i] = #39 then
      Result := Result + '\'#39
    else if s[i] = '"' then
           Result := Result + '\"'
         else
           Result := Result + s[i];
    }
  end;
end;

function TTIWCustomHTMLEdit.RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag;
var
  html: string;
  ImgName, PathPrefix: string;
  initialText,memotext,nline,HeightText, ceditable, dMode: string;
  BoldB, BoldE, ItalicB, ItalicE, UnderlineB, UnderlineE, StrikeB, StrikeE: string;
  i: integer;
  addURLBase: bool;
begin
  ImgName := '';

  initialText := '';
  for i := 1 to Flines.Count do
  begin
    nline := JSAdapt(Lines.Strings[i - 1]);

//    if (Pos('\',nline) > 0) then
//      outputdebugstring(pchar(nline));

    InitialText := InitialText + nline;
    if (i < FLines.Count) and (Pos('</P>',nline) = 0) and
       (Pos('<BR>',nline) = 0) and (Pos('</LI>',nline) = 0) and (Pos('<LI>',nline) = 0) and (Pos('<UL>',nline) = 0) and (Pos('<OL>',nline) = 0) and (Pos('<HR',nline) = 0) and (Pos('</H>',nline) = 0) then
      InitialText := InitialText + '<BR>';
  end;

  TIWComponent40Context(AContext).AddToInitProc('FindElem(''' + HTMLName + ''').value="'+ InitialText + '";');

  //Define height of textarea, depending on the visibility of the comboboxes and the toolbar.
  if ((ShowToolBar) and (ShowComboBoxes)) then
    HeightText := IntToStr(Height - 44)
  else
  begin
    if ((ShowToolBar) or (ShowComboBoxes)) then
      HeightText := IntToStr(Height - 22)
    else
      HeightText := IntToStr(Height);
  end;

  //If the property ContentEditable is false, the textarea isn't editable.  Default is true.
  if (ContentEditable) then
  begin
    ceditable := 'True';
    dMode := 'On';
  end
  else
  begin
    ceditable := 'False';
    dMode := 'Off';
  end;


  html := GetResourceText('TMSIWHTMLED');

  html := StringReplace(html, '<#BGCOLOR>', HTMLClr(BackgroundColor),[rfReplaceAll, rfIgnoreCase]);
  html := StringReplace(html, '<#FONTSIZE>', IntToStr(Font.Size),[rfReplaceAll, rfIgnoreCase]);
  html := StringReplace(html, '<#FONTNAME>', Font.FontName ,[rfReplaceAll, rfIgnoreCase]);
  html := StringReplace(html, '<#FONTCOLOR>', HTMLClr(Font.Color),[rfReplaceAll, rfIgnoreCase]);
  html := StringReplace(html, '<#FONTSTYLE>', '',[rfReplaceAll, rfIgnoreCase]);
//			html := StringReplace(html, '<#WIDTHTEXT>', IntToStr(Width) , [rfReplaceAll, rfIgnoreCase]);
//			html := StringReplace(html, '<#HEIGHTTEXT>', HeightText,[rfReplaceAll, rfIgnoreCase]);
  html := StringReplace(html, '<#WIDTHTEXT>', '100%', [rfReplaceAll, rfIgnoreCase]);
  html := StringReplace(html, '<#HEIGHTTEXT>', '100%',[rfReplaceAll, rfIgnoreCase]);
  html := StringReplace(html, 'GSubmitter.elements[''<#COMPNAME>''].value', 'FindElem(''' + HTMLName + ''').value', [rfReplaceAll, rfIgnoreCase]);
  html := StringReplace(html, '<#BORDERCOLOR>', '#000000',[rfReplaceAll, rfIgnoreCase]);
  html := StringReplace(html, '<#CONTENTEDITABLE>', ceditable,[rfReplaceAll, rfIgnoreCase]);
  html := StringReplace(html, '<#DESIGNMODE>', dMode,[rfReplaceAll, rfIgnoreCase]);

  html := StringReplace(html, '<#COMPNAME>', HTMLName,[rfReplaceAll, rfIgnoreCase]);

  //Set the checkbox "View HTML" visible or not.
  if (ViewHtml) then
    html := StringReplace(html, '<#DISPLAYHTML>', 'true',[rfReplaceAll, rfIgnoreCase])
  else
    html := StringReplace(html, '<#DISPLAYHTML>', 'false',[rfReplaceAll, rfIgnoreCase]);

  memotext := '';
  for i := 1 to lines.count do
  begin
    //nline := JSAdapt(Lines.Strings[i - 1]);
    nline := Lines.Strings[i - 1];
    if (i < FLines.Count) and (Pos('</P>',nline) = 0) and (Pos('<BR>',nline) = 0)
      and (Pos('<LI>',nline) = 0) and (Pos('</LI>',nline) = 0) and (Pos('</H>',nline) = 0) and (Pos('<HR',nline) = 0) and (Pos('<OL>',nline) = 0) and (Pos('<UL>',nline) = 0) then
//       fix: remove extra line feeds
//       memotext := memotext + ' ' + nline + '<BR>'
       memotext := memotext + ' ' + nline
    else
      memotext := memotext + ' ' + nline;
  end;

  			//Start html-code to render the Editor.
			html := html + #13'<span ID="' + HTMLName + 'myedit">'#13;
      html := html + '<body unselectable="on">'#13;
//			html := html + '<table height="100%" cellspacing="0" cellpadding="0" width="' + IntToStr(Width) + '" border="0">'#13;
			html := html + '<table style="height:100%;width:100%;" cellspacing="0" cellpadding="0" border="0">'#13;
//			html := html + '<table cellspacing="0" cellpadding="0" border="0">'#13;
			html := html + '<tbody>'#13;

      //render Toolbar
			//If property ShowToolBar is true and at least one glyph is visible --> show toolbar.
			if ((ShowToolBar) and
      ((Glyphs.Bold) or (Glyphs.Italic) or (Glyphs.Underline) or (Glyphs.Strike)
      or (Glyphs.Subscript) or (Glyphs.Superscript) or (Glyphs.Left) or (Glyphs.Center)
      or (Glyphs.Right) or (Glyphs.UnorderedList) or (Glyphs.OrderedList)
      or (Glyphs.Indent) or (Glyphs.UnIndent) or (Glyphs.Cut) or (Glyphs.Copy)
      or (Glyphs.Paste) or (Glyphs.Link) or (Glyphs.InsertImage)
      or (Glyphs.InsertHorizontalRule))) then
			begin
				html := html + '<tr style="HEIGHT: 22px">'#13;
				html := html + '<td>'#13;
				html := html + '<table cellspacing="0" cellpadding="2" border="0">'#13;
				html := html + '<tbody>'#13;
				html := html + '<tr>'#13;

			//generate the glyphs where visibility is true

      {$IFDEF TMSIW14}
      addURLBase := true;
      {$ELSE}
        {$IFDEF TMSIW11}
        addURLBase := false;
        {$ELSE}
        addURLBase := true;
        {$ENDIF}
      {$ENDIF}

      if addURLBase then
        PathPrefix := AContext.WebApplication.AppURLBase+'/Files/'
      else
        PathPrefix := 'Files/';

      // Some old code, often for compatibilty reasons produces // inline. For example
      // the old AppBaseURL didnt suffix with /, and users appended /Files/.
      // With the new URLs this creates //. As a work around we strip them out.
      PathPrefix := StringReplace(PathPrefix, '//', '/', [rfReplaceAll]);

//				if (Glyphs.Clear)
//					html := html + '<td><img id="' + HTMLName + 'i0" class="' + HTMLName + 'ToolBarButton" onclick="' + HTMLName + 'ClearArea()" title="New" src="/Files/iwnew.gif"></td>'#13;
      if (Glyphs.Bold) then
        html := html + '<td><img id="' + HTMLName + 'i1" class="'  + HTMLName + 'ToolBarButton" onclick="' + HTMLName
        + 'OnClickToolBarButton(''bold'')" title="' + Hints.Bold + '" src="'+PathPrefix+'iwbold.gif"></td>'#13;
      if (Glyphs.Italic) then
        html := html + '<td><img id="' + HTMLName + 'i2" class="' + HTMLName + 'ToolBarButton" onclick="' + HTMLName
        + 'OnClickToolBarButton(''italic'')" title="' + Hints.Italic + '" src="'+PathPrefix+'iwItalic.gif"></td>'#13;
      if (Glyphs.Underline)  then
        html := html + '<td><img id="' + HTMLName + 'i3" class="' + HTMLName + 'ToolBarButton" onclick="' + HTMLName
        + 'OnClickToolBarButton(''underline'')" title="' + Hints.Underline +'" src="'+PathPrefix+'iwUnderline.gif"></td>'#13;
      if (Glyphs.Strike) then
        html := html + '<td><img id="' + HTMLName + 'i4" class="' + HTMLName + 'ToolBarButton" onclick="' + HTMLName
        + 'OnClickToolBarButton(''strikethrough'')" title="' + Hints.Strike + '" src="'+PathPrefix+'iwstrikeout.gif"></td>'#13;
      if (Glyphs.Subscript) then
        html := html + '<td><img id="' + HTMLName + 'i18" class="' + HTMLName + 'ToolBarButton" onclick="' + HTMLName
        + 'OnClickToolBarButton(''subscript'')" title="' + Hints.Subscript + '" src="'+PathPrefix+'subscript.gif"></td>'#13;
      if (Glyphs.Superscript) then
        html := html + '<td><img id="' + HTMLName + 'i19" class="' + HTMLName + 'ToolBarButton" onclick="' + HTMLName
        + 'OnClickToolBarButton(''superscript'')" title="' + Hints.Superscript + '" src="'+PathPrefix+'superscript.gif"></td>'#13;
      if (Glyphs.Left) then
        html := html + '<td><img id="' + HTMLName + 'i5" class="' + HTMLName + 'ToolBarButton" onclick="' + HTMLName
        + 'OnClickToolBarButton(''justifyleft'')" title="' + Hints.Left + '" src="'+PathPrefix+'iwalignleft.gif"></td>'#13;
      if (Glyphs.Center) then
        html := html + '<td><img id="' + HTMLName + 'i6" class="' + HTMLName + 'ToolBarButton" onclick="' + HTMLName
        + 'OnClickToolBarButton(''justifycenter'')" title="' + Hints.Center + '" src="'+PathPrefix+'iwaligncentre.gif"></td>'#13;
      if (Glyphs.Right) then
        html := html + '<td><img id="' + HTMLName + 'i7" class="' + HTMLName + 'ToolBarButton" onclick="' + HTMLName
        + 'OnClickToolBarButton(''justifyright'')" title="' + Hints.Right + '" src="'+PathPrefix+'iwalignright.gif"></td>'#13;
      if (Glyphs.UnorderedList) then
        html := html + '<td><img id="' + HTMLName + 'i8" class="' + HTMLName + 'ToolBarButton" onclick="' + HTMLName
        + 'OnClickToolBarButton(''insertunorderedList'')" title="' + Hints.UnorderedList + '" src="'+PathPrefix+'iwbullets.gif"></td>'#13;
      if (Glyphs.OrderedList) then
        html := html + '<td><img id="' + HTMLName + 'i9" class="' + HTMLName + 'ToolBarButton" onclick="' + HTMLName
        + 'OnClickToolBarButton(''insertorderedList'')" title="' + Hints.OrderedList + '" src="'+PathPrefix+'iwnumberedlist.gif"></td>'#13;
      if (Glyphs.Indent) then
        html := html + '<td><img id="' + HTMLName + 'i10" class="' + HTMLName + 'ToolBarButton" onclick="' + HTMLName
        + 'OnClickToolBarButton(''indent'')" title="' + Hints.Indent + '" src="'+PathPrefix+'iwindentincrease.gif"></td>'#13;
      if (Glyphs.UnIndent) then
        html := html + '<td><img id="' + HTMLName + 'i11" class="' + HTMLName + 'ToolBarButton"  onclick="' + HTMLName
        + 'OnClickToolBarButton(''outdent'')" title="' + Hints.Unindent + '" src="'+PathPrefix+'iwindentdecrease.gif"></td>'#13;
      if (Glyphs.Cut) then
        html := html + '<td><img id="' + HTMLName + 'i12" class="' + HTMLName + 'ToolBarButton" onclick="' + HTMLName
        + 'OnClickToolBarButton(''cut'')" title="' + Hints.Cut + '" src="'+PathPrefix+'iwcut.gif"></td>'#13;
      if (Glyphs.Copy) then
        html := html + '<td><img id="' + HTMLName + 'i13" class="' + HTMLName + 'ToolBarButton" onclick="' + HTMLName
        + 'OnClickToolBarButton(''copy'')" title="' + Hints.Copy + '" src="'+PathPrefix+'iwcopy.gif"></td>'#13;
      if (Glyphs.Paste) then
        html := html + '<td><img id="' + HTMLName + 'i14" class="' + HTMLName + 'ToolBarButton" onclick="' + HTMLName
        + 'OnClickToolBarButton(''paste'')" title="' + Hints.Paste + '" src="'+PathPrefix+'iwpaste.gif"></td>'#13;
      if (Glyphs.Link) then
        html := html + '<td><img id="' + HTMLName + 'i15" class="' + HTMLName + 'ToolBarButton" onclick="' + HTMLName
        + 'OnClickToolBarButton(''CreateLink'')" title="' + Hints.Link + '" src="'+PathPrefix+'iwlink.gif"></td>'#13;
      if (Glyphs.InsertImage) then
        html := html + '<td><img id="' + HTMLName + 'i16" class="' + HTMLName + 'ToolBarButton" onclick="' + HTMLName
        + 'OnClickToolBarButton(''InsertImage'')" title="' + Hints.InsertImage + '" src="'+PathPrefix+'iwimg.gif"></td>'#13;
      if (Glyphs.InsertHorizontalRule) then
        html := html + '<td><img id="' + HTMLName + 'i17" class="' + HTMLName + 'ToolBarButton" onclick="' + HTMLName
        + 'OnClickToolBarButton(''InsertHorizontalRule'')" title="' + Hints.InsertHorizontalRule + '" src="'+PathPrefix+'iwruler.gif"></td>'#13;
//        if (Glyphs.Preformat) then
//          html := html + '<td>#13<img id="' + HTMLName + 'i18" class="'  + HTMLName + 'ToolBarButton" onclick="' + HTMLName + 'OnClickToolBarButton("pre")" title="PRE" src="' + Glyphs.Folder + "/iwpre.gif">#13</td>'#13;

				html := html + '</tr>'#13;
				html := html + '</tbody>'#13;
				html := html + '</table>'#13;
				html := html + '</td>'#13;
				html := html + '</tr>'#13;
			end;
      //end render Toolbar

      //render Comboboxes
			//If property ShowComboboxes is true and at least one Comboboxes is visible --> show comboboxes
			if ((ShowComboBoxes) and
      ((ComboBoxes.Paragraph) or (ComboBoxes.FontNames) or (ComboBoxes.FontSizes) or (ComboBoxes.FontColors))) then
			begin
				html := html + '<tr style="HEIGHT: 22px">'#13;
				html := html + '<td>'#13;
				html := html + '<table cellspacing="0">'#13;
				html := html + '<tbody>'#13;
				html := html + '<tr>'#13;

				if (ComboBoxes.Paragraph)  then
				begin
					html := html + '<td>'#13;
					html := html + '<select id="' + HTMLName + 'formattingList" onchange="' + HTMLName + 'OnSelectedIndexChangedFormattingList(this)">'#13;
					html := html + '<option value="<body>" selected="selected">Normal</option>'#13;
					html := html + '<option value="<h1>">Heading 1</option>'#13;
					html := html + '<option value="<h2>">Heading 2</option>'#13;
					html := html + '<option value="<h3>">Heading 3</option>'#13;
					html := html + '<option value="<h4>">Heading 4</option>'#13;
					html := html + '<option value="<h5>">Heading 5</option>'#13;
					html := html + '<option value="<h6>">Heading 6</option>'#13;
//					html := html + '<option value="<pre>">Formatted</option>'#13;
					html := html + '</select>'#13;
					html := html + '</td>'#13;
				end;

				if (ComboBoxes.FontNames) then
				begin
					html := html + '<td>'#13;
					html := html + '<select id="' + HTMLName + 'fontFaceList" onchange="' + HTMLName + 'OnSelectedIndexChangedFontFaceList(this)">'#13;
					html := html + GetFonts(FFontList);
					html := html + '</select>'#13;
					html := html + '</td>'#13;
				end;

				if (ComboBoxes.FontSizes) then
				begin
					html := html + '<td>'#13;
					html := html + '<select id="' + HTMLName + 'fontSizeList" onchange="' + HTMLName + 'OnSelectedIndexChangedFontSizeList(this)">'#13;
					html := html + '<option value="1">1</option>'#13;
					html := html + '<option value="2">2</option>'#13;
					html := html + '<option value="3" selected="selected">3</option>'#13;
					html := html + '<option value="4">4</option>'#13;
					html := html + '<option value="5">5</option>'#13;
					html := html + '<option value="6">6</option>'#13;
					html := html + '</select>'#13;
					html := html + '</td>'#13;
				end;

				if (ComboBoxes.FontColors) then
				begin
					html := html + '<td>'#13;
					html := html + '<select id="' + HTMLName + 'fontColorList" onchange="' + HTMLName + 'OnSelectedIndexChangedFontColorList(this)">'#13;
					html := html + '<option value="black" style="color:Black" selected="selected">Black</option>'#13;
					html := html + '<option value="navy" style="color:Navy">Navy</option>'#13;
					html := html + '<option value="green" style="color:Green">Green</option>'#13;
					html := html + '<option value="blue" style="color:Blue">Blue</option>'#13;
					html := html + '<option value="cyan" style="color:Cyan">Cyan</option>'#13;
					html := html + '<option value="magenta" style="color:Magenta">Magenta</option>'#13;
					html := html + '<option value="red" style="color:Red">Red</option>'#13;
					html := html + '<option value="yellow" style="color:Yellow">Yellow</option>'#13;
					html := html + '<option value="white" style="color:Black">White</option>'#13;
					html := html + '<option value="silver" style="color:Silver">Silver</option>'#13;
					html := html + '<option value="teal" style="color:Teal">Teal</option>'#13;
					html := html + '</select>'#13;
					html := html + '</td>'#13;                          
				end;

				if (ComboBoxes.BackColors) then
				begin
					html := html + '<td>'#13;
					html := html + '<select id="' + HTMLName + 'backColorList" onchange="' + HTMLName + 'OnSelectedIndexChangedBackColorList(this)">'#13;
					html := html + '<option value="black" style="color:white;background-color:Black">Black</option>'#13;
					html := html + '<option value="navy" style="color:white;background-color:Navy">Navy</option>'#13;
					html := html + '<option value="green" style="background-color:Green">Green</option>'#13;
					html := html + '<option value="blue" style="background-color:Blue">Blue</option>'#13;
					html := html + '<option value="cyan" style="background-color:Cyan">Cyan</option>'#13;
					html := html + '<option value="magenta" style="background-color:Magenta">Magenta</option>'#13;
					html := html + '<option value="red" style="background-color:Red">Red</option>'#13;
					html := html + '<option value="yellow" style="background-color:Yellow">Yellow</option>'#13;
					html := html + '<option value="white" style="background-color:White" selected="selected">White</option>'#13;
					html := html + '<option value="silver" style="background-color:Silver">Silver</option>'#13;
					html := html + '<option value="teal" style="background-color:Teal">Teal</option>'#13;
					html := html + '</select>'#13;
					html := html + '</td>'#13;
        end;

				if (ViewHtml) then
				begin
					html := html + '<td align="right" width="100%">'#13;
					html := html + '<input name="viewHtmlCheckBox" id="' + HTMLName + 'viewHtmlCheckBox" onclick="' + HTMLName + 'OnClickShowHtmlCheckBox(this)" type="checkbox"/>'#13;
					html := html + '<label unselectable="on">View HTML Source</label>'#13;
					html := html + '</td>'#13;
				end;

				html := html + '</tr>'#13;
				html := html + '</tbody>'#13;
				html := html + '</table>'#13;
				html := html + '</td>'#13;
				html := html + '</tr>'#13;
			end
			else
			begin
				if (ViewHtml) then
				begin
					html := html + '<tr style="HEIGHT: 22px">'#13;
					html := html + '<td>'#13;
					html := html + '<table cellspacing="0" cellpadding="2" width="100%" border="0">'#13;
					html := html + '<tbody>'#13;
					html := html + '<tr>'#13;
					html := html + '<td align="right" width="100%">'#13;
					html := html + '<input name="viewHtmlCheckBox" id="' + HTMLName + 'viewHtmlCheckBox" onclick="' + HTMLName + 'OnClickShowHtmlCheckBox(this)" type="checkbox"/>'#13;
					html := html + '<label unselectable="on">View HTML Source</label>'#13;
					html := html + '</td>'#13;
					html := html + '</tr>'#13;
					html := html + '</tbody>'#13;
					html := html + '</table>'#13;
					html := html + '</td>'#13;
					html := html + '</tr>'#13;
				end
			end;
      //End Render Comboboxes

      //  html := StringReplace(html, '<#FONTS>',GetFonts(FFontList), [rfReplaceAll, rfIgnoreCase]);

			//html := html + '<tr style="HEIGHT:' + HeightText + 'px;';
      html := html + '<tr style="';
      if not (BackgroundColor = clNone) then
      begin
  			html := html + 'background-color:'+HTMLClr(BackgroundColor) + '">'#13;
        html := html + '<td bgcolor="'+HTMLClr(BackgroundColor)+'" style="width:100%;height:' + IntToStr(Height - 50) + 'px;">'#13;
      end
      else
      begin
  			html := html + '">'#13;
        html := html + '<td style="width:100%;height:' + IntToStr(Height - 50) + 'px;">'#13;
      end;


//			 html := html + '<textarea style="width:'+IntToStr(Width)+'px;height:20px;display:none;" id="' + HTMLName + 'editorTextArea">'
			 html := html + '<textarea style="display:none;" id="' + HTMLName + 'editorTextArea">'
				  + StrikeB + BoldB + ItalicB + UnderlineB
				  + memotext
				  + UnderlineE + ItalicE + BoldE + StrikeE
				  + '</textarea>'#13;

//    html := html + '<iframe onBlur="' + HTMLName + 'OnBlurEditorDiv();" allowtransparency="true" style="filter:chroma(color=#FFFFFF);border:1;height:' + HeightText + 'px;width:'+ IntToStr(Width) +'" class="' + HTMLName + 'editorText" id="' + HTMLName + 'editorDiv">'
    html := html + '<iframe onBlur="' + HTMLName + 'OnBlurEditorDiv();" '
//    + 'allowtransparency="true" style="filter:chroma(color=#FFFFFF);border:1;padding:0;width:100%;height:100%" '
    + 'allowtransparency="true" style="filter:chroma(color=#FFFFFF);border:1px solid black;padding:0;" '
    + 'class="' + HTMLName + 'editorText" id="' + HTMLName + 'editorDiv">'
    + '</iframe>'#13;

  html := html + '</td>'#13;
  html := html + '</tr>'#13;
  html := html + '</tbody>'#13;
  html := html + '</table>'#13;
  html := html + '</body>'#13;
  html := html + '</span>'#13;
  html := html + '</body>'#13;

  Result := TIWHTMLTag.CreateTag('DIV');

  Result.Contents.AddText(html);
  with Result.Contents.AddTag('INPUT') do
  begin
    AddStringParam('TYPE','hidden');
    AddStringParam('NAME',HTMLName);
    AddStringParam('ID',HTMLName+'_INPUT');
  end;

  html :=	HTMLName + 'Initialize();';
  TIWComponent40Context(AContext).AddToInitProc(html + EOL);
end;

procedure TTIWCustomHTMLEdit.SetGlyphs(const Value: TTIWHTMLEdGlyphs);
begin
  FGlyphs.Assign(Value);
end;

procedure TTIWCustomHTMLEdit.SetHints(const Value: TTIWHTMLEdHints);
begin
  FHints.Assign(Value);
end;

{ TTIWComboboxes }

constructor TTIWComboboxes.Create(AOwner: TComponent);
begin
  inherited Create;
  FOwner := AOwner;
  FBackColors := true;
  FParagraph := true;
  FFontNames := true;
  FFontSizes := true;
  FFontColors := true;
end;

destructor TTIWComboboxes.Destroy;
begin
  inherited;
end;

procedure TTIWComboboxes.SetBackColors(const Value: Boolean);
begin
  FBackColors := Value;
end;

procedure TTIWComboboxes.SetFontColors(const Value: Boolean);
begin
  FFontColors := Value;
end;

procedure TTIWComboboxes.SetFontNames(const Value: Boolean);
begin
  FFontNames := Value;
end;

procedure TTIWComboboxes.SetFontSizes(const Value: Boolean);
begin
  FFontSizes := Value;
end;

procedure TTIWComboboxes.SetParagraph(const Value: Boolean);
begin
  FParagraph := Value;
end;

{ TTIWHTMLEdHints }

constructor TTIWHTMLEdHints.Create(AOwner: TComponent);
begin
  FOwner := AOwner;
  FBold := 'Bold';
  FItalic := 'Italic';
  FUnderline := 'Underline';
  FStrike := 'Striketrough';
  FSubscript := 'Subscript';
  FSuperscript := 'Superscript';
  FLeft := 'Left';
  FCenter := 'Center';
  FRight := 'Right';
  FUnorderedList := 'UnorderedList';
  FOrderedList := 'OrderedList';
  FIndent := 'Indent';
  FUnindent := 'Unindent';
  FCut := 'Cut';
  FCopy := 'Copy';
  FPaste := 'Paste';
  FNew := 'New';
  FLink := 'Create Link';
  FInsertImage := 'Insert Image';
  FInsertHorizontalRule := 'Insert Horizontal Rule';
end;

destructor TTIWHTMLEdHints.Destroy;
begin
  inherited;
end;

procedure TTIWHTMLEdHints.SetBold(const Value: string);
begin
  FBold := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);
end;

procedure TTIWHTMLEdHints.SetCenter(const Value: string);
begin
  FCenter := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);;
end;

procedure TTIWHTMLEdHints.SetCopy(const Value: string);
begin
  FCopy := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);
end;

procedure TTIWHTMLEdHints.SetCut(const Value: string);
begin
  FCut := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);
end;

procedure TTIWHTMLEdHints.SetIndent(const Value: string);
begin
  FIndent := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);
end;

procedure TTIWHTMLEdHints.SetInsertHorizontalRule(const Value: string);
begin
  FInsertHorizontalRule := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);
end;

procedure TTIWHTMLEdHints.SetInsertImage(const Value: string);
begin
  FInsertImage := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);
end;

procedure TTIWHTMLEdHints.SetItalic(const Value: string);
begin
  FItalic := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);
end;

procedure TTIWHTMLEdHints.SetLeft(const Value: string);
begin
  FLeft := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);
end;

procedure TTIWHTMLEdHints.SetLink(const Value: string);
begin
  FLink := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);
end;

procedure TTIWHTMLEdHints.SetNew(const Value: string);
begin
  FNew := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);
end;

procedure TTIWHTMLEdHints.SetOrderedList(const Value: string);
begin
  FOrderedList := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);
end;

procedure TTIWHTMLEdHints.SetPaste(const Value: string);
begin
  FPaste := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);
end;

procedure TTIWHTMLEdHints.SetRight(const Value: string);
begin
  FRight := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);
end;

procedure TTIWHTMLEdHints.SetStrike(const Value: string);
begin
  FStrike := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);
end;

procedure TTIWHTMLEdHints.SetSubscript(const Value: string);
begin
  FSubScript := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);
end;

procedure TTIWHTMLEdHints.SetSuperscript(const Value: string);
begin
  FSuperScript := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);
end;

procedure TTIWHTMLEdHints.SetUnderline(const Value: string);
begin
  FUnderLine := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);
end;

procedure TTIWHTMLEdHints.SetUnindent(const Value: string);
begin
  FUnindent := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);
end;

procedure TTIWHTMLEdHints.SetUnorderedList(const Value: string);
begin
  FUnorderedList := StringReplace(Value, '"', '&quot;', [rfReplaceAll]);
end;

end.
