forsyth20121205-174063a80cc13 years agoHistory
3025 lines · 80.0 KB · Brainfuck
RawDownload
implement JScript; include "common.m";include "ecmascript.m"; ES: Ecmascript;	Exec, Obj, Call, Prop, Val, Ref, RefVal, Builtin, ReadOnly: import ES;me: ESHostobj; # local copies from CUsys: Sys;CU: CharonUtils; D: Draw;S: String;T: StringIntTab;C: Ctype;B: Build;	Item: import B;CH: Charon;L: Layout;	Frame, Control: import L;U: Url;	Parsedurl: import U;E: Events;	Event, ScriptEvent: import E; G : Gui; JScript: module{	# First, conform to Script interface	defaultStatus: string;	jevchan: chan of ref ScriptEvent;	versions: array of string; 	init: fn(cu: CharonUtils): string;	frametreechanged: fn(top: ref Layout->Frame);	havenewdoc: fn(f: ref Layout->Frame);	evalscript: fn(f: ref Layout->Frame, s: string) : (string, string, string);	framedone: fn(f : ref Layout->Frame, hasscripts : int); 	#	# implement the host object interface, too	#	get:		fn(ex: ref Exec, o: ref Obj, property: string): ref Val;	put:		fn(ex: ref Exec, o: ref Obj, property: string, val: ref Val);	canput:	fn(ex: ref Exec, o: ref Obj, property: string): ref Val;	hasproperty:	fn(ex: ref Exec, o: ref Obj, property: string): ref Val;	delete:		fn(ex: ref Exec, o: ref Obj, property: string);	defaultval:	fn(ex: ref Exec, o: ref Obj, tyhint: int): ref Val;	call:		fn(ex: ref Exec, func, this: ref Obj, args: array of ref Val, eval: int): ref Ref;	construct:	fn(ex: ref Exec, func: ref Obj, args: array of ref Val): ref Obj;}; versions = array [] of {	"javascript",	"javascript1.0",	"javascript1.1",	"javascript1.2",	"javascript1.3",}; # Call init() before calling anything else.# It makes a global object (a Window) for the browser's top level frame,# and also puts a navaigator object in it.  The document can't be filled# in until the first document gets loaded.## This module keeps track of the correspondence between the Script Window# objects and the corresponding Layout Frames, using the ScriptWin adt to# build a tree mirroring the structure.  The root of the tree never changes# after first being set (but changing its document essentially resets all of the# other data structures).  After charon has built its top-level window, it# should call frametreechanged(top).## When a frame gets reset or gets some frame children added, call frametreechanged(f),# where f is the changed frame.  This module will update its ScriptWin tree as needed.## Whenever the document in a (Layout) Frame f changes, call havenewdoc(f)# after the frame's doc field is set. This causes this module to initialize the document# object in the corresponding window object.## From within the build process, call evalscript(containing frame, script) to evaluate# global code fragments as needed.  The return value is two strings: a possible error# description, and HTML that is the result of a document.write (so it should be spliced# in at the point where the <SCRIPT> element occurred).  evalscript() also handles# the job of synching up the Docinfo data (on the Build side) with the document object# (on the Script side).## For use by other external routines, the xfertoscriptobjs() and xferfromscriptobjs()# functions that do the just-described synch-up are available for external callers. # Adt for keeping track of correspondence between Image objects# and their corresponding Build items.ScriptImg: adt{	item: ref Build->Item.Iimage;	obj: ref Obj;}; ScriptForm : adt {	form : ref Build->Form;	obj : ref Obj;	ix : int;		# index in document.forms array	fields : list of (ref Build->Formfield, ref Obj);}; # Adt for keeping track of correspondence between Window# objects and their corresponding Frames. ScriptWin: adt{	frame: ref Layout->Frame;	ex: ref Exec;		# ex.global is frame's Window obj	locobj: ref Obj;		# Location object for window	val : ref Val;		# val of ex.global - used to side-effect entry in parent.frames[] 	parent: ref ScriptWin;	forms: list of ref ScriptForm;	# no guaranteed order	kids: cyclic list of ref ScriptWin;	imgs: list of ref ScriptImg;	newloc: string;		# url to go to after script finishes executing	newloctarg: string;	# target frame for newloc	docwriteout: string;	inbuild: int;	active: int;		# frame or sub-frame has scripts	error: int;	imgrelocs: list of ref Obj; 	new: fn(f: ref Layout->Frame, ex: ref Exec, loc: ref Obj, par: ref ScriptWin) : ref ScriptWin;	addkid: fn(sw: self ref ScriptWin, f: ref Layout->Frame);	dummy: fn(): ref ScriptWin;#	findbyframe: fn(sw: self ref ScriptWin, f: ref Layout->Frame) : ref ScriptWin;	findbyframeid: fn(sw: self ref ScriptWin, fid: int) : ref ScriptWin;	findbydoc: fn(sw: self ref ScriptWin, d: ref Build->Docinfo) : ref ScriptWin;	findbyobj: fn(sw : self ref ScriptWin, obj : ref Obj) : ref ScriptWin;	findbyname: fn(sw : self ref ScriptWin, name : string) : ref ScriptWin;}; opener: ref ScriptWin;winclose: int; # Helper adts for initializing objects.# Methods go in prototype, properties go in objects MethSpec: adt{	name: string;	args: array of string;};  IVundef, IVnull, IVtrue, IVfalse, IVnullstr, IVzero, IVzerostr, IVarray: con iota; PropSpec: adt{	name: string;	attr: int;	initval: int;	# one of IVnull, etc.}; ObjSpec: adt{	name: string;	methods: array of MethSpec;	props: array of PropSpec;}; MimeSpec: adt{	description: string;	suffixes: string;	ty: string;}; # Javascript 1.1 (Netscape 3) client objects objspecs := array[] of {    ObjSpec("Anchor", 	nil,	array[] of {PropSpec		("name", ReadOnly, IVnullstr) }	),    ObjSpec("Applet",	nil,	nil	),    ObjSpec("document",	array[] of {MethSpec		("close", nil),		("open", array[] of { "mimetype", "replace" }),		("write", array[] of { "string" }),		("writeln", array[] of { "string" }) },	array[] of {PropSpec		("alinkColor", 0, IVnullstr),		("anchors", ReadOnly, IVarray),		("applets", ReadOnly, IVarray),		("bgColor", 0, IVnullstr),		("cookie", 0, IVnullstr),		("domain", 0, IVnullstr),		("embeds", ReadOnly, IVarray),		("fgColor", 0, IVnullstr),		("forms", ReadOnly, IVarray),		("images", ReadOnly, IVarray),		("lastModified", ReadOnly, IVnullstr),		("linkColor", 0, IVnullstr),		("links", ReadOnly, IVarray),		("location", 0, IVnullstr),		("plugins", ReadOnly, IVarray),		("referrer", ReadOnly, IVnullstr),		("title", ReadOnly, IVnullstr),		("URL", ReadOnly, IVnullstr),		("vlinkColor", 0, IVnullstr) }	),    ObjSpec("Form",	array[] of {MethSpec		("reset", nil),		("submit", nil) },	array[] of {PropSpec		("action", 0, IVnullstr),		("elements", ReadOnly, IVarray),		("encoding", 0, IVnullstr),		("length", ReadOnly, IVzero),		("method", 0, IVnullstr),		("name", 0, IVnullstr),		("target", 0, IVnullstr) }	),   # This is merge of Netscape objects (to save code & data space):   # Button, Checkbox, Hidden, Radio, Reset, Select, Text, and Textarea    ObjSpec("FormField",	array[] of {MethSpec		("blur", nil),		("click", nil),		("focus", nil),		("select", nil) },	array[] of {PropSpec		("checked", 0, IVundef),		("defaultChecked", 0, IVundef),		("defaultValue", 0, IVundef),		("form", ReadOnly, IVundef),		("length", 0, IVundef),		("name", 0, IVnullstr),		("options", 0, IVundef),		("type", ReadOnly, IVundef),		("selectedIndex", 0, IVundef),		("value", 0, IVnullstr) }	),    ObjSpec("History",	array[] of {MethSpec		("back", nil),		("forward", nil),		("go", array[] of { "location-or-delta" }) },	array[] of {PropSpec		("current", ReadOnly, IVnullstr),		("length", ReadOnly, IVzero),		("next", ReadOnly, IVnullstr),		("previous", ReadOnly, IVnullstr) }	),    ObjSpec("Image",	nil,	array[] of {PropSpec		("border", ReadOnly, IVzerostr),		("complete", ReadOnly, IVfalse),		("height", ReadOnly, IVzerostr),		("hspace", ReadOnly, IVzerostr),		("lowsrc", 0, IVnullstr),		("name", ReadOnly, IVnullstr),		("src", 0, IVnullstr),		("vspace", ReadOnly, IVzerostr),		("width", ReadOnly, IVzerostr) }	),    ObjSpec("Link",	nil,	array[] of {PropSpec		("hash", 0, IVnullstr),		("host", 0, IVnullstr),		("hostname", 0, IVnullstr),		("href", 0, IVnullstr),		("pathname", 0, IVnullstr),		("port", 0, IVnullstr),		("protocol", 0, IVnullstr),		("search", 0, IVnullstr),		("target", 0, IVnullstr) }	),    ObjSpec("Location",	array[] of {MethSpec		("reload", array[] of { "forceGet" }),		("replace", array[] of { "URL" }) },	array[] of {PropSpec		("hash", 0, IVnullstr),		("host", 0, IVnullstr),		("hostname", 0, IVnullstr),		("href", 0, IVnullstr),		("pathname", 0, IVnullstr),		("port", 0, IVnullstr),		("protocol", 0, IVnullstr),		("search", 0, IVnullstr) }	),    ObjSpec("MimeType",	nil,	array[] of {PropSpec		("description", ReadOnly, IVnullstr),		("enabledPlugin", ReadOnly, IVnull),		("suffixes", ReadOnly, IVnullstr),		("type", ReadOnly, IVnullstr) }	),    ObjSpec("Option",	nil,	array[] of {PropSpec		("defaultSelected", 0, IVfalse),		("index", 0, IVundef),		("selected", 0, IVfalse),		("text", 0, IVnullstr),		("value", 0, IVnullstr) }	),    ObjSpec("navigator",	array[] of {MethSpec		("javaEnabled", nil),		("plugins.refresh", nil),		("taintEnabled", nil) },	array[] of {PropSpec		("appCodeName", ReadOnly, IVnullstr),		("appName", ReadOnly, IVnullstr),		("appVersion", ReadOnly, IVnullstr),		("mimeTypes", ReadOnly, IVarray),		("platform", ReadOnly, IVnullstr),		("plugins", ReadOnly, IVarray),		("userAgent", ReadOnly, IVnullstr) }	),    ObjSpec("Plugin",	nil,	array[] of {PropSpec		("description", 0, IVnullstr),		("filename", 0, IVnullstr),		("length", 0, IVzero),		("name", 0, IVnullstr) }	),     ObjSpec("Screen",	nil,	array[] of {PropSpec		("availHeight", ReadOnly, IVzero),		("availWidth", ReadOnly, IVzero),		("availLeft", ReadOnly, IVzero),		("availTop", ReadOnly, IVzero),		("colorDepth", ReadOnly, IVzero),		("pixelDepth", ReadOnly, IVzero),		("height", ReadOnly, IVzero),		("width", ReadOnly, IVzero) }	),     ObjSpec("Window",	array[] of {MethSpec		("alert", array[] of { "msg" }),		("blur", nil),		("clearInterval", array[] of { "intervalid" }),		("clearTimeout", array[] of { "timeoutid" }),		("close", nil),		("confirm", array[] of  { "msg" }),		("focus", nil),		("moveBy", array[] of { "dx", "dy" }),		("moveTo", array[] of { "x", "y" }),		("open", array[] of { "url", "winname", "winfeatures" }),		("prompt", array[] of { "msg", "inputdflt" }),		("resizeBy", array[] of { "dh", "dw" }),		("resizeTo", array[] of { "width", "height" }),		("scroll", array[] of { "x", "y"  }),		("scrollBy", array[] of { "dx", "dy" }),		("scrollTo", array[] of { "x", "y" }),		("setInterval", array[] of { "code", "msec" }),		("setTimeout", array[] of { "expr", "msec" }) },	array[] of {PropSpec		("closed", ReadOnly, IVfalse),		("defaultStatus", 0, IVnullstr),		("document", 0, IVnull),		("frames", ReadOnly, IVnull),	# array, really		("history", 0, IVnull),	# array, really		("length", ReadOnly, IVzero),		("location", 0, IVnullstr),#		("Math", ReadOnly, IVnull),		("name", 0, IVnullstr),		("navigator", ReadOnly, IVnull),		("offscreenBuffering", 0, IVnullstr),		("opener", 0, IVnull),		("parent", ReadOnly, IVnull),		("screen", 0, IVnull),		("self", ReadOnly, IVnull),		("status", 0, IVnullstr),		("top", ReadOnly, IVnull),		("window", ReadOnly, IVnull) }	)}; # Currently supported charon mime typesmimespecs := array[] of {    MimeSpec("HTML", 	"htm,html",	"text/html"	),    MimeSpec("Plain text", 	"txt,text",	"text/plain"	),   MimeSpec("Gif Image", 	"gif",	"image/gif"	),    MimeSpec("Jpeg Image", 	"jpeg,jpg,jpe",	"image/jpeg"	),    MimeSpec("X Bitmap Image", 	"",	"image/x-xbitmap"	)}; # charon's 's' debug flag:#	1:	basic syntax and runtime errors#	2:	'event' logging and DOM actions#	3:	print parsed code and ops as executed#	4:	print value of expression statements and abort on runtime errorsdbg := 0;dbgdom := 0; top: ref ScriptWin;createdimages : list of ref Obj;nullstrval: ref Val;zeroval: ref Val;zerostrval: ref Val; # Call this after charon's main (top) frame has been builtinit(cu: CharonUtils) : string{	CU = cu;	sys = load Sys Sys->PATH;	D = load Draw Draw->PATH;	S = load String String->PATH;	T = load StringIntTab StringIntTab->PATH;	U = load Url Url->PATH;	if (U != nil)		U->init();	C = cu->C;	B = cu->B;	L = cu->L;	E = cu->E;	CH = cu->CH;	G = cu->G;	dbg = int (CU->config).dbg['s'];	if (dbg > 1)		dbgdom = 1;	ES = load Ecmascript Ecmascript->PATH;	if(ES == nil)		return sys->sprint("could not load module %s: %r", Ecmascript->PATH);	err := ES->init();	if (err != nil) 		return sys->sprint("ecmascript error: %s", err); 	me = load ESHostobj SELF;	if(me == nil)		return sys->sprint("jscript: could not load  self as a ESHostobj: %r");	if(dbg >= 3) {		ES->debug['p'] = 1;	# print parsed code		ES->debug['e'] = 1;	# prinv ops as they are executed		if(dbg >= 4) {			ES->debug['e'] = 2;			ES->debug['v'] = 1;	# print value of expression statements			ES->debug['r'] = 1;	# print and abort if runtime errors		}	}		# some constant values, for initialization	nullstrval = ES->strval("");	zeroval = ES->numval(0.);	zerostrval = ES->strval("0");	jevchan = chan of ref ScriptEvent;	spawn jevhandler();	return nil;} doneevent := ScriptEvent(-1,0,0,0,0,0,0,0,0,nil,nil,0); # Used to receive and act upon ScriptEvents from main charon thread.# Want to queue the events up, so that the main thread doesn't have# to wait, and spawn off a do_on, one at a time, so that they don't# interfere with each other.# When do_on is finished, it must send a copy of doneevent# so that jevhandler knows it can spawn another do_on.jevhandler(){	q := array[10] of ref ScriptEvent;	qhead := 0;	qtail := 0;	spawnok := 1;	for(;;) {		jev := <- jevchan;		if(jev.kind == -1)			spawnok = 1;		else			q[qtail++] = jev;		jev = nil; 

Lines 1–500 of 3025.