source upload
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,28 @@
|
||||
/// test Mustache libraries: native SynMustache vs JavaScript/SpiderMonkey
|
||||
program TestMustache;
|
||||
|
||||
{
|
||||
-------------------------------------------------------------------------
|
||||
Download the SpiderMonkey library at https://synopse.info/files/synsm.7z
|
||||
and put mozjs-24.dll and libnspr4.dll files with your TestMustache.exe
|
||||
-------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// first line of uses clause must be {$I SynDprUses.inc}
|
||||
uses
|
||||
{$I SynDprUses.inc}
|
||||
Forms,
|
||||
{$ifdef FPC}
|
||||
Interfaces,
|
||||
{$endif}
|
||||
TestMustacheUnit in 'TestMustacheUnit.pas' {MainForm};
|
||||
|
||||
{$ifndef FPC}
|
||||
{$R *.res}
|
||||
{$endif}
|
||||
|
||||
begin
|
||||
Application.Initialize;
|
||||
Application.CreateForm(TMainForm, MainForm);
|
||||
Application.Run;
|
||||
end.
|
Binary file not shown.
@@ -0,0 +1,178 @@
|
||||
object MainForm: TMainForm
|
||||
Left = 174
|
||||
Top = 123
|
||||
Width = 1023
|
||||
Height = 552
|
||||
Caption =
|
||||
' Test Mustache libraries: native SynMustache vs JavaScript/Spide' +
|
||||
'rMonkey'
|
||||
Color = clBtnFace
|
||||
Constraints.MinHeight = 400
|
||||
Constraints.MinWidth = 980
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -11
|
||||
Font.Name = 'Tahoma'
|
||||
Font.Style = []
|
||||
OldCreateOrder = False
|
||||
Position = poScreenCenter
|
||||
OnDestroy = FormDestroy
|
||||
OnShow = FormShow
|
||||
DesignSize = (
|
||||
1007
|
||||
514)
|
||||
PixelsPerInch = 96
|
||||
TextHeight = 13
|
||||
object lblTemplate: TLabel
|
||||
Left = 16
|
||||
Top = 8
|
||||
Width = 44
|
||||
Height = 13
|
||||
Caption = 'Template'
|
||||
end
|
||||
object lblContext: TLabel
|
||||
Left = 16
|
||||
Top = 264
|
||||
Width = 39
|
||||
Height = 13
|
||||
Caption = 'Context'
|
||||
end
|
||||
object lblIteration: TLabel
|
||||
Left = 584
|
||||
Top = 40
|
||||
Width = 102
|
||||
Height = 13
|
||||
Caption = 'Number of iterations:'
|
||||
end
|
||||
object mmoTemplate: TMemo
|
||||
Left = 8
|
||||
Top = 24
|
||||
Width = 537
|
||||
Height = 233
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -11
|
||||
Font.Name = 'Consolas'
|
||||
Font.Style = []
|
||||
Lines.Strings = (
|
||||
|
||||
'{{! taken from http://boilingplastic.com/using-mustache-template' +
|
||||
's-for-javascript-practical-examples}}'
|
||||
''
|
||||
'<h2>Example 6 : Recursively binding data to templates</h2>'
|
||||
''
|
||||
' <h3>Organization Structure</h3>'
|
||||
' {{> person}}'
|
||||
''
|
||||
'{{<person}}'
|
||||
' <div>'
|
||||
' <b>{{name}}</b> ({{title}})'
|
||||
' <div style='#39'padding-left: 15px; padding-top: 5px;'#39'>'
|
||||
' {{#manages}}'
|
||||
' {{>person}}'
|
||||
' {{/manages}}'
|
||||
' </div>'
|
||||
' </div> '
|
||||
'{{/person}}')
|
||||
ParentFont = False
|
||||
ScrollBars = ssVertical
|
||||
TabOrder = 0
|
||||
WordWrap = False
|
||||
end
|
||||
object mmoContext: TMemo
|
||||
Left = 8
|
||||
Top = 280
|
||||
Width = 537
|
||||
Height = 226
|
||||
Anchors = [akLeft, akTop, akBottom]
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -11
|
||||
Font.Name = 'Consolas'
|
||||
Font.Style = []
|
||||
Lines.Strings = (
|
||||
' { title : "President", name : "Perry President", manages : ['
|
||||
' { title : "CTO", name : "Janet TechOff", manages : ['
|
||||
|
||||
' { title : "Web Architect", name : "Hari Archie", man' +
|
||||
'ages : ['
|
||||
|
||||
' { title : "Senior Developer", name : "Brenda Sen' +
|
||||
'ior", manages : []},'
|
||||
|
||||
' { title : "Developer", name : "Roger Develo", ma' +
|
||||
'nages : []},'
|
||||
|
||||
' { title : "Junior Developer", name : "Jerry Juni' +
|
||||
'or", manages : []}'
|
||||
' ]}'
|
||||
' ]}, '
|
||||
' { title : "HRO", name : "Harold HarOff", manages : ['
|
||||
|
||||
' { title : "HR Officer", name : "Susan McHorror", man' +
|
||||
'ages : []},'
|
||||
|
||||
' { title : "HR Auditor", name : "Audrey O'#39'Fae", manag' +
|
||||
'es : []}'
|
||||
' ]}'
|
||||
']}')
|
||||
ParentFont = False
|
||||
ScrollBars = ssVertical
|
||||
TabOrder = 1
|
||||
WordWrap = False
|
||||
end
|
||||
object btnExecSynMustache: TButton
|
||||
Left = 576
|
||||
Top = 64
|
||||
Width = 121
|
||||
Height = 49
|
||||
Caption = 'Render with SynMustache'
|
||||
TabOrder = 2
|
||||
WordWrap = True
|
||||
OnClick = Render
|
||||
end
|
||||
object btnExecSpiderMonkey: TButton
|
||||
Left = 712
|
||||
Top = 64
|
||||
Width = 121
|
||||
Height = 49
|
||||
Caption = 'Render with mustache.js'
|
||||
TabOrder = 3
|
||||
WordWrap = True
|
||||
OnClick = Render
|
||||
end
|
||||
object mmoResult: TMemo
|
||||
Left = 560
|
||||
Top = 128
|
||||
Width = 417
|
||||
Height = 378
|
||||
Anchors = [akLeft, akTop, akRight, akBottom]
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -11
|
||||
Font.Name = 'Consolas'
|
||||
Font.Style = []
|
||||
ParentFont = False
|
||||
ScrollBars = ssVertical
|
||||
TabOrder = 4
|
||||
WordWrap = False
|
||||
end
|
||||
object btnOpenBrowser: TButton
|
||||
Left = 872
|
||||
Top = 102
|
||||
Width = 105
|
||||
Height = 25
|
||||
Anchors = [akTop, akRight]
|
||||
Caption = 'Show in Browser'
|
||||
TabOrder = 5
|
||||
OnClick = btnOpenBrowserClick
|
||||
end
|
||||
object edtIteration: TEdit
|
||||
Left = 691
|
||||
Top = 38
|
||||
Width = 70
|
||||
Height = 21
|
||||
TabOrder = 6
|
||||
Text = '10000'
|
||||
end
|
||||
end
|
@@ -0,0 +1,161 @@
|
||||
unit TestMustacheUnit;
|
||||
|
||||
interface
|
||||
|
||||
{$I Synopse.inc} // define HASINLINE CPU32 CPU64 OWNNORMTOUPPER
|
||||
|
||||
uses
|
||||
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
|
||||
Dialogs, StdCtrls,
|
||||
SynCrtSock,
|
||||
{$ifndef CPU64} // SpiderMonkey library is not available yet in 64 bit
|
||||
SynSM, SynSMAPI,
|
||||
{$endif}
|
||||
SynCommons, SynMustache;
|
||||
|
||||
|
||||
type
|
||||
TMainForm = class(TForm)
|
||||
mmoTemplate: TMemo;
|
||||
lblTemplate: TLabel;
|
||||
mmoContext: TMemo;
|
||||
lblContext: TLabel;
|
||||
btnExecSynMustache: TButton;
|
||||
btnExecSpiderMonkey: TButton;
|
||||
mmoResult: TMemo;
|
||||
btnOpenBrowser: TButton;
|
||||
lblIteration: TLabel;
|
||||
edtIteration: TEdit;
|
||||
procedure Render(Sender: TObject);
|
||||
procedure btnOpenBrowserClick(Sender: TObject);
|
||||
procedure FormDestroy(Sender: TObject);
|
||||
procedure FormShow(Sender: TObject);
|
||||
private
|
||||
{ Private declarations }
|
||||
public
|
||||
{ Public declarations }
|
||||
{$ifndef CPU64} // SpiderMonkey library is not available yet in 64 bit
|
||||
fEngineManager: TSMEngineManager;
|
||||
fEngine: TSMEngine;
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
var
|
||||
MainForm: TMainForm;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
ShellAPI;
|
||||
|
||||
{$R *.dfm}
|
||||
|
||||
{$ifndef FPC}
|
||||
{$R vista.RES} // includes Win10 manifest - use .RES for linux cross-compilation
|
||||
{$endif}
|
||||
|
||||
procedure TMainForm.Render(Sender: TObject);
|
||||
var Template, Context, Result: RawUTF8;
|
||||
data: variant;
|
||||
i,n: Integer;
|
||||
Timer: TPrecisionTimer;
|
||||
SynMustacheTemplate: TSynMustache;
|
||||
{$ifndef CPU64} // SpiderMonkey library is not available yet in 64 bit
|
||||
person: RawUTF8;
|
||||
partial: variant;
|
||||
nn: Variant;
|
||||
{$endif}
|
||||
begin
|
||||
Template := StringToUTF8(mmoTemplate.Lines.Text);
|
||||
Context := StringToUTF8(mmoContext.Lines.Text);
|
||||
data := _JsonFast(Context);
|
||||
n := StrToIntDef(edtIteration.Text,1000);
|
||||
if Sender=btnExecSynMustache then begin
|
||||
SynMustacheTemplate := TSynMustache.Parse(Template);
|
||||
Timer.Start;
|
||||
for i := 1 to n do
|
||||
result := SynMustacheTemplate.Render(data);
|
||||
end else
|
||||
{$ifndef CPU64} // SpiderMonkey library is not available yet in 64 bit
|
||||
if Sender=btnExecSpiderMonkey then begin
|
||||
fEngine.MaybeGarbageCollect;
|
||||
i := PosEx('{{<person}}',Template);
|
||||
if i>0 then begin // extract any inlined partial (should be at the end)
|
||||
person := Copy(Template,i+12,maxInt);
|
||||
SetLength(Template,i-1);
|
||||
i := PosEx('{{/person}}',person);
|
||||
if i>0 then
|
||||
SetLength(person,i-1);
|
||||
partial := _ObjFast(['person',person]);
|
||||
end;
|
||||
fEngine.Global.testMustache(Template, data, partial, 1); //compile template
|
||||
Timer.Start;
|
||||
nn := n;
|
||||
result := VariantToUTF8(fEngine.Global.testMustache(Template, data, partial, nn));
|
||||
// test below slow because of 2 things:
|
||||
// 1) marsalling argumnets between Delphi & JS
|
||||
// 2) we measure "prepare" time
|
||||
// for i := 1 to n do
|
||||
// result := VariantToUTF8(fEngine.Global.Mustache.render(Template, data, partial));
|
||||
end else
|
||||
{$endif}
|
||||
exit;
|
||||
mmoResult.Lines.Text :=
|
||||
Format('Rendered %d times in %s (%d/sec):'#13#10#13#10'%s',
|
||||
[n,Timer.Stop,Timer.PerSec(n),result]);
|
||||
FileFromString(Result,ChangeFileExt(ExeVersion.ProgramFileName,'.html'));
|
||||
end;
|
||||
|
||||
procedure TMainForm.btnOpenBrowserClick(Sender: TObject);
|
||||
begin
|
||||
ShellExecute(0,'open',Pointer(ChangeFileExt(ExeVersion.ProgramFileName,'.html')),nil,nil,SW_SHOWNORMAL);
|
||||
end;
|
||||
|
||||
procedure TMainForm.FormShow(Sender: TObject);
|
||||
{$ifdef CPU64} // SpiderMonkey library is not available yet in 64 bit
|
||||
begin
|
||||
btnExecSpiderMonkey.Hide;
|
||||
end;
|
||||
{$else}
|
||||
const
|
||||
testMustacheFunc =
|
||||
'function testMustache(template, data, partial, iterCount){ ' +
|
||||
' var result = ""; ' +
|
||||
' for(var i=0; i<iterCount; i++){ ' +
|
||||
' result = Mustache.render(template, data, partial) ' +
|
||||
' }' +
|
||||
' return result; ' +
|
||||
'}'#10'1;';
|
||||
|
||||
var mustacheFN: TFileName;
|
||||
mSource: SynUnicode;
|
||||
mustache: RawByteString;
|
||||
i: integer;
|
||||
begin
|
||||
fEngineManager := TSMEngineManager.Create;
|
||||
fEngine := fEngineManager.ThreadSafeEngine;
|
||||
mustacheFN := ExeVersion.ProgramFilePath + 'js\mustache.js';
|
||||
mSource := AnyTextFileToSynUnicode(mustacheFN);
|
||||
if mSource='' then begin
|
||||
mustache := TWinINet.Get('https://github.com/janl/mustache.js/raw/master/mustache.js');
|
||||
if PosEx('return send(result);',mustache)=0 then begin
|
||||
i := PosEx('send(result);',mustache);
|
||||
if i>0 then
|
||||
insert('return ',mustache,i); // fix syntax error in official libary! :)
|
||||
end;
|
||||
FileFromString(mustache,mustacheFN);
|
||||
mSource := SynUnicode(mustache);
|
||||
end;
|
||||
fEngine.Evaluate(mSource,'mustache.js');
|
||||
fEngine.Evaluate(testMustacheFunc,'testMustacheFunc.js');
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
procedure TMainForm.FormDestroy(Sender: TObject);
|
||||
begin
|
||||
{$ifndef CPU64} // SpiderMonkey library is not available yet in 64 bit
|
||||
fEngineManager.Free;
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
end.
|
@@ -0,0 +1,28 @@
|
||||
/// test JavaScript execution using the SpiderMonkey library
|
||||
program TestSynSM;
|
||||
|
||||
{
|
||||
-------------------------------------------------------------------------
|
||||
Download the SpiderMonkey library at https://synopse.info/files/synsm.7z
|
||||
and put mozjs-24.dll and libnspr4.dll files with your TestSynSM.exe
|
||||
-------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
{$APPTYPE CONSOLE}
|
||||
|
||||
{$ifdef WIN64}
|
||||
begin
|
||||
writeln('SpiderMonkey is not handled in 64 bit mode yet');
|
||||
|
||||
{$else}
|
||||
// first line of uses clause must be {$I SynDprUses.inc}
|
||||
uses
|
||||
{$I SynDprUses.inc}
|
||||
SynSMSelfTest in 'SynSMSelfTest.pas';
|
||||
|
||||
begin
|
||||
SynSMConsoleTests;
|
||||
{$endif WIN64}
|
||||
end.
|
||||
|
||||
|
@@ -0,0 +1 @@
|
||||
var a=1
|
@@ -0,0 +1 @@
|
||||
var a=1
|
Reference in New Issue
Block a user