Browse Source

job: added newoperator and started some base js classes

mattias 3 years ago
parent
commit
f28dbe57cb

+ 1 - 1
demo/wasienv/dom/BrowserDomTest1.lpr

@@ -146,7 +146,7 @@ begin
   FWasiEnv.OnStdOutputWrite:=@DoWrite;
   FWADomBridge:=TJOBBridge.Create(FWasiEnv);
 
-  if FWADomBridge.RegisterGlobalObject(TJSObject(TBird.Create('Root')))<>WasiObjIdBird then
+  if FWADomBridge.RegisterGlobalObject(TJSObject(TBird.Create('Root')))<>JObjIdBird then
     raise Exception.Create('Root TBird wrong number');
 end;
 

+ 10 - 0
demo/wasienv/dom/WasiDomTest1.lpi

@@ -33,6 +33,16 @@
         <IsPartOfProject Value="True"/>
         <UnitName Value="JOB_WAsm"/>
       </Unit>
+      <Unit>
+        <Filename Value="job_web.pas"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="JOB_Web"/>
+      </Unit>
+      <Unit>
+        <Filename Value="job_js.pas"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="JOB_JS"/>
+      </Unit>
     </Units>
   </ProjectOptions>
   <CompilerOptions>

+ 13 - 2
demo/wasienv/dom/WasiDomTest1.lpr

@@ -5,7 +5,7 @@ program WasiDomTest1;
 {$codepage UTF8}
 
 uses
-  SysUtils, JOB_WAsm, JOB_Shared;
+  SysUtils, JOB_WAsm, JOB_Shared, JOB_Web, JOB_JS;
 
 type
 
@@ -76,8 +76,19 @@ var
   Freddy, Alice, aBird: TBird;
   i: Integer;
   JSValue: TJOB_JSValue;
+  JSElem: IJSElement;
+  aDate: IJSDate;
 begin
-  obj:=TJSObject.CreateFromID(WasiObjIdBird);
+  JSElem:=JSDocument.getElementById('playground');
+  writeln('Class=',JSElem._ClassName);
+
+  aDate:=JSDate.Create(2003,2,5,8,47,30,777);
+  u:=aDate.toLocaleDateString;
+  writeln('toLocaleDateString=',u);
+
+  exit;
+
+  obj:=TJSObject.CreateFromID(JObjIdBird);
   obj.WriteJSPropertyUnicodeString('Caption','Root');
   writeln('AAA1 ');
   u:='äbc';

+ 3 - 3
demo/wasienv/dom/index.html

@@ -4,7 +4,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html; charset=utf-8">
   <meta name="viewport" content="width=device-width, initial-scale=1">
-  <title>FPC-Webassembly accesing browser DOM through Pas2JS Demo</title>
+  <title>FPC-Webassembly accessing browser DOM through Pas2JS Demo</title>
   <link href="bulma.min.css" rel="stylesheet">
   <script src="BrowserDomTest1.js"></script>
   <style>
@@ -25,8 +25,8 @@
 </head>
 <body>
   <div class="section py-4">
-    <h1 class="title is-3">Canvas</h1>
-    <div class="box" id="canvases"></div>
+    <h1 class="title is-3">Test Area</h1>
+    <div class="box" id="playground"></div>
   </div>
   <div class="section py-4">
     <h1 class="title is-3">Console output</h1>

+ 69 - 2
demo/wasienv/dom/job_browser.pp

@@ -52,6 +52,39 @@ asm
   return String.fromCharCode.apply(null,a);
 end;
 
