137da2899SCharles.Forsythimplement JScript; 237da2899SCharles.Forsyth 337da2899SCharles.Forsythinclude "common.m"; 437da2899SCharles.Forsythinclude "ecmascript.m"; 537da2899SCharles.Forsyth 637da2899SCharles.ForsythES: Ecmascript; 737da2899SCharles.Forsyth Exec, Obj, Call, Prop, Val, Ref, RefVal, Builtin, ReadOnly: import ES; 837da2899SCharles.Forsythme: ESHostobj; 937da2899SCharles.Forsyth 1037da2899SCharles.Forsyth# local copies from CU 1137da2899SCharles.Forsythsys: Sys; 1237da2899SCharles.ForsythCU: CharonUtils; 1337da2899SCharles.Forsyth 1437da2899SCharles.ForsythD: Draw; 1537da2899SCharles.ForsythS: String; 1637da2899SCharles.ForsythT: StringIntTab; 1737da2899SCharles.ForsythC: Ctype; 1837da2899SCharles.ForsythB: Build; 1937da2899SCharles.Forsyth Item: import B; 2037da2899SCharles.ForsythCH: Charon; 2137da2899SCharles.ForsythL: Layout; 2237da2899SCharles.Forsyth Frame, Control: import L; 2337da2899SCharles.ForsythU: Url; 2437da2899SCharles.Forsyth Parsedurl: import U; 2537da2899SCharles.ForsythE: Events; 2637da2899SCharles.Forsyth Event, ScriptEvent: import E; 2737da2899SCharles.Forsyth 2837da2899SCharles.ForsythG : Gui; 2937da2899SCharles.Forsyth 3037da2899SCharles.ForsythJScript: module 3137da2899SCharles.Forsyth{ 3237da2899SCharles.Forsyth # First, conform to Script interface 3337da2899SCharles.Forsyth defaultStatus: string; 3437da2899SCharles.Forsyth jevchan: chan of ref ScriptEvent; 3537da2899SCharles.Forsyth versions: array of string; 3637da2899SCharles.Forsyth 3737da2899SCharles.Forsyth init: fn(cu: CharonUtils): string; 3837da2899SCharles.Forsyth frametreechanged: fn(top: ref Layout->Frame); 3937da2899SCharles.Forsyth havenewdoc: fn(f: ref Layout->Frame); 4037da2899SCharles.Forsyth evalscript: fn(f: ref Layout->Frame, s: string) : (string, string, string); 4137da2899SCharles.Forsyth framedone: fn(f : ref Layout->Frame, hasscripts : int); 4237da2899SCharles.Forsyth 4337da2899SCharles.Forsyth # 4437da2899SCharles.Forsyth # implement the host object interface, too 4537da2899SCharles.Forsyth # 4637da2899SCharles.Forsyth get: fn(ex: ref Exec, o: ref Obj, property: string): ref Val; 4737da2899SCharles.Forsyth put: fn(ex: ref Exec, o: ref Obj, property: string, val: ref Val); 4837da2899SCharles.Forsyth canput: fn(ex: ref Exec, o: ref Obj, property: string): ref Val; 4937da2899SCharles.Forsyth hasproperty: fn(ex: ref Exec, o: ref Obj, property: string): ref Val; 5037da2899SCharles.Forsyth delete: fn(ex: ref Exec, o: ref Obj, property: string); 5137da2899SCharles.Forsyth defaultval: fn(ex: ref Exec, o: ref Obj, tyhint: int): ref Val; 5237da2899SCharles.Forsyth call: fn(ex: ref Exec, func, this: ref Obj, args: array of ref Val, eval: int): ref Ref; 5337da2899SCharles.Forsyth construct: fn(ex: ref Exec, func: ref Obj, args: array of ref Val): ref Obj; 5437da2899SCharles.Forsyth}; 5537da2899SCharles.Forsyth 5637da2899SCharles.Forsythversions = array [] of { 5737da2899SCharles.Forsyth "javascript", 5837da2899SCharles.Forsyth "javascript1.0", 5937da2899SCharles.Forsyth "javascript1.1", 6037da2899SCharles.Forsyth "javascript1.2", 6137da2899SCharles.Forsyth "javascript1.3", 6237da2899SCharles.Forsyth}; 6337da2899SCharles.Forsyth 6437da2899SCharles.Forsyth# Call init() before calling anything else. 6537da2899SCharles.Forsyth# It makes a global object (a Window) for the browser's top level frame, 6637da2899SCharles.Forsyth# and also puts a navaigator object in it. The document can't be filled 6737da2899SCharles.Forsyth# in until the first document gets loaded. 6837da2899SCharles.Forsyth# 6937da2899SCharles.Forsyth# This module keeps track of the correspondence between the Script Window 7037da2899SCharles.Forsyth# objects and the corresponding Layout Frames, using the ScriptWin adt to 7137da2899SCharles.Forsyth# build a tree mirroring the structure. The root of the tree never changes 7237da2899SCharles.Forsyth# after first being set (but changing its document essentially resets all of the 7337da2899SCharles.Forsyth# other data structures). After charon has built its top-level window, it 7437da2899SCharles.Forsyth# should call frametreechanged(top). 7537da2899SCharles.Forsyth# 7637da2899SCharles.Forsyth# When a frame gets reset or gets some frame children added, call frametreechanged(f), 7737da2899SCharles.Forsyth# where f is the changed frame. This module will update its ScriptWin tree as needed. 7837da2899SCharles.Forsyth# 7937da2899SCharles.Forsyth# Whenever the document in a (Layout) Frame f changes, call havenewdoc(f) 8037da2899SCharles.Forsyth# after the frame's doc field is set. This causes this module to initialize the document 8137da2899SCharles.Forsyth# object in the corresponding window object. 8237da2899SCharles.Forsyth# 8337da2899SCharles.Forsyth# From within the build process, call evalscript(containing frame, script) to evaluate 8437da2899SCharles.Forsyth# global code fragments as needed. The return value is two strings: a possible error 8537da2899SCharles.Forsyth# description, and HTML that is the result of a document.write (so it should be spliced 8637da2899SCharles.Forsyth# in at the point where the <SCRIPT> element occurred). evalscript() also handles 8737da2899SCharles.Forsyth# the job of synching up the Docinfo data (on the Build side) with the document object 8837da2899SCharles.Forsyth# (on the Script side). 8937da2899SCharles.Forsyth# 9037da2899SCharles.Forsyth# For use by other external routines, the xfertoscriptobjs() and xferfromscriptobjs() 9137da2899SCharles.Forsyth# functions that do the just-described synch-up are available for external callers. 9237da2899SCharles.Forsyth 9337da2899SCharles.Forsyth# Adt for keeping track of correspondence between Image objects 9437da2899SCharles.Forsyth# and their corresponding Build items. 9537da2899SCharles.ForsythScriptImg: adt 9637da2899SCharles.Forsyth{ 9737da2899SCharles.Forsyth item: ref Build->Item.Iimage; 9837da2899SCharles.Forsyth obj: ref Obj; 9937da2899SCharles.Forsyth}; 10037da2899SCharles.Forsyth 10137da2899SCharles.ForsythScriptForm : adt { 10237da2899SCharles.Forsyth form : ref Build->Form; 10337da2899SCharles.Forsyth obj : ref Obj; 10437da2899SCharles.Forsyth ix : int; # index in document.forms array 10537da2899SCharles.Forsyth fields : list of (ref Build->Formfield, ref Obj); 10637da2899SCharles.Forsyth}; 10737da2899SCharles.Forsyth 10837da2899SCharles.Forsyth# Adt for keeping track of correspondence between Window 10937da2899SCharles.Forsyth# objects and their corresponding Frames. 11037da2899SCharles.Forsyth 11137da2899SCharles.ForsythScriptWin: adt 11237da2899SCharles.Forsyth{ 11337da2899SCharles.Forsyth frame: ref Layout->Frame; 11437da2899SCharles.Forsyth ex: ref Exec; # ex.global is frame's Window obj 11537da2899SCharles.Forsyth locobj: ref Obj; # Location object for window 11637da2899SCharles.Forsyth val : ref Val; # val of ex.global - used to side-effect entry in parent.frames[] 11737da2899SCharles.Forsyth 11837da2899SCharles.Forsyth parent: ref ScriptWin; 11937da2899SCharles.Forsyth forms: list of ref ScriptForm; # no guaranteed order 12037da2899SCharles.Forsyth kids: cyclic list of ref ScriptWin; 12137da2899SCharles.Forsyth imgs: list of ref ScriptImg; 12237da2899SCharles.Forsyth newloc: string; # url to go to after script finishes executing 12337da2899SCharles.Forsyth newloctarg: string; # target frame for newloc 12437da2899SCharles.Forsyth docwriteout: string; 12537da2899SCharles.Forsyth inbuild: int; 12637da2899SCharles.Forsyth active: int; # frame or sub-frame has scripts 12737da2899SCharles.Forsyth error: int; 12837da2899SCharles.Forsyth imgrelocs: list of ref Obj; 12937da2899SCharles.Forsyth 13037da2899SCharles.Forsyth new: fn(f: ref Layout->Frame, ex: ref Exec, loc: ref Obj, par: ref ScriptWin) : ref ScriptWin; 13137da2899SCharles.Forsyth addkid: fn(sw: self ref ScriptWin, f: ref Layout->Frame); 13237da2899SCharles.Forsyth dummy: fn(): ref ScriptWin; 13337da2899SCharles.Forsyth# findbyframe: fn(sw: self ref ScriptWin, f: ref Layout->Frame) : ref ScriptWin; 13437da2899SCharles.Forsyth findbyframeid: fn(sw: self ref ScriptWin, fid: int) : ref ScriptWin; 13537da2899SCharles.Forsyth findbydoc: fn(sw: self ref ScriptWin, d: ref Build->Docinfo) : ref ScriptWin; 13637da2899SCharles.Forsyth findbyobj: fn(sw : self ref ScriptWin, obj : ref Obj) : ref ScriptWin; 13737da2899SCharles.Forsyth findbyname: fn(sw : self ref ScriptWin, name : string) : ref ScriptWin; 13837da2899SCharles.Forsyth}; 13937da2899SCharles.Forsyth 14037da2899SCharles.Forsythopener: ref ScriptWin; 14137da2899SCharles.Forsythwinclose: int; 14237da2899SCharles.Forsyth 14337da2899SCharles.Forsyth# Helper adts for initializing objects. 14437da2899SCharles.Forsyth# Methods go in prototype, properties go in objects 14537da2899SCharles.Forsyth 14637da2899SCharles.ForsythMethSpec: adt 14737da2899SCharles.Forsyth{ 14837da2899SCharles.Forsyth name: string; 14937da2899SCharles.Forsyth args: array of string; 15037da2899SCharles.Forsyth}; 15137da2899SCharles.Forsyth 15237da2899SCharles.Forsyth 15337da2899SCharles.ForsythIVundef, IVnull, IVtrue, IVfalse, IVnullstr, IVzero, IVzerostr, IVarray: con iota; 15437da2899SCharles.Forsyth 15537da2899SCharles.ForsythPropSpec: adt 15637da2899SCharles.Forsyth{ 15737da2899SCharles.Forsyth name: string; 15837da2899SCharles.Forsyth attr: int; 15937da2899SCharles.Forsyth initval: int; # one of IVnull, etc. 16037da2899SCharles.Forsyth}; 16137da2899SCharles.Forsyth 16237da2899SCharles.ForsythObjSpec: adt 16337da2899SCharles.Forsyth{ 16437da2899SCharles.Forsyth name: string; 16537da2899SCharles.Forsyth methods: array of MethSpec; 16637da2899SCharles.Forsyth props: array of PropSpec; 16737da2899SCharles.Forsyth}; 16837da2899SCharles.Forsyth 16937da2899SCharles.ForsythMimeSpec: adt 17037da2899SCharles.Forsyth{ 17137da2899SCharles.Forsyth description: string; 17237da2899SCharles.Forsyth suffixes: string; 17337da2899SCharles.Forsyth ty: string; 17437da2899SCharles.Forsyth}; 17537da2899SCharles.Forsyth 17637da2899SCharles.Forsyth# Javascript 1.1 (Netscape 3) client objects 17737da2899SCharles.Forsyth 17837da2899SCharles.Forsythobjspecs := array[] of { 17937da2899SCharles.Forsyth ObjSpec("Anchor", 18037da2899SCharles.Forsyth nil, 18137da2899SCharles.Forsyth array[] of {PropSpec 18237da2899SCharles.Forsyth ("name", ReadOnly, IVnullstr) } 18337da2899SCharles.Forsyth ), 18437da2899SCharles.Forsyth ObjSpec("Applet", 18537da2899SCharles.Forsyth nil, 18637da2899SCharles.Forsyth nil 18737da2899SCharles.Forsyth ), 18837da2899SCharles.Forsyth ObjSpec("document", 18937da2899SCharles.Forsyth array[] of {MethSpec 19037da2899SCharles.Forsyth ("close", nil), 19137da2899SCharles.Forsyth ("open", array[] of { "mimetype", "replace" }), 19237da2899SCharles.Forsyth ("write", array[] of { "string" }), 19337da2899SCharles.Forsyth ("writeln", array[] of { "string" }) }, 19437da2899SCharles.Forsyth array[] of {PropSpec 19537da2899SCharles.Forsyth ("alinkColor", 0, IVnullstr), 19637da2899SCharles.Forsyth ("anchors", ReadOnly, IVarray), 19737da2899SCharles.Forsyth ("applets", ReadOnly, IVarray), 19837da2899SCharles.Forsyth ("bgColor", 0, IVnullstr), 19937da2899SCharles.Forsyth ("cookie", 0, IVnullstr), 20037da2899SCharles.Forsyth ("domain", 0, IVnullstr), 20137da2899SCharles.Forsyth ("embeds", ReadOnly, IVarray), 20237da2899SCharles.Forsyth ("fgColor", 0, IVnullstr), 20337da2899SCharles.Forsyth ("forms", ReadOnly, IVarray), 20437da2899SCharles.Forsyth ("images", ReadOnly, IVarray), 20537da2899SCharles.Forsyth ("lastModified", ReadOnly, IVnullstr), 20637da2899SCharles.Forsyth ("linkColor", 0, IVnullstr), 20737da2899SCharles.Forsyth ("links", ReadOnly, IVarray), 20837da2899SCharles.Forsyth ("location", 0, IVnullstr), 20937da2899SCharles.Forsyth ("plugins", ReadOnly, IVarray), 21037da2899SCharles.Forsyth ("referrer", ReadOnly, IVnullstr), 21137da2899SCharles.Forsyth ("title", ReadOnly, IVnullstr), 21237da2899SCharles.Forsyth ("URL", ReadOnly, IVnullstr), 21337da2899SCharles.Forsyth ("vlinkColor", 0, IVnullstr) } 21437da2899SCharles.Forsyth ), 21537da2899SCharles.Forsyth ObjSpec("Form", 21637da2899SCharles.Forsyth array[] of {MethSpec 21737da2899SCharles.Forsyth ("reset", nil), 21837da2899SCharles.Forsyth ("submit", nil) }, 21937da2899SCharles.Forsyth array[] of {PropSpec 22037da2899SCharles.Forsyth ("action", 0, IVnullstr), 22137da2899SCharles.Forsyth ("elements", ReadOnly, IVarray), 22237da2899SCharles.Forsyth ("encoding", 0, IVnullstr), 22337da2899SCharles.Forsyth ("length", ReadOnly, IVzero), 22437da2899SCharles.Forsyth ("method", 0, IVnullstr), 22537da2899SCharles.Forsyth ("name", 0, IVnullstr), 22637da2899SCharles.Forsyth ("target", 0, IVnullstr) } 22737da2899SCharles.Forsyth ), 22837da2899SCharles.Forsyth # This is merge of Netscape objects (to save code & data space): 22937da2899SCharles.Forsyth # Button, Checkbox, Hidden, Radio, Reset, Select, Text, and Textarea 23037da2899SCharles.Forsyth ObjSpec("FormField", 23137da2899SCharles.Forsyth array[] of {MethSpec 23237da2899SCharles.Forsyth ("blur", nil), 23337da2899SCharles.Forsyth ("click", nil), 23437da2899SCharles.Forsyth ("focus", nil), 23537da2899SCharles.Forsyth ("select", nil) }, 23637da2899SCharles.Forsyth array[] of {PropSpec 23737da2899SCharles.Forsyth ("checked", 0, IVundef), 23837da2899SCharles.Forsyth ("defaultChecked", 0, IVundef), 23937da2899SCharles.Forsyth ("defaultValue", 0, IVundef), 24037da2899SCharles.Forsyth ("form", ReadOnly, IVundef), 24137da2899SCharles.Forsyth ("length", 0, IVundef), 24237da2899SCharles.Forsyth ("name", 0, IVnullstr), 24337da2899SCharles.Forsyth ("options", 0, IVundef), 24437da2899SCharles.Forsyth ("type", ReadOnly, IVundef), 24537da2899SCharles.Forsyth ("selectedIndex", 0, IVundef), 24637da2899SCharles.Forsyth ("value", 0, IVnullstr) } 24737da2899SCharles.Forsyth ), 24837da2899SCharles.Forsyth ObjSpec("History", 24937da2899SCharles.Forsyth array[] of {MethSpec 25037da2899SCharles.Forsyth ("back", nil), 25137da2899SCharles.Forsyth ("forward", nil), 25237da2899SCharles.Forsyth ("go", array[] of { "location-or-delta" }) }, 25337da2899SCharles.Forsyth array[] of {PropSpec 25437da2899SCharles.Forsyth ("current", ReadOnly, IVnullstr), 25537da2899SCharles.Forsyth ("length", ReadOnly, IVzero), 25637da2899SCharles.Forsyth ("next", ReadOnly, IVnullstr), 25737da2899SCharles.Forsyth ("previous", ReadOnly, IVnullstr) } 25837da2899SCharles.Forsyth ), 25937da2899SCharles.Forsyth ObjSpec("Image", 26037da2899SCharles.Forsyth nil, 26137da2899SCharles.Forsyth array[] of {PropSpec 26237da2899SCharles.Forsyth ("border", ReadOnly, IVzerostr), 26337da2899SCharles.Forsyth ("complete", ReadOnly, IVfalse), 26437da2899SCharles.Forsyth ("height", ReadOnly, IVzerostr), 26537da2899SCharles.Forsyth ("hspace", ReadOnly, IVzerostr), 26637da2899SCharles.Forsyth ("lowsrc", 0, IVnullstr), 26737da2899SCharles.Forsyth ("name", ReadOnly, IVnullstr), 26837da2899SCharles.Forsyth ("src", 0, IVnullstr), 26937da2899SCharles.Forsyth ("vspace", ReadOnly, IVzerostr), 27037da2899SCharles.Forsyth ("width", ReadOnly, IVzerostr) } 27137da2899SCharles.Forsyth ), 27237da2899SCharles.Forsyth ObjSpec("Link", 27337da2899SCharles.Forsyth nil, 27437da2899SCharles.Forsyth array[] of {PropSpec 27537da2899SCharles.Forsyth ("hash", 0, IVnullstr), 27637da2899SCharles.Forsyth ("host", 0, IVnullstr), 27737da2899SCharles.Forsyth ("hostname", 0, IVnullstr), 27837da2899SCharles.Forsyth ("href", 0, IVnullstr), 27937da2899SCharles.Forsyth ("pathname", 0, IVnullstr), 28037da2899SCharles.Forsyth ("port", 0, IVnullstr), 28137da2899SCharles.Forsyth ("protocol", 0, IVnullstr), 28237da2899SCharles.Forsyth ("search", 0, IVnullstr), 28337da2899SCharles.Forsyth ("target", 0, IVnullstr) } 28437da2899SCharles.Forsyth ), 28537da2899SCharles.Forsyth ObjSpec("Location", 28637da2899SCharles.Forsyth array[] of {MethSpec 28737da2899SCharles.Forsyth ("reload", array[] of { "forceGet" }), 28837da2899SCharles.Forsyth ("replace", array[] of { "URL" }) }, 28937da2899SCharles.Forsyth array[] of {PropSpec 29037da2899SCharles.Forsyth ("hash", 0, IVnullstr), 29137da2899SCharles.Forsyth ("host", 0, IVnullstr), 29237da2899SCharles.Forsyth ("hostname", 0, IVnullstr), 29337da2899SCharles.Forsyth ("href", 0, IVnullstr), 29437da2899SCharles.Forsyth ("pathname", 0, IVnullstr), 29537da2899SCharles.Forsyth ("port", 0, IVnullstr), 29637da2899SCharles.Forsyth ("protocol", 0, IVnullstr), 29737da2899SCharles.Forsyth ("search", 0, IVnullstr) } 29837da2899SCharles.Forsyth ), 29937da2899SCharles.Forsyth ObjSpec("MimeType", 30037da2899SCharles.Forsyth nil, 30137da2899SCharles.Forsyth array[] of {PropSpec 30237da2899SCharles.Forsyth ("description", ReadOnly, IVnullstr), 30337da2899SCharles.Forsyth ("enabledPlugin", ReadOnly, IVnull), 30437da2899SCharles.Forsyth ("suffixes", ReadOnly, IVnullstr), 30537da2899SCharles.Forsyth ("type", ReadOnly, IVnullstr) } 30637da2899SCharles.Forsyth ), 30737da2899SCharles.Forsyth ObjSpec("Option", 30837da2899SCharles.Forsyth nil, 30937da2899SCharles.Forsyth array[] of {PropSpec 31037da2899SCharles.Forsyth ("defaultSelected", 0, IVfalse), 31137da2899SCharles.Forsyth ("index", 0, IVundef), 31237da2899SCharles.Forsyth ("selected", 0, IVfalse), 31337da2899SCharles.Forsyth ("text", 0, IVnullstr), 31437da2899SCharles.Forsyth ("value", 0, IVnullstr) } 31537da2899SCharles.Forsyth ), 31637da2899SCharles.Forsyth ObjSpec("navigator", 31737da2899SCharles.Forsyth array[] of {MethSpec 31837da2899SCharles.Forsyth ("javaEnabled", nil), 31937da2899SCharles.Forsyth ("plugins.refresh", nil), 32037da2899SCharles.Forsyth ("taintEnabled", nil) }, 32137da2899SCharles.Forsyth array[] of {PropSpec 32237da2899SCharles.Forsyth ("appCodeName", ReadOnly, IVnullstr), 32337da2899SCharles.Forsyth ("appName", ReadOnly, IVnullstr), 32437da2899SCharles.Forsyth ("appVersion", ReadOnly, IVnullstr), 32537da2899SCharles.Forsyth ("mimeTypes", ReadOnly, IVarray), 32637da2899SCharles.Forsyth ("platform", ReadOnly, IVnullstr), 32737da2899SCharles.Forsyth ("plugins", ReadOnly, IVarray), 32837da2899SCharles.Forsyth ("userAgent", ReadOnly, IVnullstr) } 32937da2899SCharles.Forsyth ), 33037da2899SCharles.Forsyth ObjSpec("Plugin", 33137da2899SCharles.Forsyth nil, 33237da2899SCharles.Forsyth array[] of {PropSpec 33337da2899SCharles.Forsyth ("description", 0, IVnullstr), 33437da2899SCharles.Forsyth ("filename", 0, IVnullstr), 33537da2899SCharles.Forsyth ("length", 0, IVzero), 33637da2899SCharles.Forsyth ("name", 0, IVnullstr) } 33737da2899SCharles.Forsyth ), 33837da2899SCharles.Forsyth ObjSpec("Screen", 33937da2899SCharles.Forsyth nil, 34037da2899SCharles.Forsyth array[] of {PropSpec 34137da2899SCharles.Forsyth ("availHeight", ReadOnly, IVzero), 34237da2899SCharles.Forsyth ("availWidth", ReadOnly, IVzero), 34337da2899SCharles.Forsyth ("availLeft", ReadOnly, IVzero), 34437da2899SCharles.Forsyth ("availTop", ReadOnly, IVzero), 34537da2899SCharles.Forsyth ("colorDepth", ReadOnly, IVzero), 34637da2899SCharles.Forsyth ("pixelDepth", ReadOnly, IVzero), 34737da2899SCharles.Forsyth ("height", ReadOnly, IVzero), 34837da2899SCharles.Forsyth ("width", ReadOnly, IVzero) } 34937da2899SCharles.Forsyth ), 35037da2899SCharles.Forsyth ObjSpec("Window", 35137da2899SCharles.Forsyth array[] of {MethSpec 35237da2899SCharles.Forsyth ("alert", array[] of { "msg" }), 35337da2899SCharles.Forsyth ("blur", nil), 35437da2899SCharles.Forsyth ("clearInterval", array[] of { "intervalid" }), 35537da2899SCharles.Forsyth ("clearTimeout", array[] of { "timeoutid" }), 35637da2899SCharles.Forsyth ("close", nil), 35737da2899SCharles.Forsyth ("confirm", array[] of { "msg" }), 35837da2899SCharles.Forsyth ("focus", nil), 35937da2899SCharles.Forsyth ("moveBy", array[] of { "dx", "dy" }), 36037da2899SCharles.Forsyth ("moveTo", array[] of { "x", "y" }), 36137da2899SCharles.Forsyth ("open", array[] of { "url", "winname", "winfeatures" }), 36237da2899SCharles.Forsyth ("prompt", array[] of { "msg", "inputdflt" }), 36337da2899SCharles.Forsyth ("resizeBy", array[] of { "dh", "dw" }), 36437da2899SCharles.Forsyth ("resizeTo", array[] of { "width", "height" }), 36537da2899SCharles.Forsyth ("scroll", array[] of { "x", "y" }), 36637da2899SCharles.Forsyth ("scrollBy", array[] of { "dx", "dy" }), 36737da2899SCharles.Forsyth ("scrollTo", array[] of { "x", "y" }), 36837da2899SCharles.Forsyth ("setInterval", array[] of { "code", "msec" }), 36937da2899SCharles.Forsyth ("setTimeout", array[] of { "expr", "msec" }) }, 37037da2899SCharles.Forsyth array[] of {PropSpec 37137da2899SCharles.Forsyth ("closed", ReadOnly, IVfalse), 37237da2899SCharles.Forsyth ("defaultStatus", 0, IVnullstr), 37337da2899SCharles.Forsyth ("document", 0, IVnull), 37437da2899SCharles.Forsyth ("frames", ReadOnly, IVnull), # array, really 37537da2899SCharles.Forsyth ("history", 0, IVnull), # array, really 37637da2899SCharles.Forsyth ("length", ReadOnly, IVzero), 37737da2899SCharles.Forsyth ("location", 0, IVnullstr), 37837da2899SCharles.Forsyth# ("Math", ReadOnly, IVnull), 37937da2899SCharles.Forsyth ("name", 0, IVnullstr), 38037da2899SCharles.Forsyth ("navigator", ReadOnly, IVnull), 38137da2899SCharles.Forsyth ("offscreenBuffering", 0, IVnullstr), 38237da2899SCharles.Forsyth ("opener", 0, IVnull), 38337da2899SCharles.Forsyth ("parent", ReadOnly, IVnull), 38437da2899SCharles.Forsyth ("screen", 0, IVnull), 38537da2899SCharles.Forsyth ("self", ReadOnly, IVnull), 38637da2899SCharles.Forsyth ("status", 0, IVnullstr), 38737da2899SCharles.Forsyth ("top", ReadOnly, IVnull), 38837da2899SCharles.Forsyth ("window", ReadOnly, IVnull) } 38937da2899SCharles.Forsyth ) 39037da2899SCharles.Forsyth}; 39137da2899SCharles.Forsyth 39237da2899SCharles.Forsyth# Currently supported charon mime types 39337da2899SCharles.Forsythmimespecs := array[] of { 39437da2899SCharles.Forsyth MimeSpec("HTML", 39537da2899SCharles.Forsyth "htm,html", 39637da2899SCharles.Forsyth "text/html" 39737da2899SCharles.Forsyth ), 39837da2899SCharles.Forsyth MimeSpec("Plain text", 39937da2899SCharles.Forsyth "txt,text", 40037da2899SCharles.Forsyth "text/plain" 40137da2899SCharles.Forsyth ), 40237da2899SCharles.Forsyth MimeSpec("Gif Image", 40337da2899SCharles.Forsyth "gif", 40437da2899SCharles.Forsyth "image/gif" 40537da2899SCharles.Forsyth ), 40637da2899SCharles.Forsyth MimeSpec("Jpeg Image", 40737da2899SCharles.Forsyth "jpeg,jpg,jpe", 40837da2899SCharles.Forsyth "image/jpeg" 40937da2899SCharles.Forsyth ), 41037da2899SCharles.Forsyth MimeSpec("X Bitmap Image", 41137da2899SCharles.Forsyth "", 41237da2899SCharles.Forsyth "image/x-xbitmap" 41337da2899SCharles.Forsyth ) 41437da2899SCharles.Forsyth}; 41537da2899SCharles.Forsyth 41637da2899SCharles.Forsyth# charon's 's' debug flag: 41737da2899SCharles.Forsyth# 1: basic syntax and runtime errors 41837da2899SCharles.Forsyth# 2: 'event' logging and DOM actions 41937da2899SCharles.Forsyth# 3: print parsed code and ops as executed 42037da2899SCharles.Forsyth# 4: print value of expression statements and abort on runtime errors 42137da2899SCharles.Forsythdbg := 0; 42237da2899SCharles.Forsythdbgdom := 0; 42337da2899SCharles.Forsyth 42437da2899SCharles.Forsythtop: ref ScriptWin; 42537da2899SCharles.Forsythcreatedimages : list of ref Obj; 42637da2899SCharles.Forsythnullstrval: ref Val; 42737da2899SCharles.Forsythzeroval: ref Val; 42837da2899SCharles.Forsythzerostrval: ref Val; 42937da2899SCharles.Forsyth 43037da2899SCharles.Forsyth# Call this after charon's main (top) frame has been built 43137da2899SCharles.Forsythinit(cu: CharonUtils) : string 43237da2899SCharles.Forsyth{ 43337da2899SCharles.Forsyth CU = cu; 43437da2899SCharles.Forsyth sys = load Sys Sys->PATH; 43537da2899SCharles.Forsyth D = load Draw Draw->PATH; 43637da2899SCharles.Forsyth S = load String String->PATH; 43737da2899SCharles.Forsyth T = load StringIntTab StringIntTab->PATH; 43837da2899SCharles.Forsyth U = load Url Url->PATH; 43937da2899SCharles.Forsyth if (U != nil) 44037da2899SCharles.Forsyth U->init(); 44137da2899SCharles.Forsyth C = cu->C; 44237da2899SCharles.Forsyth B = cu->B; 44337da2899SCharles.Forsyth L = cu->L; 44437da2899SCharles.Forsyth E = cu->E; 44537da2899SCharles.Forsyth CH = cu->CH; 44637da2899SCharles.Forsyth G = cu->G; 44737da2899SCharles.Forsyth dbg = int (CU->config).dbg['s']; 44837da2899SCharles.Forsyth if (dbg > 1) 44937da2899SCharles.Forsyth dbgdom = 1; 45037da2899SCharles.Forsyth ES = load Ecmascript Ecmascript->PATH; 45137da2899SCharles.Forsyth if(ES == nil) 45237da2899SCharles.Forsyth return sys->sprint("could not load module %s: %r", Ecmascript->PATH); 45337da2899SCharles.Forsyth err := ES->init(); 45437da2899SCharles.Forsyth if (err != nil) 45537da2899SCharles.Forsyth return sys->sprint("ecmascript error: %s", err); 45637da2899SCharles.Forsyth 45737da2899SCharles.Forsyth me = load ESHostobj SELF; 45837da2899SCharles.Forsyth if(me == nil) 45937da2899SCharles.Forsyth return sys->sprint("jscript: could not load self as a ESHostobj: %r"); 46037da2899SCharles.Forsyth if(dbg >= 3) { 46137da2899SCharles.Forsyth ES->debug['p'] = 1; # print parsed code 46237da2899SCharles.Forsyth ES->debug['e'] = 1; # prinv ops as they are executed 46337da2899SCharles.Forsyth if(dbg >= 4) { 46437da2899SCharles.Forsyth ES->debug['e'] = 2; 46537da2899SCharles.Forsyth ES->debug['v'] = 1; # print value of expression statements 46637da2899SCharles.Forsyth ES->debug['r'] = 1; # print and abort if runtime errors 46737da2899SCharles.Forsyth } 46837da2899SCharles.Forsyth } 46937da2899SCharles.Forsyth 47037da2899SCharles.Forsyth # some constant values, for initialization 47137da2899SCharles.Forsyth nullstrval = ES->strval(""); 47237da2899SCharles.Forsyth zeroval = ES->numval(0.); 47337da2899SCharles.Forsyth zerostrval = ES->strval("0"); 47437da2899SCharles.Forsyth jevchan = chan of ref ScriptEvent; 47537da2899SCharles.Forsyth spawn jevhandler(); 47637da2899SCharles.Forsyth return nil; 47737da2899SCharles.Forsyth} 47837da2899SCharles.Forsyth 47937da2899SCharles.Forsythdoneevent := ScriptEvent(-1,0,0,0,0,0,0,0,0,nil,nil,0); 48037da2899SCharles.Forsyth 48137da2899SCharles.Forsyth# Used to receive and act upon ScriptEvents from main charon thread. 48237da2899SCharles.Forsyth# Want to queue the events up, so that the main thread doesn't have 48337da2899SCharles.Forsyth# to wait, and spawn off a do_on, one at a time, so that they don't 48437da2899SCharles.Forsyth# interfere with each other. 48537da2899SCharles.Forsyth# When do_on is finished, it must send a copy of doneevent 48637da2899SCharles.Forsyth# so that jevhandler knows it can spawn another do_on. 48737da2899SCharles.Forsythjevhandler() 48837da2899SCharles.Forsyth{ 48937da2899SCharles.Forsyth q := array[10] of ref ScriptEvent; 49037da2899SCharles.Forsyth qhead := 0; 49137da2899SCharles.Forsyth qtail := 0; 49237da2899SCharles.Forsyth spawnok := 1; 49337da2899SCharles.Forsyth for(;;) { 49437da2899SCharles.Forsyth jev := <- jevchan; 49537da2899SCharles.Forsyth if(jev.kind == -1) 49637da2899SCharles.Forsyth spawnok = 1; 49737da2899SCharles.Forsyth else 49837da2899SCharles.Forsyth q[qtail++] = jev; 49937da2899SCharles.Forsyth jev = nil; 50037da2899SCharles.Forsyth 50137da2899SCharles.Forsyth # remove next event to process, if ok to and there is one 50237da2899SCharles.Forsyth if(spawnok && qhead < qtail) 50337da2899SCharles.Forsyth jev = q[qhead++]; 50437da2899SCharles.Forsyth 50537da2899SCharles.Forsyth # adjust queue to make sure there is room for next event 50637da2899SCharles.Forsyth if(qhead == qtail) { 50737da2899SCharles.Forsyth qhead = 0; 50837da2899SCharles.Forsyth qtail = 0; 50937da2899SCharles.Forsyth } 51037da2899SCharles.Forsyth if(qtail == len q) { 51137da2899SCharles.Forsyth if(qhead > 0) { 51237da2899SCharles.Forsyth q[0:] = q[qhead:qtail]; 51337da2899SCharles.Forsyth qtail -= qhead; 51437da2899SCharles.Forsyth qhead = 0; 51537da2899SCharles.Forsyth } 51637da2899SCharles.Forsyth else { 51737da2899SCharles.Forsyth newq := array[len q + 10] of ref ScriptEvent; 51837da2899SCharles.Forsyth newq[0:] = q; 51937da2899SCharles.Forsyth q = newq; 52037da2899SCharles.Forsyth } 52137da2899SCharles.Forsyth } 52237da2899SCharles.Forsyth 52337da2899SCharles.Forsyth # process next event, if any 52437da2899SCharles.Forsyth if(jev != nil) { 52537da2899SCharles.Forsyth spawnok = 0; 52637da2899SCharles.Forsyth spawn do_on(jev); 52737da2899SCharles.Forsyth } 52837da2899SCharles.Forsyth } 52937da2899SCharles.Forsyth} 53037da2899SCharles.Forsyth 53137da2899SCharles.Forsyth# Create an execution context for the frame. 53237da2899SCharles.Forsyth# The global object of the frame is the frame's Window object. 53337da2899SCharles.Forsyth# Return the execution context and the Location object for the window. 53437da2899SCharles.Forsythmakeframeex(f : ref Layout->Frame) : (ref Exec, ref Obj) 53537da2899SCharles.Forsyth{ 53637da2899SCharles.Forsyth winobj := mkhostobj(nil, "Window"); 53737da2899SCharles.Forsyth ex := ES->mkexec(winobj); 53837da2899SCharles.Forsyth winobj.prototype = ex.objproto; 53937da2899SCharles.Forsyth winobj.prototype = mkprototype(ex, specindex("Window")); 54037da2899SCharles.Forsyth 54137da2899SCharles.Forsyth navobj := mknavobj(ex); 54237da2899SCharles.Forsyth reinitprop(winobj, "navigator", ES->objval(navobj)); 54337da2899SCharles.Forsyth 54437da2899SCharles.Forsyth histobj := mkhostobj(ex, "History"); 54537da2899SCharles.Forsyth (length, current, next, previous) := CH->histinfo(); 54637da2899SCharles.Forsyth reinitprop(histobj, "current", ES->strval(current)); 54737da2899SCharles.Forsyth reinitprop(histobj, "length", ES->numval(real length)); 54837da2899SCharles.Forsyth reinitprop(histobj, "next", ES->strval(next)); 54937da2899SCharles.Forsyth reinitprop(histobj, "previous", ES->strval(previous)); 55037da2899SCharles.Forsyth ES->put(ex, winobj, "history", ES->objval(histobj)); 55137da2899SCharles.Forsyth 55237da2899SCharles.Forsyth locobj := mkhostobj(ex, "Location"); 55337da2899SCharles.Forsyth src : ref U->Parsedurl; 55437da2899SCharles.Forsyth di := f.doc; 55537da2899SCharles.Forsyth if (di != nil && di.src != nil) { 55637da2899SCharles.Forsyth src = di.src; 55737da2899SCharles.Forsyth reinitprop(locobj, "hash", ES->strval("#" + src.frag)); 55837da2899SCharles.Forsyth reinitprop(locobj, "host", ES->strval(src.host + ":" + src.port)); 55937da2899SCharles.Forsyth reinitprop(locobj, "hostname", ES->strval(src.host)); 56037da2899SCharles.Forsyth reinitprop(locobj, "href", ES->strval(src.tostring())); 56137da2899SCharles.Forsyth reinitprop(locobj, "pathname", ES->strval(src.path)); 56237da2899SCharles.Forsyth reinitprop(locobj, "port", ES->strval(src.port)); 56337da2899SCharles.Forsyth reinitprop(locobj, "protocol", ES->strval(src.scheme + ":")); 56437da2899SCharles.Forsyth reinitprop(locobj, "search", ES->strval("?" + src.query)); 56537da2899SCharles.Forsyth } 56637da2899SCharles.Forsyth ES->put(ex, winobj, "location", ES->objval(locobj)); 56737da2899SCharles.Forsyth 56837da2899SCharles.Forsyth scrobj := mkhostobj(ex, "Screen"); 56937da2899SCharles.Forsyth scr := (CU->G->display).image; 57037da2899SCharles.Forsyth scrw := D->(scr.r.dx)(); 57137da2899SCharles.Forsyth scrh := D->(scr.r.dy)(); 57237da2899SCharles.Forsyth reinitprop(scrobj, "availHeight", ES->numval(real scrh)); 57337da2899SCharles.Forsyth reinitprop(scrobj, "availWidth", ES->numval(real scrw)); 57437da2899SCharles.Forsyth reinitprop(scrobj, "availLeft", ES->numval(real scr.r.min.x)); 57537da2899SCharles.Forsyth reinitprop(scrobj, "availTop", ES->numval(real scr.r.min.y)); 57637da2899SCharles.Forsyth reinitprop(scrobj, "colorDepth", ES->numval(real scr.depth)); 57737da2899SCharles.Forsyth reinitprop(scrobj, "pixelDepth", ES->numval(real scr.depth)); 57837da2899SCharles.Forsyth reinitprop(scrobj, "height", ES->numval(real scrh)); 57937da2899SCharles.Forsyth reinitprop(scrobj, "width", ES->numval(real scrw)); 58037da2899SCharles.Forsyth ES->put(ex, winobj, "screen", ES->objval(scrobj)); 58137da2899SCharles.Forsyth 58237da2899SCharles.Forsyth # make the non-core constructor objects 58337da2899SCharles.Forsyth# improto := mkprototype(ex, specindex("Image")); 58437da2899SCharles.Forsyth o := ES->biinst(winobj, Builtin("Image", "Image", array[] of {"width", "height"}, 2), 58537da2899SCharles.Forsyth ex.funcproto, me); 58637da2899SCharles.Forsyth o.construct = o.call; 58737da2899SCharles.Forsyth 58837da2899SCharles.Forsyth o = ES->biinst(winobj, Builtin("Option", "Option", array[] of {"text", "value", "defaultSelected", "selected"}, 4), 58937da2899SCharles.Forsyth ex.funcproto, me); 59037da2899SCharles.Forsyth o.construct = o.call; 59137da2899SCharles.Forsyth defaultStatus = ""; 59237da2899SCharles.Forsyth return (ex, locobj); 59337da2899SCharles.Forsyth} 59437da2899SCharles.Forsyth 59537da2899SCharles.Forsythmknavobj(ex: ref Exec) : ref Obj 59637da2899SCharles.Forsyth{ 59737da2899SCharles.Forsyth navobj := mkhostobj(ex, "navigator"); 59837da2899SCharles.Forsyth reinitprop(navobj, "appCodeName", ES->strval("Mozilla")); 59937da2899SCharles.Forsyth reinitprop(navobj, "appName", ES->strval("Netscape")); 60037da2899SCharles.Forsyth# reinitprop(navobj, "appVersion", ES->strval("3.0 (Inferno, U)")); 60137da2899SCharles.Forsyth# reinitprop(navobj, "userAgent", ES->strval("Mozilla/3.0 (Inferno; U)")); 60237da2899SCharles.Forsyth reinitprop(navobj, "appVersion", ES->strval("4.08 (Charon; Inferno)")); 60337da2899SCharles.Forsyth reinitprop(navobj, "userAgent", ES->strval("Mozilla/4.08 (Charon; Inferno)")); 60437da2899SCharles.Forsyth 60537da2899SCharles.Forsyth omty := getobj(ex, navobj, "mimeTypes"); 60637da2899SCharles.Forsyth for(i := 0; i < len mimespecs; i++) { 60737da2899SCharles.Forsyth sp := mimespecs[i]; 60837da2899SCharles.Forsyth v := mkhostobj(ex, "MimeType"); 60937da2899SCharles.Forsyth reinitprop(v, "description", ES->strval(sp.description)); 61037da2899SCharles.Forsyth reinitprop(v, "suffixes", ES->strval(sp.suffixes)); 61137da2899SCharles.Forsyth reinitprop(v, "type", ES->strval(sp.ty)); 61237da2899SCharles.Forsyth arrayput(ex, omty, i, sp.ty, ES->objval(v)); 61337da2899SCharles.Forsyth } 61437da2899SCharles.Forsyth return navobj; 61537da2899SCharles.Forsyth} 61637da2899SCharles.Forsyth 61737da2899SCharles.Forsyth# Something changed in charon's frame tree 61837da2899SCharles.Forsythframetreechanged(t: ref Layout->Frame) 61937da2899SCharles.Forsyth{ 62037da2899SCharles.Forsyth rebuild : ref ScriptWin; 62137da2899SCharles.Forsyth if (top == nil) { 62237da2899SCharles.Forsyth (ex, loc) := makeframeex(t); 62337da2899SCharles.Forsyth top = ScriptWin.new(t, ex, loc, nil); 62437da2899SCharles.Forsyth rebuild = top; 62537da2899SCharles.Forsyth } else { 62637da2899SCharles.Forsyth rebuild = top.findbyframeid(t.id); 62737da2899SCharles.Forsyth # t could be new frame - need to look for parent 62837da2899SCharles.Forsyth while (rebuild == nil && t.parent != nil) { 62937da2899SCharles.Forsyth t = t.parent; 63037da2899SCharles.Forsyth rebuild = top.findbyframeid(t.id); 63137da2899SCharles.Forsyth } 63237da2899SCharles.Forsyth # if we haven't found it by now, it's not in the official Frame 63337da2899SCharles.Forsyth # hierarchy, so ignore it 63437da2899SCharles.Forsyth } 63537da2899SCharles.Forsyth if (rebuild != nil) 63637da2899SCharles.Forsyth wininstant(rebuild); 63737da2899SCharles.Forsyth} 63837da2899SCharles.Forsyth 63937da2899SCharles.Forsyth# Frame f has just been reset, then given a new doc field 64037da2899SCharles.Forsyth# (with initial values for src, base, refresh, chset). 64137da2899SCharles.Forsyth# We'll defer doing any actual building of the script objects 64237da2899SCharles.Forsyth# until an evalscript; that way, pages that don't use scripts 64337da2899SCharles.Forsyth# incur minimum penalties). 64437da2899SCharles.Forsythhavenewdoc(f: ref Layout->Frame) 64537da2899SCharles.Forsyth{ 64637da2899SCharles.Forsyth sw := top.findbyframeid(f.id); 64737da2899SCharles.Forsyth if(sw != nil) { 64837da2899SCharles.Forsyth sw.inbuild = 1; 64937da2899SCharles.Forsyth sw.forms = nil; 65037da2899SCharles.Forsyth (sw.ex, sw.locobj) = makeframeex(f); 65137da2899SCharles.Forsyth if (sw.val != nil) 65237da2899SCharles.Forsyth # global object is referenced via parent.frames array 65337da2899SCharles.Forsyth sw.val.obj = sw.ex.global; 65437da2899SCharles.Forsyth wininstant(sw); 65537da2899SCharles.Forsyth } 65637da2899SCharles.Forsyth} 65737da2899SCharles.Forsyth 65837da2899SCharles.Forsyth# returns (error, output, value) 65937da2899SCharles.Forsyth# error: error message 66037da2899SCharles.Forsyth# output: result of any document.writes 66137da2899SCharles.Forsyth# value: value of last statement executed (used for handling "javascript:" URL scheme) 66237da2899SCharles.Forsyth# 66337da2899SCharles.Forsythevalscript(f: ref Layout->Frame, s: string) : (string, string, string) 66437da2899SCharles.Forsyth{ 66537da2899SCharles.Forsyth if (top.error) 66637da2899SCharles.Forsyth return("scripts disabled for this document", "", ""); 66737da2899SCharles.Forsyth sw := top.findbyframeid(f.id); 66837da2899SCharles.Forsyth if (sw == nil) 66937da2899SCharles.Forsyth return("cannot find script window", "", ""); 67037da2899SCharles.Forsyth if (sw.ex == nil) 67137da2899SCharles.Forsyth return("script window has no execution context", "", ""); 67237da2899SCharles.Forsyth if(sw == nil || sw.ex == nil) 67337da2899SCharles.Forsyth return ("", "", ""); 67437da2899SCharles.Forsyth 67537da2899SCharles.Forsyth ex := sw.ex; 67637da2899SCharles.Forsyth sw.docwriteout = ""; 67737da2899SCharles.Forsyth expval := ""; 67837da2899SCharles.Forsyth createdimages = nil; 67937da2899SCharles.Forsyth { 68037da2899SCharles.Forsyth xfertoscriptobjs(f, 1); 68137da2899SCharles.Forsyth if(s != "") { 68237da2899SCharles.Forsyth ex.error = nil; 68337da2899SCharles.Forsyth c := ES->eval(ex, s); 68437da2899SCharles.Forsyth if (c.kind == ES->CThrow && dbg) { 68537da2899SCharles.Forsyth sys->print("unhandled error:\n\tvalue:%s\n\treason:%s\n", 68637da2899SCharles.Forsyth ES->toString(ex, c.val), ex.error); 68737da2899SCharles.Forsyth sys->print("%s\n", s); 68837da2899SCharles.Forsyth } 68937da2899SCharles.Forsyth if (c.kind == ES->CNormal && c.val != nil) { 69037da2899SCharles.Forsyth if (ES->isstr(c.val)) 69137da2899SCharles.Forsyth expval = c.val.str; 69237da2899SCharles.Forsyth } 69337da2899SCharles.Forsyth xferfromscriptobjs(f, 1); 69437da2899SCharles.Forsyth checknewlocs(top); 69537da2899SCharles.Forsyth checkopener(); 69637da2899SCharles.Forsyth } 69737da2899SCharles.Forsyth w := sw.docwriteout; 69837da2899SCharles.Forsyth sw.docwriteout = nil; 69937da2899SCharles.Forsyth return("", w, expval); 70037da2899SCharles.Forsyth }exception exc{ 70137da2899SCharles.Forsyth "*" => 70237da2899SCharles.Forsyth if(dbg) { 70337da2899SCharles.Forsyth sys->print("fatal error %q executing evalscript: %s\nscript=", exc, ex.error); 70437da2899SCharles.Forsyth sa := array of byte s; 70537da2899SCharles.Forsyth sys->write(sys->fildes(1), sa, len sa); 70637da2899SCharles.Forsyth sys->print("\n"); 70737da2899SCharles.Forsyth } 70837da2899SCharles.Forsyth top.error = 1; 70937da2899SCharles.Forsyth emsg := "Fatal error processing script\n\nScript processing suspended for this page"; 71037da2899SCharles.Forsyth G->alert(emsg); 71137da2899SCharles.Forsyth w := sw.docwriteout; 71237da2899SCharles.Forsyth sw.docwriteout = nil; 71337da2899SCharles.Forsyth return (ex.error, w, ""); 71437da2899SCharles.Forsyth } 71537da2899SCharles.Forsyth} 71637da2899SCharles.Forsyth 71737da2899SCharles.Forsythxfertoscriptobjs(f: ref Layout->Frame, inbuild: int) 71837da2899SCharles.Forsyth{ 71937da2899SCharles.Forsyth sw := top.findbyframeid(f.id); 72037da2899SCharles.Forsyth if(sw == nil) 72137da2899SCharles.Forsyth return; 72237da2899SCharles.Forsyth ex := sw.ex; 72337da2899SCharles.Forsyth ow := ex.global; 72437da2899SCharles.Forsyth di := f.doc; 72537da2899SCharles.Forsyth 72637da2899SCharles.Forsyth for(el := di.events; el != nil; el = tl el) { 72737da2899SCharles.Forsyth e := hd el; 72837da2899SCharles.Forsyth hname := ""; 72937da2899SCharles.Forsyth dhname := ""; 73037da2899SCharles.Forsyth case e.attid { 73137da2899SCharles.Forsyth Lex->Aonblur => 73237da2899SCharles.Forsyth hname = "onblur"; 73337da2899SCharles.Forsyth di.evmask |= E->SEonblur; 73437da2899SCharles.Forsyth Lex->Aonerror => 73537da2899SCharles.Forsyth hname = "onerror"; 73637da2899SCharles.Forsyth di.evmask |= E->SEonerror; 73737da2899SCharles.Forsyth Lex->Aonfocus => 73837da2899SCharles.Forsyth hname = "onfocus"; 73937da2899SCharles.Forsyth di.evmask |= E->SEonfocus; 74037da2899SCharles.Forsyth Lex->Aonload => 74137da2899SCharles.Forsyth hname = "onload"; 74237da2899SCharles.Forsyth di.evmask |= E->SEonload; 74337da2899SCharles.Forsyth Lex->Aonresize => 74437da2899SCharles.Forsyth hname = "onresize"; 74537da2899SCharles.Forsyth di.evmask |= E->SEonresize; 74637da2899SCharles.Forsyth Lex->Aonunload => 74737da2899SCharles.Forsyth hname = "onunload"; 74837da2899SCharles.Forsyth di.evmask |= E->SEonunload; 74937da2899SCharles.Forsyth Lex->Aondblclick => 75037da2899SCharles.Forsyth dhname = "ondblclick"; 75137da2899SCharles.Forsyth di.evmask |= E->SEondblclick; 75237da2899SCharles.Forsyth Lex->Aonkeydown => 75337da2899SCharles.Forsyth dhname = "onkeydown"; 75437da2899SCharles.Forsyth di.evmask |= E->SEonkeydown; 75537da2899SCharles.Forsyth Lex->Aonkeypress => 75637da2899SCharles.Forsyth dhname = "onkeypress"; 75737da2899SCharles.Forsyth di.evmask |= E->SEonkeypress; 75837da2899SCharles.Forsyth Lex->Aonkeyup => 75937da2899SCharles.Forsyth dhname = "onkeyup"; 76037da2899SCharles.Forsyth di.evmask |= E->SEonkeyup; 76137da2899SCharles.Forsyth Lex->Aonmousedown => 76237da2899SCharles.Forsyth dhname = "onmousedown"; 76337da2899SCharles.Forsyth di.evmask |= E->SEonmousedown; 76437da2899SCharles.Forsyth Lex->Aonmouseup => 76537da2899SCharles.Forsyth dhname = "onmouseup"; 76637da2899SCharles.Forsyth di.evmask |= E->SEonmouseup; 76737da2899SCharles.Forsyth } 76837da2899SCharles.Forsyth if(hname != "") 76937da2899SCharles.Forsyth puthandler(ex, ow, hname, e.value); 77037da2899SCharles.Forsyth if(dhname != ""){ 77137da2899SCharles.Forsyth od := getobj(ex, ow, "document"); 77237da2899SCharles.Forsyth if(od == nil) { 77337da2899SCharles.Forsyth reinitprop(ow, "document", docinstant(ex, f)); 77437da2899SCharles.Forsyth od = getobj(ex, ow, "document"); 77537da2899SCharles.Forsyth } 77637da2899SCharles.Forsyth puthandler(ex, od, dhname, e.value); 77737da2899SCharles.Forsyth } 77837da2899SCharles.Forsyth } 77937da2899SCharles.Forsyth di.events = nil; 78037da2899SCharles.Forsyth 78137da2899SCharles.Forsyth od := getobj(ex, ow, "document"); 78237da2899SCharles.Forsyth if(od == nil) { 78337da2899SCharles.Forsyth reinitprop(ow, "document", docinstant(ex, f)); 78437da2899SCharles.Forsyth od = getobj(ex, ow, "document"); 78537da2899SCharles.Forsyth CU->assert(od != nil); 78637da2899SCharles.Forsyth } 78737da2899SCharles.Forsyth else if(inbuild) { 78837da2899SCharles.Forsyth docfill(ex, od, f); 78937da2899SCharles.Forsyth ES->put(ex, od, "location", ES->objval(sw.locobj)); 79037da2899SCharles.Forsyth } 79137da2899SCharles.Forsyth for(frml := sw.forms; frml != nil; frml = tl frml) { 79237da2899SCharles.Forsyth frm := hd frml; 79337da2899SCharles.Forsyth for (fldl := frm.fields; fldl != nil; fldl = tl fldl) { 79437da2899SCharles.Forsyth (fld, ofield) := hd fldl; 79537da2899SCharles.Forsyth if (ofield == nil) 79637da2899SCharles.Forsyth continue; 79737da2899SCharles.Forsyth if(fld.ctlid >= 0 && fld.ctlid < len f.controls) { 79837da2899SCharles.Forsyth pick c := f.controls[fld.ctlid] { 79937da2899SCharles.Forsyth Centry => 80037da2899SCharles.Forsyth reinitprop(ofield, "value", ES->strval(c.s)); 80137da2899SCharles.Forsyth Ccheckbox => 80237da2899SCharles.Forsyth cv := ES->false; 80337da2899SCharles.Forsyth if(c.flags&Layout->CFactive) 80437da2899SCharles.Forsyth cv = ES->true; 80537da2899SCharles.Forsyth reinitprop(ofield, "checked", cv); 80637da2899SCharles.Forsyth Cselect => 80737da2899SCharles.Forsyth for(i := 0; i < len c.options; i++) { 80837da2899SCharles.Forsyth if(c.options[i].selected) { 80937da2899SCharles.Forsyth reinitprop(ofield, "selectedIndex", ES->numval(real i)); 81037da2899SCharles.Forsyth # hack for common mistake in scripts 81137da2899SCharles.Forsyth # (implemented by other browsers) 81237da2899SCharles.Forsyth opts := getobj(ex, ofield, "options"); 81337da2899SCharles.Forsyth if (opts != nil) 81437da2899SCharles.Forsyth reinitprop(opts, "selectedIndex", ES->numval(real i)); 81537da2899SCharles.Forsyth } 81637da2899SCharles.Forsyth } 81737da2899SCharles.Forsyth } 81837da2899SCharles.Forsyth } 81937da2899SCharles.Forsyth } 82037da2899SCharles.Forsyth } 82137da2899SCharles.Forsyth for(sil := sw.imgs; sil != nil; sil = tl sil) { 82237da2899SCharles.Forsyth si := hd sil; 82337da2899SCharles.Forsyth if(si.item.ci.complete != 0) 82437da2899SCharles.Forsyth reinitprop(si.obj, "complete", ES->true); 82537da2899SCharles.Forsyth } 82637da2899SCharles.Forsyth} 82737da2899SCharles.Forsyth 82837da2899SCharles.Forsythxferfromscriptobjs(f: ref Layout->Frame, inbuild: int) 82937da2899SCharles.Forsyth{ 83037da2899SCharles.Forsyth sw := top.findbyframeid(f.id); 83137da2899SCharles.Forsyth if(sw == nil) 83237da2899SCharles.Forsyth return; 83337da2899SCharles.Forsyth ex := sw.ex; 83437da2899SCharles.Forsyth ow := ex.global; 83537da2899SCharles.Forsyth od := getobj(ex, ow, "document"); 83637da2899SCharles.Forsyth if(od != nil) { 83737da2899SCharles.Forsyth if(inbuild) { 83837da2899SCharles.Forsyth di := f.doc; 83937da2899SCharles.Forsyth di.doctitle = strxfer(ex, od, "title", di.doctitle); 84037da2899SCharles.Forsyth di.background.color = colorxfer(ex, od, "bgColor", di.background.color); 84137da2899SCharles.Forsyth di.text = colorxfer(ex, od, "fgColor", di.text); 84237da2899SCharles.Forsyth di.alink = colorxfer(ex, od, "alinkColor", di.alink); 84337da2899SCharles.Forsyth di.link = colorxfer(ex, od, "linkColor", di.link); 84437da2899SCharles.Forsyth di.vlink = colorxfer(ex, od, "vlinkColor", di.vlink); 84537da2899SCharles.Forsyth if(createdimages != nil) { 84637da2899SCharles.Forsyth for(oil := createdimages; oil != nil; oil = tl oil) { 84737da2899SCharles.Forsyth oi := hd oil; 84837da2899SCharles.Forsyth vsrc := ES->get(ex, oi, "src"); 84937da2899SCharles.Forsyth if(ES->isstr(vsrc)) { 85037da2899SCharles.Forsyth u := U->parse(vsrc.str); 85137da2899SCharles.Forsyth if(u.path != "") { 85237da2899SCharles.Forsyth u = U->mkabs(u, di.base); 85337da2899SCharles.Forsyth it := Item.newimage(di, u, nil, "", B->Anone, 85437da2899SCharles.Forsyth 0, 0, 0, 0, 0, 0, 0, nil, nil, nil); 85537da2899SCharles.Forsyth di.images = it :: di.images; 85637da2899SCharles.Forsyth } 85737da2899SCharles.Forsyth } 85837da2899SCharles.Forsyth } 85937da2899SCharles.Forsyth } 86037da2899SCharles.Forsyth } 86137da2899SCharles.Forsyth else { 86237da2899SCharles.Forsyth for (ol := sw.imgrelocs; ol != nil; ol = tl ol) { 86337da2899SCharles.Forsyth oi := hd ol; 86437da2899SCharles.Forsyth vnewsrc := ES->get(ex, oi, "src"); 86537da2899SCharles.Forsyth if(ES->isstr(vnewsrc) && vnewsrc.str != nil) { 86637da2899SCharles.Forsyth for(sil := sw.imgs; sil != nil; sil = tl sil) { 86737da2899SCharles.Forsyth si := hd sil; 86837da2899SCharles.Forsyth if(si.obj == oi) { 86937da2899SCharles.Forsyth f.swapimage(si.item, vnewsrc.str); 87037da2899SCharles.Forsyth break; 87137da2899SCharles.Forsyth } 87237da2899SCharles.Forsyth } 87337da2899SCharles.Forsyth } 87437da2899SCharles.Forsyth } 87537da2899SCharles.Forsyth sw.imgrelocs = nil; 87637da2899SCharles.Forsyth } 87737da2899SCharles.Forsyth } 87837da2899SCharles.Forsyth} 87937da2899SCharles.Forsyth 88037da2899SCharles.Forsyth# Check ScriptWin tree for non-empty newlocs. 88137da2899SCharles.Forsyth# When found, generate a go event to the new place. 88237da2899SCharles.Forsyth# If found, don't recurse into children, because those 88337da2899SCharles.Forsyth# child frames are about to go away anyway. 88437da2899SCharles.Forsyth# Otherwise, recurse into all kids -- this might generate 88537da2899SCharles.Forsyth# multiple go events. 88637da2899SCharles.Forsyth# BUG: if multiple events are generated, later ones will 88737da2899SCharles.Forsyth# interrupt (STOP!) loading of pages specified by preceding 88837da2899SCharles.Forsyth# events. To fix, need to queue them up, probably in 88937da2899SCharles.Forsyth# main charon module. 89037da2899SCharles.Forsythchecknewlocs(sw: ref ScriptWin) 89137da2899SCharles.Forsyth{ 89237da2899SCharles.Forsyth if(sw.newloc != "") { 89337da2899SCharles.Forsyth E->evchan <-= ref Event.Ego(sw.newloc, sw.newloctarg, 0, E->EGnormal); 89437da2899SCharles.Forsyth sw.newloc = ""; 89537da2899SCharles.Forsyth } 89637da2899SCharles.Forsyth else { 89737da2899SCharles.Forsyth for(l := sw.kids; l != nil; l = tl l) 89837da2899SCharles.Forsyth checknewlocs(hd l); 89937da2899SCharles.Forsyth } 90037da2899SCharles.Forsyth} 90137da2899SCharles.Forsyth 90237da2899SCharles.Forsythcheckopener() 90337da2899SCharles.Forsyth{ 90437da2899SCharles.Forsyth if(opener != nil && opener.newloc != "") { 90537da2899SCharles.Forsyth CH->sendopener(sys->sprint("L %s", opener.newloc)); # just location for now 90637da2899SCharles.Forsyth opener.newloc = ""; 90737da2899SCharles.Forsyth } 90837da2899SCharles.Forsyth if(winclose) 90937da2899SCharles.Forsyth G->exitcharon(); 91037da2899SCharles.Forsyth} 91137da2899SCharles.Forsyth 91237da2899SCharles.Forsyth# if e.anchorid >= 0 => target is Link 91337da2899SCharles.Forsyth# if e.fieldid > 0 => target is FormField (and e.formid > 0) 91437da2899SCharles.Forsyth# if e.formid > 0 => target is Form (e.fieldid == -1) 91537da2899SCharles.Forsyth# if e.imageid >= 0 => target is Image 91637da2899SCharles.Forsyth# otherwise => target is window 91737da2899SCharles.Forsythdo_on(e: ref ScriptEvent) 91837da2899SCharles.Forsyth{ 91937da2899SCharles.Forsyth if(dbgdom) 92037da2899SCharles.Forsyth sys->print("do_on %d, frameid=%d, formid=%d, fieldid=%d, anchorid=%d, imageid=%d, x=%d, y=%d, which=%d\n", 92137da2899SCharles.Forsyth e.kind, e.frameid, e.formid, e.fieldid, e.anchorid, e.imageid, e.x, e.y, e.which); 92237da2899SCharles.Forsyth if (top.error) { 92337da2899SCharles.Forsyth if (dbgdom) 92437da2899SCharles.Forsyth sys->print("do_on() previous error prevents processing\n"); 92537da2899SCharles.Forsyth if (e.reply != nil) 92637da2899SCharles.Forsyth e.reply <-= nil; 92737da2899SCharles.Forsyth jevchan <-= ref doneevent; 92837da2899SCharles.Forsyth return; 92937da2899SCharles.Forsyth } 93037da2899SCharles.Forsyth sw := top.findbyframeid(e.frameid); 93137da2899SCharles.Forsyth # BUG FIX: Frame can be reset by Charon main thread 93237da2899SCharles.Forsyth # between us getting its ref and using it 93337da2899SCharles.Forsyth # WARNING - xferfromscriptobjs() will not update non-ref-type members of frame adt 93437da2899SCharles.Forsyth # (currently not a problem) as updates will go to our copy 93537da2899SCharles.Forsyth f : ref Frame; 93637da2899SCharles.Forsyth if (sw != nil && !sw.inbuild) { 93737da2899SCharles.Forsyth f = ref *sw.frame; 93837da2899SCharles.Forsyth if (f.doc == nil) 93937da2899SCharles.Forsyth f = nil; 94037da2899SCharles.Forsyth } 94137da2899SCharles.Forsyth if (f == nil) { 94237da2899SCharles.Forsyth if(e.reply != nil) 94337da2899SCharles.Forsyth e.reply <-= nil; 94437da2899SCharles.Forsyth jevchan <-= ref doneevent; 94537da2899SCharles.Forsyth if (dbgdom) 94637da2899SCharles.Forsyth sys->print("do_on() failed to find frame %d\n", e.frameid); 94737da2899SCharles.Forsyth return; 94837da2899SCharles.Forsyth } 94937da2899SCharles.Forsyth ex := sw.ex; 95037da2899SCharles.Forsyth ow := ex.global; 95137da2899SCharles.Forsyth od := getobj(ex, ow, "document"); 95237da2899SCharles.Forsyth sw.docwriteout = nil; 95337da2899SCharles.Forsyth 95437da2899SCharles.Forsyth{ 95537da2899SCharles.Forsyth # event target types 95637da2899SCharles.Forsyth TAnchor, TForm, TFormField, TImage, TDocument, TWindow, Tnone: con iota; 95737da2899SCharles.Forsyth ttype := Tnone; 95837da2899SCharles.Forsyth target, oform: ref Obj; 95937da2899SCharles.Forsyth if(e.anchorid >= 0) { 96037da2899SCharles.Forsyth ttype = TAnchor; 96137da2899SCharles.Forsyth target = getanchorobj(ex, e.frameid, e.anchorid); 96237da2899SCharles.Forsyth } else if(e.formid > 0) { 96337da2899SCharles.Forsyth oform = getformobj(ex, e.frameid, e.formid); 96437da2899SCharles.Forsyth if(e.fieldid > 0) { 96537da2899SCharles.Forsyth ttype = TFormField; 96637da2899SCharles.Forsyth target = getformfieldobj(e.frameid, e.formid, e.fieldid); 96737da2899SCharles.Forsyth } else { 96837da2899SCharles.Forsyth ttype = TForm; 96937da2899SCharles.Forsyth target = oform; 97037da2899SCharles.Forsyth } 97137da2899SCharles.Forsyth } else if(e.imageid >= 0) { 97237da2899SCharles.Forsyth ttype = TImage; 97337da2899SCharles.Forsyth target = getimageobj(ex, e.frameid, e.imageid); 97437da2899SCharles.Forsyth } else if(e.kind == E->SEondblclick || e.kind == E->SEonkeydown || 97537da2899SCharles.Forsyth e.kind == E->SEonkeypress || e.kind == E->SEonkeyup || 97637da2899SCharles.Forsyth e.kind == E->SEonmousedown || e.kind == E->SEonmouseup){ 97737da2899SCharles.Forsyth ttype = TDocument; 97837da2899SCharles.Forsyth target = od; 97937da2899SCharles.Forsyth } else { 98037da2899SCharles.Forsyth ttype = TWindow; 98137da2899SCharles.Forsyth target = ow; 98237da2899SCharles.Forsyth } 98337da2899SCharles.Forsyth if(target != nil) { 98437da2899SCharles.Forsyth oscript: ref Obj; 98537da2899SCharles.Forsyth scrname := ""; 98637da2899SCharles.Forsyth case e.kind { 98737da2899SCharles.Forsyth E->SEonabort => 98837da2899SCharles.Forsyth scrname = "onabort"; 98937da2899SCharles.Forsyth E->SEonblur => 99037da2899SCharles.Forsyth scrname = "onblur"; 99137da2899SCharles.Forsyth E->SEonchange => 99237da2899SCharles.Forsyth scrname = "onchange"; 99337da2899SCharles.Forsyth E->SEonclick => 99437da2899SCharles.Forsyth scrname = "onclick"; 99537da2899SCharles.Forsyth E->SEondblclick => 99637da2899SCharles.Forsyth scrname = "ondblclick"; 99737da2899SCharles.Forsyth E->SEonerror => 99837da2899SCharles.Forsyth scrname = "onerror"; 99937da2899SCharles.Forsyth E->SEonfocus => 100037da2899SCharles.Forsyth scrname = "onfocus"; 100137da2899SCharles.Forsyth E->SEonkeydown => 100237da2899SCharles.Forsyth scrname = "onkeydown"; 100337da2899SCharles.Forsyth E->SEonkeypress => 100437da2899SCharles.Forsyth scrname = "onkeypress"; 100537da2899SCharles.Forsyth E->SEonkeyup => 100637da2899SCharles.Forsyth scrname = "onkeyup"; 100737da2899SCharles.Forsyth E->SEonload => 100837da2899SCharles.Forsyth scrname = "onload"; 100937da2899SCharles.Forsyth E->SEonmousedown => 101037da2899SCharles.Forsyth scrname = "onmousedown"; 101137da2899SCharles.Forsyth E->SEonmouseout => 101237da2899SCharles.Forsyth scrname = "onmouseout"; 101337da2899SCharles.Forsyth E->SEonmouseover => 101437da2899SCharles.Forsyth scrname = "onmouseover"; 101537da2899SCharles.Forsyth E->SEonmouseup => 101637da2899SCharles.Forsyth scrname = "onmouseup"; 101737da2899SCharles.Forsyth E->SEonreset => 101837da2899SCharles.Forsyth scrname = "onreset"; 101937da2899SCharles.Forsyth E->SEonresize => 102037da2899SCharles.Forsyth scrname = "onresize"; 102137da2899SCharles.Forsyth E->SEonselect => 102237da2899SCharles.Forsyth scrname = "onselect"; 102337da2899SCharles.Forsyth E->SEonsubmit => 102437da2899SCharles.Forsyth scrname = "onsubmit"; 102537da2899SCharles.Forsyth E->SEonunload => 102637da2899SCharles.Forsyth scrname = "onunload"; 102737da2899SCharles.Forsyth E->SEtimeout or 102837da2899SCharles.Forsyth E->SEinterval => 102937da2899SCharles.Forsyth oscript = dotimeout(ex, target, e); 103037da2899SCharles.Forsyth E->SEscript => 103137da2899SCharles.Forsyth # TODO - handle document text from evalscript 103237da2899SCharles.Forsyth # need to determine if document is 'open' or not. 10338911721eSCharles.Forsyth (nil, nil, val) := evalscript(f, e.script); 103437da2899SCharles.Forsyth if (e.reply != nil) 103537da2899SCharles.Forsyth e.reply <- = val; 103637da2899SCharles.Forsyth e.reply = nil; 103737da2899SCharles.Forsyth } 103837da2899SCharles.Forsyth if(scrname != "") 103937da2899SCharles.Forsyth oscript = getobj(ex, target, scrname); 104037da2899SCharles.Forsyth if(oscript != nil) { 104137da2899SCharles.Forsyth xfertoscriptobjs(f, 0); 104237da2899SCharles.Forsyth if(dbgdom) 104337da2899SCharles.Forsyth sys->print("calling script\n"); 104437da2899SCharles.Forsyth # establish scope chain per Rhino p. 287 (3rd edition) 104537da2899SCharles.Forsyth oldsc := ex.scopechain; 104637da2899SCharles.Forsyth sc := ow :: nil; 104737da2899SCharles.Forsyth if(ttype != TWindow) { 104837da2899SCharles.Forsyth sc = od :: sc; 104937da2899SCharles.Forsyth if(ttype == TFormField) 105037da2899SCharles.Forsyth sc = oform :: sc; 105137da2899SCharles.Forsyth if(ttype != TDocument) 105237da2899SCharles.Forsyth sc = target :: sc; 105337da2899SCharles.Forsyth } 105437da2899SCharles.Forsyth ex.scopechain = sc; 105537da2899SCharles.Forsyth v := ES->call(ex, oscript, target, nil, 1).val; 105637da2899SCharles.Forsyth # 'fix' for onsubmit 105737da2899SCharles.Forsyth # JS references state that if the handler returns false 105837da2899SCharles.Forsyth # then the action is cancelled. 105937da2899SCharles.Forsyth # other browsers interpret this as "if and only if the handler 106037da2899SCharles.Forsyth # returns false." 106137da2899SCharles.Forsyth # When a function completes normally without returning a value 106237da2899SCharles.Forsyth # its value is 'undefined', toBoolean(undefined) = false 106337da2899SCharles.Forsyth if (v == ES->undefined) 106437da2899SCharles.Forsyth v = ES->true; 106537da2899SCharles.Forsyth else 106637da2899SCharles.Forsyth v = ES->toBoolean(ex, v); 106737da2899SCharles.Forsyth ex.scopechain = oldsc; 106837da2899SCharles.Forsyth # onreset/onsubmit reply channel 106937da2899SCharles.Forsyth if(e.reply != nil) { 107037da2899SCharles.Forsyth ans : string; 107137da2899SCharles.Forsyth if(v == ES->true) 107237da2899SCharles.Forsyth ans = "true"; 107337da2899SCharles.Forsyth e.reply <-= ans; 107437da2899SCharles.Forsyth e.reply = nil; 107537da2899SCharles.Forsyth } 107637da2899SCharles.Forsyth xferfromscriptobjs(f, 0); 107737da2899SCharles.Forsyth checknewlocs(top); 107837da2899SCharles.Forsyth checkopener(); 107937da2899SCharles.Forsyth 108037da2899SCharles.Forsyth if (ttype == TFormField && e.kind == E->SEonclick && v == ES->true) 108137da2899SCharles.Forsyth E->evchan <-= ref Event.Eformfield(e.frameid, e.formid, e.fieldid, E->EFFclick); 108237da2899SCharles.Forsyth if (ttype == TAnchor && e.kind == E->SEonclick && v == ES->true) { 108337da2899SCharles.Forsyth gohref := getstr(ex, target, "href"); 108437da2899SCharles.Forsyth gotarget := getstr(ex, target, "target"); 108537da2899SCharles.Forsyth if (gotarget == "") 108637da2899SCharles.Forsyth gotarget = "_self"; 108737da2899SCharles.Forsyth E->evchan <-= ref Event.Ego(gohref, gotarget, 0, E->EGnormal); 108837da2899SCharles.Forsyth } 108937da2899SCharles.Forsyth } 109037da2899SCharles.Forsyth } 109137da2899SCharles.Forsyth if(e.reply != nil) 109237da2899SCharles.Forsyth e.reply <-= nil; 109337da2899SCharles.Forsyth checkdocwrite(top); 109437da2899SCharles.Forsyth jevchan <-= ref doneevent; 109537da2899SCharles.Forsyth} 109637da2899SCharles.Forsythexception exc{ 109737da2899SCharles.Forsyth "*" => 109837da2899SCharles.Forsyth if (exc == "throw") { 109937da2899SCharles.Forsyth # ignore ecmascript runtime errors 110037da2899SCharles.Forsyth if(dbgdom) 110137da2899SCharles.Forsyth sys->print("error executing 'on' handler: %s\n", ex.error); 110237da2899SCharles.Forsyth } else { 110337da2899SCharles.Forsyth # fatal error 110437da2899SCharles.Forsyth top.error = 1; 110537da2899SCharles.Forsyth emsg := "Fatal error in script ("+exc+"):\n" + ex.error + "\n"; 110637da2899SCharles.Forsyth G->alert(emsg); 110737da2899SCharles.Forsyth } 110837da2899SCharles.Forsyth if(e.reply != nil) 110937da2899SCharles.Forsyth e.reply <-= nil; 111037da2899SCharles.Forsyth jevchan <-= ref doneevent; 111137da2899SCharles.Forsyth return; 111237da2899SCharles.Forsyth} 111337da2899SCharles.Forsyth} 111437da2899SCharles.Forsyth 111537da2899SCharles.Forsythxferframeset(sw : ref ScriptWin) 111637da2899SCharles.Forsyth{ 111737da2899SCharles.Forsyth if (!sw.inbuild) 111837da2899SCharles.Forsyth xfertoscriptobjs(sw.frame, 1); 111937da2899SCharles.Forsyth for (k := sw.kids; k != nil; k = tl k) 112037da2899SCharles.Forsyth xferframeset(hd k); 112137da2899SCharles.Forsyth} 112237da2899SCharles.Forsyth 112337da2899SCharles.Forsythframedone(f : ref Frame, hasscripts : int) 112437da2899SCharles.Forsyth{ 112537da2899SCharles.Forsyth sw := top.findbyframeid(f.id); 112637da2899SCharles.Forsyth if (sw != nil) { 112737da2899SCharles.Forsyth if (!top.active && hasscripts) { 112837da2899SCharles.Forsyth # need to transfer entire frame tree 112937da2899SCharles.Forsyth # as one frame can reference objects in another 113037da2899SCharles.Forsyth xferframeset(top); 113137da2899SCharles.Forsyth } 113237da2899SCharles.Forsyth sw.active |= hasscripts; 113337da2899SCharles.Forsyth top.active |= hasscripts; 113437da2899SCharles.Forsyth if (top.active) 113537da2899SCharles.Forsyth xfertoscriptobjs(f, 1); 113637da2899SCharles.Forsyth sw.inbuild = 0; 113737da2899SCharles.Forsyth } 113837da2899SCharles.Forsyth} 113937da2899SCharles.Forsyth 114037da2899SCharles.Forsythcheckdocwrite(sw : ref ScriptWin) : int 114137da2899SCharles.Forsyth{ 114237da2899SCharles.Forsyth if (sw.inbuild) 114337da2899SCharles.Forsyth return 0; 114437da2899SCharles.Forsyth 114537da2899SCharles.Forsyth if (sw.docwriteout != nil) { 114637da2899SCharles.Forsyth # The URL is bogus - not sure what the correct value should be 114737da2899SCharles.Forsyth ev := ref Event.Esettext(sw.frame.id, sw.frame.src, sw.docwriteout); 114837da2899SCharles.Forsyth sw.docwriteout = ""; 114937da2899SCharles.Forsyth E->evchan <- = ev; 115037da2899SCharles.Forsyth return 1; 115137da2899SCharles.Forsyth } 115237da2899SCharles.Forsyth for (k := sw.kids; k != nil; k = tl k) 115337da2899SCharles.Forsyth if (checkdocwrite(hd k)) 115437da2899SCharles.Forsyth break; 115537da2899SCharles.Forsyth return 0; 115637da2899SCharles.Forsyth} 115737da2899SCharles.Forsyth 115837da2899SCharles.Forsyth# 115937da2899SCharles.Forsyth# interface for host objects 116037da2899SCharles.Forsyth# 116137da2899SCharles.Forsythget(ex: ref Exec, o: ref Obj, property: string): ref Val 116237da2899SCharles.Forsyth{ 116337da2899SCharles.Forsyth if(o.class == "document" && property == "cookie") { 116437da2899SCharles.Forsyth ans := ""; 116537da2899SCharles.Forsyth target := top.findbyobj(o); 116637da2899SCharles.Forsyth if(target != nil) { 116737da2899SCharles.Forsyth url := target.frame.doc.src; 116837da2899SCharles.Forsyth ans = CU->getcookies(url.host, url.path, url.scheme == "https"); 116937da2899SCharles.Forsyth } 117037da2899SCharles.Forsyth return ES->strval(ans); 117137da2899SCharles.Forsyth } 117237da2899SCharles.Forsyth if(o.class == "Window" && property == "opener"){ 117337da2899SCharles.Forsyth if(!CH->hasopener() || top.ex.global != o) 117437da2899SCharles.Forsyth v := ES->undefined; 117537da2899SCharles.Forsyth else{ 117637da2899SCharles.Forsyth if(opener == nil) 117737da2899SCharles.Forsyth opener = ScriptWin.dummy(); 117837da2899SCharles.Forsyth v = ES->objval(opener.ex.global); 117937da2899SCharles.Forsyth } 118037da2899SCharles.Forsyth reinitprop(o, "opener", v); 118137da2899SCharles.Forsyth } 118237da2899SCharles.Forsyth return ES->get(ex, o, property); 118337da2899SCharles.Forsyth} 118437da2899SCharles.Forsyth 118537da2899SCharles.Forsyth 118637da2899SCharles.Forsythput(ex: ref Exec, o: ref Obj, property: string, val: ref Val) 118737da2899SCharles.Forsyth{ 118837da2899SCharles.Forsyth if(dbgdom) 118937da2899SCharles.Forsyth sys->print("put property %s in cobj of class %s\n", property, o.class); 119037da2899SCharles.Forsyth 119137da2899SCharles.Forsyth url : ref Parsedurl; 119237da2899SCharles.Forsyth target : ref ScriptWin; 119337da2899SCharles.Forsyth str := ES->toString(ex, val); 119437da2899SCharles.Forsyth ev := E->SEnone; 119537da2899SCharles.Forsyth 119637da2899SCharles.Forsyth case o.class { 119737da2899SCharles.Forsyth "Array" => 119837da2899SCharles.Forsyth # we 'host' the Formfield.options array so as we can 119937da2899SCharles.Forsyth # track changes to the options list 120037da2899SCharles.Forsyth vformfield := ES->get(ex, o, "@PRIVformfield"); 120137da2899SCharles.Forsyth if (!ES->isobj(vformfield)) 120237da2899SCharles.Forsyth # not one of our 'options' arrays 120337da2899SCharles.Forsyth break; 120437da2899SCharles.Forsyth ix := prop2index(property); 120537da2899SCharles.Forsyth if (property != "length" && ix == -1) 120637da2899SCharles.Forsyth # not a property that affects us 120737da2899SCharles.Forsyth break; 120837da2899SCharles.Forsyth oformfield := vformfield.obj; 120937da2899SCharles.Forsyth oform := getobj(ex, oformfield, "form"); 121037da2899SCharles.Forsyth if (oform == nil) 121137da2899SCharles.Forsyth break; 121237da2899SCharles.Forsyth ES->put(ex, o, property, val); 121337da2899SCharles.Forsyth if (ES->isobj(val) && val.obj.class == "Option") { 121437da2899SCharles.Forsyth ES->put(ex, val.obj, "@PRIVformfield", vformfield); 121537da2899SCharles.Forsyth ES->put(ex, val.obj, "form", ES->objval(oform)); 121637da2899SCharles.Forsyth reinitprop(val.obj, "index", ES->numval(real ix)); 121737da2899SCharles.Forsyth } 121837da2899SCharles.Forsyth updateffopts(ex, oform, oformfield, ix); 121937da2899SCharles.Forsyth return; 122037da2899SCharles.Forsyth "Window" => 122137da2899SCharles.Forsyth case property { 122237da2899SCharles.Forsyth "defaultStatus" or 122337da2899SCharles.Forsyth "status" => 122437da2899SCharles.Forsyth if(ES->isstr(val)) { 122537da2899SCharles.Forsyth if(property == "defaultStatus") 122637da2899SCharles.Forsyth defaultStatus = val.str; 122737da2899SCharles.Forsyth G->setstatus(val.str); 122837da2899SCharles.Forsyth } 122937da2899SCharles.Forsyth "location" => 123037da2899SCharles.Forsyth target = top.findbyobj(o); 123137da2899SCharles.Forsyth if (target == nil) 123237da2899SCharles.Forsyth break; 123337da2899SCharles.Forsyth url = U->parse(str); 123437da2899SCharles.Forsyth # TODO: be more defensive 123537da2899SCharles.Forsyth url = U->mkabs(url, target.frame.doc.base); 123637da2899SCharles.Forsyth "name" => 123737da2899SCharles.Forsyth sw := top.findbyobj(o); 123837da2899SCharles.Forsyth if (sw == nil) 123937da2899SCharles.Forsyth break; 124037da2899SCharles.Forsyth name := ES->toString(ex, val); 124137da2899SCharles.Forsyth if (sw.parent != nil) { 124237da2899SCharles.Forsyth w := sw.parent.ex.global; 124337da2899SCharles.Forsyth v := sw.val; 124437da2899SCharles.Forsyth if (sw.frame.name != nil) 124537da2899SCharles.Forsyth ES->delete(ex, w, sw.frame.name); 124637da2899SCharles.Forsyth ES->varinstant(w, 0, name, ref RefVal(v)); 124737da2899SCharles.Forsyth } 124837da2899SCharles.Forsyth # Window.name is used for determining TARGET of <A> etc. 124937da2899SCharles.Forsyth # update Charon's Frame info so as new name gets used properly 125037da2899SCharles.Forsyth sw.frame.name = name; 125137da2899SCharles.Forsyth "offscreenBuffering" => 125237da2899SCharles.Forsyth if(ES->isstr(val) || val == ES->true || val == ES->false){ 125337da2899SCharles.Forsyth } 125437da2899SCharles.Forsyth "onblur" => 125537da2899SCharles.Forsyth ev = E->SEonblur; 125637da2899SCharles.Forsyth "onerror" => 125737da2899SCharles.Forsyth ev = E->SEonerror; 125837da2899SCharles.Forsyth "onfocus" => 125937da2899SCharles.Forsyth ev = E->SEonfocus; 126037da2899SCharles.Forsyth "onload" => 126137da2899SCharles.Forsyth ev = E->SEonload; 126237da2899SCharles.Forsyth "onresize" => 126337da2899SCharles.Forsyth ev = E->SEonresize; 126437da2899SCharles.Forsyth "onunload" => 126537da2899SCharles.Forsyth ev = E->SEonunload; 126637da2899SCharles.Forsyth "opener" => 126737da2899SCharles.Forsyth ; 126837da2899SCharles.Forsyth } 126937da2899SCharles.Forsyth if(ev != E->SEnone) { 127037da2899SCharles.Forsyth target = top.findbyobj(o); 127137da2899SCharles.Forsyth if(target == nil) 127237da2899SCharles.Forsyth break; 127337da2899SCharles.Forsyth di := target.frame.doc; 127437da2899SCharles.Forsyth if(!ES->isobj(val) || val.obj.call == nil) 127537da2899SCharles.Forsyth di.evmask &= ~ev; 127637da2899SCharles.Forsyth else 127737da2899SCharles.Forsyth di.evmask |= ev; 127837da2899SCharles.Forsyth } 127937da2899SCharles.Forsyth "Link" => 128037da2899SCharles.Forsyth case property { 128137da2899SCharles.Forsyth "onclick" => 128237da2899SCharles.Forsyth ev = E->SEonclick; 128337da2899SCharles.Forsyth "ondblclick" => 128437da2899SCharles.Forsyth ev = E->SEondblclick; 128537da2899SCharles.Forsyth "onkeydown" => 128637da2899SCharles.Forsyth ev = E->SEonkeydown; 128737da2899SCharles.Forsyth "onkeypress" => 128837da2899SCharles.Forsyth ev = E->SEonkeypress; 128937da2899SCharles.Forsyth "onkeyup" => 129037da2899SCharles.Forsyth ev = E->SEonkeyup; 129137da2899SCharles.Forsyth "onmousedown" => 129237da2899SCharles.Forsyth ev = E->SEonmousedown; 129337da2899SCharles.Forsyth "onmouseout" => 129437da2899SCharles.Forsyth ev = E->SEonmouseout; 129537da2899SCharles.Forsyth "onmouseover" => 129637da2899SCharles.Forsyth ev = E->SEonmouseover; 129737da2899SCharles.Forsyth "onmouseup" => 129837da2899SCharles.Forsyth ev = E->SEonmouseup; 129937da2899SCharles.Forsyth } 130037da2899SCharles.Forsyth if(ev != E->SEnone) { 130137da2899SCharles.Forsyth vframeid := ES->get(ex, o, "@PRIVframeid"); 130237da2899SCharles.Forsyth vanchorid := ES->get(ex, o, "@PRIVanchorid"); 130337da2899SCharles.Forsyth if(!ES->isnum(vframeid) || !ES->isnum(vanchorid)) 130437da2899SCharles.Forsyth break; 130537da2899SCharles.Forsyth frameid := ES->toInt32(ex, vframeid); 130637da2899SCharles.Forsyth anchorid := ES->toInt32(ex, vanchorid); 130737da2899SCharles.Forsyth target = top.findbyframeid(frameid); 130837da2899SCharles.Forsyth if(target == nil) 130937da2899SCharles.Forsyth break; 131037da2899SCharles.Forsyth anchor: ref B->Anchor; 131137da2899SCharles.Forsyth for(al := target.frame.doc.anchors; al != nil; al = tl al) { 131237da2899SCharles.Forsyth a := hd al; 131337da2899SCharles.Forsyth if(a.index == anchorid) { 131437da2899SCharles.Forsyth anchor = a; 131537da2899SCharles.Forsyth break; 131637da2899SCharles.Forsyth } 131737da2899SCharles.Forsyth } 131837da2899SCharles.Forsyth if(anchor == nil) 131937da2899SCharles.Forsyth break; 132037da2899SCharles.Forsyth if(!ES->isobj(val) || val.obj.call == nil) 132137da2899SCharles.Forsyth anchor.evmask &= ~ev; 132237da2899SCharles.Forsyth else 132337da2899SCharles.Forsyth anchor.evmask |= ev; 132437da2899SCharles.Forsyth } 132537da2899SCharles.Forsyth "Location" => 132637da2899SCharles.Forsyth target = top.findbyobj(o); 132737da2899SCharles.Forsyth if (target == nil) { 132837da2899SCharles.Forsyth break; 132937da2899SCharles.Forsyth } 133037da2899SCharles.Forsyth url = ref *target.frame.doc.src; 133137da2899SCharles.Forsyth case property { 133237da2899SCharles.Forsyth "hash" => 133337da2899SCharles.Forsyth if (str != nil && str[0] == '#') 133437da2899SCharles.Forsyth str = str[1:]; 133537da2899SCharles.Forsyth url.frag = str; 133637da2899SCharles.Forsyth "host" => 133737da2899SCharles.Forsyth # host:port 133837da2899SCharles.Forsyth (h, p) := S->splitl(str, ":"); 133937da2899SCharles.Forsyth if (p != nil) 134037da2899SCharles.Forsyth p = p[1:]; 134137da2899SCharles.Forsyth if (h != nil) 134237da2899SCharles.Forsyth url.host = h; 134337da2899SCharles.Forsyth if (p != nil) 134437da2899SCharles.Forsyth url.port = p; 134537da2899SCharles.Forsyth "hostname" => 134637da2899SCharles.Forsyth url.host = str; 134737da2899SCharles.Forsyth "href" or 134837da2899SCharles.Forsyth "pathname" => 134937da2899SCharles.Forsyth url = U->mkabs(U->parse(str), target.frame.doc.base); 135037da2899SCharles.Forsyth "port" => 135137da2899SCharles.Forsyth url.port = str; 135237da2899SCharles.Forsyth "protocol" => 135337da2899SCharles.Forsyth url.scheme = S->tolower(str); 135437da2899SCharles.Forsyth "search" => 135537da2899SCharles.Forsyth url.query = str; 135637da2899SCharles.Forsyth * => 135737da2899SCharles.Forsyth url = nil; 135837da2899SCharles.Forsyth } 135937da2899SCharles.Forsyth "Image" => 136037da2899SCharles.Forsyth case property { 136137da2899SCharles.Forsyth "src" or 136237da2899SCharles.Forsyth "lowsrc" => 136337da2899SCharles.Forsyth # making URLs absolute matches Netscape 136437da2899SCharles.Forsyth target = top.findbyobj(o); 136537da2899SCharles.Forsyth if(target == nil) 136637da2899SCharles.Forsyth break; 136737da2899SCharles.Forsyth url = U->mkabs(U->parse(str), target.frame.doc.base); 136837da2899SCharles.Forsyth val = ES->strval(url.tostring()); 136937da2899SCharles.Forsyth target.imgrelocs = o :: target.imgrelocs; 137037da2899SCharles.Forsyth url = nil; 137137da2899SCharles.Forsyth "onabort" => 137237da2899SCharles.Forsyth ev = E->SEonabort; 137337da2899SCharles.Forsyth "ondblclick" => 137437da2899SCharles.Forsyth ev = E->SEondblclick; 137537da2899SCharles.Forsyth "onkeydown" => 137637da2899SCharles.Forsyth ev = E->SEonkeydown; 137737da2899SCharles.Forsyth "onkeypress" => 137837da2899SCharles.Forsyth ev = E->SEonkeypress; 137937da2899SCharles.Forsyth "onkeyup" => 138037da2899SCharles.Forsyth ev = E->SEonkeyup; 138137da2899SCharles.Forsyth "onerror" => 138237da2899SCharles.Forsyth ev = E->SEonerror; 138337da2899SCharles.Forsyth "onload" => 138437da2899SCharles.Forsyth ev = E->SEonload; 138537da2899SCharles.Forsyth "onmousedown" => 138637da2899SCharles.Forsyth ev = E->SEonmousedown; 138737da2899SCharles.Forsyth "onmouseout" => 138837da2899SCharles.Forsyth ev = E->SEonmouseout; 138937da2899SCharles.Forsyth "onmouseover" => 139037da2899SCharles.Forsyth ev = E->SEonmouseover; 139137da2899SCharles.Forsyth "onmouseup" => 139237da2899SCharles.Forsyth ev = E->SEonmouseup; 139337da2899SCharles.Forsyth } 139437da2899SCharles.Forsyth if(ev != E->SEnone) { 139537da2899SCharles.Forsyth target = top.findbyobj(o); 139637da2899SCharles.Forsyth if(target == nil) 139737da2899SCharles.Forsyth break; 139837da2899SCharles.Forsyth vimageid := ES->get(ex, o, "@PRIVimageid"); 139937da2899SCharles.Forsyth if(!ES->isnum(vimageid)) 140037da2899SCharles.Forsyth break; 140137da2899SCharles.Forsyth imageid := ES->toInt32(ex, vimageid); 140237da2899SCharles.Forsyth image: ref (Build->Item).Iimage; 140337da2899SCharles.Forsyth forloop: 140437da2899SCharles.Forsyth for(il := target.frame.doc.images; il != nil; il = tl il) { 140537da2899SCharles.Forsyth pick im := hd il { 140637da2899SCharles.Forsyth Iimage => 140737da2899SCharles.Forsyth if(im.imageid == imageid) { 140837da2899SCharles.Forsyth image = im; 140937da2899SCharles.Forsyth break forloop; 141037da2899SCharles.Forsyth } 141137da2899SCharles.Forsyth } 141237da2899SCharles.Forsyth } 141337da2899SCharles.Forsyth # BUG: if image has no genattr then the event handler update 141437da2899SCharles.Forsyth # will not be done - can never set a handler for an image that 141537da2899SCharles.Forsyth # didn't have a handler 141637da2899SCharles.Forsyth if(image == nil || image.genattr == nil) 141737da2899SCharles.Forsyth break; 141837da2899SCharles.Forsyth if(!ES->isobj(val) || val.obj.call == nil) 141937da2899SCharles.Forsyth image.genattr.evmask &= ~ev; 142037da2899SCharles.Forsyth else 142137da2899SCharles.Forsyth image.genattr.evmask |= ev; 142237da2899SCharles.Forsyth } 142337da2899SCharles.Forsyth "Form" => 142437da2899SCharles.Forsyth action := ""; 142537da2899SCharles.Forsyth case property { 142637da2899SCharles.Forsyth "onreset" => 142737da2899SCharles.Forsyth ev = E->SEonreset; 142837da2899SCharles.Forsyth "onsubmit" => 142937da2899SCharles.Forsyth ev = E->SEonsubmit; 143037da2899SCharles.Forsyth "action" => 143137da2899SCharles.Forsyth action = str; 143237da2899SCharles.Forsyth * => 143337da2899SCharles.Forsyth break; 143437da2899SCharles.Forsyth } 143537da2899SCharles.Forsyth vframeid := ES->get(ex, o, "@PRIVframeid"); 143637da2899SCharles.Forsyth vformid := ES->get(ex, o, "@PRIVformid"); 143737da2899SCharles.Forsyth if(!ES->isnum(vframeid) || !ES->isnum(vformid)) 143837da2899SCharles.Forsyth break; 143937da2899SCharles.Forsyth frameid := ES->toInt32(ex, vframeid); 144037da2899SCharles.Forsyth formid := ES->toInt32(ex, vformid); 144137da2899SCharles.Forsyth target = top.findbyframeid(frameid); 144237da2899SCharles.Forsyth if(target == nil) 144337da2899SCharles.Forsyth break; 144437da2899SCharles.Forsyth form: ref B->Form; 144537da2899SCharles.Forsyth for(fl := target.frame.doc.forms; fl != nil; fl = tl fl) { 144637da2899SCharles.Forsyth f := hd fl; 144737da2899SCharles.Forsyth if(f.formid == formid) { 144837da2899SCharles.Forsyth form = f; 144937da2899SCharles.Forsyth break; 145037da2899SCharles.Forsyth } 145137da2899SCharles.Forsyth } 145237da2899SCharles.Forsyth if(form == nil) 145337da2899SCharles.Forsyth break; 145437da2899SCharles.Forsyth if (ev != E->SEnone) { 145537da2899SCharles.Forsyth if(!ES->isobj(val) || val.obj.call == nil) 145637da2899SCharles.Forsyth form.evmask &= ~ev; 145737da2899SCharles.Forsyth else 145837da2899SCharles.Forsyth form.evmask |= ev; 145937da2899SCharles.Forsyth break; 146037da2899SCharles.Forsyth } 146137da2899SCharles.Forsyth if (action != "") 146237da2899SCharles.Forsyth form.action = U->mkabs(U->parse(action), target.frame.doc.base); 146337da2899SCharles.Forsyth "FormField" => 146437da2899SCharles.Forsyth oform := getobj(ex, o, "form"); 146537da2899SCharles.Forsyth vframeid := ES->get(ex, oform, "@PRIVframeid"); 146637da2899SCharles.Forsyth vformid := ES->get(ex, oform, "@PRIVformid"); 146737da2899SCharles.Forsyth vfieldid := ES->get(ex, o, "@PRIVfieldid"); 146837da2899SCharles.Forsyth if(!ES->isnum(vframeid) || !ES->isnum(vformid) || !ES->isnum(vfieldid)) 146937da2899SCharles.Forsyth break; 147037da2899SCharles.Forsyth frameid := ES->toInt32(ex, vframeid); 147137da2899SCharles.Forsyth formid := ES->toInt32(ex, vformid); 147237da2899SCharles.Forsyth fieldid := ES->toInt32(ex, vfieldid); 147337da2899SCharles.Forsyth target = top.findbyframeid(frameid); 147437da2899SCharles.Forsyth if(target == nil) 147537da2899SCharles.Forsyth break; 147637da2899SCharles.Forsyth form: ref B->Form; 147737da2899SCharles.Forsyth for(fl := target.frame.doc.forms; fl != nil; fl = tl fl) { 147837da2899SCharles.Forsyth f := hd fl; 147937da2899SCharles.Forsyth if(f.formid == formid) { 148037da2899SCharles.Forsyth form = f; 148137da2899SCharles.Forsyth break; 148237da2899SCharles.Forsyth } 148337da2899SCharles.Forsyth } 148437da2899SCharles.Forsyth if(form == nil) 148537da2899SCharles.Forsyth break; 148637da2899SCharles.Forsyth field: ref B->Formfield; 148737da2899SCharles.Forsyth for(ffl := form.fields; ffl != nil; ffl = tl ffl) { 148837da2899SCharles.Forsyth ff := hd ffl; 148937da2899SCharles.Forsyth if(ff.fieldid == fieldid) { 149037da2899SCharles.Forsyth field = ff; 149137da2899SCharles.Forsyth break; 149237da2899SCharles.Forsyth } 149337da2899SCharles.Forsyth } 149437da2899SCharles.Forsyth if(field == nil) 149537da2899SCharles.Forsyth break; 149637da2899SCharles.Forsyth case property { 149737da2899SCharles.Forsyth "onblur" => 149837da2899SCharles.Forsyth ev = E->SEonblur; 149937da2899SCharles.Forsyth "onchange" => 150037da2899SCharles.Forsyth ev = E->SEonchange; 150137da2899SCharles.Forsyth "onclick" => 150237da2899SCharles.Forsyth ev = E->SEonclick; 150337da2899SCharles.Forsyth "ondblclick" => 150437da2899SCharles.Forsyth ev = E->SEondblclick; 150537da2899SCharles.Forsyth "onfocus" => 150637da2899SCharles.Forsyth ev = E->SEonfocus; 150737da2899SCharles.Forsyth "onkeydown" => 150837da2899SCharles.Forsyth ev = E->SEonkeydown; 150937da2899SCharles.Forsyth "onkeypress" => 151037da2899SCharles.Forsyth ev = E->SEonkeypress; 151137da2899SCharles.Forsyth "onkeyup" => 151237da2899SCharles.Forsyth ev = E->SEonkeyup; 151337da2899SCharles.Forsyth "onmousedown" => 151437da2899SCharles.Forsyth ev = E->SEonmousedown; 151537da2899SCharles.Forsyth "onmouseup" => 151637da2899SCharles.Forsyth ev = E->SEonmouseup; 151737da2899SCharles.Forsyth "onselect" => 151837da2899SCharles.Forsyth ev = E->SEonselect; 151937da2899SCharles.Forsyth "value" => 152037da2899SCharles.Forsyth field.value = str; 152137da2899SCharles.Forsyth if(target.frame.controls == nil || 152237da2899SCharles.Forsyth field.ctlid < 0 || 152337da2899SCharles.Forsyth field.ctlid > len target.frame.controls){ 152437da2899SCharles.Forsyth break; 152537da2899SCharles.Forsyth } 152637da2899SCharles.Forsyth c := target.frame.controls[field.ctlid]; 152737da2899SCharles.Forsyth pick ctl := c { 152837da2899SCharles.Forsyth Centry => 152937da2899SCharles.Forsyth ctl.s = str; 153037da2899SCharles.Forsyth ctl.sel = (0, 0); 153137da2899SCharles.Forsyth E->evchan <-= ref Event.Eformfield(frameid, formid, fieldid, E->EFFredraw); 153237da2899SCharles.Forsyth } 153337da2899SCharles.Forsyth } 153437da2899SCharles.Forsyth 153537da2899SCharles.Forsyth if(ev != E->SEnone) { 153637da2899SCharles.Forsyth if(!ES->isobj(val) || val.obj.call == nil) 153737da2899SCharles.Forsyth field.evmask &= ~ev; 153837da2899SCharles.Forsyth else 153937da2899SCharles.Forsyth field.evmask |= ev; 154037da2899SCharles.Forsyth } 154137da2899SCharles.Forsyth "document" => 154237da2899SCharles.Forsyth case property { 154337da2899SCharles.Forsyth "location" => 154437da2899SCharles.Forsyth target = top.findbyobj(o); 154537da2899SCharles.Forsyth if (target == nil) 154637da2899SCharles.Forsyth break; 154737da2899SCharles.Forsyth # TODO: be more defensive 154837da2899SCharles.Forsyth url = U->mkabs(U->parse(str), target.frame.doc.base); 154937da2899SCharles.Forsyth "cookie" => 155037da2899SCharles.Forsyth target = top.findbyobj(o); 155137da2899SCharles.Forsyth if(target != nil && (CU->config).docookies > 0) { 155237da2899SCharles.Forsyth url = target.frame.doc.src; 155337da2899SCharles.Forsyth CU->setcookie(url.host, url.path, str); 155437da2899SCharles.Forsyth } 155537da2899SCharles.Forsyth return; 155637da2899SCharles.Forsyth "ondblclick" => 155737da2899SCharles.Forsyth ev = E->SEondblclick; 155837da2899SCharles.Forsyth "onkeydown" => 155937da2899SCharles.Forsyth ev = E->SEonkeydown; 156037da2899SCharles.Forsyth "onkeypress" => 156137da2899SCharles.Forsyth ev = E->SEonkeypress; 156237da2899SCharles.Forsyth "onkeyup" => 156337da2899SCharles.Forsyth ev = E->SEonkeyup; 156437da2899SCharles.Forsyth "onmousedown" => 156537da2899SCharles.Forsyth ev = E->SEonmousedown; 156637da2899SCharles.Forsyth "onmouseup" => 156737da2899SCharles.Forsyth ev = E->SEonmouseup; 156837da2899SCharles.Forsyth } 156937da2899SCharles.Forsyth if(ev != E->SEnone){ 157037da2899SCharles.Forsyth target = top.findbyobj(o); 157137da2899SCharles.Forsyth if(target == nil) 157237da2899SCharles.Forsyth break; 157337da2899SCharles.Forsyth di := target.frame.doc; 157437da2899SCharles.Forsyth if(!ES->isobj(val) || val.obj.call == nil) 157537da2899SCharles.Forsyth di.evmask &= ~ev; 157637da2899SCharles.Forsyth else 157737da2899SCharles.Forsyth di.evmask |= ev; 157837da2899SCharles.Forsyth } 157937da2899SCharles.Forsyth "Option" => 158037da2899SCharles.Forsyth vformfield := ES->get(ex, o, "@PRIVformfield"); 158137da2899SCharles.Forsyth vindex := ES->get(ex, o, "index"); 158237da2899SCharles.Forsyth if (!ES->isobj(vformfield) || !ES->isnum(vindex)) 158337da2899SCharles.Forsyth # not one of our 'options' objects 158437da2899SCharles.Forsyth break; 158537da2899SCharles.Forsyth oformfield := vformfield.obj; 158637da2899SCharles.Forsyth oform := getobj(ex, oformfield, "form"); 158737da2899SCharles.Forsyth if (oform == nil) 158837da2899SCharles.Forsyth break; 158937da2899SCharles.Forsyth ES->put(ex, o, property, val); 159037da2899SCharles.Forsyth index := ES->toInt32(ex, vindex); 159137da2899SCharles.Forsyth updateffopts(ex, oform, oformfield, index); 159237da2899SCharles.Forsyth } 159337da2899SCharles.Forsyth ES->put(ex, o, property, val); 159437da2899SCharles.Forsyth 159537da2899SCharles.Forsyth if (url != nil && target != nil) { 159637da2899SCharles.Forsyth if (!CU->urlequal(url, target.frame.doc.src)) { 159737da2899SCharles.Forsyth target.newloc = url.tostring(); 159837da2899SCharles.Forsyth target.newloctarg = "_top"; 159937da2899SCharles.Forsyth if(target.frame != nil) 160037da2899SCharles.Forsyth target.newloctarg = target.frame.name; 160137da2899SCharles.Forsyth } 160237da2899SCharles.Forsyth } 160337da2899SCharles.Forsyth} 160437da2899SCharles.Forsyth 160537da2899SCharles.Forsythcanput(ex: ref Exec, o: ref Obj, property: string): ref Val 160637da2899SCharles.Forsyth{ 160737da2899SCharles.Forsyth return ES->canput(ex, o, property); 160837da2899SCharles.Forsyth} 160937da2899SCharles.Forsyth 161037da2899SCharles.Forsythhasproperty(ex: ref Exec, o: ref Obj, property: string): ref Val 161137da2899SCharles.Forsyth{ 161237da2899SCharles.Forsyth return ES->hasproperty(ex, o, property); 161337da2899SCharles.Forsyth} 161437da2899SCharles.Forsyth 161537da2899SCharles.Forsythdelete(ex: ref Exec, o: ref Obj, property: string) 161637da2899SCharles.Forsyth{ 161737da2899SCharles.Forsyth ES->delete(ex, o, property); 161837da2899SCharles.Forsyth} 161937da2899SCharles.Forsyth 162037da2899SCharles.Forsythdefaultval(ex: ref Exec, o: ref Obj, tyhint: int): ref Val 162137da2899SCharles.Forsyth{ 162237da2899SCharles.Forsyth return ES->defaultval(ex, o, tyhint); 162337da2899SCharles.Forsyth} 162437da2899SCharles.Forsyth 162537da2899SCharles.Forsythcall(ex: ref Exec, func, this: ref Obj, args: array of ref Val, nil: int): ref Ref 162637da2899SCharles.Forsyth{ 162737da2899SCharles.Forsyth if(dbgdom) 162837da2899SCharles.Forsyth sys->print("call %x (class %s), val %s\n", func, func.class, func.val.str); 162937da2899SCharles.Forsyth ans := ES->valref(ES->true); 163037da2899SCharles.Forsyth case func.val.str{ 163137da2899SCharles.Forsyth "document.prototype.open" => 163237da2899SCharles.Forsyth sw := top.findbyobj(this); 163337da2899SCharles.Forsyth if (sw != nil) 163437da2899SCharles.Forsyth sw.docwriteout = ""; 163537da2899SCharles.Forsyth "document.prototype.close" => 163637da2899SCharles.Forsyth # ignore for now 163737da2899SCharles.Forsyth ; 163837da2899SCharles.Forsyth "document.prototype.write" => 163937da2899SCharles.Forsyth sw := top.findbyobj(this); 164037da2899SCharles.Forsyth if (sw != nil) { 164137da2899SCharles.Forsyth for (ai := 0; ai < len args; ai++) 164237da2899SCharles.Forsyth sw.docwriteout += ES->toString(ex, ES->biarg(args, ai)); 164337da2899SCharles.Forsyth } 164437da2899SCharles.Forsyth "document.prototype.writeln" => 164537da2899SCharles.Forsyth sw := top.findbyobj(this); 164637da2899SCharles.Forsyth if (sw != nil) { 164737da2899SCharles.Forsyth for (ai := 0; ai < len args; ai++) 164837da2899SCharles.Forsyth sw.docwriteout += ES->toString(ex, ES->biarg(args, ai)); 164937da2899SCharles.Forsyth sw.docwriteout += "\n"; 165037da2899SCharles.Forsyth } 165137da2899SCharles.Forsyth "navigator.prototype.javaEnabled" or 165237da2899SCharles.Forsyth "navigator.prototype.taintEnabled" => 165337da2899SCharles.Forsyth ans = ES->valref(ES->false); 165437da2899SCharles.Forsyth "Form.prototype.reset" or "Form.prototype.submit"=> 165537da2899SCharles.Forsyth vframeid := ES->get(ex, this, "@PRIVframeid"); 165637da2899SCharles.Forsyth vformid := ES->get(ex, this, "@PRIVformid"); 165737da2899SCharles.Forsyth if(ES->isnum(vframeid) && ES->isnum(vformid)) { 165837da2899SCharles.Forsyth frameid := ES->toInt32(ex, vframeid); 165937da2899SCharles.Forsyth formid := ES->toInt32(ex, vformid); 166037da2899SCharles.Forsyth ftype : int; 166137da2899SCharles.Forsyth if(func.val.str == "Form.prototype.reset") 166237da2899SCharles.Forsyth ftype = E->EFreset; 166337da2899SCharles.Forsyth else 166437da2899SCharles.Forsyth ftype = E->EFsubmit; 166537da2899SCharles.Forsyth E->evchan <-= ref Event.Eform(frameid, formid, ftype); 166637da2899SCharles.Forsyth } 166737da2899SCharles.Forsyth "FormField.prototype.blur" or 166837da2899SCharles.Forsyth "FormField.prototype.click" or 166937da2899SCharles.Forsyth "FormField.prototype.focus" or 167037da2899SCharles.Forsyth "FormField.prototype.select" => 167137da2899SCharles.Forsyth oform := getobj(ex, this, "form"); 167237da2899SCharles.Forsyth vformid := ES->get(ex, oform, "@PRIVformid"); 167337da2899SCharles.Forsyth vframeid := ES->get(ex, oform, "@PRIVframeid"); 167437da2899SCharles.Forsyth vfieldid := ES->get(ex, this, "@PRIVfieldid"); 167537da2899SCharles.Forsyth if(ES->isnum(vframeid) && ES->isnum(vformid) && ES->isnum(vfieldid)) { 167637da2899SCharles.Forsyth frameid := ES->toInt32(ex, vframeid); 167737da2899SCharles.Forsyth formid := ES->toInt32(ex, vformid); 167837da2899SCharles.Forsyth fieldid := ES->toInt32(ex, vfieldid); 167937da2899SCharles.Forsyth fftype : int; 168037da2899SCharles.Forsyth case func.val.str{ 168137da2899SCharles.Forsyth "FormField.prototype.blur" => 168237da2899SCharles.Forsyth fftype = E->EFFblur; 168337da2899SCharles.Forsyth "FormField.prototype.click" => 168437da2899SCharles.Forsyth fftype = E->EFFclick; 168537da2899SCharles.Forsyth "FormField.prototype.focus" => 168637da2899SCharles.Forsyth fftype = E->EFFfocus; 168737da2899SCharles.Forsyth "FormField.prototype.select" => 168837da2899SCharles.Forsyth fftype = E->EFFselect; 168937da2899SCharles.Forsyth * => 169037da2899SCharles.Forsyth fftype = E->EFFnone; 169137da2899SCharles.Forsyth } 169237da2899SCharles.Forsyth E->evchan <-= ref Event.Eformfield(frameid, formid, fieldid, fftype); 169337da2899SCharles.Forsyth } 169437da2899SCharles.Forsyth "History.prototype.back" => 169537da2899SCharles.Forsyth E->evchan <-= ref Event.Ego("", "", 0, E->EGback); 169637da2899SCharles.Forsyth "History.prototype.forward" => 169737da2899SCharles.Forsyth E->evchan <-= ref Event.Ego("", "", 0, E->EGforward); 169837da2899SCharles.Forsyth "History.prototype.go" => 169937da2899SCharles.Forsyth ego : ref Event.Ego; 170037da2899SCharles.Forsyth v := ES->biarg(args, 0); 170137da2899SCharles.Forsyth if(ES->isstr(v)) 170237da2899SCharles.Forsyth ego = ref Event.Ego(v.str, "", 0, E->EGlocation); 170337da2899SCharles.Forsyth else if(ES->isnum(v)) { 170437da2899SCharles.Forsyth delta := ES->toInt32(ex, v); 170537da2899SCharles.Forsyth case delta { 170637da2899SCharles.Forsyth -1 => 170737da2899SCharles.Forsyth ego = ref Event.Ego("", "", 0, E->EGback); 170837da2899SCharles.Forsyth 0 => 170937da2899SCharles.Forsyth ego = ref Event.Ego("", "", 0, E->EGreload); 171037da2899SCharles.Forsyth 1 => 171137da2899SCharles.Forsyth ego = ref Event.Ego("", "", 0, E->EGforward); 171237da2899SCharles.Forsyth * => 171337da2899SCharles.Forsyth ego = ref Event.Ego("", "", delta, E->EGdelta); 171437da2899SCharles.Forsyth } 171537da2899SCharles.Forsyth } 171637da2899SCharles.Forsyth if(ego != nil) 171737da2899SCharles.Forsyth E->evchan <-= ego; 171837da2899SCharles.Forsyth "Location.prototype.reload" => 171937da2899SCharles.Forsyth # ignore 'force' argument for now 172037da2899SCharles.Forsyth E->evchan <-= ref Event.Ego("", "", 0, E->EGreload); 172137da2899SCharles.Forsyth "Location.prototype.replace" => 172237da2899SCharles.Forsyth v := ES->biarg(args, 0); 172337da2899SCharles.Forsyth if(ES->isstr(v)) { 172437da2899SCharles.Forsyth sw := top.findbyobj(this); 172537da2899SCharles.Forsyth if(sw == nil) 172637da2899SCharles.Forsyth fname := "_top"; 172737da2899SCharles.Forsyth else 172837da2899SCharles.Forsyth fname = sw.frame.name; 172937da2899SCharles.Forsyth if (v.str != nil) { 173037da2899SCharles.Forsyth url := U->mkabs(U->parse(v.str), sw.frame.doc.base); 173137da2899SCharles.Forsyth E->evchan <-= ref Event.Ego(url.tostring(), fname, 0, E->EGreplace); 173237da2899SCharles.Forsyth } 173337da2899SCharles.Forsyth } 173437da2899SCharles.Forsyth "Window.prototype.alert" => 173537da2899SCharles.Forsyth G->alert(ES->toString(ex, ES->biarg(args, 0))); 173637da2899SCharles.Forsyth "Window.prototype.blur" => 173737da2899SCharles.Forsyth ; 173837da2899SCharles.Forsyth# sw := top.findbyobj(this); 173937da2899SCharles.Forsyth# if (sw != nil) 174037da2899SCharles.Forsyth# E->evchan <-= ref Event.Eframefocus(sw.frame.id, 0); 174137da2899SCharles.Forsyth 174237da2899SCharles.Forsyth "Window.prototype.clearTimeout" or 174337da2899SCharles.Forsyth "Window.prototype.clearInterval" => 174437da2899SCharles.Forsyth v := ES->biarg(args, 0); 174537da2899SCharles.Forsyth id := ES->toInt32(ex, v); 174637da2899SCharles.Forsyth clrtimeout(ex, this, id); 174737da2899SCharles.Forsyth "Window.prototype.close" => 174837da2899SCharles.Forsyth if(this == top.ex.global) 174937da2899SCharles.Forsyth winclose = 1; 175037da2899SCharles.Forsyth # no-op 175137da2899SCharles.Forsyth ; 175237da2899SCharles.Forsyth "Window.prototype.confirm" => 175337da2899SCharles.Forsyth code := G->confirm(ES->toString(ex, ES->biarg(args, 0))); 175437da2899SCharles.Forsyth if(code != 1) 175537da2899SCharles.Forsyth ans = ES->valref(ES->false); 175637da2899SCharles.Forsyth "Window.prototype.focus" => 175737da2899SCharles.Forsyth ; 175837da2899SCharles.Forsyth# sw := top.findbyobj(this); 175937da2899SCharles.Forsyth# if (sw != nil) 176037da2899SCharles.Forsyth# E->evchan <-= ref Event.Eframefocus(sw.frame.id, 1); 176137da2899SCharles.Forsyth "Window.prototype.moveBy" or 176237da2899SCharles.Forsyth "Window.prototype.moveTo" => 176337da2899SCharles.Forsyth # no-op 176437da2899SCharles.Forsyth ; 176537da2899SCharles.Forsyth "Window.prototype.open" => 176637da2899SCharles.Forsyth if (dbgdom) 176737da2899SCharles.Forsyth sys->print("window.open called\n"); 176837da2899SCharles.Forsyth u := ES->toString(ex, ES->biarg(args, 0)); 176937da2899SCharles.Forsyth n := ES->toString(ex, ES->biarg(args, 1)); 177037da2899SCharles.Forsyth sw : ref ScriptWin; 177137da2899SCharles.Forsyth if (n != "") 177237da2899SCharles.Forsyth sw = top.findbyname(n); 177337da2899SCharles.Forsyth newch := 0; 177437da2899SCharles.Forsyth if (sw == nil){ 177537da2899SCharles.Forsyth sw = top; 177637da2899SCharles.Forsyth newch = 1; 177737da2899SCharles.Forsyth } 177837da2899SCharles.Forsyth if(u != "") { 177937da2899SCharles.Forsyth # Want to replace window by navigation to u 178037da2899SCharles.Forsyth sw.newloc = u; 178137da2899SCharles.Forsyth if (sw.frame.name != "") 178237da2899SCharles.Forsyth sw.newloctarg = sw.frame.name; 178337da2899SCharles.Forsyth else 178437da2899SCharles.Forsyth sw.newloctarg = "_top"; 178537da2899SCharles.Forsyth url : ref U->Parsedurl; 178637da2899SCharles.Forsyth if (sw.frame.doc != nil && sw.frame.doc.base != nil) 178737da2899SCharles.Forsyth url = U->mkabs(U->parse(u), sw.frame.doc.base); 178837da2899SCharles.Forsyth else 178937da2899SCharles.Forsyth url = CU->makeabsurl(u); 179037da2899SCharles.Forsyth sw.newloc = url.tostring(); 179137da2899SCharles.Forsyth } 179237da2899SCharles.Forsyth if(newch){ 179337da2899SCharles.Forsyth # create dummy window 179437da2899SCharles.Forsyth dw := ScriptWin.dummy(); 179537da2899SCharles.Forsyth spawn newcharon(sw.newloc, sw.newloctarg, sw); 179637da2899SCharles.Forsyth sw.newloc = ""; 179737da2899SCharles.Forsyth sw.newloctarg = ""; 179837da2899SCharles.Forsyth ans = ES->valref(dw.val); 179937da2899SCharles.Forsyth } 180037da2899SCharles.Forsyth else 180137da2899SCharles.Forsyth ans = ES->valref(sw.val); 180237da2899SCharles.Forsyth "Window.prototype.prompt" => 180337da2899SCharles.Forsyth msg := ES->toString(ex, ES->biarg(args, 0)); 180437da2899SCharles.Forsyth dflt := ES->toString(ex, ES->biarg(args, 1)); 180537da2899SCharles.Forsyth (code, input) := G->prompt(msg, dflt); 180637da2899SCharles.Forsyth v := ES->null; 180737da2899SCharles.Forsyth if(code == 1) 180837da2899SCharles.Forsyth v = ES->strval(input); 180937da2899SCharles.Forsyth ans = ES->valref(v); 181037da2899SCharles.Forsyth "Window.prototype.resizeBy" or 181137da2899SCharles.Forsyth "Window.prototype.resizeTo" => 181237da2899SCharles.Forsyth # no-op 181337da2899SCharles.Forsyth ; 181437da2899SCharles.Forsyth "Window.prototype.scroll" or 181537da2899SCharles.Forsyth "Window.prototype.scrollTo" => 181637da2899SCharles.Forsyth # scroll is done via an event to avoid race in calls to 181737da2899SCharles.Forsyth # Layout->fixframegeom() [made by scroll code] 181837da2899SCharles.Forsyth sw := top.findbyobj(this); 181937da2899SCharles.Forsyth if (sw != nil) { 182037da2899SCharles.Forsyth (xv, yv) := (ES->biarg(args, 0), ES->biarg(args, 1)); 182137da2899SCharles.Forsyth pt := Draw->Point(ES->toInt32(ex, xv), ES->toInt32(ex, yv)); 182237da2899SCharles.Forsyth E->evchan <-= ref Event.Escroll(sw.frame.id, pt); 182337da2899SCharles.Forsyth } 182437da2899SCharles.Forsyth "Window.prototype.scrollBy" => 182537da2899SCharles.Forsyth sw := top.findbyobj(this); 182637da2899SCharles.Forsyth if (sw != nil) { 182737da2899SCharles.Forsyth (dxv, dyv) := (ES->biarg(args, 0), ES->biarg(args, 1)); 182837da2899SCharles.Forsyth pt := Draw->Point(ES->toInt32(ex, dxv), ES->toInt32(ex, dyv)); 182937da2899SCharles.Forsyth E->evchan <-= ref Event.Escrollr(sw.frame.id, pt); 183037da2899SCharles.Forsyth } 183137da2899SCharles.Forsyth "Window.prototype.setTimeout" => 183237da2899SCharles.Forsyth (v1, v2) := (ES->biarg(args, 0), ES->biarg(args, 1)); 183337da2899SCharles.Forsyth cmd := ES->toString(ex, v1); 183437da2899SCharles.Forsyth ms := ES->toInt32(ex, v2); 183537da2899SCharles.Forsyth id := addtimeout(ex, this, cmd, ms, E->SEtimeout); 183637da2899SCharles.Forsyth ans = ES->valref(ES->numval(real id)); 183737da2899SCharles.Forsyth "Window.prototype.setInterval" => 183837da2899SCharles.Forsyth (v1, v2) := (ES->biarg(args, 0), ES->biarg(args, 1)); 183937da2899SCharles.Forsyth cmd := ES->toString(ex, v1); 184037da2899SCharles.Forsyth ms := ES->toInt32(ex, v2); 184137da2899SCharles.Forsyth id := addtimeout(ex, this, cmd, ms, E->SEinterval); 184237da2899SCharles.Forsyth ans = ES->valref(ES->numval(real id)); 184337da2899SCharles.Forsyth * => 184437da2899SCharles.Forsyth ES->runtime(ex, nil, "unknown or unimplemented func "+func.val.str+" in host call"); 184537da2899SCharles.Forsyth return nil; 184637da2899SCharles.Forsyth } 184737da2899SCharles.Forsyth return ans; 184837da2899SCharles.Forsyth} 184937da2899SCharles.Forsyth 185037da2899SCharles.Forsythconstruct(ex: ref Exec, func: ref Obj, args: array of ref Val): ref Obj 185137da2899SCharles.Forsyth{ 185237da2899SCharles.Forsyth if(dbgdom) 185337da2899SCharles.Forsyth sys->print("construct %x (class %s), val %s\n", func, func.class, func.val.str); 185437da2899SCharles.Forsyth params: array of string; 185537da2899SCharles.Forsyth o: ref Obj; 185637da2899SCharles.Forsyth#sys->print("Construct(%s)\n", func.val.str); 185737da2899SCharles.Forsyth case func.val.str { 185837da2899SCharles.Forsyth "Image" => 185937da2899SCharles.Forsyth o = mkhostobj(ex, "Image"); 186037da2899SCharles.Forsyth params = array [] of {"width", "height"}; 186137da2899SCharles.Forsyth createdimages = o :: createdimages; 186237da2899SCharles.Forsyth "Option" => 186337da2899SCharles.Forsyth o = mkhostobj(ex, "Option"); 186437da2899SCharles.Forsyth params = array [] of {"text", "value", "defaultSelected", "selected"}; 186537da2899SCharles.Forsyth * => 186637da2899SCharles.Forsyth return nil; 186737da2899SCharles.Forsyth } 186837da2899SCharles.Forsyth for (i := 0; i < len args && i < len params; i++) 186937da2899SCharles.Forsyth reinitprop(o, params[i], args[i]); 187037da2899SCharles.Forsyth return o; 187137da2899SCharles.Forsyth} 187237da2899SCharles.Forsyth 187337da2899SCharles.Forsythupdateffopts(ex: ref Exec, oform, oformfield: ref Obj, ix: int) 187437da2899SCharles.Forsyth{ 187537da2899SCharles.Forsyth vframeid := ES->get(ex, oform, "@PRIVframeid"); 187637da2899SCharles.Forsyth vformid := ES->get(ex, oform, "@PRIVformid"); 187737da2899SCharles.Forsyth vfieldid := ES->get(ex, oformfield, "@PRIVfieldid"); 187837da2899SCharles.Forsyth if(!ES->isnum(vframeid) || !ES->isnum(vformid) || !ES->isnum(vfieldid)) 187937da2899SCharles.Forsyth return; 188037da2899SCharles.Forsyth frameid := ES->toInt32(ex, vframeid); 188137da2899SCharles.Forsyth formid := ES->toInt32(ex, vformid); 188237da2899SCharles.Forsyth fieldid := ES->toInt32(ex, vfieldid); 188337da2899SCharles.Forsyth 188437da2899SCharles.Forsyth target := top.findbyframeid(frameid); 188537da2899SCharles.Forsyth if(target == nil) 188637da2899SCharles.Forsyth return; 188737da2899SCharles.Forsyth form: ref B->Form; 188837da2899SCharles.Forsyth for(fl := target.frame.doc.forms; fl != nil; fl = tl fl) { 188937da2899SCharles.Forsyth f := hd fl; 189037da2899SCharles.Forsyth if(f.formid == formid) { 189137da2899SCharles.Forsyth form = f; 189237da2899SCharles.Forsyth break; 189337da2899SCharles.Forsyth } 189437da2899SCharles.Forsyth } 189537da2899SCharles.Forsyth if(form == nil) 189637da2899SCharles.Forsyth return; 189737da2899SCharles.Forsyth field: ref B->Formfield; 189837da2899SCharles.Forsyth for(ffl := form.fields; ffl != nil; ffl = tl ffl) { 189937da2899SCharles.Forsyth ff := hd ffl; 190037da2899SCharles.Forsyth if(ff.fieldid == fieldid) { 190137da2899SCharles.Forsyth field = ff; 190237da2899SCharles.Forsyth break; 190337da2899SCharles.Forsyth } 190437da2899SCharles.Forsyth } 190537da2899SCharles.Forsyth if(field == nil) 190637da2899SCharles.Forsyth return; 190737da2899SCharles.Forsyth 190837da2899SCharles.Forsyth selctl : ref Control.Cselect; 190937da2899SCharles.Forsyth pick ctl := target.frame.controls[field.ctlid] { 191037da2899SCharles.Forsyth Cselect => 191137da2899SCharles.Forsyth selctl = ctl; 191237da2899SCharles.Forsyth * => 191337da2899SCharles.Forsyth return; 191437da2899SCharles.Forsyth } 191537da2899SCharles.Forsyth 191637da2899SCharles.Forsyth (opts, nopts) := getarraywithlen(ex, oformfield, "options"); 191737da2899SCharles.Forsyth if (opts == nil) 191837da2899SCharles.Forsyth return; 191937da2899SCharles.Forsyth optl: list of ref B->Option; 192037da2899SCharles.Forsyth selobj, firstobj: ref Obj; 192137da2899SCharles.Forsyth selopt, firstopt: ref B->Option; 192237da2899SCharles.Forsyth noptl := 0; 192337da2899SCharles.Forsyth for (i := 0; i < nopts; i++) { 192437da2899SCharles.Forsyth vopt := ES->get(ex, opts, string i); 192537da2899SCharles.Forsyth if (!ES->isobj(vopt) || vopt.obj.class != "Option") 192637da2899SCharles.Forsyth continue; 192737da2899SCharles.Forsyth oopt := vopt.obj; 192837da2899SCharles.Forsyth sel := ES->get(ex, oopt, "selected") == ES->true; 192937da2899SCharles.Forsyth val := ES->toString(ex, ES->get(ex, oopt, "value")); 193037da2899SCharles.Forsyth text := ES->toString(ex, ES->get(ex, oopt, "text")); 193137da2899SCharles.Forsyth option := ref B->Option(sel, val, text); 193237da2899SCharles.Forsyth optl = option :: optl; 193337da2899SCharles.Forsyth if (noptl++ == 0) { 193437da2899SCharles.Forsyth firstobj = oopt; 193537da2899SCharles.Forsyth firstopt = option; 193637da2899SCharles.Forsyth } 193737da2899SCharles.Forsyth if (sel && (selobj == nil || ix == i)) { 193837da2899SCharles.Forsyth selobj = oopt; 193937da2899SCharles.Forsyth selopt = option; 194037da2899SCharles.Forsyth } 194137da2899SCharles.Forsyth if (! int(field.flags & B->FFmultiple)) { 194237da2899SCharles.Forsyth ES->put(ex, oopt, "selected", ES->false); 194337da2899SCharles.Forsyth option.selected = 0; 194437da2899SCharles.Forsyth } 194537da2899SCharles.Forsyth } 194637da2899SCharles.Forsyth if (selobj != nil) 194737da2899SCharles.Forsyth ES->put(ex, selobj, "selected", ES->true); 194837da2899SCharles.Forsyth else if (firstobj != nil) 194937da2899SCharles.Forsyth ES->put(ex, firstobj, "selected", ES->true); 195037da2899SCharles.Forsyth if (selopt != nil) 195137da2899SCharles.Forsyth selopt.selected = 1; 195237da2899SCharles.Forsyth else if (firstopt != nil) 195337da2899SCharles.Forsyth firstopt.selected = 1; 195437da2899SCharles.Forsyth opta := array [noptl] of B->Option; 195537da2899SCharles.Forsyth for (i = noptl - 1; i >= 0; i--) 195637da2899SCharles.Forsyth (opta[i], optl) = (*hd optl, tl optl); 195737da2899SCharles.Forsyth # race here with charon.b:form_submit() and layout code 195837da2899SCharles.Forsyth selctl.options = opta; 195937da2899SCharles.Forsyth E->evchan <-= ref Event.Eformfield(frameid, formid, fieldid, E->EFFredraw); 196037da2899SCharles.Forsyth} 196137da2899SCharles.Forsyth 196237da2899SCharles.Forsythtimeout(e : ref ScriptEvent, ms : int) 196337da2899SCharles.Forsyth{ 196437da2899SCharles.Forsyth sys->sleep(ms); 196537da2899SCharles.Forsyth jevchan <- = e; 196637da2899SCharles.Forsyth} 196737da2899SCharles.Forsyth 196837da2899SCharles.Forsyth# BUGS 196937da2899SCharles.Forsyth# cannot set a timeout for a window just created by window.open() 197037da2899SCharles.Forsyth# because it will not have an entry in the ScriptWin tree 197137da2899SCharles.Forsyth# (This is really a problem with the ScriptEvent adt only taking a frame id) 197237da2899SCharles.Forsyth# 197337da2899SCharles.Forsythaddtimeout(ex : ref Exec, win : ref Obj, cmd : string, ms : int, evk: int) : int 197437da2899SCharles.Forsyth{ 197537da2899SCharles.Forsyth sw := top.findbyobj(win); 197637da2899SCharles.Forsyth if (sw == nil || cmd == nil || ms <= 0) 197737da2899SCharles.Forsyth return -1; 197837da2899SCharles.Forsyth 197937da2899SCharles.Forsyth # check for timeout handler array, create if doesn't exist 198037da2899SCharles.Forsyth (toa, n) := getarraywithlen(ex, win, "@PRIVtoa"); 198137da2899SCharles.Forsyth if (toa == nil) { 198237da2899SCharles.Forsyth toa = ES->mkobj(ex.arrayproto, "Array"); 198337da2899SCharles.Forsyth ES->varinstant(toa, ES->DontEnum|ES->DontDelete, "length", ref RefVal(ES->numval(0.))); 198437da2899SCharles.Forsyth ES->varinstant(win, ES->DontEnum|ES->DontDelete, "@PRIVtoa", ref RefVal(ES->objval(toa))); 198537da2899SCharles.Forsyth } 198637da2899SCharles.Forsyth # find first free handler 198737da2899SCharles.Forsyth for (ix := 0; ix < n; ix++) { 198837da2899SCharles.Forsyth hv := ES->get(ex, toa, string ix); 198937da2899SCharles.Forsyth 199037da2899SCharles.Forsyth if (hv == nil) 199137da2899SCharles.Forsyth break; 199237da2899SCharles.Forsyth # val == null Timeout has been cancelled, but timer still running 199337da2899SCharles.Forsyth # val == undefined Timeout has expired 199437da2899SCharles.Forsyth if (hv == ES->undefined) 199537da2899SCharles.Forsyth break; 199637da2899SCharles.Forsyth } 199737da2899SCharles.Forsyth 199837da2899SCharles.Forsyth # construct a private handler for the timeout 199937da2899SCharles.Forsyth # The code is always executed in the scope of the window object 200037da2899SCharles.Forsyth # for which the timeout is being set. 200137da2899SCharles.Forsyth oldsc := ex.scopechain; 200237da2899SCharles.Forsyth ex.scopechain = win :: nil; 200337da2899SCharles.Forsyth ES->eval(ex, "function PRIVhandler() {" + cmd + "}"); 200437da2899SCharles.Forsyth hobj := getobj(ex, win, "PRIVhandler"); 200537da2899SCharles.Forsyth ex.scopechain = oldsc; 200637da2899SCharles.Forsyth if(hobj == nil) 200737da2899SCharles.Forsyth return -1; 200837da2899SCharles.Forsyth ES->put(ex, toa, string ix, ES->objval(hobj)); 200937da2899SCharles.Forsyth ev := ref ScriptEvent(evk, sw.frame.id, -1, -1, -1, -1, 0, 0, ix, nil, nil, ms); 201037da2899SCharles.Forsyth spawn timeout(ev, ms); 201137da2899SCharles.Forsyth return ix; 201237da2899SCharles.Forsyth} 201337da2899SCharles.Forsyth 201437da2899SCharles.Forsythdotimeout(ex : ref Exec, win : ref Obj, e: ref ScriptEvent) : ref Ecmascript->Obj 201537da2899SCharles.Forsyth{ 201637da2899SCharles.Forsyth id := e.which; 201737da2899SCharles.Forsyth if (id < 0) 201837da2899SCharles.Forsyth return nil; 201937da2899SCharles.Forsyth 202037da2899SCharles.Forsyth (toa, n) := getarraywithlen(ex, win, "@PRIVtoa"); 202137da2899SCharles.Forsyth if (toa == nil || id >= n) 202237da2899SCharles.Forsyth return nil; 202337da2899SCharles.Forsyth 202437da2899SCharles.Forsyth handler := getobj(ex, toa, string id); 202537da2899SCharles.Forsyth if (handler == nil) 202637da2899SCharles.Forsyth return nil; 202737da2899SCharles.Forsyth if(e.kind == E->SEinterval){ 202837da2899SCharles.Forsyth ev := ref ScriptEvent; 202937da2899SCharles.Forsyth *ev = *e; 203037da2899SCharles.Forsyth spawn timeout(ev, e.ms); 203137da2899SCharles.Forsyth return handler; 203237da2899SCharles.Forsyth } 203337da2899SCharles.Forsyth if (id == n-1) 203437da2899SCharles.Forsyth ES->put(ex, toa, "length", ES->numval(real (n-1))); 203537da2899SCharles.Forsyth else 203637da2899SCharles.Forsyth ES->put(ex, toa, string id, ES->undefined); 203737da2899SCharles.Forsyth return handler; 203837da2899SCharles.Forsyth} 203937da2899SCharles.Forsyth 204037da2899SCharles.Forsythclrtimeout(ex : ref Exec, win : ref Obj, id : int) 204137da2899SCharles.Forsyth{ 204237da2899SCharles.Forsyth if (id < 0) 204337da2899SCharles.Forsyth return; 204437da2899SCharles.Forsyth (toa, n) := getarraywithlen(ex, win, "@PRIVtoa"); 204537da2899SCharles.Forsyth if (toa == nil || id >= n) 204637da2899SCharles.Forsyth return; 204737da2899SCharles.Forsyth 204837da2899SCharles.Forsyth ES->put(ex, toa, string id, ES->null); 204937da2899SCharles.Forsyth} 205037da2899SCharles.Forsyth 205137da2899SCharles.Forsyth# Make a host object with given class. 205237da2899SCharles.Forsyth# Get the prototype from the objspecs array 205337da2899SCharles.Forsyth# (if none yet, make one up and install the methods). 205437da2899SCharles.Forsyth# Put in required properties, with undefined values initially. 205537da2899SCharles.Forsyth# If mainex is nil (it will be for bootstrapping the initial object), 205637da2899SCharles.Forsyth# the prototype has to be filled in later. 205737da2899SCharles.Forsythmkhostobj(ex : ref Exec, class: string) : ref Obj 205837da2899SCharles.Forsyth{ 205937da2899SCharles.Forsyth ci := specindex(class); 206037da2899SCharles.Forsyth proto : ref Obj; 206137da2899SCharles.Forsyth if(ex != nil) 206237da2899SCharles.Forsyth proto = mkprototype(ex, ci); 206337da2899SCharles.Forsyth ans := ES->mkobj(proto, class); 206437da2899SCharles.Forsyth initprops(ex, ans, objspecs[ci].props); 206537da2899SCharles.Forsyth ans.host = me; 206637da2899SCharles.Forsyth return ans; 206737da2899SCharles.Forsyth} 206837da2899SCharles.Forsyth 206937da2899SCharles.Forsythinitprops(ex : ref Exec, o: ref Obj, props: array of PropSpec) 207037da2899SCharles.Forsyth{ 207137da2899SCharles.Forsyth if(props == nil) 207237da2899SCharles.Forsyth return; 207337da2899SCharles.Forsyth for(i := 0; i < len props; i++) { 207437da2899SCharles.Forsyth v := ES->undefined; 207537da2899SCharles.Forsyth case props[i].initval { 207637da2899SCharles.Forsyth IVundef => 207737da2899SCharles.Forsyth v = ES->undefined; 207837da2899SCharles.Forsyth IVnull => 207937da2899SCharles.Forsyth v = ES->null; 208037da2899SCharles.Forsyth IVtrue => 208137da2899SCharles.Forsyth v = ES->true; 208237da2899SCharles.Forsyth IVfalse => 208337da2899SCharles.Forsyth v = ES->false; 208437da2899SCharles.Forsyth IVnullstr => 208537da2899SCharles.Forsyth v = nullstrval; 208637da2899SCharles.Forsyth IVzero => 208737da2899SCharles.Forsyth v = zeroval; 208837da2899SCharles.Forsyth IVzerostr => 208937da2899SCharles.Forsyth v = zerostrval; 209037da2899SCharles.Forsyth IVarray => 209137da2899SCharles.Forsyth # need a separate one for each array, 209237da2899SCharles.Forsyth # since we'll update these rather than replacing 209337da2899SCharles.Forsyth ao := ES->mkobj(ex.arrayproto, "Array"); 209437da2899SCharles.Forsyth ES->varinstant(ao, ES->DontEnum|ES->DontDelete, "length", ref RefVal(ES->numval(0.))); 209537da2899SCharles.Forsyth v = ES->objval(ao); 209637da2899SCharles.Forsyth * => 209737da2899SCharles.Forsyth CU->assert(0); 209837da2899SCharles.Forsyth } 209937da2899SCharles.Forsyth ES->varinstant(o, props[i].attr | ES->DontDelete, props[i].name, ref RefVal(v)); 210037da2899SCharles.Forsyth } 210137da2899SCharles.Forsyth} 210237da2899SCharles.Forsyth 210337da2899SCharles.Forsyth# Return index into objspecs where class is specified 210437da2899SCharles.Forsythspecindex(class: string) : int 210537da2899SCharles.Forsyth{ 210637da2899SCharles.Forsyth for(i := 0; i < len objspecs; i++) 210737da2899SCharles.Forsyth if(objspecs[i].name == class) 210837da2899SCharles.Forsyth break; 210937da2899SCharles.Forsyth if(i == len objspecs) 2110*54041ca4Sforsyth raise "EXInternal: couldn't find host object class " + class; 211137da2899SCharles.Forsyth return i; 211237da2899SCharles.Forsyth} 211337da2899SCharles.Forsyth 211437da2899SCharles.Forsyth# Make a prototype for host object specified by objspecs[ci] 211537da2899SCharles.Forsythmkprototype(ex : ref Exec, ci : int) : ref Obj 211637da2899SCharles.Forsyth{ 211737da2899SCharles.Forsyth CU->assert(ex != nil); 211837da2899SCharles.Forsyth class := objspecs[ci].name; 211937da2899SCharles.Forsyth prototype := ES->mkobj(ex.objproto, class); 212037da2899SCharles.Forsyth meths := objspecs[ci].methods; 212137da2899SCharles.Forsyth for(k := 0; k < len meths; k++) { 212237da2899SCharles.Forsyth name := meths[k].name; 212337da2899SCharles.Forsyth fullname := class + ".prototype." + name; 212437da2899SCharles.Forsyth args := meths[k].args; 212537da2899SCharles.Forsyth ES->biinst(prototype, Builtin(name, fullname, args, len args), 212637da2899SCharles.Forsyth ex.funcproto, me); 212737da2899SCharles.Forsyth } 212837da2899SCharles.Forsyth return prototype; 212937da2899SCharles.Forsyth} 213037da2899SCharles.Forsyth 213137da2899SCharles.Forsyth 213237da2899SCharles.Forsythgetframeobj(frameid: int) : ref Obj 213337da2899SCharles.Forsyth{ 213437da2899SCharles.Forsyth sw := top.findbyframeid(frameid); 213537da2899SCharles.Forsyth if(sw != nil) 213637da2899SCharles.Forsyth return sw.ex.global; 213737da2899SCharles.Forsyth return nil; 213837da2899SCharles.Forsyth} 213937da2899SCharles.Forsyth 214037da2899SCharles.Forsythgetdocobj(ex : ref Exec, frameid: int) : ref Obj 214137da2899SCharles.Forsyth{ 214237da2899SCharles.Forsyth return getobj(ex, getframeobj(frameid), "document"); 214337da2899SCharles.Forsyth} 214437da2899SCharles.Forsyth 214537da2899SCharles.Forsythgetformobj(ex : ref Exec, frameid, formid: int) : ref Obj 214637da2899SCharles.Forsyth{ 214737da2899SCharles.Forsyth # frameids are 1-origin, document.forms is 0-origin 214837da2899SCharles.Forsyth return getarrayelem(ex, getdocobj(ex, frameid), "forms", formid-1); 214937da2899SCharles.Forsyth} 215037da2899SCharles.Forsyth 215137da2899SCharles.Forsythgetformfieldobj(frameid, formid, fieldid: int) : ref Obj 215237da2899SCharles.Forsyth{ 215337da2899SCharles.Forsyth sw := top.findbyframeid(frameid); 215437da2899SCharles.Forsyth if (sw == nil) 215537da2899SCharles.Forsyth return nil; 215637da2899SCharles.Forsyth flds : list of (ref Build->Formfield, ref Obj); 215737da2899SCharles.Forsyth for (fl := sw.forms; fl != nil; fl = tl fl) { 215837da2899SCharles.Forsyth sf := hd fl; 215937da2899SCharles.Forsyth if (sf.form.formid == formid) { 216037da2899SCharles.Forsyth flds = sf.fields; 216137da2899SCharles.Forsyth break; 216237da2899SCharles.Forsyth } 216337da2899SCharles.Forsyth } 216437da2899SCharles.Forsyth for (; flds != nil; flds = tl flds) { 216537da2899SCharles.Forsyth (fld, obj) := hd flds; 216637da2899SCharles.Forsyth if (fld.fieldid == fieldid) 216737da2899SCharles.Forsyth return obj; 216837da2899SCharles.Forsyth } 216937da2899SCharles.Forsyth return nil; 217037da2899SCharles.Forsyth} 217137da2899SCharles.Forsyth 217237da2899SCharles.Forsythgetanchorobj(ex: ref Exec, frameid, anchorid: int) : ref Obj 217337da2899SCharles.Forsyth{ 217437da2899SCharles.Forsyth od := getdocobj(ex, frameid); 217537da2899SCharles.Forsyth if(od != nil) { 217637da2899SCharles.Forsyth (olinks, olinkslen) := getarraywithlen(ex, od, "links"); 217737da2899SCharles.Forsyth if(olinks != nil) { 217837da2899SCharles.Forsyth for(i := 0; i < olinkslen; i++) { 217937da2899SCharles.Forsyth ol := getobj(ex, olinks, string i); 218037da2899SCharles.Forsyth if(ol != nil) { 218137da2899SCharles.Forsyth v := ES->get(ex, ol, "@PRIVanchorid"); 218237da2899SCharles.Forsyth if(ES->isnum(v) && ES->toInt32(ex, v) == anchorid) 218337da2899SCharles.Forsyth return ol; 218437da2899SCharles.Forsyth } 218537da2899SCharles.Forsyth } 218637da2899SCharles.Forsyth } 218737da2899SCharles.Forsyth } 218837da2899SCharles.Forsyth return nil; 218937da2899SCharles.Forsyth} 219037da2899SCharles.Forsyth 219137da2899SCharles.Forsythgetimageobj(ex: ref Exec, frameid, imageid: int) : ref Obj 219237da2899SCharles.Forsyth{ 219337da2899SCharles.Forsyth od := getdocobj(ex, frameid); 219437da2899SCharles.Forsyth if(od != nil) { 219537da2899SCharles.Forsyth (oimages, oimageslen) := getarraywithlen(ex, od, "images"); 219637da2899SCharles.Forsyth if(oimages != nil) { 219737da2899SCharles.Forsyth for(i := 0; i < oimageslen; i++) { 219837da2899SCharles.Forsyth oi := getobj(ex, oimages, string i); 219937da2899SCharles.Forsyth if(oi != nil) { 220037da2899SCharles.Forsyth v := ES->get(ex, oi, "@PRIVimageid"); 220137da2899SCharles.Forsyth if(ES->isnum(v) && ES->toInt32(ex, v) == imageid) 220237da2899SCharles.Forsyth return oi; 220337da2899SCharles.Forsyth } 220437da2899SCharles.Forsyth } 220537da2899SCharles.Forsyth } 220637da2899SCharles.Forsyth } 220737da2899SCharles.Forsyth return nil; 220837da2899SCharles.Forsyth} 220937da2899SCharles.Forsyth 221037da2899SCharles.Forsyth# return nil if none such, or not an object 221137da2899SCharles.Forsythgetobj(ex : ref Exec, o: ref Obj, prop: string) : ref Obj 221237da2899SCharles.Forsyth{ 221337da2899SCharles.Forsyth if(o != nil) { 221437da2899SCharles.Forsyth v := ES->get(ex, o, prop); 221537da2899SCharles.Forsyth if(ES->isobj(v)) 221637da2899SCharles.Forsyth return ES->toObject(ex, v); 221737da2899SCharles.Forsyth } 221837da2899SCharles.Forsyth return nil; 221937da2899SCharles.Forsyth} 222037da2899SCharles.Forsyth 222137da2899SCharles.Forsyth# return nil if none such, or not an object 222237da2899SCharles.Forsythgetarrayelem(ex : ref Exec, o: ref Obj, arrayname: string, index: int) : ref Obj 222337da2899SCharles.Forsyth{ 222437da2899SCharles.Forsyth oarr := getobj(ex, o, arrayname); 222537da2899SCharles.Forsyth if(oarr != nil) { 222637da2899SCharles.Forsyth v := ES->get(ex, oarr, string index); 222737da2899SCharles.Forsyth if(ES->isobj(v)) 222837da2899SCharles.Forsyth return ES->toObject(ex, v); 222937da2899SCharles.Forsyth } 223037da2899SCharles.Forsyth return nil; 223137da2899SCharles.Forsyth} 223237da2899SCharles.Forsyth 223337da2899SCharles.Forsyth# return "" if none such, or not a string 223437da2899SCharles.Forsythgetstr(ex : ref Exec, o: ref Obj, prop: string) : string 223537da2899SCharles.Forsyth{ 223637da2899SCharles.Forsyth 223737da2899SCharles.Forsyth if(o != nil) { 223837da2899SCharles.Forsyth v := ES->get(ex, o, prop); 223937da2899SCharles.Forsyth if(ES->isstr(v)) 224037da2899SCharles.Forsyth return ES->toString(ex, v); 224137da2899SCharles.Forsyth } 224237da2899SCharles.Forsyth return ""; 224337da2899SCharles.Forsyth} 224437da2899SCharles.Forsyth 224537da2899SCharles.Forsyth# Property index, -1 if doesn't exist 224637da2899SCharles.Forsythpind(o: ref Obj, prop: string) : int 224737da2899SCharles.Forsyth{ 224837da2899SCharles.Forsyth props := o.props; 224937da2899SCharles.Forsyth for(i := 0; i < len props; i++){ 225037da2899SCharles.Forsyth if(props[i] != nil && props[i].name == prop) 225137da2899SCharles.Forsyth return i; 225237da2899SCharles.Forsyth } 225337da2899SCharles.Forsyth return -1; 225437da2899SCharles.Forsyth} 225537da2899SCharles.Forsyth 225637da2899SCharles.Forsyth# Reinitialize property prop of object o to value v 225737da2899SCharles.Forsyth# (pay no attention to ReadOnly status, so can't use ES->put). 225837da2899SCharles.Forsyth# Assume the property exists already. 225937da2899SCharles.Forsythreinitprop(o: ref Obj, prop: string, v: ref Val) 226037da2899SCharles.Forsyth{ 226137da2899SCharles.Forsyth i := pind(o, prop); 226237da2899SCharles.Forsyth if(i < 0) { 226337da2899SCharles.Forsyth # set up dummy ex for now - needs sorting out 226437da2899SCharles.Forsyth ex := ref Exec; 226537da2899SCharles.Forsyth ES->runtime(ex, nil, "missing property " + prop); # shouldn't happen 226637da2899SCharles.Forsyth } 226737da2899SCharles.Forsyth CU->assert(i >= 0); 226837da2899SCharles.Forsyth o.props[i].val.val = v; 226937da2899SCharles.Forsyth} 227037da2899SCharles.Forsyth 227137da2899SCharles.Forsyth# Get the array object named aname from o, and also find its current 227237da2899SCharles.Forsyth# length value. If there is any problem, return (nil, 0). 227337da2899SCharles.Forsythgetarraywithlen(ex : ref Exec, o: ref Obj, aname: string) : (ref Obj, int) 227437da2899SCharles.Forsyth{ 227537da2899SCharles.Forsyth varray := ES->get(ex, o, aname); 227637da2899SCharles.Forsyth if(ES->isobj(varray)) { 227737da2899SCharles.Forsyth oarray := ES->toObject(ex, varray); 227837da2899SCharles.Forsyth vlen := ES->get(ex, oarray, "length"); 227937da2899SCharles.Forsyth if(vlen != ES->undefined) 228037da2899SCharles.Forsyth return (oarray, ES->toInt32(ex, vlen)); 228137da2899SCharles.Forsyth } 228237da2899SCharles.Forsyth return (nil, 0); 228337da2899SCharles.Forsyth} 228437da2899SCharles.Forsyth 228537da2899SCharles.Forsyth# Put val v as property "index" of object oarray. 228637da2899SCharles.Forsyth# Also, if the name doesn't conflict with array properties, add the val as 228737da2899SCharles.Forsyth# a "name" property too 228837da2899SCharles.Forsytharrayput(ex : ref Exec, oarray: ref Obj, index: int, name: string, v: ref Val) 228937da2899SCharles.Forsyth{ 229037da2899SCharles.Forsyth ES->put(ex, oarray, string index, v); 229137da2899SCharles.Forsyth if (name != "length" && prop2index(name) == -1) 229237da2899SCharles.Forsyth ES->put(ex, oarray, name, v); 229337da2899SCharles.Forsyth} 229437da2899SCharles.Forsyth 229537da2899SCharles.Forsythprop2index(p: string): int 229637da2899SCharles.Forsyth{ 229737da2899SCharles.Forsyth if (p == nil) 229837da2899SCharles.Forsyth return -1; 229937da2899SCharles.Forsyth v := 0; 230037da2899SCharles.Forsyth for (i := 0; i < len p; i++) { 230137da2899SCharles.Forsyth c := p[i]; 230237da2899SCharles.Forsyth if (c < '0' || c > '9') 230337da2899SCharles.Forsyth return -1; 230437da2899SCharles.Forsyth v = 10 * v + c - '0'; 230537da2899SCharles.Forsyth } 230637da2899SCharles.Forsyth return v; 230737da2899SCharles.Forsyth} 230837da2899SCharles.Forsyth 230937da2899SCharles.Forsyth# Instantiate window object. 231037da2899SCharles.Forsyth# mkhostobj has already put the property names and default initial values in; 231137da2899SCharles.Forsyth# we have to fill in the proper values. 231237da2899SCharles.Forsythwininstant(sw: ref ScriptWin) 231337da2899SCharles.Forsyth{ 231437da2899SCharles.Forsyth ex := sw.ex; 231537da2899SCharles.Forsyth w := ex.global; 231637da2899SCharles.Forsyth f := sw.frame; 231737da2899SCharles.Forsyth 231837da2899SCharles.Forsyth sw.error = 0; 231937da2899SCharles.Forsyth prevkids := sw.kids; 232037da2899SCharles.Forsyth sw.kids = nil; 232137da2899SCharles.Forsyth sw.forms = nil; 232237da2899SCharles.Forsyth sw.imgs = nil; 232337da2899SCharles.Forsyth sw.active = 0; 232437da2899SCharles.Forsyth 232537da2899SCharles.Forsyth # document to be init'd by xfertoscriptobjs - WRONG, 232637da2899SCharles.Forsyth # has to be init'd up-front as one frame may refer 232737da2899SCharles.Forsyth # to another's document object (esp. for document.write calls) 232837da2899SCharles.Forsyth od := getobj(ex, w, "document"); 232937da2899SCharles.Forsyth if(od == nil) { 233037da2899SCharles.Forsyth docv := ES->objval(mkhostobj(ex, "document")); 233137da2899SCharles.Forsyth reinitprop(w, "document", docv); 233237da2899SCharles.Forsyth od = getobj(ex, w, "document"); 233337da2899SCharles.Forsyth CU->assert(od != nil); 233437da2899SCharles.Forsyth } 233537da2899SCharles.Forsyth 233637da2899SCharles.Forsyth # frames[ ] 233737da2899SCharles.Forsyth ao := ES->mkobj(ex.arrayproto, "Array"); 233837da2899SCharles.Forsyth ES->varinstant(ao, ES->DontEnum|ES->DontDelete, "length", ref RefVal(ES->numval(0.))); 233937da2899SCharles.Forsyth reinitprop(w, "frames", ES->objval(ao)); 234037da2899SCharles.Forsyth for (kl := f.kids; kl != nil; kl = tl kl) { 234137da2899SCharles.Forsyth klf := hd kl; 234237da2899SCharles.Forsyth # look for original ScriptWin 234337da2899SCharles.Forsyth for (oldkl := prevkids; oldkl != nil; oldkl = tl oldkl) { 234437da2899SCharles.Forsyth oldksw := hd oldkl; 234537da2899SCharles.Forsyth if (oldksw.frame == klf) { 234637da2899SCharles.Forsyth wininstant(oldksw); 234737da2899SCharles.Forsyth sw.kids = oldksw :: sw.kids; 234837da2899SCharles.Forsyth break; 234937da2899SCharles.Forsyth } 235037da2899SCharles.Forsyth } 235137da2899SCharles.Forsyth if (oldkl == nil) 235237da2899SCharles.Forsyth sw.addkid(klf); 235337da2899SCharles.Forsyth } 235437da2899SCharles.Forsyth kn := 0; 235537da2899SCharles.Forsyth for (swkl := sw.kids; swkl != nil; swkl = tl swkl) { 235637da2899SCharles.Forsyth k := hd swkl; 235737da2899SCharles.Forsyth # Yes, frame name should be defined as property of parent 235837da2899SCharles.Forsyth arrayput(ex, ao, kn++, "", k.val); 235937da2899SCharles.Forsyth if (k.frame != nil && k.frame.name != nil) { 236037da2899SCharles.Forsyth ES->put(ex, ao, k.frame.name, k.val); 236137da2899SCharles.Forsyth ES->varinstant(w, 0, k.frame.name, ref RefVal(k.val)); 236237da2899SCharles.Forsyth } 236337da2899SCharles.Forsyth } 236437da2899SCharles.Forsyth 236537da2899SCharles.Forsyth reinitprop(w, "length", ES->numval(real len f.kids)); 236637da2899SCharles.Forsyth 236737da2899SCharles.Forsyth v := ref Val; 236837da2899SCharles.Forsyth if (sw.parent == nil) 236937da2899SCharles.Forsyth v = ES->objval(w); 237037da2899SCharles.Forsyth else 237137da2899SCharles.Forsyth v = ES->objval(sw.parent.ex.global); 237237da2899SCharles.Forsyth reinitprop(w, "parent", v); 237337da2899SCharles.Forsyth 237437da2899SCharles.Forsyth if (f.name != nil) 237537da2899SCharles.Forsyth reinitprop(w, "name", ES->strval(f.name)); 237637da2899SCharles.Forsyth reinitprop(w, "self", ES->objval(w)); 237737da2899SCharles.Forsyth reinitprop(w, "window", ES->objval(w)); 237837da2899SCharles.Forsyth reinitprop(w, "top", ES->objval(top.ex.global)); 237937da2899SCharles.Forsyth reinitprop(w, "Math", ES->get(ex, top.ex.global, "Math")); 238037da2899SCharles.Forsyth reinitprop(w, "navigator", ES->get(ex, top.ex.global, "navigator")); 238137da2899SCharles.Forsyth} 238237da2899SCharles.Forsyth 238337da2899SCharles.Forsyth# Return initial document object value, based on d 238437da2899SCharles.Forsythdocinstant(ex: ref Exec, f: ref Layout->Frame) : ref Val 238537da2899SCharles.Forsyth{ 238637da2899SCharles.Forsyth od := mkhostobj(ex, "document"); 238737da2899SCharles.Forsyth docfill(ex, od, f); 238837da2899SCharles.Forsyth return ES->objval(od); 238937da2899SCharles.Forsyth} 239037da2899SCharles.Forsyth 239137da2899SCharles.Forsyth# Fill in properties of doc object, based on d. 239237da2899SCharles.Forsyth# Can be called at various points during build. 239337da2899SCharles.Forsythdocfill(ex: ref Exec, od: ref Obj, f: ref Layout->Frame) 239437da2899SCharles.Forsyth{ 239537da2899SCharles.Forsyth sw := top.findbyframeid(f.id); 239637da2899SCharles.Forsyth if(sw == nil) 239737da2899SCharles.Forsyth return; 239837da2899SCharles.Forsyth di := f.doc; 239937da2899SCharles.Forsyth if(di.src != nil) { 240037da2899SCharles.Forsyth reinitprop(od, "URL", ES->strval(di.src.tostring())); 240137da2899SCharles.Forsyth reinitprop(od, "domain", ES->strval(di.src.host)); 240237da2899SCharles.Forsyth } 240337da2899SCharles.Forsyth if(di.referrer != nil) 240437da2899SCharles.Forsyth reinitprop(od, "referrer", ES->strval(di.referrer.tostring())); 240537da2899SCharles.Forsyth if(di.doctitle != "") 240637da2899SCharles.Forsyth reinitprop(od, "title", ES->strval(di.doctitle)); 240737da2899SCharles.Forsyth reinitprop(od, "lastModified", ES->strval(di.lastModified)); 240837da2899SCharles.Forsyth reinitprop(od, "bgColor", colorval(di.background.color)); 240937da2899SCharles.Forsyth reinitprop(od, "fgColor", colorval(di.text)); 241037da2899SCharles.Forsyth reinitprop(od, "alinkColor", colorval(di.alink)); 241137da2899SCharles.Forsyth reinitprop(od, "linkColor", colorval(di.link)); 241237da2899SCharles.Forsyth reinitprop(od, "vlinkColor", colorval(di.vlink)); 241337da2899SCharles.Forsyth 241437da2899SCharles.Forsyth # Forms in d.forms are in reverse order of appearance. 241537da2899SCharles.Forsyth # Add any that aren't already in the document.forms object, 241637da2899SCharles.Forsyth # assuming that the relative lengths will tell us what needs 241737da2899SCharles.Forsyth # to be done. 241837da2899SCharles.Forsyth if(di.forms != nil) { 241937da2899SCharles.Forsyth newformslen := len di.forms; 242037da2899SCharles.Forsyth oldformslen := len sw.forms; 242137da2899SCharles.Forsyth oforms := getobj(ex, od, "forms"); 242237da2899SCharles.Forsyth 242337da2899SCharles.Forsyth # oforms should be non-nil, because the object is initialized 242437da2899SCharles.Forsyth # to an empty array and is readonly. The following test 242537da2899SCharles.Forsyth # is just defensive. 242637da2899SCharles.Forsyth if(oforms != nil) { 242737da2899SCharles.Forsyth # run through our existing list of forms, looking 242837da2899SCharles.Forsyth # for any not marked as Transferred (happens as a result 242937da2899SCharles.Forsyth # of a script being called in the body of a form, while it is 243037da2899SCharles.Forsyth # still being parsed) 243137da2899SCharles.Forsyth for (sfl := sw.forms; sfl != nil; sfl = tl sfl) { 243237da2899SCharles.Forsyth sf := hd sfl; 243337da2899SCharles.Forsyth form := sf.form; 243437da2899SCharles.Forsyth if (form.state != B->FormTransferred) { 243537da2899SCharles.Forsyth# (sf.obj, sf.fields) = forminstant(ex, form, di.frameid); 243637da2899SCharles.Forsyth (newobj, newfields) := forminstant(ex, form, di.frameid); 243737da2899SCharles.Forsyth *sf.obj = *newobj; 243837da2899SCharles.Forsyth sf.fields = newfields; 243937da2899SCharles.Forsyth } 244037da2899SCharles.Forsyth if (form.state == B->FormDone) 244137da2899SCharles.Forsyth form.state = B->FormTransferred; 244237da2899SCharles.Forsyth } 244337da2899SCharles.Forsyth 244437da2899SCharles.Forsyth # process additional forms 244537da2899SCharles.Forsyth fl := di.forms; 244637da2899SCharles.Forsyth for(i := newformslen-1; i >= oldformslen; i--) { 244737da2899SCharles.Forsyth form := hd fl; 244837da2899SCharles.Forsyth fl = tl fl; 244937da2899SCharles.Forsyth if (form.state != B->FormTransferred) { 245037da2899SCharles.Forsyth sf := ref ScriptForm (form, nil, i, nil); 245137da2899SCharles.Forsyth (sf.obj, sf.fields) = forminstant(ex, form, di.frameid); 245237da2899SCharles.Forsyth arrayput(ex, oforms, i, form.name, ES->objval(sf.obj)); 245337da2899SCharles.Forsyth if(form.name != "") 245437da2899SCharles.Forsyth ES->put(ex, od, form.name, ES->objval(sf.obj)); 245537da2899SCharles.Forsyth sw.forms = sf :: sw.forms; 245637da2899SCharles.Forsyth } 245737da2899SCharles.Forsyth if (form.state == B->FormDone) 245837da2899SCharles.Forsyth form.state = B->FormTransferred; 245937da2899SCharles.Forsyth } 246037da2899SCharles.Forsyth } 246137da2899SCharles.Forsyth } 246237da2899SCharles.Forsyth 246337da2899SCharles.Forsyth # Charon calls "DestAnchor" what Netscape calls "Anchor". 246437da2899SCharles.Forsyth # Use same method as for forms to discover new ones. 246537da2899SCharles.Forsyth if(di.dests != nil) { 246637da2899SCharles.Forsyth newdestslen := len di.dests; 246737da2899SCharles.Forsyth (oanchors, oldanchorslen) := getarraywithlen(ex, od, "anchors"); 246837da2899SCharles.Forsyth if(oanchors != nil) { 246937da2899SCharles.Forsyth dl := di.dests; 247037da2899SCharles.Forsyth for(i := newdestslen-1; i >= oldanchorslen; i--) { 247137da2899SCharles.Forsyth dest := hd dl; 247237da2899SCharles.Forsyth dl = tl dl; 247337da2899SCharles.Forsyth arrayput(ex, oanchors, i, dest.name, anchorinstant(ex, dest.name)); 247437da2899SCharles.Forsyth } 247537da2899SCharles.Forsyth } 247637da2899SCharles.Forsyth } 247737da2899SCharles.Forsyth 247837da2899SCharles.Forsyth # Charon calls "Anchor" what Netscape calls "Link" (how confusing for us!). 247937da2899SCharles.Forsyth # Use same method as for forms to discover new ones. 248037da2899SCharles.Forsyth # BUG: Areas are supposed to be in this list too. 248137da2899SCharles.Forsyth if(di.anchors != nil) { 248237da2899SCharles.Forsyth newanchorslen := len di.anchors; 248337da2899SCharles.Forsyth (olinks, oldlinkslen) := getarraywithlen(ex, od, "links"); 248437da2899SCharles.Forsyth if(olinks != nil) { 248537da2899SCharles.Forsyth al := di.anchors; 248637da2899SCharles.Forsyth for(i := newanchorslen-1; i >= oldlinkslen; i--) { 248737da2899SCharles.Forsyth a := hd al; 248837da2899SCharles.Forsyth al = tl al; 248937da2899SCharles.Forsyth arrayput(ex, olinks, i, a.name, linkinstant(ex, a, f.id)); 249037da2899SCharles.Forsyth } 249137da2899SCharles.Forsyth } 249237da2899SCharles.Forsyth } 249337da2899SCharles.Forsyth 249437da2899SCharles.Forsyth if(di.images != nil) { 249537da2899SCharles.Forsyth newimageslen := len di.images; 249637da2899SCharles.Forsyth (oimages, oldimageslen) := getarraywithlen(ex, od, "images"); 249737da2899SCharles.Forsyth if(oimages != nil) { 249837da2899SCharles.Forsyth il := di.images; 249937da2899SCharles.Forsyth for(i := newimageslen-1; i >= oldimageslen; i--) { 250037da2899SCharles.Forsyth imit := hd il; 250137da2899SCharles.Forsyth il = tl il; 250237da2899SCharles.Forsyth pick ii := imit { 250337da2899SCharles.Forsyth Iimage => 250437da2899SCharles.Forsyth vim := imageinstant(ex, ii); 250537da2899SCharles.Forsyth arrayput(ex, oimages, i, ii.name, vim); 250637da2899SCharles.Forsyth ES->put(ex, od, ii.name, vim); 250737da2899SCharles.Forsyth if(ES->isobj(vim)) { 250837da2899SCharles.Forsyth sw.imgs = ref ScriptImg(ii, vim.obj) :: sw.imgs; 250937da2899SCharles.Forsyth } 251037da2899SCharles.Forsyth } 251137da2899SCharles.Forsyth } 251237da2899SCharles.Forsyth } 251337da2899SCharles.Forsyth } 251437da2899SCharles.Forsyth 251537da2899SCharles.Forsyth # private variables 251637da2899SCharles.Forsyth ES->varinstant(od, ES->DontEnum|ES->DontDelete, "@PRIVframeid", 251737da2899SCharles.Forsyth ref RefVal(ES->numval(real di.frameid))); 251837da2899SCharles.Forsyth} 251937da2899SCharles.Forsyth 252037da2899SCharles.Forsythforminstant(ex : ref Exec, form: ref Build->Form, frameid: int) : (ref Obj, list of (ref Build->Formfield, ref Obj)) 252137da2899SCharles.Forsyth{ 252237da2899SCharles.Forsyth fields : list of (ref Build->Formfield, ref ES->Obj); 252337da2899SCharles.Forsyth oform := mkhostobj(ex, "Form"); 252437da2899SCharles.Forsyth reinitprop(oform, "action", ES->strval(form.action.tostring())); 252537da2899SCharles.Forsyth reinitprop(oform, "encoding", ES->strval("application/x-www-form-urlencoded")); 252637da2899SCharles.Forsyth reinitprop(oform, "length", ES->numval(real form.nfields)); 252737da2899SCharles.Forsyth reinitprop(oform, "method", ES->strval(CU->hmeth[form.method])); 252837da2899SCharles.Forsyth reinitprop(oform, "name", ES->strval(form.name)); 252937da2899SCharles.Forsyth reinitprop(oform, "target", ES->strval(form.target)); 253037da2899SCharles.Forsyth ffl := form.fields; 253137da2899SCharles.Forsyth if(ffl != nil) { 253237da2899SCharles.Forsyth velements := ES->get(ex, oform, "elements"); 253337da2899SCharles.Forsyth if(ES->isobj(velements)) { 253437da2899SCharles.Forsyth oelements := ES->toObject(ex, velements); 253537da2899SCharles.Forsyth for(i := 0; i < form.nfields; i++) { 253637da2899SCharles.Forsyth field := hd ffl; 253737da2899SCharles.Forsyth ffl = tl ffl; 253837da2899SCharles.Forsyth vfield := fieldinstant(ex, field, oform); 253937da2899SCharles.Forsyth 254037da2899SCharles.Forsyth # convert multiple fields of same name to an array 254137da2899SCharles.Forsyth prev := ES->get(ex, oform, field.name); 254237da2899SCharles.Forsyth if (prev != nil && ES->isobj(prev)) { 254337da2899SCharles.Forsyth newix := 0; 254437da2899SCharles.Forsyth ar : ref Obj; 254537da2899SCharles.Forsyth if (ES->isarray(prev.obj)) { 254637da2899SCharles.Forsyth ar = prev.obj; 254737da2899SCharles.Forsyth vlen := ES->get(ex, ar, "length"); 254837da2899SCharles.Forsyth newix = ES->toInt32(ex, vlen); 254937da2899SCharles.Forsyth } else { 255037da2899SCharles.Forsyth # create a new array 255137da2899SCharles.Forsyth ar = ES->mkobj(ex.arrayproto, "Array"); 255237da2899SCharles.Forsyth ES->varinstant(ar, ES->DontEnum|ES->DontDelete, "length", ref RefVal(ES->numval(real 2))); 255337da2899SCharles.Forsyth ES->put(ex, oform, field.name, ES->objval(ar)); 255437da2899SCharles.Forsyth arrayput(ex, ar, 0, "", prev); 255537da2899SCharles.Forsyth newix = 1; 255637da2899SCharles.Forsyth } 255737da2899SCharles.Forsyth arrayput(ex, ar, newix, "", vfield); 255837da2899SCharles.Forsyth } else { 255937da2899SCharles.Forsyth # first time we have seen a field of this name 256037da2899SCharles.Forsyth ES->put(ex, oform, field.name, vfield); 256137da2899SCharles.Forsyth } 256237da2899SCharles.Forsyth # although it is incorrect to add field name to 256337da2899SCharles.Forsyth # elements array (as well as being indexed) 256437da2899SCharles.Forsyth # - gives rise to name clashes, e.g radio buttons 256537da2899SCharles.Forsyth # do it because other browsers do and some fools use it! 256637da2899SCharles.Forsyth arrayput(ex, oelements, i, field.name, vfield); 256737da2899SCharles.Forsyth fields = (field, ES->toObject(ex, vfield)) :: fields; 256837da2899SCharles.Forsyth } 256937da2899SCharles.Forsyth } 257037da2899SCharles.Forsyth } 257137da2899SCharles.Forsyth for(el := form.events; el != nil; el = tl el) { 257237da2899SCharles.Forsyth e := hd el; 257337da2899SCharles.Forsyth hname := ""; 257437da2899SCharles.Forsyth case e.attid { 257537da2899SCharles.Forsyth Lex->Aonreset => 257637da2899SCharles.Forsyth hname = "onreset"; 257737da2899SCharles.Forsyth form.evmask |= E->SEonreset; 257837da2899SCharles.Forsyth Lex->Aonsubmit => 257937da2899SCharles.Forsyth hname = "onsubmit"; 258037da2899SCharles.Forsyth form.evmask |= E->SEonsubmit; 258137da2899SCharles.Forsyth } 258237da2899SCharles.Forsyth if(hname != "") 258337da2899SCharles.Forsyth puthandler(ex, oform, hname, e.value); 258437da2899SCharles.Forsyth } 258537da2899SCharles.Forsyth# form.events = nil; 258637da2899SCharles.Forsyth # private variables 258737da2899SCharles.Forsyth ES->varinstant(oform, ES->DontEnum|ES->DontDelete, "@PRIVformid", 258837da2899SCharles.Forsyth ref RefVal(ES->numval(real form.formid))); 258937da2899SCharles.Forsyth ES->varinstant(oform, ES->DontEnum|ES->DontDelete, "@PRIVframeid", 259037da2899SCharles.Forsyth ref RefVal(ES->numval(real frameid))); 259137da2899SCharles.Forsyth return (oform, fields); 259237da2899SCharles.Forsyth} 259337da2899SCharles.Forsyth 259437da2899SCharles.Forsythfieldinstant(ex : ref Exec, field: ref Build->Formfield, oform: ref Obj) : ref Val 259537da2899SCharles.Forsyth{ 259637da2899SCharles.Forsyth ofield := mkhostobj(ex, "FormField"); 259737da2899SCharles.Forsyth reinitprop(ofield, "form", ES->objval(oform)); 259837da2899SCharles.Forsyth reinitprop(ofield, "name", ES->strval(field.name)); 259937da2899SCharles.Forsyth reinitprop(ofield, "value", ES->strval(field.value)); 260037da2899SCharles.Forsyth reinitprop(ofield, "defaultValue", ES->strval(field.value)); 260137da2899SCharles.Forsyth chkd := ES->false; 260237da2899SCharles.Forsyth if((field.flags & Build->FFchecked) != byte 0) 260337da2899SCharles.Forsyth chkd = ES->true; 260437da2899SCharles.Forsyth reinitprop(ofield, "checked", chkd); 260537da2899SCharles.Forsyth reinitprop(ofield, "defaultChecked", chkd); 260637da2899SCharles.Forsyth nopts := len field.options; 260737da2899SCharles.Forsyth reinitprop(ofield, "length", ES->numval(real nopts)); 260837da2899SCharles.Forsyth reinitprop(ofield, "selectedIndex", ES->numval(-1.0)); # BUG: search for selected option 260937da2899SCharles.Forsyth ty : string; 261037da2899SCharles.Forsyth case field.ftype { 261137da2899SCharles.Forsyth Build->Ftext => 261237da2899SCharles.Forsyth ty = "text"; 261337da2899SCharles.Forsyth reinitprop(ofield, "value", ES->strval(field.value)); 261437da2899SCharles.Forsyth Build->Fpassword => 261537da2899SCharles.Forsyth ty = "password"; 261637da2899SCharles.Forsyth Build->Fcheckbox => 261737da2899SCharles.Forsyth ty = "checkbox"; 261837da2899SCharles.Forsyth Build->Fradio => 261937da2899SCharles.Forsyth ty = "radio"; 262037da2899SCharles.Forsyth Build->Fsubmit => 262137da2899SCharles.Forsyth ty = "submit"; 262237da2899SCharles.Forsyth Build->Fhidden => 262337da2899SCharles.Forsyth ty = "hidden"; 262437da2899SCharles.Forsyth Build->Fimage => 262537da2899SCharles.Forsyth ty = "image"; 262637da2899SCharles.Forsyth Build->Freset => 262737da2899SCharles.Forsyth ty = "reset"; 262837da2899SCharles.Forsyth Build->Ffile => 262937da2899SCharles.Forsyth ty = "fileupload"; 263037da2899SCharles.Forsyth Build->Fbutton => 263137da2899SCharles.Forsyth ty = "button"; 263237da2899SCharles.Forsyth Build->Fselect => 263337da2899SCharles.Forsyth ty = "select"; 263437da2899SCharles.Forsyth si := -1; 263537da2899SCharles.Forsyth options := ES->mkobj(ex.arrayproto, "Array"); 263637da2899SCharles.Forsyth ES->varinstant(options, ES->DontEnum|ES->DontDelete, "length", 263737da2899SCharles.Forsyth ref RefVal(ES->numval(real nopts))); 263837da2899SCharles.Forsyth reinitprop(ofield, "options", ES->objval(options)); 263937da2899SCharles.Forsyth optl := field.options; 264037da2899SCharles.Forsyth vfield := ES->objval(ofield); 264137da2899SCharles.Forsyth for(i := 0; i < nopts; i++) { 264237da2899SCharles.Forsyth opt := hd optl; 264337da2899SCharles.Forsyth optl = tl optl; 264437da2899SCharles.Forsyth oopt := mkhostobj(ex, "Option"); 264537da2899SCharles.Forsyth reinitprop(oopt, "index", ES->numval(real i)); 264637da2899SCharles.Forsyth reinitprop(oopt, "value", ES->strval(opt.value)); 264737da2899SCharles.Forsyth reinitprop(oopt, "text", ES->strval(opt.display)); 264837da2899SCharles.Forsyth # private variables 264937da2899SCharles.Forsyth ES->put(ex, oopt, "@PRIVformfield", vfield); 265037da2899SCharles.Forsyth if(opt.selected) { 265137da2899SCharles.Forsyth si = i; 265237da2899SCharles.Forsyth reinitprop(oopt, "selected", ES->true); 265337da2899SCharles.Forsyth reinitprop(oopt, "defaultSelected", ES->true); 265437da2899SCharles.Forsyth reinitprop(ofield, "selectedIndex", ES->numval(real i)); 265537da2899SCharles.Forsyth } 265637da2899SCharles.Forsyth ES->put(ex, options, string i, ES->objval(oopt)); 265737da2899SCharles.Forsyth } 265837da2899SCharles.Forsyth ES->put(ex, options, "selectedIndex", ES->numval(real si)); 265937da2899SCharles.Forsyth ES->put(ex, options, "@PRIVformfield", vfield); 266037da2899SCharles.Forsyth options.host = me; 266137da2899SCharles.Forsyth Build->Ftextarea => 266237da2899SCharles.Forsyth ty = "textarea"; 266337da2899SCharles.Forsyth } 266437da2899SCharles.Forsyth reinitprop(ofield, "type", ES->strval(ty)); 266537da2899SCharles.Forsyth for(el := field.events; el != nil; el = tl el) { 266637da2899SCharles.Forsyth e := hd el; 266737da2899SCharles.Forsyth hname := ""; 266837da2899SCharles.Forsyth case e.attid { 266937da2899SCharles.Forsyth Lex->Aonblur => 267037da2899SCharles.Forsyth hname = "onblur"; 267137da2899SCharles.Forsyth field.evmask |= E->SEonblur; 267237da2899SCharles.Forsyth Lex->Aonchange => 267337da2899SCharles.Forsyth hname = "onchange"; 267437da2899SCharles.Forsyth field.evmask |= E->SEonchange; 267537da2899SCharles.Forsyth Lex->Aonclick => 267637da2899SCharles.Forsyth hname = "onclick"; 267737da2899SCharles.Forsyth field.evmask |= E->SEonclick; 267837da2899SCharles.Forsyth Lex->Aondblclick => 267937da2899SCharles.Forsyth hname = "ondblclick"; 268037da2899SCharles.Forsyth field.evmask |= E->SEondblclick; 268137da2899SCharles.Forsyth Lex->Aonfocus => 268237da2899SCharles.Forsyth hname = "onfocus"; 268337da2899SCharles.Forsyth field.evmask |= E->SEonfocus; 268437da2899SCharles.Forsyth Lex->Aonkeydown => 268537da2899SCharles.Forsyth hname = "onkeydown"; 268637da2899SCharles.Forsyth field.evmask |= E->SEonkeydown; 268737da2899SCharles.Forsyth Lex->Aonkeypress => 268837da2899SCharles.Forsyth hname = "onkeypress"; 268937da2899SCharles.Forsyth field.evmask |= E->SEonkeypress; 269037da2899SCharles.Forsyth Lex->Aonkeyup => 269137da2899SCharles.Forsyth hname = "onkeyup"; 269237da2899SCharles.Forsyth field.evmask |= E->SEonkeyup; 269337da2899SCharles.Forsyth Lex->Aonmousedown => 269437da2899SCharles.Forsyth hname = "onmousedown"; 269537da2899SCharles.Forsyth field.evmask |= E->SEonmousedown; 269637da2899SCharles.Forsyth Lex->Aonmouseup => 269737da2899SCharles.Forsyth hname = "onmouseup"; 269837da2899SCharles.Forsyth field.evmask |= E->SEonmouseup; 269937da2899SCharles.Forsyth Lex->Aonselect => 270037da2899SCharles.Forsyth hname = "onselect"; 270137da2899SCharles.Forsyth field.evmask |= E->SEonselect; 270237da2899SCharles.Forsyth } 270337da2899SCharles.Forsyth if(hname != "") 270437da2899SCharles.Forsyth puthandler(ex, ofield, hname, e.value); 270537da2899SCharles.Forsyth } 270637da2899SCharles.Forsyth# field.events = nil; 270737da2899SCharles.Forsyth # private variables 270837da2899SCharles.Forsyth ES->varinstant(ofield, ES->DontEnum|ES->DontDelete, "@PRIVfieldid", 270937da2899SCharles.Forsyth ref RefVal(ES->numval(real field.fieldid))); 271037da2899SCharles.Forsyth return ES->objval(ofield); 271137da2899SCharles.Forsyth} 271237da2899SCharles.Forsyth 271337da2899SCharles.Forsyth# Make an event handler named hname in o, with given body. 271437da2899SCharles.Forsythputhandler(ex: ref Exec, o: ref Obj, hname: string, hbody: string) 271537da2899SCharles.Forsyth{ 27168911721eSCharles.Forsyth ES->eval(ex, "function PRIVhandler() {" + hbody + "}"); 271737da2899SCharles.Forsyth hobj := getobj(ex, ex.global, "PRIVhandler"); 271837da2899SCharles.Forsyth if(hobj != nil) { 271937da2899SCharles.Forsyth ES->put(ex, o, hname, ES->objval(hobj)); 272037da2899SCharles.Forsyth } 272137da2899SCharles.Forsyth} 272237da2899SCharles.Forsyth 272337da2899SCharles.Forsythanchorinstant(ex : ref Exec, nm: string) : ref Val 272437da2899SCharles.Forsyth{ 272537da2899SCharles.Forsyth oanchor := mkhostobj(ex, "Anchor"); 272637da2899SCharles.Forsyth reinitprop(oanchor, "name", ES->strval(nm)); 272737da2899SCharles.Forsyth return ES->objval(oanchor); 272837da2899SCharles.Forsyth} 272937da2899SCharles.Forsyth 273037da2899SCharles.Forsyth# Build ensures that the anchor href has been made absolute 273137da2899SCharles.Forsythlinkinstant(ex: ref Exec, anchor: ref Build->Anchor, frameid: int) : ref Val 273237da2899SCharles.Forsyth{ 273337da2899SCharles.Forsyth olink := mkhostobj(ex, "Link"); 273437da2899SCharles.Forsyth u := anchor.href; 273537da2899SCharles.Forsyth if(u != nil) { 273637da2899SCharles.Forsyth if(u.frag != "") 273737da2899SCharles.Forsyth reinitprop(olink, "hash", ES->strval("#" + u.frag)); 273837da2899SCharles.Forsyth host := u.host; 273937da2899SCharles.Forsyth if(u.user != "" || u.passwd != "") { 274037da2899SCharles.Forsyth host = u.user; 274137da2899SCharles.Forsyth if(u.passwd != "") 274237da2899SCharles.Forsyth host += ":" + u.passwd; 274337da2899SCharles.Forsyth host += "@" + u.host; 274437da2899SCharles.Forsyth } 274537da2899SCharles.Forsyth reinitprop(olink, "host", ES->strval(host)); 274637da2899SCharles.Forsyth hostname := host; 274737da2899SCharles.Forsyth if(u.port != "") 274837da2899SCharles.Forsyth hostname += ":" + u.port; 274937da2899SCharles.Forsyth reinitprop(olink, "hostname", ES->strval(hostname)); 275037da2899SCharles.Forsyth reinitprop(olink, "href", ES->strval(u.tostring())); 275137da2899SCharles.Forsyth reinitprop(olink, "pathname", ES->strval(u.path)); 275237da2899SCharles.Forsyth if(u.port != "") 275337da2899SCharles.Forsyth reinitprop(olink, "port", ES->strval(u.port)); 275437da2899SCharles.Forsyth reinitprop(olink, "protocol", ES->strval(u.scheme + ":")); 275537da2899SCharles.Forsyth if(u.query != "") 275637da2899SCharles.Forsyth reinitprop(olink, "search", ES->strval("?" + u.query)); 275737da2899SCharles.Forsyth } 275837da2899SCharles.Forsyth if(anchor.target != "") 275937da2899SCharles.Forsyth reinitprop(olink, "target", ES->strval(anchor.target)); 276037da2899SCharles.Forsyth 276137da2899SCharles.Forsyth for(el := anchor.events; el != nil; el = tl el) { 276237da2899SCharles.Forsyth e := hd el; 276337da2899SCharles.Forsyth hname := ""; 276437da2899SCharles.Forsyth case e.attid { 276537da2899SCharles.Forsyth Lex->Aonclick => 276637da2899SCharles.Forsyth hname = "onclick"; 276737da2899SCharles.Forsyth anchor.evmask |= E->SEonclick; 276837da2899SCharles.Forsyth Lex->Aondblclick => 276937da2899SCharles.Forsyth hname = "ondblclick"; 277037da2899SCharles.Forsyth anchor.evmask |= E->SEondblclick; 277137da2899SCharles.Forsyth Lex->Aonkeydown => 277237da2899SCharles.Forsyth hname = "onkeydown"; 277337da2899SCharles.Forsyth anchor.evmask |= E->SEonkeydown; 277437da2899SCharles.Forsyth Lex->Aonkeypress => 277537da2899SCharles.Forsyth hname = "onkeypress"; 277637da2899SCharles.Forsyth anchor.evmask |= E->SEonkeypress; 277737da2899SCharles.Forsyth Lex->Aonkeyup => 277837da2899SCharles.Forsyth hname = "onkeyup"; 277937da2899SCharles.Forsyth anchor.evmask |= E->SEonkeyup; 278037da2899SCharles.Forsyth Lex->Aonmousedown => 278137da2899SCharles.Forsyth hname = "onmousedown"; 278237da2899SCharles.Forsyth anchor.evmask |= E->SEonmousedown; 278337da2899SCharles.Forsyth Lex->Aonmouseout => 278437da2899SCharles.Forsyth hname = "onmouseout"; 278537da2899SCharles.Forsyth anchor.evmask |= E->SEonmouseout; 278637da2899SCharles.Forsyth Lex->Aonmouseover => 278737da2899SCharles.Forsyth hname = "onmouseover"; 278837da2899SCharles.Forsyth anchor.evmask |= E->SEonmouseover; 278937da2899SCharles.Forsyth Lex->Aonmouseup => 279037da2899SCharles.Forsyth hname = "onmouseup"; 279137da2899SCharles.Forsyth anchor.evmask |= E->SEonmouseup; 279237da2899SCharles.Forsyth } 279337da2899SCharles.Forsyth if(hname != "") 279437da2899SCharles.Forsyth puthandler(ex, olink, hname, e.value); 279537da2899SCharles.Forsyth } 279637da2899SCharles.Forsyth anchor.events = nil; 279737da2899SCharles.Forsyth # private variable 279837da2899SCharles.Forsyth ES->varinstant(olink, ES->DontEnum|ES->DontDelete, "@PRIVanchorid", 279937da2899SCharles.Forsyth ref RefVal(ES->numval(real anchor.index))); 280037da2899SCharles.Forsyth ES->varinstant(olink, ES->DontEnum|ES->DontDelete, "@PRIVframeid", 280137da2899SCharles.Forsyth ref RefVal(ES->numval(real frameid))); 280237da2899SCharles.Forsyth 280337da2899SCharles.Forsyth return ES->objval(olink); 280437da2899SCharles.Forsyth} 280537da2899SCharles.Forsyth 280637da2899SCharles.Forsythimageinstant(ex: ref Exec, im: ref Build->Item.Iimage) : ref Val 280737da2899SCharles.Forsyth{ 280837da2899SCharles.Forsyth oim := mkhostobj(ex, "Image"); 280937da2899SCharles.Forsyth src := im.ci.src.tostring(); 281037da2899SCharles.Forsyth reinitprop(oim, "border", ES->numval(real im.border)); 281137da2899SCharles.Forsyth reinitprop(oim, "height", ES->numval(real im.imheight)); 281237da2899SCharles.Forsyth reinitprop(oim, "hspace", ES->numval(real im.hspace)); 281337da2899SCharles.Forsyth reinitprop(oim, "name", ES->strval(im.name)); 281437da2899SCharles.Forsyth reinitprop(oim, "src", ES->strval(src)); 281537da2899SCharles.Forsyth if(im.ci.lowsrc != nil) 281637da2899SCharles.Forsyth reinitprop(oim, "lowsrc", ES->strval(im.ci.lowsrc.tostring())); 281737da2899SCharles.Forsyth reinitprop(oim, "vspace", ES->numval(real im.vspace)); 281837da2899SCharles.Forsyth reinitprop(oim, "width", ES->numval(real im.imwidth)); 281937da2899SCharles.Forsyth if(im.ci.complete == 0) 282037da2899SCharles.Forsyth done := ES->false; 282137da2899SCharles.Forsyth else 282237da2899SCharles.Forsyth done = ES->true; 282337da2899SCharles.Forsyth reinitprop(oim, "complete", done); 282437da2899SCharles.Forsyth 282537da2899SCharles.Forsyth el : list of Lex->Attr = nil; 282637da2899SCharles.Forsyth if(im.genattr != nil) 282737da2899SCharles.Forsyth el = im.genattr.events; 282837da2899SCharles.Forsyth for(; el != nil; el = tl el) { 282937da2899SCharles.Forsyth e := hd el; 283037da2899SCharles.Forsyth hname := ""; 283137da2899SCharles.Forsyth case e.attid { 283237da2899SCharles.Forsyth Lex->Aonabort => 283337da2899SCharles.Forsyth hname = "onabort"; 283437da2899SCharles.Forsyth im.genattr.evmask |= E->SEonabort; 283537da2899SCharles.Forsyth Lex->Aondblclick => 283637da2899SCharles.Forsyth hname = "ondblclick"; 283737da2899SCharles.Forsyth im.genattr.evmask |= E->SEondblclick; 283837da2899SCharles.Forsyth Lex->Aonerror => 283937da2899SCharles.Forsyth hname = "onerror"; 284037da2899SCharles.Forsyth im.genattr.evmask |= E->SEonerror; 284137da2899SCharles.Forsyth Lex->Aonkeydown => 284237da2899SCharles.Forsyth hname = "onkeydown"; 284337da2899SCharles.Forsyth im.genattr.evmask |= E->SEonkeydown; 284437da2899SCharles.Forsyth Lex->Aonkeypress => 284537da2899SCharles.Forsyth hname = "onkeypress"; 284637da2899SCharles.Forsyth im.genattr.evmask |= E->SEonkeypress; 284737da2899SCharles.Forsyth Lex->Aonkeyup => 284837da2899SCharles.Forsyth hname = "onkeyup"; 284937da2899SCharles.Forsyth im.genattr.evmask |= E->SEonkeyup; 285037da2899SCharles.Forsyth Lex->Aonload => 285137da2899SCharles.Forsyth hname = "onload"; 285237da2899SCharles.Forsyth im.genattr.evmask |= E->SEonload; 285337da2899SCharles.Forsyth Lex->Aonmousedown => 285437da2899SCharles.Forsyth hname = "onmousedown"; 285537da2899SCharles.Forsyth im.genattr.evmask |= E->SEonmousedown; 285637da2899SCharles.Forsyth Lex->Aonmouseout => 285737da2899SCharles.Forsyth hname = "onmouseout"; 285837da2899SCharles.Forsyth im.genattr.evmask |= E->SEonmouseout; 285937da2899SCharles.Forsyth Lex->Aonmouseover => 286037da2899SCharles.Forsyth hname = "onmouseover"; 286137da2899SCharles.Forsyth im.genattr.evmask |= E->SEonmouseover; 286237da2899SCharles.Forsyth Lex->Aonmouseup => 286337da2899SCharles.Forsyth hname = "onmouseup"; 286437da2899SCharles.Forsyth im.genattr.evmask |= E->SEonmouseup; 286537da2899SCharles.Forsyth } 286637da2899SCharles.Forsyth if(hname != "") 286737da2899SCharles.Forsyth puthandler(ex, oim, hname, e.value); 286837da2899SCharles.Forsyth } 286937da2899SCharles.Forsyth if(im.genattr != nil) 287037da2899SCharles.Forsyth im.genattr.events = nil; 287137da2899SCharles.Forsyth 287237da2899SCharles.Forsyth # private variables 287337da2899SCharles.Forsyth ES->varinstant(oim, ES->DontEnum|ES->DontDelete, "@PRIVimageid", 287437da2899SCharles.Forsyth ref RefVal(ES->numval(real im.imageid))); 287537da2899SCharles.Forsyth # to keep track of src as currently known in item 287637da2899SCharles.Forsyth# ES->varinstant(oim, ES->DontEnum|ES->DontDelete, "@PRIVsrc", 287737da2899SCharles.Forsyth# ref RefVal(ES->strval(src))); 287837da2899SCharles.Forsyth return ES->objval(oim); 287937da2899SCharles.Forsyth} 288037da2899SCharles.Forsyth 288137da2899SCharles.Forsythcolorval(v: int) : ref Val 288237da2899SCharles.Forsyth{ 288337da2899SCharles.Forsyth return ES->strval(sys->sprint("%.6x", v)); 288437da2899SCharles.Forsyth} 288537da2899SCharles.Forsyth 288637da2899SCharles.Forsyth# If the o.name is a recognizable color, return it, else dflt 288737da2899SCharles.Forsythcolorxfer(ex: ref Exec, o: ref Obj, name: string, dflt: int) : int 288837da2899SCharles.Forsyth{ 288937da2899SCharles.Forsyth v := ES->get(ex, o, name); 289037da2899SCharles.Forsyth if(v == ES->undefined) 289137da2899SCharles.Forsyth return dflt; 289237da2899SCharles.Forsyth return CU->color(ES->toString(ex, v), dflt); 289337da2899SCharles.Forsyth} 289437da2899SCharles.Forsyth 289537da2899SCharles.Forsythstrxfer(ex : ref Exec, o: ref Obj, name: string, dflt: string) : string 289637da2899SCharles.Forsyth{ 289737da2899SCharles.Forsyth v := ES->get(ex, o, name); 289837da2899SCharles.Forsyth if(v == ES->undefined) 289937da2899SCharles.Forsyth return dflt; 290037da2899SCharles.Forsyth return ES->toString(ex, v); 290137da2899SCharles.Forsyth} 290237da2899SCharles.Forsyth 290337da2899SCharles.ForsythScriptWin.new(f: ref Layout->Frame, ex: ref Exec, loc: ref Obj, par: ref ScriptWin) : ref ScriptWin 290437da2899SCharles.Forsyth{ 290537da2899SCharles.Forsyth return ref ScriptWin(f, ex, loc, ES->objval(ex.global), par, nil, nil, nil, "", "", "", 1, 0, 0, nil); 290637da2899SCharles.Forsyth} 290737da2899SCharles.Forsyth 290837da2899SCharles.Forsyth# Make a new ScriptWin with f as frame and new, empty 290937da2899SCharles.Forsyth# Window object as obj, to be a child window of sw's window. 291037da2899SCharles.ForsythScriptWin.addkid(sw: self ref ScriptWin, f: ref Layout->Frame) 291137da2899SCharles.Forsyth{ 291237da2899SCharles.Forsyth (cex, clocobj) := makeframeex(f); 291337da2899SCharles.Forsyth csw := ScriptWin.new(f, cex, clocobj, sw); 291437da2899SCharles.Forsyth wininstant(csw); 291537da2899SCharles.Forsyth sw.kids = csw :: sw.kids; 291637da2899SCharles.Forsyth} 291737da2899SCharles.Forsyth 291837da2899SCharles.ForsythScriptWin.dummy(): ref ScriptWin 291937da2899SCharles.Forsyth{ 292037da2899SCharles.Forsyth f := ref Layout->Frame; 292137da2899SCharles.Forsyth f.doc = ref Build->Docinfo; 292237da2899SCharles.Forsyth f.doc.base = U->parse(""); 292337da2899SCharles.Forsyth f.doc.src = U->parse(""); 292437da2899SCharles.Forsyth (cex, clocobj) := makeframeex(f); 292537da2899SCharles.Forsyth csw := ScriptWin.new(f, cex, clocobj, nil); 292637da2899SCharles.Forsyth wininstant(csw); 292737da2899SCharles.Forsyth return csw; 292837da2899SCharles.Forsyth} 292937da2899SCharles.Forsyth 293037da2899SCharles.Forsyth# Find the ScriptWin in the tree with sw as root that has 293137da2899SCharles.Forsyth# f as frame, returning nil if none. 293237da2899SCharles.Forsyth#ScriptWin.findbyframe(sw: self ref ScriptWin, f: ref Layout->Frame) : ref ScriptWin 293337da2899SCharles.Forsyth#{ 293437da2899SCharles.Forsyth# if(sw.frame.id == f.id) 293537da2899SCharles.Forsyth# return sw; 293637da2899SCharles.Forsyth# for(l := sw.kids; l != nil; l = tl l) { 293737da2899SCharles.Forsyth# x := (hd l).findbyframe(f); 293837da2899SCharles.Forsyth# if(x != nil) 293937da2899SCharles.Forsyth# return x; 294037da2899SCharles.Forsyth# } 294137da2899SCharles.Forsyth# return nil; 294237da2899SCharles.Forsyth#} 294337da2899SCharles.Forsyth 294437da2899SCharles.Forsyth# Find the ScriptWin in the tree with sw as root that has 294537da2899SCharles.Forsyth# fid as frame id, returning nil if none. 294637da2899SCharles.ForsythScriptWin.findbyframeid(sw: self ref ScriptWin, fid: int) : ref ScriptWin 294737da2899SCharles.Forsyth{ 294837da2899SCharles.Forsyth if(sw.frame.id == fid) 294937da2899SCharles.Forsyth return sw; 295037da2899SCharles.Forsyth for(l := sw.kids; l != nil; l = tl l) { 295137da2899SCharles.Forsyth x := (hd l).findbyframeid(fid); 295237da2899SCharles.Forsyth if(x != nil) 295337da2899SCharles.Forsyth return x; 295437da2899SCharles.Forsyth } 295537da2899SCharles.Forsyth return nil; 295637da2899SCharles.Forsyth} 295737da2899SCharles.Forsyth 295837da2899SCharles.Forsyth# Find the ScriptWin in the tree with sw as root that has 295937da2899SCharles.Forsyth# d as doc for the frame, returning nil if none. 296037da2899SCharles.ForsythScriptWin.findbydoc(sw: self ref ScriptWin, d: ref Build->Docinfo) : ref ScriptWin 296137da2899SCharles.Forsyth{ 296237da2899SCharles.Forsyth if(sw.frame.doc == d) 296337da2899SCharles.Forsyth return sw; 296437da2899SCharles.Forsyth for(l := sw.kids; l != nil; l = tl l) { 296537da2899SCharles.Forsyth x := (hd l).findbydoc(d); 296637da2899SCharles.Forsyth if(x != nil) 296737da2899SCharles.Forsyth return x; 296837da2899SCharles.Forsyth } 296937da2899SCharles.Forsyth return nil; 297037da2899SCharles.Forsyth} 297137da2899SCharles.Forsyth 297237da2899SCharles.Forsyth# obj can either be the frame's Window obj, Location obj, or document obj, 297337da2899SCharles.Forsyth# or an Image object within the frame 297437da2899SCharles.ForsythScriptWin.findbyobj(sw : self ref ScriptWin, obj : ref Obj) : ref ScriptWin 297537da2899SCharles.Forsyth{ 297637da2899SCharles.Forsyth if (sw.locobj == obj || sw.ex.global == obj || obj == getdocobj(sw.ex, sw.frame.id)) 297737da2899SCharles.Forsyth return sw; 297837da2899SCharles.Forsyth if(opener != nil && (opener.locobj == obj || opener.ex.global == obj)) 297937da2899SCharles.Forsyth return opener; 298037da2899SCharles.Forsyth for(sil := sw.imgs; sil != nil; sil = tl sil) { 298137da2899SCharles.Forsyth if((hd sil).obj == obj) 298237da2899SCharles.Forsyth return sw; 298337da2899SCharles.Forsyth } 298437da2899SCharles.Forsyth for (l := sw.kids; l != nil; l = tl l) { 298537da2899SCharles.Forsyth x := (hd l).findbyobj(obj); 298637da2899SCharles.Forsyth if (x != nil) 298737da2899SCharles.Forsyth return x; 298837da2899SCharles.Forsyth } 298937da2899SCharles.Forsyth return nil; 299037da2899SCharles.Forsyth} 299137da2899SCharles.Forsyth 299237da2899SCharles.ForsythScriptWin.findbyname(sw : self ref ScriptWin, name : string) : ref ScriptWin 299337da2899SCharles.Forsyth{ 299437da2899SCharles.Forsyth if (sw.frame != nil && sw.frame.name == name) 299537da2899SCharles.Forsyth return sw; 299637da2899SCharles.Forsyth for (l := sw.kids; l != nil; l = tl l) { 299737da2899SCharles.Forsyth x := (hd l).findbyname(name); 299837da2899SCharles.Forsyth if (x != nil) 299937da2899SCharles.Forsyth return x; 300037da2899SCharles.Forsyth } 300137da2899SCharles.Forsyth return nil; 300237da2899SCharles.Forsyth} 300337da2899SCharles.Forsyth 300437da2899SCharles.Forsythnewcharon(url: string, nm: string, sw: ref ScriptWin) 300537da2899SCharles.Forsyth{ 300637da2899SCharles.Forsyth cs := chan of string; 300737da2899SCharles.Forsyth 300837da2899SCharles.Forsyth spawn CH->startcharon(url, cs); 300937da2899SCharles.Forsyth for(;;){ 301037da2899SCharles.Forsyth alt{ 301137da2899SCharles.Forsyth s := <- cs => 301237da2899SCharles.Forsyth if(s == "B") 301337da2899SCharles.Forsyth continue; 301437da2899SCharles.Forsyth if(s == "E") 301537da2899SCharles.Forsyth exit; 30168911721eSCharles.Forsyth (nil, l) := sys->tokenize(s, " "); 301737da2899SCharles.Forsyth case hd l{ 301837da2899SCharles.Forsyth "L" => 301937da2899SCharles.Forsyth sw.newloc = hd tl l; 302037da2899SCharles.Forsyth sw.newloctarg = nm; 302137da2899SCharles.Forsyth checknewlocs(sw); 302237da2899SCharles.Forsyth } 302337da2899SCharles.Forsyth } 302437da2899SCharles.Forsyth } 302537da2899SCharles.Forsyth} 3026