You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

theme.js 153KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249
  1. // IE DOM Node support
  2. if(document.all) {
  3. Node = new Object();
  4. Node.ELEMENT_NODE = 1;
  5. Node.ATTRIBUTE_NODE = 2;
  6. Node.TEXT_NODE = 3;
  7. Node.CDATA_SECTION_NODE = 4;
  8. Node.ENTITY_REFERENCE_NODE = 5;
  9. Node.ENTITY_NODE = 6;
  10. Node.PROCESSING_INSTRUCTION_NODE = 7;
  11. Node.COMMENT_NODE = 8;
  12. Node.DOCUMENT_NODE = 9;
  13. Node.DOCUMENT_TYPE_NODE = 10;
  14. Node.DOCUMENT_FRAGMENT_NODE = 11;
  15. Node.NOTATION_NODE = 12;
  16. }
  17. /** Default theme constructor.
  18. *
  19. * @param themeRoot The base URL for theme resources.
  20. * @constructor
  21. *
  22. */
  23. function DefaultTheme(themeRoot) {
  24. this.themeName = "DefaultTheme";
  25. // Store the the root URL
  26. this.root = themeRoot;
  27. }
  28. /** Register all renderers to a ajax client.
  29. *
  30. * @param client The ajax client instance.
  31. */
  32. DefaultTheme.prototype.registerTo = function(client) {
  33. // This hides all integer, string, etc. variables
  34. client.registerRenderer(this,"integer",null,function() {});
  35. client.registerRenderer(this,"string",null,function() {});
  36. // and special tags
  37. client.registerRenderer(this,"description",null,function() {});
  38. client.registerRenderer(this,"error",null,function() {});
  39. client.registerRenderer(this,"actions",null,function() {});
  40. // Register renderer functions
  41. client.registerRenderer(this,"component",null,this.renderComponent);
  42. client.registerRenderer(this,"label",null,this.renderLabel);
  43. client.registerRenderer(this,"data",null,this.renderData);
  44. client.registerRenderer(this,"pre",null,this.renderData);
  45. client.registerRenderer(this,"link",null,this.renderLink);
  46. client.registerRenderer(this,"button",null,this.renderButton);
  47. client.registerRenderer(this,"textfield",null,this.renderTextField);
  48. client.registerRenderer(this,"datefield",null,this.renderDateField);
  49. client.registerRenderer(this,"datefield","calendar",this.renderDateFieldCalendar);
  50. client.registerRenderer(this,"select",null,this.renderSelect);
  51. client.registerRenderer(this,"select","optiongroup",this.renderSelectOptionGroup);
  52. client.registerRenderer(this,"select","twincol",this.renderSelectTwincol);
  53. client.registerRenderer(this,"upload",null,this.renderUpload);
  54. client.registerRenderer(this,"embedded",null,this.renderEmbedded);
  55. client.registerRenderer(this,"window",null,this.renderWindow);
  56. client.registerRenderer(this,"framewindow",null,this.renderFramewindow);
  57. client.registerRenderer(this,"open",null,this.renderOpen);
  58. client.registerRenderer(this,"panel",null,this.renderPanel);
  59. client.registerRenderer(this,"orderedlayout",null,this.renderOrderedLayout);
  60. client.registerRenderer(this,"customlayout",null,this.renderCustomLayout);
  61. client.registerRenderer(this,"gridlayout",null,this.renderGridLayout);
  62. client.registerRenderer(this,"tabsheet",null,this.renderTabSheet);
  63. client.registerRenderer(this,"table",null,this.renderScrollTable);
  64. client.registerRenderer(this,"table","paging",this.renderPagingTable);
  65. client.registerRenderer(this,"tree",null,this.renderTree);
  66. client.registerRenderer(this,"tree","coolmenu",this.renderTreeMenu);
  67. //client.registerRenderer(this,"tree","menu",this.renderTreeMenu);
  68. };
  69. /*
  70. #### DOM functions ########################################################
  71. */
  72. DefaultTheme.prototype.createElementTo = function (target, tagName, cssClass) {
  73. if (target == null) return null;
  74. // Create the requested element
  75. var e = target.ownerDocument.createElement(tagName);
  76. // Set CSS class if specified
  77. if (cssClass) {
  78. this.setCSSClass(e,cssClass);
  79. }
  80. // Append to parent
  81. target.appendChild(e);
  82. return e;
  83. }
  84. DefaultTheme.prototype.createTextNodeTo = function (target,text) {
  85. // Sanity check
  86. if (text == null || target == null) return null;
  87. // Create DIV as container
  88. var tn = target.ownerDocument.createTextNode(text);
  89. // Append to parent
  90. target.appendChild(tn);
  91. return tn;
  92. }
  93. DefaultTheme.prototype.getFirstElement = function(parent, elementName) {
  94. if (parent && parent.childNodes) {
  95. for (var i=0;i<parent.childNodes.length;i++) {
  96. if (parent.childNodes[i].nodeName == elementName) {
  97. return parent.childNodes[i];
  98. }
  99. }
  100. }
  101. return null;
  102. }
  103. DefaultTheme.prototype.getFirstTextNode = function(parent) {
  104. if (parent == null || parent.childNodes == null) return null;
  105. var cns = parent.childNodes;
  106. var len = cns.length;
  107. for (var i=0; i<len; i++) {
  108. var child = cns[i];
  109. if (child.nodeType == Node.TEXT_NODE) {
  110. return child;
  111. }
  112. }
  113. }
  114. /**
  115. * Removes all children of an element an element.
  116. *
  117. * @param element Remove children of this element.
  118. *
  119. * @return the element with children removed
  120. */
  121. DefaultTheme.prototype.removeAllChildNodes = function(element) {
  122. //TODO event listener leakage prevention, verify
  123. // MOVED to client
  124. //this.removeAllEventListeners(element);
  125. while (element.childNodes&&element.childNodes.length > 0) {
  126. element.removeChild(element.childNodes[0]);
  127. }
  128. return element;
  129. }
  130. DefaultTheme.prototype.getElementContent = function(parent, elementName) {
  131. if (elementName != null) {
  132. // Find element and return its content
  133. var n = this.getFirstElement(parent,elementName);
  134. if (n == null) return null;
  135. var tn = this.getFirstTextNode(n);
  136. if (tn != null && tn.data != null) {
  137. return tn.data;
  138. }
  139. return "";
  140. } else {
  141. // If no element name is given return
  142. // content of parent
  143. var tn = this.getFirstTextNode(parent);
  144. if (tn != null && tn.data != null) {
  145. return tn.data;
  146. }
  147. return "";
  148. }
  149. }
  150. DefaultTheme.prototype.getChildElements = function(parent, tagName) {
  151. if (parent == null || parent.childNodes == null || tagName == null) return null;
  152. // Iterate all child nodes
  153. var res = new Array();
  154. for (var i=0; i < parent.childNodes.length; i++) {
  155. var n = parent.childNodes[i];
  156. if (n.nodeType == Node.ELEMENT_NODE && n.nodeName == tagName) {
  157. res[res.length++] = n;
  158. }
  159. }
  160. return res;
  161. }
  162. DefaultTheme.prototype.nodeToString = function(node, deep) {
  163. if (node == null) {
  164. return "";
  165. } else if (node.nodeType == Node.TEXT_NODE) {
  166. // Render text nodes.
  167. if (node.data) {
  168. return node.data;
  169. } else {
  170. return "";
  171. }
  172. } else if (node.nodeType == Node.ELEMENT_NODE) {
  173. // Renderer element nodes.
  174. var txt = "<" + node.nodeName;
  175. if (node.attributes.length > 0)
  176. for(var i=0; i<node.attributes.length; i++) {
  177. var a = node.attributes.item(i);
  178. txt += " " + a.name + "=\"" + a.value+"\"";
  179. }
  180. if (deep && node.childNodes != null && node.childNodes.length >0) {
  181. txt += ">";
  182. for (var i=0; i<node.childNodes.length; i++) {
  183. var c = node.childNodes.item(i);
  184. txt += this.nodeToString(c,deep);
  185. }
  186. txt += "</"+node.nodeName+">";
  187. } else {
  188. txt += "/>";
  189. }
  190. return txt;
  191. }
  192. return ""+node.nodeName + "-node";
  193. }
  194. DefaultTheme.prototype.createInputElementTo = function(target,type,className,focusid) {
  195. var input = null;
  196. if (document.all && !window.opera) {
  197. // IE only
  198. input = this.createElementTo(target,"<input type='"+type+"'>");
  199. } else {
  200. // Other browsers
  201. input = this.createElementTo(target,"input");
  202. input.type = type;
  203. }
  204. // Assign class
  205. if (className != null && className != "") {
  206. this.setCSSClass(input,className);
  207. }
  208. if (focusid) input.focusid = focusid;
  209. return input;
  210. }
  211. /*
  212. #### CSS functions ######################################################
  213. */
  214. DefaultTheme.prototype.addCSSClass = function(element, className) {
  215. if (element == null) return element;
  216. if (element.className) {
  217. var classArray = element.className.split(" ");
  218. for (var i in classArray) {
  219. if (classArray[i]==className) {
  220. // allready in className
  221. return element;
  222. }
  223. }
  224. }
  225. element.className = (element.className?element.className:"") + " " + className;
  226. return element;
  227. }
  228. DefaultTheme.prototype.removeCSSClass = function(element, className) {
  229. if (element == null) return element;
  230. var classArray = new Array();
  231. if (element.className) {
  232. classArray = element.className.split(" ");
  233. }
  234. var newArray = new Array();
  235. for (var i in classArray) {
  236. if (classArray[i]!=className) {
  237. newArray[newArray.length] = classArray[i];
  238. }
  239. }
  240. element.className = newArray.join(" ");
  241. return element;
  242. }
  243. DefaultTheme.prototype.toggleCSSClass = function(element, className) {
  244. if (element == null) return element;
  245. var classArray = new Array();
  246. if (element.className) {
  247. classArray = element.className.split(" ");
  248. }
  249. for (var i=0;i<classArray.length;i++) {
  250. if (classArray[i]==className) {
  251. this.removeCSSClass(element, className);
  252. return;
  253. }
  254. }
  255. this.addCSSClass(element, className);
  256. return element;
  257. }
  258. DefaultTheme.prototype.setCSSClass = function(element, className) {
  259. if (element == null) return element;
  260. element.className = className;
  261. return element;
  262. }
  263. DefaultTheme.prototype.setCSSDefaultClass = function(renderer,element,uidl) {
  264. if (element == null) return element;
  265. var cn = this.styleToCSSClass(renderer.tag,uidl.getAttribute("style"));
  266. element.className = cn;
  267. return element;
  268. }
  269. DefaultTheme.prototype.styleToCSSClass = function(prefix,style) {
  270. var s = "";
  271. if (prefix != null) {
  272. s = prefix;
  273. }
  274. if (style != null) {
  275. if (s.length > 0) {
  276. s = s + "-";
  277. }
  278. s = s + style;
  279. }
  280. return s
  281. }
  282. /*
  283. #### Generic JS helpers ##################################################
  284. */
  285. /**
  286. * Check if integer list contains a number.
  287. *
  288. * @param list Comma separated list of integers
  289. * @param number Number to be tested
  290. *
  291. * @return true iff the number can be found in the list
  292. */
  293. DefaultTheme.prototype.listContainsInt = function(list,number) {
  294. if (!list) return false;
  295. a = list.split(",");
  296. for (i=0;i<a.length;i++) {
  297. if (a[i] == number) return true;
  298. }
  299. return false;
  300. }
  301. /** Add number to integer list, if it does not exit before.
  302. *
  303. *
  304. * @param list Comma separated list of integers
  305. * @param number Number to be added
  306. *
  307. * @return new list
  308. */
  309. DefaultTheme.prototype.listAddInt = function(list,number) {
  310. if (this.listContainsInt(list,number))
  311. return list;
  312. if (list == "") return number;
  313. else return list + "," + number;
  314. }
  315. /** Remove number from integer list.
  316. *
  317. * @param list Comma separated list of integers
  318. * @param number Number to be removed
  319. *
  320. * @return new list
  321. */
  322. DefaultTheme.prototype.listRemoveInt = function(list,number) {
  323. if (!list) return "";
  324. retval = "";
  325. a = list.split(',');
  326. for (i=0;i<a.length;i++) {
  327. if (a[i] != number) {
  328. if (i == 0) retval += a[i];
  329. else retval += "," + a[i];
  330. }
  331. }
  332. return retval;
  333. }
  334. /*
  335. #### Variable helpers #############################################
  336. */
  337. DefaultTheme.prototype.getVariableElement = function(uidl,type,name) {
  338. if (uidl == null) return;
  339. var nodes = this.getChildElements(uidl,type);
  340. if (nodes != null) {
  341. for (var i=0; i < nodes.length; i++) {
  342. if (nodes[i].getAttribute("name") == name) {
  343. return nodes[i];
  344. }
  345. }
  346. }
  347. return null;
  348. }
  349. DefaultTheme.prototype.createVariableElementTo = function(target,variableElement) {
  350. if (!variableElement) {
  351. return null;
  352. }
  353. /* TODO FF kludge try, does not work - how to prevent flashing hiddens?
  354. var d = this.createElementTo(target,"div");
  355. d.style.border = "none";
  356. d.style.background = "none";
  357. d.style.padding = "0px";
  358. d.style.margin = "0px;"
  359. d.style.width = "0px";
  360. d.style.height = "0px";
  361. d.style.overflow = "hidden";
  362. */
  363. var input = this.createInputElementTo(target,"hidden");
  364. input.variableId = variableElement.getAttribute("id");
  365. input.variableName = variableElement.getAttribute("name");
  366. if (variableElement.nodeName == "array") {
  367. input.variableId = "array:"+input.variableId;
  368. input.value = this.arrayToList(variableElement);
  369. } else if (variableElement.nodeName == "string") {
  370. var node = this.getFirstTextNode(variableElement);
  371. input.value = (node?node.data:"");
  372. } else {
  373. input.value = variableElement.getAttribute("value");
  374. }
  375. return input;
  376. }
  377. DefaultTheme.prototype.getVariableElementValue = function(variableElement) {
  378. if ( variableElement == null) {
  379. return null;
  380. }
  381. if (variableElement.nodeName == "array") {
  382. return this.arrayToList(variableElement);
  383. } else if (variableElement.nodeName == "string") {
  384. var node = this.getFirstTextNode(variableElement);
  385. return (node?node.data:"");
  386. } else {
  387. return variableElement.getAttribute("value");
  388. }
  389. return null;
  390. }
  391. DefaultTheme.prototype.setVariable = function(client, variableNode, newValue, immediate) {
  392. if (variableNode == null) return;
  393. variableNode.value = newValue;
  394. client.changeVariable(variableNode.variableId, newValue, immediate);
  395. }
  396. DefaultTheme.prototype.addArrayVariable = function(client, variableNode, newValue, immediate) {
  397. if (variableNode == null) return;
  398. variableNode.value = this.listAddInt(variableNode.value,newValue);
  399. client.changeVariable(variableNode.variableId, variableNode.value, immediate);
  400. }
  401. DefaultTheme.prototype.toggleArrayVariable = function(client, variableNode, value, immediate) {
  402. if (variableNode == null) return;
  403. if (this.listContainsInt(variableNode.value,value)) {
  404. variableNode.value = this.listRemoveInt(variableNode.value,value);
  405. } else {
  406. variableNode.value = this.listAddInt(variableNode.value,value);
  407. }
  408. client.changeVariable(variableNode.variableId, variableNode.value, immediate);
  409. }
  410. DefaultTheme.prototype.removeArrayVariable = function(client, variableNode, value, immediate) {
  411. if (variableNode == null) return;
  412. variableNode.value = this.listRemoveInt(variableNode.value,value);
  413. client.changeVariable(variableNode.variableId, variableNode.value, immediate);
  414. }
  415. DefaultTheme.prototype.arrayToList = function(arrayVariableElement) {
  416. var list = "";
  417. if (arrayVariableElement == null || arrayVariableElement.childNodes == null) return list;
  418. var items = arrayVariableElement.getElementsByTagName("ai");
  419. if (items == null) return list;
  420. for (var i=0; i <items.length;i++) {
  421. var v = this.getFirstTextNode(items[i]);
  422. if (v != null && v.data != null) {
  423. if (list.length >0) list += ",";
  424. list += v.data;
  425. }
  426. }
  427. return list;
  428. }
  429. /*
  430. #### Generic component functions #############################################
  431. */
  432. DefaultTheme.prototype.renderChildNodes = function(renderer, uidl, to) {
  433. for (var i=0; i<uidl.childNodes.length; i++) {
  434. var child = uidl.childNodes.item(i);
  435. if (child.nodeType == Node.ELEMENT_NODE) {
  436. renderer.client.renderUIDL(child,to);
  437. } else if (child.nodeType == Node.TEXT_NODE) {
  438. to.appendChild(to.ownerDocument.createTextNode(child.data));
  439. }
  440. }
  441. }
  442. DefaultTheme.prototype.applyWidthAndHeight = function(uidl,target) {
  443. if (target == null || uidl == null) return;
  444. // Width
  445. var widthEl = this.getVariableElement(uidl,"integer","width");
  446. if (widthEl) {
  447. var w = widthEl.getAttribute("value");
  448. if (w > 0) {
  449. target.style.width = ""+w+"px";
  450. }
  451. }
  452. // Height
  453. var heightEl = this.getVariableElement(uidl,"integer","height");
  454. if (heightEl) {
  455. var h = heightEl.getAttribute("value");
  456. if (h > 0) {
  457. target.style.height = ""+h+"px";
  458. }
  459. }
  460. }
  461. DefaultTheme.prototype.createPaintableElement = function (renderer, uidl, target,layoutInfo) {
  462. // And create DIV as container
  463. var div = null;
  464. var pid = uidl.getAttribute("id");
  465. var li = layoutInfo||target.layoutInfo;
  466. if (pid != null && target.getAttribute("id") == pid){
  467. div = target;
  468. } else {
  469. //TODO: Remove this if the statement below works.
  470. // div = renderer.theme.createElementTo(target,"div");
  471. div = renderer.client.createPaintableElement(uidl,target);
  472. }
  473. div.layoutInfo = li;
  474. // Remove possible previous content from target
  475. /* TODO remove when tested
  476. while (div.firstChild != null) {
  477. div.removeChild(div.firstChild);
  478. }
  479. */
  480. div.innerHTML = "";
  481. if (li&&li.captionNode) {
  482. // caption placed elsewhere (form); see renderDefaultComponentHeader()
  483. li.captionNode.innerHTML = "";
  484. }
  485. // Assign CSS class
  486. this.setCSSDefaultClass(renderer,div,uidl);
  487. if ("true"==uidl.getAttribute("disabled")) {
  488. this.addCSSClass(div,"disabled");
  489. }
  490. if (this.getFirstElement(uidl,"error")) {
  491. this.addCSSClass(div,"error");
  492. }
  493. return div;
  494. }
  495. DefaultTheme.prototype.renderDefaultComponentHeader = function(renderer, uidl, target, layoutInfo) {
  496. var theme = renderer.theme;
  497. var doc = renderer.doc;
  498. var client = renderer.client;
  499. var captionText = uidl.getAttribute("caption");
  500. var error = theme.getFirstElement(uidl,"error");
  501. var description = theme.getFirstElement(uidl,"description");
  502. var icon = uidl.getAttribute("icon");
  503. if (!captionText && !error && !description && !icon) {
  504. return null;
  505. }
  506. if (!layoutInfo) {
  507. layoutInfo = target.layoutInfo;
  508. }
  509. // If layout info contains caption node, use it as caption position
  510. if (layoutInfo != null && layoutInfo.captionNode) {
  511. target = layoutInfo.captionNode;
  512. target.innerHTML = "";
  513. }
  514. // Caption container
  515. var caption = this.createElementTo(target,"div");
  516. // Create debug-mode UIDL div
  517. if (renderer.client.debugEnabled) {
  518. var uidlDebug = this.createElementTo(caption,"div","uidl minimized");
  519. renderer.client.renderHTML(uidl,uidlDebug);
  520. var t = this;
  521. client.addEventListener(uidlDebug,"click", function (e) {
  522. if (uidlDebug.className.indexOf("minimized") >=0) {
  523. t.removeCSSClass(uidlDebug,"minimized");
  524. } else {
  525. t.addCSSClass(uidlDebug,"minimized");
  526. }
  527. }
  528. );
  529. }
  530. if (captionText||error||description||icon) {
  531. this.addCSSClass(caption,"caption");
  532. } else {
  533. return caption;
  534. }
  535. if (description || error) {
  536. this.addCSSClass(caption,"clickable");
  537. }
  538. var iconUrl = uidl.getAttribute("icon");
  539. var errorIcon;
  540. if (error) {
  541. var icon = this.createElementTo(caption,"img","icon");
  542. icon.src = theme.root+"img/icon/error-mini.gif";
  543. if (iconUrl) {
  544. /* overlay icon */
  545. this.setCSSClass(icon,"overlay");
  546. } else {
  547. this.setCSSClass(icon,"error");
  548. }
  549. errorIcon = icon;
  550. } else if (description) {
  551. var icon = this.createElementTo(caption,"img","icon");
  552. icon.src = theme.root+"img/icon/info-mini.gif";
  553. if (iconUrl) {
  554. /* overlay icon */
  555. this.setCSSClass(icon,"overlay");
  556. } else {
  557. this.setCSSClass(icon,"error");
  558. }
  559. }
  560. var popupTarget = (captionText)?caption:target;
  561. if (error||description) {
  562. if(description) popupTarget._descriptionHTML = client.getXMLtext(description);
  563. if(error) popupTarget._errorHTML = client.getXMLtext(error);
  564. this.addDescriptionAndErrorPopupListener(theme, client, popupTarget, errorIcon);
  565. }
  566. if (iconUrl) {
  567. if (iconUrl.indexOf("theme://") == 0) {
  568. iconUrl = (theme.iconRoot != null ? theme.iconRoot : theme.root)
  569. + iconUrl.substring(8);
  570. }
  571. var icon = this.createElementTo(caption,"img","icon");
  572. icon.src = iconUrl;
  573. }
  574. // Caption text
  575. this.createTextNodeTo(caption,captionText);
  576. return caption;
  577. }
  578. DefaultTheme.prototype.renderActionPopup = function(renderer, uidl, to, actions, actionVar, id, popupEvent) {
  579. // Shortcuts
  580. var theme = renderer.theme;
  581. var client = renderer.client;
  582. var evtName = popupEvent||"rightclick";
  583. var ak = uidl.getElementsByTagName("ak");
  584. var len = ak.length;
  585. if (len < 1) return;
  586. var popup = theme.createElementTo((to.nodeName=="TR"?to.firstChild:to),"div", "actions outset hide");
  587. theme.addHidePopupListener(theme,client,popup,"click");
  588. theme.addStopListener(theme,client,popup,"click");
  589. var inner = theme.createElementTo(popup,"div", "border");
  590. var item = theme.createElementTo(inner,"div", "item pad clickable");
  591. for (var k=0;k<len;k++) {
  592. var key = theme.getFirstTextNode(ak[k]).data;
  593. var item = theme.createElementTo(inner,"div", "item pad clickable");
  594. theme.createTextNodeTo(item,actions[key]);
  595. theme.addAddClassListener(theme,client,item,"mouseover","over");
  596. theme.addRemoveClassListener(theme,client,item,"mouseout","over");
  597. theme.addSetVarListener(theme,client,item,"click",actionVar,id+","+key,true);
  598. theme.addHidePopupListener(theme,client,item,"click");
  599. theme.addStopListener(theme,client,item,"click");
  600. }
  601. theme.addStopListener(theme,client,to,"contextmenu");
  602. //theme.addStopListener(theme,client,to,evtName);
  603. theme.addTogglePopupListener(theme,client,to,evtName,popup);
  604. }
  605. /** Show popup at specified position.
  606. * Hides previous popup.
  607. *
  608. * @param popup The element to popup
  609. * @param x horizontal popup position
  610. * @param y vertical popup position
  611. * @param delay delay before popping up
  612. * @param defWidth (optional) default width for the popup
  613. *
  614. */
  615. DefaultTheme.prototype.showPopup = function(client,popup, x, y, delay, defWidth) {
  616. if (this.popupTimeout) {
  617. clearTimeout(this.popupTimeout);
  618. delete this.popupTimeout;
  619. }
  620. if (!popup) {
  621. var popup = this.popup;
  622. this.popupShowing = true;
  623. var scrollTop = (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
  624. var scrollLeft = (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
  625. var docWidth = document.body.clientWidth;
  626. var docHeight = document.body.clientHeight;
  627. this.removeCSSClass(popup,"hide");
  628. var ua = navigator.userAgent.toLowerCase();
  629. if (ua.indexOf("msie")>=0) {
  630. var sels = popup.ownerDocument.getElementsByTagName("select");
  631. if (sels) {
  632. var len = sels.length;
  633. var hidden = new Array();
  634. for (var i=0;i<len;i++) {
  635. var sel = sels[i];
  636. if (sel.style&&sel.style.display!="none") {
  637. sel.style.visibility = "hidden";
  638. hidden[hidden.length] = sel;
  639. }
  640. }
  641. this.popupSelectsHidden = hidden;
  642. }
  643. }
  644. /* TODO fix popup width & position */
  645. return;
  646. }
  647. if (!delay) var delay = 0;
  648. if (this.popup && this.popup != popup) {
  649. this.hidePopup();
  650. }
  651. this.popup = popup;
  652. /* THIS CODE IS NOT NEEDED IF WE CAN POSITION THE POPUP BEFOREHAND
  653. popup.style.left = 0+"px";
  654. popup.style.top = 0+"px";
  655. this.removeCSSClass(popup,"hide");
  656. var p = client.getElementPosition(popup);
  657. this.addCSSClass(popup,"hide");
  658. // TODOO!!! width not working properly
  659. if (p.w > document.body.clientWidth/2) {
  660. popup.style.width = Math.round(document.body.clientWidth/2)+"px";
  661. p.w = Math.round(document.body.clientWidth/2);
  662. }
  663. var posX = x||p.x;
  664. var posY = y||p.y;
  665. if (posX+p.w>document.body.clientWidth) {
  666. posX = document.body.clientWidth-p.w;
  667. if (posX<0) posX=0;
  668. }
  669. if (posY+p.h>document.body.clientHeight) {
  670. posY = document.body.clientHeight-p.h;
  671. if (posY < 0) posY =0;
  672. }
  673. if (p.h > document.body.clientHeight -20) {
  674. popup.style.height = document.body.clientHeight -20 + "px";
  675. popup.style.overflow = "auto";
  676. posX -= 20;
  677. }
  678. popup.style.left = posX+"px";
  679. popup.style.top = posY+"px";
  680. */
  681. if (delay > 0) {
  682. with ({theme:this}) {
  683. theme.popupTimeout = setTimeout(function(){
  684. theme.showPopup(client);
  685. }, delay);
  686. }
  687. } else {
  688. this.showPopup(client);
  689. }
  690. }
  691. /** Hides previous popup.
  692. */
  693. DefaultTheme.prototype.hidePopup = function() {
  694. if (this.popupSelectsHidden) {
  695. var len = this.popupSelectsHidden.length;
  696. for (var i=0;i<len;i++) {
  697. var sel = this.popupSelectsHidden[i];
  698. sel.style.visibility = "visible";
  699. }
  700. this.popupSelectsHidden = null;
  701. }
  702. if (this.popup) {
  703. this.addCSSClass(this.popup,"hide");
  704. this.popupShowing = false;
  705. }
  706. if (this.popupTimeout) {
  707. clearTimeout(this.popupTimeout);
  708. delete this.popupTimeout;
  709. }
  710. }
  711. /** Shows the popup if it's not currently shown,
  712. * hides the popup otherwise.
  713. * Hides previous popup.
  714. *
  715. * @param popup The element to popup
  716. * @param x horizontal popup position
  717. * @param y vertical popup position
  718. * @param delay delay before popping up
  719. * @param defWidth (optional) default width for the popup
  720. *
  721. */
  722. DefaultTheme.prototype.togglePopup = function(popup, x, y, delay, defWidth) {
  723. if (this.popup == popup && this.popupShowing) {
  724. this.hidePopup();
  725. } else {
  726. this.showPopup(client,popup,x,y,delay,defWidth);
  727. }
  728. }
  729. /*
  730. #### Generic event handlers ######################################################
  731. */
  732. DefaultTheme.prototype.addAddClassListener = function(theme,client,element,event,className,target,current) {
  733. client.addEventListener(element,event, function(e) {
  734. if (current) {
  735. if (current.length) {
  736. var length = current.length;
  737. while (length--) {
  738. theme.removeCSSClass(current[length],className);
  739. delete current[length];
  740. }
  741. } else {
  742. for (e in current) {
  743. theme.removeCSSClass(current[e],className);
  744. delete current[e];
  745. }
  746. }
  747. }
  748. theme.addCSSClass((target?target:element),className);
  749. if (current) {
  750. current[current.length] = (target?target:element);
  751. }
  752. }
  753. );
  754. }
  755. DefaultTheme.prototype.addRemoveClassListener = function(theme,client,element,event,className,target) {
  756. client.addEventListener(element,event, function(e) {
  757. theme.removeCSSClass((target?target:element),className);
  758. }
  759. );
  760. }
  761. DefaultTheme.prototype.addToggleClassListener = function(theme,client,element,event,className,target) {
  762. client.addEventListener(element,event, function(e) {
  763. theme.toggleCSSClass((target?target:element),className);
  764. }
  765. );
  766. }
  767. DefaultTheme.prototype.addStopListener = function(theme,client,element,event) {
  768. client.addEventListener(element, event, function(e) {
  769. var evt = client.getEvent(e);
  770. evt.stop();
  771. return false;
  772. }
  773. );
  774. }
  775. DefaultTheme.prototype.addSetVarListener = function(theme,client,element,event,variable,key,immediate) {
  776. client.addEventListener(element,event, function(e) {
  777. var value = "";
  778. if (typeof(key)=="string") {
  779. value = key;
  780. } else if (key.type=="checkbox"||key.type=="radio") {
  781. value = key.checked;
  782. } else if (key.type=="select-multiple") {
  783. var s = new Array();
  784. for (var i = 0; i < key.options.length; i++) {
  785. if (key.options[i].selected) {
  786. s[s.length] = key.options[i].value;
  787. }
  788. }
  789. value = s.join(',');
  790. } else {
  791. value = key.value;
  792. }
  793. if (typeof(variable) == "string") {
  794. client.changeVariable(variable,value,immediate);
  795. } else {
  796. theme.setVariable(client,variable,value,immediate);
  797. }
  798. }
  799. );
  800. }
  801. DefaultTheme.prototype.addRemoveVarListener = function(theme,client,element,event,variable,key,immediate) {
  802. client.addEventListener(element,event, function(e) {
  803. theme.removeArrayVariable(client,variable,key,immediate);
  804. }
  805. );
  806. }
  807. DefaultTheme.prototype.addAddVarListener = function(theme,client,element,event,variable,key,immediate) {
  808. client.addEventListener(element,event, function(e) {
  809. theme.addArrayVariable(client,variable,key,immediate);
  810. }
  811. );
  812. }
  813. DefaultTheme.prototype.addToggleVarListener = function(theme,client,element,event,variable,key,immediate) {
  814. client.addEventListener(element,event, function(e) {
  815. theme.toggleArrayVariable(client,variable,key,immediate);
  816. }
  817. );
  818. }
  819. DefaultTheme.prototype.addExpandNodeListener = function(theme,client,img,event,subnodes,expandVariable,collapseVariable,key,immediate,target) {
  820. client.addEventListener((target?target:img), event, function(e) {
  821. if (img.expanded == "true") {
  822. theme.removeArrayVariable(client,expandVariable,key,false);
  823. theme.addArrayVariable(client,collapseVariable,key,immediate);
  824. img.src = theme.root + "img/tree/off.gif";
  825. img.expanded = "false";
  826. } else {
  827. theme.removeArrayVariable(client,collapseVariable,key,false);
  828. theme.addArrayVariable(client,expandVariable,key,immediate ||
  829. !img.expanded || !subnodes.childNodes || subnodes.childNodes.length <= 0);
  830. img.src = theme.root + "img/tree/on.gif";
  831. img.expanded = "true";
  832. }
  833. }
  834. );
  835. }
  836. DefaultTheme.prototype.addTogglePopupListener = function(theme,client,element,event,popup,delay,defWidth,popupAt) {
  837. client.addEventListener(element,(event=="rightclick"?"mouseup":event), function(e) {
  838. var evt = client.getEvent(e);
  839. if (event=="rightclick"&&!evt.rightclick) return;
  840. if(evt.target.nodeName == "INPUT" || evt.target.nodeName == "SELECT") return;
  841. if (evt.alt) return;
  842. if (popupAt) {
  843. var p = client.getElementPosition(popupAt);
  844. theme.togglePopup(popup,p.x,(p.y+p.h),(delay?delay:0),(defWidth?defWidth:100));
  845. } else {
  846. theme.togglePopup(popup,evt.mouseX,evt.mouseY,(delay?delay:0),(defWidth?defWidth:100));
  847. }
  848. evt.stop();
  849. }
  850. );
  851. }
  852. DefaultTheme.prototype.addShowPopupListener = function(theme,client,element,event,popup,delay,defWidth) {
  853. client.addEventListener(element,(event=="rightclick"?"click":event), function(e) {
  854. var evt = client.getEvent(e);
  855. if (event=="rightclick"&&!evt.rightclick) return;
  856. theme.showPopup(client,popup,evt.mouseX,evt.mouseY,(delay?delay:0),(defWidth?defWidth:100));
  857. evt.stop();
  858. }
  859. );
  860. }
  861. // TODO dontstop -> stop in all listeners
  862. DefaultTheme.prototype.addHidePopupListener = function(theme,client,element,event,dontstop) {
  863. client.addEventListener(element,(event=="rightclick"?"click":event), function(e) {
  864. var evt = client.getEvent(e);
  865. if (evt.alt) return;
  866. if (event=="rightclick"&&!evt.rightclick) return;
  867. theme.hidePopup();
  868. if (!dontstop) {
  869. evt.stop();
  870. }
  871. }
  872. );
  873. }
  874. /**
  875. * Adds a hidden button with a tabindex; adds .over to hoverTarget when focused
  876. */
  877. DefaultTheme.prototype.addTabtoHandlers = function(client,theme,target,hoverTarget,tabindex,defaultButton) {
  878. var d = this.createElementTo(target,"div");
  879. d.style.border = "none";
  880. d.style.background = "none";
  881. d.style.padding = "0px";
  882. d.style.margin = "0px";
  883. d.style.width = "0px";
  884. d.style.height = "0px";
  885. d.style.overflow = "hidden";
  886. var b = this.createInputElementTo(d,(defaultButton?"submit":"button"));
  887. if (tabindex) b.tabIndex = tabindex;
  888. client.addEventListener(b,"focus", function() {
  889. theme.addCSSClass(hoverTarget,"over");
  890. });
  891. client.addEventListener(b,"blur", function() {
  892. theme.removeCSSClass(hoverTarget,"over");
  893. });
  894. }
  895. /*
  896. #### Component renderers ######################################################
  897. */
  898. DefaultTheme.prototype.renderComponent = function(renderer,uidl,target,layoutInfo) {
  899. // Create containing element
  900. var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  901. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  902. // Render default header
  903. renderer.theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
  904. // Render children to div
  905. renderer.theme.renderChildNodes(renderer, uidl, div);
  906. }
  907. DefaultTheme.prototype.renderWindow = function(renderer,uidl,target,layoutInfo) {
  908. var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  909. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  910. var theme = renderer.theme;
  911. theme.addHidePopupListener(theme,renderer.client,div,"click",true);
  912. // Render children to div
  913. theme.renderChildNodes(renderer, uidl, div);
  914. // Apply width and height
  915. theme.applyWidthAndHeight(uidl,div);
  916. // Focusing
  917. var focused = theme.getVariableElement(uidl,"string","focused");
  918. var focusid = theme.getVariableElementValue(focused);
  919. if (focusid) {
  920. var found = false;
  921. var els = div.getElementsByTagName("input");
  922. var len = (els?els.length:0);
  923. for (var i=0;i<len;i++) {
  924. var el = els[i];
  925. if (focusid == el["focusid"]) {
  926. el.focus();
  927. found = true;
  928. break;
  929. }
  930. }
  931. if (!found) {
  932. els = div.getElementsByTagName("select");
  933. var len = (els?els.length:0);
  934. for (var i=0;i<len;i++) {
  935. var el = els[i];
  936. if (focusid == el["focusid"]) {
  937. el.focus();
  938. found = true;
  939. break;
  940. }
  941. }
  942. }
  943. if (!found) {
  944. els = div.getElementsByTagName("textarea");
  945. var len = (els?els.length:0);
  946. for (var i=0;i<len;i++) {
  947. var el = els[i];
  948. if (focusid == el["focusid"]) {
  949. el.focus();
  950. found = true;
  951. break;
  952. }
  953. }
  954. }
  955. }
  956. }
  957. DefaultTheme.prototype.renderOpen = function(renderer,uidl,target,layoutInfo) {
  958. var theme = renderer.theme;
  959. var src = uidl.getAttribute("src");
  960. var name = uidl.getAttribute("name");
  961. if (name) {
  962. window.open(src,name);
  963. } else {
  964. var div = theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  965. div.innerHTML = "<IFRAME name=\""+name+"\" id=\""+name+"\" width=100% height=100% style=\"border:none;margin:0px;padding:0px;background:none;\" src=\""+src+"\"></IFRAME>";
  966. }
  967. }
  968. DefaultTheme.prototype.renderFramewindow = function(renderer,uidl,target,layoutInfo) {
  969. var theme = renderer.theme;
  970. var client = renderer.client;
  971. // TODO: Should we unregister all previous child windows?
  972. // We just reinitialize the window
  973. var win = target.ownerDocument.ownerWindow;
  974. client.initializeNewWindow(win,uidl,theme);
  975. }
  976. DefaultTheme.prototype.renderCustomLayout = function(renderer,uidl,target,layoutInfo) {
  977. // Shortcuts
  978. var theme = renderer.theme;
  979. // Get style
  980. var style = uidl.getAttribute("style");
  981. if (style == null) return null;
  982. // Load the layout
  983. var url = theme.root + style;
  984. var text = renderer.client.loadDocument(url,false);
  985. if (text == null) {
  986. client.debug("CustomLayout " + style + " NOT FOUND @ "+ url);
  987. return null;
  988. }
  989. // Create containing element
  990. var main = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  991. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  992. var locations = new Object();
  993. var unused = new Object();
  994. var cN = uidl.childNodes;
  995. var len = cN.length;
  996. for (var j=0; j < len; j++) {
  997. var c = cN.item(j);
  998. if (c.nodeType == Node.ELEMENT_NODE
  999. && c.nodeName == "location"
  1000. && c.getAttribute("name")) {
  1001. locations[c.getAttribute("name")] = c;
  1002. unused[c.getAttribute("name")] = c;
  1003. }
  1004. }
  1005. var n = theme.createElementTo(main, "div");
  1006. n.setAttribute("id",uidl.getAttribute("id"));
  1007. n.innerHTML=text;
  1008. var divs = n.getElementsByTagName("div");
  1009. for (var i=0; i<divs.length; i++) {
  1010. var div = divs.item(i);
  1011. var name = div.getAttribute("location");
  1012. if (name != null) {
  1013. var c = locations[name];
  1014. if (c && c.getAttribute("name") == name) {
  1015. delete unused[name];
  1016. for (var k=0; k<c.childNodes.length; k++) {
  1017. var cc = c.childNodes.item(k);
  1018. if (cc.nodeType == Node.ELEMENT_NODE) {
  1019. var parent = div.parentNode;
  1020. // TODO
  1021. if (parent != null) {
  1022. theme.removeAllChildNodes(div);
  1023. var newNode = renderer.client.renderUIDL(cc,div);
  1024. }
  1025. }
  1026. }
  1027. } else {
  1028. client.warn("Location " + name + " NOT USED in CustomLayout " + style);
  1029. }
  1030. }
  1031. }
  1032. if (unused.length>0) {
  1033. for (var k in usedLocations) {
  1034. client.error("Location " + k + " NOT FOUND in CustomLayout " + style);
  1035. }
  1036. }
  1037. }
  1038. DefaultTheme.prototype.renderOrderedLayout = function(renderer,uidl,target,layoutInfo) {
  1039. // Shortcuts
  1040. var theme = renderer.theme;
  1041. // Create containing element
  1042. var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  1043. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  1044. // Render all children to table
  1045. var vertical = uidl.getAttribute("orientation") != "horizontal";
  1046. var table = null;
  1047. var tr = null;
  1048. var td = null;
  1049. var style = uidl.getAttribute("style");
  1050. var form = style == "form";
  1051. for (var i=0; i<uidl.childNodes.length; i++) {
  1052. var childUIDL = uidl.childNodes.item(i);
  1053. td = null;
  1054. if (childUIDL.nodeType == Node.ELEMENT_NODE) {
  1055. // Ensure TABLE and TR
  1056. if (tr == null || vertical) {
  1057. if (table == null) {
  1058. table = renderer.theme.createElementTo(div,"table","orderedlayout");
  1059. //table.width="100%";
  1060. renderer.theme.addCSSClass(table,"layout");
  1061. table = renderer.theme.createElementTo(table,"tbody","layout");
  1062. }
  1063. tr = renderer.theme.createElementTo(table,"tr","layout");
  1064. }
  1065. // Create extra TD for form style captions
  1066. var layoutInfo = null;
  1067. if (form) {
  1068. layoutInfo = new Object()
  1069. td = renderer.theme.createElementTo(tr,"td","layout");
  1070. layoutInfo.captionNode = td;
  1071. }
  1072. // Force new TD for each child rendered
  1073. td = renderer.theme.createElementTo(tr,"td","layout");
  1074. // Render the component to TD
  1075. renderer.client.renderUIDL(childUIDL,td, null, layoutInfo);
  1076. }
  1077. }
  1078. }
  1079. DefaultTheme.prototype.renderGridLayout = function(renderer,uidl,target,layoutInfo) {
  1080. // NOTE TODO indenting might be off
  1081. // Shortcuts
  1082. var theme = renderer.theme;
  1083. var h = uidl.getAttribute("h");
  1084. var w = uidl.getAttribute("w");
  1085. // Create component element
  1086. var div = theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  1087. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  1088. //var width = (div.offsetWidth||div.clientWidth)-20;
  1089. //var px = Math.floor(width/parseInt(w));
  1090. var table = theme.createElementTo(div,"table", "layout");
  1091. table = renderer.theme.createElementTo(table,"tbody","layout");
  1092. var tr = null;
  1093. var td = null;
  1094. for (var y=0; y<uidl.childNodes.length; y++) {
  1095. var rowUidl = uidl.childNodes[y];
  1096. if (rowUidl.nodeType == Node.ELEMENT_NODE || rowUidl.nodeName == "gr") {
  1097. tr = theme.createElementTo(table,"tr","layout");
  1098. tr.style.verticalAlign = "top";
  1099. td = null;
  1100. for (var x=0; x<rowUidl.childNodes.length; x++) {
  1101. var cellUidl = rowUidl.childNodes[x];
  1102. // Add colspan and rowspan
  1103. if (cellUidl.nodeType == Node.ELEMENT_NODE && cellUidl.nodeName == "gc") {
  1104. // Create new TD for each child rendered
  1105. td = renderer.theme.createElementTo(tr,"td","layout");
  1106. var w = cellUidl.getAttribute('w');
  1107. var h = cellUidl.getAttribute('h');
  1108. //var cont = renderer.theme.createElementTo(td,"div");
  1109. //cont.style.width = ((w?w:1)*px)+"px";
  1110. if (w != null) {
  1111. td.setAttribute('colSpan',w);
  1112. }
  1113. if (h != null) {
  1114. td.setAttribute('rowSpan',h);
  1115. }
  1116. // Render the component(s) to TD
  1117. if (cellUidl.childNodes != null && cellUidl.childNodes.length >0) {
  1118. var len = cellUidl.childNodes.length;
  1119. for (var c=0;c<len;c++) {
  1120. var el = cellUidl.childNodes[c];
  1121. if (el.nodeType == Node.ELEMENT_NODE) {
  1122. renderer.client.renderUIDL(el,td);
  1123. }
  1124. }
  1125. //cont.style.width = "";
  1126. }
  1127. }
  1128. }
  1129. }
  1130. }
  1131. }
  1132. DefaultTheme.prototype.renderPanel = function(renderer,uidl,target,layoutInfo) {
  1133. // Supports styles "light" and "none"
  1134. // Shortcuts
  1135. var theme = renderer.theme;
  1136. var style = uidl.getAttribute("style");
  1137. var borderStyle = "panelborder";
  1138. // Create component element
  1139. var outer = theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  1140. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  1141. if ("none"!=style) {
  1142. theme.addCSSClass(div,"outset");
  1143. }
  1144. if ("light"==style) {
  1145. theme.addCSSClass(div,"light");
  1146. //borderStyle += "light";
  1147. }
  1148. // Create extra DIV for visual layout
  1149. var div = theme.createElementTo(outer,"div");
  1150. if ("none"!=style) {
  1151. theme.setCSSClass(div,borderStyle);
  1152. }
  1153. // Create default header
  1154. var caption = theme.renderDefaultComponentHeader(renderer,uidl,div);
  1155. theme.addCSSClass(caption,"panelcaption");
  1156. if ("light"==style) {
  1157. theme.addCSSClass(caption,"panelcaptionlight");
  1158. }
  1159. // Create content DIV
  1160. var content = theme.createElementTo(div,"div");
  1161. theme.setCSSClass(content,"content");
  1162. // Render children to div
  1163. theme.renderChildNodes(renderer, uidl, content);
  1164. // Apply width and height
  1165. theme.applyWidthAndHeight(uidl,outer);
  1166. }
  1167. DefaultTheme.prototype.renderTabSheet = function(renderer,uidl,target,layoutInfo) {
  1168. var theme = renderer.theme;
  1169. // Create container element
  1170. var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  1171. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  1172. // Create default header
  1173. var caption = renderer.theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
  1174. // Render tabs
  1175. var tabs = theme.createElementTo(div,"div","tabs");
  1176. var varId = theme.getVariableElement(uidl,"string","selected").getAttribute("id");
  1177. var tabNodes = theme.getChildElements(uidl,"tabs");
  1178. if (tabNodes != null && tabNodes.length >0) tabNodes = theme.getChildElements(tabNodes[0],"tab");
  1179. var selectedTabNode = null;
  1180. if (tabNodes != null && tabNodes.length >0) {
  1181. for (var i=0; i< tabNodes.length;i++) {
  1182. var tabNode = tabNodes[i];
  1183. var tab = theme.createElementTo(tabs,"div");
  1184. var key = tabNode.getAttribute("key");
  1185. var iconUrl = tabNode.getAttribute("icon");
  1186. if (iconUrl && iconUrl.indexOf("theme://") == 0) {
  1187. iconUrl = (theme.iconRoot != null ? theme.iconRoot : theme.root)
  1188. + iconUrl.substring(8);
  1189. }
  1190. if (tabNode.getAttribute("selected") == "true") {
  1191. theme.addCSSClass(tab,"tab-on inline");
  1192. selectedTabNode = tabNode;
  1193. } else if (tabNode.getAttribute("disabled") == "true"
  1194. || uidl.getAttribute("disabled") == "true"
  1195. || uidl.getAttribute("readonly") == "true") {
  1196. theme.setCSSClass(tab,"tab disabled inline");
  1197. } else {
  1198. theme.setCSSClass(tab,"tab clickable inline");
  1199. theme.addAddClassListener(theme,client,tab,"mouseover","over",tab);
  1200. theme.addRemoveClassListener(theme,client,tab,"mouseout","over",tab);
  1201. theme.addSetVarListener(theme,client,tab,"click",varId,key,true);
  1202. }
  1203. // Extra div in tab
  1204. tab = theme.createElementTo(tab,"div","caption border pad inline");
  1205. // Icon
  1206. if (iconUrl) {
  1207. tab.innerHTML = "<IMG src=\""+iconUrl+"\" class=\"icon\" />" + tabNode.getAttribute("caption");
  1208. } else {
  1209. tab.innerHTML = tabNode.getAttribute("caption");
  1210. }
  1211. }
  1212. }
  1213. // Render content (IE renderbug need three)
  1214. var content = theme.createElementTo(div,"div","outset");
  1215. content = theme.createElementTo(content,"div","border");
  1216. content = theme.createElementTo(content,"div","content");
  1217. if (selectedTabNode != null) {
  1218. theme.renderChildNodes(renderer,selectedTabNode, content);
  1219. }
  1220. }
  1221. DefaultTheme.prototype.renderTree = function(renderer,uidl,target,layoutInfo) {
  1222. var theme = renderer.theme;
  1223. // Create container element
  1224. var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  1225. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  1226. // Get tree attributes
  1227. var style = uidl.getAttribute("style");
  1228. var immediate = ("true" == uidl.getAttribute("immediate"));
  1229. var disabled = ("true" == uidl.getAttribute("disabled"));
  1230. var readonly = ("true" == uidl.getAttribute("readonly"));
  1231. var selectMode = uidl.getAttribute("selectmode");
  1232. var selectable = selectMode == "multi" || selectMode == "single";
  1233. var selected;
  1234. if (selectable) {
  1235. selected = new Object();
  1236. }
  1237. var selectionVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","selected"));
  1238. var expandVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","expand"));
  1239. var collapseVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","collapse"));
  1240. var actions = null;
  1241. var actionVar = null;
  1242. var alNode = theme.getFirstElement(uidl,"actions")
  1243. if (alNode) {
  1244. actionVar = theme.createVariableElementTo(div,theme.getVariableElement(alNode,"string","action"));
  1245. actions = new Object();
  1246. var ak = alNode.getElementsByTagName("action");
  1247. for (var i=0;i<ak.length;i++) {
  1248. actions[ak[i].getAttribute("key")] = ak[i].getAttribute("caption");
  1249. }
  1250. }
  1251. delete alNode;
  1252. // Create default header
  1253. var caption = renderer.theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
  1254. // Content DIV
  1255. var content = theme.createElementTo(div,"div","content");
  1256. // Iterate all nodes
  1257. for (var i = 0; i< uidl.childNodes.length;i++) {
  1258. var node = uidl.childNodes[i];
  1259. if (node.nodeName == "node" || node.nodeName == "leaf") {
  1260. theme.renderTreeNode(renderer,node,content,selectable,selectMode,selected,selectionVariable,expandVariable,collapseVariable,actions,actionVar,immediate,disabled,readonly);
  1261. }
  1262. }
  1263. }
  1264. DefaultTheme.prototype.renderTreeNode = function(renderer,node,target,selectable,selectMode,selected,selectionVariable,expandVariable,collapseVariable,actions,actionVar,immediate,disabled,readonly) {
  1265. var theme = renderer.theme;
  1266. var client = renderer.client;
  1267. var n = theme.createElementTo(target,"div","node clickable");
  1268. // Expand/collapse/spacer button
  1269. var img = theme.createElementTo(n,"img","icon");
  1270. var key = node.getAttribute("key");
  1271. var icon = node.getAttribute("icon");
  1272. if (icon) {
  1273. var iconurl = theme.root+icon.split("theme:")[1];
  1274. var iimg = theme.createElementTo(n,"img","icon");
  1275. iimg.src = iconurl;
  1276. }
  1277. // Caption
  1278. var cap = theme.createElementTo(n,"div","nodecaption inline");
  1279. theme.createTextNodeTo(n,node.getAttribute("caption"));
  1280. // Hover effects
  1281. if (!disabled&&!readonly) {
  1282. theme.addAddClassListener(theme,client,n,"mouseover","over",n);
  1283. theme.addRemoveClassListener(theme,client,n,"mouseout","over",n);
  1284. }
  1285. // Server-side selection
  1286. if (selectable && node.getAttribute("selected") == "true") {
  1287. theme.addCSSClass(n,"selected");
  1288. selected[key] = n;
  1289. }
  1290. // Indicate selection
  1291. if (theme.listContainsInt(selectionVariable.value,key)) {
  1292. theme.addCSSClass(n, "selected");
  1293. }
  1294. // Selection listeners
  1295. if (selectable && !disabled) {
  1296. if (!readonly) {
  1297. if (selectMode == "single") {
  1298. theme.addAddClassListener(theme,client,n,"click","selected",n,selected);
  1299. theme.addSetVarListener(theme,client,n,"click",selectionVariable,key,immediate);
  1300. } else if (selectMode == "multi") {
  1301. theme.addToggleClassListener(theme,client,n,"click","selected");
  1302. theme.addToggleVarListener(theme,client,n,"click",selectionVariable,key,immediate);
  1303. }
  1304. }
  1305. }
  1306. // Actions
  1307. if (!disabled && !readonly) {
  1308. for (var i = 0; i< node.childNodes.length;i++) {
  1309. var childNode = node.childNodes[i];
  1310. if (childNode.nodeName == "al" ) {
  1311. theme.renderActionPopup(renderer,childNode,n,actions,actionVar,key); // TODO check
  1312. }
  1313. }
  1314. }
  1315. // Render all sub-nodes
  1316. if (node.nodeName == "node") {
  1317. var subnodes = theme.createElementTo(target,"div","nodes");
  1318. if (node.childNodes != null && node.childNodes.length >0) {
  1319. img.src = theme.root + "img/tree/on.gif";
  1320. img.expanded = "true";
  1321. } else {
  1322. img.src = theme.root + "img/tree/off.gif";
  1323. img.expanded = "false";
  1324. }
  1325. for (var i = 0; i< node.childNodes.length;i++) {
  1326. var childNode = node.childNodes[i];
  1327. if (childNode.nodeName == "node" || childNode.nodeName == "leaf") {
  1328. theme.renderTreeNode(renderer,childNode,subnodes,selectable,selectMode,selected,selectionVariable,expandVariable,collapseVariable,actions,actionVar,immediate,disabled,readonly);
  1329. }
  1330. }
  1331. // Add event listener
  1332. if (!disabled) {
  1333. var target = (selectable&&!readonly?img:n);
  1334. theme.addToggleClassListener(theme,client,target,"mouseup","hidden",subnodes);
  1335. theme.addExpandNodeListener(theme,client,img,"mouseup",subnodes,expandVariable,collapseVariable,key,immediate,target);
  1336. theme.addStopListener(theme,client,target,"mouseup");
  1337. theme.addStopListener(theme,client,target,"click");
  1338. }
  1339. } else {
  1340. img.src = theme.root + "img/tree/empty.gif";
  1341. }
  1342. }
  1343. DefaultTheme.prototype.renderTextField = function(renderer,uidl,target, layoutInfo) {
  1344. var client = renderer.client;
  1345. var theme = renderer.theme;
  1346. var immediate = uidl.getAttribute("immediate") == "true";
  1347. var readonly = uidl.getAttribute("readonly") == "true";
  1348. var multiline = uidl.getAttribute("multiline") == "true";
  1349. var secret = uidl.getAttribute("secret") == "true";
  1350. var cols = uidl.getAttribute("cols");
  1351. var rows = uidl.getAttribute("rows");
  1352. var disabled = uidl.getAttribute("disabled") == "true";
  1353. var focusid = uidl.getAttribute("focusid");
  1354. var tabindex = uidl.getAttribute("tabindex");
  1355. // Create containing element
  1356. var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  1357. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  1358. // Render default header
  1359. renderer.theme.renderDefaultComponentHeader(renderer,uidl,div, layoutInfo);
  1360. // Create border
  1361. var border = renderer.theme.createElementTo(div,"div","border");
  1362. // Create input
  1363. var input = null;
  1364. if (multiline) {
  1365. input = renderer.theme.createElementTo(border,"textarea");
  1366. input.wrap = "off";
  1367. if (focusid) {
  1368. input.focusid = focusid;
  1369. }
  1370. } else {
  1371. input = renderer.theme.createInputElementTo(border,(secret?"password":"text"),null,focusid);
  1372. }
  1373. if (tabindex) input.tabIndex = tabindex;
  1374. if (disabled||readonly) {
  1375. input.disabled = "true";
  1376. }
  1377. // Assign cols and rows
  1378. if (cols >0) {
  1379. if (multiline) {
  1380. input.cols = cols;
  1381. } else {
  1382. input.size = cols;
  1383. input.maxlength = cols;
  1384. }
  1385. }
  1386. if (rows >0) {
  1387. input.rows = rows;
  1388. }
  1389. // Find variable node
  1390. var strNode = theme.getVariableElement(uidl,"string","text");
  1391. var inputId = strNode.getAttribute("id");
  1392. input.id = inputId;
  1393. // Assign value
  1394. strNode= theme.getFirstTextNode(strNode);
  1395. if (strNode != null && strNode.data != null) {
  1396. input.value = strNode.data;
  1397. }
  1398. // Listener
  1399. theme.addSetVarListener(theme,client,input,"change",inputId,input,immediate);
  1400. }
  1401. DefaultTheme.prototype.renderDateField = function(renderer,uidl,target,layoutInfo) {
  1402. // TODO needs simplification
  1403. // - jscalendar supports time! but not resolution?
  1404. // - dynamic .js loading!
  1405. var theme = renderer.theme;
  1406. // Create containing element
  1407. var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  1408. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  1409. /* Styles:
  1410. * time - only time selection (no date)
  1411. */
  1412. var style = uidl.getAttribute("style");
  1413. var immediate = uidl.getAttribute("immediate") == "true";
  1414. var disabled = uidl.getAttribute("disabled") == "true";
  1415. var readonly = uidl.getAttribute("readonly") == "true";
  1416. /* locale, translate UI */
  1417. var locale = uidl.getAttribute("locale")
  1418. if (locale && !disabled && !readonly) {
  1419. locale = locale.toLowerCase().split("_")[0];
  1420. var lang = renderer.client.loadDocument(theme.root+"jscalendar/lang/calendar-"+locale+".js",false);
  1421. if (lang) {
  1422. try {
  1423. window.eval(lang);
  1424. } catch (e) {
  1425. client.error("Could not eval DateField lang ("+locale+"):"+e );
  1426. }
  1427. }
  1428. }
  1429. // Render default header
  1430. renderer.theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
  1431. var yearVar = theme.getVariableElement(uidl,"integer","year");
  1432. var monthVar = theme.getVariableElement(uidl,"integer","month");
  1433. var dayVar = theme.getVariableElement(uidl,"integer","day");
  1434. var hourVar = theme.getVariableElement(uidl,"integer","hour");
  1435. var minVar = theme.getVariableElement(uidl,"integer","min");
  1436. var secVar = theme.getVariableElement(uidl,"integer","sec");
  1437. var msecVar = theme.getVariableElement(uidl,"integer","msec");
  1438. var year = null;
  1439. var month = null;
  1440. var day = null;
  1441. var hour = null;
  1442. var min = null;
  1443. var sec = null;
  1444. var msec = null;
  1445. var text = null;
  1446. var inputId = yearVar.getAttribute("id") + "_input";
  1447. var buttonId = yearVar.getAttribute("id") + "_button";
  1448. // Assign the value to textfield
  1449. var yearValue = yearVar != null? yearVar.getAttribute("value"): null;
  1450. var monthValue = monthVar != null? monthVar.getAttribute("value"): null;
  1451. var dayValue = dayVar != null? dayVar.getAttribute("value"): null;
  1452. var hourValue = hourVar != null? hourVar.getAttribute("value"): null;
  1453. var minValue = minVar != null? minVar.getAttribute("value"): null;
  1454. var secValue = secVar != null? secVar.getAttribute("value"): null;
  1455. var msecValue = msecVar != null? msecVar.getAttribute("value"): null;
  1456. if (style != "time") {
  1457. if (dayValue) {
  1458. // Using calendar - create textfield
  1459. if (readonly) {
  1460. text = theme.createTextNodeTo(div,dayValue+"."+monthValue+"."+yearValue);
  1461. } else {
  1462. text = theme.createInputElementTo(div,"text");
  1463. text.id = inputId;
  1464. text.size = "10";
  1465. if (disabled) {
  1466. text.disabled = true;
  1467. }
  1468. if (yearValue >0 && monthValue >0 && dayValue >0) {
  1469. text.value = dayValue+"."+monthValue+"."+yearValue;
  1470. } else {
  1471. text.value ="";
  1472. }
  1473. }
  1474. // Create button
  1475. var button = theme.createInputElementTo(div,"button","btn clickable");
  1476. button.id =buttonId;
  1477. button.value = "...";
  1478. if (disabled||readonly) {
  1479. button.disabled = true;
  1480. }
  1481. } else {
  1482. if (yearVar) {
  1483. // Year select
  1484. if (readonly) {
  1485. theme.createTextNodeTo(div,yearValue);
  1486. } else {
  1487. var year = theme.createElementTo(div,"select");
  1488. year.options[0] = new Option("",-1);
  1489. for (var i=0;i<2000;i++) {
  1490. year.options[i+1] = new Option(i+1900,i+1900);
  1491. if (yearValue == (i+1900)) {
  1492. year.options[i+1].selected = true;
  1493. }
  1494. }
  1495. if (disabled) {
  1496. year.disabled = true;
  1497. }
  1498. if (!readonly) theme.addSetVarListener(theme,client,year,"change",yearVar.getAttribute("id"),year,immediate);
  1499. }
  1500. }
  1501. if (monthVar) {
  1502. // Month select
  1503. if (readonly) {
  1504. theme.createTextNodeTo(div,"."+monthValue);
  1505. } else {
  1506. month = theme.createElementTo(div,"select");
  1507. month.options[0] = new Option("",-1);
  1508. for (var i=0;i<12;i++) {
  1509. month.options[i+1] = new Option(i+2,i+2);
  1510. if (monthValue == i+2) {
  1511. month.options[i+1].selected = true;
  1512. }
  1513. }
  1514. if (disabled) {
  1515. month.disabled = true;
  1516. }
  1517. if (!readonly) theme.addSetVarListener(theme,client,month,"change",monthVar.getAttribute("id"),month,immediate);
  1518. }
  1519. }
  1520. }
  1521. }
  1522. if (hourVar) {
  1523. if (readonly) {
  1524. theme.createTextNodeTo(div," "+(hourValue<10?"0"+hourValue:hourValue));
  1525. } else {
  1526. hour = theme.createElementTo(div,"select");
  1527. hour.options[0] = new Option("",-1);
  1528. for (var i=0;i<24;i++) {
  1529. var cap = (i+1<10?"0"+(i+1):(i+1));
  1530. if (!minVar) {
  1531. // Append anyway, makes it easier to recognize as time
  1532. cap = cap + ":00";
  1533. }
  1534. hour.options[i+1] = new Option(cap,i+1);
  1535. if (hourValue == i+1) {
  1536. hour.options[i+1].selected = true;
  1537. }
  1538. }
  1539. if (disabled) {
  1540. hour.disabled = true;
  1541. }
  1542. if (!readonly) theme.addSetVarListener(theme,client,hour,"change",hourVar.getAttribute("id"),hour,immediate);
  1543. }
  1544. }
  1545. if (minVar) {
  1546. // Minute select
  1547. if (readonly) {
  1548. theme.createTextNodeTo(div,":"+(minValue<10?"0"+minValue:minValue));
  1549. } else {
  1550. theme.createTextNodeTo(div,":");
  1551. min = theme.createElementTo(div,"select");
  1552. min.options[0] = new Option("",-1);
  1553. for (var i=0;i<60;i++) {
  1554. min.options[i+1] = new Option((i<10?"0"+(i):(i)),i);
  1555. if (minValue == i) {
  1556. min.options[i+1].selected = true;
  1557. }
  1558. }
  1559. if (disabled) {
  1560. min.disabled = true;
  1561. }
  1562. if (!readonly) theme.addSetVarListener(theme,client,min,"change",minVar.getAttribute("id"),min,immediate);
  1563. }
  1564. }
  1565. if (secVar) {
  1566. // Second select
  1567. if (readonly) {
  1568. theme.createTextNodeTo(div,":"+(secValue<10?"0"+secValue:secValue));
  1569. } else {
  1570. theme.createTextNodeTo(div,":");
  1571. sec = theme.createElementTo(div,"select");
  1572. sec.options[0] = new Option("",-1);
  1573. for (var i=0;i<60;i++) {
  1574. sec.options[i+1] = new Option((i<10?"0"+(i):(i)),i);
  1575. if (secValue == i) {
  1576. sec.options[i+1].selected = true;
  1577. }
  1578. }
  1579. if (disabled) {
  1580. sec.disabled = true;
  1581. }
  1582. if (!readonly) theme.addSetVarListener(theme,client,sec,"change",secVar.getAttribute("id"),sec,immediate);
  1583. }
  1584. }
  1585. if (msecVar) {
  1586. // Millisecond select
  1587. if (readonly) {
  1588. var cap = msecValue;
  1589. if (i+1 < 100) {
  1590. cap = "0"+cap;
  1591. }
  1592. if (i+1 < 10) {
  1593. cap = "0"+cap;
  1594. }
  1595. theme.createTextNodeTo(div,"."+cap);
  1596. } else {
  1597. theme.createTextNodeTo(div,".");
  1598. msec = theme.createElementTo(div,"select");
  1599. msec.options[0] = new Option("",-1);
  1600. for (var i=0;i<1000;i++) {
  1601. var cap = i;
  1602. if (i < 100) {
  1603. cap = "0"+cap;
  1604. }
  1605. if (i < 10) {
  1606. cap = "0"+cap;
  1607. }
  1608. msec.options[i+1] = new Option(cap,i);
  1609. if (msecValue == i) {
  1610. msec.options[i+1].selected = true;
  1611. }
  1612. }
  1613. if (disabled) {
  1614. msec.disabled = true;
  1615. }
  1616. if (!readonly) theme.addSetVarListener(theme,client,msec,"change",msecVar.getAttribute("id"),msec,immediate);
  1617. }
  1618. }
  1619. if (!readonly) {
  1620. if (msec) theme.addDateFieldNullListener(client,msec,text,msec,sec,min,hour,day,month,year,yearVar,immediate);
  1621. if (sec) theme.addDateFieldNullListener(client,sec,text,msec,sec,min,hour,day,month,year,yearVar,immediate);
  1622. if (min) theme.addDateFieldNullListener(client,min,text,msec,sec,min,hour,day,month,year,yearVar,immediate);
  1623. if (hour) theme.addDateFieldNullListener(client,hour,text,msec,sec,min,hour,day,month,year,yearVar,immediate);
  1624. if (day) theme.addDateFieldNullListener(client,day,text,msec,sec,min,hour,day,month,year,yearVar,immediate);
  1625. if (month) theme.addDateFieldNullListener(client,month,text,msec,sec,min,hour,day,month,year,yearVar,immediate);
  1626. if (year) theme.addDateFieldNullListener(client,year,text,msec,sec,min,hour,day,month,year,yearVar,immediate);
  1627. }
  1628. var nullFunc = function () {
  1629. // TODO wierd when un-nulling
  1630. // -> serverside, examine
  1631. // + nulls in dropdowns!
  1632. text.value = "";
  1633. if (msec) {
  1634. msec.options[0].selected = true;
  1635. //client.changeVariable(msecVar.getAttribute("id"), -1, false);
  1636. }
  1637. if (sec) {
  1638. sec.options[0].selected = true;
  1639. //client.changeVariable(secVar.getAttribute("id"), -1, false);
  1640. }
  1641. if (min) {
  1642. min.options[0].selected = true;
  1643. //client.changeVariable(minVar.getAttribute("id"), -1, false);
  1644. }
  1645. if (hour) {
  1646. hour.options[0].selected = true;
  1647. //client.changeVariable(hourVar.getAttribute("id"), -1, false);
  1648. }
  1649. //client.changeVariable(dayVar.getAttribute("id"), -1, false);
  1650. //client.changeVariable(monthVar.getAttribute("id"), -1, false);
  1651. client.changeVariable(yearVar.getAttribute("id"), -1, immediate);
  1652. }
  1653. // Function that updates the datefield
  1654. var updateFunc = function (event) {
  1655. if (text.value == null || text.value == "") {
  1656. nullFunc();
  1657. return;
  1658. }
  1659. if (dayVar) {
  1660. var d = text.value.split(".")[0];
  1661. if (d == null || d < 1 || d > 31 ) alert("Error");
  1662. client.changeVariable(dayVar.getAttribute("id"), d, false);
  1663. }
  1664. if (monthVar) {
  1665. var m = text.value.split(".")[1];
  1666. if (m == null || m < 1 || m > 12) alert("Error");
  1667. client.changeVariable(monthVar.getAttribute("id"), m, false);
  1668. }
  1669. var y = text.value.split(".")[2];
  1670. if (y == null || y < 0 || y > 5000) alert("Error");
  1671. client.changeVariable(yearVar.getAttribute("id"), y, immediate);
  1672. };
  1673. if (!readonly && !disabled && style != "time" && dayVar) {
  1674. // Create a unique temporary variable
  1675. // Dont know if all this is needed, but its purpose is to avoid
  1676. // javascript problems with event handlers scopes.
  1677. var temp = "datefield_" + (new Date()).getTime();;
  1678. eval (temp + " = new Object();");
  1679. (eval (temp)).update = function () { updateFunc() };
  1680. var st = "Calendar.setup({onUpdate : function () { " + temp +
  1681. ".update(); } ,inputField : '"+inputId+"', firstDay : 1,"+
  1682. " ifFormat : '%d.%m.%Y', button : '"+buttonId+"'});";
  1683. // Assign update function to textfield
  1684. text.onchange = updateFunc;
  1685. // TODO externalize:
  1686. // Assign initialization to button mouseover (lazy initialization)
  1687. client.addEventListener(button, "mouseover", function(event) {
  1688. if (!eval(temp).initialized) {
  1689. eval(temp).initialized =true;
  1690. eval(st);
  1691. }
  1692. }
  1693. );
  1694. }
  1695. }
  1696. DefaultTheme.prototype.addDateFieldNullListener = function (client,elm,text,msec,sec,min,hour,day,month,year,yearVar,immediate) {
  1697. client.addEventListener(elm, "change", function(event) {
  1698. if ( !elm || elm.value != -1) return;
  1699. if (text) text.value = "";
  1700. if (msec) {
  1701. msec.options[0].selected = true;
  1702. //client.changeVariable(msecVar.getAttribute("id"), -1, false);
  1703. }
  1704. if (sec) {
  1705. sec.options[0].selected = true;
  1706. //client.changeVariable(secVar.getAttribute("id"), -1, false);
  1707. }
  1708. if (min) {
  1709. min.options[0].selected = true;
  1710. //client.changeVariable(minVar.getAttribute("id"), -1, false);
  1711. }
  1712. if (hour) {
  1713. hour.options[0].selected = true;
  1714. //client.changeVariable(hourVar.getAttribute("id"), -1, false);
  1715. }
  1716. if (day) {
  1717. hour.options[0].selected = true;
  1718. //client.changeVariable(hourVar.getAttribute("id"), -1, false);
  1719. }
  1720. if (month) {
  1721. hour.options[0].selected = true;
  1722. //client.changeVariable(hourVar.getAttribute("id"), -1, false);
  1723. }
  1724. if (year) {
  1725. hour.options[0].selected = true;
  1726. //client.changeVariable(hourVar.getAttribute("id"), -1, false);
  1727. }
  1728. //client.changeVariable(dayVar.getAttribute("id"), -1, false);
  1729. //client.changeVariable(monthVar.getAttribute("id"), -1, false);
  1730. client.changeVariable(yearVar.getAttribute("id"), -1, immediate);
  1731. });
  1732. }
  1733. DefaultTheme.prototype.renderDateFieldCalendar = function(renderer,uidl,target,layoutInfo) {
  1734. var theme = renderer.theme;
  1735. // Create containing element
  1736. var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  1737. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  1738. // Render default header
  1739. renderer.theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
  1740. var immediate = uidl.getAttribute("immediate") == "true";
  1741. var enabled = uidl.getAttribute("enabled") == "true";
  1742. var readonly = uidl.getAttribute("readonly") == "true";
  1743. var yearVar = theme.getVariableElement(uidl,"integer","year");
  1744. var monthVar = theme.getVariableElement(uidl,"integer","month");
  1745. var dayVar = theme.getVariableElement(uidl,"integer","day");
  1746. var hourVar = theme.getVariableElement(uidl,"integer","hour");
  1747. var minVar = theme.getVariableElement(uidl,"integer","minutes");
  1748. var secVar = theme.getVariableElement(uidl,"integer","seconds");
  1749. var msecVar = theme.getVariableElement(uidl,"integer","millseconds");
  1750. var showTime = hourVar != null;
  1751. var inputId = yearVar.getAttribute("id") + "_input";
  1752. // Create container DIV
  1753. var calDiv = theme.createElementTo(div,"div");
  1754. calDiv.id = inputId;
  1755. // Assign the value to textfield
  1756. var yearValue = yearVar != null? yearVar.getAttribute("value"): -1;
  1757. var monthValue = monthVar != null? monthVar.getAttribute("value"): -1;
  1758. var dayValue = dayVar != null? dayVar.getAttribute("value"): -1;
  1759. var hourValue = hourVar != null? hourVar.getAttribute("value"): -1;
  1760. var minValue = minVar != null? minVar.getAttribute("value"): -1;
  1761. var secValue = secVar != null? secVar.getAttribute("value"): -1;
  1762. var msecValue = msecVar != null? msecVar.getAttribute("value"): -1;
  1763. if (yearValue >0 && monthValue >0 && dayValue >0) {
  1764. //TODO Assign date
  1765. } else {
  1766. //TODO Assign date
  1767. }
  1768. // Create a unique temporary variable
  1769. // Dont know if all this is needed, but its purpose is to avoid
  1770. // javascript problems with event handlers scopes.
  1771. var temp = "datefield_" + (new Date()).getTime();;
  1772. eval (temp + " = new Object();");
  1773. // Function that updates the datefield
  1774. var dateChanged = function (cal) {
  1775. var y = cal.date.getFullYear();
  1776. var m = cal.date.getMonth();
  1777. var d = cal.date.getDate();
  1778. if (d == null || y == null || m == null || d < 1 ||
  1779. d > 31 || m < 1 || m > 12 || y < 0 || y > 5000) alert("Error");
  1780. client.changeVariable(dayVar.getAttribute("id"), d, false);
  1781. client.changeVariable(monthVar.getAttribute("id"), m, false);
  1782. client.changeVariable(yearVar.getAttribute("id"), y, immediate);
  1783. };
  1784. // Calendar setup code
  1785. (eval (temp)).update = dateChanged;
  1786. var st = "Calendar.setup({flatCallback : function (cal) { " + temp +
  1787. ".update(cal); } ,showsTime: "+showTime+", flat: '"+inputId+"', firstDay : 1,"+
  1788. " ifFormat : '%d.%m.%Y'});";
  1789. // Assign initialization to button mouseover (lazy initialization)
  1790. client.addEventListener(div, "mouseover", function(event) {
  1791. if (!eval(temp).initialized) {
  1792. eval(temp).initialized =true;
  1793. eval(st);
  1794. }
  1795. }
  1796. );
  1797. }
  1798. DefaultTheme.prototype.renderUpload = function(renderer,uidl,target,layoutInfo) {
  1799. var theme = renderer.theme;
  1800. var client = renderer.client;
  1801. var varNode = theme.getVariableElement(uidl,"uploadstream","stream");
  1802. // Create containing element
  1803. var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  1804. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  1805. // Render default header
  1806. renderer.theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
  1807. // Unique name for iframes
  1808. var frameName = "upload_"+varNode.getAttribute("id")+"_iframe";
  1809. var iframe = theme.createElementTo(div, "iframe","upload-iframe");
  1810. iframe.id = frameName;
  1811. iframe.name = frameName;
  1812. iframe.src = 'about:blank';
  1813. // Get the window object of the iframe
  1814. var ifr = window.frames[frameName];
  1815. // TODO: FF fix. The above does not work in FF, so we
  1816. // have to work our way around it. Iterate all frames.
  1817. if (ifr == null) {
  1818. var fi = 0;
  1819. while (fi < window.frames.length) {
  1820. if (window.frames[fi].frameElement != null && window.frames[fi].frameElement.name == frameName) {
  1821. ifr = window.frames[fi];
  1822. }
  1823. fi++;
  1824. }
  1825. }
  1826. if (ifr != null) {
  1827. // Put some initial content to IFRAME.
  1828. // Nasty, but without this the browsers fail
  1829. // to create any elements into window.
  1830. // TODO import CSS file to get right background-color for IE
  1831. var code="<HTML><BODY STYLE=\" overflow: hidden; border: none; margin: 0px; padding: 0px;background-color: transparent;\"><\/BODY><\/HTML>";
  1832. ifr.document.open();
  1833. ifr.document.write(code);
  1834. ifr.document.close();
  1835. // Ok. Now we are ready render the actual upload form and
  1836. // inputs.
  1837. var form = ifr.document.createElement('form');
  1838. form.setAttribute("action",client.ajaxAdapterServletUrl);
  1839. form.setAttribute("method", "post");
  1840. form.setAttribute("enctype", "multipart/form-data");
  1841. if (document.all) {
  1842. form = ifr.document.createElement('<form action="'+client.ajaxAdapterServletUrl+'" method="post" enctype="multipart/form-data">');
  1843. }
  1844. var upload = theme.createInputElementTo(form, "file");
  1845. upload.id = varNode.getAttribute("id");
  1846. upload.name = varNode.getAttribute("id");
  1847. var submit = theme.createInputElementTo(form, "submit");
  1848. submit.value = "Send";
  1849. // submit.value = caption
  1850. submit.disabled = true;
  1851. submit.onclick = function() {
  1852. iframe.style.visibility='hidden';
  1853. }
  1854. upload.onchange = function() {
  1855. if(upload.value) {
  1856. submit.disabled = false;
  1857. } else {
  1858. submit.disabled = true;
  1859. }
  1860. }
  1861. ifr.document.body.appendChild(form);
  1862. // Attach event listeners for processing the chencges after upload.
  1863. if (document.all) {
  1864. iframe.onreadystatechange = function() {
  1865. if (iframe.readyState == "complete") {
  1866. iframe.onreadystatechange = null;
  1867. client.processVariableChanges(true);
  1868. // FIXME next line is workaround to 'iframe is not instantly updated after upload is done' bug.
  1869. // location.reload();
  1870. }
  1871. };
  1872. } else {
  1873. iframe.onload = function() {
  1874. if (ifr.document != null && (ifr.document.contentType == "application/xml")) {
  1875. iframe.onload = null;
  1876. client.processVariableChanges(true);
  1877. // FIXME next line is workaround to 'iframe is not instantly updated after upload is done' bug.
  1878. // location.reload();
  1879. }
  1880. };
  1881. }
  1882. }
  1883. }
  1884. DefaultTheme.prototype.renderEmbedded = function(renderer,uidl,target,layoutInfo) {
  1885. var theme = renderer.theme;
  1886. // Create containing element
  1887. var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  1888. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  1889. // Render default header
  1890. renderer.theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
  1891. if (uidl.getAttribute("type") == "image") {
  1892. // Image mode
  1893. var img = renderer.theme.createElementTo(div,"img","embedded");
  1894. // SRC
  1895. var val = uidl.getAttribute("src");
  1896. if (val != null) img.src = val;
  1897. // Width
  1898. val = uidl.getAttribute("width");
  1899. if (val != null && val > 0) img.width = val;
  1900. // Height
  1901. val = uidl.getAttribute("height");
  1902. if (val != null && val > 0) img.height = val;
  1903. // ALT-attribute
  1904. img.alt = theme.getElementContent(uidl,"description");
  1905. } else {
  1906. /*
  1907. // Object mode
  1908. var embedded = renderer.theme.createElementTo(div,"object","embedded");
  1909. // SRC
  1910. var val = uidl.getAttribute("src");
  1911. if (val) embedded.src = val;
  1912. // Width
  1913. val = uidl.getAttribute("width");
  1914. if (val != null && val > 0) embedded.width = val;
  1915. // Height
  1916. val = uidl.getAttribute("height");
  1917. if (val != null && val > 0) embedded.height = val;
  1918. // Codebase
  1919. val = uidl.getAttribute("codebase");
  1920. if (val != null) embedded.codebase = val;
  1921. // Standby
  1922. val = uidl.getAttribute("standby");
  1923. if (val != null) embedded.codebase = val;
  1924. */
  1925. var html = "<object ";
  1926. var val = uidl.getAttribute("src");
  1927. if (val) html += " data=\""+val+"\" ";
  1928. val = uidl.getAttribute("width");
  1929. if (val) html += " width=\""+val+"\" ";
  1930. val = uidl.getAttribute("height");
  1931. if (val) html += " height=\""+val+"\" ";
  1932. val = uidl.getAttribute("codebase");
  1933. if (val) html += " codebase=\""+val+"\" ";
  1934. val = uidl.getAttribute("standby");
  1935. if (val) html += " standby=\""+val+"\" ";
  1936. html += ">";
  1937. // Add all parameters
  1938. var params = theme.getChildElements(uidl,"embeddedparams");
  1939. if (params != null) {
  1940. var len = params.length;
  1941. for (var i=0;i<len;i++) {
  1942. html += "<param name=\""+params[i].getAttribute("name")+"\" value=\""+params[i].getAttribute("name")+"\" />"
  1943. }
  1944. }
  1945. html += "</object>";
  1946. div.innerHTML = html;
  1947. }
  1948. }
  1949. DefaultTheme.prototype.renderLink = function(renderer,uidl,target,layoutInfo) {
  1950. // Shortcut variables
  1951. var theme = renderer.theme;
  1952. var client = renderer.client;
  1953. var immediate = "true"==uidl.getAttribute("immediate");
  1954. var disabled = "true"==uidl.getAttribute("disabled");
  1955. var readonly = "true"==uidl.getAttribute("readonly");
  1956. var targetName = uidl.getAttribute("name");
  1957. var width = uidl.getAttribute("width");
  1958. var height = uidl.getAttribute("height");
  1959. var border = uidl.getAttribute("border");
  1960. var src = uidl.getAttribute("src");
  1961. if (src && src.indexOf("theme://") == 0) {
  1962. src = theme.root + src.substring(8);
  1963. }
  1964. // Create containing element
  1965. var div = theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  1966. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  1967. var link = theme.createElementTo(div,"div", "link pad clickable");
  1968. if (!disabled&&!readonly) {
  1969. theme.addAddClassListener(theme,client,link,"mouseover","over");
  1970. theme.addRemoveClassListener(theme,client,link,"mouseout","over");
  1971. var feat;
  1972. switch (border) {
  1973. case "minimal":
  1974. feat = "menubar=yes,location=no,status=no";
  1975. break;
  1976. case "none":
  1977. feat = "menubar=no,location=no,status=no";
  1978. break;
  1979. default:
  1980. feat = "menubar=yes,location=yes,scrollbars=yes,status=yes";
  1981. break;
  1982. }
  1983. if (width||height) {
  1984. feat += ",resizable=no";
  1985. feat += (width?",width="+width:"");
  1986. feat += (height?",height="+height:"");
  1987. } else {
  1988. feat += ",resizable=yes";
  1989. }
  1990. theme.addLinkOpenWindowListener(theme,client,div,"click",src,targetName,feat);
  1991. }
  1992. /*
  1993. with(props) {
  1994. client.addEventListener(div,"mouseover", function(e) {
  1995. theme.addCSSClass(div,"over");
  1996. }
  1997. );
  1998. client.addEventListener(div,"mouseout", function(e) {
  1999. theme.removeCSSClass(div,"over");
  2000. }
  2001. );
  2002. client.addEventListener(div,"click", function(e) {
  2003. theme.hidePopup();
  2004. if (!target) {
  2005. window.location = src;
  2006. } else {
  2007. var feat;
  2008. switch (border) {
  2009. case "minimal":
  2010. feat = "menubar=yes,location=no,status=no";
  2011. break;
  2012. case "none":
  2013. feat = "menubar=no,location=no,status=no";
  2014. break;
  2015. default:
  2016. feat = "menubar=yes,location=yes,scrollbars=yes,status=yes";
  2017. break;
  2018. }
  2019. if (width||height) {
  2020. feat += ",resizable=no"
  2021. } else {
  2022. feat += ",resizable=yes"
  2023. }
  2024. var win = window.open(src, target,
  2025. feat
  2026. +(width?",width="+width:"")
  2027. +(height?",height="+height:"")
  2028. );
  2029. win.focus();
  2030. }
  2031. }
  2032. );
  2033. }
  2034. */
  2035. //var inner = theme.createElementTo(div,"div", "border pad");
  2036. // Render default header
  2037. theme.renderDefaultComponentHeader(renderer,uidl,link);
  2038. // Description under link
  2039. var descriptionText = theme.getElementContent(uidl,"description");
  2040. if (descriptionText) {
  2041. var desc = theme.createElementTo(link,"div", "description");
  2042. theme.createTextNodeTo(desc,descriptionText);
  2043. }
  2044. }
  2045. DefaultTheme.prototype.addLinkOpenWindowListener = function(theme,client,element,event,url,target,features) {
  2046. client.addEventListener(element,(event=="rightclick"?"click":event), function(e) {
  2047. var evt = client.getEvent(e);
  2048. if (event=="rightclick"&&!evt.rightclick) return;
  2049. if (!target) {
  2050. window.location = url;
  2051. } else {
  2052. var win = window.open(url, target, features);
  2053. win.focus();
  2054. }
  2055. }
  2056. );
  2057. }
  2058. DefaultTheme.prototype.renderPagingTable = function(renderer,uidl,target,layoutInfo) {
  2059. // Shortcut variables
  2060. var theme = renderer.theme;
  2061. var client = renderer.client;
  2062. // Create containing DIV
  2063. var div = theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  2064. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  2065. if ("list"==uidl.getAttribute("style")) {
  2066. theme.removeCSSClass(div,"table");
  2067. theme.addCSSClass(div,"list");
  2068. }
  2069. // Create default header
  2070. var caption = theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
  2071. // Get table attributes
  2072. var rowheaders = ("true"==uidl.getAttribute("rowheaders"));
  2073. var totalrows = parseInt(uidl.getAttribute("totalrows"));
  2074. var pagelength = parseInt(uidl.getAttribute("pagelength"));
  2075. var rowCount = parseInt(uidl.getAttribute("rows"));
  2076. var firstvisible = theme.getVariableElementValue(theme.getVariableElement(uidl,"integer","firstvisible"))||1;
  2077. var firstvisibleVar = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"integer","firstvisible"));
  2078. var immediate = ("true" == uidl.getAttribute("immediate"));
  2079. var selectMode = uidl.getAttribute("selectmode");
  2080. var selectable = selectMode == "multi" || selectMode == "single";
  2081. var selected; // Selected map
  2082. if (selectable) {
  2083. selected = new Array();
  2084. }
  2085. var selectionVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","selected"));
  2086. var visibleCols = theme.getFirstElement(uidl,"visiblecolumns");
  2087. var collapseVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","collapsedcolumns"));
  2088. var sortcolVar = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"string","sortcolumn"));
  2089. var sortkey = theme.getVariableElementValue(theme.getVariableElement(uidl,"string","sortcolumn"));
  2090. var sortasc = theme.getVariableElement(uidl,"boolean","sortascending");
  2091. var sortascVar = theme.createVariableElementTo(div,sortasc);
  2092. sortasc = sortasc != null && "true"==sortasc.getAttribute("value");
  2093. var actions = null;
  2094. var actionVar = null;
  2095. var alNode = theme.getFirstElement(uidl,"actions")
  2096. if (alNode) {
  2097. actionVar = theme.createVariableElementTo(div,theme.getVariableElement(alNode,"string","action"));
  2098. actions = new Object();
  2099. var ak = alNode.getElementsByTagName("action");
  2100. for (var i=0;i<ak.length;i++) {
  2101. actions[ak[i].getAttribute("key")] = ak[i].getAttribute("caption");
  2102. }
  2103. }
  2104. delete alNode;
  2105. // Create table for content
  2106. div = theme.createElementTo(div,"div","outset");
  2107. div = theme.createElementTo(div,"div","content border");
  2108. var table = theme.createElementTo(div,"table");
  2109. table = theme.createElementTo(table,"tbody");
  2110. table.setAttribute("cellpadding","0");
  2111. table.setAttribute("cellspacing","0");
  2112. var tr = null;
  2113. var td = null;
  2114. // Column headers
  2115. var cols = theme.getFirstElement(uidl,"cols");
  2116. if (cols != null) {
  2117. cols = cols.getElementsByTagName("ch");
  2118. }
  2119. if (cols != null && cols.length >0) {
  2120. tr = theme.createElementTo(table,"tr","header");
  2121. if (rowheaders) {
  2122. theme.createElementTo(tr,"td","empty");
  2123. }
  2124. for (var i=0; i<cols.length;i++) {
  2125. var sortable = cols[i].getAttribute("sortable");
  2126. td = theme.createElementTo(tr,"td","cheader bg");
  2127. // Sorting
  2128. var key = cols[i].getAttribute("cid");
  2129. if (sortable=="true") {
  2130. theme.addCSSClass(td,"clickable");
  2131. // Sorting always immediate
  2132. theme.addSetVarListener(theme,client,td,"click",sortascVar,(key==sortkey?!sortasc:sortasc),false);
  2133. theme.addSetVarListener(theme,client,td,"click",sortcolVar,key,true);
  2134. }
  2135. var ch = cols[i].getAttribute("caption");
  2136. var cap = theme.createElementTo(td,"div","caption");
  2137. theme.createTextNodeTo(cap,ch != null? ch : "");
  2138. if (sortkey==key) {
  2139. var icon = theme.createElementTo(cap,"IMG","icon");
  2140. icon.src = theme.root+"img/table/"+(sortasc?"asc.gif":"desc.gif");
  2141. }
  2142. }
  2143. // Collapsing
  2144. td = theme.createElementTo(tr,"td","cheader scroll bg");
  2145. if (visibleCols) {
  2146. var iconDiv = theme.createElementTo(td,"div");
  2147. var icon = theme.createElementTo(iconDiv,"img","icon");
  2148. icon.src = theme.root+"img/table/colsel.gif";
  2149. var popup = theme.createElementTo(td,"div","outset popup hide");
  2150. var inner = theme.createElementTo(popup,"div","border");
  2151. // empty row to allow closing:
  2152. var row = theme.createElementTo(inner,"div","item clickable pad border");
  2153. theme.addHidePopupListener(theme,client,row,"click");
  2154. theme.addToggleClassListener(theme,client,row,"mouseover","over");
  2155. theme.addToggleClassListener(theme,client,row,"mouseout","over");
  2156. theme.addTogglePopupListener(theme,client,iconDiv,"click",popup);
  2157. var cols = visibleCols.getElementsByTagName("column");
  2158. for (var i=0;i<cols.length;i++) {
  2159. var row = theme.createElementTo(inner,"div","item clickable pad border");
  2160. var collapsed = "true"==cols[i].getAttribute("collapsed");
  2161. icon = theme.createElementTo(row,"img","icon");
  2162. icon.src = theme.root+"img/table/"+(collapsed?"off.gif":"on.gif");
  2163. theme.createTextNodeTo(row,cols[i].getAttribute("caption"));
  2164. theme.addToggleClassListener(theme,client,row,"mouseover","over");
  2165. theme.addToggleClassListener(theme,client,row,"mouseout","over");
  2166. theme.addToggleVarListener(theme,client,row,"click",collapseVariable,cols[i].getAttribute("cid"),true);
  2167. }
  2168. delete cols;
  2169. }
  2170. }
  2171. delete cols;
  2172. // Table rows
  2173. var rows = theme.getFirstElement(uidl,"rows");
  2174. if (rows != null) {
  2175. rows = theme.getChildElements(rows,"tr");
  2176. }
  2177. if (rows != null && rows.length >0) {
  2178. for (var i=0; i<rows.length;i++) {
  2179. tr = theme.createElementTo(table,"tr");
  2180. // TODO rowheader
  2181. theme.setCSSClass(tr, (i % 2 == 0?"even":"odd"));
  2182. if (selectable) theme.addCSSClass(tr, "clickable");
  2183. var key = rows[i].getAttribute("key");
  2184. if (selectable&&"true"==rows[i].getAttribute("selected")) {
  2185. theme.addCSSClass(tr, "selected");
  2186. selected[selected.length] = tr;
  2187. }
  2188. if (selectable) {
  2189. if (selectMode == "multi") {
  2190. theme.addToggleClassListener(theme,client,tr,"click","selected");
  2191. theme.addToggleVarListener(theme,client,tr,"click",selectionVariable,key,immediate);
  2192. } else {
  2193. theme.addAddClassListener(theme,client,tr,"click","selected",tr,selected);
  2194. theme.addSetVarListener(theme,client,tr,"click",selectionVariable,key,immediate);
  2195. }
  2196. }
  2197. if (rowheaders) {
  2198. var td = theme.createElementTo(tr,"td","rheader bg");
  2199. var caption = theme.createElementTo(td,"div","caption");
  2200. theme.createTextNodeTo(caption,rows[i].getAttribute("caption"));
  2201. }
  2202. if (rows[i].childNodes != null && rows[i].childNodes.length >0) {
  2203. var al = null;
  2204. for (var j=0; j<rows[i].childNodes.length;j++) {
  2205. if (rows[i].childNodes[j].nodeName == "al") {
  2206. al = rows[i].childNodes[j];
  2207. } else if (rows[i].childNodes[j].nodeType == Node.ELEMENT_NODE) {
  2208. td = theme.createElementTo(tr,"td");
  2209. renderer.client.renderUIDL(rows[i].childNodes[j],td);
  2210. if (al) {
  2211. theme.renderActionPopup(renderer,al,td,actions,actionVar,key);
  2212. }
  2213. }
  2214. }
  2215. }
  2216. // SCROLLBAR
  2217. if (i==0) {
  2218. td = theme.createElementTo(tr,"td", "scroll border");
  2219. // TODO:
  2220. //theme.tableAddScrollEvents(theme,td);
  2221. td.setAttribute("rowSpan",rows.length);
  2222. var inner = theme.createElementTo(td,"div", "scroll");
  2223. }
  2224. }
  2225. }
  2226. delete rows;
  2227. var paging = theme.createElementTo(div,"div","nav pad");
  2228. var button = theme.createElementTo(paging,"div","pad caption inline");
  2229. if (firstvisible > 1) {
  2230. theme.addCSSClass(button,"clickable");
  2231. theme.addAddClassListener(theme,client,button,"mouseover","bg");
  2232. theme.addRemoveClassListener(theme,client,button,"mouseout","bg");
  2233. theme.addSetVarListener(theme,client,button,"click",firstvisibleVar,(String) (parseInt(firstvisible)-parseInt(pagelength)),true);
  2234. } else {
  2235. theme.addCSSClass(button,"disabled");
  2236. }
  2237. theme.createTextNodeTo(button,"<<");
  2238. button = theme.createElementTo(paging,"div","small pad inline");
  2239. theme.createTextNodeTo(button,firstvisible+" - "+(firstvisible-1+parseInt(rowCount))+ " / " + totalrows);
  2240. button = theme.createElementTo(paging,"div","pad caption inline");
  2241. if (parseInt(firstvisible)+parseInt(pagelength)<=parseInt(totalrows)) {
  2242. theme.addCSSClass(button,"clickable");
  2243. theme.addAddClassListener(theme,client,button,"mouseover","bg");
  2244. theme.addRemoveClassListener(theme,client,button,"mouseout","bg");
  2245. theme.addSetVarListener(theme,client,button,"click",firstvisibleVar, (String) (parseInt(firstvisible)+parseInt(pagelength)),true);
  2246. } else {
  2247. theme.addCSSClass(button,"disabled");
  2248. }
  2249. theme.createTextNodeTo(button,">>");
  2250. }
  2251. DefaultTheme.prototype.renderScrollTable = function(renderer,uidl,target,layoutInfo) {
  2252. // Shortcut variables
  2253. var theme = renderer.theme;
  2254. var client = renderer.client;
  2255. var colWidths;
  2256. if (target.colWidths) {
  2257. colWidths = target.colWidths;
  2258. } else {
  2259. colWidths = new Object();
  2260. }
  2261. var wholeWidth = target.wholeWidth;
  2262. var scrolledLeft = target.scrolledLeft;
  2263. // Get attributes
  2264. var pid = uidl.getAttribute("id");
  2265. var immediate = uidl.getAttribute("immediate")||false;
  2266. var selectmode = uidl.getAttribute("selectmode");
  2267. var cols = parseInt(uidl.getAttribute("cols"));
  2268. var rows = parseInt(uidl.getAttribute("rows"));
  2269. var totalrows = parseInt(uidl.getAttribute("totalrows"));
  2270. var pagelength = uidl.getAttribute("pagelength");
  2271. var colheaders = uidl.getAttribute("colheaders")||false;
  2272. var rowheaders = uidl.getAttribute("rowheaders")||false;
  2273. var visiblecols = theme.getFirstElement(uidl,"visiblecolumns");
  2274. var sortkey = theme.getVariableElementValue(theme.getVariableElement(uidl,"string","sortcolumn"));
  2275. var colorder = new Array();
  2276. var fv = parseInt(theme.getVariableElementValue(theme.getVariableElement(uidl,"integer","firstvisible"))||1);
  2277. var selected; // Selected map
  2278. if (selectmode) {
  2279. selected = new Array();
  2280. }
  2281. // Create containing DIV
  2282. var div = theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  2283. div.colWidths = colWidths;
  2284. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  2285. // Variables
  2286. var fvVar = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"integer","firstvisible"));
  2287. var ccVar = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","collapsedcolumns"));
  2288. var coVar = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","columnorder"));
  2289. var selVar = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","selected"));
  2290. var sortVar = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"string","sortcolumn"));
  2291. var sortasc = theme.getVariableElement(uidl,"boolean","sortascending");
  2292. var sortascVar = theme.createVariableElementTo(div,sortasc);
  2293. sortasc = (sortasc != null && "true"==sortasc.getAttribute("value"));
  2294. // Create default header
  2295. var caption = theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
  2296. theme.addCSSClass(caption,"tablecaption");
  2297. // column collapsing
  2298. // main div
  2299. var inner = theme.createElementTo(div,"div","border");
  2300. inner.innerHTML = "<TABLE width=\"100%\"><TR><TD></TD></TR></TABLE>";
  2301. if (!wholeWidth) {
  2302. wholeWidth = inner.offsetWidth||inner.clientWidth||300;
  2303. wholeWidth -= 2; // Leave room for border, TODO: more dynamic
  2304. if (wholeWidth<200) wholeWidth = 300;
  2305. }
  2306. div.wholeWidth = wholeWidth;
  2307. var offsetLeft = client.getElementPosition(inner).x;
  2308. // Actions
  2309. var actions = null;
  2310. var actionVar = null;
  2311. var alNode = theme.getFirstElement(uidl,"actions")
  2312. if (alNode) {
  2313. actionVar = theme.createVariableElementTo(div,theme.getVariableElement(alNode,"string","action"));
  2314. actions = new Object();
  2315. var ak = alNode.getElementsByTagName("action");
  2316. for (var i=0;i<ak.length;i++) {
  2317. actions[ak[i].getAttribute("key")] = ak[i].getAttribute("caption");
  2318. }
  2319. }
  2320. delete alNode;
  2321. inner.innerHTML = "<DIV id=\""+pid+"status\" align=\"center\" class=\"tablestatus\" style=\"width:"+(wholeWidth/2)+"px;display:none;\"></DIV><TABLE cellpadding=0 cellspacing=0 border=0 width=100%><TBODY><TR valign=top class=bg><TD></TD><TD align=center width=16></TD></TR></TBODY></TABLE><TABLE>";
  2322. //inner.style.width = wholeWidth+"px";
  2323. var vcols = inner.childNodes[1].firstChild.firstChild.childNodes[1];
  2324. if (visiblecols) {
  2325. vcols.innerHTML = "<DIV class=\"colsel\"><DIV/></DIV>";
  2326. var icon = vcols.firstChild;
  2327. vcols.id = pid+"vcols";
  2328. var popup = theme.createElementTo(div,"div","border popup hide");
  2329. theme.addTogglePopupListener(theme,client,icon,"click",popup);
  2330. theme.addStopListener(theme,client,icon,"mouseover");
  2331. theme.addStopListener(theme,client,icon,"mouseout");
  2332. var row = theme.createElementTo(popup,"div","item clickable pad border");
  2333. theme.addHidePopupListener(theme,client,row,"click");
  2334. var cols = visiblecols.getElementsByTagName("column");
  2335. for (var i=0;i<cols.length;i++) {
  2336. var row = theme.createElementTo(popup,"div","item clickable pad border");
  2337. var collapsed = "true"==cols[i].getAttribute("collapsed");
  2338. icon = theme.createElementTo(row,"img","icon");
  2339. icon.src = theme.root+"img/table/"+(collapsed?"off.gif":"on.gif");
  2340. theme.createTextNodeTo(row,cols[i].getAttribute("caption"));
  2341. theme.addAddClassListener(theme,client,row,"mouseover","over");
  2342. theme.addRemoveClassListener(theme,client,row,"mouseout","over");
  2343. theme.addToggleVarListener(theme,client,row,"click",ccVar,cols[i].getAttribute("cid"),true);
  2344. }
  2345. delete cols;
  2346. }
  2347. // FIRST render the table
  2348. var alignments = new Array();
  2349. // headers
  2350. var hout = theme.createElementTo(inner.childNodes[1].firstChild.firstChild.firstChild,"div","bg");
  2351. hout.style.width = (wholeWidth-16)+"px";
  2352. hout.style.paddingRight = "0px";
  2353. hout.id = pid+"hout";
  2354. hout.style.overflow = "hidden";
  2355. theme.addCSSClass(hout,"hout");
  2356. var html = "<TABLE id=\""+pid+"hin\" class=\"hin\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><TBODY><TR>";
  2357. if (rowheaders) {
  2358. html += "<TD ";
  2359. if (colWidths["heh"]) {
  2360. html += "width=\""+colWidths["heh"]+"\" ";
  2361. }
  2362. html += "style=\"overflow:hidden\" cid=\"heh\" id=\""+pid+"heh\"><DIV class=\"padnr hah\" style=\"";
  2363. if (colWidths["heh"]) {
  2364. html += "width:"+colWidths["heh"]+"px;";
  2365. }
  2366. html += "overflow:hidden;height:100%;white-space:nowrap;\"><IMG id=\""+pid+"hah\" align=\"right\" src=\""+theme.root+"img/table/handle.gif\" border=\"0\"></DIV></TD>";
  2367. }
  2368. var chs = theme.getFirstElement(uidl, "cols").getElementsByTagName("ch");
  2369. var len = chs.length;
  2370. for (var i=0;i<len;i++) {
  2371. var col = chs[i];
  2372. var cap = col.getAttribute("caption")||(visiblecols?"":"");
  2373. var sort = col.getAttribute("sortable");
  2374. var cid = col.getAttribute("cid");
  2375. var iconUrl = col.getAttribute("icon");
  2376. if (iconUrl && iconUrl.indexOf("theme://") == 0) {
  2377. iconUrl = (theme.iconRoot != null ? theme.iconRoot : theme.root)
  2378. + iconUrl.substring(8);
  2379. }
  2380. alignments[i] = col.getAttribute("align");
  2381. colorder[i] = cid;
  2382. html += "<TD ";
  2383. if (colWidths[cid]) {
  2384. html += "width=\""+colWidths[cid]+"\" ";
  2385. }
  2386. if (sortkey == cid) {
  2387. html += "sorted=\"true\" class=\"sorted\" ";
  2388. }
  2389. html += "style=\"overflow:hidden\" cid=\""+cid+"\" id=\""+pid+"he"+i+"\" >"
  2390. html += "<DIV class=\"padnr tableheader\" ";
  2391. if (alignments[i]) {
  2392. switch (alignments[i]) {
  2393. case "e":
  2394. html += "align=\"right\"";
  2395. break;
  2396. case "c":
  2397. html += "align=\"center\"";
  2398. break;
  2399. default:
  2400. }
  2401. }
  2402. html += " style=\"";
  2403. if (colWidths[cid]) {
  2404. html += "width:"+colWidths[cid]+"px;";
  2405. }
  2406. html += "overflow:hidden;height:100%;white-space:nowrap;\"><IMG id=\""+pid+"ha"+cid+"\" align=\"right\" src=\""+theme.root+"img/table/handle.gif\" border=\"0\">";
  2407. html += (iconUrl?"<IMG src=\""+iconUrl+"\" class=\"icon\">":"")+cap+(sortkey==cid?"<IMG align=right class=\"sort sort"+(sortasc?"asc":"desc")+"\"/>":"")+"</DIV></TD>";
  2408. }
  2409. html += "</TR></TBODY></TABLE>";
  2410. hout.innerHTML = html;
  2411. // content
  2412. // scroll padding calculations
  2413. // TODO these need to be calculated better, perhaps updated after rendering content
  2414. var prePad = (fv==1?1:fv*22);
  2415. var postPad = (totalrows-fv-rows+1)*22;
  2416. // html
  2417. cout = theme.createElementTo(inner,"div");
  2418. cout.style.width = wholeWidth+"px";
  2419. cout.style.height = (18*rows)+"px";
  2420. cout.id = pid+"cout";
  2421. theme.addCSSClass(cout,"cout");
  2422. cout.style.overflow = "scroll";
  2423. html = "<TABLE border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"cin\" id=\""+pid+"cin\"><TBODY><TR height=\""+prePad+"\"></TR>";
  2424. var trs = theme.getFirstElement(uidl, "rows").getElementsByTagName("tr");
  2425. len = trs.length;
  2426. if (len==0) {
  2427. html += "<TR id=\""+pid+"firstrow\"><TD style=\"overflow:hidden\">";
  2428. html += "<DIV class=\"tablecell pad\" style=\"overflow:hidden;height:100%;white-space:nowrap;border-right:1px solid gray;\"></DIV></TD></TR>";
  2429. }
  2430. for (var i=0;i<len;i++) {
  2431. var row = trs[i];
  2432. var cap = row.getAttribute("caption");
  2433. var key = row.getAttribute("key");
  2434. var seld = row.getAttribute("selected");
  2435. var iconUrl = row.getAttribute("icon");
  2436. html += "<TR "+(i==0?"id=\""+pid+"firstrow\"":"");
  2437. html += " key=\""+key+"\"";
  2438. if (seld) {
  2439. html += " selected=\"true\" class=\"selected\" ";
  2440. } else {
  2441. html += "class=\""+(i%2!=0?"odd":"even")+"\" ";
  2442. }
  2443. html += ">";
  2444. if (rowheaders) {
  2445. html += "<TD ";
  2446. if (colWidths["heh"]) {
  2447. html += "width=\""+colWidths["heh"]+"\" ";
  2448. }
  2449. html += "style=\"overflow:hidden\"><DIV class=\"padnr tableheader\" style=\"";
  2450. if (colWidths["heh"]) {
  2451. html += "width:"+colWidths["heh"]+"px;";
  2452. }
  2453. html += "overflow:hidden;height:100%;white-space:nowrap;border-right:1px solid gray;\">";
  2454. if (iconUrl) {
  2455. if (iconUrl.indexOf("theme://") == 0) {
  2456. iconUrl = (theme.iconRoot != null ? theme.iconRoot : theme.root)
  2457. + iconUrl.substring(8);
  2458. }
  2459. html += "<IMG src=\""+iconUrl+"\" class=\"icon\" />";
  2460. }
  2461. html += row.getAttribute("caption")+"</DIV></TD>";
  2462. }
  2463. var comps = row.childNodes;
  2464. var l = comps.length;
  2465. if (l==0) {
  2466. html += "<TD><DIV class=\"padnr tablecell\" style=\"overflow:hidden;height:100%;white-space:nowrap;border-right:1px solid gray;\"></DIV></TD>";
  2467. }
  2468. var colNum = -1;
  2469. for (j=0;j<l;j++) {
  2470. var comp = comps[j];
  2471. if (comp.nodeName == "al"||comp.nodeName == "#text") continue;
  2472. colNum++;
  2473. // Placeholder TD, we'll render the content later
  2474. html += "<TD "
  2475. if (colWidths[colorder[colNum]]) {
  2476. html += "width=\""+colWidths[colorder[colNum]]+"\" ";
  2477. }
  2478. html += "style=\"overflow:hidden\"><DIV class=\"padnr tablecell\" style=\"";
  2479. if (colWidths[colorder[colNum]]) {
  2480. html += "width:"+colWidths[colorder[colNum]]+"px;";
  2481. }
  2482. html += "overflow:hidden;height:100%;white-space:nowrap;border-right:1px solid gray;\" ";
  2483. if (alignments[colNum]) {
  2484. switch (alignments[colNum]) {
  2485. case "e":
  2486. html += " align=\"right\" ";
  2487. break;
  2488. case "c":
  2489. html += " align=\"center\" ";
  2490. break;
  2491. default:
  2492. }
  2493. }
  2494. html += "></DIV></TD>";
  2495. }
  2496. html += "</TR>";
  2497. }
  2498. html += "<TR id=\""+pid+"lastrow\" height=\""+postPad+"\"></TR></TBODY></TABLE>";
  2499. cout.innerHTML = html;
  2500. // SECOND render the sub-components (TD content)
  2501. var trs = cout.firstChild.firstChild.childNodes;
  2502. var utrs = theme.getFirstElement(uidl, "rows").getElementsByTagName("tr");
  2503. for (var i=0;i<len;i++) {
  2504. var tr = trs[i+1];
  2505. var key = tr.getAttribute("key");
  2506. var comps = utrs[i].childNodes;
  2507. var l = comps.length;
  2508. var currentCol = (rowheaders?1:0);
  2509. var al = null;
  2510. for (j=0;j<l;j++) {
  2511. var comp = comps[j];
  2512. if (comp.nodeName == "#text") continue;
  2513. if (comp.nodeName == "al") {
  2514. al = comp;
  2515. continue;
  2516. }
  2517. var trg = tr.childNodes[currentCol++].firstChild;
  2518. client.renderUIDL(comp, trg);
  2519. }
  2520. if (al&&tr.firstChild) {
  2521. theme.renderActionPopup(renderer,al,tr,actions,actionVar,key,"rightclick");
  2522. }
  2523. // selection
  2524. if (selectmode) {
  2525. selected[selected.length] = tr;
  2526. theme.addCSSClass(tr,"clickable");
  2527. theme.addToggleClassListener(theme,client,tr,"mouseover","selectable");
  2528. theme.addToggleClassListener(theme,client,tr,"mouseout","selectable");
  2529. if (selectmode == "multi") {
  2530. theme.addToggleClassListener(theme,client,tr,"click","selected");
  2531. theme.addToggleVarListener(theme,client,tr,"click",selVar,key,immediate);
  2532. } else {
  2533. theme.addAddClassListener(theme,client,tr,"click","selected",tr,selected);
  2534. theme.addSetVarListener(theme,client,tr,"click",selVar,key,immediate);
  2535. }
  2536. }
  2537. }
  2538. // THIRD do some initial sizing and scrolling
  2539. var fr = target.ownerDocument.getElementById(pid+"firstrow").offsetTop;
  2540. var lr = target.ownerDocument.getElementById(pid+"lastrow").offsetTop;
  2541. cout.style.height = (lr-fr+20)+"px";
  2542. cout.scrollTop = (fv>totalrows-rows?cout.scrollHeight:fr);
  2543. div.recalc = theme.scrollTableRecalc;
  2544. div.initialWidth = wholeWidth;
  2545. div.recalc(pid,target);
  2546. cout.scrollLeft = scrolledLeft;
  2547. hout.scrollLeft = scrolledLeft;
  2548. var status = target.ownerDocument.getElementById(pid+"status");
  2549. var p = client.getElementPosition(inner);
  2550. status.style.top = (p.y + p.h/2) + "px";
  2551. status.style.left = (p.x + p.w/2 - wholeWidth/4) +"px";
  2552. theme.scrollTableAddScrollHandler(client,theme,cout,div,status,lr,fr,rows,totalrows,fv,fvVar,immediate);
  2553. theme.scrollTableAddScrollListener(theme,div,pid,lr,fr,rows,totalrows,fv);
  2554. // Column order drag & drop
  2555. var hin = target.ownerDocument.getElementById(pid+"hin");
  2556. var h = hin.getElementsByTagName("td");
  2557. var dragOrderGroup = new Object();
  2558. for (var i = 0;i<h.length;i++) {
  2559. var id = h[i].getAttribute("id");
  2560. if (id==pid+"heh") {
  2561. var handle = target.ownerDocument.getElementById(pid+"hah");
  2562. if (handle) {
  2563. theme.tableAddWidthListeners(client,theme,handle,"heh",div,pid);
  2564. }
  2565. }
  2566. if (!id||id.indexOf(pid+"he")<0) {
  2567. continue;
  2568. }
  2569. var cid = h[i].getAttribute("cid");
  2570. var handle = target.ownerDocument.getElementById(pid+"ha"+cid);
  2571. if (handle) {
  2572. theme.tableAddWidthListeners(client,theme,handle,cid,div,pid);
  2573. }
  2574. if (coVar||sortVar) {
  2575. theme.addCSSClass(h[i],"clickable");
  2576. theme.addToDragOrderGroup(client,theme,h[i],dragOrderGroup,coVar,sortVar,sortascVar,sortasc);
  2577. }
  2578. }
  2579. var hin = target.ownerDocument.getElementById(pid+"hin");
  2580. var cin = target.ownerDocument.getElementById(pid+"cin");
  2581. theme.scrollTableRegisterLF(client,theme,div,inner,cout,hout,cin,hin);
  2582. }
  2583. // Header order drag & drop
  2584. DefaultTheme.prototype.tableAddWidthListeners = function(client,theme,element,cid,table,pid) {
  2585. var colWidths = table.colWidths;
  2586. var mouseDragListener = function (e) {
  2587. var evt = client.getEvent(e);
  2588. evt.stop();
  2589. element.ownerDocument.onselectstart = function(e) {return false;}
  2590. var target = element.target;
  2591. var div = target.parentNode;
  2592. var td = div.parentNode;
  2593. //target.style.position = "relative";
  2594. target.style.zIndex = "99999";
  2595. var offset = -(target.origX-evt.mouseX+10);
  2596. var w = (target.origW+offset);
  2597. if (w < 7) w = 7;
  2598. try {
  2599. target.style.left = offset+"px";
  2600. td.width = w;
  2601. td.style.width = w+"px";
  2602. td.firstChild.style.width = w+"px";
  2603. colWidths[cid] = w;
  2604. } catch (err) {
  2605. client.debug("Failed: d&d target.style.left="+ offset+"px");
  2606. }
  2607. }
  2608. var mouseUpListener = function(e) {
  2609. client.removeEventListener(element.ownerDocument.body,"mousemove",mouseDragListener);
  2610. client.removeEventListener(element.ownerDocument.body,"mouseup",arguments.callee);
  2611. client.removeEventListener(element.ownerDocument.body,"drag",stopListener);
  2612. var evt = client.getEvent(e);
  2613. evt.stop();
  2614. element.ownerDocument.onselectstart = null;
  2615. element.dragging = false;
  2616. // TODO apply for all rows
  2617. table.recalc(pid,table);
  2618. return false;
  2619. };
  2620. var stopListener = function (e) {
  2621. var evt = client.getEvent(e);
  2622. evt.stop();
  2623. return false;
  2624. }
  2625. client.addEventListener(element,"mousedown", function(e) {
  2626. var evt = client.getEvent(e);
  2627. evt.stop();
  2628. element.dragging = true;
  2629. element.moved = false;
  2630. element.target = evt.target;
  2631. evt.target.origX = evt.mouseX;
  2632. evt.target.origW = evt.target.parentNode.offsetWidth;
  2633. client.addEventListener(element.ownerDocument.body,"mousemove", mouseDragListener);
  2634. client.addEventListener(element.ownerDocument.body,"mouseup", mouseUpListener);
  2635. client.addEventListener(element.ownerDocument.body,"drag",stopListener);
  2636. });
  2637. }
  2638. DefaultTheme.prototype.scrollTableRegisterLF = function(client,theme,paintableElement,inner,cout,hout,cin,hin) {
  2639. client.registerLayoutFunction(paintableElement,function() {
  2640. var w = (inner.offsetWidth-2) +"px";
  2641. cout.style.width = w;
  2642. //cin.style.width = w;
  2643. //hout.style.width = w;
  2644. //hin.style.width = w;
  2645. hout.style.width = hout.offsetParent.offsetWidth + "px";
  2646. //div.recalc();
  2647. });
  2648. }
  2649. DefaultTheme.prototype.scrollTableAddScrollListener = function (theme,target,pid,lr,fr,rows,totalrows,fv) {
  2650. var hout = target.ownerDocument.getElementById(pid+"hout");
  2651. var cout = target.ownerDocument.getElementById(pid+"cout");
  2652. client.addEventListener(cout,"scroll", function (e) {
  2653. if (cout.scrollTimeout) {
  2654. clearTimeout(cout.scrollTimeout);
  2655. }
  2656. hout.scrollLeft = cout.scrollLeft;
  2657. target.scrolledLeft = cout.scrollLeft;
  2658. var status = target.ownerDocument.getElementById(pid+"status");
  2659. var d = theme.scrollTableGetFV(cout,lr,fr,rows,totalrows,fv);
  2660. if (d!=fv) {
  2661. status.innerHTML = d + "-" + (d+rows-1) + " / " + totalrows;
  2662. status.style.display = "";
  2663. }
  2664. cout.scrollTimeout = setTimeout(function () {
  2665. var cout = target.ownerDocument.getElementById(pid+"cout");
  2666. cout.scrollHandler();
  2667. },500)
  2668. });
  2669. }
  2670. DefaultTheme.prototype.scrollTableGetFV = function(cout,lr,fr,rows,totalrows,fv) {
  2671. var rh = (lr-fr)/rows;
  2672. if (cout.scrollTop >= (fr+rh/2) || cout.scrollTop <= (fr-rh/2)) {
  2673. var d = Math.round((cout.scrollTop-fr)/rh);
  2674. d = (fv+d);
  2675. if (d<1) d=1; // scrolled past begin
  2676. if (d>(totalrows-rows+1)) d=(totalrows-rows+1); // scrolled past last page
  2677. return d;
  2678. } else {
  2679. return fv;
  2680. }
  2681. }
  2682. DefaultTheme.prototype.scrollTableAddScrollHandler = function(client,theme,cout,target,status,lr,fr,rows,totalrows,fv,fvVar,immediate) {
  2683. cout.scrollHandler = function () {
  2684. var rh = (lr-fr)/rows;
  2685. var d = theme.scrollTableGetFV(cout,lr,fr,rows,totalrows,fv);
  2686. if (d!=fv) {
  2687. // only submit if firstvisible changed
  2688. status.innerHTML = d + "-" + (d+rows-1) + " / " + totalrows + "...";
  2689. status.style.display = "";
  2690. // always immediate
  2691. theme.setVariable(client, fvVar, d, true);
  2692. } else {
  2693. // else realign
  2694. status.style.display = "none";
  2695. cout.scrollTop = fr;
  2696. }
  2697. };
  2698. }
  2699. DefaultTheme.prototype.scrollTableRecalc = function(pid,target) {
  2700. var defPad = 7;
  2701. var div = target.ownerDocument.getElementById(pid);
  2702. var wholeWidth = div.initialWidth;
  2703. var colWidths = div.colWidths;
  2704. if (!colWidths) {
  2705. colWidths = new Object();
  2706. div.colWidths = colWidths;
  2707. }
  2708. var hout = target.ownerDocument.getElementById(pid+"hout");
  2709. var cout = target.ownerDocument.getElementById(pid+"cout");
  2710. var hin = target.ownerDocument.getElementById(pid+"hin");
  2711. var cin = target.ownerDocument.getElementById(pid+"cin");
  2712. var h = hin.getElementsByTagName("td");
  2713. var c = cin.getElementsByTagName("td");
  2714. var whole = 0;
  2715. var col = -1;
  2716. for (var i = 0;i<h.length;i++) {
  2717. if (!h[i].getAttribute||!h[i].getAttribute("id")||h[i].getAttribute("id").indexOf(pid+"he")<0) {
  2718. continue;
  2719. }
  2720. col++;
  2721. // colWidth, or whole width if only one column
  2722. var cw = (h.length>1?colWidths[h[i].getAttribute("cid")]:hout.clientWidth-20);
  2723. var w1 = h[i].firstChild.clientWidth + defPad;
  2724. var w2 = (c[col]?c[col].firstChild.clientWidth + defPad:0);
  2725. var w = parseInt((cw?cw:(w1>w2?w1:w2)));
  2726. h[i].width = w;
  2727. h[i].style.width = w+"px";
  2728. h[i].firstChild.style.width = w+"px";
  2729. var rows = c.length/h.length;
  2730. for (var j=0;j<rows;j++) {
  2731. var idx = j*h.length+col;
  2732. if (c[idx]) {
  2733. c[idx].width = w;
  2734. c[idx].firstChild.style.width = w+"px";
  2735. c[idx].style.width = w+"px";
  2736. colWidths[h[i].getAttribute("cid")] = w;
  2737. }
  2738. }
  2739. whole += parseInt(w);
  2740. }
  2741. }
  2742. // Header order drag & drop
  2743. DefaultTheme.prototype.addToDragOrderGroup = function (client,theme,element,group,variable,sortVar,sortascVar,sortasc) {
  2744. element.dragGroup = group;
  2745. if (!group.elements) {
  2746. group.elements = new Array();
  2747. }
  2748. var idx = group.elements.length;
  2749. group.elements[idx] = element;
  2750. var mouseDragListener = function (e) {
  2751. var evt = client.getEvent(e);
  2752. evt.stop();
  2753. element.ownerDocument.onselectstart = function() {return false;}
  2754. var target = element.target;
  2755. target.style.position = "relative";
  2756. target.style.top = "5px";
  2757. try {
  2758. target.style.left = -(target.origX-evt.mouseX+10)+"px";
  2759. } catch (err) {
  2760. client.error("Failed: d&d target.style.left="+ (-(target.origX-evt.mouseX+10)+"px"));
  2761. }
  2762. var dragGroup = element.dragGroup;
  2763. dragGroup.moved = true;
  2764. var els = dragGroup.elements;
  2765. for (var i=0;i<els.length;i++) {
  2766. if (i==element.idx) continue;
  2767. var el = els[i];
  2768. var p = client.getElementPosition(el);
  2769. if (i!=dragGroup.origIdx&&i-1!=dragGroup.origIdx&&p.x < evt.mouseX && p.x+p.w/2 > evt.mouseX) {
  2770. dragGroup.targetIdx = i;
  2771. el.style.borderLeft = "1px solid black";
  2772. el.style.borderRight = "";
  2773. break;
  2774. } else if (i!=dragGroup.origIdx&&i+1!=dragGroup.origIdx && p.x+p.w/2 < evt.mouseX && p.x+p.w > evt.mouseX) {
  2775. dragGroup.targetIdx = i+1;
  2776. el.style.borderRight = "1px solid black";
  2777. el.style.borderLeft = "";
  2778. break;
  2779. } else {
  2780. dragGroup.targetIdx = dragGroup.origIdx;
  2781. el.style.borderRight = "";
  2782. el.style.borderLeft = "";
  2783. }
  2784. }
  2785. }
  2786. var mouseUpListener = function(e) {
  2787. client.removeEventListener(element.ownerDocument.body,"mousemove",mouseDragListener);
  2788. client.removeEventListener(element.ownerDocument.body,"mouseup",arguments.callee);
  2789. var evt = client.getEvent(e);
  2790. evt.stop();
  2791. element.ownerDocument.onselectstart = null;
  2792. element.target.style.background = "";
  2793. element.dragGroup.dragging = false;
  2794. if (element.dragGroup.dragTM) {
  2795. clearTimeout(element.dragGroup.dragTM);
  2796. }
  2797. if (!element.dragGroup.moved) {
  2798. if (sortVar) {
  2799. var cid = element.getAttribute("cid");
  2800. var sorted = element.getAttribute("sorted");
  2801. //alert("sorting "+element.getAttribute("cid") + " " + sorted + " " + sortasc);
  2802. if (sorted) {
  2803. theme.setVariable(client, sortascVar, !sortasc, true);
  2804. } else {
  2805. theme.setVariable(client, sortVar, cid, true);
  2806. }
  2807. }
  2808. }
  2809. var origIdx = element.dragGroup.origIdx;
  2810. var targetIdx = element.dragGroup.targetIdx;
  2811. if (origIdx != targetIdx) {
  2812. var els = element.dragGroup.elements;
  2813. var neworder = new Array();
  2814. for (var i=0;i<els.length;i++) {
  2815. if (i==origIdx) continue;
  2816. if (i==targetIdx) {
  2817. neworder[neworder.length] = els[origIdx].getAttribute("cid");
  2818. }
  2819. neworder[neworder.length] = els[i].getAttribute("cid");
  2820. }
  2821. theme.setVariable(client, variable, neworder, true);
  2822. } else {
  2823. element.target.style.left = "0px";
  2824. element.target.style.top = "0px";
  2825. }
  2826. };
  2827. client.addEventListener(element,"mousedown", function(e) {
  2828. var evt = client.getEvent(e);
  2829. evt.stop();
  2830. element.dragGroup.dragging = true;
  2831. element.dragGroup.moved = false;
  2832. element.dragGroup.origIdx = idx;
  2833. element.dragGroup.targetIdx = idx;
  2834. element.target = evt.target;
  2835. evt.target.dragGroup = element.dragGroup;
  2836. evt.target.origX = evt.mouseX;
  2837. evt.target.idx = idx;
  2838. if (element.dragGroup.dragTM) {
  2839. clearTimeout(element.dragGroup.dragTM);
  2840. }
  2841. client.addEventListener(element.ownerDocument.body,"mouseup", mouseUpListener);
  2842. if (variable) {
  2843. // column reordering allowed
  2844. group.dragTM = setTimeout(function () {
  2845. if(element.dragGroup.dragging) {
  2846. evt.target.style.background = "white";
  2847. client.addEventListener(element.ownerDocument.body,"mousemove",mouseDragListener);
  2848. }
  2849. },100);
  2850. }
  2851. });
  2852. //client.addEventListener(element,"mouseup", mouseUpListener);
  2853. }
  2854. DefaultTheme.prototype.renderSelect = function(renderer,uidl,target,layoutInfo) {
  2855. var theme = renderer.theme;
  2856. var client = renderer.client;
  2857. // Create containing element
  2858. var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  2859. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  2860. // Create selection variable
  2861. var selectMode = uidl.getAttribute("selectmode");
  2862. var selectable = selectMode == "multi" || selectMode == "single";
  2863. var immediate = ("true" == uidl.getAttribute("immediate"));
  2864. var disabled = ("true" == uidl.getAttribute("disabled"));
  2865. var readonly = ("true" == uidl.getAttribute("readonly"));
  2866. var newitem = ("true" == uidl.getAttribute("allownewitem"));
  2867. var focusid = uidl.getAttribute("focusid");
  2868. var tabindex = uidl.getAttribute("tabindex");
  2869. var selectionVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","selected"));
  2870. // Render default header
  2871. theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
  2872. // Create select input
  2873. var select = theme.createElementTo(div,"select");
  2874. if (focusid) select.focusid = focusid;
  2875. if (tabindex) select.tabIndex = tabindex;
  2876. if (selectMode == "multi") {
  2877. select.setAttribute("multiple", "true");
  2878. if (newitem) {
  2879. theme.createElementTo(div,"br");
  2880. }
  2881. } else {
  2882. if (newitem) {
  2883. theme.addCSSClass(div,"nobr");
  2884. }
  2885. }
  2886. var options = theme.getFirstElement(uidl,"options");
  2887. if (options != null) {
  2888. options = options.getElementsByTagName("so");
  2889. if (options && options.length && selectMode == "multi") {
  2890. select.size = (options.length>7?7:options.length);
  2891. }
  2892. }
  2893. if (disabled||readonly) {
  2894. select.disabled = "true";
  2895. } else {
  2896. // Add change listener
  2897. theme.addSetVarListener(theme,client,select,"change",selectionVariable,select,immediate);
  2898. }
  2899. // Empty selection for WA compatibility
  2900. var optionNode = theme.createElementTo(select,"option");
  2901. theme.createTextNodeTo(optionNode,"-");
  2902. // Selected options
  2903. if (options != null && options.length >0) {
  2904. for (var i=0; i<options.length;i++) {
  2905. var optionNode = new Option(
  2906. options[i].getAttribute("caption"),
  2907. options[i].getAttribute("key")
  2908. );
  2909. select.options[select.options.length] = optionNode;
  2910. if (options[i].getAttribute("selected") == "true") {
  2911. optionNode.selected = true;
  2912. // IE bug workaraund to preserve selection in multiselect
  2913. if(document.all) {
  2914. window.scrollBy(0,0);
  2915. }
  2916. }
  2917. }
  2918. }
  2919. if (newitem) {
  2920. var input = theme.createInputElementTo(div,"text");
  2921. var button = theme.createElementTo(div,"button");
  2922. theme.createTextNodeTo(button,"+");
  2923. var newitemVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"string","newitem"));
  2924. theme.addSetVarListener(theme,client,input,"change",newitemVariable,input,true);
  2925. }
  2926. }
  2927. DefaultTheme.prototype.renderSelectTwincol = function(renderer,uidl,target,layoutInfo) {
  2928. function deleteOptionFromSelectByOptionValue(select, value) {
  2929. for(var i = 0; i < select.options.length; i++) {
  2930. if(select.options[i].value == value) {
  2931. select.options[i] = null;
  2932. return true;
  2933. }
  2934. }
  2935. }
  2936. function setSelectedOfOptionFromSelectByOptionValue(select, value, sel) {
  2937. for(var i = 0; i < select.options.length; i++) {
  2938. if(select.options[i].value == value) {
  2939. select.options[i].selected = sel;
  2940. return true;
  2941. }
  2942. }
  2943. }
  2944. var theme = renderer.theme;
  2945. var client = renderer.client;
  2946. // Create containing element
  2947. var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  2948. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  2949. // Create selection variable
  2950. var selectMode = uidl.getAttribute("selectmode");
  2951. var selectable = selectMode == "multi" || selectMode == "single";
  2952. var immediate = ("true" == uidl.getAttribute("immediate"));
  2953. var disabled = ("true" == uidl.getAttribute("disabled"));
  2954. var readonly = ("true" == uidl.getAttribute("readonly"));
  2955. var newitem = ("true" == uidl.getAttribute("allownewitem"));
  2956. var focusid = uidl.getAttribute("focusid");
  2957. var tabindex = uidl.getAttribute("tabindex");
  2958. var selectionVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","selected"));
  2959. // Render default header
  2960. theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
  2961. if (newitem) {
  2962. theme.createElementTo(div,"br");
  2963. }
  2964. // create two selects
  2965. var unselected = theme.createElementTo(div,"select");
  2966. unselected.setAttribute("multiple","true");
  2967. unselected.className = "unselected";
  2968. var selected = theme.createElementTo(div,"select");
  2969. selected.setAttribute("multiple","true");
  2970. selected.className = "selected";
  2971. // buttons to move selections
  2972. var buttonsDiv = theme.createElementTo(div,"div");
  2973. buttonsDiv.className = "buttons";
  2974. //set focus and tabindex to unselected select
  2975. if (focusid) unselected.focusid = focusid;
  2976. if (tabindex) unselected.tabIndex = tabindex;
  2977. var options = theme.getFirstElement(uidl,"options");
  2978. if (options != null) {
  2979. options = options.getElementsByTagName("so");
  2980. unselected.size = (options.length>7?7:options.length);
  2981. selected.size = (options.length>7?7:options.length);
  2982. }
  2983. // Select options
  2984. if (options != null && options.length >0) {
  2985. for (var i=0; i<options.length;i++) {
  2986. var modelOptionNode;
  2987. if (options[i].getAttribute("selected") == "true") {
  2988. modelOptionNode = theme.createElementTo(selected,"option");
  2989. } else {
  2990. modelOptionNode = theme.createElementTo(unselected,"option");
  2991. }
  2992. theme.createTextNodeTo(modelOptionNode,options[i].getAttribute("caption"));
  2993. modelOptionNode.setAttribute("value", options[i].getAttribute("key"));
  2994. }
  2995. }
  2996. if (newitem) {
  2997. var input = theme.createInputElementTo(div,"text");
  2998. var button = theme.createElementTo(div,"button");
  2999. theme.createTextNodeTo(button,"+");
  3000. var newitemVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"string","newitem"));
  3001. theme.addSetVarListener(theme,client,input,"change",newitemVariable,input,true);
  3002. }
  3003. var moveRightButton = theme.createElementTo(buttonsDiv, "button");
  3004. moveRightButton.innerHTML = "&gt;&gt;";
  3005. moveRightButton.onclick = function() {
  3006. // loop all selected options unselected-list
  3007. while(unselected.selectedIndex > -1) {
  3008. var option = unselected.options[unselected.selectedIndex];
  3009. //add selected options to end of selected-list
  3010. selected.options[selected.options.length] =
  3011. new Option(
  3012. option.text,
  3013. option.value
  3014. );
  3015. // remove from unselected-list
  3016. deleteOptionFromSelectByOptionValue(unselected,option.value)
  3017. }
  3018. if(selectMode != "multi") {
  3019. // in single select mode, ensure only one option on right side
  3020. // not ment for single select mode, just to be more compatible
  3021. while(selected.options.length > 1) {
  3022. var optionToLeft = selected.options[0];
  3023. unselected.options[unselected.options.length] =
  3024. new Option(
  3025. optionToLeft.text,
  3026. optionToLeft.value
  3027. );
  3028. selected.options[0] = null;
  3029. // remove from selected-list
  3030. deleteOptionFromSelectByOptionValue(selected,optionToLeft.value)
  3031. }
  3032. } // end checking for single variable
  3033. // fire variable change
  3034. var s = new Array();
  3035. for (var i = 0; i < selected.options.length; i++) {
  3036. s[s.length] = selected.options[i].value;
  3037. }
  3038. var value = s.join(',');
  3039. theme.setVariable(client,selectionVariable,value,immediate);
  3040. }
  3041. var moveLeftButton = theme.createElementTo(buttonsDiv, "button");
  3042. moveLeftButton.innerHTML = "&lt;&lt;";
  3043. moveLeftButton.onclick = function() {
  3044. // loop all selected options selected-list
  3045. while(selected.selectedIndex > -1) {
  3046. var option = selected.options[selected.selectedIndex];
  3047. //add selected options to end of selected-list
  3048. unselected.options[unselected.options.length] =
  3049. new Option(
  3050. option.text,
  3051. option.value
  3052. );
  3053. // remove from unselected-list
  3054. deleteOptionFromSelectByOptionValue(selected,option.value)
  3055. }
  3056. // fire variable change
  3057. var s = new Array();
  3058. for (var i = 0; i < selected.options.length; i++) {
  3059. s[s.length] = selected.options[i].value;
  3060. }
  3061. var value = s.join(',');
  3062. theme.setVariable(client,selectionVariable,value,immediate);
  3063. }
  3064. if (disabled||readonly) {
  3065. selected.disabled = "true";
  3066. unselected.disabled = "true";
  3067. moveLeftButton.disabled = "true";
  3068. moveRightButton.disabled = "true";
  3069. }
  3070. }
  3071. DefaultTheme.prototype.renderSelectOptionGroup = function(renderer,uidl,target,layoutInfo) {
  3072. // TODO:
  3073. // - newitem currently always immediate, change
  3074. // - optiongrouphorizontal style
  3075. var theme = renderer.theme;
  3076. var client = renderer.client;
  3077. // Create containing element
  3078. var div = theme.createPaintableElement(renderer,uidl,target);
  3079. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  3080. // Create selection variable
  3081. var selectMode = uidl.getAttribute("selectmode");
  3082. var selectable = selectMode == "multi" || selectMode == "single";
  3083. var immediate = ("true" == uidl.getAttribute("immediate"));
  3084. var disabled = ("true" == uidl.getAttribute("disabled"));
  3085. var readonly = ("true" == uidl.getAttribute("readonly"));
  3086. var newitem = ("true" == uidl.getAttribute("allownewitem"));
  3087. var selectionVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","selected"));
  3088. // Render default header
  3089. theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
  3090. // Create select input
  3091. var select = theme.createElementTo(div,"div");
  3092. var options = theme.getFirstElement(uidl,"options");
  3093. if (options != null) {
  3094. options = options.getElementsByTagName("so");
  3095. }
  3096. // Selected options
  3097. if (options != null && options.length >0) {
  3098. for (var i=0; i<options.length;i++) {
  3099. var optionUidl = options[i];
  3100. var iconUrl = optionUidl.getAttribute("icon");
  3101. var div = theme.createElementTo(select,"div", "nobr");
  3102. var key = optionUidl.getAttribute("key");
  3103. // Create input
  3104. var inputName = "input"+uidl.getAttribute("id");
  3105. var inputId = inputName+i;
  3106. var input = null;
  3107. var caption = optionUidl.getAttribute("caption");
  3108. var html;
  3109. if (selectMode == "multi") {
  3110. html = "<input class=\"option\" type=checkbox name=\""+inputName+"\" id=\""+inputId+"\" ";
  3111. } else {
  3112. html = "<input class=\"option\" type=radio name=\""+inputName+"\" id=\""+inputId+"\" ";
  3113. }
  3114. if (disabled||readonly) html += " disabled=\"true\" "
  3115. if (optionUidl.getAttribute("selected") == "true") {
  3116. html += " checked=\"true\" "
  3117. }
  3118. html += " ><label class=\"clickable\" for=\""+inputId+"\">";
  3119. if (caption) html += caption;
  3120. if (iconUrl) {
  3121. if (iconUrl.indexOf("theme://") == 0) {
  3122. iconUrl = (theme.iconRoot != null ? theme.iconRoot : theme.root)
  3123. + iconUrl.substring(8);
  3124. }
  3125. html += "<IMG src=\""+iconUrl+"\" class=\"icon\">";
  3126. }
  3127. html += "</label>";
  3128. div.innerHTML = html;
  3129. if (!(disabled||readonly)) {
  3130. var input = div.firstChild;
  3131. if (selectMode == "multi") {
  3132. theme.addToggleVarListener(theme,client,input,"click",selectionVariable,key,immediate);
  3133. } else {
  3134. theme.addSetVarListener(theme,client,input,"click",selectionVariable,key,immediate);
  3135. }
  3136. }
  3137. }
  3138. }
  3139. if (newitem) {
  3140. var ni = theme.createElementTo(div,"div","newitem");
  3141. var input = theme.createInputElementTo(ni,"text");
  3142. var button = theme.createElementTo(ni,"button");
  3143. theme.createTextNodeTo(button,"+");
  3144. var newitemVariable = theme.createVariableElementTo(ni,theme.getVariableElement(uidl,"string","newitem"));
  3145. theme.addSetVarListener(theme,client,input,"change",newitemVariable,input,true);
  3146. }
  3147. }
  3148. DefaultTheme.prototype.renderLabel = function(renderer,uidl,target,layoutInfo) {
  3149. // Create container element
  3150. var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  3151. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  3152. // Create default header
  3153. var caption = renderer.theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
  3154. // Render children to div
  3155. if (uidl.childNodes.length>0) {
  3156. div = renderer.theme.createElementTo(div,"div");
  3157. renderer.theme.renderChildNodes(renderer, uidl, div);
  3158. }
  3159. if (div.innerHTML == "") div.innerHTML = "&nbsp;";
  3160. }
  3161. DefaultTheme.prototype.renderData = function(renderer,uidl,target) {
  3162. var html = "";
  3163. for (var i=0; i<uidl.childNodes.length; i++) {
  3164. var child = uidl.childNodes.item(i);
  3165. if (child.nodeType == Node.ELEMENT_NODE) {
  3166. html += renderer.theme.nodeToString(child,true);
  3167. } if (child.nodeType == Node.TEXT_NODE && child.data != null) {
  3168. html += child.data;
  3169. }
  3170. }
  3171. target.innerHTML = html;
  3172. }
  3173. DefaultTheme.prototype.renderPre = function(renderer,uidl,target) {
  3174. // Create pre node
  3175. var pre = renderer.theme.createElementTo(target,"pre");
  3176. var html = "";
  3177. for (var i=0; i<uidl.childNodes.length; i++) {
  3178. var child = uidl.childNodes.item(i);
  3179. if (child.nodeType == Node.ELEMENT_NODE) {
  3180. html += renderer.theme.nodeToString(child,true);
  3181. } if (child.nodeType == Node.TEXT_NODE && child.data != null) {
  3182. html += child.data;
  3183. }
  3184. }
  3185. pre.innerHTML = html;
  3186. }
  3187. DefaultTheme.prototype.renderButton = function(renderer,uidl,target,layoutInfo) {
  3188. // Branch for checkbox
  3189. if (uidl.getAttribute("type") == "switch") {
  3190. return renderer.theme.renderCheckBox(renderer,uidl,target,layoutInfo);
  3191. }
  3192. // Shortcuts
  3193. var theme = renderer.theme;
  3194. var client = renderer.client;
  3195. var disabled = "true"==uidl.getAttribute("disabled");
  3196. var readonly = "true"==uidl.getAttribute("readonly");
  3197. var immediate = "true"==uidl.getAttribute("immediate");
  3198. var tabindex = uidl.getAttribute("tabindex");
  3199. var linkStyle = "link"==uidl.getAttribute("style");
  3200. var div = theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  3201. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  3202. div = renderer.theme.createElementTo(div,"div",(linkStyle?"link clickable":"outset clickable"));;
  3203. var inner = renderer.theme.createElementTo(div,"div",(linkStyle?"pad":"border pad bg"));
  3204. var caption = theme.renderDefaultComponentHeader(renderer,uidl,inner);
  3205. theme.addTabtoHandlers(client,theme,caption,div,tabindex,("default"==uidl.getAttribute("style")));
  3206. if (!disabled&&!readonly) {
  3207. // Handlers
  3208. var v = theme.getVariableElement(uidl,"boolean", "state");
  3209. if (v != null) {
  3210. var varId = v.getAttribute("id");
  3211. theme.addSetVarListener(theme,client,div,"click",varId,"true",immediate);
  3212. theme.addAddClassListener(theme,client,div,"mouseover","over",div);
  3213. theme.addRemoveClassListener(theme,client,div,"mouseout","over",div);
  3214. }
  3215. }
  3216. }
  3217. DefaultTheme.prototype.renderCheckBox = function(renderer,uidl,target,layoutInfo) {
  3218. // Shortcuts
  3219. var theme = renderer.theme;
  3220. var client = renderer.client;
  3221. var div = theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  3222. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  3223. var immediate = (uidl.getAttribute("immediate") == "true");
  3224. var disabled = (uidl.getAttribute("disabled") == "true");
  3225. var readonly = (uidl.getAttribute("readonly") == "true");
  3226. var tabindex = uidl.getAttribute("tabindex");
  3227. // Create input
  3228. var div = theme.createElementTo(div,"div","nocappad nobr");
  3229. var input = theme.createInputElementTo(div,"checkbox");
  3230. input.setAttribute("id", "input"+uidl.getAttribute("id"));
  3231. if (tabindex) input.tabIndex = tabindex;
  3232. if (disabled||readonly) {
  3233. input.disabled = "true";
  3234. }
  3235. // Create label
  3236. var label = theme.createElementTo(div,"label", "clickable");
  3237. var cap = theme.renderDefaultComponentHeader(renderer,uidl,label);
  3238. theme.addCSSClass(cap,"inline");
  3239. label.setAttribute("for","input"+uidl.getAttribute("id"));
  3240. // Value
  3241. var v = theme.getVariableElement(uidl,"boolean", "state");
  3242. if ( v!= null) {
  3243. var varId = v.getAttribute("id");
  3244. input.checked = (v.getAttribute("value") == "true");
  3245. // Attach listener
  3246. theme.addSetVarListener(theme,client,input,(immediate?"click":"change"),varId,input,immediate);
  3247. }
  3248. }
  3249. ///////
  3250. /* TODO merge or delete the rest
  3251. /**
  3252. * Render tree as a menubar.
  3253. * NOTE:
  3254. * First level nodes are not selectable - menu opens with click.
  3255. * If style == "coolmenu", immediate is forced.
  3256. *
  3257. */
  3258. DefaultTheme.prototype.renderTreeMenu = function(renderer,uidl,target,layoutInfo) {
  3259. var theme = renderer.theme;
  3260. // Create container element
  3261. var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
  3262. if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
  3263. // Get tree attributes
  3264. var style = uidl.getAttribute("style");
  3265. var immediate = ("true" == uidl.getAttribute("immediate")||style=="coolmenu");
  3266. var disabled = ("true" == uidl.getAttribute("disabled"));
  3267. var readonly = ("true" == uidl.getAttribute("readonly"));
  3268. var selectMode = uidl.getAttribute("selectmode");
  3269. var selectable = selectMode == "multi" || selectMode == "single";
  3270. var selected;
  3271. if (selectable) {
  3272. selected = new Object();
  3273. }
  3274. var selectionVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","selected"));
  3275. var expandVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","expand"));
  3276. var collapseVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","collapse"));
  3277. var actions = null;
  3278. var actionVar = null;
  3279. var alNode = theme.getFirstElement(uidl,"actions")
  3280. if (alNode) {
  3281. actionVar = theme.createVariableElementTo(div,theme.getVariableElement(alNode,"string","action"));
  3282. actions = new Object();
  3283. var ak = alNode.getElementsByTagName("action");
  3284. for (var i=0;i<ak.length;i++) {
  3285. actions[ak[i].getAttribute("key")] = ak[i].getAttribute("caption");
  3286. }
  3287. }
  3288. delete alNode;
  3289. // Create default header
  3290. var caption = renderer.theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
  3291. // Content DIV
  3292. var content = theme.createElementTo(div,"div","content menu");
  3293. // Iterate all nodes
  3294. for (var i = 0; i< uidl.childNodes.length;i++) {
  3295. var node = uidl.childNodes[i];
  3296. if (node.nodeName == "node" || node.nodeName == "leaf") {
  3297. theme.renderTreeMenuNode(renderer,node,content,selectable,selectMode,selected,selectionVariable,expandVariable,collapseVariable,actions,actionVar,immediate,disabled,readonly,0);
  3298. }
  3299. }
  3300. }
  3301. DefaultTheme.prototype.renderTreeMenuNode = function(renderer,node,target,selectable,selectMode,selected,selectionVariable,expandVariable,collapseVariable,actions,actionVar,immediate,disabled,readonly,level) {
  3302. var theme = renderer.theme;
  3303. var client = renderer.client;
  3304. var n = theme.createElementTo(target,"div",(level==0?"inline clickable":"clickable"));
  3305. // Caption
  3306. var cap = theme.createElementTo(n,"div","inline caption pad");
  3307. theme.createTextNodeTo(cap,node.getAttribute("caption"));
  3308. // Expand/collapse/spacer button
  3309. var img = theme.createElementTo(n,"img","icon");
  3310. img.align = "absbottom";
  3311. var key = node.getAttribute("key");
  3312. var icon = node.getAttribute("icon");
  3313. if (icon) {
  3314. var iconurl = theme.root+icon.split("theme:")[1];
  3315. var iimg = theme.createElementTo(n,"img","icon");
  3316. iimg.src = iconurl;
  3317. }
  3318. // Hover effects
  3319. if (!disabled&&!readonly) {
  3320. theme.addAddClassListener(theme,client,n,"mouseover","selected",n);
  3321. theme.addRemoveClassListener(theme,client,n,"mouseout","selected",n);
  3322. }
  3323. // Server-side selection
  3324. if (selectable && node.getAttribute("selected") == "true") {
  3325. theme.addCSSClass(n,"selected");
  3326. selected[key] = n;
  3327. }
  3328. // Indicate selection
  3329. if (theme.listContainsInt(selectionVariable.value,key)) {
  3330. theme.addCSSClass(n, "selected");
  3331. }
  3332. // Selection listeners
  3333. if (selectable && !disabled && (level != 0 || node.nodeName == "leaf")) {
  3334. if (!readonly) {
  3335. if (selectMode == "single") {
  3336. theme.addAddClassListener(theme,client,n,"click","selected",n,selected);
  3337. theme.addSetVarListener(theme,client,n,"click",selectionVariable,key,immediate);
  3338. } else if (selectMode == "multi") {
  3339. theme.addToggleClassListener(theme,client,n,"click","selected");
  3340. theme.addToggleVarListener(theme,client,n,"click",selectionVariable,key,immediate);
  3341. }
  3342. }
  3343. }
  3344. // Actions
  3345. if (!disabled && !readonly) {
  3346. for (var i = 0; i< node.childNodes.length;i++) {
  3347. var childNode = node.childNodes[i];
  3348. if (childNode.nodeName == "al" ) {
  3349. theme.renderActionPopup(renderer,childNode,n,actions,actionVar,key,1); // TODO check
  3350. }
  3351. }
  3352. }
  3353. // Render all sub-nodes
  3354. if (node.nodeName == "node") {
  3355. var subnodes = theme.createElementTo(target,"div","hide popup");
  3356. var inner = theme.createElementTo(subnodes,"div","border");
  3357. theme.addTogglePopupListener(theme,client,n,(level==0?"click":"mouseover"),subnodes,0,null,n);
  3358. //theme.addToggleClassListener(theme,client,n,(level==0?"click":"mouseover"),"hide",subnodes)
  3359. if (node.childNodes != null && node.childNodes.length >0) {
  3360. img.src = theme.root + "img/tree/empty.gif";
  3361. img.expanded = "true";
  3362. } else {
  3363. img.src = theme.root + "img/tree/empty.gif";
  3364. img.expanded = "false";
  3365. }
  3366. for (var i = 0; i< node.childNodes.length;i++) {
  3367. var childNode = node.childNodes[i];
  3368. if (childNode.nodeName == "node" || childNode.nodeName == "leaf") {
  3369. theme.renderTreeMenuNode(renderer,childNode,inner,selectable,selectMode,selected,selectionVariable,expandVariable,collapseVariable,actions,actionVar,immediate,disabled,readonly,level+1);
  3370. }
  3371. }
  3372. // Add event listener
  3373. if (!disabled&&level!=0) {
  3374. var target = (selectable&&!readonly?img:n);
  3375. theme.addToggleClassListener(theme,client,target,"mouseup","hidden",subnodes);
  3376. theme.addExpandNodeListener(theme,client,img,"mouseup",subnodes,expandVariable,collapseVariable,key,immediate,target);
  3377. theme.addStopListener(theme,client,target,"mouseup");
  3378. theme.addStopListener(theme,client,target,"click");
  3379. }
  3380. } else {
  3381. img.src = theme.root + "img/tree/empty.gif";
  3382. }
  3383. }
  3384. /**
  3385. * 5.6.2006 - Jouni Koivuviita
  3386. * New innerHTML components
  3387. * RENAMED for testing both - marc
  3388. */
  3389. DefaultTheme.prototype.renderNewPanel = function(renderer,uidl,target,layoutInfo) {
  3390. // Shortcuts
  3391. var theme = renderer.theme;
  3392. var style = uidl.getAttribute("style");
  3393. // Create component element
  3394. var div = theme.createPaintableElement(renderer,uidl,target);
  3395. /* New panel theme, 8.6.2006 - Jouni Koivuviita */
  3396. div.innerHTML = "<div class=\"top\"><div class=\"right\"></div><div class=\"left\"><div class=\"title\"></div></div></div><div class=\"middle\"></div><div class=\"bottom\"><div class=\"right\"></div><div class=\"left\"></div></div>";
  3397. var cap = div.firstChild.firstChild.nextSibling.firstChild;
  3398. var content = div.childNodes[1];
  3399. theme.applyWidthAndHeight(uidl,div.childNodes[1],"height");
  3400. theme.applyWidthAndHeight(uidl,div,"width");
  3401. /*
  3402. div.innerHTML = "<TABLE width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TR height=\"35\"><TD width=\"12\"><IMG onload=\"png(this);\" src=\""+theme.root+"img/top-left.png\"></TD><TD style=\"background: url('"+theme.root+"img/top.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/top.png', sizingMethod='scale');\"></TD><TD width=\"12\"><IMG onload=\"png(this);\" src=\""+theme.root+"img/top-right.png\"></TD></TR><TR><TD style=\"background: url('"+theme.root+"img/left.png') !important;background: none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/left.png', sizingMethod='scale');\"></TD><TD bgcolor=white></TD><TD style=\"background: url('"+theme.root+"img/right.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/right.png', sizingMethod='scale');\"></TD></TR><TR height=\"12\"><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/bottom-left.png\"></TD><TD style=\"background: url('"+theme.root+"img/bottom.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/bottom.png', sizingMethod='scale');\"></TD><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/bottom-right.png\"></TD></TR></TABLE>";
  3403. var cap = div.firstChild.firstChild.firstChild.childNodes[1];
  3404. var content = div.firstChild.firstChild.childNodes[1].childNodes[1];
  3405. */
  3406. theme.renderDefaultComponentHeader(renderer,uidl,cap);
  3407. theme.renderChildNodes(renderer, uidl, content);
  3408. }
  3409. DefaultTheme.prototype.renderNewPanelModal = function(renderer,uidl,target,layoutInfo,alignment) {
  3410. // Shortcuts
  3411. var theme = renderer.theme;
  3412. //var parentTheme = theme.parent;
  3413. // Create component element
  3414. var div = theme.createPaintableElement(renderer,uidl,target);
  3415. var html = "<IFRAME frameborder=\"0\" style=\"border:none;z-index:9997;position:absolute;top:0px;left:0px;width:100%;height:100%;background-color:white;filter: alpha(opacity=80);opacity:0.8;\"></IFRAME>";
  3416. html += "<DIV align=\"center\" style=\"position:absolute;top:0px;width:100%;left:0px;z-index:9999;filter: alpha(opacity=100);opacity:1;\"><TABLE cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TR height=\"35\"><TD width=\"12\"><IMG onload=\"png(this);\" src=\""+theme.root+"img/top-left.png\"></TD><TD style=\"background: url('"+theme.root+"img/top.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/top.png', sizingMethod='scale');\"></TD><TD width=\"12\"><IMG onload=\"png(this);\" src=\""+theme.root+"img/top-right.png\"></TD></TR><TR><TD style=\"background: url('"+theme.root+"img/left.png') !important;background: none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/left.png', sizingMethod='scale');\"></TD><TD bgcolor=white ></TD><TD style=\"background: url('"+theme.root+"img/right.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/right.png', sizingMethod='scale');\"></TD></TR><TR height=\"12\"><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/bottom-left.png\"></TD><TD style=\"background: url('"+theme.root+"img/bottom.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/bottom.png', sizingMethod='scale');\"></TD><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/bottom-right.png\"></TD></TR></TABLE><DIV>";
  3417. div.innerHTML = html;
  3418. var overlay = div.firstChild;
  3419. overlay.style.width = div.ownerDocument.body.offsetWidth + "px";
  3420. overlay.style.height = div.ownerDocument.body.offsetHeight + "px";
  3421. var table = div.childNodes[1].firstChild;
  3422. var cap = table.firstChild.firstChild.childNodes[1];
  3423. var content = table.firstChild.childNodes[1].childNodes[1];
  3424. theme.renderDefaultComponentHeader(renderer,uidl,cap);
  3425. theme.renderChildNodes(renderer, uidl, content);
  3426. var ifrdiv = theme.createElementTo(div,"div");
  3427. html = "<IFRAME frameborder=\"0\" style=\"border:none;z-index:9998;position:absolute;top:"+(div.childNodes[1].offsetTop+5)+"px;left:"+(table.offsetLeft+5)+"px;width:"+(table.offsetWidth-7)+"px;height:"+(table.offsetHeight-7)+"px;background-color:white;filter: alpha(opacity=100);opacity:1;\"></IFRAME>";
  3428. ifrdiv.innerHTML += html;
  3429. }
  3430. DefaultTheme.prototype.renderNewPanelLight = function(renderer,uidl,target,layoutInfo) {
  3431. // Shortcuts
  3432. var theme = renderer.theme;
  3433. var style = uidl.getAttribute("style");
  3434. // Create component element
  3435. var div = theme.createPaintableElement(renderer,uidl,target);
  3436. div.innerHTML = "<TABLE width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TR><TD width=\"12\"><IMG onload=\"png(this);\" src=\""+theme.root+"img/top-left-lite.png\"></TD><TD style=\"background: url('"+theme.root+"img/top-lite.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/top-lite.png', sizingMethod='scale');\"></TD><TD width=\"12\"><IMG onload=\"png(this);\" src=\""+theme.root+"img/top-right-lite.png\"></TD></TR><TR><TD style=\"background: url('"+theme.root+"img/left.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/left.png', sizingMethod='scale');\"></TD><TD bgcolor=white></TD><TD style=\"background: url('"+theme.root+"img/right.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/right.png', sizingMethod='scale');\"></TD></TR><TR><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/bottom-left.png\"></TD><TD style=\"background: url('"+theme.root+"img/bottom.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/bottom.png', sizingMethod='scale');\"></TD><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/bottom-right.png\"></TD></TR></TABLE>";
  3437. var content = div.firstChild.firstChild.childNodes[1].childNodes[1];
  3438. theme.renderDefaultComponentHeader(renderer,uidl,content);
  3439. theme.renderChildNodes(renderer, uidl, content);
  3440. }
  3441. DefaultTheme.prototype.renderNewPanelNone = function(renderer,uidl,target,layoutInfo) {
  3442. // Shortcuts
  3443. var theme = renderer.theme;
  3444. var style = uidl.getAttribute("style");
  3445. // Create component element
  3446. var div = theme.createPaintableElement(renderer,uidl,target);
  3447. var content = theme.createElementTo(div,"div");
  3448. theme.renderDefaultComponentHeader(renderer,uidl,content);
  3449. theme.renderChildNodes(renderer, uidl, content);
  3450. }
  3451. DefaultTheme.prototype.renderNewTabSheet = function(renderer,uidl,target,layoutInfo) {
  3452. // Shortcuts
  3453. var theme = renderer.theme;
  3454. // Create component element
  3455. var div = theme.createPaintableElement(renderer,uidl,target);
  3456. if (uidl.getAttribute("invisible")) return;
  3457. var style = uidl.getAttribute("style");
  3458. var disabled = ("true"==uidl.getAttribute("disabled"));
  3459. var cdiv = theme.createElementTo(div,"div");
  3460. var caption = theme.renderDefaultComponentHeader(renderer,uidl,cdiv,layoutInfo);
  3461. div = theme.createElementTo(div,"div");
  3462. // Tabs
  3463. var tabNodes = theme.getChildElements(uidl,"tabs");
  3464. if (tabNodes != null && tabNodes.length >0) tabNodes = theme.getChildElements(tabNodes[0],"tab");
  3465. var selectedTabNode = null;
  3466. if (tabNodes != null && tabNodes.length >0) {
  3467. var html = "<TABLE width=\"100%\" class=\"tabsheet-table\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TBODY>";
  3468. html += "<TR valign=\"bottom\"><TD></TD>";
  3469. var posttabs = "<TR valign=\"top\"><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/tabsheet/top-left-lite.png\"/></TD>";
  3470. var len = tabNodes.length;
  3471. for (var i=0; i<len;i++) {
  3472. var tab = tabNodes[i];
  3473. var caption = tab.getAttribute("caption");
  3474. var icon = tab.getAttribute("icon");
  3475. if (icon) icon = theme.root+icon.split("theme://")[1];
  3476. var selected = ("true"==tab.getAttribute("selected"));
  3477. var disabled = ("true"==tab.getAttribute("disabled"));
  3478. var offset = (selected?6:4);
  3479. var variant = "";
  3480. if (disabled) {
  3481. variant = "-dis";
  3482. } else if (selected) {
  3483. variant = "-on";
  3484. }
  3485. if (selected) selectedTabNode = tab;
  3486. html += "<TD width=\"1\" align=\"right\"><IMG onload=\"png(this);\" onload=\"png(this);\" src=\""+theme.root+"img/tabsheet/top-left"+variant+".png\"/></TD><TD class=\""+(disabled?"caption":"caption clickable")+"\" style=\"background-image: url('"+theme.root+"img/tabsheet/top"+variant+".png') !important;background: none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/tabsheet/top"+variant+".png', sizingMethod='scale');\">"
  3487. html += "<DIV style=\"padding-top:0.5em;\" class=\"caption"+(selected&&!disabled?"":" clickable")+"\">";
  3488. if (icon) html += "<IMG onload=\"png(this);\" class=\"icon\" src=\""+icon+"\"/>";
  3489. html += caption+"</DIV>";
  3490. html += "</TD><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/tabsheet/top-right"+variant+".png\"/></TD>";
  3491. // POSTTABS
  3492. posttabs += "<TD align=\"right\" style=\"background-image: url('"+theme.root+"img/tabsheet/top-lite.png') !important;background: none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/tabsheet/top-lite.png', sizingMethod='scale');\"><IMG onload=\"png(this);\" height=\""+(selected?6:4)+"\" width=\"8\" src=\""+theme.root+"img/tabsheet/tab-left.png\"/></TD><TD "+(selected?"bgcolor=\"white\"":"style=\"background-image: url('"+theme.root+"img/tabsheet/top-lite.png') !important;background: white;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/tabsheet/top-lite.png', sizingMethod='scale');\"")+"></TD><TD style=\"background-image: url('"+theme.root+"img/tabsheet/top-lite.png') !important;background: none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/tabsheet/top-lite.png', sizingMethod='scale');\"><IMG onload=\"png(this);\" height=\""+(selected?6:4)+"\" width=\"8\" src=\""+theme.root+"img/tabsheet/tab-right.png\"/></TD>";
  3493. }
  3494. html += "<TD width=\"100%\"></TD></TR>"+posttabs+"<TD style=\"background-image: url('"+theme.root+"img/tabsheet/top-lite.png') !important;background: none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/tabsheet/top-lite.png', sizingMethod='scale');\" ></TD><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/tabsheet/top-right-lite.png\"/></TD></TR>";
  3495. //Content
  3496. html +="</TBODY></TABLE><TABLE width=\"100%\" class=\"tabsheet-table\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TBODY><TR valign=\"top\"><TD style=\"width:12px;background-image: url('"+theme.root+"img/tabsheet/left.png') !important;background: none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/tabsheet/left.png', sizingMethod='scale');\"></TD><TD style=\"width:100% !important;width:auto;\" class=\"tabsheet-content\" bgcolor=\"white\" colspan=\""+(len*3+1)+"\"><DIV></DIV></TD><TD width=\"12\" style=\"background-image: url('"+theme.root+"img/tabsheet/right.png') !important;background: none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/tabsheet/right.png', sizingMethod='scale');\"></TD></TR>";
  3497. html += "<TR height=\"12\" valign=\"top\"><TD width=\"8\"><IMG onload=\"png(this);\" src=\""+theme.root+"img/tabsheet/bottom-left.png\"></TD><TD style=\"background-image: url('"+theme.root+"img/tabsheet/bottom.png') !important;background: none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/tabsheet/bottom.png', sizingMethod='scale');\" colspan=\""+(len*3+1)+"\"></TD><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/tabsheet/bottom-right.png\"></TD></TR></TBODY></TABLE>";
  3498. div.innerHTML = html;
  3499. // TODO click listeners
  3500. if (!disabled) {
  3501. var varId = theme.getVariableElement(uidl,"string","selected").getAttribute("id");
  3502. for (var i=0; i<len;i++) {
  3503. var tabNode = tabNodes[i];
  3504. if (tabNode == selectedTabNode||("true"==tabNode.getAttribute("disabled"))) continue;
  3505. var key = tabNode.getAttribute("key");
  3506. var tab = div.firstChild.firstChild.firstChild.childNodes[2+i*3];
  3507. theme.addAddClassListener(theme,client,tab,"mouseover","over",tab);
  3508. theme.addRemoveClassListener(theme,client,tab,"mouseout","over",tab);
  3509. theme.addSetVarListener(theme,client,tab,"click",varId,key,true);
  3510. }
  3511. }
  3512. var content = div.childNodes[1].firstChild.firstChild.childNodes[1];
  3513. if (selectedTabNode) {
  3514. theme.renderChildNodes(renderer,selectedTabNode, content);
  3515. }
  3516. }
  3517. }
  3518. DefaultTheme.prototype.addDescriptionAndErrorPopupListener = function(theme, client, target, errorIcon) {
  3519. client.addEventListener(target, "mouseover",
  3520. function(e) {
  3521. var pos = theme.calculateAbsoluteEventPosition(theme, client, e);
  3522. theme.showDescriptionAndErrorPopup(theme, target, pos, 500); // 500 = delay
  3523. }
  3524. );
  3525. client.addEventListener(target, "mouseout",
  3526. function(e) {
  3527. if(!target._forcedOpen) theme.hideDescriptionAndErrorPopup(target);
  3528. }
  3529. );
  3530. client.addEventListener(target.ownerDocument.body, "click",
  3531. function(e) {
  3532. var ev = e? e:window.event;
  3533. if(!ev.cancelBubble) theme.hideDescriptionAndErrorPopup(target, true); // true = force close
  3534. }
  3535. );
  3536. if(errorIcon) {
  3537. client.addEventListener(errorIcon, "click",
  3538. function(e) {
  3539. var ev = e? e:window.event;
  3540. var pos = theme.calculateAbsoluteEventPosition(theme, client, e);
  3541. theme.showDescriptionAndErrorPopup(theme, target, pos, null, true); // null = no delay, true = force open
  3542. if(e.stopPropagation) e.stopPropagation();
  3543. ev.cancelBubble = true;
  3544. }
  3545. );
  3546. }
  3547. }
  3548. DefaultTheme.prototype.showDescriptionAndErrorPopup = function(theme, target, pos, delay, forceOpen) {
  3549. if(target._descriptionPopupTimeout) clearTimeout(target._descriptionPopupTimeout);
  3550. var descHTML = target._descriptionHTML;
  3551. var errorHTML = target._errorHTML;
  3552. if(!descHTML && !errorHTML) return;
  3553. if(!delay) {
  3554. // Reference to correct document
  3555. var doc = target.ownerDocument;
  3556. // Maximum css width of the description popup
  3557. var maxPopupWidth = "35em";
  3558. var popupContainer;
  3559. var description;
  3560. var error;
  3561. // TODO IFRAME below popup?
  3562. // If the container div is not found, create it once
  3563. if(!(popupContainer = doc.getElementById("popup-container-div"))) {
  3564. popupContainer = doc.createElement("div");
  3565. popupContainer.className = "popup";
  3566. popupContainer.id = "popup-container-div";
  3567. popupContainer.style.left = "-10000px";
  3568. popupContainer.style.top = "-10000px";
  3569. description = doc.createElement("div");
  3570. description.className = "description border";
  3571. popupContainer.appendChild(description);
  3572. error = doc.createElement("div");
  3573. error.className = "error";
  3574. popupContainer.appendChild(error);
  3575. doc.body.appendChild(popupContainer);
  3576. // Enable clicking on container
  3577. client.addEventListener(popupContainer, "click",
  3578. function(e) {
  3579. var ev = e? e:window.event;
  3580. if(e.stopPropagation) e.stopPropagation();
  3581. ev.cancelBubble = true;
  3582. }
  3583. );
  3584. // If already create, restore references
  3585. } else {
  3586. description = popupContainer.firstChild;
  3587. error = popupContainer.childNodes[1];
  3588. }
  3589. description.innerHTML = descHTML? descHTML : "";
  3590. error.innerHTML = errorHTML? errorHTML : "";
  3591. if(!descHTML) description.style.display = "none";
  3592. else description.style.display = "block";
  3593. if(!errorHTML) error.style.display = "none";
  3594. else error.style.display = "block";
  3595. popupContainer.style.width = "auto";
  3596. // Align the popup
  3597. // TODO take smaller resolutions into consideration (i.e. if the popupWidth is wider than the browser window)
  3598. var popupWidth = popupContainer.clientWidth;
  3599. var available = doc.body.clientWidth-pos.x;
  3600. if(popupWidth > available) {
  3601. popupContainer.style.width = maxPopupWidth;
  3602. popupWidth = popupContainer.clientWidth;
  3603. if(popupWidth > available) popupContainer.style.left = pos.x + 12 - (popupWidth-available) + "px";
  3604. else popupContainer.style.left = pos.x + 12 + "px";
  3605. popupContainer.style.top = pos.y + 20 + "px";
  3606. } else {
  3607. popupContainer.style.left = pos.x + 12 + "px";
  3608. popupContainer.style.top = pos.y + 20 + "px";
  3609. }
  3610. if(forceOpen) target._forcedOpen = true;
  3611. else target._forcedOpen = false;
  3612. } else {
  3613. target._descriptionPopupTimeout = setTimeout(function() {theme.showDescriptionAndErrorPopup(theme, target, pos);}, delay);
  3614. }
  3615. }
  3616. DefaultTheme.prototype.hideDescriptionAndErrorPopup = function(target, forceClose) {
  3617. if(target._descriptionPopupTimeout) clearTimeout(target._descriptionPopupTimeout);
  3618. if((popupContainer = target.ownerDocument.getElementById("popup-container-div")) && (!target._forcedOpen || forceClose)) {
  3619. popupContainer.style.left = "-10000px";
  3620. popupContainer.style.top = "-10000px";
  3621. target._forcedOpen = false;
  3622. }
  3623. }
  3624. /**
  3625. * Calculate the absolute coordinates relative to this documents window of
  3626. * the event using mouse and browser window positions relative to the screen (IE)
  3627. * (Not 100% accurate, some pixels off in both IE and FF)
  3628. * Firefox uses normal DOM calculations.
  3629. *
  3630. * @param boolean modFF Don't use DOM calculations to get the position in Firefox.
  3631. * (Not reliable with all frame and browser plugin compositions)
  3632. *
  3633. * Returns an object with x and y properties.
  3634. */
  3635. DefaultTheme.prototype.calculateAbsoluteEventPosition = function(theme, client, e, modFF) {
  3636. if (!e) var e = window.event;
  3637. if(window.screenY) { // Firefox
  3638. // Calculate with default DOM calculation
  3639. if(!modFF) return theme.eventPosition(e);
  3640. // Doesn't actually work, always returns true.
  3641. var statusBarHeight = (window.statusbar.visible)? 26 : 0; // Default XP Blue theme estimate
  3642. // Coordinates to browser windows content area, with no frames.
  3643. // Substract browser chrome (toolbars and such) from the height.
  3644. // Some plugins, that require screen estate from the browser content
  3645. // window, may misalign the coordinates.
  3646. var windowY = window.screenY + (window.outerHeight - window.innerHeight - statusBarHeight);
  3647. var windowX = window.screenX + (window.outerWidth - window.innerWidth);
  3648. // Gecko needs to take frames into consideration when calculating the position.
  3649. // TODO Only works reliably when the page is simply divided either into rows or cols.
  3650. // Are we in a frame?
  3651. // (this script is in one of the frames, so the parent will have frames)
  3652. var frames = window.parent.frames;
  3653. var len = frames.length;
  3654. if(len > 0) { // Frames in use
  3655. var precedingWidth = 0, precedingHeight = 0;
  3656. var flagSucceeding = false;
  3657. for(var i=0; i < len; i++) {
  3658. var frame = frames[i];
  3659. if(window==frame) flagSucceeding = true;
  3660. // Only count preceding widths that are different from this window (don't count row widths)
  3661. if(frame.innerWidth != window.innerWidth || frame != window) {
  3662. if(!flagSucceeding) {
  3663. precedingWidth += frame.innerWidth;
  3664. continue; // Don't count the height anymore
  3665. }
  3666. }
  3667. // Same for preceding heights, if no width was added
  3668. if(frame.innerHeight != window.innerHeight || frame != window) {
  3669. if(!flagSucceeding) precedingHeight += frame.innerHeight;
  3670. }
  3671. }
  3672. // Do the math :)
  3673. windowY = window.screenY + (window.outerHeight - window.parent.innerHeight + precedingHeight - statusBarHeight);
  3674. windowX = window.screenX + (window.outerWidth - window.parent.innerWidth + precedingWidth);
  3675. }
  3676. } else if(window.screenTop) { // IE, handles frames correct natively
  3677. var windowY = window.screenTop;
  3678. var windowX = window.screenLeft;
  3679. }
  3680. var scroll = theme.getScrollXY(window);
  3681. // TODO Relative positioned containers for the popup
  3682. // will cause wrong positioning
  3683. var posx = e.screenX - windowX + scroll.x;
  3684. var posy = e.screenY - windowY + scroll.y;
  3685. return {x:posx, y:posy};
  3686. }
  3687. /**
  3688. * Calculate the scroll amount of a window, both x and y.
  3689. *
  3690. * Returns an object with x and y properties.
  3691. */
  3692. DefaultTheme.prototype.getScrollXY = function(win) {
  3693. var doc = win.document;
  3694. var scrOfX = 0, scrOfY = 0;
  3695. if( typeof( win.pageYOffset ) == 'number' ) {
  3696. //Netscape compliant
  3697. scrOfY = win.pageYOffset;
  3698. scrOfX = win.pageXOffset;
  3699. } else if( doc.body && ( doc.body.scrollLeft || doc.body.scrollTop ) ) {
  3700. //DOM compliant
  3701. scrOfY = doc.body.scrollTop;
  3702. scrOfX = doc.body.scrollLeft;
  3703. } else if( doc.documentElement && ( doc.documentElement.scrollLeft || doc.documentElement.scrollTop ) ) {
  3704. //IE6 standards compliant mode
  3705. scrOfY = doc.documentElement.scrollTop;
  3706. scrOfX = doc.documentElement.scrollLeft;
  3707. }
  3708. return {x:scrOfX, y:scrOfY};
  3709. }
  3710. /**
  3711. * Calculate event position (Quirksmode.org script)
  3712. */
  3713. DefaultTheme.prototype.eventPosition = function(e) {
  3714. var posx = 0;
  3715. var posy = 0;
  3716. if (!e) var e = window.event;
  3717. if (e.pageX || e.pageY) {
  3718. posx = e.pageX;
  3719. posy = e.pageY;
  3720. } else if (e.clientX || e.clientY) {
  3721. posx = e.clientX + document.body.scrollLeft
  3722. + document.documentElement.scrollLeft;
  3723. posy = e.clientY + document.body.scrollTop
  3724. + document.documentElement.scrollTop;
  3725. }
  3726. return {x:posx, y:posy};
  3727. }