+function NewObj(const fn: TJSFunction; const Args: TJSValueDynArray): TJSFunction; assembler;
+asm
+  if (Args == null){
+    return new fn();
+  }
+  var l = Args.length;
+  if (l==0){
+    return new fn();
+  } else if (l==1){
+    return new fn(Args[0]);
+  } else if (l==2){
+    return new fn(Args[0],Args[1]);
+  } else if (l==3){
+    return new fn(Args[0],Args[1],Args[2]);
+  } else if (l==4){
+    return new fn(Args[0],Args[1],Args[2],Args[3]);
+  } else if (l==5){
+    return new fn(Args[0],Args[1],Args[2],Args[3],Args[4]);
+  } else if (l==6){
+    return new fn(Args[0],Args[1],Args[2],Args[3],Args[4],Args[5]);
+  } else if (l==7){
+    return new fn(Args[0],Args[1],Args[2],Args[3],Args[4],Args[5],Args[6]);
+  } else if (l==8){
+    return new fn(Args[0],Args[1],Args[2],Args[3],Args[4],Args[5],Args[6],Args[7]);
+  } else if (l==9){
+    return new fn(Args[0],Args[1],Args[2],Args[3],Args[4],Args[5],Args[6],Args[7],Args[8]);
+  } else if (l==10){
+    return new fn(Args[0],Args[1],Args[2],Args[3],Args[4],Args[5],Args[6],Args[7],Args[8],Args[9]);
+  } else {
+    return null;
+  }
+end;
+
 constructor TJOBBridge.Create(aEnv: TPas2JSWASIEnvironment);
 begin
   Inherited Create(aEnv);
@@ -60,6 +93,22 @@ begin
   FGlobalObjects[-JOBObjIdWindow]:=window;
   FGlobalObjects[-JOBObjIdConsole]:=console;
   FGlobalObjects[-JOBObjIdCaches]:=caches;
+  FGlobalObjects[-JOBObjIdObject]:=TJSObject;
+  FGlobalObjects[-JOBObjIdFunction]:=TJSFunction;
+  FGlobalObjects[-JOBObjIdDate]:=TJSDate;
+  FGlobalObjects[-JOBObjIdString]:=TJSString;
+  FGlobalObjects[-JOBObjIdArray]:=TJSArray;
+  FGlobalObjects[-JOBObjIdArrayBuffer]:=TJSArrayBuffer;
+  FGlobalObjects[-JOBObjIdInt8Array]:=TJSInt8Array;
+  FGlobalObjects[-JOBObjIdUint8Array]:=TJSUint8Array;
+  FGlobalObjects[-JOBObjIdUint8ClampedArray]:=TJSUint8ClampedArray;
+  FGlobalObjects[-JOBObjIdInt16Array]:=TJSInt16Array;
+  FGlobalObjects[-JOBObjIdUint16Array]:=TJSUint16Array;
+  FGlobalObjects[-JOBObjIdInt32Array]:=TJSUint32Array;
+  FGlobalObjects[-JOBObjIdFloat32Array]:=TJSFloat32Array;
+  FGlobalObjects[-JOBObjIdFloat64Array]:=TJSFloat64Array;
+  FGlobalObjects[-JOBObjIdJSON]:=TJSJSON;
+  FGlobalObjects[-JOBObjIdPromise]:=TJSPromise;
   FLocalObjects:=TJSArray.new;
   FFreeLocalIds:=TJSArray.new;
 end;
@@ -149,13 +198,29 @@ begin
         JSResult:=TJSFunction(fn).apply(Obj,Args);
       end;
     end;
-  JOBInvokeGetter:
+  JOBInvokeNew:
+    begin
+      if PropName<>'' then
+        fn:=Obj[PropName]
+      else
+        fn:=Obj;
+      if jstypeof(fn)<>'function' then
+        exit(JOBResult_NotAFunction);
+
+      if ArgsP=0 then
+        JSResult:=NewObj(TJSFunction(fn),nil)
+      else begin
+        Args:=GetInvokeArguments(View,ArgsP);
+        JSResult:=NewObj(TJSFunction(fn),Args)
+      end;
+    end;
+  JOBInvokeGet:
     begin
       if ArgsP>0 then
         exit(JOBResult_WrongArgs);
       JSResult:=Obj[PropName];
     end;
-  JOBInvokeSetter:
+  JOBInvokeSet:
     begin
       JSResult:=Undefined;
       if ArgsP=0 then
@@ -359,6 +424,8 @@ begin
     aType:=View.getUInt8(p);
     inc(p);
     case aType of
+    JOBArgNone:
+      Result[i]:=Undefined;
     JOBArgLongint:
       begin
         Result[i]:=View.getInt32(p,env.IsLittleEndian);

+ 49 - 0
demo/wasienv/dom/job_js.pas

