{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.

The Original Code is: IntrawebPatch.pas, released on 2012-01-17

The Initial Developer of the Original Code is Alexandre C. Machado
All Rights Reserved.

Notes:
  Requires modified version of unit RtlVclOptimize.pas by Andreas Hausladen

History:
  Version 1.0 (2012-01-17)
    - Initial version
-------------------------------------------------------------------------------}

interface

uses
  SysUtils, IWBaseHTMLControl;

type
  TIWBaseHTMLControlHack = class
  public
    class function TextToHTML(const AText: string; const
      AConvertEOLs: Boolean; const AConvertSpaces: Boolean): string;
    class function TextToJSStringLiteral(const AText: string): string;
  end;

implementation

uses
  IWApplication, RtlVclOptimize;
  
class function TIWBaseHTMLControlHack.TextToHTML(const AText: string; const
  AConvertEOLs: Boolean; const AConvertSpaces: Boolean): string;
var
  Sp, Rp: PChar;
  xIsCallBack: Boolean;
begin
  xIsCallBack := GGetWebApplicationThreadVar.IsCallBack;
  SetLength(Result, Length(AText) * 10);
  Sp := PChar(AText);
  Rp := PChar(Result);
  while Sp^ <> #0 do
  begin
    case Sp^ of
      '&':
        begin
          FormatBuf(Rp^, 5, '&amp;', 5, []);
          Inc(Rp, 4);
        end;
      '<',
        '>':
        begin
          if Sp^ = '<' then
            FormatBuf(Rp^, 4, '&lt;', 4, [])
          else
            FormatBuf(Rp^, 4, '&gt;', 4, []);
          Inc(Rp, 3);
        end;
      '"':
        begin
          FormatBuf(Rp^, 6, '&quot;', 6, []);
          Inc(Rp, 5);
        end;
      '''':
        begin
          FormatBuf(Rp^, 5, '&#39;', 5, []);
          Inc(Rp, 4);
        end;
      '\':
        begin
          FormatBuf(Rp^, 5, '&#92;', 5, []);
          Inc(Rp, 4);
        end;
      #10:
        if AConvertEOLs then
        begin
          FormatBuf(Rp^, 4, '<br>', 4, []);
          Inc(Rp, 3);
        end
        else
          Rp^ := Sp^;
      #13:
        if AConvertEOLs then
        begin
          Dec(Rp);
        end
        else
          Rp^ := Sp^;
      #32:
        if AConvertSpaces then
        begin
          if xIsCallBack then
          begin
            FormatBuf(Rp^, 10, '&amp;nbsp;', 10, []);
            Inc(Rp, 9);
          end else
          begin
            FormatBuf(Rp^, 6, '&nbsp;', 6, []);
            Inc(Rp, 5);
          end;
        end
        else
          Rp^ := Sp^;
    else
      Rp^ := Sp^
    end;
    Inc(Rp);
    Inc(Sp);
  end;
  SetLength(Result, Rp - PChar(Result));
end;

class function TIWBaseHTMLControlHack.TextToJSStringLiteral(const AText: string): string;
var
  Sp, Rp: PChar;
begin
  SetLength(Result, Length(AText) * 2);
  Sp := PChar(AText);
  Rp := PChar(Result);
  while Sp^ <> #0 do
  begin
    case Sp^ of
      '\':
        begin
          FormatBuf(Rp^, 2, '\\', 2, []);
          Inc(Rp, 1);
        end;
      '<':
        begin
          FormatBuf(Rp^, 2, '\<', 2, []);
          Inc(Rp, 1);
        end;
      '>':
        begin
          FormatBuf(Rp^, 2, '\>', 2, []);
          Inc(Rp, 1);
        end;
      '"':
        begin
          FormatBuf(Rp^, 2, '\"', 2, []);
          Inc(Rp, 1);
        end;
      '''':
        begin
          FormatBuf(Rp^, 2, '\''', 2, []);
          Inc(Rp, 1);
        end;
      #10:
        begin
          FormatBuf(Rp^, 2, '\n', 2, []);
          Inc(Rp, 1);
        end;
      #13:
        begin
          Dec(Rp);
        end;
    else
      Rp^ := Sp^
    end;
    Inc(Rp);
    Inc(Sp);
  end;
  SetLength(Result, Rp - PChar(Result));
end;

initialization
  CodeRedirect(@TIWBaseHTMLControl.TextToHTML, @TIWBaseHTMLControlHack.TextToHTML);
  CodeRedirect(@TIWBaseHTMLControl.TextToJSStringLiteral, @TIWBaseHTMLControlHack.TextToJSStringLiteral);

end.


