123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521(**************************************************************************
* Copyright (C) 2005-2008
* Dmitri Boulytchev (db@tepkom.ru), St.Petersburg State University
* Universitetskii pr., 28, St.Petersburg, 198504, RUSSIA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* See the GNU Lesser General Public License version 2.1 for more details
* (enclosed in the file COPYING).
**************************************************************************)openPrintftypeer=View.ertypeviewer=erletref'=reflettoHTML=View.toStringletescapes=letbuf=Buffer.create(String.lengths*2)infori=0toString.lengths-1doBuffer.add_stringbuf(matchs.[i]with|'<'->"<"|'>'->">"|'&'->"&"|'"'->"""|c->String.make1c)done;Buffer.contentsbufletstrings=View.string(escapes)letraws=View.stringsletunit=View.unitletint=View.intletfloat=View.floatletbool=View.boolletchar=View.charletseq=View.seqletseqa=View.seqaletbr=raw"<br>"lettag?(attrs="")sp=seq[raw(sprintf"<%s>"(s^(ifattrs=""then""else" ")^attrs));p;raw(sprintf"</%s>"s)]letlinkurl=seq[raw@@sprintf"<link rel=\"stylesheet\" type=\"text/css\" href=\"%s\" media=\"screen\">"url]lethtml?(attrs="")=tag"html"~attrs:attrslettitle?(attrs="")=tag"title"~attrs:attrsletbody?(attrs="")=tag"body"~attrs:attrsletul?(attrs="")=tag"ul"~attrs:attrsletol?(attrs="")=tag"ol"~attrs:attrsletli?(attrs="")=tag"li"~attrs:attrsletb?(attrs="")=tag"b"~attrs:attrsleti?(attrs="")=tag"i"~attrs:attrslettable?(attrs="")=tag"table"~attrs:attrslettr?(attrs="")=tag"tr"~attrs:attrslettd?(attrs="")=tag"td"~attrs:attrsletth?(attrs="")=tag"th"~attrs:attrsletform?(attrs="")=tag"form"~attrs:attrsletinput?(attrs="")=tag"input"~attrs:attrsletcheckbox?(attrs="")=tag"input"~attrs:(sprintf"%s type=\"checkbox\""attrs)letbutton?(attrs="")=tag"button"~attrs:(sprintf"%s type=\"button\""attrs)letdiv?(attrs="")=tag"div"~attrs:(sprintf"%s contentEditable=\"true\""attrs)lettext?(attrs="")=tag"input"~attrs:(sprintf"%s type=\"text\""attrs)lettextarea?(attrs="")=tag"textarea"~attrs:attrsletradio?(attrs="")triples=seq(List.map(fun(name,v,a)->seq[tag"input"~attrs:(sprintf"%s %s type=\"radio\" value=\"%s\""attrsav)name;raw" "])triples)letselect?(attrs="")triples=tag"select"~attrs:attrs(seq(List.map(fun(name,v,a)->tag"option"~attrs:(sprintf"%s value=\"%s\""av)name)triples))letanchorrp=seq[raw(sprintf"<a name=%S>"r);p;raw"</a>"]letrefrp=seq[raw(sprintf"<a href=%S>"r);p;raw"</a>"]letnamednp=seq[b(string(n^": "));p]letlistp=tag"ul"(seq(List.map(tag"li")p))letarrayp=tag"ul"(seqa(Array.map(tag"li")p))letfieldsl=list(List.map(fun(n,x)->namednx)l)letmakefx=raw(fx)moduleWizard=structmodulePage=structmoduleItem=structtypetyp=|Stringofstring|Textofstring*string|Divofstring*string|Flagofstring|Selectofstring*(viewer*string*string)list|Radioofstring*(viewer*string*string)listtypet={name:string;id:string;typ:typ}letmakeidnametyp={name=name;id=sprintf"%s_%s"idname;typ=typ}letrendert=letattrs'attrs=sprintf"%s id=\"%s\""attrst.idint.id,(seq[td~attrs:"align=\"right\" valign=\"center\""(rawt.name);td~attrs:"align=\"center\" valign=\"center\""(raw":");td~attrs:"align=\"left\" valign=\"center\""(matcht.typwith|Stringattrs->text~attrs:(attrs'attrs)View.empty|Text(attrs,text)->textarea~attrs:(attrs'attrs)(rawtext)|Div(attrs,text)->div~attrs:(attrs'attrs)(rawtext)|Flagattrs->checkbox~attrs:(attrs'attrs)View.empty|Select(attrs,triples)->select~attrs:(attrs'attrs)triples|Radio(attrs,triples)->radio~attrs:(attrs'(sprintf"%s name=\"%s\""attrst.id))triples)])endclasscidattrs=object(this)valmutableitems:Item.tlist=[]methodaddnameitem=items<-(Item.makeidnameitem)::items;thismethodtext?(attrs="")?(default="")name=this#addname(Item.Text(attrs,default))methoddiv?(attrs="")?(default="")name=this#addname(Item.Div(attrs,default))methodstring?(attrs="")name=this#addname(Item.Stringattrs)methodflag?(attrs="")name=this#addname(Item.Flagattrs)methodcombo?(attrs="")nameitems=this#addname(Item.Select(attrs,items))methodradio?(attrs="")nameitems=this#addname(Item.Radio(attrs,items))methodidname=(List.find(funi->i.Item.name=name)items).Item.idmethodrender(back,backA,backCb)(next,nextA,nextCb)=letids,rendered=List.split(List.map(funt->letid,r=Item.rendertin(t.Item.name,id,t.Item.typ),r)(List.revitems))inlethtml=table~attrs:attrs(seq((List.maptrrendered)@[tr(td~attrs:"colspan=\"3\""(raw"<hr>"));tr(td~attrs:"colspan=\"3\" align=\"center\""(seq[button~attrs:(sprintf"%s onclick=\"%s\""backAbackCb)(rawback);raw" ";button~attrs:(sprintf"%s onclick=\"%s\""nextAnextCb)(rawnext)]))]))inletsavef=sprintf"save_%s"idinletloadf=sprintf"load_%s"idinletjs=Buffer.create1024inletgenerates=Buffer.add_stringjssinletinnerTextelemgen=generate(sprintf"if (typeof %s.innerText === \"undefined\") {"elem);generate(sprintf" %s"(gen(elem^".textContent")));generate("}\n");generate("else {\n");generate(sprintf" %s"(gen(elem^".innerText")));generate("}\n")ingenerate(sprintf"function %s (curr) {\n"loadf);generate" var coll = null;\n";List.iter(fun(name,id,t)->matchtwith|Item.Flag_->generate(sprintf" if (curr[\"%s\"]) document.getElementById (\"%s\").checked = curr[\"%s\"];\n"nameidname);|Item.Div_->innerText(sprintf"document.getElementById (\"%s\")"id)(funelem->sprintf" if (curr[\"%s\"]) %s = curr[\"%s\"];\n"nameelemname)|Item.Radio_->generate(sprintf" if (curr[\"%s\"]) {\n"name);generate(sprintf" coll = document.getElementsByName (\"%s\");\n"id);generate" for (var i = 0; i<coll.length; i++) {\n";generate(sprintf" coll[i].checked = coll[i].value == curr[\"%s\"];\n"name);generate" }\n";generate" }\n"|_->generate(sprintf" if (curr[\"%s\"]) document.getElementById (\"%s\").value = curr[\"%s\"];\n"nameidname);)ids;generate"}\n";generate(sprintf"function %s (curr) {\n"savef);generate" var coll = null;\n";List.iter(fun(name,id,t)->matchtwith|Item.Flag_->generate(sprintf" curr[\"%s\"] = document.getElementById(\"%s\").checked;\n"nameid)|Item.Div_->innerText(sprintf"document.getElementById(\"%s\")"id)(funelem->sprintf" curr[\"%s\"] = %s.replace(/\\u00a0/g, \" \");\n"nameelem)|Item.Radio_->generate(sprintf" coll = document.getElementsByName (\"%s\");\n"id);generate" for (var i = 0 ; i<coll.length; i++) {\n";generate" if (coll[i].checked) {\n";generate(sprintf" curr[\"%s\"] = coll[i].value;\n"name);generate" break;\n";generate" }\n";generate" }\n";|_->generate(sprintf" curr[\"%s\"] = document.getElementById(\"%s\").value;\n"nameid))ids;generate"}\n";savef,loadf,Buffer.contentsjs,htmlendendtypepage=<string:?attrs:string->string->page;text:?attrs:string->?default:string->string->page;div:?attrs:string->?default:string->string->page;flag:?attrs:string->string->page;combo:?attrs:string->string->(viewer*string*string)list->page;radio:?attrs:string->string->(viewer*string*string)list->page;id:string->string;>typet=<page:(page->page)list->page;generate:string*string>letstring?(attrs="")name(p:page)=p#string~attrs:attrsnameletflag?(attrs="")name(p:page)=p#flag~attrs:attrsnameletcombo?(attrs="")nameitems(p:page)=p#combo~attrs:attrsnameitemsletradio?(attrs="")nameitems(p:page)=p#radio~attrs:attrsnameitemslettext?(attrs="")?(default="")name(p:page)=p#text~attrs:attrs~default:defaultnameletdiv?(attrs="")?(default="")name(p:page)=p#div~attrs:attrs~default:defaultnameletmapifl=letrecinneri=function|[]->[]|h::tl->fih::inner(i+1)tlininner0lclasscattrsidtargetnavigate=objectvalmutablepages:Page.clist=[]valmutablei:int=0methodpagel=letp=newPage.c(sprintf"page_%s_%d"idi)attrsinpages<-p::pages;i<-i+1;List.fold_left(funpf->fp)(p:>page)lmethodgenerate=letn=List.lengthpagesinletbb=sprintf"bb_%s"idinletnb=sprintf"nb_%s"idinletpg=sprintf"page_%s"idinletbf=sprintf"do_back_%s"idinletnf=sprintf"do_next_%s"idinletpc=sprintf"pages_%s"idinletpr=sprintf"present_%s"idinletsf=sprintf"savefs_%s"idinletlf=sprintf"loadfs_%s"idinletcr=sprintf"curr_%s"idinletsv=sprintf"save_%s"idinletld=sprintf"load_%s"idinletst=sprintf"stack_%s"idinletsp=sprintf"stack_ptr_%s"idinletpu=sprintf"push_%s"idinletpo=sprintf"pop_%s"idinletjs=Buffer.create1024inletgenerates=Buffer.add_stringjssinletfuns,pages=List.split(mapi(funip->letsavef,loadf,script,page=p#render("Back",sprintf"id=\"%s\""bb,bf^" ()")("Next",sprintf"id=\"%s\""nb,nf^" ()")ingeneratescript;(savef,loadf),toHTMLpage)(List.revpages))inletsavefs,loadfs=List.splitfunsingenerate(sprintf"var %s = 0;\n"sp);generate(sprintf"var %s = new Array(%d);\n"stn);generate(sprintf"function %s (i) {\n"pu);generate(sprintf" %s [%s++] = i;\n"stsp);generate"}\n";generate(sprintf"function %s () {\n"po);generate(sprintf" return %s [--%s];\n"stsp);generate"}\n";generate(sprintf"var %s = {};\n"cr);generate(sprintf"var %s = 0;\n"pg);generate(sprintf"var %s = [\n"pc);List.iter(funp->generate(sprintf" \"%s\",\n"(String.escapedp)))pages;generate" \"\"];\n";generate(sprintf"var %s = [\n"sf);List.iter(funs->generate(sprintf" %s,\n"s))savefs;generate" \"\"];\n";generate(sprintf"function %s () {\n"sv);generate(sprintf" %s[%s] (%s);\n"sfpgcr);generate"}\n";generate(sprintf"var %s = [\n"lf);List.iter(funs->generate(sprintf" %s,\n"s))loadfs;generate" \"\"];\n";generate(sprintf"function %s () {\n"ld);generate(sprintf" %s[%s] (%s);\n"lfpgcr);generate"}\n";generate(sprintf"function %s () {\n"pr);generate(sprintf" document.getElementById (\"%s\").innerHTML = %s[%s];\n"targetpcpg);generate(sprintf" %s (%s);\n"ldcr);generate(sprintf" document.getElementById (\"%s\").disabled = 0 == %s;\n"bbpg);generate"}\n";generate(sprintf"function %s () {\n"bf);generate(sprintf" %s (%s);\n"svcr);generate(sprintf" %s = %s ();\n"pgpo);generate(sprintf" %s ();\n"pr);generate"}\n";generate(sprintf"function %s () {\n"nf);generate(sprintf" %s (%s);\n"svcr);generate(sprintf" var nxt = %s (%s, %s);\n"navigatepgcr);generate(sprintf" if (nxt < 0 || nxt == %s) return;\n"pg);generate(sprintf" %s (%s);\n"pupg);generate(sprintf" %s = nxt;\n"pg);generate(sprintf" %s ();\n"pr);generate"}\n";(pr,Buffer.contentsjs)endletcreate?(attrs="")idtargetnavigate=newcattrsidtargetnavigateendmoduletypeElement=sigtypetvaltoHTML:t->stringendmoduleL=ListmoduleString=structtypet=stringletnamednv=toHTML(namedn(rawv))letfieldsv=toHTML(fields(List.map(fun(n,v)->n,rawv)v))letanchornv=toHTML(anchorn(rawv))letrefnv=toHTML(refn(rawv))lettoHTMLs=sendmoduleAnchor(X:sigtypetvalname:stringend)=structmoduleH=Hashtbl.Make(structtypet=X.tlethash=Hashtbl.hashletequal=(==)end)leth=H.create1024letindex=leti=ref'0in(fun()->incri;!i)letsetx=H.addhx(index())letisSetx=H.memhxletgetx=ifnot(isSetx)thensetx;sprintf"%s.anchor%d"X.name(H.findhx)leturlt="#"^gettletrefttext=ref(urlt)textmoduleString=structletrefttext=String.ref(urlt)textendendmoduleRaw=structtypet=stringlettoHTMLs=toHTML(raws)endopenListmoduleList(T:Element)=structtypet=T.tlistlettoHTMLl=toHTML(list(List.map(makeT.toHTML)l))endmoduleArray(T:Element)=structtypet=T.tarraylettoHTMLa=toHTML(array(Array.map(makeT.toHTML)a))endmoduleNamedPair(N:sigvalfirst:stringvalsecond:stringend)(F:Element)(S:Element)=structtypet=F.t*S.tlettoHTML(f,s)=toHTML(list[namedN.first(makeF.toHTMLf);namedN.second(makeS.toHTMLs);])endmodulePair=NamedPair(structletfirst=""letsecond=""end)moduleSet(S:Set.S)(V:Elementwithtypet=S.elt)=structtypet=S.tlettoHTMLx=letmoduleLL=List(String)inLL.toHTML(L.sortcompare(L.mapV.toHTML(S.elementsx)))endmoduleMap(M:Map.S)(K:Elementwithtypet=M.key)(V:Element)=structtypet=V.tM.tlettoHTMLx=letmoduleP=NamedPair(structletfirst="key"letsecond="value"end)(K)(V)inletmoduleLL=List(String)inLL.toHTML(L.sortcompare(M.fold(funxyacc->(P.toHTML(x,y))::acc)x[]))endmoduleHashtbl(M:Hashtbl.S)(K:Elementwithtypet=M.key)(V:Element)=structtypet=V.tM.tlettoHTMLx=letmoduleP=NamedPair(structletfirst="key"letsecond="value"end)(K)(V)inletmoduleLL=List(String)inLL.toHTML(L.sortcompare(M.fold(funxyacc->(P.toHTML(x,y))::acc)x[]))end