@@ -0,0 +1,49 @@
+unit JOB_JS;
+
+{$mode ObjFPC}{$H+}
+
+interface
+
+uses
+  JOB_Shared, JOB_WAsm;
+
+type
+  IJSDate = interface(IJSObject)
+    ['{F12818EA-542E-488C-A3C5-279E05639E9E}']
+    function toLocaleDateString: UnicodeString; overload; // date in locale timezone, no time
+  end;
+
+  { TJSDate }
+
+  TJSDate = class(TJSObject,IJSDate)
+  public
+    class function Create(aYear: NativeInt; aMonth: NativeInt; aDayOfMonth: NativeInt = 1;
+      TheHours: NativeInt = 0; TheMinutes: NativeInt = 0; TheSeconds: NativeInt = 0;
+      TheMilliseconds: NativeInt = 0): IJSDate;
+    function toLocaleDateString: UnicodeString; overload; // date in locale timezone, no time
+  end;
+
+var
+  JSDate: TJSDate;
+
+implementation
+
+{ TJSDate }
+
+class function TJSDate.Create(aYear: NativeInt; aMonth: NativeInt;
+  aDayOfMonth: NativeInt; TheHours: NativeInt; TheMinutes: NativeInt;
+  TheSeconds: NativeInt; TheMilliseconds: NativeInt): IJSDate;
+begin
+  Result:=JSDate.NewJSObject([aYear,aMonth,aDayOfMonth,TheHours,TheMinutes,TheSeconds,TheMilliseconds],TJSDate) as IJSDate;
+end;
+
+function TJSDate.toLocaleDateString: UnicodeString;
+begin
+  Result:=InvokeJSUnicodeStringResult('toLocaleDateString',[]);
+end;
+
+initialization
+  JSDate:=TJSDate.CreateFromID(JOBObjIdDate);
+
+end.
+

+ 28 - 4
demo/wasienv/dom/job_shared.pp

@@ -71,16 +71,40 @@ const
   JOBArgPointer = 9;
   JOBArgObject = 10; // followed by ObjectID
 
-  JOBInvokeCall = 0;
-  JOBInvokeGetter = 1;
-  JOBInvokeSetter = 2;
+  JOBInvokeCall = 0; // call function
+  JOBInvokeGet = 1; // read property
+  JOBInvokeSet = 2; // set property
+  JOBInvokeNew = 3; // new operator
+
+  JOBInvokeNames: array[0..3] of string = (
+    'Call',
+    'Get',
+    'Set',
+    'New'
+    );
 
   JOBObjIdDocument = -1;
   JOBObjIdWindow = -2;
   JOBObjIdConsole = -3;
   JOBObjIdCaches = -4;
+  JOBObjIdObject = -5;
+  JOBObjIdFunction = -6;
+  JOBObjIdDate = -7;
+  JOBObjIdString = -8;
+  JOBObjIdArray = -9;
+  JOBObjIdArrayBuffer = -10;
+  JOBObjIdInt8Array = -11;
+  JOBObjIdUint8Array = -12;
+  JOBObjIdUint8ClampedArray = -13;
+  JOBObjIdInt16Array = -13;
+  JOBObjIdUint16Array = -14;
+  JOBObjIdInt32Array = -16;
+  JOBObjIdFloat32Array = -17;
+  JOBObjIdFloat64Array = -18;
+  JOBObjIdJSON = -19;
+  JOBObjIdPromise = -20;
 
-  WasiObjIdBird = -5;
+  JObjIdBird = -21;
 
 implementation
 

+ 123 - 43
demo/wasienv/dom/job_wasm.pas

@@ -46,6 +46,8 @@ const
     'Object'
     );
 
+  JOB_Undefined = Pointer(1);
+
 type
 
   { TJOB_JSValue }
@@ -96,7 +98,8 @@ type
 
   TJOBInvokeGetType = (
     jigCall,  // call function
-    jigGetter // read property
+    jigGetter, // read property
+    jigNew // new operator
     );
   TJOBInvokeSetType = (
     jisCall,  // call function
@@ -106,11 +109,34 @@ type
   TJSObject = class;
   TJSObjectClass = class of TJSObject;
 
+  { IJSObject }
+
   IJSObject = interface
-    function GetObjectID: TJOBObjectID;
-    function GetClassName: string;
-    property ObjectID: TJOBObjectID read GetObjectID;
-    property ClassName: string read GetClassName;
+    ['{BE5CDE03-D471-4AB3-8F27-A5EA637416F7}']
+    function GetJSObjectID: TJOBObjectID;
+    function GetPascalClassName: string;
+    procedure InvokeJSNoResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeSetType = jisCall); virtual;
+    function InvokeJSBooleanResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeGetType = jigCall): Boolean; virtual;
+    function InvokeJSDoubleResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeGetType = jigCall): Double; virtual;
+    function InvokeJSUnicodeStringResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeGetType = jigCall): UnicodeString; virtual;
+    function InvokeJSObjectResult(const aName: string; Const Args: Array of const; aResultClass: TJSObjectClass; Invoke: TJOBInvokeGetType = jigCall): TJSObject; virtual;
+    function InvokeJSValueResult(const aName: string; Const Args: Array of const; Invoke: TJOBInvokeGetType = jigCall): TJOB_JSValue; virtual;
+    function InvokeJSUtf8StringResult(const aName: string; Const args: Array of const; Invoke: TJOBInvokeGetType = jigCall): String; virtual;
+    function InvokeJSLongIntResult(const aName: string; Const args: Array of const; Invoke: TJOBInvokeGetType = jigCall): LongInt; virtual;
+    function ReadJSPropertyBoolean(const aName: string): boolean; virtual;
+    function ReadJSPropertyDouble(const aName: string): double; virtual;
+    function ReadJSPropertyUnicodeString(const aName: string): UnicodeString; virtual;
+    function ReadJSPropertyObject(const aName: string; aResultClass: TJSObjectClass): TJSObject; virtual;
+    function ReadJSPropertyUtf8String(const aName: string): string; virtual;
+    function ReadJSPropertyLongInt(const aName: string): LongInt; virtual;
+    function ReadJSPropertyValue(const aName: string): TJOB_JSValue; virtual;
+    procedure WriteJSPropertyBoolean(const aName: string; Value: Boolean); virtual;
+    procedure WriteJSPropertyDouble(const aName: string; Value: Double); virtual;
+    procedure WriteJSPropertyUnicodeString(const aName: string; const Value: UnicodeString); virtual;
+    procedure WriteJSPropertyUtf8String(const aName: string; const Value: String); virtual;
+    procedure WriteJSPropertyObject(const aName: string; Value: TJSObject); virtual;
+    procedure WriteJSPropertyLongInt(const aName: string; Value: LongInt); virtual;
+    function NewJSObject(Const Args: Array of const; aResultClass: TJSObjectClass): TJSObject; virtual;
   end;
 
   { TJOB_JSValueObject }
@@ -128,8 +154,8 @@ type
   private
     FObjectID: TJOBObjectID;
   protected
-    function GetObjectID: TJOBObjectID;
-    function GetClassName: string;
+    function GetJSObjectID: TJOBObjectID;
+    function GetPascalClassName: string;
     function FetchString(Len: NativeInt): UnicodeString;
     function InvokeJSOneResult(const aName: string; Const Args: Array of const;
       const InvokeFunc: TJOBInvokeOneResultFunc; ResultP: PByte; Invoke: TJOBInvokeGetType): TJOBResult;
@@ -156,18 +182,19 @@ type
     function ReadJSPropertyUtf8String(const aName: string): string; virtual;
     function ReadJSPropertyLongInt(const aName: string): LongInt; virtual;
     function ReadJSPropertyValue(const aName: string): TJOB_JSValue; virtual;
-    // ToDo: get JSValue property
     procedure WriteJSPropertyBoolean(const aName: string; Value: Boolean); virtual;
     procedure WriteJSPropertyDouble(const aName: string; Value: Double); virtual;
     procedure WriteJSPropertyUnicodeString(const aName: string; const Value: UnicodeString); virtual;
     procedure WriteJSPropertyUtf8String(const aName: string; const Value: String); virtual;
     procedure WriteJSPropertyObject(const aName: string; Value: TJSObject); virtual;
     procedure WriteJSPropertyLongInt(const aName: string; Value: LongInt); virtual;
+    function NewJSObject(Const Args: Array of const; aResultClass: TJSObjectClass): TJSObject; virtual;
   end;
 
 var
-  JSDocument: TJSObject; // ToDo
+  JSObject: TJSObject;
 
+// imported functions from browser
 function __job_invoke_noresult(
   ObjID: TJOBObjectID;
   NameP: PChar;
@@ -182,7 +209,7 @@ function __job_invoke_boolresult(
   NameLen: longint;
   Invoke: longint;
   ArgP: PByte;
-  ResultP: PByte // bytebool
+  ResultByteBoolP: PByte
 ): TJOBResult; external JOBExportName name JOBFn_InvokeBooleanResult;
 
 function __job_invoke_doubleresult(
@@ -191,7 +218,7 @@ function __job_invoke_doubleresult(
   NameLen: longint;
   Invoke: longint;
   ArgP: PByte;
-  ResultP: PByte // double
+  ResultDoubleP: PByte
 ): TJOBResult; external JOBExportName name JOBFn_InvokeDoubleResult;
 
 function __job_invoke_stringresult(
@@ -200,7 +227,7 @@ function __job_invoke_stringresult(
   NameLen: longint;
   Invoke: longint;
   ArgP: PByte;
-  ResultLenP: PByte // length
+  ResultLenP: PByte // nativeint
 ): TJOBResult; external JOBExportName name JOBFn_InvokeStringResult;
 
 function __job_getstringresult(
@@ -216,7 +243,7 @@ function __job_invoke_objectresult(
   NameLen: longint;
   Invoke: longint;
   ArgP: PByte;
-  ResultP: PByte // nativeint
+  ResultObjIDP: PByte // nativeint
 ): TJOBResult; external JOBExportName name JOBFn_InvokeObjectResult;
 
 function __job_release_object(
@@ -229,7 +256,7 @@ function __job_invoke_jsvalueresult(
   NameLen: longint;
   Invoke: longint;
   ArgP: PByte;
-  ResultP: PByte
+  ResultP: PByte  // various
 ): TJOBResult; external JOBExportName name JOBFn_InvokeJSValueResult;
 
 implementation
@@ -237,11 +264,12 @@ implementation
 const
   InvokeGetToInt: array[TJOBInvokeGetType] of integer = (
     JOBInvokeCall,
-    JOBInvokeGetter
+    JOBInvokeGet,
+    JOBInvokeNew
     );
   InvokeSetToInt: array[TJOBInvokeSetType] of integer = (
     JOBInvokeCall,
-    JOBInvokeSetter
+    JOBInvokeSet
     );
 
 {$IFDEF VerboseJOB}
@@ -273,6 +301,13 @@ begin
     Result:='vt?';
   end;
 end;
+
+function __job_callback(w: NativeInt): boolean;
+begin
+  writeln('__job_callback w=',w);
+  Result:=true;
+end;
+
 {$ENDIF}
 
 { TJOB_JSValue }
@@ -345,17 +380,17 @@ begin
   if Value=nil then
     Result:='nil'
   else
-    Result:='['+IntToStr(Value.ObjectID)+']:'+Value.ClassName;
+    Result:='['+IntToStr(Value.GetJSObjectID)+']:'+Value.GetPascalClassName;
 end;
 
 { TJSObject }
 
-function TJSObject.GetObjectID: TJOBObjectID;
+function TJSObject.GetJSObjectID: TJOBObjectID;
 begin
   Result:=FObjectID;
 end;
 
-function TJSObject.GetClassName: string;
+function TJSObject.GetPascalClassName: string;
 begin
   Result:=ClassName;
 end;
@@ -467,7 +502,14 @@ begin
       end;
     {$endif}
     vtString        : inc(Len,1+SizeOf(NativeInt)+SizeOf(PByte));
-    vtPointer,
+    vtPointer:
+      begin
+        p:=Args[i].VPointer;
+        if p=JOB_Undefined then
+          inc(Len)
+        else
+          inc(Len,1+SizeOf(PByte));
+      end;
     vtPChar         :
       begin
         strlen(Args[i].VPChar);
@@ -485,14 +527,25 @@ begin
       end;
     vtClass         : RaiseNotSupported('class');
     vtPWideChar     : RaiseNotSupported('pwidechar');
-    vtAnsiString    : inc(Len,1+SizeOf(NativeInt)+SizeOf(PByte));
+    vtAnsiString:
+      inc(Len,1+SizeOf(NativeInt)+SizeOf(PByte));
     vtCurrency      : RaiseNotSupported('currency');
     {$ifdef FPC_HAS_FEATURE_VARIANTS}
     vtVariant       : RaiseNotSupported('variant');
     {$endif FPC_HAS_FEATURE_VARIANTS}
-    vtInterface     : RaiseNotSupported('interface');
-    vtWideString    : inc(Len,1+SizeOf(NativeInt)+SizeOf(PByte));
-    vtInt64         :
+    vtInterface:
+      begin
+        p:=Args[i].VInterface;
+        if p=nil then
+          inc(Len,1)
+        else if IInterface(p) is IJSObject then
+          inc(Len,1+sizeof(TJOBObjectID))
+        else
+          RaiseNotSupported('interface');
+      end;
+    vtWideString:
+      inc(Len,1+SizeOf(NativeInt)+SizeOf(PByte));
+    vtInt64:
       begin
         i64:=Args[i].VInt64^;
         if (i64<MinSafeIntDouble) or (i64>MaxSafeIntDouble) then
@@ -503,7 +556,7 @@ begin
           inc(Len,9);
       end;
     vtUnicodeString : inc(Len,1+SizeOf(NativeInt)+SizeOf(PByte));
-    vtQWord         :
+    vtQWord:
       begin
         qw:=Args[i].VQWord^;
         if (qw>MaxSafeIntDouble) then
@@ -523,14 +576,14 @@ begin
   for i:=0 to high(Args) do
   begin
     case Args[i].VType of
-    vtInteger       :
+    vtInteger:
       begin
         p^:=JOBArgLongint;
         inc(p);
         PLongint(p)^:=Args[i].VInteger;
         inc(p,4);
       end;
-    vtBoolean       :
+    vtBoolean:
       begin
         if Args[i].VBoolean then
           p^:=JOBArgTrue
@@ -539,7 +592,7 @@ begin
         inc(p);
       end;
     {$ifndef FPUNONE}
-    vtExtended      :
+    vtExtended:
       begin
         p^:=JOBArgDouble;
         inc(p);
@@ -554,14 +607,14 @@ begin
         PWord(p)^:=ord(Args[i].VChar);
         inc(p,2);
       end;
-    vtWideChar      :
+    vtWideChar:
       begin
         p^:=JOBArgChar;
         inc(p);
         PWord(p)^:=ord(Args[i].VWideChar);
         inc(p,2);
       end;
-    vtString        :
+    vtString:
       begin
         // shortstring
         p^:=JOBArgUTF8String;
@@ -575,12 +628,20 @@ begin
       end;
     vtPointer:
       begin
-        p^:=JOBArgPointer;
-        inc(p);
-        PPointer(p)^:=Args[i].VPointer;
-        inc(p,sizeof(Pointer));
+        h:=Args[i].VPointer;
+        if h=JOB_Undefined then
+        begin
+          p^:=JOBArgNone;
+          inc(p);
+        end
+        else begin
+          p^:=JOBArgPointer;
+          inc(p);
+          PPointer(p)^:=h;
+          inc(p,sizeof(Pointer));
+        end;
       end;
-    vtPChar         :
+    vtPChar:
       begin
         p^:=JOBArgUTF8String;
         inc(p);
@@ -590,7 +651,7 @@ begin
         PPointer(p)^:=h;
         inc(p,sizeof(Pointer));
       end;
-    vtObject        :
+    vtObject:
       begin
         Obj:=Args[i].VObject;
         if Obj=nil then
@@ -600,7 +661,7 @@ begin
         end else begin
           p^:=JOBArgObject;
           inc(p);
-          PNativeInt(p)^:=TJSObject(Args[i].VObject).ObjectID;
+          PNativeInt(p)^:=TJSObject(Obj).ObjectID;
           inc(p,sizeof(NativeInt));
         end;
       end;
@@ -621,8 +682,21 @@ begin
     {$ifdef FPC_HAS_FEATURE_VARIANTS}
     vtVariant       : ;
     {$endif FPC_HAS_FEATURE_VARIANTS}
-    vtInterface     : ;
-    vtWideString    :
+    vtInterface:
+      begin
+        h:=Args[i].VInterface;
+        if h=nil then
+        begin
+          p^:=JOBArgNil;
+          inc(p);
+        end else begin
+          p^:=JOBArgObject;
+          inc(p);
+          PNativeInt(p)^:=IJSObject(h).GetJSObjectID;
+          inc(p,sizeof(NativeInt));
+        end;
+      end;
+    vtWideString:
       begin
         p^:=JOBArgUnicodeString;
         inc(p);
@@ -633,7 +707,7 @@ begin
         PPointer(p)^:=h;
         inc(p,sizeof(Pointer));
       end;
-    vtInt64         :
+    vtInt64:
       begin
         i64:=Args[i].VInt64^;
         if (i64>=low(longint)) and (i64<=high(longint)) then
@@ -649,7 +723,7 @@ begin
           inc(p,8);
         end;
       end;
-    vtUnicodeString :
+    vtUnicodeString:
       begin
         p^:=JOBArgUnicodeString;
         inc(p);
@@ -660,7 +734,7 @@ begin
         PPointer(p)^:=h;
         inc(p,sizeof(Pointer));
       end;
-    vtQWord         :
+    vtQWord:
       begin
         qw:=Args[i].VQWord^;
         if (qw<=high(longint)) then
@@ -902,8 +976,14 @@ begin
   InvokeJSNoResult(aName,[Value],jisSetter);
 end;
 
+function TJSObject.NewJSObject(const Args: array of const;
+  aResultClass: TJSObjectClass): TJSObject;
+begin
+  Result:=InvokeJSObjectResult('',Args,aResultClass,jigNew);
+end;
+
 initialization
-  JSDocument:=TJSObject.CreateFromID(JOBObjIdDocument);
+  JSObject:=TJSObject.CreateFromID(JOBObjIdObject);
 
 end.
 

+ 203 - 0
demo/wasienv/dom/job_web.pas

@@ -0,0 +1,203 @@
+unit JOB_Web;
+
+{$mode ObjFPC}{$H+}
+{$ModeSwitch FunctionReferences}
+
+interface
+
+uses
+  Classes, SysUtils, JOB_Shared, JOB_WAsm;
+
+type
+
+  { IJSNode }
+
+  IJSNode = interface(IJSObject)
+    ['{D7A751A8-73AD-4620-B2EE-03165A9D65D7}']
+    function GetInnerText: UnicodeString;
+    procedure SetInnerText(const AValue: UnicodeString);
+    property InnerText : UnicodeString read GetInnerText write SetInnerText;
+  end;
+
+  { TJSNode }
+
+  TJSNode = class(TJSObject,IJSNode)
+  public
+    function GetInnerText: UnicodeString;
+    procedure SetInnerText(const AValue: UnicodeString);
+  end;
+
+  { IJSElement }
+
+  IJSElement = interface(IJSNode)
+    ['{A160069E-378F-4B76-BE64-1979A28B9EEA}']
+    function childElementCount : Integer;
+    function firstElementChild : IJSElement;
+    function GetInnerHTML: UnicodeString;
+    function GetName: UnicodeString;
+    function Get_ClassName: UnicodeString;
+    procedure SetInnerHTML(const AValue: UnicodeString);
+    procedure SetName(const AValue: UnicodeString);
+    procedure Set_ClassName(const AValue: UnicodeString);
+    property Name: UnicodeString read GetName write SetName;
+    property _ClassName: UnicodeString read Get_ClassName write Set_ClassName;
+    property InnerHTML: UnicodeString read GetInnerHTML write SetInnerHTML;
+  end;
+
+  { TJSElement }
+
+  TJSElement = class(TJSNode,IJSElement)
+    function childElementCount : Integer;
+    function firstElementChild : IJSElement;
+    function GetInnerHTML: UnicodeString;
+    function GetName: UnicodeString;
+    function Get_ClassName: UnicodeString;
+    procedure SetInnerHTML(const AValue: UnicodeString);
+    procedure SetName(const AValue: UnicodeString);
+    procedure Set_ClassName(const AValue: UnicodeString);
+  end;
+
+  IJSDocument = interface(IJSNode)
+    ['{CC3FB7C1-C4ED-4BBC-80AB-7B6C2989E026}']
+    function getElementById(const aID : UnicodeString) : IJSElement;
+  end;
+
+  { TJSDocument }
+
+  TJSDocument = class(TJSNode,IJSDocument)
+  public
+    function getElementById(const aID : UnicodeString) : IJSElement;
+  end;
+
+  IJSEvent = interface(IJSObject)
+    ['{8B752F08-21F6-4F0D-B7A0-5A6616E752AD}']
+    function CurrentTargetElement: IJSElement;
+    function TargetElement: IJSElement;
+  end;
+
+  { TJSEvent }
+
+  TJSEvent = class(TJSObject,IJSEvent)
+  public
+    function CurrentTargetElement: IJSElement;
+    function TargetElement: IJSElement;
+  end;
+
+  TEventListenerEvent = TJSEvent;
+
+  TJSEventHandler = reference to function(Event: TEventListenerEvent): boolean;
+
+  IJSWindow = interface(IJSObject)
+    ['{7DEBCDE5-2C6C-4758-9EE3-CF153AF2AFA0}']
+    procedure AddEventListener(const aName: UnicodeString; const aListener: TJSEventHandler);
+    procedure Alert(Const Msg: UnicodeString);
+  end;
+
+  { TJSWindow }
+
+  TJSWindow = class(TJSObject,IJSWindow)
+  public
+    procedure AddEventListener(const aName: UnicodeString; const aListener: TJSEventHandler);
+    procedure Alert(Const Msg: UnicodeString);
+  end;
+
+var
+  JSDocument: TJSDocument;
+  JSWindow: TJSWindow;
+
+implementation
+
+{ TJSEvent }
+
+function TJSEvent.CurrentTargetElement: IJSElement;
+begin
+  Result:=ReadJSPropertyObject('currentTargetElement',TJSElement) as IJSElement;
+end;
+
+function TJSEvent.TargetElement: IJSElement;
+begin
+  Result:=ReadJSPropertyObject('targetElement',TJSElement) as IJSElement;
+end;
+
+{ TJSNode }
+
+function TJSNode.GetInnerText: UnicodeString;
+begin
+  Result:=ReadJSPropertyUnicodeString('innerText');
+end;
+
+procedure TJSNode.SetInnerText(const AValue: UnicodeString);
+begin
+  WriteJSPropertyUnicodeString('innerText',AValue);
+end;
+
+{ TJSElement }
+
+function TJSElement.childElementCount: Integer;
+begin
+  Result:=ReadJSPropertyLongInt('childElementCount');
+end;
+
+function TJSElement.firstElementChild: IJSElement;
+begin
+  Result:=ReadJSPropertyObject('firstElementChild',TJSElement) as IJSElement;
+end;
+
+function TJSElement.GetInnerHTML: UnicodeString;
+begin
+  Result:=ReadJSPropertyUnicodeString('innerHTML');
+end;
+
+function TJSElement.GetName: UnicodeString;
+begin
+  Result:=ReadJSPropertyUnicodeString('name');
+end;
+
+function TJSElement.Get_ClassName: UnicodeString;
+begin
+  Result:=ReadJSPropertyUnicodeString('className');
+end;
+
+procedure TJSElement.SetInnerHTML(const AValue: UnicodeString);
+begin
+  WriteJSPropertyUnicodeString('innerHTML',AValue);
+end;
+
+procedure TJSElement.SetName(const AValue: UnicodeString);
+begin
+  WriteJSPropertyUnicodeString('name',AValue);
+end;
+
+procedure TJSElement.Set_ClassName(const AValue: UnicodeString);
+begin
+  WriteJSPropertyUnicodeString('className',AValue);
+end;
+
+{ TJSDocument }
+
+function TJSDocument.getElementById(const aID: UnicodeString): IJSElement;
+begin
+  Result:=InvokeJSObjectResult('getElementById',[aID],TJSElement) as IJSElement;
+end;
+
+{ TJSWindow }
+
+procedure TJSWindow.AddEventListener(const aName: UnicodeString;
+  const aListener: TJSEventHandler);
+begin
+  InvokeJSNoResult('addEventListener',[{Todo}]);
+end;
+
+procedure TJSWindow.Alert(const Msg: UnicodeString);
+begin
+  InvokeJSNoResult('alert',[Msg]);
+end;
+
+initialization
+  JSDocument:=TJSDocument.CreateFromID(JOBObjIdDocument);
+  JSWindow:=TJSWindow.CreateFromID(JOBObjIdWindow);
+finalization
+  JSDocument.Free;
+  JSWindow.Free;
+end.
+